From 159d24571c4fa6557fee3bbc1910a812d1afb094 Mon Sep 17 00:00:00 2001 From: Alan Agius <17563226+alan-agius4@users.noreply.github.com> Date: Wed, 3 Jun 2026 12:33:40 +0000 Subject: [PATCH 001/787] docs: release notes for the v21.2.14 release --- CHANGELOG.md | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4257d646347f..b7b992b2af1b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,21 @@ + + +# 21.2.14 (2026-06-03) + +### @angular/cli + +| Commit | Type | Description | +| --------------------------------------------------------------------------------------------------- | ---- | --------------------------------------------------------------------------- | +| [aed448748](https://github.com/angular/angular-cli/commit/aed448748451b6b87c20e7bd9b3b1f822067f681) | fix | expand package groups for newly added peer dependencies in update schematic | + +### @angular/build + +| Commit | Type | Description | +| --------------------------------------------------------------------------------------------------- | ---- | --------------------------------------------- | +| [d46c082fb](https://github.com/angular/angular-cli/commit/d46c082fb994138327eb36882373f63daeec8bc1) | fix | prevent esbuild service child process leakage | + + + # 20.3.27 (2026-06-02) From 09d3bbb2766aa6310fd250da72f39960c633a8fe Mon Sep 17 00:00:00 2001 From: Alan Agius <17563226+alan-agius4@users.noreply.github.com> Date: Wed, 3 Jun 2026 13:56:43 +0000 Subject: [PATCH 002/787] docs: update changelog with v22 release --- CHANGELOG.md | 545 ++++++++++++--------------------------------------- 1 file changed, 122 insertions(+), 423 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index b7b992b2af1b..dd3b18b1101e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,210 +1,198 @@ - + -# 21.2.14 (2026-06-03) +# 22.0.0 (2026-06-03) -### @angular/cli +## Breaking Changes -| Commit | Type | Description | -| --------------------------------------------------------------------------------------------------- | ---- | --------------------------------------------------------------------------- | -| [aed448748](https://github.com/angular/angular-cli/commit/aed448748451b6b87c20e7bd9b3b1f822067f681) | fix | expand package groups for newly added peer dependencies in update schematic | +### -### @angular/build +- Node.js v20 is no longer supported. The minimum supported Node.js versions are now v22.22.0 and v24.13.1. +- The `@angular-devkit/architect-cli` package is no longer available. The `architect` CLI tool has been moved to the `@angular-devkit/architect` package. +- The experimental `@angular-devkit/build-angular:jest` and `@angular-devkit/build-angular:web-test-runner` builders have been removed. -| Commit | Type | Description | -| --------------------------------------------------------------------------------------------------- | ---- | --------------------------------------------- | -| [d46c082fb](https://github.com/angular/angular-cli/commit/d46c082fb994138327eb36882373f63daeec8bc1) | fix | prevent esbuild service child process leakage | +### @angular/build - +- The `@angular/build:dev-server (ng serve)` now assigns the highest priority to the `PORT` environment variable. This value will override any port configurations specified in `angular.json` or via the `--port` command-line flag. This includes the default port 4200. +- `istanbul-lib-instrument` is now an optional peer dependency. + Projects using karma with code coverage enabled will need to ensure that istanbul-lib-instrument is installed. Note: `ng update` will automatically add this dependency during the update process. - +### @angular/ssr -# 20.3.27 (2026-06-02) +- The server no longer falls back to Client-Side Rendering (CSR) when a request fails host validation. Requests with unrecognized 'Host' headers will now return a 400 Bad Request status code. Users must ensure all valid hosts are correctly configured in the 'allowedHosts' option. -### @angular/ssr +## Deprecations -| Commit | Type | Description | -| --------------------------------------------------------------------------------------------------- | ---- | -------------------------------------------------------------------------- | -| [07c6c96ba](https://github.com/angular/angular-cli/commit/07c6c96baf2901f44322beb70b77c32dc0824e45) | fix | add support for configuring trusted proxy headers via environment variable | +### @angular-devkit/build-angular - +- Webpack builders in build-angular are deprecated. Use @angular/build builders instead. - +### @angular-devkit/build-webpack -# 19.2.27 (2026-06-02) +- Webpack builders in build-webpack are deprecated. Use @angular/build builders instead. ### @angular/ssr -| Commit | Type | Description | -| --------------------------------------------------------------------------------------------------- | ---- | -------------------------------------------------------------------------- | -| [2c0dfc2ac](https://github.com/angular/angular-cli/commit/2c0dfc2ac8ce2f08741d25f687b4c605477978d6) | fix | add support for configuring trusted proxy headers via environment variable | - - +- CommonEngine APIs are deprecated in favor of AngularNodeAppEngine or AngularAppEngine. - +### @ngtools/webpack -# 22.0.0-rc.3 (2026-06-01) +- @ngtools/webpack loader and plugin are deprecated. Use @angular/build instead. ### @angular/cli -| Commit | Type | Description | -| --------------------------------------------------------------------------------------------------- | ---- | --------------------------------------------------------------------------- | -| [f05343a42](https://github.com/angular/angular-cli/commit/f05343a429b5445fb07aa6031b6fad02affe2ec1) | fix | expand package groups for newly added peer dependencies in update schematic | +| Commit | Type | Description | +| --------------------------------------------------------------------------------------------------- | ---- | ------------------------------------------------------------------------- | +| [58c0978f6](https://github.com/angular/angular-cli/commit/58c0978f658ee5fa7232abd8e2eb7f146e4eb6bb) | feat | add support for Node.js 26.0.0 | +| [a5c7c0b5f](https://github.com/angular/angular-cli/commit/a5c7c0b5fda4ae0c00351ba34e5f39dab2c6baee) | fix | reflect new minimum supported Node version in ng.js | +| [a5e1e48db](https://github.com/angular/angular-cli/commit/a5e1e48db759e9ffcaa89f04504f5f93a1afdda4) | fix | update odd-numbered Node.js version warning condition for future releases | +| [93c3eb8fb](https://github.com/angular/angular-cli/commit/93c3eb8fb2a0d531f18779152b0a62e9b73dbb23) | fix | update zoneless migration tool to handle `ChangeDetectionStrategy.Eager` | +| [a39a33128](https://github.com/angular/angular-cli/commit/a39a33128fb56e9c65ea89e06c4f127252d3b220) | perf | cache root manifest and resolve restricted package exports in ng add | ### @schematics/angular -| Commit | Type | Description | -| --------------------------------------------------------------------------------------------------- | ---- | --------------------------------------------------------- | -| [4fbc60891](https://github.com/angular/angular-cli/commit/4fbc6089174142623fbd28cc68cede181074fab5) | fix | preserve Jasmine stub-by-default semantics for bare spies | - -### @angular/build - -| Commit | Type | Description | -| --------------------------------------------------------------------------------------------------- | ---- | --------------------------------------------- | -| [418abd825](https://github.com/angular/angular-cli/commit/418abd8258d98f1371d561af92e4c0f018c860fa) | fix | prevent esbuild service child process leakage | - -### @angular/ssr - -| Commit | Type | Description | -| --------------------------------------------------------------------------------------------------- | ---- | --------------------------------------------------- | -| [8471ba634](https://github.com/angular/angular-cli/commit/8471ba63433d87ba3e59af622ed9cfa89b732cd9) | fix | support server-side rendering configuration options | - - +| Commit | Type | Description | +| --------------------------------------------------------------------------------------------------- | ---- | ------------------------------------------------------------------------- | +| [be60a63b7](https://github.com/angular/angular-cli/commit/be60a63b7b8fdea26bfd3329ce54d321334db2d2) | feat | add migrate-karma-to-vitest update migration | +| [43505066e](https://github.com/angular/angular-cli/commit/43505066e2350ca875051bb0f9991da8003c9247) | feat | add migration to add istanbul-lib-instrument | +| [b2f7a038b](https://github.com/angular/angular-cli/commit/b2f7a038b4a321e4e1b0b340cd09425f948c77ad) | feat | conditionally install istanbul coverage provider for Vitest migration | +| [d227e6985](https://github.com/angular/angular-cli/commit/d227e6985ef5540e0eea2571577ee2b9be0d3c64) | feat | migrate fake async to Vitest fake timers | +| [d2aa9ede5](https://github.com/angular/angular-cli/commit/d2aa9ede55a3e16b61ce6ae60dba6c8ea8954358) | feat | migrate fakeAsync's flush behavior when used in beforeEach | +| [f98cc82eb](https://github.com/angular/angular-cli/commit/f98cc82eb0f46986e61b4f94b57dcd36e4eaf215) | feat | rely on strict template default in generated workspaces | +| [c9f408153](https://github.com/angular/angular-cli/commit/c9f4081533f6f114846b88a152a9d5dc7363d680) | feat | set up fake timers in beforeEach instead of beforeAll | +| [de630c2fc](https://github.com/angular/angular-cli/commit/de630c2fcee22622942478c98117d8f473d8c894) | feat | stabilize refactor-jasmine-vitest schematic | +| [8d0805dd1](https://github.com/angular/angular-cli/commit/8d0805dd1750cb16af620811dc01b40e46ad030e) | feat | update TSConfig globals during karma to vitest migration | +| [470e1f937](https://github.com/angular/angular-cli/commit/470e1f937492e73971dea9c39af83368caf74e42) | fix | add istanbul-lib-instrument to application/library generator dependencies | +| [dc1238e5a](https://github.com/angular/angular-cli/commit/dc1238e5a4c9ab5902735e3d74bc7c5cc57553bd) | fix | add trusted-proxy-headers migration | +| [6572a6944](https://github.com/angular/angular-cli/commit/6572a69443356ff0022e6ce162915125fee0e3bb) | fix | default components to OnPush change detection | +| [aed407db8](https://github.com/angular/angular-cli/commit/aed407db8be6bc7591fb82f10c79586cbd072a8a) | fix | defer karma config deletion in Karma to Vitest migration | +| [4fbc60891](https://github.com/angular/angular-cli/commit/4fbc6089174142623fbd28cc68cede181074fab5) | fix | preserve Jasmine stub-by-default semantics for bare spies | +| [b3d838dfd](https://github.com/angular/angular-cli/commit/b3d838dfdb2adc3bd035b495f7f9457d742d73a4) | fix | replace deprecated `ChangeDetectionStrategy.Default` with `Eager` | +| [a7ac8e5f0](https://github.com/angular/angular-cli/commit/a7ac8e5f0a268994a8fcfebbf56f76e994b6207d) | fix | support spy call arguments migration in refactor-jasmine-vitest | +| [7fb59eaa6](https://github.com/angular/angular-cli/commit/7fb59eaa65a8d7e880b6f44d715b2aeaff9301ca) | fix | use service decorator in ng generate | - +### -# 22.0.0-rc.2 (2026-05-27) +| Commit | Type | Description | +| --------------------------------------------------------------------------------------------------- | -------- | ----------------------------------------------------- | +| [d0e9e8163](https://github.com/angular/angular-cli/commit/d0e9e81639be33c453f1ef66c7c1c8ea4fe543c2) | build | update minimum supported Node.js versions | +| [1f21e89d9](https://github.com/angular/angular-cli/commit/1f21e89d99c191642627df6842402644a1bf26ee) | refactor | remove `@angular-devkit/architect-cli` package | +| [b4885b851](https://github.com/angular/angular-cli/commit/b4885b851226709ae4146070122806e14a3d5eb9) | refactor | remove experimental Jest and Web Test Runner builders | ### @angular-devkit/build-angular -| Commit | Type | Description | -| --------------------------------------------------------------------------------------------------- | ---- | ---------------------------------------------------------- | -| [c0f7bd833](https://github.com/angular/angular-cli/commit/c0f7bd83379c0715bceeffae0e3c6d37d15bf327) | fix | remove unconditional CORS wildcard from webpack dev-server | - - - - - -# 21.2.13 (2026-05-27) +| Commit | Type | Description | +| --------------------------------------------------------------------------------------------------- | -------- | -------------------------- | +| [b7940dbcb](https://github.com/angular/angular-cli/commit/b7940dbcb40291be4de5b31e8a8001165459a7d4) | refactor | deprecate Webpack builders | -### @angular-devkit/build-angular +### @angular-devkit/build-webpack -| Commit | Type | Description | -| --------------------------------------------------------------------------------------------------- | ---- | ---------------------------------------------------------- | -| [3c6d26a31](https://github.com/angular/angular-cli/commit/3c6d26a316cd6aea455c19b249dc6852d84a698e) | fix | remove unconditional CORS wildcard from webpack dev-server | +| Commit | Type | Description | +| --------------------------------------------------------------------------------------------------- | -------- | ------------------------------------------------- | +| [3d5daa45e](https://github.com/angular/angular-cli/commit/3d5daa45e3ade025c1bc0df35d2766563ccf7c03) | refactor | deprecate webpack and webpack-dev-server builders | ### @angular/build -| Commit | Type | Description | -| --------------------------------------------------------------------------------------------------- | ---- | ------------------------------------------------------- | -| [2b3e95517](https://github.com/angular/angular-cli/commit/2b3e95517358f8ef3482d5319d970f4774e45ad0) | fix | assert that asset input paths are within workspace root | - - +| Commit | Type | Description | +| --------------------------------------------------------------------------------------------------- | ---- | ------------------------------------------------------------------ | +| [e9aa7967b](https://github.com/angular/angular-cli/commit/e9aa7967ba391e429ec1c04473efb4a2d38a62bf) | feat | add isolate option to unit-test builder | +| [fe720cab6](https://github.com/angular/angular-cli/commit/fe720cab64bbc8bcc2db583188e32ad938e63a23) | feat | add process.env.PORT support to the dev server | +| [0781f7498](https://github.com/angular/angular-cli/commit/0781f74986e773d143b9bdf5d3f0747de0df6b0a) | feat | add quiet option to suppress build noise in unit tests | +| [cd2ad3c19](https://github.com/angular/angular-cli/commit/cd2ad3c1958d9adadc214045b5e59c0c8f8b4499) | feat | enable chunk optimization by default with heuristics | +| [3007f46b7](https://github.com/angular/angular-cli/commit/3007f46b7e077227b17d8bb1090edd2f8ff19ae3) | feat | move istanbul-lib-instrument to optional peer dependency | +| [af2c7e944](https://github.com/angular/angular-cli/commit/af2c7e9444fba81d3b1fd2d37dc4412f8305b5ed) | feat | rename `experimentalPlatform` to `platform` in application builder | +| [58c7c7a9d](https://github.com/angular/angular-cli/commit/58c7c7a9d80fc6af5cf8b82a6d87f1d3cf3808c6) | feat | subresource integrity validation for dynamically loaded modules | +| [73233dc5f](https://github.com/angular/angular-cli/commit/73233dc5f41b570f5ac095b255a46de6cbfb54b7) | feat | support Istanbul coverage in Vitest runner | +| [414320d02](https://github.com/angular/angular-cli/commit/414320d02a090b7b36720051569cba7563bf9ac6) | feat | support runtime Zone.js detection in Vitest unit test runner | +| [b85ec6798](https://github.com/angular/angular-cli/commit/b85ec6798b5c74f778a69a657729e446a2156261) | fix | allow configuring Access-Control-Allow-Origin via headers option | +| [edfa782d5](https://github.com/angular/angular-cli/commit/edfa782d52fd971aebead8b96b6ca470a3f5123e) | fix | use dynamic TestComponentRenderer for Vitest | - +### @angular/ssr -# 22.0.0-rc.1 (2026-05-21) +| Commit | Type | Description | +| --------------------------------------------------------------------------------------------------- | -------- | ----------------------------------------------------------------- | +| [5adc92541](https://github.com/angular/angular-cli/commit/5adc92541433be23fc2246db5a199cf5c0dc9e67) | fix | enforce explicit opt-in for proxy headers | +| [f85343925](https://github.com/angular/angular-cli/commit/f8534392552f4896ee9449939cdc705010331e3d) | fix | support all X-Forwarded-\* headers when trustProxyHeaders is true | +| [8471ba634](https://github.com/angular/angular-cli/commit/8471ba63433d87ba3e59af622ed9cfa89b732cd9) | fix | support server-side rendering configuration options | +| [50b16a65b](https://github.com/angular/angular-cli/commit/50b16a65b1be1f9c2ec11d578240a8884518d517) | refactor | deprecate CommonEngine APIs | +| [27cd35561](https://github.com/angular/angular-cli/commit/27cd355619aad140dfc221c6bd161f4a981e0f3b) | refactor | remove CSR fallback for invalid hosts | -### @schematics/angular +### @ngtools/webpack -| Commit | Type | Description | -| --------------------------------------------------------------------------------------------------- | ---- | --------------------------------------------------------------- | -| [a7ac8e5f0](https://github.com/angular/angular-cli/commit/a7ac8e5f0a268994a8fcfebbf56f76e994b6207d) | fix | support spy call arguments migration in refactor-jasmine-vitest | +| Commit | Type | Description | +| --------------------------------------------------------------------------------------------------- | -------- | -------------------------------------------- | +| [547ca515b](https://github.com/angular/angular-cli/commit/547ca515b707c283489a3f088d86fc84807d830d) | refactor | deprecate @ngtools/webpack loader and plugin | -### @angular/build + -| Commit | Type | Description | -| --------------------------------------------------------------------------------------------------- | ---- | ------------------------------------------------------- | -| [327cc2414](https://github.com/angular/angular-cli/commit/327cc24144ab7e0e36ff3d6e9a67585588f2f69f) | fix | assert that asset input paths are within workspace root | -| [93d352798](https://github.com/angular/angular-cli/commit/93d3527985f8aa1950f62ab42a88c0a74ae0b051) | fix | ignore virtual esbuild paths with (disabled): | + - +# 21.2.14 (2026-06-03) - +### @angular/cli -# 21.2.12 (2026-05-20) +| Commit | Type | Description | +| --------------------------------------------------------------------------------------------------- | ---- | --------------------------------------------------------------------------- | +| [aed448748](https://github.com/angular/angular-cli/commit/aed448748451b6b87c20e7bd9b3b1f822067f681) | fix | expand package groups for newly added peer dependencies in update schematic | ### @angular/build | Commit | Type | Description | | --------------------------------------------------------------------------------------------------- | ---- | --------------------------------------------- | -| [cbad57579](https://github.com/angular/angular-cli/commit/cbad57579adb5de7887985afbb2bf1f40adf3cb2) | fix | ignore virtual esbuild paths with (disabled): | +| [d46c082fb](https://github.com/angular/angular-cli/commit/d46c082fb994138327eb36882373f63daeec8bc1) | fix | prevent esbuild service child process leakage | - + -# 22.0.0-rc.0 (2026-05-13) +# 20.3.27 (2026-06-02) -## Deprecations +### @angular/ssr -### @angular-devkit/build-angular +| Commit | Type | Description | +| --------------------------------------------------------------------------------------------------- | ---- | -------------------------------------------------------------------------- | +| [07c6c96ba](https://github.com/angular/angular-cli/commit/07c6c96baf2901f44322beb70b77c32dc0824e45) | fix | add support for configuring trusted proxy headers via environment variable | -- Webpack builders in build-angular are deprecated. Use @angular/build builders instead. + -### @angular-devkit/build-webpack + -- Webpack builders in build-webpack are deprecated. Use @angular/build builders instead. +# 19.2.27 (2026-06-02) ### @angular/ssr -- CommonEngine APIs are deprecated in favor of AngularNodeAppEngine or AngularAppEngine. - -### @ngtools/webpack - -- @ngtools/webpack loader and plugin are deprecated. Use @angular/build instead. - -### @schematics/angular +| Commit | Type | Description | +| --------------------------------------------------------------------------------------------------- | ---- | -------------------------------------------------------------------------- | +| [2c0dfc2ac](https://github.com/angular/angular-cli/commit/2c0dfc2ac8ce2f08741d25f687b4c605477978d6) | fix | add support for configuring trusted proxy headers via environment variable | -| Commit | Type | Description | -| --------------------------------------------------------------------------------------------------- | ---- | --------------------------------------------------------------------- | -| [b2f7a038b](https://github.com/angular/angular-cli/commit/b2f7a038b4a321e4e1b0b340cd09425f948c77ad) | feat | conditionally install istanbul coverage provider for Vitest migration | -| [d227e6985](https://github.com/angular/angular-cli/commit/d227e6985ef5540e0eea2571577ee2b9be0d3c64) | feat | migrate fake async to Vitest fake timers | -| [d2aa9ede5](https://github.com/angular/angular-cli/commit/d2aa9ede55a3e16b61ce6ae60dba6c8ea8954358) | feat | migrate fakeAsync's flush behavior when used in beforeEach | -| [c9f408153](https://github.com/angular/angular-cli/commit/c9f4081533f6f114846b88a152a9d5dc7363d680) | feat | set up fake timers in beforeEach instead of beforeAll | -| [8d0805dd1](https://github.com/angular/angular-cli/commit/8d0805dd1750cb16af620811dc01b40e46ad030e) | feat | update TSConfig globals during karma to vitest migration | -| [aed407db8](https://github.com/angular/angular-cli/commit/aed407db8be6bc7591fb82f10c79586cbd072a8a) | fix | defer karma config deletion in Karma to Vitest migration | -| [7fb59eaa6](https://github.com/angular/angular-cli/commit/7fb59eaa65a8d7e880b6f44d715b2aeaff9301ca) | fix | use service decorator in ng generate | + -### @angular/cli + -| Commit | Type | Description | -| --------------------------------------------------------------------------------------------------- | ---- | ------------------------------------------------------------------------- | -| [58c0978f6](https://github.com/angular/angular-cli/commit/58c0978f658ee5fa7232abd8e2eb7f146e4eb6bb) | feat | add support for Node.js 26.0.0 | -| [ff88f491d](https://github.com/angular/angular-cli/commit/ff88f491da38493d6e06f3e4ac080d171c630ccd) | fix | restrict MCP workspace access to allowed client roots during resolution | -| [a5e1e48db](https://github.com/angular/angular-cli/commit/a5e1e48db759e9ffcaa89f04504f5f93a1afdda4) | fix | update odd-numbered Node.js version warning condition for future releases | +# 21.2.13 (2026-05-27) ### @angular-devkit/build-angular -| Commit | Type | Description | -| --------------------------------------------------------------------------------------------------- | -------- | -------------------------- | -| [b7940dbcb](https://github.com/angular/angular-cli/commit/b7940dbcb40291be4de5b31e8a8001165459a7d4) | refactor | deprecate Webpack builders | - -### @angular-devkit/build-webpack - -| Commit | Type | Description | -| --------------------------------------------------------------------------------------------------- | -------- | ------------------------------------------------- | -| [3d5daa45e](https://github.com/angular/angular-cli/commit/3d5daa45e3ade025c1bc0df35d2766563ccf7c03) | refactor | deprecate webpack and webpack-dev-server builders | +| Commit | Type | Description | +| --------------------------------------------------------------------------------------------------- | ---- | ---------------------------------------------------------- | +| [3c6d26a31](https://github.com/angular/angular-cli/commit/3c6d26a316cd6aea455c19b249dc6852d84a698e) | fix | remove unconditional CORS wildcard from webpack dev-server | ### @angular/build -| Commit | Type | Description | -| --------------------------------------------------------------------------------------------------- | ---- | --------------------------------------------------------------- | -| [58c7c7a9d](https://github.com/angular/angular-cli/commit/58c7c7a9d80fc6af5cf8b82a6d87f1d3cf3808c6) | feat | subresource integrity validation for dynamically loaded modules | -| [edfa782d5](https://github.com/angular/angular-cli/commit/edfa782d52fd971aebead8b96b6ca470a3f5123e) | fix | use dynamic TestComponentRenderer for Vitest | +| Commit | Type | Description | +| --------------------------------------------------------------------------------------------------- | ---- | ------------------------------------------------------- | +| [2b3e95517](https://github.com/angular/angular-cli/commit/2b3e95517358f8ef3482d5319d970f4774e45ad0) | fix | assert that asset input paths are within workspace root | -### @angular/ssr + -| Commit | Type | Description | -| --------------------------------------------------------------------------------------------------- | -------- | ----------------------------------------------------------------- | -| [ea95e1a87](https://github.com/angular/angular-cli/commit/ea95e1a87ebfb5b452a6b6ffa7838ca1fe094100) | fix | remove stateful flag from URL_PARAMETER_REGEXP | -| [f85343925](https://github.com/angular/angular-cli/commit/f8534392552f4896ee9449939cdc705010331e3d) | fix | support all X-Forwarded-\* headers when trustProxyHeaders is true | -| [50b16a65b](https://github.com/angular/angular-cli/commit/50b16a65b1be1f9c2ec11d578240a8884518d517) | refactor | deprecate CommonEngine APIs | + -### @ngtools/webpack +# 21.2.12 (2026-05-20) -| Commit | Type | Description | -| --------------------------------------------------------------------------------------------------- | -------- | -------------------------------------------- | -| [547ca515b](https://github.com/angular/angular-cli/commit/547ca515b707c283489a3f088d86fc84807d830d) | refactor | deprecate @ngtools/webpack loader and plugin | +### @angular/build + +| Commit | Type | Description | +| --------------------------------------------------------------------------------------------------- | ---- | --------------------------------------------- | +| [cbad57579](https://github.com/angular/angular-cli/commit/cbad57579adb5de7887985afbb2bf1f40adf3cb2) | fix | ignore virtual esbuild paths with (disabled): | @@ -287,43 +275,6 @@ - - -# 22.0.0-next.7 (2026-04-29) - -### @angular/cli - -| Commit | Type | Description | -| --------------------------------------------------------------------------------------------------- | ---- | ----------------------------------------------------- | -| [0572df064](https://github.com/angular/angular-cli/commit/0572df06457a46276cf229c7c50ccb59167a75d8) | fix | fix broken img ref in ai-tutor | -| [d6121b5e8](https://github.com/angular/angular-cli/commit/d6121b5e87796b61dd0e2157a5ce4e8f3d33e915) | fix | introduce initial package manager workspace awareness | -| [48eab1fc0](https://github.com/angular/angular-cli/commit/48eab1fc0bd83c6f87a015252283579ebbd7d0fb) | fix | remove standalone true ref in ai tutor | - -### @schematics/angular - -| Commit | Type | Description | -| --------------------------------------------------------------------------------------------------- | ---- | ---------------------------------------------------------------------- | -| [b47dfbac4](https://github.com/angular/angular-cli/commit/b47dfbac431b7f22f769dbe3eec491811fa46aca) | fix | add missing imports for focus and skip APIs in refactor-jasmine-vitest | -| [dc1238e5a](https://github.com/angular/angular-cli/commit/dc1238e5a4c9ab5902735e3d74bc7c5cc57553bd) | fix | add trusted-proxy-headers migration | - -### @angular/build - -| Commit | Type | Description | -| --------------------------------------------------------------------------------------------------- | ---- | ------------------------------------------ | -| [e9aa7967b](https://github.com/angular/angular-cli/commit/e9aa7967ba391e429ec1c04473efb4a2d38a62bf) | feat | add isolate option to unit-test builder | -| [73233dc5f](https://github.com/angular/angular-cli/commit/73233dc5f41b570f5ac095b255a46de6cbfb54b7) | feat | support Istanbul coverage in Vitest runner | - -### @angular/ssr - -| Commit | Type | Description | -| --------------------------------------------------------------------------------------------------- | ---- | -------------------------------------------------------------------------- | -| [126b19b9c](https://github.com/angular/angular-cli/commit/126b19b9c74422211619aad0e523ef5f7e8eeabb) | fix | add support for configuring trusted proxy headers via environment variable | -| [53b9623b7](https://github.com/angular/angular-cli/commit/53b9623b7b4ee2266332f57e71896361dac21db8) | fix | decode route segments when building and matching route tree | -| [5adc92541](https://github.com/angular/angular-cli/commit/5adc92541433be23fc2246db5a199cf5c0dc9e67) | fix | enforce explicit opt-in for proxy headers | -| [c34c569b0](https://github.com/angular/angular-cli/commit/c34c569b076c8b9d82bf18a094a29cb68fd8a63d) | fix | use router to normalize URLs for comparison | - - - # 21.2.9 (2026-04-29) @@ -371,43 +322,6 @@ - - -# 22.0.0-next.6 (2026-04-22) - -### @angular/cli - -| Commit | Type | Description | -| --------------------------------------------------------------------------------------------------- | ---- | ------------------------------------------------------------------- | -| [cc30034da](https://github.com/angular/angular-cli/commit/cc30034da25f1b873e354c493043fe46f0bfc8dd) | fix | dynamically resolve project Angular CLI executable inside MCP tools | -| [ead60d3d5](https://github.com/angular/angular-cli/commit/ead60d3d5fcf7c013392ba25b932b86f0e5cd9d9) | fix | ignore EBADF file system errors during MCP project scan | -| [0d984cf1c](https://github.com/angular/angular-cli/commit/0d984cf1cdfed0a4f74e6bf8efb8a3c999ebc373) | fix | use headless option in MCP test tool | - -### @schematics/angular - -| Commit | Type | Description | -| --------------------------------------------------------------------------------------------------- | ---- | ------------------------------------------- | -| [de630c2fc](https://github.com/angular/angular-cli/commit/de630c2fcee22622942478c98117d8f473d8c894) | feat | stabilize refactor-jasmine-vitest schematic | - -### @angular-devkit/build-angular - -| Commit | Type | Description | -| --------------------------------------------------------------------------------------------------- | ---- | --------------------------------------------------- | -| [30d8332ed](https://github.com/angular/angular-cli/commit/30d8332edc10786fc90512809a59189865a5d956) | fix | ensure route has leading slash in prerender builder | -| [cf5b49ed7](https://github.com/angular/angular-cli/commit/cf5b49ed7843250607ff0fc49ae6d97f13f4d9ab) | fix | fix app-shell route format and | - -### @angular/build - -| Commit | Type | Description | -| --------------------------------------------------------------------------------------------------- | ---- | ---------------------------------------------------------------- | -| [0781f7498](https://github.com/angular/angular-cli/commit/0781f74986e773d143b9bdf5d3f0747de0df6b0a) | feat | add quiet option to suppress build noise in unit tests | -| [cd2ad3c19](https://github.com/angular/angular-cli/commit/cd2ad3c1958d9adadc214045b5e59c0c8f8b4499) | feat | enable chunk optimization by default with heuristics | -| [b85ec6798](https://github.com/angular/angular-cli/commit/b85ec6798b5c74f778a69a657729e446a2156261) | fix | allow configuring Access-Control-Allow-Origin via headers option | -| [59803b12b](https://github.com/angular/angular-cli/commit/59803b12ba69d4ba17c769ee5e81c3175d79ab58) | fix | use rootDir for HMR component updates path resolution | -| [74e7dbe56](https://github.com/angular/angular-cli/commit/74e7dbe56c825c521fc711cf6c0d5ba8fabece75) | fix | validate V8 coverage support for browsers in Vitest | - - - # 20.3.24 (2026-04-15) @@ -420,41 +334,6 @@ - - -# 22.0.0-next.5 (2026-04-08) - -## Breaking Changes - -### @angular/build - -- `istanbul-lib-instrument` is now an optional peer dependency. - Projects using karma with code coverage enabled will need to ensure that istanbul-lib-instrument is installed. Note: `ng update` will automatically add this dependency during the update process. - -### @schematics/angular - -| Commit | Type | Description | -| --------------------------------------------------------------------------------------------------- | ---- | ------------------------------------------------------------------------- | -| [be60a63b7](https://github.com/angular/angular-cli/commit/be60a63b7b8fdea26bfd3329ce54d321334db2d2) | feat | add migrate-karma-to-vitest update migration | -| [43505066e](https://github.com/angular/angular-cli/commit/43505066e2350ca875051bb0f9991da8003c9247) | feat | add migration to add istanbul-lib-instrument | -| [470e1f937](https://github.com/angular/angular-cli/commit/470e1f937492e73971dea9c39af83368caf74e42) | fix | add istanbul-lib-instrument to application/library generator dependencies | - -### @angular/cli - -| Commit | Type | Description | -| --------------------------------------------------------------------------------------------------- | ---- | -------------------------------------------------------------- | -| [422c8183e](https://github.com/angular/angular-cli/commit/422c8183ea3596660475491b9630df34276c468e) | fix | handle missing package manager during analytics initialization | - -### @angular/build - -| Commit | Type | Description | -| --------------------------------------------------------------------------------------------------- | ---- | ---------------------------------------------------------- | -| [3007f46b7](https://github.com/angular/angular-cli/commit/3007f46b7e077227b17d8bb1090edd2f8ff19ae3) | feat | move istanbul-lib-instrument to optional peer dependency | -| [829bdc61d](https://github.com/angular/angular-cli/commit/829bdc61dd77231bb13f01efd052811661fe4f48) | fix | preserve coverage ignore comments in development | -| [e2f95fc19](https://github.com/angular/angular-cli/commit/e2f95fc19a648f3da84b58ace91283d0fa422cc1) | fix | show clear error when styleUrl points to a TypeScript file | - - - # 21.2.7 (2026-04-08) @@ -498,35 +377,6 @@ - - -# 22.0.0-next.4 (2026-04-01) - -### @angular/cli - -| Commit | Type | Description | -| --------------------------------------------------------------------------------------------------- | ---- | ----------------------------------------------- | -| [87d99e98b](https://github.com/angular/angular-cli/commit/87d99e98b178c8f7d5e944a346faf70c51bdfcef) | feat | support custom port in MCP devserver start tool | -| [4815a5417](https://github.com/angular/angular-cli/commit/4815a5417c7a0135fb66149c2e4c1008e21e3a26) | fix | fix sourceRoot resolution for MCP projects tool | - -### @angular/build - -| Commit | Type | Description | -| --------------------------------------------------------------------------------------------------- | ---- | ------------------------------------------------------------------- | -| [21d8aa474](https://github.com/angular/angular-cli/commit/21d8aa4747573132476c3a0a4b7ea1f6405a71ef) | fix | ensure transitive SCSS partial errors are tracked in watch mode | -| [e558117b7](https://github.com/angular/angular-cli/commit/e558117b748ee5837324d49466108d21db596b2e) | fix | ensure Vitest mock patching is executed only once | -| [81e4faae7](https://github.com/angular/angular-cli/commit/81e4faae7699e2ed1eb8f4656dc115ca9c20f416) | fix | preserve error stack traces during prerendering | -| [8dd341e21](https://github.com/angular/angular-cli/commit/8dd341e21b8f44e8e2bf3f322cced8ff6e861098) | fix | scope CHROME_BIN executable path to individual playwright instances | - -### @angular/ssr - -| Commit | Type | Description | -| --------------------------------------------------------------------------------------------------- | ---- | ---------------------------------------------------- | -| [e7e434ca3](https://github.com/angular/angular-cli/commit/e7e434ca3d78a8369b592bf870c9466962f77c94) | fix | allow underscores in host validation | -| [bcd99f944](https://github.com/angular/angular-cli/commit/bcd99f944ecb90f896040030b98f1d03692b5b6f) | fix | patch Headers.forEach in cloneRequestAndPatchHeaders | - - - # 21.2.6 (2026-04-01) @@ -621,41 +471,6 @@ - - -# 22.0.0-next.3 (2026-03-26) - -### @angular/cli - -| Commit | Type | Description | -| --------------------------------------------------------------------------------------------------- | ---- | ---------------------------------------------- | -| [4bbd1bf53](https://github.com/angular/angular-cli/commit/4bbd1bf532fc2d9c36650121a05eae2fb096eb09) | fix | restore console methods after logger completes | - -### @schematics/angular - -| Commit | Type | Description | -| --------------------------------------------------------------------------------------------------- | ---- | ------------------------------------------------------- | -| [f98cc82eb](https://github.com/angular/angular-cli/commit/f98cc82eb0f46986e61b4f94b57dcd36e4eaf215) | feat | rely on strict template default in generated workspaces | - -### @angular/build - -| Commit | Type | Description | -| --------------------------------------------------------------------------------------------------- | ---- | ------------------------------------------------------------------------- | -| [01bd5d064](https://github.com/angular/angular-cli/commit/01bd5d06410719f66fcabb0bfd04c809e7db12f7) | fix | deduplicate and merge coverage excludes with vitest | -| [355ebe8c5](https://github.com/angular/angular-cli/commit/355ebe8c54b58201c8080543e5e04208599f0947) | fix | prevent reporter duplicates by explicitly overriding Vitest configuration | -| [1a8376bee](https://github.com/angular/angular-cli/commit/1a8376bee9b7683b84c2ae50d08e50d5c5c7b99a) | fix | remove default for unit-test coverage option | -| [a203dcf1d](https://github.com/angular/angular-cli/commit/a203dcf1d9a6d544cbae867aa949ab0582e60a88) | fix | warn about performance of test.exclude in vitest configuration | -| [ec10eb365](https://github.com/angular/angular-cli/commit/ec10eb365261549c2181efa98a494a749444a787) | fix | warn when vitest watch config conflicts with builder | - -### @angular/ssr - -| Commit | Type | Description | -| --------------------------------------------------------------------------------------------------- | ---- | ------------------------------------------------------------------- | -| [ca6f08c6e](https://github.com/angular/angular-cli/commit/ca6f08c6e59820160f7ae496a9d8775c78ce1a58) | fix | apply forwarded prefix and vary header in accept-language redirects | -| [3b99ee140](https://github.com/angular/angular-cli/commit/3b99ee140db82c8ddae3f6e48f9fc38eca204a53) | fix | support '\*' in allowedHosts and warn about security risks | - - - # 21.2.4 (2026-03-26) @@ -699,39 +514,6 @@ - - -# 22.0.0-next.2 (2026-03-18) - -### @angular/cli - -| Commit | Type | Description | -| --------------------------------------------------------------------------------------------------- | ---- | ------------------------------------------------ | -| [c9f07db8f](https://github.com/angular/angular-cli/commit/c9f07db8fcb0b3f8400fbbf0e131be7f9857a987) | fix | use parsed package name for migrate-only updates | - -### @schematics/angular - -| Commit | Type | Description | -| --------------------------------------------------------------------------------------------------- | ---- | --------------------------------------------- | -| [6572a6944](https://github.com/angular/angular-cli/commit/6572a69443356ff0022e6ce162915125fee0e3bb) | fix | default components to OnPush change detection | - -### @angular/build - -| Commit | Type | Description | -| --------------------------------------------------------------------------------------------------- | ---- | ------------------------------------------------------------------------ | -| [9b33e1781](https://github.com/angular/angular-cli/commit/9b33e1781328d3b42665145bf580fb8e06c8ad2b) | fix | alias createRequire banner import to avoid duplicate binding | -| [4643a8a3b](https://github.com/angular/angular-cli/commit/4643a8a3b3e2a3bcf7baae9f812ae8a9ef10ebad) | fix | only use external packages for polyfills when no local files are present | - -### @angular/ssr - -| Commit | Type | Description | -| --------------------------------------------------------------------------------------------------- | ---- | ----------------------------------------------------- | -| [4d564f66f](https://github.com/angular/angular-cli/commit/4d564f66f694011724d4933bf025f1c4fed55bca) | fix | disallow x-forwarded-prefix starting with a backslash | -| [ff1160e30](https://github.com/angular/angular-cli/commit/ff1160e3015eb321971e398cbedff80f4c053166) | fix | ensure unique values in redirect response Vary header | -| [998b8298e](https://github.com/angular/angular-cli/commit/998b8298e3106c95d77ced8090ab815365c462c7) | fix | support custom headers in redirect responses | - - - # 21.2.3 (2026-03-18) @@ -759,44 +541,6 @@ - - -# 22.0.0-next.1 (2026-03-11) - -## Breaking Changes - -### @angular/build - -- The `@angular/build:dev-server (ng serve)` now assigns the highest priority to the `PORT` environment variable. This value will override any port configurations specified in `angular.json` or via the `--port` command-line flag. This includes the default port 4200. - -### @schematics/angular - -| Commit | Type | Description | -| --------------------------------------------------------------------------------------------------- | ---- | ----------------------------------------------------------------- | -| [b3d838dfd](https://github.com/angular/angular-cli/commit/b3d838dfdb2adc3bd035b495f7f9457d742d73a4) | fix | replace deprecated `ChangeDetectionStrategy.Default` with `Eager` | - -### @angular/cli - -| Commit | Type | Description | -| --------------------------------------------------------------------------------------------------- | ---- | ------------------------------------------------------------------------------------- | -| [598a690a0](https://github.com/angular/angular-cli/commit/598a690a0baea5cd54af5cea38e673c33605a627) | fix | conditionally quote package names when adding dependencies based on host requirements | -| [b5fb457e1](https://github.com/angular/angular-cli/commit/b5fb457e157fa78b61565eaba6b88e9f80b3b288) | fix | preserve exact version in ng add when requested | -| [93c3eb8fb](https://github.com/angular/angular-cli/commit/93c3eb8fb2a0d531f18779152b0a62e9b73dbb23) | fix | update zoneless migration tool to handle `ChangeDetectionStrategy.Eager` | -| [ad0fd5f41](https://github.com/angular/angular-cli/commit/ad0fd5f41fc6ee5d920fb3c725f09f17d86d2ab4) | perf | avoid redundant package version resolution in ng add | -| [a39a33128](https://github.com/angular/angular-cli/commit/a39a33128fb56e9c65ea89e06c4f127252d3b220) | perf | cache root manifest and resolve restricted package exports in ng add | - -### @angular/build - -| Commit | Type | Description | -| --------------------------------------------------------------------------------------------------- | ---- | ------------------------------------------------------------------ | -| [fe720cab6](https://github.com/angular/angular-cli/commit/fe720cab64bbc8bcc2db583188e32ad938e63a23) | feat | add process.env.PORT support to the dev server | -| [af2c7e944](https://github.com/angular/angular-cli/commit/af2c7e9444fba81d3b1fd2d37dc4412f8305b5ed) | feat | rename `experimentalPlatform` to `platform` in application builder | -| [6324133c2](https://github.com/angular/angular-cli/commit/6324133c282f5e04ee6e9e46fc5f387cbbefad8e) | fix | normalize line endings for CSP hash generation | -| [839c725c2](https://github.com/angular/angular-cli/commit/839c725c234b2c1c3e44d52e3a1442ad1b538be9) | fix | pass process environment variables to prerender workers | -| [f30f8900e](https://github.com/angular/angular-cli/commit/f30f8900efb8ad9a835630f57e3667346926dc4d) | fix | resolve assets correctly during i18n prerendering | - - - # 21.2.2 (2026-03-11) @@ -832,51 +576,6 @@ - - -# 22.0.0-next.0 (2026-03-05) - -## Breaking Changes - -### - -- Node.js v20 is no longer supported. The minimum supported Node.js versions are now v22.22.0 and v24.13.1. -- The `@angular-devkit/architect-cli` package is no longer available. The `architect` CLI tool has been moved to the `@angular-devkit/architect` package. -- The experimental `@angular-devkit/build-angular:jest` and `@angular-devkit/build-angular:web-test-runner` builders have been removed. - -### @angular/ssr - -- The server no longer falls back to Client-Side Rendering (CSR) when a request fails host validation. Requests with unrecognized 'Host' headers will now return a 400 Bad Request status code. Users must ensure all valid hosts are correctly configured in the 'allowedHosts' option. - -### @angular/cli - -| Commit | Type | Description | -| --------------------------------------------------------------------------------------------------- | ---- | --------------------------------------------------- | -| [a5c7c0b5f](https://github.com/angular/angular-cli/commit/a5c7c0b5fda4ae0c00351ba34e5f39dab2c6baee) | fix | reflect new minimum supported Node version in ng.js | - -### - -| Commit | Type | Description | -| --------------------------------------------------------------------------------------------------- | -------- | ----------------------------------------------------- | -| [d0e9e8163](https://github.com/angular/angular-cli/commit/d0e9e81639be33c453f1ef66c7c1c8ea4fe543c2) | build | update minimum supported Node.js versions | -| [1f21e89d9](https://github.com/angular/angular-cli/commit/1f21e89d99c191642627df6842402644a1bf26ee) | refactor | remove `@angular-devkit/architect-cli` package | -| [b4885b851](https://github.com/angular/angular-cli/commit/b4885b851226709ae4146070122806e14a3d5eb9) | refactor | remove experimental Jest and Web Test Runner builders | - -### @angular/build - -| Commit | Type | Description | -| --------------------------------------------------------------------------------------------------- | ---- | ------------------------------------------------------------ | -| [414320d02](https://github.com/angular/angular-cli/commit/414320d02a090b7b36720051569cba7563bf9ac6) | feat | support runtime Zone.js detection in Vitest unit test runner | -| [f190263a4](https://github.com/angular/angular-cli/commit/f190263a4010a4f7b9ae85806b5d70a16b57b9fa) | fix | allow any `CHROME_BIN` for vitest playwright provider | - -### @angular/ssr - -| Commit | Type | Description | -| --------------------------------------------------------------------------------------------------- | -------- | ------------------------------------- | -| [27cd35561](https://github.com/angular/angular-cli/commit/27cd355619aad140dfc221c6bd161f4a981e0f3b) | refactor | remove CSR fallback for invalid hosts | - - - # 21.2.1 (2026-03-05) From 11a4438a733a118909c72d54423c4a9705bdfafb Mon Sep 17 00:00:00 2001 From: Alan Agius <17563226+alan-agius4@users.noreply.github.com> Date: Wed, 3 Jun 2026 14:40:04 +0000 Subject: [PATCH 003/787] test: add 20.0-project E2E test asset and update update tests to use it Update e2e assets --- tests/e2e/assets/19.0-project/package.json | 37 -------- .../src/app/app.component.spec.ts | 29 ------ .../19.0-project/src/app/app.component.ts | 12 --- .../assets/19.0-project/src/app/app.config.ts | 8 -- tests/e2e/assets/19.0-project/src/index.html | 13 --- tests/e2e/assets/19.0-project/src/main.ts | 5 - .../.editorconfig | 0 .../{19.0-project => 20.0-project}/.gitignore | 1 + .../20.0-project/.vscode/extensions.json | 4 + .../assets/20.0-project/.vscode/launch.json | 20 ++++ .../assets/20.0-project/.vscode/tasks.json | 42 +++++++++ .../{19.0-project => 20.0-project}/README.md | 4 +- .../angular.json | 36 +++++--- tests/e2e/assets/20.0-project/package.json | 48 ++++++++++ .../public/favicon.ico | Bin .../assets/20.0-project/src/app/app.config.ts | 12 +++ .../src/app/app.css} | 0 .../src/app/app.html} | 86 +++++++++--------- .../src/app/app.routes.ts | 0 .../assets/20.0-project/src/app/app.spec.ts | 23 +++++ tests/e2e/assets/20.0-project/src/app/app.ts | 12 +++ tests/e2e/assets/20.0-project/src/index.html | 13 +++ tests/e2e/assets/20.0-project/src/main.ts | 6 ++ .../src/styles.css | 0 .../tsconfig.app.json | 8 +- .../tsconfig.json | 17 +++- .../tsconfig.spec.json | 9 +- .../tests/update/update-multiple-versions.ts | 2 +- tests/e2e/tests/update/update.ts | 14 +-- 29 files changed, 280 insertions(+), 181 deletions(-) delete mode 100644 tests/e2e/assets/19.0-project/package.json delete mode 100644 tests/e2e/assets/19.0-project/src/app/app.component.spec.ts delete mode 100644 tests/e2e/assets/19.0-project/src/app/app.component.ts delete mode 100644 tests/e2e/assets/19.0-project/src/app/app.config.ts delete mode 100644 tests/e2e/assets/19.0-project/src/index.html delete mode 100644 tests/e2e/assets/19.0-project/src/main.ts rename tests/e2e/assets/{19.0-project => 20.0-project}/.editorconfig (100%) rename tests/e2e/assets/{19.0-project => 20.0-project}/.gitignore (97%) create mode 100644 tests/e2e/assets/20.0-project/.vscode/extensions.json create mode 100644 tests/e2e/assets/20.0-project/.vscode/launch.json create mode 100644 tests/e2e/assets/20.0-project/.vscode/tasks.json rename tests/e2e/assets/{19.0-project => 20.0-project}/README.md (96%) rename tests/e2e/assets/{19.0-project => 20.0-project}/angular.json (70%) create mode 100644 tests/e2e/assets/20.0-project/package.json rename tests/e2e/assets/{19.0-project => 20.0-project}/public/favicon.ico (100%) create mode 100644 tests/e2e/assets/20.0-project/src/app/app.config.ts rename tests/e2e/assets/{19.0-project/src/app/app.component.css => 20.0-project/src/app/app.css} (100%) rename tests/e2e/assets/{19.0-project/src/app/app.component.html => 20.0-project/src/app/app.html} (91%) rename tests/e2e/assets/{19.0-project => 20.0-project}/src/app/app.routes.ts (100%) create mode 100644 tests/e2e/assets/20.0-project/src/app/app.spec.ts create mode 100644 tests/e2e/assets/20.0-project/src/app/app.ts create mode 100644 tests/e2e/assets/20.0-project/src/index.html create mode 100644 tests/e2e/assets/20.0-project/src/main.ts rename tests/e2e/assets/{19.0-project => 20.0-project}/src/styles.css (100%) rename tests/e2e/assets/{19.0-project => 20.0-project}/tsconfig.app.json (81%) rename tests/e2e/assets/{19.0-project => 20.0-project}/tsconfig.json (79%) rename tests/e2e/assets/{19.0-project => 20.0-project}/tsconfig.spec.json (76%) diff --git a/tests/e2e/assets/19.0-project/package.json b/tests/e2e/assets/19.0-project/package.json deleted file mode 100644 index 7b65d66807a2..000000000000 --- a/tests/e2e/assets/19.0-project/package.json +++ /dev/null @@ -1,37 +0,0 @@ -{ - "name": "nineteen-project", - "version": "0.0.0", - "scripts": { - "ng": "ng", - "start": "ng serve", - "build": "ng build", - "watch": "ng build --watch --configuration development", - "test": "ng test" - }, - "private": true, - "dependencies": { - "@angular/common": "^19.2.0", - "@angular/compiler": "^19.2.0", - "@angular/core": "^19.2.0", - "@angular/forms": "^19.2.0", - "@angular/platform-browser": "^19.2.0", - "@angular/platform-browser-dynamic": "^19.2.0", - "@angular/router": "^19.2.0", - "rxjs": "~7.8.0", - "tslib": "^2.3.0", - "zone.js": "~0.15.0" - }, - "devDependencies": { - "@angular-devkit/build-angular": "^19.2.13", - "@angular/cli": "^19.2.13", - "@angular/compiler-cli": "^19.2.0", - "@types/jasmine": "~5.1.0", - "jasmine-core": "~5.6.0", - "karma": "~6.4.0", - "karma-chrome-launcher": "~3.2.0", - "karma-coverage": "~2.2.0", - "karma-jasmine": "~5.1.0", - "karma-jasmine-html-reporter": "~2.1.0", - "typescript": "~5.7.2" - } -} diff --git a/tests/e2e/assets/19.0-project/src/app/app.component.spec.ts b/tests/e2e/assets/19.0-project/src/app/app.component.spec.ts deleted file mode 100644 index e390fd7bd137..000000000000 --- a/tests/e2e/assets/19.0-project/src/app/app.component.spec.ts +++ /dev/null @@ -1,29 +0,0 @@ -import { TestBed } from '@angular/core/testing'; -import { AppComponent } from './app.component'; - -describe('AppComponent', () => { - beforeEach(async () => { - await TestBed.configureTestingModule({ - imports: [AppComponent], - }).compileComponents(); - }); - - it('should create the app', () => { - const fixture = TestBed.createComponent(AppComponent); - const app = fixture.componentInstance; - expect(app).toBeTruthy(); - }); - - it(`should have the 'nineteen-project' title`, () => { - const fixture = TestBed.createComponent(AppComponent); - const app = fixture.componentInstance; - expect(app.title).toEqual('nineteen-project'); - }); - - it('should render title', () => { - const fixture = TestBed.createComponent(AppComponent); - fixture.detectChanges(); - const compiled = fixture.nativeElement as HTMLElement; - expect(compiled.querySelector('h1')?.textContent).toContain('Hello, nineteen-project'); - }); -}); diff --git a/tests/e2e/assets/19.0-project/src/app/app.component.ts b/tests/e2e/assets/19.0-project/src/app/app.component.ts deleted file mode 100644 index 620c8a058372..000000000000 --- a/tests/e2e/assets/19.0-project/src/app/app.component.ts +++ /dev/null @@ -1,12 +0,0 @@ -import { Component } from '@angular/core'; -import { RouterOutlet } from '@angular/router'; - -@Component({ - selector: 'app-root', - imports: [RouterOutlet], - templateUrl: './app.component.html', - styleUrl: './app.component.css', -}) -export class AppComponent { - title = 'nineteen-project'; -} diff --git a/tests/e2e/assets/19.0-project/src/app/app.config.ts b/tests/e2e/assets/19.0-project/src/app/app.config.ts deleted file mode 100644 index 7afc797fbab7..000000000000 --- a/tests/e2e/assets/19.0-project/src/app/app.config.ts +++ /dev/null @@ -1,8 +0,0 @@ -import { ApplicationConfig, provideZoneChangeDetection } from '@angular/core'; -import { provideRouter } from '@angular/router'; - -import { routes } from './app.routes'; - -export const appConfig: ApplicationConfig = { - providers: [provideZoneChangeDetection({ eventCoalescing: true }), provideRouter(routes)], -}; diff --git a/tests/e2e/assets/19.0-project/src/index.html b/tests/e2e/assets/19.0-project/src/index.html deleted file mode 100644 index f374b0fe3d5e..000000000000 --- a/tests/e2e/assets/19.0-project/src/index.html +++ /dev/null @@ -1,13 +0,0 @@ - - - - - NineteenProject - - - - - - - - diff --git a/tests/e2e/assets/19.0-project/src/main.ts b/tests/e2e/assets/19.0-project/src/main.ts deleted file mode 100644 index 17447a5dce2c..000000000000 --- a/tests/e2e/assets/19.0-project/src/main.ts +++ /dev/null @@ -1,5 +0,0 @@ -import { bootstrapApplication } from '@angular/platform-browser'; -import { appConfig } from './app/app.config'; -import { AppComponent } from './app/app.component'; - -bootstrapApplication(AppComponent, appConfig).catch((err) => console.error(err)); diff --git a/tests/e2e/assets/19.0-project/.editorconfig b/tests/e2e/assets/20.0-project/.editorconfig similarity index 100% rename from tests/e2e/assets/19.0-project/.editorconfig rename to tests/e2e/assets/20.0-project/.editorconfig diff --git a/tests/e2e/assets/19.0-project/.gitignore b/tests/e2e/assets/20.0-project/.gitignore similarity index 97% rename from tests/e2e/assets/19.0-project/.gitignore rename to tests/e2e/assets/20.0-project/.gitignore index cc7b141350ff..b1d225e26e57 100644 --- a/tests/e2e/assets/19.0-project/.gitignore +++ b/tests/e2e/assets/20.0-project/.gitignore @@ -36,6 +36,7 @@ yarn-error.log /libpeerconnection.log testem.log /typings +__screenshots__/ # System files .DS_Store diff --git a/tests/e2e/assets/20.0-project/.vscode/extensions.json b/tests/e2e/assets/20.0-project/.vscode/extensions.json new file mode 100644 index 000000000000..77b374577de8 --- /dev/null +++ b/tests/e2e/assets/20.0-project/.vscode/extensions.json @@ -0,0 +1,4 @@ +{ + // For more information, visit: https://go.microsoft.com/fwlink/?linkid=827846 + "recommendations": ["angular.ng-template"] +} diff --git a/tests/e2e/assets/20.0-project/.vscode/launch.json b/tests/e2e/assets/20.0-project/.vscode/launch.json new file mode 100644 index 000000000000..925af837050a --- /dev/null +++ b/tests/e2e/assets/20.0-project/.vscode/launch.json @@ -0,0 +1,20 @@ +{ + // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 + "version": "0.2.0", + "configurations": [ + { + "name": "ng serve", + "type": "chrome", + "request": "launch", + "preLaunchTask": "npm: start", + "url": "http://localhost:4200/" + }, + { + "name": "ng test", + "type": "chrome", + "request": "launch", + "preLaunchTask": "npm: test", + "url": "http://localhost:9876/debug.html" + } + ] +} diff --git a/tests/e2e/assets/20.0-project/.vscode/tasks.json b/tests/e2e/assets/20.0-project/.vscode/tasks.json new file mode 100644 index 000000000000..a298b5bd8796 --- /dev/null +++ b/tests/e2e/assets/20.0-project/.vscode/tasks.json @@ -0,0 +1,42 @@ +{ + // For more information, visit: https://go.microsoft.com/fwlink/?LinkId=733558 + "version": "2.0.0", + "tasks": [ + { + "type": "npm", + "script": "start", + "isBackground": true, + "problemMatcher": { + "owner": "typescript", + "pattern": "$tsc", + "background": { + "activeOnStart": true, + "beginsPattern": { + "regexp": "(.*?)" + }, + "endsPattern": { + "regexp": "bundle generation complete" + } + } + } + }, + { + "type": "npm", + "script": "test", + "isBackground": true, + "problemMatcher": { + "owner": "typescript", + "pattern": "$tsc", + "background": { + "activeOnStart": true, + "beginsPattern": { + "regexp": "(.*?)" + }, + "endsPattern": { + "regexp": "bundle generation complete" + } + } + } + } + ] +} diff --git a/tests/e2e/assets/19.0-project/README.md b/tests/e2e/assets/20.0-project/README.md similarity index 96% rename from tests/e2e/assets/19.0-project/README.md rename to tests/e2e/assets/20.0-project/README.md index 80d80f5a3f1f..1f4d992edb5b 100644 --- a/tests/e2e/assets/19.0-project/README.md +++ b/tests/e2e/assets/20.0-project/README.md @@ -1,6 +1,6 @@ -# NineteenProject +# TwentyProject -This project was generated using [Angular CLI](https://github.com/angular/angular-cli) version 19.2.13. +This project was generated using [Angular CLI](https://github.com/angular/angular-cli) version 20.3.27. ## Development server diff --git a/tests/e2e/assets/19.0-project/angular.json b/tests/e2e/assets/20.0-project/angular.json similarity index 70% rename from tests/e2e/assets/19.0-project/angular.json rename to tests/e2e/assets/20.0-project/angular.json index b435223e9930..6c24b184adf2 100644 --- a/tests/e2e/assets/19.0-project/angular.json +++ b/tests/e2e/assets/20.0-project/angular.json @@ -3,7 +3,7 @@ "version": 1, "newProjectRoot": "projects", "projects": { - "nineteen-project": { + "twenty-project": { "projectType": "application", "schematics": {}, "root": "", @@ -11,12 +11,13 @@ "prefix": "app", "architect": { "build": { - "builder": "@angular-devkit/build-angular:application", + "builder": "@angular/build:application", "options": { - "outputPath": "dist/nineteen-project", - "index": "src/index.html", + "outputPath": "dist/twenty-project", "browser": "src/main.ts", - "polyfills": ["zone.js"], + "polyfills": [ + "zone.js" + ], "tsConfig": "tsconfig.app.json", "assets": [ { @@ -24,8 +25,9 @@ "input": "public" } ], - "styles": ["src/styles.css"], - "scripts": [] + "styles": [ + "src/styles.css" + ] }, "configurations": { "production": { @@ -52,24 +54,27 @@ "defaultConfiguration": "production" }, "serve": { - "builder": "@angular-devkit/build-angular:dev-server", + "builder": "@angular/build:dev-server", "configurations": { "production": { - "buildTarget": "nineteen-project:build:production" + "buildTarget": "twenty-project:build:production" }, "development": { - "buildTarget": "nineteen-project:build:development" + "buildTarget": "twenty-project:build:development" } }, "defaultConfiguration": "development" }, "extract-i18n": { - "builder": "@angular-devkit/build-angular:extract-i18n" + "builder": "@angular/build:extract-i18n" }, "test": { - "builder": "@angular-devkit/build-angular:karma", + "builder": "@angular/build:karma", "options": { - "polyfills": ["zone.js", "zone.js/testing"], + "polyfills": [ + "zone.js", + "zone.js/testing" + ], "tsConfig": "tsconfig.spec.json", "assets": [ { @@ -77,8 +82,9 @@ "input": "public" } ], - "styles": ["src/styles.css"], - "scripts": [] + "styles": [ + "src/styles.css" + ] } } } diff --git a/tests/e2e/assets/20.0-project/package.json b/tests/e2e/assets/20.0-project/package.json new file mode 100644 index 000000000000..dbbe2cd1478a --- /dev/null +++ b/tests/e2e/assets/20.0-project/package.json @@ -0,0 +1,48 @@ +{ + "name": "twenty-project", + "version": "0.0.0", + "scripts": { + "ng": "ng", + "start": "ng serve", + "build": "ng build", + "watch": "ng build --watch --configuration development", + "test": "ng test" + }, + "prettier": { + "printWidth": 100, + "singleQuote": true, + "overrides": [ + { + "files": "*.html", + "options": { + "parser": "angular" + } + } + ] + }, + "private": true, + "dependencies": { + "@angular/common": "^20.3.0", + "@angular/compiler": "^20.3.0", + "@angular/core": "^20.3.0", + "@angular/forms": "^20.3.0", + "@angular/platform-browser": "^20.3.0", + "@angular/router": "^20.3.0", + "rxjs": "~7.8.0", + "tslib": "^2.3.0", + "zone.js": "~0.15.0" + }, + "devDependencies": { + "@angular/build": "^20.3.27", + "@angular/cli": "^20.3.27", + "@angular/compiler-cli": "^20.3.0", + "@types/jasmine": "~5.1.0", + "jasmine-core": "~5.9.0", + "karma": "~6.4.0", + "karma-chrome-launcher": "~3.2.0", + "karma-coverage": "~2.2.0", + "karma-jasmine": "~5.1.0", + "karma-jasmine-html-reporter": "~2.1.0", + "typescript": "~5.9.2" + } +} \ No newline at end of file diff --git a/tests/e2e/assets/19.0-project/public/favicon.ico b/tests/e2e/assets/20.0-project/public/favicon.ico similarity index 100% rename from tests/e2e/assets/19.0-project/public/favicon.ico rename to tests/e2e/assets/20.0-project/public/favicon.ico diff --git a/tests/e2e/assets/20.0-project/src/app/app.config.ts b/tests/e2e/assets/20.0-project/src/app/app.config.ts new file mode 100644 index 000000000000..d953f4c41b31 --- /dev/null +++ b/tests/e2e/assets/20.0-project/src/app/app.config.ts @@ -0,0 +1,12 @@ +import { ApplicationConfig, provideBrowserGlobalErrorListeners, provideZoneChangeDetection } from '@angular/core'; +import { provideRouter } from '@angular/router'; + +import { routes } from './app.routes'; + +export const appConfig: ApplicationConfig = { + providers: [ + provideBrowserGlobalErrorListeners(), + provideZoneChangeDetection({ eventCoalescing: true }), + provideRouter(routes) + ] +}; diff --git a/tests/e2e/assets/19.0-project/src/app/app.component.css b/tests/e2e/assets/20.0-project/src/app/app.css similarity index 100% rename from tests/e2e/assets/19.0-project/src/app/app.component.css rename to tests/e2e/assets/20.0-project/src/app/app.css diff --git a/tests/e2e/assets/19.0-project/src/app/app.component.html b/tests/e2e/assets/20.0-project/src/app/app.html similarity index 91% rename from tests/e2e/assets/19.0-project/src/app/app.component.html rename to tests/e2e/assets/20.0-project/src/app/app.html index f8135391366c..752837241913 100644 --- a/tests/e2e/assets/19.0-project/src/app/app.component.html +++ b/tests/e2e/assets/20.0-project/src/app/app.html @@ -36,18 +36,9 @@ --pill-accent: var(--bright-blue); - font-family: - 'Inter', - -apple-system, - BlinkMacSystemFont, - 'Segoe UI', - Roboto, - Helvetica, - Arial, - sans-serif, - 'Apple Color Emoji', - 'Segoe UI Emoji', - 'Segoe UI Symbol'; + font-family: "Inter", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, + Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", + "Segoe UI Symbol"; box-sizing: border-box; -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; @@ -60,18 +51,9 @@ line-height: 100%; letter-spacing: -0.125rem; margin: 0; - font-family: - 'Inter Tight', - -apple-system, - BlinkMacSystemFont, - 'Segoe UI', - Roboto, - Helvetica, - Arial, - sans-serif, - 'Apple Color Emoji', - 'Segoe UI Emoji', - 'Segoe UI Symbol'; + font-family: "Inter Tight", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, + Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", + "Segoe UI Symbol"; } p { @@ -142,6 +124,7 @@ line-height: 1.4rem; letter-spacing: -0.00875rem; text-decoration: none; + white-space: nowrap; } .pill:hover { @@ -152,11 +135,15 @@ --pill-accent: var(--bright-blue); } .pill-group .pill:nth-child(6n + 2) { + --pill-accent: var(--electric-violet); + } + .pill-group .pill:nth-child(6n + 3) { --pill-accent: var(--french-violet); } - .pill-group .pill:nth-child(6n + 3), + .pill-group .pill:nth-child(6n + 4), - .pill-group .pill:nth-child(6n + 5) { + .pill-group .pill:nth-child(6n + 5), + .pill-group .pill:nth-child(6n + 6) { --pill-accent: var(--hot-red); } @@ -227,7 +214,14 @@ - + @@ -236,26 +230,26 @@ -

Hello, {{ title }}

+

Hello, {{ title() }}

Congratulations! Your app is running. 🎉

- @for ( - item of [ - { title: 'Explore the Docs', link: 'https://angular.dev' }, - { title: 'Learn with Tutorials', link: 'https://angular.dev/tutorials' }, - { title: 'CLI Docs', link: 'https://angular.dev/tools/cli' }, - { - title: 'Angular Language Service', - link: 'https://angular.dev/tools/language-service', - }, - { title: 'Angular DevTools', link: 'https://angular.dev/tools/devtools' }, - ]; - track item.title - ) { - + @for (item of [ + { title: 'Explore the Docs', link: 'https://angular.dev' }, + { title: 'Learn with Tutorials', link: 'https://angular.dev/tutorials' }, + { title: 'Prompt and best practices for AI', link: 'https://angular.dev/ai/develop-with-ai'}, + { title: 'CLI Docs', link: 'https://angular.dev/tools/cli' }, + { title: 'Angular Language Service', link: 'https://angular.dev/tools/language-service' }, + { title: 'Angular DevTools', link: 'https://angular.dev/tools/devtools' }, + ]; track item.title) { + {{ item.title }} Hello, {{ title }} /> - + Hello, {{ title }} + diff --git a/tests/e2e/assets/19.0-project/src/app/app.routes.ts b/tests/e2e/assets/20.0-project/src/app/app.routes.ts similarity index 100% rename from tests/e2e/assets/19.0-project/src/app/app.routes.ts rename to tests/e2e/assets/20.0-project/src/app/app.routes.ts diff --git a/tests/e2e/assets/20.0-project/src/app/app.spec.ts b/tests/e2e/assets/20.0-project/src/app/app.spec.ts new file mode 100644 index 000000000000..e2efaa52a155 --- /dev/null +++ b/tests/e2e/assets/20.0-project/src/app/app.spec.ts @@ -0,0 +1,23 @@ +import { TestBed } from '@angular/core/testing'; +import { App } from './app'; + +describe('App', () => { + beforeEach(async () => { + await TestBed.configureTestingModule({ + imports: [App], + }).compileComponents(); + }); + + it('should create the app', () => { + const fixture = TestBed.createComponent(App); + const app = fixture.componentInstance; + expect(app).toBeTruthy(); + }); + + it('should render title', () => { + const fixture = TestBed.createComponent(App); + fixture.detectChanges(); + const compiled = fixture.nativeElement as HTMLElement; + expect(compiled.querySelector('h1')?.textContent).toContain('Hello, twenty-project'); + }); +}); diff --git a/tests/e2e/assets/20.0-project/src/app/app.ts b/tests/e2e/assets/20.0-project/src/app/app.ts new file mode 100644 index 000000000000..41950ee52c8b --- /dev/null +++ b/tests/e2e/assets/20.0-project/src/app/app.ts @@ -0,0 +1,12 @@ +import { Component, signal } from '@angular/core'; +import { RouterOutlet } from '@angular/router'; + +@Component({ + selector: 'app-root', + imports: [RouterOutlet], + templateUrl: './app.html', + styleUrl: './app.css' +}) +export class App { + protected readonly title = signal('twenty-project'); +} diff --git a/tests/e2e/assets/20.0-project/src/index.html b/tests/e2e/assets/20.0-project/src/index.html new file mode 100644 index 000000000000..72285bc13676 --- /dev/null +++ b/tests/e2e/assets/20.0-project/src/index.html @@ -0,0 +1,13 @@ + + + + + TwentyProject + + + + + + + + diff --git a/tests/e2e/assets/20.0-project/src/main.ts b/tests/e2e/assets/20.0-project/src/main.ts new file mode 100644 index 000000000000..5df75f9c838e --- /dev/null +++ b/tests/e2e/assets/20.0-project/src/main.ts @@ -0,0 +1,6 @@ +import { bootstrapApplication } from '@angular/platform-browser'; +import { appConfig } from './app/app.config'; +import { App } from './app/app'; + +bootstrapApplication(App, appConfig) + .catch((err) => console.error(err)); diff --git a/tests/e2e/assets/19.0-project/src/styles.css b/tests/e2e/assets/20.0-project/src/styles.css similarity index 100% rename from tests/e2e/assets/19.0-project/src/styles.css rename to tests/e2e/assets/20.0-project/src/styles.css diff --git a/tests/e2e/assets/19.0-project/tsconfig.app.json b/tests/e2e/assets/20.0-project/tsconfig.app.json similarity index 81% rename from tests/e2e/assets/19.0-project/tsconfig.app.json rename to tests/e2e/assets/20.0-project/tsconfig.app.json index 8886e903f8d0..264f459bf876 100644 --- a/tests/e2e/assets/19.0-project/tsconfig.app.json +++ b/tests/e2e/assets/20.0-project/tsconfig.app.json @@ -6,6 +6,10 @@ "outDir": "./out-tsc/app", "types": [] }, - "files": ["src/main.ts"], - "include": ["src/**/*.d.ts"] + "include": [ + "src/**/*.ts" + ], + "exclude": [ + "src/**/*.spec.ts" + ] } diff --git a/tests/e2e/assets/19.0-project/tsconfig.json b/tests/e2e/assets/20.0-project/tsconfig.json similarity index 79% rename from tests/e2e/assets/19.0-project/tsconfig.json rename to tests/e2e/assets/20.0-project/tsconfig.json index 5525117c6744..e4955f26b14b 100644 --- a/tests/e2e/assets/19.0-project/tsconfig.json +++ b/tests/e2e/assets/20.0-project/tsconfig.json @@ -3,7 +3,6 @@ { "compileOnSave": false, "compilerOptions": { - "outDir": "./dist/out-tsc", "strict": true, "noImplicitOverride": true, "noPropertyAccessFromIndexSignature": true, @@ -11,17 +10,25 @@ "noFallthroughCasesInSwitch": true, "skipLibCheck": true, "isolatedModules": true, - "esModuleInterop": true, "experimentalDecorators": true, - "moduleResolution": "bundler", "importHelpers": true, "target": "ES2022", - "module": "ES2022" + "module": "preserve" }, "angularCompilerOptions": { "enableI18nLegacyMessageIdFormat": false, "strictInjectionParameters": true, "strictInputAccessModifiers": true, + "typeCheckHostBindings": true, "strictTemplates": true - } + }, + "files": [], + "references": [ + { + "path": "./tsconfig.app.json" + }, + { + "path": "./tsconfig.spec.json" + } + ] } diff --git a/tests/e2e/assets/19.0-project/tsconfig.spec.json b/tests/e2e/assets/20.0-project/tsconfig.spec.json similarity index 76% rename from tests/e2e/assets/19.0-project/tsconfig.spec.json rename to tests/e2e/assets/20.0-project/tsconfig.spec.json index e00e30e6d4fb..940b30a5fcc8 100644 --- a/tests/e2e/assets/19.0-project/tsconfig.spec.json +++ b/tests/e2e/assets/20.0-project/tsconfig.spec.json @@ -4,7 +4,12 @@ "extends": "./tsconfig.json", "compilerOptions": { "outDir": "./out-tsc/spec", - "types": ["jasmine"] + "types": [ + "jasmine" + ] }, - "include": ["src/**/*.spec.ts", "src/**/*.d.ts"] + "include": [ + "src/**/*.d.ts", + "src/**/*.spec.ts" + ] } diff --git a/tests/e2e/tests/update/update-multiple-versions.ts b/tests/e2e/tests/update/update-multiple-versions.ts index 6fecb7b15b58..c9070b1a090b 100644 --- a/tests/e2e/tests/update/update-multiple-versions.ts +++ b/tests/e2e/tests/update/update-multiple-versions.ts @@ -7,7 +7,7 @@ import { expectToFail } from '../../utils/utils'; export default async function () { let restoreRegistry: (() => Promise) | undefined; try { - restoreRegistry = await createProjectFromAsset('19.0-project', true); + restoreRegistry = await createProjectFromAsset('20.0-project', true); await setRegistry(true); const extraArgs = ['--force']; diff --git a/tests/e2e/tests/update/update.ts b/tests/e2e/tests/update/update.ts index ae941762d6ca..fd8663503ecc 100644 --- a/tests/e2e/tests/update/update.ts +++ b/tests/e2e/tests/update/update.ts @@ -12,10 +12,10 @@ export default async function () { try { // We need to use the public registry because in the local NPM server we don't have // older versions @angular/cli packages which would cause `npm install` during `ng update` to fail. - restoreRegistry = await createProjectFromAsset('19.0-project', true); + restoreRegistry = await createProjectFromAsset('20.0-project', true); // CLI project version - const cliMajorProjectVersion = 19; + const cliMajorProjectVersion = 20; // If using npm, enable legacy peer deps mode to avoid defects in npm 7+'s peer dependency resolution // Example error where 11.2.14 satisfies the SemVer range ^11.0.0 but still fails: @@ -72,8 +72,8 @@ export default async function () { await ng('update', '@angular/cli', ...extraUpdateArgs); // Setup testing to use CI Chrome. - await useCIChrome('nineteen-project', './'); - await useCIDefaults('nineteen-project'); + await useCIChrome('twenty-project', './'); + await useCIDefaults('twenty-project'); // Run CLI commands. await ng('generate', 'component', 'my-comp'); @@ -81,14 +81,14 @@ export default async function () { await executeBrowserTest({ configuration: 'production', - expectedTitleText: 'Hello, nineteen-project', + expectedTitleText: 'Hello, twenty-project', }); await executeBrowserTest({ configuration: 'development', - expectedTitleText: 'Hello, nineteen-project', + expectedTitleText: 'Hello, twenty-project', }); // Verify project now creates bundles await noSilentNg('build', '--configuration=production'); - await expectFileMatchToExist('dist/nineteen-project/browser', /main-[a-zA-Z0-9]{8}\.js/); + await expectFileMatchToExist('dist/twenty-project/browser', /main-[a-zA-Z0-9]{8}\.js/); } From 3124d165de476ed219f860c7ea582b96a8181d5c Mon Sep 17 00:00:00 2001 From: Charles Lyding <19598772+clydin@users.noreply.github.com> Date: Tue, 2 Jun 2026 11:24:03 -0400 Subject: [PATCH 004/787] fix(@angular/build): exclude JSON imports from Vite dependency optimization Importing `.json` files (such as package.json files from third-party packages) causes Vite's dependency optimizer to throw errors and warnings during `ng serve`, as Vite is unable to optimize non-JS/TS modules: `Cannot optimize dependency: @pkg-name/package.json, present in client 'optimizeDeps.include'` This fix filters out any implicit dependencies ending in `.json` in the `updateExternalMetadata` utility, preventing them from being included in Vite's `optimizeDeps.include` array. Closes #33280 --- packages/angular/build/src/tools/vite/utils.ts | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/packages/angular/build/src/tools/vite/utils.ts b/packages/angular/build/src/tools/vite/utils.ts index 8f3ded5325f7..7250fd93ceb7 100644 --- a/packages/angular/build/src/tools/vite/utils.ts +++ b/packages/angular/build/src/tools/vite/utils.ts @@ -140,8 +140,12 @@ export function updateExternalMetadata( } const { implicitBrowser, implicitServer, explicit } = result.detail['externalMetadata']; - const implicitServerFiltered = implicitServer.filter((m) => !isBuiltin(m) && !isAbsoluteUrl(m)); - const implicitBrowserFiltered = implicitBrowser.filter((m) => !isAbsoluteUrl(m)); + const implicitServerFiltered = implicitServer.filter( + (m) => !isBuiltin(m) && !isAbsoluteUrl(m) && !m.endsWith('.json'), + ); + const implicitBrowserFiltered = implicitBrowser.filter( + (m) => !isAbsoluteUrl(m) && !m.endsWith('.json'), + ); const explicitBrowserFiltered = explicitPackagesOnly ? explicit.filter((m) => !isAbsoluteUrl(m)) : explicit; From 7be9910057b4adaa56ac29917bb88efd1564cce9 Mon Sep 17 00:00:00 2001 From: Charles Lyding <19598772+clydin@users.noreply.github.com> Date: Mon, 1 Jun 2026 12:26:50 -0400 Subject: [PATCH 005/787] fix(@angular/cli): fallback to local package.json for schematic detection on first run Private package registries frequently strip out custom non-npm metadata properties such as "schematics" or "ng-add" from their remote API responses. This causes `ng add` to bypass executing schematics on the first run. This fix adds a fallback check immediately after package installation: if the registry did not report `hasSchematics` as `true`, the CLI falls back to resolving and reading the physically installed package's `package.json` on disk as the single source of truth. Additionally, if the local manifest specifies `ng-add.save: false` (but it was persistently installed due to registry omissions), it programmatically prunes the package from `dependencies` or `devDependencies` post-execution, and executes a silent `packageManager.install()` to cleanly remove the physical package files and update the lockfile. Fixes #33060 --- packages/angular/cli/src/commands/add/cli.ts | 57 ++++++++- .../add/add-registry-stripped-schematics.ts | 121 ++++++++++++++++++ 2 files changed, 177 insertions(+), 1 deletion(-) create mode 100644 tests/e2e/tests/commands/add/add-registry-stripped-schematics.ts diff --git a/packages/angular/cli/src/commands/add/cli.ts b/packages/angular/cli/src/commands/add/cli.ts index 136704947e69..b1c57a59ad45 100644 --- a/packages/angular/cli/src/commands/add/cli.ts +++ b/packages/angular/cli/src/commands/add/cli.ts @@ -245,6 +245,22 @@ export default class AddCommandModule const result = await tasks.run(taskContext); assert(result.collectionName, 'Collection name should always be available'); + let shouldCleanUp = false; + if (!result.hasSchematics && !options.dryRun) { + const packageJsonPath = this.resolvePackageJson(result.collectionName); + if (packageJsonPath && existsSync(packageJsonPath)) { + try { + const localManifest = JSON.parse(await fs.readFile(packageJsonPath, 'utf-8')); + if (localManifest.schematics) { + result.hasSchematics = true; + if (localManifest['ng-add']?.save === false) { + shouldCleanUp = true; + } + } + } catch {} + } + } + // Check if the installed package has actual add actions and not just schematic support if (result.hasSchematics && !options.dryRun) { const workflow = this.getOrCreateWorkflowForBuilder(result.collectionName); @@ -299,7 +315,16 @@ export default class AddCommandModule return; } - return this.executeSchematic({ ...options, collection: result.collectionName }); + const schematicExitCode = await this.executeSchematic({ + ...options, + collection: result.collectionName, + }); + + if (shouldCleanUp) { + await this.cleanUpTemporaryDependency(result.collectionName); + } + + return schematicExitCode; } catch (e) { if (e instanceof CommandError) { logger.error(e.message); @@ -560,6 +585,36 @@ export default class AddCommandModule } } + private async cleanUpTemporaryDependency(packageName: string): Promise { + try { + this.context.logger.info(`Cleaning up temporary dependency '${packageName}'...`); + + // 1. Remove from root package.json + const projectManifest = await this.getProjectManifest(); + if (projectManifest) { + if (projectManifest.dependencies) { + delete projectManifest.dependencies[packageName]; + } + if (projectManifest.devDependencies) { + delete projectManifest.devDependencies[packageName]; + } + + await fs.writeFile( + join(this.context.root, 'package.json'), + JSON.stringify(projectManifest, null, 2) + '\n', + ); + } + + // 2. Silent install pass to prune files from node_modules and update the lockfile + await this.context.packageManager.install({ ignoreScripts: true }); + } catch (error) { + this.context.logger.warn( + `Failed to clean up temporary dependency '${packageName}': ` + + `${error instanceof Error ? error.message : error}`, + ); + } + } + private async installPackageTask( context: AddCommandTaskContext, task: AddCommandTaskWrapper, diff --git a/tests/e2e/tests/commands/add/add-registry-stripped-schematics.ts b/tests/e2e/tests/commands/add/add-registry-stripped-schematics.ts new file mode 100644 index 000000000000..c6356dc8d92c --- /dev/null +++ b/tests/e2e/tests/commands/add/add-registry-stripped-schematics.ts @@ -0,0 +1,121 @@ +import { join } from 'node:path'; +import { promises as fs } from 'node:fs'; +import { getGlobalVariable } from '../../../utils/env'; +import { expectFileToExist, expectFileNotToExist, rimraf } from '../../../utils/fs'; +import { getActivePackageManager } from '../../../utils/packages'; +import { ng, silentNpm } from '../../../utils/process'; +import { mktempd } from '../../../utils/utils'; + +export default async function () { + const testRegistry = getGlobalVariable('package-registry'); + const tmpRoot = getGlobalVariable('tmp-root'); + + // 1. Create a temp directory for the custom package + const pkgDir = await mktempd('registry-stripped-pkg-', tmpRoot); + + try { + // 2. Write the package files + const packageJson = { + name: '@angular-devkit/ng-add-registry-stripped', + version: '1.0.0', + schematics: './collection.json', + 'ng-add': { + save: false, + }, + }; + + const collectionJson = { + schematics: { + 'ng-add': { + factory: './index.js', + description: 'Add test empty file to your application.', + }, + }, + }; + + const indexJs = ` + exports.default = function() { + return function(tree) { + tree.create('schematic-executed-successfully.txt', 'Registry Stripped schematic works!'); + return tree; + }; + }; + `; + + await fs.writeFile(join(pkgDir, 'package.json'), JSON.stringify(packageJson, null, 2)); + await fs.writeFile(join(pkgDir, 'collection.json'), JSON.stringify(collectionJson, null, 2)); + await fs.writeFile(join(pkgDir, 'index.js'), indexJs); + + // Write a temporary .npmrc with a fake authentication token so that npm publish succeeds + // without needing real credentials or throwing ENEEDAUTH. + const npmrcContent = ` +${testRegistry.replace(/^https?:/, '')}/:_authToken=fake-secret +registry=${testRegistry} +`; + await fs.writeFile(join(pkgDir, '.npmrc'), npmrcContent); + + // 3. Pack the package + const packResult = await silentNpm(['pack'], { cwd: pkgDir }); + const tarballName = packResult.stdout.trim().split('\n').pop() || ''; + + // 4. Publish the package to the local verdaccio registry + // Verdaccio has publish: $all for @angular-devkit/* so this will succeed + await silentNpm(['publish'], { cwd: pkgDir }); + + // 5. Strip "schematics" and "ng-add" from Verdaccio's metadata on disk + const verdaccioDbPath = join( + tmpRoot, + 'registry', + 'storage', + '@angular-devkit', + 'ng-add-registry-stripped', + 'package.json', + ); + + const verdaccioDb = JSON.parse(await fs.readFile(verdaccioDbPath, 'utf-8')); + + // Strip from the top-level versions list + if (verdaccioDb.versions) { + for (const versionKey of Object.keys(verdaccioDb.versions)) { + delete verdaccioDb.versions[versionKey].schematics; + delete verdaccioDb.versions[versionKey]['ng-add']; + } + } + + // Write back the modified metadata + await fs.writeFile(verdaccioDbPath, JSON.stringify(verdaccioDb, null, 2), 'utf-8'); + + // 6. Execute `ng add` on the registry-stripped package + // Ensure file doesn't already exist + await expectFileNotToExist('schematic-executed-successfully.txt'); + + await ng('add', '@angular-devkit/ng-add-registry-stripped', '--skip-confirmation'); + + // 7. Assertions + // A. The schematic executed successfully + await expectFileToExist('schematic-executed-successfully.txt'); + + // B. The dependency was pruned from package.json since save: false + const rootPackageJson = JSON.parse(await fs.readFile('package.json', 'utf-8')); + const hasDep = + (rootPackageJson.dependencies && + rootPackageJson.dependencies['@angular-devkit/ng-add-registry-stripped']) || + (rootPackageJson.devDependencies && + rootPackageJson.devDependencies['@angular-devkit/ng-add-registry-stripped']); + + if (hasDep) { + throw new Error( + 'Package @angular-devkit/ng-add-registry-stripped was not cleaned up from package.json dependencies!', + ); + } + + // C. The dependency was pruned from node_modules physical folder + // Bun intentionally does not prune unreferenced packages from node_modules automatically. + if (getActivePackageManager() !== 'bun') { + await expectFileNotToExist('node_modules/@angular-devkit/ng-add-registry-stripped'); + } + } finally { + // Cleanup temp package source folder + await rimraf(pkgDir); + } +} From e2cdb40ddc2ae093daf94494a0982af18a4d08ef Mon Sep 17 00:00:00 2001 From: Angular Robot Date: Thu, 4 Jun 2026 08:43:06 +0000 Subject: [PATCH 006/787] build: update cross-repo angular dependencies See associated pull request for more information. --- MODULE.bazel | 6 +- MODULE.bazel.lock | 38 +-- modules/testing/builder/package.json | 2 +- package.json | 28 +- packages/angular/build/package.json | 2 +- packages/angular/ssr/package.json | 12 +- .../angular_devkit/build_angular/package.json | 2 +- packages/ngtools/webpack/package.json | 4 +- pnpm-lock.yaml | 320 +++++++++--------- tests/e2e/ng-snapshot/package.json | 32 +- 10 files changed, 223 insertions(+), 223 deletions(-) diff --git a/MODULE.bazel b/MODULE.bazel index 0aca99e702d8..d93aac020710 100644 --- a/MODULE.bazel +++ b/MODULE.bazel @@ -19,21 +19,21 @@ bazel_dep(name = "aspect_rules_jasmine", version = "2.0.4") bazel_dep(name = "rules_angular") git_override( module_name = "rules_angular", - commit = "c898ddb32c0428e7d97efc713393db84ffa6a38e", + commit = "582ffa9559d60f99fd1d3e50ae32c4223f013fea", remote = "https://github.com/angular/rules_angular.git", ) bazel_dep(name = "devinfra") git_override( module_name = "devinfra", - commit = "9ee8a680dd018d61d21588bb04cf40d49a9f5deb", + commit = "b490e5cc7fd2aa57136a1962047bd89454f3df94", remote = "https://github.com/angular/dev-infra.git", ) bazel_dep(name = "rules_browsers") git_override( module_name = "rules_browsers", - commit = "45441c79322943fc1638b3a40741e925d6089e7b", + commit = "96a315fb4737861718aa59a7e7361408db704148", remote = "https://github.com/angular/rules_browsers.git", ) diff --git a/MODULE.bazel.lock b/MODULE.bazel.lock index af29118bb1f4..0753cd1055ce 100644 --- a/MODULE.bazel.lock +++ b/MODULE.bazel.lock @@ -28,7 +28,6 @@ "https://bcr.bazel.build/modules/aspect_rules_js/3.1.2/source.json": "a32ab71831452b945f3f83a1b1feb9402007e600bce55ac76e15ef0c1e08b520", "https://bcr.bazel.build/modules/aspect_rules_ts/3.8.10/MODULE.bazel": "a17a49a21226fc90163a29b3d6eac56703697205530b8d5cc38b3c074dbac039", "https://bcr.bazel.build/modules/aspect_rules_ts/3.8.10/source.json": "745c8dba237b4088409800143241bbb138e7ef37a359bd81a250c2c423f380ce", - "https://bcr.bazel.build/modules/aspect_rules_ts/3.8.9/MODULE.bazel": "bd5f9ebf517cfcd377eaa7ce1cb16035d167f00774b77789909590c53bc6f20c", "https://bcr.bazel.build/modules/aspect_tools_telemetry/0.2.8/MODULE.bazel": "aa975a83e72bcaac62ee61ab12b788ea324a1d05c4aab28aadb202f647881679", "https://bcr.bazel.build/modules/aspect_tools_telemetry/0.3.3/MODULE.bazel": "37c764292861c2f70314efa9846bb6dbb44fc0308903b3285da6528305450183", "https://bcr.bazel.build/modules/aspect_tools_telemetry/0.3.3/source.json": "605086bbc197743a0d360f7ddc550a1d4dfa0441bc807236e17170f636153348", @@ -199,7 +198,8 @@ "https://bcr.bazel.build/modules/stardoc/0.7.2/MODULE.bazel": "fc152419aa2ea0f51c29583fab1e8c99ddefd5b3778421845606ee628629e0e5", "https://bcr.bazel.build/modules/stardoc/0.7.2/source.json": "58b029e5e901d6802967754adf0a9056747e8176f017cfe3607c0851f4d42216", "https://bcr.bazel.build/modules/tar.bzl/0.10.4/MODULE.bazel": "e8f9ff79199e8d9eaad7f1b0a77ad74b30bb82d794b87d8ca942bead5de83ae9", - "https://bcr.bazel.build/modules/tar.bzl/0.10.4/source.json": "20143442376c03426f6135292ba02d825cb75308aa47e6bf42dd4cc5a435c2ff", + "https://bcr.bazel.build/modules/tar.bzl/0.10.5/MODULE.bazel": "e964c1f07f7174478d43be7177f364640e24956d5994bd39d48548cc6a436e2c", + "https://bcr.bazel.build/modules/tar.bzl/0.10.5/source.json": "6703dc57a6c7118722ac452ffb0a05f6e205408b810c6aaf25741a635d5f4b89", "https://bcr.bazel.build/modules/tar.bzl/0.2.1/MODULE.bazel": "52d1c00a80a8cc67acbd01649e83d8dd6a9dc426a6c0b754a04fe8c219c76468", "https://bcr.bazel.build/modules/tar.bzl/0.5.1/MODULE.bazel": "7c2eb3dcfc53b0f3d6f9acdfd911ca803eaf92aadf54f8ca6e4c1f3aee288351", "https://bcr.bazel.build/modules/tar.bzl/0.6.0/MODULE.bazel": "a3584b4edcfafcabd9b0ef9819808f05b372957bbdff41601429d5fd0aac2e7c", @@ -592,7 +592,7 @@ }, "@@rules_browsers+//browsers:extensions.bzl%browsers": { "general": { - "bzlTransitiveDigest": "lFwT6yuDqc73sJB9lqKqoCIJq/vYSrS0UPimP2c0ZWA=", + "bzlTransitiveDigest": "WLnUVJj/ND5g3OI+Y8YJwgtWXfoXpunqLGs7GRZ3PqI=", "usagesDigest": "FmXYJVoVJlnfUU8x8gObSvu4qWcco/9Faw61aC/wBF0=", "recordedFileInputs": {}, "recordedDirentsInputs": {}, @@ -601,9 +601,9 @@ "rules_browsers_chrome_linux": { "repoRuleId": "@@rules_browsers+//browsers/private:browser_repo.bzl%browser_repo", "attributes": { - "sha256": "f8b9f220f5691f88e00a64dafa98570158b50e7051637644df1152e3c96f9738", + "sha256": "7db2d5ced82b7f4c62ed593ff2a0e486dde48ae2b09609ab74fe30dad6eadbab", "urls": [ - "https://storage.googleapis.com/chrome-for-testing-public/150.0.7860.0/linux64/chrome-headless-shell-linux64.zip" + "https://storage.googleapis.com/chrome-for-testing-public/151.0.7872.0/linux64/chrome-headless-shell-linux64.zip" ], "named_files": { "CHROME-HEADLESS-SHELL": "chrome-headless-shell-linux64/chrome-headless-shell" @@ -619,9 +619,9 @@ "rules_browsers_chrome_mac": { "repoRuleId": "@@rules_browsers+//browsers/private:browser_repo.bzl%browser_repo", "attributes": { - "sha256": "e989d33e0c27d8884ff95d8c485993205b554499587f33ca390041d54dd57415", + "sha256": "87e67dc147587e0c6b7ae5e6d14b778e7782c8273d1798a2841b7b6b8cbcb669", "urls": [ - "https://storage.googleapis.com/chrome-for-testing-public/150.0.7860.0/mac-x64/chrome-headless-shell-mac-x64.zip" + "https://storage.googleapis.com/chrome-for-testing-public/151.0.7872.0/mac-x64/chrome-headless-shell-mac-x64.zip" ], "named_files": { "CHROME-HEADLESS-SHELL": "chrome-headless-shell-mac-x64/chrome-headless-shell" @@ -637,9 +637,9 @@ "rules_browsers_chrome_mac_arm": { "repoRuleId": "@@rules_browsers+//browsers/private:browser_repo.bzl%browser_repo", "attributes": { - "sha256": "e92afa41f45c8cd5241572e21ec3a17a68d12926f7fad7047e8d4bbef0397f4e", + "sha256": "42675dfaf8e89174fafecf300fdba58bc8410c31b7d9d2300505dce3358cff9c", "urls": [ - "https://storage.googleapis.com/chrome-for-testing-public/150.0.7860.0/mac-arm64/chrome-headless-shell-mac-arm64.zip" + "https://storage.googleapis.com/chrome-for-testing-public/151.0.7872.0/mac-arm64/chrome-headless-shell-mac-arm64.zip" ], "named_files": { "CHROME-HEADLESS-SHELL": "chrome-headless-shell-mac-arm64/chrome-headless-shell" @@ -655,9 +655,9 @@ "rules_browsers_chrome_win64": { "repoRuleId": "@@rules_browsers+//browsers/private:browser_repo.bzl%browser_repo", "attributes": { - "sha256": "374efaa85908a078e41a0a75bded482eeb1d652aea6c5bb0c14cd854736943c8", + "sha256": "f9b135b3d1ca7e80dcced8ece4975a918f1d37d2b1f74793902e3b1ab3fa4ea6", "urls": [ - "https://storage.googleapis.com/chrome-for-testing-public/150.0.7860.0/win64/chrome-headless-shell-win64.zip" + "https://storage.googleapis.com/chrome-for-testing-public/151.0.7872.0/win64/chrome-headless-shell-win64.zip" ], "named_files": { "CHROME-HEADLESS-SHELL": "chrome-headless-shell-win64/chrome-headless-shell.exe" @@ -673,9 +673,9 @@ "rules_browsers_chromedriver_linux": { "repoRuleId": "@@rules_browsers+//browsers/private:browser_repo.bzl%browser_repo", "attributes": { - "sha256": "69e0625253c89cc7f8d265016fa46bf63401f9f7ca0454d0dade828c58bd9a08", + "sha256": "39c2d4425b848f2e09940b4060f50484ca83f18b9d3bdbe2f42495d4a1d38f71", "urls": [ - "https://storage.googleapis.com/chrome-for-testing-public/150.0.7860.0/linux64/chromedriver-linux64.zip" + "https://storage.googleapis.com/chrome-for-testing-public/151.0.7872.0/linux64/chromedriver-linux64.zip" ], "named_files": { "CHROMEDRIVER": "chromedriver-linux64/chromedriver" @@ -689,9 +689,9 @@ "rules_browsers_chromedriver_mac": { "repoRuleId": "@@rules_browsers+//browsers/private:browser_repo.bzl%browser_repo", "attributes": { - "sha256": "95e64bff15615dede9e6a690cf91fc76603354daa05d80437be39e15dfc94611", + "sha256": "48ece94ee9b286f47c6662f3d2640a4a035af2e4f8101f8a971a909bc552bd36", "urls": [ - "https://storage.googleapis.com/chrome-for-testing-public/150.0.7860.0/mac-x64/chromedriver-mac-x64.zip" + "https://storage.googleapis.com/chrome-for-testing-public/151.0.7872.0/mac-x64/chromedriver-mac-x64.zip" ], "named_files": { "CHROMEDRIVER": "chromedriver-mac-x64/chromedriver" @@ -705,9 +705,9 @@ "rules_browsers_chromedriver_mac_arm": { "repoRuleId": "@@rules_browsers+//browsers/private:browser_repo.bzl%browser_repo", "attributes": { - "sha256": "63d0da6ef29c4ad9f6b5ddbe68466e3c301c9e04daed509ac31f339a5948fe8e", + "sha256": "736ec9b51a4d6fe1622d1940df29e3b183fe5d09f7f06d68141c2330f76a9790", "urls": [ - "https://storage.googleapis.com/chrome-for-testing-public/150.0.7860.0/mac-arm64/chromedriver-mac-arm64.zip" + "https://storage.googleapis.com/chrome-for-testing-public/151.0.7872.0/mac-arm64/chromedriver-mac-arm64.zip" ], "named_files": { "CHROMEDRIVER": "chromedriver-mac-arm64/chromedriver" @@ -721,9 +721,9 @@ "rules_browsers_chromedriver_win64": { "repoRuleId": "@@rules_browsers+//browsers/private:browser_repo.bzl%browser_repo", "attributes": { - "sha256": "93b27d5b09340d650923cfd9d8e306c2e6430dcf0b826f34e79080b43dff7064", + "sha256": "77b5c787237dcac62686c125e702d0bddc28466e9660f79a77d8389cd1d94513", "urls": [ - "https://storage.googleapis.com/chrome-for-testing-public/150.0.7860.0/win64/chromedriver-win64.zip" + "https://storage.googleapis.com/chrome-for-testing-public/151.0.7872.0/win64/chromedriver-win64.zip" ], "named_files": { "CHROMEDRIVER": "chromedriver-win64/chromedriver.exe" diff --git a/modules/testing/builder/package.json b/modules/testing/builder/package.json index 4df27d0c3b7c..f03f858b009a 100644 --- a/modules/testing/builder/package.json +++ b/modules/testing/builder/package.json @@ -8,7 +8,7 @@ "browser-sync": "3.0.4", "istanbul-lib-instrument": "6.0.3", "jsdom": "29.1.1", - "ng-packagr": "22.0.0-rc.0", + "ng-packagr": "22.1.0-next.1", "rxjs": "7.8.2", "vitest": "4.1.7" } diff --git a/package.json b/package.json index 4854c4f4ad8a..7443df2d3cab 100644 --- a/package.json +++ b/package.json @@ -42,23 +42,23 @@ }, "homepage": "https://github.com/angular/angular-cli", "dependencies": { - "@angular/compiler-cli": "22.0.0-rc.2", + "@angular/compiler-cli": "22.0.0", "typescript": "6.0.3" }, "devDependencies": { - "@angular/animations": "22.0.0-rc.2", - "@angular/cdk": "22.0.0-rc.2", - "@angular/common": "22.0.0-rc.2", - "@angular/compiler": "22.0.0-rc.2", - "@angular/core": "22.0.0-rc.2", - "@angular/forms": "22.0.0-rc.2", - "@angular/localize": "22.0.0-rc.2", - "@angular/material": "22.0.0-rc.2", - "@angular/ng-dev": "https://github.com/angular/dev-infra-private-ng-dev-builds.git#a450a2420ca888116e6d4207b38819cd27b06179", - "@angular/platform-browser": "22.0.0-rc.2", - "@angular/platform-server": "22.0.0-rc.2", - "@angular/router": "22.0.0-rc.2", - "@angular/service-worker": "22.0.0-rc.2", + "@angular/animations": "22.0.0", + "@angular/cdk": "22.0.0", + "@angular/common": "22.0.0", + "@angular/compiler": "22.0.0", + "@angular/core": "22.0.0", + "@angular/forms": "22.0.0", + "@angular/localize": "22.0.0", + "@angular/material": "22.0.0", + "@angular/ng-dev": "https://github.com/angular/dev-infra-private-ng-dev-builds.git#e882d214a66c8335dc38fe15ebeabeba85a0ea29", + "@angular/platform-browser": "22.0.0", + "@angular/platform-server": "22.0.0", + "@angular/router": "22.0.0", + "@angular/service-worker": "22.0.0", "@babel/core": "7.29.7", "@bazel/bazelisk": "1.28.1", "@bazel/buildifier": "8.2.1", diff --git a/packages/angular/build/package.json b/packages/angular/build/package.json index 3c0aa9abd62a..79612fd1fde1 100644 --- a/packages/angular/build/package.json +++ b/packages/angular/build/package.json @@ -53,7 +53,7 @@ "istanbul-lib-instrument": "6.0.3", "jsdom": "29.1.1", "less": "4.6.4", - "ng-packagr": "22.0.0-rc.0", + "ng-packagr": "22.1.0-next.1", "postcss": "8.5.15", "rolldown": "1.0.2", "rxjs": "7.8.2", diff --git a/packages/angular/ssr/package.json b/packages/angular/ssr/package.json index 435a597a89f4..2e99519ed20c 100644 --- a/packages/angular/ssr/package.json +++ b/packages/angular/ssr/package.json @@ -37,12 +37,12 @@ }, "devDependencies": { "@angular-devkit/schematics": "workspace:*", - "@angular/common": "22.0.0-rc.2", - "@angular/compiler": "22.0.0-rc.2", - "@angular/core": "22.0.0-rc.2", - "@angular/platform-browser": "22.0.0-rc.2", - "@angular/platform-server": "22.0.0-rc.2", - "@angular/router": "22.0.0-rc.2", + "@angular/common": "22.0.0", + "@angular/compiler": "22.0.0", + "@angular/core": "22.0.0", + "@angular/platform-browser": "22.0.0", + "@angular/platform-server": "22.0.0", + "@angular/router": "22.0.0", "@schematics/angular": "workspace:*", "beasties": "0.4.2" }, diff --git a/packages/angular_devkit/build_angular/package.json b/packages/angular_devkit/build_angular/package.json index bc7b623d1d62..d1badb54885e 100644 --- a/packages/angular_devkit/build_angular/package.json +++ b/packages/angular_devkit/build_angular/package.json @@ -66,7 +66,7 @@ "devDependencies": { "@angular/ssr": "workspace:*", "browser-sync": "3.0.4", - "ng-packagr": "22.0.0-rc.0", + "ng-packagr": "22.1.0-next.1", "undici": "8.3.0" }, "peerDependencies": { diff --git a/packages/ngtools/webpack/package.json b/packages/ngtools/webpack/package.json index c93dbbee2337..40443c7f3ea0 100644 --- a/packages/ngtools/webpack/package.json +++ b/packages/ngtools/webpack/package.json @@ -17,8 +17,8 @@ }, "devDependencies": { "@angular-devkit/core": "workspace:0.0.0-PLACEHOLDER", - "@angular/compiler": "22.0.0-rc.2", - "@angular/compiler-cli": "22.0.0-rc.2", + "@angular/compiler": "22.0.0", + "@angular/compiler-cli": "22.0.0", "typescript": "6.0.3", "webpack": "5.107.2" } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 7ffcc40ef8cb..496cd47a99eb 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -14,8 +14,8 @@ importers: .: dependencies: '@angular/compiler-cli': - specifier: 22.0.0-rc.2 - version: 22.0.0-rc.2(@angular/compiler@22.0.0-rc.2)(typescript@6.0.3) + specifier: 22.0.0 + version: 22.0.0(@angular/compiler@22.0.0)(typescript@6.0.3) typescript: specifier: 6.0.3 version: 6.0.3 @@ -26,44 +26,44 @@ importers: built: true devDependencies: '@angular/animations': - specifier: 22.0.0-rc.2 - version: 22.0.0-rc.2(@angular/core@22.0.0-rc.2(@angular/compiler@22.0.0-rc.2)(rxjs@7.8.2)(zone.js@0.16.2)) + specifier: 22.0.0 + version: 22.0.0(@angular/core@22.0.0(@angular/compiler@22.0.0)(rxjs@7.8.2)(zone.js@0.16.2)) '@angular/cdk': - specifier: 22.0.0-rc.2 - version: 22.0.0-rc.2(@angular/common@22.0.0-rc.2(@angular/core@22.0.0-rc.2(@angular/compiler@22.0.0-rc.2)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2))(@angular/core@22.0.0-rc.2(@angular/compiler@22.0.0-rc.2)(rxjs@7.8.2)(zone.js@0.16.2))(@angular/platform-browser@22.0.0-rc.2(@angular/animations@22.0.0-rc.2(@angular/core@22.0.0-rc.2(@angular/compiler@22.0.0-rc.2)(rxjs@7.8.2)(zone.js@0.16.2)))(@angular/common@22.0.0-rc.2(@angular/core@22.0.0-rc.2(@angular/compiler@22.0.0-rc.2)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2))(@angular/core@22.0.0-rc.2(@angular/compiler@22.0.0-rc.2)(rxjs@7.8.2)(zone.js@0.16.2)))(rxjs@7.8.2) + specifier: 22.0.0 + version: 22.0.0(@angular/common@22.0.0(@angular/core@22.0.0(@angular/compiler@22.0.0)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2))(@angular/core@22.0.0(@angular/compiler@22.0.0)(rxjs@7.8.2)(zone.js@0.16.2))(@angular/platform-browser@22.0.0(@angular/animations@22.0.0(@angular/core@22.0.0(@angular/compiler@22.0.0)(rxjs@7.8.2)(zone.js@0.16.2)))(@angular/common@22.0.0(@angular/core@22.0.0(@angular/compiler@22.0.0)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2))(@angular/core@22.0.0(@angular/compiler@22.0.0)(rxjs@7.8.2)(zone.js@0.16.2)))(rxjs@7.8.2) '@angular/common': - specifier: 22.0.0-rc.2 - version: 22.0.0-rc.2(@angular/core@22.0.0-rc.2(@angular/compiler@22.0.0-rc.2)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2) + specifier: 22.0.0 + version: 22.0.0(@angular/core@22.0.0(@angular/compiler@22.0.0)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2) '@angular/compiler': - specifier: 22.0.0-rc.2 - version: 22.0.0-rc.2 + specifier: 22.0.0 + version: 22.0.0 '@angular/core': - specifier: 22.0.0-rc.2 - version: 22.0.0-rc.2(@angular/compiler@22.0.0-rc.2)(rxjs@7.8.2)(zone.js@0.16.2) + specifier: 22.0.0 + version: 22.0.0(@angular/compiler@22.0.0)(rxjs@7.8.2)(zone.js@0.16.2) '@angular/forms': - specifier: 22.0.0-rc.2 - version: 22.0.0-rc.2(@angular/common@22.0.0-rc.2(@angular/core@22.0.0-rc.2(@angular/compiler@22.0.0-rc.2)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2))(@angular/core@22.0.0-rc.2(@angular/compiler@22.0.0-rc.2)(rxjs@7.8.2)(zone.js@0.16.2))(@angular/platform-browser@22.0.0-rc.2(@angular/animations@22.0.0-rc.2(@angular/core@22.0.0-rc.2(@angular/compiler@22.0.0-rc.2)(rxjs@7.8.2)(zone.js@0.16.2)))(@angular/common@22.0.0-rc.2(@angular/core@22.0.0-rc.2(@angular/compiler@22.0.0-rc.2)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2))(@angular/core@22.0.0-rc.2(@angular/compiler@22.0.0-rc.2)(rxjs@7.8.2)(zone.js@0.16.2)))(rxjs@7.8.2) + specifier: 22.0.0 + version: 22.0.0(@angular/common@22.0.0(@angular/core@22.0.0(@angular/compiler@22.0.0)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2))(@angular/core@22.0.0(@angular/compiler@22.0.0)(rxjs@7.8.2)(zone.js@0.16.2))(@angular/platform-browser@22.0.0(@angular/animations@22.0.0(@angular/core@22.0.0(@angular/compiler@22.0.0)(rxjs@7.8.2)(zone.js@0.16.2)))(@angular/common@22.0.0(@angular/core@22.0.0(@angular/compiler@22.0.0)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2))(@angular/core@22.0.0(@angular/compiler@22.0.0)(rxjs@7.8.2)(zone.js@0.16.2)))(rxjs@7.8.2) '@angular/localize': - specifier: 22.0.0-rc.2 - version: 22.0.0-rc.2(@angular/compiler-cli@22.0.0-rc.2(@angular/compiler@22.0.0-rc.2)(typescript@6.0.3))(@angular/compiler@22.0.0-rc.2) + specifier: 22.0.0 + version: 22.0.0(@angular/compiler-cli@22.0.0(@angular/compiler@22.0.0)(typescript@6.0.3))(@angular/compiler@22.0.0) '@angular/material': - specifier: 22.0.0-rc.2 - version: 22.0.0-rc.2(8f7a4024ad7b6c55fb0a3a6a45a14224) + specifier: 22.0.0 + version: 22.0.0(6eb83275f51d1d41f72333b1955c7306) '@angular/ng-dev': - specifier: https://github.com/angular/dev-infra-private-ng-dev-builds.git#a450a2420ca888116e6d4207b38819cd27b06179 - version: https://codeload.github.com/angular/dev-infra-private-ng-dev-builds/tar.gz/a450a2420ca888116e6d4207b38819cd27b06179(@modelcontextprotocol/sdk@1.29.0(zod@4.4.3)) + specifier: https://github.com/angular/dev-infra-private-ng-dev-builds.git#e882d214a66c8335dc38fe15ebeabeba85a0ea29 + version: https://codeload.github.com/angular/dev-infra-private-ng-dev-builds/tar.gz/e882d214a66c8335dc38fe15ebeabeba85a0ea29(@modelcontextprotocol/sdk@1.29.0(zod@4.4.3)) '@angular/platform-browser': - specifier: 22.0.0-rc.2 - version: 22.0.0-rc.2(@angular/animations@22.0.0-rc.2(@angular/core@22.0.0-rc.2(@angular/compiler@22.0.0-rc.2)(rxjs@7.8.2)(zone.js@0.16.2)))(@angular/common@22.0.0-rc.2(@angular/core@22.0.0-rc.2(@angular/compiler@22.0.0-rc.2)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2))(@angular/core@22.0.0-rc.2(@angular/compiler@22.0.0-rc.2)(rxjs@7.8.2)(zone.js@0.16.2)) + specifier: 22.0.0 + version: 22.0.0(@angular/animations@22.0.0(@angular/core@22.0.0(@angular/compiler@22.0.0)(rxjs@7.8.2)(zone.js@0.16.2)))(@angular/common@22.0.0(@angular/core@22.0.0(@angular/compiler@22.0.0)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2))(@angular/core@22.0.0(@angular/compiler@22.0.0)(rxjs@7.8.2)(zone.js@0.16.2)) '@angular/platform-server': - specifier: 22.0.0-rc.2 - version: 22.0.0-rc.2(@angular/common@22.0.0-rc.2(@angular/core@22.0.0-rc.2(@angular/compiler@22.0.0-rc.2)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2))(@angular/compiler@22.0.0-rc.2)(@angular/core@22.0.0-rc.2(@angular/compiler@22.0.0-rc.2)(rxjs@7.8.2)(zone.js@0.16.2))(@angular/platform-browser@22.0.0-rc.2(@angular/animations@22.0.0-rc.2(@angular/core@22.0.0-rc.2(@angular/compiler@22.0.0-rc.2)(rxjs@7.8.2)(zone.js@0.16.2)))(@angular/common@22.0.0-rc.2(@angular/core@22.0.0-rc.2(@angular/compiler@22.0.0-rc.2)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2))(@angular/core@22.0.0-rc.2(@angular/compiler@22.0.0-rc.2)(rxjs@7.8.2)(zone.js@0.16.2)))(rxjs@7.8.2) + specifier: 22.0.0 + version: 22.0.0(@angular/common@22.0.0(@angular/core@22.0.0(@angular/compiler@22.0.0)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2))(@angular/compiler@22.0.0)(@angular/core@22.0.0(@angular/compiler@22.0.0)(rxjs@7.8.2)(zone.js@0.16.2))(@angular/platform-browser@22.0.0(@angular/animations@22.0.0(@angular/core@22.0.0(@angular/compiler@22.0.0)(rxjs@7.8.2)(zone.js@0.16.2)))(@angular/common@22.0.0(@angular/core@22.0.0(@angular/compiler@22.0.0)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2))(@angular/core@22.0.0(@angular/compiler@22.0.0)(rxjs@7.8.2)(zone.js@0.16.2)))(rxjs@7.8.2) '@angular/router': - specifier: 22.0.0-rc.2 - version: 22.0.0-rc.2(@angular/common@22.0.0-rc.2(@angular/core@22.0.0-rc.2(@angular/compiler@22.0.0-rc.2)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2))(@angular/core@22.0.0-rc.2(@angular/compiler@22.0.0-rc.2)(rxjs@7.8.2)(zone.js@0.16.2))(@angular/platform-browser@22.0.0-rc.2(@angular/animations@22.0.0-rc.2(@angular/core@22.0.0-rc.2(@angular/compiler@22.0.0-rc.2)(rxjs@7.8.2)(zone.js@0.16.2)))(@angular/common@22.0.0-rc.2(@angular/core@22.0.0-rc.2(@angular/compiler@22.0.0-rc.2)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2))(@angular/core@22.0.0-rc.2(@angular/compiler@22.0.0-rc.2)(rxjs@7.8.2)(zone.js@0.16.2)))(rxjs@7.8.2) + specifier: 22.0.0 + version: 22.0.0(@angular/common@22.0.0(@angular/core@22.0.0(@angular/compiler@22.0.0)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2))(@angular/core@22.0.0(@angular/compiler@22.0.0)(rxjs@7.8.2)(zone.js@0.16.2))(@angular/platform-browser@22.0.0(@angular/animations@22.0.0(@angular/core@22.0.0(@angular/compiler@22.0.0)(rxjs@7.8.2)(zone.js@0.16.2)))(@angular/common@22.0.0(@angular/core@22.0.0(@angular/compiler@22.0.0)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2))(@angular/core@22.0.0(@angular/compiler@22.0.0)(rxjs@7.8.2)(zone.js@0.16.2)))(rxjs@7.8.2) '@angular/service-worker': - specifier: 22.0.0-rc.2 - version: 22.0.0-rc.2(@angular/core@22.0.0-rc.2(@angular/compiler@22.0.0-rc.2)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2) + specifier: 22.0.0 + version: 22.0.0(@angular/core@22.0.0(@angular/compiler@22.0.0)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2) '@babel/core': specifier: 7.29.7 version: 7.29.7 @@ -326,8 +326,8 @@ importers: specifier: 29.1.1 version: 29.1.1 ng-packagr: - specifier: 22.0.0-rc.0 - version: 22.0.0-rc.0(@angular/compiler-cli@22.0.0-rc.2(@angular/compiler@22.0.0-rc.2)(typescript@6.0.3))(tslib@2.8.1)(typescript@6.0.3) + specifier: 22.1.0-next.1 + version: 22.1.0-next.1(@angular/compiler-cli@22.0.0(@angular/compiler@22.0.0)(typescript@6.0.3))(tslib@2.8.1)(typescript@6.0.3) rxjs: specifier: 7.8.2 version: 7.8.2 @@ -429,8 +429,8 @@ importers: specifier: 4.6.4 version: 4.6.4 ng-packagr: - specifier: 22.0.0-rc.0 - version: 22.0.0-rc.0(@angular/compiler-cli@22.0.0-rc.2(@angular/compiler@22.0.0-rc.2)(typescript@6.0.3))(tslib@2.8.1)(typescript@6.0.3) + specifier: 22.1.0-next.1 + version: 22.1.0-next.1(@angular/compiler-cli@22.0.0(@angular/compiler@22.0.0)(typescript@6.0.3))(tslib@2.8.1)(typescript@6.0.3) postcss: specifier: 8.5.15 version: 8.5.15 @@ -527,23 +527,23 @@ importers: specifier: workspace:* version: link:../../angular_devkit/schematics '@angular/common': - specifier: 22.0.0-rc.2 - version: 22.0.0-rc.2(@angular/core@22.0.0-rc.2(@angular/compiler@22.0.0-rc.2)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2) + specifier: 22.0.0 + version: 22.0.0(@angular/core@22.0.0(@angular/compiler@22.0.0)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2) '@angular/compiler': - specifier: 22.0.0-rc.2 - version: 22.0.0-rc.2 + specifier: 22.0.0 + version: 22.0.0 '@angular/core': - specifier: 22.0.0-rc.2 - version: 22.0.0-rc.2(@angular/compiler@22.0.0-rc.2)(rxjs@7.8.2)(zone.js@0.16.2) + specifier: 22.0.0 + version: 22.0.0(@angular/compiler@22.0.0)(rxjs@7.8.2)(zone.js@0.16.2) '@angular/platform-browser': - specifier: 22.0.0-rc.2 - version: 22.0.0-rc.2(@angular/animations@22.0.0-rc.2(@angular/core@22.0.0-rc.2(@angular/compiler@22.0.0-rc.2)(rxjs@7.8.2)(zone.js@0.16.2)))(@angular/common@22.0.0-rc.2(@angular/core@22.0.0-rc.2(@angular/compiler@22.0.0-rc.2)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2))(@angular/core@22.0.0-rc.2(@angular/compiler@22.0.0-rc.2)(rxjs@7.8.2)(zone.js@0.16.2)) + specifier: 22.0.0 + version: 22.0.0(@angular/animations@22.0.0(@angular/core@22.0.0(@angular/compiler@22.0.0)(rxjs@7.8.2)(zone.js@0.16.2)))(@angular/common@22.0.0(@angular/core@22.0.0(@angular/compiler@22.0.0)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2))(@angular/core@22.0.0(@angular/compiler@22.0.0)(rxjs@7.8.2)(zone.js@0.16.2)) '@angular/platform-server': - specifier: 22.0.0-rc.2 - version: 22.0.0-rc.2(@angular/common@22.0.0-rc.2(@angular/core@22.0.0-rc.2(@angular/compiler@22.0.0-rc.2)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2))(@angular/compiler@22.0.0-rc.2)(@angular/core@22.0.0-rc.2(@angular/compiler@22.0.0-rc.2)(rxjs@7.8.2)(zone.js@0.16.2))(@angular/platform-browser@22.0.0-rc.2(@angular/animations@22.0.0-rc.2(@angular/core@22.0.0-rc.2(@angular/compiler@22.0.0-rc.2)(rxjs@7.8.2)(zone.js@0.16.2)))(@angular/common@22.0.0-rc.2(@angular/core@22.0.0-rc.2(@angular/compiler@22.0.0-rc.2)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2))(@angular/core@22.0.0-rc.2(@angular/compiler@22.0.0-rc.2)(rxjs@7.8.2)(zone.js@0.16.2)))(rxjs@7.8.2) + specifier: 22.0.0 + version: 22.0.0(@angular/common@22.0.0(@angular/core@22.0.0(@angular/compiler@22.0.0)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2))(@angular/compiler@22.0.0)(@angular/core@22.0.0(@angular/compiler@22.0.0)(rxjs@7.8.2)(zone.js@0.16.2))(@angular/platform-browser@22.0.0(@angular/animations@22.0.0(@angular/core@22.0.0(@angular/compiler@22.0.0)(rxjs@7.8.2)(zone.js@0.16.2)))(@angular/common@22.0.0(@angular/core@22.0.0(@angular/compiler@22.0.0)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2))(@angular/core@22.0.0(@angular/compiler@22.0.0)(rxjs@7.8.2)(zone.js@0.16.2)))(rxjs@7.8.2) '@angular/router': - specifier: 22.0.0-rc.2 - version: 22.0.0-rc.2(@angular/common@22.0.0-rc.2(@angular/core@22.0.0-rc.2(@angular/compiler@22.0.0-rc.2)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2))(@angular/core@22.0.0-rc.2(@angular/compiler@22.0.0-rc.2)(rxjs@7.8.2)(zone.js@0.16.2))(@angular/platform-browser@22.0.0-rc.2(@angular/animations@22.0.0-rc.2(@angular/core@22.0.0-rc.2(@angular/compiler@22.0.0-rc.2)(rxjs@7.8.2)(zone.js@0.16.2)))(@angular/common@22.0.0-rc.2(@angular/core@22.0.0-rc.2(@angular/compiler@22.0.0-rc.2)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2))(@angular/core@22.0.0-rc.2(@angular/compiler@22.0.0-rc.2)(rxjs@7.8.2)(zone.js@0.16.2)))(rxjs@7.8.2) + specifier: 22.0.0 + version: 22.0.0(@angular/common@22.0.0(@angular/core@22.0.0(@angular/compiler@22.0.0)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2))(@angular/core@22.0.0(@angular/compiler@22.0.0)(rxjs@7.8.2)(zone.js@0.16.2))(@angular/platform-browser@22.0.0(@angular/animations@22.0.0(@angular/core@22.0.0(@angular/compiler@22.0.0)(rxjs@7.8.2)(zone.js@0.16.2)))(@angular/common@22.0.0(@angular/core@22.0.0(@angular/compiler@22.0.0)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2))(@angular/core@22.0.0(@angular/compiler@22.0.0)(rxjs@7.8.2)(zone.js@0.16.2)))(rxjs@7.8.2) '@schematics/angular': specifier: workspace:* version: link:../../schematics/angular @@ -729,8 +729,8 @@ importers: specifier: 3.0.4 version: 3.0.4(bufferutil@4.1.0)(utf-8-validate@6.0.6) ng-packagr: - specifier: 22.0.0-rc.0 - version: 22.0.0-rc.0(@angular/compiler-cli@22.0.0-rc.2(@angular/compiler@22.0.0-rc.2)(typescript@6.0.3))(tslib@2.8.1)(typescript@6.0.3) + specifier: 22.1.0-next.1 + version: 22.1.0-next.1(@angular/compiler-cli@22.0.0(@angular/compiler@22.0.0)(typescript@6.0.3))(tslib@2.8.1)(typescript@6.0.3) undici: specifier: 8.3.0 version: 8.3.0 @@ -822,11 +822,11 @@ importers: specifier: workspace:0.0.0-PLACEHOLDER version: link:../../angular_devkit/core '@angular/compiler': - specifier: 22.0.0-rc.2 - version: 22.0.0-rc.2 + specifier: 22.0.0 + version: 22.0.0 '@angular/compiler-cli': - specifier: 22.0.0-rc.2 - version: 22.0.0-rc.2(@angular/compiler@22.0.0-rc.2)(typescript@6.0.3) + specifier: 22.0.0 + version: 22.0.0(@angular/compiler@22.0.0)(typescript@6.0.3) typescript: specifier: 6.0.3 version: 6.0.3 @@ -935,47 +935,47 @@ packages: resolution: {integrity: sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==} engines: {node: '>=6.0.0'} - '@angular/animations@22.0.0-rc.2': - resolution: {integrity: sha512-52HYIiFcAfp9G3+X/EfMNTtklZg63F0OXvZoiVxPLITAIFZ9DTPHsgSWedJ0uylH4r+SmApInIdpXpkqVBqsoA==} + '@angular/animations@22.0.0': + resolution: {integrity: sha512-Klo9ZiRj5ykXPliUmwy0eXvDad079YMy+Ob4EITSFSXVLRy55qv64/8SvWNtKEQPelF50H9O2vULoqpIvdWoAw==} engines: {node: ^22.22.3 || ^24.15.0 || >=26.0.0} peerDependencies: - '@angular/core': 22.0.0-rc.2 + '@angular/core': 22.0.0 - '@angular/cdk@22.0.0-rc.2': - resolution: {integrity: sha512-KiQInxX5WrPgsNjqqaD3/voRXNNsp0cuvH8VZerIeRUrOxsuqsyU8bUk6q6GWobL4LDj7afiqjDTEdwnq9KVww==} + '@angular/cdk@22.0.0': + resolution: {integrity: sha512-mahXlRD4V8Tj2NtttRNFfuTru5HmMgJt8ny/SJ/Bx1NCOymxLEqxREACNpuwMf/3q1XUe33/oh++mvJQ2JYkgw==} peerDependencies: - '@angular/common': ^22.0.0-0 || ^22.1.0-0 || ^22.2.0-0 || ^22.3.0-0 || ^23.0.0-0 - '@angular/core': ^22.0.0-0 || ^22.1.0-0 || ^22.2.0-0 || ^22.3.0-0 || ^23.0.0-0 - '@angular/platform-browser': ^22.0.0-0 || ^22.1.0-0 || ^22.2.0-0 || ^22.3.0-0 || ^23.0.0-0 + '@angular/common': ^22.0.0 || ^23.0.0 + '@angular/core': ^22.0.0 || ^23.0.0 + '@angular/platform-browser': ^22.0.0 || ^23.0.0 rxjs: ^6.5.3 || ^7.4.0 - '@angular/common@22.0.0-rc.2': - resolution: {integrity: sha512-RRLQPS19whiCATcKZPegAxgncwKDezwKqr5Jsgdv5jD44VqzsCB7FsUWZk9sUsdF3NmzK0FUjlvqAn8PnzYzlg==} + '@angular/common@22.0.0': + resolution: {integrity: sha512-O9Qk60/OQQuZXMeXRfOpsq+/B609nd5KIxjSZFddRQUfSMZrdvVDNK0irjgYVKGDkMx3dqCiQ8a4nAIdGy7V6A==} engines: {node: ^22.22.3 || ^24.15.0 || >=26.0.0} peerDependencies: - '@angular/core': 22.0.0-rc.2 + '@angular/core': 22.0.0 rxjs: ^6.5.3 || ^7.4.0 - '@angular/compiler-cli@22.0.0-rc.2': - resolution: {integrity: sha512-GeFujbuSgUsCGjshs2BQN+C85vNVkaFkpWDhRqGHmtSZlDis4/C8aQTw08mpDMx+0N4hvJiiF3zvzs4fjn3AqQ==} + '@angular/compiler-cli@22.0.0': + resolution: {integrity: sha512-7r4ufQ8CUhlRBol/N8a6psg40kOu/Y3H6iuUGwq9cs6Gs/fII7mVB6QgPi0bCiNDjaQB7xGq6NZ0iT6CPBH8Sw==} engines: {node: ^22.22.3 || ^24.15.0 || >=26.0.0} hasBin: true peerDependencies: - '@angular/compiler': 22.0.0-rc.2 + '@angular/compiler': 22.0.0 typescript: '>=6.0 <6.1' peerDependenciesMeta: typescript: optional: true - '@angular/compiler@22.0.0-rc.2': - resolution: {integrity: sha512-URPbTubtOPtx5nSUbb5gG2JNeJabLglsxa4iyBENdTLwI2OTmRmxSBlU5mF9xwevOYsJpbr7pWnSpwttT+Jovg==} + '@angular/compiler@22.0.0': + resolution: {integrity: sha512-g8Ab5Lcji2cxADfcPPM7kltEzSlCjUevPK3udm+3S5uhkTcLNH236/XCAwhD1XIgHQDv9p7FWm1xS7zkvbwXhA==} engines: {node: ^22.22.3 || ^24.15.0 || >=26.0.0} - '@angular/core@22.0.0-rc.2': - resolution: {integrity: sha512-6d97Dgh3G6/ZwwEzY6hkl8VsAodRrOvmOtqOnbGBMEG0eCo0uQDcu8oMKm+DdaSmy2+PEXSmdkIARj5Ux1SNFg==} + '@angular/core@22.0.0': + resolution: {integrity: sha512-H4lzunB+LUNylQ3hZGYWDz1NfNAdFzPdOadwuS6VpPyxF4Ti0MLyAfx7NDnyTrmdY2/PFx8I6jXrveNlIsORXg==} engines: {node: ^22.22.3 || ^24.15.0 || >=26.0.0} peerDependencies: - '@angular/compiler': 22.0.0-rc.2 + '@angular/compiler': 22.0.0 rxjs: ^6.5.3 || ^7.4.0 zone.js: ~0.15.0 || ~0.16.0 peerDependenciesMeta: @@ -984,74 +984,74 @@ packages: zone.js: optional: true - '@angular/forms@22.0.0-rc.2': - resolution: {integrity: sha512-eOHVPpmjcoCbIdIonhjH2JH6vv8oFyxTlO4Enf2pAdzjYzFTCfrR+w6zBG8El4SF0G7OVSaJfsqjpNipBqqfag==} + '@angular/forms@22.0.0': + resolution: {integrity: sha512-OjyiF0hgbNXrFbIgqazyNJlFTtqfU0kfwJgmlMr4FG+e9P89UmgZhELUWs1CIuNX+jhh3DePm+Fo26dJIS7cfg==} engines: {node: ^22.22.3 || ^24.15.0 || >=26.0.0} peerDependencies: - '@angular/common': 22.0.0-rc.2 - '@angular/core': 22.0.0-rc.2 - '@angular/platform-browser': 22.0.0-rc.2 + '@angular/common': 22.0.0 + '@angular/core': 22.0.0 + '@angular/platform-browser': 22.0.0 rxjs: ^6.5.3 || ^7.4.0 - '@angular/localize@22.0.0-rc.2': - resolution: {integrity: sha512-fgDjnPyAb/kkU3CTt6I+tTBIQj52w0Pm1KppOCT/WhYy7lPsj3dziRqSgKgoBtDgnYjXJIje6TbOo2ajqHeuIg==} + '@angular/localize@22.0.0': + resolution: {integrity: sha512-K3qGoi3+jGHp+HN2YGMlCaQHDYfF8O+XxvOvAffl1TpoGfzFqEwDv3tHpYmrF99JH5S8NiTBWcdDBZ/BP6E9qQ==} engines: {node: ^22.22.3 || ^24.15.0 || >=26.0.0} hasBin: true peerDependencies: - '@angular/compiler': 22.0.0-rc.2 - '@angular/compiler-cli': 22.0.0-rc.2 + '@angular/compiler': 22.0.0 + '@angular/compiler-cli': 22.0.0 - '@angular/material@22.0.0-rc.2': - resolution: {integrity: sha512-pHs8iMDjyX9o07B2qQqsQ1/n7WgonV2RVVJjxp4c9cralKDufizCpQSCgrkq9fnGu4Ijv7f8ShqHVXLGITMAPg==} + '@angular/material@22.0.0': + resolution: {integrity: sha512-sRxbEEgmaVqbwcT65PWfZV/cIpLsZ8vD+yc6rH83L83jDJWVABpqDWFg8Hl88iFMOts8iffml6GddvXhsNHAEQ==} peerDependencies: - '@angular/cdk': 22.0.0-rc.2 - '@angular/common': ^22.0.0-0 || ^22.1.0-0 || ^22.2.0-0 || ^22.3.0-0 || ^23.0.0-0 - '@angular/core': ^22.0.0-0 || ^22.1.0-0 || ^22.2.0-0 || ^22.3.0-0 || ^23.0.0-0 - '@angular/forms': ^22.0.0-0 || ^22.1.0-0 || ^22.2.0-0 || ^22.3.0-0 || ^23.0.0-0 - '@angular/platform-browser': ^22.0.0-0 || ^22.1.0-0 || ^22.2.0-0 || ^22.3.0-0 || ^23.0.0-0 + '@angular/cdk': 22.0.0 + '@angular/common': ^22.0.0 || ^23.0.0 + '@angular/core': ^22.0.0 || ^23.0.0 + '@angular/forms': ^22.0.0 || ^23.0.0 + '@angular/platform-browser': ^22.0.0 || ^23.0.0 rxjs: ^6.5.3 || ^7.4.0 - '@angular/ng-dev@https://codeload.github.com/angular/dev-infra-private-ng-dev-builds/tar.gz/a450a2420ca888116e6d4207b38819cd27b06179': - resolution: {gitHosted: true, integrity: sha512-yKQqLu4g+2WiIoXV4M7F0x94929zZESjhTj0kTrincYgJ6GrAzfzdeayD5D2ZVg6xUg6ubPEMDDVUwEMeB93Mw==, tarball: https://codeload.github.com/angular/dev-infra-private-ng-dev-builds/tar.gz/a450a2420ca888116e6d4207b38819cd27b06179} - version: 0.0.0-9ee8a680dd018d61d21588bb04cf40d49a9f5deb + '@angular/ng-dev@https://codeload.github.com/angular/dev-infra-private-ng-dev-builds/tar.gz/e882d214a66c8335dc38fe15ebeabeba85a0ea29': + resolution: {gitHosted: true, integrity: sha512-JAec9kjT065fvyeoiFW/iLaTTZ0QTpg6oiMVoV51l0o7HkIWoNIvIOyVk1WELR6Y2vEw0pNMdQQAlYEiQDshMA==, tarball: https://codeload.github.com/angular/dev-infra-private-ng-dev-builds/tar.gz/e882d214a66c8335dc38fe15ebeabeba85a0ea29} + version: 0.0.0-b64a291ca373bc91e5ee876488710c026157bf91 hasBin: true - '@angular/platform-browser@22.0.0-rc.2': - resolution: {integrity: sha512-Y6wrhH7n+b8Jjpfi8KhJlrZZ/o6mPY6VymNtNoB07K5EAPe2omqi7F+gJdoNwgJ2czDgB/L1oLzHwoXSjWheuw==} + '@angular/platform-browser@22.0.0': + resolution: {integrity: sha512-ry4Hdov19V8sA+MrIEIeISXA8GKWluCDUg06PaAm9nJveYjQUUlElZqa3fTNGOmy3/eNV8H9nmaroD27L8yU1A==} engines: {node: ^22.22.3 || ^24.15.0 || >=26.0.0} peerDependencies: - '@angular/animations': 22.0.0-rc.2 - '@angular/common': 22.0.0-rc.2 - '@angular/core': 22.0.0-rc.2 + '@angular/animations': 22.0.0 + '@angular/common': 22.0.0 + '@angular/core': 22.0.0 peerDependenciesMeta: '@angular/animations': optional: true - '@angular/platform-server@22.0.0-rc.2': - resolution: {integrity: sha512-FOor4Q5dPq8y1x/BuR1D5e/dOvz2NgLzZNwkOAfa0DoKOaj96Ia0dJJ3r0ccpDt5REebUC99GLz8bIKJ046JBg==} + '@angular/platform-server@22.0.0': + resolution: {integrity: sha512-ruwVqS0g38/2ATl+iB04/SwL7qAGOT5uEKeXUdeitx+gxE+DOq4MoCc4cr5sq6kS0/XpQ+p1RBnzHxU5XKpJUA==} engines: {node: ^22.22.3 || ^24.15.0 || >=26.0.0} peerDependencies: - '@angular/common': 22.0.0-rc.2 - '@angular/compiler': 22.0.0-rc.2 - '@angular/core': 22.0.0-rc.2 - '@angular/platform-browser': 22.0.0-rc.2 + '@angular/common': 22.0.0 + '@angular/compiler': 22.0.0 + '@angular/core': 22.0.0 + '@angular/platform-browser': 22.0.0 rxjs: ^6.5.3 || ^7.4.0 - '@angular/router@22.0.0-rc.2': - resolution: {integrity: sha512-vdMST+ZUOYjKcEnYIalx8QnVbICriBFp8j9e50mm1DM5kA2Ewdx3oiHanP0yI2826uNjwoVn5nwxDfRCPciJsQ==} + '@angular/router@22.0.0': + resolution: {integrity: sha512-CCtonkDVkkfKLtuKol8rC1zmWI4QX7w3uUtdlOoz6K9HXAhpZYGcSq5RyloA767QLj36u7108K9xHBs2abOajQ==} engines: {node: ^22.22.3 || ^24.15.0 || >=26.0.0} peerDependencies: - '@angular/common': 22.0.0-rc.2 - '@angular/core': 22.0.0-rc.2 - '@angular/platform-browser': 22.0.0-rc.2 + '@angular/common': 22.0.0 + '@angular/core': 22.0.0 + '@angular/platform-browser': 22.0.0 rxjs: ^6.5.3 || ^7.4.0 - '@angular/service-worker@22.0.0-rc.2': - resolution: {integrity: sha512-0FGrFYrMoWC3lhLwELxYN146OLAYD7azkVqa0fWOM7IeYbOvbVgRpxvFu6Ba2LRcwbk5Gs12lXR3M4ZNlC8X/A==} + '@angular/service-worker@22.0.0': + resolution: {integrity: sha512-QpY57hBHh9BI/3L/MxbtYuQ0eZc+ra/7TB6VSLLg9zLA8jbScqWphyB5+Xsyn0u8Z8c3aEA3I+zZgv3r8wlN4g==} engines: {node: ^22.22.3 || ^24.15.0 || >=26.0.0} hasBin: true peerDependencies: - '@angular/core': 22.0.0-rc.2 + '@angular/core': 22.0.0 rxjs: ^6.5.3 || ^7.4.0 '@asamuzakjp/css-color@5.1.11': @@ -4597,9 +4597,9 @@ packages: resolution: {integrity: sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==} engines: {node: '>= 0.8'} - commander@14.0.3: - resolution: {integrity: sha512-H+y0Jo/T1RZ9qPP4Eh1pkcQcLRglraJaSLoyOtHxu6AapkjWVCy2Sit1QQ4x3Dng8qDlSsZEet7g5Pq06MvTgw==} - engines: {node: '>=20'} + commander@15.0.0: + resolution: {integrity: sha512-z67u4ZhzCL/Tydu1lJARtEZYWbWaN7oYLHbsuzocr6y4N6WZAagG3RQ4FW61V1/0+jImpj293XfrcYnd1qxtPg==} + engines: {node: '>=22.12.0'} commander@2.20.3: resolution: {integrity: sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==} @@ -6621,12 +6621,12 @@ packages: neo-async@2.6.2: resolution: {integrity: sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==} - ng-packagr@22.0.0-rc.0: - resolution: {integrity: sha512-5R/axgfRB500l2fhFMVdjqZB2FhEgxHIKIauSsFBFTeJ3XbODKsQZiVya2P8/LTXEQRit1tOkvjYYB9iwlrPZg==} - engines: {node: ^22.22.0 || ^24.13.1 || >=26.0.0} + ng-packagr@22.1.0-next.1: + resolution: {integrity: sha512-EouABEYnyYUW7ovcxgI8QQhXWZKQncKO37914yPy2Z/GNNsZypSBuA0ienrRc3XfkPbsmMF6FuUGninM/+1Ccg==} + engines: {node: ^22.22.3 || ^24.15.0 || >=26.0.0} hasBin: true peerDependencies: - '@angular/compiler-cli': ^22.0.0-next.3 + '@angular/compiler-cli': ^22.0.0 || ^22.0.0-next.0 tailwindcss: ^2.0.0 || ^3.0.0 || ^4.0.0 tslib: ^2.3.0 typescript: '>=6.0 <6.1' @@ -8669,29 +8669,29 @@ snapshots: '@jridgewell/gen-mapping': 0.3.13 '@jridgewell/trace-mapping': 0.3.31 - '@angular/animations@22.0.0-rc.2(@angular/core@22.0.0-rc.2(@angular/compiler@22.0.0-rc.2)(rxjs@7.8.2)(zone.js@0.16.2))': + '@angular/animations@22.0.0(@angular/core@22.0.0(@angular/compiler@22.0.0)(rxjs@7.8.2)(zone.js@0.16.2))': dependencies: - '@angular/core': 22.0.0-rc.2(@angular/compiler@22.0.0-rc.2)(rxjs@7.8.2)(zone.js@0.16.2) + '@angular/core': 22.0.0(@angular/compiler@22.0.0)(rxjs@7.8.2)(zone.js@0.16.2) tslib: 2.8.1 - '@angular/cdk@22.0.0-rc.2(@angular/common@22.0.0-rc.2(@angular/core@22.0.0-rc.2(@angular/compiler@22.0.0-rc.2)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2))(@angular/core@22.0.0-rc.2(@angular/compiler@22.0.0-rc.2)(rxjs@7.8.2)(zone.js@0.16.2))(@angular/platform-browser@22.0.0-rc.2(@angular/animations@22.0.0-rc.2(@angular/core@22.0.0-rc.2(@angular/compiler@22.0.0-rc.2)(rxjs@7.8.2)(zone.js@0.16.2)))(@angular/common@22.0.0-rc.2(@angular/core@22.0.0-rc.2(@angular/compiler@22.0.0-rc.2)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2))(@angular/core@22.0.0-rc.2(@angular/compiler@22.0.0-rc.2)(rxjs@7.8.2)(zone.js@0.16.2)))(rxjs@7.8.2)': + '@angular/cdk@22.0.0(@angular/common@22.0.0(@angular/core@22.0.0(@angular/compiler@22.0.0)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2))(@angular/core@22.0.0(@angular/compiler@22.0.0)(rxjs@7.8.2)(zone.js@0.16.2))(@angular/platform-browser@22.0.0(@angular/animations@22.0.0(@angular/core@22.0.0(@angular/compiler@22.0.0)(rxjs@7.8.2)(zone.js@0.16.2)))(@angular/common@22.0.0(@angular/core@22.0.0(@angular/compiler@22.0.0)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2))(@angular/core@22.0.0(@angular/compiler@22.0.0)(rxjs@7.8.2)(zone.js@0.16.2)))(rxjs@7.8.2)': dependencies: - '@angular/common': 22.0.0-rc.2(@angular/core@22.0.0-rc.2(@angular/compiler@22.0.0-rc.2)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2) - '@angular/core': 22.0.0-rc.2(@angular/compiler@22.0.0-rc.2)(rxjs@7.8.2)(zone.js@0.16.2) - '@angular/platform-browser': 22.0.0-rc.2(@angular/animations@22.0.0-rc.2(@angular/core@22.0.0-rc.2(@angular/compiler@22.0.0-rc.2)(rxjs@7.8.2)(zone.js@0.16.2)))(@angular/common@22.0.0-rc.2(@angular/core@22.0.0-rc.2(@angular/compiler@22.0.0-rc.2)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2))(@angular/core@22.0.0-rc.2(@angular/compiler@22.0.0-rc.2)(rxjs@7.8.2)(zone.js@0.16.2)) + '@angular/common': 22.0.0(@angular/core@22.0.0(@angular/compiler@22.0.0)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2) + '@angular/core': 22.0.0(@angular/compiler@22.0.0)(rxjs@7.8.2)(zone.js@0.16.2) + '@angular/platform-browser': 22.0.0(@angular/animations@22.0.0(@angular/core@22.0.0(@angular/compiler@22.0.0)(rxjs@7.8.2)(zone.js@0.16.2)))(@angular/common@22.0.0(@angular/core@22.0.0(@angular/compiler@22.0.0)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2))(@angular/core@22.0.0(@angular/compiler@22.0.0)(rxjs@7.8.2)(zone.js@0.16.2)) parse5: 8.0.1 rxjs: 7.8.2 tslib: 2.8.1 - '@angular/common@22.0.0-rc.2(@angular/core@22.0.0-rc.2(@angular/compiler@22.0.0-rc.2)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2)': + '@angular/common@22.0.0(@angular/core@22.0.0(@angular/compiler@22.0.0)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2)': dependencies: - '@angular/core': 22.0.0-rc.2(@angular/compiler@22.0.0-rc.2)(rxjs@7.8.2)(zone.js@0.16.2) + '@angular/core': 22.0.0(@angular/compiler@22.0.0)(rxjs@7.8.2)(zone.js@0.16.2) rxjs: 7.8.2 tslib: 2.8.1 - '@angular/compiler-cli@22.0.0-rc.2(@angular/compiler@22.0.0-rc.2)(typescript@6.0.3)': + '@angular/compiler-cli@22.0.0(@angular/compiler@22.0.0)(typescript@6.0.3)': dependencies: - '@angular/compiler': 22.0.0-rc.2 + '@angular/compiler': 22.0.0 '@babel/core': 7.29.0 '@jridgewell/sourcemap-codec': 1.5.5 chokidar: 5.0.0 @@ -8705,32 +8705,32 @@ snapshots: transitivePeerDependencies: - supports-color - '@angular/compiler@22.0.0-rc.2': + '@angular/compiler@22.0.0': dependencies: tslib: 2.8.1 - '@angular/core@22.0.0-rc.2(@angular/compiler@22.0.0-rc.2)(rxjs@7.8.2)(zone.js@0.16.2)': + '@angular/core@22.0.0(@angular/compiler@22.0.0)(rxjs@7.8.2)(zone.js@0.16.2)': dependencies: rxjs: 7.8.2 tslib: 2.8.1 optionalDependencies: - '@angular/compiler': 22.0.0-rc.2 + '@angular/compiler': 22.0.0 zone.js: 0.16.2 - '@angular/forms@22.0.0-rc.2(@angular/common@22.0.0-rc.2(@angular/core@22.0.0-rc.2(@angular/compiler@22.0.0-rc.2)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2))(@angular/core@22.0.0-rc.2(@angular/compiler@22.0.0-rc.2)(rxjs@7.8.2)(zone.js@0.16.2))(@angular/platform-browser@22.0.0-rc.2(@angular/animations@22.0.0-rc.2(@angular/core@22.0.0-rc.2(@angular/compiler@22.0.0-rc.2)(rxjs@7.8.2)(zone.js@0.16.2)))(@angular/common@22.0.0-rc.2(@angular/core@22.0.0-rc.2(@angular/compiler@22.0.0-rc.2)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2))(@angular/core@22.0.0-rc.2(@angular/compiler@22.0.0-rc.2)(rxjs@7.8.2)(zone.js@0.16.2)))(rxjs@7.8.2)': + '@angular/forms@22.0.0(@angular/common@22.0.0(@angular/core@22.0.0(@angular/compiler@22.0.0)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2))(@angular/core@22.0.0(@angular/compiler@22.0.0)(rxjs@7.8.2)(zone.js@0.16.2))(@angular/platform-browser@22.0.0(@angular/animations@22.0.0(@angular/core@22.0.0(@angular/compiler@22.0.0)(rxjs@7.8.2)(zone.js@0.16.2)))(@angular/common@22.0.0(@angular/core@22.0.0(@angular/compiler@22.0.0)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2))(@angular/core@22.0.0(@angular/compiler@22.0.0)(rxjs@7.8.2)(zone.js@0.16.2)))(rxjs@7.8.2)': dependencies: - '@angular/common': 22.0.0-rc.2(@angular/core@22.0.0-rc.2(@angular/compiler@22.0.0-rc.2)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2) - '@angular/core': 22.0.0-rc.2(@angular/compiler@22.0.0-rc.2)(rxjs@7.8.2)(zone.js@0.16.2) - '@angular/platform-browser': 22.0.0-rc.2(@angular/animations@22.0.0-rc.2(@angular/core@22.0.0-rc.2(@angular/compiler@22.0.0-rc.2)(rxjs@7.8.2)(zone.js@0.16.2)))(@angular/common@22.0.0-rc.2(@angular/core@22.0.0-rc.2(@angular/compiler@22.0.0-rc.2)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2))(@angular/core@22.0.0-rc.2(@angular/compiler@22.0.0-rc.2)(rxjs@7.8.2)(zone.js@0.16.2)) + '@angular/common': 22.0.0(@angular/core@22.0.0(@angular/compiler@22.0.0)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2) + '@angular/core': 22.0.0(@angular/compiler@22.0.0)(rxjs@7.8.2)(zone.js@0.16.2) + '@angular/platform-browser': 22.0.0(@angular/animations@22.0.0(@angular/core@22.0.0(@angular/compiler@22.0.0)(rxjs@7.8.2)(zone.js@0.16.2)))(@angular/common@22.0.0(@angular/core@22.0.0(@angular/compiler@22.0.0)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2))(@angular/core@22.0.0(@angular/compiler@22.0.0)(rxjs@7.8.2)(zone.js@0.16.2)) '@standard-schema/spec': 1.1.0 rxjs: 7.8.2 tslib: 2.8.1 zod: 4.4.3 - '@angular/localize@22.0.0-rc.2(@angular/compiler-cli@22.0.0-rc.2(@angular/compiler@22.0.0-rc.2)(typescript@6.0.3))(@angular/compiler@22.0.0-rc.2)': + '@angular/localize@22.0.0(@angular/compiler-cli@22.0.0(@angular/compiler@22.0.0)(typescript@6.0.3))(@angular/compiler@22.0.0)': dependencies: - '@angular/compiler': 22.0.0-rc.2 - '@angular/compiler-cli': 22.0.0-rc.2(@angular/compiler@22.0.0-rc.2)(typescript@6.0.3) + '@angular/compiler': 22.0.0 + '@angular/compiler-cli': 22.0.0(@angular/compiler@22.0.0)(typescript@6.0.3) '@babel/core': 7.29.0 '@types/babel__core': 7.20.5 tinyglobby: 0.2.16 @@ -8738,17 +8738,17 @@ snapshots: transitivePeerDependencies: - supports-color - '@angular/material@22.0.0-rc.2(8f7a4024ad7b6c55fb0a3a6a45a14224)': + '@angular/material@22.0.0(6eb83275f51d1d41f72333b1955c7306)': dependencies: - '@angular/cdk': 22.0.0-rc.2(@angular/common@22.0.0-rc.2(@angular/core@22.0.0-rc.2(@angular/compiler@22.0.0-rc.2)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2))(@angular/core@22.0.0-rc.2(@angular/compiler@22.0.0-rc.2)(rxjs@7.8.2)(zone.js@0.16.2))(@angular/platform-browser@22.0.0-rc.2(@angular/animations@22.0.0-rc.2(@angular/core@22.0.0-rc.2(@angular/compiler@22.0.0-rc.2)(rxjs@7.8.2)(zone.js@0.16.2)))(@angular/common@22.0.0-rc.2(@angular/core@22.0.0-rc.2(@angular/compiler@22.0.0-rc.2)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2))(@angular/core@22.0.0-rc.2(@angular/compiler@22.0.0-rc.2)(rxjs@7.8.2)(zone.js@0.16.2)))(rxjs@7.8.2) - '@angular/common': 22.0.0-rc.2(@angular/core@22.0.0-rc.2(@angular/compiler@22.0.0-rc.2)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2) - '@angular/core': 22.0.0-rc.2(@angular/compiler@22.0.0-rc.2)(rxjs@7.8.2)(zone.js@0.16.2) - '@angular/forms': 22.0.0-rc.2(@angular/common@22.0.0-rc.2(@angular/core@22.0.0-rc.2(@angular/compiler@22.0.0-rc.2)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2))(@angular/core@22.0.0-rc.2(@angular/compiler@22.0.0-rc.2)(rxjs@7.8.2)(zone.js@0.16.2))(@angular/platform-browser@22.0.0-rc.2(@angular/animations@22.0.0-rc.2(@angular/core@22.0.0-rc.2(@angular/compiler@22.0.0-rc.2)(rxjs@7.8.2)(zone.js@0.16.2)))(@angular/common@22.0.0-rc.2(@angular/core@22.0.0-rc.2(@angular/compiler@22.0.0-rc.2)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2))(@angular/core@22.0.0-rc.2(@angular/compiler@22.0.0-rc.2)(rxjs@7.8.2)(zone.js@0.16.2)))(rxjs@7.8.2) - '@angular/platform-browser': 22.0.0-rc.2(@angular/animations@22.0.0-rc.2(@angular/core@22.0.0-rc.2(@angular/compiler@22.0.0-rc.2)(rxjs@7.8.2)(zone.js@0.16.2)))(@angular/common@22.0.0-rc.2(@angular/core@22.0.0-rc.2(@angular/compiler@22.0.0-rc.2)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2))(@angular/core@22.0.0-rc.2(@angular/compiler@22.0.0-rc.2)(rxjs@7.8.2)(zone.js@0.16.2)) + '@angular/cdk': 22.0.0(@angular/common@22.0.0(@angular/core@22.0.0(@angular/compiler@22.0.0)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2))(@angular/core@22.0.0(@angular/compiler@22.0.0)(rxjs@7.8.2)(zone.js@0.16.2))(@angular/platform-browser@22.0.0(@angular/animations@22.0.0(@angular/core@22.0.0(@angular/compiler@22.0.0)(rxjs@7.8.2)(zone.js@0.16.2)))(@angular/common@22.0.0(@angular/core@22.0.0(@angular/compiler@22.0.0)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2))(@angular/core@22.0.0(@angular/compiler@22.0.0)(rxjs@7.8.2)(zone.js@0.16.2)))(rxjs@7.8.2) + '@angular/common': 22.0.0(@angular/core@22.0.0(@angular/compiler@22.0.0)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2) + '@angular/core': 22.0.0(@angular/compiler@22.0.0)(rxjs@7.8.2)(zone.js@0.16.2) + '@angular/forms': 22.0.0(@angular/common@22.0.0(@angular/core@22.0.0(@angular/compiler@22.0.0)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2))(@angular/core@22.0.0(@angular/compiler@22.0.0)(rxjs@7.8.2)(zone.js@0.16.2))(@angular/platform-browser@22.0.0(@angular/animations@22.0.0(@angular/core@22.0.0(@angular/compiler@22.0.0)(rxjs@7.8.2)(zone.js@0.16.2)))(@angular/common@22.0.0(@angular/core@22.0.0(@angular/compiler@22.0.0)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2))(@angular/core@22.0.0(@angular/compiler@22.0.0)(rxjs@7.8.2)(zone.js@0.16.2)))(rxjs@7.8.2) + '@angular/platform-browser': 22.0.0(@angular/animations@22.0.0(@angular/core@22.0.0(@angular/compiler@22.0.0)(rxjs@7.8.2)(zone.js@0.16.2)))(@angular/common@22.0.0(@angular/core@22.0.0(@angular/compiler@22.0.0)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2))(@angular/core@22.0.0(@angular/compiler@22.0.0)(rxjs@7.8.2)(zone.js@0.16.2)) rxjs: 7.8.2 tslib: 2.8.1 - '@angular/ng-dev@https://codeload.github.com/angular/dev-infra-private-ng-dev-builds/tar.gz/a450a2420ca888116e6d4207b38819cd27b06179(@modelcontextprotocol/sdk@1.29.0(zod@4.4.3))': + '@angular/ng-dev@https://codeload.github.com/angular/dev-infra-private-ng-dev-builds/tar.gz/e882d214a66c8335dc38fe15ebeabeba85a0ea29(@modelcontextprotocol/sdk@1.29.0(zod@4.4.3))': dependencies: '@actions/core': 3.0.1 '@conventional-changelog/git-client': 2.7.0(conventional-commits-filter@5.0.0)(conventional-commits-parser@6.4.0) @@ -8808,35 +8808,35 @@ snapshots: - '@modelcontextprotocol/sdk' - '@react-native-async-storage/async-storage' - '@angular/platform-browser@22.0.0-rc.2(@angular/animations@22.0.0-rc.2(@angular/core@22.0.0-rc.2(@angular/compiler@22.0.0-rc.2)(rxjs@7.8.2)(zone.js@0.16.2)))(@angular/common@22.0.0-rc.2(@angular/core@22.0.0-rc.2(@angular/compiler@22.0.0-rc.2)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2))(@angular/core@22.0.0-rc.2(@angular/compiler@22.0.0-rc.2)(rxjs@7.8.2)(zone.js@0.16.2))': + '@angular/platform-browser@22.0.0(@angular/animations@22.0.0(@angular/core@22.0.0(@angular/compiler@22.0.0)(rxjs@7.8.2)(zone.js@0.16.2)))(@angular/common@22.0.0(@angular/core@22.0.0(@angular/compiler@22.0.0)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2))(@angular/core@22.0.0(@angular/compiler@22.0.0)(rxjs@7.8.2)(zone.js@0.16.2))': dependencies: - '@angular/common': 22.0.0-rc.2(@angular/core@22.0.0-rc.2(@angular/compiler@22.0.0-rc.2)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2) - '@angular/core': 22.0.0-rc.2(@angular/compiler@22.0.0-rc.2)(rxjs@7.8.2)(zone.js@0.16.2) + '@angular/common': 22.0.0(@angular/core@22.0.0(@angular/compiler@22.0.0)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2) + '@angular/core': 22.0.0(@angular/compiler@22.0.0)(rxjs@7.8.2)(zone.js@0.16.2) tslib: 2.8.1 optionalDependencies: - '@angular/animations': 22.0.0-rc.2(@angular/core@22.0.0-rc.2(@angular/compiler@22.0.0-rc.2)(rxjs@7.8.2)(zone.js@0.16.2)) + '@angular/animations': 22.0.0(@angular/core@22.0.0(@angular/compiler@22.0.0)(rxjs@7.8.2)(zone.js@0.16.2)) - '@angular/platform-server@22.0.0-rc.2(@angular/common@22.0.0-rc.2(@angular/core@22.0.0-rc.2(@angular/compiler@22.0.0-rc.2)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2))(@angular/compiler@22.0.0-rc.2)(@angular/core@22.0.0-rc.2(@angular/compiler@22.0.0-rc.2)(rxjs@7.8.2)(zone.js@0.16.2))(@angular/platform-browser@22.0.0-rc.2(@angular/animations@22.0.0-rc.2(@angular/core@22.0.0-rc.2(@angular/compiler@22.0.0-rc.2)(rxjs@7.8.2)(zone.js@0.16.2)))(@angular/common@22.0.0-rc.2(@angular/core@22.0.0-rc.2(@angular/compiler@22.0.0-rc.2)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2))(@angular/core@22.0.0-rc.2(@angular/compiler@22.0.0-rc.2)(rxjs@7.8.2)(zone.js@0.16.2)))(rxjs@7.8.2)': + '@angular/platform-server@22.0.0(@angular/common@22.0.0(@angular/core@22.0.0(@angular/compiler@22.0.0)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2))(@angular/compiler@22.0.0)(@angular/core@22.0.0(@angular/compiler@22.0.0)(rxjs@7.8.2)(zone.js@0.16.2))(@angular/platform-browser@22.0.0(@angular/animations@22.0.0(@angular/core@22.0.0(@angular/compiler@22.0.0)(rxjs@7.8.2)(zone.js@0.16.2)))(@angular/common@22.0.0(@angular/core@22.0.0(@angular/compiler@22.0.0)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2))(@angular/core@22.0.0(@angular/compiler@22.0.0)(rxjs@7.8.2)(zone.js@0.16.2)))(rxjs@7.8.2)': dependencies: - '@angular/common': 22.0.0-rc.2(@angular/core@22.0.0-rc.2(@angular/compiler@22.0.0-rc.2)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2) - '@angular/compiler': 22.0.0-rc.2 - '@angular/core': 22.0.0-rc.2(@angular/compiler@22.0.0-rc.2)(rxjs@7.8.2)(zone.js@0.16.2) - '@angular/platform-browser': 22.0.0-rc.2(@angular/animations@22.0.0-rc.2(@angular/core@22.0.0-rc.2(@angular/compiler@22.0.0-rc.2)(rxjs@7.8.2)(zone.js@0.16.2)))(@angular/common@22.0.0-rc.2(@angular/core@22.0.0-rc.2(@angular/compiler@22.0.0-rc.2)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2))(@angular/core@22.0.0-rc.2(@angular/compiler@22.0.0-rc.2)(rxjs@7.8.2)(zone.js@0.16.2)) + '@angular/common': 22.0.0(@angular/core@22.0.0(@angular/compiler@22.0.0)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2) + '@angular/compiler': 22.0.0 + '@angular/core': 22.0.0(@angular/compiler@22.0.0)(rxjs@7.8.2)(zone.js@0.16.2) + '@angular/platform-browser': 22.0.0(@angular/animations@22.0.0(@angular/core@22.0.0(@angular/compiler@22.0.0)(rxjs@7.8.2)(zone.js@0.16.2)))(@angular/common@22.0.0(@angular/core@22.0.0(@angular/compiler@22.0.0)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2))(@angular/core@22.0.0(@angular/compiler@22.0.0)(rxjs@7.8.2)(zone.js@0.16.2)) rxjs: 7.8.2 tslib: 2.8.1 xhr2: 0.2.1 - '@angular/router@22.0.0-rc.2(@angular/common@22.0.0-rc.2(@angular/core@22.0.0-rc.2(@angular/compiler@22.0.0-rc.2)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2))(@angular/core@22.0.0-rc.2(@angular/compiler@22.0.0-rc.2)(rxjs@7.8.2)(zone.js@0.16.2))(@angular/platform-browser@22.0.0-rc.2(@angular/animations@22.0.0-rc.2(@angular/core@22.0.0-rc.2(@angular/compiler@22.0.0-rc.2)(rxjs@7.8.2)(zone.js@0.16.2)))(@angular/common@22.0.0-rc.2(@angular/core@22.0.0-rc.2(@angular/compiler@22.0.0-rc.2)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2))(@angular/core@22.0.0-rc.2(@angular/compiler@22.0.0-rc.2)(rxjs@7.8.2)(zone.js@0.16.2)))(rxjs@7.8.2)': + '@angular/router@22.0.0(@angular/common@22.0.0(@angular/core@22.0.0(@angular/compiler@22.0.0)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2))(@angular/core@22.0.0(@angular/compiler@22.0.0)(rxjs@7.8.2)(zone.js@0.16.2))(@angular/platform-browser@22.0.0(@angular/animations@22.0.0(@angular/core@22.0.0(@angular/compiler@22.0.0)(rxjs@7.8.2)(zone.js@0.16.2)))(@angular/common@22.0.0(@angular/core@22.0.0(@angular/compiler@22.0.0)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2))(@angular/core@22.0.0(@angular/compiler@22.0.0)(rxjs@7.8.2)(zone.js@0.16.2)))(rxjs@7.8.2)': dependencies: - '@angular/common': 22.0.0-rc.2(@angular/core@22.0.0-rc.2(@angular/compiler@22.0.0-rc.2)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2) - '@angular/core': 22.0.0-rc.2(@angular/compiler@22.0.0-rc.2)(rxjs@7.8.2)(zone.js@0.16.2) - '@angular/platform-browser': 22.0.0-rc.2(@angular/animations@22.0.0-rc.2(@angular/core@22.0.0-rc.2(@angular/compiler@22.0.0-rc.2)(rxjs@7.8.2)(zone.js@0.16.2)))(@angular/common@22.0.0-rc.2(@angular/core@22.0.0-rc.2(@angular/compiler@22.0.0-rc.2)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2))(@angular/core@22.0.0-rc.2(@angular/compiler@22.0.0-rc.2)(rxjs@7.8.2)(zone.js@0.16.2)) + '@angular/common': 22.0.0(@angular/core@22.0.0(@angular/compiler@22.0.0)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2) + '@angular/core': 22.0.0(@angular/compiler@22.0.0)(rxjs@7.8.2)(zone.js@0.16.2) + '@angular/platform-browser': 22.0.0(@angular/animations@22.0.0(@angular/core@22.0.0(@angular/compiler@22.0.0)(rxjs@7.8.2)(zone.js@0.16.2)))(@angular/common@22.0.0(@angular/core@22.0.0(@angular/compiler@22.0.0)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2))(@angular/core@22.0.0(@angular/compiler@22.0.0)(rxjs@7.8.2)(zone.js@0.16.2)) rxjs: 7.8.2 tslib: 2.8.1 - '@angular/service-worker@22.0.0-rc.2(@angular/core@22.0.0-rc.2(@angular/compiler@22.0.0-rc.2)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2)': + '@angular/service-worker@22.0.0(@angular/core@22.0.0(@angular/compiler@22.0.0)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2)': dependencies: - '@angular/core': 22.0.0-rc.2(@angular/compiler@22.0.0-rc.2)(rxjs@7.8.2)(zone.js@0.16.2) + '@angular/core': 22.0.0(@angular/compiler@22.0.0)(rxjs@7.8.2)(zone.js@0.16.2) rxjs: 7.8.2 tslib: 2.8.1 @@ -12774,7 +12774,7 @@ snapshots: dependencies: delayed-stream: 1.0.0 - commander@14.0.3: {} + commander@15.0.0: {} commander@2.20.3: {} @@ -15126,16 +15126,16 @@ snapshots: neo-async@2.6.2: {} - ng-packagr@22.0.0-rc.0(@angular/compiler-cli@22.0.0-rc.2(@angular/compiler@22.0.0-rc.2)(typescript@6.0.3))(tslib@2.8.1)(typescript@6.0.3): + ng-packagr@22.1.0-next.1(@angular/compiler-cli@22.0.0(@angular/compiler@22.0.0)(typescript@6.0.3))(tslib@2.8.1)(typescript@6.0.3): dependencies: '@ampproject/remapping': 2.3.0 - '@angular/compiler-cli': 22.0.0-rc.2(@angular/compiler@22.0.0-rc.2)(typescript@6.0.3) + '@angular/compiler-cli': 22.0.0(@angular/compiler@22.0.0)(typescript@6.0.3) '@rollup/plugin-json': 6.1.0(rollup@4.60.4) '@rollup/wasm-node': 4.60.4 ajv: 8.20.0 browserslist: 4.28.2 chokidar: 5.0.0 - commander: 14.0.3 + commander: 15.0.0 dependency-graph: 1.0.0 esbuild: 0.28.0 find-cache-directory: 6.0.0 diff --git a/tests/e2e/ng-snapshot/package.json b/tests/e2e/ng-snapshot/package.json index c4357215a3bd..f59c6f824c43 100644 --- a/tests/e2e/ng-snapshot/package.json +++ b/tests/e2e/ng-snapshot/package.json @@ -2,21 +2,21 @@ "description": "snapshot versions of Angular for e2e testing", "private": true, "dependencies": { - "@angular/animations": "github:angular/animations-builds#4422ba9b6868149351bb0f7570f6985a57bcd0c3", - "@angular/cdk": "github:angular/cdk-builds#f409388d3117cdafced6c9f2cb51b58c2124cf50", - "@angular/common": "github:angular/common-builds#51528cd78a2ad6f2f61fc3d52b1365ae8460b144", - "@angular/compiler": "github:angular/compiler-builds#b7f196f8f28c3be66100a6b94a155329a85a4c51", - "@angular/compiler-cli": "github:angular/compiler-cli-builds#c74e3cb39a6b013a731a3996d50dfdbc96e8e32a", - "@angular/core": "github:angular/core-builds#cd9acb575d72a16ce34e8104de2048fd456e1e94", - "@angular/forms": "github:angular/forms-builds#c7bc5a0abe5485757d8d4b0aa1ec3dc4120e05d6", - "@angular/language-service": "github:angular/language-service-builds#85c4efcc6f8fd6f61bf84118800933fe0d8bdd02", - "@angular/localize": "github:angular/localize-builds#a9161114e9cbf6ca41c86cd8b8efb00435a3d90f", - "@angular/material": "github:angular/material-builds#2a93b9f351b70757969aa2252a059ed41a78cc0c", - "@angular/material-moment-adapter": "github:angular/material-moment-adapter-builds#d5940dda8dbeaeeecf10f08117037e3515591e0f", - "@angular/platform-browser": "github:angular/platform-browser-builds#c4b1ffbe155b4243a9bea3152fc71af8e3ecac68", - "@angular/platform-browser-dynamic": "github:angular/platform-browser-dynamic-builds#19610b4ab8a52c5b6c05cbbfae105c845f2b0964", - "@angular/platform-server": "github:angular/platform-server-builds#dc98a104b7350c69c583a5e2d340e2b9e98e386c", - "@angular/router": "github:angular/router-builds#583c40f7c66349f4fb0f53113ef4a4e67080ebe5", - "@angular/service-worker": "github:angular/service-worker-builds#1fc98db7fa17ec479e72632101083b7a9a34dacd" + "@angular/animations": "github:angular/animations-builds#936f15ea645969dcdd0ca1231b6ad42e15717d43", + "@angular/cdk": "github:angular/cdk-builds#e9f4d9cccbbb97453d691345a5b84551babaae72", + "@angular/common": "github:angular/common-builds#eb84679493b610ff5e080722fa2d17cb225880a5", + "@angular/compiler": "github:angular/compiler-builds#815a9f01619f19086210c9f52de23073b7f0f7d6", + "@angular/compiler-cli": "github:angular/compiler-cli-builds#7243a2ec83b00dbc2cd5d02aa6f88f7b98651fa9", + "@angular/core": "github:angular/core-builds#13b3c6a7b51b632df604447a6ffd471bcc75010a", + "@angular/forms": "github:angular/forms-builds#363c61e2bc92d13405ed1fd3266e74df692b1cca", + "@angular/language-service": "github:angular/language-service-builds#508cdb107e428200a42e2cab64c83dd3ef21b15d", + "@angular/localize": "github:angular/localize-builds#69da74166dbcc5e9d32edd9b39cab4364b7a42fc", + "@angular/material": "github:angular/material-builds#e4845e098d075f57eb240f4a5183f7930076f443", + "@angular/material-moment-adapter": "github:angular/material-moment-adapter-builds#db48bc7e3a1363cb9d53157f865965abd6c03283", + "@angular/platform-browser": "github:angular/platform-browser-builds#6051300fa832bbf114fede3a7aa896c0af0ace4b", + "@angular/platform-browser-dynamic": "github:angular/platform-browser-dynamic-builds#c76c84bcd994e3bc02abe00a50a3f6fa05b1bfeb", + "@angular/platform-server": "github:angular/platform-server-builds#7564dc6fdc115044d6dc2cb4a372158be2e6ceb3", + "@angular/router": "github:angular/router-builds#69dab3fb05b1ca4184667d5c26cd387b74a51352", + "@angular/service-worker": "github:angular/service-worker-builds#3eb7a1b09bf7eb7e02a845673963afe233ab0798" } } From 2d0a1c598c3e8a0d06e8927aab6854343705f305 Mon Sep 17 00:00:00 2001 From: cexbrayat Date: Wed, 3 Jun 2026 10:59:10 +0200 Subject: [PATCH 007/787] fix(@angular/build): allow disabling Vitest isolation from builder Keep the isolate builder option undefined when it is omitted so a Vitest runner config can provide its own value. Previously, ng test --isolate worked because true was forwarded as an override, but ng test --no-isolate was normalized to false and then treated the same as an omitted option. As a result, test.isolate: true in vitest-base.config.ts stayed active. Forward explicit false values to the Vitest project config so --no-isolate can override runnerConfig while the default still aligns with the Karma/Jasmine experience. --- .../build/src/builders/unit-test/options.ts | 2 +- .../unit-test/runners/vitest/plugins.ts | 6 +-- .../unit-test/tests/options/isolate_spec.ts | 54 +++++++++++++++++++ 3 files changed, 58 insertions(+), 4 deletions(-) diff --git a/packages/angular/build/src/builders/unit-test/options.ts b/packages/angular/build/src/builders/unit-test/options.ts index 5cd04c4ca7bf..ef09958885a7 100644 --- a/packages/angular/build/src/builders/unit-test/options.ts +++ b/packages/angular/build/src/builders/unit-test/options.ts @@ -126,7 +126,7 @@ export async function normalizeOptions( watch, debug: options.debug ?? false, ui: process.env['CI'] ? false : ui, - isolate: isolate ?? false, + isolate, quiet: options.quiet ?? (process.env['CI'] ? false : true), providersFile: options.providersFile && path.join(workspaceRoot, options.providersFile), setupFiles: options.setupFiles diff --git a/packages/angular/build/src/builders/unit-test/runners/vitest/plugins.ts b/packages/angular/build/src/builders/unit-test/runners/vitest/plugins.ts index eb3d7d106ab4..c5e3764043bb 100644 --- a/packages/angular/build/src/builders/unit-test/runners/vitest/plugins.ts +++ b/packages/angular/build/src/builders/unit-test/runners/vitest/plugins.ts @@ -54,7 +54,7 @@ interface VitestConfigPluginOptions { include: string[]; optimizeDepsInclude: string[]; watch: boolean; - isolate: boolean; + isolate: boolean | undefined; } async function findTestEnvironment( @@ -268,8 +268,8 @@ export async function createVitestConfigPlugin( include, // CLI provider browser options override, if present ...(browser ? { browser } : {}), - // Only override if the user explicitly enabled it via CLI - ...(options.isolate ? { isolate: true } : {}), + // Only override if the user explicitly set it via CLI + ...(options.isolate !== undefined ? { isolate: options.isolate } : {}), // If the user has not specified an environment, use a smart default. ...(!testConfig?.environment ? { environment: await findTestEnvironment(projectResolver) } diff --git a/packages/angular/build/src/builders/unit-test/tests/options/isolate_spec.ts b/packages/angular/build/src/builders/unit-test/tests/options/isolate_spec.ts index 6ca00a02d94d..a37bf597e91a 100644 --- a/packages/angular/build/src/builders/unit-test/tests/options/isolate_spec.ts +++ b/packages/angular/build/src/builders/unit-test/tests/options/isolate_spec.ts @@ -54,5 +54,59 @@ describeBuilder(execute, UNIT_TEST_BUILDER_INFO, (harness) => { const { result } = await harness.executeOnce(); expect(result?.success).toBeTrue(); }); + + it('should override isolate from the Vitest config file when set to false', async () => { + harness.writeFile( + 'vitest-base.config.ts', + ` + import { defineConfig } from 'vitest/config'; + + export default defineConfig({ + test: { + fileParallelism: false, + isolate: true, + setupFiles: ['./src/setup.ts'], + }, + }); + `, + ); + + harness.writeFile( + 'src/setup.ts', + ` + const global = globalThis as typeof globalThis & { setupCount?: number }; + global.setupCount = (global.setupCount ?? 0) + 1; + `, + ); + + harness.writeFile( + 'src/app/first.spec.ts', + ` + it('runs first', () => { + expect(true).toBe(true); + }); + `, + ); + + harness.writeFile( + 'src/app/second.spec.ts', + ` + it('shares the test environment with the first spec file', () => { + const global = globalThis as typeof globalThis & { setupCount?: number }; + expect(global.setupCount).toBeGreaterThan(1); + }); + `, + ); + + harness.useTarget('test', { + ...BASE_OPTIONS, + runner: 'vitest' as any, + runnerConfig: true, + isolate: false, + }); + + const { result } = await harness.executeOnce(); + expect(result?.success).toBeTrue(); + }); }); }); From 5a1632be2ddb98ef17a66b8868e89c9ddee84321 Mon Sep 17 00:00:00 2001 From: Angular Robot Date: Thu, 4 Jun 2026 06:56:26 +0000 Subject: [PATCH 008/787] build: update all github actions See associated pull request for more information. --- .github/workflows/assistant-to-the-branch-manager.yml | 2 +- .github/workflows/codeql.yml | 6 +++--- .github/workflows/pr.yml | 2 +- .github/workflows/scorecard.yml | 4 ++-- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/.github/workflows/assistant-to-the-branch-manager.yml b/.github/workflows/assistant-to-the-branch-manager.yml index 87519e50b728..eb299f1e8855 100644 --- a/.github/workflows/assistant-to-the-branch-manager.yml +++ b/.github/workflows/assistant-to-the-branch-manager.yml @@ -14,7 +14,7 @@ jobs: runs-on: ubuntu-latest if: github.event.repository.fork == false steps: - - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 with: persist-credentials: false - uses: angular/dev-infra/github-actions/branch-manager@ba726e7bca0b08b125ccc6f93c233749e1213c17 diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml index 6595df14c26d..dd199499e759 100644 --- a/.github/workflows/codeql.yml +++ b/.github/workflows/codeql.yml @@ -19,16 +19,16 @@ jobs: fail-fast: false steps: - name: Checkout repository - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 with: persist-credentials: false - name: Initialize CodeQL - uses: github/codeql-action/init@7211b7c8077ea37d8641b6271f6a365a22a5fbfa # v4.36.0 + uses: github/codeql-action/init@87557b9c84dde89fdd9b10e88954ac2f4248e463 # v4.36.1 with: languages: javascript-typescript build-mode: none config-file: .github/codeql/config.yml - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@7211b7c8077ea37d8641b6271f6a365a22a5fbfa # v4.36.0 + uses: github/codeql-action/analyze@87557b9c84dde89fdd9b10e88954ac2f4248e463 # v4.36.1 with: category: '/language:javascript-typescript' diff --git a/.github/workflows/pr.yml b/.github/workflows/pr.yml index ae107e5c34d6..dd68d34f72e7 100644 --- a/.github/workflows/pr.yml +++ b/.github/workflows/pr.yml @@ -20,7 +20,7 @@ jobs: outputs: snapshots: ${{ steps.filter.outputs.snapshots }} steps: - - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 with: persist-credentials: false - uses: dorny/paths-filter@fbd0ab8f3e69293af611ebaee6363fc25e6d187d # v4.0.1 diff --git a/.github/workflows/scorecard.yml b/.github/workflows/scorecard.yml index fb88be1f8b98..3cf9ef0b1a8d 100644 --- a/.github/workflows/scorecard.yml +++ b/.github/workflows/scorecard.yml @@ -25,7 +25,7 @@ jobs: steps: - name: 'Checkout code' - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 with: persist-credentials: false @@ -46,6 +46,6 @@ jobs: # Upload the results to GitHub's code scanning dashboard. - name: 'Upload to code-scanning' - uses: github/codeql-action/upload-sarif@7211b7c8077ea37d8641b6271f6a365a22a5fbfa # v4.36.0 + uses: github/codeql-action/upload-sarif@87557b9c84dde89fdd9b10e88954ac2f4248e463 # v4.36.1 with: sarif_file: results.sarif From 661d996f656398a65a365db6d258edab5d1af597 Mon Sep 17 00:00:00 2001 From: Angular Robot Date: Wed, 3 Jun 2026 09:02:24 +0000 Subject: [PATCH 009/787] build: update pnpm to v11.5.1 See associated pull request for more information. --- MODULE.bazel | 4 ++-- package.json | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/MODULE.bazel b/MODULE.bazel index d93aac020710..1bb78a1895be 100644 --- a/MODULE.bazel +++ b/MODULE.bazel @@ -131,8 +131,8 @@ use_repo( pnpm = use_extension("@aspect_rules_js//npm:extensions.bzl", "pnpm") pnpm.pnpm( name = "pnpm", - pnpm_version = "11.5.0", - pnpm_version_integrity = "sha512-2/zE+Bz0hZev1Lw5H/3xLBHxqfuDo5W/prCi2cwv2P/rr9scy9UpYyFT95OQTCYVt/Cf4aNFRz/Rw1hFFyqOsQ==", + pnpm_version = "11.5.1", + pnpm_version_integrity = "sha512-k/e1dCLqcGglcjW0wW62B2LraOHcI3IxmcxzkEPqm+LEFDJ0o5nYxt76KxF2Im2cocS2NILWIAwaj7qnjB0UhQ==", ) use_repo(pnpm, "pnpm") diff --git a/package.json b/package.json index 7443df2d3cab..7505feff7fe1 100644 --- a/package.json +++ b/package.json @@ -28,12 +28,12 @@ "type": "git", "url": "git+https://github.com/angular/angular-cli.git" }, - "packageManager": "pnpm@11.5.0", + "packageManager": "pnpm@11.5.1", "engines": { "node": "^22.22.3 || ^24.15.0 || >=26.0.0", "npm": "Please use pnpm instead of NPM to install dependencies", "yarn": "Please use pnpm instead of Yarn to install dependencies", - "pnpm": "11.5.0" + "pnpm": "11.5.1" }, "author": "Angular Authors", "license": "MIT", From 548520462bb4bf5837abeea9e00d75fc41d3d215 Mon Sep 17 00:00:00 2001 From: Angular Robot Date: Thu, 4 Jun 2026 06:56:51 +0000 Subject: [PATCH 010/787] build: update all non-major dependencies See associated pull request for more information. --- modules/testing/builder/package.json | 4 +- package.json | 10 +- packages/angular/build/package.json | 14 +- packages/angular/cli/package.json | 6 +- .../angular_devkit/build_angular/package.json | 2 +- .../schematics_cli/package.json | 2 +- pnpm-lock.yaml | 1435 ++++++++++++----- 7 files changed, 1033 insertions(+), 440 deletions(-) diff --git a/modules/testing/builder/package.json b/modules/testing/builder/package.json index f03f858b009a..5f98e3097d25 100644 --- a/modules/testing/builder/package.json +++ b/modules/testing/builder/package.json @@ -4,12 +4,12 @@ "@angular-devkit/build-angular": "workspace:*", "@angular-devkit/core": "workspace:*", "@angular/ssr": "workspace:*", - "@vitest/coverage-v8": "4.1.7", + "@vitest/coverage-v8": "4.1.8", "browser-sync": "3.0.4", "istanbul-lib-instrument": "6.0.3", "jsdom": "29.1.1", "ng-packagr": "22.1.0-next.1", "rxjs": "7.8.2", - "vitest": "4.1.7" + "vitest": "4.1.8" } } diff --git a/package.json b/package.json index 7505feff7fe1..621217fc8cf8 100644 --- a/package.json +++ b/package.json @@ -70,7 +70,7 @@ "@rollup/plugin-commonjs": "^29.0.0", "@rollup/plugin-json": "^6.1.0", "@rollup/plugin-node-resolve": "16.0.3", - "@rollup/wasm-node": "4.60.4", + "@rollup/wasm-node": "4.61.0", "@stylistic/eslint-plugin": "^5.0.0", "@tony.ganchev/eslint-plugin-header": "~3.4.0", "@types/babel__core": "7.20.5", @@ -95,13 +95,13 @@ "@types/yargs": "^17.0.20", "@types/yargs-parser": "^21.0.0", "@types/yarnpkg__lockfile": "^1.1.5", - "@typescript-eslint/eslint-plugin": "8.60.0", - "@typescript-eslint/parser": "8.60.0", + "@typescript-eslint/eslint-plugin": "8.60.1", + "@typescript-eslint/parser": "8.60.1", "ajv": "8.20.0", "buffer": "6.0.3", "esbuild": "0.28.0", "esbuild-wasm": "0.28.0", - "eslint": "10.4.0", + "eslint": "10.4.1", "eslint-config-prettier": "10.1.8", "eslint-plugin-import": "2.32.0", "express": "5.2.1", @@ -125,7 +125,7 @@ "prettier": "^3.0.0", "puppeteer": "25.1.0", "quicktype-core": "23.2.6", - "rollup": "4.60.4", + "rollup": "4.61.0", "rollup-license-plugin": "~3.2.0", "rollup-plugin-dts": "6.4.1", "rollup-plugin-sourcemaps2": "0.5.7", diff --git a/packages/angular/build/package.json b/packages/angular/build/package.json index 79612fd1fde1..2058061982ef 100644 --- a/packages/angular/build/package.json +++ b/packages/angular/build/package.json @@ -23,7 +23,7 @@ "@babel/core": "7.29.7", "@babel/helper-annotate-as-pure": "7.29.7", "@babel/helper-split-export-declaration": "7.24.7", - "@inquirer/confirm": "6.1.0", + "@inquirer/confirm": "6.1.1", "@vitejs/plugin-basic-ssl": "2.3.0", "beasties": "0.4.2", "browserslist": "^4.26.0", @@ -36,16 +36,16 @@ "parse5-html-rewriting-stream": "8.0.1", "picomatch": "4.0.4", "piscina": "5.1.4", - "rollup": "4.60.4", + "rollup": "4.61.0", "sass": "1.100.0", "semver": "7.8.1", "source-map-support": "0.5.21", - "tinyglobby": "0.2.16", - "vite": "7.3.3", + "tinyglobby": "0.2.17", + "vite": "7.3.5", "watchpack": "2.5.1" }, "optionalDependencies": { - "lmdb": "3.5.4" + "lmdb": "3.5.5" }, "devDependencies": { "@angular-devkit/core": "workspace:*", @@ -55,9 +55,9 @@ "less": "4.6.4", "ng-packagr": "22.1.0-next.1", "postcss": "8.5.15", - "rolldown": "1.0.2", + "rolldown": "1.0.3", "rxjs": "7.8.2", - "vitest": "4.1.7" + "vitest": "4.1.8" }, "peerDependencies": { "@angular/compiler": "0.0.0-ANGULAR-FW-PEER-DEP", diff --git a/packages/angular/cli/package.json b/packages/angular/cli/package.json index 24474d6c9c49..4488b768601b 100644 --- a/packages/angular/cli/package.json +++ b/packages/angular/cli/package.json @@ -15,12 +15,12 @@ "@angular-devkit/architect": "workspace:0.0.0-EXPERIMENTAL-PLACEHOLDER", "@angular-devkit/core": "workspace:0.0.0-PLACEHOLDER", "@angular-devkit/schematics": "workspace:0.0.0-PLACEHOLDER", - "@inquirer/prompts": "8.5.0", - "@listr2/prompt-adapter-inquirer": "4.2.3", + "@inquirer/prompts": "8.5.2", + "@listr2/prompt-adapter-inquirer": "4.2.4", "@modelcontextprotocol/sdk": "1.29.0", "@schematics/angular": "workspace:0.0.0-PLACEHOLDER", "@yarnpkg/lockfile": "1.1.0", - "algoliasearch": "5.52.1", + "algoliasearch": "5.53.0", "ini": "7.0.0", "jsonc-parser": "3.3.1", "listr2": "10.2.1", diff --git a/packages/angular_devkit/build_angular/package.json b/packages/angular_devkit/build_angular/package.json index d1badb54885e..03feae5219d7 100644 --- a/packages/angular_devkit/build_angular/package.json +++ b/packages/angular_devkit/build_angular/package.json @@ -52,7 +52,7 @@ "source-map-loader": "5.0.0", "source-map-support": "0.5.21", "terser": "5.48.0", - "tinyglobby": "0.2.16", + "tinyglobby": "0.2.17", "tslib": "2.8.1", "webpack": "5.107.2", "webpack-dev-middleware": "8.0.3", diff --git a/packages/angular_devkit/schematics_cli/package.json b/packages/angular_devkit/schematics_cli/package.json index a7ecd75f42aa..97ab57c4fce7 100644 --- a/packages/angular_devkit/schematics_cli/package.json +++ b/packages/angular_devkit/schematics_cli/package.json @@ -18,6 +18,6 @@ "dependencies": { "@angular-devkit/core": "workspace:0.0.0-PLACEHOLDER", "@angular-devkit/schematics": "workspace:0.0.0-PLACEHOLDER", - "@inquirer/prompts": "8.5.0" + "@inquirer/prompts": "8.5.2" } } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 496cd47a99eb..1eef8da49336 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -78,34 +78,34 @@ importers: version: 0.28.0 '@eslint/compat': specifier: 2.1.0 - version: 2.1.0(eslint@10.4.0(jiti@2.7.0)) + version: 2.1.0(eslint@10.4.1(jiti@2.7.0)) '@eslint/eslintrc': specifier: 3.3.5 version: 3.3.5 '@eslint/js': specifier: 10.0.1 - version: 10.0.1(eslint@10.4.0(jiti@2.7.0)) + version: 10.0.1(eslint@10.4.1(jiti@2.7.0)) '@rollup/plugin-alias': specifier: ^6.0.0 - version: 6.0.0(rollup@4.60.4) + version: 6.0.0(rollup@4.61.0) '@rollup/plugin-commonjs': specifier: ^29.0.0 - version: 29.0.2(rollup@4.60.4) + version: 29.0.2(rollup@4.61.0) '@rollup/plugin-json': specifier: ^6.1.0 - version: 6.1.0(rollup@4.60.4) + version: 6.1.0(rollup@4.61.0) '@rollup/plugin-node-resolve': specifier: 16.0.3 - version: 16.0.3(rollup@4.60.4) + version: 16.0.3(rollup@4.61.0) '@rollup/wasm-node': - specifier: 4.60.4 - version: 4.60.4 + specifier: 4.61.0 + version: 4.61.0 '@stylistic/eslint-plugin': specifier: ^5.0.0 - version: 5.10.0(eslint@10.4.0(jiti@2.7.0)) + version: 5.10.0(eslint@10.4.1(jiti@2.7.0)) '@tony.ganchev/eslint-plugin-header': specifier: ~3.4.0 - version: 3.4.4(eslint@10.4.0(jiti@2.7.0)) + version: 3.4.4(eslint@10.4.1(jiti@2.7.0)) '@types/babel__core': specifier: 7.20.5 version: 7.20.5 @@ -173,11 +173,11 @@ importers: specifier: ^1.1.5 version: 1.1.9 '@typescript-eslint/eslint-plugin': - specifier: 8.60.0 - version: 8.60.0(@typescript-eslint/parser@8.60.0(eslint@10.4.0(jiti@2.7.0))(typescript@6.0.3))(eslint@10.4.0(jiti@2.7.0))(typescript@6.0.3) + specifier: 8.60.1 + version: 8.60.1(@typescript-eslint/parser@8.60.1(eslint@10.4.1(jiti@2.7.0))(typescript@6.0.3))(eslint@10.4.1(jiti@2.7.0))(typescript@6.0.3) '@typescript-eslint/parser': - specifier: 8.60.0 - version: 8.60.0(eslint@10.4.0(jiti@2.7.0))(typescript@6.0.3) + specifier: 8.60.1 + version: 8.60.1(eslint@10.4.1(jiti@2.7.0))(typescript@6.0.3) ajv: specifier: 8.20.0 version: 8.20.0 @@ -191,14 +191,14 @@ importers: specifier: 0.28.0 version: 0.28.0 eslint: - specifier: 10.4.0 - version: 10.4.0(jiti@2.7.0) + specifier: 10.4.1 + version: 10.4.1(jiti@2.7.0) eslint-config-prettier: specifier: 10.1.8 - version: 10.1.8(eslint@10.4.0(jiti@2.7.0)) + version: 10.1.8(eslint@10.4.1(jiti@2.7.0)) eslint-plugin-import: specifier: 2.32.0 - version: 2.32.0(@typescript-eslint/parser@8.60.0(eslint@10.4.0(jiti@2.7.0))(typescript@6.0.3))(eslint@10.4.0(jiti@2.7.0)) + version: 2.32.0(@typescript-eslint/parser@8.60.1(eslint@10.4.1(jiti@2.7.0))(typescript@6.0.3))(eslint@10.4.1(jiti@2.7.0)) express: specifier: 5.2.1 version: 5.2.1 @@ -263,17 +263,17 @@ importers: specifier: 23.2.6 version: 23.2.6(encoding@0.1.13) rollup: - specifier: 4.60.4 - version: 4.60.4 + specifier: 4.61.0 + version: 4.61.0 rollup-license-plugin: specifier: ~3.2.0 version: 3.2.1 rollup-plugin-dts: specifier: 6.4.1 - version: 6.4.1(rollup@4.60.4)(typescript@6.0.3) + version: 6.4.1(rollup@4.61.0)(typescript@6.0.3) rollup-plugin-sourcemaps2: specifier: 0.5.7 - version: 0.5.7(@types/node@22.19.19)(rollup@4.60.4) + version: 0.5.7(@types/node@22.19.19)(rollup@4.61.0) semver: specifier: 7.8.1 version: 7.8.1 @@ -314,8 +314,8 @@ importers: specifier: workspace:* version: link:../../../packages/angular/ssr '@vitest/coverage-v8': - specifier: 4.1.7 - version: 4.1.7(vitest@4.1.7) + specifier: 4.1.8 + version: 4.1.8(vitest@4.1.8) browser-sync: specifier: 3.0.4 version: 3.0.4(bufferutil@4.1.0)(utf-8-validate@6.0.6) @@ -332,8 +332,8 @@ importers: specifier: 7.8.2 version: 7.8.2 vitest: - specifier: 4.1.7 - version: 4.1.7(@opentelemetry/api@1.9.1)(@types/node@24.12.4)(@vitest/coverage-v8@4.1.7)(jiti@2.7.0)(jsdom@29.1.1)(less@4.6.4)(sass@1.100.0)(terser@5.48.0)(tsx@4.22.3)(yaml@2.9.0) + specifier: 4.1.8 + version: 4.1.8(@opentelemetry/api@1.9.1)(@types/node@24.12.4)(@vitest/coverage-v8@4.1.8)(jiti@2.7.0)(jsdom@29.1.1)(less@4.6.4)(sass@1.100.0)(terser@5.48.0)(tsx@4.22.3)(yaml@2.9.0) packages/angular/build: dependencies: @@ -353,11 +353,11 @@ importers: specifier: 7.24.7 version: 7.24.7 '@inquirer/confirm': - specifier: 6.1.0 - version: 6.1.0(@types/node@24.12.4) + specifier: 6.1.1 + version: 6.1.1(@types/node@24.12.4) '@vitejs/plugin-basic-ssl': specifier: 2.3.0 - version: 2.3.0(vite@7.3.3(@types/node@24.12.4)(jiti@2.7.0)(less@4.6.4)(sass@1.100.0)(terser@5.48.0)(tsx@4.22.3)(yaml@2.9.0)) + version: 2.3.0(vite@7.3.5(@types/node@24.12.4)(jiti@2.7.0)(less@4.6.4)(sass@1.100.0)(terser@5.48.0)(tsx@4.22.3)(yaml@2.9.0)) beasties: specifier: 0.4.2 version: 0.4.2 @@ -392,8 +392,8 @@ importers: specifier: 5.1.4 version: 5.1.4 rollup: - specifier: 4.60.4 - version: 4.60.4 + specifier: 4.61.0 + version: 4.61.0 sass: specifier: 1.100.0 version: 1.100.0 @@ -404,11 +404,11 @@ importers: specifier: 0.5.21 version: 0.5.21 tinyglobby: - specifier: 0.2.16 - version: 0.2.16 + specifier: 0.2.17 + version: 0.2.17 vite: - specifier: 7.3.3 - version: 7.3.3(@types/node@24.12.4)(jiti@2.7.0)(less@4.6.4)(sass@1.100.0)(terser@5.48.0)(tsx@4.22.3)(yaml@2.9.0) + specifier: 7.3.5 + version: 7.3.5(@types/node@24.12.4)(jiti@2.7.0)(less@4.6.4)(sass@1.100.0)(terser@5.48.0)(tsx@4.22.3)(yaml@2.9.0) watchpack: specifier: 2.5.1 version: 2.5.1 @@ -435,18 +435,18 @@ importers: specifier: 8.5.15 version: 8.5.15 rolldown: - specifier: 1.0.2 - version: 1.0.2 + specifier: 1.0.3 + version: 1.0.3 rxjs: specifier: 7.8.2 version: 7.8.2 vitest: - specifier: 4.1.7 - version: 4.1.7(@opentelemetry/api@1.9.1)(@types/node@24.12.4)(@vitest/coverage-v8@4.1.7)(jiti@2.7.0)(jsdom@29.1.1)(less@4.6.4)(sass@1.100.0)(terser@5.48.0)(tsx@4.22.3)(yaml@2.9.0) + specifier: 4.1.8 + version: 4.1.8(@opentelemetry/api@1.9.1)(@types/node@24.12.4)(@vitest/coverage-v8@4.1.8)(jiti@2.7.0)(jsdom@29.1.1)(less@4.6.4)(sass@1.100.0)(terser@5.48.0)(tsx@4.22.3)(yaml@2.9.0) optionalDependencies: lmdb: - specifier: 3.5.4 - version: 3.5.4 + specifier: 3.5.5 + version: 3.5.5 packages/angular/cli: dependencies: @@ -460,11 +460,11 @@ importers: specifier: workspace:0.0.0-PLACEHOLDER version: link:../../angular_devkit/schematics '@inquirer/prompts': - specifier: 8.5.0 - version: 8.5.0(@types/node@24.12.4) + specifier: 8.5.2 + version: 8.5.2(@types/node@24.12.4) '@listr2/prompt-adapter-inquirer': - specifier: 4.2.3 - version: 4.2.3(@inquirer/prompts@8.5.0(@types/node@24.12.4))(@types/node@24.12.4)(listr2@10.2.1) + specifier: 4.2.4 + version: 4.2.4(@inquirer/prompts@8.5.2(@types/node@24.12.4))(@types/node@24.12.4)(listr2@10.2.1) '@modelcontextprotocol/sdk': specifier: 1.29.0 version: 1.29.0(zod@4.4.3) @@ -475,8 +475,8 @@ importers: specifier: 1.1.0 version: 1.1.0 algoliasearch: - specifier: 5.52.1 - version: 5.52.1 + specifier: 5.53.0 + version: 5.53.0 ini: specifier: 7.0.0 version: 7.0.0 @@ -701,8 +701,8 @@ importers: specifier: 5.48.0 version: 5.48.0 tinyglobby: - specifier: 0.2.16 - version: 0.2.16 + specifier: 0.2.17 + version: 0.2.17 tslib: specifier: 2.8.1 version: 2.8.1 @@ -813,8 +813,8 @@ importers: specifier: workspace:0.0.0-PLACEHOLDER version: link:../schematics '@inquirer/prompts': - specifier: 8.5.0 - version: 8.5.0(@types/node@24.12.4) + specifier: 8.5.2 + version: 8.5.2(@types/node@24.12.4) packages/ngtools/webpack: devDependencies: @@ -875,60 +875,60 @@ packages: '@actions/io@3.0.2': resolution: {integrity: sha512-nRBchcMM+QK1pdjO7/idu86rbJI5YHUKCvKs0KxnSYbVe3F51UfGxuZX4Qy/fWlp6l7gWFwIkrOzN+oUK03kfw==} - '@algolia/abtesting@1.18.1': - resolution: {integrity: sha512-aehCadlWOGvrT91KUIZpC0MbB8KBW9yUuvTJFd2xesR7le/IsT4nJUnjCCZ4ZqZCeTcPHPV5mo//fZ5oxcSVYw==} + '@algolia/abtesting@1.19.0': + resolution: {integrity: sha512-Lhnez3hhXHk25lfxLAMxvkP4fmN3+1RgADhD2ssMDBYuAsDVReeyP+3SGRx+ntq8ijMrLqUyfvO72TB6jsTteQ==} engines: {node: '>= 14.0.0'} - '@algolia/client-abtesting@5.52.1': - resolution: {integrity: sha512-HmXOGBOAOJPounpBzBpuY0zDYeiCpxgHnQmuA7JO6ScukcBdGp3/XM9zJk5pJx/xNGD68mbPGXWpDxGtl6BwDQ==} + '@algolia/client-abtesting@5.53.0': + resolution: {integrity: sha512-0ZjA5Hcmaoz5Lj6OG0zhfIyeqzJZnLW2CRJA1W17UwMFGRtZAJ9yJKRvPEDA6gkpsIoQxORTSW6sWFiuYncPNQ==} engines: {node: '>= 14.0.0'} - '@algolia/client-analytics@5.52.1': - resolution: {integrity: sha512-5oo4+I8iixie9vXhCyNFCzeIr8pqA3FQ//VsLHTDvZAV4ttYOPGvYHGQq5NSalrLx5Jc3dRro/5uDOlnUMcBJg==} + '@algolia/client-analytics@5.53.0': + resolution: {integrity: sha512-kWNodP75iiEaOtemC9F/hlxNBG5E2QUjN1BusnE6m2b4l7Qh/BUO3fGCVsmKJI65VO4VKGGmT43ICvHtTcJ2JQ==} engines: {node: '>= 14.0.0'} - '@algolia/client-common@5.52.1': - resolution: {integrity: sha512-qCDoZfx5MpX7XQzvQ3bC4tSEMkQWQMaF/ABtLuoze03Y/flR563CCSws02qIJ23oX7lxl92LsilZjINVyTdtLw==} + '@algolia/client-common@5.53.0': + resolution: {integrity: sha512-YPN45TXD9Wrse185t/Ta7nktZsqpv97oOjCzp2sblHnCL6rBc9TDeJAg1IGl2UpdwnSD05Zu/5wLB4watOUMyg==} engines: {node: '>= 14.0.0'} - '@algolia/client-insights@5.52.1': - resolution: {integrity: sha512-hnGs0/lsFJ2PWDxNBz7pxreXo/Xz7gxYRcfePBUjsH26ad0kU/sgnVZd9LwWBpsQv65z2jlb5dkyaB9WE9M9FQ==} + '@algolia/client-insights@5.53.0': + resolution: {integrity: sha512-qAcYTDJE6m924FDDUQvdD6vh7DYaqOeSpFS74IP37/JRV0v4cGBauyxTF2WzDnokUylQDbqreoFIJZfg0Fitmw==} engines: {node: '>= 14.0.0'} - '@algolia/client-personalization@5.52.1': - resolution: {integrity: sha512-2VxxNc/uBysyKvGeBdSM5n9eIDKH8kWD7wd9/yqbJAiVwU4Yv6tU1LSJusHKrXV/aCu1KW7t9Gug9QyeEmtn/Q==} + '@algolia/client-personalization@5.53.0': + resolution: {integrity: sha512-fQaY+DkSJOpuUVUe8MQTwrdiKAqkJGhpDarB08duBn/sUv7Bkib6MDRQauCcWTWTe4HIW+EbwQP9R4kci1V/Yw==} engines: {node: '>= 14.0.0'} - '@algolia/client-query-suggestions@5.52.1': - resolution: {integrity: sha512-O6mPtsw3xEfNOe6gWFpYLeAZAIljNa4Hgna3bq15PwyN7nbjTY0wXJFRbzs/0YVf75Br+SbOQUmjKxXYjDiSiQ==} + '@algolia/client-query-suggestions@5.53.0': + resolution: {integrity: sha512-o72tsiEZGfeS/dxL9IADfzcZWGEwKDEe5CvtrBuT//3JR+SHuTtHRI2ZTf7D7bcKagcbojvO8hnkHdfoakSlYg==} engines: {node: '>= 14.0.0'} - '@algolia/client-search@5.52.1': - resolution: {integrity: sha512-gA8oJOV1LnQQkDf91iebNnFInHuW0gRPEgLSOQ7EfipCEjYTHm5swm1DlH9H5RaRw4RrHuzHBegnlzc0MAstcg==} + '@algolia/client-search@5.53.0': + resolution: {integrity: sha512-Ds16IyPm/dNJPCU8OzApo2gwGrgWT5BYHhE3NFwZbpCveqyvPDB9sZDDkJ5DsdOGT2aC+R3i0/M1OVXF2qdgPg==} engines: {node: '>= 14.0.0'} - '@algolia/ingestion@1.52.1': - resolution: {integrity: sha512-U9zZfc5xIu9wRxZkt+HceJUAD4VKHKbAyLSloJdEyMRmphXeibfrY9cxqIXBcmPeZzGhn3Imb35Dq8l19PkJhw==} + '@algolia/ingestion@1.53.0': + resolution: {integrity: sha512-oNbT6z4NwD8Pou9VPINGlN/tlG1afESh2EbxqnP6rwl95xKVD/Zlciis1PpNeO/9U/rrajc1+7DcfKi03tX1KQ==} engines: {node: '>= 14.0.0'} - '@algolia/monitoring@1.52.1': - resolution: {integrity: sha512-a3SGNceHmkQfq77iG8Ka+w1pvwfZa/0lzEIgse30fL0kD+yKnd/dg0dQvSfFPAEt2f21DMcGkDSSeJlO3KdQjQ==} + '@algolia/monitoring@1.53.0': + resolution: {integrity: sha512-G+KZb/yd+qAOFn/cEvTGeLxQm8aP3a0od50l3z/ylccY+/o4YG3TNcjU1tFQHW4mXC137GPyR7W70R0kRQDLnA==} engines: {node: '>= 14.0.0'} - '@algolia/recommend@5.52.1': - resolution: {integrity: sha512-z98QEguCFDpxb4S/PyrUK1igqF8tPsdbqOUUO6ON91vJ58w+Gwa6ncrI0oNXSFcrkxA5EqPKPQ2A1PBCn08TYQ==} + '@algolia/recommend@5.53.0': + resolution: {integrity: sha512-6aVfYd55Un6IUgPLbo84WfgFZlS3L0vA1ttzXL5vahHewUJ8jYgd89TzlWRTeej7w70mb9RWsVlFYGmJ/diQww==} engines: {node: '>= 14.0.0'} - '@algolia/requester-browser-xhr@5.52.1': - resolution: {integrity: sha512-CI7+/0I11QeZM59Uc8whd2or0kqzFVjpaPn9Qpwll/krHcBAxk24WkAQ6WX+IwDVMfpont4YGbKwAmCre3vE8Q==} + '@algolia/requester-browser-xhr@5.53.0': + resolution: {integrity: sha512-ke27DqgzCOlt+RbeEdCxtXxMQOnAOi8ujr2wid0DmDKzR95Kw/f9sBsuhBxtjevCqJRJszfRTLY0B1pbO6IhkA==} engines: {node: '>= 14.0.0'} - '@algolia/requester-fetch@5.52.1': - resolution: {integrity: sha512-S6bDuw9byfOvm3T71cgdoZgrgnZq6hpdMLkx52Louh57nUAmvGQESz2aojOynQHjbTiV55smvAFbgn0qT4tJrg==} + '@algolia/requester-fetch@5.53.0': + resolution: {integrity: sha512-GngiOqt2Gq4oLno6yXQVj9om+qSO9SWAoduoTOEg79dKZ62brB8OOIvSJG/vDNoanYi6a7Al9uDZwXvi+bcVTg==} engines: {node: '>= 14.0.0'} - '@algolia/requester-node-http@5.52.1': - resolution: {integrity: sha512-tqZXM+54rWo4mk5jL5Z/flE11nPmNEdXwFBM5py9DkOmbjeCNemfVd45FyM97XdzfZ0dl9uOJC6PYn1FpkeyQg==} + '@algolia/requester-node-http@5.53.0': + resolution: {integrity: sha512-6mF9LZMUk0QqWvrnxkxBqhswwz6Xfiwy6/gmTzL5HrlhdVG3ITAqGV2k3XmVThP1h0Ulc3VQwiNCD7/Nr4JNlQ==} engines: {node: '>= 14.0.0'} '@ampproject/remapping@2.3.0': @@ -2033,8 +2033,8 @@ packages: resolution: {integrity: sha512-vqTaUEgxzm+YDSdElad6PiRoX4t8VGDjCtt05zn4nU810UIx/uNEV7/lZJ6KwFThKZOzOxzXy48da+No7HZaMw==} engines: {node: ^20.19.0 || ^22.13.0 || >=24} - '@eslint/plugin-kit@0.7.1': - resolution: {integrity: sha512-rZAP3aVgB9ds9KOeUSL+zZ21hPmo8dh6fnIFwRQj5EAZl9gzR7wxYbYXYysAM8CTqGmUGyp2S4kUdV17MnGuWQ==} + '@eslint/plugin-kit@0.7.2': + resolution: {integrity: sha512-+CNAzxglkrpNf/kKywqQfk74QjtceuOE7Qm+AF8miRvPF/wmmK5+OJOgVh3AVTT3RP2mH3+FOaxlE5v72owk0A==} engines: {node: ^20.19.0 || ^22.13.0 || >=24} '@exodus/bytes@1.15.1': @@ -2351,6 +2351,10 @@ packages: resolution: {integrity: sha512-I/INw4sHGlVZ/afZOckpLiDP9SmbMl1g/GCqeHjLw1Afw/0PlRs2tRFgTGWmdI0hoNuWZn3y2iHNmG1vyECyQQ==} engines: {node: '>=23.5.0 || ^22.13.0 || ^21.7.0 || ^20.12.0'} + '@inquirer/ansi@2.0.7': + resolution: {integrity: sha512-3eTuUO1vH2cZm2ZKHeQxnOqlTi9EfZDGgIe3BL3I4u+rJHocr9Fz86M4fjYABPvFnQG/gGK551HqDiIcETwU6Q==} + engines: {node: '>=23.5.0 || ^22.13.0 || ^20.17.0'} + '@inquirer/checkbox@5.2.0': resolution: {integrity: sha512-1HJt+3fqxblp/GQjdntSyoSHYBc0e3CzXVgjFpKA6qFLd9FHBBqwN8Co0xYH6t2JVUZrtFwZ4bBiwptkiLxyOg==} engines: {node: '>=23.5.0 || ^22.13.0 || ^21.7.0 || ^20.12.0'} @@ -2360,6 +2364,15 @@ packages: '@types/node': optional: true + '@inquirer/checkbox@5.2.1': + resolution: {integrity: sha512-b6xmA/VlTe0ZgDQHDui+Nav470u7u49nRd8/iuhOcQPO9Ch7lGuogydhi2VOmNlZ+zXcM8IcPuNSwQcdJaF/kw==} + engines: {node: '>=23.5.0 || ^22.13.0 || ^20.17.0'} + peerDependencies: + '@types/node': '>=18' + peerDependenciesMeta: + '@types/node': + optional: true + '@inquirer/confirm@6.1.0': resolution: {integrity: sha512-USpeB76eqK7yGricDlGAupxWlp4a59qpeZOoNWaxO/nJln7agpJveyNkQ1d5u8YXG6TOqxZtQpKPORQQDrdVsA==} engines: {node: '>=23.5.0 || ^22.13.0 || ^21.7.0 || ^20.12.0'} @@ -2369,6 +2382,15 @@ packages: '@types/node': optional: true + '@inquirer/confirm@6.1.1': + resolution: {integrity: sha512-eb8DBZcz/2qHWQda4rk2JiQk5h9QV/cVHi1yjt0f69WFZMRFn0sJTye3EAP8icut8UDMjQPsaH5KbcOogefrFQ==} + engines: {node: '>=23.5.0 || ^22.13.0 || ^20.17.0'} + peerDependencies: + '@types/node': '>=18' + peerDependenciesMeta: + '@types/node': + optional: true + '@inquirer/core@11.2.0': resolution: {integrity: sha512-joR1YS2sI0us+9d0I8ViqFbrRLONO8CFTuyvBX4ZVBSch+VsZiugUABdrhBXXJR1VyEzvpz5SQCix3keETQ58g==} engines: {node: '>=23.5.0 || ^22.13.0 || ^21.7.0 || ^20.12.0'} @@ -2378,6 +2400,15 @@ packages: '@types/node': optional: true + '@inquirer/core@11.2.1': + resolution: {integrity: sha512-Qd6GJT1yVyrZZCfN8W2qKF5ApmqryXRhRKCuip8h01x2w/esJQ2XIYc6f9abMIHgKQdBfFTSOdbHRLAhuM09UA==} + engines: {node: '>=23.5.0 || ^22.13.0 || ^20.17.0'} + peerDependencies: + '@types/node': '>=18' + peerDependenciesMeta: + '@types/node': + optional: true + '@inquirer/editor@5.2.0': resolution: {integrity: sha512-/m+sgRmzSdK6HDtVnl3PmI6MnZC4O+LLezedoJcrX7mINhTjjb0hlC7aEDGZXkFTB4b5uQ0q59AhYTah88KbNg==} engines: {node: '>=23.5.0 || ^22.13.0 || ^21.7.0 || ^20.12.0'} @@ -2387,6 +2418,15 @@ packages: '@types/node': optional: true + '@inquirer/editor@5.2.2': + resolution: {integrity: sha512-ZRVd/oD+sYsUd5zVm0NflqEzlqfYCyHNsqkHl2oWXEUHs12tCbcSFi+wVFEvD8+LGRaMUsVrE7qeo6lSG/S1Vg==} + engines: {node: '>=23.5.0 || ^22.13.0 || ^20.17.0'} + peerDependencies: + '@types/node': '>=18' + peerDependenciesMeta: + '@types/node': + optional: true + '@inquirer/expand@5.1.0': resolution: {integrity: sha512-fR7g4BVnIcs+4NApF6C5byflNM/EULxSxsv/2Jvg+gmop0R6eBIPvZqE6RYnTy1tQTFnf9wyHkwNoQSZbofaGA==} engines: {node: '>=23.5.0 || ^22.13.0 || ^21.7.0 || ^20.12.0'} @@ -2396,6 +2436,15 @@ packages: '@types/node': optional: true + '@inquirer/expand@5.1.1': + resolution: {integrity: sha512-YmQpenjbFSHAK3sOd44puHh3V1KXXr+JiNpUztoSQ4drLh2rTVzTap/YtlAVu/5xavifIlBfNEzJ/neZJ1a/1g==} + engines: {node: '>=23.5.0 || ^22.13.0 || ^20.17.0'} + peerDependencies: + '@types/node': '>=18' + peerDependenciesMeta: + '@types/node': + optional: true + '@inquirer/external-editor@3.0.1': resolution: {integrity: sha512-tam+Gwjsxg2sx3iUVPkAnhKT/yrk2rd2NAa7XJU/J8OYpU0ifXsnp12xlvzp/DCpWBXVv+vLQsqnpAWwUcWD5Q==} engines: {node: '>=23.5.0 || ^22.13.0 || ^21.7.0 || ^20.12.0'} @@ -2405,10 +2454,23 @@ packages: '@types/node': optional: true + '@inquirer/external-editor@3.0.3': + resolution: {integrity: sha512-6thf5I8q7lZwzGLAxPaaGEREEkZ3nyePPDQ1oyobblxmEE8mqTLguScP7pDjUTAibiyb4hfXl+qjUEJ+di/aNA==} + engines: {node: '>=23.5.0 || ^22.13.0 || ^20.17.0'} + peerDependencies: + '@types/node': '>=18' + peerDependenciesMeta: + '@types/node': + optional: true + '@inquirer/figures@2.0.6': resolution: {integrity: sha512-dsZgQtH2t5Q6ah3aPbZbeEZAxsD9qQu0DXf01AltuEfRTm+NoLN6+rLVbr+4edeEbNCp/wBNM6mALRWtsQpfkw==} engines: {node: '>=23.5.0 || ^22.13.0 || ^21.7.0 || ^20.12.0'} + '@inquirer/figures@2.0.7': + resolution: {integrity: sha512-aJ8TBPOGB6f/2qziPfElISTCEd5XOYTFckA2SGjhNmiKzfK/u4ot3v0DUzGVdUnKjN10EqnnEPck36BkyfLnJw==} + engines: {node: '>=23.5.0 || ^22.13.0 || ^20.17.0'} + '@inquirer/input@5.1.0': resolution: {integrity: sha512-sVZCz6P6e8tW5g2bSFel1oLpa6jK/u7BexFfrgTqR8syIdnHqy+iopnlSbYBZMsCK52chLjhGNBxt0eRqhsghw==} engines: {node: '>=23.5.0 || ^22.13.0 || ^21.7.0 || ^20.12.0'} @@ -2418,6 +2480,15 @@ packages: '@types/node': optional: true + '@inquirer/input@5.1.2': + resolution: {integrity: sha512-9K/DDBSQpOyZSkt6sOVP9Vo0TR7atX2kuILsUu0x3wVcVbe97lJwIJKMLdMw25tDYuXl/qp6erT0Xs1rfmcfZg==} + engines: {node: '>=23.5.0 || ^22.13.0 || ^20.17.0'} + peerDependencies: + '@types/node': '>=18' + peerDependenciesMeta: + '@types/node': + optional: true + '@inquirer/number@4.1.0': resolution: {integrity: sha512-VMXB/XejCbaSTf9Xucl7dqjzzsaGsrs6XwSYXPbGZ2QbSuq/Gz8XamhSi9ClRubNXZlGry9xVg1tKkJdTDgCtQ==} engines: {node: '>=23.5.0 || ^22.13.0 || ^21.7.0 || ^20.12.0'} @@ -2427,6 +2498,15 @@ packages: '@types/node': optional: true + '@inquirer/number@4.1.1': + resolution: {integrity: sha512-XF4IXAbPnGPgw0wsbC/i2tPcyfdZgDpUlhsqU0SfT4IRIGWha6Xm9VRgN5yYxJq+jnyXlfXI/nQ3ulfk0iEICA==} + engines: {node: '>=23.5.0 || ^22.13.0 || ^20.17.0'} + peerDependencies: + '@types/node': '>=18' + peerDependenciesMeta: + '@types/node': + optional: true + '@inquirer/password@5.1.0': resolution: {integrity: sha512-5tqRuKCDIUxdPxTI/CuLnh914kz+WMPmURHKnZgui9gk43ebudEsdu4EwSn1CPSi5R+17YpBG+ba/YqTnRAcJA==} engines: {node: '>=23.5.0 || ^22.13.0 || ^21.7.0 || ^20.12.0'} @@ -2436,6 +2516,15 @@ packages: '@types/node': optional: true + '@inquirer/password@5.1.1': + resolution: {integrity: sha512-3XBfF7DAsp5qeDsvN5Rd1HmbNokVvEQoUM0QLrRcybC9nX96w3Pbmu7qUsb3IT3J3jBvs2+mTXaKHOUsgHMLzg==} + engines: {node: '>=23.5.0 || ^22.13.0 || ^20.17.0'} + peerDependencies: + '@types/node': '>=18' + peerDependenciesMeta: + '@types/node': + optional: true + '@inquirer/prompts@8.4.3': resolution: {integrity: sha512-ai5LseTw9HhegupIgmo4cn7RpnCGznjjXu4OI+7jMR8vu7T1ZCCNMzFFAovUCjL1fl0cceksIN1++yQE59SmZw==} engines: {node: '>=23.5.0 || ^22.13.0 || ^21.7.0 || ^20.12.0'} @@ -2445,9 +2534,9 @@ packages: '@types/node': optional: true - '@inquirer/prompts@8.5.0': - resolution: {integrity: sha512-pLjXOnY4y3R1mgyHP3pXD/8eXejp+L/dde/0N2NLKgKfMstqhNZrpvs7Wkzbl9FYFQh10LRQ7QZwq+cz9rrhyw==} - engines: {node: '>=23.5.0 || ^22.13.0 || ^21.7.0 || ^20.12.0'} + '@inquirer/prompts@8.5.2': + resolution: {integrity: sha512-IYR/3C/paEVVQYQvdDlFZVjRCJVYHHON0XXMH91KO9GSxs0TdKYWlUdvfQl2EfAHDxUaN3IBffkE/BDTh5nJ6g==} + engines: {node: '>=23.5.0 || ^22.13.0 || ^20.17.0'} peerDependencies: '@types/node': '>=18' peerDependenciesMeta: @@ -2463,6 +2552,15 @@ packages: '@types/node': optional: true + '@inquirer/rawlist@5.3.1': + resolution: {integrity: sha512-QqdTqQddL3qPX/PPrjobpsO25NZ4dWXgTLenrR445L2ptLEYE6Z+PD5c5CNDJNx4ugRgELAIpSIJxZaO2jJ2Og==} + engines: {node: '>=23.5.0 || ^22.13.0 || ^20.17.0'} + peerDependencies: + '@types/node': '>=18' + peerDependenciesMeta: + '@types/node': + optional: true + '@inquirer/search@4.2.0': resolution: {integrity: sha512-ByURoSGIaSl5O5Q0AmYmVmUsXbMUcBGNoA3FRL7TOyiA22IeFHymJKRkuILbOIlJwqnBk7AnPpseodyFUBzg+g==} engines: {node: '>=23.5.0 || ^22.13.0 || ^21.7.0 || ^20.12.0'} @@ -2472,6 +2570,15 @@ packages: '@types/node': optional: true + '@inquirer/search@4.2.1': + resolution: {integrity: sha512-xJj8QWKRSrfKoBIITLZK61dD3zwo0Rz11fgDImku30/Oe81zMdIdGgrLY2h6RkJ+KZ/GhNYIRMKnH/62qBTA5g==} + engines: {node: '>=23.5.0 || ^22.13.0 || ^20.17.0'} + peerDependencies: + '@types/node': '>=18' + peerDependenciesMeta: + '@types/node': + optional: true + '@inquirer/select@5.2.0': resolution: {integrity: sha512-6IzkcmEbEXfgVbxZ2d1UyJFbCBoc6dTofulFmrYuomIp88HXiVqRbqbg4/mbfZhvnNo6xYmnYo2AEmDof6fQkg==} engines: {node: '>=23.5.0 || ^22.13.0 || ^21.7.0 || ^20.12.0'} @@ -2481,6 +2588,15 @@ packages: '@types/node': optional: true + '@inquirer/select@5.2.1': + resolution: {integrity: sha512-FlDndEUww8m7BfukO2nJa25vhD+H5jxxCv4oGioKqzyWz3nPHhhw4LKdYRSlXuAx7DsdWia7iyaBPKKS95Evfw==} + engines: {node: '>=23.5.0 || ^22.13.0 || ^20.17.0'} + peerDependencies: + '@types/node': '>=18' + peerDependenciesMeta: + '@types/node': + optional: true + '@inquirer/type@4.0.5': resolution: {integrity: sha512-aetVUNeKNc/VriqXlw1NRSW0zhMBB0W4bNbWRJgzRl/3d0QNDQFfk0GO5SDdtjMZVg6o8ZKEiadd7SCCzoOn5Q==} engines: {node: '>=23.5.0 || ^22.13.0 || ^21.7.0 || ^20.12.0'} @@ -2499,6 +2615,15 @@ packages: '@types/node': optional: true + '@inquirer/type@4.0.7': + resolution: {integrity: sha512-t28inv14nMQ1PhKpsJPY+kEs/c00qzeCOS2gTNRyTjG5d6qsVA2fItxW4hkvGZ5lvanGLdtCzVIx5dwdRpN1+g==} + engines: {node: '>=23.5.0 || ^22.13.0 || ^20.17.0'} + peerDependencies: + '@types/node': '>=18' + peerDependenciesMeta: + '@types/node': + optional: true + '@isaacs/cliui@8.0.2': resolution: {integrity: sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==} engines: {node: '>=12'} @@ -2659,45 +2784,45 @@ packages: '@leichtgewicht/ip-codec@2.0.5': resolution: {integrity: sha512-Vo+PSpZG2/fmgmiNzYK9qWRh8h/CHrwD0mo1h1DzL4yzHNSfWYujGTYsWGreD000gcgmZ7K4Ys6Tx9TxtsKdDw==} - '@listr2/prompt-adapter-inquirer@4.2.3': - resolution: {integrity: sha512-Co9U3AJ3LW0J8XBHjVoNKA79dMAyFt8EZH3OaKTMcDTj8r+6kG3vSUPq/eGLHT7P0iK3uLaFfhdFYd3033P24g==} + '@listr2/prompt-adapter-inquirer@4.2.4': + resolution: {integrity: sha512-/KRI2DMD7JGSYaREF0Ygl7AefJ/2ase4Gc5cBiKqT5l4tFjsSJfhFGcc5nSkgl0Sp9LkCQNzl/cqbVJYP2L3dw==} engines: {node: '>=22.13.0'} peerDependencies: '@inquirer/prompts': '>= 3 < 9' listr2: 10.2.1 - '@lmdb/lmdb-darwin-arm64@3.5.4': - resolution: {integrity: sha512-Kk4Kz3iyu1QiLsLZBS9Af1eSKUC8VR2T+/jyE2iAyuGw2VwK08pp5iTbZnXn6sWu0LogO/RFktMxOjiDA2sS3w==} + '@lmdb/lmdb-darwin-arm64@3.5.5': + resolution: {integrity: sha512-hcSIUgSblRtwEuPzV/88cTbEPxaWfxVSrTaMIVUreyAA02ysE3S9tsiQdmT7KNmUaXlwgRGs+x+GaVDCuk7Prg==} cpu: [arm64] os: [darwin] - '@lmdb/lmdb-darwin-x64@3.5.4': - resolution: {integrity: sha512-BEe5Rp3trn26oxoXOVL5HVDoiYmjUDwr8NRPkBOdUdCSBEorKI+7JrZLRKAdxO+G6cGQLgseXk0gR7qIQa7aGw==} + '@lmdb/lmdb-darwin-x64@3.5.5': + resolution: {integrity: sha512-cLlp9ypk3W9Hr4fuTYwg1kL2vPfz887v9NXiHQE1raSKtJ8/hnghekqUu62wUQdQPgThLV8Om+Ran08wWuM/3w==} cpu: [x64] os: [darwin] - '@lmdb/lmdb-linux-arm64@3.5.4': - resolution: {integrity: sha512-cUXEengO8o60v1SWerJTH4/RH4U3+9jC0/4njp2Z9NdmvaGzhKsbRM2wpXuRYrN8tytsoJCg0SvWEWwHAwLbCA==} + '@lmdb/lmdb-linux-arm64@3.5.5': + resolution: {integrity: sha512-tn8KSYdvX5sietpuGyJJSXocvQQtWlenzquap/Mzr+wWx5jrjK5I3nEAIMFxvTtuMMrpPTGHGNuE/Hanh3o0EQ==} cpu: [arm64] os: [linux] - '@lmdb/lmdb-linux-arm@3.5.4': - resolution: {integrity: sha512-SGbFR7816uBcTHc2ZY4S6WyOkl9bICnzqTQd2Mv4V/j24cfds88xx2nC6cm/y8zGQL7Ds31YF/5NGxjgcdM5Hw==} + '@lmdb/lmdb-linux-arm@3.5.5': + resolution: {integrity: sha512-eDeK9vZww0dIXlRCZa7pvbEXSUpUNIJKUs13FxDzazL8CRLDLggbeirm5m0hZvJcRgZzTYGESE8UUEBqHcdZ9Q==} cpu: [arm] os: [linux] - '@lmdb/lmdb-linux-x64@3.5.4': - resolution: {integrity: sha512-Gxq8jpgOWXwd0PUR+c9R2Ik1/uBnGd5GMIIzRRDqABCkvmjtC3KWcyhesV9jSPCz759isl0NlbsstZ2oyvk8lA==} + '@lmdb/lmdb-linux-x64@3.5.5': + resolution: {integrity: sha512-o6VRcJjZ6Zc67MnymLEa3AtbYSreFzm6Um6LMHh4lkynlE5Qk/XUHXU2beTZBdB3QuZBiMoXO2gjPSgP0tYUKg==} cpu: [x64] os: [linux] - '@lmdb/lmdb-win32-arm64@3.5.4': - resolution: {integrity: sha512-pKv1DJ1bPZAaHkdFsSz5IDfUG8x9vntgquXF9/Dm2xuupcIe/EkLzylpoBxppFVK5vzbV561Dq26jNY2fIMA7g==} + '@lmdb/lmdb-win32-arm64@3.5.5': + resolution: {integrity: sha512-k0k/CwywhymTAJT7Uj5PdehH31Vem2ov/Jp0rn5McuJEHgzj7vbE0cmnByhjrQv+VeHLALI8wUZNicqwocPB4Q==} cpu: [arm64] os: [win32] - '@lmdb/lmdb-win32-x64@3.5.4': - resolution: {integrity: sha512-JF1BmLCm9kGEVZgYmJq43zeQVdHVgAJnTi/NURWEsy6L1ZrrlSmdltS+D17QN4LODwf+1LMXAA9auIZVXtWwzw==} + '@lmdb/lmdb-win32-x64@3.5.5': + resolution: {integrity: sha512-dkV3r04ro8MfhBaPj4ZsARy0LIP3sK+rm2LAuVe2QLCepBIpSzRx8p8RLWfRfkKV5YNyJ3c0NUJxGNMqtTB6Fg==} cpu: [x64] os: [win32] @@ -3025,8 +3150,8 @@ packages: resolution: {integrity: sha512-/UhIkaZgPutTFmQ7RnIJGgDXZmtEJ7Dvi86xNTFWcnRxVRNk/aotsqDJYeEvDP+FSMB2SdW+pQzNMcWP0rwuNA==} engines: {node: '>=14'} - '@oxc-project/types@0.132.0': - resolution: {integrity: sha512-FESMOxil5Se014ui/Eq8fT5uHJo6nIRwH0PfJrZJXs6Gek3ZVFOrpUv3YIZT20m+extU98Hg1Ym72U58rlsxUQ==} + '@oxc-project/types@0.133.0': + resolution: {integrity: sha512-KzkdCd6Uxqnf6l3HOw1xfatAlUURA0g14cvBYFyJ5SaNOQbOUvBr9PKArcPcrNIeRsBdgcUzOGrhKveVpvOIGA==} '@parcel/watcher-android-arm64@2.5.6': resolution: {integrity: sha512-YQxSS34tPF/6ZG7r/Ih9xy+kP/WwediEUsqmtf0cuCV5TPPKw/PQHRhueUo6JdeFJaqV3pyjm0GdYjZotbRt/A==} @@ -3220,97 +3345,97 @@ packages: proxy-agent: optional: true - '@rolldown/binding-android-arm64@1.0.2': - resolution: {integrity: sha512-ZS4D1JPGn/MYQN/SYDWftIE/nVsM8j/AFOYEzAoOE2O3NktQOZru+/vYXGbR/qtdLdIfGCP0lcoJiYVzsEz+iQ==} + '@rolldown/binding-android-arm64@1.0.3': + resolution: {integrity: sha512-454rs7jHngixp/NMxd5srYD57OnzSlZ/eFTETjORQHLwJG1lRtmNOJcBerZlfu4GjKqeq8aCCIQrMdHyhI51Hw==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [android] - '@rolldown/binding-darwin-arm64@1.0.2': - resolution: {integrity: sha512-vdFA9+C/rekyGce7WqHs/xoT0ioZEWaOFyZLIV1mEeNFaFDUQrPIo8Vs2GvJ6eetb3rzDUtUBgzto3ExpXJB3w==} + '@rolldown/binding-darwin-arm64@1.0.3': + resolution: {integrity: sha512-PcAhP+ynjURNyy8SKGl5DQP94aGuB/7JrXJb/t7P+hanXvQVMWzUvRRhBAcg/lNRadBhoUPqSoP4xw5tR/KBEA==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [darwin] - '@rolldown/binding-darwin-x64@1.0.2': - resolution: {integrity: sha512-BewSOwTHazv77DTYiAZXSqqKZ4KP/KonFisDMVU7PImxoWfB2aepnPhd2E4SWz3zDzYgDNbs6jBmTdgNnF02GA==} + '@rolldown/binding-darwin-x64@1.0.3': + resolution: {integrity: sha512-9YpfeUvSE2RS7wysJ81uOZkXJz7f7Q55H2Gvp3VEw/EsahqDtrphrZ0EwDLK5vvKOzaCrBsjF8JmnMLcUt78Gg==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [darwin] - '@rolldown/binding-freebsd-x64@1.0.2': - resolution: {integrity: sha512-m41o7M0YWtUdqk61Tb+jnKb2rN++iRdIASlExkUoKfIAH30DOHCB8fVLzSUpbWHHU8esmEioY62PxzexE8MBuA==} + '@rolldown/binding-freebsd-x64@1.0.3': + resolution: {integrity: sha512-yB1IlAsSNHncV6SCTL27/MVGR5htvQsoGxIv5KMGXALp+Ll1wYsn+x98M9MW7qa+NdSbvrrY7ANI4wLJ0n1e6g==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [freebsd] - '@rolldown/binding-linux-arm-gnueabihf@1.0.2': - resolution: {integrity: sha512-jcojB9H7W/jS29pMKWAK1N+fU99vXodHDTatS3b3y/XSOCiHo0kkA74pL3jJmkoQtYpOCxDvaKs1fo2Ij/1X5w==} + '@rolldown/binding-linux-arm-gnueabihf@1.0.3': + resolution: {integrity: sha512-Yi30IVAAfLUCy2MseFjbB1jAMDl1VMCAas5StnYp8da9+CKvMd2H2cbEjWcw5NPaPqzvYkVIaF1nNUG+b7u/sw==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm] os: [linux] - '@rolldown/binding-linux-arm64-gnu@1.0.2': - resolution: {integrity: sha512-1jn6qDU5iiOgFgygDzKUuKP0maTi0/f1+sBLgvij/76C77Nm3ts6ufz9Bjg5q5dduxiUIxtq86JIoBvo1xQ4Ig==} + '@rolldown/binding-linux-arm64-gnu@1.0.3': + resolution: {integrity: sha512-jsO7R8To+AdlYgUmN5sHSCZbfhtMBkO0WUx8iORQnPcMMdgr7qM2DQmMwgabs3GhNztdmoKkMKQFHD6DTMCIQw==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [linux] libc: [glibc] - '@rolldown/binding-linux-arm64-musl@1.0.2': - resolution: {integrity: sha512-QVLO/czFMdoMFSqlX3bcswcJNm/23r+qoa/jgtmFc/qEp6/jXmIkDjF/XIo8dPfGaiwy1xfQn8o77L79GeXFgw==} + '@rolldown/binding-linux-arm64-musl@1.0.3': + resolution: {integrity: sha512-VWkUHwWriDciit80wleYwKILoR/KMvxh/IdwS/paX+ZgpuRpCrKLUdadJbc0NpBEiyhpYawsJ73j9aCvOH+f7Q==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [linux] libc: [musl] - '@rolldown/binding-linux-ppc64-gnu@1.0.2': - resolution: {integrity: sha512-hgO5Abm0w5UL6FEa2iFnZqo2KlK7TQ5QhV5x09hujBf7t5KzHQ1VmfPuTpqRy/rNlSxua3eWH374xxiVrP+lcA==} + '@rolldown/binding-linux-ppc64-gnu@1.0.3': + resolution: {integrity: sha512-5f1laC0SlIR0yDbFCd8acUhvJIag6N3zC5P7oUPN6wX0aOma+uKJ0wBDH5aq7I1PVI2ttTlhJwzwRIBnLiSGEg==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [ppc64] os: [linux] libc: [glibc] - '@rolldown/binding-linux-s390x-gnu@1.0.2': - resolution: {integrity: sha512-fy8rXxuYEu602abC8MUNaPjYLIFzReOaEIEMKMUa0rFEUxNpVXhs15KSSQ4qlqSaM7B6rcj9rDZgADh/IGDzLQ==} + '@rolldown/binding-linux-s390x-gnu@1.0.3': + resolution: {integrity: sha512-Iq4ko0r4XsgbrF/LunNgHtAGLRRVE2kXonAXQ/MV0mC6jQpMOhW1SvtZja2EhC/kd05++bP78dsqBeIQyYJ6Yg==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [s390x] os: [linux] libc: [glibc] - '@rolldown/binding-linux-x64-gnu@1.0.2': - resolution: {integrity: sha512-0+bOkiQ779+r1WpoHOWHqncvyySci0vKph+myNDYb+im6meJAzHQXay6oEgnkHuUGouM1LKTZwqKpBow6Kj7CQ==} + '@rolldown/binding-linux-x64-gnu@1.0.3': + resolution: {integrity: sha512-B8m6tD5+/N5FeNQFbKlLA/2yVq9ycQP1SeedyEYYKWBNR3ZQbkvIUcNnDNM03lO1l5F2roiiFJGgvoLLyZXtSg==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [linux] libc: [glibc] - '@rolldown/binding-linux-x64-musl@1.0.2': - resolution: {integrity: sha512-mjSkrzZK5Qsl0a9d1JgILOiuZOSDTVdKENcSXBoqbzSrspLR/4/IRVDo5wd2GgZjNss/viBFJdeq+j7qH2nypw==} + '@rolldown/binding-linux-x64-musl@1.0.3': + resolution: {integrity: sha512-pSdpdUJHkuCxun9LE7jvgUB9qsRgaiyNNCX7m/AvHTcq67AiT/Yhoxvw5zPfhrM8k/BfP8ce/hMOpthKDpEUow==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [linux] libc: [musl] - '@rolldown/binding-openharmony-arm64@1.0.2': - resolution: {integrity: sha512-1v5vHasdfQAZoEHakBV72LIFAC9JjnymsiKxp+GEr/ma3+NJCPSaYK+qavInOovJkgwFrs7GccX2d6IgDA3Z5w==} + '@rolldown/binding-openharmony-arm64@1.0.3': + resolution: {integrity: sha512-OXXS3RKJgX2uLwM+gYyuH5omcH8fL1LJs96pZGgtetVCahON57+d4SJHzTgZiOjxgGkSnpXpOsWuPDGAKAigEg==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [openharmony] - '@rolldown/binding-wasm32-wasi@1.0.2': - resolution: {integrity: sha512-mb1VobWn6NheziTk5/WEaR6AKVbrwT5sOi6C7zk3gy/pD1qtJfU1j4PgTo2NJnOtbL9Dl3Aeei8w9jJ7qC2jZQ==} + '@rolldown/binding-wasm32-wasi@1.0.3': + resolution: {integrity: sha512-JTtb8BWFynicNSoPrehsCzBtOKjZ6jhMiPFEmOiuXg1Fl8dn2KHQob+GuPSGR0dryQa1PQJbzjF3dqO/whhjLg==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [wasm32] - '@rolldown/binding-win32-arm64-msvc@1.0.2': - resolution: {integrity: sha512-SqKonF56vA/L2yHwHYcEp2P34URpOZ7d1fS635cTkpDnUtEGdUbhI6NzsPdqeSWvAAeGDrxjWjNmibDIdFf9/A==} + '@rolldown/binding-win32-arm64-msvc@1.0.3': + resolution: {integrity: sha512-gEdFFEN70A/jxb2svrWsN3aDL7OUtmvlOy+6fa2jxG8K0wQ1ZbdeLGnidov6Yu5/733dI5ySfzFlQ/cb0bSz1g==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [win32] - '@rolldown/binding-win32-x64-msvc@1.0.2': - resolution: {integrity: sha512-v7qRI7gXLRINcOGXt+7YmAZ6iFuyZVMIoXAxhd8oP+DR9dLfL9GfNIx7PLMxmhZdvq8waUJBQiWN9EKNy+TRBQ==} + '@rolldown/binding-win32-x64-msvc@1.0.3': + resolution: {integrity: sha512-eXB7CHuaQdqmJcc3koCNtNPmT/bj2gc999kUFgBxG8Ac0NdgXc4rkCHhqrgrhN3zddvvvrgzj1e90SuSfmyIXA==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [win32] @@ -3368,144 +3493,287 @@ packages: cpu: [arm] os: [android] + '@rollup/rollup-android-arm-eabi@4.61.0': + resolution: {integrity: sha512-dnxczajOqt0gesZlN5pGQ1s1imQVrsmCw5G2Ci4oM+0WvNz3pyRnlWrT7McoZIb8VlFwCawdmbWRmxRn7HI+VQ==} + cpu: [arm] + os: [android] + '@rollup/rollup-android-arm64@4.60.4': resolution: {integrity: sha512-GxxTKApUpzRhof7poWvCJHRF51C67u1R7D6DiluBE8wKU1u5GWE8t+v81JvJYtbawoBFX1hLv5Ei4eVjkWokaw==} cpu: [arm64] os: [android] + '@rollup/rollup-android-arm64@4.61.0': + resolution: {integrity: sha512-Bp3JpGP00Vu3f238ivRrjf7z3xSzVPXqCmaJYA9t2c+c8vKYvOzmXF7LkkeUalTEGd6cZcSWe+PFIP3Vy48fRg==} + cpu: [arm64] + os: [android] + '@rollup/rollup-darwin-arm64@4.60.4': resolution: {integrity: sha512-tua0TaJxMOB1R0V0RS1jFZ/RpURFDJIOR2A6jWwQeawuFyS4gBW+rntLRaQd0EQ4bd6Vp44Z2rXW+YYDBsj6IA==} cpu: [arm64] os: [darwin] + '@rollup/rollup-darwin-arm64@4.61.0': + resolution: {integrity: sha512-zaYIpr670mUmmZ1tVzUFplbQbG7h3Gugx3L5FoqhsC2m/YnLlR1a7zVLmXNPy+iY1tFPEbNG+HHBXZGyId0G5w==} + cpu: [arm64] + os: [darwin] + '@rollup/rollup-darwin-x64@4.60.4': resolution: {integrity: sha512-CSKq7MsP+5PFIcydhAiR1K0UhEI1A2jWXVKHPCBZ151yOutENwvnPocgVHkivu2kviURtCEB6zUQw0vs8RrhMg==} cpu: [x64] os: [darwin] + '@rollup/rollup-darwin-x64@4.61.0': + resolution: {integrity: sha512-+P49fvkv2dSoeevUW+lgZ/I2JHSsJCK1Lyjj7Cu6E4UHG4tS9XIefzIjo5qhgELjAclnen1rLzK2PMKJdo+Dyg==} + cpu: [x64] + os: [darwin] + '@rollup/rollup-freebsd-arm64@4.60.4': resolution: {integrity: sha512-+O8OkVdyvXMtJEciu2wS/pzm1IxntEEQx3z5TAVy4l32G0etZn+RsA48ARRrFm6Ri8fvqPQfgrvNxSjKAbnd3g==} cpu: [arm64] os: [freebsd] + '@rollup/rollup-freebsd-arm64@4.61.0': + resolution: {integrity: sha512-l3FAAOyKJXH2ea6KNFN+MMgC/rnE94YGLXs2ehYqDcCoHt1DpvgWX75BhUJxN38XojP7Ul+4H8PRn7EdyqSDrw==} + cpu: [arm64] + os: [freebsd] + '@rollup/rollup-freebsd-x64@4.60.4': resolution: {integrity: sha512-Iw3oMskH3AfNuhU0MSN7vNbdi4me/NiYo2azqPz/Le16zHSa+3RRmliCMWWQmh4lcndccU40xcJuTYJZxNo/lw==} cpu: [x64] os: [freebsd] + '@rollup/rollup-freebsd-x64@4.61.0': + resolution: {integrity: sha512-VokPN3TSctKj65cyCNPaUh4vMFA8awxOot/0sp+4J7ZlNRKQEhXhawqPwajoi8H5ZFt61i0ugZJuTKXBjGJ17Q==} + cpu: [x64] + os: [freebsd] + '@rollup/rollup-linux-arm-gnueabihf@4.60.4': resolution: {integrity: sha512-EIPRXTVQpHyF8WOo219AD2yEltPehLTcTMz2fn6JsatLYSzQf00hj3rulF+yauOlF9/FtM2WpkT/hJh/KJFGhA==} cpu: [arm] os: [linux] libc: [glibc] + '@rollup/rollup-linux-arm-gnueabihf@4.61.0': + resolution: {integrity: sha512-DxH0P3wxm+Yzs/p3zrk9dw1rURu8p0Nv5+MRK/L7OtnLNg5rLZraSBFZ8iUXOd9f2BlhJyEpIZUH/emjq4UJ4g==} + cpu: [arm] + os: [linux] + libc: [glibc] + '@rollup/rollup-linux-arm-musleabihf@4.60.4': resolution: {integrity: sha512-J3Yh9PzzF1Ovah2At+lHiGQdsYgArxBbXv/zHfSyaiFQEqvNv7DcW98pCrmdjCZBrqBiKrKKe2V+aaSGWuBe/w==} cpu: [arm] os: [linux] libc: [musl] + '@rollup/rollup-linux-arm-musleabihf@4.61.0': + resolution: {integrity: sha512-T6ZvMNe84kAz6TBWHC7hGAoEtzP1LWYw/AqayGWEF6uISt3Abk/st06LqRD9THd7Xz3NxzurUpzAuEAUbZf+nw==} + cpu: [arm] + os: [linux] + libc: [musl] + '@rollup/rollup-linux-arm64-gnu@4.60.4': resolution: {integrity: sha512-BFDEZMYfUvLn37ONE1yMBojPxnMlTFsdyNoqncT0qFq1mAfllL+ATMMJd8TeuVMiX84s1KbcxcZbXInmcO2mRg==} cpu: [arm64] os: [linux] libc: [glibc] + '@rollup/rollup-linux-arm64-gnu@4.61.0': + resolution: {integrity: sha512-q/4hzvQkDs8b4jIBab1pnLiiM0ayTZsN2amBFPDzuyZxjEd4wDwx0UJFYM3cOZzSf5Kw8fnWSprJzIBMkcR44Q==} + cpu: [arm64] + os: [linux] + libc: [glibc] + '@rollup/rollup-linux-arm64-musl@4.60.4': resolution: {integrity: sha512-pc9EYOSlOgdQ2uPl1o9PF6/kLSgaUosia7gOuS8mB69IxJvlclko1MECXysjs5ryez1/5zjYqx3+xYU0TU6R1A==} cpu: [arm64] os: [linux] libc: [musl] + '@rollup/rollup-linux-arm64-musl@4.61.0': + resolution: {integrity: sha512-vvYWX3akdEAY6km+9wAqFDnk6pQsbJKVnj7xawcvs/+fdlYBGp+U+Qq/lLfpIxYIZvZLHMAKD9HLdacSx/r3dw==} + cpu: [arm64] + os: [linux] + libc: [musl] + '@rollup/rollup-linux-loong64-gnu@4.60.4': resolution: {integrity: sha512-NxnomyxYerDh5n4iLrNa+sH+Z+U4BMEE46V2PgQ/hoB909i8gV1M5wPojWg9fk1jWpO3IQnOs20K4wyZuFLEFQ==} cpu: [loong64] os: [linux] libc: [glibc] + '@rollup/rollup-linux-loong64-gnu@4.61.0': + resolution: {integrity: sha512-DePa5cqOxDP/Zp0VOXpeWaGew5iIv5DXp9NYbzkX5PFQyWVX9184WCTh3hvr/7lhXo8ZVlbFLkz8+o/q1dU6gA==} + cpu: [loong64] + os: [linux] + libc: [glibc] + '@rollup/rollup-linux-loong64-musl@4.60.4': resolution: {integrity: sha512-nbJnQ8a3z1mtmrwImCYhc6BGpThAyYVRQxw9uKSKG4wR6aAYno9sVjJ0zaZcW9BPJX1GbrDPf+SvdWjgTuDmnw==} cpu: [loong64] os: [linux] libc: [musl] + '@rollup/rollup-linux-loong64-musl@4.61.0': + resolution: {integrity: sha512-LV8aWMB8UChglMCEzs7RkN0GsH29RJaLLqwm9fCIjlqwxQTiWAqNcc7wjBkH31hV0PU/yVxGYvrYsgfea2qw6g==} + cpu: [loong64] + os: [linux] + libc: [musl] + '@rollup/rollup-linux-ppc64-gnu@4.60.4': resolution: {integrity: sha512-2EU6acNrQLd8tYvo/LXW535wupT3m6fo7HKo6lr7ktQoItxTyOL1ZCR/GfGCuXl2vR+zmfI6eRXkSemafv+iVg==} cpu: [ppc64] os: [linux] libc: [glibc] + '@rollup/rollup-linux-ppc64-gnu@4.61.0': + resolution: {integrity: sha512-QoNSnwQtaeNu5grdBbsL0tt1uyl5EnS8DA8Mr3nluMXbhdQNyhN+G4tBax7VCdxLKj8YJ0/4OO9Ho84jMnJtKA==} + cpu: [ppc64] + os: [linux] + libc: [glibc] + '@rollup/rollup-linux-ppc64-musl@4.60.4': resolution: {integrity: sha512-WeBtoMuaMxiiIrO2IYP3xs6GMWkJP2C0EoT8beTLkUPmzV1i/UcOSVw1d5r9KBODtHKilG5yFxsGRnBbK3wJ4A==} cpu: [ppc64] os: [linux] libc: [musl] + '@rollup/rollup-linux-ppc64-musl@4.61.0': + resolution: {integrity: sha512-/zZp5MKapIIApE8trN8qLGNSiRN9TUoaUZ1cmVu4XnVdd5LQLOXTtyi+vtfUbNnT3iyjzpPqYeKXmvJ+gJGYWw==} + cpu: [ppc64] + os: [linux] + libc: [musl] + '@rollup/rollup-linux-riscv64-gnu@4.60.4': resolution: {integrity: sha512-FJHFfqpKUI3A10WrWKiFbBZ7yVbGT4q4B5o1qKFFojqpaYoh9LrQgqWCmmcxQzVSXYtyB5bzkXrYzlHTs21MYA==} cpu: [riscv64] os: [linux] libc: [glibc] + '@rollup/rollup-linux-riscv64-gnu@4.61.0': + resolution: {integrity: sha512-RbrzcD3aJ1k3UbtMRRBNwojdVVyXjuVAFTfn/xPa6EEl6GE9Sm/akPgFTb9aAC9pMKGJ6CtWxaGrqWcabH+ySg==} + cpu: [riscv64] + os: [linux] + libc: [glibc] + '@rollup/rollup-linux-riscv64-musl@4.60.4': resolution: {integrity: sha512-mcEl6CUT5IAUmQf1m9FYSmVqCJlpQ8r8eyftFUHG8i9OhY7BkBXSUdnLH5DOf0wCOjcP9v/QO93zpmF1SptCCw==} cpu: [riscv64] os: [linux] libc: [musl] + '@rollup/rollup-linux-riscv64-musl@4.61.0': + resolution: {integrity: sha512-ZF+onDsBso8PJf1XaG9lB+O9RnBpKGnY6OrzC4CSHrtC1jb6jWLTKK4bRqdoCXHd22gyr2hiYmEAm8Wns/BOCw==} + cpu: [riscv64] + os: [linux] + libc: [musl] + '@rollup/rollup-linux-s390x-gnu@4.60.4': resolution: {integrity: sha512-ynt3JxVd2w2buzoKDWIyiV1pJW93xlQic1THVLXilz429oijRpSHivZAgp65KBu+cMcgf1eVVjdnTLvPxgCuoQ==} cpu: [s390x] os: [linux] libc: [glibc] + '@rollup/rollup-linux-s390x-gnu@4.61.0': + resolution: {integrity: sha512-Atk0aSIk5Zx2Wuh9dgRQgLP0Koc8hOeYpbWryMXyk8G8/HmPkwPPkMqIIDhrXHHYqfUzSJA/I7IWSBv8xSmRBA==} + cpu: [s390x] + os: [linux] + libc: [glibc] + '@rollup/rollup-linux-x64-gnu@4.60.4': resolution: {integrity: sha512-Boiz5+MsaROEWDf+GGEwF8VMHGhlUoQMtIPjOgA5fv4osupqTVnJteQNKJwUcnUog2G55jYXH7KZFFiJe0TEzQ==} cpu: [x64] os: [linux] libc: [glibc] + '@rollup/rollup-linux-x64-gnu@4.61.0': + resolution: {integrity: sha512-0uMOcf3eZ5K+K4cYHkdxShFMPlPXCOdfDFEFn9dNYAEEd2cVvmOfH7zFgRVoDgmtQ1m9k5q7qfrHzyMAubKYUA==} + cpu: [x64] + os: [linux] + libc: [glibc] + '@rollup/rollup-linux-x64-musl@4.60.4': resolution: {integrity: sha512-+qfSY27qIrFfI/Hom04KYFw3GKZSGU4lXus51wsb5EuySfFlWRwjkKWoE9emgRw/ukoT4Udsj4W/+xxG8VbPKg==} cpu: [x64] os: [linux] libc: [musl] + '@rollup/rollup-linux-x64-musl@4.61.0': + resolution: {integrity: sha512-mvFtE4A/t/7hRJ7X8Ozmu8FsIkAUat2nzl12pgU337BRmq87AQUJztwHz2Zv5/tjo9/C95E66CK03SI/ToEDJw==} + cpu: [x64] + os: [linux] + libc: [musl] + '@rollup/rollup-openbsd-x64@4.60.4': resolution: {integrity: sha512-VpTfOPHgVXEBeeR8hZ2O0F3aSso+JDWqTWmTmzcQKted54IAdUVbxE+j/MVxUsKa8L20HJhv3vUezVPoquqWjA==} cpu: [x64] os: [openbsd] + '@rollup/rollup-openbsd-x64@4.61.0': + resolution: {integrity: sha512-z9b9+aTxvt8n2rNltMPvyaUfB8NJ+CVyOrGK/MdIKHx7B+lXmZpm/XbRsU7Rpf3fRqJ2uS6mBJiJveCtq8LHDg==} + cpu: [x64] + os: [openbsd] + '@rollup/rollup-openharmony-arm64@4.60.4': resolution: {integrity: sha512-IPOsh5aRYuLv/nkU51X10Bf75Bsf6+gZdx1X+QP5QM6lIJFHHqbHLG0uJn/hWthzo13UAc2umiUorqZy3axoZg==} cpu: [arm64] os: [openharmony] + '@rollup/rollup-openharmony-arm64@4.61.0': + resolution: {integrity: sha512-jXaXFqKMehsOc+g8R6oo33RRC6w07G9jDBxAE5eAKX7mOcCbZloYIPNhfG9Wl+P9O9IWHFO4OJgPi1Ml2qkt7w==} + cpu: [arm64] + os: [openharmony] + '@rollup/rollup-win32-arm64-msvc@4.60.4': resolution: {integrity: sha512-4QzE9E81OohJ/HKzHhsqU+zcYYojVOXlFMs1DdyMT6qXl/niOH7AVElmmEdUNHHS/oRkc++d5k6Vy85zFs0DEw==} cpu: [arm64] os: [win32] + '@rollup/rollup-win32-arm64-msvc@4.61.0': + resolution: {integrity: sha512-OXNWVFocS2IA4+QplhTZZ2a+8hPZR7T8KuozsNmJKK8y7cp83StHvGksfHzPG3wczWTczyWHVQuqeiTUbjiyBg==} + cpu: [arm64] + os: [win32] + '@rollup/rollup-win32-ia32-msvc@4.60.4': resolution: {integrity: sha512-zTPgT1YuHHcd+Tmx7h8aml0FWFVelV5N54oHow9SLj+GfoDy/huQ+UV396N/C7KpMDMiPspRktzM1/0r1usYEA==} cpu: [ia32] os: [win32] + '@rollup/rollup-win32-ia32-msvc@4.61.0': + resolution: {integrity: sha512-AlAbNtBO637LxSldqV43z0FfXoGfl2TW1DgAg/bs7aQswFbDewz2SJm3BUhiGfbOVtW571xbc9p+REdxhyN/Eg==} + cpu: [ia32] + os: [win32] + '@rollup/rollup-win32-x64-gnu@4.60.4': resolution: {integrity: sha512-DRS4G7mi9lJxqEDezIkKCaUIKCrLUUDCUaCsTPCi/rtqaC6D/jjwslMQyiDU50Ka0JKpeXeRBFBAXwArY52vBw==} cpu: [x64] os: [win32] + '@rollup/rollup-win32-x64-gnu@4.61.0': + resolution: {integrity: sha512-QRSrQXyJ1M4tjNXdR0/G/IgV6lzfQQJYBjlWIEYkY2Xs86DRl/iEpQ4blMDjJxSl7n19eDKKXMg0AmuBVYy8pQ==} + cpu: [x64] + os: [win32] + '@rollup/rollup-win32-x64-msvc@4.60.4': resolution: {integrity: sha512-QVTUovf40zgTqlFVrKA1uXMVvU2QWEFWfAH8Wdc48IxLvrJMQVMBRjuQyUpzZCDkakImib9eVazbWlC6ksWtJw==} cpu: [x64] os: [win32] + '@rollup/rollup-win32-x64-msvc@4.61.0': + resolution: {integrity: sha512-tkuFxhvKO/HlGd0VsINF6vHSYH8AF8W0TcNxKDK6JZmrehngFj78pToc8iemtnvwilDjs2G/qSzYFhe9U8q+fw==} + cpu: [x64] + os: [win32] + '@rollup/wasm-node@4.60.4': resolution: {integrity: sha512-j6qaRjdDujJ5utX5l6+8eiWlvMLmBfPMBht8mHP2au3xuzf+4deu6PuCquH5GvDIvIOsWHZhA1UVz/s0FvvgAA==} engines: {node: '>=18.0.0', npm: '>=8.0.0'} hasBin: true + '@rollup/wasm-node@4.61.0': + resolution: {integrity: sha512-UpYM5v/7Quee4u+VWHuNSgSlvIEQMQL7T/jEaOuaNJQ+JJcqSVvcqN6s1cLiDH5DuJMWRqJzvaCnyexp/UGftQ==} + engines: {node: '>=18.0.0', npm: '>=8.0.0'} + hasBin: true + '@rtsao/scc@1.1.0': resolution: {integrity: sha512-zt6OdqaDoOnJ1ZYsCYGt9YmWzDXl4vQdKTyJev62gFhRGKdx7mcT54V9KIjg+d2wi9EXsPvAPKe7i7WjfVWB8g==} @@ -3793,39 +4061,39 @@ packages: '@types/yarnpkg__lockfile@1.1.9': resolution: {integrity: sha512-GD4Fk15UoP5NLCNor51YdfL9MSdldKCqOC9EssrRw3HVfar9wUZ5y8Lfnp+qVD6hIinLr8ygklDYnmlnlQo12Q==} - '@typescript-eslint/eslint-plugin@8.60.0': - resolution: {integrity: sha512-QYb/sa74/s7OKMbACMjrYnGspj9Hs5YI5aaffSL65UfeBUzVzBJfVo3oWSpbzPurvm7yaCCo2Lk7lVj610HqKw==} + '@typescript-eslint/eslint-plugin@8.60.1': + resolution: {integrity: sha512-JQ4S5GB0tfjO8BuJ4fcX+HodkzJjYBV+7OJ+wLygaX7OGQ7FudyHL4NSCA6ob+w3Yn+5MkKIozOwQhXeM7opVg==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: - '@typescript-eslint/parser': ^8.60.0 + '@typescript-eslint/parser': ^8.60.1 eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 typescript: '>=4.8.4 <6.1.0' - '@typescript-eslint/parser@8.60.0': - resolution: {integrity: sha512-fcqpj/MyK4sxDPcbe7STNPbpQL4RLZOPWuaTmwZYuc+hJKzRf58yRxfhqGpc6PIq9ZyfSBpfHgmUHmHs0KwHwg==} + '@typescript-eslint/parser@8.60.1': + resolution: {integrity: sha512-A0M6ua6H252bVjPvvtSgl2QA4+ET9S5Mtkb2GDyTxIhH/C4qDItT7RQNO5PhMC6NXGYXOR9dIalcDDgBKT7oFA==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 typescript: '>=4.8.4 <6.1.0' - '@typescript-eslint/project-service@8.60.0': - resolution: {integrity: sha512-aZu74NNKJeUWqCjDddzdiKaS82dgYgV/vmf+Ui3ZdZejmgfXR/q+pRumgobnQ2cCJTgGTWp4ypiwsuofFubavg==} + '@typescript-eslint/project-service@8.60.1': + resolution: {integrity: sha512-eXkTH2bxmXlqD1RnOPmLZ9ZM9D3VwSx04JOwBnP9RQ+yUA5a2Mu7SfW8uaV2Aon53NJzZlZYuX7tn91Izf+xaw==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: typescript: '>=4.8.4 <6.1.0' - '@typescript-eslint/scope-manager@8.60.0': - resolution: {integrity: sha512-pFzqhllJMs+jghLQWzV00ds39xLzuyqPSev5pd8f4Ir0rtKR3ZLUB4/4dhjOFighWb9larvtfJvqL+4yKDI3Xw==} + '@typescript-eslint/scope-manager@8.60.1': + resolution: {integrity: sha512-gvI5OQoptnxQnchOirukCuQ55svJSTuD/4k5+pC267xyBtYry748R9/c3tYUzb/iE6RZfllRz2lVulLCHkTm4w==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@typescript-eslint/tsconfig-utils@8.60.0': - resolution: {integrity: sha512-BZPR3RGYlAXnly6ymAxfkVn5rCbZzQNou0rxv3GfWZ8cTQp+hhVd73khbGLAd8k1TlAPLISH337M+tAgAnaJDQ==} + '@typescript-eslint/tsconfig-utils@8.60.1': + resolution: {integrity: sha512-nh8w4qAteiKuZu3pSSzG/yGKpw0OlkrKnzFmbVRenKaD4qc+7i1GrmZaLVkr8rk4uipiPGMOW4YsM6WmKZ5CvA==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: typescript: '>=4.8.4 <6.1.0' - '@typescript-eslint/type-utils@8.60.0': - resolution: {integrity: sha512-SX46wEUtitCpq7AN38HkUU/+zvUpdKf7ephtWAFgckH8O7PQIyL5gvrhQgBLuEYgLfuKWOVvWVskMbuFHAz5xg==} + '@typescript-eslint/type-utils@8.60.1': + resolution: {integrity: sha512-sdwTrpjosW7ANQYJ39ZBF1ZyEMEGVB2UsikrserVM/30a/F1dTLnu9bGxEdosugyu5caigjLrR2qiD11asjI1A==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 @@ -3835,21 +4103,25 @@ packages: resolution: {integrity: sha512-AsE7x2XaAK+CVbeih0Fvbn+r1qHxtpLDJ3XUuFcIinT318T90yHMJC+Zgv+jUuDjQQd06HKwxnDu6sz1IcTilA==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@typescript-eslint/typescript-estree@8.60.0': - resolution: {integrity: sha512-3AcZNBGMClm6CXDyo8kYvVGT/sx29sS0oBsIb9oZI2gunA4Vm2M3YHzRLPvsUBBsl+yB5FPtltq7gGH0iTlp9g==} + '@typescript-eslint/types@8.60.1': + resolution: {integrity: sha512-4h0tY8ppCkdCzcrl2YM5M3my0xsE1Tf8om3owEu5oPWmXwkKRmk0j0LGDzYBGUcAlesEbxBhazqu/K4cu3Ug7w==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@typescript-eslint/typescript-estree@8.60.1': + resolution: {integrity: sha512-alpRkfG8hlVE5kdJW2GkfgDgXxold3e8e4l6EnmhRmRLbekgAPCCGDVD++sABy9FcgPFroq+uFcCSM1vR57Cew==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: typescript: '>=4.8.4 <6.1.0' - '@typescript-eslint/utils@8.60.0': - resolution: {integrity: sha512-HtXuPfrHTyBDkameWpl+vJb1Uevu2tznAyahM1Oc4AENidCLTPiZDWIo4GfcxNdC/RcfGcadzzkqbRG87dUrQA==} + '@typescript-eslint/utils@8.60.1': + resolution: {integrity: sha512-h2MPBLoNtjc3qZWfY3Tl51yPorQ2McHn8pJfcMNTcIvrrZrr90Ykffit0yjrPFWQcRcUxzH20+6OcVdW4yHtUg==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 typescript: '>=4.8.4 <6.1.0' - '@typescript-eslint/visitor-keys@8.60.0': - resolution: {integrity: sha512-9WI52t8ZGLVGrPMBet25yAftqY/n95+zmoUUtJBBQTKDSKUu7OsPTroT2op7U9JatkoRccL0YkWDNMFfC4Sjxg==} + '@typescript-eslint/visitor-keys@8.60.1': + resolution: {integrity: sha512-EbGRQg4FhrmwLodl+t3JNAnXHWVr9Vp+Zl1QBZVPY4ByfkzIT8cX3K6QWODHtkIZqqJVEWvhHSx3v5PDHsaQag==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} '@verdaccio/auth@8.0.2': @@ -3933,20 +4205,20 @@ packages: peerDependencies: vite: ^6.0.0 || ^7.0.0 || ^8.0.0 - '@vitest/coverage-v8@4.1.7': - resolution: {integrity: sha512-qsYPeXc5Q9dFLd1i8Ap+Bx8sQgcp+rFVQo4R0dDsWNBzl26ldVF1qOO+RL24K7FDrR6pA+50XedRLSoSG24bVQ==} + '@vitest/coverage-v8@4.1.8': + resolution: {integrity: sha512-lt3kovsyHwYe00wq4D1ti0Z974fWj4NLp6siqiyEufUpyFwK9Yhi7rBhac9JL5aA0zoMrJqc4vYPZRUnI7l7nw==} peerDependencies: - '@vitest/browser': 4.1.7 - vitest: 4.1.7 + '@vitest/browser': 4.1.8 + vitest: 4.1.8 peerDependenciesMeta: '@vitest/browser': optional: true - '@vitest/expect@4.1.7': - resolution: {integrity: sha512-1R+tw0ortHEbZDGMymm+pN7/AFQ/RkFFdtd7EN+VBpynKmLbP8A3rpEXdshBJ7+8hQ9zBJh/i1s0yKNtxAnU7w==} + '@vitest/expect@4.1.8': + resolution: {integrity: sha512-h3nDO677RDLEGlBxyQ5CW8RlMThSKSRLUePLOx09gNIWRL40edgA1GCZSZgf1W55MFAG6/Sw14KeaAnqv0NKdQ==} - '@vitest/mocker@4.1.7': - resolution: {integrity: sha512-vY7nuamKgfvpA1Koa3oYIw/k7D6kZnpGyNMZW8loow2bsBYla1TFdqTaXncWdRn4pgwNs+90RhnXhJScDwQeJA==} + '@vitest/mocker@4.1.8': + resolution: {integrity: sha512-LEiN/xe4OSIbKe9HQIp5OC24agGD9J5CnmMgsLohVVoOPWL9a2sBoR6VBx43jQZb7Kr1l4RCuyCJzcAa0+dojw==} peerDependencies: msw: ^2.4.9 vite: ^6.0.0 || ^7.0.0 || ^8.0.0 @@ -3956,20 +4228,20 @@ packages: vite: optional: true - '@vitest/pretty-format@4.1.7': - resolution: {integrity: sha512-umgCarTOYQWIaDMvGDRZij+6b9oVeLIyJzfN+AS88e0ZOU3QTgNNSTtjQOpcvWr3np1N0j4WgZj+sb3oYBDscw==} + '@vitest/pretty-format@4.1.8': + resolution: {integrity: sha512-9GasEBxpZ1VYIpqHf/0+YGg121uSNwCKOJqIrTwWP/TB7DmFCiaBpNl3aPZzoLWfWkuqhbH8vJIVobZkvdo2cA==} - '@vitest/runner@4.1.7': - resolution: {integrity: sha512-BapjmAQ2aI78WdMEfeUWivnfVzB+VPGwWRQcJE0OUq7qEeEcBsCSf+0T5iREBNE5nBb4wA5Ya0W6IA+sghdEFw==} + '@vitest/runner@4.1.8': + resolution: {integrity: sha512-EmVxeBAfMJvycdjd6Hm+RbFBbA9fKvo0Kx37hNpBYoYeavH3RNsBXWDooR1mgD52dCrxIIuP7UotpfiwOikvcg==} - '@vitest/snapshot@4.1.7': - resolution: {integrity: sha512-ZacLzja+TmJeZ1h14xW2FB/WpeimUD3haBXQPyJqxvo8jQTmfeA8zv58mtjN2C7EHXZDYVcVYdYmAxjkWVvKCw==} + '@vitest/snapshot@4.1.8': + resolution: {integrity: sha512-acfZboRmAIf05DEKcBQy33VXojFJjtUdLyo7oOmV9kebb2xdU01UknNiPuPZoJZQyO7DF0gZdTGTpeAzET9QPQ==} - '@vitest/spy@4.1.7': - resolution: {integrity: sha512-kbkI5LMWakyuTIvs6fUJ5qdIVb1XVKsYJAT4OJ938cHMROYMSfmoQdZy0aaAnjbbc8F61vkoTqz/Az+/HiIu5Q==} + '@vitest/spy@4.1.8': + resolution: {integrity: sha512-6EevtBp6OZOPF7bmz36HrGMeP3txgVSrgebWxHOafDXGkhIzfXK14f8KF6MuFfgXXUeHxmpD3BQxkV00/3s5mA==} - '@vitest/utils@4.1.7': - resolution: {integrity: sha512-T532WBu791cBxJlCl6SO+J14l81DQx6uQHm1bQbmCDY7nqlEIgkza/UFnSBNaUtSf41unldDFjdOBYEQC4b5Hw==} + '@vitest/utils@4.1.8': + resolution: {integrity: sha512-uOJamYALNhfJ6iolExyQM40yIQwDqYnkKtQ5VCiSe17E33H0aQ/u+1GlRuz4LZBk6Mm3sg90G9hEbmEt37C1Zg==} '@webassemblyjs/ast@1.14.1': resolution: {integrity: sha512-nuBEDgQfm1ccRp/8bCQrx1frohyufl4JlbMMZ4P1wpeOfDhF6FQkxZJ1b/e+PLwr6X1Nhw6OLme5usuBWYBvuQ==} @@ -4106,8 +4378,8 @@ packages: ajv@8.20.0: resolution: {integrity: sha512-Thbli+OlOj+iMPYFBVBfJ3OmCAnaSyNn4M1vz9T6Gka5Jt9ba/HIR56joy65tY6kx/FCF5VXNB819Y7/GUrBGA==} - algoliasearch@5.52.1: - resolution: {integrity: sha512-fHA8+kXTbjagw3jkLiaS7KKrH8qe2DyOsiUhGlN4cdT77PEsfqXZl7ewDk1hsg+pJnPlnE50XtLxjR91iJOpmg==} + algoliasearch@5.53.0: + resolution: {integrity: sha512-OGW1q6b91CRSSeiOnM8LxuR5NYJ2esvw66jUZ4IIvdv+ItNkx3pwLuyR+jaCdbGee4ov5WgUnyPryyh11xvByQ==} engines: {node: '>= 14.0.0'} ansi-colors@4.1.3: @@ -5158,8 +5430,8 @@ packages: resolution: {integrity: sha512-tD40eHxA35h0PEIZNeIjkHoDR4YjjJp34biM0mDvplBe//mB+IHCqHDGV7pxF+7MklTvighcCPPZC7ynWyjdTA==} engines: {node: ^20.19.0 || ^22.13.0 || >=24} - eslint@10.4.0: - resolution: {integrity: sha512-loXy6bWOoP3EP6JA7jo6p5jMpBJmHmsNZM5SFRHLdh1MGOPurMnNBj4ZlAbaqUAaQWbCr7jHV4P7gzAyryZWkQ==} + eslint@10.4.1: + resolution: {integrity: sha512-AyIKhnOBuOAdueD7RB3xB+YeAWScb9jHsJBgH2Hcde8InP5JYhqrRR6iTMHyTEwgENK54Cp44e4v8BwNhsuHuw==} engines: {node: ^20.19.0 || ^22.13.0 || >=24} hasBin: true peerDependencies: @@ -6283,8 +6555,8 @@ packages: resolution: {integrity: sha512-7I5knELsJKTUjXG+A6BkKAiGkW1i25fNa/xlUl9hFtk15WbE9jndA89xu5FzQKrY5llajE1hfZZFMILXkDHk/Q==} engines: {node: '>=22.13.0'} - lmdb@3.5.4: - resolution: {integrity: sha512-9FKQA6G1MMtqNxfxvSBNXD/axeG2QRjYbNh0/ykRL5xYcRbCm2vXq7B9bhc7nSuKdHzr8/BHIwfPuYYH1UsXXw==} + lmdb@3.5.5: + resolution: {integrity: sha512-e2q1RtHdJoDaQQNMJ55wJnD5BqpvzoJIEL3NBxfZXNBjYxY0QjCh3RSL/sqmi+y9l97cERdO4WwGFfYYVft1fA==} hasBin: true loader-runner@4.3.2: @@ -6589,6 +6861,10 @@ packages: resolution: {integrity: sha512-0D10M2/MnEyvoog7tmozlpSqL3HEU1evxUFa3v1dsKYmBDFSP1dLSX4CH2rNjpQ+4Fps8GKmUkCwiKryaKqd9A==} engines: {node: '>=20'} + mute-stream@3.0.0: + resolution: {integrity: sha512-dkEJPVvun4FryqBmZ5KhDo0K9iDXAwn08tMLDinNdRBNPcYEDiWYysLcc6k3mjTMlbP9KyylvRpd4wFtwrT9rw==} + engines: {node: ^20.17.0 || >=22.9.0} + mute-stream@4.0.0: resolution: {integrity: sha512-gSrprq0fJ3EiOErzjdIZrjysVVmJ4uu1QWfCDss5LypA5OXvrMje5Ym5z6V6RLyJ2eF87lasX7t6a0AnFvZblg==} engines: {node: ^22.22.2 || ^24.15.0 || >=26.0.0} @@ -7323,8 +7599,8 @@ packages: resolution: {integrity: sha512-l0OE8wL34P4nJH/H2ffoaniAokM2qSmrtXHmlpvYr5AVVX8msAyW0l8NVJFDxlSK4u3Uh/f41cQheDVdnYijwQ==} hasBin: true - rolldown@1.0.2: - resolution: {integrity: sha512-oZx5zVDtVB44AW3eaifgDml1gWRDZGvjcfdxonE4swNPG98PrrXjaO/KrnUjzlMnztCCRVlUueA1kCXhARGk6g==} + rolldown@1.0.3: + resolution: {integrity: sha512-i00lAJ2ks1BYr7rjNjKC7BcqAS7nVfiT3QX1SI5aY+AFHblCmaUf9OE9dbdzDvW6dJxbi2ZCZiy9v3CcwOiX3g==} engines: {node: ^20.19.0 || >=22.12.0} hasBin: true @@ -7354,6 +7630,11 @@ packages: engines: {node: '>=18.0.0', npm: '>=8.0.0'} hasBin: true + rollup@4.61.0: + resolution: {integrity: sha512-T9mWdbWfQtp0B5lv/HX+wrhYsmXRlcWnXXmJbXqKJhlRaoS6KMhq0gpyzW4UJfclcxrEdLnTgjT2NjruLONu0g==} + engines: {node: '>=18.0.0', npm: '>=8.0.0'} + hasBin: true + router@2.2.0: resolution: {integrity: sha512-nLTrUKm2UyiL7rlhapu/Zl45FwNgkZGaCpZbIHajDYgwlJCOzLSk+cIPAnsEqV955GjILJnKbdQC1nVPz+gAYQ==} engines: {node: '>= 18'} @@ -7898,6 +8179,10 @@ packages: resolution: {integrity: sha512-pn99VhoACYR8nFHhxqix+uvsbXineAasWm5ojXoN8xEwK5Kd3/TrhNn1wByuD52UxWRLy8pu+kRMniEi6Eq9Zg==} engines: {node: '>=12.0.0'} + tinyglobby@0.2.17: + resolution: {integrity: sha512-wXR/dYpcqKmfWpEdZjiKJOwCNFndD0DMnrW/cYjVGttEkBfVgcLFHoNrlj47mjOVic9yyNu65alsgF4NQyTa2g==} + engines: {node: '>=12.0.0'} + tinyrainbow@3.1.0: resolution: {integrity: sha512-Bf+ILmBgretUrdJxzXM0SgXLZ3XfiaUuOj/IKQHuTXip+05Xn+uyEYdVg0kYDipTBcLrCVyUzAPz7QmArb0mmw==} engines: {node: '>=14.0.0'} @@ -8224,20 +8509,60 @@ packages: yaml: optional: true - vitest@4.1.7: - resolution: {integrity: sha512-flYyaFd2CgoCoU+0UKt3pxksgC+S02iTDN0n3LtqaMeXsI9SBcdNujc2k0DeFLzUn/0k538yNjOSdwgCqcrwJA==} + vite@7.3.5: + resolution: {integrity: sha512-KuOaNhcnGFN2zIPGA7wRmzF+lJA1sea7rHq17aiJ++9lzY1WWG6Jpwqwe1KNbRVPIqHmr8GLYx7jbrQcN/7/ww==} + engines: {node: ^20.19.0 || >=22.12.0} + hasBin: true + peerDependencies: + '@types/node': ^20.19.0 || >=22.12.0 + jiti: '>=1.21.0' + less: ^4.0.0 + lightningcss: ^1.21.0 + sass: ^1.70.0 + sass-embedded: ^1.70.0 + stylus: '>=0.54.8' + sugarss: ^5.0.0 + terser: ^5.16.0 + tsx: ^4.8.1 + yaml: ^2.4.2 + peerDependenciesMeta: + '@types/node': + optional: true + jiti: + optional: true + less: + optional: true + lightningcss: + optional: true + sass: + optional: true + sass-embedded: + optional: true + stylus: + optional: true + sugarss: + optional: true + terser: + optional: true + tsx: + optional: true + yaml: + optional: true + + vitest@4.1.8: + resolution: {integrity: sha512-flY6ScbCIt9HThs+C5HS7jvGOB560DJtk/Z15IQROTA6zEy49Nh8T/dofWTQL+n3vswqn87sbJNiuqw1SDp5Ig==} engines: {node: ^20.0.0 || ^22.0.0 || >=24.0.0} hasBin: true peerDependencies: '@edge-runtime/vm': '*' '@opentelemetry/api': ^1.9.0 '@types/node': ^20.0.0 || ^22.0.0 || >=24.0.0 - '@vitest/browser-playwright': 4.1.7 - '@vitest/browser-preview': 4.1.7 - '@vitest/browser-webdriverio': 4.1.7 - '@vitest/coverage-istanbul': 4.1.7 - '@vitest/coverage-v8': 4.1.7 - '@vitest/ui': 4.1.7 + '@vitest/browser-playwright': 4.1.8 + '@vitest/browser-preview': 4.1.8 + '@vitest/browser-webdriverio': 4.1.8 + '@vitest/coverage-istanbul': 4.1.8 + '@vitest/coverage-v8': 4.1.8 + '@vitest/ui': 4.1.8 happy-dom: '*' jsdom: '*' peerDependenciesMeta: @@ -8580,89 +8905,89 @@ snapshots: '@actions/io@3.0.2': {} - '@algolia/abtesting@1.18.1': + '@algolia/abtesting@1.19.0': dependencies: - '@algolia/client-common': 5.52.1 - '@algolia/requester-browser-xhr': 5.52.1 - '@algolia/requester-fetch': 5.52.1 - '@algolia/requester-node-http': 5.52.1 + '@algolia/client-common': 5.53.0 + '@algolia/requester-browser-xhr': 5.53.0 + '@algolia/requester-fetch': 5.53.0 + '@algolia/requester-node-http': 5.53.0 - '@algolia/client-abtesting@5.52.1': + '@algolia/client-abtesting@5.53.0': dependencies: - '@algolia/client-common': 5.52.1 - '@algolia/requester-browser-xhr': 5.52.1 - '@algolia/requester-fetch': 5.52.1 - '@algolia/requester-node-http': 5.52.1 + '@algolia/client-common': 5.53.0 + '@algolia/requester-browser-xhr': 5.53.0 + '@algolia/requester-fetch': 5.53.0 + '@algolia/requester-node-http': 5.53.0 - '@algolia/client-analytics@5.52.1': + '@algolia/client-analytics@5.53.0': dependencies: - '@algolia/client-common': 5.52.1 - '@algolia/requester-browser-xhr': 5.52.1 - '@algolia/requester-fetch': 5.52.1 - '@algolia/requester-node-http': 5.52.1 + '@algolia/client-common': 5.53.0 + '@algolia/requester-browser-xhr': 5.53.0 + '@algolia/requester-fetch': 5.53.0 + '@algolia/requester-node-http': 5.53.0 - '@algolia/client-common@5.52.1': {} + '@algolia/client-common@5.53.0': {} - '@algolia/client-insights@5.52.1': + '@algolia/client-insights@5.53.0': dependencies: - '@algolia/client-common': 5.52.1 - '@algolia/requester-browser-xhr': 5.52.1 - '@algolia/requester-fetch': 5.52.1 - '@algolia/requester-node-http': 5.52.1 + '@algolia/client-common': 5.53.0 + '@algolia/requester-browser-xhr': 5.53.0 + '@algolia/requester-fetch': 5.53.0 + '@algolia/requester-node-http': 5.53.0 - '@algolia/client-personalization@5.52.1': + '@algolia/client-personalization@5.53.0': dependencies: - '@algolia/client-common': 5.52.1 - '@algolia/requester-browser-xhr': 5.52.1 - '@algolia/requester-fetch': 5.52.1 - '@algolia/requester-node-http': 5.52.1 + '@algolia/client-common': 5.53.0 + '@algolia/requester-browser-xhr': 5.53.0 + '@algolia/requester-fetch': 5.53.0 + '@algolia/requester-node-http': 5.53.0 - '@algolia/client-query-suggestions@5.52.1': + '@algolia/client-query-suggestions@5.53.0': dependencies: - '@algolia/client-common': 5.52.1 - '@algolia/requester-browser-xhr': 5.52.1 - '@algolia/requester-fetch': 5.52.1 - '@algolia/requester-node-http': 5.52.1 + '@algolia/client-common': 5.53.0 + '@algolia/requester-browser-xhr': 5.53.0 + '@algolia/requester-fetch': 5.53.0 + '@algolia/requester-node-http': 5.53.0 - '@algolia/client-search@5.52.1': + '@algolia/client-search@5.53.0': dependencies: - '@algolia/client-common': 5.52.1 - '@algolia/requester-browser-xhr': 5.52.1 - '@algolia/requester-fetch': 5.52.1 - '@algolia/requester-node-http': 5.52.1 + '@algolia/client-common': 5.53.0 + '@algolia/requester-browser-xhr': 5.53.0 + '@algolia/requester-fetch': 5.53.0 + '@algolia/requester-node-http': 5.53.0 - '@algolia/ingestion@1.52.1': + '@algolia/ingestion@1.53.0': dependencies: - '@algolia/client-common': 5.52.1 - '@algolia/requester-browser-xhr': 5.52.1 - '@algolia/requester-fetch': 5.52.1 - '@algolia/requester-node-http': 5.52.1 + '@algolia/client-common': 5.53.0 + '@algolia/requester-browser-xhr': 5.53.0 + '@algolia/requester-fetch': 5.53.0 + '@algolia/requester-node-http': 5.53.0 - '@algolia/monitoring@1.52.1': + '@algolia/monitoring@1.53.0': dependencies: - '@algolia/client-common': 5.52.1 - '@algolia/requester-browser-xhr': 5.52.1 - '@algolia/requester-fetch': 5.52.1 - '@algolia/requester-node-http': 5.52.1 + '@algolia/client-common': 5.53.0 + '@algolia/requester-browser-xhr': 5.53.0 + '@algolia/requester-fetch': 5.53.0 + '@algolia/requester-node-http': 5.53.0 - '@algolia/recommend@5.52.1': + '@algolia/recommend@5.53.0': dependencies: - '@algolia/client-common': 5.52.1 - '@algolia/requester-browser-xhr': 5.52.1 - '@algolia/requester-fetch': 5.52.1 - '@algolia/requester-node-http': 5.52.1 + '@algolia/client-common': 5.53.0 + '@algolia/requester-browser-xhr': 5.53.0 + '@algolia/requester-fetch': 5.53.0 + '@algolia/requester-node-http': 5.53.0 - '@algolia/requester-browser-xhr@5.52.1': + '@algolia/requester-browser-xhr@5.53.0': dependencies: - '@algolia/client-common': 5.52.1 + '@algolia/client-common': 5.53.0 - '@algolia/requester-fetch@5.52.1': + '@algolia/requester-fetch@5.53.0': dependencies: - '@algolia/client-common': 5.52.1 + '@algolia/client-common': 5.53.0 - '@algolia/requester-node-http@5.52.1': + '@algolia/requester-node-http@5.53.0': dependencies: - '@algolia/client-common': 5.52.1 + '@algolia/client-common': 5.53.0 '@ampproject/remapping@2.3.0': dependencies: @@ -9810,18 +10135,18 @@ snapshots: '@esbuild/win32-x64@0.28.0': optional: true - '@eslint-community/eslint-utils@4.9.1(eslint@10.4.0(jiti@2.7.0))': + '@eslint-community/eslint-utils@4.9.1(eslint@10.4.1(jiti@2.7.0))': dependencies: - eslint: 10.4.0(jiti@2.7.0) + eslint: 10.4.1(jiti@2.7.0) eslint-visitor-keys: 3.4.3 '@eslint-community/regexpp@4.12.2': {} - '@eslint/compat@2.1.0(eslint@10.4.0(jiti@2.7.0))': + '@eslint/compat@2.1.0(eslint@10.4.1(jiti@2.7.0))': dependencies: '@eslint/core': 1.2.1 optionalDependencies: - eslint: 10.4.0(jiti@2.7.0) + eslint: 10.4.1(jiti@2.7.0) '@eslint/config-array@0.23.5': dependencies: @@ -9853,13 +10178,13 @@ snapshots: transitivePeerDependencies: - supports-color - '@eslint/js@10.0.1(eslint@10.4.0(jiti@2.7.0))': + '@eslint/js@10.0.1(eslint@10.4.1(jiti@2.7.0))': optionalDependencies: - eslint: 10.4.0(jiti@2.7.0) + eslint: 10.4.1(jiti@2.7.0) '@eslint/object-schema@3.0.5': {} - '@eslint/plugin-kit@0.7.1': + '@eslint/plugin-kit@0.7.2': dependencies: '@eslint/core': 1.2.1 levn: 0.4.1 @@ -10311,6 +10636,8 @@ snapshots: '@inquirer/ansi@2.0.6': {} + '@inquirer/ansi@2.0.7': {} + '@inquirer/checkbox@5.2.0(@types/node@24.12.4)': dependencies: '@inquirer/ansi': 2.0.6 @@ -10320,6 +10647,15 @@ snapshots: optionalDependencies: '@types/node': 24.12.4 + '@inquirer/checkbox@5.2.1(@types/node@24.12.4)': + dependencies: + '@inquirer/ansi': 2.0.7 + '@inquirer/core': 11.2.1(@types/node@24.12.4) + '@inquirer/figures': 2.0.7 + '@inquirer/type': 4.0.7(@types/node@24.12.4) + optionalDependencies: + '@types/node': 24.12.4 + '@inquirer/confirm@6.1.0(@types/node@24.12.4)': dependencies: '@inquirer/core': 11.2.0(@types/node@24.12.4) @@ -10327,6 +10663,13 @@ snapshots: optionalDependencies: '@types/node': 24.12.4 + '@inquirer/confirm@6.1.1(@types/node@24.12.4)': + dependencies: + '@inquirer/core': 11.2.1(@types/node@24.12.4) + '@inquirer/type': 4.0.7(@types/node@24.12.4) + optionalDependencies: + '@types/node': 24.12.4 + '@inquirer/core@11.2.0(@types/node@24.12.4)': dependencies: '@inquirer/ansi': 2.0.6 @@ -10339,6 +10682,18 @@ snapshots: optionalDependencies: '@types/node': 24.12.4 + '@inquirer/core@11.2.1(@types/node@24.12.4)': + dependencies: + '@inquirer/ansi': 2.0.7 + '@inquirer/figures': 2.0.7 + '@inquirer/type': 4.0.7(@types/node@24.12.4) + cli-width: 4.1.0 + fast-wrap-ansi: 0.2.2 + mute-stream: 3.0.0 + signal-exit: 4.1.0 + optionalDependencies: + '@types/node': 24.12.4 + '@inquirer/editor@5.2.0(@types/node@24.12.4)': dependencies: '@inquirer/core': 11.2.0(@types/node@24.12.4) @@ -10347,6 +10702,14 @@ snapshots: optionalDependencies: '@types/node': 24.12.4 + '@inquirer/editor@5.2.2(@types/node@24.12.4)': + dependencies: + '@inquirer/core': 11.2.1(@types/node@24.12.4) + '@inquirer/external-editor': 3.0.3(@types/node@24.12.4) + '@inquirer/type': 4.0.7(@types/node@24.12.4) + optionalDependencies: + '@types/node': 24.12.4 + '@inquirer/expand@5.1.0(@types/node@24.12.4)': dependencies: '@inquirer/core': 11.2.0(@types/node@24.12.4) @@ -10354,6 +10717,13 @@ snapshots: optionalDependencies: '@types/node': 24.12.4 + '@inquirer/expand@5.1.1(@types/node@24.12.4)': + dependencies: + '@inquirer/core': 11.2.1(@types/node@24.12.4) + '@inquirer/type': 4.0.7(@types/node@24.12.4) + optionalDependencies: + '@types/node': 24.12.4 + '@inquirer/external-editor@3.0.1(@types/node@24.12.4)': dependencies: chardet: 2.1.1 @@ -10361,8 +10731,17 @@ snapshots: optionalDependencies: '@types/node': 24.12.4 + '@inquirer/external-editor@3.0.3(@types/node@24.12.4)': + dependencies: + chardet: 2.1.1 + iconv-lite: 0.7.2 + optionalDependencies: + '@types/node': 24.12.4 + '@inquirer/figures@2.0.6': {} + '@inquirer/figures@2.0.7': {} + '@inquirer/input@5.1.0(@types/node@24.12.4)': dependencies: '@inquirer/core': 11.2.0(@types/node@24.12.4) @@ -10370,6 +10749,13 @@ snapshots: optionalDependencies: '@types/node': 24.12.4 + '@inquirer/input@5.1.2(@types/node@24.12.4)': + dependencies: + '@inquirer/core': 11.2.1(@types/node@24.12.4) + '@inquirer/type': 4.0.7(@types/node@24.12.4) + optionalDependencies: + '@types/node': 24.12.4 + '@inquirer/number@4.1.0(@types/node@24.12.4)': dependencies: '@inquirer/core': 11.2.0(@types/node@24.12.4) @@ -10377,6 +10763,13 @@ snapshots: optionalDependencies: '@types/node': 24.12.4 + '@inquirer/number@4.1.1(@types/node@24.12.4)': + dependencies: + '@inquirer/core': 11.2.1(@types/node@24.12.4) + '@inquirer/type': 4.0.7(@types/node@24.12.4) + optionalDependencies: + '@types/node': 24.12.4 + '@inquirer/password@5.1.0(@types/node@24.12.4)': dependencies: '@inquirer/ansi': 2.0.6 @@ -10385,22 +10778,15 @@ snapshots: optionalDependencies: '@types/node': 24.12.4 - '@inquirer/prompts@8.4.3(@types/node@24.12.4)': + '@inquirer/password@5.1.1(@types/node@24.12.4)': dependencies: - '@inquirer/checkbox': 5.2.0(@types/node@24.12.4) - '@inquirer/confirm': 6.1.0(@types/node@24.12.4) - '@inquirer/editor': 5.2.0(@types/node@24.12.4) - '@inquirer/expand': 5.1.0(@types/node@24.12.4) - '@inquirer/input': 5.1.0(@types/node@24.12.4) - '@inquirer/number': 4.1.0(@types/node@24.12.4) - '@inquirer/password': 5.1.0(@types/node@24.12.4) - '@inquirer/rawlist': 5.3.0(@types/node@24.12.4) - '@inquirer/search': 4.2.0(@types/node@24.12.4) - '@inquirer/select': 5.2.0(@types/node@24.12.4) + '@inquirer/ansi': 2.0.7 + '@inquirer/core': 11.2.1(@types/node@24.12.4) + '@inquirer/type': 4.0.7(@types/node@24.12.4) optionalDependencies: '@types/node': 24.12.4 - '@inquirer/prompts@8.5.0(@types/node@24.12.4)': + '@inquirer/prompts@8.4.3(@types/node@24.12.4)': dependencies: '@inquirer/checkbox': 5.2.0(@types/node@24.12.4) '@inquirer/confirm': 6.1.0(@types/node@24.12.4) @@ -10415,6 +10801,21 @@ snapshots: optionalDependencies: '@types/node': 24.12.4 + '@inquirer/prompts@8.5.2(@types/node@24.12.4)': + dependencies: + '@inquirer/checkbox': 5.2.1(@types/node@24.12.4) + '@inquirer/confirm': 6.1.1(@types/node@24.12.4) + '@inquirer/editor': 5.2.2(@types/node@24.12.4) + '@inquirer/expand': 5.1.1(@types/node@24.12.4) + '@inquirer/input': 5.1.2(@types/node@24.12.4) + '@inquirer/number': 4.1.1(@types/node@24.12.4) + '@inquirer/password': 5.1.1(@types/node@24.12.4) + '@inquirer/rawlist': 5.3.1(@types/node@24.12.4) + '@inquirer/search': 4.2.1(@types/node@24.12.4) + '@inquirer/select': 5.2.1(@types/node@24.12.4) + optionalDependencies: + '@types/node': 24.12.4 + '@inquirer/rawlist@5.3.0(@types/node@24.12.4)': dependencies: '@inquirer/core': 11.2.0(@types/node@24.12.4) @@ -10422,6 +10823,13 @@ snapshots: optionalDependencies: '@types/node': 24.12.4 + '@inquirer/rawlist@5.3.1(@types/node@24.12.4)': + dependencies: + '@inquirer/core': 11.2.1(@types/node@24.12.4) + '@inquirer/type': 4.0.7(@types/node@24.12.4) + optionalDependencies: + '@types/node': 24.12.4 + '@inquirer/search@4.2.0(@types/node@24.12.4)': dependencies: '@inquirer/core': 11.2.0(@types/node@24.12.4) @@ -10430,6 +10838,14 @@ snapshots: optionalDependencies: '@types/node': 24.12.4 + '@inquirer/search@4.2.1(@types/node@24.12.4)': + dependencies: + '@inquirer/core': 11.2.1(@types/node@24.12.4) + '@inquirer/figures': 2.0.7 + '@inquirer/type': 4.0.7(@types/node@24.12.4) + optionalDependencies: + '@types/node': 24.12.4 + '@inquirer/select@5.2.0(@types/node@24.12.4)': dependencies: '@inquirer/ansi': 2.0.6 @@ -10439,6 +10855,15 @@ snapshots: optionalDependencies: '@types/node': 24.12.4 + '@inquirer/select@5.2.1(@types/node@24.12.4)': + dependencies: + '@inquirer/ansi': 2.0.7 + '@inquirer/core': 11.2.1(@types/node@24.12.4) + '@inquirer/figures': 2.0.7 + '@inquirer/type': 4.0.7(@types/node@24.12.4) + optionalDependencies: + '@types/node': 24.12.4 + '@inquirer/type@4.0.5(@types/node@24.12.4)': optionalDependencies: '@types/node': 24.12.4 @@ -10447,6 +10872,10 @@ snapshots: optionalDependencies: '@types/node': 24.12.4 + '@inquirer/type@4.0.7(@types/node@24.12.4)': + optionalDependencies: + '@types/node': 24.12.4 + '@isaacs/cliui@8.0.2': dependencies: string-width: 5.1.2 @@ -10619,33 +11048,33 @@ snapshots: '@leichtgewicht/ip-codec@2.0.5': {} - '@listr2/prompt-adapter-inquirer@4.2.3(@inquirer/prompts@8.5.0(@types/node@24.12.4))(@types/node@24.12.4)(listr2@10.2.1)': + '@listr2/prompt-adapter-inquirer@4.2.4(@inquirer/prompts@8.5.2(@types/node@24.12.4))(@types/node@24.12.4)(listr2@10.2.1)': dependencies: - '@inquirer/prompts': 8.5.0(@types/node@24.12.4) + '@inquirer/prompts': 8.5.2(@types/node@24.12.4) '@inquirer/type': 4.0.6(@types/node@24.12.4) listr2: 10.2.1 transitivePeerDependencies: - '@types/node' - '@lmdb/lmdb-darwin-arm64@3.5.4': + '@lmdb/lmdb-darwin-arm64@3.5.5': optional: true - '@lmdb/lmdb-darwin-x64@3.5.4': + '@lmdb/lmdb-darwin-x64@3.5.5': optional: true - '@lmdb/lmdb-linux-arm64@3.5.4': + '@lmdb/lmdb-linux-arm64@3.5.5': optional: true - '@lmdb/lmdb-linux-arm@3.5.4': + '@lmdb/lmdb-linux-arm@3.5.5': optional: true - '@lmdb/lmdb-linux-x64@3.5.4': + '@lmdb/lmdb-linux-x64@3.5.5': optional: true - '@lmdb/lmdb-win32-arm64@3.5.4': + '@lmdb/lmdb-win32-arm64@3.5.5': optional: true - '@lmdb/lmdb-win32-x64@3.5.4': + '@lmdb/lmdb-win32-x64@3.5.5': optional: true '@modelcontextprotocol/sdk@1.29.0(zod@4.4.3)': @@ -10979,7 +11408,7 @@ snapshots: '@opentelemetry/semantic-conventions@1.41.1': {} - '@oxc-project/types@0.132.0': {} + '@oxc-project/types@0.133.0': {} '@parcel/watcher-android-arm64@2.5.6': optional: true @@ -11188,64 +11617,64 @@ snapshots: modern-tar: 0.7.6 yargs: 17.7.2 - '@rolldown/binding-android-arm64@1.0.2': + '@rolldown/binding-android-arm64@1.0.3': optional: true - '@rolldown/binding-darwin-arm64@1.0.2': + '@rolldown/binding-darwin-arm64@1.0.3': optional: true - '@rolldown/binding-darwin-x64@1.0.2': + '@rolldown/binding-darwin-x64@1.0.3': optional: true - '@rolldown/binding-freebsd-x64@1.0.2': + '@rolldown/binding-freebsd-x64@1.0.3': optional: true - '@rolldown/binding-linux-arm-gnueabihf@1.0.2': + '@rolldown/binding-linux-arm-gnueabihf@1.0.3': optional: true - '@rolldown/binding-linux-arm64-gnu@1.0.2': + '@rolldown/binding-linux-arm64-gnu@1.0.3': optional: true - '@rolldown/binding-linux-arm64-musl@1.0.2': + '@rolldown/binding-linux-arm64-musl@1.0.3': optional: true - '@rolldown/binding-linux-ppc64-gnu@1.0.2': + '@rolldown/binding-linux-ppc64-gnu@1.0.3': optional: true - '@rolldown/binding-linux-s390x-gnu@1.0.2': + '@rolldown/binding-linux-s390x-gnu@1.0.3': optional: true - '@rolldown/binding-linux-x64-gnu@1.0.2': + '@rolldown/binding-linux-x64-gnu@1.0.3': optional: true - '@rolldown/binding-linux-x64-musl@1.0.2': + '@rolldown/binding-linux-x64-musl@1.0.3': optional: true - '@rolldown/binding-openharmony-arm64@1.0.2': + '@rolldown/binding-openharmony-arm64@1.0.3': optional: true - '@rolldown/binding-wasm32-wasi@1.0.2': + '@rolldown/binding-wasm32-wasi@1.0.3': dependencies: '@emnapi/core': 1.10.0 '@emnapi/runtime': 1.10.0 '@napi-rs/wasm-runtime': 1.1.4(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0) optional: true - '@rolldown/binding-win32-arm64-msvc@1.0.2': + '@rolldown/binding-win32-arm64-msvc@1.0.3': optional: true - '@rolldown/binding-win32-x64-msvc@1.0.2': + '@rolldown/binding-win32-x64-msvc@1.0.3': optional: true '@rolldown/pluginutils@1.0.1': {} - '@rollup/plugin-alias@6.0.0(rollup@4.60.4)': + '@rollup/plugin-alias@6.0.0(rollup@4.61.0)': optionalDependencies: - rollup: 4.60.4 + rollup: 4.61.0 - '@rollup/plugin-commonjs@29.0.2(rollup@4.60.4)': + '@rollup/plugin-commonjs@29.0.2(rollup@4.61.0)': dependencies: - '@rollup/pluginutils': 5.3.0(rollup@4.60.4) + '@rollup/pluginutils': 5.3.0(rollup@4.61.0) commondir: 1.0.1 estree-walker: 2.0.2 fdir: 6.5.0(picomatch@4.0.4) @@ -11253,7 +11682,7 @@ snapshots: magic-string: 0.30.21 picomatch: 4.0.4 optionalDependencies: - rollup: 4.60.4 + rollup: 4.61.0 '@rollup/plugin-json@6.1.0(rollup@4.60.4)': dependencies: @@ -11261,15 +11690,21 @@ snapshots: optionalDependencies: rollup: 4.60.4 - '@rollup/plugin-node-resolve@16.0.3(rollup@4.60.4)': + '@rollup/plugin-json@6.1.0(rollup@4.61.0)': dependencies: - '@rollup/pluginutils': 5.3.0(rollup@4.60.4) + '@rollup/pluginutils': 5.3.0(rollup@4.61.0) + optionalDependencies: + rollup: 4.61.0 + + '@rollup/plugin-node-resolve@16.0.3(rollup@4.61.0)': + dependencies: + '@rollup/pluginutils': 5.3.0(rollup@4.61.0) '@types/resolve': 1.20.2 deepmerge: 4.3.1 is-module: 1.0.0 resolve: 1.22.12 optionalDependencies: - rollup: 4.60.4 + rollup: 4.61.0 '@rollup/pluginutils@5.3.0(rollup@4.60.4)': dependencies: @@ -11279,87 +11714,176 @@ snapshots: optionalDependencies: rollup: 4.60.4 + '@rollup/pluginutils@5.3.0(rollup@4.61.0)': + dependencies: + '@types/estree': 1.0.9 + estree-walker: 2.0.2 + picomatch: 4.0.4 + optionalDependencies: + rollup: 4.61.0 + '@rollup/rollup-android-arm-eabi@4.60.4': optional: true + '@rollup/rollup-android-arm-eabi@4.61.0': + optional: true + '@rollup/rollup-android-arm64@4.60.4': optional: true + '@rollup/rollup-android-arm64@4.61.0': + optional: true + '@rollup/rollup-darwin-arm64@4.60.4': optional: true + '@rollup/rollup-darwin-arm64@4.61.0': + optional: true + '@rollup/rollup-darwin-x64@4.60.4': optional: true + '@rollup/rollup-darwin-x64@4.61.0': + optional: true + '@rollup/rollup-freebsd-arm64@4.60.4': optional: true + '@rollup/rollup-freebsd-arm64@4.61.0': + optional: true + '@rollup/rollup-freebsd-x64@4.60.4': optional: true + '@rollup/rollup-freebsd-x64@4.61.0': + optional: true + '@rollup/rollup-linux-arm-gnueabihf@4.60.4': optional: true + '@rollup/rollup-linux-arm-gnueabihf@4.61.0': + optional: true + '@rollup/rollup-linux-arm-musleabihf@4.60.4': optional: true + '@rollup/rollup-linux-arm-musleabihf@4.61.0': + optional: true + '@rollup/rollup-linux-arm64-gnu@4.60.4': optional: true + '@rollup/rollup-linux-arm64-gnu@4.61.0': + optional: true + '@rollup/rollup-linux-arm64-musl@4.60.4': optional: true + '@rollup/rollup-linux-arm64-musl@4.61.0': + optional: true + '@rollup/rollup-linux-loong64-gnu@4.60.4': optional: true + '@rollup/rollup-linux-loong64-gnu@4.61.0': + optional: true + '@rollup/rollup-linux-loong64-musl@4.60.4': optional: true + '@rollup/rollup-linux-loong64-musl@4.61.0': + optional: true + '@rollup/rollup-linux-ppc64-gnu@4.60.4': optional: true + '@rollup/rollup-linux-ppc64-gnu@4.61.0': + optional: true + '@rollup/rollup-linux-ppc64-musl@4.60.4': optional: true + '@rollup/rollup-linux-ppc64-musl@4.61.0': + optional: true + '@rollup/rollup-linux-riscv64-gnu@4.60.4': optional: true + '@rollup/rollup-linux-riscv64-gnu@4.61.0': + optional: true + '@rollup/rollup-linux-riscv64-musl@4.60.4': optional: true + '@rollup/rollup-linux-riscv64-musl@4.61.0': + optional: true + '@rollup/rollup-linux-s390x-gnu@4.60.4': optional: true + '@rollup/rollup-linux-s390x-gnu@4.61.0': + optional: true + '@rollup/rollup-linux-x64-gnu@4.60.4': optional: true + '@rollup/rollup-linux-x64-gnu@4.61.0': + optional: true + '@rollup/rollup-linux-x64-musl@4.60.4': optional: true + '@rollup/rollup-linux-x64-musl@4.61.0': + optional: true + '@rollup/rollup-openbsd-x64@4.60.4': optional: true + '@rollup/rollup-openbsd-x64@4.61.0': + optional: true + '@rollup/rollup-openharmony-arm64@4.60.4': optional: true + '@rollup/rollup-openharmony-arm64@4.61.0': + optional: true + '@rollup/rollup-win32-arm64-msvc@4.60.4': optional: true + '@rollup/rollup-win32-arm64-msvc@4.61.0': + optional: true + '@rollup/rollup-win32-ia32-msvc@4.60.4': optional: true + '@rollup/rollup-win32-ia32-msvc@4.61.0': + optional: true + '@rollup/rollup-win32-x64-gnu@4.60.4': optional: true + '@rollup/rollup-win32-x64-gnu@4.61.0': + optional: true + '@rollup/rollup-win32-x64-msvc@4.60.4': optional: true + '@rollup/rollup-win32-x64-msvc@4.61.0': + optional: true + '@rollup/wasm-node@4.60.4': dependencies: '@types/estree': 1.0.8 optionalDependencies: fsevents: 2.3.3 + '@rollup/wasm-node@4.61.0': + dependencies: + '@types/estree': 1.0.9 + optionalDependencies: + fsevents: 2.3.3 + '@rtsao/scc@1.1.0': {} '@sigstore/bundle@4.0.0': @@ -11406,11 +11930,11 @@ snapshots: '@standard-schema/spec@1.1.0': {} - '@stylistic/eslint-plugin@5.10.0(eslint@10.4.0(jiti@2.7.0))': + '@stylistic/eslint-plugin@5.10.0(eslint@10.4.1(jiti@2.7.0))': dependencies: - '@eslint-community/eslint-utils': 4.9.1(eslint@10.4.0(jiti@2.7.0)) + '@eslint-community/eslint-utils': 4.9.1(eslint@10.4.1(jiti@2.7.0)) '@typescript-eslint/types': 8.60.0 - eslint: 10.4.0(jiti@2.7.0) + eslint: 10.4.1(jiti@2.7.0) eslint-visitor-keys: 4.2.1 espree: 10.4.0 estraverse: 5.3.0 @@ -11420,9 +11944,9 @@ snapshots: dependencies: defer-to-connect: 2.0.1 - '@tony.ganchev/eslint-plugin-header@3.4.4(eslint@10.4.0(jiti@2.7.0))': + '@tony.ganchev/eslint-plugin-header@3.4.4(eslint@10.4.1(jiti@2.7.0))': dependencies: - eslint: 10.4.0(jiti@2.7.0) + eslint: 10.4.1(jiti@2.7.0) '@tufjs/canonical-json@2.0.0': {} @@ -11720,15 +12244,15 @@ snapshots: '@types/yarnpkg__lockfile@1.1.9': {} - '@typescript-eslint/eslint-plugin@8.60.0(@typescript-eslint/parser@8.60.0(eslint@10.4.0(jiti@2.7.0))(typescript@6.0.3))(eslint@10.4.0(jiti@2.7.0))(typescript@6.0.3)': + '@typescript-eslint/eslint-plugin@8.60.1(@typescript-eslint/parser@8.60.1(eslint@10.4.1(jiti@2.7.0))(typescript@6.0.3))(eslint@10.4.1(jiti@2.7.0))(typescript@6.0.3)': dependencies: '@eslint-community/regexpp': 4.12.2 - '@typescript-eslint/parser': 8.60.0(eslint@10.4.0(jiti@2.7.0))(typescript@6.0.3) - '@typescript-eslint/scope-manager': 8.60.0 - '@typescript-eslint/type-utils': 8.60.0(eslint@10.4.0(jiti@2.7.0))(typescript@6.0.3) - '@typescript-eslint/utils': 8.60.0(eslint@10.4.0(jiti@2.7.0))(typescript@6.0.3) - '@typescript-eslint/visitor-keys': 8.60.0 - eslint: 10.4.0(jiti@2.7.0) + '@typescript-eslint/parser': 8.60.1(eslint@10.4.1(jiti@2.7.0))(typescript@6.0.3) + '@typescript-eslint/scope-manager': 8.60.1 + '@typescript-eslint/type-utils': 8.60.1(eslint@10.4.1(jiti@2.7.0))(typescript@6.0.3) + '@typescript-eslint/utils': 8.60.1(eslint@10.4.1(jiti@2.7.0))(typescript@6.0.3) + '@typescript-eslint/visitor-keys': 8.60.1 + eslint: 10.4.1(jiti@2.7.0) ignore: 7.0.5 natural-compare: 1.4.0 ts-api-utils: 2.5.0(typescript@6.0.3) @@ -11736,43 +12260,43 @@ snapshots: transitivePeerDependencies: - supports-color - '@typescript-eslint/parser@8.60.0(eslint@10.4.0(jiti@2.7.0))(typescript@6.0.3)': + '@typescript-eslint/parser@8.60.1(eslint@10.4.1(jiti@2.7.0))(typescript@6.0.3)': dependencies: - '@typescript-eslint/scope-manager': 8.60.0 - '@typescript-eslint/types': 8.60.0 - '@typescript-eslint/typescript-estree': 8.60.0(typescript@6.0.3) - '@typescript-eslint/visitor-keys': 8.60.0 + '@typescript-eslint/scope-manager': 8.60.1 + '@typescript-eslint/types': 8.60.1 + '@typescript-eslint/typescript-estree': 8.60.1(typescript@6.0.3) + '@typescript-eslint/visitor-keys': 8.60.1 debug: 4.4.3(supports-color@10.2.2) - eslint: 10.4.0(jiti@2.7.0) + eslint: 10.4.1(jiti@2.7.0) typescript: 6.0.3 transitivePeerDependencies: - supports-color - '@typescript-eslint/project-service@8.60.0(typescript@6.0.3)': + '@typescript-eslint/project-service@8.60.1(typescript@6.0.3)': dependencies: - '@typescript-eslint/tsconfig-utils': 8.60.0(typescript@6.0.3) - '@typescript-eslint/types': 8.60.0 + '@typescript-eslint/tsconfig-utils': 8.60.1(typescript@6.0.3) + '@typescript-eslint/types': 8.60.1 debug: 4.4.3(supports-color@10.2.2) typescript: 6.0.3 transitivePeerDependencies: - supports-color - '@typescript-eslint/scope-manager@8.60.0': + '@typescript-eslint/scope-manager@8.60.1': dependencies: - '@typescript-eslint/types': 8.60.0 - '@typescript-eslint/visitor-keys': 8.60.0 + '@typescript-eslint/types': 8.60.1 + '@typescript-eslint/visitor-keys': 8.60.1 - '@typescript-eslint/tsconfig-utils@8.60.0(typescript@6.0.3)': + '@typescript-eslint/tsconfig-utils@8.60.1(typescript@6.0.3)': dependencies: typescript: 6.0.3 - '@typescript-eslint/type-utils@8.60.0(eslint@10.4.0(jiti@2.7.0))(typescript@6.0.3)': + '@typescript-eslint/type-utils@8.60.1(eslint@10.4.1(jiti@2.7.0))(typescript@6.0.3)': dependencies: - '@typescript-eslint/types': 8.60.0 - '@typescript-eslint/typescript-estree': 8.60.0(typescript@6.0.3) - '@typescript-eslint/utils': 8.60.0(eslint@10.4.0(jiti@2.7.0))(typescript@6.0.3) + '@typescript-eslint/types': 8.60.1 + '@typescript-eslint/typescript-estree': 8.60.1(typescript@6.0.3) + '@typescript-eslint/utils': 8.60.1(eslint@10.4.1(jiti@2.7.0))(typescript@6.0.3) debug: 4.4.3(supports-color@10.2.2) - eslint: 10.4.0(jiti@2.7.0) + eslint: 10.4.1(jiti@2.7.0) ts-api-utils: 2.5.0(typescript@6.0.3) typescript: 6.0.3 transitivePeerDependencies: @@ -11780,12 +12304,14 @@ snapshots: '@typescript-eslint/types@8.60.0': {} - '@typescript-eslint/typescript-estree@8.60.0(typescript@6.0.3)': + '@typescript-eslint/types@8.60.1': {} + + '@typescript-eslint/typescript-estree@8.60.1(typescript@6.0.3)': dependencies: - '@typescript-eslint/project-service': 8.60.0(typescript@6.0.3) - '@typescript-eslint/tsconfig-utils': 8.60.0(typescript@6.0.3) - '@typescript-eslint/types': 8.60.0 - '@typescript-eslint/visitor-keys': 8.60.0 + '@typescript-eslint/project-service': 8.60.1(typescript@6.0.3) + '@typescript-eslint/tsconfig-utils': 8.60.1(typescript@6.0.3) + '@typescript-eslint/types': 8.60.1 + '@typescript-eslint/visitor-keys': 8.60.1 debug: 4.4.3(supports-color@10.2.2) minimatch: 10.2.5 semver: 7.8.1 @@ -11795,20 +12321,20 @@ snapshots: transitivePeerDependencies: - supports-color - '@typescript-eslint/utils@8.60.0(eslint@10.4.0(jiti@2.7.0))(typescript@6.0.3)': + '@typescript-eslint/utils@8.60.1(eslint@10.4.1(jiti@2.7.0))(typescript@6.0.3)': dependencies: - '@eslint-community/eslint-utils': 4.9.1(eslint@10.4.0(jiti@2.7.0)) - '@typescript-eslint/scope-manager': 8.60.0 - '@typescript-eslint/types': 8.60.0 - '@typescript-eslint/typescript-estree': 8.60.0(typescript@6.0.3) - eslint: 10.4.0(jiti@2.7.0) + '@eslint-community/eslint-utils': 4.9.1(eslint@10.4.1(jiti@2.7.0)) + '@typescript-eslint/scope-manager': 8.60.1 + '@typescript-eslint/types': 8.60.1 + '@typescript-eslint/typescript-estree': 8.60.1(typescript@6.0.3) + eslint: 10.4.1(jiti@2.7.0) typescript: 6.0.3 transitivePeerDependencies: - supports-color - '@typescript-eslint/visitor-keys@8.60.0': + '@typescript-eslint/visitor-keys@8.60.1': dependencies: - '@typescript-eslint/types': 8.60.0 + '@typescript-eslint/types': 8.60.1 eslint-visitor-keys: 5.0.1 '@verdaccio/auth@8.0.2': @@ -11973,14 +12499,14 @@ snapshots: lodash: 4.18.1 minimatch: 7.4.9 - '@vitejs/plugin-basic-ssl@2.3.0(vite@7.3.3(@types/node@24.12.4)(jiti@2.7.0)(less@4.6.4)(sass@1.100.0)(terser@5.48.0)(tsx@4.22.3)(yaml@2.9.0))': + '@vitejs/plugin-basic-ssl@2.3.0(vite@7.3.5(@types/node@24.12.4)(jiti@2.7.0)(less@4.6.4)(sass@1.100.0)(terser@5.48.0)(tsx@4.22.3)(yaml@2.9.0))': dependencies: - vite: 7.3.3(@types/node@24.12.4)(jiti@2.7.0)(less@4.6.4)(sass@1.100.0)(terser@5.48.0)(tsx@4.22.3)(yaml@2.9.0) + vite: 7.3.5(@types/node@24.12.4)(jiti@2.7.0)(less@4.6.4)(sass@1.100.0)(terser@5.48.0)(tsx@4.22.3)(yaml@2.9.0) - '@vitest/coverage-v8@4.1.7(vitest@4.1.7)': + '@vitest/coverage-v8@4.1.8(vitest@4.1.8)': dependencies: '@bcoe/v8-coverage': 1.0.2 - '@vitest/utils': 4.1.7 + '@vitest/utils': 4.1.8 ast-v8-to-istanbul: 1.0.2 istanbul-lib-coverage: 3.2.2 istanbul-lib-report: 3.0.1 @@ -11989,46 +12515,46 @@ snapshots: obug: 2.1.1 std-env: 4.1.0 tinyrainbow: 3.1.0 - vitest: 4.1.7(@opentelemetry/api@1.9.1)(@types/node@24.12.4)(@vitest/coverage-v8@4.1.7)(jiti@2.7.0)(jsdom@29.1.1)(less@4.6.4)(sass@1.100.0)(terser@5.48.0)(tsx@4.22.3)(yaml@2.9.0) + vitest: 4.1.8(@opentelemetry/api@1.9.1)(@types/node@24.12.4)(@vitest/coverage-v8@4.1.8)(jiti@2.7.0)(jsdom@29.1.1)(less@4.6.4)(sass@1.100.0)(terser@5.48.0)(tsx@4.22.3)(yaml@2.9.0) - '@vitest/expect@4.1.7': + '@vitest/expect@4.1.8': dependencies: '@standard-schema/spec': 1.1.0 '@types/chai': 5.2.3 - '@vitest/spy': 4.1.7 - '@vitest/utils': 4.1.7 + '@vitest/spy': 4.1.8 + '@vitest/utils': 4.1.8 chai: 6.2.2 tinyrainbow: 3.1.0 - '@vitest/mocker@4.1.7(vite@7.3.3(@types/node@24.12.4)(jiti@2.7.0)(less@4.6.4)(sass@1.100.0)(terser@5.48.0)(tsx@4.22.3)(yaml@2.9.0))': + '@vitest/mocker@4.1.8(vite@7.3.3(@types/node@24.12.4)(jiti@2.7.0)(less@4.6.4)(sass@1.100.0)(terser@5.48.0)(tsx@4.22.3)(yaml@2.9.0))': dependencies: - '@vitest/spy': 4.1.7 + '@vitest/spy': 4.1.8 estree-walker: 3.0.3 magic-string: 0.30.21 optionalDependencies: vite: 7.3.3(@types/node@24.12.4)(jiti@2.7.0)(less@4.6.4)(sass@1.100.0)(terser@5.48.0)(tsx@4.22.3)(yaml@2.9.0) - '@vitest/pretty-format@4.1.7': + '@vitest/pretty-format@4.1.8': dependencies: tinyrainbow: 3.1.0 - '@vitest/runner@4.1.7': + '@vitest/runner@4.1.8': dependencies: - '@vitest/utils': 4.1.7 + '@vitest/utils': 4.1.8 pathe: 2.0.3 - '@vitest/snapshot@4.1.7': + '@vitest/snapshot@4.1.8': dependencies: - '@vitest/pretty-format': 4.1.7 - '@vitest/utils': 4.1.7 + '@vitest/pretty-format': 4.1.8 + '@vitest/utils': 4.1.8 magic-string: 0.30.21 pathe: 2.0.3 - '@vitest/spy@4.1.7': {} + '@vitest/spy@4.1.8': {} - '@vitest/utils@4.1.7': + '@vitest/utils@4.1.8': dependencies: - '@vitest/pretty-format': 4.1.7 + '@vitest/pretty-format': 4.1.8 convert-source-map: 2.0.0 tinyrainbow: 3.1.0 @@ -12196,22 +12722,22 @@ snapshots: json-schema-traverse: 1.0.0 require-from-string: 2.0.2 - algoliasearch@5.52.1: - dependencies: - '@algolia/abtesting': 1.18.1 - '@algolia/client-abtesting': 5.52.1 - '@algolia/client-analytics': 5.52.1 - '@algolia/client-common': 5.52.1 - '@algolia/client-insights': 5.52.1 - '@algolia/client-personalization': 5.52.1 - '@algolia/client-query-suggestions': 5.52.1 - '@algolia/client-search': 5.52.1 - '@algolia/ingestion': 1.52.1 - '@algolia/monitoring': 1.52.1 - '@algolia/recommend': 5.52.1 - '@algolia/requester-browser-xhr': 5.52.1 - '@algolia/requester-fetch': 5.52.1 - '@algolia/requester-node-http': 5.52.1 + algoliasearch@5.53.0: + dependencies: + '@algolia/abtesting': 1.19.0 + '@algolia/client-abtesting': 5.53.0 + '@algolia/client-analytics': 5.53.0 + '@algolia/client-common': 5.53.0 + '@algolia/client-insights': 5.53.0 + '@algolia/client-personalization': 5.53.0 + '@algolia/client-query-suggestions': 5.53.0 + '@algolia/client-search': 5.53.0 + '@algolia/ingestion': 1.53.0 + '@algolia/monitoring': 1.53.0 + '@algolia/recommend': 5.53.0 + '@algolia/requester-browser-xhr': 5.53.0 + '@algolia/requester-fetch': 5.53.0 + '@algolia/requester-node-http': 5.53.0 ansi-colors@4.1.3: {} @@ -13357,9 +13883,9 @@ snapshots: escape-string-regexp@4.0.0: {} - eslint-config-prettier@10.1.8(eslint@10.4.0(jiti@2.7.0)): + eslint-config-prettier@10.1.8(eslint@10.4.1(jiti@2.7.0)): dependencies: - eslint: 10.4.0(jiti@2.7.0) + eslint: 10.4.1(jiti@2.7.0) eslint-import-resolver-node@0.3.10: dependencies: @@ -13369,17 +13895,17 @@ snapshots: transitivePeerDependencies: - supports-color - eslint-module-utils@2.12.1(@typescript-eslint/parser@8.60.0(eslint@10.4.0(jiti@2.7.0))(typescript@6.0.3))(eslint-import-resolver-node@0.3.10)(eslint@10.4.0(jiti@2.7.0)): + eslint-module-utils@2.12.1(@typescript-eslint/parser@8.60.1(eslint@10.4.1(jiti@2.7.0))(typescript@6.0.3))(eslint-import-resolver-node@0.3.10)(eslint@10.4.1(jiti@2.7.0)): dependencies: debug: 3.2.7 optionalDependencies: - '@typescript-eslint/parser': 8.60.0(eslint@10.4.0(jiti@2.7.0))(typescript@6.0.3) - eslint: 10.4.0(jiti@2.7.0) + '@typescript-eslint/parser': 8.60.1(eslint@10.4.1(jiti@2.7.0))(typescript@6.0.3) + eslint: 10.4.1(jiti@2.7.0) eslint-import-resolver-node: 0.3.10 transitivePeerDependencies: - supports-color - eslint-plugin-import@2.32.0(@typescript-eslint/parser@8.60.0(eslint@10.4.0(jiti@2.7.0))(typescript@6.0.3))(eslint@10.4.0(jiti@2.7.0)): + eslint-plugin-import@2.32.0(@typescript-eslint/parser@8.60.1(eslint@10.4.1(jiti@2.7.0))(typescript@6.0.3))(eslint@10.4.1(jiti@2.7.0)): dependencies: '@rtsao/scc': 1.1.0 array-includes: 3.1.9 @@ -13388,9 +13914,9 @@ snapshots: array.prototype.flatmap: 1.3.3 debug: 3.2.7 doctrine: 2.1.0 - eslint: 10.4.0(jiti@2.7.0) + eslint: 10.4.1(jiti@2.7.0) eslint-import-resolver-node: 0.3.10 - eslint-module-utils: 2.12.1(@typescript-eslint/parser@8.60.0(eslint@10.4.0(jiti@2.7.0))(typescript@6.0.3))(eslint-import-resolver-node@0.3.10)(eslint@10.4.0(jiti@2.7.0)) + eslint-module-utils: 2.12.1(@typescript-eslint/parser@8.60.1(eslint@10.4.1(jiti@2.7.0))(typescript@6.0.3))(eslint-import-resolver-node@0.3.10)(eslint@10.4.1(jiti@2.7.0)) hasown: 2.0.3 is-core-module: 2.16.2 is-glob: 4.0.3 @@ -13402,7 +13928,7 @@ snapshots: string.prototype.trimend: 1.0.9 tsconfig-paths: 3.15.0 optionalDependencies: - '@typescript-eslint/parser': 8.60.0(eslint@10.4.0(jiti@2.7.0))(typescript@6.0.3) + '@typescript-eslint/parser': 8.60.1(eslint@10.4.1(jiti@2.7.0))(typescript@6.0.3) transitivePeerDependencies: - eslint-import-resolver-typescript - eslint-import-resolver-webpack @@ -13426,14 +13952,14 @@ snapshots: eslint-visitor-keys@5.0.1: {} - eslint@10.4.0(jiti@2.7.0): + eslint@10.4.1(jiti@2.7.0): dependencies: - '@eslint-community/eslint-utils': 4.9.1(eslint@10.4.0(jiti@2.7.0)) + '@eslint-community/eslint-utils': 4.9.1(eslint@10.4.1(jiti@2.7.0)) '@eslint-community/regexpp': 4.12.2 '@eslint/config-array': 0.23.5 '@eslint/config-helpers': 0.6.0 '@eslint/core': 1.2.1 - '@eslint/plugin-kit': 0.7.1 + '@eslint/plugin-kit': 0.7.2 '@humanfs/node': 0.16.8 '@humanwhocodes/module-importer': 1.0.1 '@humanwhocodes/retry': 0.4.3 @@ -14792,7 +15318,7 @@ snapshots: rfdc: 1.4.1 wrap-ansi: 10.0.0 - lmdb@3.5.4: + lmdb@3.5.5: dependencies: '@harperfast/extended-iterable': 1.0.3 msgpackr: 1.11.12 @@ -14801,13 +15327,13 @@ snapshots: ordered-binary: 1.6.1 weak-lru-cache: 1.2.2 optionalDependencies: - '@lmdb/lmdb-darwin-arm64': 3.5.4 - '@lmdb/lmdb-darwin-x64': 3.5.4 - '@lmdb/lmdb-linux-arm': 3.5.4 - '@lmdb/lmdb-linux-arm64': 3.5.4 - '@lmdb/lmdb-linux-x64': 3.5.4 - '@lmdb/lmdb-win32-arm64': 3.5.4 - '@lmdb/lmdb-win32-x64': 3.5.4 + '@lmdb/lmdb-darwin-arm64': 3.5.5 + '@lmdb/lmdb-darwin-x64': 3.5.5 + '@lmdb/lmdb-linux-arm': 3.5.5 + '@lmdb/lmdb-linux-arm64': 3.5.5 + '@lmdb/lmdb-linux-x64': 3.5.5 + '@lmdb/lmdb-win32-arm64': 3.5.5 + '@lmdb/lmdb-win32-x64': 3.5.5 optional: true loader-runner@4.3.2: {} @@ -15106,6 +15632,8 @@ snapshots: array-union: 3.0.1 minimatch: 10.2.5 + mute-stream@3.0.0: {} + mute-stream@4.0.0: {} nanoid@3.3.12: {} @@ -15945,26 +16473,26 @@ snapshots: dependencies: glob: 10.5.0 - rolldown@1.0.2: + rolldown@1.0.3: dependencies: - '@oxc-project/types': 0.132.0 + '@oxc-project/types': 0.133.0 '@rolldown/pluginutils': 1.0.1 optionalDependencies: - '@rolldown/binding-android-arm64': 1.0.2 - '@rolldown/binding-darwin-arm64': 1.0.2 - '@rolldown/binding-darwin-x64': 1.0.2 - '@rolldown/binding-freebsd-x64': 1.0.2 - '@rolldown/binding-linux-arm-gnueabihf': 1.0.2 - '@rolldown/binding-linux-arm64-gnu': 1.0.2 - '@rolldown/binding-linux-arm64-musl': 1.0.2 - '@rolldown/binding-linux-ppc64-gnu': 1.0.2 - '@rolldown/binding-linux-s390x-gnu': 1.0.2 - '@rolldown/binding-linux-x64-gnu': 1.0.2 - '@rolldown/binding-linux-x64-musl': 1.0.2 - '@rolldown/binding-openharmony-arm64': 1.0.2 - '@rolldown/binding-wasm32-wasi': 1.0.2 - '@rolldown/binding-win32-arm64-msvc': 1.0.2 - '@rolldown/binding-win32-x64-msvc': 1.0.2 + '@rolldown/binding-android-arm64': 1.0.3 + '@rolldown/binding-darwin-arm64': 1.0.3 + '@rolldown/binding-darwin-x64': 1.0.3 + '@rolldown/binding-freebsd-x64': 1.0.3 + '@rolldown/binding-linux-arm-gnueabihf': 1.0.3 + '@rolldown/binding-linux-arm64-gnu': 1.0.3 + '@rolldown/binding-linux-arm64-musl': 1.0.3 + '@rolldown/binding-linux-ppc64-gnu': 1.0.3 + '@rolldown/binding-linux-s390x-gnu': 1.0.3 + '@rolldown/binding-linux-x64-gnu': 1.0.3 + '@rolldown/binding-linux-x64-musl': 1.0.3 + '@rolldown/binding-openharmony-arm64': 1.0.3 + '@rolldown/binding-wasm32-wasi': 1.0.3 + '@rolldown/binding-win32-arm64-msvc': 1.0.3 + '@rolldown/binding-win32-x64-msvc': 1.0.3 rollup-license-plugin@3.2.1: dependencies: @@ -15984,10 +16512,21 @@ snapshots: optionalDependencies: '@babel/code-frame': 7.29.7 - rollup-plugin-sourcemaps2@0.5.7(@types/node@22.19.19)(rollup@4.60.4): + rollup-plugin-dts@6.4.1(rollup@4.61.0)(typescript@6.0.3): dependencies: - '@rollup/pluginutils': 5.3.0(rollup@4.60.4) - rollup: 4.60.4 + '@jridgewell/remapping': 2.3.5 + '@jridgewell/sourcemap-codec': 1.5.5 + convert-source-map: 2.0.0 + magic-string: 0.30.21 + rollup: 4.61.0 + typescript: 6.0.3 + optionalDependencies: + '@babel/code-frame': 7.29.7 + + rollup-plugin-sourcemaps2@0.5.7(@types/node@22.19.19)(rollup@4.61.0): + dependencies: + '@rollup/pluginutils': 5.3.0(rollup@4.61.0) + rollup: 4.61.0 optionalDependencies: '@types/node': 22.19.19 @@ -16022,6 +16561,37 @@ snapshots: '@rollup/rollup-win32-x64-msvc': 4.60.4 fsevents: 2.3.3 + rollup@4.61.0: + dependencies: + '@types/estree': 1.0.9 + optionalDependencies: + '@rollup/rollup-android-arm-eabi': 4.61.0 + '@rollup/rollup-android-arm64': 4.61.0 + '@rollup/rollup-darwin-arm64': 4.61.0 + '@rollup/rollup-darwin-x64': 4.61.0 + '@rollup/rollup-freebsd-arm64': 4.61.0 + '@rollup/rollup-freebsd-x64': 4.61.0 + '@rollup/rollup-linux-arm-gnueabihf': 4.61.0 + '@rollup/rollup-linux-arm-musleabihf': 4.61.0 + '@rollup/rollup-linux-arm64-gnu': 4.61.0 + '@rollup/rollup-linux-arm64-musl': 4.61.0 + '@rollup/rollup-linux-loong64-gnu': 4.61.0 + '@rollup/rollup-linux-loong64-musl': 4.61.0 + '@rollup/rollup-linux-ppc64-gnu': 4.61.0 + '@rollup/rollup-linux-ppc64-musl': 4.61.0 + '@rollup/rollup-linux-riscv64-gnu': 4.61.0 + '@rollup/rollup-linux-riscv64-musl': 4.61.0 + '@rollup/rollup-linux-s390x-gnu': 4.61.0 + '@rollup/rollup-linux-x64-gnu': 4.61.0 + '@rollup/rollup-linux-x64-musl': 4.61.0 + '@rollup/rollup-openbsd-x64': 4.61.0 + '@rollup/rollup-openharmony-arm64': 4.61.0 + '@rollup/rollup-win32-arm64-msvc': 4.61.0 + '@rollup/rollup-win32-ia32-msvc': 4.61.0 + '@rollup/rollup-win32-x64-gnu': 4.61.0 + '@rollup/rollup-win32-x64-msvc': 4.61.0 + fsevents: 2.3.3 + router@2.2.0: dependencies: debug: 4.4.3(supports-color@10.2.2) @@ -16685,6 +17255,11 @@ snapshots: fdir: 6.5.0(picomatch@4.0.4) picomatch: 4.0.4 + tinyglobby@0.2.17: + dependencies: + fdir: 6.5.0(picomatch@4.0.4) + picomatch: 4.0.4 + tinyrainbow@3.1.0: {} tldts-core@6.1.86: {} @@ -17018,15 +17593,33 @@ snapshots: tsx: 4.22.3 yaml: 2.9.0 - vitest@4.1.7(@opentelemetry/api@1.9.1)(@types/node@24.12.4)(@vitest/coverage-v8@4.1.7)(jiti@2.7.0)(jsdom@29.1.1)(less@4.6.4)(sass@1.100.0)(terser@5.48.0)(tsx@4.22.3)(yaml@2.9.0): + vite@7.3.5(@types/node@24.12.4)(jiti@2.7.0)(less@4.6.4)(sass@1.100.0)(terser@5.48.0)(tsx@4.22.3)(yaml@2.9.0): + dependencies: + esbuild: 0.27.7 + fdir: 6.5.0(picomatch@4.0.4) + picomatch: 4.0.4 + postcss: 8.5.15 + rollup: 4.60.4 + tinyglobby: 0.2.16 + optionalDependencies: + '@types/node': 24.12.4 + fsevents: 2.3.3 + jiti: 2.7.0 + less: 4.6.4 + sass: 1.100.0 + terser: 5.48.0 + tsx: 4.22.3 + yaml: 2.9.0 + + vitest@4.1.8(@opentelemetry/api@1.9.1)(@types/node@24.12.4)(@vitest/coverage-v8@4.1.8)(jiti@2.7.0)(jsdom@29.1.1)(less@4.6.4)(sass@1.100.0)(terser@5.48.0)(tsx@4.22.3)(yaml@2.9.0): dependencies: - '@vitest/expect': 4.1.7 - '@vitest/mocker': 4.1.7(vite@7.3.3(@types/node@24.12.4)(jiti@2.7.0)(less@4.6.4)(sass@1.100.0)(terser@5.48.0)(tsx@4.22.3)(yaml@2.9.0)) - '@vitest/pretty-format': 4.1.7 - '@vitest/runner': 4.1.7 - '@vitest/snapshot': 4.1.7 - '@vitest/spy': 4.1.7 - '@vitest/utils': 4.1.7 + '@vitest/expect': 4.1.8 + '@vitest/mocker': 4.1.8(vite@7.3.3(@types/node@24.12.4)(jiti@2.7.0)(less@4.6.4)(sass@1.100.0)(terser@5.48.0)(tsx@4.22.3)(yaml@2.9.0)) + '@vitest/pretty-format': 4.1.8 + '@vitest/runner': 4.1.8 + '@vitest/snapshot': 4.1.8 + '@vitest/spy': 4.1.8 + '@vitest/utils': 4.1.8 es-module-lexer: 2.1.0 expect-type: 1.3.0 magic-string: 0.30.21 @@ -17043,7 +17636,7 @@ snapshots: optionalDependencies: '@opentelemetry/api': 1.9.1 '@types/node': 24.12.4 - '@vitest/coverage-v8': 4.1.7(vitest@4.1.7) + '@vitest/coverage-v8': 4.1.8(vitest@4.1.8) jsdom: 29.1.1 transitivePeerDependencies: - jiti From 9931007163eaaf402fcceab4ab3d443710dcd363 Mon Sep 17 00:00:00 2001 From: Angular Robot Date: Thu, 4 Jun 2026 06:57:46 +0000 Subject: [PATCH 011/787] build: update bazel dependencies See associated pull request for more information. --- MODULE.bazel | 4 ++-- MODULE.bazel.lock | 23 ++++++++++++----------- 2 files changed, 14 insertions(+), 13 deletions(-) diff --git a/MODULE.bazel b/MODULE.bazel index 1bb78a1895be..ec09798fcde4 100644 --- a/MODULE.bazel +++ b/MODULE.bazel @@ -7,10 +7,10 @@ module( bazel_dep(name = "platforms", version = "1.1.0") bazel_dep(name = "yq.bzl", version = "0.3.6") bazel_dep(name = "rules_nodejs", version = "6.7.4") -bazel_dep(name = "aspect_rules_js", version = "3.1.2") +bazel_dep(name = "aspect_rules_js", version = "3.2.0") bazel_dep(name = "aspect_rules_ts", version = "3.8.10") bazel_dep(name = "rules_pkg", version = "1.2.0") -bazel_dep(name = "rules_cc", version = "0.2.18") +bazel_dep(name = "rules_cc", version = "0.2.19") bazel_dep(name = "jq.bzl", version = "0.6.1") bazel_dep(name = "bazel_lib", version = "3.3.1") bazel_dep(name = "bazel_skylib", version = "1.9.0") diff --git a/MODULE.bazel.lock b/MODULE.bazel.lock index 0753cd1055ce..53f5ff646cb4 100644 --- a/MODULE.bazel.lock +++ b/MODULE.bazel.lock @@ -25,7 +25,8 @@ "https://bcr.bazel.build/modules/aspect_rules_js/2.0.0/MODULE.bazel": "b45b507574aa60a92796e3e13c195cd5744b3b8aff516a9c0cb5ae6a048161c5", "https://bcr.bazel.build/modules/aspect_rules_js/3.0.3/MODULE.bazel": "28a30e8fc33bf64a67835d64d124f6e05a7d59648dcb27b110fb3502f761e503", "https://bcr.bazel.build/modules/aspect_rules_js/3.1.2/MODULE.bazel": "e3685502155d3cc65f3bf98e714f7435de67d7f8f355d63478a80197310311fc", - "https://bcr.bazel.build/modules/aspect_rules_js/3.1.2/source.json": "a32ab71831452b945f3f83a1b1feb9402007e600bce55ac76e15ef0c1e08b520", + "https://bcr.bazel.build/modules/aspect_rules_js/3.2.0/MODULE.bazel": "c3d34345c51a4d90cf678d3b251c6f345b63d5e2e6b0253dbdda467a01efc31f", + "https://bcr.bazel.build/modules/aspect_rules_js/3.2.0/source.json": "3538ab18ac72ba3eaa3db0e4ec5171e04322768723afaa1149c0d822fe5411e2", "https://bcr.bazel.build/modules/aspect_rules_ts/3.8.10/MODULE.bazel": "a17a49a21226fc90163a29b3d6eac56703697205530b8d5cc38b3c074dbac039", "https://bcr.bazel.build/modules/aspect_rules_ts/3.8.10/source.json": "745c8dba237b4088409800143241bbb138e7ef37a359bd81a250c2c423f380ce", "https://bcr.bazel.build/modules/aspect_tools_telemetry/0.2.8/MODULE.bazel": "aa975a83e72bcaac62ee61ab12b788ea324a1d05c4aab28aadb202f647881679", @@ -44,8 +45,8 @@ "https://bcr.bazel.build/modules/bazel_features/1.39.0/MODULE.bazel": "28739425c1fc283c91931619749c832b555e60bcd1010b40d8441ce0a5cf726d", "https://bcr.bazel.build/modules/bazel_features/1.4.1/MODULE.bazel": "e45b6bb2350aff3e442ae1111c555e27eac1d915e77775f6fdc4b351b758b5d7", "https://bcr.bazel.build/modules/bazel_features/1.41.0/MODULE.bazel": "6e0f87fafed801273c371d41e22a15a6f8abf83fdd7f87d5e44ad317b94433d0", - "https://bcr.bazel.build/modules/bazel_features/1.43.0/MODULE.bazel": "defa2226f06ba20550d6548c3a2ea2a7929634437a52973869c20c225450eb91", - "https://bcr.bazel.build/modules/bazel_features/1.43.0/source.json": "1c4207dc858d6de0eecef30026793616bbf420c74aac27b6bad212534a730437", + "https://bcr.bazel.build/modules/bazel_features/1.47.0/MODULE.bazel": "e34df3cb35b1684cfa69923a61ae3803595babd3942cd306a488d51400886b30", + "https://bcr.bazel.build/modules/bazel_features/1.47.0/source.json": "4ba0b5138327f2d73352a51547a4e49a0a828ef400e046b15334d8905bf6b7ff", "https://bcr.bazel.build/modules/bazel_features/1.9.0/MODULE.bazel": "885151d58d90d8d9c811eb75e3288c11f850e1d6b481a8c9f766adee4712358b", "https://bcr.bazel.build/modules/bazel_features/1.9.1/MODULE.bazel": "8f679097876a9b609ad1f60249c49d68bfab783dd9be012faf9d82547b14815a", "https://bcr.bazel.build/modules/bazel_lib/3.0.0-rc.0/MODULE.bazel": "d6e00979a98ac14ada5e31c8794708b41434d461e7e7ca39b59b765e6d233b18", @@ -126,8 +127,8 @@ "https://bcr.bazel.build/modules/rules_cc/0.0.9/MODULE.bazel": "836e76439f354b89afe6a911a7adf59a6b2518fafb174483ad78a2a2fde7b1c5", "https://bcr.bazel.build/modules/rules_cc/0.1.1/MODULE.bazel": "2f0222a6f229f0bf44cd711dc13c858dad98c62d52bd51d8fc3a764a83125513", "https://bcr.bazel.build/modules/rules_cc/0.2.16/MODULE.bazel": "9242fa89f950c6ef7702801ab53922e99c69b02310c39fb6e62b2bd30df2a1d4", - "https://bcr.bazel.build/modules/rules_cc/0.2.18/MODULE.bazel": "4460ec36adc8f722a6a2a4ac9374cb91f2acebadaa93fc37966129afb3dece87", - "https://bcr.bazel.build/modules/rules_cc/0.2.18/source.json": "abad668ff2fd63ada1ac49bf386d37e27048b89a3465a6fd968bb832b00a09d3", + "https://bcr.bazel.build/modules/rules_cc/0.2.19/MODULE.bazel": "d5e0f05b63273281a16654eb6b1a8742a75ec153ac8b4f0419949d6e401e46f0", + "https://bcr.bazel.build/modules/rules_cc/0.2.19/source.json": "1ef48cdbd7aa6238015189b582d3d74ef0cbea3cb3e2cb259d782463f570c14a", "https://bcr.bazel.build/modules/rules_cc/0.2.4/MODULE.bazel": "1ff1223dfd24f3ecf8f028446d4a27608aa43c3f41e346d22838a4223980b8cc", "https://bcr.bazel.build/modules/rules_foreign_cc/0.9.0/MODULE.bazel": "c9e8c682bf75b0e7c704166d79b599f93b72cfca5ad7477df596947891feeef6", "https://bcr.bazel.build/modules/rules_fuzzing/0.5.2/MODULE.bazel": "40c97d1144356f52905566c55811f13b299453a14ac7769dfba2ac38192337a8", @@ -219,7 +220,7 @@ "moduleExtensions": { "@@aspect_rules_esbuild+//esbuild:extensions.bzl%esbuild": { "general": { - "bzlTransitiveDigest": "eWM29sOFdgwS2/XR2bEHk1NS/hPrYIX7ly4yh7MH5As=", + "bzlTransitiveDigest": "8bNoUkbLk1vCab3fXdV3RN1UoOjEcHlo/bk9XxZ7e3A=", "usagesDigest": "LSQ+zZp7JNgnBONTxxXnwGr4NTh2qtQYk7qwXXz5qWo=", "recordedFileInputs": {}, "recordedDirentsInputs": {}, @@ -498,7 +499,7 @@ "@@aspect_tools_telemetry+//:extension.bzl%telemetry": { "general": { "bzlTransitiveDigest": "cl5A2O84vDL6Tt+Qga8FCj1DUDGqn+e7ly5rZ+4xvcc=", - "usagesDigest": "SOv3fnWScyh5pAbfi8TO0WqlioqyUWt3t29KT0VkqLE=", + "usagesDigest": "bsm1cFI7hhC0zj7wvllOScDJKporKySjStBNr8xm+dY=", "recordedFileInputs": {}, "recordedDirentsInputs": {}, "envVariables": {}, @@ -507,7 +508,7 @@ "repoRuleId": "@@aspect_tools_telemetry+//:extension.bzl%tel_repository", "attributes": { "deps": { - "aspect_rules_js": "3.1.2", + "aspect_rules_js": "3.2.0", "aspect_rules_ts": "3.8.10", "aspect_rules_esbuild": "0.26.0", "aspect_rules_jasmine": "2.0.4", @@ -952,7 +953,7 @@ "@@rules_nodejs+//nodejs:extensions.bzl%node": { "general": { "bzlTransitiveDigest": "oZFClfRhTTwsYzpxVPkOpOt/r0+OzEfEV37au0jFZ0s=", - "usagesDigest": "28HwARS2PIkmyhXuiSyS1jAaG14m/bsZo/Sm+OPn2M8=", + "usagesDigest": "00+3uj4j6s/drSt+SUad8w/R4Rp2/GHGBsCgrKvF7mE=", "recordedFileInputs": {}, "recordedDirentsInputs": {}, "envVariables": {}, @@ -2603,7 +2604,7 @@ }, "@@rules_python+//python/extensions:pip.bzl%pip": { "general": { - "bzlTransitiveDigest": "1CieYf7PBGYmx4QxddIeJFyAiJ2OB1ah39h4F4rtjxo=", + "bzlTransitiveDigest": "JOGVSMFw3XSY/6/iPEgXTZqFR5YFbDaa20WiXWZ8m4U=", "usagesDigest": "AK1R124YPWwAs8z1CQYyjYuci8RO5Ofot+EP5ZCNQDc=", "recordedFileInputs": { "@@protobuf+//python/requirements.txt": "983be60d3cec4b319dcab6d48aeb3f5b2f7c3350f26b3a9e97486c37967c73c5", @@ -5342,7 +5343,7 @@ "@@yq.bzl+//yq:extensions.bzl%yq": { "general": { "bzlTransitiveDigest": "UfFMy8CWK4/dVo/tfaSAIYUiDGNAPes5eRllx9O9Q9Q=", - "usagesDigest": "8e3rbqq064p0a9Kvcmva2jmDBY/XStrYwTWmi2gmqTY=", + "usagesDigest": "6JGNN6+d6JD7F98c3T4zg7eUxkfsfsMEDemA2CIoNQQ=", "recordedFileInputs": {}, "recordedDirentsInputs": {}, "envVariables": {}, From be251999be4ac6ecc685347271db10ad3c04ee62 Mon Sep 17 00:00:00 2001 From: Charles Lyding <19598772+clydin@users.noreply.github.com> Date: Wed, 3 Jun 2026 18:10:04 -0400 Subject: [PATCH 012/787] fix(@angular/cli): validate registry option is a valid URL in ng add Ensure that the --registry option passed to ng add is parsed as a valid absolute URL. --- packages/angular/cli/src/commands/add/cli.ts | 12 ++++++++ .../e2e/tests/commands/add/registry-option.ts | 28 ++++++++++++++++++- 2 files changed, 39 insertions(+), 1 deletion(-) diff --git a/packages/angular/cli/src/commands/add/cli.ts b/packages/angular/cli/src/commands/add/cli.ts index b1c57a59ad45..dd78b7038120 100644 --- a/packages/angular/cli/src/commands/add/cli.ts +++ b/packages/angular/cli/src/commands/add/cli.ts @@ -16,6 +16,7 @@ import npa from 'npm-package-arg'; import semver, { Range, compare, intersects, prerelease, satisfies, valid } from 'semver'; import { Argv } from 'yargs'; import { + CommandModuleError, CommandModuleImplementation, Options, OtherOptions, @@ -131,6 +132,17 @@ export default class AddCommandModule type: 'boolean', default: false, }) + .check(({ registry }) => { + if (registry === undefined) { + return true; + } + + if (typeof registry === 'string' && URL.canParse(registry)) { + return true; + } + + throw new CommandModuleError('Option --registry must be a valid URL.'); + }) // Prior to downloading we don't know the full schema and therefore we cannot be strict on the options. // Possibly in the future update the logic to use the following syntax: // `ng add @angular/localize -- --package-options`. diff --git a/tests/e2e/tests/commands/add/registry-option.ts b/tests/e2e/tests/commands/add/registry-option.ts index dc336cdd5b30..1343cebf4dd1 100644 --- a/tests/e2e/tests/commands/add/registry-option.ts +++ b/tests/e2e/tests/commands/add/registry-option.ts @@ -1,11 +1,37 @@ import { getGlobalVariable } from '../../../utils/env'; import { expectFileToExist } from '../../../utils/fs'; -import { ng } from '../../../utils/process'; +import { execAndCaptureError, ng } from '../../../utils/process'; import { expectToFail } from '../../../utils/utils'; export default async function () { const testRegistry = getGlobalVariable('package-registry'); + // Validate that a non-URL registry string fails with a validation error + const error = await execAndCaptureError('ng', [ + 'add', + '--registry=not-a-valid-url', + '@angular/pwa', + '--skip-confirmation', + ]); + if (!error.message.includes('Option --registry must be a valid URL.')) { + throw new Error( + `Expected registry validation error, but got different error: ${error.message}`, + ); + } + + // Validate that an empty registry string fails with a validation error + const errorEmpty = await execAndCaptureError('ng', [ + 'add', + '--registry=', + '@angular/pwa', + '--skip-confirmation', + ]); + if (!errorEmpty.message.includes('Option --registry must be a valid URL.')) { + throw new Error( + `Expected registry validation error for empty string, but got: ${errorEmpty.message}`, + ); + } + // Set an invalid registry process.env['NPM_CONFIG_REGISTRY'] = 'http://127.0.0.1:9999'; From 3dac9e88be572d5203009648f8210a6dc6e62ebc Mon Sep 17 00:00:00 2001 From: Angular Robot Date: Thu, 4 Jun 2026 10:13:38 +0000 Subject: [PATCH 013/787] build: lock file maintenance See associated pull request for more information. --- pnpm-lock.yaml | 1115 ++++++++++++------------------------------------ 1 file changed, 271 insertions(+), 844 deletions(-) diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 1eef8da49336..1bbd8605856a 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -90,7 +90,7 @@ importers: version: 6.0.0(rollup@4.61.0) '@rollup/plugin-commonjs': specifier: ^29.0.0 - version: 29.0.2(rollup@4.61.0) + version: 29.0.3(rollup@4.61.0) '@rollup/plugin-json': specifier: ^6.1.0 version: 6.1.0(rollup@4.61.0) @@ -1012,7 +1012,7 @@ packages: rxjs: ^6.5.3 || ^7.4.0 '@angular/ng-dev@https://codeload.github.com/angular/dev-infra-private-ng-dev-builds/tar.gz/e882d214a66c8335dc38fe15ebeabeba85a0ea29': - resolution: {gitHosted: true, integrity: sha512-JAec9kjT065fvyeoiFW/iLaTTZ0QTpg6oiMVoV51l0o7HkIWoNIvIOyVk1WELR6Y2vEw0pNMdQQAlYEiQDshMA==, tarball: https://codeload.github.com/angular/dev-infra-private-ng-dev-builds/tar.gz/e882d214a66c8335dc38fe15ebeabeba85a0ea29} + resolution: {gitHosted: true, tarball: https://codeload.github.com/angular/dev-infra-private-ng-dev-builds/tar.gz/e882d214a66c8335dc38fe15ebeabeba85a0ea29} version: 0.0.0-b64a291ca373bc91e5ee876488710c026157bf91 hasBin: true @@ -2347,23 +2347,10 @@ packages: resolution: {integrity: sha512-bV0Tgo9K4hfPCek+aMAn81RppFKv2ySDQeMoSZuvTASywNTnVJCArCZE2FWqpvIatKu7VMRLWlR1EazvVhDyhQ==} engines: {node: '>=18.18'} - '@inquirer/ansi@2.0.6': - resolution: {integrity: sha512-I/INw4sHGlVZ/afZOckpLiDP9SmbMl1g/GCqeHjLw1Afw/0PlRs2tRFgTGWmdI0hoNuWZn3y2iHNmG1vyECyQQ==} - engines: {node: '>=23.5.0 || ^22.13.0 || ^21.7.0 || ^20.12.0'} - '@inquirer/ansi@2.0.7': resolution: {integrity: sha512-3eTuUO1vH2cZm2ZKHeQxnOqlTi9EfZDGgIe3BL3I4u+rJHocr9Fz86M4fjYABPvFnQG/gGK551HqDiIcETwU6Q==} engines: {node: '>=23.5.0 || ^22.13.0 || ^20.17.0'} - '@inquirer/checkbox@5.2.0': - resolution: {integrity: sha512-1HJt+3fqxblp/GQjdntSyoSHYBc0e3CzXVgjFpKA6qFLd9FHBBqwN8Co0xYH6t2JVUZrtFwZ4bBiwptkiLxyOg==} - engines: {node: '>=23.5.0 || ^22.13.0 || ^21.7.0 || ^20.12.0'} - peerDependencies: - '@types/node': '>=18' - peerDependenciesMeta: - '@types/node': - optional: true - '@inquirer/checkbox@5.2.1': resolution: {integrity: sha512-b6xmA/VlTe0ZgDQHDui+Nav470u7u49nRd8/iuhOcQPO9Ch7lGuogydhi2VOmNlZ+zXcM8IcPuNSwQcdJaF/kw==} engines: {node: '>=23.5.0 || ^22.13.0 || ^20.17.0'} @@ -2373,15 +2360,6 @@ packages: '@types/node': optional: true - '@inquirer/confirm@6.1.0': - resolution: {integrity: sha512-USpeB76eqK7yGricDlGAupxWlp4a59qpeZOoNWaxO/nJln7agpJveyNkQ1d5u8YXG6TOqxZtQpKPORQQDrdVsA==} - engines: {node: '>=23.5.0 || ^22.13.0 || ^21.7.0 || ^20.12.0'} - peerDependencies: - '@types/node': '>=18' - peerDependenciesMeta: - '@types/node': - optional: true - '@inquirer/confirm@6.1.1': resolution: {integrity: sha512-eb8DBZcz/2qHWQda4rk2JiQk5h9QV/cVHi1yjt0f69WFZMRFn0sJTye3EAP8icut8UDMjQPsaH5KbcOogefrFQ==} engines: {node: '>=23.5.0 || ^22.13.0 || ^20.17.0'} @@ -2391,15 +2369,6 @@ packages: '@types/node': optional: true - '@inquirer/core@11.2.0': - resolution: {integrity: sha512-joR1YS2sI0us+9d0I8ViqFbrRLONO8CFTuyvBX4ZVBSch+VsZiugUABdrhBXXJR1VyEzvpz5SQCix3keETQ58g==} - engines: {node: '>=23.5.0 || ^22.13.0 || ^21.7.0 || ^20.12.0'} - peerDependencies: - '@types/node': '>=18' - peerDependenciesMeta: - '@types/node': - optional: true - '@inquirer/core@11.2.1': resolution: {integrity: sha512-Qd6GJT1yVyrZZCfN8W2qKF5ApmqryXRhRKCuip8h01x2w/esJQ2XIYc6f9abMIHgKQdBfFTSOdbHRLAhuM09UA==} engines: {node: '>=23.5.0 || ^22.13.0 || ^20.17.0'} @@ -2409,15 +2378,6 @@ packages: '@types/node': optional: true - '@inquirer/editor@5.2.0': - resolution: {integrity: sha512-/m+sgRmzSdK6HDtVnl3PmI6MnZC4O+LLezedoJcrX7mINhTjjb0hlC7aEDGZXkFTB4b5uQ0q59AhYTah88KbNg==} - engines: {node: '>=23.5.0 || ^22.13.0 || ^21.7.0 || ^20.12.0'} - peerDependencies: - '@types/node': '>=18' - peerDependenciesMeta: - '@types/node': - optional: true - '@inquirer/editor@5.2.2': resolution: {integrity: sha512-ZRVd/oD+sYsUd5zVm0NflqEzlqfYCyHNsqkHl2oWXEUHs12tCbcSFi+wVFEvD8+LGRaMUsVrE7qeo6lSG/S1Vg==} engines: {node: '>=23.5.0 || ^22.13.0 || ^20.17.0'} @@ -2427,15 +2387,6 @@ packages: '@types/node': optional: true - '@inquirer/expand@5.1.0': - resolution: {integrity: sha512-fR7g4BVnIcs+4NApF6C5byflNM/EULxSxsv/2Jvg+gmop0R6eBIPvZqE6RYnTy1tQTFnf9wyHkwNoQSZbofaGA==} - engines: {node: '>=23.5.0 || ^22.13.0 || ^21.7.0 || ^20.12.0'} - peerDependencies: - '@types/node': '>=18' - peerDependenciesMeta: - '@types/node': - optional: true - '@inquirer/expand@5.1.1': resolution: {integrity: sha512-YmQpenjbFSHAK3sOd44puHh3V1KXXr+JiNpUztoSQ4drLh2rTVzTap/YtlAVu/5xavifIlBfNEzJ/neZJ1a/1g==} engines: {node: '>=23.5.0 || ^22.13.0 || ^20.17.0'} @@ -2445,15 +2396,6 @@ packages: '@types/node': optional: true - '@inquirer/external-editor@3.0.1': - resolution: {integrity: sha512-tam+Gwjsxg2sx3iUVPkAnhKT/yrk2rd2NAa7XJU/J8OYpU0ifXsnp12xlvzp/DCpWBXVv+vLQsqnpAWwUcWD5Q==} - engines: {node: '>=23.5.0 || ^22.13.0 || ^21.7.0 || ^20.12.0'} - peerDependencies: - '@types/node': '>=18' - peerDependenciesMeta: - '@types/node': - optional: true - '@inquirer/external-editor@3.0.3': resolution: {integrity: sha512-6thf5I8q7lZwzGLAxPaaGEREEkZ3nyePPDQ1oyobblxmEE8mqTLguScP7pDjUTAibiyb4hfXl+qjUEJ+di/aNA==} engines: {node: '>=23.5.0 || ^22.13.0 || ^20.17.0'} @@ -2463,23 +2405,10 @@ packages: '@types/node': optional: true - '@inquirer/figures@2.0.6': - resolution: {integrity: sha512-dsZgQtH2t5Q6ah3aPbZbeEZAxsD9qQu0DXf01AltuEfRTm+NoLN6+rLVbr+4edeEbNCp/wBNM6mALRWtsQpfkw==} - engines: {node: '>=23.5.0 || ^22.13.0 || ^21.7.0 || ^20.12.0'} - '@inquirer/figures@2.0.7': resolution: {integrity: sha512-aJ8TBPOGB6f/2qziPfElISTCEd5XOYTFckA2SGjhNmiKzfK/u4ot3v0DUzGVdUnKjN10EqnnEPck36BkyfLnJw==} engines: {node: '>=23.5.0 || ^22.13.0 || ^20.17.0'} - '@inquirer/input@5.1.0': - resolution: {integrity: sha512-sVZCz6P6e8tW5g2bSFel1oLpa6jK/u7BexFfrgTqR8syIdnHqy+iopnlSbYBZMsCK52chLjhGNBxt0eRqhsghw==} - engines: {node: '>=23.5.0 || ^22.13.0 || ^21.7.0 || ^20.12.0'} - peerDependencies: - '@types/node': '>=18' - peerDependenciesMeta: - '@types/node': - optional: true - '@inquirer/input@5.1.2': resolution: {integrity: sha512-9K/DDBSQpOyZSkt6sOVP9Vo0TR7atX2kuILsUu0x3wVcVbe97lJwIJKMLdMw25tDYuXl/qp6erT0Xs1rfmcfZg==} engines: {node: '>=23.5.0 || ^22.13.0 || ^20.17.0'} @@ -2489,15 +2418,6 @@ packages: '@types/node': optional: true - '@inquirer/number@4.1.0': - resolution: {integrity: sha512-VMXB/XejCbaSTf9Xucl7dqjzzsaGsrs6XwSYXPbGZ2QbSuq/Gz8XamhSi9ClRubNXZlGry9xVg1tKkJdTDgCtQ==} - engines: {node: '>=23.5.0 || ^22.13.0 || ^21.7.0 || ^20.12.0'} - peerDependencies: - '@types/node': '>=18' - peerDependenciesMeta: - '@types/node': - optional: true - '@inquirer/number@4.1.1': resolution: {integrity: sha512-XF4IXAbPnGPgw0wsbC/i2tPcyfdZgDpUlhsqU0SfT4IRIGWha6Xm9VRgN5yYxJq+jnyXlfXI/nQ3ulfk0iEICA==} engines: {node: '>=23.5.0 || ^22.13.0 || ^20.17.0'} @@ -2507,15 +2427,6 @@ packages: '@types/node': optional: true - '@inquirer/password@5.1.0': - resolution: {integrity: sha512-5tqRuKCDIUxdPxTI/CuLnh914kz+WMPmURHKnZgui9gk43ebudEsdu4EwSn1CPSi5R+17YpBG+ba/YqTnRAcJA==} - engines: {node: '>=23.5.0 || ^22.13.0 || ^21.7.0 || ^20.12.0'} - peerDependencies: - '@types/node': '>=18' - peerDependenciesMeta: - '@types/node': - optional: true - '@inquirer/password@5.1.1': resolution: {integrity: sha512-3XBfF7DAsp5qeDsvN5Rd1HmbNokVvEQoUM0QLrRcybC9nX96w3Pbmu7qUsb3IT3J3jBvs2+mTXaKHOUsgHMLzg==} engines: {node: '>=23.5.0 || ^22.13.0 || ^20.17.0'} @@ -2543,15 +2454,6 @@ packages: '@types/node': optional: true - '@inquirer/rawlist@5.3.0': - resolution: {integrity: sha512-p+vAeTAD+cGXjGleP1F5LXrX2ISxNDZm+lqeBpnJausNLSZskZZkcggwhomqP8Igx9oIjnoeOrw98xvdFvdm2w==} - engines: {node: '>=23.5.0 || ^22.13.0 || ^21.7.0 || ^20.12.0'} - peerDependencies: - '@types/node': '>=18' - peerDependenciesMeta: - '@types/node': - optional: true - '@inquirer/rawlist@5.3.1': resolution: {integrity: sha512-QqdTqQddL3qPX/PPrjobpsO25NZ4dWXgTLenrR445L2ptLEYE6Z+PD5c5CNDJNx4ugRgELAIpSIJxZaO2jJ2Og==} engines: {node: '>=23.5.0 || ^22.13.0 || ^20.17.0'} @@ -2561,15 +2463,6 @@ packages: '@types/node': optional: true - '@inquirer/search@4.2.0': - resolution: {integrity: sha512-ByURoSGIaSl5O5Q0AmYmVmUsXbMUcBGNoA3FRL7TOyiA22IeFHymJKRkuILbOIlJwqnBk7AnPpseodyFUBzg+g==} - engines: {node: '>=23.5.0 || ^22.13.0 || ^21.7.0 || ^20.12.0'} - peerDependencies: - '@types/node': '>=18' - peerDependenciesMeta: - '@types/node': - optional: true - '@inquirer/search@4.2.1': resolution: {integrity: sha512-xJj8QWKRSrfKoBIITLZK61dD3zwo0Rz11fgDImku30/Oe81zMdIdGgrLY2h6RkJ+KZ/GhNYIRMKnH/62qBTA5g==} engines: {node: '>=23.5.0 || ^22.13.0 || ^20.17.0'} @@ -2579,15 +2472,6 @@ packages: '@types/node': optional: true - '@inquirer/select@5.2.0': - resolution: {integrity: sha512-6IzkcmEbEXfgVbxZ2d1UyJFbCBoc6dTofulFmrYuomIp88HXiVqRbqbg4/mbfZhvnNo6xYmnYo2AEmDof6fQkg==} - engines: {node: '>=23.5.0 || ^22.13.0 || ^21.7.0 || ^20.12.0'} - peerDependencies: - '@types/node': '>=18' - peerDependenciesMeta: - '@types/node': - optional: true - '@inquirer/select@5.2.1': resolution: {integrity: sha512-FlDndEUww8m7BfukO2nJa25vhD+H5jxxCv4oGioKqzyWz3nPHhhw4LKdYRSlXuAx7DsdWia7iyaBPKKS95Evfw==} engines: {node: '>=23.5.0 || ^22.13.0 || ^20.17.0'} @@ -2606,15 +2490,6 @@ packages: '@types/node': optional: true - '@inquirer/type@4.0.6': - resolution: {integrity: sha512-J+9tdxOskuYuGjsvGaq00AamhDgjR7anhEW2dP4QdQpFCMPngCeC/bCYWQ5NsMWZRdsy53is7kAHb/+7cwDk2g==} - engines: {node: '>=23.5.0 || ^22.13.0 || ^21.7.0 || ^20.12.0'} - peerDependencies: - '@types/node': '>=18' - peerDependenciesMeta: - '@types/node': - optional: true - '@inquirer/type@4.0.7': resolution: {integrity: sha512-t28inv14nMQ1PhKpsJPY+kEs/c00qzeCOS2gTNRyTjG5d6qsVA2fItxW4hkvGZ5lvanGLdtCzVIx5dwdRpN1+g==} engines: {node: '>=23.5.0 || ^22.13.0 || ^20.17.0'} @@ -2697,50 +2572,50 @@ packages: peerDependencies: tslib: '2' - '@jsonjoy.com/fs-core@4.57.2': - resolution: {integrity: sha512-SVjwklkpIV5wrynpYtuYnfYH1QF4/nDuLBX7VXdb+3miglcAgBVZb/5y0cOsehRV/9Vb+3UqhkMq3/NR3ztdkQ==} + '@jsonjoy.com/fs-core@4.57.5': + resolution: {integrity: sha512-wl7eAKUwOcEZ8lL2/C38+w6VnNtBiNmvzKstlKPqRV/ymzg/7Aal5H74HEazSM2khYn9XG20I3fRp0Wr7xIbHA==} engines: {node: '>=10.0'} peerDependencies: tslib: '2' - '@jsonjoy.com/fs-fsa@4.57.2': - resolution: {integrity: sha512-fhO8+iR2I+OCw668ISDJdn1aArc9zx033sWejIyzQ8RBeXa9bDSaUeA3ix0poYOfrj1KdOzytmYNv2/uLDfV6g==} + '@jsonjoy.com/fs-fsa@4.57.5': + resolution: {integrity: sha512-zIUMYeOgAdhA1M3JvceA2Fli7qas2WJrv6qmruXbq81bgIRKUM1LueJ1G0VRPk4D8wfOceBpayWQZqSEXA0AGA==} engines: {node: '>=10.0'} peerDependencies: tslib: '2' - '@jsonjoy.com/fs-node-builtins@4.57.2': - resolution: {integrity: sha512-xhiegylRmhw43Ki2HO1ZBL7DQ5ja/qpRsL29VtQ2xuUHiuDGbgf2uD4p9Qd8hJI5P6RCtGYD50IXHXVq/Ocjcg==} + '@jsonjoy.com/fs-node-builtins@4.57.5': + resolution: {integrity: sha512-maev+EH0kBJt7R6GZQgRmL5cHvs46PS71Y5M1FfZKN2/JVSAZPpdrLS+z7KYrvPn4oIYMKcG/XAhircG3eP88g==} engines: {node: '>=10.0'} peerDependencies: tslib: '2' - '@jsonjoy.com/fs-node-to-fsa@4.57.2': - resolution: {integrity: sha512-18LmWTSONhoAPW+IWRuf8w/+zRolPFGPeGwMxlAhhfY11EKzX+5XHDBPAw67dBF5dxDErHJbl40U+3IXSDRXSQ==} + '@jsonjoy.com/fs-node-to-fsa@4.57.5': + resolution: {integrity: sha512-6IQi4TNoR1d+cSRZisWh6eqQ2mq32qgwESjVeXDs2pMWa+H/pZ24kSJKrDkyooUIfk1OIe40Dv9bnqc0FMcFjQ==} engines: {node: '>=10.0'} peerDependencies: tslib: '2' - '@jsonjoy.com/fs-node-utils@4.57.2': - resolution: {integrity: sha512-rsPSJgekz43IlNbLyAM/Ab+ouYLWGp5DDBfYBNNEqDaSpsbXfthBn29Q4muFA9L0F+Z3mKo+CWlgSCXrf+mOyQ==} + '@jsonjoy.com/fs-node-utils@4.57.5': + resolution: {integrity: sha512-u8GXaNr2VeQvHBXbJ9byY6GWP5z3HK3kCmdEPwVzjcgpEyAPjNnl0alP3Ylo6Aa4JSS8Ssc/F4+q69/03J2bUA==} engines: {node: '>=10.0'} peerDependencies: tslib: '2' - '@jsonjoy.com/fs-node@4.57.2': - resolution: {integrity: sha512-nX2AdL6cOFwLdju9G4/nbRnYevmCJbh7N7hvR3gGm97Cs60uEjyd0rpR+YBS7cTg175zzl22pGKXR5USaQMvKg==} + '@jsonjoy.com/fs-node@4.57.5': + resolution: {integrity: sha512-F6kdnfsmK6q+WEjGhCOd/2iJpcmffj8q3qgXUG1/gHMXaThZp30Ienk3eMT+GfOpEbuVqoPvqNe8IwiPlDk/QQ==} engines: {node: '>=10.0'} peerDependencies: tslib: '2' - '@jsonjoy.com/fs-print@4.57.2': - resolution: {integrity: sha512-wK9NSow48i4DbDl9F1CQE5TqnyZOJ04elU3WFG5aJ76p+YxO/ulyBBQvKsessPxdo381Bc2pcEoyPujMOhcRqQ==} + '@jsonjoy.com/fs-print@4.57.5': + resolution: {integrity: sha512-fTcwBpqk9CEmzYd4Un4WxemvWbS69dGFEQgYmCQ0q02xsMzsZcTKzd3kduB46DBhjRTK77ga4HIQe08Oyn86kg==} engines: {node: '>=10.0'} peerDependencies: tslib: '2' - '@jsonjoy.com/fs-snapshot@4.57.2': - resolution: {integrity: sha512-GdduDZuoP5V/QCgJkx9+BZ6SC0EZ/smXAdTS7PfMqgMTGXLlt/bH/FqMYaqB9JmLf05sJPtO0XRbAwwkEEPbVw==} + '@jsonjoy.com/fs-snapshot@4.57.5': + resolution: {integrity: sha512-oAUUlG+E4uBw5sFERdMu3FRqt0hEM6jVCIKWkj194xiWppfShAqbMK5G3PahBXfGiTtlJjYErUWDbX3UhQhldw==} engines: {node: '>=10.0'} peerDependencies: tslib: '2' @@ -3005,8 +2880,8 @@ packages: resolution: {integrity: sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==} engines: {node: '>= 8'} - '@npmcli/agent@4.0.0': - resolution: {integrity: sha512-kAQTcEN9E8ERLVg5AsGwLNoFb+oEG6engbqAU2P43gD4JEIkNGMHdVQ096FsOAAYpZPB0RSt0zgInKIAS1l5QA==} + '@npmcli/agent@4.0.2': + resolution: {integrity: sha512-EUEuWAxnL07Sp5/iC/1X6Xj+XThUvnbei9zfRWZdEXa7lss9RTHMhAHBeg+MZ5To9s/gGaSI+UwZTPdYMvKSeg==} engines: {node: ^20.17.0 || >=22.9.0} '@npmcli/fs@5.0.0': @@ -3452,8 +3327,8 @@ packages: rollup: optional: true - '@rollup/plugin-commonjs@29.0.2': - resolution: {integrity: sha512-S/ggWH1LU7jTyi9DxZOKyxpVd4hF/OZ0JrEbeLjXk/DFXwRny0tjD2c992zOUYQobLrVkRVMDdmHP16HKP7GRg==} + '@rollup/plugin-commonjs@29.0.3': + resolution: {integrity: sha512-ZaOxZceP7SOUW7Lqw5IRVweSQYWaeIPnXIGLiB690EBA3FGJTO40EEr2L5yZplJWsgTCogILRSpcAe7+U0Otdg==} engines: {node: '>=16.0.0 || 14 >= 14.17'} peerDependencies: rollup: ^2.68.0||^3.0.0||^4.0.0 @@ -3488,287 +3363,153 @@ packages: rollup: optional: true - '@rollup/rollup-android-arm-eabi@4.60.4': - resolution: {integrity: sha512-F5QXMSiFebS9hKZj02XhWLLnRpJ3B3AROP0tWbFBSj+6kCbg5m9j5JoHKd4mmSVy5mS/IMQloYgYxCuJC0fxEQ==} - cpu: [arm] - os: [android] + '@rollup/pluginutils@5.4.0': + resolution: {integrity: sha512-MfPp06CjRLfXQ3wY0R8vJDYBy/MvVcc9OulEfR0B8Iv9ko+GCNaRZ+EpJYFl27LhKsZK0o420sYCRHCjfCgeUg==} + engines: {node: '>=14.0.0'} + peerDependencies: + rollup: ^1.20.0||^2.0.0||^3.0.0||^4.0.0 + peerDependenciesMeta: + rollup: + optional: true '@rollup/rollup-android-arm-eabi@4.61.0': resolution: {integrity: sha512-dnxczajOqt0gesZlN5pGQ1s1imQVrsmCw5G2Ci4oM+0WvNz3pyRnlWrT7McoZIb8VlFwCawdmbWRmxRn7HI+VQ==} cpu: [arm] os: [android] - '@rollup/rollup-android-arm64@4.60.4': - resolution: {integrity: sha512-GxxTKApUpzRhof7poWvCJHRF51C67u1R7D6DiluBE8wKU1u5GWE8t+v81JvJYtbawoBFX1hLv5Ei4eVjkWokaw==} - cpu: [arm64] - os: [android] - '@rollup/rollup-android-arm64@4.61.0': resolution: {integrity: sha512-Bp3JpGP00Vu3f238ivRrjf7z3xSzVPXqCmaJYA9t2c+c8vKYvOzmXF7LkkeUalTEGd6cZcSWe+PFIP3Vy48fRg==} cpu: [arm64] os: [android] - '@rollup/rollup-darwin-arm64@4.60.4': - resolution: {integrity: sha512-tua0TaJxMOB1R0V0RS1jFZ/RpURFDJIOR2A6jWwQeawuFyS4gBW+rntLRaQd0EQ4bd6Vp44Z2rXW+YYDBsj6IA==} - cpu: [arm64] - os: [darwin] - '@rollup/rollup-darwin-arm64@4.61.0': resolution: {integrity: sha512-zaYIpr670mUmmZ1tVzUFplbQbG7h3Gugx3L5FoqhsC2m/YnLlR1a7zVLmXNPy+iY1tFPEbNG+HHBXZGyId0G5w==} cpu: [arm64] os: [darwin] - '@rollup/rollup-darwin-x64@4.60.4': - resolution: {integrity: sha512-CSKq7MsP+5PFIcydhAiR1K0UhEI1A2jWXVKHPCBZ151yOutENwvnPocgVHkivu2kviURtCEB6zUQw0vs8RrhMg==} - cpu: [x64] - os: [darwin] - '@rollup/rollup-darwin-x64@4.61.0': resolution: {integrity: sha512-+P49fvkv2dSoeevUW+lgZ/I2JHSsJCK1Lyjj7Cu6E4UHG4tS9XIefzIjo5qhgELjAclnen1rLzK2PMKJdo+Dyg==} cpu: [x64] os: [darwin] - '@rollup/rollup-freebsd-arm64@4.60.4': - resolution: {integrity: sha512-+O8OkVdyvXMtJEciu2wS/pzm1IxntEEQx3z5TAVy4l32G0etZn+RsA48ARRrFm6Ri8fvqPQfgrvNxSjKAbnd3g==} - cpu: [arm64] - os: [freebsd] - '@rollup/rollup-freebsd-arm64@4.61.0': resolution: {integrity: sha512-l3FAAOyKJXH2ea6KNFN+MMgC/rnE94YGLXs2ehYqDcCoHt1DpvgWX75BhUJxN38XojP7Ul+4H8PRn7EdyqSDrw==} cpu: [arm64] os: [freebsd] - '@rollup/rollup-freebsd-x64@4.60.4': - resolution: {integrity: sha512-Iw3oMskH3AfNuhU0MSN7vNbdi4me/NiYo2azqPz/Le16zHSa+3RRmliCMWWQmh4lcndccU40xcJuTYJZxNo/lw==} - cpu: [x64] - os: [freebsd] - '@rollup/rollup-freebsd-x64@4.61.0': resolution: {integrity: sha512-VokPN3TSctKj65cyCNPaUh4vMFA8awxOot/0sp+4J7ZlNRKQEhXhawqPwajoi8H5ZFt61i0ugZJuTKXBjGJ17Q==} cpu: [x64] os: [freebsd] - '@rollup/rollup-linux-arm-gnueabihf@4.60.4': - resolution: {integrity: sha512-EIPRXTVQpHyF8WOo219AD2yEltPehLTcTMz2fn6JsatLYSzQf00hj3rulF+yauOlF9/FtM2WpkT/hJh/KJFGhA==} - cpu: [arm] - os: [linux] - libc: [glibc] - '@rollup/rollup-linux-arm-gnueabihf@4.61.0': resolution: {integrity: sha512-DxH0P3wxm+Yzs/p3zrk9dw1rURu8p0Nv5+MRK/L7OtnLNg5rLZraSBFZ8iUXOd9f2BlhJyEpIZUH/emjq4UJ4g==} cpu: [arm] os: [linux] libc: [glibc] - '@rollup/rollup-linux-arm-musleabihf@4.60.4': - resolution: {integrity: sha512-J3Yh9PzzF1Ovah2At+lHiGQdsYgArxBbXv/zHfSyaiFQEqvNv7DcW98pCrmdjCZBrqBiKrKKe2V+aaSGWuBe/w==} - cpu: [arm] - os: [linux] - libc: [musl] - '@rollup/rollup-linux-arm-musleabihf@4.61.0': resolution: {integrity: sha512-T6ZvMNe84kAz6TBWHC7hGAoEtzP1LWYw/AqayGWEF6uISt3Abk/st06LqRD9THd7Xz3NxzurUpzAuEAUbZf+nw==} cpu: [arm] os: [linux] libc: [musl] - '@rollup/rollup-linux-arm64-gnu@4.60.4': - resolution: {integrity: sha512-BFDEZMYfUvLn37ONE1yMBojPxnMlTFsdyNoqncT0qFq1mAfllL+ATMMJd8TeuVMiX84s1KbcxcZbXInmcO2mRg==} - cpu: [arm64] - os: [linux] - libc: [glibc] - '@rollup/rollup-linux-arm64-gnu@4.61.0': resolution: {integrity: sha512-q/4hzvQkDs8b4jIBab1pnLiiM0ayTZsN2amBFPDzuyZxjEd4wDwx0UJFYM3cOZzSf5Kw8fnWSprJzIBMkcR44Q==} cpu: [arm64] os: [linux] libc: [glibc] - '@rollup/rollup-linux-arm64-musl@4.60.4': - resolution: {integrity: sha512-pc9EYOSlOgdQ2uPl1o9PF6/kLSgaUosia7gOuS8mB69IxJvlclko1MECXysjs5ryez1/5zjYqx3+xYU0TU6R1A==} - cpu: [arm64] - os: [linux] - libc: [musl] - '@rollup/rollup-linux-arm64-musl@4.61.0': resolution: {integrity: sha512-vvYWX3akdEAY6km+9wAqFDnk6pQsbJKVnj7xawcvs/+fdlYBGp+U+Qq/lLfpIxYIZvZLHMAKD9HLdacSx/r3dw==} cpu: [arm64] os: [linux] libc: [musl] - '@rollup/rollup-linux-loong64-gnu@4.60.4': - resolution: {integrity: sha512-NxnomyxYerDh5n4iLrNa+sH+Z+U4BMEE46V2PgQ/hoB909i8gV1M5wPojWg9fk1jWpO3IQnOs20K4wyZuFLEFQ==} - cpu: [loong64] - os: [linux] - libc: [glibc] - '@rollup/rollup-linux-loong64-gnu@4.61.0': resolution: {integrity: sha512-DePa5cqOxDP/Zp0VOXpeWaGew5iIv5DXp9NYbzkX5PFQyWVX9184WCTh3hvr/7lhXo8ZVlbFLkz8+o/q1dU6gA==} cpu: [loong64] os: [linux] libc: [glibc] - '@rollup/rollup-linux-loong64-musl@4.60.4': - resolution: {integrity: sha512-nbJnQ8a3z1mtmrwImCYhc6BGpThAyYVRQxw9uKSKG4wR6aAYno9sVjJ0zaZcW9BPJX1GbrDPf+SvdWjgTuDmnw==} - cpu: [loong64] - os: [linux] - libc: [musl] - '@rollup/rollup-linux-loong64-musl@4.61.0': resolution: {integrity: sha512-LV8aWMB8UChglMCEzs7RkN0GsH29RJaLLqwm9fCIjlqwxQTiWAqNcc7wjBkH31hV0PU/yVxGYvrYsgfea2qw6g==} cpu: [loong64] os: [linux] libc: [musl] - '@rollup/rollup-linux-ppc64-gnu@4.60.4': - resolution: {integrity: sha512-2EU6acNrQLd8tYvo/LXW535wupT3m6fo7HKo6lr7ktQoItxTyOL1ZCR/GfGCuXl2vR+zmfI6eRXkSemafv+iVg==} - cpu: [ppc64] - os: [linux] - libc: [glibc] - '@rollup/rollup-linux-ppc64-gnu@4.61.0': resolution: {integrity: sha512-QoNSnwQtaeNu5grdBbsL0tt1uyl5EnS8DA8Mr3nluMXbhdQNyhN+G4tBax7VCdxLKj8YJ0/4OO9Ho84jMnJtKA==} cpu: [ppc64] os: [linux] libc: [glibc] - '@rollup/rollup-linux-ppc64-musl@4.60.4': - resolution: {integrity: sha512-WeBtoMuaMxiiIrO2IYP3xs6GMWkJP2C0EoT8beTLkUPmzV1i/UcOSVw1d5r9KBODtHKilG5yFxsGRnBbK3wJ4A==} - cpu: [ppc64] - os: [linux] - libc: [musl] - '@rollup/rollup-linux-ppc64-musl@4.61.0': resolution: {integrity: sha512-/zZp5MKapIIApE8trN8qLGNSiRN9TUoaUZ1cmVu4XnVdd5LQLOXTtyi+vtfUbNnT3iyjzpPqYeKXmvJ+gJGYWw==} cpu: [ppc64] os: [linux] libc: [musl] - '@rollup/rollup-linux-riscv64-gnu@4.60.4': - resolution: {integrity: sha512-FJHFfqpKUI3A10WrWKiFbBZ7yVbGT4q4B5o1qKFFojqpaYoh9LrQgqWCmmcxQzVSXYtyB5bzkXrYzlHTs21MYA==} - cpu: [riscv64] - os: [linux] - libc: [glibc] - '@rollup/rollup-linux-riscv64-gnu@4.61.0': resolution: {integrity: sha512-RbrzcD3aJ1k3UbtMRRBNwojdVVyXjuVAFTfn/xPa6EEl6GE9Sm/akPgFTb9aAC9pMKGJ6CtWxaGrqWcabH+ySg==} cpu: [riscv64] os: [linux] libc: [glibc] - '@rollup/rollup-linux-riscv64-musl@4.60.4': - resolution: {integrity: sha512-mcEl6CUT5IAUmQf1m9FYSmVqCJlpQ8r8eyftFUHG8i9OhY7BkBXSUdnLH5DOf0wCOjcP9v/QO93zpmF1SptCCw==} - cpu: [riscv64] - os: [linux] - libc: [musl] - '@rollup/rollup-linux-riscv64-musl@4.61.0': resolution: {integrity: sha512-ZF+onDsBso8PJf1XaG9lB+O9RnBpKGnY6OrzC4CSHrtC1jb6jWLTKK4bRqdoCXHd22gyr2hiYmEAm8Wns/BOCw==} cpu: [riscv64] os: [linux] libc: [musl] - '@rollup/rollup-linux-s390x-gnu@4.60.4': - resolution: {integrity: sha512-ynt3JxVd2w2buzoKDWIyiV1pJW93xlQic1THVLXilz429oijRpSHivZAgp65KBu+cMcgf1eVVjdnTLvPxgCuoQ==} - cpu: [s390x] - os: [linux] - libc: [glibc] - '@rollup/rollup-linux-s390x-gnu@4.61.0': resolution: {integrity: sha512-Atk0aSIk5Zx2Wuh9dgRQgLP0Koc8hOeYpbWryMXyk8G8/HmPkwPPkMqIIDhrXHHYqfUzSJA/I7IWSBv8xSmRBA==} cpu: [s390x] os: [linux] libc: [glibc] - '@rollup/rollup-linux-x64-gnu@4.60.4': - resolution: {integrity: sha512-Boiz5+MsaROEWDf+GGEwF8VMHGhlUoQMtIPjOgA5fv4osupqTVnJteQNKJwUcnUog2G55jYXH7KZFFiJe0TEzQ==} - cpu: [x64] - os: [linux] - libc: [glibc] - '@rollup/rollup-linux-x64-gnu@4.61.0': resolution: {integrity: sha512-0uMOcf3eZ5K+K4cYHkdxShFMPlPXCOdfDFEFn9dNYAEEd2cVvmOfH7zFgRVoDgmtQ1m9k5q7qfrHzyMAubKYUA==} cpu: [x64] os: [linux] libc: [glibc] - '@rollup/rollup-linux-x64-musl@4.60.4': - resolution: {integrity: sha512-+qfSY27qIrFfI/Hom04KYFw3GKZSGU4lXus51wsb5EuySfFlWRwjkKWoE9emgRw/ukoT4Udsj4W/+xxG8VbPKg==} - cpu: [x64] - os: [linux] - libc: [musl] - '@rollup/rollup-linux-x64-musl@4.61.0': resolution: {integrity: sha512-mvFtE4A/t/7hRJ7X8Ozmu8FsIkAUat2nzl12pgU337BRmq87AQUJztwHz2Zv5/tjo9/C95E66CK03SI/ToEDJw==} cpu: [x64] os: [linux] libc: [musl] - '@rollup/rollup-openbsd-x64@4.60.4': - resolution: {integrity: sha512-VpTfOPHgVXEBeeR8hZ2O0F3aSso+JDWqTWmTmzcQKted54IAdUVbxE+j/MVxUsKa8L20HJhv3vUezVPoquqWjA==} - cpu: [x64] - os: [openbsd] - '@rollup/rollup-openbsd-x64@4.61.0': resolution: {integrity: sha512-z9b9+aTxvt8n2rNltMPvyaUfB8NJ+CVyOrGK/MdIKHx7B+lXmZpm/XbRsU7Rpf3fRqJ2uS6mBJiJveCtq8LHDg==} cpu: [x64] os: [openbsd] - '@rollup/rollup-openharmony-arm64@4.60.4': - resolution: {integrity: sha512-IPOsh5aRYuLv/nkU51X10Bf75Bsf6+gZdx1X+QP5QM6lIJFHHqbHLG0uJn/hWthzo13UAc2umiUorqZy3axoZg==} - cpu: [arm64] - os: [openharmony] - '@rollup/rollup-openharmony-arm64@4.61.0': resolution: {integrity: sha512-jXaXFqKMehsOc+g8R6oo33RRC6w07G9jDBxAE5eAKX7mOcCbZloYIPNhfG9Wl+P9O9IWHFO4OJgPi1Ml2qkt7w==} cpu: [arm64] os: [openharmony] - '@rollup/rollup-win32-arm64-msvc@4.60.4': - resolution: {integrity: sha512-4QzE9E81OohJ/HKzHhsqU+zcYYojVOXlFMs1DdyMT6qXl/niOH7AVElmmEdUNHHS/oRkc++d5k6Vy85zFs0DEw==} - cpu: [arm64] - os: [win32] - '@rollup/rollup-win32-arm64-msvc@4.61.0': resolution: {integrity: sha512-OXNWVFocS2IA4+QplhTZZ2a+8hPZR7T8KuozsNmJKK8y7cp83StHvGksfHzPG3wczWTczyWHVQuqeiTUbjiyBg==} cpu: [arm64] os: [win32] - '@rollup/rollup-win32-ia32-msvc@4.60.4': - resolution: {integrity: sha512-zTPgT1YuHHcd+Tmx7h8aml0FWFVelV5N54oHow9SLj+GfoDy/huQ+UV396N/C7KpMDMiPspRktzM1/0r1usYEA==} - cpu: [ia32] - os: [win32] - '@rollup/rollup-win32-ia32-msvc@4.61.0': resolution: {integrity: sha512-AlAbNtBO637LxSldqV43z0FfXoGfl2TW1DgAg/bs7aQswFbDewz2SJm3BUhiGfbOVtW571xbc9p+REdxhyN/Eg==} cpu: [ia32] os: [win32] - '@rollup/rollup-win32-x64-gnu@4.60.4': - resolution: {integrity: sha512-DRS4G7mi9lJxqEDezIkKCaUIKCrLUUDCUaCsTPCi/rtqaC6D/jjwslMQyiDU50Ka0JKpeXeRBFBAXwArY52vBw==} - cpu: [x64] - os: [win32] - '@rollup/rollup-win32-x64-gnu@4.61.0': resolution: {integrity: sha512-QRSrQXyJ1M4tjNXdR0/G/IgV6lzfQQJYBjlWIEYkY2Xs86DRl/iEpQ4blMDjJxSl7n19eDKKXMg0AmuBVYy8pQ==} cpu: [x64] os: [win32] - '@rollup/rollup-win32-x64-msvc@4.60.4': - resolution: {integrity: sha512-QVTUovf40zgTqlFVrKA1uXMVvU2QWEFWfAH8Wdc48IxLvrJMQVMBRjuQyUpzZCDkakImib9eVazbWlC6ksWtJw==} - cpu: [x64] - os: [win32] - '@rollup/rollup-win32-x64-msvc@4.61.0': resolution: {integrity: sha512-tkuFxhvKO/HlGd0VsINF6vHSYH8AF8W0TcNxKDK6JZmrehngFj78pToc8iemtnvwilDjs2G/qSzYFhe9U8q+fw==} cpu: [x64] os: [win32] - '@rollup/wasm-node@4.60.4': - resolution: {integrity: sha512-j6qaRjdDujJ5utX5l6+8eiWlvMLmBfPMBht8mHP2au3xuzf+4deu6PuCquH5GvDIvIOsWHZhA1UVz/s0FvvgAA==} - engines: {node: '>=18.0.0', npm: '>=8.0.0'} - hasBin: true - '@rollup/wasm-node@4.61.0': resolution: {integrity: sha512-UpYM5v/7Quee4u+VWHuNSgSlvIEQMQL7T/jEaOuaNJQ+JJcqSVvcqN6s1cLiDH5DuJMWRqJzvaCnyexp/UGftQ==} engines: {node: '>=18.0.0', npm: '>=8.0.0'} @@ -3896,9 +3637,6 @@ packages: '@types/esrecurse@4.3.1': resolution: {integrity: sha512-xJBAbDifo5hpffDBuHl0Y8ywswbiAp/Wi7Y/GtAgSlZyIABppyurxVueOPE8LUQOxdlgi6Zqce7uoEpqNTeiUw==} - '@types/estree@1.0.8': - resolution: {integrity: sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==} - '@types/estree@1.0.9': resolution: {integrity: sha512-GhdPgy1el4/ImP05X05Uw4cw2/M93BCUmnEvWZNStlCzEKME4Fkk+YpoA5OiHNQmoS7Cafb8Xa3Pya8m1Qrzeg==} @@ -4099,10 +3837,6 @@ packages: eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 typescript: '>=4.8.4 <6.1.0' - '@typescript-eslint/types@8.60.0': - resolution: {integrity: sha512-AsE7x2XaAK+CVbeih0Fvbn+r1qHxtpLDJ3XUuFcIinT318T90yHMJC+Zgv+jUuDjQQd06HKwxnDu6sz1IcTilA==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@typescript-eslint/types@8.60.1': resolution: {integrity: sha512-4h0tY8ppCkdCzcrl2YM5M3my0xsE1Tf8om3owEu5oPWmXwkKRmk0j0LGDzYBGUcAlesEbxBhazqu/K4cu3Ug7w==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} @@ -4480,8 +4214,8 @@ packages: resolution: {integrity: sha512-Izi8RQcffqCeNVgFigKli1ssklIbpHnCYc6AknXGYoB6grJqyeby7jv12JUQgmTAnIDnbck1uxksT4dzN3PWBA==} engines: {node: '>=12'} - ast-v8-to-istanbul@1.0.2: - resolution: {integrity: sha512-dKmJxJsGItLmc5CYZKuEjuG6GnBs6PG4gohMhyFOWKaNQoYCuRZJDECaBlHmcG0lv2wc2E0uU8lESmBEumC3DQ==} + ast-v8-to-istanbul@1.0.3: + resolution: {integrity: sha512-jCMQ6ZylLPudp0CDfBmQBZUsrh1/8psbmu9ibeVWKuHWD0YrH9YABwlKu5kVEFoT0GCQQW9Z/SxfuEbbkGQCRg==} async-each-series@0.1.1: resolution: {integrity: sha512-p4jj6Fws4Iy2m0iCmI2am2ZNZCgbdgE+P8F/8csmn2vx7ixXrO2zGcuNsD46X5uZSVecmkEy/M06X2vG8KD6dQ==} @@ -4569,16 +4303,16 @@ packages: resolution: {integrity: sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA==} engines: {node: 18 || 20 || >=22} - bare-events@2.8.3: - resolution: {integrity: sha512-HdUm8EMQBLaJvGUdidNNbqpA1kYkwNcb+MYxkxCLAPJGQzlv9J0C24h8V65Z4c5GLd/JEALDvpFCQgpLJqc0zw==} + bare-events@2.9.1: + resolution: {integrity: sha512-Z0oHEHAFDZkffN8Qc39zNZjQlMDkPJRyyyZieU1VH7u8c5S+qHZ2S8ixdKIAxEjfHO7FJxXmJWgteOghVanIsg==} peerDependencies: bare-abort-controller: '*' peerDependenciesMeta: bare-abort-controller: optional: true - bare-fs@4.7.1: - resolution: {integrity: sha512-WDRsyVN52eAx/lBamKD6uyw8H4228h/x0sGGGegOamM2cd7Pag88GfMQalobXI+HaEUxpCkbKQUDOQqt9wawRw==} + bare-fs@4.7.2: + resolution: {integrity: sha512-aTvMFUWkBmjzKtEQMDGGDNF8bkfpD5N1b/FCwt7A3wrU4t1o/e/85Wzkluh6JlODCjqVESYCkQCdTXqZ9G7VFg==} engines: {bare: '>=1.16.0'} peerDependencies: bare-buffer: '*' @@ -4590,8 +4324,8 @@ packages: resolution: {integrity: sha512-6M5XjcnsygQNPMCMPXSK379xrJFiZ/AEMNBmFEmQW8d/789VQATvriyi5r0HYTL9TkQ26rn3kgdTG3aisbrXkQ==} engines: {bare: '>=1.14.0'} - bare-path@3.0.0: - resolution: {integrity: sha512-tyfW2cQcB5NN8Saijrhqn0Zh7AnFNsnczRcuWODH0eYAXBsJ5gVxAUuNr7tsHSC6IZ77cA0SitzT+s47kot8Mw==} + bare-path@3.0.1: + resolution: {integrity: sha512-ghj2DSK/2e99a1anTVPCV4m4YIYtrbXhfM7V3D7XZLOTsybnYyaJloymGqssQc8l/or0UoDyRtNQkmkEF/ysgQ==} bare-stream@2.13.1: resolution: {integrity: sha512-Vp0cnjYyrEC4whYTymQ+YZi6pBpfiICZO3cfRG8sy67ZNWe951urv1x4eW1BKNngw3U+3fPYb5JQvHbCtxH7Ow==} @@ -4617,8 +4351,8 @@ packages: resolution: {integrity: sha512-lGe34o6EHj9y3Kts9R4ZYs/Gr+6N7MCaMlIFA3F1R2O5/m7K06AxfSeO5530PEERE6/WyEg3lsuyw4GHlPZHog==} engines: {node: ^4.5.0 || >= 5.9} - baseline-browser-mapping@2.10.32: - resolution: {integrity: sha512-wbPvpyjJPC0zdfdKXxqEL3Ea+bOMD/87X4lftiJkkaBiuG6ALQy1SLmEd7BSmVCuwCQsBrCamgBoLyfFDD1EPg==} + baseline-browser-mapping@2.10.33: + resolution: {integrity: sha512-bA6+tcSLpz2tIEdDXZPpPTIuxBcC4+w6SieaYyfigIa4h8GlFxbA17v22Vx3JUtuZQj9SgOsnbK+aTBzyDyEuw==} engines: {node: '>=6.0.0'} hasBin: true @@ -5232,8 +4966,8 @@ packages: engines: {node: '>=0.12.18'} hasBin: true - electron-to-chromium@1.5.361: - resolution: {integrity: sha512-Q6Hts7N9FnJc5LeGRINFvLhCI9xZmNtTDe5ZbcVezQz7cU4a8Aua3GH1b8J2XY8Al9PF+OCwYqhgsOOheMdvkA==} + electron-to-chromium@1.5.366: + resolution: {integrity: sha512-OlRuhb688YTCzzU3gXPLn6nGyd+F+53INE1qaKKlu6kETErE8FYsyDh0XqXEU+uBRn0MpCzz2vfNwORhkap8qg==} emoji-regex@10.6.0: resolution: {integrity: sha512-toUI84YS5YmxW219erniWD0CIVOo46xGKColeNQRgOzDorgBi1v4D71/OFzgD9GO2UGKIv1C3Sp8DAn0+j5w7A==} @@ -5273,8 +5007,8 @@ packages: resolution: {integrity: sha512-2agL3ueZhqxoVrfmntO8yuVj+uNSlIOnhykYHk3Cq0ShYPdUjjUiSJrQvXjq01I9jAuI0Zl2YO8Evv5Mqytm5g==} engines: {node: '>=10.2.0'} - enhanced-resolve@5.22.0: - resolution: {integrity: sha512-xYcDWrpELkFzz9SpZ3PlI6Eu6eD93Yf0WLDRxikGhWJ3MAir2SNZTIVCVZqZ/NUyx8AdMc2gT9C0gPiw18kG+A==} + enhanced-resolve@5.22.1: + resolution: {integrity: sha512-6QEuw3zoX1SJQc7b87aBXke/no+mG2bTBgw29gWMQonLmpEkWoCAVkl+M49e48AZlWzxiDzDZzYdp6kobcyLww==} engines: {node: '>=10.13.0'} ent@2.2.2: @@ -5379,8 +5113,8 @@ packages: eslint-import-resolver-node@0.3.10: resolution: {integrity: sha512-tRrKqFyCaKict5hOd244sL6EQFNycnMQnBe+j8uqGNXYzsImGbGUU4ibtoaBmv5FLwJwcFJNeg1GeVjQfbMrDQ==} - eslint-module-utils@2.12.1: - resolution: {integrity: sha512-L8jSWTze7K2mTg0vos/RuLRS5soomksDPoJLXIslC7c8Wmut3bx7CPpJijDcBZtxQ5lrbUdM+s0OlNbz0DCDNw==} + eslint-module-utils@2.13.0: + resolution: {integrity: sha512-bLohSkT6469rRs8czj0tLTD8vaeIS/whvPRJVjDr7IuoTT1k5DYDERlNycjDj/HkOlvQdYurmfZ/g3fG5bgeLQ==} engines: {node: '>=4'} peerDependencies: '@typescript-eslint/parser': '*' @@ -5498,8 +5232,8 @@ packages: resolution: {integrity: sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==} engines: {node: '>=0.8.x'} - eventsource-parser@3.0.8: - resolution: {integrity: sha512-70QWGkr4snxr0OXLRWsFLeRBIRPuQOvt4s8QYjmUlmlkyTZkRqS7EDVRZtzU3TiyDbXSzaOeF0XUKy8PchzukQ==} + eventsource-parser@3.1.0: + resolution: {integrity: sha512-kJezFj9YFAMLeORyi7aCLxLbD5/qWMQnoMVlVPyHIll7lgRJCc3JVln9Vgl9nwQi0YkMnhdGTMNn7CkRRAptMg==} engines: {node: '>=18.0.0'} eventsource@3.0.7: @@ -5849,8 +5583,8 @@ packages: peerDependencies: graphql: ^0.9.0 || ^0.10.0 || ^0.11.0 || ^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0 || ^16.0.0 - graphql@16.14.0: - resolution: {integrity: sha512-BBvQ/406p+4CZbTpCbVPSxfzrZrbnuWSP1ELYgyS6B+hNeKzgrdB4JczCa5VZUBQrDa9hUngm0KnexY6pJRN5Q==} + graphql@16.14.1: + resolution: {integrity: sha512-cQOsSMS/IrDz82PVyRDvf/Q1F/bRbBVjJlh+xYOkI1qw2bWRvWGiWc+m2O0d6l4Bt1fyY+8kzJ8JFWGJqNeDBg==} engines: {node: ^12.22.0 || ^14.16.0 || ^16.0.0 || >=17.0.0} grpc-gcp@1.0.1: @@ -5894,8 +5628,8 @@ packages: resolution: {integrity: sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==} engines: {node: '>= 0.4'} - hasown@2.0.3: - resolution: {integrity: sha512-ej4AhfhfL2Q2zpMmLo7U1Uv9+PyhIZpgQLGT1F9miIGmiCJIoCgSmczFdrc97mWT4kVY72KA+WnnhJ5pghSvSg==} + hasown@2.0.4: + resolution: {integrity: sha512-T2UbfbBEF32wiepXIsMlTW9+dDYC6wMh/t/vYA4tuOMKqWz/n3vr1NFSxQiyP+zk2mXsoMA/i/7qV6LKut1t1A==} engines: {node: '>= 0.4'} hono@4.12.23: @@ -6044,8 +5778,8 @@ packages: resolution: {integrity: sha512-AUY/VyX0E5XlibOmWt10uabJzam1zlYjwiEgQSDc5+UIkFNaF9WM0JxXKaNMGf+F/ffUF+7kRKXM9A7C0xXqMg==} engines: {node: '>=0.10.0'} - immutable@5.1.5: - resolution: {integrity: sha512-t7xcm2siw+hlUM68I+UEOK+z84RzmN59as9DZ7P1l0994DKUWV7UXBMQZVxaoMSRQ+PBZbHCOoBt7a2wxOMt+A==} + immutable@5.1.6: + resolution: {integrity: sha512-q1swsS8K7L8usSHuOqF2TAoCCkonYz0SG38wLAggaa4Wml70zixIvt2ql4coQ2C2B3hTjltJry4r6bULwgAXLQ==} import-fresh@3.3.1: resolution: {integrity: sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ==} @@ -6386,6 +6120,10 @@ packages: resolution: {integrity: sha512-qQKT4zQxXl8lLwBtHMWwaTcGfFOZviOJet3Oy/xmGk2gZH677CJM9EvtfdSkgWcATZhj/55JZ0rmy3myCT5lsA==} hasBin: true + js-yaml@4.2.0: + resolution: {integrity: sha512-ePWsvanv0DWuDRsW8dnt+R4jQ31SCRCQ7hhNcPXZPsoBZiemuZNYGf7adZdqX2D86j6rvKp3RpCxVTSb8WQlOw==} + hasBin: true + jsbn@0.1.1: resolution: {integrity: sha512-UVU9dibq2JcFWxQPA6KCqj5O42VOmAY3zQUfEKxU0KpTGXwNoCjkX1e13eHNvw/xPynt6pU0rZ1htjWTNTSXsg==} @@ -6508,8 +6246,8 @@ packages: resolution: {integrity: sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==} engines: {node: '>=0.10.0'} - launch-editor@2.13.2: - resolution: {integrity: sha512-4VVDnbOpLXy/s8rdRCSXb+zfMeFR0WlJWpET1iA9CQdlZDfwyLjUuGQzXU4VeOoey6AicSAluWan7Etga6Kcmg==} + launch-editor@2.14.1: + resolution: {integrity: sha512-QWBrQsMpH7gPr965dsKD/3cKWiNoTjpATQf++Xq63N6sKRGMwlVXz41O1IZTMfZQgBctD/K5Zt06+/I6pP6+HA==} less-loader@13.0.0: resolution: {integrity: sha512-TIa8d6znKH634Mg+7OU3jevZT6KeOhh0amW+YeMPD0GM9buUn5Y7HvtyCR5pUDdLaFfqLA8AX5PTSIHMNSexEA==} @@ -6640,8 +6378,8 @@ packages: lru-cache@10.4.3: resolution: {integrity: sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==} - lru-cache@11.5.0: - resolution: {integrity: sha512-5YgH9UJd7wVb9hIouI2adWpgqrrICkt070Dnj8EUY1+B4B2P9eRLPAkAAo6NICA7CEhOIeBHl46u9zSNpNu7zA==} + lru-cache@11.5.1: + resolution: {integrity: sha512-RPimw/7aMdv2oqRrxKwvZXcPfwBrn/JZ2xYcY9Hus/6LaS3VOAKVWKWgNLCFSiOm1ESXinjsDlidVU7JlnCN2A==} engines: {node: 20 || >=22} lru-cache@5.1.1: @@ -6665,8 +6403,8 @@ packages: resolution: {integrity: sha512-hXdUTZYIVOt1Ex//jAQi+wTZZpUpwBj/0QsOzqegb3rGMMeJiSEu5xLHnYfBrRV4RH2+OCSOO95Is/7x1WJ4bw==} engines: {node: '>=10'} - make-fetch-happen@15.0.5: - resolution: {integrity: sha512-uCbIa8jWWmQZt4dSnEStkVC6gdakiinAm4PiGsywIkguF0eWMdcjDz0ECYhUolFU3pFLOev9VNPCEygydXnddg==} + make-fetch-happen@15.0.6: + resolution: {integrity: sha512-Je0fLJ0F5atA7F+eIlLzk+Wkcl57JDf4kf+EW8xiP5E31xOQxkIxTbgf1Oi1Lw9tRI9UEMRdI5Vz2xTzoNU1Jw==} engines: {node: ^20.17.0 || >=22.9.0} math-intrinsics@1.1.0: @@ -6684,8 +6422,8 @@ packages: resolution: {integrity: sha512-aisnrDP4GNe06UcKFnV5bfMNPBUw4jsLGaWwWfnH3v02GnBuXX2MCVn5RbrWo0j3pczUilYblq7fQ7Nw2t5XKw==} engines: {node: '>= 0.8'} - memfs@4.57.2: - resolution: {integrity: sha512-2nWzSsJzrukurSDna4Z0WywuScK4Id3tSKejgu74u8KCdW4uNrseKRSIDg75C6Yw5ZRqBe0F0EtMNlTbUq8bAQ==} + memfs@4.57.5: + resolution: {integrity: sha512-qT8bQJyjF6+DsDI9X1yMwUyIkYHrZI8D2PaWjze8aUUbGUkcNlxppcRZF/0VWesIPHtgx6T2mLx3qPmTQxUd6A==} peerDependencies: tslib: '2' @@ -6865,10 +6603,6 @@ packages: resolution: {integrity: sha512-dkEJPVvun4FryqBmZ5KhDo0K9iDXAwn08tMLDinNdRBNPcYEDiWYysLcc6k3mjTMlbP9KyylvRpd4wFtwrT9rw==} engines: {node: ^20.17.0 || >=22.9.0} - mute-stream@4.0.0: - resolution: {integrity: sha512-gSrprq0fJ3EiOErzjdIZrjysVVmJ4uu1QWfCDss5LypA5OXvrMje5Ym5z6V6RLyJ2eF87lasX7t6a0AnFvZblg==} - engines: {node: ^22.22.2 || ^24.15.0 || >=26.0.0} - nanoid@3.3.12: resolution: {integrity: sha512-ZB9RH/39qpq5Vu6Y+NmUaFhQR6pp+M2Xt76XBnEwDaGcVAqhlvxrl3B2bKS5D3NH3QR76v3aSrKaF/Kiy7lEtQ==} engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} @@ -6967,8 +6701,8 @@ packages: engines: {node: ^20.17.0 || >=22.9.0} hasBin: true - node-releases@2.0.46: - resolution: {integrity: sha512-GYVXHE2KnrzAfsAjl4uP++evGFCrAU1jta4ubEjIG7YWt/64Gqv66a30yKwWczVjA6j3bM4nBwH7Pk1JmDHaxQ==} + node-releases@2.0.47: + resolution: {integrity: sha512-Uzmd6LXpouKo8EUK68IjH4+E01w/hXyV3R3g/geCJo+rXLNfh1xucB+LOzYEOQPSiUK3h/xZf0cQGcSsmyL2Og==} engines: {node: '>=18'} nopt@9.0.0: @@ -7393,8 +7127,8 @@ packages: resolution: {integrity: sha512-E1sbAYg3aEbXrq0n1ojJkRHQJGE1kaE/O6GLA94y8rnJBfgvOPTOd1b9hOceQK1FFZI9qMh1vBERCyO2ifubcw==} engines: {node: '>=18'} - protobufjs@7.6.1: - resolution: {integrity: sha512-4K0myLaWL5EteuSAro91EGFgcfVgxb64Jx+7oDAY6GOkXD4M69yuSEljNcInGVCA5sOPxmZ/EqDLj2x0Q0+Ygg==} + protobufjs@7.6.2: + resolution: {integrity: sha512-N9EiLovGEQOJSPF26Ij7qUGvahfEnq0eeYZ02aigIedkmz1qZSwjnP9SBITHJuF/6MYbIW4HDN8zdYjsjqJKXQ==} engines: {node: '>=12.0.0'} proxy-addr@2.0.7: @@ -7625,11 +7359,6 @@ packages: '@types/node': optional: true - rollup@4.60.4: - resolution: {integrity: sha512-WHeFSbZYsPu3+bLoNRUuAO+wavNlocOPf3wSHTP7hcFKVnJeWsYlCDbr3mTS14FCizf9ccIxXA8sGL8zKeQN3g==} - engines: {node: '>=18.0.0', npm: '>=8.0.0'} - hasBin: true - rollup@4.61.0: resolution: {integrity: sha512-T9mWdbWfQtp0B5lv/HX+wrhYsmXRlcWnXXmJbXqKJhlRaoS6KMhq0gpyzW4UJfclcxrEdLnTgjT2NjruLONu0g==} engines: {node: '>=18.0.0', npm: '>=8.0.0'} @@ -7994,8 +7723,8 @@ packages: resolution: {integrity: sha512-KFxaM7XT+irxvdqSP1LGLgNWbYN7ay5owZ3r/8t77p+EtSUAfUgtl7be3xtqtOmGUl9K9YPO2ca8133RlTjvKw==} engines: {node: '>=8.0'} - streamx@2.25.0: - resolution: {integrity: sha512-0nQuG6jf1w+wddNEEXCF4nTg3LtufWINB5eFEN+5TNZW7KWJp6x87+JFL43vaAUPyCfH1wID+mNVyW6OHtFamg==} + streamx@2.26.0: + resolution: {integrity: sha512-VvNG1K72Po/xwJzxZFnZ++Tbrv4lwSptsbkFuzXCJAYZvCK5nnxsvXU6ajqkv7chyiI1Y0YXq2Jh8Iy8Y7NF/A==} strict-event-emitter@0.5.1: resolution: {integrity: sha512-vMgjE/GGEPEFnhFub6pa4FmJBRBVOLpIII2hvCZ8Kzb7K0hlHo7mQv6xYrBvCL2LtAIBwFUK8wvuJgTVSQ5MFQ==} @@ -8082,8 +7811,8 @@ packages: tar-stream@3.2.0: resolution: {integrity: sha512-ojzvCvVaNp6aOTFmG7jaRD0meowIAuPc3cMMhSgKiVWws1GyHbGd/xvnyuRKcKlMpt3qvxx6r0hreCNITP9hIg==} - tar@7.5.15: - resolution: {integrity: sha512-dzGK0boVlC4W5QFuQN1EFSl3bIDYsk7Tj40U6eIBnK2k/8ml7TZ5agbI5j5+qnoVcAA+rNtBml8SEiLxZpNqRQ==} + tar@7.5.16: + resolution: {integrity: sha512-56adEpPMouktRlBLXiaYFFzZ/3+JXa8P9n7WbR+ibIjtviN55mEaOkiysCnPnWm+7kkui1Dn8J9l+g6zV8731w==} engines: {node: '>=18'} teeny-request@10.1.2: @@ -8093,8 +7822,8 @@ packages: teex@1.0.1: resolution: {integrity: sha512-eYE6iEI62Ni1H8oIa7KlDU6uQBtqr4Eajni3wX7rpfXD8ysFx8z0+dri+KWEPWpBsxXfxu58x/0jvTVT1ekOSg==} - terser-webpack-plugin@5.6.0: - resolution: {integrity: sha512-Eum+5ajkaOhf5KbM26osvv21kLD7BaGqQ1UA4Ami4arYwylmGUQTgHFpHDdmJod1q4QXa66p0to/FBKID+J1vA==} + terser-webpack-plugin@5.6.1: + resolution: {integrity: sha512-201R5j+sJpK8nFWwKVyNfZot8FaJbLZDq5evriVzbV1wDtSXDjRUDRfJzHpAaxFDMEhsZL1QkeqM61wgsS3KaQ==} engines: {node: '>= 10.13.0'} peerDependencies: '@minify-html/node': '*' @@ -8150,8 +7879,8 @@ packages: peerDependencies: tslib: ^2 - thread-stream@3.1.0: - resolution: {integrity: sha512-OqyPZ9u96VohAyMfJykzmivOrY2wfMSf3C5TtFJVgN+Hm6aj+voFhlK+kZEIv2FBh1X6Xp3DlnCOfEQ3B2J86A==} + thread-stream@3.2.0: + resolution: {integrity: sha512-zLBvqpwr4Esa0kRjcrzGU6zL25lePWaCLMx0RQFrmteozIfeNdaMLpG5U7PeHzvlFkAWaRKA9/KVW4F60iB+qw==} through2@2.0.5: resolution: {integrity: sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==} @@ -8171,14 +7900,10 @@ packages: tinybench@2.9.0: resolution: {integrity: sha512-0+DUvqWMValLmha6lr4kD8iAMK1HzV0/aKnCtWb9v9641TnP/MFb7Pc2bxoxQjTXAErryXVgUOfv2YqNllqGeg==} - tinyexec@1.2.2: - resolution: {integrity: sha512-M/Q0B2cp4K7kynaT/vnED1j8TlLY+Pp7C6Wl2bl/7u/F0mUVwdyOpwomQb8JpYLitHUssAJRmLZdMCGsrx7i+g==} + tinyexec@1.2.4: + resolution: {integrity: sha512-SHf/r48b7vOrjve9PxJo3MN5v5yuyjHvdUcrQffT3WXMUfnGmHDVbC4k3sHJaJTgZCwpUplIaAo5ANtMyp3YHg==} engines: {node: '>=18'} - tinyglobby@0.2.16: - resolution: {integrity: sha512-pn99VhoACYR8nFHhxqix+uvsbXineAasWm5ojXoN8xEwK5Kd3/TrhNn1wByuD52UxWRLy8pu+kRMniEi6Eq9Zg==} - engines: {node: '>=12.0.0'} - tinyglobby@0.2.17: resolution: {integrity: sha512-wXR/dYpcqKmfWpEdZjiKJOwCNFndD0DMnrW/cYjVGttEkBfVgcLFHoNrlj47mjOVic9yyNu65alsgF4NQyTa2g==} engines: {node: '>=12.0.0'} @@ -8190,19 +7915,19 @@ packages: tldts-core@6.1.86: resolution: {integrity: sha512-Je6p7pkk+KMzMv2XXKmAE3McmolOQFdxkKw0R8EYNr7sELW46JqnNeTX8ybPiQgvg1ymCoF8LXs5fzFaZvJPTA==} - tldts-core@7.4.0: - resolution: {integrity: sha512-/mb9kRld+x1sIMXxWNOAp5m6C+D4GrAORWlJkOJ5dElvxdN1eutz/o7qHLp9gFvDF4Y3/L2xeScoxz6AbEo8rQ==} + tldts-core@7.4.2: + resolution: {integrity: sha512-nwEyF4vl4RSJjwSjBUmOSxc3BFPoIFdlRthJ6e+5v9P3bHNsoD06UjuqMUspqp7vsEZ1beaHi1km+optiE17yA==} tldts@6.1.86: resolution: {integrity: sha512-WMi/OQ2axVTf/ykqCQgXiIct+mSQDFdH2fkwhPwgEwvJ1kSzZRiinb0zF2Xb8u4+OqPChmyI6MEu4EezNJz+FQ==} hasBin: true - tldts@7.4.0: - resolution: {integrity: sha512-yHBe+zVfzNZ3QfTPW/Z6KK1G2t340gFjMHqI/4KKSt/abzYydzuCnpqdaF5gCCABby+9Yfbj59oR5F2Fd5CBzg==} + tldts@7.4.2: + resolution: {integrity: sha512-kCwffuaH8ntKtygnWe1b4BJKWiCUH30n5KfoTr6IchcXOwR7chAOFJxFrH3vjANafUYrIA4a7SDL+nn7SiR4Sw==} hasBin: true - tmp@0.2.5: - resolution: {integrity: sha512-voyz6MApa1rQGUxT3E+BK7/ROe8itEx7vD8/HEvt4xwXucvQ5G5oeEiHkmHZJuBO21RpOf+YYm9MOivj709jow==} + tmp@0.2.7: + resolution: {integrity: sha512-e0votIpp4Uo2AJYSzVHV6xCcawuiez3DzqDAbrTc3YxBkplN6e+dM13ZeIcZnDg/QpSuU2zfZ3rzwY8ukEnaXw==} engines: {node: '>=14.14'} to-regex-range@5.0.1: @@ -8306,8 +8031,8 @@ packages: resolution: {integrity: sha512-bTlAFB/FBYMcuX81gbL4OcpH5PmlFHqlCCpAl8AlEzMz5k53oNDvN8p1PNOWLEmI2x4orp3raOFB51tv9X+MFQ==} engines: {node: '>= 0.4'} - typed-array-length@1.0.7: - resolution: {integrity: sha512-3KS2b+kL7fsuk/eJZ7EQdnEmQoaho/r6KUef7hxvltNA5DR8NAUM+8wJMbJyZ4G9/7i3v5zPBIMN5aybAh2/Jg==} + typed-array-length@1.0.8: + resolution: {integrity: sha512-phPGCwqr2+Qo0fwniCE8e4pKnGu/yFb5nD5Y8bf0EEeiI5GklnACYA9GFy/DrAeRrKHXvHn+1SUsOWgJp6RO+g==} engines: {node: '>= 0.4'} typed-assert@1.0.9: @@ -8351,8 +8076,8 @@ packages: resolution: {integrity: sha512-4yqz8a3n5HmGTlsbADNtr/dJlhkh/55Rq798G6ibiULcXbDtaLpTl1pvdqcbFfeoj3iSi52lePFM7h9H21cw/A==} engines: {node: '>=18.17'} - undici@7.26.0: - resolution: {integrity: sha512-3O9Tf67pGhgOv9jM35AbhkXAKi13f3oy3aE4CSgr+TckGeY+/iu97ZXN+J7DpHPzLbVApFd1IFhcnBjREYXYcg==} + undici@7.27.0: + resolution: {integrity: sha512-+t2Z/GwkZQDtu00813aP66ygViGtPHKhhoFZpQKpKrE+9jIgES+Zw+mFNaDWOVRKiuJjuqKHzD3B1sfGg8+ZOQ==} engines: {node: '>=20.18.1'} undici@8.3.0: @@ -8469,46 +8194,6 @@ packages: resolution: {integrity: sha512-ZZKSmDAEFOijERBLkmYfJ+vmk3w+7hOLYDNkRCuRuMJGEmqYNCNLyBBFwWKVMhfwaEF3WOd0Zlw86U/WC/+nYw==} engines: {'0': node >=0.6.0} - vite@7.3.3: - resolution: {integrity: sha512-/4XH147Ui7OGTjg3HbdWe5arnZQSbfuRzdr9Ec7TQi5I7R+ir0Rlc9GIvD4v0XZurELqA035KVXJXpR61xhiTA==} - engines: {node: ^20.19.0 || >=22.12.0} - hasBin: true - peerDependencies: - '@types/node': ^20.19.0 || >=22.12.0 - jiti: '>=1.21.0' - less: ^4.0.0 - lightningcss: ^1.21.0 - sass: ^1.70.0 - sass-embedded: ^1.70.0 - stylus: '>=0.54.8' - sugarss: ^5.0.0 - terser: ^5.16.0 - tsx: ^4.8.1 - yaml: ^2.4.2 - peerDependenciesMeta: - '@types/node': - optional: true - jiti: - optional: true - less: - optional: true - lightningcss: - optional: true - sass: - optional: true - sass-embedded: - optional: true - stylus: - optional: true - sugarss: - optional: true - terser: - optional: true - tsx: - optional: true - yaml: - optional: true - vite@7.3.5: resolution: {integrity: sha512-KuOaNhcnGFN2zIPGA7wRmzF+lJA1sea7rHq17aiJ++9lzY1WWG6Jpwqwe1KNbRVPIqHmr8GLYx7jbrQcN/7/ww==} engines: {node: ^20.19.0 || >=22.12.0} @@ -8714,8 +8399,8 @@ packages: resolution: {integrity: sha512-K4jVyjnBdgvc86Y6BkaLZEN933SwYOuBFkdmBu9ZfkcAbdVbpITnDmjvZ/aQjRXQrv5EPkTnD1s39GiiqbngCw==} engines: {node: '>= 0.4'} - which-typed-array@1.1.20: - resolution: {integrity: sha512-LYfpUkmqwl0h9A2HL09Mms427Q1RZWuOHsukfVcKRq9q95iQxdw0ix1JQrqbcDR9PH1QDwf5Qo8OZb5lksZ8Xg==} + which-typed-array@1.1.21: + resolution: {integrity: sha512-zbRA8cVm6io/d5W8uIe2hblzN76/Wm3v/yiythQvr+dpBWeqhPSWIDNj4zOyHi4zKbMK6DN34Xsr9jPHJERAEw==} engines: {node: '>= 0.4'} which@1.3.1: @@ -9058,7 +8743,7 @@ snapshots: '@angular/compiler-cli': 22.0.0(@angular/compiler@22.0.0)(typescript@6.0.3) '@babel/core': 7.29.0 '@types/babel__core': 7.20.5 - tinyglobby: 0.2.16 + tinyglobby: 0.2.17 yargs: 18.0.0 transitivePeerDependencies: - supports-color @@ -10172,7 +9857,7 @@ snapshots: globals: 14.0.0 ignore: 5.3.2 import-fresh: 3.3.1 - js-yaml: 4.1.1 + js-yaml: 4.2.0 minimatch: 3.1.5 strip-json-comments: 3.1.1 transitivePeerDependencies: @@ -10559,12 +10244,12 @@ snapshots: extend: 3.0.2 google-auth-library: 10.6.2(supports-color@10.2.2) google-gax: 5.0.6(supports-color@10.2.2) - grpc-gcp: 1.0.1(protobufjs@7.6.1) + grpc-gcp: 1.0.1(protobufjs@7.6.2) is: 3.3.2 lodash.snakecase: 4.1.1 merge-stream: 2.0.0 p-queue: 6.6.2 - protobufjs: 7.6.1 + protobufjs: 7.6.2 retry-request: 8.0.2(supports-color@10.2.2) split-array-stream: 2.0.0 stack-trace: 0.0.10 @@ -10578,7 +10263,7 @@ snapshots: dependencies: google-auth-library: 10.6.2(supports-color@10.2.2) p-retry: 4.6.2 - protobufjs: 7.6.1 + protobufjs: 7.6.2 ws: 8.21.0(bufferutil@4.1.0)(utf-8-validate@6.0.6) optionalDependencies: '@modelcontextprotocol/sdk': 1.29.0(zod@4.4.3) @@ -10601,14 +10286,14 @@ snapshots: dependencies: lodash.camelcase: 4.3.0 long: 5.3.2 - protobufjs: 7.6.1 + protobufjs: 7.6.2 yargs: 17.7.2 '@grpc/proto-loader@0.8.1': dependencies: lodash.camelcase: 4.3.0 long: 5.3.2 - protobufjs: 7.6.1 + protobufjs: 7.6.2 yargs: 17.7.2 '@harperfast/extended-iterable@1.0.3': @@ -10634,19 +10319,8 @@ snapshots: '@humanwhocodes/retry@0.4.3': {} - '@inquirer/ansi@2.0.6': {} - '@inquirer/ansi@2.0.7': {} - '@inquirer/checkbox@5.2.0(@types/node@24.12.4)': - dependencies: - '@inquirer/ansi': 2.0.6 - '@inquirer/core': 11.2.0(@types/node@24.12.4) - '@inquirer/figures': 2.0.6 - '@inquirer/type': 4.0.6(@types/node@24.12.4) - optionalDependencies: - '@types/node': 24.12.4 - '@inquirer/checkbox@5.2.1(@types/node@24.12.4)': dependencies: '@inquirer/ansi': 2.0.7 @@ -10656,13 +10330,6 @@ snapshots: optionalDependencies: '@types/node': 24.12.4 - '@inquirer/confirm@6.1.0(@types/node@24.12.4)': - dependencies: - '@inquirer/core': 11.2.0(@types/node@24.12.4) - '@inquirer/type': 4.0.6(@types/node@24.12.4) - optionalDependencies: - '@types/node': 24.12.4 - '@inquirer/confirm@6.1.1(@types/node@24.12.4)': dependencies: '@inquirer/core': 11.2.1(@types/node@24.12.4) @@ -10670,18 +10337,6 @@ snapshots: optionalDependencies: '@types/node': 24.12.4 - '@inquirer/core@11.2.0(@types/node@24.12.4)': - dependencies: - '@inquirer/ansi': 2.0.6 - '@inquirer/figures': 2.0.6 - '@inquirer/type': 4.0.6(@types/node@24.12.4) - cli-width: 4.1.0 - fast-wrap-ansi: 0.2.2 - mute-stream: 4.0.0 - signal-exit: 4.1.0 - optionalDependencies: - '@types/node': 24.12.4 - '@inquirer/core@11.2.1(@types/node@24.12.4)': dependencies: '@inquirer/ansi': 2.0.7 @@ -10694,14 +10349,6 @@ snapshots: optionalDependencies: '@types/node': 24.12.4 - '@inquirer/editor@5.2.0(@types/node@24.12.4)': - dependencies: - '@inquirer/core': 11.2.0(@types/node@24.12.4) - '@inquirer/external-editor': 3.0.1(@types/node@24.12.4) - '@inquirer/type': 4.0.6(@types/node@24.12.4) - optionalDependencies: - '@types/node': 24.12.4 - '@inquirer/editor@5.2.2(@types/node@24.12.4)': dependencies: '@inquirer/core': 11.2.1(@types/node@24.12.4) @@ -10710,13 +10357,6 @@ snapshots: optionalDependencies: '@types/node': 24.12.4 - '@inquirer/expand@5.1.0(@types/node@24.12.4)': - dependencies: - '@inquirer/core': 11.2.0(@types/node@24.12.4) - '@inquirer/type': 4.0.6(@types/node@24.12.4) - optionalDependencies: - '@types/node': 24.12.4 - '@inquirer/expand@5.1.1(@types/node@24.12.4)': dependencies: '@inquirer/core': 11.2.1(@types/node@24.12.4) @@ -10724,13 +10364,6 @@ snapshots: optionalDependencies: '@types/node': 24.12.4 - '@inquirer/external-editor@3.0.1(@types/node@24.12.4)': - dependencies: - chardet: 2.1.1 - iconv-lite: 0.7.2 - optionalDependencies: - '@types/node': 24.12.4 - '@inquirer/external-editor@3.0.3(@types/node@24.12.4)': dependencies: chardet: 2.1.1 @@ -10738,17 +10371,8 @@ snapshots: optionalDependencies: '@types/node': 24.12.4 - '@inquirer/figures@2.0.6': {} - '@inquirer/figures@2.0.7': {} - '@inquirer/input@5.1.0(@types/node@24.12.4)': - dependencies: - '@inquirer/core': 11.2.0(@types/node@24.12.4) - '@inquirer/type': 4.0.6(@types/node@24.12.4) - optionalDependencies: - '@types/node': 24.12.4 - '@inquirer/input@5.1.2(@types/node@24.12.4)': dependencies: '@inquirer/core': 11.2.1(@types/node@24.12.4) @@ -10756,13 +10380,6 @@ snapshots: optionalDependencies: '@types/node': 24.12.4 - '@inquirer/number@4.1.0(@types/node@24.12.4)': - dependencies: - '@inquirer/core': 11.2.0(@types/node@24.12.4) - '@inquirer/type': 4.0.6(@types/node@24.12.4) - optionalDependencies: - '@types/node': 24.12.4 - '@inquirer/number@4.1.1(@types/node@24.12.4)': dependencies: '@inquirer/core': 11.2.1(@types/node@24.12.4) @@ -10770,14 +10387,6 @@ snapshots: optionalDependencies: '@types/node': 24.12.4 - '@inquirer/password@5.1.0(@types/node@24.12.4)': - dependencies: - '@inquirer/ansi': 2.0.6 - '@inquirer/core': 11.2.0(@types/node@24.12.4) - '@inquirer/type': 4.0.6(@types/node@24.12.4) - optionalDependencies: - '@types/node': 24.12.4 - '@inquirer/password@5.1.1(@types/node@24.12.4)': dependencies: '@inquirer/ansi': 2.0.7 @@ -10788,16 +10397,16 @@ snapshots: '@inquirer/prompts@8.4.3(@types/node@24.12.4)': dependencies: - '@inquirer/checkbox': 5.2.0(@types/node@24.12.4) - '@inquirer/confirm': 6.1.0(@types/node@24.12.4) - '@inquirer/editor': 5.2.0(@types/node@24.12.4) - '@inquirer/expand': 5.1.0(@types/node@24.12.4) - '@inquirer/input': 5.1.0(@types/node@24.12.4) - '@inquirer/number': 4.1.0(@types/node@24.12.4) - '@inquirer/password': 5.1.0(@types/node@24.12.4) - '@inquirer/rawlist': 5.3.0(@types/node@24.12.4) - '@inquirer/search': 4.2.0(@types/node@24.12.4) - '@inquirer/select': 5.2.0(@types/node@24.12.4) + '@inquirer/checkbox': 5.2.1(@types/node@24.12.4) + '@inquirer/confirm': 6.1.1(@types/node@24.12.4) + '@inquirer/editor': 5.2.2(@types/node@24.12.4) + '@inquirer/expand': 5.1.1(@types/node@24.12.4) + '@inquirer/input': 5.1.2(@types/node@24.12.4) + '@inquirer/number': 4.1.1(@types/node@24.12.4) + '@inquirer/password': 5.1.1(@types/node@24.12.4) + '@inquirer/rawlist': 5.3.1(@types/node@24.12.4) + '@inquirer/search': 4.2.1(@types/node@24.12.4) + '@inquirer/select': 5.2.1(@types/node@24.12.4) optionalDependencies: '@types/node': 24.12.4 @@ -10816,13 +10425,6 @@ snapshots: optionalDependencies: '@types/node': 24.12.4 - '@inquirer/rawlist@5.3.0(@types/node@24.12.4)': - dependencies: - '@inquirer/core': 11.2.0(@types/node@24.12.4) - '@inquirer/type': 4.0.6(@types/node@24.12.4) - optionalDependencies: - '@types/node': 24.12.4 - '@inquirer/rawlist@5.3.1(@types/node@24.12.4)': dependencies: '@inquirer/core': 11.2.1(@types/node@24.12.4) @@ -10830,14 +10432,6 @@ snapshots: optionalDependencies: '@types/node': 24.12.4 - '@inquirer/search@4.2.0(@types/node@24.12.4)': - dependencies: - '@inquirer/core': 11.2.0(@types/node@24.12.4) - '@inquirer/figures': 2.0.6 - '@inquirer/type': 4.0.6(@types/node@24.12.4) - optionalDependencies: - '@types/node': 24.12.4 - '@inquirer/search@4.2.1(@types/node@24.12.4)': dependencies: '@inquirer/core': 11.2.1(@types/node@24.12.4) @@ -10846,15 +10440,6 @@ snapshots: optionalDependencies: '@types/node': 24.12.4 - '@inquirer/select@5.2.0(@types/node@24.12.4)': - dependencies: - '@inquirer/ansi': 2.0.6 - '@inquirer/core': 11.2.0(@types/node@24.12.4) - '@inquirer/figures': 2.0.6 - '@inquirer/type': 4.0.6(@types/node@24.12.4) - optionalDependencies: - '@types/node': 24.12.4 - '@inquirer/select@5.2.1(@types/node@24.12.4)': dependencies: '@inquirer/ansi': 2.0.7 @@ -10868,10 +10453,6 @@ snapshots: optionalDependencies: '@types/node': 24.12.4 - '@inquirer/type@4.0.6(@types/node@24.12.4)': - optionalDependencies: - '@types/node': 24.12.4 - '@inquirer/type@4.0.7(@types/node@24.12.4)': optionalDependencies: '@types/node': 24.12.4 @@ -10943,58 +10524,58 @@ snapshots: dependencies: tslib: 2.8.1 - '@jsonjoy.com/fs-core@4.57.2(tslib@2.8.1)': + '@jsonjoy.com/fs-core@4.57.5(tslib@2.8.1)': dependencies: - '@jsonjoy.com/fs-node-builtins': 4.57.2(tslib@2.8.1) - '@jsonjoy.com/fs-node-utils': 4.57.2(tslib@2.8.1) + '@jsonjoy.com/fs-node-builtins': 4.57.5(tslib@2.8.1) + '@jsonjoy.com/fs-node-utils': 4.57.5(tslib@2.8.1) thingies: 2.6.0(tslib@2.8.1) tslib: 2.8.1 - '@jsonjoy.com/fs-fsa@4.57.2(tslib@2.8.1)': + '@jsonjoy.com/fs-fsa@4.57.5(tslib@2.8.1)': dependencies: - '@jsonjoy.com/fs-core': 4.57.2(tslib@2.8.1) - '@jsonjoy.com/fs-node-builtins': 4.57.2(tslib@2.8.1) - '@jsonjoy.com/fs-node-utils': 4.57.2(tslib@2.8.1) + '@jsonjoy.com/fs-core': 4.57.5(tslib@2.8.1) + '@jsonjoy.com/fs-node-builtins': 4.57.5(tslib@2.8.1) + '@jsonjoy.com/fs-node-utils': 4.57.5(tslib@2.8.1) thingies: 2.6.0(tslib@2.8.1) tslib: 2.8.1 - '@jsonjoy.com/fs-node-builtins@4.57.2(tslib@2.8.1)': + '@jsonjoy.com/fs-node-builtins@4.57.5(tslib@2.8.1)': dependencies: tslib: 2.8.1 - '@jsonjoy.com/fs-node-to-fsa@4.57.2(tslib@2.8.1)': + '@jsonjoy.com/fs-node-to-fsa@4.57.5(tslib@2.8.1)': dependencies: - '@jsonjoy.com/fs-fsa': 4.57.2(tslib@2.8.1) - '@jsonjoy.com/fs-node-builtins': 4.57.2(tslib@2.8.1) - '@jsonjoy.com/fs-node-utils': 4.57.2(tslib@2.8.1) + '@jsonjoy.com/fs-fsa': 4.57.5(tslib@2.8.1) + '@jsonjoy.com/fs-node-builtins': 4.57.5(tslib@2.8.1) + '@jsonjoy.com/fs-node-utils': 4.57.5(tslib@2.8.1) tslib: 2.8.1 - '@jsonjoy.com/fs-node-utils@4.57.2(tslib@2.8.1)': + '@jsonjoy.com/fs-node-utils@4.57.5(tslib@2.8.1)': dependencies: - '@jsonjoy.com/fs-node-builtins': 4.57.2(tslib@2.8.1) + '@jsonjoy.com/fs-node-builtins': 4.57.5(tslib@2.8.1) tslib: 2.8.1 - '@jsonjoy.com/fs-node@4.57.2(tslib@2.8.1)': + '@jsonjoy.com/fs-node@4.57.5(tslib@2.8.1)': dependencies: - '@jsonjoy.com/fs-core': 4.57.2(tslib@2.8.1) - '@jsonjoy.com/fs-node-builtins': 4.57.2(tslib@2.8.1) - '@jsonjoy.com/fs-node-utils': 4.57.2(tslib@2.8.1) - '@jsonjoy.com/fs-print': 4.57.2(tslib@2.8.1) - '@jsonjoy.com/fs-snapshot': 4.57.2(tslib@2.8.1) + '@jsonjoy.com/fs-core': 4.57.5(tslib@2.8.1) + '@jsonjoy.com/fs-node-builtins': 4.57.5(tslib@2.8.1) + '@jsonjoy.com/fs-node-utils': 4.57.5(tslib@2.8.1) + '@jsonjoy.com/fs-print': 4.57.5(tslib@2.8.1) + '@jsonjoy.com/fs-snapshot': 4.57.5(tslib@2.8.1) glob-to-regex.js: 1.2.0(tslib@2.8.1) thingies: 2.6.0(tslib@2.8.1) tslib: 2.8.1 - '@jsonjoy.com/fs-print@4.57.2(tslib@2.8.1)': + '@jsonjoy.com/fs-print@4.57.5(tslib@2.8.1)': dependencies: - '@jsonjoy.com/fs-node-utils': 4.57.2(tslib@2.8.1) + '@jsonjoy.com/fs-node-utils': 4.57.5(tslib@2.8.1) tree-dump: 1.1.0(tslib@2.8.1) tslib: 2.8.1 - '@jsonjoy.com/fs-snapshot@4.57.2(tslib@2.8.1)': + '@jsonjoy.com/fs-snapshot@4.57.5(tslib@2.8.1)': dependencies: '@jsonjoy.com/buffers': 17.67.0(tslib@2.8.1) - '@jsonjoy.com/fs-node-utils': 4.57.2(tslib@2.8.1) + '@jsonjoy.com/fs-node-utils': 4.57.5(tslib@2.8.1) '@jsonjoy.com/json-pack': 17.67.0(tslib@2.8.1) '@jsonjoy.com/util': 17.67.0(tslib@2.8.1) tslib: 2.8.1 @@ -11051,7 +10632,7 @@ snapshots: '@listr2/prompt-adapter-inquirer@4.2.4(@inquirer/prompts@8.5.2(@types/node@24.12.4))(@types/node@24.12.4)(listr2@10.2.1)': dependencies: '@inquirer/prompts': 8.5.2(@types/node@24.12.4) - '@inquirer/type': 4.0.6(@types/node@24.12.4) + '@inquirer/type': 4.0.7(@types/node@24.12.4) listr2: 10.2.1 transitivePeerDependencies: - '@types/node' @@ -11086,7 +10667,7 @@ snapshots: cors: 2.8.6 cross-spawn: 7.0.6 eventsource: 3.0.7 - eventsource-parser: 3.0.8 + eventsource-parser: 3.1.0 express: 5.2.1 express-rate-limit: 8.5.2(express@5.2.1) hono: 4.12.23 @@ -11219,12 +10800,12 @@ snapshots: '@nodelib/fs.scandir': 2.1.5 fastq: 1.20.1 - '@npmcli/agent@4.0.0': + '@npmcli/agent@4.0.2': dependencies: agent-base: 7.1.4 http-proxy-agent: 7.0.2(supports-color@10.2.2) https-proxy-agent: 7.0.6(supports-color@10.2.2) - lru-cache: 11.5.0 + lru-cache: 11.5.1 socks-proxy-agent: 8.0.5 transitivePeerDependencies: - supports-color @@ -11238,7 +10819,7 @@ snapshots: '@gar/promise-retry': 1.0.3 '@npmcli/promise-spawn': 9.0.1 ini: 6.0.0 - lru-cache: 11.5.0 + lru-cache: 11.5.1 npm-pick-manifest: 11.0.3 proc-log: 6.1.0 semver: 7.8.1 @@ -11328,8 +10909,8 @@ snapshots: '@octokit/graphql-schema@15.26.1': dependencies: - graphql: 16.14.0 - graphql-tag: 2.12.6(graphql@16.14.0) + graphql: 16.14.1 + graphql-tag: 2.12.6(graphql@16.14.1) '@octokit/graphql@9.0.3': dependencies: @@ -11672,9 +11253,9 @@ snapshots: optionalDependencies: rollup: 4.61.0 - '@rollup/plugin-commonjs@29.0.2(rollup@4.61.0)': + '@rollup/plugin-commonjs@29.0.3(rollup@4.61.0)': dependencies: - '@rollup/pluginutils': 5.3.0(rollup@4.61.0) + '@rollup/pluginutils': 5.4.0(rollup@4.61.0) commondir: 1.0.1 estree-walker: 2.0.2 fdir: 6.5.0(picomatch@4.0.4) @@ -11684,21 +11265,15 @@ snapshots: optionalDependencies: rollup: 4.61.0 - '@rollup/plugin-json@6.1.0(rollup@4.60.4)': - dependencies: - '@rollup/pluginutils': 5.3.0(rollup@4.60.4) - optionalDependencies: - rollup: 4.60.4 - '@rollup/plugin-json@6.1.0(rollup@4.61.0)': dependencies: - '@rollup/pluginutils': 5.3.0(rollup@4.61.0) + '@rollup/pluginutils': 5.4.0(rollup@4.61.0) optionalDependencies: rollup: 4.61.0 '@rollup/plugin-node-resolve@16.0.3(rollup@4.61.0)': dependencies: - '@rollup/pluginutils': 5.3.0(rollup@4.61.0) + '@rollup/pluginutils': 5.4.0(rollup@4.61.0) '@types/resolve': 1.20.2 deepmerge: 4.3.1 is-module: 1.0.0 @@ -11706,15 +11281,15 @@ snapshots: optionalDependencies: rollup: 4.61.0 - '@rollup/pluginutils@5.3.0(rollup@4.60.4)': + '@rollup/pluginutils@5.3.0(rollup@4.61.0)': dependencies: '@types/estree': 1.0.9 estree-walker: 2.0.2 picomatch: 4.0.4 optionalDependencies: - rollup: 4.60.4 + rollup: 4.61.0 - '@rollup/pluginutils@5.3.0(rollup@4.61.0)': + '@rollup/pluginutils@5.4.0(rollup@4.61.0)': dependencies: '@types/estree': 1.0.9 estree-walker: 2.0.2 @@ -11722,162 +11297,81 @@ snapshots: optionalDependencies: rollup: 4.61.0 - '@rollup/rollup-android-arm-eabi@4.60.4': - optional: true - '@rollup/rollup-android-arm-eabi@4.61.0': optional: true - '@rollup/rollup-android-arm64@4.60.4': - optional: true - '@rollup/rollup-android-arm64@4.61.0': optional: true - '@rollup/rollup-darwin-arm64@4.60.4': - optional: true - '@rollup/rollup-darwin-arm64@4.61.0': optional: true - '@rollup/rollup-darwin-x64@4.60.4': - optional: true - '@rollup/rollup-darwin-x64@4.61.0': optional: true - '@rollup/rollup-freebsd-arm64@4.60.4': - optional: true - '@rollup/rollup-freebsd-arm64@4.61.0': optional: true - '@rollup/rollup-freebsd-x64@4.60.4': - optional: true - '@rollup/rollup-freebsd-x64@4.61.0': optional: true - '@rollup/rollup-linux-arm-gnueabihf@4.60.4': - optional: true - '@rollup/rollup-linux-arm-gnueabihf@4.61.0': optional: true - '@rollup/rollup-linux-arm-musleabihf@4.60.4': - optional: true - '@rollup/rollup-linux-arm-musleabihf@4.61.0': optional: true - '@rollup/rollup-linux-arm64-gnu@4.60.4': - optional: true - '@rollup/rollup-linux-arm64-gnu@4.61.0': optional: true - '@rollup/rollup-linux-arm64-musl@4.60.4': - optional: true - '@rollup/rollup-linux-arm64-musl@4.61.0': optional: true - '@rollup/rollup-linux-loong64-gnu@4.60.4': - optional: true - '@rollup/rollup-linux-loong64-gnu@4.61.0': optional: true - '@rollup/rollup-linux-loong64-musl@4.60.4': - optional: true - '@rollup/rollup-linux-loong64-musl@4.61.0': optional: true - '@rollup/rollup-linux-ppc64-gnu@4.60.4': - optional: true - '@rollup/rollup-linux-ppc64-gnu@4.61.0': optional: true - '@rollup/rollup-linux-ppc64-musl@4.60.4': - optional: true - '@rollup/rollup-linux-ppc64-musl@4.61.0': optional: true - '@rollup/rollup-linux-riscv64-gnu@4.60.4': - optional: true - '@rollup/rollup-linux-riscv64-gnu@4.61.0': optional: true - '@rollup/rollup-linux-riscv64-musl@4.60.4': - optional: true - '@rollup/rollup-linux-riscv64-musl@4.61.0': optional: true - '@rollup/rollup-linux-s390x-gnu@4.60.4': - optional: true - '@rollup/rollup-linux-s390x-gnu@4.61.0': optional: true - '@rollup/rollup-linux-x64-gnu@4.60.4': - optional: true - '@rollup/rollup-linux-x64-gnu@4.61.0': optional: true - '@rollup/rollup-linux-x64-musl@4.60.4': - optional: true - '@rollup/rollup-linux-x64-musl@4.61.0': optional: true - '@rollup/rollup-openbsd-x64@4.60.4': - optional: true - '@rollup/rollup-openbsd-x64@4.61.0': optional: true - '@rollup/rollup-openharmony-arm64@4.60.4': - optional: true - '@rollup/rollup-openharmony-arm64@4.61.0': optional: true - '@rollup/rollup-win32-arm64-msvc@4.60.4': - optional: true - '@rollup/rollup-win32-arm64-msvc@4.61.0': optional: true - '@rollup/rollup-win32-ia32-msvc@4.60.4': - optional: true - '@rollup/rollup-win32-ia32-msvc@4.61.0': optional: true - '@rollup/rollup-win32-x64-gnu@4.60.4': - optional: true - '@rollup/rollup-win32-x64-gnu@4.61.0': optional: true - '@rollup/rollup-win32-x64-msvc@4.60.4': - optional: true - '@rollup/rollup-win32-x64-msvc@4.61.0': optional: true - '@rollup/wasm-node@4.60.4': - dependencies: - '@types/estree': 1.0.8 - optionalDependencies: - fsevents: 2.3.3 - '@rollup/wasm-node@4.61.0': dependencies: '@types/estree': 1.0.9 @@ -11900,7 +11394,7 @@ snapshots: '@sigstore/bundle': 4.0.0 '@sigstore/core': 3.2.1 '@sigstore/protobuf-specs': 0.5.1 - make-fetch-happen: 15.0.5 + make-fetch-happen: 15.0.6 proc-log: 6.1.0 transitivePeerDependencies: - supports-color @@ -11933,7 +11427,7 @@ snapshots: '@stylistic/eslint-plugin@5.10.0(eslint@10.4.1(jiti@2.7.0))': dependencies: '@eslint-community/eslint-utils': 4.9.1(eslint@10.4.1(jiti@2.7.0)) - '@typescript-eslint/types': 8.60.0 + '@typescript-eslint/types': 8.60.1 eslint: 10.4.1(jiti@2.7.0) eslint-visitor-keys: 4.2.1 espree: 10.4.0 @@ -12031,8 +11525,6 @@ snapshots: '@types/esrecurse@4.3.1': {} - '@types/estree@1.0.8': {} - '@types/estree@1.0.9': {} '@types/events@3.0.3': {} @@ -12302,8 +11794,6 @@ snapshots: transitivePeerDependencies: - supports-color - '@typescript-eslint/types@8.60.0': {} - '@typescript-eslint/types@8.60.1': {} '@typescript-eslint/typescript-estree@8.60.1(typescript@6.0.3)': @@ -12315,7 +11805,7 @@ snapshots: debug: 4.4.3(supports-color@10.2.2) minimatch: 10.2.5 semver: 7.8.1 - tinyglobby: 0.2.16 + tinyglobby: 0.2.17 ts-api-utils: 2.5.0(typescript@6.0.3) typescript: 6.0.3 transitivePeerDependencies: @@ -12507,7 +11997,7 @@ snapshots: dependencies: '@bcoe/v8-coverage': 1.0.2 '@vitest/utils': 4.1.8 - ast-v8-to-istanbul: 1.0.2 + ast-v8-to-istanbul: 1.0.3 istanbul-lib-coverage: 3.2.2 istanbul-lib-report: 3.0.1 istanbul-reports: 3.2.0 @@ -12526,13 +12016,13 @@ snapshots: chai: 6.2.2 tinyrainbow: 3.1.0 - '@vitest/mocker@4.1.8(vite@7.3.3(@types/node@24.12.4)(jiti@2.7.0)(less@4.6.4)(sass@1.100.0)(terser@5.48.0)(tsx@4.22.3)(yaml@2.9.0))': + '@vitest/mocker@4.1.8(vite@7.3.5(@types/node@24.12.4)(jiti@2.7.0)(less@4.6.4)(sass@1.100.0)(terser@5.48.0)(tsx@4.22.3)(yaml@2.9.0))': dependencies: '@vitest/spy': 4.1.8 estree-walker: 3.0.3 magic-string: 0.30.21 optionalDependencies: - vite: 7.3.3(@types/node@24.12.4)(jiti@2.7.0)(less@4.6.4)(sass@1.100.0)(terser@5.48.0)(tsx@4.22.3)(yaml@2.9.0) + vite: 7.3.5(@types/node@24.12.4)(jiti@2.7.0)(less@4.6.4)(sass@1.100.0)(terser@5.48.0)(tsx@4.22.3)(yaml@2.9.0) '@vitest/pretty-format@4.1.8': dependencies: @@ -12840,7 +12330,7 @@ snapshots: assertion-error@2.0.1: {} - ast-v8-to-istanbul@1.0.2: + ast-v8-to-istanbul@1.0.3: dependencies: '@jridgewell/trace-mapping': 0.3.31 estree-walker: 3.0.3 @@ -12922,13 +12412,13 @@ snapshots: balanced-match@4.0.4: {} - bare-events@2.8.3: {} + bare-events@2.9.1: {} - bare-fs@4.7.1: + bare-fs@4.7.2: dependencies: - bare-events: 2.8.3 - bare-path: 3.0.0 - bare-stream: 2.13.1(bare-events@2.8.3) + bare-events: 2.9.1 + bare-path: 3.0.1 + bare-stream: 2.13.1(bare-events@2.9.1) bare-url: 2.4.3 fast-fifo: 1.3.2 transitivePeerDependencies: @@ -12937,28 +12427,28 @@ snapshots: bare-os@3.9.1: {} - bare-path@3.0.0: + bare-path@3.0.1: dependencies: bare-os: 3.9.1 - bare-stream@2.13.1(bare-events@2.8.3): + bare-stream@2.13.1(bare-events@2.9.1): dependencies: - streamx: 2.25.0 + streamx: 2.26.0 teex: 1.0.1 optionalDependencies: - bare-events: 2.8.3 + bare-events: 2.9.1 transitivePeerDependencies: - react-native-b4a bare-url@2.4.3: dependencies: - bare-path: 3.0.0 + bare-path: 3.0.1 base64-js@1.5.1: {} base64id@2.0.0: {} - baseline-browser-mapping@2.10.32: {} + baseline-browser-mapping@2.10.33: {} batch@0.6.1: {} @@ -13113,10 +12603,10 @@ snapshots: browserslist@4.28.2: dependencies: - baseline-browser-mapping: 2.10.32 + baseline-browser-mapping: 2.10.33 caniuse-lite: 1.0.30001793 - electron-to-chromium: 1.5.361 - node-releases: 2.0.46 + electron-to-chromium: 1.5.366 + node-releases: 2.0.47 update-browserslist-db: 1.2.3(browserslist@4.28.2) bs-recipes@1.3.4: {} @@ -13147,7 +12637,7 @@ snapshots: '@npmcli/fs': 5.0.0 fs-minipass: 3.0.3 glob: 13.0.6 - lru-cache: 11.5.0 + lru-cache: 11.5.1 minipass: 7.1.3 minipass-collect: 2.0.1 minipass-flush: 1.0.7 @@ -13387,7 +12877,7 @@ snapshots: normalize-path: 3.0.0 schema-utils: 4.3.3 serialize-javascript: 7.0.5 - tinyglobby: 0.2.16 + tinyglobby: 0.2.17 webpack: 5.107.2(esbuild@0.28.0)(postcss@8.5.15) core-js-compat@3.49.0: @@ -13407,7 +12897,7 @@ snapshots: dependencies: env-paths: 2.2.1 import-fresh: 3.3.1 - js-yaml: 4.1.1 + js-yaml: 4.2.0 parse-json: 5.2.0 optionalDependencies: typescript: 6.0.3 @@ -13647,7 +13137,7 @@ snapshots: ejs@5.0.2: {} - electron-to-chromium@1.5.361: {} + electron-to-chromium@1.5.366: {} emoji-regex@10.6.0: {} @@ -13700,7 +13190,7 @@ snapshots: - supports-color - utf-8-validate - enhanced-resolve@5.22.0: + enhanced-resolve@5.22.1: dependencies: graceful-fs: 4.2.11 tapable: 2.3.3 @@ -13757,7 +13247,7 @@ snapshots: has-property-descriptors: 1.0.2 has-proto: 1.2.0 has-symbols: 1.1.0 - hasown: 2.0.3 + hasown: 2.0.4 internal-slot: 1.1.0 is-array-buffer: 3.0.5 is-callable: 1.2.7 @@ -13786,9 +13276,9 @@ snapshots: typed-array-buffer: 1.0.3 typed-array-byte-length: 1.0.3 typed-array-byte-offset: 1.0.4 - typed-array-length: 1.0.7 + typed-array-length: 1.0.8 unbox-primitive: 1.1.0 - which-typed-array: 1.1.20 + which-typed-array: 1.1.21 es-define-property@1.0.1: {} @@ -13805,11 +13295,11 @@ snapshots: es-errors: 1.3.0 get-intrinsic: 1.3.0 has-tostringtag: 1.0.2 - hasown: 2.0.3 + hasown: 2.0.4 es-shim-unscopables@1.1.0: dependencies: - hasown: 2.0.3 + hasown: 2.0.4 es-to-primitive@1.3.0: dependencies: @@ -13895,7 +13385,7 @@ snapshots: transitivePeerDependencies: - supports-color - eslint-module-utils@2.12.1(@typescript-eslint/parser@8.60.1(eslint@10.4.1(jiti@2.7.0))(typescript@6.0.3))(eslint-import-resolver-node@0.3.10)(eslint@10.4.1(jiti@2.7.0)): + eslint-module-utils@2.13.0(@typescript-eslint/parser@8.60.1(eslint@10.4.1(jiti@2.7.0))(typescript@6.0.3))(eslint-import-resolver-node@0.3.10)(eslint@10.4.1(jiti@2.7.0)): dependencies: debug: 3.2.7 optionalDependencies: @@ -13916,8 +13406,8 @@ snapshots: doctrine: 2.1.0 eslint: 10.4.1(jiti@2.7.0) eslint-import-resolver-node: 0.3.10 - eslint-module-utils: 2.12.1(@typescript-eslint/parser@8.60.1(eslint@10.4.1(jiti@2.7.0))(typescript@6.0.3))(eslint-import-resolver-node@0.3.10)(eslint@10.4.1(jiti@2.7.0)) - hasown: 2.0.3 + eslint-module-utils: 2.13.0(@typescript-eslint/parser@8.60.1(eslint@10.4.1(jiti@2.7.0))(typescript@6.0.3))(eslint-import-resolver-node@0.3.10)(eslint@10.4.1(jiti@2.7.0)) + hasown: 2.0.4 is-core-module: 2.16.2 is-glob: 4.0.3 minimatch: 3.1.5 @@ -14033,17 +13523,17 @@ snapshots: events-universal@1.0.1: dependencies: - bare-events: 2.8.3 + bare-events: 2.9.1 transitivePeerDependencies: - bare-abort-controller events@3.3.0: {} - eventsource-parser@3.0.8: {} + eventsource-parser@3.1.0: {} eventsource@3.0.7: dependencies: - eventsource-parser: 3.0.8 + eventsource-parser: 3.1.0 expect-type@1.3.0: {} @@ -14346,7 +13836,7 @@ snapshots: asynckit: 0.4.0 combined-stream: 1.0.8 es-set-tostringtag: 2.1.0 - hasown: 2.0.3 + hasown: 2.0.4 mime-types: 2.1.35 formdata-polyfill@4.0.10: @@ -14390,7 +13880,7 @@ snapshots: call-bound: 1.0.4 define-properties: 1.2.1 functions-have-names: 1.2.3 - hasown: 2.0.3 + hasown: 2.0.4 is-callable: 1.2.7 functions-have-names@1.2.3: {} @@ -14431,7 +13921,7 @@ snapshots: get-proto: 1.0.1 gopd: 1.2.0 has-symbols: 1.1.0 - hasown: 2.0.3 + hasown: 2.0.4 math-intrinsics: 1.1.0 get-npm-tarball-url@2.1.0: {} @@ -14534,7 +14024,7 @@ snapshots: node-fetch: 3.3.2 object-hash: 3.0.0 proto3-json-serializer: 3.0.4 - protobufjs: 7.6.1 + protobufjs: 7.6.2 retry-request: 8.0.2(supports-color@10.2.2) rimraf: 5.0.10 transitivePeerDependencies: @@ -14561,17 +14051,17 @@ snapshots: graceful-fs@4.2.11: {} - graphql-tag@2.12.6(graphql@16.14.0): + graphql-tag@2.12.6(graphql@16.14.1): dependencies: - graphql: 16.14.0 + graphql: 16.14.1 tslib: 2.8.1 - graphql@16.14.0: {} + graphql@16.14.1: {} - grpc-gcp@1.0.1(protobufjs@7.6.1): + grpc-gcp@1.0.1(protobufjs@7.6.2): dependencies: '@grpc/grpc-js': 1.14.4 - protobufjs: 7.6.1 + protobufjs: 7.6.2 gunzip-maybe@1.4.2: dependencies: @@ -14611,7 +14101,7 @@ snapshots: dependencies: has-symbols: 1.1.0 - hasown@2.0.3: + hasown@2.0.4: dependencies: function-bind: 1.1.2 @@ -14619,11 +14109,11 @@ snapshots: hosted-git-info@10.1.1: dependencies: - lru-cache: 11.5.0 + lru-cache: 11.5.1 hosted-git-info@9.0.3: dependencies: - lru-cache: 11.5.0 + lru-cache: 11.5.1 hpack.js@2.1.6: dependencies: @@ -14781,7 +14271,7 @@ snapshots: immutable@3.8.3: {} - immutable@5.1.5: {} + immutable@5.1.6: {} import-fresh@3.3.1: dependencies: @@ -14808,7 +14298,7 @@ snapshots: internal-slot@1.1.0: dependencies: es-errors: 1.3.0 - hasown: 2.0.3 + hasown: 2.0.4 side-channel: 1.1.0 ip-address@10.2.0: {} @@ -14850,7 +14340,7 @@ snapshots: is-core-module@2.16.2: dependencies: - hasown: 2.0.3 + hasown: 2.0.4 is-data-view@1.0.2: dependencies: @@ -14945,7 +14435,7 @@ snapshots: call-bound: 1.0.4 gopd: 1.2.0 has-tostringtag: 1.0.2 - hasown: 2.0.3 + hasown: 2.0.4 is-set@2.0.3: {} @@ -14968,7 +14458,7 @@ snapshots: is-typed-array@1.1.15: dependencies: - which-typed-array: 1.1.20 + which-typed-array: 1.1.21 is-typedarray@1.0.0: {} @@ -15097,6 +14587,10 @@ snapshots: dependencies: argparse: 2.0.1 + js-yaml@4.2.0: + dependencies: + argparse: 2.0.1 + jsbn@0.1.1: {} jsdom@29.1.1: @@ -15111,12 +14605,12 @@ snapshots: decimal.js: 10.6.0 html-encoding-sniffer: 6.0.0 is-potential-custom-element-name: 1.0.1 - lru-cache: 11.5.0 + lru-cache: 11.5.1 parse5: 8.0.1 saxes: 6.0.0 symbol-tree: 3.2.4 tough-cookie: 6.0.1 - undici: 7.26.0 + undici: 7.27.0 w3c-xmlserializer: 5.0.0 webidl-conversions: 8.0.1 whatwg-mimetype: 5.0.0 @@ -15253,7 +14747,7 @@ snapshots: rimraf: 3.0.2 socket.io: 4.8.3(bufferutil@4.1.0)(utf-8-validate@6.0.6) source-map: 0.6.1 - tmp: 0.2.5 + tmp: 0.2.7 ua-parser-js: 0.7.41 yargs: 16.2.0 transitivePeerDependencies: @@ -15268,7 +14762,7 @@ snapshots: kind-of@6.0.3: {} - launch-editor@2.13.2: + launch-editor@2.14.1: dependencies: picocolors: 1.1.1 shell-quote: 1.8.4 @@ -15415,7 +14909,7 @@ snapshots: lru-cache@10.4.3: {} - lru-cache@11.5.0: {} + lru-cache@11.5.1: {} lru-cache@5.1.1: dependencies: @@ -15443,10 +14937,10 @@ snapshots: dependencies: semver: 7.8.1 - make-fetch-happen@15.0.5: + make-fetch-happen@15.0.6: dependencies: '@gar/promise-retry': 1.0.3 - '@npmcli/agent': 4.0.0 + '@npmcli/agent': 4.0.2 '@npmcli/redact': 4.0.0 cacache: 20.0.4 http-cache-semantics: 4.2.0 @@ -15468,16 +14962,16 @@ snapshots: media-typer@1.1.0: {} - memfs@4.57.2(tslib@2.8.1): + memfs@4.57.5(tslib@2.8.1): dependencies: - '@jsonjoy.com/fs-core': 4.57.2(tslib@2.8.1) - '@jsonjoy.com/fs-fsa': 4.57.2(tslib@2.8.1) - '@jsonjoy.com/fs-node': 4.57.2(tslib@2.8.1) - '@jsonjoy.com/fs-node-builtins': 4.57.2(tslib@2.8.1) - '@jsonjoy.com/fs-node-to-fsa': 4.57.2(tslib@2.8.1) - '@jsonjoy.com/fs-node-utils': 4.57.2(tslib@2.8.1) - '@jsonjoy.com/fs-print': 4.57.2(tslib@2.8.1) - '@jsonjoy.com/fs-snapshot': 4.57.2(tslib@2.8.1) + '@jsonjoy.com/fs-core': 4.57.5(tslib@2.8.1) + '@jsonjoy.com/fs-fsa': 4.57.5(tslib@2.8.1) + '@jsonjoy.com/fs-node': 4.57.5(tslib@2.8.1) + '@jsonjoy.com/fs-node-builtins': 4.57.5(tslib@2.8.1) + '@jsonjoy.com/fs-node-to-fsa': 4.57.5(tslib@2.8.1) + '@jsonjoy.com/fs-node-utils': 4.57.5(tslib@2.8.1) + '@jsonjoy.com/fs-print': 4.57.5(tslib@2.8.1) + '@jsonjoy.com/fs-snapshot': 4.57.5(tslib@2.8.1) '@jsonjoy.com/json-pack': 1.21.0(tslib@2.8.1) '@jsonjoy.com/util': 1.9.0(tslib@2.8.1) glob-to-regex.js: 1.2.0(tslib@2.8.1) @@ -15634,8 +15128,6 @@ snapshots: mute-stream@3.0.0: {} - mute-stream@4.0.0: {} - nanoid@3.3.12: {} natural-compare@1.4.0: {} @@ -15658,8 +15150,8 @@ snapshots: dependencies: '@ampproject/remapping': 2.3.0 '@angular/compiler-cli': 22.0.0(@angular/compiler@22.0.0)(typescript@6.0.3) - '@rollup/plugin-json': 6.1.0(rollup@4.60.4) - '@rollup/wasm-node': 4.60.4 + '@rollup/plugin-json': 6.1.0(rollup@4.61.0) + '@rollup/wasm-node': 4.61.0 ajv: 8.20.0 browserslist: 4.28.2 chokidar: 5.0.0 @@ -15673,14 +15165,14 @@ snapshots: ora: 9.4.0 piscina: 5.1.4 postcss: 8.5.15 - rollup-plugin-dts: 6.4.1(rollup@4.60.4)(typescript@6.0.3) + rollup-plugin-dts: 6.4.1(rollup@4.61.0)(typescript@6.0.3) rxjs: 7.8.2 sass: 1.100.0 - tinyglobby: 0.2.16 + tinyglobby: 0.2.17 tslib: 2.8.1 typescript: 6.0.3 optionalDependencies: - rollup: 4.60.4 + rollup: 4.61.0 nock@14.0.15: dependencies: @@ -15738,12 +15230,12 @@ snapshots: nopt: 9.0.0 proc-log: 6.1.0 semver: 7.8.1 - tar: 7.5.15 - tinyglobby: 0.2.16 + tar: 7.5.16 + tinyglobby: 0.2.17 undici: 6.26.0 which: 6.0.1 - node-releases@2.0.46: {} + node-releases@2.0.47: {} nopt@9.0.0: dependencies: @@ -15793,7 +15285,7 @@ snapshots: dependencies: '@npmcli/redact': 4.0.0 jsonparse: 1.3.1 - make-fetch-happen: 15.0.5 + make-fetch-happen: 15.0.6 minipass: 7.1.3 minipass-fetch: 5.0.2 minizlib: 3.1.0 @@ -15979,7 +15471,7 @@ snapshots: proc-log: 6.1.0 sigstore: 4.1.1 ssri: 13.0.1 - tar: 7.5.15 + tar: 7.5.16 transitivePeerDependencies: - supports-color @@ -16031,7 +15523,7 @@ snapshots: path-scurry@2.0.2: dependencies: - lru-cache: 11.5.0 + lru-cache: 11.5.1 minipass: 7.1.3 path-to-regexp@0.1.13: {} @@ -16086,7 +15578,7 @@ snapshots: real-require: 0.2.0 safe-stable-stringify: 2.5.0 sonic-boom: 4.2.1 - thread-stream: 3.1.0 + thread-stream: 3.2.0 piscina@5.1.4: optionalDependencies: @@ -16189,9 +15681,9 @@ snapshots: proto3-json-serializer@3.0.4: dependencies: - protobufjs: 7.6.1 + protobufjs: 7.6.2 - protobufjs@7.6.1: + protobufjs@7.6.2: dependencies: '@protobufjs/aspromise': 1.1.2 '@protobufjs/base64': 1.1.2 @@ -16501,17 +15993,6 @@ snapshots: semver: 7.8.1 spdx-expression-validate: 2.0.0 - rollup-plugin-dts@6.4.1(rollup@4.60.4)(typescript@6.0.3): - dependencies: - '@jridgewell/remapping': 2.3.5 - '@jridgewell/sourcemap-codec': 1.5.5 - convert-source-map: 2.0.0 - magic-string: 0.30.21 - rollup: 4.60.4 - typescript: 6.0.3 - optionalDependencies: - '@babel/code-frame': 7.29.7 - rollup-plugin-dts@6.4.1(rollup@4.61.0)(typescript@6.0.3): dependencies: '@jridgewell/remapping': 2.3.5 @@ -16530,37 +16011,6 @@ snapshots: optionalDependencies: '@types/node': 22.19.19 - rollup@4.60.4: - dependencies: - '@types/estree': 1.0.8 - optionalDependencies: - '@rollup/rollup-android-arm-eabi': 4.60.4 - '@rollup/rollup-android-arm64': 4.60.4 - '@rollup/rollup-darwin-arm64': 4.60.4 - '@rollup/rollup-darwin-x64': 4.60.4 - '@rollup/rollup-freebsd-arm64': 4.60.4 - '@rollup/rollup-freebsd-x64': 4.60.4 - '@rollup/rollup-linux-arm-gnueabihf': 4.60.4 - '@rollup/rollup-linux-arm-musleabihf': 4.60.4 - '@rollup/rollup-linux-arm64-gnu': 4.60.4 - '@rollup/rollup-linux-arm64-musl': 4.60.4 - '@rollup/rollup-linux-loong64-gnu': 4.60.4 - '@rollup/rollup-linux-loong64-musl': 4.60.4 - '@rollup/rollup-linux-ppc64-gnu': 4.60.4 - '@rollup/rollup-linux-ppc64-musl': 4.60.4 - '@rollup/rollup-linux-riscv64-gnu': 4.60.4 - '@rollup/rollup-linux-riscv64-musl': 4.60.4 - '@rollup/rollup-linux-s390x-gnu': 4.60.4 - '@rollup/rollup-linux-x64-gnu': 4.60.4 - '@rollup/rollup-linux-x64-musl': 4.60.4 - '@rollup/rollup-openbsd-x64': 4.60.4 - '@rollup/rollup-openharmony-arm64': 4.60.4 - '@rollup/rollup-win32-arm64-msvc': 4.60.4 - '@rollup/rollup-win32-ia32-msvc': 4.60.4 - '@rollup/rollup-win32-x64-gnu': 4.60.4 - '@rollup/rollup-win32-x64-msvc': 4.60.4 - fsevents: 2.3.3 - rollup@4.61.0: dependencies: '@types/estree': 1.0.9 @@ -16653,7 +16103,7 @@ snapshots: sass@1.100.0: dependencies: chokidar: 5.0.0 - immutable: 5.1.5 + immutable: 5.1.6 source-map-js: 1.2.1 optionalDependencies: '@parcel/watcher': 2.5.6 @@ -17050,7 +16500,7 @@ snapshots: transitivePeerDependencies: - supports-color - streamx@2.25.0: + streamx@2.26.0: dependencies: events-universal: 1.0.1 fast-fifo: 1.3.2 @@ -17149,7 +16599,7 @@ snapshots: dependencies: b4a: 1.8.1 fast-fifo: 1.3.2 - streamx: 2.25.0 + streamx: 2.26.0 transitivePeerDependencies: - bare-abort-controller - react-native-b4a @@ -17157,15 +16607,15 @@ snapshots: tar-stream@3.2.0: dependencies: b4a: 1.8.1 - bare-fs: 4.7.1 + bare-fs: 4.7.2 fast-fifo: 1.3.2 - streamx: 2.25.0 + streamx: 2.26.0 transitivePeerDependencies: - bare-abort-controller - bare-buffer - react-native-b4a - tar@7.5.15: + tar@7.5.16: dependencies: '@isaacs/fs-minipass': 4.0.1 chownr: 3.0.0 @@ -17184,12 +16634,12 @@ snapshots: teex@1.0.1: dependencies: - streamx: 2.25.0 + streamx: 2.26.0 transitivePeerDependencies: - bare-abort-controller - react-native-b4a - terser-webpack-plugin@5.6.0(esbuild@0.28.0)(postcss@8.5.15)(webpack@5.107.2(esbuild@0.28.0)(postcss@8.5.15)): + terser-webpack-plugin@5.6.1(esbuild@0.28.0)(postcss@8.5.15)(webpack@5.107.2(esbuild@0.28.0)(postcss@8.5.15)): dependencies: '@jridgewell/trace-mapping': 0.3.31 jest-worker: 27.5.1 @@ -17200,7 +16650,7 @@ snapshots: esbuild: 0.28.0 postcss: 8.5.15 - terser-webpack-plugin@5.6.0(esbuild@0.28.0)(webpack@5.107.2(esbuild@0.28.0)): + terser-webpack-plugin@5.6.1(esbuild@0.28.0)(webpack@5.107.2(esbuild@0.28.0)): dependencies: '@jridgewell/trace-mapping': 0.3.31 jest-worker: 27.5.1 @@ -17227,7 +16677,7 @@ snapshots: dependencies: tslib: 2.8.1 - thread-stream@3.1.0: + thread-stream@3.2.0: dependencies: real-require: 0.2.0 @@ -17248,12 +16698,7 @@ snapshots: tinybench@2.9.0: {} - tinyexec@1.2.2: {} - - tinyglobby@0.2.16: - dependencies: - fdir: 6.5.0(picomatch@4.0.4) - picomatch: 4.0.4 + tinyexec@1.2.4: {} tinyglobby@0.2.17: dependencies: @@ -17264,17 +16709,17 @@ snapshots: tldts-core@6.1.86: {} - tldts-core@7.4.0: {} + tldts-core@7.4.2: {} tldts@6.1.86: dependencies: tldts-core: 6.1.86 - tldts@7.4.0: + tldts@7.4.2: dependencies: - tldts-core: 7.4.0 + tldts-core: 7.4.2 - tmp@0.2.5: {} + tmp@0.2.7: {} to-regex-range@5.0.1: dependencies: @@ -17290,7 +16735,7 @@ snapshots: tough-cookie@6.0.1: dependencies: - tldts: 7.4.0 + tldts: 7.4.2 tr46@0.0.3: {} @@ -17335,7 +16780,7 @@ snapshots: dependencies: '@tufjs/models': 4.1.0 debug: 4.4.3(supports-color@10.2.2) - make-fetch-happen: 15.0.5 + make-fetch-happen: 15.0.6 transitivePeerDependencies: - supports-color @@ -17388,7 +16833,7 @@ snapshots: is-typed-array: 1.1.15 reflect.getprototypeof: 1.0.10 - typed-array-length@1.0.7: + typed-array-length@1.0.8: dependencies: call-bind: 1.0.9 for-each: 0.3.5 @@ -17425,7 +16870,7 @@ snapshots: undici@6.26.0: {} - undici@7.26.0: {} + undici@7.27.0: {} undici@8.3.0: {} @@ -17575,32 +17020,14 @@ snapshots: core-util-is: 1.0.2 extsprintf: 1.3.0 - vite@7.3.3(@types/node@24.12.4)(jiti@2.7.0)(less@4.6.4)(sass@1.100.0)(terser@5.48.0)(tsx@4.22.3)(yaml@2.9.0): - dependencies: - esbuild: 0.27.7 - fdir: 6.5.0(picomatch@4.0.4) - picomatch: 4.0.4 - postcss: 8.5.15 - rollup: 4.60.4 - tinyglobby: 0.2.16 - optionalDependencies: - '@types/node': 24.12.4 - fsevents: 2.3.3 - jiti: 2.7.0 - less: 4.6.4 - sass: 1.100.0 - terser: 5.48.0 - tsx: 4.22.3 - yaml: 2.9.0 - vite@7.3.5(@types/node@24.12.4)(jiti@2.7.0)(less@4.6.4)(sass@1.100.0)(terser@5.48.0)(tsx@4.22.3)(yaml@2.9.0): dependencies: esbuild: 0.27.7 fdir: 6.5.0(picomatch@4.0.4) picomatch: 4.0.4 postcss: 8.5.15 - rollup: 4.60.4 - tinyglobby: 0.2.16 + rollup: 4.61.0 + tinyglobby: 0.2.17 optionalDependencies: '@types/node': 24.12.4 fsevents: 2.3.3 @@ -17614,7 +17041,7 @@ snapshots: vitest@4.1.8(@opentelemetry/api@1.9.1)(@types/node@24.12.4)(@vitest/coverage-v8@4.1.8)(jiti@2.7.0)(jsdom@29.1.1)(less@4.6.4)(sass@1.100.0)(terser@5.48.0)(tsx@4.22.3)(yaml@2.9.0): dependencies: '@vitest/expect': 4.1.8 - '@vitest/mocker': 4.1.8(vite@7.3.3(@types/node@24.12.4)(jiti@2.7.0)(less@4.6.4)(sass@1.100.0)(terser@5.48.0)(tsx@4.22.3)(yaml@2.9.0)) + '@vitest/mocker': 4.1.8(vite@7.3.5(@types/node@24.12.4)(jiti@2.7.0)(less@4.6.4)(sass@1.100.0)(terser@5.48.0)(tsx@4.22.3)(yaml@2.9.0)) '@vitest/pretty-format': 4.1.8 '@vitest/runner': 4.1.8 '@vitest/snapshot': 4.1.8 @@ -17628,10 +17055,10 @@ snapshots: picomatch: 4.0.4 std-env: 4.1.0 tinybench: 2.9.0 - tinyexec: 1.2.2 - tinyglobby: 0.2.16 + tinyexec: 1.2.4 + tinyglobby: 0.2.17 tinyrainbow: 3.1.0 - vite: 7.3.3(@types/node@24.12.4)(jiti@2.7.0)(less@4.6.4)(sass@1.100.0)(terser@5.48.0)(tsx@4.22.3)(yaml@2.9.0) + vite: 7.3.5(@types/node@24.12.4)(jiti@2.7.0)(less@4.6.4)(sass@1.100.0)(terser@5.48.0)(tsx@4.22.3)(yaml@2.9.0) why-is-node-running: 2.3.0 optionalDependencies: '@opentelemetry/api': 1.9.1 @@ -17682,7 +17109,7 @@ snapshots: webpack-dev-middleware@7.4.5(tslib@2.8.1)(webpack@5.107.2(esbuild@0.28.0)(postcss@8.5.15)): dependencies: colorette: 2.0.20 - memfs: 4.57.2(tslib@2.8.1) + memfs: 4.57.5(tslib@2.8.1) mime-types: 3.0.2 on-finished: 2.4.1 range-parser: 1.2.1 @@ -17695,7 +17122,7 @@ snapshots: webpack-dev-middleware@7.4.5(tslib@2.8.1)(webpack@5.107.2(esbuild@0.28.0)): dependencies: colorette: 2.0.20 - memfs: 4.57.2(tslib@2.8.1) + memfs: 4.57.5(tslib@2.8.1) mime-types: 3.0.2 on-finished: 2.4.1 range-parser: 1.2.1 @@ -17707,7 +17134,7 @@ snapshots: webpack-dev-middleware@8.0.3(tslib@2.8.1)(webpack@5.107.2(esbuild@0.28.0)(postcss@8.5.15)): dependencies: - memfs: 4.57.2(tslib@2.8.1) + memfs: 4.57.5(tslib@2.8.1) mime-types: 3.0.2 on-finished: 2.4.1 range-parser: 1.2.1 @@ -17737,7 +17164,7 @@ snapshots: graceful-fs: 4.2.11 http-proxy-middleware: 2.0.9(@types/express@4.17.25) ipaddr.js: 2.4.0 - launch-editor: 2.13.2 + launch-editor: 2.14.1 open: 10.2.0 p-retry: 6.2.1 schema-utils: 4.3.3 @@ -17776,7 +17203,7 @@ snapshots: graceful-fs: 4.2.11 http-proxy-middleware: 2.0.9(@types/express@4.17.25) ipaddr.js: 2.4.0 - launch-editor: 2.13.2 + launch-editor: 2.14.1 open: 10.2.0 p-retry: 6.2.1 schema-utils: 4.3.3 @@ -17819,7 +17246,7 @@ snapshots: acorn-import-phases: 1.0.4(acorn@8.16.0) browserslist: 4.28.2 chrome-trace-event: 1.0.4 - enhanced-resolve: 5.22.0 + enhanced-resolve: 5.22.1 es-module-lexer: 2.1.0 eslint-scope: 5.1.1 events: 3.3.0 @@ -17830,7 +17257,7 @@ snapshots: neo-async: 2.6.2 schema-utils: 4.3.3 tapable: 2.3.3 - terser-webpack-plugin: 5.6.0(esbuild@0.28.0)(webpack@5.107.2(esbuild@0.28.0)) + terser-webpack-plugin: 5.6.1(esbuild@0.28.0)(webpack@5.107.2(esbuild@0.28.0)) watchpack: 2.5.1 webpack-sources: 3.5.0 transitivePeerDependencies: @@ -17858,7 +17285,7 @@ snapshots: acorn-import-phases: 1.0.4(acorn@8.16.0) browserslist: 4.28.2 chrome-trace-event: 1.0.4 - enhanced-resolve: 5.22.0 + enhanced-resolve: 5.22.1 es-module-lexer: 2.1.0 eslint-scope: 5.1.1 events: 3.3.0 @@ -17869,7 +17296,7 @@ snapshots: neo-async: 2.6.2 schema-utils: 4.3.3 tapable: 2.3.3 - terser-webpack-plugin: 5.6.0(esbuild@0.28.0)(postcss@8.5.15)(webpack@5.107.2(esbuild@0.28.0)(postcss@8.5.15)) + terser-webpack-plugin: 5.6.1(esbuild@0.28.0)(postcss@8.5.15)(webpack@5.107.2(esbuild@0.28.0)(postcss@8.5.15)) watchpack: 2.5.1 webpack-sources: 3.5.0 transitivePeerDependencies: @@ -17931,7 +17358,7 @@ snapshots: isarray: 2.0.5 which-boxed-primitive: 1.1.1 which-collection: 1.0.2 - which-typed-array: 1.1.20 + which-typed-array: 1.1.21 which-collection@1.0.2: dependencies: @@ -17940,7 +17367,7 @@ snapshots: is-weakmap: 2.0.2 is-weakset: 2.0.4 - which-typed-array@1.1.20: + which-typed-array@1.1.21: dependencies: available-typed-arrays: 1.0.7 call-bind: 1.0.9 From 21cb6284df0647daf365433ea735990744ad4edc Mon Sep 17 00:00:00 2001 From: Charles Lyding <19598772+clydin@users.noreply.github.com> Date: Fri, 5 Jun 2026 09:21:32 -0400 Subject: [PATCH 014/787] fix(@schematics/angular): fix browserMode option mapping in refactor-jasmine-vitest The jasmine-vitest refactor schematic previously mapped the `browserMode` option to `options.browerMode` (with a spelling typo). Because of the index signature `[property: string]: any` in the generated options Schema type, the compiler did not emit any error, which resulted in the option silently resolving to `undefined` at runtime and disabling browser-mode transformations. --- .../angular/refactor/jasmine-vitest/index.ts | 2 +- .../refactor/jasmine-vitest/index_spec.ts | 42 +++++++++++++++++++ 2 files changed, 43 insertions(+), 1 deletion(-) diff --git a/packages/schematics/angular/refactor/jasmine-vitest/index.ts b/packages/schematics/angular/refactor/jasmine-vitest/index.ts index 493bb0eb1800..e163a88c6207 100644 --- a/packages/schematics/angular/refactor/jasmine-vitest/index.ts +++ b/packages/schematics/angular/refactor/jasmine-vitest/index.ts @@ -121,7 +121,7 @@ export default function (options: Schema): Rule { const content = tree.readText(file); const newContent = transformJasmineToVitest(file, content, reporter, { addImports: !!options.addImports, - browserMode: !!options.browerMode, + browserMode: !!options.browserMode, fakeAsync: !!options.fakeAsync, }); diff --git a/packages/schematics/angular/refactor/jasmine-vitest/index_spec.ts b/packages/schematics/angular/refactor/jasmine-vitest/index_spec.ts index a1abb7562ee8..2581d8bbacc9 100644 --- a/packages/schematics/angular/refactor/jasmine-vitest/index_spec.ts +++ b/packages/schematics/angular/refactor/jasmine-vitest/index_spec.ts @@ -238,4 +238,46 @@ describe('Jasmine to Vitest Schematic', () => { expect(logs).toContain('- 1 TODO(s) added for manual review:'); expect(logs).toContain(' - 1x spyOnAllFunctions'); }); + + it('should not transform toHaveClass when browserMode is true', async () => { + const specFilePath = 'projects/bar/src/app/app.spec.ts'; + const content = ` + describe('AppComponent', () => { + it('should check class', () => { + expect(element).toHaveClass('active'); + }); + }); + `; + appTree.overwrite(specFilePath, content); + + const tree = await schematicRunner.runSchematic( + 'refactor-jasmine-vitest', + { project: 'bar', browserMode: true }, + appTree, + ); + + const result = tree.readContent(specFilePath); + expect(result).toContain("expect(element).toHaveClass('active');"); + }); + + it('should transform toHaveClass when browserMode is false', async () => { + const specFilePath = 'projects/bar/src/app/app.spec.ts'; + const content = ` + describe('AppComponent', () => { + it('should check class', () => { + expect(element).toHaveClass('active'); + }); + }); + `; + appTree.overwrite(specFilePath, content); + + const tree = await schematicRunner.runSchematic( + 'refactor-jasmine-vitest', + { project: 'bar', browserMode: false }, + appTree, + ); + + const result = tree.readContent(specFilePath); + expect(result).toContain("expect(element.classList.contains('active')).toBe(true);"); + }); }); From 8358805d31232229fb86bde9498a5ccef5048c6c Mon Sep 17 00:00:00 2001 From: Charles Lyding <19598772+clydin@users.noreply.github.com> Date: Thu, 4 Jun 2026 13:36:33 -0400 Subject: [PATCH 015/787] fix(@angular/build): restrict application builder output paths to output directory Ensure all file writes and deletions produced by the application builder are strictly scoped to the configured `outputPath` base directory. This prevents accidental writes and overwrites of files outside of the output directory (e.g. if the `browser` directory option is configured with relative path segments like `..` that escape the base output folder). --- .../build/src/builders/application/index.ts | 83 ++++++++++++------- .../tests/options/output-path_spec.ts | 22 +++++ packages/angular/build/src/utils/path.ts | 7 +- packages/angular/build/src/utils/path_spec.ts | 41 +++++++++ 4 files changed, 118 insertions(+), 35 deletions(-) create mode 100644 packages/angular/build/src/utils/path_spec.ts diff --git a/packages/angular/build/src/builders/application/index.ts b/packages/angular/build/src/builders/application/index.ts index f127ef4bdc7f..b31fc0a8f81b 100644 --- a/packages/angular/build/src/builders/application/index.ts +++ b/packages/angular/build/src/builders/application/index.ts @@ -15,6 +15,7 @@ import { createJsonBuildManifest, emitFilesToDisk } from '../../tools/esbuild/ut import { colors as ansiColors } from '../../utils/color'; import { deleteOutputDir } from '../../utils/delete-output-dir'; import { bazelEsbuildPluginPath, useJSONBuildLogs } from '../../utils/environment-options'; +import { isSubDirectory } from '../../utils/path'; import { purgeStaleBuildCache } from '../../utils/purge-cache'; import { assertCompatibleAngularVersion } from '../../utils/version'; import { runEsBuildBuildAction } from './build-action'; @@ -197,45 +198,57 @@ export async function* buildApplication( // Writes the output files to disk and ensures the containing directories are present const directoryExists = new Set(); - await emitFilesToDisk(Object.entries(result.files), async ([filePath, file]) => { - if ( - outputOptions.ignoreServer && - (file.type === BuildOutputFileType.ServerApplication || - file.type === BuildOutputFileType.ServerRoot) - ) { - return; - } + try { + await emitFilesToDisk(Object.entries(result.files), async ([filePath, file]) => { + if ( + outputOptions.ignoreServer && + (file.type === BuildOutputFileType.ServerApplication || + file.type === BuildOutputFileType.ServerRoot) + ) { + return; + } - const fullFilePath = generateFullPath(filePath, file.type, outputOptions); + const fullFilePath = generateFullPath(filePath, file.type, outputOptions); - // Ensure output subdirectories exist - const fileBasePath = path.dirname(fullFilePath); - if (fileBasePath && !directoryExists.has(fileBasePath)) { - await fs.mkdir(fileBasePath, { recursive: true }); - directoryExists.add(fileBasePath); - } + // Ensure output subdirectories exist + const fileBasePath = path.dirname(fullFilePath); + if (fileBasePath && !directoryExists.has(fileBasePath)) { + await fs.mkdir(fileBasePath, { recursive: true }); + directoryExists.add(fileBasePath); + } - if (file.origin === 'memory') { - // Write file contents - await fs.writeFile(fullFilePath, file.contents); - } else { - // Copy file contents - await fs.cp(file.inputPath, fullFilePath, { - mode: fs.constants.COPYFILE_FICLONE, - preserveTimestamps: true, - }); - } - }); + if (file.origin === 'memory') { + // Write file contents + await fs.writeFile(fullFilePath, file.contents); + } else { + // Copy file contents + await fs.cp(file.inputPath, fullFilePath, { + mode: fs.constants.COPYFILE_FICLONE, + preserveTimestamps: true, + }); + } + }); + } catch (error) { + context.logger.error(error instanceof Error ? error.message : String(error)); + yield { success: false }; + continue; + } // Delete any removed files if incremental if (result.kind === ResultKind.Incremental && result.removed?.length) { - await Promise.all( - result.removed.map((file) => { - const fullFilePath = generateFullPath(file.path, file.type, outputOptions); + try { + await Promise.all( + result.removed.map((file) => { + const fullFilePath = generateFullPath(file.path, file.type, outputOptions); - return fs.rm(fullFilePath, { force: true, maxRetries: 3 }); - }), - ); + return fs.rm(fullFilePath, { force: true, maxRetries: 3 }); + }), + ); + } catch (error) { + context.logger.error(error instanceof Error ? error.message : String(error)); + yield { success: false }; + continue; + } } yield { success: true }; @@ -268,6 +281,12 @@ function generateFullPath( // NOTE: 'base' is a fully resolved path at this point const fullFilePath = path.join(outputOptions.base, typeDirectory, filePath); + if (!isSubDirectory(outputOptions.base, fullFilePath)) { + throw new Error( + `The output file path "${fullFilePath}" is outside of the configured output path "${outputOptions.base}".`, + ); + } + return fullFilePath; } diff --git a/packages/angular/build/src/builders/application/tests/options/output-path_spec.ts b/packages/angular/build/src/builders/application/tests/options/output-path_spec.ts index b6c72b9bee58..3fc98c83ed36 100644 --- a/packages/angular/build/src/builders/application/tests/options/output-path_spec.ts +++ b/packages/angular/build/src/builders/application/tests/options/output-path_spec.ts @@ -260,6 +260,28 @@ describeBuilder(buildApplication, APPLICATION_BUILDER_INFO, (harness) => { }), ); }); + + it('should error when browser directory escapes the output path base', async () => { + harness.useTarget('build', { + ...BASE_OPTIONS, + polyfills: [], + outputPath: { + base: 'dist', + browser: '..', + }, + ssr: false, + }); + + const { result, logs } = await harness.executeOnce({ outputLogsOnFailure: false }); + expect(result?.success).toBeFalse(); + expect(logs).toContain( + jasmine.objectContaining({ + message: jasmine.stringMatching( + `The output file path .* is outside of the configured output path`, + ), + }), + ); + }); }); }); }); diff --git a/packages/angular/build/src/utils/path.ts b/packages/angular/build/src/utils/path.ts index eafef4ee9f2b..e969d420e429 100644 --- a/packages/angular/build/src/utils/path.ts +++ b/packages/angular/build/src/utils/path.ts @@ -6,7 +6,7 @@ * found in the LICENSE file at https://angular.dev/license */ -import { normalize, posix, resolve } from 'node:path'; +import { isAbsolute, posix, relative, resolve } from 'node:path'; import { platform } from 'node:process'; const WINDOWS_PATH_SEPERATOR_REGEXP = /\\/g; @@ -44,8 +44,9 @@ export function toPosixPath(path: string): string { * @returns `true` if the child path is within the parent directory, `false` otherwise. */ export function isSubDirectory(parent: string, child: string): boolean { - const normalizedParent = normalize(parent); + const resolvedParent = resolve(parent); const resolvedChild = resolve(parent, child); + const relativePath = toPosixPath(relative(resolvedParent, resolvedChild)); - return resolvedChild.startsWith(normalizedParent); + return relativePath !== '..' && !relativePath.startsWith('../') && !isAbsolute(relativePath); } diff --git a/packages/angular/build/src/utils/path_spec.ts b/packages/angular/build/src/utils/path_spec.ts new file mode 100644 index 000000000000..84c7d8ac31c4 --- /dev/null +++ b/packages/angular/build/src/utils/path_spec.ts @@ -0,0 +1,41 @@ +/** + * @license + * Copyright Google LLC All Rights Reserved. + * + * Use of this source code is governed by an MIT-style license that can be + * found in the LICENSE file at https://angular.dev/license + */ + +import { isSubDirectory } from './path'; + +describe('isSubDirectory', () => { + it('should return true for a direct child', () => { + expect(isSubDirectory('/foo/bar', '/foo/bar/baz')).toBeTrue(); + }); + + it('should return true for a nested child', () => { + expect(isSubDirectory('/foo/bar', '/foo/bar/baz/qux/file.txt')).toBeTrue(); + }); + + it('should return true if paths are identical', () => { + expect(isSubDirectory('/foo/bar', '/foo/bar')).toBeTrue(); + }); + + it('should return false for a sibling directory starting with same prefix', () => { + expect(isSubDirectory('/foo/bar', '/foo/bar-outside')).toBeFalse(); + expect(isSubDirectory('/foo/bar', '/foo/bar-outside/file.txt')).toBeFalse(); + }); + + it('should return false for directory outside parent via traversal', () => { + expect(isSubDirectory('/foo/bar', '/foo/bar/../outside')).toBeFalse(); + }); + + it('should return false for parent directory', () => { + expect(isSubDirectory('/foo/bar', '/foo')).toBeFalse(); + }); + + it('should return true for children containing directory names starting with double dots', () => { + expect(isSubDirectory('/foo/bar', '/foo/bar/..baz')).toBeTrue(); + expect(isSubDirectory('/foo/bar', '/foo/bar/..baz/qux')).toBeTrue(); + }); +}); From 59e5e967a35af4d9b828f7ca05bb41926271d62e Mon Sep 17 00:00:00 2001 From: Charles Lyding <19598772+clydin@users.noreply.github.com> Date: Fri, 5 Jun 2026 09:29:21 -0400 Subject: [PATCH 016/787] fix(@schematics/angular): safely comment out multiline statements in refactor-jasmine-vitest When refactoring unsupported or empty statements (such as `pending()`, `expect().nothing()`, and certain `jasmine` member assignments), the schematic previously commented out the code using a single-line comment prefix on the full text of the node. If the statement spanned multiple lines, only the first line was commented, leaving subsequent lines uncommented. This resulted in invalid syntax or unexpected compile errors. --- .../transformers/jasmine-lifecycle.ts | 10 ++-------- .../transformers/jasmine-matcher.ts | 10 ++-------- .../transformers/jasmine-misc.ts | 10 ++-------- .../jasmine-vitest/utils/comment-helpers.ts | 20 +++++++++++++++++++ .../utils/comment-helpers_spec.ts | 17 +++++++++++++++- 5 files changed, 42 insertions(+), 25 deletions(-) diff --git a/packages/schematics/angular/refactor/jasmine-vitest/transformers/jasmine-lifecycle.ts b/packages/schematics/angular/refactor/jasmine-vitest/transformers/jasmine-lifecycle.ts index 78ddd1e99316..eb58a7f9d5b9 100644 --- a/packages/schematics/angular/refactor/jasmine-vitest/transformers/jasmine-lifecycle.ts +++ b/packages/schematics/angular/refactor/jasmine-vitest/transformers/jasmine-lifecycle.ts @@ -15,7 +15,7 @@ import ts from 'typescript'; import { createPropertyAccess } from '../utils/ast-helpers'; -import { addTodoComment } from '../utils/comment-helpers'; +import { addCommentedNodeText, addTodoComment } from '../utils/comment-helpers'; import { RefactorContext } from '../utils/refactor-context'; const FOCUSED_SKIPPED_RENAMES = new Map([ @@ -77,7 +77,6 @@ export function transformPending( ) { hasPending = true; const replacement = ts.factory.createEmptyStatement(); - const originalText = bodyNode.getFullText().trim(); reporter.reportTransformation( sourceFile, @@ -87,12 +86,7 @@ export function transformPending( const category = 'pending'; reporter.recordTodo(category, sourceFile, bodyNode); addTodoComment(replacement, category); - ts.addSyntheticLeadingComment( - replacement, - ts.SyntaxKind.SingleLineCommentTrivia, - ` ${originalText}`, - true, - ); + addCommentedNodeText(replacement, bodyNode); return replacement; } diff --git a/packages/schematics/angular/refactor/jasmine-vitest/transformers/jasmine-matcher.ts b/packages/schematics/angular/refactor/jasmine-vitest/transformers/jasmine-matcher.ts index c1e669b144ef..1e0a87dc80f2 100644 --- a/packages/schematics/angular/refactor/jasmine-vitest/transformers/jasmine-matcher.ts +++ b/packages/schematics/angular/refactor/jasmine-vitest/transformers/jasmine-matcher.ts @@ -21,7 +21,7 @@ import { createPropertyAccess, } from '../utils/ast-helpers'; import { getJasmineMethodName, isJasmineCallExpression } from '../utils/ast-validation'; -import { addTodoComment } from '../utils/comment-helpers'; +import { addCommentedNodeText, addTodoComment } from '../utils/comment-helpers'; import { RefactorContext } from '../utils/refactor-context'; const SUGAR_MATCHER_CHANGES = new Map([ @@ -607,18 +607,12 @@ export function transformExpectNothing( // The statement is `expect().nothing()`, which can be removed. const replacement = ts.factory.createEmptyStatement(); - const originalText = node.getFullText().trim(); reporter.reportTransformation(sourceFile, node, 'Removed `expect().nothing()` statement.'); const category = 'expect-nothing'; reporter.recordTodo(category, sourceFile, node); addTodoComment(replacement, category); - ts.addSyntheticLeadingComment( - replacement, - ts.SyntaxKind.SingleLineCommentTrivia, - ` ${originalText}`, - true, - ); + addCommentedNodeText(replacement, node); return replacement; } diff --git a/packages/schematics/angular/refactor/jasmine-vitest/transformers/jasmine-misc.ts b/packages/schematics/angular/refactor/jasmine-vitest/transformers/jasmine-misc.ts index 6832e36b9273..f71353cc9783 100644 --- a/packages/schematics/angular/refactor/jasmine-vitest/transformers/jasmine-misc.ts +++ b/packages/schematics/angular/refactor/jasmine-vitest/transformers/jasmine-misc.ts @@ -16,7 +16,7 @@ import ts from 'typescript'; import { addVitestValueImport } from '../utils/ast-helpers'; import { getJasmineMethodName, isJasmineCallExpression } from '../utils/ast-validation'; -import { addTodoComment } from '../utils/comment-helpers'; +import { addCommentedNodeText, addTodoComment } from '../utils/comment-helpers'; import { RefactorContext } from '../utils/refactor-context'; import { createViCallExpression } from '../utils/refactor-helpers'; import { TodoCategory } from '../utils/todo-notes'; @@ -143,7 +143,6 @@ export function transformJasmineMembers(node: ts.Node, refactorCtx: RefactorCont case 'MAX_PRETTY_PRINT_DEPTH': case 'MAX_PRETTY_PRINT_CHARS': { const replacement = ts.factory.createEmptyStatement(); - const originalText = node.getFullText().trim(); reporter.reportTransformation( sourceFile, @@ -153,12 +152,7 @@ export function transformJasmineMembers(node: ts.Node, refactorCtx: RefactorCont const category = 'unsupported-jasmine-member'; reporter.recordTodo(category, sourceFile, node); addTodoComment(replacement, category, { name: memberName }); - ts.addSyntheticLeadingComment( - replacement, - ts.SyntaxKind.SingleLineCommentTrivia, - ` ${originalText}`, - true, - ); + addCommentedNodeText(replacement, node); return replacement; } diff --git a/packages/schematics/angular/refactor/jasmine-vitest/utils/comment-helpers.ts b/packages/schematics/angular/refactor/jasmine-vitest/utils/comment-helpers.ts index 2ece945e2951..02a9255deb3a 100644 --- a/packages/schematics/angular/refactor/jasmine-vitest/utils/comment-helpers.ts +++ b/packages/schematics/angular/refactor/jasmine-vitest/utils/comment-helpers.ts @@ -70,3 +70,23 @@ export function addTodoComment( true, ); } + +/** + * Safely comments out the full text of a node line-by-line and attaches + * it to a target node. This prevents multi-line statements from breaking + * syntax when converted to single-line comments. + * @param targetNode The node to which the comments will be added. + * @param nodeToComment The original node whose text will be commented out. + */ +export function addCommentedNodeText(targetNode: ts.Node, nodeToComment: ts.Node): void { + const originalText = nodeToComment.getFullText().trim(); + const lines = originalText.split('\n'); + for (const line of lines) { + ts.addSyntheticLeadingComment( + targetNode, + ts.SyntaxKind.SingleLineCommentTrivia, + ` ${line.trim()}`, + true, + ); + } +} diff --git a/packages/schematics/angular/refactor/jasmine-vitest/utils/comment-helpers_spec.ts b/packages/schematics/angular/refactor/jasmine-vitest/utils/comment-helpers_spec.ts index ddfb1b8b7ad1..4f44b2664368 100644 --- a/packages/schematics/angular/refactor/jasmine-vitest/utils/comment-helpers_spec.ts +++ b/packages/schematics/angular/refactor/jasmine-vitest/utils/comment-helpers_spec.ts @@ -7,7 +7,7 @@ */ import ts from 'typescript'; -import { addTodoComment } from './comment-helpers'; +import { addCommentedNodeText, addTodoComment } from './comment-helpers'; describe('addTodoComment', () => { function createTestHarness(sourceText: string) { @@ -65,4 +65,19 @@ describe('addTodoComment', () => { expect(result.trim().startsWith('// TODO')).toBe(true); expect(result).toContain('const mySpy = jasmine.createSpy()'); }); + + describe('addCommentedNodeText', () => { + it('should comment out a multiline node line-by-line', () => { + const sourceText = `expect()\n .nothing();`; + const sourceFile = ts.createSourceFile('test.ts', sourceText, ts.ScriptTarget.Latest, true); + const statement = sourceFile.statements[0]; + const replacement = ts.factory.createEmptyStatement(); + const printer = ts.createPrinter({ newLine: ts.NewLineKind.LineFeed }); + + addCommentedNodeText(replacement, statement); + + const result = printer.printNode(ts.EmitHint.Unspecified, replacement, sourceFile); + expect(result).toContain('// expect()\n// .nothing();'); + }); + }); }); From 5e7508a128d7da885917aa68cd121fa8a54d35f7 Mon Sep 17 00:00:00 2001 From: Charles Lyding <19598772+clydin@users.noreply.github.com> Date: Fri, 5 Jun 2026 10:21:30 -0400 Subject: [PATCH 017/787] perf(@angular/cli): optimize update schematic registry query counts by fetching package metadata lazily Optimize the ng update registry requests by only querying package metadata for packages that are actually being updated, while resolving other dependencies locally from disk (with fallback to registry for uninstalled/mocked packages). This reduces network query counts by 80-90% during ng update. --- .../angular/cli/src/commands/update/cli.ts | 2 + .../src/commands/update/schematic/index.ts | 419 +++++++++++++----- .../commands/update/schematic/index_spec.ts | 2 +- .../src/commands/update/schematic/schema.json | 4 + 4 files changed, 318 insertions(+), 109 deletions(-) diff --git a/packages/angular/cli/src/commands/update/cli.ts b/packages/angular/cli/src/commands/update/cli.ts index de6d7f53fea0..62416b1c1ee7 100644 --- a/packages/angular/cli/src/commands/update/cli.ts +++ b/packages/angular/cli/src/commands/update/cli.ts @@ -256,6 +256,7 @@ export default class UpdateCommandModule extends CommandModule(); const packagesToUpdate = [...infoMap.entries()] .map(([name, info]) => { - let tag = options.next - ? info.npmPackageJson['dist-tags']['next'] - ? 'next' - : 'latest' - : 'latest'; - let version = info.npmPackageJson['dist-tags'][tag]; - let target = info.npmPackageJson.versions[version]; + const distTags = info.npmPackageJson['dist-tags'] ?? {}; + let tag = options.next ? (distTags['next'] ? 'next' : 'latest') : 'latest'; + let version = distTags[tag] ?? info.installed.version; + const versions = info.npmPackageJson.versions ?? {}; + let target = versions[version]; const versionDiff = semver.diff(info.installed.version, version); if ( @@ -426,13 +427,13 @@ function _usageMessage( installedMajorVersion < toInstallMajorVersion - 1 ) { const nextMajorVersion = `${installedMajorVersion + 1}.`; - const nextMajorVersions = Object.keys(info.npmPackageJson.versions) + const nextMajorVersions = Object.keys(versions) .filter((v) => v.startsWith(nextMajorVersion)) .sort((a, b) => (a > b ? -1 : 1)); if (nextMajorVersions.length) { version = nextMajorVersions[0]; - target = info.npmPackageJson.versions[version]; + target = versions[version]; tag = ''; } } @@ -525,11 +526,147 @@ function _usageMessage( return; } +/** + * Resolves a semver range or npm dist-tag to a specific version based on the package's registry metadata. + * It prioritizes non-deprecated versions and handles fallback to deprecated versions if necessary. + * + * @private + */ +function resolvePackageVersion( + metadata: NpmRepositoryPackageJson, + range: string, + next = false, +): string | null { + // Check if range matches an npm dist-tag directly (e.g. "latest", "next") + const distTags = metadata['dist-tags'] ?? {}; + if (distTags[range]) { + return distTags[range]; + } + // If 'next' is requested (e.g. via the --next CLI flag) but the package doesn't publish + // a 'next' pre-release tag, fallback to 'latest'. + if (range === 'next') { + return distTags['latest'] ?? null; + } + + // Split deprecated and non-deprecated versions from registry metadata + const packageVersionsNonDeprecated: string[] = []; + const packageVersionsDeprecated: string[] = []; + for (const [v, { deprecated }] of Object.entries(metadata.versions ?? {})) { + if (deprecated) { + packageVersionsDeprecated.push(v); + } else { + packageVersionsNonDeprecated.push(v); + } + } + + // Find the highest satisfying version, prioritizing non-deprecated versions + return ( + semver.maxSatisfying(packageVersionsNonDeprecated, range, { + includePrerelease: next || undefined, + }) ?? + semver.maxSatisfying(packageVersionsDeprecated, range, { + includePrerelease: next || undefined, + }) + ); +} + +/** + * Checks if Yarn Plug'n'Play is active in the current workspace. + * + * @private + */ +function isPnpActive(workspaceRoot: string): boolean { + return ( + process.versions.pnp !== undefined || + existsSync(path.join(workspaceRoot, '.pnp.cjs')) || + existsSync(path.join(workspaceRoot, '.pnp.js')) + ); +} + +/** + * Resolves and reads the installed package.json manifest for a package. + * It checks the virtual schematic Tree first (vital for unit tests/mocks), + * and falls back to physical disk resolution using createRequire only if Yarn PnP is active. + * + * @private + */ +function getInstalledPackageJson( + tree: Tree, + packageName: string, + workspaceRoot: string, +): PackageManifest | null { + // First, check the virtual tree (critical for testing mocks) + const pkgJsonPath = `/node_modules/${packageName}/package.json`; + if (tree.exists(pkgJsonPath)) { + try { + return tree.readJson(pkgJsonPath) as PackageManifest; + } catch {} + } + + // In Yarn PnP, mock package trees are not written to node_modules in the virtual tree, + // so we resolve the manifest physically from Yarn's zip cache via createRequire. + // Note: This fallback resolution is strictly gated on Yarn PnP being active. Because schematics + // operate on a virtual file system (Tree), running disk lookups in non-PnP + // environments could cause tests to resolve dependencies from this monorepo's own node_modules + // instead of the simulated virtual file system. + if (isPnpActive(workspaceRoot)) { + try { + const workspaceRequire = createRequire(path.join(workspaceRoot, 'package.json')); + const manifestPath = workspaceRequire.resolve(`${packageName}/package.json`); + const content = readFileSync(manifestPath, 'utf8'); + + return JSON.parse(content) as PackageManifest; + } catch {} + } + + return null; +} + +function getInstalledVersion( + tree: Tree, + packageName: string, + workspaceRoot: string, +): string | null { + const pkgJson = getInstalledPackageJson(tree, packageName, workspaceRoot); + + return pkgJson?.version ?? null; +} + +function _buildLocalPackageInfo( + tree: Tree, + name: string, + allDependencies: ReadonlyMap, + workspaceRoot: string, + logger: logging.LoggerApi, +): PackageInfo { + const packageJsonRange = allDependencies.get(name); + if (!packageJsonRange) { + throw new SchematicsException(`Package ${JSON.stringify(name)} was not found in package.json.`); + } + + const localPkgJson = getInstalledPackageJson(tree, name, workspaceRoot); + if (!localPkgJson) { + throw new SchematicsException(`Package ${name} is not installed.`); + } + + return { + name, + npmPackageJson: {} as NpmRepositoryPackageJson, + installed: { + version: localPkgJson.version as VersionRange, + packageJson: localPkgJson, + updateMetadata: _getUpdateMetadata(localPkgJson, logger), + }, + packageJsonRange, + }; +} + function _buildPackageInfo( tree: Tree, packages: Map, allDependencies: ReadonlyMap, npmPackageJson: NpmRepositoryPackageJson, + workspaceRoot: string, logger: logging.LoggerApi, ): PackageInfo { const name = npmPackageJson.name; @@ -538,21 +675,13 @@ function _buildPackageInfo( throw new SchematicsException(`Package ${JSON.stringify(name)} was not found in package.json.`); } - // Find out the currently installed version. Either from the package.json or the node_modules/ - // TODO: figure out a way to read package-lock.json and/or yarn.lock. - const pkgJsonPath = `/node_modules/${name}/package.json`; - const pkgJsonExists = tree.exists(pkgJsonPath); - - let installedVersion: string | undefined | null; - if (pkgJsonExists) { - const { version } = tree.readJson(pkgJsonPath) as PackageManifest; - installedVersion = version; - } + const localPkgJson = getInstalledPackageJson(tree, name, workspaceRoot); + let installedVersion = localPkgJson?.version; const packageVersionsNonDeprecated: string[] = []; const packageVersionsDeprecated: string[] = []; - for (const [version, { deprecated }] of Object.entries(npmPackageJson.versions)) { + for (const [version, { deprecated }] of Object.entries(npmPackageJson.versions ?? {})) { if (deprecated) { packageVersionsDeprecated.push(version); } else { @@ -576,7 +705,8 @@ function _buildPackageInfo( ); } - const installedPackageJson = npmPackageJson.versions[installedVersion] || pkgJsonExists; + const versions = npmPackageJson.versions ?? {}; + const installedPackageJson = versions[installedVersion] || localPkgJson; if (!installedPackageJson) { throw new SchematicsException( `An unexpected error happened; package ${name} has no version ${installedVersion}.`, @@ -585,10 +715,11 @@ function _buildPackageInfo( let targetVersion: VersionRange | undefined = packages.get(name); if (targetVersion) { - if (npmPackageJson['dist-tags'][targetVersion]) { - targetVersion = npmPackageJson['dist-tags'][targetVersion] as VersionRange; + const distTags = npmPackageJson['dist-tags'] ?? {}; + if (distTags[targetVersion]) { + targetVersion = distTags[targetVersion] as VersionRange; } else if (targetVersion == 'next') { - targetVersion = npmPackageJson['dist-tags']['latest'] as VersionRange; + targetVersion = distTags['latest'] as VersionRange; } else { targetVersion = findSatisfyingVersion(targetVersion); } @@ -602,19 +733,18 @@ function _buildPackageInfo( const target: PackageVersionInfo | undefined = targetVersion ? { version: targetVersion, - packageJson: npmPackageJson.versions[targetVersion], - updateMetadata: _getUpdateMetadata(npmPackageJson.versions[targetVersion], logger), + packageJson: versions[targetVersion], + updateMetadata: _getUpdateMetadata(versions[targetVersion], logger), } : undefined; - // Check if there's an installed version. return { name, npmPackageJson, installed: { version: installedVersion as VersionRange, - packageJson: installedPackageJson, - updateMetadata: _getUpdateMetadata(installedPackageJson, logger), + packageJson: installedPackageJson as PackageManifest, + updateMetadata: _getUpdateMetadata(installedPackageJson as PackageManifest, logger), }, target, packageJsonRange, @@ -665,16 +795,34 @@ function _addPackageGroup( return; } - const info = _buildPackageInfo(tree, packages, allDependencies, npmPackageJson, logger); + const distTags = npmPackageJson['dist-tags'] ?? {}; + let version = maybePackage; + if (distTags[version]) { + version = distTags[version] as VersionRange; + } else if (version === 'next') { + version = distTags['latest'] as VersionRange; + } else { + const packageVersionsNonDeprecated: string[] = []; + const packageVersionsDeprecated: string[] = []; + const versions = npmPackageJson.versions ?? {}; + for (const [v, { deprecated }] of Object.entries(versions)) { + if (deprecated) { + packageVersionsDeprecated.push(v); + } else { + packageVersionsNonDeprecated.push(v); + } + } + version = + ((semver.maxSatisfying(packageVersionsNonDeprecated, version) ?? + semver.maxSatisfying(packageVersionsDeprecated, version)) as VersionRange | null) ?? + version; + } - const version = - (info.target && info.target.version) || - npmPackageJson['dist-tags'][maybePackage] || - maybePackage; - if (!npmPackageJson.versions[version]) { + const versions = npmPackageJson.versions ?? {}; + if (!versions[version]) { return; } - const ngUpdateMetadata = npmPackageJson.versions[version]['ng-update']; + const ngUpdateMetadata = versions[version]['ng-update']; if (!ngUpdateMetadata) { return; } @@ -721,51 +869,64 @@ function _addPackageGroup( * be ignored by the --force flag). * @private */ -function _addPeerDependencies( +async function _addPeerDependencies( tree: Tree, packages: Map, allDependencies: ReadonlyMap, npmPackageJson: NpmRepositoryPackageJson, - npmPackageJsonMap: Map, + workspaceRoot: string, + fetchMetadata: (name: string) => Promise, logger: logging.LoggerApi, -): void { +): Promise { const maybePackage = packages.get(npmPackageJson.name); if (!maybePackage) { return; } - - const info = _buildPackageInfo(tree, packages, allDependencies, npmPackageJson, logger); - - const version = - (info.target && info.target.version) || - npmPackageJson['dist-tags'][maybePackage] || - maybePackage; - if (!npmPackageJson.versions[version]) { + const distTags = npmPackageJson['dist-tags'] ?? {}; + const version = distTags[maybePackage] || maybePackage; + const versions = npmPackageJson.versions ?? {}; + const packageJson = versions[version]; + if (!packageJson) { return; } - const packageJson = npmPackageJson.versions[version]; - const error = false; - for (const [peer, range] of Object.entries(packageJson.peerDependencies || {})) { if (packages.has(peer)) { continue; } - const peerPackageJson = npmPackageJsonMap.get(peer); - if (peerPackageJson) { - const peerInfo = _buildPackageInfo(tree, packages, allDependencies, peerPackageJson, logger); - if (semver.satisfies(peerInfo.installed.version, range)) { + const installedVersion = getInstalledVersion(tree, peer, workspaceRoot); + if (installedVersion) { + if (semver.satisfies(installedVersion, range)) { continue; } + } else { + const packageJsonRange = allDependencies.get(peer); + if (packageJsonRange) { + const peerMetadata = await fetchMetadata(peer); + if (peerMetadata) { + const packageVersionsNonDeprecated: string[] = []; + const packageVersionsDeprecated: string[] = []; + for (const [v, { deprecated }] of Object.entries(peerMetadata.versions ?? {})) { + if (deprecated) { + packageVersionsDeprecated.push(v); + } else { + packageVersionsNonDeprecated.push(v); + } + } + const resolvedInstalledVersion = + semver.maxSatisfying(packageVersionsNonDeprecated, packageJsonRange) ?? + semver.maxSatisfying(packageVersionsDeprecated, packageJsonRange); + + if (resolvedInstalledVersion && semver.satisfies(resolvedInstalledVersion, range)) { + continue; + } + } + } } packages.set(peer, range as VersionRange); } - - if (error) { - throw new SchematicsException('An error occured, see above.'); - } } function _getAllDependencies(tree: Tree): Array { @@ -846,67 +1007,109 @@ export default function (options: UpdateSchema): Rule { ); const packages = _buildPackageList(options, npmDeps, logger); - // Grab all package.json from the npm repository. This requires a lot of HTTP calls so we - // try to parallelize as many as possible. - const allPackageMetadata = await Promise.all( - Array.from(npmDeps.keys()).map((depName) => - getNpmPackageJson(depName, logger, { + const workspaceRoot = options.workspaceRoot ?? process.cwd(); + const npmPackageJsonMap = new Map(); + + const getOrFetchPackageMetadata = async ( + packageName: string, + ): Promise => { + let metadata = npmPackageJsonMap.get(packageName); + if (!metadata) { + const raw = await getNpmPackageJson(packageName, logger, { registry: options.registry, usingYarn, verbose: options.verbose, - }), - ), - ); - - // Build a map of all dependencies and their packageJson. - const npmPackageJsonMap = allPackageMetadata.reduce((acc, npmPackageJson) => { - // If the package was not found on the registry. It could be private, so we will just - // ignore. If the package was part of the list, we will error out, but will simply ignore - // if it's either not requested (so just part of package.json. silently). - if (!npmPackageJson.name) { - if (npmPackageJson.requestedName && packages.has(npmPackageJson.requestedName)) { - throw new SchematicsException( - `Package ${JSON.stringify(npmPackageJson.requestedName)} was not found on the ` + - 'registry. Cannot continue as this may be an error.', - ); + }); + if (raw.name) { + metadata = raw as NpmRepositoryPackageJson; + npmPackageJsonMap.set(packageName, metadata); } - } else { - // If a name is present, it is assumed to be fully populated - acc.set(npmPackageJson.name, npmPackageJson as NpmRepositoryPackageJson); } - return acc; - }, new Map()); - - // Augment the command line package list with packageGroups and forward peer dependencies. - // Each added package may uncover new package groups and peer dependencies, so we must - // repeat this process until the package list stabilizes. - let lastPackagesSize; - do { - lastPackagesSize = packages.size; + return metadata ?? null; + }; - let lastGroupSize; + if (packages.size === 0) { + // User ran just `ng update` to see the outdated package list. + // We must fetch metadata for all npm dependencies to generate the usage message. + await Promise.all( + Array.from(npmDeps.keys()).map(async (depName) => { + await getOrFetchPackageMetadata(depName); + }), + ); + } else { + // User requested updates. We resolve dependencies lazily. + let lastPackagesSize; do { - lastGroupSize = packages.size; - npmPackageJsonMap.forEach((npmPackageJson) => { - _addPackageGroup(tree, packages, npmDeps, npmPackageJson, logger); - }); - } while (packages.size > lastGroupSize); - - // This is done in seperate loop to ensure that package groups are added before peer dependencies. - npmPackageJsonMap.forEach((npmPackageJson) => { - _addPeerDependencies(tree, packages, npmDeps, npmPackageJson, npmPackageJsonMap, logger); - }); - } while (packages.size > lastPackagesSize); + lastPackagesSize = packages.size; + + let lastGroupSize; + do { + lastGroupSize = packages.size; + for (const name of Array.from(packages.keys())) { + const metadata = await getOrFetchPackageMetadata(name); + const spec = packages.get(name); + if (metadata && spec) { + const resolvedVersion = resolvePackageVersion(metadata, spec, !!options.next); + if (resolvedVersion) { + packages.set(name, resolvedVersion as VersionRange); + } + _addPackageGroup(tree, packages, npmDeps, metadata, logger); + } + } + } while (packages.size > lastGroupSize); + + for (const name of Array.from(packages.keys())) { + const metadata = await getOrFetchPackageMetadata(name); + const spec = packages.get(name); + if (metadata && spec) { + const resolvedVersion = resolvePackageVersion(metadata, spec, !!options.next); + if (resolvedVersion) { + packages.set(name, resolvedVersion as VersionRange); + } + await _addPeerDependencies( + tree, + packages, + npmDeps, + metadata, + workspaceRoot, + getOrFetchPackageMetadata, + logger, + ); + } + } + } while (packages.size > lastPackagesSize); + } // Build the PackageInfo for each module. const packageInfoMap = new Map(); - npmPackageJsonMap.forEach((npmPackageJson) => { - packageInfoMap.set( - npmPackageJson.name, - _buildPackageInfo(tree, packages, npmDeps, npmPackageJson, logger), - ); - }); + for (const depName of npmDeps.keys()) { + const isUpdating = packages.has(depName); + const localPkgJson = getInstalledPackageJson(tree, depName, workspaceRoot); + + if (isUpdating || !localPkgJson) { + // If updating OR not installed locally, resolve via registry metadata + const metadata = await getOrFetchPackageMetadata(depName); + if (metadata) { + packageInfoMap.set( + depName, + _buildPackageInfo(tree, packages, npmDeps, metadata, workspaceRoot, logger), + ); + } else { + // Fallback if metadata could not be fetched + packageInfoMap.set( + depName, + _buildLocalPackageInfo(tree, depName, npmDeps, workspaceRoot, logger), + ); + } + } else { + // If not updating and installed locally, resolve purely locally + packageInfoMap.set( + depName, + _buildLocalPackageInfo(tree, depName, npmDeps, workspaceRoot, logger), + ); + } + } // Now that we have all the information, check the flags. if (packages.size > 0) { diff --git a/packages/angular/cli/src/commands/update/schematic/index_spec.ts b/packages/angular/cli/src/commands/update/schematic/index_spec.ts index 11b2a0b5855e..7e8ca436150d 100644 --- a/packages/angular/cli/src/commands/update/schematic/index_spec.ts +++ b/packages/angular/cli/src/commands/update/schematic/index_spec.ts @@ -387,5 +387,5 @@ describe('@schematics/update', () => { expect(dependencies['@angular/cdk']).toMatch(version20Regexp); expect(dependencies['@angular/common']).toMatch(version20Regexp); expect(dependencies['@angular/core']).toMatch(version20Regexp); - }); + }, 45000); }); diff --git a/packages/angular/cli/src/commands/update/schematic/schema.json b/packages/angular/cli/src/commands/update/schematic/schema.json index 4768df46f2d5..63bf2df87813 100644 --- a/packages/angular/cli/src/commands/update/schematic/schema.json +++ b/packages/angular/cli/src/commands/update/schematic/schema.json @@ -58,6 +58,10 @@ "type": "string", "default": "npm", "enum": ["npm", "yarn", "pnpm", "bun"] + }, + "workspaceRoot": { + "description": "The path to the workspace root directory.", + "type": "string" } }, "required": [] From 7786de1a1fdf232a9c665f76d0f8a5861f148622 Mon Sep 17 00:00:00 2001 From: Charles Lyding <19598772+clydin@users.noreply.github.com> Date: Fri, 5 Jun 2026 18:59:03 -0400 Subject: [PATCH 018/787] fix(@angular/build): prevent concurrent stylesheet bundling esbuild context leaks When multiple components in the same file define identical inline styles, concurrent calls to the stylesheet bundler invoke Cache.getOrCreate concurrently with the same key. Because getOrCreate is not concurrency-safe, multiple BundlerContext instances are created. Additionally, if multiple bundle() requests occur concurrently on a BundlerContext when the esbuild context is not yet initialized, they both invoke context(), causing one to overwrite and leak the other. Leaked esbuild contexts keep the Node event loop active forever, hanging the test runner. Resolve the Cache race by using an internal Map of in-flight promises to share the same active request, along with a version counter to detect mid-flight writes and safely retry. Resolve the BundlerContext race by memoizing and sharing the active performBundle promise. Fixes #33317 --- .../src/tools/esbuild/bundler-context.ts | 24 ++- .../angular/build/src/tools/esbuild/cache.ts | 101 +++++++++++- .../build/src/tools/esbuild/cache_spec.ts | 144 ++++++++++++++++++ 3 files changed, 261 insertions(+), 8 deletions(-) create mode 100644 packages/angular/build/src/tools/esbuild/cache_spec.ts diff --git a/packages/angular/build/src/tools/esbuild/bundler-context.ts b/packages/angular/build/src/tools/esbuild/bundler-context.ts index dd2764c8c608..7fe28e5a51d4 100644 --- a/packages/angular/build/src/tools/esbuild/bundler-context.ts +++ b/packages/angular/build/src/tools/esbuild/bundler-context.ts @@ -59,6 +59,8 @@ export class BundlerContext { #esbuildContext?: BuildContext<{ metafile: true; write: false }>; #esbuildOptions?: BuildOptions & { metafile: true; write: false }; #esbuildResult?: BundleContextResult; + #activeBundlePromise?: Promise; + #disposed = false; #optionsFactory: BundlerOptionsFactory; #shouldCacheResult: boolean; #loadCache?: MemoryLoadResultCache; @@ -177,7 +179,18 @@ export class BundlerContext { return this.#esbuildResult; } - const result = await this.#performBundle(); + if (!force && this.#activeBundlePromise) { + return this.#activeBundlePromise; + } + + const bundlePromise = this.#performBundle().finally(() => { + if (this.#activeBundlePromise === bundlePromise) { + this.#activeBundlePromise = undefined; + } + }); + this.#activeBundlePromise = bundlePromise; + + const result = await bundlePromise; if (this.#shouldCacheResult) { this.#esbuildResult = result; } @@ -207,7 +220,12 @@ export class BundlerContext { } else { // Create a build context and perform the build. // Context creation does not perform a build. - this.#esbuildContext = await context(this.#esbuildOptions); + const esbuildContext = await context(this.#esbuildOptions); + if (this.#disposed) { + await esbuildContext.dispose(); + throw new Error('BundlerContext was disposed during build.'); + } + this.#esbuildContext = esbuildContext; result = await this.#esbuildContext.rebuild(); } } catch (failure) { @@ -446,9 +464,11 @@ export class BundlerContext { * @returns A promise that resolves when disposal is complete. */ async dispose(): Promise { + this.#disposed = true; try { this.#esbuildOptions = undefined; this.#esbuildResult = undefined; + this.#activeBundlePromise = undefined; this.#loadCache = undefined; await this.#esbuildContext?.dispose(); } finally { diff --git a/packages/angular/build/src/tools/esbuild/cache.ts b/packages/angular/build/src/tools/esbuild/cache.ts index 5bd0dc84d73f..0634ec5268e8 100644 --- a/packages/angular/build/src/tools/esbuild/cache.ts +++ b/packages/angular/build/src/tools/esbuild/cache.ts @@ -44,11 +44,26 @@ export interface CacheStore { * to use a cache. */ export class Cache = CacheStore> { + // In-flight creator promises to deduplicate concurrent requests for the same key. + readonly #requests = new Map>(); + // Track how many writes occurred for a key to detect mutations during await gaps. + readonly #writeCounts = new Map(); + // Count the number of active, pending getOrCreate operations per key to avoid memory leaks. + readonly #pendingGets = new Map(); + constructor( protected readonly store: S, readonly namespace?: string, ) {} + #incrementWrite(key: string) { + // Only track write counts if there is a pending getOrCreate operation active for the key. + // This ensures that write counts are not leaked when no concurrent gets are running. + if (this.#pendingGets.has(key)) { + this.#writeCounts.set(key, (this.#writeCounts.get(key) || 0) + 1); + } + } + /** * Prefixes a key with the cache namespace if present. * @param key A key string to prefix. @@ -72,14 +87,75 @@ export class Cache = CacheStore> { */ async getOrCreate(key: string, creator: () => V | Promise): Promise { const namespacedKey = this.withNamespace(key); - let value = await this.store.get(namespacedKey); - if (value === undefined) { - value = await creator(); - await this.store.set(namespacedKey, value); + // 1. If another call is already running the creator for this key, share its promise. + let activeRequest = this.#requests.get(namespacedKey); + if (activeRequest !== undefined) { + return activeRequest; } - return value; + // Increment pending gets count to enable write-tracking for this key. + const currentPending = this.#pendingGets.get(namespacedKey) || 0; + this.#pendingGets.set(namespacedKey, currentPending + 1); + + try { + const startWriteCount = this.#writeCounts.get(namespacedKey) || 0; + + // 2. Query the backing store. Since store.get can be async, we yield to the event loop. + const value = await this.store.get(namespacedKey); + + // If a write (e.g. put) occurred during the store.get await gap, we must abort + // the current execution and restart to ensure we return the newly written value. + if ((this.#writeCounts.get(namespacedKey) || 0) !== startWriteCount) { + return this.getOrCreate(key, creator); + } + + if (value !== undefined) { + return value; + } + + // 3. Recheck active request after the await gap in case another concurrent call + // initiated a creator during the store.get wait. + activeRequest = this.#requests.get(namespacedKey); + if (activeRequest !== undefined) { + return activeRequest; + } + + // 4. Run the creator to produce the new value, and store its promise in #requests. + activeRequest = Promise.resolve(creator()).then( + async (newValue) => { + // Ensure this request is still the active one before writing back to the store + // (prevents overwriting newer data if put() was called before resolution). + if (this.#requests.get(namespacedKey) === activeRequest) { + this.#incrementWrite(namespacedKey); + await this.store.set(namespacedKey, newValue); + this.#requests.delete(namespacedKey); + } + + return newValue; + }, + (error) => { + // Clean up the active request if the creator fails. + if (this.#requests.get(namespacedKey) === activeRequest) { + this.#requests.delete(namespacedKey); + } + throw error; + }, + ); + + this.#requests.set(namespacedKey, activeRequest); + + return activeRequest; + } finally { + // Clean up write counts and pending gets once all concurrent gets for this key finish. + const current = this.#pendingGets.get(namespacedKey) || 0; + if (current <= 1) { + this.#pendingGets.delete(namespacedKey); + this.#writeCounts.delete(namespacedKey); + } else { + this.#pendingGets.set(namespacedKey, current - 1); + } + } } /** @@ -100,7 +176,19 @@ export class Cache = CacheStore> { * @param value A value to put in the cache. */ async put(key: string, value: V): Promise { - await this.store.set(this.withNamespace(key), value); + const namespacedKey = this.withNamespace(key); + this.#requests.delete(namespacedKey); + this.#incrementWrite(namespacedKey); + await this.store.set(namespacedKey, value); + } + + /** + * Clears the base class internal state (requests, write counts, and pending gets). + */ + protected clearInternal(): void { + this.#requests.clear(); + this.#writeCounts.clear(); + this.#pendingGets.clear(); } } @@ -116,6 +204,7 @@ export class MemoryCache extends Cache> { * Removes all entries from the cache instance. */ clear() { + this.clearInternal(); this.store.clear(); } diff --git a/packages/angular/build/src/tools/esbuild/cache_spec.ts b/packages/angular/build/src/tools/esbuild/cache_spec.ts new file mode 100644 index 000000000000..a30852836eff --- /dev/null +++ b/packages/angular/build/src/tools/esbuild/cache_spec.ts @@ -0,0 +1,144 @@ +/** + * @license + * Copyright Google LLC All Rights Reserved. + * + * Use of this source code is governed by an MIT-style license that can be + * found in the LICENSE file at https://angular.dev/license + */ + +import { MemoryCache } from './cache'; + +describe('MemoryCache', () => { + let cache: MemoryCache; + + beforeEach(() => { + cache = new MemoryCache(); + }); + + it('should return cached value on subsequent getOrCreate calls', async () => { + let callCount = 0; + const creator = () => { + callCount++; + + return 'value'; + }; + + const val1 = await cache.getOrCreate('key', creator); + const val2 = await cache.getOrCreate('key', creator); + + expect(val1).toBe('value'); + expect(val2).toBe('value'); + expect(callCount).toBe(1); + }); + + it('should call creator only once for concurrent getOrCreate calls with the same key', async () => { + let callCount = 0; + let resolveCreator!: (value: string) => void; + const promise = new Promise((resolve) => { + resolveCreator = resolve; + }); + + const creator = () => { + callCount++; + + return promise; + }; + + const p1 = cache.getOrCreate('key', creator); + const p2 = cache.getOrCreate('key', creator); + + resolveCreator('concurrent-value'); + + const [val1, val2] = await Promise.all([p1, p2]); + + expect(val1).toBe('concurrent-value'); + expect(val2).toBe('concurrent-value'); + expect(callCount).toBe(1); + }); + + it('should call creator multiple times for concurrent getOrCreate calls with different keys', async () => { + let callCount = 0; + const creator = (val: string) => { + callCount++; + + return Promise.resolve(val); + }; + + const p1 = cache.getOrCreate('key1', () => creator('value1')); + const p2 = cache.getOrCreate('key2', () => creator('value2')); + + const [val1, val2] = await Promise.all([p1, p2]); + + expect(val1).toBe('value1'); + expect(val2).toBe('value2'); + expect(callCount).toBe(2); + }); + + it('should clean up active request if creator throws/rejects', async () => { + let callCount = 0; + let rejectCreator!: (err: Error) => void; + const promise = new Promise((_, reject) => { + rejectCreator = reject; + }); + + const creator = () => { + callCount++; + + return promise; + }; + + const p1 = cache.getOrCreate('key', creator); + const p2 = cache.getOrCreate('key', creator); + + rejectCreator(new Error('creator error')); + + await expectAsync(p1).toBeRejectedWithError('creator error'); + await expectAsync(p2).toBeRejectedWithError('creator error'); + + // Subsequent call should trigger the creator again + const p3 = cache.getOrCreate('key', () => { + callCount++; + + return Promise.resolve('new-value'); + }); + const val3 = await p3; + expect(val3).toBe('new-value'); + expect(callCount).toBe(2); + }); + + it('should override/clear active requests when put is called', async () => { + let resolveCreator!: (value: string) => void; + const promise = new Promise((resolve) => { + resolveCreator = resolve; + }); + + let creatorStarted!: (value: void) => void; + const creatorStartedPromise = new Promise((resolve) => { + creatorStarted = resolve; + }); + + const creator = () => { + creatorStarted(); + + return promise; + }; + + const p1 = cache.getOrCreate('key', creator); + + // Wait for the creator to be called so that the active request is created + await creatorStartedPromise; + + // Call put before the creator promise resolves + await cache.put('key', 'override-value'); + + resolveCreator('original-value'); + + const val1 = await p1; + // p1 was already returned, so it resolves to original-value + expect(val1).toBe('original-value'); + + // Subsequent getOrCreate should return the put/overridden value, not the resolved original-value + const val2 = await cache.getOrCreate('key', () => 'should-not-run'); + expect(val2).toBe('override-value'); + }); +}); From 4b670c0209e3a38564e0ae2b1ddcac5d415ff078 Mon Sep 17 00:00:00 2001 From: Angular Robot Date: Mon, 8 Jun 2026 06:27:04 +0000 Subject: [PATCH 019/787] build: update pnpm to v11.5.2 See associated pull request for more information. --- MODULE.bazel | 4 ++-- package.json | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/MODULE.bazel b/MODULE.bazel index ec09798fcde4..7e365cca8d10 100644 --- a/MODULE.bazel +++ b/MODULE.bazel @@ -131,8 +131,8 @@ use_repo( pnpm = use_extension("@aspect_rules_js//npm:extensions.bzl", "pnpm") pnpm.pnpm( name = "pnpm", - pnpm_version = "11.5.1", - pnpm_version_integrity = "sha512-k/e1dCLqcGglcjW0wW62B2LraOHcI3IxmcxzkEPqm+LEFDJ0o5nYxt76KxF2Im2cocS2NILWIAwaj7qnjB0UhQ==", + pnpm_version = "11.5.2", + pnpm_version_integrity = "sha512-ccYx44IGbvwlYl1c8CkHXeB7YbN/bic1D72Esb2lhkyMGWetwoB3a0XDCnFcA1mjvgj+9C1bsJ4rmQKZeWkpFg==", ) use_repo(pnpm, "pnpm") diff --git a/package.json b/package.json index 621217fc8cf8..0bdcf9189a16 100644 --- a/package.json +++ b/package.json @@ -28,12 +28,12 @@ "type": "git", "url": "git+https://github.com/angular/angular-cli.git" }, - "packageManager": "pnpm@11.5.1", + "packageManager": "pnpm@11.5.2", "engines": { "node": "^22.22.3 || ^24.15.0 || >=26.0.0", "npm": "Please use pnpm instead of NPM to install dependencies", "yarn": "Please use pnpm instead of Yarn to install dependencies", - "pnpm": "11.5.1" + "pnpm": "11.5.2" }, "author": "Angular Authors", "license": "MIT", From 3f7494cbfafe3d0af04f94d8a182b6edb9552064 Mon Sep 17 00:00:00 2001 From: Angular Robot Date: Mon, 8 Jun 2026 22:53:15 +0000 Subject: [PATCH 020/787] build: update cross-repo angular dependencies See associated pull request for more information. --- MODULE.bazel | 6 +- MODULE.bazel.lock | 35 ++- package.json | 2 +- pnpm-lock.yaml | 351 +++++++++++++---------------- tests/e2e/ng-snapshot/package.json | 32 +-- 5 files changed, 194 insertions(+), 232 deletions(-) diff --git a/MODULE.bazel b/MODULE.bazel index 7e365cca8d10..0da20dc77a64 100644 --- a/MODULE.bazel +++ b/MODULE.bazel @@ -19,21 +19,21 @@ bazel_dep(name = "aspect_rules_jasmine", version = "2.0.4") bazel_dep(name = "rules_angular") git_override( module_name = "rules_angular", - commit = "582ffa9559d60f99fd1d3e50ae32c4223f013fea", + commit = "02e0d38eb29b2721128ca7e93ee694e68d4f06f6", remote = "https://github.com/angular/rules_angular.git", ) bazel_dep(name = "devinfra") git_override( module_name = "devinfra", - commit = "b490e5cc7fd2aa57136a1962047bd89454f3df94", + commit = "e78f06f32bc0780cfda374af155a1b5dc84fa14d", remote = "https://github.com/angular/dev-infra.git", ) bazel_dep(name = "rules_browsers") git_override( module_name = "rules_browsers", - commit = "96a315fb4737861718aa59a7e7361408db704148", + commit = "c7e596a4a34f651113c42a9da3f82acc0a01484e", remote = "https://github.com/angular/rules_browsers.git", ) diff --git a/MODULE.bazel.lock b/MODULE.bazel.lock index 53f5ff646cb4..dc32a6881872 100644 --- a/MODULE.bazel.lock +++ b/MODULE.bazel.lock @@ -24,7 +24,6 @@ "https://bcr.bazel.build/modules/aspect_rules_jasmine/2.0.4/source.json": "81ffb708333cd98ec3c0b4cc004f4d5cf92a16914b5196a2892c45141bba7cff", "https://bcr.bazel.build/modules/aspect_rules_js/2.0.0/MODULE.bazel": "b45b507574aa60a92796e3e13c195cd5744b3b8aff516a9c0cb5ae6a048161c5", "https://bcr.bazel.build/modules/aspect_rules_js/3.0.3/MODULE.bazel": "28a30e8fc33bf64a67835d64d124f6e05a7d59648dcb27b110fb3502f761e503", - "https://bcr.bazel.build/modules/aspect_rules_js/3.1.2/MODULE.bazel": "e3685502155d3cc65f3bf98e714f7435de67d7f8f355d63478a80197310311fc", "https://bcr.bazel.build/modules/aspect_rules_js/3.2.0/MODULE.bazel": "c3d34345c51a4d90cf678d3b251c6f345b63d5e2e6b0253dbdda467a01efc31f", "https://bcr.bazel.build/modules/aspect_rules_js/3.2.0/source.json": "3538ab18ac72ba3eaa3db0e4ec5171e04322768723afaa1149c0d822fe5411e2", "https://bcr.bazel.build/modules/aspect_rules_ts/3.8.10/MODULE.bazel": "a17a49a21226fc90163a29b3d6eac56703697205530b8d5cc38b3c074dbac039", @@ -593,7 +592,7 @@ }, "@@rules_browsers+//browsers:extensions.bzl%browsers": { "general": { - "bzlTransitiveDigest": "WLnUVJj/ND5g3OI+Y8YJwgtWXfoXpunqLGs7GRZ3PqI=", + "bzlTransitiveDigest": "lQlRwI+HZTXohoZ41oufeudyNMhYrxQizk07ADXimPI=", "usagesDigest": "FmXYJVoVJlnfUU8x8gObSvu4qWcco/9Faw61aC/wBF0=", "recordedFileInputs": {}, "recordedDirentsInputs": {}, @@ -602,9 +601,9 @@ "rules_browsers_chrome_linux": { "repoRuleId": "@@rules_browsers+//browsers/private:browser_repo.bzl%browser_repo", "attributes": { - "sha256": "7db2d5ced82b7f4c62ed593ff2a0e486dde48ae2b09609ab74fe30dad6eadbab", + "sha256": "fd4df6dcadda8641af4f5d79137b23f1b1271a1cfcc0b96f52cb1b8bcd7c01d5", "urls": [ - "https://storage.googleapis.com/chrome-for-testing-public/151.0.7872.0/linux64/chrome-headless-shell-linux64.zip" + "https://storage.googleapis.com/chrome-for-testing-public/151.0.7881.0/linux64/chrome-headless-shell-linux64.zip" ], "named_files": { "CHROME-HEADLESS-SHELL": "chrome-headless-shell-linux64/chrome-headless-shell" @@ -620,9 +619,9 @@ "rules_browsers_chrome_mac": { "repoRuleId": "@@rules_browsers+//browsers/private:browser_repo.bzl%browser_repo", "attributes": { - "sha256": "87e67dc147587e0c6b7ae5e6d14b778e7782c8273d1798a2841b7b6b8cbcb669", + "sha256": "4136f1a9524ac5130dd29fe9eef82094139f079520af0b28f0d360f4f3f550ed", "urls": [ - "https://storage.googleapis.com/chrome-for-testing-public/151.0.7872.0/mac-x64/chrome-headless-shell-mac-x64.zip" + "https://storage.googleapis.com/chrome-for-testing-public/151.0.7881.0/mac-x64/chrome-headless-shell-mac-x64.zip" ], "named_files": { "CHROME-HEADLESS-SHELL": "chrome-headless-shell-mac-x64/chrome-headless-shell" @@ -638,9 +637,9 @@ "rules_browsers_chrome_mac_arm": { "repoRuleId": "@@rules_browsers+//browsers/private:browser_repo.bzl%browser_repo", "attributes": { - "sha256": "42675dfaf8e89174fafecf300fdba58bc8410c31b7d9d2300505dce3358cff9c", + "sha256": "f2cb9d22ad425a23e1d58dab7ac91e546386099a5acb811ca5749d40bf2d9886", "urls": [ - "https://storage.googleapis.com/chrome-for-testing-public/151.0.7872.0/mac-arm64/chrome-headless-shell-mac-arm64.zip" + "https://storage.googleapis.com/chrome-for-testing-public/151.0.7881.0/mac-arm64/chrome-headless-shell-mac-arm64.zip" ], "named_files": { "CHROME-HEADLESS-SHELL": "chrome-headless-shell-mac-arm64/chrome-headless-shell" @@ -656,9 +655,9 @@ "rules_browsers_chrome_win64": { "repoRuleId": "@@rules_browsers+//browsers/private:browser_repo.bzl%browser_repo", "attributes": { - "sha256": "f9b135b3d1ca7e80dcced8ece4975a918f1d37d2b1f74793902e3b1ab3fa4ea6", + "sha256": "684055979848753211b24215d25993c453ee26cdb2d84d7bfb24f84118e02198", "urls": [ - "https://storage.googleapis.com/chrome-for-testing-public/151.0.7872.0/win64/chrome-headless-shell-win64.zip" + "https://storage.googleapis.com/chrome-for-testing-public/151.0.7881.0/win64/chrome-headless-shell-win64.zip" ], "named_files": { "CHROME-HEADLESS-SHELL": "chrome-headless-shell-win64/chrome-headless-shell.exe" @@ -674,9 +673,9 @@ "rules_browsers_chromedriver_linux": { "repoRuleId": "@@rules_browsers+//browsers/private:browser_repo.bzl%browser_repo", "attributes": { - "sha256": "39c2d4425b848f2e09940b4060f50484ca83f18b9d3bdbe2f42495d4a1d38f71", + "sha256": "d9e12133a8af192f8a28f2ef0d86ac54f7458c71e28bddf95947d5636472d508", "urls": [ - "https://storage.googleapis.com/chrome-for-testing-public/151.0.7872.0/linux64/chromedriver-linux64.zip" + "https://storage.googleapis.com/chrome-for-testing-public/151.0.7881.0/linux64/chromedriver-linux64.zip" ], "named_files": { "CHROMEDRIVER": "chromedriver-linux64/chromedriver" @@ -690,9 +689,9 @@ "rules_browsers_chromedriver_mac": { "repoRuleId": "@@rules_browsers+//browsers/private:browser_repo.bzl%browser_repo", "attributes": { - "sha256": "48ece94ee9b286f47c6662f3d2640a4a035af2e4f8101f8a971a909bc552bd36", + "sha256": "7432080f1c3fc8131d58870e93ca9a96c807fedc04deaaf5c1a60942f3c1d321", "urls": [ - "https://storage.googleapis.com/chrome-for-testing-public/151.0.7872.0/mac-x64/chromedriver-mac-x64.zip" + "https://storage.googleapis.com/chrome-for-testing-public/151.0.7881.0/mac-x64/chromedriver-mac-x64.zip" ], "named_files": { "CHROMEDRIVER": "chromedriver-mac-x64/chromedriver" @@ -706,9 +705,9 @@ "rules_browsers_chromedriver_mac_arm": { "repoRuleId": "@@rules_browsers+//browsers/private:browser_repo.bzl%browser_repo", "attributes": { - "sha256": "736ec9b51a4d6fe1622d1940df29e3b183fe5d09f7f06d68141c2330f76a9790", + "sha256": "0bfbda9352bbae72755b463f656a6f335481bc02be1ba8edfe1fb74a08ce0d7b", "urls": [ - "https://storage.googleapis.com/chrome-for-testing-public/151.0.7872.0/mac-arm64/chromedriver-mac-arm64.zip" + "https://storage.googleapis.com/chrome-for-testing-public/151.0.7881.0/mac-arm64/chromedriver-mac-arm64.zip" ], "named_files": { "CHROMEDRIVER": "chromedriver-mac-arm64/chromedriver" @@ -722,9 +721,9 @@ "rules_browsers_chromedriver_win64": { "repoRuleId": "@@rules_browsers+//browsers/private:browser_repo.bzl%browser_repo", "attributes": { - "sha256": "77b5c787237dcac62686c125e702d0bddc28466e9660f79a77d8389cd1d94513", + "sha256": "766efed7d9c6a3aa89733d59b64316849775002bdde7e247318c8129bbd6d747", "urls": [ - "https://storage.googleapis.com/chrome-for-testing-public/151.0.7872.0/win64/chromedriver-win64.zip" + "https://storage.googleapis.com/chrome-for-testing-public/151.0.7881.0/win64/chromedriver-win64.zip" ], "named_files": { "CHROMEDRIVER": "chromedriver-win64/chromedriver.exe" diff --git a/package.json b/package.json index 0bdcf9189a16..6012a74835cb 100644 --- a/package.json +++ b/package.json @@ -54,7 +54,7 @@ "@angular/forms": "22.0.0", "@angular/localize": "22.0.0", "@angular/material": "22.0.0", - "@angular/ng-dev": "https://github.com/angular/dev-infra-private-ng-dev-builds.git#e882d214a66c8335dc38fe15ebeabeba85a0ea29", + "@angular/ng-dev": "https://github.com/angular/dev-infra-private-ng-dev-builds.git#74db100f1fee202d031c5f306778b847f577398c", "@angular/platform-browser": "22.0.0", "@angular/platform-server": "22.0.0", "@angular/router": "22.0.0", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 1bbd8605856a..01183bb12896 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -50,8 +50,8 @@ importers: specifier: 22.0.0 version: 22.0.0(6eb83275f51d1d41f72333b1955c7306) '@angular/ng-dev': - specifier: https://github.com/angular/dev-infra-private-ng-dev-builds.git#e882d214a66c8335dc38fe15ebeabeba85a0ea29 - version: https://codeload.github.com/angular/dev-infra-private-ng-dev-builds/tar.gz/e882d214a66c8335dc38fe15ebeabeba85a0ea29(@modelcontextprotocol/sdk@1.29.0(zod@4.4.3)) + specifier: https://github.com/angular/dev-infra-private-ng-dev-builds.git#74db100f1fee202d031c5f306778b847f577398c + version: https://codeload.github.com/angular/dev-infra-private-ng-dev-builds/tar.gz/74db100f1fee202d031c5f306778b847f577398c(@modelcontextprotocol/sdk@1.29.0(zod@4.4.3)) '@angular/platform-browser': specifier: 22.0.0 version: 22.0.0(@angular/animations@22.0.0(@angular/core@22.0.0(@angular/compiler@22.0.0)(rxjs@7.8.2)(zone.js@0.16.2)))(@angular/common@22.0.0(@angular/core@22.0.0(@angular/compiler@22.0.0)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2))(@angular/core@22.0.0(@angular/compiler@22.0.0)(rxjs@7.8.2)(zone.js@0.16.2)) @@ -333,7 +333,7 @@ importers: version: 7.8.2 vitest: specifier: 4.1.8 - version: 4.1.8(@opentelemetry/api@1.9.1)(@types/node@24.12.4)(@vitest/coverage-v8@4.1.8)(jiti@2.7.0)(jsdom@29.1.1)(less@4.6.4)(sass@1.100.0)(terser@5.48.0)(tsx@4.22.3)(yaml@2.9.0) + version: 4.1.8(@opentelemetry/api@1.9.1)(@types/node@24.12.4)(@vitest/coverage-v8@4.1.8)(jiti@2.7.0)(jsdom@29.1.1)(less@4.6.4)(sass@1.100.0)(terser@5.48.0)(tsx@4.22.4)(yaml@2.9.0) packages/angular/build: dependencies: @@ -357,7 +357,7 @@ importers: version: 6.1.1(@types/node@24.12.4) '@vitejs/plugin-basic-ssl': specifier: 2.3.0 - version: 2.3.0(vite@7.3.5(@types/node@24.12.4)(jiti@2.7.0)(less@4.6.4)(sass@1.100.0)(terser@5.48.0)(tsx@4.22.3)(yaml@2.9.0)) + version: 2.3.0(vite@7.3.5(@types/node@24.12.4)(jiti@2.7.0)(less@4.6.4)(sass@1.100.0)(terser@5.48.0)(tsx@4.22.4)(yaml@2.9.0)) beasties: specifier: 0.4.2 version: 0.4.2 @@ -408,7 +408,7 @@ importers: version: 0.2.17 vite: specifier: 7.3.5 - version: 7.3.5(@types/node@24.12.4)(jiti@2.7.0)(less@4.6.4)(sass@1.100.0)(terser@5.48.0)(tsx@4.22.3)(yaml@2.9.0) + version: 7.3.5(@types/node@24.12.4)(jiti@2.7.0)(less@4.6.4)(sass@1.100.0)(terser@5.48.0)(tsx@4.22.4)(yaml@2.9.0) watchpack: specifier: 2.5.1 version: 2.5.1 @@ -442,7 +442,7 @@ importers: version: 7.8.2 vitest: specifier: 4.1.8 - version: 4.1.8(@opentelemetry/api@1.9.1)(@types/node@24.12.4)(@vitest/coverage-v8@4.1.8)(jiti@2.7.0)(jsdom@29.1.1)(less@4.6.4)(sass@1.100.0)(terser@5.48.0)(tsx@4.22.3)(yaml@2.9.0) + version: 4.1.8(@opentelemetry/api@1.9.1)(@types/node@24.12.4)(@vitest/coverage-v8@4.1.8)(jiti@2.7.0)(jsdom@29.1.1)(less@4.6.4)(sass@1.100.0)(terser@5.48.0)(tsx@4.22.4)(yaml@2.9.0) optionalDependencies: lmdb: specifier: 3.5.5 @@ -1011,9 +1011,9 @@ packages: '@angular/platform-browser': ^22.0.0 || ^23.0.0 rxjs: ^6.5.3 || ^7.4.0 - '@angular/ng-dev@https://codeload.github.com/angular/dev-infra-private-ng-dev-builds/tar.gz/e882d214a66c8335dc38fe15ebeabeba85a0ea29': - resolution: {gitHosted: true, tarball: https://codeload.github.com/angular/dev-infra-private-ng-dev-builds/tar.gz/e882d214a66c8335dc38fe15ebeabeba85a0ea29} - version: 0.0.0-b64a291ca373bc91e5ee876488710c026157bf91 + '@angular/ng-dev@https://codeload.github.com/angular/dev-infra-private-ng-dev-builds/tar.gz/74db100f1fee202d031c5f306778b847f577398c': + resolution: {gitHosted: true, integrity: sha512-DolaJQq/Bl29sdXrd8YUw+a/T0Xf2hzug0mbuWk4poeLAQ7GQpx1C+fw1TyRvu89HONzhLDYj8RMGkESZlYxwQ==, tarball: https://codeload.github.com/angular/dev-infra-private-ng-dev-builds/tar.gz/74db100f1fee202d031c5f306778b847f577398c} + version: 0.0.0-e78f06f32bc0780cfda374af155a1b5dc84fa14d hasBin: true '@angular/platform-browser@22.0.0': @@ -2046,8 +2046,8 @@ packages: '@noble/hashes': optional: true - '@firebase/ai@2.12.0': - resolution: {integrity: sha512-b+OL4vdyiSLZL/7dLd67V55CjKJvU9MpNmwnday7eA6GG2+J4iwUEsEHgw0/jKY3A41FfkF0SrnYFvtKbQZ65A==} + '@firebase/ai@2.13.0': + resolution: {integrity: sha512-nJJDQKqjAcbkZdZGT/5WTVLrGZ+pYhWbwKC90nNzmvtoRTtnOJaNS34fhKSHQeB9SALgD2kxuWT5I4AkytdZ/Q==} engines: {node: '>=20.0.0'} peerDependencies: '@firebase/app': 0.x @@ -2066,8 +2066,8 @@ packages: peerDependencies: '@firebase/app': 0.x - '@firebase/app-check-compat@0.4.3': - resolution: {integrity: sha512-L3AKIRTJxT9b7cDUH3OyV8gWTnmW3vYkwdzRsukWt4kbPBTct12xalnyvHDkm1lKkr+cQq/4uzBx1bOWsQ2ciw==} + '@firebase/app-check-compat@0.4.4': + resolution: {integrity: sha512-9iP0MvmaVagulNXmrca96U3tqNAI3j98wsC1z7rj62nnOTajlrHM//jjB9VoHqRw6/islMskp6RsKnM7vhLDqA==} engines: {node: '>=20.0.0'} peerDependencies: '@firebase/app-compat': 0.x @@ -2078,25 +2078,25 @@ packages: '@firebase/app-check-types@0.5.4': resolution: {integrity: sha512-xV7JsIyzVr15aA7f3Pi0rB9gdBuVubs89FGA8VkRYA4g0l78poADgdfrScgf7NndSg9mm7cR7PJyY0+t22KaGw==} - '@firebase/app-check@0.11.3': - resolution: {integrity: sha512-aJ4DfubWfTO8/2vhEhIAizOoOmiycESTU32e+OUgbWcS/G3PA4Vxlr/9zaiN2wfUG2AptQ7DTvj00tyuFZP5Bg==} + '@firebase/app-check@0.11.4': + resolution: {integrity: sha512-G8EsbVJV9gSfoibx0dNoNOUrvr+PkL7J//+W/BST/oUassimkZeq9bjj3bKkB0pn4og5GMQ9qs7FefwP00kkgg==} engines: {node: '>=20.0.0'} peerDependencies: '@firebase/app': 0.x - '@firebase/app-compat@0.5.12': - resolution: {integrity: sha512-Pe513OBerK/CIBxz4/za9atd5MsZtd6DzHz4cmqkvkrcDWhQChAoHBpZ3McuZNuSP8YZiKwfX/J1frR07l15/w==} + '@firebase/app-compat@0.5.13': + resolution: {integrity: sha512-pn3FvXwUR34kWPccDQfCKsNZcM2wD1OS+J1jeEgzM1ZNXoxR2NaF6e5DjDuRrnTwR6LN2XQQt0IqE6yKmgpCQg==} engines: {node: '>=20.0.0'} '@firebase/app-types@0.9.5': resolution: {integrity: sha512-YevqTjvo7Iujsa9Dwowmd6dSoElhzmD63ZSrq6bzjvQ6POjYgNjOFHLmNIgJs48eNO093NCERibuFnxbfOvU7A==} - '@firebase/app@0.14.12': - resolution: {integrity: sha512-FT+HoNp1NdaZ/N26hCwV3WbxS1m6gTn3p2QRBQ3KH7YqyCQqJx0iT7126RgVk68/Rq+9DeL/zCFnHZ0C4u1nLQ==} + '@firebase/app@0.14.13': + resolution: {integrity: sha512-H89Jeyp31+EZk9GPu6vaeL9mEmoXgM3nASB7UPBYYS/lqAks21mO1BU1dF8NbsVTL6tgGZkGUtiGJgxtDiwHkw==} engines: {node: '>=20.0.0'} - '@firebase/auth-compat@0.6.6': - resolution: {integrity: sha512-KDJ/GAf/rt7galOpn3DRb2buFfGkZCsHTryKjXDG0eeRnok4+2B4nnkMOMdjRnPkElmcJv2Ao0vEA6kp5m98PQ==} + '@firebase/auth-compat@0.6.7': + resolution: {integrity: sha512-XgKnOgY1Siq7gylAmLkYtHAlRxNeWEAspH+nO3gJZJnfHqoTHbr9UjJ3nHNFALYXV5CfpQlyPROyB2ztySBHBQ==} engines: {node: '>=20.0.0'} peerDependencies: '@firebase/app-compat': 0.x @@ -2110,8 +2110,8 @@ packages: '@firebase/app-types': 0.x '@firebase/util': 1.x - '@firebase/auth@1.13.1': - resolution: {integrity: sha512-/1nkKY/MicI+I9WWcx6R4NKs77AaW9NQ0IwsFdUBomWrW0/cXEmopfM2dtLm2oI1qG6z6vom3CXZDHJIJXoMuw==} + '@firebase/auth@1.13.2': + resolution: {integrity: sha512-B4w0iS7MxRg28oIh2fJFTE6cM0lYdBrW19eHpc42jqEcloUjlYyVrpPqZvqA4+v9KFEVSKEs2SfWyta7hbzkJQ==} engines: {node: '>=20.0.0'} peerDependencies: '@firebase/app': 0.x @@ -2124,8 +2124,8 @@ packages: resolution: {integrity: sha512-wFofIaa2879ogD/WvkjYXJxRmfnL0scen6ORgaC3na1FNOR9ASIUANQdhqQcmWu/h77/pVHY7ch5flewa5Bcew==} engines: {node: '>=20.0.0'} - '@firebase/data-connect@0.7.0': - resolution: {integrity: sha512-ar9sNOJh5poQCSMSVlnVE8eo8+usTD1POWDCv65omkKUvnFMcdXaQ7J/e7WGKqJzcEMgiezSX/TZiKHZkItMbQ==} + '@firebase/data-connect@0.7.1': + resolution: {integrity: sha512-2LbUU8mmSA63HknxQMmWHjpzuNLBKflvVwQc2tpoVKg0biWleNEJX031ELks0vzFs+dDjOUkCJR72RP6mQHFOg==} peerDependencies: '@firebase/app': 0.x @@ -2140,8 +2140,8 @@ packages: resolution: {integrity: sha512-XwWCa+E4TvNGpGwXrycLRNfdogADwFcvuhyow6wDWma9W54roaQIhe+4PM0KiLsIftBdSCGI7OKCXrdSRHbIhw==} engines: {node: '>=20.0.0'} - '@firebase/firestore-compat@0.4.9': - resolution: {integrity: sha512-NPtBuFr79BbIQJXFWhW4xFC6rBksK8/ewqCTYbbAYfZBDDx0/iHTUj4WpKi5D4d0Pn2Md/3T/e5V9379G5N/Zg==} + '@firebase/firestore-compat@0.4.10': + resolution: {integrity: sha512-yMP3FADDjikdrQv4YmvL4EkIny6Hw+N+a2O5T40rlHiniyMpRPxgYkKiFOvMZnsqKLqBVnKqCAElC0pa/IZtdw==} engines: {node: '>=20.0.0'} peerDependencies: '@firebase/app-compat': 0.x @@ -2152,14 +2152,14 @@ packages: '@firebase/app-types': 0.x '@firebase/util': 1.x - '@firebase/firestore@4.14.1': - resolution: {integrity: sha512-PouS0NJZ3NYOZE/tPDvXa8VUeJ10Ll//7jIdFvMYdhQkd/P3O7nlqhyoTmY0h8Xa9hxg+H0j6gxUytJcoZ9YOg==} + '@firebase/firestore@4.15.0': + resolution: {integrity: sha512-Fj9osqYkz2Rqr7kW3/A8BRd8CyJ7yA5K8YjhihRdyJWbL+FsELVcR6DpoCplrp1IyU+xeGgTubo1UOySXpY+EA==} engines: {node: '>=20.0.0'} peerDependencies: '@firebase/app': 0.x - '@firebase/functions-compat@0.4.4': - resolution: {integrity: sha512-Be+MwhseVf/eFAZwGrFJGok6S7cmsLrAPK8MgyM8LjM0MewTsx2n01WOOca9jio1UsCZOJ0aVyQobnINcdNuIQ==} + '@firebase/functions-compat@0.4.5': + resolution: {integrity: sha512-10qlUXGY25G5/1g9UihqksPp2po+ZqSE7LEizsrdUP7vrTmkysXxGSZCDyojSEp6mQe/ecRDdDDI+z4XRdb4wQ==} engines: {node: '>=20.0.0'} peerDependencies: '@firebase/app-compat': 0.x @@ -2167,8 +2167,8 @@ packages: '@firebase/functions-types@0.6.4': resolution: {integrity: sha512-zV6kgqtduR4rUAdC/ilS7kmb93XD7bEZoJDlVBZqlOw2uGGGCNBQBuleww2rr0Ulr3L9o2TDjumEt68/l1f9DQ==} - '@firebase/functions@0.13.4': - resolution: {integrity: sha512-oB5rpm2Emxn2+IS1gRelAeT/5tSZMwM/KhqC5LnJsmTNnS1ZDhD7ZMZNgCI8vchTW6PbaXIwEnpUryGuIQsNbg==} + '@firebase/functions@0.13.5': + resolution: {integrity: sha512-bWCx713f4kE/uFV7gdFOLBS7lDoiZj48MRkbAqe35gkXcCeWF4QjRNO07Jhmve7EJIoQOBczL29y2r8VRuN1kw==} engines: {node: '>=20.0.0'} peerDependencies: '@firebase/app': 0.x @@ -2192,16 +2192,16 @@ packages: resolution: {integrity: sha512-vZKLsqE1ABOy8OjQiE7cUTFn4gvaqlk88yp8N94Pk/sDpq61YqZGqmVFZTvOyflTwuYFcWirBdYGoJgbDaXKYQ==} engines: {node: '>=20.0.0'} - '@firebase/messaging-compat@0.2.26': - resolution: {integrity: sha512-fn0XvWOfK4tsDLSipwJUW9Cp6ahWA6z+iJHxZ0pHp9MzMSUNQx85yuxZAuI7gkGXfqs7+DqEDHyyS7jDGswrmQ==} + '@firebase/messaging-compat@0.2.27': + resolution: {integrity: sha512-JNOiu1PPgdHzEPEtoFiNxQuu0x9bm4bfETSQCpGfcTlgWkhlSK7uh7nlsjC10TQLUNgYetLmuutaYTh8aeYLVA==} peerDependencies: '@firebase/app-compat': 0.x - '@firebase/messaging-interop-types@0.2.4': - resolution: {integrity: sha512-wrzITQq+xw5LtygX7O0fu43/k9ABQ4x5H9/sR5m1SbNnhIRI5xd3+raSNJaJkYC4BUhM9A4ZNSnyR2sjhxnb2Q==} + '@firebase/messaging-interop-types@0.2.5': + resolution: {integrity: sha512-tUEKnaAP2Y/MNIqgnriPpV6e5l13Vs/+p2yrd6NGlncPJT9O3a8muYZtdnWe+IJ4fgKLHJVC79n/asxk/N5Msw==} - '@firebase/messaging@0.12.26': - resolution: {integrity: sha512-lHVTO9uLofymHVWkYeUtMddIPcmJvSzVbHRB88W6XKfxbcKF+p3QrfqKhDxremSB4NQjUla1Gwn7d9umSMmt/w==} + '@firebase/messaging@0.13.0': + resolution: {integrity: sha512-GZoo0uGRvEbszo83xcgbjJp4FpkmBEr4l8Z4hi8gl+P1Spn/MTK3HapanMzSX4yUHuTEiF5hasWRxOaz+o5sxQ==} peerDependencies: '@firebase/app': 0.x @@ -2218,16 +2218,16 @@ packages: peerDependencies: '@firebase/app': 0.x - '@firebase/remote-config-compat@0.2.24': - resolution: {integrity: sha512-EWZTt6fJ7YmPHodQNsSxAIDZY2x8P5kRPvXAc5CmzzBm+NyPFhODbfDsNllDXDL8jlzp50bVWjDY+BXepZS9Mg==} + '@firebase/remote-config-compat@0.2.25': + resolution: {integrity: sha512-FnA5S4IxFJAAFrCnYzWlO0FCaizlYdqhe42ygFMA+wE/mUP+w36iXzHyKj1OO1A+2gyMFjeRHyg8HhkJ6c5vRA==} peerDependencies: '@firebase/app-compat': 0.x '@firebase/remote-config-types@0.5.1': resolution: {integrity: sha512-cX/1LT6KQwkXzck2eSzeKnuvXZCyr8qaPpDcikoJs7jmI+oBOXixpDLeDtWj1U6GNMkIoXrEDNoyT2Ypcyp5/A==} - '@firebase/remote-config@0.8.3': - resolution: {integrity: sha512-ggGKAaLy9YNOvpFoQZgm5p5SiFw3ZFtwti08dojnBQmQicpThTxvG5xZMSpCTYMj2o3gM/yK9CVd2w+kZub8YA==} + '@firebase/remote-config@0.8.4': + resolution: {integrity: sha512-lslywR5lGvHWTu4z/MPoYs3UwS3CKdeY+ELXY87087VsOpBpkD+9Orra23tA9GW683arPTDOM3CM6eKmtiOO3g==} peerDependencies: '@firebase/app': 0.x @@ -2291,8 +2291,8 @@ packages: resolution: {integrity: sha512-IJn+8A3QZJfe7FUtWqHVNo3xJs7KFpurCWGWCiCz3oEh+BkRymKZ1QxfAbU2yGMDzTytLGQ2IV6T2r3cuo75/w==} engines: {node: '>=18'} - '@google/genai@2.6.0': - resolution: {integrity: sha512-HjoW3mPuEn7pnuKABJl9VbDoWDSF4nbwYKYvYYor7YjPeDxrrBxHzu2d1Prcd+BAuC4w+85UP6y7ZdcrQAoO7g==} + '@google/genai@2.7.0': + resolution: {integrity: sha512-tv0DRtcndt2oEhBYy+5mA0TaXH98+L1Gt0AP9unBfH7DP20KhB7+O3QqAN1Lz+laMARGTHS7BFQSNpLbl4gm1g==} engines: {node: '>=20.0.0'} peerDependencies: '@modelcontextprotocol/sdk': ^1.25.2 @@ -2436,15 +2436,6 @@ packages: '@types/node': optional: true - '@inquirer/prompts@8.4.3': - resolution: {integrity: sha512-ai5LseTw9HhegupIgmo4cn7RpnCGznjjXu4OI+7jMR8vu7T1ZCCNMzFFAovUCjL1fl0cceksIN1++yQE59SmZw==} - engines: {node: '>=23.5.0 || ^22.13.0 || ^21.7.0 || ^20.12.0'} - peerDependencies: - '@types/node': '>=18' - peerDependenciesMeta: - '@types/node': - optional: true - '@inquirer/prompts@8.5.2': resolution: {integrity: sha512-IYR/3C/paEVVQYQvdDlFZVjRCJVYHHON0XXMH91KO9GSxs0TdKYWlUdvfQl2EfAHDxUaN3IBffkE/BDTh5nJ6g==} engines: {node: '>=23.5.0 || ^22.13.0 || ^20.17.0'} @@ -2481,15 +2472,6 @@ packages: '@types/node': optional: true - '@inquirer/type@4.0.5': - resolution: {integrity: sha512-aetVUNeKNc/VriqXlw1NRSW0zhMBB0W4bNbWRJgzRl/3d0QNDQFfk0GO5SDdtjMZVg6o8ZKEiadd7SCCzoOn5Q==} - engines: {node: '>=23.5.0 || ^22.13.0 || ^21.7.0 || ^20.12.0'} - peerDependencies: - '@types/node': '>=18' - peerDependenciesMeta: - '@types/node': - optional: true - '@inquirer/type@4.0.7': resolution: {integrity: sha512-t28inv14nMQ1PhKpsJPY+kEs/c00qzeCOS2gTNRyTjG5d6qsVA2fItxW4hkvGZ5lvanGLdtCzVIx5dwdRpN1+g==} engines: {node: '>=23.5.0 || ^22.13.0 || ^20.17.0'} @@ -5359,8 +5341,8 @@ packages: resolution: {integrity: sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==} engines: {node: '>=10'} - firebase@12.13.0: - resolution: {integrity: sha512-iutR8ejvAqk6qUClnsPz3U3VIjTWp243AX4cD3iifak5t56to1J29xUIQgSDDzaAqKvhshZerzSahwMQj2TlvA==} + firebase@12.14.0: + resolution: {integrity: sha512-aEZ/lniDR1hOCYpx/x/V8Nrrqq9pepKDNkqP/4WGZFC69gTv6F59Z4/54W/SUP4L/hFlrRNmWj35aweQq+IHow==} flat-cache@4.0.1: resolution: {integrity: sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw==} @@ -7981,8 +7963,8 @@ packages: tslib@2.8.1: resolution: {integrity: sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==} - tsx@4.22.3: - resolution: {integrity: sha512-mdoNxBC/cSQObGGVQ5Bpn5i+yv7j68gk3Nfm3wFjcJg3Z0Mix9jzAFfP12prmm5eVGmDKtp0yyArrs0Q+8gZHg==} + tsx@4.22.4: + resolution: {integrity: sha512-X8EX+XV4QR5xCsrgxaED954zTDfY8KqlDtskKEL0cHhyS/P8b4IFOvGDQpsC9Q1XnLq915wEfwwY/zzskCtmhg==} engines: {node: '>=18.0.0'} hasBin: true @@ -8758,14 +8740,14 @@ snapshots: rxjs: 7.8.2 tslib: 2.8.1 - '@angular/ng-dev@https://codeload.github.com/angular/dev-infra-private-ng-dev-builds/tar.gz/e882d214a66c8335dc38fe15ebeabeba85a0ea29(@modelcontextprotocol/sdk@1.29.0(zod@4.4.3))': + '@angular/ng-dev@https://codeload.github.com/angular/dev-infra-private-ng-dev-builds/tar.gz/74db100f1fee202d031c5f306778b847f577398c(@modelcontextprotocol/sdk@1.29.0(zod@4.4.3))': dependencies: '@actions/core': 3.0.1 '@conventional-changelog/git-client': 2.7.0(conventional-commits-filter@5.0.0)(conventional-commits-parser@6.4.0) '@google-cloud/spanner': 8.0.0(supports-color@10.2.2) - '@google/genai': 2.6.0(@modelcontextprotocol/sdk@1.29.0(zod@4.4.3))(bufferutil@4.1.0)(supports-color@10.2.2)(utf-8-validate@6.0.6) - '@inquirer/prompts': 8.4.3(@types/node@24.12.4) - '@inquirer/type': 4.0.5(@types/node@24.12.4) + '@google/genai': 2.7.0(@modelcontextprotocol/sdk@1.29.0(zod@4.4.3))(bufferutil@4.1.0)(supports-color@10.2.2)(utf-8-validate@6.0.6) + '@inquirer/prompts': 8.5.2(@types/node@24.12.4) + '@inquirer/type': 4.0.7(@types/node@24.12.4) '@octokit/auth-app': 8.2.0 '@octokit/core': 7.0.6 '@octokit/graphql': 9.0.3 @@ -8795,7 +8777,7 @@ snapshots: ejs: 5.0.2 encoding: 0.1.13 fast-glob: 3.3.3 - firebase: 12.13.0 + firebase: 12.14.0 folder-hash: 4.1.3(supports-color@10.2.2) jasmine: 6.2.0 jasmine-core: 6.2.0 @@ -8804,9 +8786,9 @@ snapshots: minimatch: 10.2.5 multimatch: 8.0.0 nock: 14.0.15 - semver: 7.8.0 + semver: 7.8.1 supports-color: 10.2.2 - tsx: 4.22.3 + tsx: 4.22.4 typed-graphqlify: 3.1.6 typescript: 6.0.3 utf-8-validate: 6.0.6 @@ -9876,9 +9858,9 @@ snapshots: '@exodus/bytes@1.15.1': {} - '@firebase/ai@2.12.0(@firebase/app-types@0.9.5)(@firebase/app@0.14.12)': + '@firebase/ai@2.13.0(@firebase/app-types@0.9.5)(@firebase/app@0.14.13)': dependencies: - '@firebase/app': 0.14.12 + '@firebase/app': 0.14.13 '@firebase/app-check-interop-types': 0.3.4 '@firebase/app-types': 0.9.5 '@firebase/component': 0.7.3 @@ -9886,11 +9868,11 @@ snapshots: '@firebase/util': 1.15.1 tslib: 2.8.1 - '@firebase/analytics-compat@0.2.28(@firebase/app-compat@0.5.12)(@firebase/app@0.14.12)': + '@firebase/analytics-compat@0.2.28(@firebase/app-compat@0.5.13)(@firebase/app@0.14.13)': dependencies: - '@firebase/analytics': 0.10.22(@firebase/app@0.14.12) + '@firebase/analytics': 0.10.22(@firebase/app@0.14.13) '@firebase/analytics-types': 0.8.4 - '@firebase/app-compat': 0.5.12 + '@firebase/app-compat': 0.5.13 '@firebase/component': 0.7.3 '@firebase/util': 1.15.1 tslib: 2.8.1 @@ -9899,20 +9881,20 @@ snapshots: '@firebase/analytics-types@0.8.4': {} - '@firebase/analytics@0.10.22(@firebase/app@0.14.12)': + '@firebase/analytics@0.10.22(@firebase/app@0.14.13)': dependencies: - '@firebase/app': 0.14.12 + '@firebase/app': 0.14.13 '@firebase/component': 0.7.3 - '@firebase/installations': 0.6.22(@firebase/app@0.14.12) + '@firebase/installations': 0.6.22(@firebase/app@0.14.13) '@firebase/logger': 0.5.1 '@firebase/util': 1.15.1 tslib: 2.8.1 - '@firebase/app-check-compat@0.4.3(@firebase/app-compat@0.5.12)(@firebase/app@0.14.12)': + '@firebase/app-check-compat@0.4.4(@firebase/app-compat@0.5.13)(@firebase/app@0.14.13)': dependencies: - '@firebase/app-check': 0.11.3(@firebase/app@0.14.12) + '@firebase/app-check': 0.11.4(@firebase/app@0.14.13) '@firebase/app-check-types': 0.5.4 - '@firebase/app-compat': 0.5.12 + '@firebase/app-compat': 0.5.13 '@firebase/component': 0.7.3 '@firebase/logger': 0.5.1 '@firebase/util': 1.15.1 @@ -9924,17 +9906,17 @@ snapshots: '@firebase/app-check-types@0.5.4': {} - '@firebase/app-check@0.11.3(@firebase/app@0.14.12)': + '@firebase/app-check@0.11.4(@firebase/app@0.14.13)': dependencies: - '@firebase/app': 0.14.12 + '@firebase/app': 0.14.13 '@firebase/component': 0.7.3 '@firebase/logger': 0.5.1 '@firebase/util': 1.15.1 tslib: 2.8.1 - '@firebase/app-compat@0.5.12': + '@firebase/app-compat@0.5.13': dependencies: - '@firebase/app': 0.14.12 + '@firebase/app': 0.14.13 '@firebase/component': 0.7.3 '@firebase/logger': 0.5.1 '@firebase/util': 1.15.1 @@ -9944,7 +9926,7 @@ snapshots: dependencies: '@firebase/logger': 0.5.1 - '@firebase/app@0.14.12': + '@firebase/app@0.14.13': dependencies: '@firebase/component': 0.7.3 '@firebase/logger': 0.5.1 @@ -9952,10 +9934,10 @@ snapshots: idb: 7.1.1 tslib: 2.8.1 - '@firebase/auth-compat@0.6.6(@firebase/app-compat@0.5.12)(@firebase/app-types@0.9.5)(@firebase/app@0.14.12)': + '@firebase/auth-compat@0.6.7(@firebase/app-compat@0.5.13)(@firebase/app-types@0.9.5)(@firebase/app@0.14.13)': dependencies: - '@firebase/app-compat': 0.5.12 - '@firebase/auth': 1.13.1(@firebase/app@0.14.12) + '@firebase/app-compat': 0.5.13 + '@firebase/auth': 1.13.2(@firebase/app@0.14.13) '@firebase/auth-types': 0.13.1(@firebase/app-types@0.9.5)(@firebase/util@1.15.1) '@firebase/component': 0.7.3 '@firebase/util': 1.15.1 @@ -9972,9 +9954,9 @@ snapshots: '@firebase/app-types': 0.9.5 '@firebase/util': 1.15.1 - '@firebase/auth@1.13.1(@firebase/app@0.14.12)': + '@firebase/auth@1.13.2(@firebase/app@0.14.13)': dependencies: - '@firebase/app': 0.14.12 + '@firebase/app': 0.14.13 '@firebase/component': 0.7.3 '@firebase/logger': 0.5.1 '@firebase/util': 1.15.1 @@ -9985,9 +9967,9 @@ snapshots: '@firebase/util': 1.15.1 tslib: 2.8.1 - '@firebase/data-connect@0.7.0(@firebase/app@0.14.12)': + '@firebase/data-connect@0.7.1(@firebase/app@0.14.13)': dependencies: - '@firebase/app': 0.14.12 + '@firebase/app': 0.14.13 '@firebase/auth-interop-types': 0.2.5 '@firebase/component': 0.7.3 '@firebase/logger': 0.5.1 @@ -10018,11 +10000,11 @@ snapshots: faye-websocket: 0.11.4 tslib: 2.8.1 - '@firebase/firestore-compat@0.4.9(@firebase/app-compat@0.5.12)(@firebase/app-types@0.9.5)(@firebase/app@0.14.12)': + '@firebase/firestore-compat@0.4.10(@firebase/app-compat@0.5.13)(@firebase/app-types@0.9.5)(@firebase/app@0.14.13)': dependencies: - '@firebase/app-compat': 0.5.12 + '@firebase/app-compat': 0.5.13 '@firebase/component': 0.7.3 - '@firebase/firestore': 4.14.1(@firebase/app@0.14.12) + '@firebase/firestore': 4.15.0(@firebase/app@0.14.13) '@firebase/firestore-types': 3.0.4(@firebase/app-types@0.9.5)(@firebase/util@1.15.1) '@firebase/util': 1.15.1 tslib: 2.8.1 @@ -10035,9 +10017,9 @@ snapshots: '@firebase/app-types': 0.9.5 '@firebase/util': 1.15.1 - '@firebase/firestore@4.14.1(@firebase/app@0.14.12)': + '@firebase/firestore@4.15.0(@firebase/app@0.14.13)': dependencies: - '@firebase/app': 0.14.12 + '@firebase/app': 0.14.13 '@firebase/component': 0.7.3 '@firebase/logger': 0.5.1 '@firebase/util': 1.15.1 @@ -10046,11 +10028,11 @@ snapshots: '@grpc/proto-loader': 0.7.15 tslib: 2.8.1 - '@firebase/functions-compat@0.4.4(@firebase/app-compat@0.5.12)(@firebase/app@0.14.12)': + '@firebase/functions-compat@0.4.5(@firebase/app-compat@0.5.13)(@firebase/app@0.14.13)': dependencies: - '@firebase/app-compat': 0.5.12 + '@firebase/app-compat': 0.5.13 '@firebase/component': 0.7.3 - '@firebase/functions': 0.13.4(@firebase/app@0.14.12) + '@firebase/functions': 0.13.5(@firebase/app@0.14.13) '@firebase/functions-types': 0.6.4 '@firebase/util': 1.15.1 tslib: 2.8.1 @@ -10059,21 +10041,21 @@ snapshots: '@firebase/functions-types@0.6.4': {} - '@firebase/functions@0.13.4(@firebase/app@0.14.12)': + '@firebase/functions@0.13.5(@firebase/app@0.14.13)': dependencies: - '@firebase/app': 0.14.12 + '@firebase/app': 0.14.13 '@firebase/app-check-interop-types': 0.3.4 '@firebase/auth-interop-types': 0.2.5 '@firebase/component': 0.7.3 - '@firebase/messaging-interop-types': 0.2.4 + '@firebase/messaging-interop-types': 0.2.5 '@firebase/util': 1.15.1 tslib: 2.8.1 - '@firebase/installations-compat@0.2.22(@firebase/app-compat@0.5.12)(@firebase/app-types@0.9.5)(@firebase/app@0.14.12)': + '@firebase/installations-compat@0.2.22(@firebase/app-compat@0.5.13)(@firebase/app-types@0.9.5)(@firebase/app@0.14.13)': dependencies: - '@firebase/app-compat': 0.5.12 + '@firebase/app-compat': 0.5.13 '@firebase/component': 0.7.3 - '@firebase/installations': 0.6.22(@firebase/app@0.14.12) + '@firebase/installations': 0.6.22(@firebase/app@0.14.13) '@firebase/installations-types': 0.5.4(@firebase/app-types@0.9.5) '@firebase/util': 1.15.1 tslib: 2.8.1 @@ -10085,9 +10067,9 @@ snapshots: dependencies: '@firebase/app-types': 0.9.5 - '@firebase/installations@0.6.22(@firebase/app@0.14.12)': + '@firebase/installations@0.6.22(@firebase/app@0.14.13)': dependencies: - '@firebase/app': 0.14.12 + '@firebase/app': 0.14.13 '@firebase/component': 0.7.3 '@firebase/util': 1.15.1 idb: 7.1.1 @@ -10097,34 +10079,34 @@ snapshots: dependencies: tslib: 2.8.1 - '@firebase/messaging-compat@0.2.26(@firebase/app-compat@0.5.12)(@firebase/app@0.14.12)': + '@firebase/messaging-compat@0.2.27(@firebase/app-compat@0.5.13)(@firebase/app@0.14.13)': dependencies: - '@firebase/app-compat': 0.5.12 + '@firebase/app-compat': 0.5.13 '@firebase/component': 0.7.3 - '@firebase/messaging': 0.12.26(@firebase/app@0.14.12) + '@firebase/messaging': 0.13.0(@firebase/app@0.14.13) '@firebase/util': 1.15.1 tslib: 2.8.1 transitivePeerDependencies: - '@firebase/app' - '@firebase/messaging-interop-types@0.2.4': {} + '@firebase/messaging-interop-types@0.2.5': {} - '@firebase/messaging@0.12.26(@firebase/app@0.14.12)': + '@firebase/messaging@0.13.0(@firebase/app@0.14.13)': dependencies: - '@firebase/app': 0.14.12 + '@firebase/app': 0.14.13 '@firebase/component': 0.7.3 - '@firebase/installations': 0.6.22(@firebase/app@0.14.12) - '@firebase/messaging-interop-types': 0.2.4 + '@firebase/installations': 0.6.22(@firebase/app@0.14.13) + '@firebase/messaging-interop-types': 0.2.5 '@firebase/util': 1.15.1 idb: 7.1.1 tslib: 2.8.1 - '@firebase/performance-compat@0.2.25(@firebase/app-compat@0.5.12)(@firebase/app@0.14.12)': + '@firebase/performance-compat@0.2.25(@firebase/app-compat@0.5.13)(@firebase/app@0.14.13)': dependencies: - '@firebase/app-compat': 0.5.12 + '@firebase/app-compat': 0.5.13 '@firebase/component': 0.7.3 '@firebase/logger': 0.5.1 - '@firebase/performance': 0.7.12(@firebase/app@0.14.12) + '@firebase/performance': 0.7.12(@firebase/app@0.14.13) '@firebase/performance-types': 0.2.4 '@firebase/util': 1.15.1 tslib: 2.8.1 @@ -10133,22 +10115,22 @@ snapshots: '@firebase/performance-types@0.2.4': {} - '@firebase/performance@0.7.12(@firebase/app@0.14.12)': + '@firebase/performance@0.7.12(@firebase/app@0.14.13)': dependencies: - '@firebase/app': 0.14.12 + '@firebase/app': 0.14.13 '@firebase/component': 0.7.3 - '@firebase/installations': 0.6.22(@firebase/app@0.14.12) + '@firebase/installations': 0.6.22(@firebase/app@0.14.13) '@firebase/logger': 0.5.1 '@firebase/util': 1.15.1 tslib: 2.8.1 web-vitals: 4.2.4 - '@firebase/remote-config-compat@0.2.24(@firebase/app-compat@0.5.12)(@firebase/app@0.14.12)': + '@firebase/remote-config-compat@0.2.25(@firebase/app-compat@0.5.13)(@firebase/app@0.14.13)': dependencies: - '@firebase/app-compat': 0.5.12 + '@firebase/app-compat': 0.5.13 '@firebase/component': 0.7.3 '@firebase/logger': 0.5.1 - '@firebase/remote-config': 0.8.3(@firebase/app@0.14.12) + '@firebase/remote-config': 0.8.4(@firebase/app@0.14.13) '@firebase/remote-config-types': 0.5.1 '@firebase/util': 1.15.1 tslib: 2.8.1 @@ -10157,20 +10139,20 @@ snapshots: '@firebase/remote-config-types@0.5.1': {} - '@firebase/remote-config@0.8.3(@firebase/app@0.14.12)': + '@firebase/remote-config@0.8.4(@firebase/app@0.14.13)': dependencies: - '@firebase/app': 0.14.12 + '@firebase/app': 0.14.13 '@firebase/component': 0.7.3 - '@firebase/installations': 0.6.22(@firebase/app@0.14.12) + '@firebase/installations': 0.6.22(@firebase/app@0.14.13) '@firebase/logger': 0.5.1 '@firebase/util': 1.15.1 tslib: 2.8.1 - '@firebase/storage-compat@0.4.3(@firebase/app-compat@0.5.12)(@firebase/app-types@0.9.5)(@firebase/app@0.14.12)': + '@firebase/storage-compat@0.4.3(@firebase/app-compat@0.5.13)(@firebase/app-types@0.9.5)(@firebase/app@0.14.13)': dependencies: - '@firebase/app-compat': 0.5.12 + '@firebase/app-compat': 0.5.13 '@firebase/component': 0.7.3 - '@firebase/storage': 0.14.3(@firebase/app@0.14.12) + '@firebase/storage': 0.14.3(@firebase/app@0.14.13) '@firebase/storage-types': 0.8.4(@firebase/app-types@0.9.5)(@firebase/util@1.15.1) '@firebase/util': 1.15.1 tslib: 2.8.1 @@ -10183,9 +10165,9 @@ snapshots: '@firebase/app-types': 0.9.5 '@firebase/util': 1.15.1 - '@firebase/storage@0.14.3(@firebase/app@0.14.12)': + '@firebase/storage@0.14.3(@firebase/app@0.14.13)': dependencies: - '@firebase/app': 0.14.12 + '@firebase/app': 0.14.13 '@firebase/component': 0.7.3 '@firebase/util': 1.15.1 tslib: 2.8.1 @@ -10259,7 +10241,7 @@ snapshots: transitivePeerDependencies: - supports-color - '@google/genai@2.6.0(@modelcontextprotocol/sdk@1.29.0(zod@4.4.3))(bufferutil@4.1.0)(supports-color@10.2.2)(utf-8-validate@6.0.6)': + '@google/genai@2.7.0(@modelcontextprotocol/sdk@1.29.0(zod@4.4.3))(bufferutil@4.1.0)(supports-color@10.2.2)(utf-8-validate@6.0.6)': dependencies: google-auth-library: 10.6.2(supports-color@10.2.2) p-retry: 4.6.2 @@ -10395,21 +10377,6 @@ snapshots: optionalDependencies: '@types/node': 24.12.4 - '@inquirer/prompts@8.4.3(@types/node@24.12.4)': - dependencies: - '@inquirer/checkbox': 5.2.1(@types/node@24.12.4) - '@inquirer/confirm': 6.1.1(@types/node@24.12.4) - '@inquirer/editor': 5.2.2(@types/node@24.12.4) - '@inquirer/expand': 5.1.1(@types/node@24.12.4) - '@inquirer/input': 5.1.2(@types/node@24.12.4) - '@inquirer/number': 4.1.1(@types/node@24.12.4) - '@inquirer/password': 5.1.1(@types/node@24.12.4) - '@inquirer/rawlist': 5.3.1(@types/node@24.12.4) - '@inquirer/search': 4.2.1(@types/node@24.12.4) - '@inquirer/select': 5.2.1(@types/node@24.12.4) - optionalDependencies: - '@types/node': 24.12.4 - '@inquirer/prompts@8.5.2(@types/node@24.12.4)': dependencies: '@inquirer/checkbox': 5.2.1(@types/node@24.12.4) @@ -10449,10 +10416,6 @@ snapshots: optionalDependencies: '@types/node': 24.12.4 - '@inquirer/type@4.0.5(@types/node@24.12.4)': - optionalDependencies: - '@types/node': 24.12.4 - '@inquirer/type@4.0.7(@types/node@24.12.4)': optionalDependencies: '@types/node': 24.12.4 @@ -11989,9 +11952,9 @@ snapshots: lodash: 4.18.1 minimatch: 7.4.9 - '@vitejs/plugin-basic-ssl@2.3.0(vite@7.3.5(@types/node@24.12.4)(jiti@2.7.0)(less@4.6.4)(sass@1.100.0)(terser@5.48.0)(tsx@4.22.3)(yaml@2.9.0))': + '@vitejs/plugin-basic-ssl@2.3.0(vite@7.3.5(@types/node@24.12.4)(jiti@2.7.0)(less@4.6.4)(sass@1.100.0)(terser@5.48.0)(tsx@4.22.4)(yaml@2.9.0))': dependencies: - vite: 7.3.5(@types/node@24.12.4)(jiti@2.7.0)(less@4.6.4)(sass@1.100.0)(terser@5.48.0)(tsx@4.22.3)(yaml@2.9.0) + vite: 7.3.5(@types/node@24.12.4)(jiti@2.7.0)(less@4.6.4)(sass@1.100.0)(terser@5.48.0)(tsx@4.22.4)(yaml@2.9.0) '@vitest/coverage-v8@4.1.8(vitest@4.1.8)': dependencies: @@ -12005,7 +11968,7 @@ snapshots: obug: 2.1.1 std-env: 4.1.0 tinyrainbow: 3.1.0 - vitest: 4.1.8(@opentelemetry/api@1.9.1)(@types/node@24.12.4)(@vitest/coverage-v8@4.1.8)(jiti@2.7.0)(jsdom@29.1.1)(less@4.6.4)(sass@1.100.0)(terser@5.48.0)(tsx@4.22.3)(yaml@2.9.0) + vitest: 4.1.8(@opentelemetry/api@1.9.1)(@types/node@24.12.4)(@vitest/coverage-v8@4.1.8)(jiti@2.7.0)(jsdom@29.1.1)(less@4.6.4)(sass@1.100.0)(terser@5.48.0)(tsx@4.22.4)(yaml@2.9.0) '@vitest/expect@4.1.8': dependencies: @@ -12016,13 +11979,13 @@ snapshots: chai: 6.2.2 tinyrainbow: 3.1.0 - '@vitest/mocker@4.1.8(vite@7.3.5(@types/node@24.12.4)(jiti@2.7.0)(less@4.6.4)(sass@1.100.0)(terser@5.48.0)(tsx@4.22.3)(yaml@2.9.0))': + '@vitest/mocker@4.1.8(vite@7.3.5(@types/node@24.12.4)(jiti@2.7.0)(less@4.6.4)(sass@1.100.0)(terser@5.48.0)(tsx@4.22.4)(yaml@2.9.0))': dependencies: '@vitest/spy': 4.1.8 estree-walker: 3.0.3 magic-string: 0.30.21 optionalDependencies: - vite: 7.3.5(@types/node@24.12.4)(jiti@2.7.0)(less@4.6.4)(sass@1.100.0)(terser@5.48.0)(tsx@4.22.3)(yaml@2.9.0) + vite: 7.3.5(@types/node@24.12.4)(jiti@2.7.0)(less@4.6.4)(sass@1.100.0)(terser@5.48.0)(tsx@4.22.4)(yaml@2.9.0) '@vitest/pretty-format@4.1.8': dependencies: @@ -13767,35 +13730,35 @@ snapshots: locate-path: 6.0.0 path-exists: 4.0.0 - firebase@12.13.0: + firebase@12.14.0: dependencies: - '@firebase/ai': 2.12.0(@firebase/app-types@0.9.5)(@firebase/app@0.14.12) - '@firebase/analytics': 0.10.22(@firebase/app@0.14.12) - '@firebase/analytics-compat': 0.2.28(@firebase/app-compat@0.5.12)(@firebase/app@0.14.12) - '@firebase/app': 0.14.12 - '@firebase/app-check': 0.11.3(@firebase/app@0.14.12) - '@firebase/app-check-compat': 0.4.3(@firebase/app-compat@0.5.12)(@firebase/app@0.14.12) - '@firebase/app-compat': 0.5.12 + '@firebase/ai': 2.13.0(@firebase/app-types@0.9.5)(@firebase/app@0.14.13) + '@firebase/analytics': 0.10.22(@firebase/app@0.14.13) + '@firebase/analytics-compat': 0.2.28(@firebase/app-compat@0.5.13)(@firebase/app@0.14.13) + '@firebase/app': 0.14.13 + '@firebase/app-check': 0.11.4(@firebase/app@0.14.13) + '@firebase/app-check-compat': 0.4.4(@firebase/app-compat@0.5.13)(@firebase/app@0.14.13) + '@firebase/app-compat': 0.5.13 '@firebase/app-types': 0.9.5 - '@firebase/auth': 1.13.1(@firebase/app@0.14.12) - '@firebase/auth-compat': 0.6.6(@firebase/app-compat@0.5.12)(@firebase/app-types@0.9.5)(@firebase/app@0.14.12) - '@firebase/data-connect': 0.7.0(@firebase/app@0.14.12) + '@firebase/auth': 1.13.2(@firebase/app@0.14.13) + '@firebase/auth-compat': 0.6.7(@firebase/app-compat@0.5.13)(@firebase/app-types@0.9.5)(@firebase/app@0.14.13) + '@firebase/data-connect': 0.7.1(@firebase/app@0.14.13) '@firebase/database': 1.1.3 '@firebase/database-compat': 2.1.4 - '@firebase/firestore': 4.14.1(@firebase/app@0.14.12) - '@firebase/firestore-compat': 0.4.9(@firebase/app-compat@0.5.12)(@firebase/app-types@0.9.5)(@firebase/app@0.14.12) - '@firebase/functions': 0.13.4(@firebase/app@0.14.12) - '@firebase/functions-compat': 0.4.4(@firebase/app-compat@0.5.12)(@firebase/app@0.14.12) - '@firebase/installations': 0.6.22(@firebase/app@0.14.12) - '@firebase/installations-compat': 0.2.22(@firebase/app-compat@0.5.12)(@firebase/app-types@0.9.5)(@firebase/app@0.14.12) - '@firebase/messaging': 0.12.26(@firebase/app@0.14.12) - '@firebase/messaging-compat': 0.2.26(@firebase/app-compat@0.5.12)(@firebase/app@0.14.12) - '@firebase/performance': 0.7.12(@firebase/app@0.14.12) - '@firebase/performance-compat': 0.2.25(@firebase/app-compat@0.5.12)(@firebase/app@0.14.12) - '@firebase/remote-config': 0.8.3(@firebase/app@0.14.12) - '@firebase/remote-config-compat': 0.2.24(@firebase/app-compat@0.5.12)(@firebase/app@0.14.12) - '@firebase/storage': 0.14.3(@firebase/app@0.14.12) - '@firebase/storage-compat': 0.4.3(@firebase/app-compat@0.5.12)(@firebase/app-types@0.9.5)(@firebase/app@0.14.12) + '@firebase/firestore': 4.15.0(@firebase/app@0.14.13) + '@firebase/firestore-compat': 0.4.10(@firebase/app-compat@0.5.13)(@firebase/app-types@0.9.5)(@firebase/app@0.14.13) + '@firebase/functions': 0.13.5(@firebase/app@0.14.13) + '@firebase/functions-compat': 0.4.5(@firebase/app-compat@0.5.13)(@firebase/app@0.14.13) + '@firebase/installations': 0.6.22(@firebase/app@0.14.13) + '@firebase/installations-compat': 0.2.22(@firebase/app-compat@0.5.13)(@firebase/app-types@0.9.5)(@firebase/app@0.14.13) + '@firebase/messaging': 0.13.0(@firebase/app@0.14.13) + '@firebase/messaging-compat': 0.2.27(@firebase/app-compat@0.5.13)(@firebase/app@0.14.13) + '@firebase/performance': 0.7.12(@firebase/app@0.14.13) + '@firebase/performance-compat': 0.2.25(@firebase/app-compat@0.5.13)(@firebase/app@0.14.13) + '@firebase/remote-config': 0.8.4(@firebase/app@0.14.13) + '@firebase/remote-config-compat': 0.2.25(@firebase/app-compat@0.5.13)(@firebase/app@0.14.13) + '@firebase/storage': 0.14.3(@firebase/app@0.14.13) + '@firebase/storage-compat': 0.4.3(@firebase/app-compat@0.5.13)(@firebase/app-types@0.9.5)(@firebase/app@0.14.13) '@firebase/util': 1.15.1 transitivePeerDependencies: - '@react-native-async-storage/async-storage' @@ -16766,7 +16729,7 @@ snapshots: tslib@2.8.1: {} - tsx@4.22.3: + tsx@4.22.4: dependencies: esbuild: 0.28.0 optionalDependencies: @@ -17020,7 +16983,7 @@ snapshots: core-util-is: 1.0.2 extsprintf: 1.3.0 - vite@7.3.5(@types/node@24.12.4)(jiti@2.7.0)(less@4.6.4)(sass@1.100.0)(terser@5.48.0)(tsx@4.22.3)(yaml@2.9.0): + vite@7.3.5(@types/node@24.12.4)(jiti@2.7.0)(less@4.6.4)(sass@1.100.0)(terser@5.48.0)(tsx@4.22.4)(yaml@2.9.0): dependencies: esbuild: 0.27.7 fdir: 6.5.0(picomatch@4.0.4) @@ -17035,13 +16998,13 @@ snapshots: less: 4.6.4 sass: 1.100.0 terser: 5.48.0 - tsx: 4.22.3 + tsx: 4.22.4 yaml: 2.9.0 - vitest@4.1.8(@opentelemetry/api@1.9.1)(@types/node@24.12.4)(@vitest/coverage-v8@4.1.8)(jiti@2.7.0)(jsdom@29.1.1)(less@4.6.4)(sass@1.100.0)(terser@5.48.0)(tsx@4.22.3)(yaml@2.9.0): + vitest@4.1.8(@opentelemetry/api@1.9.1)(@types/node@24.12.4)(@vitest/coverage-v8@4.1.8)(jiti@2.7.0)(jsdom@29.1.1)(less@4.6.4)(sass@1.100.0)(terser@5.48.0)(tsx@4.22.4)(yaml@2.9.0): dependencies: '@vitest/expect': 4.1.8 - '@vitest/mocker': 4.1.8(vite@7.3.5(@types/node@24.12.4)(jiti@2.7.0)(less@4.6.4)(sass@1.100.0)(terser@5.48.0)(tsx@4.22.3)(yaml@2.9.0)) + '@vitest/mocker': 4.1.8(vite@7.3.5(@types/node@24.12.4)(jiti@2.7.0)(less@4.6.4)(sass@1.100.0)(terser@5.48.0)(tsx@4.22.4)(yaml@2.9.0)) '@vitest/pretty-format': 4.1.8 '@vitest/runner': 4.1.8 '@vitest/snapshot': 4.1.8 @@ -17058,7 +17021,7 @@ snapshots: tinyexec: 1.2.4 tinyglobby: 0.2.17 tinyrainbow: 3.1.0 - vite: 7.3.5(@types/node@24.12.4)(jiti@2.7.0)(less@4.6.4)(sass@1.100.0)(terser@5.48.0)(tsx@4.22.3)(yaml@2.9.0) + vite: 7.3.5(@types/node@24.12.4)(jiti@2.7.0)(less@4.6.4)(sass@1.100.0)(terser@5.48.0)(tsx@4.22.4)(yaml@2.9.0) why-is-node-running: 2.3.0 optionalDependencies: '@opentelemetry/api': 1.9.1 diff --git a/tests/e2e/ng-snapshot/package.json b/tests/e2e/ng-snapshot/package.json index f59c6f824c43..12f117edede2 100644 --- a/tests/e2e/ng-snapshot/package.json +++ b/tests/e2e/ng-snapshot/package.json @@ -2,21 +2,21 @@ "description": "snapshot versions of Angular for e2e testing", "private": true, "dependencies": { - "@angular/animations": "github:angular/animations-builds#936f15ea645969dcdd0ca1231b6ad42e15717d43", - "@angular/cdk": "github:angular/cdk-builds#e9f4d9cccbbb97453d691345a5b84551babaae72", - "@angular/common": "github:angular/common-builds#eb84679493b610ff5e080722fa2d17cb225880a5", - "@angular/compiler": "github:angular/compiler-builds#815a9f01619f19086210c9f52de23073b7f0f7d6", - "@angular/compiler-cli": "github:angular/compiler-cli-builds#7243a2ec83b00dbc2cd5d02aa6f88f7b98651fa9", - "@angular/core": "github:angular/core-builds#13b3c6a7b51b632df604447a6ffd471bcc75010a", - "@angular/forms": "github:angular/forms-builds#363c61e2bc92d13405ed1fd3266e74df692b1cca", - "@angular/language-service": "github:angular/language-service-builds#508cdb107e428200a42e2cab64c83dd3ef21b15d", - "@angular/localize": "github:angular/localize-builds#69da74166dbcc5e9d32edd9b39cab4364b7a42fc", - "@angular/material": "github:angular/material-builds#e4845e098d075f57eb240f4a5183f7930076f443", - "@angular/material-moment-adapter": "github:angular/material-moment-adapter-builds#db48bc7e3a1363cb9d53157f865965abd6c03283", - "@angular/platform-browser": "github:angular/platform-browser-builds#6051300fa832bbf114fede3a7aa896c0af0ace4b", - "@angular/platform-browser-dynamic": "github:angular/platform-browser-dynamic-builds#c76c84bcd994e3bc02abe00a50a3f6fa05b1bfeb", - "@angular/platform-server": "github:angular/platform-server-builds#7564dc6fdc115044d6dc2cb4a372158be2e6ceb3", - "@angular/router": "github:angular/router-builds#69dab3fb05b1ca4184667d5c26cd387b74a51352", - "@angular/service-worker": "github:angular/service-worker-builds#3eb7a1b09bf7eb7e02a845673963afe233ab0798" + "@angular/animations": "github:angular/animations-builds#f19d4bc55df72a54991fd5518bdf297daead0253", + "@angular/cdk": "github:angular/cdk-builds#15ce04718b588d3948f59052038d65e72893a3e0", + "@angular/common": "github:angular/common-builds#163d09d8b541b2e20cdc515e0e8191c7f890a366", + "@angular/compiler": "github:angular/compiler-builds#1fd7c0e72896815839a63243bdd3654cab6ec2ad", + "@angular/compiler-cli": "github:angular/compiler-cli-builds#36ae95b63ce91ff6bc56668990ee2ef9393b1a33", + "@angular/core": "github:angular/core-builds#9c24a6dc19753176a142c918722cb72b81e3ba23", + "@angular/forms": "github:angular/forms-builds#50ea33241d57a602fb788f6c86566b5c042a79c7", + "@angular/language-service": "github:angular/language-service-builds#b41df57e48290894d12a56113e06e52dbc5c5ac2", + "@angular/localize": "github:angular/localize-builds#c45916e33a8da351d980ab5ad1d1b31d1879a78c", + "@angular/material": "github:angular/material-builds#e10777f01b458d5418486306ed377dbe455f5f20", + "@angular/material-moment-adapter": "github:angular/material-moment-adapter-builds#95c30cd7636ed27f768d6f5b25117556b970a397", + "@angular/platform-browser": "github:angular/platform-browser-builds#a78c2f8434b05e3c95b55861e978e618c22d1c7e", + "@angular/platform-browser-dynamic": "github:angular/platform-browser-dynamic-builds#2a42255c688ac9aa22eab6dbdc65626b4b428a34", + "@angular/platform-server": "github:angular/platform-server-builds#209d235677e313f0a060b1eac35a11fa83b9eabe", + "@angular/router": "github:angular/router-builds#8051a26ba7b361d0756a81185bb03d166f7623b4", + "@angular/service-worker": "github:angular/service-worker-builds#d480fc85ac0ed8b47a49c52a8857f4676a308bfe" } } From 167aea1098f00e604e4b383f7d897b76bfd824de Mon Sep 17 00:00:00 2001 From: Charles Lyding <19598772+clydin@users.noreply.github.com> Date: Wed, 3 Jun 2026 18:47:20 -0400 Subject: [PATCH 021/787] fix(@angular/cli): isolate temporary package installation from parent pnpm workspace Write an empty pnpm-workspace.yaml file inside the temporary installation directory when using pnpm. This acts as a workspace boundary, preventing pnpm from searching up the directory tree and modifying the parent workspace's lockfile during ng update. --- .../src/package-managers/package-manager.ts | 77 +++++++++++++ .../package-managers/package-manager_spec.ts | 109 ++++++++++++++++++ .../src/package-managers/testing/mock-host.ts | 21 +++- .../e2e/tests/update/update-pnpm-workspace.ts | 33 ++++++ 4 files changed, 234 insertions(+), 6 deletions(-) create mode 100644 tests/e2e/tests/update/update-pnpm-workspace.ts diff --git a/packages/angular/cli/src/package-managers/package-manager.ts b/packages/angular/cli/src/package-managers/package-manager.ts index 33b8b07d48e3..46adbd118b9b 100644 --- a/packages/angular/cli/src/package-managers/package-manager.ts +++ b/packages/angular/cli/src/package-managers/package-manager.ts @@ -647,6 +647,25 @@ export class PackageManager { // Writing an empty package.json file beforehand prevents this. await this.host.writeFile(join(workingDirectory, 'package.json'), '{}'); + // To prevent pnpm from traversing up the directory tree and modifying the project's workspace lockfile, + // copy the project's `pnpm-workspace.yaml` (excluding monorepo local overrides/packages) + // to the temporary directory if it exists, or write an empty one to act as a workspace boundary. + if (this.name === 'pnpm') { + try { + const workspaceConfigPath = join(this.cwd, 'pnpm-workspace.yaml'); + const content = await this.host.readFile(workspaceConfigPath); + await this.host.writeFile( + join(workingDirectory, 'pnpm-workspace.yaml'), + sanitizePnpmWorkspace(content), + ); + } catch { + await this.host.writeFile( + join(workingDirectory, 'pnpm-workspace.yaml'), + "packages:\n - '.'\n", + ); + } + } + // Copy configuration files if the package manager requires it (e.g., bun). if (this.descriptor.copyConfigFromProject) { for (const configFile of this.descriptor.configFiles) { @@ -675,3 +694,61 @@ export class PackageManager { return { workingDirectory, cleanup }; } } + +/** + * Sanitizes a `pnpm-workspace.yaml` file content to be safely used inside + * a temporary installation directory. + * + * This function removes monorepo-specific settings that would fail or cause + * unintended behaviors in a standalone, temporary project environment: + * 1. Removes the `overrides:` block, as it may contain `workspace:` protocol + * resolutions which cannot be resolved in a standalone folder. + * 2. Rewrites the `packages:` block to include only the current directory (`'.'`), + * isolating the temporary installation from other projects in the monorepo. + * + * All other settings (such as `minimumReleaseAge`, package extensions, etc.) + * are preserved intact. + * + * @param content The original `pnpm-workspace.yaml` content. + * @returns The sanitized YAML content. + */ +function sanitizePnpmWorkspace(content: string): string { + const lines = content.split(/\r?\n/); + const result: string[] = []; + let inBlockToRemove = false; + let blockIndent = 0; + + for (const line of lines) { + const trimmed = line.trim(); + if (!trimmed) { + result.push(line); + continue; + } + + // Determine the current line's indentation level. + const indent = line.length - line.trimStart().length; + + // If we are currently parsing a block to remove, skip any lines with larger indentation. + if (inBlockToRemove) { + if (indent > blockIndent) { + continue; + } + inBlockToRemove = false; + } + + // Identify blocks we want to remove or customize (e.g. 'overrides' or 'packages'). + if (trimmed.startsWith('overrides:') || trimmed.startsWith('packages:')) { + inBlockToRemove = true; + blockIndent = indent; + if (trimmed.startsWith('packages:')) { + // Replace packages list to restrict it strictly to the current standalone folder. + result.push(line.replace(/packages:.*/, "packages:\n - '.'")); + } + continue; + } + + result.push(line); + } + + return result.join('\n'); +} diff --git a/packages/angular/cli/src/package-managers/package-manager_spec.ts b/packages/angular/cli/src/package-managers/package-manager_spec.ts index 8d439d9b3b75..176b604eeca6 100644 --- a/packages/angular/cli/src/package-managers/package-manager_spec.ts +++ b/packages/angular/cli/src/package-managers/package-manager_spec.ts @@ -86,6 +86,115 @@ describe('PackageManager', () => { }); }); + describe('acquireTempPackage', () => { + it('should copy and sanitize pnpm-workspace.yaml when package manager is pnpm and workspace file exists', async () => { + const pnpmDescriptor = SUPPORTED_PACKAGE_MANAGERS['pnpm']; + const testHost = new MockHost({ '/tmp/project/node_modules': true }); + const pm = new PackageManager(testHost, '/tmp/project', pnpmDescriptor); + + const createTempDirectorySpy = spyOn(testHost, 'createTempDirectory').and.resolveTo( + '/tmp/project/node_modules/angular-cli-tmp-packages-abc', + ); + const mockWorkspaceContent = [ + 'packages:', + ' - .', + ' - packages/*', + 'minimumReleaseAge: 1440', + 'minimumReleaseAgeExclude:', + " - '@angular/*'", + 'overrides:', + " '@angular/build': workspace:*", + 'packageExtensions:', + ' vitest:', + ' peerDependencies:', + " '@vitest/coverage-v8': '*'", + ].join('\n'); + const readFileSpy = spyOn(testHost, 'readFile').and.resolveTo(mockWorkspaceContent); + const writeFileSpy = spyOn(testHost, 'writeFile').and.resolveTo(); + spyOn(testHost, 'runCommand').and.resolveTo({ stdout: '', stderr: '' }); + + const { workingDirectory } = await pm.acquireTempPackage('foo@1.0.0'); + + expect(workingDirectory).toBe('/tmp/project/node_modules/angular-cli-tmp-packages-abc'); + expect(createTempDirectorySpy).toHaveBeenCalledWith('/tmp/project/node_modules'); + expect(readFileSpy).toHaveBeenCalledWith('/tmp/project/pnpm-workspace.yaml'); + + const expectedSanitizedContent = [ + 'packages:', + " - '.'", + 'minimumReleaseAge: 1440', + 'minimumReleaseAgeExclude:', + " - '@angular/*'", + 'packageExtensions:', + ' vitest:', + ' peerDependencies:', + " '@vitest/coverage-v8': '*'", + ].join('\n'); + expect(writeFileSpy).toHaveBeenCalledWith( + '/tmp/project/node_modules/angular-cli-tmp-packages-abc/pnpm-workspace.yaml', + expectedSanitizedContent, + ); + expect(writeFileSpy).toHaveBeenCalledWith( + '/tmp/project/node_modules/angular-cli-tmp-packages-abc/package.json', + '{}', + ); + }); + + it('should write empty pnpm-workspace.yaml as fallback when package manager is pnpm and workspace file does not exist', async () => { + const pnpmDescriptor = SUPPORTED_PACKAGE_MANAGERS['pnpm']; + const testHost = new MockHost({ '/tmp/project/node_modules': true }); + const pm = new PackageManager(testHost, '/tmp/project', pnpmDescriptor); + + const createTempDirectorySpy = spyOn(testHost, 'createTempDirectory').and.resolveTo( + '/tmp/project/node_modules/angular-cli-tmp-packages-abc', + ); + const readFileSpy = spyOn(testHost, 'readFile').and.throwError( + new Error('ENOENT: no such file or directory'), + ); + const writeFileSpy = spyOn(testHost, 'writeFile').and.resolveTo(); + spyOn(testHost, 'runCommand').and.resolveTo({ stdout: '', stderr: '' }); + + const { workingDirectory } = await pm.acquireTempPackage('foo@1.0.0'); + + expect(workingDirectory).toBe('/tmp/project/node_modules/angular-cli-tmp-packages-abc'); + expect(createTempDirectorySpy).toHaveBeenCalledWith('/tmp/project/node_modules'); + expect(readFileSpy).toHaveBeenCalledWith('/tmp/project/pnpm-workspace.yaml'); + expect(writeFileSpy).toHaveBeenCalledWith( + '/tmp/project/node_modules/angular-cli-tmp-packages-abc/package.json', + '{}', + ); + expect(writeFileSpy).toHaveBeenCalledWith( + '/tmp/project/node_modules/angular-cli-tmp-packages-abc/pnpm-workspace.yaml', + "packages:\n - '.'\n", + ); + }); + + it('should NOT write pnpm-workspace.yaml when package manager is npm', async () => { + const npmDescriptor = SUPPORTED_PACKAGE_MANAGERS['npm']; + const testHost = new MockHost({ '/tmp/project/node_modules': true }); + const pm = new PackageManager(testHost, '/tmp/project', npmDescriptor); + + const createTempDirectorySpy = spyOn(testHost, 'createTempDirectory').and.resolveTo( + '/tmp/project/node_modules/angular-cli-tmp-packages-abc', + ); + const writeFileSpy = spyOn(testHost, 'writeFile').and.resolveTo(); + spyOn(testHost, 'runCommand').and.resolveTo({ stdout: '', stderr: '' }); + + const { workingDirectory } = await pm.acquireTempPackage('foo@1.0.0'); + + expect(workingDirectory).toBe('/tmp/project/node_modules/angular-cli-tmp-packages-abc'); + expect(createTempDirectorySpy).toHaveBeenCalledWith('/tmp/project/node_modules'); + expect(writeFileSpy).toHaveBeenCalledWith( + '/tmp/project/node_modules/angular-cli-tmp-packages-abc/package.json', + '{}', + ); + expect(writeFileSpy).not.toHaveBeenCalledWith( + '/tmp/project/node_modules/angular-cli-tmp-packages-abc/pnpm-workspace.yaml', + '', + ); + }); + }); + describe('initializationError', () => { it('should throw initializationError when running commands', async () => { const error = new Error('Not installed'); diff --git a/packages/angular/cli/src/package-managers/testing/mock-host.ts b/packages/angular/cli/src/package-managers/testing/mock-host.ts index 46e71be3cf60..9051cfae3b04 100644 --- a/packages/angular/cli/src/package-managers/testing/mock-host.ts +++ b/packages/angular/cli/src/package-managers/testing/mock-host.ts @@ -51,27 +51,36 @@ export class MockHost implements Host { } as Stats); } - runCommand(): Promise<{ stdout: string; stderr: string }> { + runCommand( + command: string, + args: readonly string[], + options?: { + timeout?: number; + stdio?: 'pipe' | 'ignore'; + cwd?: string; + env?: Record; + }, + ): Promise<{ stdout: string; stderr: string }> { throw new Error('Method not implemented.'); } - createTempDirectory(): Promise { + createTempDirectory(baseDir?: string): Promise { throw new Error('Method not implemented.'); } - deleteDirectory(): Promise { + deleteDirectory(path: string): Promise { throw new Error('Method not implemented.'); } - writeFile(): Promise { + writeFile(path: string, content: string): Promise { throw new Error('Method not implemented.'); } - readFile(): Promise { + readFile(path: string): Promise { throw new Error('Method not implemented.'); } - copyFile(): Promise { + copyFile(src: string, dest: string): Promise { throw new Error('Method not implemented.'); } } diff --git a/tests/e2e/tests/update/update-pnpm-workspace.ts b/tests/e2e/tests/update/update-pnpm-workspace.ts new file mode 100644 index 000000000000..29aff7bff42a --- /dev/null +++ b/tests/e2e/tests/update/update-pnpm-workspace.ts @@ -0,0 +1,33 @@ +import { createProjectFromAsset } from '../../utils/assets'; +import { readFile, writeFile } from '../../utils/fs'; +import { getActivePackageManager } from '../../utils/packages'; +import { ng } from '../../utils/process'; + +export default async function () { + if (getActivePackageManager() !== 'pnpm') { + return; + } + + let restoreRegistry: (() => Promise) | undefined; + + try { + // Setup project from older asset using the public registry + restoreRegistry = await createProjectFromAsset('20.0-project', true); + + // Create pnpm-workspace.yaml inside the project directory + await writeFile('pnpm-workspace.yaml', "packages:\n - '.'\n"); + + // Run ng update on @angular/cli to trigger the update from version 20 to the next major version + await ng('update', '@angular/cli@21', '@angular/core@21'); + + // Verify that the pnpm lockfile does not contain references to the temporary package directory + const lockfileContent = await readFile('pnpm-lock.yaml'); + if (lockfileContent.includes('angular-cli-tmp-packages-')) { + throw new Error( + 'pnpm-lock.yaml contains reference to temporary package directory, isolation failed!', + ); + } + } finally { + await restoreRegistry?.(); + } +} From b0dcf00eca7429000c376a0812df94310ab0fc45 Mon Sep 17 00:00:00 2001 From: Charles Lyding <19598772+clydin@users.noreply.github.com> Date: Mon, 8 Jun 2026 13:13:34 -0400 Subject: [PATCH 022/787] refactor(@angular/cli): move update version resolution directly to CLI command Removes the @schematics/update:update schematic and moves the package version resolution, group expansion, and peer dependency validation logic directly into the CLI's update command. This simplifies the command execution flow, eliminates sharing state via global variables, and enables direct unit testing of the resolution plan in isolated temporary directories without host monorepo package leakage. --- packages/angular/cli/BUILD.bazel | 7 - .../angular/cli/src/commands/update/cli.ts | 251 ++-- .../commands/update/schematic/collection.json | 9 - .../src/commands/update/schematic/index.ts | 1128 ----------------- .../commands/update/schematic/index_spec.ts | 391 ------ .../src/commands/update/schematic/schema.json | 68 - .../src/commands/update/update-resolver.ts | 1028 +++++++++++++++ .../commands/update/update-resolver_spec.ts | 230 ++++ 8 files changed, 1373 insertions(+), 1739 deletions(-) delete mode 100644 packages/angular/cli/src/commands/update/schematic/collection.json delete mode 100644 packages/angular/cli/src/commands/update/schematic/index.ts delete mode 100644 packages/angular/cli/src/commands/update/schematic/index_spec.ts delete mode 100644 packages/angular/cli/src/commands/update/schematic/schema.json create mode 100644 packages/angular/cli/src/commands/update/update-resolver.ts create mode 100644 packages/angular/cli/src/commands/update/update-resolver_spec.ts diff --git a/packages/angular/cli/BUILD.bazel b/packages/angular/cli/BUILD.bazel index eed9ad7360f1..b73ed5fba5fe 100644 --- a/packages/angular/cli/BUILD.bazel +++ b/packages/angular/cli/BUILD.bazel @@ -29,7 +29,6 @@ RUNTIME_ASSETS = glob( include = [ "bin/**/*", "src/**/*.md", - "src/**/*.json", ], exclude = [ "lib/config/workspace-schema.json", @@ -53,7 +52,6 @@ ts_project( ) + [ # These files are generated from the JSON schema "//packages/angular/cli:lib/config/workspace-schema.ts", - "//packages/angular/cli:src/commands/update/schematic/schema.ts", ], data = RUNTIME_ASSETS, deps = [ @@ -105,11 +103,6 @@ ts_json_schema( data = CLI_SCHEMA_DATA, ) -ts_json_schema( - name = "update_schematic_schema", - src = "src/commands/update/schematic/schema.json", -) - ts_project( name = "angular-cli_test_lib", testonly = True, diff --git a/packages/angular/cli/src/commands/update/cli.ts b/packages/angular/cli/src/commands/update/cli.ts index 62416b1c1ee7..447782da0616 100644 --- a/packages/angular/cli/src/commands/update/cli.ts +++ b/packages/angular/cli/src/commands/update/cli.ts @@ -24,6 +24,13 @@ import type { InstalledPackage, PackageManager, PackageManifest } from '../../pa import { colors } from '../../utilities/color'; import { disableVersionCheck } from '../../utilities/environment-options'; import { assertIsError } from '../../utilities/error'; +import { + UpdatePlan, + applyUpdatePlan, + findPackageJson, + printUpdateUsageMessage, + resolveUserUpdatePlan, +} from './update-resolver'; import { checkCLIVersion, coerceVersionNumber, @@ -32,12 +39,7 @@ import { } from './utilities/cli-version'; import { ANGULAR_PACKAGES_REGEXP } from './utilities/constants'; import { checkCleanGit } from './utilities/git'; -import { - commitChanges, - executeMigration, - executeMigrations, - executeSchematic, -} from './utilities/migration'; +import { commitChanges, executeMigration, executeMigrations } from './utilities/migration'; interface UpdateCommandArgs { packages?: string[]; @@ -54,8 +56,6 @@ interface UpdateCommandArgs { class CommandError extends Error {} -const UPDATE_SCHEMATIC_COLLECTION = path.join(__dirname, 'schematic/collection.json'); - export default class UpdateCommandModule extends CommandModule { override scope = CommandScope.In; protected override shouldReportAnalytics = false; @@ -244,23 +244,28 @@ export default class UpdateCommandModule extends CommandModule string); - -// Angular guarantees that a major is compatible with its following major (so packages that depend -// on Angular 5 are also compatible with Angular 6). This is, in code, represented by verifying -// that all other packages that have a peer dependency of `"@angular/core": "^5.0.0"` actually -// supports 6.0, by adding that compatibility to the range, so it is `^5.0.0 || ^6.0.0`. -// We export it to allow for testing. -export function angularMajorCompatGuarantee(range: string) { - let newRange = semver.validRange(range); - if (!newRange) { - return range; - } - let major = 1; - while (!semver.gtr(major + '.0.0', newRange)) { - major++; - if (major >= 99) { - // Use original range if it supports a major this high - // Range is most likely unbounded (e.g., >=5.0.0) - return newRange; - } - } - - // Add the major version as compatible with the angular compatible, with all minors. This is - // already one major above the greatest supported, because we increment `major` before checking. - // We add minors like this because a minor beta is still compatible with a minor non-beta. - newRange = range; - for (let minor = 0; minor < 20; minor++) { - newRange += ` || ^${major}.${minor}.0-alpha.0 `; - } - - return semver.validRange(newRange) || range; -} - -// This is a map of packageGroupName to range extending function. If it isn't found, the range is -// kept the same. -const knownPeerCompatibleList: { [name: string]: PeerVersionTransform } = { - '@angular/core': angularMajorCompatGuarantee, -}; - -interface PackageVersionInfo { - version: VersionRange; - packageJson: PackageManifest; - updateMetadata: UpdateMetadata; -} - -interface PackageInfo { - name: string; - npmPackageJson: NpmRepositoryPackageJson; - installed: PackageVersionInfo; - target?: PackageVersionInfo; - packageJsonRange: string; -} - -interface UpdateMetadata { - packageGroupName?: string; - packageGroup: { [packageName: string]: string }; - requirements: { [packageName: string]: string }; - migrations?: string; -} - -function _updatePeerVersion(infoMap: Map, name: string, range: string) { - // Resolve packageGroupName. - const maybePackageInfo = infoMap.get(name); - if (!maybePackageInfo) { - return range; - } - if (maybePackageInfo.target) { - name = maybePackageInfo.target.updateMetadata.packageGroupName || name; - } else { - name = maybePackageInfo.installed.updateMetadata.packageGroupName || name; - } - - const maybeTransform = knownPeerCompatibleList[name]; - if (maybeTransform) { - if (typeof maybeTransform == 'function') { - return maybeTransform(range); - } else { - return maybeTransform; - } - } - - return range; -} - -function _validateForwardPeerDependencies( - name: string, - infoMap: Map, - peers: { [name: string]: string }, - peersMeta: { [name: string]: { optional?: boolean } }, - logger: logging.LoggerApi, - next: boolean, -): boolean { - let validationFailed = false; - for (const [peer, range] of Object.entries(peers)) { - logger.debug(`Checking forward peer ${peer}...`); - const maybePeerInfo = infoMap.get(peer); - const isOptional = peersMeta[peer] && !!peersMeta[peer].optional; - if (!maybePeerInfo) { - if (!isOptional) { - logger.warn( - [ - `Package ${JSON.stringify(name)} has a missing peer dependency of`, - `${JSON.stringify(peer)} @ ${JSON.stringify(range)}.`, - ].join(' '), - ); - } - - continue; - } - - const peerVersion = - maybePeerInfo.target && maybePeerInfo.target.packageJson.version - ? maybePeerInfo.target.packageJson.version - : maybePeerInfo.installed.version; - - logger.debug(` Range intersects(${range}, ${peerVersion})...`); - if (!semver.satisfies(peerVersion, range, { includePrerelease: next || undefined })) { - logger.error( - [ - `Package ${JSON.stringify(name)} has an incompatible peer dependency to`, - `${JSON.stringify(peer)} (requires ${JSON.stringify(range)},`, - `would install ${JSON.stringify(peerVersion)})`, - ].join(' '), - ); - - validationFailed = true; - continue; - } - } - - return validationFailed; -} - -function _validateReversePeerDependencies( - name: string, - version: string, - infoMap: Map, - logger: logging.LoggerApi, - next: boolean, -) { - for (const [installed, installedInfo] of infoMap.entries()) { - const installedLogger = logger.createChild(installed); - installedLogger.debug(`${installed}...`); - const peers = (installedInfo.target || installedInfo.installed).packageJson.peerDependencies; - - for (const [peer, range] of Object.entries(peers || {})) { - if (peer != name) { - // Only check peers to the packages we're updating. We don't care about peers - // that are unmet but we have no effect on. - continue; - } - - // Ignore peerDependency mismatches for these packages. - // They are deprecated and removed via a migration. - const ignoredPackages = [ - 'codelyzer', - '@schematics/update', - '@angular-devkit/build-ng-packagr', - 'tsickle', - '@nguniversal/builders', - ]; - if (ignoredPackages.includes(installed)) { - continue; - } - - // Override the peer version range if it's known as a compatible. - const extendedRange = _updatePeerVersion(infoMap, peer, range); - - if (!semver.satisfies(version, extendedRange, { includePrerelease: next || undefined })) { - logger.error( - [ - `Package ${JSON.stringify(installed)} has an incompatible peer dependency to`, - `${JSON.stringify(name)} (requires`, - `${JSON.stringify(range)}${extendedRange == range ? '' : ' (extended)'},`, - `would install ${JSON.stringify(version)}).`, - ].join(' '), - ); - - return true; - } - } - } - - return false; -} - -function _validateUpdatePackages( - infoMap: Map, - force: boolean, - next: boolean, - logger: logging.LoggerApi, -): void { - logger.debug('Updating the following packages:'); - infoMap.forEach((info) => { - if (info.target) { - logger.debug(` ${info.name} => ${info.target.version}`); - } - }); - - let peerErrors = false; - infoMap.forEach((info) => { - const { name, target } = info; - if (!target) { - return; - } - - const pkgLogger = logger.createChild(name); - logger.debug(`${name}...`); - - const { peerDependencies = {}, peerDependenciesMeta = {} } = target.packageJson; - peerErrors = - _validateForwardPeerDependencies( - name, - infoMap, - peerDependencies, - peerDependenciesMeta, - pkgLogger, - next, - ) || peerErrors; - peerErrors = - _validateReversePeerDependencies(name, target.version, infoMap, pkgLogger, next) || - peerErrors; - }); - - if (!force && peerErrors) { - throw new SchematicsException( - 'Incompatible peer dependencies found.\n' + - 'Peer dependency warnings when installing dependencies means that those dependencies might not work correctly together.\n' + - `You can use the '--force' option to ignore incompatible peer dependencies and instead address these warnings later.`, - ); - } -} - -function _performUpdate( - tree: Tree, - context: SchematicContext, - infoMap: Map, - logger: logging.LoggerApi, - migrateOnly: boolean, -): void { - const packageJsonContent = tree.read('/package.json')?.toString(); - if (!packageJsonContent) { - throw new SchematicsException('Could not find a package.json. Are you in a Node project?'); - } - - const packageJson = tree.readJson('/package.json') as PackageManifest; - - const updateDependency = (deps: Record, name: string, newVersion: string) => { - const oldVersion = deps[name]; - // We only respect caret and tilde ranges on update. - const execResult = /^[\^~]/.exec(oldVersion); - deps[name] = `${execResult ? execResult[0] : ''}${newVersion}`; - }; - - const toInstall = [...infoMap.values()] - .map((x) => [x.name, x.target, x.installed]) - .filter(([name, target, installed]) => { - return !!name && !!target && !!installed; - }) as [string, PackageVersionInfo, PackageVersionInfo][]; - - toInstall.forEach(([name, target, installed]) => { - logger.info( - `Updating package.json with dependency ${name} ` + - `@ ${JSON.stringify(target.version)} (was ${JSON.stringify(installed.version)})...`, - ); - - if (packageJson.dependencies && packageJson.dependencies[name]) { - updateDependency(packageJson.dependencies, name, target.version); - - if (packageJson.devDependencies && packageJson.devDependencies[name]) { - delete packageJson.devDependencies[name]; - } - if (packageJson.peerDependencies && packageJson.peerDependencies[name]) { - delete packageJson.peerDependencies[name]; - } - } else if (packageJson.devDependencies && packageJson.devDependencies[name]) { - updateDependency(packageJson.devDependencies, name, target.version); - - if (packageJson.peerDependencies && packageJson.peerDependencies[name]) { - delete packageJson.peerDependencies[name]; - } - } else if (packageJson.peerDependencies && packageJson.peerDependencies[name]) { - updateDependency(packageJson.peerDependencies, name, target.version); - } else { - logger.warn(`Package ${name} was not found in dependencies.`); - } - }); - const eofMatches = packageJsonContent.match(/\r?\n$/); - const eof = eofMatches?.[0] ?? ''; - const newContent = JSON.stringify(packageJson, null, 2) + eof; - if (packageJsonContent != newContent || migrateOnly) { - if (!migrateOnly) { - tree.overwrite('/package.json', newContent); - } - - const externalMigrations: {}[] = []; - - // Run the migrate schematics with the list of packages to use. The collection contains - // version information and we need to do this post installation. Please note that the - // migration COULD fail and leave side effects on disk. - // Run the schematics task of those packages. - toInstall.forEach(([name, target, installed]) => { - if (!target.updateMetadata.migrations) { - return; - } - - externalMigrations.push({ - package: name, - collection: target.updateMetadata.migrations, - from: installed.version, - to: target.version, - }); - - return; - }); - - if (externalMigrations.length > 0) { - // eslint-disable-next-line @typescript-eslint/no-explicit-any - (global as any).externalMigrations = externalMigrations; - } - } -} - -function _getUpdateMetadata( - packageJson: PackageManifest, - logger: logging.LoggerApi, -): UpdateMetadata { - const metadata = packageJson['ng-update']; - - const result: UpdateMetadata = { - packageGroup: {}, - requirements: {}, - }; - - if (!metadata || typeof metadata != 'object' || Array.isArray(metadata)) { - return result; - } - - if (metadata['packageGroup']) { - const packageGroup = metadata['packageGroup']; - // Verify that packageGroup is an array of strings or an map of versions. This is not an error - // but we still warn the user and ignore the packageGroup keys. - if (Array.isArray(packageGroup) && packageGroup.every((x) => typeof x == 'string')) { - result.packageGroup = packageGroup.reduce((group, name) => { - group[name] = packageJson.version; - - return group; - }, result.packageGroup); - } else if ( - typeof packageGroup == 'object' && - packageGroup && - !Array.isArray(packageGroup) && - Object.values(packageGroup).every((x) => typeof x == 'string') - ) { - result.packageGroup = packageGroup; - } else { - logger.warn(`packageGroup metadata of package ${packageJson.name} is malformed. Ignoring.`); - } - - result.packageGroupName = Object.keys(result.packageGroup)[0]; - } - - if (typeof metadata['packageGroupName'] == 'string') { - result.packageGroupName = metadata['packageGroupName']; - } - - if (metadata['migrations']) { - const migrations = metadata['migrations']; - if (typeof migrations != 'string') { - logger.warn(`migrations metadata of package ${packageJson.name} is malformed. Ignoring.`); - } else { - result.migrations = migrations; - } - } - - return result; -} - -function _usageMessage( - options: UpdateSchema, - infoMap: Map, - logger: logging.LoggerApi, -) { - const packageGroups = new Map(); - const packagesToUpdate = [...infoMap.entries()] - .map(([name, info]) => { - const distTags = info.npmPackageJson['dist-tags'] ?? {}; - let tag = options.next ? (distTags['next'] ? 'next' : 'latest') : 'latest'; - let version = distTags[tag] ?? info.installed.version; - const versions = info.npmPackageJson.versions ?? {}; - let target = versions[version]; - - const versionDiff = semver.diff(info.installed.version, version); - if ( - versionDiff !== 'patch' && - versionDiff !== 'minor' && - /^@(?:angular|nguniversal)\//.test(name) - ) { - const installedMajorVersion = semver.parse(info.installed.version)?.major; - const toInstallMajorVersion = semver.parse(version)?.major; - if ( - installedMajorVersion !== undefined && - toInstallMajorVersion !== undefined && - installedMajorVersion < toInstallMajorVersion - 1 - ) { - const nextMajorVersion = `${installedMajorVersion + 1}.`; - const nextMajorVersions = Object.keys(versions) - .filter((v) => v.startsWith(nextMajorVersion)) - .sort((a, b) => (a > b ? -1 : 1)); - - if (nextMajorVersions.length) { - version = nextMajorVersions[0]; - target = versions[version]; - tag = ''; - } - } - } - - return { - name, - info, - version, - tag, - target, - }; - }) - .filter( - ({ info, version, target }) => - target?.['ng-update'] && semver.compare(info.installed.version, version) < 0, - ) - .map(({ name, info, version, tag, target }) => { - // Look for packageGroup. - const ngUpdate = target['ng-update']; - const packageGroup = ngUpdate?.['packageGroup']; - if (packageGroup) { - const packageGroupNames = Array.isArray(packageGroup) - ? packageGroup - : Object.keys(packageGroup); - const packageGroupName = - ngUpdate?.['packageGroupName'] || packageGroupNames.find((n) => infoMap.has(n)); - - if (packageGroupName) { - if (packageGroups.has(name)) { - return null; - } - - for (const groupName of packageGroupNames) { - packageGroups.set(groupName, packageGroupName); - } - - packageGroups.set(packageGroupName, packageGroupName); - name = packageGroupName; - } - } - - let command = `ng update ${name}`; - if (!tag) { - command += `@${semver.parse(version)?.major || version}`; - } else if (tag == 'next') { - command += ' --next'; - } - - return [name, `${info.installed.version} -> ${version} `, command]; - }) - .filter((x) => x !== null) - .sort((a, b) => (a && b ? a[0].localeCompare(b[0]) : 0)); - - if (packagesToUpdate.length == 0) { - logger.info('We analyzed your package.json and everything seems to be in order. Good work!'); - - return; - } - - logger.info('We analyzed your package.json, there are some packages to update:\n'); - - // Find the largest name to know the padding needed. - let namePad = Math.max(...[...infoMap.keys()].map((x) => x.length)) + 2; - if (!Number.isFinite(namePad)) { - namePad = 30; - } - const pads = [namePad, 25, 0]; - - logger.info( - ' ' + ['Name', 'Version', 'Command to update'].map((x, i) => x.padEnd(pads[i])).join(''), - ); - - const totalWidth = pads.reduce((sum, width) => sum + width, 20); - logger.info(` ${'-'.repeat(totalWidth)}`); - - packagesToUpdate.forEach((fields) => { - if (!fields) { - return; - } - - logger.info(' ' + fields.map((x, i) => x.padEnd(pads[i])).join('')); - }); - - logger.info( - `\nThere might be additional packages which don't provide 'ng update' capabilities that are outdated.\n` + - `You can update the additional packages by running the update command of your package manager.`, - ); - - return; -} - -/** - * Resolves a semver range or npm dist-tag to a specific version based on the package's registry metadata. - * It prioritizes non-deprecated versions and handles fallback to deprecated versions if necessary. - * - * @private - */ -function resolvePackageVersion( - metadata: NpmRepositoryPackageJson, - range: string, - next = false, -): string | null { - // Check if range matches an npm dist-tag directly (e.g. "latest", "next") - const distTags = metadata['dist-tags'] ?? {}; - if (distTags[range]) { - return distTags[range]; - } - // If 'next' is requested (e.g. via the --next CLI flag) but the package doesn't publish - // a 'next' pre-release tag, fallback to 'latest'. - if (range === 'next') { - return distTags['latest'] ?? null; - } - - // Split deprecated and non-deprecated versions from registry metadata - const packageVersionsNonDeprecated: string[] = []; - const packageVersionsDeprecated: string[] = []; - for (const [v, { deprecated }] of Object.entries(metadata.versions ?? {})) { - if (deprecated) { - packageVersionsDeprecated.push(v); - } else { - packageVersionsNonDeprecated.push(v); - } - } - - // Find the highest satisfying version, prioritizing non-deprecated versions - return ( - semver.maxSatisfying(packageVersionsNonDeprecated, range, { - includePrerelease: next || undefined, - }) ?? - semver.maxSatisfying(packageVersionsDeprecated, range, { - includePrerelease: next || undefined, - }) - ); -} - -/** - * Checks if Yarn Plug'n'Play is active in the current workspace. - * - * @private - */ -function isPnpActive(workspaceRoot: string): boolean { - return ( - process.versions.pnp !== undefined || - existsSync(path.join(workspaceRoot, '.pnp.cjs')) || - existsSync(path.join(workspaceRoot, '.pnp.js')) - ); -} - -/** - * Resolves and reads the installed package.json manifest for a package. - * It checks the virtual schematic Tree first (vital for unit tests/mocks), - * and falls back to physical disk resolution using createRequire only if Yarn PnP is active. - * - * @private - */ -function getInstalledPackageJson( - tree: Tree, - packageName: string, - workspaceRoot: string, -): PackageManifest | null { - // First, check the virtual tree (critical for testing mocks) - const pkgJsonPath = `/node_modules/${packageName}/package.json`; - if (tree.exists(pkgJsonPath)) { - try { - return tree.readJson(pkgJsonPath) as PackageManifest; - } catch {} - } - - // In Yarn PnP, mock package trees are not written to node_modules in the virtual tree, - // so we resolve the manifest physically from Yarn's zip cache via createRequire. - // Note: This fallback resolution is strictly gated on Yarn PnP being active. Because schematics - // operate on a virtual file system (Tree), running disk lookups in non-PnP - // environments could cause tests to resolve dependencies from this monorepo's own node_modules - // instead of the simulated virtual file system. - if (isPnpActive(workspaceRoot)) { - try { - const workspaceRequire = createRequire(path.join(workspaceRoot, 'package.json')); - const manifestPath = workspaceRequire.resolve(`${packageName}/package.json`); - const content = readFileSync(manifestPath, 'utf8'); - - return JSON.parse(content) as PackageManifest; - } catch {} - } - - return null; -} - -function getInstalledVersion( - tree: Tree, - packageName: string, - workspaceRoot: string, -): string | null { - const pkgJson = getInstalledPackageJson(tree, packageName, workspaceRoot); - - return pkgJson?.version ?? null; -} - -function _buildLocalPackageInfo( - tree: Tree, - name: string, - allDependencies: ReadonlyMap, - workspaceRoot: string, - logger: logging.LoggerApi, -): PackageInfo { - const packageJsonRange = allDependencies.get(name); - if (!packageJsonRange) { - throw new SchematicsException(`Package ${JSON.stringify(name)} was not found in package.json.`); - } - - const localPkgJson = getInstalledPackageJson(tree, name, workspaceRoot); - if (!localPkgJson) { - throw new SchematicsException(`Package ${name} is not installed.`); - } - - return { - name, - npmPackageJson: {} as NpmRepositoryPackageJson, - installed: { - version: localPkgJson.version as VersionRange, - packageJson: localPkgJson, - updateMetadata: _getUpdateMetadata(localPkgJson, logger), - }, - packageJsonRange, - }; -} - -function _buildPackageInfo( - tree: Tree, - packages: Map, - allDependencies: ReadonlyMap, - npmPackageJson: NpmRepositoryPackageJson, - workspaceRoot: string, - logger: logging.LoggerApi, -): PackageInfo { - const name = npmPackageJson.name; - const packageJsonRange = allDependencies.get(name); - if (!packageJsonRange) { - throw new SchematicsException(`Package ${JSON.stringify(name)} was not found in package.json.`); - } - - const localPkgJson = getInstalledPackageJson(tree, name, workspaceRoot); - let installedVersion = localPkgJson?.version; - - const packageVersionsNonDeprecated: string[] = []; - const packageVersionsDeprecated: string[] = []; - - for (const [version, { deprecated }] of Object.entries(npmPackageJson.versions ?? {})) { - if (deprecated) { - packageVersionsDeprecated.push(version); - } else { - packageVersionsNonDeprecated.push(version); - } - } - - const findSatisfyingVersion = (targetVersion: VersionRange): VersionRange | undefined => - ((semver.maxSatisfying(packageVersionsNonDeprecated, targetVersion) ?? - semver.maxSatisfying(packageVersionsDeprecated, targetVersion)) as VersionRange | null) ?? - undefined; - - if (!installedVersion) { - // Find the version from NPM that fits the range to max. - installedVersion = findSatisfyingVersion(packageJsonRange); - } - - if (!installedVersion) { - throw new SchematicsException( - `An unexpected error happened; could not determine version for package ${name}.`, - ); - } - - const versions = npmPackageJson.versions ?? {}; - const installedPackageJson = versions[installedVersion] || localPkgJson; - if (!installedPackageJson) { - throw new SchematicsException( - `An unexpected error happened; package ${name} has no version ${installedVersion}.`, - ); - } - - let targetVersion: VersionRange | undefined = packages.get(name); - if (targetVersion) { - const distTags = npmPackageJson['dist-tags'] ?? {}; - if (distTags[targetVersion]) { - targetVersion = distTags[targetVersion] as VersionRange; - } else if (targetVersion == 'next') { - targetVersion = distTags['latest'] as VersionRange; - } else { - targetVersion = findSatisfyingVersion(targetVersion); - } - } - - if (targetVersion && semver.lte(targetVersion, installedVersion)) { - logger.debug(`Package ${name} already satisfied by package.json (${packageJsonRange}).`); - targetVersion = undefined; - } - - const target: PackageVersionInfo | undefined = targetVersion - ? { - version: targetVersion, - packageJson: versions[targetVersion], - updateMetadata: _getUpdateMetadata(versions[targetVersion], logger), - } - : undefined; - - return { - name, - npmPackageJson, - installed: { - version: installedVersion as VersionRange, - packageJson: installedPackageJson as PackageManifest, - updateMetadata: _getUpdateMetadata(installedPackageJson as PackageManifest, logger), - }, - target, - packageJsonRange, - }; -} - -function _buildPackageList( - options: UpdateSchema, - projectDeps: Map, - logger: logging.LoggerApi, -): Map { - // Parse the packages options to set the targeted version. - const packages = new Map(); - const commandLinePackages = - options.packages && options.packages.length > 0 ? options.packages : []; - - for (const pkg of commandLinePackages) { - // Split the version asked on command line. - const m = pkg.match(/^((?:@[^/]{1,100}\/)?[^@]{1,100})(?:@(.{1,100}))?$/); - if (!m) { - logger.warn(`Invalid package argument: ${JSON.stringify(pkg)}. Skipping.`); - continue; - } - - const [, npmName, maybeVersion] = m; - - const version = projectDeps.get(npmName); - if (!version) { - logger.warn(`Package not installed: ${JSON.stringify(npmName)}. Skipping.`); - continue; - } - - packages.set(npmName, (maybeVersion || (options.next ? 'next' : 'latest')) as VersionRange); - } - - return packages; -} - -function _addPackageGroup( - tree: Tree, - packages: Map, - allDependencies: ReadonlyMap, - npmPackageJson: NpmRepositoryPackageJson, - logger: logging.LoggerApi, -): void { - const maybePackage = packages.get(npmPackageJson.name); - if (!maybePackage) { - return; - } - - const distTags = npmPackageJson['dist-tags'] ?? {}; - let version = maybePackage; - if (distTags[version]) { - version = distTags[version] as VersionRange; - } else if (version === 'next') { - version = distTags['latest'] as VersionRange; - } else { - const packageVersionsNonDeprecated: string[] = []; - const packageVersionsDeprecated: string[] = []; - const versions = npmPackageJson.versions ?? {}; - for (const [v, { deprecated }] of Object.entries(versions)) { - if (deprecated) { - packageVersionsDeprecated.push(v); - } else { - packageVersionsNonDeprecated.push(v); - } - } - version = - ((semver.maxSatisfying(packageVersionsNonDeprecated, version) ?? - semver.maxSatisfying(packageVersionsDeprecated, version)) as VersionRange | null) ?? - version; - } - - const versions = npmPackageJson.versions ?? {}; - if (!versions[version]) { - return; - } - const ngUpdateMetadata = versions[version]['ng-update']; - if (!ngUpdateMetadata) { - return; - } - - const packageGroup = ngUpdateMetadata['packageGroup']; - if (!packageGroup) { - return; - } - let packageGroupNormalized: Record; - if (Array.isArray(packageGroup) && !packageGroup.some((x) => typeof x != 'string')) { - packageGroupNormalized = packageGroup.reduce( - (acc, curr) => { - acc[curr] = maybePackage; - - return acc; - }, - {} as { [name: string]: string }, - ); - } else if ( - typeof packageGroup == 'object' && - packageGroup && - !Array.isArray(packageGroup) && - Object.values(packageGroup).every((x) => typeof x == 'string') - ) { - packageGroupNormalized = packageGroup; - } else { - logger.warn(`packageGroup metadata of package ${npmPackageJson.name} is malformed. Ignoring.`); - - return; - } - - for (const [name, value] of Object.entries(packageGroupNormalized)) { - // Don't override names from the command line. - // Remove packages that aren't installed. - if (!packages.has(name) && allDependencies.has(name)) { - packages.set(name, value as VersionRange); - } - } -} - -/** - * Add peer dependencies of packages on the command line to the list of packages to update. - * We don't do verification of the versions here as this will be done by a later step (and can - * be ignored by the --force flag). - * @private - */ -async function _addPeerDependencies( - tree: Tree, - packages: Map, - allDependencies: ReadonlyMap, - npmPackageJson: NpmRepositoryPackageJson, - workspaceRoot: string, - fetchMetadata: (name: string) => Promise, - logger: logging.LoggerApi, -): Promise { - const maybePackage = packages.get(npmPackageJson.name); - if (!maybePackage) { - return; - } - const distTags = npmPackageJson['dist-tags'] ?? {}; - const version = distTags[maybePackage] || maybePackage; - const versions = npmPackageJson.versions ?? {}; - const packageJson = versions[version]; - if (!packageJson) { - return; - } - - for (const [peer, range] of Object.entries(packageJson.peerDependencies || {})) { - if (packages.has(peer)) { - continue; - } - - const installedVersion = getInstalledVersion(tree, peer, workspaceRoot); - if (installedVersion) { - if (semver.satisfies(installedVersion, range)) { - continue; - } - } else { - const packageJsonRange = allDependencies.get(peer); - if (packageJsonRange) { - const peerMetadata = await fetchMetadata(peer); - if (peerMetadata) { - const packageVersionsNonDeprecated: string[] = []; - const packageVersionsDeprecated: string[] = []; - for (const [v, { deprecated }] of Object.entries(peerMetadata.versions ?? {})) { - if (deprecated) { - packageVersionsDeprecated.push(v); - } else { - packageVersionsNonDeprecated.push(v); - } - } - const resolvedInstalledVersion = - semver.maxSatisfying(packageVersionsNonDeprecated, packageJsonRange) ?? - semver.maxSatisfying(packageVersionsDeprecated, packageJsonRange); - - if (resolvedInstalledVersion && semver.satisfies(resolvedInstalledVersion, range)) { - continue; - } - } - } - } - - packages.set(peer, range as VersionRange); - } -} - -function _getAllDependencies(tree: Tree): Array { - const { dependencies, devDependencies, peerDependencies } = tree.readJson( - '/package.json', - ) as PackageManifest; - - return [ - ...(Object.entries(peerDependencies || {}) as Array<[string, VersionRange]>), - ...(Object.entries(devDependencies || {}) as Array<[string, VersionRange]>), - ...(Object.entries(dependencies || {}) as Array<[string, VersionRange]>), - ]; -} - -function _formatVersion(version: string | undefined) { - if (version === undefined) { - return undefined; - } - - if (!version.match(/^\d{1,30}\.\d{1,30}\.\d{1,30}/)) { - version += '.0'; - } - if (!version.match(/^\d{1,30}\.\d{1,30}\.\d{1,30}/)) { - version += '.0'; - } - if (!semver.valid(version)) { - throw new SchematicsException(`Invalid migration version: ${JSON.stringify(version)}`); - } - - return version; -} - -/** - * Returns whether or not the given package specifier (the value string in a - * `package.json` dependency) is hosted in the NPM registry. - * @throws When the specifier cannot be parsed. - */ -function isPkgFromRegistry(name: string, specifier: string): boolean { - const result = npa.resolve(name, specifier); - - return !!result.registry; -} - -export default function (options: UpdateSchema): Rule { - if (!options.packages) { - // We cannot just return this because we need to fetch the packages from NPM still for the - // help/guide to show. - options.packages = []; - } else { - // We split every packages by commas to allow people to pass in multiple and make it an array. - options.packages = options.packages.reduce((acc, curr) => { - return acc.concat(curr.split(',')); - }, [] as string[]); - } - - if (options.migrateOnly && options.from) { - if (options.packages.length !== 1) { - throw new SchematicsException('--from requires that only a single package be passed.'); - } - } - - options.from = _formatVersion(options.from); - options.to = _formatVersion(options.to); - const usingYarn = options.packageManager === 'yarn'; - - return async (tree: Tree, context: SchematicContext) => { - const logger = context.logger; - const npmDeps = new Map( - _getAllDependencies(tree).filter(([name, specifier]) => { - try { - return isPkgFromRegistry(name, specifier); - } catch { - logger.warn(`Package ${name} was not found on the registry. Skipping.`); - - return false; - } - }), - ); - const packages = _buildPackageList(options, npmDeps, logger); - - const workspaceRoot = options.workspaceRoot ?? process.cwd(); - const npmPackageJsonMap = new Map(); - - const getOrFetchPackageMetadata = async ( - packageName: string, - ): Promise => { - let metadata = npmPackageJsonMap.get(packageName); - if (!metadata) { - const raw = await getNpmPackageJson(packageName, logger, { - registry: options.registry, - usingYarn, - verbose: options.verbose, - }); - if (raw.name) { - metadata = raw as NpmRepositoryPackageJson; - npmPackageJsonMap.set(packageName, metadata); - } - } - - return metadata ?? null; - }; - - if (packages.size === 0) { - // User ran just `ng update` to see the outdated package list. - // We must fetch metadata for all npm dependencies to generate the usage message. - await Promise.all( - Array.from(npmDeps.keys()).map(async (depName) => { - await getOrFetchPackageMetadata(depName); - }), - ); - } else { - // User requested updates. We resolve dependencies lazily. - let lastPackagesSize; - do { - lastPackagesSize = packages.size; - - let lastGroupSize; - do { - lastGroupSize = packages.size; - for (const name of Array.from(packages.keys())) { - const metadata = await getOrFetchPackageMetadata(name); - const spec = packages.get(name); - if (metadata && spec) { - const resolvedVersion = resolvePackageVersion(metadata, spec, !!options.next); - if (resolvedVersion) { - packages.set(name, resolvedVersion as VersionRange); - } - _addPackageGroup(tree, packages, npmDeps, metadata, logger); - } - } - } while (packages.size > lastGroupSize); - - for (const name of Array.from(packages.keys())) { - const metadata = await getOrFetchPackageMetadata(name); - const spec = packages.get(name); - if (metadata && spec) { - const resolvedVersion = resolvePackageVersion(metadata, spec, !!options.next); - if (resolvedVersion) { - packages.set(name, resolvedVersion as VersionRange); - } - await _addPeerDependencies( - tree, - packages, - npmDeps, - metadata, - workspaceRoot, - getOrFetchPackageMetadata, - logger, - ); - } - } - } while (packages.size > lastPackagesSize); - } - - // Build the PackageInfo for each module. - const packageInfoMap = new Map(); - for (const depName of npmDeps.keys()) { - const isUpdating = packages.has(depName); - const localPkgJson = getInstalledPackageJson(tree, depName, workspaceRoot); - - if (isUpdating || !localPkgJson) { - // If updating OR not installed locally, resolve via registry metadata - const metadata = await getOrFetchPackageMetadata(depName); - if (metadata) { - packageInfoMap.set( - depName, - _buildPackageInfo(tree, packages, npmDeps, metadata, workspaceRoot, logger), - ); - } else { - // Fallback if metadata could not be fetched - packageInfoMap.set( - depName, - _buildLocalPackageInfo(tree, depName, npmDeps, workspaceRoot, logger), - ); - } - } else { - // If not updating and installed locally, resolve purely locally - packageInfoMap.set( - depName, - _buildLocalPackageInfo(tree, depName, npmDeps, workspaceRoot, logger), - ); - } - } - - // Now that we have all the information, check the flags. - if (packages.size > 0) { - if (options.migrateOnly && options.from && options.packages) { - return; - } - - const sublog = new logging.LevelCapLogger('validation', logger.createChild(''), 'warn'); - _validateUpdatePackages(packageInfoMap, !!options.force, !!options.next, sublog); - - _performUpdate(tree, context, packageInfoMap, logger, !!options.migrateOnly); - } else { - _usageMessage(options, packageInfoMap, logger); - } - }; -} diff --git a/packages/angular/cli/src/commands/update/schematic/index_spec.ts b/packages/angular/cli/src/commands/update/schematic/index_spec.ts deleted file mode 100644 index 7e8ca436150d..000000000000 --- a/packages/angular/cli/src/commands/update/schematic/index_spec.ts +++ /dev/null @@ -1,391 +0,0 @@ -/** - * @license - * Copyright Google LLC All Rights Reserved. - * - * Use of this source code is governed by an MIT-style license that can be - * found in the LICENSE file at https://angular.dev/license - */ - -import { normalize, virtualFs } from '@angular-devkit/core'; -import { HostTree } from '@angular-devkit/schematics'; -import { SchematicTestRunner, UnitTestTree } from '@angular-devkit/schematics/testing'; -import * as semver from 'semver'; -import { angularMajorCompatGuarantee } from './index'; - -describe('angularMajorCompatGuarantee', () => { - [ - '5.0.0', - '5.1.0', - '5.20.0', - '6.0.0', - '6.0.0-rc.0', - '6.0.0-beta.0', - '6.1.0-beta.0', - '6.1.0-rc.0', - '6.10.11', - ].forEach((golden) => { - it('works with ' + JSON.stringify(golden), () => { - expect(semver.satisfies(golden, angularMajorCompatGuarantee('^5.0.0'))).toBeTruthy(); - }); - }); -}); - -describe('@schematics/update', () => { - const schematicRunner = new SchematicTestRunner( - '@schematics/update', - require.resolve('./collection.json'), - ); - let host: virtualFs.test.TestHost; - let appTree: UnitTestTree = new UnitTestTree(new HostTree()); - - beforeEach(() => { - host = new virtualFs.test.TestHost({ - '/package.json': `{ - "name": "blah", - "dependencies": { - "@angular-devkit-tests/update-base": "1.0.0" - } - }`, - }); - appTree = new UnitTestTree(new HostTree(host)); - }); - - it('ignores dependencies not hosted on the NPM registry', async () => { - let newTree = new UnitTestTree( - new HostTree( - new virtualFs.test.TestHost({ - '/package.json': `{ - "name": "blah", - "dependencies": { - "@angular-devkit-tests/update-base": "file:update-base-1.0.0.tgz" - } - }`, - }), - ), - ); - - newTree = await schematicRunner.runSchematic('update', undefined, newTree); - const packageJson = JSON.parse(newTree.readContent('/package.json')); - expect(packageJson['dependencies']['@angular-devkit-tests/update-base']).toBe( - 'file:update-base-1.0.0.tgz', - ); - }, 45000); - - it('should not error with yarn 2.0 protocols', async () => { - let newTree = new UnitTestTree( - new HostTree( - new virtualFs.test.TestHost({ - '/package.json': `{ - "name": "blah", - "dependencies": { - "src": "src@link:./src", - "@angular-devkit-tests/update-base": "1.0.0" - } - }`, - }), - ), - ); - - newTree = await schematicRunner.runSchematic( - 'update', - { - packages: ['@angular-devkit-tests/update-base'], - }, - newTree, - ); - const { dependencies } = JSON.parse(newTree.readContent('/package.json')); - expect(dependencies['@angular-devkit-tests/update-base']).toBe('1.1.0'); - }); - - it('updates Angular as compatible with Angular N-1', async () => { - // Add the basic migration package. - const content = virtualFs.fileBufferToString(host.sync.read(normalize('/package.json'))); - const packageJson = JSON.parse(content); - const dependencies = packageJson['dependencies']; - dependencies['@angular-devkit-tests/update-peer-dependencies-angular-5'] = '1.0.0'; - dependencies['@angular/core'] = '5.1.0'; - dependencies['rxjs'] = '5.5.0'; - dependencies['zone.js'] = '0.8.26'; - host.sync.write( - normalize('/package.json'), - virtualFs.stringToFileBuffer(JSON.stringify(packageJson)), - ); - - const newTree = await schematicRunner.runSchematic( - 'update', - { - packages: ['@angular/core@^6.0.0'], - }, - appTree, - ); - const newPpackageJson = JSON.parse(newTree.readContent('/package.json')); - expect(newPpackageJson['dependencies']['@angular/core'][0]).toBe('6'); - }, 45000); - - it('updates Angular as compatible with Angular N-1 (2)', async () => { - // Add the basic migration package. - const content = virtualFs.fileBufferToString(host.sync.read(normalize('/package.json'))); - const packageJson = JSON.parse(content); - const dependencies = packageJson['dependencies']; - dependencies['@angular-devkit-tests/update-peer-dependencies-angular-5-2'] = '1.0.0'; - dependencies['@angular/core'] = '5.1.0'; - dependencies['@angular/animations'] = '5.1.0'; - dependencies['@angular/common'] = '5.1.0'; - dependencies['@angular/compiler'] = '5.1.0'; - dependencies['@angular/compiler-cli'] = '5.1.0'; - dependencies['@angular/platform-browser'] = '5.1.0'; - dependencies['rxjs'] = '5.5.0'; - dependencies['zone.js'] = '0.8.26'; - dependencies['typescript'] = '2.4.2'; - host.sync.write( - normalize('/package.json'), - virtualFs.stringToFileBuffer(JSON.stringify(packageJson)), - ); - - const newTree = await schematicRunner.runSchematic( - 'update', - { - packages: ['@angular/core@^6.0.0'], - }, - appTree, - ); - - const newPackageJson = JSON.parse(newTree.readContent('/package.json')); - expect(newPackageJson['dependencies']['@angular/core'][0]).toBe('6'); - expect(newPackageJson['dependencies']['rxjs'][0]).toBe('6'); - expect(newPackageJson['dependencies']['typescript'][0]).toBe('2'); - expect(newPackageJson['dependencies']['typescript'][2]).not.toBe('4'); - }, 45000); - - it('uses packageGroup for versioning', async () => { - // Add the basic migration package. - const content = virtualFs.fileBufferToString(host.sync.read(normalize('/package.json'))); - const packageJson = JSON.parse(content); - const dependencies = packageJson['dependencies']; - dependencies['@angular-devkit-tests/update-package-group-1'] = '1.0.0'; - dependencies['@angular-devkit-tests/update-package-group-2'] = '1.0.0'; - host.sync.write( - normalize('/package.json'), - virtualFs.stringToFileBuffer(JSON.stringify(packageJson)), - ); - - const newTree = await schematicRunner.runSchematic( - 'update', - { - packages: ['@angular-devkit-tests/update-package-group-1'], - }, - appTree, - ); - const { dependencies: deps } = JSON.parse(newTree.readContent('/package.json')); - expect(deps['@angular-devkit-tests/update-package-group-1']).toBe('1.2.0'); - expect(deps['@angular-devkit-tests/update-package-group-2']).toBe('2.0.0'); - }, 45000); - - it('can migrate only', async () => { - // Add the basic migration package. - const content = virtualFs.fileBufferToString(host.sync.read(normalize('/package.json'))); - const packageJson = JSON.parse(content); - packageJson['dependencies']['@angular-devkit-tests/update-migrations'] = '1.0.0'; - host.sync.write( - normalize('/package.json'), - virtualFs.stringToFileBuffer(JSON.stringify(packageJson)), - ); - - const newTree = await schematicRunner.runSchematic( - 'update', - { - packages: ['@angular-devkit-tests/update-migrations'], - migrateOnly: true, - }, - appTree, - ); - - const newPackageJson = JSON.parse(newTree.readContent('/package.json')); - expect(newPackageJson['dependencies']['@angular-devkit-tests/update-base']).toBe('1.0.0'); - expect(newPackageJson['dependencies']['@angular-devkit-tests/update-migrations']).toBe('1.0.0'); - }, 45000); - - it('can migrate from only', async () => { - // Add the basic migration package. - const content = virtualFs.fileBufferToString(host.sync.read(normalize('/package.json'))); - const packageJson = JSON.parse(content); - packageJson['dependencies']['@angular-devkit-tests/update-migrations'] = '1.6.0'; - host.sync.write( - normalize('/package.json'), - virtualFs.stringToFileBuffer(JSON.stringify(packageJson)), - ); - - const newTree = await schematicRunner.runSchematic( - 'update', - { - packages: ['@angular-devkit-tests/update-migrations'], - migrateOnly: true, - from: '0.1.2', - }, - appTree, - ); - const { dependencies } = JSON.parse(newTree.readContent('/package.json')); - expect(dependencies['@angular-devkit-tests/update-migrations']).toBe('1.6.0'); - }, 45000); - - it('can install and migrate with --from (short version number)', async () => { - // Add the basic migration package. - const content = virtualFs.fileBufferToString(host.sync.read(normalize('/package.json'))); - const packageJson = JSON.parse(content); - packageJson['dependencies']['@angular-devkit-tests/update-migrations'] = '1.6.0'; - host.sync.write( - normalize('/package.json'), - virtualFs.stringToFileBuffer(JSON.stringify(packageJson)), - ); - - const newTree = await schematicRunner.runSchematic( - 'update', - { - packages: ['@angular-devkit-tests/update-migrations'], - migrateOnly: true, - from: '0', - }, - appTree, - ); - const { dependencies } = JSON.parse(newTree.readContent('/package.json')); - expect(dependencies['@angular-devkit-tests/update-migrations']).toBe('1.6.0'); - }, 45000); - - it('validates peer dependencies', async () => { - const content = virtualFs.fileBufferToString(host.sync.read(normalize('/package.json'))); - const packageJson = JSON.parse(content); - const dependencies = packageJson['dependencies']; - // TODO: when we start using a local npm registry for test packages, add a package that includes - // a optional peer dependency and a non-optional one for this test. Use it instead of - // @angular-devkit/build-angular, whose optional peerdep is @angular/localize and non-optional - // are typescript and @angular/compiler-cli. - dependencies['@angular-devkit/build-angular'] = '0.900.0-next.1'; - host.sync.write( - normalize('/package.json'), - virtualFs.stringToFileBuffer(JSON.stringify(packageJson)), - ); - - const messages: string[] = []; - schematicRunner.logger.subscribe((x) => messages.push(x.message)); - const hasPeerdepMsg = (dep: string) => - messages.some((str) => str.includes(`missing peer dependency of "${dep}"`)); - - await schematicRunner.runSchematic( - 'update', - { - packages: ['@angular-devkit/build-angular'], - next: true, - }, - appTree, - ); - expect(hasPeerdepMsg('@angular/compiler-cli')).toBeTruthy(); - expect(hasPeerdepMsg('typescript')).toBeTruthy(); - expect(hasPeerdepMsg('@angular/localize')).toBeFalsy(); - }, 45000); - - it('does not remove newline at the end of package.json', async () => { - const newlineStyles = ['\n', '\r\n']; - for (const newline of newlineStyles) { - const packageJsonContent = `{ - "name": "blah", - "dependencies": { - "@angular-devkit-tests/update-base": "1.0.0" - } - }${newline}`; - const inputTree = new UnitTestTree( - new HostTree( - new virtualFs.test.TestHost({ - '/package.json': packageJsonContent, - }), - ), - ); - - const resultTree = await schematicRunner.runSchematic( - 'update', - { packages: ['@angular-devkit-tests/update-base'] }, - inputTree, - ); - - const resultTreeContent = resultTree.readContent('/package.json'); - expect(resultTreeContent.endsWith(newline)).toBeTrue(); - } - }); - - it('does not add a newline at the end of package.json', async () => { - const packageJsonContent = `{ - "name": "blah", - "dependencies": { - "@angular-devkit-tests/update-base": "1.0.0" - } - }`; - const inputTree = new UnitTestTree( - new HostTree( - new virtualFs.test.TestHost({ - '/package.json': packageJsonContent, - }), - ), - ); - - const resultTree = await schematicRunner.runSchematic( - 'update', - { packages: ['@angular-devkit-tests/update-base'] }, - inputTree, - ); - - const resultTreeContent = resultTree.readContent('/package.json'); - expect(resultTreeContent.endsWith('}')).toBeTrue(); - }); - - it('updates group members to the same version as the targeted package', async () => { - const packageJsonContent = `{ - "name": "test", - "dependencies": { - "@angular/cdk": "^19.2.19", - "@angular/common": "^19.2.0", - "@angular/compiler": "^19.2.0", - "@angular/core": "^19.2.0", - "@angular/forms": "^19.2.0", - "@angular/platform-browser": "^19.2.0", - "@angular/platform-browser-dynamic": "^19.2.0", - "@angular/router": "^19.2.0", - "rxjs": "~7.8.0", - "tslib": "^2.3.0", - "zone.js": "~0.15.0" - }, - "devDependencies": { - "@angular-devkit/build-angular": "^19.2.21", - "@angular/cli": "^19.2.21", - "@angular/compiler-cli": "^19.2.0", - "typescript": "~5.7.2" - } - }`; - - const inputTree = new UnitTestTree( - new HostTree( - new virtualFs.test.TestHost({ - '/package.json': packageJsonContent, - }), - ), - ); - - const resultTree = await schematicRunner.runSchematic( - 'update', - { force: true, packages: ['@angular/cli@20', '@angular/cdk@20', '@angular/core@20'] }, - inputTree, - ); - - const { devDependencies, dependencies } = resultTree.readJson('/package.json') as { - devDependencies: Record; - dependencies: Record; - }; - - const version20Regexp = /^\^20.\d+.\d+$/; - - expect(devDependencies['typescript']).toMatch(/5\.9\.\d+/); - expect(devDependencies['@angular/cli']).toMatch(version20Regexp); - expect(devDependencies['@angular/compiler-cli']).toMatch(version20Regexp); - expect(dependencies['@angular/cdk']).toMatch(version20Regexp); - expect(dependencies['@angular/common']).toMatch(version20Regexp); - expect(dependencies['@angular/core']).toMatch(version20Regexp); - }, 45000); -}); diff --git a/packages/angular/cli/src/commands/update/schematic/schema.json b/packages/angular/cli/src/commands/update/schematic/schema.json deleted file mode 100644 index 63bf2df87813..000000000000 --- a/packages/angular/cli/src/commands/update/schematic/schema.json +++ /dev/null @@ -1,68 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema", - "$id": "SchematicsUpdateSchema", - "title": "Schematic Options Schema", - "type": "object", - "properties": { - "packages": { - "description": "The package or packages to update.", - "type": "array", - "items": { - "type": "string" - }, - "$default": { - "$source": "argv" - } - }, - "force": { - "description": "When false (the default), reports an error if installed packages are incompatible with the update.", - "default": false, - "type": "boolean" - }, - "next": { - "description": "Update to the latest version, including beta and RCs.", - "default": false, - "type": "boolean" - }, - "migrateOnly": { - "description": "Perform a migration, but do not update the installed version.", - "default": false, - "type": "boolean" - }, - "from": { - "description": "When using `--migrateOnly` for a single package, the version of that package from which to migrate.", - "type": "string" - }, - "to": { - "description": "When using `--migrateOnly` for a single package, the version of that package to which to migrate.", - "type": "string" - }, - "registry": { - "description": "The npm registry to use.", - "type": "string", - "oneOf": [ - { - "format": "uri" - }, - { - "format": "hostname" - } - ] - }, - "verbose": { - "description": "Display additional details during the update process.", - "type": "boolean" - }, - "packageManager": { - "description": "The preferred package manager configuration files to use for registry settings.", - "type": "string", - "default": "npm", - "enum": ["npm", "yarn", "pnpm", "bun"] - }, - "workspaceRoot": { - "description": "The path to the workspace root directory.", - "type": "string" - } - }, - "required": [] -} diff --git a/packages/angular/cli/src/commands/update/update-resolver.ts b/packages/angular/cli/src/commands/update/update-resolver.ts new file mode 100644 index 000000000000..7e840e13ae55 --- /dev/null +++ b/packages/angular/cli/src/commands/update/update-resolver.ts @@ -0,0 +1,1028 @@ +/** + * @license + * Copyright Google LLC All Rights Reserved. + * + * Use of this source code is governed by an MIT-style license that can be + * found in the LICENSE file at https://angular.dev/license + */ + +import { logging } from '@angular-devkit/core'; +import { existsSync, promises as fs, readFileSync, realpathSync } from 'node:fs'; +import { createRequire } from 'node:module'; +import * as path from 'node:path'; +import npa from 'npm-package-arg'; +import * as semver from 'semver'; +import { + NpmRepositoryPackageJson, + PackageManifest, + getNpmPackageJson, +} from '../../utilities/package-metadata'; + +export type VersionRange = string & { __VERSION_RANGE: void }; +type PeerVersionTransform = string | ((range: string) => string); + +export function angularMajorCompatGuarantee(range: string) { + let newRange = semver.validRange(range); + if (!newRange) { + return range; + } + let major = 1; + while (!semver.gtr(major + '.0.0', newRange)) { + major++; + if (major >= 99) { + return newRange; + } + } + + newRange = range; + for (let minor = 0; minor < 20; minor++) { + newRange += ` || ^${major}.${minor}.0-alpha.0 `; + } + + return semver.validRange(newRange) || range; +} + +const knownPeerCompatibleList: { [name: string]: PeerVersionTransform } = { + '@angular/core': angularMajorCompatGuarantee, +}; + +export interface PackageVersionInfo { + version: VersionRange; + packageJson: PackageManifest; + updateMetadata: UpdateMetadata; +} + +export interface PackageInfo { + name: string; + npmPackageJson: NpmRepositoryPackageJson; + installed: PackageVersionInfo; + target?: PackageVersionInfo; + packageJsonRange: string; +} + +export interface UpdateMetadata { + packageGroupName?: string; + packageGroup: { [packageName: string]: string }; + requirements: { [packageName: string]: string }; + migrations?: string; +} + +export interface UpdateResolverOptions { + packages?: string[]; + force?: boolean; + next?: boolean; + migrateOnly?: boolean; + from?: string; + to?: string; + registry?: string; + packageManager?: string; + verbose?: boolean; + workspaceRoot?: string; +} + +export interface UpdatePlan { + packagesToUpdate: Map; // name -> target version range + migrationsToRun: { package: string; collection: string; from: string; to: string }[]; + packageInfoMap: Map; +} + +function _updatePeerVersion(infoMap: Map, name: string, range: string) { + const maybePackageInfo = infoMap.get(name); + if (!maybePackageInfo) { + return range; + } + if (maybePackageInfo.target) { + name = maybePackageInfo.target.updateMetadata.packageGroupName || name; + } else { + name = maybePackageInfo.installed.updateMetadata.packageGroupName || name; + } + + const maybeTransform = knownPeerCompatibleList[name]; + if (maybeTransform) { + if (typeof maybeTransform == 'function') { + return maybeTransform(range); + } else { + return maybeTransform; + } + } + + return range; +} + +function _validateForwardPeerDependencies( + name: string, + infoMap: Map, + logger: logging.LoggerApi, +): boolean { + let error = false; + const info = infoMap.get(name); + if (!info || !info.target) { + return error; + } + + const peerDependencies = info.target.packageJson.peerDependencies || {}; + const peerDependenciesMeta = info.target.packageJson.peerDependenciesMeta || {}; + + for (const [peer, range] of Object.entries(peerDependencies)) { + const peerInfo = infoMap.get(peer); + if (!peerInfo) { + continue; + } + + const isOptional = !!peerDependenciesMeta[peer]?.optional; + const resolvedRange = _updatePeerVersion(infoMap, peer, range); + const resolvedVersion = peerInfo.target ? peerInfo.target.version : peerInfo.installed.version; + + if (!semver.satisfies(resolvedVersion, resolvedRange, { includePrerelease: true })) { + logger.error( + `Package ${JSON.stringify(name)} has an incompatible peer dependency to ` + + `${JSON.stringify(peer)} (requires ${JSON.stringify(range)}, ` + + `would install ${JSON.stringify(resolvedVersion)}).`, + ); + error = error || !isOptional; + } + } + + return error; +} + +function _validateReversePeerDependencies( + name: string, + version: string, + infoMap: Map, + logger: logging.LoggerApi, + next: boolean, +): boolean { + let error = false; + for (const [installed, installedInfo] of infoMap.entries()) { + const installedLogger = logger.createChild(installed); + installedLogger.debug(`${installed}...`); + const peers = (installedInfo.target || installedInfo.installed).packageJson.peerDependencies; + const peersMeta = (installedInfo.target || installedInfo.installed).packageJson + .peerDependenciesMeta; + + for (const [peer, range] of Object.entries(peers || {})) { + if (peer !== name) { + continue; + } + + const isOptional = !!peersMeta?.[peer]?.optional; + const resolvedRange = _updatePeerVersion(infoMap, name, range); + if (!semver.satisfies(version, resolvedRange, { includePrerelease: next || undefined })) { + logger.error( + `Package ${JSON.stringify(installed)} has an incompatible peer dependency to ` + + `${JSON.stringify(name)} (requires ${JSON.stringify(range)}, ` + + `would install ${JSON.stringify(version)}).`, + ); + error = error || !isOptional; + } + } + } + + return error; +} + +function _validateUpdatePackages( + infoMap: Map, + force: boolean, + next: boolean, + logger: logging.LoggerApi, +): void { + logger.debug('Validating peer dependencies...'); + let error = false; + + for (const name of infoMap.keys()) { + const info = infoMap.get(name); + if (!info || !info.target) { + continue; + } + + logger.debug(`Checking ${name}...`); + error = _validateForwardPeerDependencies(name, infoMap, logger) || error; + error = + _validateReversePeerDependencies(name, info.target.version, infoMap, logger, next) || error; + } + + if (error && !force) { + throw new Error( + 'Incompatible peer dependencies found. See above for details. ' + + 'You can bypass this check using the --force option.', + ); + } +} + +function _getUpdateMetadata( + packageJson: PackageManifest, + logger: logging.LoggerApi, +): UpdateMetadata { + const metadata = packageJson['ng-update']; + + const result: UpdateMetadata = { + packageGroup: {}, + requirements: {}, + }; + + if (!metadata || typeof metadata != 'object' || Array.isArray(metadata)) { + return result; + } + + if (metadata['packageGroup']) { + const packageGroup = metadata['packageGroup']; + if (Array.isArray(packageGroup) && packageGroup.every((x) => typeof x == 'string')) { + result.packageGroup = packageGroup.reduce( + (group, name) => { + group[name] = packageJson.version; + + return group; + }, + {} as { [key: string]: string }, + ); + } else if (typeof packageGroup == 'object' && packageGroup !== null) { + result.packageGroup = Object.entries(packageGroup).reduce( + (group, [name, version]) => { + if (typeof version == 'string') { + group[name] = version; + } + + return group; + }, + {} as { [key: string]: string }, + ); + } else { + logger.warn(`PackageGroup metadata for ${packageJson.name} is malformed. Ignoring.`); + } + } + + if (typeof metadata['packageGroupName'] == 'string') { + result.packageGroupName = metadata['packageGroupName']; + } + + if (typeof metadata['migrations'] == 'string') { + result.migrations = metadata['migrations']; + } + + return result; +} + +export function isPnpActive(workspaceRoot: string): boolean { + return ( + process.versions.pnp !== undefined || + existsSync(path.join(workspaceRoot, '.pnp.cjs')) || + existsSync(path.join(workspaceRoot, '.pnp.js')) + ); +} + +export function findPackageJson(workspaceDir: string, packageName: string): string | undefined { + if (isPnpActive(workspaceDir)) { + try { + const workspaceRequire = createRequire(path.join(workspaceDir, 'package.json')); + + return workspaceRequire.resolve(`${packageName}/package.json`); + } catch { + return undefined; + } + } + + let currentDir = workspaceDir; + while (true) { + const candidatePath = path.join(currentDir, 'node_modules', packageName, 'package.json'); + if (existsSync(candidatePath)) { + return realpathSync(candidatePath); + } + const parentDir = path.dirname(currentDir); + if (parentDir === currentDir) { + break; + } + currentDir = parentDir; + } + + return undefined; +} + +function getInstalledPackageJson( + packageName: string, + workspaceRoot: string, +): PackageManifest | null { + try { + const manifestPath = findPackageJson(workspaceRoot, packageName); + if (manifestPath) { + const content = readFileSync(manifestPath, 'utf8'); + + return JSON.parse(content) as PackageManifest; + } + } catch {} + + return null; +} + +function getInstalledVersion(packageName: string, workspaceRoot: string): string | null { + const pkgJson = getInstalledPackageJson(packageName, workspaceRoot); + + return pkgJson?.version ?? null; +} + +function _buildLocalPackageInfo( + name: string, + allDependencies: ReadonlyMap, + workspaceRoot: string, +): PackageInfo { + const packageJsonRange = allDependencies.get(name); + if (!packageJsonRange) { + throw new Error(`Package ${JSON.stringify(name)} was not found in package.json.`); + } + + const localPkgJson = getInstalledPackageJson(name, workspaceRoot); + if (!localPkgJson) { + throw new Error(`Package ${name} is not installed.`); + } + + const installedVersion = localPkgJson.version; + const npmPackageJson: NpmRepositoryPackageJson = { + name, + versions: { + [installedVersion]: localPkgJson, + }, + 'dist-tags': {}, + } as unknown as NpmRepositoryPackageJson; + + const logger = new logging.NullLogger(); + + return { + name, + npmPackageJson, + installed: { + version: installedVersion as VersionRange, + packageJson: localPkgJson, + updateMetadata: _getUpdateMetadata(localPkgJson, logger), + }, + packageJsonRange, + }; +} + +function _buildPackageInfo( + packages: Map, + allDependencies: ReadonlyMap, + npmPackageJson: NpmRepositoryPackageJson, + workspaceRoot: string, + logger: logging.LoggerApi, +): PackageInfo { + const name = npmPackageJson.name; + const packageJsonRange = allDependencies.get(name); + if (!packageJsonRange) { + throw new Error(`Package ${JSON.stringify(name)} was not found in package.json.`); + } + + const localPkgJson = getInstalledPackageJson(name, workspaceRoot); + let installedVersion = localPkgJson?.version; + + const packageVersionsNonDeprecated: string[] = []; + const packageVersionsDeprecated: string[] = []; + + for (const [version, { deprecated }] of Object.entries(npmPackageJson.versions ?? {})) { + if (deprecated) { + packageVersionsDeprecated.push(version); + } else { + packageVersionsNonDeprecated.push(version); + } + } + + const findSatisfyingVersion = (targetVersion: VersionRange): VersionRange | undefined => + ((semver.maxSatisfying(packageVersionsNonDeprecated, targetVersion) ?? + semver.maxSatisfying(packageVersionsDeprecated, targetVersion)) as VersionRange | null) ?? + undefined; + + if (!installedVersion) { + installedVersion = findSatisfyingVersion(packageJsonRange); + } + + if (!installedVersion) { + throw new Error( + `An unexpected error happened; could not determine version for package ${name}.`, + ); + } + + const versions = npmPackageJson.versions ?? {}; + const installedPackageJson = versions[installedVersion] || localPkgJson; + if (!installedPackageJson) { + throw new Error( + `An unexpected error happened; package ${name} has no version ${installedVersion}.`, + ); + } + + let targetVersion: VersionRange | undefined = packages.get(name); + if (targetVersion) { + const distTags = npmPackageJson['dist-tags'] ?? {}; + if (distTags[targetVersion]) { + targetVersion = distTags[targetVersion] as VersionRange; + } else if (targetVersion == 'next') { + targetVersion = distTags['latest'] as VersionRange; + } else { + targetVersion = findSatisfyingVersion(targetVersion); + } + } + + if (targetVersion && semver.lte(targetVersion, installedVersion)) { + logger.debug(`Package ${name} already satisfied by package.json (${packageJsonRange}).`); + targetVersion = undefined; + } + + const target: PackageVersionInfo | undefined = targetVersion + ? { + version: targetVersion, + packageJson: versions[targetVersion], + updateMetadata: _getUpdateMetadata(versions[targetVersion], logger), + } + : undefined; + + return { + name, + npmPackageJson, + installed: { + version: installedVersion as VersionRange, + packageJson: installedPackageJson, + updateMetadata: _getUpdateMetadata(installedPackageJson, logger), + }, + target, + packageJsonRange, + }; +} + +function _buildPackageList( + options: UpdateResolverOptions, + allDependencies: ReadonlyMap, + logger: logging.LoggerApi, +): Map { + const packages = new Map(); + const inputPackages = options.packages ?? []; + + if (inputPackages.length === 0) { + return packages; + } + + for (const pkg of inputPackages) { + let pkgName = pkg; + let pkgVersion: string | undefined; + + if (pkg.startsWith('@')) { + const parts = pkg.split('@'); + pkgName = '@' + parts[1]; + pkgVersion = parts[2]; + } else if (pkg.includes('@')) { + const parts = pkg.split('@'); + pkgName = parts[0]; + pkgVersion = parts[1]; + } + + if (!allDependencies.has(pkgName)) { + throw new Error(`Package ${JSON.stringify(pkgName)} is not in package.json.`); + } + + if (options.migrateOnly && !pkgVersion && options.from) { + pkgVersion = options.from; + } + + packages.set(pkgName, (pkgVersion || (options.next ? 'next' : 'latest')) as VersionRange); + } + + return packages; +} + +function resolvePackageVersion( + metadata: NpmRepositoryPackageJson, + range: string, + next = false, +): string | null { + const distTags = metadata['dist-tags'] ?? {}; + if (distTags[range]) { + return distTags[range]; + } + if (range === 'next') { + return distTags['latest'] ?? null; + } + + const packageVersionsNonDeprecated: string[] = []; + const packageVersionsDeprecated: string[] = []; + for (const [v, { deprecated }] of Object.entries(metadata.versions ?? {})) { + if (deprecated) { + packageVersionsDeprecated.push(v); + } else { + packageVersionsNonDeprecated.push(v); + } + } + + return ( + semver.maxSatisfying(packageVersionsNonDeprecated, range, { + includePrerelease: next || undefined, + }) ?? + semver.maxSatisfying(packageVersionsDeprecated, range, { + includePrerelease: next || undefined, + }) + ); +} + +function _addPackageGroup( + packages: Map, + allDependencies: ReadonlyMap, + metadata: NpmRepositoryPackageJson, + logger: logging.LoggerApi, +): void { + const maybePackage = packages.get(metadata.name); + if (!maybePackage) { + return; + } + + const distTags = metadata['dist-tags'] ?? {}; + let version = maybePackage; + if (distTags[version]) { + version = distTags[version] as VersionRange; + } else if (version === 'next') { + version = distTags['latest'] as VersionRange; + } else { + const packageVersionsNonDeprecated: string[] = []; + const packageVersionsDeprecated: string[] = []; + const versions = metadata.versions ?? {}; + for (const [v, { deprecated }] of Object.entries(versions)) { + if (deprecated) { + packageVersionsDeprecated.push(v); + } else { + packageVersionsNonDeprecated.push(v); + } + } + version = + ((semver.maxSatisfying(packageVersionsNonDeprecated, version) ?? + semver.maxSatisfying(packageVersionsDeprecated, version)) as VersionRange | null) ?? + version; + } + + const versions = metadata.versions ?? {}; + if (!versions[version]) { + return; + } + const ngUpdateMetadata = versions[version]['ng-update']; + if (!ngUpdateMetadata) { + return; + } + + const packageGroup = ngUpdateMetadata['packageGroup']; + if (!packageGroup) { + return; + } + let packageGroupNormalized: Record; + if (Array.isArray(packageGroup) && !packageGroup.some((x) => typeof x != 'string')) { + packageGroupNormalized = packageGroup.reduce( + (acc, curr) => { + acc[curr] = version; + + return acc; + }, + {} as Record, + ); + } else if (typeof packageGroup === 'object' && packageGroup !== null) { + packageGroupNormalized = Object.entries(packageGroup).reduce( + (acc, [name, v]) => { + if (typeof v === 'string') { + acc[name] = v; + } + + return acc; + }, + {} as Record, + ); + } else { + logger.warn(`PackageGroup metadata for ${metadata.name} is malformed. Ignoring.`); + + return; + } + + for (const [member, memberVersion] of Object.entries(packageGroupNormalized)) { + if (packages.has(member)) { + continue; + } + if (allDependencies.has(member)) { + packages.set(member, memberVersion as VersionRange); + } + } +} + +async function _addPeerDependencies( + packages: Map, + allDependencies: ReadonlyMap, + npmPackageJson: NpmRepositoryPackageJson, + workspaceRoot: string, + fetchMetadata: (name: string) => Promise, + logger: logging.LoggerApi, +): Promise { + const maybePackage = packages.get(npmPackageJson.name); + if (!maybePackage) { + return; + } + + const distTags = npmPackageJson['dist-tags'] ?? {}; + const version = distTags[maybePackage] || maybePackage; + const versions = npmPackageJson.versions ?? {}; + const packageJson = versions[version]; + if (!packageJson) { + return; + } + + for (const [peer, range] of Object.entries(packageJson.peerDependencies || {})) { + if (packages.has(peer)) { + continue; + } + + const installedVersion = getInstalledVersion(peer, workspaceRoot); + if (installedVersion) { + if (semver.satisfies(installedVersion, range)) { + continue; + } + } else { + const packageJsonRange = allDependencies.get(peer); + if (packageJsonRange) { + const peerMetadata = await fetchMetadata(peer); + if (peerMetadata) { + const packageVersionsNonDeprecated: string[] = []; + const packageVersionsDeprecated: string[] = []; + for (const [v, { deprecated }] of Object.entries(peerMetadata.versions ?? {})) { + if (deprecated) { + packageVersionsDeprecated.push(v); + } else { + packageVersionsNonDeprecated.push(v); + } + } + const resolvedInstalledVersion = + semver.maxSatisfying(packageVersionsNonDeprecated, packageJsonRange) ?? + semver.maxSatisfying(packageVersionsDeprecated, packageJsonRange); + + if (resolvedInstalledVersion && semver.satisfies(resolvedInstalledVersion, range)) { + continue; + } + } + } + } + + packages.set(peer, range as VersionRange); + } +} + +function _formatVersion(v?: string): string | undefined { + if (v === undefined) { + return v; + } + if (semver.valid(v)) { + return v; + } + const coerced = semver.coerce(v); + + return coerced ? coerced.toString() : undefined; +} + +function isPkgFromRegistry(name: string, specifier: string): boolean { + const result = npa.resolve(name, specifier); + + return !!result.registry; +} + +export async function resolveUserUpdatePlan( + options: UpdateResolverOptions, + logger: logging.LoggerApi, +): Promise { + const workspaceRoot = options.workspaceRoot ?? process.cwd(); + const packageJsonPath = path.join(workspaceRoot, 'package.json'); + if (!existsSync(packageJsonPath)) { + throw new Error('Could not find a package.json. Are you in a Node project?'); + } + + const rawJson = readFileSync(packageJsonPath, 'utf8'); + const packageJsonContent = JSON.parse(rawJson) as PackageManifest; + + const getDependencies = (deps: Record | undefined) => + Object.entries(deps ?? {}).map(([name, range]) => [name, range] as const); + + const allRawDeps = [ + ...getDependencies(packageJsonContent.dependencies), + ...getDependencies(packageJsonContent.devDependencies), + ...getDependencies(packageJsonContent.peerDependencies), + ]; + + const npmDeps = new Map( + allRawDeps.filter(([name, specifier]) => { + try { + return isPkgFromRegistry(name, specifier); + } catch { + logger.warn(`Package ${name} was not found on the registry. Skipping.`); + + return false; + } + }) as [string, VersionRange][], + ); + + const packagesOption = options.packages ?? []; + const normalizedPackages = packagesOption.reduce((acc, curr) => { + return acc.concat(curr.split(',')); + }, [] as string[]); + options.packages = normalizedPackages; + + if (options.migrateOnly && options.from) { + if (options.packages.length !== 1) { + throw new Error('--from requires that only a single package be passed.'); + } + } + + options.from = _formatVersion(options.from); + options.to = _formatVersion(options.to); + const usingYarn = options.packageManager === 'yarn'; + + const packages = _buildPackageList(options, npmDeps, logger); + const npmPackageJsonMap = new Map(); + + const getOrFetchPackageMetadata = async ( + packageName: string, + ): Promise => { + let metadata = npmPackageJsonMap.get(packageName); + if (!metadata) { + const raw = await getNpmPackageJson(packageName, logger, { + registry: options.registry, + usingYarn, + verbose: options.verbose, + }); + if (raw.name) { + metadata = raw as NpmRepositoryPackageJson; + npmPackageJsonMap.set(packageName, metadata); + } + } + + return metadata ?? null; + }; + + if (packages.size === 0) { + await Promise.all( + Array.from(npmDeps.keys()).map(async (depName) => { + await getOrFetchPackageMetadata(depName); + }), + ); + } else { + let lastPackagesSize; + do { + lastPackagesSize = packages.size; + + let lastGroupSize; + do { + lastGroupSize = packages.size; + for (const name of Array.from(packages.keys())) { + const metadata = await getOrFetchPackageMetadata(name); + const spec = packages.get(name); + if (metadata && spec) { + const resolvedVersion = resolvePackageVersion(metadata, spec, !!options.next); + if (resolvedVersion) { + packages.set(name, resolvedVersion as VersionRange); + } + _addPackageGroup(packages, npmDeps, metadata, logger); + } + } + } while (packages.size > lastGroupSize); + + for (const name of Array.from(packages.keys())) { + const metadata = await getOrFetchPackageMetadata(name); + const spec = packages.get(name); + if (metadata && spec) { + const resolvedVersion = resolvePackageVersion(metadata, spec, !!options.next); + if (resolvedVersion) { + packages.set(name, resolvedVersion as VersionRange); + } + await _addPeerDependencies( + packages, + npmDeps, + metadata, + workspaceRoot, + getOrFetchPackageMetadata, + logger, + ); + } + } + } while (packages.size > lastPackagesSize); + } + + const packageInfoMap = new Map(); + for (const depName of npmDeps.keys()) { + const isUpdating = packages.has(depName); + const localPkgJson = getInstalledPackageJson(depName, workspaceRoot); + + if (isUpdating || !localPkgJson) { + const metadata = await getOrFetchPackageMetadata(depName); + if (metadata) { + packageInfoMap.set( + depName, + _buildPackageInfo(packages, npmDeps, metadata, workspaceRoot, logger), + ); + } else { + packageInfoMap.set(depName, _buildLocalPackageInfo(depName, npmDeps, workspaceRoot)); + } + } else { + packageInfoMap.set(depName, _buildLocalPackageInfo(depName, npmDeps, workspaceRoot)); + } + } + + const packagesToUpdate = new Map(); + const migrationsToRun: { package: string; collection: string; from: string; to: string }[] = []; + + if (packages.size > 0) { + if (!(options.migrateOnly && options.from && options.packages)) { + const sublog = new logging.LevelCapLogger('validation', logger.createChild(''), 'warn'); + _validateUpdatePackages(packageInfoMap, !!options.force, !!options.next, sublog); + + for (const [name, info] of packageInfoMap.entries()) { + if (!info.target || !info.installed) { + continue; + } + packagesToUpdate.set(name, info.target.version); + + if (info.target.updateMetadata.migrations) { + migrationsToRun.push({ + package: name, + collection: info.target.updateMetadata.migrations, + from: info.installed.version, + to: info.target.version, + }); + } + } + } + } + + return { + packagesToUpdate, + migrationsToRun, + packageInfoMap, + }; +} + +export function printUpdateUsageMessage( + infoMap: Map, + logger: logging.LoggerApi, + next = false, +) { + const packageGroups = new Map(); + const packagesToUpdate = [...infoMap.entries()] + .map(([name, info]) => { + const distTags = info.npmPackageJson['dist-tags'] ?? {}; + let tag = next ? (distTags['next'] ? 'next' : 'latest') : 'latest'; + let version = distTags[tag] ?? info.installed.version; + const versions = info.npmPackageJson.versions ?? {}; + let target = versions[version]; + + const versionDiff = semver.diff(info.installed.version, version); + if ( + versionDiff !== 'patch' && + versionDiff !== 'minor' && + /^@(?:angular|nguniversal)\//.test(name) + ) { + const installedMajorVersion = semver.parse(info.installed.version)?.major; + const toInstallMajorVersion = semver.parse(version)?.major; + if ( + installedMajorVersion !== undefined && + toInstallMajorVersion !== undefined && + installedMajorVersion < toInstallMajorVersion - 1 + ) { + const nextMajorVersion = `${installedMajorVersion + 1}.`; + const nextMajorVersions = Object.keys(versions) + .filter((v) => v.startsWith(nextMajorVersion)) + .sort((a, b) => (a > b ? -1 : 1)); + + if (nextMajorVersions.length) { + version = nextMajorVersions[0]; + target = versions[version]; + tag = ''; + } + } + } + + return { + name, + info, + version, + tag, + target, + }; + }) + .filter( + ({ info, version, target }) => + target?.['ng-update'] && semver.compare(info.installed.version, version) < 0, + ) + .map(({ name, info, version, tag, target }) => { + // Look for packageGroup. + const ngUpdate = target['ng-update']; + const packageGroup = ngUpdate?.['packageGroup']; + if (packageGroup) { + const packageGroupNames = Array.isArray(packageGroup) + ? packageGroup + : Object.keys(packageGroup); + const packageGroupName = + ngUpdate?.['packageGroupName'] || packageGroupNames.find((n) => infoMap.has(n)); + + if (packageGroupName) { + if (packageGroups.has(name)) { + return null; + } + + for (const groupName of packageGroupNames) { + packageGroups.set(groupName, packageGroupName); + } + + packageGroups.set(packageGroupName, packageGroupName); + name = packageGroupName; + } + } + + let command = `ng update ${name}`; + if (!tag) { + command += `@${semver.parse(version)?.major || version}`; + } else if (tag == 'next') { + command += ' --next'; + } + + return [name, `${info.installed.version} -> ${version} `, command]; + }) + .filter((x): x is string[] => x !== null) + .sort((a, b) => a[0].localeCompare(b[0])); + + if (packagesToUpdate.length == 0) { + logger.info('We analyzed your package.json and everything seems to be in order. Good work!'); + + return; + } + + logger.info('We analyzed your package.json, there are some packages to update:\n'); + + // Find the largest name to know the padding needed. + let namePad = Math.max(...[...infoMap.keys()].map((x) => x.length)) + 2; + if (!Number.isFinite(namePad)) { + namePad = 30; + } + const pads = [namePad, 25, 0]; + + logger.info( + ' ' + ['Name', 'Version', 'Command to update'].map((x, i) => x.padEnd(pads[i])).join(''), + ); + + const totalWidth = pads.reduce((sum, width) => sum + width, 20); + logger.info(` ${'-'.repeat(totalWidth)}`); + + packagesToUpdate.forEach((fields) => { + if (!fields) { + return; + } + + logger.info(' ' + fields.map((x, i) => x.padEnd(pads[i])).join('')); + }); + + logger.info( + `\nThere might be additional packages which don't provide 'ng update' capabilities that are outdated.\n` + + `You can update the additional packages by running the update command of your package manager.`, + ); +} + +export async function applyUpdatePlan( + workspaceRoot: string, + plan: UpdatePlan, + logger: logging.LoggerApi, +): Promise { + const packageJsonPath = path.join(workspaceRoot, 'package.json'); + const packageJsonContent = await fs.readFile(packageJsonPath, 'utf8'); + const packageJson = JSON.parse(packageJsonContent) as PackageManifest; + + const updateDependency = (deps: Record, name: string, newVersion: string) => { + const oldVersion = deps[name]; + const execResult = /^[\^~]/.exec(oldVersion); + deps[name] = `${execResult ? execResult[0] : ''}${newVersion}`; + }; + + for (const [name, targetVersion] of plan.packagesToUpdate.entries()) { + logger.info(`Updating package.json with dependency ${name} to version ${targetVersion}...`); + + if (packageJson.dependencies && packageJson.dependencies[name]) { + updateDependency(packageJson.dependencies, name, targetVersion); + if (packageJson.devDependencies) { + delete packageJson.devDependencies[name]; + } + if (packageJson.peerDependencies) { + delete packageJson.peerDependencies[name]; + } + } else if (packageJson.devDependencies && packageJson.devDependencies[name]) { + updateDependency(packageJson.devDependencies, name, targetVersion); + if (packageJson.peerDependencies) { + delete packageJson.peerDependencies[name]; + } + } else if (packageJson.peerDependencies && packageJson.peerDependencies[name]) { + updateDependency(packageJson.peerDependencies, name, targetVersion); + } else { + if (!packageJson.dependencies) { + packageJson.dependencies = {}; + } + packageJson.dependencies[name] = `^${targetVersion}`; + } + } + + const eofMatches = packageJsonContent.match(/\r?\n$/); + const eof = eofMatches?.[0] ?? ''; + const newContent = JSON.stringify(packageJson, null, 2) + eof; + await fs.writeFile(packageJsonPath, newContent, 'utf8'); +} diff --git a/packages/angular/cli/src/commands/update/update-resolver_spec.ts b/packages/angular/cli/src/commands/update/update-resolver_spec.ts new file mode 100644 index 000000000000..6953b9817906 --- /dev/null +++ b/packages/angular/cli/src/commands/update/update-resolver_spec.ts @@ -0,0 +1,230 @@ +/** + * @license + * Copyright Google LLC All Rights Reserved. + * + * Use of this source code is governed by an MIT-style license that can be + * found in the LICENSE file at https://angular.dev/license + */ + +import { logging } from '@angular-devkit/core'; +import { existsSync, mkdirSync, mkdtempSync, readFileSync, rmSync, writeFileSync } from 'node:fs'; +import { tmpdir } from 'node:os'; +import * as path from 'node:path'; +import * as semver from 'semver'; +import { + angularMajorCompatGuarantee, + applyUpdatePlan, + resolveUserUpdatePlan, +} from './update-resolver'; + +describe('angularMajorCompatGuarantee', () => { + [ + '5.0.0', + '5.1.0', + '5.20.0', + '6.0.0', + '6.0.0-rc.0', + '6.0.0-beta.0', + '6.1.0-beta.0', + '6.1.0-rc.0', + '6.10.11', + ].forEach((golden) => { + it('works with ' + JSON.stringify(golden), () => { + expect(semver.satisfies(golden, angularMajorCompatGuarantee('^5.0.0'))).toBeTruthy(); + }); + }); +}); + +describe('UpdateResolver', () => { + let tempRoot: string; + const logger = new logging.NullLogger(); + + beforeEach(() => { + tempRoot = mkdtempSync(path.join(tmpdir(), 'angular-cli-update-resolver-test-')); + }); + + afterEach(() => { + rmSync(tempRoot, { recursive: true, force: true }); + }); + + function createMockWorkspace( + packageJson: Record, + nodeModules: { [name: string]: { version: string; manifest?: Record } } = {}, + ) { + writeFileSync(path.join(tempRoot, 'package.json'), JSON.stringify(packageJson, null, 2)); + for (const [name, info] of Object.entries(nodeModules)) { + const pkgDir = path.join(tempRoot, 'node_modules', name); + mkdirSync(pkgDir, { recursive: true }); + writeFileSync( + path.join(pkgDir, 'package.json'), + JSON.stringify({ name, version: info.version, ...info.manifest }, null, 2), + ); + } + } + + it('ignores dependencies not hosted on the NPM registry', async () => { + createMockWorkspace({ + name: 'blah', + dependencies: { + '@angular-devkit-tests/update-base': 'file:update-base-1.0.0.tgz', + }, + }); + + const plan = await resolveUserUpdatePlan( + { + packages: [], + workspaceRoot: tempRoot, + }, + logger, + ); + + expect(plan.packagesToUpdate.size).toBe(0); + }); + + it('should not error with yarn 2.0 protocols', async () => { + createMockWorkspace( + { + name: 'blah', + dependencies: { + src: 'src@link:./src', + '@angular-devkit-tests/update-base': '1.0.0', + }, + }, + { + '@angular-devkit-tests/update-base': { version: '1.0.0' }, + }, + ); + + const plan = await resolveUserUpdatePlan( + { + packages: ['@angular-devkit-tests/update-base'], + workspaceRoot: tempRoot, + }, + logger, + ); + + expect(plan.packagesToUpdate.get('@angular-devkit-tests/update-base')).toBe('1.1.0'); + }); + + it('updates Angular as compatible with Angular N-1', async () => { + createMockWorkspace( + { + name: 'blah', + dependencies: { + '@angular-devkit-tests/update-peer-dependencies-angular-5': '1.0.0', + '@angular/core': '5.1.0', + rxjs: '5.5.0', + 'zone.js': '0.8.26', + }, + }, + { + '@angular-devkit-tests/update-peer-dependencies-angular-5': { version: '1.0.0' }, + '@angular/core': { version: '5.1.0' }, + rxjs: { version: '5.5.0' }, + 'zone.js': { version: '0.8.26' }, + }, + ); + + const plan = await resolveUserUpdatePlan( + { + packages: ['@angular/core@^6.0.0'], + workspaceRoot: tempRoot, + }, + logger, + ); + + expect(plan.packagesToUpdate.get('@angular/core')?.[0]).toBe('6'); + }); + + it('uses packageGroup for versioning', async () => { + createMockWorkspace( + { + name: 'blah', + dependencies: { + '@angular-devkit-tests/update-package-group-1': '1.0.0', + '@angular-devkit-tests/update-package-group-2': '1.0.0', + }, + }, + { + '@angular-devkit-tests/update-package-group-1': { version: '1.0.0' }, + '@angular-devkit-tests/update-package-group-2': { version: '1.0.0' }, + }, + ); + + const plan = await resolveUserUpdatePlan( + { + packages: ['@angular-devkit-tests/update-package-group-1'], + workspaceRoot: tempRoot, + }, + logger, + ); + + expect(plan.packagesToUpdate.get('@angular-devkit-tests/update-package-group-1')).toBe('1.2.0'); + expect(plan.packagesToUpdate.get('@angular-devkit-tests/update-package-group-2')).toBe('2.0.0'); + }); + + it('does not remove newline at the end of package.json', async () => { + const newline = '\n'; + const packageJsonContent = `{ + "name": "blah", + "dependencies": { + "@angular-devkit-tests/update-base": "1.0.0" + } +}${newline}`; + + writeFileSync(path.join(tempRoot, 'package.json'), packageJsonContent); + + // Mock installed package + const pkgDir = path.join(tempRoot, 'node_modules', '@angular-devkit-tests/update-base'); + mkdirSync(pkgDir, { recursive: true }); + writeFileSync( + path.join(pkgDir, 'package.json'), + JSON.stringify({ name: '@angular-devkit-tests/update-base', version: '1.0.0' }, null, 2), + ); + + const plan = await resolveUserUpdatePlan( + { + packages: ['@angular-devkit-tests/update-base'], + workspaceRoot: tempRoot, + }, + logger, + ); + + await applyUpdatePlan(tempRoot, plan, logger); + + const result = readFileSync(path.join(tempRoot, 'package.json'), 'utf8'); + expect(result.endsWith(newline)).toBeTrue(); + }); + + it('does not add a newline at the end of package.json', async () => { + const packageJsonContent = `{ + "name": "blah", + "dependencies": { + "@angular-devkit-tests/update-base": "1.0.0" + } +}`; + + writeFileSync(path.join(tempRoot, 'package.json'), packageJsonContent); + + // Mock installed package + const pkgDir = path.join(tempRoot, 'node_modules', '@angular-devkit-tests/update-base'); + mkdirSync(pkgDir, { recursive: true }); + writeFileSync( + path.join(pkgDir, 'package.json'), + JSON.stringify({ name: '@angular-devkit-tests/update-base', version: '1.0.0' }, null, 2), + ); + + const plan = await resolveUserUpdatePlan( + { + packages: ['@angular-devkit-tests/update-base'], + workspaceRoot: tempRoot, + }, + logger, + ); + + await applyUpdatePlan(tempRoot, plan, logger); + + const result = readFileSync(path.join(tempRoot, 'package.json'), 'utf8'); + expect(result.endsWith('}')).toBeTrue(); + }); +}); From f6b01f3b7c4227dec9dc56ad1cfab5a98e4ef49a Mon Sep 17 00:00:00 2001 From: Charles Lyding <19598772+clydin@users.noreply.github.com> Date: Thu, 4 Jun 2026 11:19:59 -0400 Subject: [PATCH 023/787] fix(@schematics/angular): use null objects and callbacks in karma-to-vitest migration The karma-to-vitest migration schematic previously used plain JavaScript objects as dictionaries when processing custom build options and analyzing Karma AST configurations. In environments where the input workspace files contain custom keys such as "__proto__", these assignments would leak properties onto the global Object prototype. --- .../migrate-karma-to-vitest/karma-config-analyzer.ts | 2 +- .../migrate-karma-to-vitest/karma-config-comparer.ts | 5 ++--- .../angular/migrations/migrate-karma-to-vitest/migration.ts | 6 +++++- 3 files changed, 8 insertions(+), 5 deletions(-) diff --git a/packages/schematics/angular/migrations/migrate-karma-to-vitest/karma-config-analyzer.ts b/packages/schematics/angular/migrations/migrate-karma-to-vitest/karma-config-analyzer.ts index d39e1a16bab6..8a1c49c58f61 100644 --- a/packages/schematics/angular/migrations/migrate-karma-to-vitest/karma-config-analyzer.ts +++ b/packages/schematics/angular/migrations/migrate-karma-to-vitest/karma-config-analyzer.ts @@ -142,7 +142,7 @@ export function analyzeKarmaConfig(content: string): KarmaConfigAnalysis { case ts.SyntaxKind.ArrayLiteralExpression: return (node as ts.ArrayLiteralExpression).elements.map(extractValue); case ts.SyntaxKind.ObjectLiteralExpression: { - const obj: { [key: string]: KarmaConfigValue } = {}; + const obj: { [key: string]: KarmaConfigValue } = Object.create(null); for (const prop of (node as ts.ObjectLiteralExpression).properties) { if (isSupportedPropertyAssignment(prop)) { // Recursively extract values for nested objects. diff --git a/packages/schematics/angular/migrations/migrate-karma-to-vitest/karma-config-comparer.ts b/packages/schematics/angular/migrations/migrate-karma-to-vitest/karma-config-comparer.ts index 0c11a7196f1c..f7bef0213b1f 100644 --- a/packages/schematics/angular/migrations/migrate-karma-to-vitest/karma-config-comparer.ts +++ b/packages/schematics/angular/migrations/migrate-karma-to-vitest/karma-config-comparer.ts @@ -46,11 +46,10 @@ export async function generateDefaultKarmaConfig( // TODO: Replace this with the actual schematic templating logic. template = template - .replace( - /<%= relativePathToWorkspaceRoot %>/g, + .replace(/<%= relativePathToWorkspaceRoot %>/g, () => path.normalize(relativePathToWorkspaceRoot).replace(/\\/g, '/'), ) - .replace(/<%= folderName %>/g, projectName); + .replace(/<%= folderName %>/g, () => projectName); const devkitPluginRegex = /<% if \(needDevkitPlugin\) { %>(.*?)<% } %>/gs; const replacement = needDevkitPlugin ? '$1' : ''; diff --git a/packages/schematics/angular/migrations/migrate-karma-to-vitest/migration.ts b/packages/schematics/angular/migrations/migrate-karma-to-vitest/migration.ts index 7d2306428b32..fc5b11fb5eb0 100644 --- a/packages/schematics/angular/migrations/migrate-karma-to-vitest/migration.ts +++ b/packages/schematics/angular/migrations/migrate-karma-to-vitest/migration.ts @@ -32,6 +32,7 @@ async function processTestTargetOptions( let needsIstanbul = false; for (const [configName, options] of allTargetOptions(testTarget, false)) { const configKey = configName || ''; + if (!customBuildOptions[configKey]) { // Match Karma behavior where AOT was disabled by default customBuildOptions[configKey] = { @@ -276,7 +277,10 @@ function updateProjects(tree: Tree, context: SchematicContext): Rule { tsConfigsToUpdate.add(join(project.root, 'tsconfig.spec.json')); // Store custom build options to move to a new build configuration if needed - const customBuildOptions: Record> = {}; + const customBuildOptions: Record< + string, + Record + > = Object.create(null); const projectCoverageInfo = await processTestTargetOptions( testTarget, From 53e82f9bb0ba4ba82d6ea4a7572ca73c4c8685b5 Mon Sep 17 00:00:00 2001 From: Angular Robot Date: Tue, 9 Jun 2026 06:16:01 +0000 Subject: [PATCH 024/787] build: lock file maintenance See associated pull request for more information. --- pnpm-lock.yaml | 480 +++++++++++++++++++++++++++---------------------- 1 file changed, 267 insertions(+), 213 deletions(-) diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 01183bb12896..bfa4103873ba 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -144,7 +144,7 @@ importers: version: 4.17.24 '@types/node': specifier: ^22.12.0 - version: 22.19.19 + version: 22.19.20 '@types/npm-package-arg': specifier: ^6.1.0 version: 6.1.4 @@ -273,7 +273,7 @@ importers: version: 6.4.1(rollup@4.61.0)(typescript@6.0.3) rollup-plugin-sourcemaps2: specifier: 0.5.7 - version: 0.5.7(@types/node@22.19.19)(rollup@4.61.0) + version: 0.5.7(@types/node@22.19.20)(rollup@4.61.0) semver: specifier: 7.8.1 version: 7.8.1 @@ -1644,8 +1644,8 @@ packages: peerDependencies: '@csstools/css-tokenizer': ^4.0.0 - '@csstools/css-syntax-patches-for-csstree@1.1.4': - resolution: {integrity: sha512-wgsqt92b7C7tQhIdPNxj0n9zuUbQlvAuI1exyzeNrOKOi62SD7ren8zqszmpVREjAOqg8cD2FqYhQfAuKjk4sw==} + '@csstools/css-syntax-patches-for-csstree@1.1.5': + resolution: {integrity: sha512-oNjBvzLq2GPZtJphCjLqXow/cHySHSgtxvKZb7OqSZ/xHgw6NWNhfad+6AB9cLeVm6eA9d/qMll3JdEHjy6M+A==} peerDependencies: css-tree: ^3.2.1 peerDependenciesMeta: @@ -2263,28 +2263,28 @@ packages: '@glideapps/ts-necessities@2.2.3': resolution: {integrity: sha512-gXi0awOZLHk3TbW55GZLCPP6O+y/b5X1pBXKBVckFONSwF1z1E5ND2BGJsghQFah+pW7pkkyFb2VhUQI2qhL5w==} - '@google-cloud/common@6.0.0': - resolution: {integrity: sha512-IXh04DlkLMxWgYLIUYuHHKXKOUwPDzDgke1ykkkJPe48cGIS9kkL2U/o0pm4ankHLlvzLF/ma1eO86n/bkumIA==} + '@google-cloud/common@6.0.1': + resolution: {integrity: sha512-1uvKzbmAWUdchIYRsg0f4rUmezOamWuVBSWAPAhnYoUE5OiPEx6v6JOxFIdr3MsrqV+6fyLV3EI1vMPlHoeRvw==} engines: {node: '>=18'} - '@google-cloud/precise-date@5.0.0': - resolution: {integrity: sha512-9h0Gvw92EvPdE8AK8AgZPbMnH5ftDyPtKm7/KUfcJVaPEPjwGDsJd1QV0H8esBDV4II41R/2lDWH1epBqIoKUw==} + '@google-cloud/precise-date@5.0.1': + resolution: {integrity: sha512-9HlRbOcDb8b2tSsOvljPD/Rm+Jn9KxMVB6sLf85CBnoIYdCFTNO1FIizQ13P75itXpSXsLuMlg1XK5opHKVzjg==} engines: {node: '>=18'} '@google-cloud/projectify@4.0.0': resolution: {integrity: sha512-MmaX6HeSvyPbWGwFq7mXdo0uQZLGBYCwziiLIGq5JVX+/bdI3SAq6bP98trV5eTWfLuvsMcIC1YJOF2vfteLFA==} engines: {node: '>=14.0.0'} - '@google-cloud/projectify@5.0.0': - resolution: {integrity: sha512-XXQLaIcLrOAMWvRrzz+mlUGtN6vlVNja3XQbMqRi/V7XJTAVwib3VcKd7oRwyZPkp7rBVlHGcaqdyGRrcnkhlA==} + '@google-cloud/projectify@5.0.1': + resolution: {integrity: sha512-yAIqOAlDwx1nPmmA0WICFMSGttVuWX97HpphN71JQ7G+tD/Q6lHbiCTcMJ9r2+PwX6sIwK3ahO4FdSNt5pwhFg==} engines: {node: '>=18'} '@google-cloud/promisify@4.1.0': resolution: {integrity: sha512-G/FQx5cE/+DqBbOpA5jKsegGwdPniU6PuIEMt+qxWgFxvxuFOzVmp6zYchtYuwAWV5/8Dgs0yAmjvNZv3uXLQg==} engines: {node: '>=18'} - '@google-cloud/promisify@5.0.0': - resolution: {integrity: sha512-N8qS6dlORGHwk7WjGXKOSsLjIjNINCPicsOX6gyyLiYk7mq3MtII96NZ9N2ahwA2vnkLmZODOIH9rlNniYWvCQ==} + '@google-cloud/promisify@5.0.1': + resolution: {integrity: sha512-Ste6NGraHq30ge3Sdq7m+pZE6lRUlkt2YgsEdq/vcoEgdbdZ/7h37Z1dMvivjhlbgrcmYRvlLF9FgI7tXm5wjg==} engines: {node: '>=18'} '@google-cloud/spanner@8.0.0': @@ -2554,50 +2554,50 @@ packages: peerDependencies: tslib: '2' - '@jsonjoy.com/fs-core@4.57.5': - resolution: {integrity: sha512-wl7eAKUwOcEZ8lL2/C38+w6VnNtBiNmvzKstlKPqRV/ymzg/7Aal5H74HEazSM2khYn9XG20I3fRp0Wr7xIbHA==} + '@jsonjoy.com/fs-core@4.57.6': + resolution: {integrity: sha512-uI++Wx6VkBJqVmkb4ZeExwAVpZiA2Do5NrEtXoDk0Pdvce3ytFXJoviT1sLOj16+qDIMnD5nWPfOhVpnDmRJKg==} engines: {node: '>=10.0'} peerDependencies: tslib: '2' - '@jsonjoy.com/fs-fsa@4.57.5': - resolution: {integrity: sha512-zIUMYeOgAdhA1M3JvceA2Fli7qas2WJrv6qmruXbq81bgIRKUM1LueJ1G0VRPk4D8wfOceBpayWQZqSEXA0AGA==} + '@jsonjoy.com/fs-fsa@4.57.6': + resolution: {integrity: sha512-pKkw/yC5CzSZKhIIUIsH1przOa+K5jGmZIg1sWaSF24JojyrUFbjcQv7QrcGAudriei6HQ6R0BFj+V8NbQinJw==} engines: {node: '>=10.0'} peerDependencies: tslib: '2' - '@jsonjoy.com/fs-node-builtins@4.57.5': - resolution: {integrity: sha512-maev+EH0kBJt7R6GZQgRmL5cHvs46PS71Y5M1FfZKN2/JVSAZPpdrLS+z7KYrvPn4oIYMKcG/XAhircG3eP88g==} + '@jsonjoy.com/fs-node-builtins@4.57.6': + resolution: {integrity: sha512-V4DgEFT3Cg5S9fCMOZSCVdTxdJWWLBO0WnAazV7hnCM96u5zXHyW/ubDAfcSVwqjkMJ50W1Y44IXtxRoIwaCVg==} engines: {node: '>=10.0'} peerDependencies: tslib: '2' - '@jsonjoy.com/fs-node-to-fsa@4.57.5': - resolution: {integrity: sha512-6IQi4TNoR1d+cSRZisWh6eqQ2mq32qgwESjVeXDs2pMWa+H/pZ24kSJKrDkyooUIfk1OIe40Dv9bnqc0FMcFjQ==} + '@jsonjoy.com/fs-node-to-fsa@4.57.6': + resolution: {integrity: sha512-+JptNw3iifihxH2rEXrninDzX4FFVW8JD/wPR8GbJPAeL9CQUSblrlumOPB5gZuS7tYRX+PJPLtT7XzKoRhv/Q==} engines: {node: '>=10.0'} peerDependencies: tslib: '2' - '@jsonjoy.com/fs-node-utils@4.57.5': - resolution: {integrity: sha512-u8GXaNr2VeQvHBXbJ9byY6GWP5z3HK3kCmdEPwVzjcgpEyAPjNnl0alP3Ylo6Aa4JSS8Ssc/F4+q69/03J2bUA==} + '@jsonjoy.com/fs-node-utils@4.57.6': + resolution: {integrity: sha512-foyUrfS7WmYEUzqYXSNxmJBcSj04TABrkpFabwO9SCDCpVCfJ+qG+2sk5FjfiflG2n0SDFZDCJ6vYlJAEpxJFg==} engines: {node: '>=10.0'} peerDependencies: tslib: '2' - '@jsonjoy.com/fs-node@4.57.5': - resolution: {integrity: sha512-F6kdnfsmK6q+WEjGhCOd/2iJpcmffj8q3qgXUG1/gHMXaThZp30Ienk3eMT+GfOpEbuVqoPvqNe8IwiPlDk/QQ==} + '@jsonjoy.com/fs-node@4.57.6': + resolution: {integrity: sha512-Kbn1jdkvDN4F2+BhoB6mMu7NCbhP0bgA5NcI1aJj/Q5UcU+I1JLLW+dEQean33iV4tXv35AzBVKPICnDltBpxw==} engines: {node: '>=10.0'} peerDependencies: tslib: '2' - '@jsonjoy.com/fs-print@4.57.5': - resolution: {integrity: sha512-fTcwBpqk9CEmzYd4Un4WxemvWbS69dGFEQgYmCQ0q02xsMzsZcTKzd3kduB46DBhjRTK77ga4HIQe08Oyn86kg==} + '@jsonjoy.com/fs-print@4.57.6': + resolution: {integrity: sha512-96eAn4Dudtt67LTeuU47yUD+pg9/G/oKpI10zei9ljk3X3WK4lYKc+n3cpaPCAbKPzoyfxl0mXm8f8Y7BOSFXw==} engines: {node: '>=10.0'} peerDependencies: tslib: '2' - '@jsonjoy.com/fs-snapshot@4.57.5': - resolution: {integrity: sha512-oAUUlG+E4uBw5sFERdMu3FRqt0hEM6jVCIKWkj194xiWppfShAqbMK5G3PahBXfGiTtlJjYErUWDbX3UhQhldw==} + '@jsonjoy.com/fs-snapshot@4.57.6': + resolution: {integrity: sha512-V57CMzbOgTzUWGOWQ8GzHQdpJP6JnrYVNCtTBNxVYEnlVRvo4uEJqHhtAT8vhDFrIuJOXLrTL1Fki4h5oI7xxg==} engines: {node: '>=10.0'} peerDependencies: tslib: '2' @@ -3685,8 +3685,8 @@ packages: '@types/node-fetch@2.6.13': resolution: {integrity: sha512-QGpRVpzSaUs30JBSGPjOg4Uveu384erbHBoT1zeONvyCfwQxIkUshLAOqN/k9EjGviPRmWTTe6aH2qySWKTVSw==} - '@types/node@22.19.19': - resolution: {integrity: sha512-dyh/xO2Fh5bYrfWaaqGrRQQGkNdmYw6AmaAUvYeUMNTWQtvb796ikLdmTchRmOlOiIJ1TDXfWgVx1QkUlQ6Hew==} + '@types/node@22.19.20': + resolution: {integrity: sha512-6tELRwSDYWW9EdZhbeZmYGZ1/7Djkt+Ah3/ScEYT9cDord7UJzasR/4D3VONg9tQI5CDp+/CZC1AXj2pCFOvpw==} '@types/node@24.12.4': resolution: {integrity: sha512-GUUEShf+PBCGW2KaXwcIt3Yk+e3pkKwWKb9GSyM9WQVE+ep2jzmHdGsHzu4wgcZy5fN9FBdVzjpBQsYlpfpgLA==} @@ -4323,8 +4323,8 @@ packages: bare-events: optional: true - bare-url@2.4.3: - resolution: {integrity: sha512-Kccpc7ACfXaxfeInfqKcZtW4pT5YBn1mesc4sCsun6sRwtbJ4h+sNOaksUpYEJUKfN65YWC6Bw2OJEFiKxq8nQ==} + bare-url@2.4.5: + resolution: {integrity: sha512-K+y9xF1tN+CdPu4qWwr0QiK1Al07eFPGYK5M2pDXcmHdMdgC/tT/bpmMe1hrmRHaidKLkXrC+cRNYf3XVDUhSQ==} base64-js@1.5.1: resolution: {integrity: sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==} @@ -4333,8 +4333,8 @@ packages: resolution: {integrity: sha512-lGe34o6EHj9y3Kts9R4ZYs/Gr+6N7MCaMlIFA3F1R2O5/m7K06AxfSeO5530PEERE6/WyEg3lsuyw4GHlPZHog==} engines: {node: ^4.5.0 || >= 5.9} - baseline-browser-mapping@2.10.33: - resolution: {integrity: sha512-bA6+tcSLpz2tIEdDXZPpPTIuxBcC4+w6SieaYyfigIa4h8GlFxbA17v22Vx3JUtuZQj9SgOsnbK+aTBzyDyEuw==} + baseline-browser-mapping@2.10.34: + resolution: {integrity: sha512-IMDedajPifLnHNY0X9n8hKxRTQ6/eTHwr5bDo04WnuqxyKw6LYtQywCuuqPZwhl3aBXMvQpJov42GLCwRRdQzw==} engines: {node: '>=6.0.0'} hasBin: true @@ -4477,8 +4477,8 @@ packages: resolution: {integrity: sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==} engines: {node: '>=6'} - caniuse-lite@1.0.30001793: - resolution: {integrity: sha512-iwSsYWaCOoh26cV8NwNRViHlrfUvYsHDfRVcbtmw0Kg6PJIZZXwMkj1442FYLBGkeUf1juAsU3DTfxW579mrPA==} + caniuse-lite@1.0.30001797: + resolution: {integrity: sha512-l8xKG+gwAIExZGl9FrF7KUwuOmk6wbEPC9Xoy/RtnWv1XG0Q4LFlagaLpUv3Kiza3W/wm27zy0yWJEieYKAP6w==} caseless@0.12.0: resolution: {integrity: sha512-4tYFyifaFfGacoiObjJegolkwSU4xQNGbVgUiNYVUxbQ2x2lUsFvY4hVgVzGiIe6WLOPqycWXA40l+PWsxthUw==} @@ -4694,8 +4694,8 @@ packages: resolution: {integrity: sha512-tJtZBBHA6vjIAaF6EnIaq6laBBP9aq/Y3ouVJjEfoHbRBcHBAHYcMh/w8LDrk2PvIMMq8gmopa5D4V8RmbrxGw==} engines: {node: '>= 0.10'} - cosmiconfig@9.0.1: - resolution: {integrity: sha512-hr4ihw+DBqcvrsEDioRO31Z17x71pUYoNe/4h6Z0wB72p7MU7/9gH8Q3s12NFhHPfYBBOV3qyfUxmr/Yn3shnQ==} + cosmiconfig@9.0.2: + resolution: {integrity: sha512-gtTZxTDau1wL7Y7zifc2dd8jHSK/k6BTx/2Xp/BpdlAdnlYWFVt7qhJqgwi7637yRwRQ3qL4ZidbB4I8tA5VOg==} engines: {node: '>=14'} peerDependencies: typescript: '>=4.9.5' @@ -4948,8 +4948,8 @@ packages: engines: {node: '>=0.12.18'} hasBin: true - electron-to-chromium@1.5.366: - resolution: {integrity: sha512-OlRuhb688YTCzzU3gXPLn6nGyd+F+53INE1qaKKlu6kETErE8FYsyDh0XqXEU+uBRn0MpCzz2vfNwORhkap8qg==} + electron-to-chromium@1.5.368: + resolution: {integrity: sha512-7RckJJK4uESJF9PxvfMWd3TGqIiieUTG4HxnKaKuIpGbcr+r2ZEB3g2gAhCP3Fqm42vJSzLfgab9eva/C4/XVw==} emoji-regex@10.6.0: resolution: {integrity: sha512-toUI84YS5YmxW219erniWD0CIVOo46xGKColeNQRgOzDorgBi1v4D71/OFzgD9GO2UGKIv1C3Sp8DAn0+j5w7A==} @@ -4989,8 +4989,8 @@ packages: resolution: {integrity: sha512-2agL3ueZhqxoVrfmntO8yuVj+uNSlIOnhykYHk3Cq0ShYPdUjjUiSJrQvXjq01I9jAuI0Zl2YO8Evv5Mqytm5g==} engines: {node: '>=10.2.0'} - enhanced-resolve@5.22.1: - resolution: {integrity: sha512-6QEuw3zoX1SJQc7b87aBXke/no+mG2bTBgw29gWMQonLmpEkWoCAVkl+M49e48AZlWzxiDzDZzYdp6kobcyLww==} + enhanced-resolve@5.23.0: + resolution: {integrity: sha512-yJN/BOOLxcOW2aQgeif9mSnaUB8KtvmMMp56oA1kx1CRfBKbhZm2pJ+NBY+3eOboHxix8lfjWpHE0Ei5U8RbSA==} engines: {node: '>=10.13.0'} ent@2.2.2: @@ -5439,14 +5439,22 @@ packages: resolution: {integrity: sha512-plz8RVjfcDedTGfVngWH1jmJvBvAwi1v2jecfDerbEnMcmOYUEEwKFTHbNoCiYyzaK2Ws8lABkTCcRSqCY1q4w==} engines: {node: '>=10'} - gaxios@7.1.4: - resolution: {integrity: sha512-bTIgTsM2bWn3XklZISBTQX7ZSddGW+IO3bMdGaemHZ3tbqExMENHLx6kKZ/KlejgrMtj8q7wBItt51yegqalrA==} + gaxios@7.1.3: + resolution: {integrity: sha512-YGGyuEdVIjqxkxVH1pUTMY/XtmmsApXrCVv5EU25iX6inEPbV+VakJfLealkBtJN69AQmh1eGOdCl9Sm1UP6XQ==} + engines: {node: '>=18'} + + gaxios@7.1.5: + resolution: {integrity: sha512-5FZy72Rh8LhtjmvDrKkI+lVhrsQrVKVsItxMoDm5mNQE+xR0WVIIs+jzPSJgBvKVsLi24fZhXJIsNI0bihDzFg==} engines: {node: '>=18'} gcp-metadata@8.1.2: resolution: {integrity: sha512-zV/5HKTfCeKWnxG0Dmrw51hEWFGfcF2xiXqcA3+J90WDuP0SvoiSO5ORvcBsifmx/FoIjgQN3oNOGaQ5PhLFkg==} engines: {node: '>=18'} + gcp-metadata@8.1.3: + resolution: {integrity: sha512-ziTrzUhhpL9Zk5k0HHzgP/KIpWDJT0VMBC/ynt/QIBvTW+UUcSivQRl6VlwTf/EilDxtSWklHoRsKy1c4k+59w==} + engines: {node: '>=18'} + generator-function@2.0.1: resolution: {integrity: sha512-SFdFmIJi+ybC0vjlHN0ZGVGHc3lgE0DxPAT0djjVg+kjOnSqclqmj0KQ7ykTOLP6YxoqOvuAODGdcHJn+43q3g==} engines: {node: '>= 0.4'} @@ -5536,12 +5544,16 @@ packages: resolution: {integrity: sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==} engines: {node: '>=10'} - google-auth-library@10.6.2: - resolution: {integrity: sha512-e27Z6EThmVNNvtYASwQxose/G57rkRuaRbQyxM2bvYLLX/GqWZ5chWq2EBoUchJbCc57eC9ArzO5wMsEmWftCw==} + google-auth-library@10.5.0: + resolution: {integrity: sha512-7ABviyMOlX5hIVD60YOfHw4/CxOfBhyduaYB+wbFWCWoni4N7SLcV46hrVRktuBbZjFC9ONyqamZITN7q3n32w==} + engines: {node: '>=18'} + + google-auth-library@10.7.0: + resolution: {integrity: sha512-QpTAbNJ36TliZLx3TTtahR8HG0hN9RllL1e3FymOvQSIKK8JmgV58H924ub2wa2DsS3ANjjP1Aw1N+Ramc8hqQ==} engines: {node: '>=18'} - google-gax@5.0.6: - resolution: {integrity: sha512-1kGbqVQBZPAAu4+/R1XxPQKP0ydbNYoLAr4l0ZO2bMV0kLyLW4I1gAk++qBLWt7DPORTzmWRMsCZe86gDjShJA==} + google-gax@5.0.7: + resolution: {integrity: sha512-EhiqaWWJ+9h7sCcKJTsoo6tMcjokVHhWsbSuWCnZJT4vIBP3y4mAoFLnt9SzgkVZeq24ZsFaArr06nnYYku2yA==} engines: {node: '>=18'} google-logging-utils@1.1.3: @@ -5575,6 +5587,10 @@ packages: peerDependencies: protobufjs: '*' + gtoken@8.0.0: + resolution: {integrity: sha512-+CqsMbHPiSTdtSO14O51eMNlrp9N79gmeqmXeouJOhfucAedHw9noVe/n5uJk3tbKE6a+6ZCQg3RPhVhHByAIw==} + engines: {node: '>=18'} + gunzip-maybe@1.4.2: resolution: {integrity: sha512-4haO1M4mLO91PW57BMsDFf75UmwoRX0GkdD+Faw+Lr+r/OZrOCS0pIBwOL1xCKQqnQzbNFGgK2V2CpBUPeFNTw==} hasBin: true @@ -6404,8 +6420,8 @@ packages: resolution: {integrity: sha512-aisnrDP4GNe06UcKFnV5bfMNPBUw4jsLGaWwWfnH3v02GnBuXX2MCVn5RbrWo0j3pczUilYblq7fQ7Nw2t5XKw==} engines: {node: '>= 0.8'} - memfs@4.57.5: - resolution: {integrity: sha512-qT8bQJyjF6+DsDI9X1yMwUyIkYHrZI8D2PaWjze8aUUbGUkcNlxppcRZF/0VWesIPHtgx6T2mLx3qPmTQxUd6A==} + memfs@4.57.6: + resolution: {integrity: sha512-WQK+DGjKCnPdpSyJUXphz+COF2uEhhsxQ3VIWBSbzpbbXuch3h4FePMqXrXGdLjsTgo4JFzBFsP6AWd9pVazGw==} peerDependencies: tslib: '2' @@ -6570,8 +6586,8 @@ packages: resolution: {integrity: sha512-4kmO/MdyUIkLIvTPr8VHLil4AtoKIoniWPIEk5+CDy0xnWC84azhSFmuJ7PxZdsYtiP5kEeQsORAVIeMgxT+Hw==} hasBin: true - msgpackr@1.11.12: - resolution: {integrity: sha512-RBdJ1Un7yGlXWajrkxcSa93nvQ0w4zBf60c0yYv7YtBelP8H2FA7XsfBbMHtXKXUMUxH7zV3Zuozh+kUQWhHvg==} + msgpackr@1.11.13: + resolution: {integrity: sha512-pWaxg0k1iiNdkAayUQ7Zlz/vYNfVefUttmHxqFcQjjtyqFa3w4x5rginOEzy/GvbWhBDD9K65/ZXyq8qz8utaQ==} multicast-dns@7.2.5: resolution: {integrity: sha512-2eznPJP8z2BFLX50tf0LuODrpINqP1RVIm/CObbTcBRITQgmC/TjcREF1NeTBzIcR5XO/ukWo+YHOjBbFwIupg==} @@ -6678,8 +6694,8 @@ packages: resolution: {integrity: sha512-LA4ZjwlnUblHVgq0oBF3Jl/6h/Nvs5fzBLwdEF4nuxnFdsfajde4WfxtJr3CaiH+F6ewcIB/q4jQ4UzPyid+CQ==} hasBin: true - node-gyp@12.3.0: - resolution: {integrity: sha512-QNcUWM+HgJplcPzBvFBZ9VXacyGZ4+VTOb80PwWR+TlVzoHbRKULNEzpRsnaoxG3Wzr7Qh7BYxGDU3CbKib2Yg==} + node-gyp@12.4.0: + resolution: {integrity: sha512-OMcPNvqTCFUnNaBlmdgq+lfNqY7gTiSmNRDjY3uAXRyudeKZEZxu3CLtjMQrx4zZxCX2b/mpNqTtwuCJgXhHkw==} engines: {node: ^20.17.0 || >=22.9.0} hasBin: true @@ -6774,8 +6790,9 @@ packages: obuf@1.1.2: resolution: {integrity: sha512-PX1wu0AmAdPqOL1mWhqmlOd8kOIZQwGZw6rh7uby9fTc5lhaOWFLX3I6R1hrF9k3zUY40e6igsLGkDXK92LJNg==} - obug@2.1.1: - resolution: {integrity: sha512-uTqF9MuPraAQ+IsnPf366RG4cP9RtUi7MLO1N3KEc+wb0a6yKpeL0lmk2IB1jY5KHPAlTc6T/JRdC/YqxHNwkQ==} + obug@2.1.2: + resolution: {integrity: sha512-AWGB9WFcRXOQs48Z/udjI5ZcZMHXwX8XPByNpOydgcGsDLIzjGizhoMWJyKAWze7AVW/2W1i+/gPX4YtKe5cyg==} + engines: {node: '>=12.20.0'} on-exit-leak-free@2.1.2: resolution: {integrity: sha512-0eJJY6hXLGf1udHwfNftBqH+g73EU4B504nZeKpz1sYRKafAghwxEJunB2O7rDZkL4PGfsMVnTXZ2EjibbqcsA==} @@ -7291,8 +7308,8 @@ packages: resolution: {integrity: sha512-oMA2dcrw6u0YfxJQXm342bFKX/E4sG9rbTzO9ptUcR/e8A33cHuvStiYOwH7fszkZlZ1z/ta9AAoPk2F4qIOHA==} engines: {node: '>=18'} - retry-request@8.0.2: - resolution: {integrity: sha512-JzFPAfklk1kjR1w76f0QOIhoDkNkSqW8wYKT08n9yysTmZfB+RQ2QoXoTAeOi1HD9ZipTyTAZg3c4pM/jeqgSw==} + retry-request@8.0.3: + resolution: {integrity: sha512-qqoc4kkGgP9cmQDWELlOpAmfgJOg0Yi7MT82ZjiPWu451ayju4itwomjM4/dBEliify8C1b3tSaeCOldugtwPQ==} engines: {node: '>=18'} retry@0.13.1: @@ -7705,8 +7722,8 @@ packages: resolution: {integrity: sha512-KFxaM7XT+irxvdqSP1LGLgNWbYN7ay5owZ3r/8t77p+EtSUAfUgtl7be3xtqtOmGUl9K9YPO2ca8133RlTjvKw==} engines: {node: '>=8.0'} - streamx@2.26.0: - resolution: {integrity: sha512-VvNG1K72Po/xwJzxZFnZ++Tbrv4lwSptsbkFuzXCJAYZvCK5nnxsvXU6ajqkv7chyiI1Y0YXq2Jh8Iy8Y7NF/A==} + streamx@2.27.0: + resolution: {integrity: sha512-WZ189TKnHoAokYHvwzaAQMpd55cgUmFIcJFzBSgGcb886jau5DL+XdDhTWV4ps3FLvk+OORp0dLRTPsLZ21CSA==} strict-event-emitter@0.5.1: resolution: {integrity: sha512-vMgjE/GGEPEFnhFub6pa4FmJBRBVOLpIII2hvCZ8Kzb7K0hlHo7mQv6xYrBvCL2LtAIBwFUK8wvuJgTVSQ5MFQ==} @@ -7727,12 +7744,12 @@ packages: resolution: {integrity: sha512-IIaP0g3iy9Cyy18w3M9YcaDudujEAVHKt3a3QJg1+sr/oX96TbaGUubG0hJyCjCBThFH+tFpcIyoUHUn1ogaLA==} engines: {node: '>=20'} - string.prototype.trim@1.2.10: - resolution: {integrity: sha512-Rs66F0P/1kedk5lyYyH9uBzuiI/kNRmwJAR9quK6VOtIpZ2G+hMZd+HQbbv25MgCA6gEffoMZYxlTod4WcdrKA==} + string.prototype.trim@1.2.11: + resolution: {integrity: sha512-PwvK7BU+CMTJGYQCTZb5RWXIML92lftJLhQz1tBzgKiqGxJaMlBAa48POXaNAC2s4y8jr3EFqrkF9+44neS46w==} engines: {node: '>= 0.4'} - string.prototype.trimend@1.0.9: - resolution: {integrity: sha512-G7Ok5C6E/j4SGfyLCloXTrngQIQU3PWtXGst3yM7Bea9FRURf1S42ZHlZZtsNque2FN2PoUhfZXYLNWwEr4dLQ==} + string.prototype.trimend@1.0.10: + resolution: {integrity: sha512-2+3aDAOmPTmuFwjDnmJG2ctEkQKVki7vOSqaxkv42Mowj1V6PnvuwFCRrR5lChUux1TBskPjfkeTOhqczDMxTw==} engines: {node: '>= 0.4'} string.prototype.trimstart@1.0.8: @@ -7797,8 +7814,8 @@ packages: resolution: {integrity: sha512-56adEpPMouktRlBLXiaYFFzZ/3+JXa8P9n7WbR+ibIjtviN55mEaOkiysCnPnWm+7kkui1Dn8J9l+g6zV8731w==} engines: {node: '>=18'} - teeny-request@10.1.2: - resolution: {integrity: sha512-Xj0ZAQ0CeuQn6UxCDPLbFRlgcSTUEyO3+wiepr2grjIjyL/lMMs1Z4OwXn8kLvn/V1OuaEP0UY7Na6UDNNsYrQ==} + teeny-request@10.1.3: + resolution: {integrity: sha512-5yDliI1uWkYPo7W+Zvrxg6YmoWuj5iC5EydewqrRTvc68nyMTZhlPPlLg6cptUGfbQAb+N9XDPDPzF6N081lug==} engines: {node: '>=18'} teex@1.0.1: @@ -8058,8 +8075,8 @@ packages: resolution: {integrity: sha512-4yqz8a3n5HmGTlsbADNtr/dJlhkh/55Rq798G6ibiULcXbDtaLpTl1pvdqcbFfeoj3iSi52lePFM7h9H21cw/A==} engines: {node: '>=18.17'} - undici@7.27.0: - resolution: {integrity: sha512-+t2Z/GwkZQDtu00813aP66ygViGtPHKhhoFZpQKpKrE+9jIgES+Zw+mFNaDWOVRKiuJjuqKHzD3B1sfGg8+ZOQ==} + undici@7.27.2: + resolution: {integrity: sha512-uZsKNuzQxDMUY6M3pIMvy5tvlGmtq8XJ2oLAkfRKGNu+1VQAIvLy2xIVG5ATZl5wDXl/tddByAWCizRbOme+TA==} engines: {node: '>=20.18.1'} undici@8.3.0: @@ -8350,8 +8367,8 @@ packages: webpack-cli: optional: true - websocket-driver@0.7.4: - resolution: {integrity: sha512-b17KeDIQVjvb0ssuSDF2cYXSg2iztliJ4B9WdsuB6J952qCPKmnVq4DyW5motImXHDC1cBT/1UezrJVsKw5zjg==} + websocket-driver@0.7.5: + resolution: {integrity: sha512-ZL2+3c7kMBdIRCMz6l8jQMHyGVxj+UL+xVk74Ombiciboca8rHa15L86B19E5oh1pL9Ii/uj54gtsIrZGMo6zA==} engines: {node: '>=0.8.0'} websocket-extensions@0.1.4: @@ -8381,8 +8398,8 @@ packages: resolution: {integrity: sha512-K4jVyjnBdgvc86Y6BkaLZEN933SwYOuBFkdmBu9ZfkcAbdVbpITnDmjvZ/aQjRXQrv5EPkTnD1s39GiiqbngCw==} engines: {node: '>= 0.4'} - which-typed-array@1.1.21: - resolution: {integrity: sha512-zbRA8cVm6io/d5W8uIe2hblzN76/Wm3v/yiythQvr+dpBWeqhPSWIDNj4zOyHi4zKbMK6DN34Xsr9jPHJERAEw==} + which-typed-array@1.1.22: + resolution: {integrity: sha512-fvO4ExWMFsqyhG3AiPAObMuY1lxaqgYcxbc49CNdWDDECOJNgQyvsOWVwbZc+qf3rzRtxojBK+CMEv0Ld5CYpw==} engines: {node: '>= 0.4'} which@1.3.1: @@ -9601,7 +9618,7 @@ snapshots: dependencies: '@csstools/css-tokenizer': 4.0.0 - '@csstools/css-syntax-patches-for-csstree@1.1.4(css-tree@3.2.1)': + '@csstools/css-syntax-patches-for-csstree@1.1.5(css-tree@3.2.1)': optionalDependencies: css-tree: 3.2.1 @@ -10182,36 +10199,36 @@ snapshots: '@glideapps/ts-necessities@2.2.3': {} - '@google-cloud/common@6.0.0(supports-color@10.2.2)': + '@google-cloud/common@6.0.1(supports-color@10.2.2)': dependencies: '@google-cloud/projectify': 4.0.0 '@google-cloud/promisify': 4.1.0 arrify: 2.0.1 duplexify: 4.1.3 extend: 3.0.2 - google-auth-library: 10.6.2(supports-color@10.2.2) + google-auth-library: 10.7.0(supports-color@10.2.2) html-entities: 2.6.0 - retry-request: 8.0.2(supports-color@10.2.2) - teeny-request: 10.1.2(supports-color@10.2.2) + retry-request: 8.0.3(supports-color@10.2.2) + teeny-request: 10.1.3(supports-color@10.2.2) transitivePeerDependencies: - supports-color - '@google-cloud/precise-date@5.0.0': {} + '@google-cloud/precise-date@5.0.1': {} '@google-cloud/projectify@4.0.0': {} - '@google-cloud/projectify@5.0.0': {} + '@google-cloud/projectify@5.0.1': {} '@google-cloud/promisify@4.1.0': {} - '@google-cloud/promisify@5.0.0': {} + '@google-cloud/promisify@5.0.1': {} '@google-cloud/spanner@8.0.0(supports-color@10.2.2)': dependencies: - '@google-cloud/common': 6.0.0(supports-color@10.2.2) - '@google-cloud/precise-date': 5.0.0 - '@google-cloud/projectify': 5.0.0 - '@google-cloud/promisify': 5.0.0 + '@google-cloud/common': 6.0.1(supports-color@10.2.2) + '@google-cloud/precise-date': 5.0.1 + '@google-cloud/projectify': 5.0.1 + '@google-cloud/promisify': 5.0.1 '@grpc/proto-loader': 0.7.15 '@opentelemetry/api': 1.9.1 '@opentelemetry/context-async-hooks': 2.7.1(@opentelemetry/api@1.9.1) @@ -10224,26 +10241,26 @@ snapshots: duplexify: 4.1.3 events-intercept: 2.0.0 extend: 3.0.2 - google-auth-library: 10.6.2(supports-color@10.2.2) - google-gax: 5.0.6(supports-color@10.2.2) + google-auth-library: 10.7.0(supports-color@10.2.2) + google-gax: 5.0.7(supports-color@10.2.2) grpc-gcp: 1.0.1(protobufjs@7.6.2) is: 3.3.2 lodash.snakecase: 4.1.1 merge-stream: 2.0.0 p-queue: 6.6.2 protobufjs: 7.6.2 - retry-request: 8.0.2(supports-color@10.2.2) + retry-request: 8.0.3(supports-color@10.2.2) split-array-stream: 2.0.0 stack-trace: 0.0.10 stream-events: 1.0.5 - teeny-request: 10.1.2(supports-color@10.2.2) + teeny-request: 10.1.3(supports-color@10.2.2) through2: 4.0.2 transitivePeerDependencies: - supports-color '@google/genai@2.7.0(@modelcontextprotocol/sdk@1.29.0(zod@4.4.3))(bufferutil@4.1.0)(supports-color@10.2.2)(utf-8-validate@6.0.6)': dependencies: - google-auth-library: 10.6.2(supports-color@10.2.2) + google-auth-library: 10.7.0(supports-color@10.2.2) p-retry: 4.6.2 protobufjs: 7.6.2 ws: 8.21.0(bufferutil@4.1.0)(utf-8-validate@6.0.6) @@ -10262,7 +10279,7 @@ snapshots: '@grpc/grpc-js@1.9.16': dependencies: '@grpc/proto-loader': 0.7.15 - '@types/node': 22.19.19 + '@types/node': 22.19.20 '@grpc/proto-loader@0.7.15': dependencies: @@ -10487,58 +10504,58 @@ snapshots: dependencies: tslib: 2.8.1 - '@jsonjoy.com/fs-core@4.57.5(tslib@2.8.1)': + '@jsonjoy.com/fs-core@4.57.6(tslib@2.8.1)': dependencies: - '@jsonjoy.com/fs-node-builtins': 4.57.5(tslib@2.8.1) - '@jsonjoy.com/fs-node-utils': 4.57.5(tslib@2.8.1) + '@jsonjoy.com/fs-node-builtins': 4.57.6(tslib@2.8.1) + '@jsonjoy.com/fs-node-utils': 4.57.6(tslib@2.8.1) thingies: 2.6.0(tslib@2.8.1) tslib: 2.8.1 - '@jsonjoy.com/fs-fsa@4.57.5(tslib@2.8.1)': + '@jsonjoy.com/fs-fsa@4.57.6(tslib@2.8.1)': dependencies: - '@jsonjoy.com/fs-core': 4.57.5(tslib@2.8.1) - '@jsonjoy.com/fs-node-builtins': 4.57.5(tslib@2.8.1) - '@jsonjoy.com/fs-node-utils': 4.57.5(tslib@2.8.1) + '@jsonjoy.com/fs-core': 4.57.6(tslib@2.8.1) + '@jsonjoy.com/fs-node-builtins': 4.57.6(tslib@2.8.1) + '@jsonjoy.com/fs-node-utils': 4.57.6(tslib@2.8.1) thingies: 2.6.0(tslib@2.8.1) tslib: 2.8.1 - '@jsonjoy.com/fs-node-builtins@4.57.5(tslib@2.8.1)': + '@jsonjoy.com/fs-node-builtins@4.57.6(tslib@2.8.1)': dependencies: tslib: 2.8.1 - '@jsonjoy.com/fs-node-to-fsa@4.57.5(tslib@2.8.1)': + '@jsonjoy.com/fs-node-to-fsa@4.57.6(tslib@2.8.1)': dependencies: - '@jsonjoy.com/fs-fsa': 4.57.5(tslib@2.8.1) - '@jsonjoy.com/fs-node-builtins': 4.57.5(tslib@2.8.1) - '@jsonjoy.com/fs-node-utils': 4.57.5(tslib@2.8.1) + '@jsonjoy.com/fs-fsa': 4.57.6(tslib@2.8.1) + '@jsonjoy.com/fs-node-builtins': 4.57.6(tslib@2.8.1) + '@jsonjoy.com/fs-node-utils': 4.57.6(tslib@2.8.1) tslib: 2.8.1 - '@jsonjoy.com/fs-node-utils@4.57.5(tslib@2.8.1)': + '@jsonjoy.com/fs-node-utils@4.57.6(tslib@2.8.1)': dependencies: - '@jsonjoy.com/fs-node-builtins': 4.57.5(tslib@2.8.1) + '@jsonjoy.com/fs-node-builtins': 4.57.6(tslib@2.8.1) tslib: 2.8.1 - '@jsonjoy.com/fs-node@4.57.5(tslib@2.8.1)': + '@jsonjoy.com/fs-node@4.57.6(tslib@2.8.1)': dependencies: - '@jsonjoy.com/fs-core': 4.57.5(tslib@2.8.1) - '@jsonjoy.com/fs-node-builtins': 4.57.5(tslib@2.8.1) - '@jsonjoy.com/fs-node-utils': 4.57.5(tslib@2.8.1) - '@jsonjoy.com/fs-print': 4.57.5(tslib@2.8.1) - '@jsonjoy.com/fs-snapshot': 4.57.5(tslib@2.8.1) + '@jsonjoy.com/fs-core': 4.57.6(tslib@2.8.1) + '@jsonjoy.com/fs-node-builtins': 4.57.6(tslib@2.8.1) + '@jsonjoy.com/fs-node-utils': 4.57.6(tslib@2.8.1) + '@jsonjoy.com/fs-print': 4.57.6(tslib@2.8.1) + '@jsonjoy.com/fs-snapshot': 4.57.6(tslib@2.8.1) glob-to-regex.js: 1.2.0(tslib@2.8.1) thingies: 2.6.0(tslib@2.8.1) tslib: 2.8.1 - '@jsonjoy.com/fs-print@4.57.5(tslib@2.8.1)': + '@jsonjoy.com/fs-print@4.57.6(tslib@2.8.1)': dependencies: - '@jsonjoy.com/fs-node-utils': 4.57.5(tslib@2.8.1) + '@jsonjoy.com/fs-node-utils': 4.57.6(tslib@2.8.1) tree-dump: 1.1.0(tslib@2.8.1) tslib: 2.8.1 - '@jsonjoy.com/fs-snapshot@4.57.5(tslib@2.8.1)': + '@jsonjoy.com/fs-snapshot@4.57.6(tslib@2.8.1)': dependencies: '@jsonjoy.com/buffers': 17.67.0(tslib@2.8.1) - '@jsonjoy.com/fs-node-utils': 4.57.5(tslib@2.8.1) + '@jsonjoy.com/fs-node-utils': 4.57.6(tslib@2.8.1) '@jsonjoy.com/json-pack': 17.67.0(tslib@2.8.1) '@jsonjoy.com/util': 17.67.0(tslib@2.8.1) tslib: 2.8.1 @@ -10816,7 +10833,7 @@ snapshots: '@npmcli/node-gyp': 5.0.0 '@npmcli/package-json': 7.0.5 '@npmcli/promise-spawn': 9.0.1 - node-gyp: 12.3.0 + node-gyp: 12.4.0 proc-log: 6.1.0 '@octokit/auth-app@8.2.0': @@ -11443,16 +11460,16 @@ snapshots: '@types/body-parser@1.19.6': dependencies: '@types/connect': 3.4.38 - '@types/node': 22.19.19 + '@types/node': 22.19.20 '@types/bonjour@3.5.13': dependencies: - '@types/node': 22.19.19 + '@types/node': 22.19.20 '@types/browser-sync@2.29.1': dependencies: '@types/micromatch': 2.3.35 - '@types/node': 22.19.19 + '@types/node': 22.19.20 '@types/serve-static': 2.2.0 chokidar: 3.6.0 @@ -11463,26 +11480,26 @@ snapshots: '@types/cli-progress@3.11.6': dependencies: - '@types/node': 22.19.19 + '@types/node': 22.19.20 '@types/connect-history-api-fallback@1.5.4': dependencies: '@types/express-serve-static-core': 4.19.8 - '@types/node': 22.19.19 + '@types/node': 22.19.20 '@types/connect@3.4.38': dependencies: - '@types/node': 22.19.19 + '@types/node': 22.19.20 '@types/cors@2.8.19': dependencies: - '@types/node': 22.19.19 + '@types/node': 22.19.20 '@types/deep-eql@4.0.2': {} '@types/duplexify@3.6.5': dependencies: - '@types/node': 22.19.19 + '@types/node': 22.19.20 '@types/ejs@3.1.5': {} @@ -11494,14 +11511,14 @@ snapshots: '@types/express-serve-static-core@4.19.8': dependencies: - '@types/node': 22.19.19 + '@types/node': 22.19.20 '@types/qs': 6.15.1 '@types/range-parser': 1.2.7 '@types/send': 1.2.1 '@types/express-serve-static-core@5.1.1': dependencies: - '@types/node': 22.19.19 + '@types/node': 22.19.20 '@types/qs': 6.15.1 '@types/range-parser': 1.2.7 '@types/send': 1.2.1 @@ -11523,13 +11540,13 @@ snapshots: '@types/graceful-fs@4.1.9': dependencies: - '@types/node': 22.19.19 + '@types/node': 22.19.20 '@types/http-errors@2.0.5': {} '@types/http-proxy@1.17.17': dependencies: - '@types/node': 22.19.19 + '@types/node': 22.19.20 '@types/ini@4.1.1': {} @@ -11545,7 +11562,7 @@ snapshots: '@types/karma@6.3.9': dependencies: - '@types/node': 22.19.19 + '@types/node': 22.19.20 log4js: 6.9.1 transitivePeerDependencies: - supports-color @@ -11554,7 +11571,7 @@ snapshots: '@types/loader-utils@3.0.0(esbuild@0.28.0)': dependencies: - '@types/node': 22.19.19 + '@types/node': 22.19.20 webpack: 5.107.2(esbuild@0.28.0) transitivePeerDependencies: - '@minify-html/node' @@ -11581,10 +11598,10 @@ snapshots: '@types/node-fetch@2.6.13': dependencies: - '@types/node': 22.19.19 + '@types/node': 22.19.20 form-data: 4.0.5 - '@types/node@22.19.19': + '@types/node@22.19.20': dependencies: undici-types: 6.21.0 @@ -11596,7 +11613,7 @@ snapshots: '@types/npm-registry-fetch@8.0.9': dependencies: - '@types/node': 22.19.19 + '@types/node': 22.19.20 '@types/node-fetch': 2.6.13 '@types/npm-package-arg': 6.1.4 '@types/npmlog': 7.0.0 @@ -11604,11 +11621,11 @@ snapshots: '@types/npmlog@7.0.0': dependencies: - '@types/node': 22.19.19 + '@types/node': 22.19.20 '@types/pacote@11.1.8': dependencies: - '@types/node': 22.19.19 + '@types/node': 22.19.20 '@types/npm-registry-fetch': 8.0.9 '@types/npmlog': 7.0.0 '@types/ssri': 7.1.5 @@ -11619,12 +11636,12 @@ snapshots: '@types/progress@2.0.7': dependencies: - '@types/node': 22.19.19 + '@types/node': 22.19.20 '@types/pumpify@1.4.5': dependencies: '@types/duplexify': 3.6.5 - '@types/node': 22.19.19 + '@types/node': 22.19.20 '@types/qs@6.15.1': {} @@ -11634,7 +11651,7 @@ snapshots: '@types/responselike@1.0.0': dependencies: - '@types/node': 22.19.19 + '@types/node': 22.19.20 '@types/retry@0.12.0': {} @@ -11645,11 +11662,11 @@ snapshots: '@types/send@0.17.6': dependencies: '@types/mime': 1.3.5 - '@types/node': 22.19.19 + '@types/node': 22.19.20 '@types/send@1.2.1': dependencies: - '@types/node': 22.19.19 + '@types/node': 22.19.20 '@types/serve-index@1.9.4': dependencies: @@ -11658,38 +11675,38 @@ snapshots: '@types/serve-static@1.15.10': dependencies: '@types/http-errors': 2.0.5 - '@types/node': 22.19.19 + '@types/node': 22.19.20 '@types/send': 0.17.6 '@types/serve-static@2.2.0': dependencies: '@types/http-errors': 2.0.5 - '@types/node': 22.19.19 + '@types/node': 22.19.20 '@types/sockjs@0.3.36': dependencies: - '@types/node': 22.19.19 + '@types/node': 22.19.20 '@types/ssri@7.1.5': dependencies: - '@types/node': 22.19.19 + '@types/node': 22.19.20 '@types/stack-trace@0.0.33': {} '@types/tar-stream@3.1.4': dependencies: - '@types/node': 22.19.19 + '@types/node': 22.19.20 '@types/watchpack@2.4.5': dependencies: '@types/graceful-fs': 4.1.9 - '@types/node': 22.19.19 + '@types/node': 22.19.20 '@types/which@3.0.4': {} '@types/ws@8.18.1': dependencies: - '@types/node': 22.19.19 + '@types/node': 22.19.20 '@types/yargs-parser@21.0.3': {} @@ -11965,7 +11982,7 @@ snapshots: istanbul-lib-report: 3.0.1 istanbul-reports: 3.2.0 magicast: 0.5.3 - obug: 2.1.1 + obug: 2.1.2 std-env: 4.1.0 tinyrainbow: 3.1.0 vitest: 4.1.8(@opentelemetry/api@1.9.1)(@types/node@24.12.4)(@vitest/coverage-v8@4.1.8)(jiti@2.7.0)(jsdom@29.1.1)(less@4.6.4)(sass@1.100.0)(terser@5.48.0)(tsx@4.22.4)(yaml@2.9.0) @@ -12316,7 +12333,7 @@ snapshots: autoprefixer@10.5.0(postcss@8.5.15): dependencies: browserslist: 4.28.2 - caniuse-lite: 1.0.30001793 + caniuse-lite: 1.0.30001797 fraction.js: 5.3.4 picocolors: 1.1.1 postcss: 8.5.15 @@ -12382,7 +12399,7 @@ snapshots: bare-events: 2.9.1 bare-path: 3.0.1 bare-stream: 2.13.1(bare-events@2.9.1) - bare-url: 2.4.3 + bare-url: 2.4.5 fast-fifo: 1.3.2 transitivePeerDependencies: - bare-abort-controller @@ -12396,14 +12413,14 @@ snapshots: bare-stream@2.13.1(bare-events@2.9.1): dependencies: - streamx: 2.26.0 + streamx: 2.27.0 teex: 1.0.1 optionalDependencies: bare-events: 2.9.1 transitivePeerDependencies: - react-native-b4a - bare-url@2.4.3: + bare-url@2.4.5: dependencies: bare-path: 3.0.1 @@ -12411,7 +12428,7 @@ snapshots: base64id@2.0.0: {} - baseline-browser-mapping@2.10.33: {} + baseline-browser-mapping@2.10.34: {} batch@0.6.1: {} @@ -12566,9 +12583,9 @@ snapshots: browserslist@4.28.2: dependencies: - baseline-browser-mapping: 2.10.33 - caniuse-lite: 1.0.30001793 - electron-to-chromium: 1.5.366 + baseline-browser-mapping: 2.10.34 + caniuse-lite: 1.0.30001797 + electron-to-chromium: 1.5.368 node-releases: 2.0.47 update-browserslist-db: 1.2.3(browserslist@4.28.2) @@ -12639,7 +12656,7 @@ snapshots: callsites@3.1.0: {} - caniuse-lite@1.0.30001793: {} + caniuse-lite@1.0.30001797: {} caseless@0.12.0: {} @@ -12856,7 +12873,7 @@ snapshots: object-assign: 4.1.1 vary: 1.1.2 - cosmiconfig@9.0.1(typescript@6.0.3): + cosmiconfig@9.0.2(typescript@6.0.3): dependencies: env-paths: 2.2.1 import-fresh: 3.3.1 @@ -13100,7 +13117,7 @@ snapshots: ejs@5.0.2: {} - electron-to-chromium@1.5.366: {} + electron-to-chromium@1.5.368: {} emoji-regex@10.6.0: {} @@ -13139,7 +13156,7 @@ snapshots: engine.io@6.6.8(bufferutil@4.1.0)(utf-8-validate@6.0.6): dependencies: '@types/cors': 2.8.19 - '@types/node': 22.19.19 + '@types/node': 22.19.20 '@types/ws': 8.18.1 accepts: 1.3.8 base64id: 2.0.0 @@ -13153,7 +13170,7 @@ snapshots: - supports-color - utf-8-validate - enhanced-resolve@5.22.1: + enhanced-resolve@5.23.0: dependencies: graceful-fs: 4.2.11 tapable: 2.3.3 @@ -13233,15 +13250,15 @@ snapshots: safe-regex-test: 1.1.0 set-proto: 1.0.0 stop-iteration-iterator: 1.1.0 - string.prototype.trim: 1.2.10 - string.prototype.trimend: 1.0.9 + string.prototype.trim: 1.2.11 + string.prototype.trimend: 1.0.10 string.prototype.trimstart: 1.0.8 typed-array-buffer: 1.0.3 typed-array-byte-length: 1.0.3 typed-array-byte-offset: 1.0.4 typed-array-length: 1.0.8 unbox-primitive: 1.1.0 - which-typed-array: 1.1.21 + which-typed-array: 1.1.22 es-define-property@1.0.1: {} @@ -13378,7 +13395,7 @@ snapshots: object.groupby: 1.0.3 object.values: 1.2.1 semver: 6.3.1 - string.prototype.trimend: 1.0.9 + string.prototype.trimend: 1.0.10 tsconfig-paths: 3.15.0 optionalDependencies: '@typescript-eslint/parser': 8.60.1(eslint@10.4.1(jiti@2.7.0))(typescript@6.0.3) @@ -13652,7 +13669,7 @@ snapshots: faye-websocket@0.11.4: dependencies: - websocket-driver: 0.7.4 + websocket-driver: 0.7.5 fdir@6.5.0(picomatch@4.0.4): optionalDependencies: @@ -13850,7 +13867,16 @@ snapshots: fuse.js@7.3.0: {} - gaxios@7.1.4(supports-color@10.2.2): + gaxios@7.1.3(supports-color@10.2.2): + dependencies: + extend: 3.0.2 + https-proxy-agent: 7.0.6(supports-color@10.2.2) + node-fetch: 3.3.2 + rimraf: 5.0.10 + transitivePeerDependencies: + - supports-color + + gaxios@7.1.5(supports-color@10.2.2): dependencies: extend: 3.0.2 https-proxy-agent: 7.0.6(supports-color@10.2.2) @@ -13860,7 +13886,15 @@ snapshots: gcp-metadata@8.1.2(supports-color@10.2.2): dependencies: - gaxios: 7.1.4(supports-color@10.2.2) + gaxios: 7.1.5(supports-color@10.2.2) + google-logging-utils: 1.1.3 + json-bigint: 1.0.0 + transitivePeerDependencies: + - supports-color + + gcp-metadata@8.1.3(supports-color@10.2.2): + dependencies: + gaxios: 7.1.3(supports-color@10.2.2) google-logging-utils: 1.1.3 json-bigint: 1.0.0 transitivePeerDependencies: @@ -13966,29 +14000,41 @@ snapshots: merge2: 1.4.1 slash: 3.0.0 - google-auth-library@10.6.2(supports-color@10.2.2): + google-auth-library@10.5.0(supports-color@10.2.2): + dependencies: + base64-js: 1.5.1 + ecdsa-sig-formatter: 1.0.11 + gaxios: 7.1.5(supports-color@10.2.2) + gcp-metadata: 8.1.3(supports-color@10.2.2) + google-logging-utils: 1.1.3 + gtoken: 8.0.0(supports-color@10.2.2) + jws: 4.0.1 + transitivePeerDependencies: + - supports-color + + google-auth-library@10.7.0(supports-color@10.2.2): dependencies: base64-js: 1.5.1 ecdsa-sig-formatter: 1.0.11 - gaxios: 7.1.4(supports-color@10.2.2) + gaxios: 7.1.5(supports-color@10.2.2) gcp-metadata: 8.1.2(supports-color@10.2.2) google-logging-utils: 1.1.3 jws: 4.0.1 transitivePeerDependencies: - supports-color - google-gax@5.0.6(supports-color@10.2.2): + google-gax@5.0.7(supports-color@10.2.2): dependencies: '@grpc/grpc-js': 1.14.4 '@grpc/proto-loader': 0.8.1 duplexify: 4.1.3 - google-auth-library: 10.6.2(supports-color@10.2.2) + google-auth-library: 10.5.0(supports-color@10.2.2) google-logging-utils: 1.1.3 node-fetch: 3.3.2 object-hash: 3.0.0 proto3-json-serializer: 3.0.4 protobufjs: 7.6.2 - retry-request: 8.0.2(supports-color@10.2.2) + retry-request: 8.0.3(supports-color@10.2.2) rimraf: 5.0.10 transitivePeerDependencies: - supports-color @@ -14026,6 +14072,13 @@ snapshots: '@grpc/grpc-js': 1.14.4 protobufjs: 7.6.2 + gtoken@8.0.0(supports-color@10.2.2): + dependencies: + gaxios: 7.1.5(supports-color@10.2.2) + jws: 4.0.1 + transitivePeerDependencies: + - supports-color + gunzip-maybe@1.4.2: dependencies: browserify-zlib: 0.1.4 @@ -14421,7 +14474,7 @@ snapshots: is-typed-array@1.1.15: dependencies: - which-typed-array: 1.1.21 + which-typed-array: 1.1.22 is-typedarray@1.0.0: {} @@ -14532,7 +14585,7 @@ snapshots: jest-worker@27.5.1: dependencies: - '@types/node': 22.19.19 + '@types/node': 22.19.20 merge-stream: 2.0.0 supports-color: 8.1.1 @@ -14561,7 +14614,7 @@ snapshots: '@asamuzakjp/css-color': 5.1.11 '@asamuzakjp/dom-selector': 7.1.1 '@bramus/specificity': 2.4.2 - '@csstools/css-syntax-patches-for-csstree': 1.1.4(css-tree@3.2.1) + '@csstools/css-syntax-patches-for-csstree': 1.1.5(css-tree@3.2.1) '@exodus/bytes': 1.15.1 css-tree: 3.2.1 data-urls: 7.0.0 @@ -14573,7 +14626,7 @@ snapshots: saxes: 6.0.0 symbol-tree: 3.2.4 tough-cookie: 6.0.1 - undici: 7.27.0 + undici: 7.27.2 w3c-xmlserializer: 5.0.0 webidl-conversions: 8.0.1 whatwg-mimetype: 5.0.0 @@ -14778,7 +14831,7 @@ snapshots: lmdb@3.5.5: dependencies: '@harperfast/extended-iterable': 1.0.3 - msgpackr: 1.11.12 + msgpackr: 1.11.13 node-addon-api: 6.1.0 node-gyp-build-optional-packages: 5.2.2 ordered-binary: 1.6.1 @@ -14925,16 +14978,16 @@ snapshots: media-typer@1.1.0: {} - memfs@4.57.5(tslib@2.8.1): + memfs@4.57.6(tslib@2.8.1): dependencies: - '@jsonjoy.com/fs-core': 4.57.5(tslib@2.8.1) - '@jsonjoy.com/fs-fsa': 4.57.5(tslib@2.8.1) - '@jsonjoy.com/fs-node': 4.57.5(tslib@2.8.1) - '@jsonjoy.com/fs-node-builtins': 4.57.5(tslib@2.8.1) - '@jsonjoy.com/fs-node-to-fsa': 4.57.5(tslib@2.8.1) - '@jsonjoy.com/fs-node-utils': 4.57.5(tslib@2.8.1) - '@jsonjoy.com/fs-print': 4.57.5(tslib@2.8.1) - '@jsonjoy.com/fs-snapshot': 4.57.5(tslib@2.8.1) + '@jsonjoy.com/fs-core': 4.57.6(tslib@2.8.1) + '@jsonjoy.com/fs-fsa': 4.57.6(tslib@2.8.1) + '@jsonjoy.com/fs-node': 4.57.6(tslib@2.8.1) + '@jsonjoy.com/fs-node-builtins': 4.57.6(tslib@2.8.1) + '@jsonjoy.com/fs-node-to-fsa': 4.57.6(tslib@2.8.1) + '@jsonjoy.com/fs-node-utils': 4.57.6(tslib@2.8.1) + '@jsonjoy.com/fs-print': 4.57.6(tslib@2.8.1) + '@jsonjoy.com/fs-snapshot': 4.57.6(tslib@2.8.1) '@jsonjoy.com/json-pack': 1.21.0(tslib@2.8.1) '@jsonjoy.com/util': 1.9.0(tslib@2.8.1) glob-to-regex.js: 1.2.0(tslib@2.8.1) @@ -15073,7 +15126,7 @@ snapshots: '@msgpackr-extract/msgpackr-extract-win32-x64': 3.0.4 optional: true - msgpackr@1.11.12: + msgpackr@1.11.13: optionalDependencies: msgpackr-extract: 3.0.4 optional: true @@ -15185,7 +15238,7 @@ snapshots: node-gyp-build@4.8.4: {} - node-gyp@12.3.0: + node-gyp@12.4.0: dependencies: env-paths: 2.2.1 exponential-backoff: 3.1.3 @@ -15307,7 +15360,7 @@ snapshots: obuf@1.1.2: {} - obug@2.1.1: {} + obug@2.1.2: {} on-exit-leak-free@2.1.2: {} @@ -15573,7 +15626,7 @@ snapshots: postcss-loader@8.2.1(postcss@8.5.15)(typescript@6.0.3)(webpack@5.107.2(esbuild@0.28.0)(postcss@8.5.15)): dependencies: - cosmiconfig: 9.0.1(typescript@6.0.3) + cosmiconfig: 9.0.2(typescript@6.0.3) jiti: 2.7.0 postcss: 8.5.15 semver: 7.8.1 @@ -15658,7 +15711,7 @@ snapshots: '@protobufjs/path': 1.1.2 '@protobufjs/pool': 1.1.0 '@protobufjs/utf8': 1.1.1 - '@types/node': 22.19.19 + '@types/node': 22.19.20 long: 5.3.2 proxy-addr@2.0.7: @@ -15907,10 +15960,10 @@ snapshots: onetime: 7.0.0 signal-exit: 4.1.0 - retry-request@8.0.2(supports-color@10.2.2): + retry-request@8.0.3(supports-color@10.2.2): dependencies: extend: 3.0.2 - teeny-request: 10.1.2(supports-color@10.2.2) + teeny-request: 10.1.3(supports-color@10.2.2) transitivePeerDependencies: - supports-color @@ -15967,12 +16020,12 @@ snapshots: optionalDependencies: '@babel/code-frame': 7.29.7 - rollup-plugin-sourcemaps2@0.5.7(@types/node@22.19.19)(rollup@4.61.0): + rollup-plugin-sourcemaps2@0.5.7(@types/node@22.19.20)(rollup@4.61.0): dependencies: '@rollup/pluginutils': 5.3.0(rollup@4.61.0) rollup: 4.61.0 optionalDependencies: - '@types/node': 22.19.19 + '@types/node': 22.19.20 rollup@4.61.0: dependencies: @@ -16311,7 +16364,7 @@ snapshots: dependencies: faye-websocket: 0.11.4 uuid: 8.3.2 - websocket-driver: 0.7.4 + websocket-driver: 0.7.5 socks-proxy-agent@8.0.5: dependencies: @@ -16463,7 +16516,7 @@ snapshots: transitivePeerDependencies: - supports-color - streamx@2.26.0: + streamx@2.27.0: dependencies: events-universal: 1.0.1 fast-fifo: 1.3.2 @@ -16497,7 +16550,7 @@ snapshots: get-east-asian-width: 1.6.0 strip-ansi: 7.2.0 - string.prototype.trim@1.2.10: + string.prototype.trim@1.2.11: dependencies: call-bind: 1.0.9 call-bound: 1.0.4 @@ -16506,8 +16559,9 @@ snapshots: es-abstract: 1.24.2 es-object-atoms: 1.1.2 has-property-descriptors: 1.0.2 + safe-regex-test: 1.1.0 - string.prototype.trimend@1.0.9: + string.prototype.trimend@1.0.10: dependencies: call-bind: 1.0.9 call-bound: 1.0.4 @@ -16562,7 +16616,7 @@ snapshots: dependencies: b4a: 1.8.1 fast-fifo: 1.3.2 - streamx: 2.26.0 + streamx: 2.27.0 transitivePeerDependencies: - bare-abort-controller - react-native-b4a @@ -16572,7 +16626,7 @@ snapshots: b4a: 1.8.1 bare-fs: 4.7.2 fast-fifo: 1.3.2 - streamx: 2.26.0 + streamx: 2.27.0 transitivePeerDependencies: - bare-abort-controller - bare-buffer @@ -16586,7 +16640,7 @@ snapshots: minizlib: 3.1.0 yallist: 5.0.0 - teeny-request@10.1.2(supports-color@10.2.2): + teeny-request@10.1.3(supports-color@10.2.2): dependencies: http-proxy-agent: 7.0.2(supports-color@10.2.2) https-proxy-agent: 7.0.6(supports-color@10.2.2) @@ -16597,7 +16651,7 @@ snapshots: teex@1.0.1: dependencies: - streamx: 2.26.0 + streamx: 2.27.0 transitivePeerDependencies: - bare-abort-controller - react-native-b4a @@ -16833,7 +16887,7 @@ snapshots: undici@6.26.0: {} - undici@7.27.0: {} + undici@7.27.2: {} undici@8.3.0: {} @@ -17013,7 +17067,7 @@ snapshots: es-module-lexer: 2.1.0 expect-type: 1.3.0 magic-string: 0.30.21 - obug: 2.1.1 + obug: 2.1.2 pathe: 2.0.3 picomatch: 4.0.4 std-env: 4.1.0 @@ -17072,7 +17126,7 @@ snapshots: webpack-dev-middleware@7.4.5(tslib@2.8.1)(webpack@5.107.2(esbuild@0.28.0)(postcss@8.5.15)): dependencies: colorette: 2.0.20 - memfs: 4.57.5(tslib@2.8.1) + memfs: 4.57.6(tslib@2.8.1) mime-types: 3.0.2 on-finished: 2.4.1 range-parser: 1.2.1 @@ -17085,7 +17139,7 @@ snapshots: webpack-dev-middleware@7.4.5(tslib@2.8.1)(webpack@5.107.2(esbuild@0.28.0)): dependencies: colorette: 2.0.20 - memfs: 4.57.5(tslib@2.8.1) + memfs: 4.57.6(tslib@2.8.1) mime-types: 3.0.2 on-finished: 2.4.1 range-parser: 1.2.1 @@ -17097,7 +17151,7 @@ snapshots: webpack-dev-middleware@8.0.3(tslib@2.8.1)(webpack@5.107.2(esbuild@0.28.0)(postcss@8.5.15)): dependencies: - memfs: 4.57.5(tslib@2.8.1) + memfs: 4.57.6(tslib@2.8.1) mime-types: 3.0.2 on-finished: 2.4.1 range-parser: 1.2.1 @@ -17209,7 +17263,7 @@ snapshots: acorn-import-phases: 1.0.4(acorn@8.16.0) browserslist: 4.28.2 chrome-trace-event: 1.0.4 - enhanced-resolve: 5.22.1 + enhanced-resolve: 5.23.0 es-module-lexer: 2.1.0 eslint-scope: 5.1.1 events: 3.3.0 @@ -17248,7 +17302,7 @@ snapshots: acorn-import-phases: 1.0.4(acorn@8.16.0) browserslist: 4.28.2 chrome-trace-event: 1.0.4 - enhanced-resolve: 5.22.1 + enhanced-resolve: 5.23.0 es-module-lexer: 2.1.0 eslint-scope: 5.1.1 events: 3.3.0 @@ -17276,7 +17330,7 @@ snapshots: - postcss - uglify-js - websocket-driver@0.7.4: + websocket-driver@0.7.5: dependencies: http-parser-js: 0.5.10 safe-buffer: 5.2.1 @@ -17321,7 +17375,7 @@ snapshots: isarray: 2.0.5 which-boxed-primitive: 1.1.1 which-collection: 1.0.2 - which-typed-array: 1.1.21 + which-typed-array: 1.1.22 which-collection@1.0.2: dependencies: @@ -17330,7 +17384,7 @@ snapshots: is-weakmap: 2.0.2 is-weakset: 2.0.4 - which-typed-array@1.1.21: + which-typed-array@1.1.22: dependencies: available-typed-arrays: 1.0.7 call-bind: 1.0.9 From 96202a3e1ea3900a671d3a049d0ae212f02267b2 Mon Sep 17 00:00:00 2001 From: Angular Robot Date: Tue, 9 Jun 2026 19:06:05 +0000 Subject: [PATCH 025/787] build: update cross-repo angular dependencies See associated pull request for more information. --- MODULE.bazel | 2 +- package.json | 2 +- pnpm-lock.yaml | 12 +++++------ tests/e2e/ng-snapshot/package.json | 32 +++++++++++++++--------------- 4 files changed, 24 insertions(+), 24 deletions(-) diff --git a/MODULE.bazel b/MODULE.bazel index 0da20dc77a64..0e007aeff6a3 100644 --- a/MODULE.bazel +++ b/MODULE.bazel @@ -26,7 +26,7 @@ git_override( bazel_dep(name = "devinfra") git_override( module_name = "devinfra", - commit = "e78f06f32bc0780cfda374af155a1b5dc84fa14d", + commit = "cef5e36af124e7442d7e2868be3f8c0bba496952", remote = "https://github.com/angular/dev-infra.git", ) diff --git a/package.json b/package.json index 6012a74835cb..6b418b99adb8 100644 --- a/package.json +++ b/package.json @@ -54,7 +54,7 @@ "@angular/forms": "22.0.0", "@angular/localize": "22.0.0", "@angular/material": "22.0.0", - "@angular/ng-dev": "https://github.com/angular/dev-infra-private-ng-dev-builds.git#74db100f1fee202d031c5f306778b847f577398c", + "@angular/ng-dev": "https://github.com/angular/dev-infra-private-ng-dev-builds.git#68eef04ac1e37b69e3e61d3e32802e0a6046d54c", "@angular/platform-browser": "22.0.0", "@angular/platform-server": "22.0.0", "@angular/router": "22.0.0", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index bfa4103873ba..f6187188171b 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -50,8 +50,8 @@ importers: specifier: 22.0.0 version: 22.0.0(6eb83275f51d1d41f72333b1955c7306) '@angular/ng-dev': - specifier: https://github.com/angular/dev-infra-private-ng-dev-builds.git#74db100f1fee202d031c5f306778b847f577398c - version: https://codeload.github.com/angular/dev-infra-private-ng-dev-builds/tar.gz/74db100f1fee202d031c5f306778b847f577398c(@modelcontextprotocol/sdk@1.29.0(zod@4.4.3)) + specifier: https://github.com/angular/dev-infra-private-ng-dev-builds.git#68eef04ac1e37b69e3e61d3e32802e0a6046d54c + version: https://codeload.github.com/angular/dev-infra-private-ng-dev-builds/tar.gz/68eef04ac1e37b69e3e61d3e32802e0a6046d54c(@modelcontextprotocol/sdk@1.29.0(zod@4.4.3)) '@angular/platform-browser': specifier: 22.0.0 version: 22.0.0(@angular/animations@22.0.0(@angular/core@22.0.0(@angular/compiler@22.0.0)(rxjs@7.8.2)(zone.js@0.16.2)))(@angular/common@22.0.0(@angular/core@22.0.0(@angular/compiler@22.0.0)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2))(@angular/core@22.0.0(@angular/compiler@22.0.0)(rxjs@7.8.2)(zone.js@0.16.2)) @@ -1011,9 +1011,9 @@ packages: '@angular/platform-browser': ^22.0.0 || ^23.0.0 rxjs: ^6.5.3 || ^7.4.0 - '@angular/ng-dev@https://codeload.github.com/angular/dev-infra-private-ng-dev-builds/tar.gz/74db100f1fee202d031c5f306778b847f577398c': - resolution: {gitHosted: true, integrity: sha512-DolaJQq/Bl29sdXrd8YUw+a/T0Xf2hzug0mbuWk4poeLAQ7GQpx1C+fw1TyRvu89HONzhLDYj8RMGkESZlYxwQ==, tarball: https://codeload.github.com/angular/dev-infra-private-ng-dev-builds/tar.gz/74db100f1fee202d031c5f306778b847f577398c} - version: 0.0.0-e78f06f32bc0780cfda374af155a1b5dc84fa14d + '@angular/ng-dev@https://codeload.github.com/angular/dev-infra-private-ng-dev-builds/tar.gz/68eef04ac1e37b69e3e61d3e32802e0a6046d54c': + resolution: {gitHosted: true, integrity: sha512-T6Drp02fXuaD+9yiRcv4bXTKsMROEIuCATiKQSgcILd02lT9FoyqBzNHdNHzHEYNtOZeLhMn+hkhooTTAlcpPw==, tarball: https://codeload.github.com/angular/dev-infra-private-ng-dev-builds/tar.gz/68eef04ac1e37b69e3e61d3e32802e0a6046d54c} + version: 0.0.0-cef5e36af124e7442d7e2868be3f8c0bba496952 hasBin: true '@angular/platform-browser@22.0.0': @@ -8757,7 +8757,7 @@ snapshots: rxjs: 7.8.2 tslib: 2.8.1 - '@angular/ng-dev@https://codeload.github.com/angular/dev-infra-private-ng-dev-builds/tar.gz/74db100f1fee202d031c5f306778b847f577398c(@modelcontextprotocol/sdk@1.29.0(zod@4.4.3))': + '@angular/ng-dev@https://codeload.github.com/angular/dev-infra-private-ng-dev-builds/tar.gz/68eef04ac1e37b69e3e61d3e32802e0a6046d54c(@modelcontextprotocol/sdk@1.29.0(zod@4.4.3))': dependencies: '@actions/core': 3.0.1 '@conventional-changelog/git-client': 2.7.0(conventional-commits-filter@5.0.0)(conventional-commits-parser@6.4.0) diff --git a/tests/e2e/ng-snapshot/package.json b/tests/e2e/ng-snapshot/package.json index 12f117edede2..f1ff119f821a 100644 --- a/tests/e2e/ng-snapshot/package.json +++ b/tests/e2e/ng-snapshot/package.json @@ -2,21 +2,21 @@ "description": "snapshot versions of Angular for e2e testing", "private": true, "dependencies": { - "@angular/animations": "github:angular/animations-builds#f19d4bc55df72a54991fd5518bdf297daead0253", - "@angular/cdk": "github:angular/cdk-builds#15ce04718b588d3948f59052038d65e72893a3e0", - "@angular/common": "github:angular/common-builds#163d09d8b541b2e20cdc515e0e8191c7f890a366", - "@angular/compiler": "github:angular/compiler-builds#1fd7c0e72896815839a63243bdd3654cab6ec2ad", - "@angular/compiler-cli": "github:angular/compiler-cli-builds#36ae95b63ce91ff6bc56668990ee2ef9393b1a33", - "@angular/core": "github:angular/core-builds#9c24a6dc19753176a142c918722cb72b81e3ba23", - "@angular/forms": "github:angular/forms-builds#50ea33241d57a602fb788f6c86566b5c042a79c7", - "@angular/language-service": "github:angular/language-service-builds#b41df57e48290894d12a56113e06e52dbc5c5ac2", - "@angular/localize": "github:angular/localize-builds#c45916e33a8da351d980ab5ad1d1b31d1879a78c", - "@angular/material": "github:angular/material-builds#e10777f01b458d5418486306ed377dbe455f5f20", - "@angular/material-moment-adapter": "github:angular/material-moment-adapter-builds#95c30cd7636ed27f768d6f5b25117556b970a397", - "@angular/platform-browser": "github:angular/platform-browser-builds#a78c2f8434b05e3c95b55861e978e618c22d1c7e", - "@angular/platform-browser-dynamic": "github:angular/platform-browser-dynamic-builds#2a42255c688ac9aa22eab6dbdc65626b4b428a34", - "@angular/platform-server": "github:angular/platform-server-builds#209d235677e313f0a060b1eac35a11fa83b9eabe", - "@angular/router": "github:angular/router-builds#8051a26ba7b361d0756a81185bb03d166f7623b4", - "@angular/service-worker": "github:angular/service-worker-builds#d480fc85ac0ed8b47a49c52a8857f4676a308bfe" + "@angular/animations": "github:angular/animations-builds#b3dc61bac20b83ab12dff1b8d8c47de2faabefdb", + "@angular/cdk": "github:angular/cdk-builds#beb2e36aee811fddd26cf4fdad151555d0640b8a", + "@angular/common": "github:angular/common-builds#b720928348a31bc237b1e57d240c3dc3f9f51e0e", + "@angular/compiler": "github:angular/compiler-builds#6e98bd2a16b16e3b6e9d43e51d1cf55f8e2fd8bb", + "@angular/compiler-cli": "github:angular/compiler-cli-builds#70e01c035d849c74b540d745741989bb88147d24", + "@angular/core": "github:angular/core-builds#73867fc72fb30528d806ce3df7f4056875d38ca2", + "@angular/forms": "github:angular/forms-builds#faa2869a9215f3fa188b3c18be2eeab6ed95a007", + "@angular/language-service": "github:angular/language-service-builds#7213ebe0f0b13af4a26773772ce7a1a756f87de5", + "@angular/localize": "github:angular/localize-builds#a884cb7cabc5581a58e36f3edc1e0312447e8be6", + "@angular/material": "github:angular/material-builds#ed67e578d7989382f2078e7d5477c81ac52c2eb6", + "@angular/material-moment-adapter": "github:angular/material-moment-adapter-builds#029a918b5d25bbe325f7e0e22ecccea34674340c", + "@angular/platform-browser": "github:angular/platform-browser-builds#0a51cd956fe1069d0492275bca891cb4066054a4", + "@angular/platform-browser-dynamic": "github:angular/platform-browser-dynamic-builds#d5dda743cdbb320d6fba94c13dff9169a738f709", + "@angular/platform-server": "github:angular/platform-server-builds#d4ce7deb33ef39dc40bc71f5cfd8f45feede3acf", + "@angular/router": "github:angular/router-builds#6a23310099c39804d655bdab4bce882e6ebe87d0", + "@angular/service-worker": "github:angular/service-worker-builds#ed9cc1fec1ffe5966b6d2589987e9e94fec3e7eb" } } From ecda7061f6af9abf9e1793493dc521c79c28404a Mon Sep 17 00:00:00 2001 From: Charles Lyding <19598772+clydin@users.noreply.github.com> Date: Wed, 10 Jun 2026 07:30:32 -0400 Subject: [PATCH 026/787] test(@angular/cli): remove unscoped authentication test cases from registry tests Modern package managers do not support unscoped authentication, and Yarn Classic's metadata command (yarn info) does not propagate unscoped credentials correctly, leading to 403 Forbidden failures on secure registries during ng update and ng add. This commit removes the unscoped authentication test cases from both add and update secure registry E2E tests, and cleans up the createNpmConfigForAuthentication helper to default to scoped authentication. --- .../e2e/tests/commands/add/secure-registry.ts | 26 +++---------------- .../tests/update/update-secure-registry.ts | 18 +------------ tests/e2e/utils/registry.ts | 2 +- 3 files changed, 5 insertions(+), 41 deletions(-) diff --git a/tests/e2e/tests/commands/add/secure-registry.ts b/tests/e2e/tests/commands/add/secure-registry.ts index 4a640607f8be..e585444b02e4 100644 --- a/tests/e2e/tests/commands/add/secure-registry.ts +++ b/tests/e2e/tests/commands/add/secure-registry.ts @@ -1,5 +1,5 @@ -import { expectFileNotToExist, expectFileToExist, rimraf } from '../../../utils/fs'; -import { getActivePackageManager, installWorkspacePackages } from '../../../utils/packages'; +import { expectFileNotToExist, expectFileToExist } from '../../../utils/fs'; +import { installWorkspacePackages } from '../../../utils/packages'; import { git, ng } from '../../../utils/process'; import { createNpmConfigForAuthentication } from '../../../utils/registry'; import { expectToFail } from '../../../utils/utils'; @@ -9,37 +9,17 @@ export default async function () { try { // The environment variable has priority over the .npmrc delete process.env['NPM_CONFIG_REGISTRY']; - const packageManager = getActivePackageManager(); - const supportsUnscopedAuth = packageManager === 'yarn'; const command = ['add', '@angular/pwa', '--skip-confirmation']; - // Works with unscoped registry authentication details - if (supportsUnscopedAuth) { - // Some package managers such as Bun and NPM do not support unscoped auth. - await createNpmConfigForAuthentication(false); - - await expectFileNotToExist('public/manifest.webmanifest'); - - await ng(...command); - await expectFileToExist('public/manifest.webmanifest'); - await git('clean', '-dxf'); - } - // Works with scoped registry authentication details await expectFileNotToExist('public/manifest.webmanifest'); - await createNpmConfigForAuthentication(true); + await createNpmConfigForAuthentication(); await ng(...command); await expectFileToExist('public/manifest.webmanifest'); await git('clean', '-dxf'); // Invalid authentication token - if (supportsUnscopedAuth) { - // Some package managers such as Bun and NPM do not support unscoped auth. - await createNpmConfigForAuthentication(false, true); - await expectToFail(() => ng(...command)); - } - await createNpmConfigForAuthentication(true, true); await expectToFail(() => ng(...command)); } finally { diff --git a/tests/e2e/tests/update/update-secure-registry.ts b/tests/e2e/tests/update/update-secure-registry.ts index b52d311a622f..3c0a9d468e44 100644 --- a/tests/e2e/tests/update/update-secure-registry.ts +++ b/tests/e2e/tests/update/update-secure-registry.ts @@ -6,9 +6,6 @@ import { getActivePackageManager } from '../../utils/packages'; import assert from 'node:assert'; export default async function () { - const packageManager = getActivePackageManager(); - const supportsUnscopedAuth = packageManager === 'yarn'; - // The environment variable has priority over the .npmrc delete process.env['NPM_CONFIG_REGISTRY']; const worksMessage = 'We analyzed your package.json'; @@ -20,15 +17,7 @@ export default async function () { // Valid authentication token - if (supportsUnscopedAuth) { - await createNpmConfigForAuthentication(false); - const { stdout: stdout1 } = await ng('update', ...extraArgs); - if (!stdout1.includes(worksMessage)) { - throw new Error(`Expected stdout to contain "${worksMessage}"`); - } - } - - await createNpmConfigForAuthentication(true); + await createNpmConfigForAuthentication(); const { stdout: stdout2 } = await ng('update', ...extraArgs); if (!stdout2.includes(worksMessage)) { throw new Error(`Expected stdout to contain "${worksMessage}"`); @@ -36,11 +25,6 @@ export default async function () { // Invalid authentication token - if (supportsUnscopedAuth) { - await createNpmConfigForAuthentication(false, true); - await expectToFail(() => ng('update', ...extraArgs)); - } - await createNpmConfigForAuthentication(true, true); await expectToFail(() => ng('update', ...extraArgs)); diff --git a/tests/e2e/utils/registry.ts b/tests/e2e/utils/registry.ts index fd557c116120..d8d75b566fb9 100644 --- a/tests/e2e/utils/registry.ts +++ b/tests/e2e/utils/registry.ts @@ -63,7 +63,7 @@ export async function createNpmConfigForAuthentication( * _auth="dGVzdGluZzpzM2NyZXQ="` * ``` */ - scopedAuthentication: boolean, + scopedAuthentication = true, /** When true, an incorrect token is used. Use this to validate authentication failures. */ invalidToken = false, ): Promise { From f8c3df4e29d834014e955a6762651458e139f231 Mon Sep 17 00:00:00 2001 From: Charles Lyding <19598772+clydin@users.noreply.github.com> Date: Tue, 9 Jun 2026 15:13:56 -0400 Subject: [PATCH 027/787] fix(@angular/cli): remove forceAuth and unscoped credential parsing Remove the non-standard forceAuth option and custom parsing for unscoped registry credentials (token, username, password, auth) in package-metadata.ts. Since the npm CLI does not support unscoped credentials and ignores them by default, this aligning removes the unnecessary parsing complexity. Unscoped credentials will now behave identically to any other standard configuration property, falling through to default configuration parsing. --- .../cli/src/utilities/package-metadata.ts | 17 +---------------- 1 file changed, 1 insertion(+), 16 deletions(-) diff --git a/packages/angular/cli/src/utilities/package-metadata.ts b/packages/angular/cli/src/utilities/package-metadata.ts index fd31000f989a..05a739e898ae 100644 --- a/packages/angular/cli/src/utilities/package-metadata.ts +++ b/packages/angular/cli/src/utilities/package-metadata.ts @@ -52,9 +52,7 @@ export interface PackageManifest extends Manifest, NgPackageManifestProperties { peerDependenciesMeta?: Record; } -interface PackageManagerOptions extends Record { - forceAuth?: Record; -} +type PackageManagerOptions = Record; let npmrc: PackageManagerOptions; const npmPackageJsonCache = new Map>>(); @@ -175,19 +173,6 @@ function normalizeOptions( } switch (key) { - // Unless auth options are scope with the registry url it appears that npm-registry-fetch ignores them, - // even though they are documented. - // https://github.com/npm/npm-registry-fetch/blob/8954f61d8d703e5eb7f3d93c9b40488f8b1b62ac/README.md - // https://github.com/npm/npm-registry-fetch/blob/8954f61d8d703e5eb7f3d93c9b40488f8b1b62ac/auth.js#L45-L91 - case '_authToken': - case 'token': - case 'username': - case 'password': - case '_auth': - case 'auth': - options['forceAuth'] ??= {}; - options['forceAuth'][key] = substitutedValue; - break; case 'noproxy': case 'no-proxy': options['noProxy'] = substitutedValue; From 19c90cb691cef3b7862df860462ca08d745cac56 Mon Sep 17 00:00:00 2001 From: Alan Agius <17563226+alan-agius4@users.noreply.github.com> Date: Wed, 10 Jun 2026 13:57:04 +0000 Subject: [PATCH 028/787] fix(@angular/cli): do not sort migrations of the same version alphabetically When executing update migrations, schematics targeting the same version were previously sorted alphabetically by name. This change removes the alphabetical sorting fallback, allowing migrations targeting the same version to preserve their original declaration/discovery order. --- .../src/commands/update/utilities/migration.ts | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/packages/angular/cli/src/commands/update/utilities/migration.ts b/packages/angular/cli/src/commands/update/utilities/migration.ts index f52726de5523..21331364bc2f 100644 --- a/packages/angular/cli/src/commands/update/utilities/migration.ts +++ b/packages/angular/cli/src/commands/update/utilities/migration.ts @@ -153,9 +153,7 @@ export async function executeMigrations( if (requiredMigrations.length) { logger.info(colors.cyan(`** Executing migrations of package '${packageName}' **\n`)); - requiredMigrations.sort( - (a, b) => semver.compare(a.version, b.version) || a.name.localeCompare(b.name), - ); + requiredMigrations.sort(compareMigrations); const result = await executePackageMigrations( workflow, @@ -174,9 +172,7 @@ export async function executeMigrations( if (optionalMigrations.length) { logger.info(colors.magenta(`** Optional migrations of package '${packageName}' **\n`)); - optionalMigrations.sort( - (a, b) => semver.compare(a.version, b.version) || a.name.localeCompare(b.name), - ); + optionalMigrations.sort(compareMigrations); const migrationsToRun = await getOptionalMigrationsToRun( logger, @@ -372,3 +368,10 @@ function getMigrationTitleAndDescription(migration: MigrationSchematicDescriptio : undefined, }; } + +function compareMigrations( + a: MigrationSchematicDescriptionWithVersion, + b: MigrationSchematicDescriptionWithVersion, +): number { + return semver.compare(a.version, b.version); +} From df985bf3d7ef1facc10f365aff221c1bc3582d1a Mon Sep 17 00:00:00 2001 From: Angular Robot Date: Wed, 10 Jun 2026 09:38:13 +0000 Subject: [PATCH 029/787] build: update cross-repo angular dependencies See associated pull request for more information. --- tests/e2e/ng-snapshot/package.json | 32 +++++++++++++++--------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/tests/e2e/ng-snapshot/package.json b/tests/e2e/ng-snapshot/package.json index f1ff119f821a..e29823426365 100644 --- a/tests/e2e/ng-snapshot/package.json +++ b/tests/e2e/ng-snapshot/package.json @@ -2,21 +2,21 @@ "description": "snapshot versions of Angular for e2e testing", "private": true, "dependencies": { - "@angular/animations": "github:angular/animations-builds#b3dc61bac20b83ab12dff1b8d8c47de2faabefdb", - "@angular/cdk": "github:angular/cdk-builds#beb2e36aee811fddd26cf4fdad151555d0640b8a", - "@angular/common": "github:angular/common-builds#b720928348a31bc237b1e57d240c3dc3f9f51e0e", - "@angular/compiler": "github:angular/compiler-builds#6e98bd2a16b16e3b6e9d43e51d1cf55f8e2fd8bb", - "@angular/compiler-cli": "github:angular/compiler-cli-builds#70e01c035d849c74b540d745741989bb88147d24", - "@angular/core": "github:angular/core-builds#73867fc72fb30528d806ce3df7f4056875d38ca2", - "@angular/forms": "github:angular/forms-builds#faa2869a9215f3fa188b3c18be2eeab6ed95a007", - "@angular/language-service": "github:angular/language-service-builds#7213ebe0f0b13af4a26773772ce7a1a756f87de5", - "@angular/localize": "github:angular/localize-builds#a884cb7cabc5581a58e36f3edc1e0312447e8be6", - "@angular/material": "github:angular/material-builds#ed67e578d7989382f2078e7d5477c81ac52c2eb6", - "@angular/material-moment-adapter": "github:angular/material-moment-adapter-builds#029a918b5d25bbe325f7e0e22ecccea34674340c", - "@angular/platform-browser": "github:angular/platform-browser-builds#0a51cd956fe1069d0492275bca891cb4066054a4", - "@angular/platform-browser-dynamic": "github:angular/platform-browser-dynamic-builds#d5dda743cdbb320d6fba94c13dff9169a738f709", - "@angular/platform-server": "github:angular/platform-server-builds#d4ce7deb33ef39dc40bc71f5cfd8f45feede3acf", - "@angular/router": "github:angular/router-builds#6a23310099c39804d655bdab4bce882e6ebe87d0", - "@angular/service-worker": "github:angular/service-worker-builds#ed9cc1fec1ffe5966b6d2589987e9e94fec3e7eb" + "@angular/animations": "github:angular/animations-builds#995e14b3622334a08fa2dd61ad4a32ada5f23bed", + "@angular/cdk": "github:angular/cdk-builds#7bc49b61b45807fb27e77317193ad90283f93f93", + "@angular/common": "github:angular/common-builds#b61ffd86d49ba0b9a851b1096f1f03260659c13c", + "@angular/compiler": "github:angular/compiler-builds#95b12983913cfbfa0d263e2cfa98d2983e4f9c88", + "@angular/compiler-cli": "github:angular/compiler-cli-builds#3e011b17c96dc76ca925fc5e914fbd8238c668c7", + "@angular/core": "github:angular/core-builds#03ca0858e056118762a745b64bbfd2285a110fee", + "@angular/forms": "github:angular/forms-builds#0abbf545d7f1dabb7cc5e6fcb9cf66223d8b3fc7", + "@angular/language-service": "github:angular/language-service-builds#5998ae5e86464885664600bd19650d9c38d30fad", + "@angular/localize": "github:angular/localize-builds#8f7ae70fdeb50866f556e73bc3a8f4473cb65804", + "@angular/material": "github:angular/material-builds#7a236ec3084f76850f2aa2ae1d1fe58ab504a290", + "@angular/material-moment-adapter": "github:angular/material-moment-adapter-builds#f710a88fd1a7ad4b31d23d7d188b2591e6366d6a", + "@angular/platform-browser": "github:angular/platform-browser-builds#9b66d5030f5ed1370e26bb0ebeb408f8555c0664", + "@angular/platform-browser-dynamic": "github:angular/platform-browser-dynamic-builds#2e6ce4e7ade1c180eba4c6fa261962a89a9014e5", + "@angular/platform-server": "github:angular/platform-server-builds#42691726ca2611679ff5d64b60201ef9a1a75f6b", + "@angular/router": "github:angular/router-builds#41090511daed2112637dd8e1fb121966faf97509", + "@angular/service-worker": "github:angular/service-worker-builds#2cf5d8e2053c0d9a5942ab56876b8b197ae3692e" } } From d07e4190a730f09be4318586bee74bd40ec470d3 Mon Sep 17 00:00:00 2001 From: Doug Parker Date: Wed, 10 Jun 2026 15:59:34 -0700 Subject: [PATCH 030/787] docs: release notes for the v22.0.1 release --- CHANGELOG.md | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index dd3b18b1101e..5a607c51a75a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,37 @@ + + +# 22.0.1 (2026-06-10) + +### @angular/cli + +| Commit | Type | Description | +| --------------------------------------------------------------------------------------------------- | ---- | ----------------------------------------------------------------------------------- | +| [b54e9a549](https://github.com/angular/angular-cli/commit/b54e9a549d30871f6017b1db4cf7a4ab5f3e02db) | fix | do not sort migrations of the same version alphabetically | +| [d33311612](https://github.com/angular/angular-cli/commit/d333116123c7d3d5e87713b7baac048b78f28517) | fix | fallback to local package.json for schematic detection on first run | +| [918102a93](https://github.com/angular/angular-cli/commit/918102a9373085394c41f10d9f5df3e3c17b263f) | fix | isolate temporary package installation from parent pnpm workspace | +| [b048b5f4a](https://github.com/angular/angular-cli/commit/b048b5f4a83d7b20095d79654b849808e7d58fdb) | fix | remove forceAuth and unscoped credential parsing | +| [277934035](https://github.com/angular/angular-cli/commit/277934035138c5af803e8daeebc2313f0a4cb5b3) | fix | validate registry option is a valid URL in ng add | +| [4510dae02](https://github.com/angular/angular-cli/commit/4510dae021ab25bb852eeed6415dbd52cfabfce5) | perf | optimize update schematic registry query counts by fetching package metadata lazily | + +### @schematics/angular + +| Commit | Type | Description | +| --------------------------------------------------------------------------------------------------- | ---- | ------------------------------------------------------------------ | +| [c80012294](https://github.com/angular/angular-cli/commit/c8001229453211b37cd7bb12ed26a2deb9257fd5) | fix | fix browserMode option mapping in refactor-jasmine-vitest | +| [a9b6bd904](https://github.com/angular/angular-cli/commit/a9b6bd9042d6b859c384a6fc782541fca30dfb68) | fix | safely comment out multiline statements in refactor-jasmine-vitest | +| [12199df00](https://github.com/angular/angular-cli/commit/12199df00f2e3e8436ada13e04799e5825eb3f7b) | fix | use null objects and callbacks in karma-to-vitest migration | + +### @angular/build + +| Commit | Type | Description | +| --------------------------------------------------------------------------------------------------- | ---- | ------------------------------------------------------------- | +| [89d1be979](https://github.com/angular/angular-cli/commit/89d1be979f388d85e9c428bbf1df4e7fb4036dce) | fix | allow disabling Vitest isolation from builder | +| [d45b84be9](https://github.com/angular/angular-cli/commit/d45b84be9a607e49b391cb216cb6de7eca274931) | fix | exclude JSON imports from Vite dependency optimization | +| [e3cab4ddd](https://github.com/angular/angular-cli/commit/e3cab4dddade2538125e8a2f345f42c95e26aeae) | fix | prevent concurrent stylesheet bundling esbuild context leaks | +| [bd413b0eb](https://github.com/angular/angular-cli/commit/bd413b0eb156184ea432cbb7d4e6d7f6f70813ab) | fix | restrict application builder output paths to output directory | + + + # 22.0.0 (2026-06-03) From e8312fa5f1bab850d31c0d78f7abf43abaef74a8 Mon Sep 17 00:00:00 2001 From: Angular Robot Date: Wed, 10 Jun 2026 22:57:35 +0000 Subject: [PATCH 031/787] build: update cross-repo angular dependencies See associated pull request for more information. --- MODULE.bazel | 6 +- MODULE.bazel.lock | 34 +- .../hello-world-lib/projects/lib/package.json | 4 +- package.json | 28 +- packages/angular/ssr/package.json | 12 +- packages/ngtools/webpack/package.json | 4 +- pnpm-lock.yaml | 342 ++++++++---------- tests/e2e/ng-snapshot/package.json | 32 +- 8 files changed, 215 insertions(+), 247 deletions(-) diff --git a/MODULE.bazel b/MODULE.bazel index 0e007aeff6a3..062573179302 100644 --- a/MODULE.bazel +++ b/MODULE.bazel @@ -19,21 +19,21 @@ bazel_dep(name = "aspect_rules_jasmine", version = "2.0.4") bazel_dep(name = "rules_angular") git_override( module_name = "rules_angular", - commit = "02e0d38eb29b2721128ca7e93ee694e68d4f06f6", + commit = "0571709fc1bf8174c94f4b01c87f50a3b3d3cf23", remote = "https://github.com/angular/rules_angular.git", ) bazel_dep(name = "devinfra") git_override( module_name = "devinfra", - commit = "cef5e36af124e7442d7e2868be3f8c0bba496952", + commit = "b9d15e3de22a6b8b161046d1ed5cea574a2537ca", remote = "https://github.com/angular/dev-infra.git", ) bazel_dep(name = "rules_browsers") git_override( module_name = "rules_browsers", - commit = "c7e596a4a34f651113c42a9da3f82acc0a01484e", + commit = "3e345a43e88f86a744003da90a28fc31cf4e07fb", remote = "https://github.com/angular/rules_browsers.git", ) diff --git a/MODULE.bazel.lock b/MODULE.bazel.lock index dc32a6881872..c04a9caaf272 100644 --- a/MODULE.bazel.lock +++ b/MODULE.bazel.lock @@ -592,7 +592,7 @@ }, "@@rules_browsers+//browsers:extensions.bzl%browsers": { "general": { - "bzlTransitiveDigest": "lQlRwI+HZTXohoZ41oufeudyNMhYrxQizk07ADXimPI=", + "bzlTransitiveDigest": "WS+hxcF6xP7F7M8vQJNunWdRe2E7XZ7FmTakAtg8A1Q=", "usagesDigest": "FmXYJVoVJlnfUU8x8gObSvu4qWcco/9Faw61aC/wBF0=", "recordedFileInputs": {}, "recordedDirentsInputs": {}, @@ -601,9 +601,9 @@ "rules_browsers_chrome_linux": { "repoRuleId": "@@rules_browsers+//browsers/private:browser_repo.bzl%browser_repo", "attributes": { - "sha256": "fd4df6dcadda8641af4f5d79137b23f1b1271a1cfcc0b96f52cb1b8bcd7c01d5", + "sha256": "03883cfad5344e0815091f53a03909af9989f72a800b0ad2a691c9de52ff7df9", "urls": [ - "https://storage.googleapis.com/chrome-for-testing-public/151.0.7881.0/linux64/chrome-headless-shell-linux64.zip" + "https://storage.googleapis.com/chrome-for-testing-public/151.0.7884.0/linux64/chrome-headless-shell-linux64.zip" ], "named_files": { "CHROME-HEADLESS-SHELL": "chrome-headless-shell-linux64/chrome-headless-shell" @@ -619,9 +619,9 @@ "rules_browsers_chrome_mac": { "repoRuleId": "@@rules_browsers+//browsers/private:browser_repo.bzl%browser_repo", "attributes": { - "sha256": "4136f1a9524ac5130dd29fe9eef82094139f079520af0b28f0d360f4f3f550ed", + "sha256": "a3d20f3b47f5d7c1b5695229f599d1981be3e0f8a71f782477d4a9343c4a477e", "urls": [ - "https://storage.googleapis.com/chrome-for-testing-public/151.0.7881.0/mac-x64/chrome-headless-shell-mac-x64.zip" + "https://storage.googleapis.com/chrome-for-testing-public/151.0.7884.0/mac-x64/chrome-headless-shell-mac-x64.zip" ], "named_files": { "CHROME-HEADLESS-SHELL": "chrome-headless-shell-mac-x64/chrome-headless-shell" @@ -637,9 +637,9 @@ "rules_browsers_chrome_mac_arm": { "repoRuleId": "@@rules_browsers+//browsers/private:browser_repo.bzl%browser_repo", "attributes": { - "sha256": "f2cb9d22ad425a23e1d58dab7ac91e546386099a5acb811ca5749d40bf2d9886", + "sha256": "b381e35fecea3e7e712b5874eadbd0fb06644fa925fb4ce35cfc5187bd8da82b", "urls": [ - "https://storage.googleapis.com/chrome-for-testing-public/151.0.7881.0/mac-arm64/chrome-headless-shell-mac-arm64.zip" + "https://storage.googleapis.com/chrome-for-testing-public/151.0.7884.0/mac-arm64/chrome-headless-shell-mac-arm64.zip" ], "named_files": { "CHROME-HEADLESS-SHELL": "chrome-headless-shell-mac-arm64/chrome-headless-shell" @@ -655,9 +655,9 @@ "rules_browsers_chrome_win64": { "repoRuleId": "@@rules_browsers+//browsers/private:browser_repo.bzl%browser_repo", "attributes": { - "sha256": "684055979848753211b24215d25993c453ee26cdb2d84d7bfb24f84118e02198", + "sha256": "2e17c31f672b767ca6aa2789c31d956a2a518d3dc0e7838417a7a43c9152ecb2", "urls": [ - "https://storage.googleapis.com/chrome-for-testing-public/151.0.7881.0/win64/chrome-headless-shell-win64.zip" + "https://storage.googleapis.com/chrome-for-testing-public/151.0.7884.0/win64/chrome-headless-shell-win64.zip" ], "named_files": { "CHROME-HEADLESS-SHELL": "chrome-headless-shell-win64/chrome-headless-shell.exe" @@ -673,9 +673,9 @@ "rules_browsers_chromedriver_linux": { "repoRuleId": "@@rules_browsers+//browsers/private:browser_repo.bzl%browser_repo", "attributes": { - "sha256": "d9e12133a8af192f8a28f2ef0d86ac54f7458c71e28bddf95947d5636472d508", + "sha256": "a48735d28dfc6131ee9060a33925ad32004dd8fd5811f8c8b5b90c22be2be2ea", "urls": [ - "https://storage.googleapis.com/chrome-for-testing-public/151.0.7881.0/linux64/chromedriver-linux64.zip" + "https://storage.googleapis.com/chrome-for-testing-public/151.0.7884.0/linux64/chromedriver-linux64.zip" ], "named_files": { "CHROMEDRIVER": "chromedriver-linux64/chromedriver" @@ -689,9 +689,9 @@ "rules_browsers_chromedriver_mac": { "repoRuleId": "@@rules_browsers+//browsers/private:browser_repo.bzl%browser_repo", "attributes": { - "sha256": "7432080f1c3fc8131d58870e93ca9a96c807fedc04deaaf5c1a60942f3c1d321", + "sha256": "d55ad1405b03849147996c208e0a4962161d4d8d2a60067635d7e4330beb157e", "urls": [ - "https://storage.googleapis.com/chrome-for-testing-public/151.0.7881.0/mac-x64/chromedriver-mac-x64.zip" + "https://storage.googleapis.com/chrome-for-testing-public/151.0.7884.0/mac-x64/chromedriver-mac-x64.zip" ], "named_files": { "CHROMEDRIVER": "chromedriver-mac-x64/chromedriver" @@ -705,9 +705,9 @@ "rules_browsers_chromedriver_mac_arm": { "repoRuleId": "@@rules_browsers+//browsers/private:browser_repo.bzl%browser_repo", "attributes": { - "sha256": "0bfbda9352bbae72755b463f656a6f335481bc02be1ba8edfe1fb74a08ce0d7b", + "sha256": "86ab265ac6951ea5f338398c0ebc9b67a4ed0052c69f00d406542f67af98d28f", "urls": [ - "https://storage.googleapis.com/chrome-for-testing-public/151.0.7881.0/mac-arm64/chromedriver-mac-arm64.zip" + "https://storage.googleapis.com/chrome-for-testing-public/151.0.7884.0/mac-arm64/chromedriver-mac-arm64.zip" ], "named_files": { "CHROMEDRIVER": "chromedriver-mac-arm64/chromedriver" @@ -721,9 +721,9 @@ "rules_browsers_chromedriver_win64": { "repoRuleId": "@@rules_browsers+//browsers/private:browser_repo.bzl%browser_repo", "attributes": { - "sha256": "766efed7d9c6a3aa89733d59b64316849775002bdde7e247318c8129bbd6d747", + "sha256": "ae1b4dfd27a4c35f3662f942d5e430b1502bac241e822170067dd94b026373ac", "urls": [ - "https://storage.googleapis.com/chrome-for-testing-public/151.0.7881.0/win64/chromedriver-win64.zip" + "https://storage.googleapis.com/chrome-for-testing-public/151.0.7884.0/win64/chromedriver-win64.zip" ], "named_files": { "CHROMEDRIVER": "chromedriver-win64/chromedriver.exe" diff --git a/modules/testing/builder/projects/hello-world-lib/projects/lib/package.json b/modules/testing/builder/projects/hello-world-lib/projects/lib/package.json index ac7b847f2366..0ec9802c2c70 100644 --- a/modules/testing/builder/projects/hello-world-lib/projects/lib/package.json +++ b/modules/testing/builder/projects/hello-world-lib/projects/lib/package.json @@ -2,7 +2,7 @@ "name": "lib", "version": "0.0.1", "peerDependencies": { - "@angular/common": "^22.0.0-next", - "@angular/core": "^22.0.0-next" + "@angular/common": "^22.1.0-next", + "@angular/core": "^22.1.0-next" } } \ No newline at end of file diff --git a/package.json b/package.json index 6b418b99adb8..0e4856408374 100644 --- a/package.json +++ b/package.json @@ -42,23 +42,23 @@ }, "homepage": "https://github.com/angular/angular-cli", "dependencies": { - "@angular/compiler-cli": "22.0.0", + "@angular/compiler-cli": "22.1.0-next.0", "typescript": "6.0.3" }, "devDependencies": { - "@angular/animations": "22.0.0", - "@angular/cdk": "22.0.0", - "@angular/common": "22.0.0", - "@angular/compiler": "22.0.0", - "@angular/core": "22.0.0", - "@angular/forms": "22.0.0", - "@angular/localize": "22.0.0", - "@angular/material": "22.0.0", - "@angular/ng-dev": "https://github.com/angular/dev-infra-private-ng-dev-builds.git#68eef04ac1e37b69e3e61d3e32802e0a6046d54c", - "@angular/platform-browser": "22.0.0", - "@angular/platform-server": "22.0.0", - "@angular/router": "22.0.0", - "@angular/service-worker": "22.0.0", + "@angular/animations": "22.1.0-next.0", + "@angular/cdk": "22.1.0-next.0", + "@angular/common": "22.1.0-next.0", + "@angular/compiler": "22.1.0-next.0", + "@angular/core": "22.1.0-next.0", + "@angular/forms": "22.1.0-next.0", + "@angular/localize": "22.1.0-next.0", + "@angular/material": "22.1.0-next.0", + "@angular/ng-dev": "https://github.com/angular/dev-infra-private-ng-dev-builds.git#5d9842518819d66cfb65994e2dda90354410a449", + "@angular/platform-browser": "22.1.0-next.0", + "@angular/platform-server": "22.1.0-next.0", + "@angular/router": "22.1.0-next.0", + "@angular/service-worker": "22.1.0-next.0", "@babel/core": "7.29.7", "@bazel/bazelisk": "1.28.1", "@bazel/buildifier": "8.2.1", diff --git a/packages/angular/ssr/package.json b/packages/angular/ssr/package.json index 2e99519ed20c..95ff9b5804a5 100644 --- a/packages/angular/ssr/package.json +++ b/packages/angular/ssr/package.json @@ -37,12 +37,12 @@ }, "devDependencies": { "@angular-devkit/schematics": "workspace:*", - "@angular/common": "22.0.0", - "@angular/compiler": "22.0.0", - "@angular/core": "22.0.0", - "@angular/platform-browser": "22.0.0", - "@angular/platform-server": "22.0.0", - "@angular/router": "22.0.0", + "@angular/common": "22.1.0-next.0", + "@angular/compiler": "22.1.0-next.0", + "@angular/core": "22.1.0-next.0", + "@angular/platform-browser": "22.1.0-next.0", + "@angular/platform-server": "22.1.0-next.0", + "@angular/router": "22.1.0-next.0", "@schematics/angular": "workspace:*", "beasties": "0.4.2" }, diff --git a/packages/ngtools/webpack/package.json b/packages/ngtools/webpack/package.json index 40443c7f3ea0..db6ff5aac0b2 100644 --- a/packages/ngtools/webpack/package.json +++ b/packages/ngtools/webpack/package.json @@ -17,8 +17,8 @@ }, "devDependencies": { "@angular-devkit/core": "workspace:0.0.0-PLACEHOLDER", - "@angular/compiler": "22.0.0", - "@angular/compiler-cli": "22.0.0", + "@angular/compiler": "22.1.0-next.0", + "@angular/compiler-cli": "22.1.0-next.0", "typescript": "6.0.3", "webpack": "5.107.2" } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index f6187188171b..ea01c8e1f27b 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -14,8 +14,8 @@ importers: .: dependencies: '@angular/compiler-cli': - specifier: 22.0.0 - version: 22.0.0(@angular/compiler@22.0.0)(typescript@6.0.3) + specifier: 22.1.0-next.0 + version: 22.1.0-next.0(@angular/compiler@22.1.0-next.0)(typescript@6.0.3) typescript: specifier: 6.0.3 version: 6.0.3 @@ -26,44 +26,44 @@ importers: built: true devDependencies: '@angular/animations': - specifier: 22.0.0 - version: 22.0.0(@angular/core@22.0.0(@angular/compiler@22.0.0)(rxjs@7.8.2)(zone.js@0.16.2)) + specifier: 22.1.0-next.0 + version: 22.1.0-next.0(@angular/core@22.1.0-next.0(@angular/compiler@22.1.0-next.0)(rxjs@7.8.2)(zone.js@0.16.2)) '@angular/cdk': - specifier: 22.0.0 - version: 22.0.0(@angular/common@22.0.0(@angular/core@22.0.0(@angular/compiler@22.0.0)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2))(@angular/core@22.0.0(@angular/compiler@22.0.0)(rxjs@7.8.2)(zone.js@0.16.2))(@angular/platform-browser@22.0.0(@angular/animations@22.0.0(@angular/core@22.0.0(@angular/compiler@22.0.0)(rxjs@7.8.2)(zone.js@0.16.2)))(@angular/common@22.0.0(@angular/core@22.0.0(@angular/compiler@22.0.0)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2))(@angular/core@22.0.0(@angular/compiler@22.0.0)(rxjs@7.8.2)(zone.js@0.16.2)))(rxjs@7.8.2) + specifier: 22.1.0-next.0 + version: 22.1.0-next.0(@angular/common@22.1.0-next.0(@angular/core@22.1.0-next.0(@angular/compiler@22.1.0-next.0)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2))(@angular/core@22.1.0-next.0(@angular/compiler@22.1.0-next.0)(rxjs@7.8.2)(zone.js@0.16.2))(@angular/platform-browser@22.1.0-next.0(@angular/animations@22.1.0-next.0(@angular/core@22.1.0-next.0(@angular/compiler@22.1.0-next.0)(rxjs@7.8.2)(zone.js@0.16.2)))(@angular/common@22.1.0-next.0(@angular/core@22.1.0-next.0(@angular/compiler@22.1.0-next.0)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2))(@angular/core@22.1.0-next.0(@angular/compiler@22.1.0-next.0)(rxjs@7.8.2)(zone.js@0.16.2)))(rxjs@7.8.2) '@angular/common': - specifier: 22.0.0 - version: 22.0.0(@angular/core@22.0.0(@angular/compiler@22.0.0)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2) + specifier: 22.1.0-next.0 + version: 22.1.0-next.0(@angular/core@22.1.0-next.0(@angular/compiler@22.1.0-next.0)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2) '@angular/compiler': - specifier: 22.0.0 - version: 22.0.0 + specifier: 22.1.0-next.0 + version: 22.1.0-next.0 '@angular/core': - specifier: 22.0.0 - version: 22.0.0(@angular/compiler@22.0.0)(rxjs@7.8.2)(zone.js@0.16.2) + specifier: 22.1.0-next.0 + version: 22.1.0-next.0(@angular/compiler@22.1.0-next.0)(rxjs@7.8.2)(zone.js@0.16.2) '@angular/forms': - specifier: 22.0.0 - version: 22.0.0(@angular/common@22.0.0(@angular/core@22.0.0(@angular/compiler@22.0.0)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2))(@angular/core@22.0.0(@angular/compiler@22.0.0)(rxjs@7.8.2)(zone.js@0.16.2))(@angular/platform-browser@22.0.0(@angular/animations@22.0.0(@angular/core@22.0.0(@angular/compiler@22.0.0)(rxjs@7.8.2)(zone.js@0.16.2)))(@angular/common@22.0.0(@angular/core@22.0.0(@angular/compiler@22.0.0)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2))(@angular/core@22.0.0(@angular/compiler@22.0.0)(rxjs@7.8.2)(zone.js@0.16.2)))(rxjs@7.8.2) + specifier: 22.1.0-next.0 + version: 22.1.0-next.0(@angular/common@22.1.0-next.0(@angular/core@22.1.0-next.0(@angular/compiler@22.1.0-next.0)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2))(@angular/core@22.1.0-next.0(@angular/compiler@22.1.0-next.0)(rxjs@7.8.2)(zone.js@0.16.2))(@angular/platform-browser@22.1.0-next.0(@angular/animations@22.1.0-next.0(@angular/core@22.1.0-next.0(@angular/compiler@22.1.0-next.0)(rxjs@7.8.2)(zone.js@0.16.2)))(@angular/common@22.1.0-next.0(@angular/core@22.1.0-next.0(@angular/compiler@22.1.0-next.0)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2))(@angular/core@22.1.0-next.0(@angular/compiler@22.1.0-next.0)(rxjs@7.8.2)(zone.js@0.16.2)))(rxjs@7.8.2) '@angular/localize': - specifier: 22.0.0 - version: 22.0.0(@angular/compiler-cli@22.0.0(@angular/compiler@22.0.0)(typescript@6.0.3))(@angular/compiler@22.0.0) + specifier: 22.1.0-next.0 + version: 22.1.0-next.0(@angular/compiler-cli@22.1.0-next.0(@angular/compiler@22.1.0-next.0)(typescript@6.0.3))(@angular/compiler@22.1.0-next.0) '@angular/material': - specifier: 22.0.0 - version: 22.0.0(6eb83275f51d1d41f72333b1955c7306) + specifier: 22.1.0-next.0 + version: 22.1.0-next.0(25ca0260cba80497f59a6bedbf88cafa) '@angular/ng-dev': - specifier: https://github.com/angular/dev-infra-private-ng-dev-builds.git#68eef04ac1e37b69e3e61d3e32802e0a6046d54c - version: https://codeload.github.com/angular/dev-infra-private-ng-dev-builds/tar.gz/68eef04ac1e37b69e3e61d3e32802e0a6046d54c(@modelcontextprotocol/sdk@1.29.0(zod@4.4.3)) + specifier: https://github.com/angular/dev-infra-private-ng-dev-builds.git#5d9842518819d66cfb65994e2dda90354410a449 + version: https://codeload.github.com/angular/dev-infra-private-ng-dev-builds/tar.gz/5d9842518819d66cfb65994e2dda90354410a449(@modelcontextprotocol/sdk@1.29.0(zod@4.4.3)) '@angular/platform-browser': - specifier: 22.0.0 - version: 22.0.0(@angular/animations@22.0.0(@angular/core@22.0.0(@angular/compiler@22.0.0)(rxjs@7.8.2)(zone.js@0.16.2)))(@angular/common@22.0.0(@angular/core@22.0.0(@angular/compiler@22.0.0)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2))(@angular/core@22.0.0(@angular/compiler@22.0.0)(rxjs@7.8.2)(zone.js@0.16.2)) + specifier: 22.1.0-next.0 + version: 22.1.0-next.0(@angular/animations@22.1.0-next.0(@angular/core@22.1.0-next.0(@angular/compiler@22.1.0-next.0)(rxjs@7.8.2)(zone.js@0.16.2)))(@angular/common@22.1.0-next.0(@angular/core@22.1.0-next.0(@angular/compiler@22.1.0-next.0)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2))(@angular/core@22.1.0-next.0(@angular/compiler@22.1.0-next.0)(rxjs@7.8.2)(zone.js@0.16.2)) '@angular/platform-server': - specifier: 22.0.0 - version: 22.0.0(@angular/common@22.0.0(@angular/core@22.0.0(@angular/compiler@22.0.0)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2))(@angular/compiler@22.0.0)(@angular/core@22.0.0(@angular/compiler@22.0.0)(rxjs@7.8.2)(zone.js@0.16.2))(@angular/platform-browser@22.0.0(@angular/animations@22.0.0(@angular/core@22.0.0(@angular/compiler@22.0.0)(rxjs@7.8.2)(zone.js@0.16.2)))(@angular/common@22.0.0(@angular/core@22.0.0(@angular/compiler@22.0.0)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2))(@angular/core@22.0.0(@angular/compiler@22.0.0)(rxjs@7.8.2)(zone.js@0.16.2)))(rxjs@7.8.2) + specifier: 22.1.0-next.0 + version: 22.1.0-next.0(@angular/common@22.1.0-next.0(@angular/core@22.1.0-next.0(@angular/compiler@22.1.0-next.0)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2))(@angular/compiler@22.1.0-next.0)(@angular/core@22.1.0-next.0(@angular/compiler@22.1.0-next.0)(rxjs@7.8.2)(zone.js@0.16.2))(@angular/platform-browser@22.1.0-next.0(@angular/animations@22.1.0-next.0(@angular/core@22.1.0-next.0(@angular/compiler@22.1.0-next.0)(rxjs@7.8.2)(zone.js@0.16.2)))(@angular/common@22.1.0-next.0(@angular/core@22.1.0-next.0(@angular/compiler@22.1.0-next.0)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2))(@angular/core@22.1.0-next.0(@angular/compiler@22.1.0-next.0)(rxjs@7.8.2)(zone.js@0.16.2)))(rxjs@7.8.2) '@angular/router': - specifier: 22.0.0 - version: 22.0.0(@angular/common@22.0.0(@angular/core@22.0.0(@angular/compiler@22.0.0)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2))(@angular/core@22.0.0(@angular/compiler@22.0.0)(rxjs@7.8.2)(zone.js@0.16.2))(@angular/platform-browser@22.0.0(@angular/animations@22.0.0(@angular/core@22.0.0(@angular/compiler@22.0.0)(rxjs@7.8.2)(zone.js@0.16.2)))(@angular/common@22.0.0(@angular/core@22.0.0(@angular/compiler@22.0.0)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2))(@angular/core@22.0.0(@angular/compiler@22.0.0)(rxjs@7.8.2)(zone.js@0.16.2)))(rxjs@7.8.2) + specifier: 22.1.0-next.0 + version: 22.1.0-next.0(@angular/common@22.1.0-next.0(@angular/core@22.1.0-next.0(@angular/compiler@22.1.0-next.0)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2))(@angular/core@22.1.0-next.0(@angular/compiler@22.1.0-next.0)(rxjs@7.8.2)(zone.js@0.16.2))(@angular/platform-browser@22.1.0-next.0(@angular/animations@22.1.0-next.0(@angular/core@22.1.0-next.0(@angular/compiler@22.1.0-next.0)(rxjs@7.8.2)(zone.js@0.16.2)))(@angular/common@22.1.0-next.0(@angular/core@22.1.0-next.0(@angular/compiler@22.1.0-next.0)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2))(@angular/core@22.1.0-next.0(@angular/compiler@22.1.0-next.0)(rxjs@7.8.2)(zone.js@0.16.2)))(rxjs@7.8.2) '@angular/service-worker': - specifier: 22.0.0 - version: 22.0.0(@angular/core@22.0.0(@angular/compiler@22.0.0)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2) + specifier: 22.1.0-next.0 + version: 22.1.0-next.0(@angular/core@22.1.0-next.0(@angular/compiler@22.1.0-next.0)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2) '@babel/core': specifier: 7.29.7 version: 7.29.7 @@ -327,7 +327,7 @@ importers: version: 29.1.1 ng-packagr: specifier: 22.1.0-next.1 - version: 22.1.0-next.1(@angular/compiler-cli@22.0.0(@angular/compiler@22.0.0)(typescript@6.0.3))(tslib@2.8.1)(typescript@6.0.3) + version: 22.1.0-next.1(@angular/compiler-cli@22.1.0-next.0(@angular/compiler@22.1.0-next.0)(typescript@6.0.3))(tslib@2.8.1)(typescript@6.0.3) rxjs: specifier: 7.8.2 version: 7.8.2 @@ -430,7 +430,7 @@ importers: version: 4.6.4 ng-packagr: specifier: 22.1.0-next.1 - version: 22.1.0-next.1(@angular/compiler-cli@22.0.0(@angular/compiler@22.0.0)(typescript@6.0.3))(tslib@2.8.1)(typescript@6.0.3) + version: 22.1.0-next.1(@angular/compiler-cli@22.1.0-next.0(@angular/compiler@22.1.0-next.0)(typescript@6.0.3))(tslib@2.8.1)(typescript@6.0.3) postcss: specifier: 8.5.15 version: 8.5.15 @@ -527,23 +527,23 @@ importers: specifier: workspace:* version: link:../../angular_devkit/schematics '@angular/common': - specifier: 22.0.0 - version: 22.0.0(@angular/core@22.0.0(@angular/compiler@22.0.0)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2) + specifier: 22.1.0-next.0 + version: 22.1.0-next.0(@angular/core@22.1.0-next.0(@angular/compiler@22.1.0-next.0)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2) '@angular/compiler': - specifier: 22.0.0 - version: 22.0.0 + specifier: 22.1.0-next.0 + version: 22.1.0-next.0 '@angular/core': - specifier: 22.0.0 - version: 22.0.0(@angular/compiler@22.0.0)(rxjs@7.8.2)(zone.js@0.16.2) + specifier: 22.1.0-next.0 + version: 22.1.0-next.0(@angular/compiler@22.1.0-next.0)(rxjs@7.8.2)(zone.js@0.16.2) '@angular/platform-browser': - specifier: 22.0.0 - version: 22.0.0(@angular/animations@22.0.0(@angular/core@22.0.0(@angular/compiler@22.0.0)(rxjs@7.8.2)(zone.js@0.16.2)))(@angular/common@22.0.0(@angular/core@22.0.0(@angular/compiler@22.0.0)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2))(@angular/core@22.0.0(@angular/compiler@22.0.0)(rxjs@7.8.2)(zone.js@0.16.2)) + specifier: 22.1.0-next.0 + version: 22.1.0-next.0(@angular/animations@22.1.0-next.0(@angular/core@22.1.0-next.0(@angular/compiler@22.1.0-next.0)(rxjs@7.8.2)(zone.js@0.16.2)))(@angular/common@22.1.0-next.0(@angular/core@22.1.0-next.0(@angular/compiler@22.1.0-next.0)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2))(@angular/core@22.1.0-next.0(@angular/compiler@22.1.0-next.0)(rxjs@7.8.2)(zone.js@0.16.2)) '@angular/platform-server': - specifier: 22.0.0 - version: 22.0.0(@angular/common@22.0.0(@angular/core@22.0.0(@angular/compiler@22.0.0)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2))(@angular/compiler@22.0.0)(@angular/core@22.0.0(@angular/compiler@22.0.0)(rxjs@7.8.2)(zone.js@0.16.2))(@angular/platform-browser@22.0.0(@angular/animations@22.0.0(@angular/core@22.0.0(@angular/compiler@22.0.0)(rxjs@7.8.2)(zone.js@0.16.2)))(@angular/common@22.0.0(@angular/core@22.0.0(@angular/compiler@22.0.0)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2))(@angular/core@22.0.0(@angular/compiler@22.0.0)(rxjs@7.8.2)(zone.js@0.16.2)))(rxjs@7.8.2) + specifier: 22.1.0-next.0 + version: 22.1.0-next.0(@angular/common@22.1.0-next.0(@angular/core@22.1.0-next.0(@angular/compiler@22.1.0-next.0)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2))(@angular/compiler@22.1.0-next.0)(@angular/core@22.1.0-next.0(@angular/compiler@22.1.0-next.0)(rxjs@7.8.2)(zone.js@0.16.2))(@angular/platform-browser@22.1.0-next.0(@angular/animations@22.1.0-next.0(@angular/core@22.1.0-next.0(@angular/compiler@22.1.0-next.0)(rxjs@7.8.2)(zone.js@0.16.2)))(@angular/common@22.1.0-next.0(@angular/core@22.1.0-next.0(@angular/compiler@22.1.0-next.0)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2))(@angular/core@22.1.0-next.0(@angular/compiler@22.1.0-next.0)(rxjs@7.8.2)(zone.js@0.16.2)))(rxjs@7.8.2) '@angular/router': - specifier: 22.0.0 - version: 22.0.0(@angular/common@22.0.0(@angular/core@22.0.0(@angular/compiler@22.0.0)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2))(@angular/core@22.0.0(@angular/compiler@22.0.0)(rxjs@7.8.2)(zone.js@0.16.2))(@angular/platform-browser@22.0.0(@angular/animations@22.0.0(@angular/core@22.0.0(@angular/compiler@22.0.0)(rxjs@7.8.2)(zone.js@0.16.2)))(@angular/common@22.0.0(@angular/core@22.0.0(@angular/compiler@22.0.0)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2))(@angular/core@22.0.0(@angular/compiler@22.0.0)(rxjs@7.8.2)(zone.js@0.16.2)))(rxjs@7.8.2) + specifier: 22.1.0-next.0 + version: 22.1.0-next.0(@angular/common@22.1.0-next.0(@angular/core@22.1.0-next.0(@angular/compiler@22.1.0-next.0)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2))(@angular/core@22.1.0-next.0(@angular/compiler@22.1.0-next.0)(rxjs@7.8.2)(zone.js@0.16.2))(@angular/platform-browser@22.1.0-next.0(@angular/animations@22.1.0-next.0(@angular/core@22.1.0-next.0(@angular/compiler@22.1.0-next.0)(rxjs@7.8.2)(zone.js@0.16.2)))(@angular/common@22.1.0-next.0(@angular/core@22.1.0-next.0(@angular/compiler@22.1.0-next.0)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2))(@angular/core@22.1.0-next.0(@angular/compiler@22.1.0-next.0)(rxjs@7.8.2)(zone.js@0.16.2)))(rxjs@7.8.2) '@schematics/angular': specifier: workspace:* version: link:../../schematics/angular @@ -730,7 +730,7 @@ importers: version: 3.0.4(bufferutil@4.1.0)(utf-8-validate@6.0.6) ng-packagr: specifier: 22.1.0-next.1 - version: 22.1.0-next.1(@angular/compiler-cli@22.0.0(@angular/compiler@22.0.0)(typescript@6.0.3))(tslib@2.8.1)(typescript@6.0.3) + version: 22.1.0-next.1(@angular/compiler-cli@22.1.0-next.0(@angular/compiler@22.1.0-next.0)(typescript@6.0.3))(tslib@2.8.1)(typescript@6.0.3) undici: specifier: 8.3.0 version: 8.3.0 @@ -822,11 +822,11 @@ importers: specifier: workspace:0.0.0-PLACEHOLDER version: link:../../angular_devkit/core '@angular/compiler': - specifier: 22.0.0 - version: 22.0.0 + specifier: 22.1.0-next.0 + version: 22.1.0-next.0 '@angular/compiler-cli': - specifier: 22.0.0 - version: 22.0.0(@angular/compiler@22.0.0)(typescript@6.0.3) + specifier: 22.1.0-next.0 + version: 22.1.0-next.0(@angular/compiler@22.1.0-next.0)(typescript@6.0.3) typescript: specifier: 6.0.3 version: 6.0.3 @@ -935,47 +935,48 @@ packages: resolution: {integrity: sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==} engines: {node: '>=6.0.0'} - '@angular/animations@22.0.0': - resolution: {integrity: sha512-Klo9ZiRj5ykXPliUmwy0eXvDad079YMy+Ob4EITSFSXVLRy55qv64/8SvWNtKEQPelF50H9O2vULoqpIvdWoAw==} + '@angular/animations@22.1.0-next.0': + resolution: {integrity: sha512-Gi3BNfHZEfqs9EZrnd9rAiuh8YKfiijs4YJO0mJWWmJULmgaISJVfrOCv1+iqlSy/VnN3cVtHpNtwvqiMyU0Sg==} engines: {node: ^22.22.3 || ^24.15.0 || >=26.0.0} + deprecated: '@angular/animations is deprecated. Use `animate.enter` and `animate.leave` instead.' peerDependencies: - '@angular/core': 22.0.0 + '@angular/core': 22.1.0-next.0 - '@angular/cdk@22.0.0': - resolution: {integrity: sha512-mahXlRD4V8Tj2NtttRNFfuTru5HmMgJt8ny/SJ/Bx1NCOymxLEqxREACNpuwMf/3q1XUe33/oh++mvJQ2JYkgw==} + '@angular/cdk@22.1.0-next.0': + resolution: {integrity: sha512-LlWJs+rf8PUCM9HMJ8KZqqFTw6gQWoIrAnDuKi1KjBULURYjY7iQomtYEl6fQ+Zi1Ta+erRz6oIPftgdAV5p/g==} peerDependencies: - '@angular/common': ^22.0.0 || ^23.0.0 - '@angular/core': ^22.0.0 || ^23.0.0 - '@angular/platform-browser': ^22.0.0 || ^23.0.0 + '@angular/common': ^22.0.0-0 || ^22.1.0-0 || ^22.2.0-0 || ^22.3.0-0 || ^23.0.0-0 + '@angular/core': ^22.0.0-0 || ^22.1.0-0 || ^22.2.0-0 || ^22.3.0-0 || ^23.0.0-0 + '@angular/platform-browser': ^22.0.0-0 || ^22.1.0-0 || ^22.2.0-0 || ^22.3.0-0 || ^23.0.0-0 rxjs: ^6.5.3 || ^7.4.0 - '@angular/common@22.0.0': - resolution: {integrity: sha512-O9Qk60/OQQuZXMeXRfOpsq+/B609nd5KIxjSZFddRQUfSMZrdvVDNK0irjgYVKGDkMx3dqCiQ8a4nAIdGy7V6A==} + '@angular/common@22.1.0-next.0': + resolution: {integrity: sha512-d6hYNsG73xouc0kON+p0Hw8DqDgQwllh8xATxjCkjHtu551eMGptRy1+vUIcZJEZbM8BQNXt+/VuHS2rVLlEBA==} engines: {node: ^22.22.3 || ^24.15.0 || >=26.0.0} peerDependencies: - '@angular/core': 22.0.0 + '@angular/core': 22.1.0-next.0 rxjs: ^6.5.3 || ^7.4.0 - '@angular/compiler-cli@22.0.0': - resolution: {integrity: sha512-7r4ufQ8CUhlRBol/N8a6psg40kOu/Y3H6iuUGwq9cs6Gs/fII7mVB6QgPi0bCiNDjaQB7xGq6NZ0iT6CPBH8Sw==} + '@angular/compiler-cli@22.1.0-next.0': + resolution: {integrity: sha512-vZiE7QVG7pMLyoBiSpFWzDtXqCBCZCo3QdgbTEqIym2/bVCPLcZ32HIBsbmbJG4O311OIfpsmxLNPlUojw1QCw==} engines: {node: ^22.22.3 || ^24.15.0 || >=26.0.0} hasBin: true peerDependencies: - '@angular/compiler': 22.0.0 + '@angular/compiler': 22.1.0-next.0 typescript: '>=6.0 <6.1' peerDependenciesMeta: typescript: optional: true - '@angular/compiler@22.0.0': - resolution: {integrity: sha512-g8Ab5Lcji2cxADfcPPM7kltEzSlCjUevPK3udm+3S5uhkTcLNH236/XCAwhD1XIgHQDv9p7FWm1xS7zkvbwXhA==} + '@angular/compiler@22.1.0-next.0': + resolution: {integrity: sha512-ghmJI+tuVYUbkvrovWmv1/9g2u94H3kcFRnGVOmI58j6gCBxOxuUeLujTGQzDtgz7wXjkekpsgml5hxRwIOGBg==} engines: {node: ^22.22.3 || ^24.15.0 || >=26.0.0} - '@angular/core@22.0.0': - resolution: {integrity: sha512-H4lzunB+LUNylQ3hZGYWDz1NfNAdFzPdOadwuS6VpPyxF4Ti0MLyAfx7NDnyTrmdY2/PFx8I6jXrveNlIsORXg==} + '@angular/core@22.1.0-next.0': + resolution: {integrity: sha512-SfGaPijz4D/GGlOK0UpGRAVA/Ri3W1tu06ASOn/Hcan39n2Wq733ot4NUPTEaxZOr91FYMaXZ1bPdriDM9vTag==} engines: {node: ^22.22.3 || ^24.15.0 || >=26.0.0} peerDependencies: - '@angular/compiler': 22.0.0 + '@angular/compiler': 22.1.0-next.0 rxjs: ^6.5.3 || ^7.4.0 zone.js: ~0.15.0 || ~0.16.0 peerDependenciesMeta: @@ -984,74 +985,74 @@ packages: zone.js: optional: true - '@angular/forms@22.0.0': - resolution: {integrity: sha512-OjyiF0hgbNXrFbIgqazyNJlFTtqfU0kfwJgmlMr4FG+e9P89UmgZhELUWs1CIuNX+jhh3DePm+Fo26dJIS7cfg==} + '@angular/forms@22.1.0-next.0': + resolution: {integrity: sha512-4IzC7IBKnXXNlukBs6d8r8MaxB6CCQlRyDglSQPilVnwy4Qht1jHDZWIt5hOI3fFj/1dOl/ccB2zHPxbKTHglA==} engines: {node: ^22.22.3 || ^24.15.0 || >=26.0.0} peerDependencies: - '@angular/common': 22.0.0 - '@angular/core': 22.0.0 - '@angular/platform-browser': 22.0.0 + '@angular/common': 22.1.0-next.0 + '@angular/core': 22.1.0-next.0 + '@angular/platform-browser': 22.1.0-next.0 rxjs: ^6.5.3 || ^7.4.0 - '@angular/localize@22.0.0': - resolution: {integrity: sha512-K3qGoi3+jGHp+HN2YGMlCaQHDYfF8O+XxvOvAffl1TpoGfzFqEwDv3tHpYmrF99JH5S8NiTBWcdDBZ/BP6E9qQ==} + '@angular/localize@22.1.0-next.0': + resolution: {integrity: sha512-7R2eI5mqYpI9moYYJ0mWbxdtE9KL+vlBXxKjydhNAcTSo8pZSaeIep5LNST72cbGCy7E/nwWQNCStrRoF0Mqgg==} engines: {node: ^22.22.3 || ^24.15.0 || >=26.0.0} hasBin: true peerDependencies: - '@angular/compiler': 22.0.0 - '@angular/compiler-cli': 22.0.0 + '@angular/compiler': 22.1.0-next.0 + '@angular/compiler-cli': 22.1.0-next.0 - '@angular/material@22.0.0': - resolution: {integrity: sha512-sRxbEEgmaVqbwcT65PWfZV/cIpLsZ8vD+yc6rH83L83jDJWVABpqDWFg8Hl88iFMOts8iffml6GddvXhsNHAEQ==} + '@angular/material@22.1.0-next.0': + resolution: {integrity: sha512-7ey//rQjKTC1IvhQ/F9D2feN5DPkoUUtUdpExMSCUaeN/fA74+msdxIMHX0nylB9eFDRuyToCJ5AAsCDW4IsMA==} peerDependencies: - '@angular/cdk': 22.0.0 - '@angular/common': ^22.0.0 || ^23.0.0 - '@angular/core': ^22.0.0 || ^23.0.0 - '@angular/forms': ^22.0.0 || ^23.0.0 - '@angular/platform-browser': ^22.0.0 || ^23.0.0 + '@angular/cdk': 22.1.0-next.0 + '@angular/common': ^22.0.0-0 || ^22.1.0-0 || ^22.2.0-0 || ^22.3.0-0 || ^23.0.0-0 + '@angular/core': ^22.0.0-0 || ^22.1.0-0 || ^22.2.0-0 || ^22.3.0-0 || ^23.0.0-0 + '@angular/forms': ^22.0.0-0 || ^22.1.0-0 || ^22.2.0-0 || ^22.3.0-0 || ^23.0.0-0 + '@angular/platform-browser': ^22.0.0-0 || ^22.1.0-0 || ^22.2.0-0 || ^22.3.0-0 || ^23.0.0-0 rxjs: ^6.5.3 || ^7.4.0 - '@angular/ng-dev@https://codeload.github.com/angular/dev-infra-private-ng-dev-builds/tar.gz/68eef04ac1e37b69e3e61d3e32802e0a6046d54c': - resolution: {gitHosted: true, integrity: sha512-T6Drp02fXuaD+9yiRcv4bXTKsMROEIuCATiKQSgcILd02lT9FoyqBzNHdNHzHEYNtOZeLhMn+hkhooTTAlcpPw==, tarball: https://codeload.github.com/angular/dev-infra-private-ng-dev-builds/tar.gz/68eef04ac1e37b69e3e61d3e32802e0a6046d54c} - version: 0.0.0-cef5e36af124e7442d7e2868be3f8c0bba496952 + '@angular/ng-dev@https://codeload.github.com/angular/dev-infra-private-ng-dev-builds/tar.gz/5d9842518819d66cfb65994e2dda90354410a449': + resolution: {gitHosted: true, integrity: sha512-sp07Jlt/pO9uei3u6ZJdLgnOJ+Dj4/Jl30FjapEWoQf+M9f2UQ2waL1rN5thZCcHQnwNfbNbIHDCcXPFQjFeUg==, tarball: https://codeload.github.com/angular/dev-infra-private-ng-dev-builds/tar.gz/5d9842518819d66cfb65994e2dda90354410a449} + version: 0.0.0-b9d15e3de22a6b8b161046d1ed5cea574a2537ca hasBin: true - '@angular/platform-browser@22.0.0': - resolution: {integrity: sha512-ry4Hdov19V8sA+MrIEIeISXA8GKWluCDUg06PaAm9nJveYjQUUlElZqa3fTNGOmy3/eNV8H9nmaroD27L8yU1A==} + '@angular/platform-browser@22.1.0-next.0': + resolution: {integrity: sha512-xTZZOA5j0CNXm94rfX6FPtVAvbrutRAwD6RkNn+V8vBljZmj4VY/RZZFvhWx6EvcQe0vkOs/2nAtibx38PHxZQ==} engines: {node: ^22.22.3 || ^24.15.0 || >=26.0.0} peerDependencies: - '@angular/animations': 22.0.0 - '@angular/common': 22.0.0 - '@angular/core': 22.0.0 + '@angular/animations': 22.1.0-next.0 + '@angular/common': 22.1.0-next.0 + '@angular/core': 22.1.0-next.0 peerDependenciesMeta: '@angular/animations': optional: true - '@angular/platform-server@22.0.0': - resolution: {integrity: sha512-ruwVqS0g38/2ATl+iB04/SwL7qAGOT5uEKeXUdeitx+gxE+DOq4MoCc4cr5sq6kS0/XpQ+p1RBnzHxU5XKpJUA==} + '@angular/platform-server@22.1.0-next.0': + resolution: {integrity: sha512-Lr2gk3hE+moDuoev7389iL9BdZZM0vS48hR2wv/2EANaYGKTr8QmVsdPBqqZgR5t9In/eDRvGUej9F8jhXzHNQ==} engines: {node: ^22.22.3 || ^24.15.0 || >=26.0.0} peerDependencies: - '@angular/common': 22.0.0 - '@angular/compiler': 22.0.0 - '@angular/core': 22.0.0 - '@angular/platform-browser': 22.0.0 + '@angular/common': 22.1.0-next.0 + '@angular/compiler': 22.1.0-next.0 + '@angular/core': 22.1.0-next.0 + '@angular/platform-browser': 22.1.0-next.0 rxjs: ^6.5.3 || ^7.4.0 - '@angular/router@22.0.0': - resolution: {integrity: sha512-CCtonkDVkkfKLtuKol8rC1zmWI4QX7w3uUtdlOoz6K9HXAhpZYGcSq5RyloA767QLj36u7108K9xHBs2abOajQ==} + '@angular/router@22.1.0-next.0': + resolution: {integrity: sha512-GvYwRQeuPLcYP/7S0FwdbeFDvGnzmuPD7P/8oMO36hKSreUZ9UEL7V+rM3FR+AvY5mj0t2onzbLGY7UgM0itDw==} engines: {node: ^22.22.3 || ^24.15.0 || >=26.0.0} peerDependencies: - '@angular/common': 22.0.0 - '@angular/core': 22.0.0 - '@angular/platform-browser': 22.0.0 + '@angular/common': 22.1.0-next.0 + '@angular/core': 22.1.0-next.0 + '@angular/platform-browser': 22.1.0-next.0 rxjs: ^6.5.3 || ^7.4.0 - '@angular/service-worker@22.0.0': - resolution: {integrity: sha512-QpY57hBHh9BI/3L/MxbtYuQ0eZc+ra/7TB6VSLLg9zLA8jbScqWphyB5+Xsyn0u8Z8c3aEA3I+zZgv3r8wlN4g==} + '@angular/service-worker@22.1.0-next.0': + resolution: {integrity: sha512-0r7DUPWoKxeamhf0ao64k1OD053jYYDpLMLa10FudiF04mBqVj9z31hHGDCPi7H2SMFnERwKK6JDyjFTUMJqSQ==} engines: {node: ^22.22.3 || ^24.15.0 || >=26.0.0} hasBin: true peerDependencies: - '@angular/core': 22.0.0 + '@angular/core': 22.1.0-next.0 rxjs: ^6.5.3 || ^7.4.0 '@asamuzakjp/css-color@5.1.11': @@ -1077,10 +1078,6 @@ packages: resolution: {integrity: sha512-locTkQyKvwIEgBzVrn8693ebc97F2U8ZHjbXwDXJ5Fn2TCpNwTlKcaKLkdHop5c/icOFE7qt7Q9JC5hnKNa6Gg==} engines: {node: '>=6.9.0'} - '@babel/core@7.29.0': - resolution: {integrity: sha512-CGOfOJqWjg2qW/Mb6zNsDm+u5vFQ8DxXfbM09z69p5Z6+mE1ikP2jUXw+j42Pf1XTYED2Rni5f95npYeuwMDQA==} - engines: {node: '>=6.9.0'} - '@babel/core@7.29.7': resolution: {integrity: sha512-RgHBCvtjbOK2gXSNBNIkNoEc9qoVEtau3hj8gEqKQuL3HZAibKarWFEI3Lfm6EYKkLalOh8eSrj9b+ch9H/VBA==} engines: {node: '>=6.9.0'} @@ -4943,8 +4940,8 @@ packages: ee-first@1.1.1: resolution: {integrity: sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==} - ejs@5.0.2: - resolution: {integrity: sha512-IpbUaI/CAW86l3f+T8zN0iggSc0LmMZLcIW5eRVStLVNCoTXkE0YlncbbH50fp8Cl6zHIky0sW2uUbhBqGw0Jw==} + ejs@6.0.1: + resolution: {integrity: sha512-UaaM14yby8U3k02ihS1Bmj5Kz2d7CCQM1scxpgs4Mhkq8F1wR2gl3+Ts4h5Ne4Mnt7M9m4Dw7jsuMr3+xO4vZA==} engines: {node: '>=0.12.18'} hasBin: true @@ -8678,30 +8675,30 @@ snapshots: '@jridgewell/gen-mapping': 0.3.13 '@jridgewell/trace-mapping': 0.3.31 - '@angular/animations@22.0.0(@angular/core@22.0.0(@angular/compiler@22.0.0)(rxjs@7.8.2)(zone.js@0.16.2))': + '@angular/animations@22.1.0-next.0(@angular/core@22.1.0-next.0(@angular/compiler@22.1.0-next.0)(rxjs@7.8.2)(zone.js@0.16.2))': dependencies: - '@angular/core': 22.0.0(@angular/compiler@22.0.0)(rxjs@7.8.2)(zone.js@0.16.2) + '@angular/core': 22.1.0-next.0(@angular/compiler@22.1.0-next.0)(rxjs@7.8.2)(zone.js@0.16.2) tslib: 2.8.1 - '@angular/cdk@22.0.0(@angular/common@22.0.0(@angular/core@22.0.0(@angular/compiler@22.0.0)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2))(@angular/core@22.0.0(@angular/compiler@22.0.0)(rxjs@7.8.2)(zone.js@0.16.2))(@angular/platform-browser@22.0.0(@angular/animations@22.0.0(@angular/core@22.0.0(@angular/compiler@22.0.0)(rxjs@7.8.2)(zone.js@0.16.2)))(@angular/common@22.0.0(@angular/core@22.0.0(@angular/compiler@22.0.0)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2))(@angular/core@22.0.0(@angular/compiler@22.0.0)(rxjs@7.8.2)(zone.js@0.16.2)))(rxjs@7.8.2)': + '@angular/cdk@22.1.0-next.0(@angular/common@22.1.0-next.0(@angular/core@22.1.0-next.0(@angular/compiler@22.1.0-next.0)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2))(@angular/core@22.1.0-next.0(@angular/compiler@22.1.0-next.0)(rxjs@7.8.2)(zone.js@0.16.2))(@angular/platform-browser@22.1.0-next.0(@angular/animations@22.1.0-next.0(@angular/core@22.1.0-next.0(@angular/compiler@22.1.0-next.0)(rxjs@7.8.2)(zone.js@0.16.2)))(@angular/common@22.1.0-next.0(@angular/core@22.1.0-next.0(@angular/compiler@22.1.0-next.0)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2))(@angular/core@22.1.0-next.0(@angular/compiler@22.1.0-next.0)(rxjs@7.8.2)(zone.js@0.16.2)))(rxjs@7.8.2)': dependencies: - '@angular/common': 22.0.0(@angular/core@22.0.0(@angular/compiler@22.0.0)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2) - '@angular/core': 22.0.0(@angular/compiler@22.0.0)(rxjs@7.8.2)(zone.js@0.16.2) - '@angular/platform-browser': 22.0.0(@angular/animations@22.0.0(@angular/core@22.0.0(@angular/compiler@22.0.0)(rxjs@7.8.2)(zone.js@0.16.2)))(@angular/common@22.0.0(@angular/core@22.0.0(@angular/compiler@22.0.0)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2))(@angular/core@22.0.0(@angular/compiler@22.0.0)(rxjs@7.8.2)(zone.js@0.16.2)) + '@angular/common': 22.1.0-next.0(@angular/core@22.1.0-next.0(@angular/compiler@22.1.0-next.0)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2) + '@angular/core': 22.1.0-next.0(@angular/compiler@22.1.0-next.0)(rxjs@7.8.2)(zone.js@0.16.2) + '@angular/platform-browser': 22.1.0-next.0(@angular/animations@22.1.0-next.0(@angular/core@22.1.0-next.0(@angular/compiler@22.1.0-next.0)(rxjs@7.8.2)(zone.js@0.16.2)))(@angular/common@22.1.0-next.0(@angular/core@22.1.0-next.0(@angular/compiler@22.1.0-next.0)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2))(@angular/core@22.1.0-next.0(@angular/compiler@22.1.0-next.0)(rxjs@7.8.2)(zone.js@0.16.2)) parse5: 8.0.1 rxjs: 7.8.2 tslib: 2.8.1 - '@angular/common@22.0.0(@angular/core@22.0.0(@angular/compiler@22.0.0)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2)': + '@angular/common@22.1.0-next.0(@angular/core@22.1.0-next.0(@angular/compiler@22.1.0-next.0)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2)': dependencies: - '@angular/core': 22.0.0(@angular/compiler@22.0.0)(rxjs@7.8.2)(zone.js@0.16.2) + '@angular/core': 22.1.0-next.0(@angular/compiler@22.1.0-next.0)(rxjs@7.8.2)(zone.js@0.16.2) rxjs: 7.8.2 tslib: 2.8.1 - '@angular/compiler-cli@22.0.0(@angular/compiler@22.0.0)(typescript@6.0.3)': + '@angular/compiler-cli@22.1.0-next.0(@angular/compiler@22.1.0-next.0)(typescript@6.0.3)': dependencies: - '@angular/compiler': 22.0.0 - '@babel/core': 7.29.0 + '@angular/compiler': 22.1.0-next.0 + '@babel/core': 7.29.7 '@jridgewell/sourcemap-codec': 1.5.5 chokidar: 5.0.0 convert-source-map: 1.9.0 @@ -8714,50 +8711,50 @@ snapshots: transitivePeerDependencies: - supports-color - '@angular/compiler@22.0.0': + '@angular/compiler@22.1.0-next.0': dependencies: tslib: 2.8.1 - '@angular/core@22.0.0(@angular/compiler@22.0.0)(rxjs@7.8.2)(zone.js@0.16.2)': + '@angular/core@22.1.0-next.0(@angular/compiler@22.1.0-next.0)(rxjs@7.8.2)(zone.js@0.16.2)': dependencies: rxjs: 7.8.2 tslib: 2.8.1 optionalDependencies: - '@angular/compiler': 22.0.0 + '@angular/compiler': 22.1.0-next.0 zone.js: 0.16.2 - '@angular/forms@22.0.0(@angular/common@22.0.0(@angular/core@22.0.0(@angular/compiler@22.0.0)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2))(@angular/core@22.0.0(@angular/compiler@22.0.0)(rxjs@7.8.2)(zone.js@0.16.2))(@angular/platform-browser@22.0.0(@angular/animations@22.0.0(@angular/core@22.0.0(@angular/compiler@22.0.0)(rxjs@7.8.2)(zone.js@0.16.2)))(@angular/common@22.0.0(@angular/core@22.0.0(@angular/compiler@22.0.0)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2))(@angular/core@22.0.0(@angular/compiler@22.0.0)(rxjs@7.8.2)(zone.js@0.16.2)))(rxjs@7.8.2)': + '@angular/forms@22.1.0-next.0(@angular/common@22.1.0-next.0(@angular/core@22.1.0-next.0(@angular/compiler@22.1.0-next.0)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2))(@angular/core@22.1.0-next.0(@angular/compiler@22.1.0-next.0)(rxjs@7.8.2)(zone.js@0.16.2))(@angular/platform-browser@22.1.0-next.0(@angular/animations@22.1.0-next.0(@angular/core@22.1.0-next.0(@angular/compiler@22.1.0-next.0)(rxjs@7.8.2)(zone.js@0.16.2)))(@angular/common@22.1.0-next.0(@angular/core@22.1.0-next.0(@angular/compiler@22.1.0-next.0)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2))(@angular/core@22.1.0-next.0(@angular/compiler@22.1.0-next.0)(rxjs@7.8.2)(zone.js@0.16.2)))(rxjs@7.8.2)': dependencies: - '@angular/common': 22.0.0(@angular/core@22.0.0(@angular/compiler@22.0.0)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2) - '@angular/core': 22.0.0(@angular/compiler@22.0.0)(rxjs@7.8.2)(zone.js@0.16.2) - '@angular/platform-browser': 22.0.0(@angular/animations@22.0.0(@angular/core@22.0.0(@angular/compiler@22.0.0)(rxjs@7.8.2)(zone.js@0.16.2)))(@angular/common@22.0.0(@angular/core@22.0.0(@angular/compiler@22.0.0)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2))(@angular/core@22.0.0(@angular/compiler@22.0.0)(rxjs@7.8.2)(zone.js@0.16.2)) + '@angular/common': 22.1.0-next.0(@angular/core@22.1.0-next.0(@angular/compiler@22.1.0-next.0)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2) + '@angular/core': 22.1.0-next.0(@angular/compiler@22.1.0-next.0)(rxjs@7.8.2)(zone.js@0.16.2) + '@angular/platform-browser': 22.1.0-next.0(@angular/animations@22.1.0-next.0(@angular/core@22.1.0-next.0(@angular/compiler@22.1.0-next.0)(rxjs@7.8.2)(zone.js@0.16.2)))(@angular/common@22.1.0-next.0(@angular/core@22.1.0-next.0(@angular/compiler@22.1.0-next.0)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2))(@angular/core@22.1.0-next.0(@angular/compiler@22.1.0-next.0)(rxjs@7.8.2)(zone.js@0.16.2)) '@standard-schema/spec': 1.1.0 rxjs: 7.8.2 tslib: 2.8.1 zod: 4.4.3 - '@angular/localize@22.0.0(@angular/compiler-cli@22.0.0(@angular/compiler@22.0.0)(typescript@6.0.3))(@angular/compiler@22.0.0)': + '@angular/localize@22.1.0-next.0(@angular/compiler-cli@22.1.0-next.0(@angular/compiler@22.1.0-next.0)(typescript@6.0.3))(@angular/compiler@22.1.0-next.0)': dependencies: - '@angular/compiler': 22.0.0 - '@angular/compiler-cli': 22.0.0(@angular/compiler@22.0.0)(typescript@6.0.3) - '@babel/core': 7.29.0 + '@angular/compiler': 22.1.0-next.0 + '@angular/compiler-cli': 22.1.0-next.0(@angular/compiler@22.1.0-next.0)(typescript@6.0.3) + '@babel/core': 7.29.7 '@types/babel__core': 7.20.5 tinyglobby: 0.2.17 yargs: 18.0.0 transitivePeerDependencies: - supports-color - '@angular/material@22.0.0(6eb83275f51d1d41f72333b1955c7306)': + '@angular/material@22.1.0-next.0(25ca0260cba80497f59a6bedbf88cafa)': dependencies: - '@angular/cdk': 22.0.0(@angular/common@22.0.0(@angular/core@22.0.0(@angular/compiler@22.0.0)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2))(@angular/core@22.0.0(@angular/compiler@22.0.0)(rxjs@7.8.2)(zone.js@0.16.2))(@angular/platform-browser@22.0.0(@angular/animations@22.0.0(@angular/core@22.0.0(@angular/compiler@22.0.0)(rxjs@7.8.2)(zone.js@0.16.2)))(@angular/common@22.0.0(@angular/core@22.0.0(@angular/compiler@22.0.0)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2))(@angular/core@22.0.0(@angular/compiler@22.0.0)(rxjs@7.8.2)(zone.js@0.16.2)))(rxjs@7.8.2) - '@angular/common': 22.0.0(@angular/core@22.0.0(@angular/compiler@22.0.0)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2) - '@angular/core': 22.0.0(@angular/compiler@22.0.0)(rxjs@7.8.2)(zone.js@0.16.2) - '@angular/forms': 22.0.0(@angular/common@22.0.0(@angular/core@22.0.0(@angular/compiler@22.0.0)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2))(@angular/core@22.0.0(@angular/compiler@22.0.0)(rxjs@7.8.2)(zone.js@0.16.2))(@angular/platform-browser@22.0.0(@angular/animations@22.0.0(@angular/core@22.0.0(@angular/compiler@22.0.0)(rxjs@7.8.2)(zone.js@0.16.2)))(@angular/common@22.0.0(@angular/core@22.0.0(@angular/compiler@22.0.0)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2))(@angular/core@22.0.0(@angular/compiler@22.0.0)(rxjs@7.8.2)(zone.js@0.16.2)))(rxjs@7.8.2) - '@angular/platform-browser': 22.0.0(@angular/animations@22.0.0(@angular/core@22.0.0(@angular/compiler@22.0.0)(rxjs@7.8.2)(zone.js@0.16.2)))(@angular/common@22.0.0(@angular/core@22.0.0(@angular/compiler@22.0.0)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2))(@angular/core@22.0.0(@angular/compiler@22.0.0)(rxjs@7.8.2)(zone.js@0.16.2)) + '@angular/cdk': 22.1.0-next.0(@angular/common@22.1.0-next.0(@angular/core@22.1.0-next.0(@angular/compiler@22.1.0-next.0)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2))(@angular/core@22.1.0-next.0(@angular/compiler@22.1.0-next.0)(rxjs@7.8.2)(zone.js@0.16.2))(@angular/platform-browser@22.1.0-next.0(@angular/animations@22.1.0-next.0(@angular/core@22.1.0-next.0(@angular/compiler@22.1.0-next.0)(rxjs@7.8.2)(zone.js@0.16.2)))(@angular/common@22.1.0-next.0(@angular/core@22.1.0-next.0(@angular/compiler@22.1.0-next.0)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2))(@angular/core@22.1.0-next.0(@angular/compiler@22.1.0-next.0)(rxjs@7.8.2)(zone.js@0.16.2)))(rxjs@7.8.2) + '@angular/common': 22.1.0-next.0(@angular/core@22.1.0-next.0(@angular/compiler@22.1.0-next.0)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2) + '@angular/core': 22.1.0-next.0(@angular/compiler@22.1.0-next.0)(rxjs@7.8.2)(zone.js@0.16.2) + '@angular/forms': 22.1.0-next.0(@angular/common@22.1.0-next.0(@angular/core@22.1.0-next.0(@angular/compiler@22.1.0-next.0)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2))(@angular/core@22.1.0-next.0(@angular/compiler@22.1.0-next.0)(rxjs@7.8.2)(zone.js@0.16.2))(@angular/platform-browser@22.1.0-next.0(@angular/animations@22.1.0-next.0(@angular/core@22.1.0-next.0(@angular/compiler@22.1.0-next.0)(rxjs@7.8.2)(zone.js@0.16.2)))(@angular/common@22.1.0-next.0(@angular/core@22.1.0-next.0(@angular/compiler@22.1.0-next.0)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2))(@angular/core@22.1.0-next.0(@angular/compiler@22.1.0-next.0)(rxjs@7.8.2)(zone.js@0.16.2)))(rxjs@7.8.2) + '@angular/platform-browser': 22.1.0-next.0(@angular/animations@22.1.0-next.0(@angular/core@22.1.0-next.0(@angular/compiler@22.1.0-next.0)(rxjs@7.8.2)(zone.js@0.16.2)))(@angular/common@22.1.0-next.0(@angular/core@22.1.0-next.0(@angular/compiler@22.1.0-next.0)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2))(@angular/core@22.1.0-next.0(@angular/compiler@22.1.0-next.0)(rxjs@7.8.2)(zone.js@0.16.2)) rxjs: 7.8.2 tslib: 2.8.1 - '@angular/ng-dev@https://codeload.github.com/angular/dev-infra-private-ng-dev-builds/tar.gz/68eef04ac1e37b69e3e61d3e32802e0a6046d54c(@modelcontextprotocol/sdk@1.29.0(zod@4.4.3))': + '@angular/ng-dev@https://codeload.github.com/angular/dev-infra-private-ng-dev-builds/tar.gz/5d9842518819d66cfb65994e2dda90354410a449(@modelcontextprotocol/sdk@1.29.0(zod@4.4.3))': dependencies: '@actions/core': 3.0.1 '@conventional-changelog/git-client': 2.7.0(conventional-commits-filter@5.0.0)(conventional-commits-parser@6.4.0) @@ -8791,7 +8788,7 @@ snapshots: cli-progress: 3.12.0 conventional-commits-filter: 5.0.0 conventional-commits-parser: 6.4.0 - ejs: 5.0.2 + ejs: 6.0.1 encoding: 0.1.13 fast-glob: 3.3.3 firebase: 12.14.0 @@ -8817,35 +8814,35 @@ snapshots: - '@modelcontextprotocol/sdk' - '@react-native-async-storage/async-storage' - '@angular/platform-browser@22.0.0(@angular/animations@22.0.0(@angular/core@22.0.0(@angular/compiler@22.0.0)(rxjs@7.8.2)(zone.js@0.16.2)))(@angular/common@22.0.0(@angular/core@22.0.0(@angular/compiler@22.0.0)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2))(@angular/core@22.0.0(@angular/compiler@22.0.0)(rxjs@7.8.2)(zone.js@0.16.2))': + '@angular/platform-browser@22.1.0-next.0(@angular/animations@22.1.0-next.0(@angular/core@22.1.0-next.0(@angular/compiler@22.1.0-next.0)(rxjs@7.8.2)(zone.js@0.16.2)))(@angular/common@22.1.0-next.0(@angular/core@22.1.0-next.0(@angular/compiler@22.1.0-next.0)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2))(@angular/core@22.1.0-next.0(@angular/compiler@22.1.0-next.0)(rxjs@7.8.2)(zone.js@0.16.2))': dependencies: - '@angular/common': 22.0.0(@angular/core@22.0.0(@angular/compiler@22.0.0)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2) - '@angular/core': 22.0.0(@angular/compiler@22.0.0)(rxjs@7.8.2)(zone.js@0.16.2) + '@angular/common': 22.1.0-next.0(@angular/core@22.1.0-next.0(@angular/compiler@22.1.0-next.0)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2) + '@angular/core': 22.1.0-next.0(@angular/compiler@22.1.0-next.0)(rxjs@7.8.2)(zone.js@0.16.2) tslib: 2.8.1 optionalDependencies: - '@angular/animations': 22.0.0(@angular/core@22.0.0(@angular/compiler@22.0.0)(rxjs@7.8.2)(zone.js@0.16.2)) + '@angular/animations': 22.1.0-next.0(@angular/core@22.1.0-next.0(@angular/compiler@22.1.0-next.0)(rxjs@7.8.2)(zone.js@0.16.2)) - '@angular/platform-server@22.0.0(@angular/common@22.0.0(@angular/core@22.0.0(@angular/compiler@22.0.0)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2))(@angular/compiler@22.0.0)(@angular/core@22.0.0(@angular/compiler@22.0.0)(rxjs@7.8.2)(zone.js@0.16.2))(@angular/platform-browser@22.0.0(@angular/animations@22.0.0(@angular/core@22.0.0(@angular/compiler@22.0.0)(rxjs@7.8.2)(zone.js@0.16.2)))(@angular/common@22.0.0(@angular/core@22.0.0(@angular/compiler@22.0.0)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2))(@angular/core@22.0.0(@angular/compiler@22.0.0)(rxjs@7.8.2)(zone.js@0.16.2)))(rxjs@7.8.2)': + '@angular/platform-server@22.1.0-next.0(@angular/common@22.1.0-next.0(@angular/core@22.1.0-next.0(@angular/compiler@22.1.0-next.0)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2))(@angular/compiler@22.1.0-next.0)(@angular/core@22.1.0-next.0(@angular/compiler@22.1.0-next.0)(rxjs@7.8.2)(zone.js@0.16.2))(@angular/platform-browser@22.1.0-next.0(@angular/animations@22.1.0-next.0(@angular/core@22.1.0-next.0(@angular/compiler@22.1.0-next.0)(rxjs@7.8.2)(zone.js@0.16.2)))(@angular/common@22.1.0-next.0(@angular/core@22.1.0-next.0(@angular/compiler@22.1.0-next.0)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2))(@angular/core@22.1.0-next.0(@angular/compiler@22.1.0-next.0)(rxjs@7.8.2)(zone.js@0.16.2)))(rxjs@7.8.2)': dependencies: - '@angular/common': 22.0.0(@angular/core@22.0.0(@angular/compiler@22.0.0)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2) - '@angular/compiler': 22.0.0 - '@angular/core': 22.0.0(@angular/compiler@22.0.0)(rxjs@7.8.2)(zone.js@0.16.2) - '@angular/platform-browser': 22.0.0(@angular/animations@22.0.0(@angular/core@22.0.0(@angular/compiler@22.0.0)(rxjs@7.8.2)(zone.js@0.16.2)))(@angular/common@22.0.0(@angular/core@22.0.0(@angular/compiler@22.0.0)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2))(@angular/core@22.0.0(@angular/compiler@22.0.0)(rxjs@7.8.2)(zone.js@0.16.2)) + '@angular/common': 22.1.0-next.0(@angular/core@22.1.0-next.0(@angular/compiler@22.1.0-next.0)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2) + '@angular/compiler': 22.1.0-next.0 + '@angular/core': 22.1.0-next.0(@angular/compiler@22.1.0-next.0)(rxjs@7.8.2)(zone.js@0.16.2) + '@angular/platform-browser': 22.1.0-next.0(@angular/animations@22.1.0-next.0(@angular/core@22.1.0-next.0(@angular/compiler@22.1.0-next.0)(rxjs@7.8.2)(zone.js@0.16.2)))(@angular/common@22.1.0-next.0(@angular/core@22.1.0-next.0(@angular/compiler@22.1.0-next.0)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2))(@angular/core@22.1.0-next.0(@angular/compiler@22.1.0-next.0)(rxjs@7.8.2)(zone.js@0.16.2)) rxjs: 7.8.2 tslib: 2.8.1 xhr2: 0.2.1 - '@angular/router@22.0.0(@angular/common@22.0.0(@angular/core@22.0.0(@angular/compiler@22.0.0)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2))(@angular/core@22.0.0(@angular/compiler@22.0.0)(rxjs@7.8.2)(zone.js@0.16.2))(@angular/platform-browser@22.0.0(@angular/animations@22.0.0(@angular/core@22.0.0(@angular/compiler@22.0.0)(rxjs@7.8.2)(zone.js@0.16.2)))(@angular/common@22.0.0(@angular/core@22.0.0(@angular/compiler@22.0.0)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2))(@angular/core@22.0.0(@angular/compiler@22.0.0)(rxjs@7.8.2)(zone.js@0.16.2)))(rxjs@7.8.2)': + '@angular/router@22.1.0-next.0(@angular/common@22.1.0-next.0(@angular/core@22.1.0-next.0(@angular/compiler@22.1.0-next.0)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2))(@angular/core@22.1.0-next.0(@angular/compiler@22.1.0-next.0)(rxjs@7.8.2)(zone.js@0.16.2))(@angular/platform-browser@22.1.0-next.0(@angular/animations@22.1.0-next.0(@angular/core@22.1.0-next.0(@angular/compiler@22.1.0-next.0)(rxjs@7.8.2)(zone.js@0.16.2)))(@angular/common@22.1.0-next.0(@angular/core@22.1.0-next.0(@angular/compiler@22.1.0-next.0)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2))(@angular/core@22.1.0-next.0(@angular/compiler@22.1.0-next.0)(rxjs@7.8.2)(zone.js@0.16.2)))(rxjs@7.8.2)': dependencies: - '@angular/common': 22.0.0(@angular/core@22.0.0(@angular/compiler@22.0.0)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2) - '@angular/core': 22.0.0(@angular/compiler@22.0.0)(rxjs@7.8.2)(zone.js@0.16.2) - '@angular/platform-browser': 22.0.0(@angular/animations@22.0.0(@angular/core@22.0.0(@angular/compiler@22.0.0)(rxjs@7.8.2)(zone.js@0.16.2)))(@angular/common@22.0.0(@angular/core@22.0.0(@angular/compiler@22.0.0)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2))(@angular/core@22.0.0(@angular/compiler@22.0.0)(rxjs@7.8.2)(zone.js@0.16.2)) + '@angular/common': 22.1.0-next.0(@angular/core@22.1.0-next.0(@angular/compiler@22.1.0-next.0)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2) + '@angular/core': 22.1.0-next.0(@angular/compiler@22.1.0-next.0)(rxjs@7.8.2)(zone.js@0.16.2) + '@angular/platform-browser': 22.1.0-next.0(@angular/animations@22.1.0-next.0(@angular/core@22.1.0-next.0(@angular/compiler@22.1.0-next.0)(rxjs@7.8.2)(zone.js@0.16.2)))(@angular/common@22.1.0-next.0(@angular/core@22.1.0-next.0(@angular/compiler@22.1.0-next.0)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2))(@angular/core@22.1.0-next.0(@angular/compiler@22.1.0-next.0)(rxjs@7.8.2)(zone.js@0.16.2)) rxjs: 7.8.2 tslib: 2.8.1 - '@angular/service-worker@22.0.0(@angular/core@22.0.0(@angular/compiler@22.0.0)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2)': + '@angular/service-worker@22.1.0-next.0(@angular/core@22.1.0-next.0(@angular/compiler@22.1.0-next.0)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2)': dependencies: - '@angular/core': 22.0.0(@angular/compiler@22.0.0)(rxjs@7.8.2)(zone.js@0.16.2) + '@angular/core': 22.1.0-next.0(@angular/compiler@22.1.0-next.0)(rxjs@7.8.2)(zone.js@0.16.2) rxjs: 7.8.2 tslib: 2.8.1 @@ -8877,26 +8874,6 @@ snapshots: '@babel/compat-data@7.29.7': {} - '@babel/core@7.29.0': - dependencies: - '@babel/code-frame': 7.29.7 - '@babel/generator': 7.29.7 - '@babel/helper-compilation-targets': 7.29.7 - '@babel/helper-module-transforms': 7.29.7(@babel/core@7.29.0) - '@babel/helpers': 7.29.7 - '@babel/parser': 7.29.7 - '@babel/template': 7.29.7 - '@babel/traverse': 7.29.7 - '@babel/types': 7.29.7 - '@jridgewell/remapping': 2.3.5 - convert-source-map: 2.0.0 - debug: 4.4.3(supports-color@10.2.2) - gensync: 1.0.0-beta.2 - json5: 2.2.3 - semver: 6.3.1 - transitivePeerDependencies: - - supports-color - '@babel/core@7.29.7': dependencies: '@babel/code-frame': 7.29.7 @@ -8984,15 +8961,6 @@ snapshots: transitivePeerDependencies: - supports-color - '@babel/helper-module-transforms@7.29.7(@babel/core@7.29.0)': - dependencies: - '@babel/core': 7.29.0 - '@babel/helper-module-imports': 7.29.7 - '@babel/helper-validator-identifier': 7.29.7 - '@babel/traverse': 7.29.7 - transitivePeerDependencies: - - supports-color - '@babel/helper-module-transforms@7.29.7(@babel/core@7.29.7)': dependencies: '@babel/core': 7.29.7 @@ -13115,7 +13083,7 @@ snapshots: ee-first@1.1.1: {} - ejs@5.0.2: {} + ejs@6.0.1: {} electron-to-chromium@1.5.368: {} @@ -15162,10 +15130,10 @@ snapshots: neo-async@2.6.2: {} - ng-packagr@22.1.0-next.1(@angular/compiler-cli@22.0.0(@angular/compiler@22.0.0)(typescript@6.0.3))(tslib@2.8.1)(typescript@6.0.3): + ng-packagr@22.1.0-next.1(@angular/compiler-cli@22.1.0-next.0(@angular/compiler@22.1.0-next.0)(typescript@6.0.3))(tslib@2.8.1)(typescript@6.0.3): dependencies: '@ampproject/remapping': 2.3.0 - '@angular/compiler-cli': 22.0.0(@angular/compiler@22.0.0)(typescript@6.0.3) + '@angular/compiler-cli': 22.1.0-next.0(@angular/compiler@22.1.0-next.0)(typescript@6.0.3) '@rollup/plugin-json': 6.1.0(rollup@4.61.0) '@rollup/wasm-node': 4.61.0 ajv: 8.20.0 diff --git a/tests/e2e/ng-snapshot/package.json b/tests/e2e/ng-snapshot/package.json index e29823426365..897457a6eefa 100644 --- a/tests/e2e/ng-snapshot/package.json +++ b/tests/e2e/ng-snapshot/package.json @@ -2,21 +2,21 @@ "description": "snapshot versions of Angular for e2e testing", "private": true, "dependencies": { - "@angular/animations": "github:angular/animations-builds#995e14b3622334a08fa2dd61ad4a32ada5f23bed", - "@angular/cdk": "github:angular/cdk-builds#7bc49b61b45807fb27e77317193ad90283f93f93", - "@angular/common": "github:angular/common-builds#b61ffd86d49ba0b9a851b1096f1f03260659c13c", - "@angular/compiler": "github:angular/compiler-builds#95b12983913cfbfa0d263e2cfa98d2983e4f9c88", - "@angular/compiler-cli": "github:angular/compiler-cli-builds#3e011b17c96dc76ca925fc5e914fbd8238c668c7", - "@angular/core": "github:angular/core-builds#03ca0858e056118762a745b64bbfd2285a110fee", - "@angular/forms": "github:angular/forms-builds#0abbf545d7f1dabb7cc5e6fcb9cf66223d8b3fc7", - "@angular/language-service": "github:angular/language-service-builds#5998ae5e86464885664600bd19650d9c38d30fad", - "@angular/localize": "github:angular/localize-builds#8f7ae70fdeb50866f556e73bc3a8f4473cb65804", - "@angular/material": "github:angular/material-builds#7a236ec3084f76850f2aa2ae1d1fe58ab504a290", - "@angular/material-moment-adapter": "github:angular/material-moment-adapter-builds#f710a88fd1a7ad4b31d23d7d188b2591e6366d6a", - "@angular/platform-browser": "github:angular/platform-browser-builds#9b66d5030f5ed1370e26bb0ebeb408f8555c0664", - "@angular/platform-browser-dynamic": "github:angular/platform-browser-dynamic-builds#2e6ce4e7ade1c180eba4c6fa261962a89a9014e5", - "@angular/platform-server": "github:angular/platform-server-builds#42691726ca2611679ff5d64b60201ef9a1a75f6b", - "@angular/router": "github:angular/router-builds#41090511daed2112637dd8e1fb121966faf97509", - "@angular/service-worker": "github:angular/service-worker-builds#2cf5d8e2053c0d9a5942ab56876b8b197ae3692e" + "@angular/animations": "github:angular/animations-builds#9d3d315860f65e40f0e514da755199d4a792c4eb", + "@angular/cdk": "github:angular/cdk-builds#58e2053cad359db28eba76240f6557dcf94be7d1", + "@angular/common": "github:angular/common-builds#be537ed30640e631054ce06c6bfdd429b6adef2a", + "@angular/compiler": "github:angular/compiler-builds#282e1c5ee3c9c7b80c4875c4599a876f88d329d6", + "@angular/compiler-cli": "github:angular/compiler-cli-builds#a3a4b6b15e14b25d277eb6aa2cee57d9e9f03e34", + "@angular/core": "github:angular/core-builds#3d52c13033170016a5993f426461d3072fb30a85", + "@angular/forms": "github:angular/forms-builds#05a284aa0e0a3a41a148f440e2ce07154a9475e0", + "@angular/language-service": "github:angular/language-service-builds#61a48036df076a4e0dcf8c2443f26e588fbf87ea", + "@angular/localize": "github:angular/localize-builds#edaed6ab8ca7a30d33e431e870c281a6750797a1", + "@angular/material": "github:angular/material-builds#5528675fa28eb4796cd8e39e954809f04c06d457", + "@angular/material-moment-adapter": "github:angular/material-moment-adapter-builds#5b9de0d562321e4efafe3d4b646a9846966068c7", + "@angular/platform-browser": "github:angular/platform-browser-builds#b7253e10d58dd467c6a8c2d76b9102d785f5ba8e", + "@angular/platform-browser-dynamic": "github:angular/platform-browser-dynamic-builds#65960a68257c6dfb9ff874e1d05bae9660d91b82", + "@angular/platform-server": "github:angular/platform-server-builds#e3fe333b0ba105786bf7d33fff50dd19fc6c4fd3", + "@angular/router": "github:angular/router-builds#67a575caa48cfce117881991ea5553f261d47b70", + "@angular/service-worker": "github:angular/service-worker-builds#8a08a9bdbfd3b4810bdb1f9fbfe51df6f3ab98cc" } } From 0130da991164445164fd84d91d16e741b3de6e05 Mon Sep 17 00:00:00 2001 From: Alan Agius <17563226+alan-agius4@users.noreply.github.com> Date: Thu, 11 Jun 2026 09:48:49 +0000 Subject: [PATCH 032/787] build: bump Angular framework and ng-packagr versions to 22.1.0-next.0 --- constants.bzl | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/constants.bzl b/constants.bzl index abf02a051f90..6987637a4442 100644 --- a/constants.bzl +++ b/constants.bzl @@ -3,10 +3,10 @@ RELEASE_ENGINES_NODE = "^22.22.3 || ^24.15.0 || >=26.0.0" RELEASE_ENGINES_NPM = "^6.11.0 || ^7.5.6 || >=8.0.0" RELEASE_ENGINES_YARN = ">= 1.13.0" -NG_PACKAGR_VERSION = "^22.0.0-next.0" -ANGULAR_FW_VERSION = "^22.0.0-next.0" -ANGULAR_FW_PEER_DEP = "^22.0.0-next.0" -NG_PACKAGR_PEER_DEP = "^22.0.0-next.0" +NG_PACKAGR_VERSION = "^22.1.0-next.0" +ANGULAR_FW_VERSION = "^22.1.0-next.0" +ANGULAR_FW_PEER_DEP = "^22.0.0 || ^22.1.0-next.0" +NG_PACKAGR_PEER_DEP = "^22.0.0 || ^22.1.0-next.0" # Baseline widely-available date in `YYYY-MM-DD` format which defines Angular's # browser support. This date serves as the source of truth for the Angular CLI's From ddcef9d484e205c5fcfd93d184425c1c1af19c34 Mon Sep 17 00:00:00 2001 From: Alan Agius <17563226+alan-agius4@users.noreply.github.com> Date: Thu, 11 Jun 2026 09:50:47 +0000 Subject: [PATCH 033/787] fix(@angular/ssr): correct grammar in console warning for redirected location headers The console message had incorrect grammer. --- packages/angular/ssr/src/utils/redirect.ts | 2 +- packages/angular/ssr/test/utils/redirect_spec.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/angular/ssr/src/utils/redirect.ts b/packages/angular/ssr/src/utils/redirect.ts index 79fb10f424dc..d6f83f2c9870 100644 --- a/packages/angular/ssr/src/utils/redirect.ts +++ b/packages/angular/ssr/src/utils/redirect.ts @@ -46,7 +46,7 @@ export function createRedirectResponse( if (ngDevMode && resHeaders.has('location')) { // eslint-disable-next-line no-console console.warn( - `Location header "${resHeaders.get('location')}" will ignored and set to "${location}".`, + `Location header "${resHeaders.get('location')}" will be ignored and set to "${location}".`, ); } diff --git a/packages/angular/ssr/test/utils/redirect_spec.ts b/packages/angular/ssr/test/utils/redirect_spec.ts index b26edd458ac3..4d0b94a87798 100644 --- a/packages/angular/ssr/test/utils/redirect_spec.ts +++ b/packages/angular/ssr/test/utils/redirect_spec.ts @@ -52,7 +52,7 @@ describe('Redirect Utils', () => { const warnSpy = spyOn(console, 'warn'); createRedirectResponse('/home', 302, { 'Location': '/evil' }); expect(warnSpy).toHaveBeenCalledWith( - 'Location header "/evil" will ignored and set to "/home".', + 'Location header "/evil" will be ignored and set to "/home".', ); }); From a715b3b125a1adb9bab88a0dadbb1ca2daee66eb Mon Sep 17 00:00:00 2001 From: Doug Parker Date: Thu, 11 Jun 2026 08:55:57 -0700 Subject: [PATCH 034/787] docs: release notes for the v21.2.15 release --- CHANGELOG.md | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5a607c51a75a..09cd9b197481 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,16 @@ + + +# 21.2.15 (2026-06-11) + +### @angular/cli + +| Commit | Type | Description | +| --------------------------------------------------------------------------------------------------- | ---- | ------------------------------------------------------------ | +| [42ac0ed0f](https://github.com/angular/angular-cli/commit/42ac0ed0ff8b98862b9df1cef048f463ddc2cd85) | fix | remove forceAuth and unscoped credential parsing | +| [c7a7f1955](https://github.com/angular/angular-cli/commit/c7a7f1955619717ca775f730d67e3311047537f8) | fix | support registry metadata fetching under bun package manager | + + + # 22.0.1 (2026-06-10) From b233e2cac6f79bcbb0fb2cbdcac4895229264652 Mon Sep 17 00:00:00 2001 From: Alan Agius <17563226+alan-agius4@users.noreply.github.com> Date: Thu, 11 Jun 2026 16:38:56 +0000 Subject: [PATCH 035/787] docs: release notes for the v20.3.28 release --- CHANGELOG.md | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 09cd9b197481..d9633e21ef9c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,16 @@ + + +# 20.3.28 (2026-06-11) + +### @angular/cli + +| Commit | Type | Description | +| --------------------------------------------------------------------------------------------------- | ---- | ------------------------------------------------------------------------------------------- | +| [e3d564667](https://github.com/angular/angular-cli/commit/e3d5646679215d9b73a72e04d87aa7848f2c01d2) | fix | fallback to deprecated versions when resolving ranges if no non-deprecated version is found | +| [f12e17025](https://github.com/angular/angular-cli/commit/f12e17025a262f9432afd58971c47aec7dbfab25) | fix | remove forceAuth and unscoped credential parsing | + + + # 21.2.15 (2026-06-11) From ee2bf0a87aa73ff0c23782cd3042551facb6d2b2 Mon Sep 17 00:00:00 2001 From: Alan Agius <17563226+alan-agius4@users.noreply.github.com> Date: Thu, 11 Jun 2026 16:40:30 +0000 Subject: [PATCH 036/787] release: cut the v22.1.0-next.0 release --- CHANGELOG.md | 38 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index d9633e21ef9c..2d8708e02174 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,41 @@ + + +# 22.1.0-next.0 (2026-06-11) + +## Deprecations + +### @angular-devkit/core + +- `stringToFileBuffer` and `fileBufferToString` are deprecated. Use standard Web APIs (`TextEncoder` and `TextDecoder`) instead. + + Internal usages within the repository have been removed and replaced with standard Web APIs. The public API golden file for `@angular-devkit/core` has been updated to reflect the deprecations. + +### @schematics/angular + +| Commit | Type | Description | +| --------------------------------------------------------------------------------------------------- | ---- | ----------------------------------------------------- | +| [89d7f59cd](https://github.com/angular/angular-cli/commit/89d7f59cd7cc5d821ac0e81b1fee50e27877c976) | feat | update ai-config to include Angular MCP server config | + +### @angular/cli + +| Commit | Type | Description | +| --------------------------------------------------------------------------------------------------- | ---- | -------------------------------------- | +| [7932caaf9](https://github.com/angular/angular-cli/commit/7932caaf987c5692d6624f6af23e65ce3f6d27fd) | fix | robustly parse npm manifest from array | + +### @angular-devkit/core + +| Commit | Type | Description | +| --------------------------------------------------------------------------------------------------- | -------- | --------------------------------------------------- | +| [fd336d365](https://github.com/angular/angular-cli/commit/fd336d365dbfe8f558db177a8da24790914a541b) | refactor | deprecate stringToFileBuffer and fileBufferToString | + +### @angular/ssr + +| Commit | Type | Description | +| --------------------------------------------------------------------------------------------------- | ---- | ------------------------------------------------------------------ | +| [ddcef9d48](https://github.com/angular/angular-cli/commit/ddcef9d484e205c5fcfd93d184425c1c1af19c34) | fix | correct grammar in console warning for redirected location headers | + + + # 20.3.28 (2026-06-11) From 5875b6024ff9e59fddf7481b6b961d73ae809963 Mon Sep 17 00:00:00 2001 From: Alan Agius <17563226+alan-agius4@users.noreply.github.com> Date: Thu, 11 Jun 2026 09:05:36 +0000 Subject: [PATCH 037/787] fix(@angular/ssr): prioritize options over environment variables in AngularNodeAppEngine Prioritize constructor options over environment variables when initializing the AngularNodeAppEngine. Previously, environment variables took priority and blindly overrode the constructor options if they were defined in the environment. Now, explicit constructor options act as the override, while the environment variables serve as a fallback. --- packages/angular/ssr/node/src/app-engine.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/angular/ssr/node/src/app-engine.ts b/packages/angular/ssr/node/src/app-engine.ts index b947107a3c5a..89e6a942856b 100644 --- a/packages/angular/ssr/node/src/app-engine.ts +++ b/packages/angular/ssr/node/src/app-engine.ts @@ -38,8 +38,8 @@ export class AngularNodeAppEngine { constructor(options?: AngularNodeAppEngineOptions) { const appEngineOptions: AngularAppEngineOptions = { ...options, - allowedHosts: getAllowedHostsFromEnv() ?? options?.allowedHosts, - trustProxyHeaders: getTrustProxyHeadersFromEnv() ?? options?.trustProxyHeaders, + allowedHosts: options?.allowedHosts ?? getAllowedHostsFromEnv(), + trustProxyHeaders: options?.trustProxyHeaders ?? getTrustProxyHeadersFromEnv(), }; this.angularAppEngine = new AngularAppEngine(appEngineOptions); From b04f4a0ebbbe9c0522e54cc8fda1581d92125e3b Mon Sep 17 00:00:00 2001 From: Angular Robot Date: Thu, 11 Jun 2026 06:25:38 +0000 Subject: [PATCH 038/787] build: update all github actions to v4.36.2 See associated pull request for more information. --- .github/workflows/codeql.yml | 4 ++-- .github/workflows/scorecard.yml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml index dd199499e759..00365fa5b47d 100644 --- a/.github/workflows/codeql.yml +++ b/.github/workflows/codeql.yml @@ -23,12 +23,12 @@ jobs: with: persist-credentials: false - name: Initialize CodeQL - uses: github/codeql-action/init@87557b9c84dde89fdd9b10e88954ac2f4248e463 # v4.36.1 + uses: github/codeql-action/init@8aad20d150bbac5944a9f9d289da16a4b0d87c1e # v4.36.2 with: languages: javascript-typescript build-mode: none config-file: .github/codeql/config.yml - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@87557b9c84dde89fdd9b10e88954ac2f4248e463 # v4.36.1 + uses: github/codeql-action/analyze@8aad20d150bbac5944a9f9d289da16a4b0d87c1e # v4.36.2 with: category: '/language:javascript-typescript' diff --git a/.github/workflows/scorecard.yml b/.github/workflows/scorecard.yml index 3cf9ef0b1a8d..053909cb5511 100644 --- a/.github/workflows/scorecard.yml +++ b/.github/workflows/scorecard.yml @@ -46,6 +46,6 @@ jobs: # Upload the results to GitHub's code scanning dashboard. - name: 'Upload to code-scanning' - uses: github/codeql-action/upload-sarif@87557b9c84dde89fdd9b10e88954ac2f4248e463 # v4.36.1 + uses: github/codeql-action/upload-sarif@8aad20d150bbac5944a9f9d289da16a4b0d87c1e # v4.36.2 with: sarif_file: results.sarif From ad371819150f5096d260b22be2a599f6dca913c9 Mon Sep 17 00:00:00 2001 From: Angular Robot Date: Thu, 11 Jun 2026 20:10:44 +0000 Subject: [PATCH 039/787] build: update bazel dependencies to v3.2.2 See associated pull request for more information. --- MODULE.bazel | 2 +- MODULE.bazel.lock | 13 +++++++------ 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/MODULE.bazel b/MODULE.bazel index 062573179302..9d48d64be6f9 100644 --- a/MODULE.bazel +++ b/MODULE.bazel @@ -7,7 +7,7 @@ module( bazel_dep(name = "platforms", version = "1.1.0") bazel_dep(name = "yq.bzl", version = "0.3.6") bazel_dep(name = "rules_nodejs", version = "6.7.4") -bazel_dep(name = "aspect_rules_js", version = "3.2.0") +bazel_dep(name = "aspect_rules_js", version = "3.2.2") bazel_dep(name = "aspect_rules_ts", version = "3.8.10") bazel_dep(name = "rules_pkg", version = "1.2.0") bazel_dep(name = "rules_cc", version = "0.2.19") diff --git a/MODULE.bazel.lock b/MODULE.bazel.lock index c04a9caaf272..6dd3f65f8d69 100644 --- a/MODULE.bazel.lock +++ b/MODULE.bazel.lock @@ -25,7 +25,8 @@ "https://bcr.bazel.build/modules/aspect_rules_js/2.0.0/MODULE.bazel": "b45b507574aa60a92796e3e13c195cd5744b3b8aff516a9c0cb5ae6a048161c5", "https://bcr.bazel.build/modules/aspect_rules_js/3.0.3/MODULE.bazel": "28a30e8fc33bf64a67835d64d124f6e05a7d59648dcb27b110fb3502f761e503", "https://bcr.bazel.build/modules/aspect_rules_js/3.2.0/MODULE.bazel": "c3d34345c51a4d90cf678d3b251c6f345b63d5e2e6b0253dbdda467a01efc31f", - "https://bcr.bazel.build/modules/aspect_rules_js/3.2.0/source.json": "3538ab18ac72ba3eaa3db0e4ec5171e04322768723afaa1149c0d822fe5411e2", + "https://bcr.bazel.build/modules/aspect_rules_js/3.2.2/MODULE.bazel": "e844196321b64537cfade338f361633e7d5fe084eee3214fc531b9e7b9838813", + "https://bcr.bazel.build/modules/aspect_rules_js/3.2.2/source.json": "0e650e493b3bc784dc3f8240ff00b4b32258cde6d021ef6b1db4e387bcfd6a9a", "https://bcr.bazel.build/modules/aspect_rules_ts/3.8.10/MODULE.bazel": "a17a49a21226fc90163a29b3d6eac56703697205530b8d5cc38b3c074dbac039", "https://bcr.bazel.build/modules/aspect_rules_ts/3.8.10/source.json": "745c8dba237b4088409800143241bbb138e7ef37a359bd81a250c2c423f380ce", "https://bcr.bazel.build/modules/aspect_tools_telemetry/0.2.8/MODULE.bazel": "aa975a83e72bcaac62ee61ab12b788ea324a1d05c4aab28aadb202f647881679", @@ -219,7 +220,7 @@ "moduleExtensions": { "@@aspect_rules_esbuild+//esbuild:extensions.bzl%esbuild": { "general": { - "bzlTransitiveDigest": "8bNoUkbLk1vCab3fXdV3RN1UoOjEcHlo/bk9XxZ7e3A=", + "bzlTransitiveDigest": "Z+j2tSHH9t9v/z9GznMJ0Nat/j5BO97aNd3SxoLuUU0=", "usagesDigest": "LSQ+zZp7JNgnBONTxxXnwGr4NTh2qtQYk7qwXXz5qWo=", "recordedFileInputs": {}, "recordedDirentsInputs": {}, @@ -498,7 +499,7 @@ "@@aspect_tools_telemetry+//:extension.bzl%telemetry": { "general": { "bzlTransitiveDigest": "cl5A2O84vDL6Tt+Qga8FCj1DUDGqn+e7ly5rZ+4xvcc=", - "usagesDigest": "bsm1cFI7hhC0zj7wvllOScDJKporKySjStBNr8xm+dY=", + "usagesDigest": "gNir09X+lMWmGxyBnlL7YHmzYUntq/va2IwI5K7Dm24=", "recordedFileInputs": {}, "recordedDirentsInputs": {}, "envVariables": {}, @@ -507,7 +508,7 @@ "repoRuleId": "@@aspect_tools_telemetry+//:extension.bzl%tel_repository", "attributes": { "deps": { - "aspect_rules_js": "3.2.0", + "aspect_rules_js": "3.2.2", "aspect_rules_ts": "3.8.10", "aspect_rules_esbuild": "0.26.0", "aspect_rules_jasmine": "2.0.4", @@ -952,7 +953,7 @@ "@@rules_nodejs+//nodejs:extensions.bzl%node": { "general": { "bzlTransitiveDigest": "oZFClfRhTTwsYzpxVPkOpOt/r0+OzEfEV37au0jFZ0s=", - "usagesDigest": "00+3uj4j6s/drSt+SUad8w/R4Rp2/GHGBsCgrKvF7mE=", + "usagesDigest": "LRA5BIxJ47Tm5Zf32yRf+uGjU5vrAxqctgLR6FJZQQ0=", "recordedFileInputs": {}, "recordedDirentsInputs": {}, "envVariables": {}, @@ -5342,7 +5343,7 @@ "@@yq.bzl+//yq:extensions.bzl%yq": { "general": { "bzlTransitiveDigest": "UfFMy8CWK4/dVo/tfaSAIYUiDGNAPes5eRllx9O9Q9Q=", - "usagesDigest": "6JGNN6+d6JD7F98c3T4zg7eUxkfsfsMEDemA2CIoNQQ=", + "usagesDigest": "2OWRv1SUsHDts+8CqhpVrVqZHB3EPHP3YgWSn+Mg+lk=", "recordedFileInputs": {}, "recordedDirentsInputs": {}, "envVariables": {}, From 6a01fe0ee6e2c36872535aeb9e9df5c39b55ebf9 Mon Sep 17 00:00:00 2001 From: Angular Robot Date: Thu, 11 Jun 2026 06:26:29 +0000 Subject: [PATCH 040/787] build: update schematics dependencies to ~6.3.0 See associated pull request for more information. --- .../angular_devkit/schematics_cli/schematic/files/package.json | 2 +- .../schematics/angular/utility/latest-versions/package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/angular_devkit/schematics_cli/schematic/files/package.json b/packages/angular_devkit/schematics_cli/schematic/files/package.json index 0d723b4004e6..fda5cef4423b 100644 --- a/packages/angular_devkit/schematics_cli/schematic/files/package.json +++ b/packages/angular_devkit/schematics_cli/schematic/files/package.json @@ -19,7 +19,7 @@ "devDependencies": { "@types/node": "^20.17.19", "@types/jasmine": "~6.0.0", - "jasmine": "~6.2.0", + "jasmine": "~6.3.0", "typescript": "~6.0.2" } } diff --git a/packages/schematics/angular/utility/latest-versions/package.json b/packages/schematics/angular/utility/latest-versions/package.json index 4ad8149fe646..96b002df8b92 100644 --- a/packages/schematics/angular/utility/latest-versions/package.json +++ b/packages/schematics/angular/utility/latest-versions/package.json @@ -9,7 +9,7 @@ "browser-sync": "^3.0.0", "express": "^5.1.0", "istanbul-lib-instrument": "^6.0.3", - "jasmine-core": "~6.2.0", + "jasmine-core": "~6.3.0", "jasmine-spec-reporter": "~7.0.0", "karma-chrome-launcher": "~3.2.0", "karma-coverage": "~2.2.0", From e6e88e2e0ded6ee37de5e2e73c5d360c5d4cf9f2 Mon Sep 17 00:00:00 2001 From: Angular Robot Date: Fri, 12 Jun 2026 06:23:34 +0000 Subject: [PATCH 041/787] build: update pnpm to v11.5.3 See associated pull request for more information. --- MODULE.bazel | 4 ++-- package.json | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/MODULE.bazel b/MODULE.bazel index 9d48d64be6f9..3f42ca04a729 100644 --- a/MODULE.bazel +++ b/MODULE.bazel @@ -131,8 +131,8 @@ use_repo( pnpm = use_extension("@aspect_rules_js//npm:extensions.bzl", "pnpm") pnpm.pnpm( name = "pnpm", - pnpm_version = "11.5.2", - pnpm_version_integrity = "sha512-ccYx44IGbvwlYl1c8CkHXeB7YbN/bic1D72Esb2lhkyMGWetwoB3a0XDCnFcA1mjvgj+9C1bsJ4rmQKZeWkpFg==", + pnpm_version = "11.5.3", + pnpm_version_integrity = "sha512-esHJGTQcITo03A0Cr7cUPFwmrCbujEeC3uqCG4rGTSE0oIH9iUHa5uKbu0j1jfwrf7zuzMB8svCdIZ00Kklp7Q==", ) use_repo(pnpm, "pnpm") diff --git a/package.json b/package.json index 0e4856408374..a1c171a9609a 100644 --- a/package.json +++ b/package.json @@ -28,12 +28,12 @@ "type": "git", "url": "git+https://github.com/angular/angular-cli.git" }, - "packageManager": "pnpm@11.5.2", + "packageManager": "pnpm@11.5.3", "engines": { "node": "^22.22.3 || ^24.15.0 || >=26.0.0", "npm": "Please use pnpm instead of NPM to install dependencies", "yarn": "Please use pnpm instead of Yarn to install dependencies", - "pnpm": "11.5.2" + "pnpm": "11.5.3" }, "author": "Angular Authors", "license": "MIT", From 38e0fabc05eb5d622a25c68692d7d073485750e3 Mon Sep 17 00:00:00 2001 From: Charles Lyding <19598772+clydin@users.noreply.github.com> Date: Wed, 10 Jun 2026 12:47:20 -0400 Subject: [PATCH 042/787] fix(@angular/cli): support registry metadata fetching under bun package manager Bun's `pm view` command does not support requesting multiple fields at once (e.g. `pm view dist-tags versions --json`), which is required by the default package manager abstraction to fetch package metadata during version compatibility search. This change introduces a custom `getRegistryMetadata` handler in the package manager descriptor, allowing individual package managers to override registry metadata fetching entirely. The `bun` descriptor now implements this by querying `dist-tags` and `versions` separately in parallel, and returning the aggregated metadata object. --- .../package-manager-descriptor.ts | 41 +++++++++++++++++++ .../src/package-managers/package-manager.ts | 38 ++++++++++++----- .../package-managers/package-manager_spec.ts | 36 ++++++++++++++++ 3 files changed, 105 insertions(+), 10 deletions(-) diff --git a/packages/angular/cli/src/package-managers/package-manager-descriptor.ts b/packages/angular/cli/src/package-managers/package-manager-descriptor.ts index 2dfe75ee01cd..d99d2c950702 100644 --- a/packages/angular/cli/src/package-managers/package-manager-descriptor.ts +++ b/packages/angular/cli/src/package-managers/package-manager-descriptor.ts @@ -99,6 +99,15 @@ export interface PackageManagerDescriptor { /** A function that formats the arguments for field-filtered registry views. */ readonly viewCommandFieldArgFormatter?: (fields: readonly string[]) => string[]; + /** An optional custom function to fetch registry metadata when the default logic is not sufficient. */ + readonly getRegistryMetadata?: ( + packageName: string, + fetchAndParse: ( + args: readonly string[], + parser: (stdout: string, logger?: Logger) => T | null, + ) => Promise, + ) => Promise; + /** A collection of functions to parse the output of specific commands. */ readonly outputParsers: { /** A function to parse the output of `listDependenciesCommand`. */ @@ -273,6 +282,38 @@ export const SUPPORTED_PACKAGE_MANAGERS = { versionCommand: ['--version'], listDependenciesCommand: ['pm', 'ls'], getManifestCommand: ['pm', 'view', '--json'], + getRegistryMetadata: async (packageName, fetchAndParse) => { + const [distTags, versions] = await Promise.all([ + fetchAndParse(['pm', 'view', '--json', packageName, 'dist-tags'], (stdout) => { + if (!stdout) { + return {}; + } + + const parsed = JSON.parse(stdout); + + return parsed && typeof parsed === 'object' && !Array.isArray(parsed) ? parsed : {}; + }), + fetchAndParse(['pm', 'view', '--json', packageName, 'versions'], (stdout) => { + if (!stdout) { + return null; + } + + const parsed = JSON.parse(stdout); + + return Array.isArray(parsed) ? parsed : [parsed]; + }), + ]); + + if (!versions || versions.length === 0) { + return null; + } + + return { + name: packageName, + 'dist-tags': (distTags || {}) as Record, + versions: versions as string[], + }; + }, outputParsers: { listDependencies: parseBunDependencies, getRegistryManifest: parseNpmLikeManifest, diff --git a/packages/angular/cli/src/package-managers/package-manager.ts b/packages/angular/cli/src/package-managers/package-manager.ts index 46adbd118b9b..a5ebfad62553 100644 --- a/packages/angular/cli/src/package-managers/package-manager.ts +++ b/packages/angular/cli/src/package-managers/package-manager.ts @@ -441,19 +441,37 @@ export class PackageManager { packageName: string, options: { timeout?: number; registry?: string; bypassCache?: boolean } = {}, ): Promise { - const commandArgs = [...this.descriptor.getManifestCommand, packageName]; - const formatter = this.descriptor.viewCommandFieldArgFormatter; - if (formatter) { - commandArgs.push(...formatter(METADATA_FIELDS)); + const cacheKey = options.registry ? `${packageName}|${options.registry}` : packageName; + + if (!options.bypassCache) { + const cached = this.#metadataCache.get(cacheKey); + if (cached !== undefined) { + return cached; + } } - const cacheKey = options.registry ? `${packageName}|${options.registry}` : packageName; + let metadata: PackageMetadata | null; + if (this.descriptor.getRegistryMetadata) { + metadata = await this.descriptor.getRegistryMetadata(packageName, (args, parser) => + this.#fetchAndParse(args, parser, options), + ); + } else { + const commandArgs = [...this.descriptor.getManifestCommand, packageName]; + const formatter = this.descriptor.viewCommandFieldArgFormatter; + if (formatter) { + commandArgs.push(...formatter(METADATA_FIELDS)); + } - return this.#fetchAndParse( - commandArgs, - (stdout, logger) => this.descriptor.outputParsers.getRegistryMetadata(stdout, logger), - { ...options, cache: this.#metadataCache, cacheKey }, - ); + metadata = await this.#fetchAndParse( + commandArgs, + (stdout, logger) => this.descriptor.outputParsers.getRegistryMetadata(stdout, logger), + options, + ); + } + + this.#metadataCache.set(cacheKey, metadata); + + return metadata; } /** diff --git a/packages/angular/cli/src/package-managers/package-manager_spec.ts b/packages/angular/cli/src/package-managers/package-manager_spec.ts index 176b604eeca6..105fcf5930b0 100644 --- a/packages/angular/cli/src/package-managers/package-manager_spec.ts +++ b/packages/angular/cli/src/package-managers/package-manager_spec.ts @@ -195,6 +195,42 @@ describe('PackageManager', () => { }); }); + describe('getRegistryMetadata', () => { + it('should query dist-tags and versions separately for bun', async () => { + const bunDescriptor = SUPPORTED_PACKAGE_MANAGERS['bun']; + const pm = new PackageManager(host, '/tmp', bunDescriptor); + + runCommandSpy.and.callFake((binary, args) => { + if (args.includes('dist-tags')) { + return Promise.resolve({ stdout: JSON.stringify({ latest: '2.0.0' }), stderr: '' }); + } else if (args.includes('versions')) { + return Promise.resolve({ stdout: JSON.stringify(['1.0.0', '2.0.0']), stderr: '' }); + } + + return Promise.resolve({ stdout: '', stderr: '' }); + }); + + const metadata = await pm.getRegistryMetadata('foo'); + + expect(metadata).toEqual({ + name: 'foo', + 'dist-tags': { latest: '2.0.0' }, + versions: ['1.0.0', '2.0.0'], + }); + + expect(runCommandSpy).toHaveBeenCalledWith( + 'bun', + ['pm', 'view', '--json', 'foo', 'dist-tags'], + jasmine.anything(), + ); + expect(runCommandSpy).toHaveBeenCalledWith( + 'bun', + ['pm', 'view', '--json', 'foo', 'versions'], + jasmine.anything(), + ); + }); + }); + describe('initializationError', () => { it('should throw initializationError when running commands', async () => { const error = new Error('Not installed'); From 583736a4de8b3d0b4d79709a445809c264e38c17 Mon Sep 17 00:00:00 2001 From: Charles Lyding <19598772+clydin@users.noreply.github.com> Date: Sat, 13 Jun 2026 19:13:28 -0400 Subject: [PATCH 043/787] perf(@angular/build): implement semaphore backpressure throttling in JavaScriptTransformer MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Throttle active esbuild transformation requests higher in the pipeline using an asynchronous semaphore queue bounded to maxThreads * 2. In large monorepo builds (thousands of files), esbuild crawls the import graph via parallel goroutines much faster than Node.js workers can process downleveling and linking. Unthrottled onLoad calls flood libuv's file read pool and accumulate thousands of source buffers in Piscina's task queue. Throttling active requests higher in the chain keeps libuv's I/O pool free, caps Buffer memory overhead at ~10MB–30MB, and ensures file buffers remain short-lived for quicker GC reclamation. --- .../tools/esbuild/javascript-transformer.ts | 152 ++++++++++++------ 1 file changed, 100 insertions(+), 52 deletions(-) diff --git a/packages/angular/build/src/tools/esbuild/javascript-transformer.ts b/packages/angular/build/src/tools/esbuild/javascript-transformer.ts index b728a0f599e2..36c505d714fc 100644 --- a/packages/angular/build/src/tools/esbuild/javascript-transformer.ts +++ b/packages/angular/build/src/tools/esbuild/javascript-transformer.ts @@ -34,11 +34,22 @@ export class JavaScriptTransformer { #commonOptions: Required; #fileCacheKeyBase: Uint8Array; + /** Queue of pending transformation tasks waiting for an active concurrency slot. */ + #pendingTasks: { resolve: () => void; reject: (reason: Error) => void }[] = []; + + /** Current count of actively executing transformation tasks. */ + #activeTasks = 0; + + /** Maximum number of transformation tasks allowed to execute concurrently. */ + #maxConcurrent: number; + constructor( options: JavaScriptTransformerOptions, readonly maxThreads: number, private readonly cache?: Cache, ) { + // Maintain 2 active tasks per worker thread to keep transformation pipelines fully saturated + this.#maxConcurrent = Math.max(1, maxThreads * 2); // Extract options to ensure only the named options are serialized and sent to the worker const { sourcemap, @@ -55,6 +66,33 @@ export class JavaScriptTransformer { this.#fileCacheKeyBase = Buffer.from(JSON.stringify(this.#commonOptions), 'utf-8'); } + /** + * Executes a transformation action using a semaphore-based backpressure throttle. + * Prevents libuv thread pool saturation and excessive V8 heap accumulation. + * @param action A callback that produces a promise for the transformation result. + * @returns A promise resolving to the transformation result. + */ + async #runWithThrottle(action: () => Promise): Promise { + if (this.#activeTasks >= this.#maxConcurrent) { + await new Promise((resolve, reject) => { + this.#pendingTasks.push({ resolve, reject }); + }); + } else { + this.#activeTasks++; + } + + try { + return await action(); + } finally { + const next = this.#pendingTasks.shift(); + if (next) { + next.resolve(); + } else { + this.#activeTasks--; + } + } + } + #ensureWorkerPool(): WorkerPool { if (this.#workerPool) { return this.#workerPool; @@ -90,56 +128,58 @@ export class JavaScriptTransformer { sideEffects?: boolean, instrumentForCoverage?: boolean, ): Promise { - const data = await readFile(filename); - - let result; - let cacheKey; - if (this.cache) { - // Create a cache key from the file data and options that effect the output. - // NOTE: If additional options are added, this may need to be updated. - // TODO: Consider xxhash or similar instead of SHA256 - const hash = createHash('sha256'); - hash.update(`${!!skipLinker}--${!!sideEffects}`); - hash.update(data); - hash.update(this.#fileCacheKeyBase); - cacheKey = hash.digest('hex'); + return this.#runWithThrottle(async () => { + const data = await readFile(filename); + + let result; + let cacheKey; + if (this.cache) { + // Create a cache key from the file data and options that effect the output. + // NOTE: If additional options are added, this may need to be updated. + // TODO: Consider xxhash or similar instead of SHA256 + const hash = createHash('sha256'); + hash.update(`${!!skipLinker}--${!!sideEffects}`); + hash.update(data); + hash.update(this.#fileCacheKeyBase); + cacheKey = hash.digest('hex'); - try { - result = await this.cache?.get(cacheKey); - } catch { - // Failure to get the value should not fail the transform - } - } - - if (result === undefined) { - // If there is no cache or no cached entry, process the file - result = (await this.#ensureWorkerPool().run( - { - filename, - data, - skipLinker, - sideEffects, - instrumentForCoverage, - ...this.#commonOptions, - }, - { - // The below is disable as with Yarn PNP this causes build failures with the below message - // `Unable to deserialize cloned data`. - transferList: process.versions.pnp ? undefined : [data.buffer], - }, - )) as Uint8Array; - - // If there is a cache then store the result - if (this.cache && cacheKey) { try { - await this.cache.put(cacheKey, result); + result = await this.cache?.get(cacheKey); } catch { - // Failure to store the value in the cache should not fail the transform + // Failure to get the value should not fail the transform } } - } - return result; + if (result === undefined) { + // If there is no cache or no cached entry, process the file + result = (await this.#ensureWorkerPool().run( + { + filename, + data, + skipLinker, + sideEffects, + instrumentForCoverage, + ...this.#commonOptions, + }, + { + // The below is disable as with Yarn PNP this causes build failures with the below message + // `Unable to deserialize cloned data`. + transferList: process.versions.pnp ? undefined : [data.buffer], + }, + )) as Uint8Array; + + // If there is a cache then store the result + if (this.cache && cacheKey) { + try { + await this.cache.put(cacheKey, result); + } catch { + // Failure to store the value in the cache should not fail the transform + } + } + } + + return result; + }); } /** @@ -171,14 +211,16 @@ export class JavaScriptTransformer { ); } - return this.#ensureWorkerPool().run({ - filename, - data, - skipLinker, - sideEffects, - instrumentForCoverage, - ...this.#commonOptions, - }); + return this.#runWithThrottle(() => + this.#ensureWorkerPool().run({ + filename, + data, + skipLinker, + sideEffects, + instrumentForCoverage, + ...this.#commonOptions, + }), + ); } /** @@ -186,6 +228,12 @@ export class JavaScriptTransformer { * @returns A void promise that resolves when closing is complete. */ async close(): Promise { + const pending = this.#pendingTasks; + this.#pendingTasks = []; + for (const task of pending) { + task.reject(new Error('JavaScriptTransformer closed.')); + } + if (this.#workerPool) { try { await this.#workerPool.destroy(); From ce3261cc2a10d0e92f4f2138db46f1eb1593de63 Mon Sep 17 00:00:00 2001 From: Angular Robot Date: Mon, 15 Jun 2026 19:11:08 +0000 Subject: [PATCH 044/787] build: update cross-repo angular dependencies See associated pull request for more information. --- MODULE.bazel | 6 +- MODULE.bazel.lock | 36 +-- modules/testing/builder/package.json | 2 +- package.json | 2 +- packages/angular/build/package.json | 2 +- .../angular_devkit/build_angular/package.json | 2 +- pnpm-lock.yaml | 258 ++++++++++-------- tests/e2e/ng-snapshot/package.json | 32 +-- 8 files changed, 181 insertions(+), 159 deletions(-) diff --git a/MODULE.bazel b/MODULE.bazel index 3f42ca04a729..6b21b34ca20c 100644 --- a/MODULE.bazel +++ b/MODULE.bazel @@ -19,21 +19,21 @@ bazel_dep(name = "aspect_rules_jasmine", version = "2.0.4") bazel_dep(name = "rules_angular") git_override( module_name = "rules_angular", - commit = "0571709fc1bf8174c94f4b01c87f50a3b3d3cf23", + commit = "7657fae9f218f1fcd818a4b594bdd8833e83c734", remote = "https://github.com/angular/rules_angular.git", ) bazel_dep(name = "devinfra") git_override( module_name = "devinfra", - commit = "b9d15e3de22a6b8b161046d1ed5cea574a2537ca", + commit = "023fc8fd55661b2ba24151350bd7460dafd8ae88", remote = "https://github.com/angular/dev-infra.git", ) bazel_dep(name = "rules_browsers") git_override( module_name = "rules_browsers", - commit = "3e345a43e88f86a744003da90a28fc31cf4e07fb", + commit = "cbd4a436db23d9c3156f1b17a007d01ee60608d9", remote = "https://github.com/angular/rules_browsers.git", ) diff --git a/MODULE.bazel.lock b/MODULE.bazel.lock index 6dd3f65f8d69..fc8198c538cc 100644 --- a/MODULE.bazel.lock +++ b/MODULE.bazel.lock @@ -24,7 +24,7 @@ "https://bcr.bazel.build/modules/aspect_rules_jasmine/2.0.4/source.json": "81ffb708333cd98ec3c0b4cc004f4d5cf92a16914b5196a2892c45141bba7cff", "https://bcr.bazel.build/modules/aspect_rules_js/2.0.0/MODULE.bazel": "b45b507574aa60a92796e3e13c195cd5744b3b8aff516a9c0cb5ae6a048161c5", "https://bcr.bazel.build/modules/aspect_rules_js/3.0.3/MODULE.bazel": "28a30e8fc33bf64a67835d64d124f6e05a7d59648dcb27b110fb3502f761e503", - "https://bcr.bazel.build/modules/aspect_rules_js/3.2.0/MODULE.bazel": "c3d34345c51a4d90cf678d3b251c6f345b63d5e2e6b0253dbdda467a01efc31f", + "https://bcr.bazel.build/modules/aspect_rules_js/3.2.1/MODULE.bazel": "c1322ead2330fb8b8c84fc1b1cb4a053ab48c1c5da791b3732cb994b7c0dc2bb", "https://bcr.bazel.build/modules/aspect_rules_js/3.2.2/MODULE.bazel": "e844196321b64537cfade338f361633e7d5fe084eee3214fc531b9e7b9838813", "https://bcr.bazel.build/modules/aspect_rules_js/3.2.2/source.json": "0e650e493b3bc784dc3f8240ff00b4b32258cde6d021ef6b1db4e387bcfd6a9a", "https://bcr.bazel.build/modules/aspect_rules_ts/3.8.10/MODULE.bazel": "a17a49a21226fc90163a29b3d6eac56703697205530b8d5cc38b3c074dbac039", @@ -593,7 +593,7 @@ }, "@@rules_browsers+//browsers:extensions.bzl%browsers": { "general": { - "bzlTransitiveDigest": "WS+hxcF6xP7F7M8vQJNunWdRe2E7XZ7FmTakAtg8A1Q=", + "bzlTransitiveDigest": "UKZtUX6IBvCRrfn0KFUmDLmhaT5IJaWD6ctmDFfRFj8=", "usagesDigest": "FmXYJVoVJlnfUU8x8gObSvu4qWcco/9Faw61aC/wBF0=", "recordedFileInputs": {}, "recordedDirentsInputs": {}, @@ -602,9 +602,9 @@ "rules_browsers_chrome_linux": { "repoRuleId": "@@rules_browsers+//browsers/private:browser_repo.bzl%browser_repo", "attributes": { - "sha256": "03883cfad5344e0815091f53a03909af9989f72a800b0ad2a691c9de52ff7df9", + "sha256": "7b81d44a96b579d198ac929fdbeeb6b329e9345759b101a0483701763dfa339f", "urls": [ - "https://storage.googleapis.com/chrome-for-testing-public/151.0.7884.0/linux64/chrome-headless-shell-linux64.zip" + "https://storage.googleapis.com/chrome-for-testing-public/151.0.7886.0/linux64/chrome-headless-shell-linux64.zip" ], "named_files": { "CHROME-HEADLESS-SHELL": "chrome-headless-shell-linux64/chrome-headless-shell" @@ -620,9 +620,9 @@ "rules_browsers_chrome_mac": { "repoRuleId": "@@rules_browsers+//browsers/private:browser_repo.bzl%browser_repo", "attributes": { - "sha256": "a3d20f3b47f5d7c1b5695229f599d1981be3e0f8a71f782477d4a9343c4a477e", + "sha256": "d991d55c69b1b9e4da88abad870585a3b81849cb9b3e1cd667b65f0a7edcdee4", "urls": [ - "https://storage.googleapis.com/chrome-for-testing-public/151.0.7884.0/mac-x64/chrome-headless-shell-mac-x64.zip" + "https://storage.googleapis.com/chrome-for-testing-public/151.0.7886.0/mac-x64/chrome-headless-shell-mac-x64.zip" ], "named_files": { "CHROME-HEADLESS-SHELL": "chrome-headless-shell-mac-x64/chrome-headless-shell" @@ -638,9 +638,9 @@ "rules_browsers_chrome_mac_arm": { "repoRuleId": "@@rules_browsers+//browsers/private:browser_repo.bzl%browser_repo", "attributes": { - "sha256": "b381e35fecea3e7e712b5874eadbd0fb06644fa925fb4ce35cfc5187bd8da82b", + "sha256": "78ecce4673957a4ddaae944fd7b5fbd1c2400c5c82092490eb0cb4004928dc93", "urls": [ - "https://storage.googleapis.com/chrome-for-testing-public/151.0.7884.0/mac-arm64/chrome-headless-shell-mac-arm64.zip" + "https://storage.googleapis.com/chrome-for-testing-public/151.0.7886.0/mac-arm64/chrome-headless-shell-mac-arm64.zip" ], "named_files": { "CHROME-HEADLESS-SHELL": "chrome-headless-shell-mac-arm64/chrome-headless-shell" @@ -656,9 +656,9 @@ "rules_browsers_chrome_win64": { "repoRuleId": "@@rules_browsers+//browsers/private:browser_repo.bzl%browser_repo", "attributes": { - "sha256": "2e17c31f672b767ca6aa2789c31d956a2a518d3dc0e7838417a7a43c9152ecb2", + "sha256": "987f0fba9d2150e125edd1afd324aad4efcbc760d47dcc7341a1f544083ae85e", "urls": [ - "https://storage.googleapis.com/chrome-for-testing-public/151.0.7884.0/win64/chrome-headless-shell-win64.zip" + "https://storage.googleapis.com/chrome-for-testing-public/151.0.7886.0/win64/chrome-headless-shell-win64.zip" ], "named_files": { "CHROME-HEADLESS-SHELL": "chrome-headless-shell-win64/chrome-headless-shell.exe" @@ -674,9 +674,9 @@ "rules_browsers_chromedriver_linux": { "repoRuleId": "@@rules_browsers+//browsers/private:browser_repo.bzl%browser_repo", "attributes": { - "sha256": "a48735d28dfc6131ee9060a33925ad32004dd8fd5811f8c8b5b90c22be2be2ea", + "sha256": "cedb06e3bb84c768a21c43a474a9fb35e2505eaab25357dfcf30c3511a1da0f5", "urls": [ - "https://storage.googleapis.com/chrome-for-testing-public/151.0.7884.0/linux64/chromedriver-linux64.zip" + "https://storage.googleapis.com/chrome-for-testing-public/151.0.7886.0/linux64/chromedriver-linux64.zip" ], "named_files": { "CHROMEDRIVER": "chromedriver-linux64/chromedriver" @@ -690,9 +690,9 @@ "rules_browsers_chromedriver_mac": { "repoRuleId": "@@rules_browsers+//browsers/private:browser_repo.bzl%browser_repo", "attributes": { - "sha256": "d55ad1405b03849147996c208e0a4962161d4d8d2a60067635d7e4330beb157e", + "sha256": "5aa64dcf25474b11fca25fb25b99822d9afc9d01ee37ba5acef00148a2bff7a6", "urls": [ - "https://storage.googleapis.com/chrome-for-testing-public/151.0.7884.0/mac-x64/chromedriver-mac-x64.zip" + "https://storage.googleapis.com/chrome-for-testing-public/151.0.7886.0/mac-x64/chromedriver-mac-x64.zip" ], "named_files": { "CHROMEDRIVER": "chromedriver-mac-x64/chromedriver" @@ -706,9 +706,9 @@ "rules_browsers_chromedriver_mac_arm": { "repoRuleId": "@@rules_browsers+//browsers/private:browser_repo.bzl%browser_repo", "attributes": { - "sha256": "86ab265ac6951ea5f338398c0ebc9b67a4ed0052c69f00d406542f67af98d28f", + "sha256": "9ffb270d0a79144a71b770266e178de22f67261df3497f716eb536e15a12f1ac", "urls": [ - "https://storage.googleapis.com/chrome-for-testing-public/151.0.7884.0/mac-arm64/chromedriver-mac-arm64.zip" + "https://storage.googleapis.com/chrome-for-testing-public/151.0.7886.0/mac-arm64/chromedriver-mac-arm64.zip" ], "named_files": { "CHROMEDRIVER": "chromedriver-mac-arm64/chromedriver" @@ -722,9 +722,9 @@ "rules_browsers_chromedriver_win64": { "repoRuleId": "@@rules_browsers+//browsers/private:browser_repo.bzl%browser_repo", "attributes": { - "sha256": "ae1b4dfd27a4c35f3662f942d5e430b1502bac241e822170067dd94b026373ac", + "sha256": "374576d46728e3529de1d1535880fa11033aeb3c4d5ead3f54dbab4143aa8a65", "urls": [ - "https://storage.googleapis.com/chrome-for-testing-public/151.0.7884.0/win64/chromedriver-win64.zip" + "https://storage.googleapis.com/chrome-for-testing-public/151.0.7886.0/win64/chromedriver-win64.zip" ], "named_files": { "CHROMEDRIVER": "chromedriver-win64/chromedriver.exe" diff --git a/modules/testing/builder/package.json b/modules/testing/builder/package.json index 5f98e3097d25..1aea49b4c16c 100644 --- a/modules/testing/builder/package.json +++ b/modules/testing/builder/package.json @@ -8,7 +8,7 @@ "browser-sync": "3.0.4", "istanbul-lib-instrument": "6.0.3", "jsdom": "29.1.1", - "ng-packagr": "22.1.0-next.1", + "ng-packagr": "22.1.0-next.2", "rxjs": "7.8.2", "vitest": "4.1.8" } diff --git a/package.json b/package.json index a1c171a9609a..f3978e7be6fb 100644 --- a/package.json +++ b/package.json @@ -54,7 +54,7 @@ "@angular/forms": "22.1.0-next.0", "@angular/localize": "22.1.0-next.0", "@angular/material": "22.1.0-next.0", - "@angular/ng-dev": "https://github.com/angular/dev-infra-private-ng-dev-builds.git#5d9842518819d66cfb65994e2dda90354410a449", + "@angular/ng-dev": "https://github.com/angular/dev-infra-private-ng-dev-builds.git#cefe10420ad2ecdadd21129be75b71aa485baea6", "@angular/platform-browser": "22.1.0-next.0", "@angular/platform-server": "22.1.0-next.0", "@angular/router": "22.1.0-next.0", diff --git a/packages/angular/build/package.json b/packages/angular/build/package.json index 2058061982ef..acf0b30b84ba 100644 --- a/packages/angular/build/package.json +++ b/packages/angular/build/package.json @@ -53,7 +53,7 @@ "istanbul-lib-instrument": "6.0.3", "jsdom": "29.1.1", "less": "4.6.4", - "ng-packagr": "22.1.0-next.1", + "ng-packagr": "22.1.0-next.2", "postcss": "8.5.15", "rolldown": "1.0.3", "rxjs": "7.8.2", diff --git a/packages/angular_devkit/build_angular/package.json b/packages/angular_devkit/build_angular/package.json index 03feae5219d7..a512ba1e5175 100644 --- a/packages/angular_devkit/build_angular/package.json +++ b/packages/angular_devkit/build_angular/package.json @@ -66,7 +66,7 @@ "devDependencies": { "@angular/ssr": "workspace:*", "browser-sync": "3.0.4", - "ng-packagr": "22.1.0-next.1", + "ng-packagr": "22.1.0-next.2", "undici": "8.3.0" }, "peerDependencies": { diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index ea01c8e1f27b..40f11de65b60 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -50,8 +50,8 @@ importers: specifier: 22.1.0-next.0 version: 22.1.0-next.0(25ca0260cba80497f59a6bedbf88cafa) '@angular/ng-dev': - specifier: https://github.com/angular/dev-infra-private-ng-dev-builds.git#5d9842518819d66cfb65994e2dda90354410a449 - version: https://codeload.github.com/angular/dev-infra-private-ng-dev-builds/tar.gz/5d9842518819d66cfb65994e2dda90354410a449(@modelcontextprotocol/sdk@1.29.0(zod@4.4.3)) + specifier: https://github.com/angular/dev-infra-private-ng-dev-builds.git#cefe10420ad2ecdadd21129be75b71aa485baea6 + version: https://codeload.github.com/angular/dev-infra-private-ng-dev-builds/tar.gz/cefe10420ad2ecdadd21129be75b71aa485baea6(@modelcontextprotocol/sdk@1.29.0(zod@4.4.3)) '@angular/platform-browser': specifier: 22.1.0-next.0 version: 22.1.0-next.0(@angular/animations@22.1.0-next.0(@angular/core@22.1.0-next.0(@angular/compiler@22.1.0-next.0)(rxjs@7.8.2)(zone.js@0.16.2)))(@angular/common@22.1.0-next.0(@angular/core@22.1.0-next.0(@angular/compiler@22.1.0-next.0)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2))(@angular/core@22.1.0-next.0(@angular/compiler@22.1.0-next.0)(rxjs@7.8.2)(zone.js@0.16.2)) @@ -326,14 +326,14 @@ importers: specifier: 29.1.1 version: 29.1.1 ng-packagr: - specifier: 22.1.0-next.1 - version: 22.1.0-next.1(@angular/compiler-cli@22.1.0-next.0(@angular/compiler@22.1.0-next.0)(typescript@6.0.3))(tslib@2.8.1)(typescript@6.0.3) + specifier: 22.1.0-next.2 + version: 22.1.0-next.2(@angular/compiler-cli@22.1.0-next.0(@angular/compiler@22.1.0-next.0)(typescript@6.0.3))(tslib@2.8.1)(typescript@6.0.3) rxjs: specifier: 7.8.2 version: 7.8.2 vitest: specifier: 4.1.8 - version: 4.1.8(@opentelemetry/api@1.9.1)(@types/node@24.12.4)(@vitest/coverage-v8@4.1.8)(jiti@2.7.0)(jsdom@29.1.1)(less@4.6.4)(sass@1.100.0)(terser@5.48.0)(tsx@4.22.4)(yaml@2.9.0) + version: 4.1.8(@opentelemetry/api@1.9.1)(@types/node@24.13.2)(@vitest/coverage-v8@4.1.8)(jiti@2.7.0)(jsdom@29.1.1)(less@4.6.4)(sass@1.100.0)(terser@5.48.0)(tsx@4.22.4)(yaml@2.9.0) packages/angular/build: dependencies: @@ -354,10 +354,10 @@ importers: version: 7.24.7 '@inquirer/confirm': specifier: 6.1.1 - version: 6.1.1(@types/node@24.12.4) + version: 6.1.1(@types/node@24.13.2) '@vitejs/plugin-basic-ssl': specifier: 2.3.0 - version: 2.3.0(vite@7.3.5(@types/node@24.12.4)(jiti@2.7.0)(less@4.6.4)(sass@1.100.0)(terser@5.48.0)(tsx@4.22.4)(yaml@2.9.0)) + version: 2.3.0(vite@7.3.5(@types/node@24.13.2)(jiti@2.7.0)(less@4.6.4)(sass@1.100.0)(terser@5.48.0)(tsx@4.22.4)(yaml@2.9.0)) beasties: specifier: 0.4.2 version: 0.4.2 @@ -408,7 +408,7 @@ importers: version: 0.2.17 vite: specifier: 7.3.5 - version: 7.3.5(@types/node@24.12.4)(jiti@2.7.0)(less@4.6.4)(sass@1.100.0)(terser@5.48.0)(tsx@4.22.4)(yaml@2.9.0) + version: 7.3.5(@types/node@24.13.2)(jiti@2.7.0)(less@4.6.4)(sass@1.100.0)(terser@5.48.0)(tsx@4.22.4)(yaml@2.9.0) watchpack: specifier: 2.5.1 version: 2.5.1 @@ -429,8 +429,8 @@ importers: specifier: 4.6.4 version: 4.6.4 ng-packagr: - specifier: 22.1.0-next.1 - version: 22.1.0-next.1(@angular/compiler-cli@22.1.0-next.0(@angular/compiler@22.1.0-next.0)(typescript@6.0.3))(tslib@2.8.1)(typescript@6.0.3) + specifier: 22.1.0-next.2 + version: 22.1.0-next.2(@angular/compiler-cli@22.1.0-next.0(@angular/compiler@22.1.0-next.0)(typescript@6.0.3))(tslib@2.8.1)(typescript@6.0.3) postcss: specifier: 8.5.15 version: 8.5.15 @@ -442,7 +442,7 @@ importers: version: 7.8.2 vitest: specifier: 4.1.8 - version: 4.1.8(@opentelemetry/api@1.9.1)(@types/node@24.12.4)(@vitest/coverage-v8@4.1.8)(jiti@2.7.0)(jsdom@29.1.1)(less@4.6.4)(sass@1.100.0)(terser@5.48.0)(tsx@4.22.4)(yaml@2.9.0) + version: 4.1.8(@opentelemetry/api@1.9.1)(@types/node@24.13.2)(@vitest/coverage-v8@4.1.8)(jiti@2.7.0)(jsdom@29.1.1)(less@4.6.4)(sass@1.100.0)(terser@5.48.0)(tsx@4.22.4)(yaml@2.9.0) optionalDependencies: lmdb: specifier: 3.5.5 @@ -461,10 +461,10 @@ importers: version: link:../../angular_devkit/schematics '@inquirer/prompts': specifier: 8.5.2 - version: 8.5.2(@types/node@24.12.4) + version: 8.5.2(@types/node@24.13.2) '@listr2/prompt-adapter-inquirer': specifier: 4.2.4 - version: 4.2.4(@inquirer/prompts@8.5.2(@types/node@24.12.4))(@types/node@24.12.4)(listr2@10.2.1) + version: 4.2.4(@inquirer/prompts@8.5.2(@types/node@24.13.2))(@types/node@24.13.2)(listr2@10.2.1) '@modelcontextprotocol/sdk': specifier: 1.29.0 version: 1.29.0(zod@4.4.3) @@ -729,8 +729,8 @@ importers: specifier: 3.0.4 version: 3.0.4(bufferutil@4.1.0)(utf-8-validate@6.0.6) ng-packagr: - specifier: 22.1.0-next.1 - version: 22.1.0-next.1(@angular/compiler-cli@22.1.0-next.0(@angular/compiler@22.1.0-next.0)(typescript@6.0.3))(tslib@2.8.1)(typescript@6.0.3) + specifier: 22.1.0-next.2 + version: 22.1.0-next.2(@angular/compiler-cli@22.1.0-next.0(@angular/compiler@22.1.0-next.0)(typescript@6.0.3))(tslib@2.8.1)(typescript@6.0.3) undici: specifier: 8.3.0 version: 8.3.0 @@ -814,7 +814,7 @@ importers: version: link:../schematics '@inquirer/prompts': specifier: 8.5.2 - version: 8.5.2(@types/node@24.12.4) + version: 8.5.2(@types/node@24.13.2) packages/ngtools/webpack: devDependencies: @@ -938,7 +938,7 @@ packages: '@angular/animations@22.1.0-next.0': resolution: {integrity: sha512-Gi3BNfHZEfqs9EZrnd9rAiuh8YKfiijs4YJO0mJWWmJULmgaISJVfrOCv1+iqlSy/VnN3cVtHpNtwvqiMyU0Sg==} engines: {node: ^22.22.3 || ^24.15.0 || >=26.0.0} - deprecated: '@angular/animations is deprecated. Use `animate.enter` and `animate.leave` instead.' + deprecated: '@angular/animations is deprecated. Use `animate.enter` and `animate.leave` instead. For more information see: https://v22.angular.dev/guide/animations.' peerDependencies: '@angular/core': 22.1.0-next.0 @@ -1012,9 +1012,9 @@ packages: '@angular/platform-browser': ^22.0.0-0 || ^22.1.0-0 || ^22.2.0-0 || ^22.3.0-0 || ^23.0.0-0 rxjs: ^6.5.3 || ^7.4.0 - '@angular/ng-dev@https://codeload.github.com/angular/dev-infra-private-ng-dev-builds/tar.gz/5d9842518819d66cfb65994e2dda90354410a449': - resolution: {gitHosted: true, integrity: sha512-sp07Jlt/pO9uei3u6ZJdLgnOJ+Dj4/Jl30FjapEWoQf+M9f2UQ2waL1rN5thZCcHQnwNfbNbIHDCcXPFQjFeUg==, tarball: https://codeload.github.com/angular/dev-infra-private-ng-dev-builds/tar.gz/5d9842518819d66cfb65994e2dda90354410a449} - version: 0.0.0-b9d15e3de22a6b8b161046d1ed5cea574a2537ca + '@angular/ng-dev@https://codeload.github.com/angular/dev-infra-private-ng-dev-builds/tar.gz/cefe10420ad2ecdadd21129be75b71aa485baea6': + resolution: {gitHosted: true, integrity: sha512-w3tzwKpn+TNJL6RXw7D2puYVbLfo1SZco49vh8xym9hhUNa80MfLkaYS5yz8N0wpzucm2GfpT2vuAX0tnWNtwA==, tarball: https://codeload.github.com/angular/dev-infra-private-ng-dev-builds/tar.gz/cefe10420ad2ecdadd21129be75b71aa485baea6} + version: 0.0.0-023fc8fd55661b2ba24151350bd7460dafd8ae88 hasBin: true '@angular/platform-browser@22.1.0-next.0': @@ -2288,8 +2288,8 @@ packages: resolution: {integrity: sha512-IJn+8A3QZJfe7FUtWqHVNo3xJs7KFpurCWGWCiCz3oEh+BkRymKZ1QxfAbU2yGMDzTytLGQ2IV6T2r3cuo75/w==} engines: {node: '>=18'} - '@google/genai@2.7.0': - resolution: {integrity: sha512-tv0DRtcndt2oEhBYy+5mA0TaXH98+L1Gt0AP9unBfH7DP20KhB7+O3QqAN1Lz+laMARGTHS7BFQSNpLbl4gm1g==} + '@google/genai@2.8.0': + resolution: {integrity: sha512-pc2ayxqO5+O7AvnHBqpNHIk7PAZkHZgL31tbyx0gJZBSS9qPYiQoqwK7oYOw/ePmG6QY4EMSu+304vD5QlhXAw==} engines: {node: '>=20.0.0'} peerDependencies: '@modelcontextprotocol/sdk': ^1.25.2 @@ -3685,8 +3685,8 @@ packages: '@types/node@22.19.20': resolution: {integrity: sha512-6tELRwSDYWW9EdZhbeZmYGZ1/7Djkt+Ah3/ScEYT9cDord7UJzasR/4D3VONg9tQI5CDp+/CZC1AXj2pCFOvpw==} - '@types/node@24.12.4': - resolution: {integrity: sha512-GUUEShf+PBCGW2KaXwcIt3Yk+e3pkKwWKb9GSyM9WQVE+ep2jzmHdGsHzu4wgcZy5fN9FBdVzjpBQsYlpfpgLA==} + '@types/node@24.13.2': + resolution: {integrity: sha512-fRa09kZTgu8o71KFcDjUFuc7F+dEbZYZmkI0mg5YBTRs0yMKjYHsq/c0urDKeDb+D5qVgXOdFcuu+DZPKOITwA==} '@types/npm-package-arg@6.1.4': resolution: {integrity: sha512-vDgdbMy2QXHnAruzlv68pUtXCjmqUk3WrBAsRboRovsOmxbfn/WiYCjmecyKjGztnMps5dWp4Uq2prp+Ilo17Q==} @@ -6081,6 +6081,9 @@ packages: jasmine-core@6.2.0: resolution: {integrity: sha512-b16WZG/pFEFj8qRW1ss7nDuNGYz9ji8BDGj7fJNrROauk5rj/diO3KPOuyIpcgUChdC+c0PfQ8iUk4nHE+EN4w==} + jasmine-core@6.3.0: + resolution: {integrity: sha512-eMm5qBovNjNoGOcgE/W207+wrcK5zrQv0Rg/rWGboUJUmZp0dFCpHTyjpuDAfCwRCqg7f9U2q2jtv/aUuzdCQg==} + jasmine-reporters@2.5.2: resolution: {integrity: sha512-qdewRUuFOSiWhiyWZX8Yx3YNQ9JG51ntBEO4ekLQRpktxFTwUHy24a86zD/Oi2BRTKksEdfWQZcQFqzjqIkPig==} @@ -6091,6 +6094,10 @@ packages: resolution: {integrity: sha512-dvYt7bidcu0JvvSbiUnSDW7UQQiflUwDr6C+5wzoZ0J7RY9u+UcoSIzyhMPj6fnU/tC7KinJ5QrjwD2Y9p4T4w==} hasBin: true + jasmine@6.3.0: + resolution: {integrity: sha512-u6L7yYtrtS1JALlp7f4k7Wz7o7ZKXauSKKkXc0L3qUkKrdaxYvNiMHhHp5gtTuVZZXVihXRxS7bWwDBX1wJ7EQ==} + hasBin: true + jest-worker@27.5.1: resolution: {integrity: sha512-7vuh85V5cdDofPyxn58nrPjBktZo0u9x1g8WtjQol+jZDaE+fhN+cIvTj11GndBnMnyfrUOG1sZQxCdjKh+DKg==} engines: {node: '>= 10.13.0'} @@ -6626,12 +6633,12 @@ packages: neo-async@2.6.2: resolution: {integrity: sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==} - ng-packagr@22.1.0-next.1: - resolution: {integrity: sha512-EouABEYnyYUW7ovcxgI8QQhXWZKQncKO37914yPy2Z/GNNsZypSBuA0ienrRc3XfkPbsmMF6FuUGninM/+1Ccg==} + ng-packagr@22.1.0-next.2: + resolution: {integrity: sha512-gBQdNiAotarfYzO9Wiznena0zPUE1kjvRV2anT4tx+o0cgMb/tXJ7oLZh/FMtNvhimXi6meT+M+DO+iFP1UamQ==} engines: {node: ^22.22.3 || ^24.15.0 || >=26.0.0} hasBin: true peerDependencies: - '@angular/compiler-cli': ^22.0.0 || ^22.0.0-next.0 + '@angular/compiler-cli': ^22.0.0 || ^22.1.0-next.0 tailwindcss: ^2.0.0 || ^3.0.0 || ^4.0.0 tslib: ^2.3.0 typescript: '>=6.0 <6.1' @@ -7470,6 +7477,11 @@ packages: engines: {node: '>=10'} hasBin: true + semver@7.8.4: + resolution: {integrity: sha512-rUCObTnP32Q08R2uuIrt7r9PlEonuTmtuXYcW6s5kjdlj3xbnwe+21yXptAUYcMAABLkYYTtnmzb3w3EDZfueA==} + engines: {node: '>=10'} + hasBin: true + send@0.19.2: resolution: {integrity: sha512-VMbMxbDeehAxpOtWJXlcUS5E8iXh6QmN+BkRX1GARS3wRaXEEgzCcB10gTQazO42tpNIya8xIyNx8fll1OFPrg==} engines: {node: '>= 0.8.0'} @@ -8065,8 +8077,8 @@ packages: undici-types@6.21.0: resolution: {integrity: sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==} - undici-types@7.16.0: - resolution: {integrity: sha512-Zz+aZWSj8LE6zoxD+xrjh4VfkIG8Ya6LvYkZqtUQGJPZjYl53ypCaUwWqo7eI0x66KBGeRo+mlBEkMSeSZ38Nw==} + undici-types@7.18.2: + resolution: {integrity: sha512-AsuCzffGHJybSaRrmr5eHr81mwJU3kjw6M+uprWvCXiNeN9SOGwQ3Jn8jb8m3Z6izVgknn1R0FTCEAP2QrLY/w==} undici@6.26.0: resolution: {integrity: sha512-4yqz8a3n5HmGTlsbADNtr/dJlhkh/55Rq798G6ibiULcXbDtaLpTl1pvdqcbFfeoj3iSi52lePFM7h9H21cw/A==} @@ -8754,14 +8766,14 @@ snapshots: rxjs: 7.8.2 tslib: 2.8.1 - '@angular/ng-dev@https://codeload.github.com/angular/dev-infra-private-ng-dev-builds/tar.gz/5d9842518819d66cfb65994e2dda90354410a449(@modelcontextprotocol/sdk@1.29.0(zod@4.4.3))': + '@angular/ng-dev@https://codeload.github.com/angular/dev-infra-private-ng-dev-builds/tar.gz/cefe10420ad2ecdadd21129be75b71aa485baea6(@modelcontextprotocol/sdk@1.29.0(zod@4.4.3))': dependencies: '@actions/core': 3.0.1 '@conventional-changelog/git-client': 2.7.0(conventional-commits-filter@5.0.0)(conventional-commits-parser@6.4.0) '@google-cloud/spanner': 8.0.0(supports-color@10.2.2) - '@google/genai': 2.7.0(@modelcontextprotocol/sdk@1.29.0(zod@4.4.3))(bufferutil@4.1.0)(supports-color@10.2.2)(utf-8-validate@6.0.6) - '@inquirer/prompts': 8.5.2(@types/node@24.12.4) - '@inquirer/type': 4.0.7(@types/node@24.12.4) + '@google/genai': 2.8.0(@modelcontextprotocol/sdk@1.29.0(zod@4.4.3))(bufferutil@4.1.0)(supports-color@10.2.2)(utf-8-validate@6.0.6) + '@inquirer/prompts': 8.5.2(@types/node@24.13.2) + '@inquirer/type': 4.0.7(@types/node@24.13.2) '@octokit/auth-app': 8.2.0 '@octokit/core': 7.0.6 '@octokit/graphql': 9.0.3 @@ -8778,7 +8790,7 @@ snapshots: '@types/events': 3.0.3 '@types/folder-hash': 4.0.4 '@types/jasmine': 6.0.0 - '@types/node': 24.12.4 + '@types/node': 24.13.2 '@types/semver': 7.7.1 '@types/which': 3.0.4 '@types/yargs': 17.0.35 @@ -8793,14 +8805,14 @@ snapshots: fast-glob: 3.3.3 firebase: 12.14.0 folder-hash: 4.1.3(supports-color@10.2.2) - jasmine: 6.2.0 - jasmine-core: 6.2.0 + jasmine: 6.3.0 + jasmine-core: 6.3.0 jasmine-reporters: 2.5.2 jsonc-parser: 3.3.1 minimatch: 10.2.5 multimatch: 8.0.0 nock: 14.0.15 - semver: 7.8.1 + semver: 7.8.4 supports-color: 10.2.2 tsx: 4.22.4 typed-graphqlify: 3.1.6 @@ -10226,7 +10238,7 @@ snapshots: transitivePeerDependencies: - supports-color - '@google/genai@2.7.0(@modelcontextprotocol/sdk@1.29.0(zod@4.4.3))(bufferutil@4.1.0)(supports-color@10.2.2)(utf-8-validate@6.0.6)': + '@google/genai@2.8.0(@modelcontextprotocol/sdk@1.29.0(zod@4.4.3))(bufferutil@4.1.0)(supports-color@10.2.2)(utf-8-validate@6.0.6)': dependencies: google-auth-library: 10.7.0(supports-color@10.2.2) p-retry: 4.6.2 @@ -10288,122 +10300,122 @@ snapshots: '@inquirer/ansi@2.0.7': {} - '@inquirer/checkbox@5.2.1(@types/node@24.12.4)': + '@inquirer/checkbox@5.2.1(@types/node@24.13.2)': dependencies: '@inquirer/ansi': 2.0.7 - '@inquirer/core': 11.2.1(@types/node@24.12.4) + '@inquirer/core': 11.2.1(@types/node@24.13.2) '@inquirer/figures': 2.0.7 - '@inquirer/type': 4.0.7(@types/node@24.12.4) + '@inquirer/type': 4.0.7(@types/node@24.13.2) optionalDependencies: - '@types/node': 24.12.4 + '@types/node': 24.13.2 - '@inquirer/confirm@6.1.1(@types/node@24.12.4)': + '@inquirer/confirm@6.1.1(@types/node@24.13.2)': dependencies: - '@inquirer/core': 11.2.1(@types/node@24.12.4) - '@inquirer/type': 4.0.7(@types/node@24.12.4) + '@inquirer/core': 11.2.1(@types/node@24.13.2) + '@inquirer/type': 4.0.7(@types/node@24.13.2) optionalDependencies: - '@types/node': 24.12.4 + '@types/node': 24.13.2 - '@inquirer/core@11.2.1(@types/node@24.12.4)': + '@inquirer/core@11.2.1(@types/node@24.13.2)': dependencies: '@inquirer/ansi': 2.0.7 '@inquirer/figures': 2.0.7 - '@inquirer/type': 4.0.7(@types/node@24.12.4) + '@inquirer/type': 4.0.7(@types/node@24.13.2) cli-width: 4.1.0 fast-wrap-ansi: 0.2.2 mute-stream: 3.0.0 signal-exit: 4.1.0 optionalDependencies: - '@types/node': 24.12.4 + '@types/node': 24.13.2 - '@inquirer/editor@5.2.2(@types/node@24.12.4)': + '@inquirer/editor@5.2.2(@types/node@24.13.2)': dependencies: - '@inquirer/core': 11.2.1(@types/node@24.12.4) - '@inquirer/external-editor': 3.0.3(@types/node@24.12.4) - '@inquirer/type': 4.0.7(@types/node@24.12.4) + '@inquirer/core': 11.2.1(@types/node@24.13.2) + '@inquirer/external-editor': 3.0.3(@types/node@24.13.2) + '@inquirer/type': 4.0.7(@types/node@24.13.2) optionalDependencies: - '@types/node': 24.12.4 + '@types/node': 24.13.2 - '@inquirer/expand@5.1.1(@types/node@24.12.4)': + '@inquirer/expand@5.1.1(@types/node@24.13.2)': dependencies: - '@inquirer/core': 11.2.1(@types/node@24.12.4) - '@inquirer/type': 4.0.7(@types/node@24.12.4) + '@inquirer/core': 11.2.1(@types/node@24.13.2) + '@inquirer/type': 4.0.7(@types/node@24.13.2) optionalDependencies: - '@types/node': 24.12.4 + '@types/node': 24.13.2 - '@inquirer/external-editor@3.0.3(@types/node@24.12.4)': + '@inquirer/external-editor@3.0.3(@types/node@24.13.2)': dependencies: chardet: 2.1.1 iconv-lite: 0.7.2 optionalDependencies: - '@types/node': 24.12.4 + '@types/node': 24.13.2 '@inquirer/figures@2.0.7': {} - '@inquirer/input@5.1.2(@types/node@24.12.4)': + '@inquirer/input@5.1.2(@types/node@24.13.2)': dependencies: - '@inquirer/core': 11.2.1(@types/node@24.12.4) - '@inquirer/type': 4.0.7(@types/node@24.12.4) + '@inquirer/core': 11.2.1(@types/node@24.13.2) + '@inquirer/type': 4.0.7(@types/node@24.13.2) optionalDependencies: - '@types/node': 24.12.4 + '@types/node': 24.13.2 - '@inquirer/number@4.1.1(@types/node@24.12.4)': + '@inquirer/number@4.1.1(@types/node@24.13.2)': dependencies: - '@inquirer/core': 11.2.1(@types/node@24.12.4) - '@inquirer/type': 4.0.7(@types/node@24.12.4) + '@inquirer/core': 11.2.1(@types/node@24.13.2) + '@inquirer/type': 4.0.7(@types/node@24.13.2) optionalDependencies: - '@types/node': 24.12.4 + '@types/node': 24.13.2 - '@inquirer/password@5.1.1(@types/node@24.12.4)': + '@inquirer/password@5.1.1(@types/node@24.13.2)': dependencies: '@inquirer/ansi': 2.0.7 - '@inquirer/core': 11.2.1(@types/node@24.12.4) - '@inquirer/type': 4.0.7(@types/node@24.12.4) + '@inquirer/core': 11.2.1(@types/node@24.13.2) + '@inquirer/type': 4.0.7(@types/node@24.13.2) optionalDependencies: - '@types/node': 24.12.4 - - '@inquirer/prompts@8.5.2(@types/node@24.12.4)': - dependencies: - '@inquirer/checkbox': 5.2.1(@types/node@24.12.4) - '@inquirer/confirm': 6.1.1(@types/node@24.12.4) - '@inquirer/editor': 5.2.2(@types/node@24.12.4) - '@inquirer/expand': 5.1.1(@types/node@24.12.4) - '@inquirer/input': 5.1.2(@types/node@24.12.4) - '@inquirer/number': 4.1.1(@types/node@24.12.4) - '@inquirer/password': 5.1.1(@types/node@24.12.4) - '@inquirer/rawlist': 5.3.1(@types/node@24.12.4) - '@inquirer/search': 4.2.1(@types/node@24.12.4) - '@inquirer/select': 5.2.1(@types/node@24.12.4) + '@types/node': 24.13.2 + + '@inquirer/prompts@8.5.2(@types/node@24.13.2)': + dependencies: + '@inquirer/checkbox': 5.2.1(@types/node@24.13.2) + '@inquirer/confirm': 6.1.1(@types/node@24.13.2) + '@inquirer/editor': 5.2.2(@types/node@24.13.2) + '@inquirer/expand': 5.1.1(@types/node@24.13.2) + '@inquirer/input': 5.1.2(@types/node@24.13.2) + '@inquirer/number': 4.1.1(@types/node@24.13.2) + '@inquirer/password': 5.1.1(@types/node@24.13.2) + '@inquirer/rawlist': 5.3.1(@types/node@24.13.2) + '@inquirer/search': 4.2.1(@types/node@24.13.2) + '@inquirer/select': 5.2.1(@types/node@24.13.2) optionalDependencies: - '@types/node': 24.12.4 + '@types/node': 24.13.2 - '@inquirer/rawlist@5.3.1(@types/node@24.12.4)': + '@inquirer/rawlist@5.3.1(@types/node@24.13.2)': dependencies: - '@inquirer/core': 11.2.1(@types/node@24.12.4) - '@inquirer/type': 4.0.7(@types/node@24.12.4) + '@inquirer/core': 11.2.1(@types/node@24.13.2) + '@inquirer/type': 4.0.7(@types/node@24.13.2) optionalDependencies: - '@types/node': 24.12.4 + '@types/node': 24.13.2 - '@inquirer/search@4.2.1(@types/node@24.12.4)': + '@inquirer/search@4.2.1(@types/node@24.13.2)': dependencies: - '@inquirer/core': 11.2.1(@types/node@24.12.4) + '@inquirer/core': 11.2.1(@types/node@24.13.2) '@inquirer/figures': 2.0.7 - '@inquirer/type': 4.0.7(@types/node@24.12.4) + '@inquirer/type': 4.0.7(@types/node@24.13.2) optionalDependencies: - '@types/node': 24.12.4 + '@types/node': 24.13.2 - '@inquirer/select@5.2.1(@types/node@24.12.4)': + '@inquirer/select@5.2.1(@types/node@24.13.2)': dependencies: '@inquirer/ansi': 2.0.7 - '@inquirer/core': 11.2.1(@types/node@24.12.4) + '@inquirer/core': 11.2.1(@types/node@24.13.2) '@inquirer/figures': 2.0.7 - '@inquirer/type': 4.0.7(@types/node@24.12.4) + '@inquirer/type': 4.0.7(@types/node@24.13.2) optionalDependencies: - '@types/node': 24.12.4 + '@types/node': 24.13.2 - '@inquirer/type@4.0.7(@types/node@24.12.4)': + '@inquirer/type@4.0.7(@types/node@24.13.2)': optionalDependencies: - '@types/node': 24.12.4 + '@types/node': 24.13.2 '@isaacs/cliui@8.0.2': dependencies: @@ -10577,10 +10589,10 @@ snapshots: '@leichtgewicht/ip-codec@2.0.5': {} - '@listr2/prompt-adapter-inquirer@4.2.4(@inquirer/prompts@8.5.2(@types/node@24.12.4))(@types/node@24.12.4)(listr2@10.2.1)': + '@listr2/prompt-adapter-inquirer@4.2.4(@inquirer/prompts@8.5.2(@types/node@24.13.2))(@types/node@24.13.2)(listr2@10.2.1)': dependencies: - '@inquirer/prompts': 8.5.2(@types/node@24.12.4) - '@inquirer/type': 4.0.7(@types/node@24.12.4) + '@inquirer/prompts': 8.5.2(@types/node@24.13.2) + '@inquirer/type': 4.0.7(@types/node@24.13.2) listr2: 10.2.1 transitivePeerDependencies: - '@types/node' @@ -11573,9 +11585,9 @@ snapshots: dependencies: undici-types: 6.21.0 - '@types/node@24.12.4': + '@types/node@24.13.2': dependencies: - undici-types: 7.16.0 + undici-types: 7.18.2 '@types/npm-package-arg@6.1.4': {} @@ -11937,9 +11949,9 @@ snapshots: lodash: 4.18.1 minimatch: 7.4.9 - '@vitejs/plugin-basic-ssl@2.3.0(vite@7.3.5(@types/node@24.12.4)(jiti@2.7.0)(less@4.6.4)(sass@1.100.0)(terser@5.48.0)(tsx@4.22.4)(yaml@2.9.0))': + '@vitejs/plugin-basic-ssl@2.3.0(vite@7.3.5(@types/node@24.13.2)(jiti@2.7.0)(less@4.6.4)(sass@1.100.0)(terser@5.48.0)(tsx@4.22.4)(yaml@2.9.0))': dependencies: - vite: 7.3.5(@types/node@24.12.4)(jiti@2.7.0)(less@4.6.4)(sass@1.100.0)(terser@5.48.0)(tsx@4.22.4)(yaml@2.9.0) + vite: 7.3.5(@types/node@24.13.2)(jiti@2.7.0)(less@4.6.4)(sass@1.100.0)(terser@5.48.0)(tsx@4.22.4)(yaml@2.9.0) '@vitest/coverage-v8@4.1.8(vitest@4.1.8)': dependencies: @@ -11953,7 +11965,7 @@ snapshots: obug: 2.1.2 std-env: 4.1.0 tinyrainbow: 3.1.0 - vitest: 4.1.8(@opentelemetry/api@1.9.1)(@types/node@24.12.4)(@vitest/coverage-v8@4.1.8)(jiti@2.7.0)(jsdom@29.1.1)(less@4.6.4)(sass@1.100.0)(terser@5.48.0)(tsx@4.22.4)(yaml@2.9.0) + vitest: 4.1.8(@opentelemetry/api@1.9.1)(@types/node@24.13.2)(@vitest/coverage-v8@4.1.8)(jiti@2.7.0)(jsdom@29.1.1)(less@4.6.4)(sass@1.100.0)(terser@5.48.0)(tsx@4.22.4)(yaml@2.9.0) '@vitest/expect@4.1.8': dependencies: @@ -11964,13 +11976,13 @@ snapshots: chai: 6.2.2 tinyrainbow: 3.1.0 - '@vitest/mocker@4.1.8(vite@7.3.5(@types/node@24.12.4)(jiti@2.7.0)(less@4.6.4)(sass@1.100.0)(terser@5.48.0)(tsx@4.22.4)(yaml@2.9.0))': + '@vitest/mocker@4.1.8(vite@7.3.5(@types/node@24.13.2)(jiti@2.7.0)(less@4.6.4)(sass@1.100.0)(terser@5.48.0)(tsx@4.22.4)(yaml@2.9.0))': dependencies: '@vitest/spy': 4.1.8 estree-walker: 3.0.3 magic-string: 0.30.21 optionalDependencies: - vite: 7.3.5(@types/node@24.12.4)(jiti@2.7.0)(less@4.6.4)(sass@1.100.0)(terser@5.48.0)(tsx@4.22.4)(yaml@2.9.0) + vite: 7.3.5(@types/node@24.13.2)(jiti@2.7.0)(less@4.6.4)(sass@1.100.0)(terser@5.48.0)(tsx@4.22.4)(yaml@2.9.0) '@vitest/pretty-format@4.1.8': dependencies: @@ -14536,6 +14548,8 @@ snapshots: jasmine-core@6.2.0: {} + jasmine-core@6.3.0: {} + jasmine-reporters@2.5.2: dependencies: '@xmldom/xmldom': 0.8.13 @@ -14551,6 +14565,12 @@ snapshots: glob: 13.0.6 jasmine-core: 6.2.0 + jasmine@6.3.0: + dependencies: + '@jasminejs/reporters': 1.0.0 + glob: 13.0.6 + jasmine-core: 6.3.0 + jest-worker@27.5.1: dependencies: '@types/node': 22.19.20 @@ -15130,7 +15150,7 @@ snapshots: neo-async@2.6.2: {} - ng-packagr@22.1.0-next.1(@angular/compiler-cli@22.1.0-next.0(@angular/compiler@22.1.0-next.0)(typescript@6.0.3))(tslib@2.8.1)(typescript@6.0.3): + ng-packagr@22.1.0-next.2(@angular/compiler-cli@22.1.0-next.0(@angular/compiler@22.1.0-next.0)(typescript@6.0.3))(tslib@2.8.1)(typescript@6.0.3): dependencies: '@ampproject/remapping': 2.3.0 '@angular/compiler-cli': 22.1.0-next.0(@angular/compiler@22.1.0-next.0)(typescript@6.0.3) @@ -16124,6 +16144,8 @@ snapshots: semver@7.8.1: {} + semver@7.8.4: {} + send@0.19.2: dependencies: debug: 2.6.9 @@ -16851,7 +16873,7 @@ snapshots: undici-types@6.21.0: {} - undici-types@7.16.0: {} + undici-types@7.18.2: {} undici@6.26.0: {} @@ -17005,7 +17027,7 @@ snapshots: core-util-is: 1.0.2 extsprintf: 1.3.0 - vite@7.3.5(@types/node@24.12.4)(jiti@2.7.0)(less@4.6.4)(sass@1.100.0)(terser@5.48.0)(tsx@4.22.4)(yaml@2.9.0): + vite@7.3.5(@types/node@24.13.2)(jiti@2.7.0)(less@4.6.4)(sass@1.100.0)(terser@5.48.0)(tsx@4.22.4)(yaml@2.9.0): dependencies: esbuild: 0.27.7 fdir: 6.5.0(picomatch@4.0.4) @@ -17014,7 +17036,7 @@ snapshots: rollup: 4.61.0 tinyglobby: 0.2.17 optionalDependencies: - '@types/node': 24.12.4 + '@types/node': 24.13.2 fsevents: 2.3.3 jiti: 2.7.0 less: 4.6.4 @@ -17023,10 +17045,10 @@ snapshots: tsx: 4.22.4 yaml: 2.9.0 - vitest@4.1.8(@opentelemetry/api@1.9.1)(@types/node@24.12.4)(@vitest/coverage-v8@4.1.8)(jiti@2.7.0)(jsdom@29.1.1)(less@4.6.4)(sass@1.100.0)(terser@5.48.0)(tsx@4.22.4)(yaml@2.9.0): + vitest@4.1.8(@opentelemetry/api@1.9.1)(@types/node@24.13.2)(@vitest/coverage-v8@4.1.8)(jiti@2.7.0)(jsdom@29.1.1)(less@4.6.4)(sass@1.100.0)(terser@5.48.0)(tsx@4.22.4)(yaml@2.9.0): dependencies: '@vitest/expect': 4.1.8 - '@vitest/mocker': 4.1.8(vite@7.3.5(@types/node@24.12.4)(jiti@2.7.0)(less@4.6.4)(sass@1.100.0)(terser@5.48.0)(tsx@4.22.4)(yaml@2.9.0)) + '@vitest/mocker': 4.1.8(vite@7.3.5(@types/node@24.13.2)(jiti@2.7.0)(less@4.6.4)(sass@1.100.0)(terser@5.48.0)(tsx@4.22.4)(yaml@2.9.0)) '@vitest/pretty-format': 4.1.8 '@vitest/runner': 4.1.8 '@vitest/snapshot': 4.1.8 @@ -17043,11 +17065,11 @@ snapshots: tinyexec: 1.2.4 tinyglobby: 0.2.17 tinyrainbow: 3.1.0 - vite: 7.3.5(@types/node@24.12.4)(jiti@2.7.0)(less@4.6.4)(sass@1.100.0)(terser@5.48.0)(tsx@4.22.4)(yaml@2.9.0) + vite: 7.3.5(@types/node@24.13.2)(jiti@2.7.0)(less@4.6.4)(sass@1.100.0)(terser@5.48.0)(tsx@4.22.4)(yaml@2.9.0) why-is-node-running: 2.3.0 optionalDependencies: '@opentelemetry/api': 1.9.1 - '@types/node': 24.12.4 + '@types/node': 24.13.2 '@vitest/coverage-v8': 4.1.8(vitest@4.1.8) jsdom: 29.1.1 transitivePeerDependencies: diff --git a/tests/e2e/ng-snapshot/package.json b/tests/e2e/ng-snapshot/package.json index 897457a6eefa..ce9bad7829f6 100644 --- a/tests/e2e/ng-snapshot/package.json +++ b/tests/e2e/ng-snapshot/package.json @@ -2,21 +2,21 @@ "description": "snapshot versions of Angular for e2e testing", "private": true, "dependencies": { - "@angular/animations": "github:angular/animations-builds#9d3d315860f65e40f0e514da755199d4a792c4eb", - "@angular/cdk": "github:angular/cdk-builds#58e2053cad359db28eba76240f6557dcf94be7d1", - "@angular/common": "github:angular/common-builds#be537ed30640e631054ce06c6bfdd429b6adef2a", - "@angular/compiler": "github:angular/compiler-builds#282e1c5ee3c9c7b80c4875c4599a876f88d329d6", - "@angular/compiler-cli": "github:angular/compiler-cli-builds#a3a4b6b15e14b25d277eb6aa2cee57d9e9f03e34", - "@angular/core": "github:angular/core-builds#3d52c13033170016a5993f426461d3072fb30a85", - "@angular/forms": "github:angular/forms-builds#05a284aa0e0a3a41a148f440e2ce07154a9475e0", - "@angular/language-service": "github:angular/language-service-builds#61a48036df076a4e0dcf8c2443f26e588fbf87ea", - "@angular/localize": "github:angular/localize-builds#edaed6ab8ca7a30d33e431e870c281a6750797a1", - "@angular/material": "github:angular/material-builds#5528675fa28eb4796cd8e39e954809f04c06d457", - "@angular/material-moment-adapter": "github:angular/material-moment-adapter-builds#5b9de0d562321e4efafe3d4b646a9846966068c7", - "@angular/platform-browser": "github:angular/platform-browser-builds#b7253e10d58dd467c6a8c2d76b9102d785f5ba8e", - "@angular/platform-browser-dynamic": "github:angular/platform-browser-dynamic-builds#65960a68257c6dfb9ff874e1d05bae9660d91b82", - "@angular/platform-server": "github:angular/platform-server-builds#e3fe333b0ba105786bf7d33fff50dd19fc6c4fd3", - "@angular/router": "github:angular/router-builds#67a575caa48cfce117881991ea5553f261d47b70", - "@angular/service-worker": "github:angular/service-worker-builds#8a08a9bdbfd3b4810bdb1f9fbfe51df6f3ab98cc" + "@angular/animations": "github:angular/animations-builds#f1a1ee8c782b879df1f346daf0c1c489dc6754c7", + "@angular/cdk": "github:angular/cdk-builds#0d5389dc4437bc9d9e5ceffa3be6610454f8f46b", + "@angular/common": "github:angular/common-builds#ead9c0df2d447397c75cff61ebee8ac46118fe04", + "@angular/compiler": "github:angular/compiler-builds#e0d7a09079b23ef2d3e15fe1e4f235fec12ecb3a", + "@angular/compiler-cli": "github:angular/compiler-cli-builds#199e266910ed6d3f1eb6da50bb46be836afb277f", + "@angular/core": "github:angular/core-builds#0e95bdf40db38f3389763a2d7578cd1ba139204c", + "@angular/forms": "github:angular/forms-builds#7c9da8a94ea07d58f6ab737b578e8c3287b1a77b", + "@angular/language-service": "github:angular/language-service-builds#5134fc1cde9fcb7243557b4d10f19c3bdfdc39d4", + "@angular/localize": "github:angular/localize-builds#ce5f3157dbf7559e60670bcb16e4ad5833df27cd", + "@angular/material": "github:angular/material-builds#d0d36e575c65f01b5860c75de27c786b1fa24345", + "@angular/material-moment-adapter": "github:angular/material-moment-adapter-builds#e556974205a895e999f27bc59481156d9c84417c", + "@angular/platform-browser": "github:angular/platform-browser-builds#1a15323bce1b483d6a85d740bbdd030d5d93246c", + "@angular/platform-browser-dynamic": "github:angular/platform-browser-dynamic-builds#a5fb144747c92312d2de659c7c385eec78953a84", + "@angular/platform-server": "github:angular/platform-server-builds#1383fcf921b2eb6f3687e7f2f8371bc193daaa55", + "@angular/router": "github:angular/router-builds#386b0b500207c76c8bd09a265f723ff0bb327845", + "@angular/service-worker": "github:angular/service-worker-builds#38a3ac76fb6cf87f7fdf1c15ecce8353b5e9811e" } } From 3ce6e5fc3b4f4b5fb6ac99cc82023bf01894d14c Mon Sep 17 00:00:00 2001 From: Charles Lyding <19598772+clydin@users.noreply.github.com> Date: Mon, 15 Jun 2026 10:05:41 -0400 Subject: [PATCH 045/787] perf(@angular/cli): implement semaphore backpressure throttling in PackageManager Execute package manager subprocess invocations using a semaphore-based backpressure throttle. When callers perform concurrent registry lookups (such as running Promise.all over candidate update packages), this prevents unbounded child subprocess spawning. Clamping active concurrent CLI commands to a fixed limit protects the operating system against process table exhaustion, V8 heap saturation, and upstream registry rate-limiting while maintaining fast execution. --- .../src/package-managers/package-manager.ts | 88 ++++++++++++------- 1 file changed, 57 insertions(+), 31 deletions(-) diff --git a/packages/angular/cli/src/package-managers/package-manager.ts b/packages/angular/cli/src/package-managers/package-manager.ts index a5ebfad62553..afa2aa6b4c57 100644 --- a/packages/angular/cli/src/package-managers/package-manager.ts +++ b/packages/angular/cli/src/package-managers/package-manager.ts @@ -93,6 +93,9 @@ export class PackageManager { readonly #initializationError?: Error; #dependencyCache: Map | null = null; #version: string | undefined; + #activeTasks = 0; + readonly #pendingTasks: (() => void)[] = []; + readonly #maxConcurrent = 5; /** * Creates a new `PackageManager` instance. @@ -159,49 +162,72 @@ export class PackageManager { * @param options Options for the child process. * @returns A promise that resolves with the standard output and standard error of the command. */ + async #runWithThrottle(action: () => Promise): Promise { + if (this.#activeTasks >= this.#maxConcurrent) { + await new Promise((resolve) => { + this.#pendingTasks.push(resolve); + }); + } else { + this.#activeTasks++; + } + + try { + return await action(); + } finally { + const next = this.#pendingTasks.shift(); + if (next) { + next(); + } else { + this.#activeTasks--; + } + } + } + async #run( args: readonly string[], options: { timeout?: number; registry?: string; cwd?: string } = {}, ): Promise<{ stdout: string; stderr: string }> { - this.ensureInstalled(); + return this.#runWithThrottle(async () => { + this.ensureInstalled(); + + const { registry, cwd, ...runOptions } = options; + const finalArgs = [...args]; + let finalEnv: Record | undefined; + + if (registry) { + const registryOptions = this.descriptor.getRegistryOptions?.(registry); + if (!registryOptions) { + throw new Error( + `The configured package manager, '${this.descriptor.binary}', does not support a custom registry.`, + ); + } - const { registry, cwd, ...runOptions } = options; - const finalArgs = [...args]; - let finalEnv: Record | undefined; + if (registryOptions.args) { + finalArgs.push(...registryOptions.args); + } + if (registryOptions.env) { + finalEnv = registryOptions.env; + } + } - if (registry) { - const registryOptions = this.descriptor.getRegistryOptions?.(registry); - if (!registryOptions) { - throw new Error( - `The configured package manager, '${this.descriptor.binary}', does not support a custom registry.`, + const executionDirectory = cwd ?? this.cwd; + if (this.options.dryRun) { + this.options.logger?.info( + `[DRY RUN] Would execute in [${executionDirectory}]: ${this.descriptor.binary} ${finalArgs.join(' ')}`, ); - } - if (registryOptions.args) { - finalArgs.push(...registryOptions.args); - } - if (registryOptions.env) { - finalEnv = registryOptions.env; + return { stdout: '', stderr: '' }; } - } - const executionDirectory = cwd ?? this.cwd; - if (this.options.dryRun) { - this.options.logger?.info( - `[DRY RUN] Would execute in [${executionDirectory}]: ${this.descriptor.binary} ${finalArgs.join(' ')}`, - ); + const commandResult = await this.host.runCommand(this.descriptor.binary, finalArgs, { + ...runOptions, + cwd: executionDirectory, + stdio: 'pipe', + env: finalEnv, + }); - return { stdout: '', stderr: '' }; - } - - const commandResult = await this.host.runCommand(this.descriptor.binary, finalArgs, { - ...runOptions, - cwd: executionDirectory, - stdio: 'pipe', - env: finalEnv, + return { stdout: commandResult.stdout.trim(), stderr: commandResult.stderr.trim() }; }); - - return { stdout: commandResult.stdout.trim(), stderr: commandResult.stderr.trim() }; } /** From a527d02206b484369b5560f65151aa2b71dc8621 Mon Sep 17 00:00:00 2001 From: Alan Agius <17563226+alan-agius4@users.noreply.github.com> Date: Tue, 16 Jun 2026 09:04:45 +0000 Subject: [PATCH 046/787] refactor: move eslint disable comment to top of file Fixes eslint update --- .../src/builders/browser/index.ts | 452 +++++++++--------- 1 file changed, 223 insertions(+), 229 deletions(-) diff --git a/packages/angular_devkit/build_angular/src/builders/browser/index.ts b/packages/angular_devkit/build_angular/src/builders/browser/index.ts index f78d9ecd2e8e..355c407192e5 100644 --- a/packages/angular_devkit/build_angular/src/builders/browser/index.ts +++ b/packages/angular_devkit/build_angular/src/builders/browser/index.ts @@ -6,6 +6,8 @@ * found in the LICENSE file at https://angular.dev/license */ +/* eslint-disable max-lines-per-function */ + import { BudgetCalculatorResult, FileInfo, @@ -113,7 +115,6 @@ async function initialize( /** * @experimental Direct usage of this function is considered experimental. */ -// eslint-disable-next-line max-lines-per-function export function buildWebpackBrowser( options: BrowserBuilderSchema, context: BuilderContext, @@ -165,267 +166,260 @@ export function buildWebpackBrowser( cacheOptions: normalizeCacheOptions(projectMetadata, context.workspaceRoot), }; }), - switchMap( - // eslint-disable-next-line max-lines-per-function - ({ config, projectRoot, projectSourceRoot, i18n, cacheOptions }) => { - const normalizedOptimization = normalizeOptimization(options.optimization); - - return runWebpack(config, context, { - webpackFactory: require('webpack') as typeof webpack, - logging: - transforms.logging || - ((stats, config) => { - if (options.verbose && config.stats !== false) { - const statsOptions = config.stats === true ? undefined : config.stats; - context.logger.info(stats.toString(statsOptions)); + switchMap(({ config, projectRoot, projectSourceRoot, i18n, cacheOptions }) => { + const normalizedOptimization = normalizeOptimization(options.optimization); + + return runWebpack(config, context, { + webpackFactory: require('webpack') as typeof webpack, + logging: + transforms.logging || + ((stats, config) => { + if (options.verbose && config.stats !== false) { + const statsOptions = config.stats === true ? undefined : config.stats; + context.logger.info(stats.toString(statsOptions)); + } + }), + }).pipe( + concatMap( + async ( + buildEvent, + ): Promise<{ output: BuilderOutput; webpackStats: StatsCompilation }> => { + const spinner = new Spinner(); + spinner.enabled = options.progress !== false; + + const { success, emittedFiles = [], outputPath: webpackOutputPath } = buildEvent; + const webpackRawStats = buildEvent.webpackStats; + if (!webpackRawStats) { + throw new Error('Webpack stats build result is required.'); + } + + // Fix incorrectly set `initial` value on chunks. + const extraEntryPoints = [ + ...normalizeExtraEntryPoints(options.styles || [], 'styles'), + ...normalizeExtraEntryPoints(options.scripts || [], 'scripts'), + ]; + + const webpackStats = { + ...webpackRawStats, + chunks: markAsyncChunksNonInitial(webpackRawStats, extraEntryPoints), + }; + + if (!success) { + // If using bundle downleveling then there is only one build + // If it fails show any diagnostic messages and bail + if (statsHasWarnings(webpackStats)) { + context.logger.warn(statsWarningsToString(webpackStats, { colors: true })); } - }), - }).pipe( - concatMap( - // eslint-disable-next-line max-lines-per-function - async ( - buildEvent, - ): Promise<{ output: BuilderOutput; webpackStats: StatsCompilation }> => { - const spinner = new Spinner(); - spinner.enabled = options.progress !== false; - - const { success, emittedFiles = [], outputPath: webpackOutputPath } = buildEvent; - const webpackRawStats = buildEvent.webpackStats; - if (!webpackRawStats) { - throw new Error('Webpack stats build result is required.'); + if (statsHasErrors(webpackStats)) { + context.logger.error(statsErrorsToString(webpackStats, { colors: true })); } - // Fix incorrectly set `initial` value on chunks. - const extraEntryPoints = [ - ...normalizeExtraEntryPoints(options.styles || [], 'styles'), - ...normalizeExtraEntryPoints(options.scripts || [], 'scripts'), - ]; - - const webpackStats = { - ...webpackRawStats, - chunks: markAsyncChunksNonInitial(webpackRawStats, extraEntryPoints), + return { + webpackStats: webpackRawStats, + output: { success: false }, }; - - if (!success) { - // If using bundle downleveling then there is only one build - // If it fails show any diagnostic messages and bail - if (statsHasWarnings(webpackStats)) { - context.logger.warn(statsWarningsToString(webpackStats, { colors: true })); + } else { + outputPaths = ensureOutputPaths(baseOutputPath, i18n); + + const scriptsEntryPointName = normalizeExtraEntryPoints( + options.scripts || [], + 'scripts', + ).map((x) => x.bundleName); + + if (i18n.shouldInline) { + const success = await i18nInlineEmittedFiles( + context, + emittedFiles, + i18n, + baseOutputPath, + Array.from(outputPaths.values()), + scriptsEntryPointName, + webpackOutputPath, + options.i18nMissingTranslation, + ); + if (!success) { + return { + webpackStats: webpackRawStats, + output: { success: false }, + }; } - if (statsHasErrors(webpackStats)) { - context.logger.error(statsErrorsToString(webpackStats, { colors: true })); + } + + // Check for budget errors and display them to the user. + const budgets = options.budgets; + let budgetFailures: BudgetCalculatorResult[] | undefined; + if (budgets?.length) { + budgetFailures = [...checkBudgets(budgets, webpackStats)]; + for (const { severity, message } of budgetFailures) { + switch (severity) { + case ThresholdSeverity.Warning: + webpackStats.warnings?.push({ message }); + break; + case ThresholdSeverity.Error: + webpackStats.errors?.push({ message }); + break; + default: + assertNever(severity); + } } + } + + const buildSuccess = success && !statsHasErrors(webpackStats); + if (buildSuccess) { + // Copy assets + if (!options.watch && options.assets?.length) { + spinner.start('Copying assets...'); + try { + await copyAssets( + normalizeAssetPatterns( + options.assets, + context.workspaceRoot, + projectRoot, + projectSourceRoot, + ), + Array.from(outputPaths.values()), + context.workspaceRoot, + ); + spinner.succeed('Copying assets complete.'); + } catch (err) { + spinner.fail('Copying of assets failed.'); + assertIsError(err); - return { - webpackStats: webpackRawStats, - output: { success: false }, - }; - } else { - outputPaths = ensureOutputPaths(baseOutputPath, i18n); - - const scriptsEntryPointName = normalizeExtraEntryPoints( - options.scripts || [], - 'scripts', - ).map((x) => x.bundleName); - - if (i18n.shouldInline) { - const success = await i18nInlineEmittedFiles( - context, - emittedFiles, - i18n, - baseOutputPath, - Array.from(outputPaths.values()), - scriptsEntryPointName, - webpackOutputPath, - options.i18nMissingTranslation, - ); - if (!success) { return { + output: { + success: false, + error: 'Unable to copy assets: ' + err.message, + }, webpackStats: webpackRawStats, - output: { success: false }, }; } } - // Check for budget errors and display them to the user. - const budgets = options.budgets; - let budgetFailures: BudgetCalculatorResult[] | undefined; - if (budgets?.length) { - budgetFailures = [...checkBudgets(budgets, webpackStats)]; - for (const { severity, message } of budgetFailures) { - switch (severity) { - case ThresholdSeverity.Warning: - webpackStats.warnings?.push({ message }); - break; - case ThresholdSeverity.Error: - webpackStats.errors?.push({ message }); - break; - default: - assertNever(severity); - } - } - } - - const buildSuccess = success && !statsHasErrors(webpackStats); - if (buildSuccess) { - // Copy assets - if (!options.watch && options.assets?.length) { - spinner.start('Copying assets...'); + if (options.index) { + spinner.start('Generating index html...'); + + const entrypoints = generateEntryPoints({ + scripts: options.scripts ?? [], + styles: options.styles ?? [], + }); + + const indexHtmlGenerator = new IndexHtmlGenerator({ + cache: cacheOptions, + indexPath: path.join(context.workspaceRoot, getIndexInputFile(options.index)), + entrypoints, + deployUrl: options.deployUrl, + sri: options.subresourceIntegrity, + optimization: normalizedOptimization, + crossOrigin: options.crossOrigin, + postTransform: transforms.indexHtml, + imageDomains: Array.from(imageDomains), + }); + + let hasErrors = false; + for (const [locale, outputPath] of outputPaths.entries()) { try { - await copyAssets( - normalizeAssetPatterns( - options.assets, - context.workspaceRoot, - projectRoot, - projectSourceRoot, - ), - Array.from(outputPaths.values()), - context.workspaceRoot, - ); - spinner.succeed('Copying assets complete.'); - } catch (err) { - spinner.fail('Copying of assets failed.'); - assertIsError(err); + const { + csrContent: content, + warnings, + errors, + } = await indexHtmlGenerator.process({ + baseHref: getLocaleBaseHref(i18n, locale) ?? options.baseHref, + // i18nLocale is used when Ivy is disabled + lang: locale || undefined, + outputPath, + files: mapEmittedFilesToFileInfo(emittedFiles), + }); + + if (warnings.length || errors.length) { + spinner.stop(); + warnings.forEach((m) => context.logger.warn(m)); + errors.forEach((m) => { + context.logger.error(m); + hasErrors = true; + }); + spinner.start(); + } + + const indexOutput = path.join(outputPath, getIndexOutputFile(options.index)); + await fs.promises.mkdir(path.dirname(indexOutput), { recursive: true }); + await fs.promises.writeFile(indexOutput, content); + } catch (error) { + spinner.fail('Index html generation failed.'); + assertIsError(error); return { - output: { - success: false, - error: 'Unable to copy assets: ' + err.message, - }, webpackStats: webpackRawStats, + output: { success: false, error: error.message }, }; } } - if (options.index) { - spinner.start('Generating index html...'); - - const entrypoints = generateEntryPoints({ - scripts: options.scripts ?? [], - styles: options.styles ?? [], - }); - - const indexHtmlGenerator = new IndexHtmlGenerator({ - cache: cacheOptions, - indexPath: path.join(context.workspaceRoot, getIndexInputFile(options.index)), - entrypoints, - deployUrl: options.deployUrl, - sri: options.subresourceIntegrity, - optimization: normalizedOptimization, - crossOrigin: options.crossOrigin, - postTransform: transforms.indexHtml, - imageDomains: Array.from(imageDomains), - }); - - let hasErrors = false; - for (const [locale, outputPath] of outputPaths.entries()) { - try { - const { - csrContent: content, - warnings, - errors, - } = await indexHtmlGenerator.process({ - baseHref: getLocaleBaseHref(i18n, locale) ?? options.baseHref, - // i18nLocale is used when Ivy is disabled - lang: locale || undefined, - outputPath, - files: mapEmittedFilesToFileInfo(emittedFiles), - }); + if (hasErrors) { + spinner.fail('Index html generation failed.'); - if (warnings.length || errors.length) { - spinner.stop(); - warnings.forEach((m) => context.logger.warn(m)); - errors.forEach((m) => { - context.logger.error(m); - hasErrors = true; - }); - spinner.start(); - } - - const indexOutput = path.join( - outputPath, - getIndexOutputFile(options.index), - ); - await fs.promises.mkdir(path.dirname(indexOutput), { recursive: true }); - await fs.promises.writeFile(indexOutput, content); - } catch (error) { - spinner.fail('Index html generation failed.'); - assertIsError(error); - - return { - webpackStats: webpackRawStats, - output: { success: false, error: error.message }, - }; - } - } + return { + webpackStats: webpackRawStats, + output: { success: false }, + }; + } else { + spinner.succeed('Index html generation complete.'); + } + } - if (hasErrors) { - spinner.fail('Index html generation failed.'); + if (options.serviceWorker) { + spinner.start('Generating service worker...'); + for (const [locale, outputPath] of outputPaths.entries()) { + try { + await augmentAppWithServiceWorker( + projectRoot, + context.workspaceRoot, + outputPath, + getLocaleBaseHref(i18n, locale) ?? options.baseHref ?? '/', + options.ngswConfigPath, + ); + } catch (error) { + spinner.fail('Service worker generation failed.'); + assertIsError(error); return { webpackStats: webpackRawStats, - output: { success: false }, + output: { success: false, error: error.message }, }; - } else { - spinner.succeed('Index html generation complete.'); } } - if (options.serviceWorker) { - spinner.start('Generating service worker...'); - for (const [locale, outputPath] of outputPaths.entries()) { - try { - await augmentAppWithServiceWorker( - projectRoot, - context.workspaceRoot, - outputPath, - getLocaleBaseHref(i18n, locale) ?? options.baseHref ?? '/', - options.ngswConfigPath, - ); - } catch (error) { - spinner.fail('Service worker generation failed.'); - assertIsError(error); - - return { - webpackStats: webpackRawStats, - output: { success: false, error: error.message }, - }; - } - } - - spinner.succeed('Service worker generation complete.'); - } + spinner.succeed('Service worker generation complete.'); } + } - webpackStatsLogger(context.logger, webpackStats, config, budgetFailures); + webpackStatsLogger(context.logger, webpackStats, config, budgetFailures); - return { - webpackStats: webpackRawStats, - output: { success: buildSuccess }, - }; - } - }, - ), - map( - ({ output: event, webpackStats }) => - ({ - ...event, - stats: generateBuildEventStats(webpackStats, options), - baseOutputPath, - outputs: (outputPaths && - [...outputPaths.entries()].map(([locale, path]) => ({ - locale, - path, - baseHref: getLocaleBaseHref(i18n, locale) ?? options.baseHref, - }))) || { - path: baseOutputPath, - baseHref: options.baseHref, - }, - }) as BrowserBuilderOutput, - ), - ); - }, - ), + return { + webpackStats: webpackRawStats, + output: { success: buildSuccess }, + }; + } + }, + ), + map( + ({ output: event, webpackStats }) => + ({ + ...event, + stats: generateBuildEventStats(webpackStats, options), + baseOutputPath, + outputs: (outputPaths && + [...outputPaths.entries()].map(([locale, path]) => ({ + locale, + path, + baseHref: getLocaleBaseHref(i18n, locale) ?? options.baseHref, + }))) || { + path: baseOutputPath, + baseHref: options.baseHref, + }, + }) as BrowserBuilderOutput, + ), + ); + }), ); function getLocaleBaseHref(i18n: I18nOptions, locale: string): string | undefined { From af76464481ec465d33131327c3c3a61d00704d07 Mon Sep 17 00:00:00 2001 From: Angular Robot Date: Tue, 16 Jun 2026 09:13:34 +0000 Subject: [PATCH 047/787] build: update all non-major dependencies See associated pull request for more information. --- modules/testing/builder/package.json | 4 +- package.json | 24 +- packages/angular/build/package.json | 20 +- packages/angular/cli/package.json | 6 +- .../angular_devkit/build_angular/package.json | 18 +- .../angular_devkit/build_webpack/package.json | 2 +- pnpm-lock.yaml | 2046 +++++++++++------ 7 files changed, 1362 insertions(+), 758 deletions(-) diff --git a/modules/testing/builder/package.json b/modules/testing/builder/package.json index 1aea49b4c16c..2906aeda46d0 100644 --- a/modules/testing/builder/package.json +++ b/modules/testing/builder/package.json @@ -4,12 +4,12 @@ "@angular-devkit/build-angular": "workspace:*", "@angular-devkit/core": "workspace:*", "@angular/ssr": "workspace:*", - "@vitest/coverage-v8": "4.1.8", + "@vitest/coverage-v8": "4.1.9", "browser-sync": "3.0.4", "istanbul-lib-instrument": "6.0.3", "jsdom": "29.1.1", "ng-packagr": "22.1.0-next.2", "rxjs": "7.8.2", - "vitest": "4.1.8" + "vitest": "4.1.9" } } diff --git a/package.json b/package.json index f3978e7be6fb..a60331058036 100644 --- a/package.json +++ b/package.json @@ -70,7 +70,7 @@ "@rollup/plugin-commonjs": "^29.0.0", "@rollup/plugin-json": "^6.1.0", "@rollup/plugin-node-resolve": "16.0.3", - "@rollup/wasm-node": "4.61.0", + "@rollup/wasm-node": "4.62.0", "@stylistic/eslint-plugin": "^5.0.0", "@tony.ganchev/eslint-plugin-header": "~3.4.0", "@types/babel__core": "7.20.5", @@ -95,23 +95,23 @@ "@types/yargs": "^17.0.20", "@types/yargs-parser": "^21.0.0", "@types/yarnpkg__lockfile": "^1.1.5", - "@typescript-eslint/eslint-plugin": "8.60.1", - "@typescript-eslint/parser": "8.60.1", + "@typescript-eslint/eslint-plugin": "8.61.0", + "@typescript-eslint/parser": "8.61.0", "ajv": "8.20.0", "buffer": "6.0.3", - "esbuild": "0.28.0", - "esbuild-wasm": "0.28.0", - "eslint": "10.4.1", + "esbuild": "0.28.1", + "esbuild-wasm": "0.28.1", + "eslint": "10.5.0", "eslint-config-prettier": "10.1.8", "eslint-plugin-import": "2.32.0", "express": "5.2.1", "fast-glob": "3.3.3", "globals": "17.6.0", "http-proxy": "^1.18.1", - "http-proxy-middleware": "4.0.0", + "http-proxy-middleware": "4.1.1", "husky": "9.1.7", - "jasmine": "~6.2.0", - "jasmine-core": "~6.2.0", + "jasmine": "~6.3.0", + "jasmine-core": "~6.3.0", "jasmine-reporters": "^2.5.2", "jasmine-spec-reporter": "~7.0.0", "karma": "~6.4.0", @@ -125,14 +125,14 @@ "prettier": "^3.0.0", "puppeteer": "25.1.0", "quicktype-core": "23.2.6", - "rollup": "4.61.0", + "rollup": "4.62.0", "rollup-license-plugin": "~3.2.0", "rollup-plugin-dts": "6.4.1", "rollup-plugin-sourcemaps2": "0.5.7", - "semver": "7.8.1", + "semver": "7.8.4", "source-map-support": "0.5.21", "tslib": "2.8.1", - "undici": "8.3.0", + "undici": "8.4.1", "unenv": "^1.10.0", "verdaccio": "6.7.2", "verdaccio-auth-memory": "^13.0.0", diff --git a/packages/angular/build/package.json b/packages/angular/build/package.json index acf0b30b84ba..1690da4c60c7 100644 --- a/packages/angular/build/package.json +++ b/packages/angular/build/package.json @@ -27,22 +27,22 @@ "@vitejs/plugin-basic-ssl": "2.3.0", "beasties": "0.4.2", "browserslist": "^4.26.0", - "esbuild": "0.28.0", - "https-proxy-agent": "9.0.0", + "esbuild": "0.28.1", + "https-proxy-agent": "9.1.0", "jsonc-parser": "3.3.1", "listr2": "10.2.1", "magic-string": "0.30.21", "mrmime": "2.0.1", "parse5-html-rewriting-stream": "8.0.1", "picomatch": "4.0.4", - "piscina": "5.1.4", - "rollup": "4.61.0", - "sass": "1.100.0", - "semver": "7.8.1", + "piscina": "5.2.0", + "rollup": "4.62.0", + "sass": "1.101.0", + "semver": "7.8.4", "source-map-support": "0.5.21", "tinyglobby": "0.2.17", "vite": "7.3.5", - "watchpack": "2.5.1" + "watchpack": "2.5.2" }, "optionalDependencies": { "lmdb": "3.5.5" @@ -52,12 +52,12 @@ "@angular/ssr": "workspace:*", "istanbul-lib-instrument": "6.0.3", "jsdom": "29.1.1", - "less": "4.6.4", + "less": "4.6.6", "ng-packagr": "22.1.0-next.2", "postcss": "8.5.15", - "rolldown": "1.0.3", + "rolldown": "1.1.1", "rxjs": "7.8.2", - "vitest": "4.1.8" + "vitest": "4.1.9" }, "peerDependencies": { "@angular/compiler": "0.0.0-ANGULAR-FW-PEER-DEP", diff --git a/packages/angular/cli/package.json b/packages/angular/cli/package.json index 4488b768601b..9a22e424e4b5 100644 --- a/packages/angular/cli/package.json +++ b/packages/angular/cli/package.json @@ -20,14 +20,14 @@ "@modelcontextprotocol/sdk": "1.29.0", "@schematics/angular": "workspace:0.0.0-PLACEHOLDER", "@yarnpkg/lockfile": "1.1.0", - "algoliasearch": "5.53.0", + "algoliasearch": "5.54.0", "ini": "7.0.0", "jsonc-parser": "3.3.1", "listr2": "10.2.1", "npm-package-arg": "14.0.0", - "pacote": "21.5.0", + "pacote": "21.5.1", "parse5-html-rewriting-stream": "8.0.1", - "semver": "7.8.1", + "semver": "7.8.4", "yargs": "18.0.0", "zod": "4.4.3" }, diff --git a/packages/angular_devkit/build_angular/package.json b/packages/angular_devkit/build_angular/package.json index a512ba1e5175..b832b1f642f4 100644 --- a/packages/angular_devkit/build_angular/package.json +++ b/packages/angular_devkit/build_angular/package.json @@ -28,12 +28,12 @@ "browserslist": "^4.26.0", "copy-webpack-plugin": "14.0.0", "css-loader": "7.1.4", - "esbuild-wasm": "0.28.0", - "http-proxy-middleware": "4.0.0", + "esbuild-wasm": "0.28.1", + "http-proxy-middleware": "4.1.1", "istanbul-lib-instrument": "6.0.3", "jsonc-parser": "3.3.1", "karma-source-map-support": "1.4.0", - "less": "4.6.4", + "less": "4.6.6", "less-loader": "13.0.0", "license-webpack-plugin": "4.0.2", "loader-utils": "3.3.1", @@ -41,14 +41,14 @@ "open": "11.0.0", "ora": "9.4.0", "picomatch": "4.0.4", - "piscina": "5.1.4", + "piscina": "5.2.0", "postcss": "8.5.15", "postcss-loader": "8.2.1", "resolve-url-loader": "5.0.0", "rxjs": "7.8.2", - "sass": "1.100.0", + "sass": "1.101.0", "sass-loader": "17.0.0", - "semver": "7.8.1", + "semver": "7.8.4", "source-map-loader": "5.0.0", "source-map-support": "0.5.21", "terser": "5.48.0", @@ -56,18 +56,18 @@ "tslib": "2.8.1", "webpack": "5.107.2", "webpack-dev-middleware": "8.0.3", - "webpack-dev-server": "5.2.4", + "webpack-dev-server": "5.2.5", "webpack-merge": "6.0.1", "webpack-subresource-integrity": "5.1.0" }, "optionalDependencies": { - "esbuild": "0.28.0" + "esbuild": "0.28.1" }, "devDependencies": { "@angular/ssr": "workspace:*", "browser-sync": "3.0.4", "ng-packagr": "22.1.0-next.2", - "undici": "8.3.0" + "undici": "8.4.1" }, "peerDependencies": { "@angular/compiler-cli": "0.0.0-ANGULAR-FW-PEER-DEP", diff --git a/packages/angular_devkit/build_webpack/package.json b/packages/angular_devkit/build_webpack/package.json index 64f03929b502..65a53accdaa5 100644 --- a/packages/angular_devkit/build_webpack/package.json +++ b/packages/angular_devkit/build_webpack/package.json @@ -23,7 +23,7 @@ "@angular-devkit/core": "workspace:0.0.0-PLACEHOLDER", "@ngtools/webpack": "workspace:0.0.0-PLACEHOLDER", "webpack": "5.107.2", - "webpack-dev-server": "5.2.4" + "webpack-dev-server": "5.2.5" }, "peerDependencies": { "webpack": "^5.30.0", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 40f11de65b60..2a9699137447 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -66,7 +66,7 @@ importers: version: 22.1.0-next.0(@angular/core@22.1.0-next.0(@angular/compiler@22.1.0-next.0)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2) '@babel/core': specifier: 7.29.7 - version: 7.29.7 + version: 7.29.7(supports-color@10.2.2) '@bazel/bazelisk': specifier: 1.28.1 version: 1.28.1 @@ -78,34 +78,34 @@ importers: version: 0.28.0 '@eslint/compat': specifier: 2.1.0 - version: 2.1.0(eslint@10.4.1(jiti@2.7.0)) + version: 2.1.0(eslint@10.5.0(jiti@2.7.0)) '@eslint/eslintrc': specifier: 3.3.5 - version: 3.3.5 + version: 3.3.5(supports-color@10.2.2) '@eslint/js': specifier: 10.0.1 - version: 10.0.1(eslint@10.4.1(jiti@2.7.0)) + version: 10.0.1(eslint@10.5.0(jiti@2.7.0)) '@rollup/plugin-alias': specifier: ^6.0.0 - version: 6.0.0(rollup@4.61.0) + version: 6.0.0(rollup@4.62.0) '@rollup/plugin-commonjs': specifier: ^29.0.0 - version: 29.0.3(rollup@4.61.0) + version: 29.0.3(rollup@4.62.0) '@rollup/plugin-json': specifier: ^6.1.0 - version: 6.1.0(rollup@4.61.0) + version: 6.1.0(rollup@4.62.0) '@rollup/plugin-node-resolve': specifier: 16.0.3 - version: 16.0.3(rollup@4.61.0) + version: 16.0.3(rollup@4.62.0) '@rollup/wasm-node': - specifier: 4.61.0 - version: 4.61.0 + specifier: 4.62.0 + version: 4.62.0 '@stylistic/eslint-plugin': specifier: ^5.0.0 - version: 5.10.0(eslint@10.4.1(jiti@2.7.0)) + version: 5.10.0(eslint@10.5.0(jiti@2.7.0)) '@tony.ganchev/eslint-plugin-header': specifier: ~3.4.0 - version: 3.4.4(eslint@10.4.1(jiti@2.7.0)) + version: 3.4.4(eslint@10.5.0(jiti@2.7.0)) '@types/babel__core': specifier: 7.20.5 version: 7.20.5 @@ -138,7 +138,7 @@ importers: version: 3.0.8 '@types/loader-utils': specifier: ^3.0.0 - version: 3.0.0(esbuild@0.28.0) + version: 3.0.0(esbuild@0.28.1) '@types/lodash': specifier: ^4.17.0 version: 4.17.24 @@ -173,11 +173,11 @@ importers: specifier: ^1.1.5 version: 1.1.9 '@typescript-eslint/eslint-plugin': - specifier: 8.60.1 - version: 8.60.1(@typescript-eslint/parser@8.60.1(eslint@10.4.1(jiti@2.7.0))(typescript@6.0.3))(eslint@10.4.1(jiti@2.7.0))(typescript@6.0.3) + specifier: 8.61.0 + version: 8.61.0(@typescript-eslint/parser@8.61.0(eslint@10.5.0(jiti@2.7.0))(typescript@6.0.3))(eslint@10.5.0(jiti@2.7.0))(typescript@6.0.3) '@typescript-eslint/parser': - specifier: 8.60.1 - version: 8.60.1(eslint@10.4.1(jiti@2.7.0))(typescript@6.0.3) + specifier: 8.61.0 + version: 8.61.0(eslint@10.5.0(jiti@2.7.0))(typescript@6.0.3) ajv: specifier: 8.20.0 version: 8.20.0 @@ -185,23 +185,23 @@ importers: specifier: 6.0.3 version: 6.0.3 esbuild: - specifier: 0.28.0 - version: 0.28.0 + specifier: 0.28.1 + version: 0.28.1 esbuild-wasm: - specifier: 0.28.0 - version: 0.28.0 + specifier: 0.28.1 + version: 0.28.1 eslint: - specifier: 10.4.1 - version: 10.4.1(jiti@2.7.0) + specifier: 10.5.0 + version: 10.5.0(jiti@2.7.0) eslint-config-prettier: specifier: 10.1.8 - version: 10.1.8(eslint@10.4.1(jiti@2.7.0)) + version: 10.1.8(eslint@10.5.0(jiti@2.7.0)) eslint-plugin-import: specifier: 2.32.0 - version: 2.32.0(@typescript-eslint/parser@8.60.1(eslint@10.4.1(jiti@2.7.0))(typescript@6.0.3))(eslint@10.4.1(jiti@2.7.0)) + version: 2.32.0(@typescript-eslint/parser@8.61.0(eslint@10.5.0(jiti@2.7.0))(typescript@6.0.3))(eslint@10.5.0(jiti@2.7.0)) express: specifier: 5.2.1 - version: 5.2.1 + version: 5.2.1(supports-color@10.2.2) fast-glob: specifier: 3.3.3 version: 3.3.3 @@ -212,17 +212,17 @@ importers: specifier: ^1.18.1 version: 1.18.1 http-proxy-middleware: - specifier: 4.0.0 - version: 4.0.0 + specifier: 4.1.1 + version: 4.1.1 husky: specifier: 9.1.7 version: 9.1.7 jasmine: - specifier: ~6.2.0 - version: 6.2.0 + specifier: ~6.3.0 + version: 6.3.0 jasmine-core: - specifier: ~6.2.0 - version: 6.2.0 + specifier: ~6.3.0 + version: 6.3.0 jasmine-reporters: specifier: ^2.5.2 version: 2.5.2 @@ -231,19 +231,19 @@ importers: version: 7.0.0 karma: specifier: ~6.4.0 - version: 6.4.4(bufferutil@4.1.0)(utf-8-validate@6.0.6) + version: 6.4.4(bufferutil@4.1.0)(supports-color@10.2.2)(utf-8-validate@6.0.6) karma-chrome-launcher: specifier: ~3.2.0 version: 3.2.0 karma-coverage: specifier: ~2.2.0 - version: 2.2.1 + version: 2.2.1(supports-color@10.2.2) karma-jasmine: specifier: ~5.1.0 - version: 5.1.0(karma@6.4.4(bufferutil@4.1.0)(utf-8-validate@6.0.6)) + version: 5.1.0(karma@6.4.4(bufferutil@4.1.0)(supports-color@10.2.2)(utf-8-validate@6.0.6)) karma-jasmine-html-reporter: specifier: ~2.2.0 - version: 2.2.0(jasmine-core@6.2.0)(karma-jasmine@5.1.0(karma@6.4.4(bufferutil@4.1.0)(utf-8-validate@6.0.6)))(karma@6.4.4(bufferutil@4.1.0)(utf-8-validate@6.0.6)) + version: 2.2.0(jasmine-core@6.3.0)(karma-jasmine@5.1.0(karma@6.4.4(bufferutil@4.1.0)(supports-color@10.2.2)(utf-8-validate@6.0.6)))(karma@6.4.4(bufferutil@4.1.0)(supports-color@10.2.2)(utf-8-validate@6.0.6)) karma-source-map-support: specifier: 1.4.0 version: 1.4.0 @@ -263,20 +263,20 @@ importers: specifier: 23.2.6 version: 23.2.6(encoding@0.1.13) rollup: - specifier: 4.61.0 - version: 4.61.0 + specifier: 4.62.0 + version: 4.62.0 rollup-license-plugin: specifier: ~3.2.0 version: 3.2.1 rollup-plugin-dts: specifier: 6.4.1 - version: 6.4.1(rollup@4.61.0)(typescript@6.0.3) + version: 6.4.1(rollup@4.62.0)(typescript@6.0.3) rollup-plugin-sourcemaps2: specifier: 0.5.7 - version: 0.5.7(@types/node@22.19.20)(rollup@4.61.0) + version: 0.5.7(@types/node@22.19.20)(rollup@4.62.0) semver: - specifier: 7.8.1 - version: 7.8.1 + specifier: 7.8.4 + version: 7.8.4 source-map-support: specifier: 0.5.21 version: 0.5.21 @@ -284,17 +284,17 @@ importers: specifier: 2.8.1 version: 2.8.1 undici: - specifier: 8.3.0 - version: 8.3.0 + specifier: 8.4.1 + version: 8.4.1 unenv: specifier: ^1.10.0 version: 1.10.0 verdaccio: specifier: 6.7.2 - version: 6.7.2(encoding@0.1.13) + version: 6.7.2(encoding@0.1.13)(supports-color@10.2.2) verdaccio-auth-memory: specifier: ^13.0.0 - version: 13.0.2 + version: 13.0.2(supports-color@10.2.2) zone.js: specifier: ^0.16.0 version: 0.16.2 @@ -314,11 +314,11 @@ importers: specifier: workspace:* version: link:../../../packages/angular/ssr '@vitest/coverage-v8': - specifier: 4.1.8 - version: 4.1.8(vitest@4.1.8) + specifier: 4.1.9 + version: 4.1.9(vitest@4.1.9) browser-sync: specifier: 3.0.4 - version: 3.0.4(bufferutil@4.1.0)(utf-8-validate@6.0.6) + version: 3.0.4(bufferutil@4.1.0)(supports-color@10.2.2)(utf-8-validate@6.0.6) istanbul-lib-instrument: specifier: 6.0.3 version: 6.0.3 @@ -332,8 +332,8 @@ importers: specifier: 7.8.2 version: 7.8.2 vitest: - specifier: 4.1.8 - version: 4.1.8(@opentelemetry/api@1.9.1)(@types/node@24.13.2)(@vitest/coverage-v8@4.1.8)(jiti@2.7.0)(jsdom@29.1.1)(less@4.6.4)(sass@1.100.0)(terser@5.48.0)(tsx@4.22.4)(yaml@2.9.0) + specifier: 4.1.9 + version: 4.1.9(@opentelemetry/api@1.9.1)(@types/node@24.13.2)(@vitest/coverage-v8@4.1.9)(jiti@2.7.0)(jsdom@29.1.1)(less@4.6.6)(sass@1.101.0)(terser@5.48.0)(tsx@4.22.4)(yaml@2.9.0) packages/angular/build: dependencies: @@ -345,7 +345,7 @@ importers: version: link:../../angular_devkit/architect '@babel/core': specifier: 7.29.7 - version: 7.29.7 + version: 7.29.7(supports-color@10.2.2) '@babel/helper-annotate-as-pure': specifier: 7.29.7 version: 7.29.7 @@ -357,7 +357,7 @@ importers: version: 6.1.1(@types/node@24.13.2) '@vitejs/plugin-basic-ssl': specifier: 2.3.0 - version: 2.3.0(vite@7.3.5(@types/node@24.13.2)(jiti@2.7.0)(less@4.6.4)(sass@1.100.0)(terser@5.48.0)(tsx@4.22.4)(yaml@2.9.0)) + version: 2.3.0(vite@7.3.5(@types/node@24.13.2)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.48.0)(tsx@4.22.4)(yaml@2.9.0)) beasties: specifier: 0.4.2 version: 0.4.2 @@ -365,11 +365,11 @@ importers: specifier: ^4.26.0 version: 4.28.2 esbuild: - specifier: 0.28.0 - version: 0.28.0 + specifier: 0.28.1 + version: 0.28.1 https-proxy-agent: - specifier: 9.0.0 - version: 9.0.0 + specifier: 9.1.0 + version: 9.1.0 jsonc-parser: specifier: 3.3.1 version: 3.3.1 @@ -389,17 +389,17 @@ importers: specifier: 4.0.4 version: 4.0.4 piscina: - specifier: 5.1.4 - version: 5.1.4 + specifier: 5.2.0 + version: 5.2.0 rollup: - specifier: 4.61.0 - version: 4.61.0 + specifier: 4.62.0 + version: 4.62.0 sass: - specifier: 1.100.0 - version: 1.100.0 + specifier: 1.101.0 + version: 1.101.0 semver: - specifier: 7.8.1 - version: 7.8.1 + specifier: 7.8.4 + version: 7.8.4 source-map-support: specifier: 0.5.21 version: 0.5.21 @@ -408,10 +408,10 @@ importers: version: 0.2.17 vite: specifier: 7.3.5 - version: 7.3.5(@types/node@24.13.2)(jiti@2.7.0)(less@4.6.4)(sass@1.100.0)(terser@5.48.0)(tsx@4.22.4)(yaml@2.9.0) + version: 7.3.5(@types/node@24.13.2)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.48.0)(tsx@4.22.4)(yaml@2.9.0) watchpack: - specifier: 2.5.1 - version: 2.5.1 + specifier: 2.5.2 + version: 2.5.2 devDependencies: '@angular-devkit/core': specifier: workspace:* @@ -426,8 +426,8 @@ importers: specifier: 29.1.1 version: 29.1.1 less: - specifier: 4.6.4 - version: 4.6.4 + specifier: 4.6.6 + version: 4.6.6 ng-packagr: specifier: 22.1.0-next.2 version: 22.1.0-next.2(@angular/compiler-cli@22.1.0-next.0(@angular/compiler@22.1.0-next.0)(typescript@6.0.3))(tslib@2.8.1)(typescript@6.0.3) @@ -435,14 +435,14 @@ importers: specifier: 8.5.15 version: 8.5.15 rolldown: - specifier: 1.0.3 - version: 1.0.3 + specifier: 1.1.1 + version: 1.1.1 rxjs: specifier: 7.8.2 version: 7.8.2 vitest: - specifier: 4.1.8 - version: 4.1.8(@opentelemetry/api@1.9.1)(@types/node@24.13.2)(@vitest/coverage-v8@4.1.8)(jiti@2.7.0)(jsdom@29.1.1)(less@4.6.4)(sass@1.100.0)(terser@5.48.0)(tsx@4.22.4)(yaml@2.9.0) + specifier: 4.1.9 + version: 4.1.9(@opentelemetry/api@1.9.1)(@types/node@24.13.2)(@vitest/coverage-v8@4.1.9)(jiti@2.7.0)(jsdom@29.1.1)(less@4.6.6)(sass@1.101.0)(terser@5.48.0)(tsx@4.22.4)(yaml@2.9.0) optionalDependencies: lmdb: specifier: 3.5.5 @@ -475,8 +475,8 @@ importers: specifier: 1.1.0 version: 1.1.0 algoliasearch: - specifier: 5.53.0 - version: 5.53.0 + specifier: 5.54.0 + version: 5.54.0 ini: specifier: 7.0.0 version: 7.0.0 @@ -490,14 +490,14 @@ importers: specifier: 14.0.0 version: 14.0.0 pacote: - specifier: 21.5.0 - version: 21.5.0 + specifier: 21.5.1 + version: 21.5.1 parse5-html-rewriting-stream: specifier: 8.0.1 version: 8.0.1 semver: - specifier: 7.8.1 - version: 7.8.1 + specifier: 7.8.4 + version: 7.8.4 yargs: specifier: 18.0.0 version: 18.0.0 @@ -579,7 +579,7 @@ importers: version: link:../../angular/build '@babel/core': specifier: 7.29.7 - version: 7.29.7 + version: 7.29.7(supports-color@10.2.2) '@babel/generator': specifier: 7.29.7 version: 7.29.7 @@ -597,7 +597,7 @@ importers: version: 7.29.7(@babel/core@7.29.7) '@babel/plugin-transform-runtime': specifier: 7.29.7 - version: 7.29.7(@babel/core@7.29.7) + version: 7.29.7(@babel/core@7.29.7)(supports-color@10.2.2) '@babel/preset-env': specifier: 7.29.7 version: 7.29.7(@babel/core@7.29.7) @@ -618,22 +618,22 @@ importers: version: 10.5.0(postcss@8.5.15) babel-loader: specifier: 10.1.1 - version: 10.1.1(@babel/core@7.29.7)(webpack@5.107.2(esbuild@0.28.0)(postcss@8.5.15)) + version: 10.1.1(@babel/core@7.29.7)(webpack@5.107.2(esbuild@0.28.1)(postcss@8.5.15)) browserslist: specifier: ^4.26.0 version: 4.28.2 copy-webpack-plugin: specifier: 14.0.0 - version: 14.0.0(webpack@5.107.2(esbuild@0.28.0)(postcss@8.5.15)) + version: 14.0.0(webpack@5.107.2(esbuild@0.28.1)(postcss@8.5.15)) css-loader: specifier: 7.1.4 - version: 7.1.4(webpack@5.107.2(esbuild@0.28.0)(postcss@8.5.15)) + version: 7.1.4(webpack@5.107.2(esbuild@0.28.1)(postcss@8.5.15)) esbuild-wasm: - specifier: 0.28.0 - version: 0.28.0 + specifier: 0.28.1 + version: 0.28.1 http-proxy-middleware: - specifier: 4.0.0 - version: 4.0.0 + specifier: 4.1.1 + version: 4.1.1 istanbul-lib-instrument: specifier: 6.0.3 version: 6.0.3 @@ -644,20 +644,20 @@ importers: specifier: 1.4.0 version: 1.4.0 less: - specifier: 4.6.4 - version: 4.6.4 + specifier: 4.6.6 + version: 4.6.6 less-loader: specifier: 13.0.0 - version: 13.0.0(less@4.6.4)(webpack@5.107.2(esbuild@0.28.0)(postcss@8.5.15)) + version: 13.0.0(less@4.6.6)(webpack@5.107.2(esbuild@0.28.1)(postcss@8.5.15)) license-webpack-plugin: specifier: 4.0.2 - version: 4.0.2(webpack@5.107.2(esbuild@0.28.0)(postcss@8.5.15)) + version: 4.0.2(webpack@5.107.2(esbuild@0.28.1)(postcss@8.5.15)) loader-utils: specifier: 3.3.1 version: 3.3.1 mini-css-extract-plugin: specifier: 2.10.2 - version: 2.10.2(webpack@5.107.2(esbuild@0.28.0)(postcss@8.5.15)) + version: 2.10.2(webpack@5.107.2(esbuild@0.28.1)(postcss@8.5.15)) open: specifier: 11.0.0 version: 11.0.0 @@ -668,14 +668,14 @@ importers: specifier: 4.0.4 version: 4.0.4 piscina: - specifier: 5.1.4 - version: 5.1.4 + specifier: 5.2.0 + version: 5.2.0 postcss: specifier: 8.5.15 version: 8.5.15 postcss-loader: specifier: 8.2.1 - version: 8.2.1(postcss@8.5.15)(typescript@6.0.3)(webpack@5.107.2(esbuild@0.28.0)(postcss@8.5.15)) + version: 8.2.1(postcss@8.5.15)(typescript@6.0.3)(webpack@5.107.2(esbuild@0.28.1)(postcss@8.5.15)) resolve-url-loader: specifier: 5.0.0 version: 5.0.0 @@ -683,17 +683,17 @@ importers: specifier: 7.8.2 version: 7.8.2 sass: - specifier: 1.100.0 - version: 1.100.0 + specifier: 1.101.0 + version: 1.101.0 sass-loader: specifier: 17.0.0 - version: 17.0.0(sass@1.100.0)(webpack@5.107.2(esbuild@0.28.0)(postcss@8.5.15)) + version: 17.0.0(sass@1.101.0)(webpack@5.107.2(esbuild@0.28.1)(postcss@8.5.15)) semver: - specifier: 7.8.1 - version: 7.8.1 + specifier: 7.8.4 + version: 7.8.4 source-map-loader: specifier: 5.0.0 - version: 5.0.0(webpack@5.107.2(esbuild@0.28.0)(postcss@8.5.15)) + version: 5.0.0(webpack@5.107.2(esbuild@0.28.1)(postcss@8.5.15)) source-map-support: specifier: 0.5.21 version: 0.5.21 @@ -708,36 +708,36 @@ importers: version: 2.8.1 webpack: specifier: 5.107.2 - version: 5.107.2(esbuild@0.28.0)(postcss@8.5.15) + version: 5.107.2(esbuild@0.28.1)(postcss@8.5.15) webpack-dev-middleware: specifier: 8.0.3 - version: 8.0.3(tslib@2.8.1)(webpack@5.107.2(esbuild@0.28.0)(postcss@8.5.15)) + version: 8.0.3(tslib@2.8.1)(webpack@5.107.2(esbuild@0.28.1)(postcss@8.5.15)) webpack-dev-server: - specifier: 5.2.4 - version: 5.2.4(bufferutil@4.1.0)(tslib@2.8.1)(utf-8-validate@6.0.6)(webpack@5.107.2(esbuild@0.28.0)(postcss@8.5.15)) + specifier: 5.2.5 + version: 5.2.5(bufferutil@4.1.0)(tslib@2.8.1)(utf-8-validate@6.0.6)(webpack@5.107.2(esbuild@0.28.1)(postcss@8.5.15)) webpack-merge: specifier: 6.0.1 version: 6.0.1 webpack-subresource-integrity: specifier: 5.1.0 - version: 5.1.0(webpack@5.107.2(esbuild@0.28.0)(postcss@8.5.15)) + version: 5.1.0(webpack@5.107.2(esbuild@0.28.1)(postcss@8.5.15)) devDependencies: '@angular/ssr': specifier: workspace:* version: link:../../angular/ssr browser-sync: specifier: 3.0.4 - version: 3.0.4(bufferutil@4.1.0)(utf-8-validate@6.0.6) + version: 3.0.4(bufferutil@4.1.0)(supports-color@10.2.2)(utf-8-validate@6.0.6) ng-packagr: specifier: 22.1.0-next.2 version: 22.1.0-next.2(@angular/compiler-cli@22.1.0-next.0(@angular/compiler@22.1.0-next.0)(typescript@6.0.3))(tslib@2.8.1)(typescript@6.0.3) undici: - specifier: 8.3.0 - version: 8.3.0 + specifier: 8.4.1 + version: 8.4.1 optionalDependencies: esbuild: - specifier: 0.28.0 - version: 0.28.0 + specifier: 0.28.1 + version: 0.28.1 packages/angular_devkit/build_webpack: dependencies: @@ -756,10 +756,10 @@ importers: version: link:../../ngtools/webpack webpack: specifier: 5.107.2 - version: 5.107.2(esbuild@0.28.0) + version: 5.107.2(esbuild@0.28.1) webpack-dev-server: - specifier: 5.2.4 - version: 5.2.4(bufferutil@4.1.0)(tslib@2.8.1)(utf-8-validate@6.0.6)(webpack@5.107.2(esbuild@0.28.0)) + specifier: 5.2.5 + version: 5.2.5(bufferutil@4.1.0)(tslib@2.8.1)(utf-8-validate@6.0.6)(webpack@5.107.2(esbuild@0.28.1)) packages/angular_devkit/core: dependencies: @@ -832,7 +832,7 @@ importers: version: 6.0.3 webpack: specifier: 5.107.2 - version: 5.107.2(esbuild@0.28.0) + version: 5.107.2(esbuild@0.28.1) packages/schematics/angular: dependencies: @@ -875,60 +875,60 @@ packages: '@actions/io@3.0.2': resolution: {integrity: sha512-nRBchcMM+QK1pdjO7/idu86rbJI5YHUKCvKs0KxnSYbVe3F51UfGxuZX4Qy/fWlp6l7gWFwIkrOzN+oUK03kfw==} - '@algolia/abtesting@1.19.0': - resolution: {integrity: sha512-Lhnez3hhXHk25lfxLAMxvkP4fmN3+1RgADhD2ssMDBYuAsDVReeyP+3SGRx+ntq8ijMrLqUyfvO72TB6jsTteQ==} + '@algolia/abtesting@1.20.0': + resolution: {integrity: sha512-5CqkS592H3+24b6H6CQ2RVpphdmAuIElZzv0Hngqo/ZEZpUZJ+KGLcueBhx33fv2wYBXyuuvskG5aQ7Ti+lR0g==} engines: {node: '>= 14.0.0'} - '@algolia/client-abtesting@5.53.0': - resolution: {integrity: sha512-0ZjA5Hcmaoz5Lj6OG0zhfIyeqzJZnLW2CRJA1W17UwMFGRtZAJ9yJKRvPEDA6gkpsIoQxORTSW6sWFiuYncPNQ==} + '@algolia/client-abtesting@5.54.0': + resolution: {integrity: sha512-IXnH1x3DBsPQA4/FRO0Pvkfy79tKy5Qr+ugAV9jdcGkpzHc476D0WV1MFJ+pZxtbts0xh2JqzUVmYEqA6LkOpA==} engines: {node: '>= 14.0.0'} - '@algolia/client-analytics@5.53.0': - resolution: {integrity: sha512-kWNodP75iiEaOtemC9F/hlxNBG5E2QUjN1BusnE6m2b4l7Qh/BUO3fGCVsmKJI65VO4VKGGmT43ICvHtTcJ2JQ==} + '@algolia/client-analytics@5.54.0': + resolution: {integrity: sha512-pBpRqm1wpE0GnGy2rNLk9rjDn0Le4iywNRtnAWblLeqfjxpWKg8lWnk7nmSoTShFO31sz2jatXXzxK2lz8ipbA==} engines: {node: '>= 14.0.0'} - '@algolia/client-common@5.53.0': - resolution: {integrity: sha512-YPN45TXD9Wrse185t/Ta7nktZsqpv97oOjCzp2sblHnCL6rBc9TDeJAg1IGl2UpdwnSD05Zu/5wLB4watOUMyg==} + '@algolia/client-common@5.54.0': + resolution: {integrity: sha512-WbuwRUlFvSOsuxqTDjSSmgusuF5KFt+oFPzobvPDvodra6EWnVwUXjz0elkNSsnsIlZGtcXlX3LhxkO7rF90jw==} engines: {node: '>= 14.0.0'} - '@algolia/client-insights@5.53.0': - resolution: {integrity: sha512-qAcYTDJE6m924FDDUQvdD6vh7DYaqOeSpFS74IP37/JRV0v4cGBauyxTF2WzDnokUylQDbqreoFIJZfg0Fitmw==} + '@algolia/client-insights@5.54.0': + resolution: {integrity: sha512-/HNLVi3kPI+JhO59WbglLjPM2c4uECU+x4gk1iADseKtE5eYqJ/RJ+FIwM8xzPFKhFJaw+8hVq4lkd0nn8HDDg==} engines: {node: '>= 14.0.0'} - '@algolia/client-personalization@5.53.0': - resolution: {integrity: sha512-fQaY+DkSJOpuUVUe8MQTwrdiKAqkJGhpDarB08duBn/sUv7Bkib6MDRQauCcWTWTe4HIW+EbwQP9R4kci1V/Yw==} + '@algolia/client-personalization@5.54.0': + resolution: {integrity: sha512-6TolyyDRumIKeLGBGSFAZsSIJ8hrm6NFCGR1jO7pQTiOtSWgAIxcFE5/JRpZ3g+unG4OkNOFy+I0dUEquIDbig==} engines: {node: '>= 14.0.0'} - '@algolia/client-query-suggestions@5.53.0': - resolution: {integrity: sha512-o72tsiEZGfeS/dxL9IADfzcZWGEwKDEe5CvtrBuT//3JR+SHuTtHRI2ZTf7D7bcKagcbojvO8hnkHdfoakSlYg==} + '@algolia/client-query-suggestions@5.54.0': + resolution: {integrity: sha512-AxW2MLBhjBtGX5kIZrVLO2SP2vRkZxJw5qHGxnQJfLcYhA04mFNP0fWRtHshlcVnDk9M8L9lwfr2lGpf3Er+hw==} engines: {node: '>= 14.0.0'} - '@algolia/client-search@5.53.0': - resolution: {integrity: sha512-Ds16IyPm/dNJPCU8OzApo2gwGrgWT5BYHhE3NFwZbpCveqyvPDB9sZDDkJ5DsdOGT2aC+R3i0/M1OVXF2qdgPg==} + '@algolia/client-search@5.54.0': + resolution: {integrity: sha512-ngdgVGp05lJzUyA+sUzr0MDZ7AMtANcJpwIzq4ZsfpZL5B3S7A4XYfMcU2sECZc3bx3ysOhYcdbbaTjc3ve0WQ==} engines: {node: '>= 14.0.0'} - '@algolia/ingestion@1.53.0': - resolution: {integrity: sha512-oNbT6z4NwD8Pou9VPINGlN/tlG1afESh2EbxqnP6rwl95xKVD/Zlciis1PpNeO/9U/rrajc1+7DcfKi03tX1KQ==} + '@algolia/ingestion@1.54.0': + resolution: {integrity: sha512-hee59Z7FgZ6/13FYL05ANPwRJY1pfvIlrwC8eBZYdiRFXTJVvf94IyTWOxLqRVpbseDP6eQQTW+PT7/DxTZIng==} engines: {node: '>= 14.0.0'} - '@algolia/monitoring@1.53.0': - resolution: {integrity: sha512-G+KZb/yd+qAOFn/cEvTGeLxQm8aP3a0od50l3z/ylccY+/o4YG3TNcjU1tFQHW4mXC137GPyR7W70R0kRQDLnA==} + '@algolia/monitoring@1.54.0': + resolution: {integrity: sha512-diCjZVbIO7Pzw98tEKqLWIAgmQBI3Zt1sHsXyAPNGZgn32derpIXTnjjpJbZl+uAhSSznd6SfxFGdC9uYdN1TA==} engines: {node: '>= 14.0.0'} - '@algolia/recommend@5.53.0': - resolution: {integrity: sha512-6aVfYd55Un6IUgPLbo84WfgFZlS3L0vA1ttzXL5vahHewUJ8jYgd89TzlWRTeej7w70mb9RWsVlFYGmJ/diQww==} + '@algolia/recommend@5.54.0': + resolution: {integrity: sha512-6zeslypRAGWDgVJEJYAPuqmyquHvnw4MQwG+XXdrw5dTNDjXYIcCJdQQcCY06xPF9tUvmzy/1vHiH9QxhgwuOQ==} engines: {node: '>= 14.0.0'} - '@algolia/requester-browser-xhr@5.53.0': - resolution: {integrity: sha512-ke27DqgzCOlt+RbeEdCxtXxMQOnAOi8ujr2wid0DmDKzR95Kw/f9sBsuhBxtjevCqJRJszfRTLY0B1pbO6IhkA==} + '@algolia/requester-browser-xhr@5.54.0': + resolution: {integrity: sha512-iHZax214LPXd7XizQ4BNnTsegl8f3IeKm8JcrmSNZ/5x1rZ5xLkbG/anltAWtLpoRNnfpr4Z80YdYeVVPpx6wQ==} engines: {node: '>= 14.0.0'} - '@algolia/requester-fetch@5.53.0': - resolution: {integrity: sha512-GngiOqt2Gq4oLno6yXQVj9om+qSO9SWAoduoTOEg79dKZ62brB8OOIvSJG/vDNoanYi6a7Al9uDZwXvi+bcVTg==} + '@algolia/requester-fetch@5.54.0': + resolution: {integrity: sha512-YKtuG5YwPxZ+kkfd4HmUO7Z9aICPUSMlHslzKTmtMMhxGnetxEqGj9T/v2r/PdcuOUC5oW0CHe8akJk8cpS3gQ==} engines: {node: '>= 14.0.0'} - '@algolia/requester-node-http@5.53.0': - resolution: {integrity: sha512-6mF9LZMUk0QqWvrnxkxBqhswwz6Xfiwy6/gmTzL5HrlhdVG3ITAqGV2k3XmVThP1h0Ulc3VQwiNCD7/Nr4JNlQ==} + '@algolia/requester-node-http@5.54.0': + resolution: {integrity: sha512-zyZDJ4WS5TnjZZ5pqywTBFO9olW7QMtY2kf2dbLnu+UTzfc9ri/HGf27jRN2NTbX9FcRPxSqPqzUhF/BZIx0VA==} engines: {node: '>= 14.0.0'} '@ampproject/remapping@2.3.0': @@ -1661,14 +1661,14 @@ packages: resolution: {integrity: sha512-Xc3VhU02wqZ1HvHRJUwL09HkZSTvidqY5Ya0NXBSYOxAp+Ln9dcJr9fySI+CkONzP3PekQo9WdzCv0PGER/mOA==} engines: {node: '>=14.17.0'} - '@emnapi/core@1.10.0': - resolution: {integrity: sha512-yq6OkJ4p82CAfPl0u9mQebQHKPJkY7WrIuk205cTYnYe+k2Z8YBh11FrbRG/H6ihirqcacOgl2BIO8oyMQLeXw==} + '@emnapi/core@1.11.0': + resolution: {integrity: sha512-l9Oo58x0HOP5znGzVhYW9U3e5wVuA4LAZU2AGezTmkhO1CgQRFDhDg4nneHsu/t3WniXg9QrG2nIXL/ZS8ln8Q==} - '@emnapi/runtime@1.10.0': - resolution: {integrity: sha512-ewvYlk86xUoGI0zQRNq/mC+16R1QeDlKQy21Ki3oSYXNgLb45GV1P6A0M+/s6nyCuNDqe5VpaY84BzXGwVbwFA==} + '@emnapi/runtime@1.11.0': + resolution: {integrity: sha512-55coeOFKHv1ywEcUXJtWU5f+Jr/W5tZDvZig8DLKSwUN1JpROQ4rk/SNOQiFWmaR/VKF4zuFyW1B8JduOSv6Pg==} - '@emnapi/wasi-threads@1.2.1': - resolution: {integrity: sha512-uTII7OYF+/Mes/MrcIOYp5yOtSMLBWSIoLPpcgwipoiKbli6k322tcoFsxoIIxPDqW01SQGAgko4EzZi2BNv2w==} + '@emnapi/wasi-threads@1.2.2': + resolution: {integrity: sha512-c95qOXkHdydNKhscBTebqEC1CVAZpyqOfVfBzQ1qgzyl3gfeldUjIggDbIZgDKsHLgnsM+igH7TJ/eAasaVuMA==} '@esbuild/aix-ppc64@0.27.7': resolution: {integrity: sha512-EKX3Qwmhz1eMdEJokhALr0YiD0lhQNwDqkPYyPhiSwKrh7/4KRjQc04sZ8db+5DVVnZ1LmbNDI1uAMPEUBnQPg==} @@ -1682,6 +1682,12 @@ packages: cpu: [ppc64] os: [aix] + '@esbuild/aix-ppc64@0.28.1': + resolution: {integrity: sha512-Svl7tq8k/08+p6CXPpRjQ1fKX+1odH/BQbb48fV6fj3CWHhsoIOoY87w1oHXm0qEpkIK3ZfVgp0hed3XBXzXMQ==} + engines: {node: '>=18'} + cpu: [ppc64] + os: [aix] + '@esbuild/android-arm64@0.27.7': resolution: {integrity: sha512-62dPZHpIXzvChfvfLJow3q5dDtiNMkwiRzPylSCfriLvZeq0a1bWChrGx/BbUbPwOrsWKMn8idSllklzBy+dgQ==} engines: {node: '>=18'} @@ -1694,6 +1700,12 @@ packages: cpu: [arm64] os: [android] + '@esbuild/android-arm64@0.28.1': + resolution: {integrity: sha512-34EGEbCIAgosYz6goLcopX6Mo7NyGv9tfwEM2/7Ce2VcVRk568iSvniGWcUXIy7wEDR1wzolcxcriFVrWYcwBg==} + engines: {node: '>=18'} + cpu: [arm64] + os: [android] + '@esbuild/android-arm@0.27.7': resolution: {integrity: sha512-jbPXvB4Yj2yBV7HUfE2KHe4GJX51QplCN1pGbYjvsyCZbQmies29EoJbkEc+vYuU5o45AfQn37vZlyXy4YJ8RQ==} engines: {node: '>=18'} @@ -1706,6 +1718,12 @@ packages: cpu: [arm] os: [android] + '@esbuild/android-arm@0.28.1': + resolution: {integrity: sha512-0k2F129Xdio1TdJfzJ8sy1Q47vUD2NnwdhiAf7drUN1EBTfPf4hsFCtmMgu/6m8JSzsBrlmVjudMBQqOfG8usQ==} + engines: {node: '>=18'} + cpu: [arm] + os: [android] + '@esbuild/android-x64@0.27.7': resolution: {integrity: sha512-x5VpMODneVDb70PYV2VQOmIUUiBtY3D3mPBG8NxVk5CogneYhkR7MmM3yR/uMdITLrC1ml/NV1rj4bMJuy9MCg==} engines: {node: '>=18'} @@ -1718,6 +1736,12 @@ packages: cpu: [x64] os: [android] + '@esbuild/android-x64@0.28.1': + resolution: {integrity: sha512-dbwY7ltSMDWsRatcRpCnES4F+im88OCUgGZjy52shC7GqHRE/cYlxNbB4Z4UpJswpcc4Qxd2oE/ufM0p61IKng==} + engines: {node: '>=18'} + cpu: [x64] + os: [android] + '@esbuild/darwin-arm64@0.27.7': resolution: {integrity: sha512-5lckdqeuBPlKUwvoCXIgI2D9/ABmPq3Rdp7IfL70393YgaASt7tbju3Ac+ePVi3KDH6N2RqePfHnXkaDtY9fkw==} engines: {node: '>=18'} @@ -1730,6 +1754,12 @@ packages: cpu: [arm64] os: [darwin] + '@esbuild/darwin-arm64@0.28.1': + resolution: {integrity: sha512-TZbWkQY7kvTAXbXUT7uVACR5cMHsDiSz9z7ZKAX/RTq/WJEk3QyRr0wZpNhBDX+/0CtdqUIJlOiodQcta6tY3Q==} + engines: {node: '>=18'} + cpu: [arm64] + os: [darwin] + '@esbuild/darwin-x64@0.27.7': resolution: {integrity: sha512-rYnXrKcXuT7Z+WL5K980jVFdvVKhCHhUwid+dDYQpH+qu+TefcomiMAJpIiC2EM3Rjtq0sO3StMV/+3w3MyyqQ==} engines: {node: '>=18'} @@ -1742,6 +1772,12 @@ packages: cpu: [x64] os: [darwin] + '@esbuild/darwin-x64@0.28.1': + resolution: {integrity: sha512-zfdzgK9ACBNZLI/CyHTOx81SyNbM6YXn7rxSgX97VjyiPl9W1i4Ka4fgKECEoFCKGpvBj5qArWIGgQjOwkgskQ==} + engines: {node: '>=18'} + cpu: [x64] + os: [darwin] + '@esbuild/freebsd-arm64@0.27.7': resolution: {integrity: sha512-B48PqeCsEgOtzME2GbNM2roU29AMTuOIN91dsMO30t+Ydis3z/3Ngoj5hhnsOSSwNzS+6JppqWsuhTp6E82l2w==} engines: {node: '>=18'} @@ -1754,6 +1790,12 @@ packages: cpu: [arm64] os: [freebsd] + '@esbuild/freebsd-arm64@0.28.1': + resolution: {integrity: sha512-wG2EA8ENdEI0qhkSZMjfqrdY+ziCYCPMmtZjjIwOmXFjmyzEHn+UUxk5of+SYsjtfs3VpnlC7QLzSI5hY/rOAw==} + engines: {node: '>=18'} + cpu: [arm64] + os: [freebsd] + '@esbuild/freebsd-x64@0.27.7': resolution: {integrity: sha512-jOBDK5XEjA4m5IJK3bpAQF9/Lelu/Z9ZcdhTRLf4cajlB+8VEhFFRjWgfy3M1O4rO2GQ/b2dLwCUGpiF/eATNQ==} engines: {node: '>=18'} @@ -1766,6 +1808,12 @@ packages: cpu: [x64] os: [freebsd] + '@esbuild/freebsd-x64@0.28.1': + resolution: {integrity: sha512-i7dZ9vQgnvSCzi/rYCXNgtF/U+eKZNJBzu3eTQbRgHnM7tNSizLOkRFAl3qzVc/Op/u5YkHHa4pf/3DOYHthLQ==} + engines: {node: '>=18'} + cpu: [x64] + os: [freebsd] + '@esbuild/linux-arm64@0.27.7': resolution: {integrity: sha512-RZPHBoxXuNnPQO9rvjh5jdkRmVizktkT7TCDkDmQ0W2SwHInKCAV95GRuvdSvA7w4VMwfCjUiPwDi0ZO6Nfe9A==} engines: {node: '>=18'} @@ -1778,6 +1826,12 @@ packages: cpu: [arm64] os: [linux] + '@esbuild/linux-arm64@0.28.1': + resolution: {integrity: sha512-yHs+0uc8+nvEAfAfxrWQKK5peSNzBc4PegcMO0EJ2hT71uA7vB8Ihg2e77R2P7SG5uYjPbHlLLmve4LLLRCf0g==} + engines: {node: '>=18'} + cpu: [arm64] + os: [linux] + '@esbuild/linux-arm@0.27.7': resolution: {integrity: sha512-RkT/YXYBTSULo3+af8Ib0ykH8u2MBh57o7q/DAs3lTJlyVQkgQvlrPTnjIzzRPQyavxtPtfg0EopvDyIt0j1rA==} engines: {node: '>=18'} @@ -1790,6 +1844,12 @@ packages: cpu: [arm] os: [linux] + '@esbuild/linux-arm@0.28.1': + resolution: {integrity: sha512-qVXBOHQS+d5Y722GwJzJUtOLlX7km3CraOaGormF1pDtPd2C/l1SHRPgjLunLGe51Sh5YYWKMFDyV4SxgMQYTQ==} + engines: {node: '>=18'} + cpu: [arm] + os: [linux] + '@esbuild/linux-ia32@0.27.7': resolution: {integrity: sha512-GA48aKNkyQDbd3KtkplYWT102C5sn/EZTY4XROkxONgruHPU72l+gW+FfF8tf2cFjeHaRbWpOYa/uRBz/Xq1Pg==} engines: {node: '>=18'} @@ -1802,6 +1862,12 @@ packages: cpu: [ia32] os: [linux] + '@esbuild/linux-ia32@0.28.1': + resolution: {integrity: sha512-d1z4ZuP0ajrfz/FhGT4vv278rX8KnPPJx8i5+AtK7TYbx9Le9F1hyzurZpkEyjkGa9dUGhQow4C1NmeGvqxN2w==} + engines: {node: '>=18'} + cpu: [ia32] + os: [linux] + '@esbuild/linux-loong64@0.27.7': resolution: {integrity: sha512-a4POruNM2oWsD4WKvBSEKGIiWQF8fZOAsycHOt6JBpZ+JN2n2JH9WAv56SOyu9X5IqAjqSIPTaJkqN8F7XOQ5Q==} engines: {node: '>=18'} @@ -1814,6 +1880,12 @@ packages: cpu: [loong64] os: [linux] + '@esbuild/linux-loong64@0.28.1': + resolution: {integrity: sha512-M5sRjUVZrkm1OAPR3dlOYzNmN+loZKGVi1VUQGrwuqLcbR6qeAz+famMhjASeH3YVKvZz+zT1jlh/keC3Rj/lg==} + engines: {node: '>=18'} + cpu: [loong64] + os: [linux] + '@esbuild/linux-mips64el@0.27.7': resolution: {integrity: sha512-KabT5I6StirGfIz0FMgl1I+R1H73Gp0ofL9A3nG3i/cYFJzKHhouBV5VWK1CSgKvVaG4q1RNpCTR2LuTVB3fIw==} engines: {node: '>=18'} @@ -1826,6 +1898,12 @@ packages: cpu: [mips64el] os: [linux] + '@esbuild/linux-mips64el@0.28.1': + resolution: {integrity: sha512-mRObBZeHh2OxcBFPWE/FjylkRgZdYuiTR3vaTozquCGOH14iP9oN4x4Ge81CoIDYQrXmIxpFumJBu5MtZpnQJQ==} + engines: {node: '>=18'} + cpu: [mips64el] + os: [linux] + '@esbuild/linux-ppc64@0.27.7': resolution: {integrity: sha512-gRsL4x6wsGHGRqhtI+ifpN/vpOFTQtnbsupUF5R5YTAg+y/lKelYR1hXbnBdzDjGbMYjVJLJTd2OFmMewAgwlQ==} engines: {node: '>=18'} @@ -1838,6 +1916,12 @@ packages: cpu: [ppc64] os: [linux] + '@esbuild/linux-ppc64@0.28.1': + resolution: {integrity: sha512-slScBsMAb3GFDcdrCgLwZtPYRoH2H/youv10QiZyRjmsP48fznoveWytSgCI/R0ZcUgpc0ZhIUEx6LHts8yrfQ==} + engines: {node: '>=18'} + cpu: [ppc64] + os: [linux] + '@esbuild/linux-riscv64@0.27.7': resolution: {integrity: sha512-hL25LbxO1QOngGzu2U5xeXtxXcW+/GvMN3ejANqXkxZ/opySAZMrc+9LY/WyjAan41unrR3YrmtTsUpwT66InQ==} engines: {node: '>=18'} @@ -1850,6 +1934,12 @@ packages: cpu: [riscv64] os: [linux] + '@esbuild/linux-riscv64@0.28.1': + resolution: {integrity: sha512-kw0owk1o0GFETUJyW0jc0G4Yzs0BHZn0JDZ8JRT088vjJYX777BAs1fDGxAC+q831qOs2DTC96mNsG2opdfyyQ==} + engines: {node: '>=18'} + cpu: [riscv64] + os: [linux] + '@esbuild/linux-s390x@0.27.7': resolution: {integrity: sha512-2k8go8Ycu1Kb46vEelhu1vqEP+UeRVj2zY1pSuPdgvbd5ykAw82Lrro28vXUrRmzEsUV0NzCf54yARIK8r0fdw==} engines: {node: '>=18'} @@ -1862,6 +1952,12 @@ packages: cpu: [s390x] os: [linux] + '@esbuild/linux-s390x@0.28.1': + resolution: {integrity: sha512-/lAIjX8aYFRByhh6L5rYtPEDRqa9de/4V/juOXcta5frjvzXO4/sqEtyytse0g3zZFuWu5cDN0MkLz2qRDD2Ag==} + engines: {node: '>=18'} + cpu: [s390x] + os: [linux] + '@esbuild/linux-x64@0.27.7': resolution: {integrity: sha512-hzznmADPt+OmsYzw1EE33ccA+HPdIqiCRq7cQeL1Jlq2gb1+OyWBkMCrYGBJ+sxVzve2ZJEVeePbLM2iEIZSxA==} engines: {node: '>=18'} @@ -1874,6 +1970,12 @@ packages: cpu: [x64] os: [linux] + '@esbuild/linux-x64@0.28.1': + resolution: {integrity: sha512-u/anNYF2mmVOEDwLtnQ1wOr3EZ9sTNGLWrsYGYwHWzGA3Si84IOkHXlbWTD1NB+9/1lcnweYKO54uhxZydNzfA==} + engines: {node: '>=18'} + cpu: [x64] + os: [linux] + '@esbuild/netbsd-arm64@0.27.7': resolution: {integrity: sha512-b6pqtrQdigZBwZxAn1UpazEisvwaIDvdbMbmrly7cDTMFnw/+3lVxxCTGOrkPVnsYIosJJXAsILG9XcQS+Yu6w==} engines: {node: '>=18'} @@ -1886,6 +1988,12 @@ packages: cpu: [arm64] os: [netbsd] + '@esbuild/netbsd-arm64@0.28.1': + resolution: {integrity: sha512-oks0DYbLwWMmaakTsCb+zL4E+aHRVLom9IJZOAthMQEPiQmydXHkziYEsGYRx0uNV/IjEKGAV941JzH02pflqw==} + engines: {node: '>=18'} + cpu: [arm64] + os: [netbsd] + '@esbuild/netbsd-x64@0.27.7': resolution: {integrity: sha512-OfatkLojr6U+WN5EDYuoQhtM+1xco+/6FSzJJnuWiUw5eVcicbyK3dq5EeV/QHT1uy6GoDhGbFpprUiHUYggrw==} engines: {node: '>=18'} @@ -1898,6 +2006,12 @@ packages: cpu: [x64] os: [netbsd] + '@esbuild/netbsd-x64@0.28.1': + resolution: {integrity: sha512-aeL6lAnN89Hz43Mlh1G8ARasbuoYvSITDEx0tHh5b7jJnHcssqgjy9Yx430GDpmCa6OyrKoS0aNRjKundRizGg==} + engines: {node: '>=18'} + cpu: [x64] + os: [netbsd] + '@esbuild/openbsd-arm64@0.27.7': resolution: {integrity: sha512-AFuojMQTxAz75Fo8idVcqoQWEHIXFRbOc1TrVcFSgCZtQfSdc1RXgB3tjOn/krRHENUB4j00bfGjyl2mJrU37A==} engines: {node: '>=18'} @@ -1910,6 +2024,12 @@ packages: cpu: [arm64] os: [openbsd] + '@esbuild/openbsd-arm64@0.28.1': + resolution: {integrity: sha512-MEFJe5C3R8pwXdZ5Y21oo6m7ePiS0d9pWucn99O/wvyJZChoIQKrQDxKrGeW8F5+T0okTHesAmDeiHDTIq0V/Q==} + engines: {node: '>=18'} + cpu: [arm64] + os: [openbsd] + '@esbuild/openbsd-x64@0.27.7': resolution: {integrity: sha512-+A1NJmfM8WNDv5CLVQYJ5PshuRm/4cI6WMZRg1by1GwPIQPCTs1GLEUHwiiQGT5zDdyLiRM/l1G0Pv54gvtKIg==} engines: {node: '>=18'} @@ -1922,6 +2042,12 @@ packages: cpu: [x64] os: [openbsd] + '@esbuild/openbsd-x64@0.28.1': + resolution: {integrity: sha512-i/ZLIOafE0Z8cI/XANJAixoJL/uRAoS2xOA3rb0xN+KK0K177cMAsQYkzHtBrtMXAKuAc7HGgcWiZ/sRC1Nxgw==} + engines: {node: '>=18'} + cpu: [x64] + os: [openbsd] + '@esbuild/openharmony-arm64@0.27.7': resolution: {integrity: sha512-+KrvYb/C8zA9CU/g0sR6w2RBw7IGc5J2BPnc3dYc5VJxHCSF1yNMxTV5LQ7GuKteQXZtspjFbiuW5/dOj7H4Yw==} engines: {node: '>=18'} @@ -1934,6 +2060,12 @@ packages: cpu: [arm64] os: [openharmony] + '@esbuild/openharmony-arm64@0.28.1': + resolution: {integrity: sha512-ge+Z7EXFNt2BO1oAMsVpiQ8EwndV9i1xXerAeTIK7AtPs3bKFXQM7nlRxDSIUIMeueR1CNXxqztLzdNeReKBJg==} + engines: {node: '>=18'} + cpu: [arm64] + os: [openharmony] + '@esbuild/sunos-x64@0.27.7': resolution: {integrity: sha512-ikktIhFBzQNt/QDyOL580ti9+5mL/YZeUPKU2ivGtGjdTYoqz6jObj6nOMfhASpS4GU4Q/Clh1QtxWAvcYKamA==} engines: {node: '>=18'} @@ -1946,6 +2078,12 @@ packages: cpu: [x64] os: [sunos] + '@esbuild/sunos-x64@0.28.1': + resolution: {integrity: sha512-BEjgtECkL3vY+SaSQ6nzVfiALUeFxpawyp8Jmf5PtYhf1Ug40N1h/hxlhts+f1FvSvarEigdxS3BlSMI2PJLcQ==} + engines: {node: '>=18'} + cpu: [x64] + os: [sunos] + '@esbuild/win32-arm64@0.27.7': resolution: {integrity: sha512-7yRhbHvPqSpRUV7Q20VuDwbjW5kIMwTHpptuUzV+AA46kiPze5Z7qgt6CLCK3pWFrHeNfDd1VKgyP4O+ng17CA==} engines: {node: '>=18'} @@ -1958,6 +2096,12 @@ packages: cpu: [arm64] os: [win32] + '@esbuild/win32-arm64@0.28.1': + resolution: {integrity: sha512-lCv9eK/H6ZJWbE7bh2nw54CZ9M2nupBxJcTsdk/QQnWkdSjKGuxmmH8/GWrlT1eMmZfn4dGcCjRte397WqfQXA==} + engines: {node: '>=18'} + cpu: [arm64] + os: [win32] + '@esbuild/win32-ia32@0.27.7': resolution: {integrity: sha512-SmwKXe6VHIyZYbBLJrhOoCJRB/Z1tckzmgTLfFYOfpMAx63BJEaL9ExI8x7v0oAO3Zh6D/Oi1gVxEYr5oUCFhw==} engines: {node: '>=18'} @@ -1970,6 +2114,12 @@ packages: cpu: [ia32] os: [win32] + '@esbuild/win32-ia32@0.28.1': + resolution: {integrity: sha512-zvb/mB2bSCoJOpoCBgYKKpX6YM6mJBlBUVUtVj41DlZJVEB6/0CKlRYxP5wWl1C1ILiCoAU5wZZ4q1P3qeS6Eg==} + engines: {node: '>=18'} + cpu: [ia32] + os: [win32] + '@esbuild/win32-x64@0.27.7': resolution: {integrity: sha512-56hiAJPhwQ1R4i+21FVF7V8kSD5zZTdHcVuRFMW0hn753vVfQN8xlx4uOPT4xoGH0Z/oVATuR82AiqSTDIpaHg==} engines: {node: '>=18'} @@ -1982,6 +2132,12 @@ packages: cpu: [x64] os: [win32] + '@esbuild/win32-x64@0.28.1': + resolution: {integrity: sha512-bm4Mowrv+GXMlpWX++EcXw/iLyd1o3+bJkC2DkWXYVvgZCqD/bSj9ctZeAMC3cIxgjRVR2Dufaiu4YPxr5gW1A==} + engines: {node: '>=18'} + cpu: [x64] + os: [win32] + '@eslint-community/eslint-utils@4.9.1': resolution: {integrity: sha512-phrYmNiYppR7znFEdqgfWHXR6NCkZEK7hwWDHZUjit/2/U0r6XvkDl0SYnoM51Hq7FhCGdLDT6zxCCOY1hexsQ==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} @@ -2837,8 +2993,8 @@ packages: resolution: {integrity: sha512-xJIPs+bYuc9ASBl+cvGsKbGrJmS6fAKaSZCnT0lhahT5rhA2VVy9/EcIgd2JhtEuFOJNx7UHNn/qiTPTY4nrQw==} engines: {node: '>= 10'} - '@napi-rs/wasm-runtime@1.1.4': - resolution: {integrity: sha512-3NQNNgA1YSlJb/kMH1ildASP9HW7/7kYnRI2szWJaofaS1hWmbGI4H+d3+22aGzXXN9IJ+n+GiFVcGipJP18ow==} + '@napi-rs/wasm-runtime@1.1.5': + resolution: {integrity: sha512-AWPoBRJ9tsnVhor4sjO7rkni+7p+2IAEFj6cx06UgP10jkQHqay/36uRV/bFkgrh18D9vb4cr8Q0Pthskgzy+Q==} peerDependencies: '@emnapi/core': ^1.7.1 '@emnapi/runtime': ^1.7.1 @@ -3004,8 +3160,8 @@ packages: resolution: {integrity: sha512-/UhIkaZgPutTFmQ7RnIJGgDXZmtEJ7Dvi86xNTFWcnRxVRNk/aotsqDJYeEvDP+FSMB2SdW+pQzNMcWP0rwuNA==} engines: {node: '>=14'} - '@oxc-project/types@0.133.0': - resolution: {integrity: sha512-KzkdCd6Uxqnf6l3HOw1xfatAlUURA0g14cvBYFyJ5SaNOQbOUvBr9PKArcPcrNIeRsBdgcUzOGrhKveVpvOIGA==} + '@oxc-project/types@0.135.0': + resolution: {integrity: sha512-wR+xRdFkUBMvcAjBJ2q2kcZM6d+DKu2NgoOyxZgYwZdLhmiv6+rnO8PZ/P68kMiZtIKm+pW7zyEJ4kSOs0vo+Q==} '@parcel/watcher-android-arm64@2.5.6': resolution: {integrity: sha512-YQxSS34tPF/6ZG7r/Ih9xy+kP/WwediEUsqmtf0cuCV5TPPKw/PQHRhueUo6JdeFJaqV3pyjm0GdYjZotbRt/A==} @@ -3199,97 +3355,97 @@ packages: proxy-agent: optional: true - '@rolldown/binding-android-arm64@1.0.3': - resolution: {integrity: sha512-454rs7jHngixp/NMxd5srYD57OnzSlZ/eFTETjORQHLwJG1lRtmNOJcBerZlfu4GjKqeq8aCCIQrMdHyhI51Hw==} + '@rolldown/binding-android-arm64@1.1.1': + resolution: {integrity: sha512-BLf9Wak/gfwVb7NQTQW4wBgL3oAfPy7ArEkhwV543OVw/uY6B47z5xYsqPSZ9PDOorvURPinws6ThaFuNgGLgA==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [android] - '@rolldown/binding-darwin-arm64@1.0.3': - resolution: {integrity: sha512-PcAhP+ynjURNyy8SKGl5DQP94aGuB/7JrXJb/t7P+hanXvQVMWzUvRRhBAcg/lNRadBhoUPqSoP4xw5tR/KBEA==} + '@rolldown/binding-darwin-arm64@1.1.1': + resolution: {integrity: sha512-rRZRPy/Ynb+Mxu0O6tfPldHeDgAn0sRij+IOUy6sFdUlv3hArGW/DloE3GfAxtqpOJuRNgF74Nr5gM4xBeU2jQ==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [darwin] - '@rolldown/binding-darwin-x64@1.0.3': - resolution: {integrity: sha512-9YpfeUvSE2RS7wysJ81uOZkXJz7f7Q55H2Gvp3VEw/EsahqDtrphrZ0EwDLK5vvKOzaCrBsjF8JmnMLcUt78Gg==} + '@rolldown/binding-darwin-x64@1.1.1': + resolution: {integrity: sha512-/MtefPxhKPyWWFM8L45OWiEqRf+eSU2Qv9ZAyTaoZOoGcoPKxbbhjTJO2/U2IThv0uDZ4NWHc3/oTsR6IEOtww==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [darwin] - '@rolldown/binding-freebsd-x64@1.0.3': - resolution: {integrity: sha512-yB1IlAsSNHncV6SCTL27/MVGR5htvQsoGxIv5KMGXALp+Ll1wYsn+x98M9MW7qa+NdSbvrrY7ANI4wLJ0n1e6g==} + '@rolldown/binding-freebsd-x64@1.1.1': + resolution: {integrity: sha512-202K+cpIi1kx/Zn7AtxBi4LTXSY67Aszb2K9rNsuW7FeBeh0nqoNmYLOSZidV0p88VPBzMmTZcHAdPNo3kRYzQ==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [freebsd] - '@rolldown/binding-linux-arm-gnueabihf@1.0.3': - resolution: {integrity: sha512-Yi30IVAAfLUCy2MseFjbB1jAMDl1VMCAas5StnYp8da9+CKvMd2H2cbEjWcw5NPaPqzvYkVIaF1nNUG+b7u/sw==} + '@rolldown/binding-linux-arm-gnueabihf@1.1.1': + resolution: {integrity: sha512-wl9NfeXNUwrXtUc063tddmZFUI6qiNs1CNOwni0OL4vC7MqVSYugra3ZgtDmtVy8e0DluJTENmzIv2BwqLzT4Q==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm] os: [linux] - '@rolldown/binding-linux-arm64-gnu@1.0.3': - resolution: {integrity: sha512-jsO7R8To+AdlYgUmN5sHSCZbfhtMBkO0WUx8iORQnPcMMdgr7qM2DQmMwgabs3GhNztdmoKkMKQFHD6DTMCIQw==} + '@rolldown/binding-linux-arm64-gnu@1.1.1': + resolution: {integrity: sha512-at2EO4o7D/PJLC4Xik16bU4CcjQE2tSv1LfqMA0TRYQYQihRm3gZeDB8xaX28A9SFedibcAk5DeMCKt4REKG0A==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [linux] libc: [glibc] - '@rolldown/binding-linux-arm64-musl@1.0.3': - resolution: {integrity: sha512-VWkUHwWriDciit80wleYwKILoR/KMvxh/IdwS/paX+ZgpuRpCrKLUdadJbc0NpBEiyhpYawsJ73j9aCvOH+f7Q==} + '@rolldown/binding-linux-arm64-musl@1.1.1': + resolution: {integrity: sha512-5PUjZx366h9tkJTPJF5eibxOlK3sGoeRiBJLLjjEB5/kLDuhr6qB3LkhqLz1smXNgsX+pBhnbcJBrPE30HznAA==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [linux] libc: [musl] - '@rolldown/binding-linux-ppc64-gnu@1.0.3': - resolution: {integrity: sha512-5f1laC0SlIR0yDbFCd8acUhvJIag6N3zC5P7oUPN6wX0aOma+uKJ0wBDH5aq7I1PVI2ttTlhJwzwRIBnLiSGEg==} + '@rolldown/binding-linux-ppc64-gnu@1.1.1': + resolution: {integrity: sha512-1WK84XPeio3tjP1sM/TMXiC0G1i1iq1qGZ71KfNQjEFLU1kwD+Cv5T8nGySg/JUFwLbaScu6ve9DmeXlmqpkFA==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [ppc64] os: [linux] libc: [glibc] - '@rolldown/binding-linux-s390x-gnu@1.0.3': - resolution: {integrity: sha512-Iq4ko0r4XsgbrF/LunNgHtAGLRRVE2kXonAXQ/MV0mC6jQpMOhW1SvtZja2EhC/kd05++bP78dsqBeIQyYJ6Yg==} + '@rolldown/binding-linux-s390x-gnu@1.1.1': + resolution: {integrity: sha512-1nS1X5z1uMJ369RU25hTpKCFvUwXZp12dIzlzk4S+UxCTcSVGsAE6tzkOSufv/7jnmAtK0ZlrsJxh2fGmsnVSw==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [s390x] os: [linux] libc: [glibc] - '@rolldown/binding-linux-x64-gnu@1.0.3': - resolution: {integrity: sha512-B8m6tD5+/N5FeNQFbKlLA/2yVq9ycQP1SeedyEYYKWBNR3ZQbkvIUcNnDNM03lO1l5F2roiiFJGgvoLLyZXtSg==} + '@rolldown/binding-linux-x64-gnu@1.1.1': + resolution: {integrity: sha512-NwX/wspnq4vYyMFsqbYvzums3ki/Tk8FZbMzMAovPDp3OfLeYKby/D+9osokadXuYEV3OvpeHlwnr/bG8QMixA==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [linux] libc: [glibc] - '@rolldown/binding-linux-x64-musl@1.0.3': - resolution: {integrity: sha512-pSdpdUJHkuCxun9LE7jvgUB9qsRgaiyNNCX7m/AvHTcq67AiT/Yhoxvw5zPfhrM8k/BfP8ce/hMOpthKDpEUow==} + '@rolldown/binding-linux-x64-musl@1.1.1': + resolution: {integrity: sha512-+n46LhDrJFQM+229y4oXtVpj1G50U/+XuHMlpnisFTEXhrg9f/YIjp/HymX+PVJjBEr7XHRs3CFLelV464pqwA==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [linux] libc: [musl] - '@rolldown/binding-openharmony-arm64@1.0.3': - resolution: {integrity: sha512-OXXS3RKJgX2uLwM+gYyuH5omcH8fL1LJs96pZGgtetVCahON57+d4SJHzTgZiOjxgGkSnpXpOsWuPDGAKAigEg==} + '@rolldown/binding-openharmony-arm64@1.1.1': + resolution: {integrity: sha512-qGwEu47zOWYo7LdRHhCWTNhzwGtxXpdY6CERs8QEOqC0PXGGics/e3vHnyEUKt8xK6YkbZXFUCeklrpB6js8ag==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [openharmony] - '@rolldown/binding-wasm32-wasi@1.0.3': - resolution: {integrity: sha512-JTtb8BWFynicNSoPrehsCzBtOKjZ6jhMiPFEmOiuXg1Fl8dn2KHQob+GuPSGR0dryQa1PQJbzjF3dqO/whhjLg==} + '@rolldown/binding-wasm32-wasi@1.1.1': + resolution: {integrity: sha512-qczfgEH8u0wHGGOXtA7UMAybNKuQjjEXairyQaw4WzjiMztfbgatG1h4OKays/smhtwbWltpKCRGtVhU6h40Sg==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [wasm32] - '@rolldown/binding-win32-arm64-msvc@1.0.3': - resolution: {integrity: sha512-gEdFFEN70A/jxb2svrWsN3aDL7OUtmvlOy+6fa2jxG8K0wQ1ZbdeLGnidov6Yu5/733dI5ySfzFlQ/cb0bSz1g==} + '@rolldown/binding-win32-arm64-msvc@1.1.1': + resolution: {integrity: sha512-4psXSh63mSbwJF+mB8/9yfUUEzBiHYcUjxa32EO9ZwKy0Ypwjcg4F10D8SvVXgd+isy2UUUjF9HJJnDu1T/4Gg==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [win32] - '@rolldown/binding-win32-x64-msvc@1.0.3': - resolution: {integrity: sha512-eXB7CHuaQdqmJcc3koCNtNPmT/bj2gc999kUFgBxG8Ac0NdgXc4rkCHhqrgrhN3zddvvvrgzj1e90SuSfmyIXA==} + '@rolldown/binding-win32-x64-msvc@1.1.1': + resolution: {integrity: sha512-MUvC/HLXVjzkQkWiExdVTEEWf0py+GfWm8WKSZsekG3ih6a21iy0BHPF07X3JIf3ifoklZXTIaHTLPBgH1C3dw==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [win32] @@ -3356,144 +3512,287 @@ packages: cpu: [arm] os: [android] + '@rollup/rollup-android-arm-eabi@4.62.0': + resolution: {integrity: sha512-IPIQ55ythEHkfEd9jMEi32OQ7SxURsGA43JI22lj01OLZNt2NUbJX8YUHxkVWyQ6daHPNn0truF5nSj3DQp6YQ==} + cpu: [arm] + os: [android] + '@rollup/rollup-android-arm64@4.61.0': resolution: {integrity: sha512-Bp3JpGP00Vu3f238ivRrjf7z3xSzVPXqCmaJYA9t2c+c8vKYvOzmXF7LkkeUalTEGd6cZcSWe+PFIP3Vy48fRg==} cpu: [arm64] os: [android] + '@rollup/rollup-android-arm64@4.62.0': + resolution: {integrity: sha512-M6s9cr10MibETyo8JsOkq+Lo1+lU6hcvb1MApnUql5qte/5hMEgzlN8/ReIKNfRV8rrqX50W1BX9zoUhC192RA==} + cpu: [arm64] + os: [android] + '@rollup/rollup-darwin-arm64@4.61.0': resolution: {integrity: sha512-zaYIpr670mUmmZ1tVzUFplbQbG7h3Gugx3L5FoqhsC2m/YnLlR1a7zVLmXNPy+iY1tFPEbNG+HHBXZGyId0G5w==} cpu: [arm64] os: [darwin] + '@rollup/rollup-darwin-arm64@4.62.0': + resolution: {integrity: sha512-BqCoMoIbn0keKys+dEAdBa70EtOwV1bEsQCUgU9FdiZmmMge/Zk7LlkYGqbrdHR+Frnt0E1FOanly+rlwvvQzw==} + cpu: [arm64] + os: [darwin] + '@rollup/rollup-darwin-x64@4.61.0': resolution: {integrity: sha512-+P49fvkv2dSoeevUW+lgZ/I2JHSsJCK1Lyjj7Cu6E4UHG4tS9XIefzIjo5qhgELjAclnen1rLzK2PMKJdo+Dyg==} cpu: [x64] os: [darwin] + '@rollup/rollup-darwin-x64@4.62.0': + resolution: {integrity: sha512-SIMzST3VFNXDAbeIWDWiFCNM5qncUBDWaEV7NfE7oZbDt2mgfW4MvbKdbYiGOLoM32gbTv608UMd0XktEYSD7w==} + cpu: [x64] + os: [darwin] + '@rollup/rollup-freebsd-arm64@4.61.0': resolution: {integrity: sha512-l3FAAOyKJXH2ea6KNFN+MMgC/rnE94YGLXs2ehYqDcCoHt1DpvgWX75BhUJxN38XojP7Ul+4H8PRn7EdyqSDrw==} cpu: [arm64] os: [freebsd] + '@rollup/rollup-freebsd-arm64@4.62.0': + resolution: {integrity: sha512-ezjfSQMP7ArdUsbBwbQIfwAlhE84I2iVnzQNCFSveqV42q+BmKlzVpf7mxv5EchLcoWU4y6/heFzVg1F+hodUQ==} + cpu: [arm64] + os: [freebsd] + '@rollup/rollup-freebsd-x64@4.61.0': resolution: {integrity: sha512-VokPN3TSctKj65cyCNPaUh4vMFA8awxOot/0sp+4J7ZlNRKQEhXhawqPwajoi8H5ZFt61i0ugZJuTKXBjGJ17Q==} cpu: [x64] os: [freebsd] + '@rollup/rollup-freebsd-x64@4.62.0': + resolution: {integrity: sha512-9+qTWGW9AZRhnUgwtTwzNwcPlL87ngkeN0LA+q1bADvmY9aNvWaF2TFW8BZgnQPYxpDI7+rMVLivcd4V737TAQ==} + cpu: [x64] + os: [freebsd] + '@rollup/rollup-linux-arm-gnueabihf@4.61.0': resolution: {integrity: sha512-DxH0P3wxm+Yzs/p3zrk9dw1rURu8p0Nv5+MRK/L7OtnLNg5rLZraSBFZ8iUXOd9f2BlhJyEpIZUH/emjq4UJ4g==} cpu: [arm] os: [linux] libc: [glibc] + '@rollup/rollup-linux-arm-gnueabihf@4.62.0': + resolution: {integrity: sha512-T1dMEQhXA/jkJ/jyMIw9IovK8bSUq7A8kLIlvZTb/6YIVsp2zLavr4F3oyllHWo7eIVJRyE5n3tUjQJEbE1IuQ==} + cpu: [arm] + os: [linux] + libc: [glibc] + '@rollup/rollup-linux-arm-musleabihf@4.61.0': resolution: {integrity: sha512-T6ZvMNe84kAz6TBWHC7hGAoEtzP1LWYw/AqayGWEF6uISt3Abk/st06LqRD9THd7Xz3NxzurUpzAuEAUbZf+nw==} cpu: [arm] os: [linux] libc: [musl] + '@rollup/rollup-linux-arm-musleabihf@4.62.0': + resolution: {integrity: sha512-2as0LgT7qQpyceQq6VUJYnumUMUrgGQCWIiDIN9DE0/tglsk6o66uCB4f3djRawAltvfCNLyZZrsqbPA6inCsA==} + cpu: [arm] + os: [linux] + libc: [musl] + '@rollup/rollup-linux-arm64-gnu@4.61.0': resolution: {integrity: sha512-q/4hzvQkDs8b4jIBab1pnLiiM0ayTZsN2amBFPDzuyZxjEd4wDwx0UJFYM3cOZzSf5Kw8fnWSprJzIBMkcR44Q==} cpu: [arm64] os: [linux] libc: [glibc] + '@rollup/rollup-linux-arm64-gnu@4.62.0': + resolution: {integrity: sha512-bVURMg+6eNN9C/yc0aVjooZcwTTtYF4YW3xta5pP0//r3o1V8gXEHXWCndj47w/HhwsFroZrFhR+6uQP5T0n0g==} + cpu: [arm64] + os: [linux] + libc: [glibc] + '@rollup/rollup-linux-arm64-musl@4.61.0': resolution: {integrity: sha512-vvYWX3akdEAY6km+9wAqFDnk6pQsbJKVnj7xawcvs/+fdlYBGp+U+Qq/lLfpIxYIZvZLHMAKD9HLdacSx/r3dw==} cpu: [arm64] os: [linux] libc: [musl] + '@rollup/rollup-linux-arm64-musl@4.62.0': + resolution: {integrity: sha512-Ful8pM/2yYI83PViWdFdpZhdI8HJ5qsXANe5atypbHDf+KIBBDsZsbyy8hbXnULVvW9NsTh5DHwbcBftyLTfiw==} + cpu: [arm64] + os: [linux] + libc: [musl] + '@rollup/rollup-linux-loong64-gnu@4.61.0': resolution: {integrity: sha512-DePa5cqOxDP/Zp0VOXpeWaGew5iIv5DXp9NYbzkX5PFQyWVX9184WCTh3hvr/7lhXo8ZVlbFLkz8+o/q1dU6gA==} cpu: [loong64] os: [linux] libc: [glibc] + '@rollup/rollup-linux-loong64-gnu@4.62.0': + resolution: {integrity: sha512-9Gp/DgrkzfUBmNPVTyPTvay+4xEP7M/clXpj3efXBcm6uTIVIgDg4rqUpqKXvLEuFRVuEpSAOkhgNeecvaZ4Cg==} + cpu: [loong64] + os: [linux] + libc: [glibc] + '@rollup/rollup-linux-loong64-musl@4.61.0': resolution: {integrity: sha512-LV8aWMB8UChglMCEzs7RkN0GsH29RJaLLqwm9fCIjlqwxQTiWAqNcc7wjBkH31hV0PU/yVxGYvrYsgfea2qw6g==} cpu: [loong64] os: [linux] libc: [musl] + '@rollup/rollup-linux-loong64-musl@4.62.0': + resolution: {integrity: sha512-m9tsJz54LUXkSYM8+8PG81B9IKK5r+2T0clMq4QrS16xFosufU7firBDAZEsDheDs7wTlP7h3++S7lMsU955HA==} + cpu: [loong64] + os: [linux] + libc: [musl] + '@rollup/rollup-linux-ppc64-gnu@4.61.0': resolution: {integrity: sha512-QoNSnwQtaeNu5grdBbsL0tt1uyl5EnS8DA8Mr3nluMXbhdQNyhN+G4tBax7VCdxLKj8YJ0/4OO9Ho84jMnJtKA==} cpu: [ppc64] os: [linux] libc: [glibc] + '@rollup/rollup-linux-ppc64-gnu@4.62.0': + resolution: {integrity: sha512-3UvJ5PNVU16aJf6M3tFI24pWzAl2/ynfbyRN3ICyQajK1lSkrnVYNnLz3v04J32qKa0FczJc22zeToc0lr2A3w==} + cpu: [ppc64] + os: [linux] + libc: [glibc] + '@rollup/rollup-linux-ppc64-musl@4.61.0': resolution: {integrity: sha512-/zZp5MKapIIApE8trN8qLGNSiRN9TUoaUZ1cmVu4XnVdd5LQLOXTtyi+vtfUbNnT3iyjzpPqYeKXmvJ+gJGYWw==} cpu: [ppc64] os: [linux] libc: [musl] + '@rollup/rollup-linux-ppc64-musl@4.62.0': + resolution: {integrity: sha512-vRWUAbYLGHBZS6Q8Msb2sfnf1fvJf+47t8l/TwOerM2qArzy+IeNMTHrYLHXh95h8MoatPHI5hhSZNs+mGXKPg==} + cpu: [ppc64] + os: [linux] + libc: [musl] + '@rollup/rollup-linux-riscv64-gnu@4.61.0': resolution: {integrity: sha512-RbrzcD3aJ1k3UbtMRRBNwojdVVyXjuVAFTfn/xPa6EEl6GE9Sm/akPgFTb9aAC9pMKGJ6CtWxaGrqWcabH+ySg==} cpu: [riscv64] os: [linux] libc: [glibc] + '@rollup/rollup-linux-riscv64-gnu@4.62.0': + resolution: {integrity: sha512-c00T5SYENHAt86cfW47URaP3Us5vLC/4QO7GYud1G5VNRffCwwCuBspwqYrriuJB+5m0WFzClCn9wed0FBjKvg==} + cpu: [riscv64] + os: [linux] + libc: [glibc] + '@rollup/rollup-linux-riscv64-musl@4.61.0': resolution: {integrity: sha512-ZF+onDsBso8PJf1XaG9lB+O9RnBpKGnY6OrzC4CSHrtC1jb6jWLTKK4bRqdoCXHd22gyr2hiYmEAm8Wns/BOCw==} cpu: [riscv64] os: [linux] libc: [musl] + '@rollup/rollup-linux-riscv64-musl@4.62.0': + resolution: {integrity: sha512-krrCDilhXOwFkSkO3Wm9I/f9H0L92XHHwy2fwxjukxIbh0dem8gZqOW5Y8BsHrpJv5qwlRBV+Wl4ZFyRWhUpwg==} + cpu: [riscv64] + os: [linux] + libc: [musl] + '@rollup/rollup-linux-s390x-gnu@4.61.0': resolution: {integrity: sha512-Atk0aSIk5Zx2Wuh9dgRQgLP0Koc8hOeYpbWryMXyk8G8/HmPkwPPkMqIIDhrXHHYqfUzSJA/I7IWSBv8xSmRBA==} cpu: [s390x] os: [linux] libc: [glibc] + '@rollup/rollup-linux-s390x-gnu@4.62.0': + resolution: {integrity: sha512-7pfYFSTc4/rUC/FtAI0Qp6QthDBCIi6/AuP1xYqFk5vanI6KnL5dWKP60OM/05LOsbwTmIcvr6eXC4CJuJ75IA==} + cpu: [s390x] + os: [linux] + libc: [glibc] + '@rollup/rollup-linux-x64-gnu@4.61.0': resolution: {integrity: sha512-0uMOcf3eZ5K+K4cYHkdxShFMPlPXCOdfDFEFn9dNYAEEd2cVvmOfH7zFgRVoDgmtQ1m9k5q7qfrHzyMAubKYUA==} cpu: [x64] os: [linux] libc: [glibc] + '@rollup/rollup-linux-x64-gnu@4.62.0': + resolution: {integrity: sha512-7SDIalKeIpG0Ifogbbdn58HmSotYMlf23K3dCJEmiVd9Fg36Vmni82iPQec27N3wY4Bvbxftkxz6vSx9OcouTg==} + cpu: [x64] + os: [linux] + libc: [glibc] + '@rollup/rollup-linux-x64-musl@4.61.0': resolution: {integrity: sha512-mvFtE4A/t/7hRJ7X8Ozmu8FsIkAUat2nzl12pgU337BRmq87AQUJztwHz2Zv5/tjo9/C95E66CK03SI/ToEDJw==} cpu: [x64] os: [linux] libc: [musl] + '@rollup/rollup-linux-x64-musl@4.62.0': + resolution: {integrity: sha512-eRZevouTH2i1HeAVLqJuLnt256krQkGY0TN6WsTmsIhuzbh457HuWDMakKwmi0Cjadux983CoSr8Lim2QhUIFw==} + cpu: [x64] + os: [linux] + libc: [musl] + '@rollup/rollup-openbsd-x64@4.61.0': resolution: {integrity: sha512-z9b9+aTxvt8n2rNltMPvyaUfB8NJ+CVyOrGK/MdIKHx7B+lXmZpm/XbRsU7Rpf3fRqJ2uS6mBJiJveCtq8LHDg==} cpu: [x64] os: [openbsd] + '@rollup/rollup-openbsd-x64@4.62.0': + resolution: {integrity: sha512-3oVS7FLGa4U1qcvao9ylGxrjXZyUQqR8UwxEcnUEyPX53O/C/mKDZegNXTdHCP+h3e6ta/f1EN38Yif1mmZHYg==} + cpu: [x64] + os: [openbsd] + '@rollup/rollup-openharmony-arm64@4.61.0': resolution: {integrity: sha512-jXaXFqKMehsOc+g8R6oo33RRC6w07G9jDBxAE5eAKX7mOcCbZloYIPNhfG9Wl+P9O9IWHFO4OJgPi1Ml2qkt7w==} cpu: [arm64] os: [openharmony] + '@rollup/rollup-openharmony-arm64@4.62.0': + resolution: {integrity: sha512-yTB9TgfWj5wHe5QgktAgXTLLot1gvEjl1NiPPAUiCs4oPrIWFl5V4nC3GrkNdj9LaAU4s94nVrGbGOCqUpyWsg==} + cpu: [arm64] + os: [openharmony] + '@rollup/rollup-win32-arm64-msvc@4.61.0': resolution: {integrity: sha512-OXNWVFocS2IA4+QplhTZZ2a+8hPZR7T8KuozsNmJKK8y7cp83StHvGksfHzPG3wczWTczyWHVQuqeiTUbjiyBg==} cpu: [arm64] os: [win32] + '@rollup/rollup-win32-arm64-msvc@4.62.0': + resolution: {integrity: sha512-5LOhoaesY3doG1c+ac/2JtgREpKoJr5bUHH8tKY0V8di7+uSV6BwLs2PlR0/yzefGOkR+wE7ZolZphHCsyG5Rw==} + cpu: [arm64] + os: [win32] + '@rollup/rollup-win32-ia32-msvc@4.61.0': resolution: {integrity: sha512-AlAbNtBO637LxSldqV43z0FfXoGfl2TW1DgAg/bs7aQswFbDewz2SJm3BUhiGfbOVtW571xbc9p+REdxhyN/Eg==} cpu: [ia32] os: [win32] + '@rollup/rollup-win32-ia32-msvc@4.62.0': + resolution: {integrity: sha512-yYkWHhmbhRTWTnWos5HC4GcPQfjlzzCNbM9e/+GXrLuaBXYA3qSDR9f0Vgufd5S8yX81U8jPKp7ZnAjZFMtRnw==} + cpu: [ia32] + os: [win32] + '@rollup/rollup-win32-x64-gnu@4.61.0': resolution: {integrity: sha512-QRSrQXyJ1M4tjNXdR0/G/IgV6lzfQQJYBjlWIEYkY2Xs86DRl/iEpQ4blMDjJxSl7n19eDKKXMg0AmuBVYy8pQ==} cpu: [x64] os: [win32] + '@rollup/rollup-win32-x64-gnu@4.62.0': + resolution: {integrity: sha512-SoTb6lPg25xZlA2ibwQ++ahCCnH+FP0qmEuafMJ4gznZKOlXioKEAeJLgCrqjM98ACziXM9V1amFjICVL4IFoA==} + cpu: [x64] + os: [win32] + '@rollup/rollup-win32-x64-msvc@4.61.0': resolution: {integrity: sha512-tkuFxhvKO/HlGd0VsINF6vHSYH8AF8W0TcNxKDK6JZmrehngFj78pToc8iemtnvwilDjs2G/qSzYFhe9U8q+fw==} cpu: [x64] os: [win32] + '@rollup/rollup-win32-x64-msvc@4.62.0': + resolution: {integrity: sha512-5L+T1fMX4RIEBoZzT0+sQ0PhTS36NULFmMXtl1TZo44TMAROIMHbZufSOjVWt/Y622BtxgxtaNOokbTDvfsrZA==} + cpu: [x64] + os: [win32] + '@rollup/wasm-node@4.61.0': resolution: {integrity: sha512-UpYM5v/7Quee4u+VWHuNSgSlvIEQMQL7T/jEaOuaNJQ+JJcqSVvcqN6s1cLiDH5DuJMWRqJzvaCnyexp/UGftQ==} engines: {node: '>=18.0.0', npm: '>=8.0.0'} hasBin: true + '@rollup/wasm-node@4.62.0': + resolution: {integrity: sha512-TW5f2b5d8Y1DwilaxaXhPkYI1a+i1Am2+eDEf6Tu/QrPxt6kdh/4HT6y460MmzE1im71rudvEs5zLLFr7qBAtQ==} + engines: {node: '>=18.0.0', npm: '>=8.0.0'} + hasBin: true + '@rtsao/scc@1.1.0': resolution: {integrity: sha512-zt6OdqaDoOnJ1ZYsCYGt9YmWzDXl4vQdKTyJev62gFhRGKdx7mcT54V9KIjg+d2wi9EXsPvAPKe7i7WjfVWB8g==} @@ -3778,39 +4077,39 @@ packages: '@types/yarnpkg__lockfile@1.1.9': resolution: {integrity: sha512-GD4Fk15UoP5NLCNor51YdfL9MSdldKCqOC9EssrRw3HVfar9wUZ5y8Lfnp+qVD6hIinLr8ygklDYnmlnlQo12Q==} - '@typescript-eslint/eslint-plugin@8.60.1': - resolution: {integrity: sha512-JQ4S5GB0tfjO8BuJ4fcX+HodkzJjYBV+7OJ+wLygaX7OGQ7FudyHL4NSCA6ob+w3Yn+5MkKIozOwQhXeM7opVg==} + '@typescript-eslint/eslint-plugin@8.61.0': + resolution: {integrity: sha512-bFNvl9ZczlVb+wR2Akszf3gHfKVj/8WanXaGJ3UstTA7brNKg0cNdk6X1Psu5V7MZ2oQtzZKOEzIUehaoxbDGw==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: - '@typescript-eslint/parser': ^8.60.1 + '@typescript-eslint/parser': ^8.61.0 eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 typescript: '>=4.8.4 <6.1.0' - '@typescript-eslint/parser@8.60.1': - resolution: {integrity: sha512-A0M6ua6H252bVjPvvtSgl2QA4+ET9S5Mtkb2GDyTxIhH/C4qDItT7RQNO5PhMC6NXGYXOR9dIalcDDgBKT7oFA==} + '@typescript-eslint/parser@8.61.0': + resolution: {integrity: sha512-5B7PfA2e1NQGCnDHd/0lW7W3gvp3d59Ryw54FYO8Uswxo9f6ikw3AZV+Xj/TvpImmpsiYyUqAfhC6kJID1jF6w==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 typescript: '>=4.8.4 <6.1.0' - '@typescript-eslint/project-service@8.60.1': - resolution: {integrity: sha512-eXkTH2bxmXlqD1RnOPmLZ9ZM9D3VwSx04JOwBnP9RQ+yUA5a2Mu7SfW8uaV2Aon53NJzZlZYuX7tn91Izf+xaw==} + '@typescript-eslint/project-service@8.61.0': + resolution: {integrity: sha512-DV42F7MLJO6Rax7SK1yg43tcnEfGUrurSpSxKuVX+a3RCTzBlH3fuxprrOJXKCJGAaw82xXocikJ0uQaqwXgGA==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: typescript: '>=4.8.4 <6.1.0' - '@typescript-eslint/scope-manager@8.60.1': - resolution: {integrity: sha512-gvI5OQoptnxQnchOirukCuQ55svJSTuD/4k5+pC267xyBtYry748R9/c3tYUzb/iE6RZfllRz2lVulLCHkTm4w==} + '@typescript-eslint/scope-manager@8.61.0': + resolution: {integrity: sha512-IWdXFHFSb6mlC3HPc7QsLDm5zYEbUla6trDEHf32D3/dnuUyXd87plScSNXSbm0/RxMvObpI17sv/EDTGrGZkA==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@typescript-eslint/tsconfig-utils@8.60.1': - resolution: {integrity: sha512-nh8w4qAteiKuZu3pSSzG/yGKpw0OlkrKnzFmbVRenKaD4qc+7i1GrmZaLVkr8rk4uipiPGMOW4YsM6WmKZ5CvA==} + '@typescript-eslint/tsconfig-utils@8.61.0': + resolution: {integrity: sha512-O5Amvdv9ztMpxpf+vmFULGG78IE6Qwdr3bCGvqwG4nwc9H2qXkOYJJnRbRHyMkQTjv1d03olqwwwzHLMqpFePQ==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: typescript: '>=4.8.4 <6.1.0' - '@typescript-eslint/type-utils@8.60.1': - resolution: {integrity: sha512-sdwTrpjosW7ANQYJ39ZBF1ZyEMEGVB2UsikrserVM/30a/F1dTLnu9bGxEdosugyu5caigjLrR2qiD11asjI1A==} + '@typescript-eslint/type-utils@8.61.0': + resolution: {integrity: sha512-TuBiQYIkd97yBfInHCTKVYMbX4kvEmpOEuixIuzCU9p8BGT1SfyyO0d0IfDMbPIHcjn/hWnusUX5e8v5Xg+X8A==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 @@ -3820,21 +4119,25 @@ packages: resolution: {integrity: sha512-4h0tY8ppCkdCzcrl2YM5M3my0xsE1Tf8om3owEu5oPWmXwkKRmk0j0LGDzYBGUcAlesEbxBhazqu/K4cu3Ug7w==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@typescript-eslint/typescript-estree@8.60.1': - resolution: {integrity: sha512-alpRkfG8hlVE5kdJW2GkfgDgXxold3e8e4l6EnmhRmRLbekgAPCCGDVD++sABy9FcgPFroq+uFcCSM1vR57Cew==} + '@typescript-eslint/types@8.61.0': + resolution: {integrity: sha512-9QTQpZ5Iin4CdIodfbDQFSeiSJKidgYJYug1P9CC2xWgUTvlmixViqDZNciMjwLBZyJnG4tGmPl97rVAFb1AJg==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@typescript-eslint/typescript-estree@8.61.0': + resolution: {integrity: sha512-42zatd5qSvvcV1JdDBCLxYRznvP4eIHpPoZXdkPFnAmanA4FuZ5dibSnCBggY8hQnqajPpoGjXFdZ7fIJKQnlA==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: typescript: '>=4.8.4 <6.1.0' - '@typescript-eslint/utils@8.60.1': - resolution: {integrity: sha512-h2MPBLoNtjc3qZWfY3Tl51yPorQ2McHn8pJfcMNTcIvrrZrr90Ykffit0yjrPFWQcRcUxzH20+6OcVdW4yHtUg==} + '@typescript-eslint/utils@8.61.0': + resolution: {integrity: sha512-3bzFt7ImFMW/jVYwJamDoe/dMOdFLSC6pom6rRjdh4SZJEYupyMzem8e7vKZLclLfpHjlwSAXOUxtKxGXUiLqA==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 typescript: '>=4.8.4 <6.1.0' - '@typescript-eslint/visitor-keys@8.60.1': - resolution: {integrity: sha512-EbGRQg4FhrmwLodl+t3JNAnXHWVr9Vp+Zl1QBZVPY4ByfkzIT8cX3K6QWODHtkIZqqJVEWvhHSx3v5PDHsaQag==} + '@typescript-eslint/visitor-keys@8.61.0': + resolution: {integrity: sha512-QVLZu3ZPQEE+HICQyAMZ2yLQhxf0meY/wx6Hx14YcTNj13JB3qHlX3lJ02L3fLGHgERRH71kvYDwiXIguT3AjQ==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} '@verdaccio/auth@8.0.2': @@ -3918,20 +4221,20 @@ packages: peerDependencies: vite: ^6.0.0 || ^7.0.0 || ^8.0.0 - '@vitest/coverage-v8@4.1.8': - resolution: {integrity: sha512-lt3kovsyHwYe00wq4D1ti0Z974fWj4NLp6siqiyEufUpyFwK9Yhi7rBhac9JL5aA0zoMrJqc4vYPZRUnI7l7nw==} + '@vitest/coverage-v8@4.1.9': + resolution: {integrity: sha512-G9/lgqibheLVBDRuya45EbsEXTYcWoSG+TLg7i2axuzx0Eq62eXn+aWXyaVdV5vKvFSWd6ywcX8hA7la9Pvu8g==} peerDependencies: - '@vitest/browser': 4.1.8 - vitest: 4.1.8 + '@vitest/browser': 4.1.9 + vitest: 4.1.9 peerDependenciesMeta: '@vitest/browser': optional: true - '@vitest/expect@4.1.8': - resolution: {integrity: sha512-h3nDO677RDLEGlBxyQ5CW8RlMThSKSRLUePLOx09gNIWRL40edgA1GCZSZgf1W55MFAG6/Sw14KeaAnqv0NKdQ==} + '@vitest/expect@4.1.9': + resolution: {integrity: sha512-vl/rYsUKcBr3SnQn166+XR5ZQcgMx3DQhFWdfli/cWpLnLUmbxZvyrJZotLFUryib+LtArYMSTJ5RbQ57ZqrlA==} - '@vitest/mocker@4.1.8': - resolution: {integrity: sha512-LEiN/xe4OSIbKe9HQIp5OC24agGD9J5CnmMgsLohVVoOPWL9a2sBoR6VBx43jQZb7Kr1l4RCuyCJzcAa0+dojw==} + '@vitest/mocker@4.1.9': + resolution: {integrity: sha512-EVkXzBjrPGM+cK8/ANWgBrkUCfJfb38/EfTSO8h7pWvKkyPkpWxvR7BkD2MyItMF62C97zAEoqdpUixwR/e+Rw==} peerDependencies: msw: ^2.4.9 vite: ^6.0.0 || ^7.0.0 || ^8.0.0 @@ -3941,20 +4244,20 @@ packages: vite: optional: true - '@vitest/pretty-format@4.1.8': - resolution: {integrity: sha512-9GasEBxpZ1VYIpqHf/0+YGg121uSNwCKOJqIrTwWP/TB7DmFCiaBpNl3aPZzoLWfWkuqhbH8vJIVobZkvdo2cA==} + '@vitest/pretty-format@4.1.9': + resolution: {integrity: sha512-s0iufns3iIFitdgm+YR7g1whCAaGtXz459VS9/PqyKDEEFgYIhsHOQmXgIgDuYCt7DeQmiZT0Qe2OA2p4ZPu5A==} - '@vitest/runner@4.1.8': - resolution: {integrity: sha512-EmVxeBAfMJvycdjd6Hm+RbFBbA9fKvo0Kx37hNpBYoYeavH3RNsBXWDooR1mgD52dCrxIIuP7UotpfiwOikvcg==} + '@vitest/runner@4.1.9': + resolution: {integrity: sha512-KXLMDtc7oe70+3mJfGrPUWPesswH+3sTxAMAMl8DG7I8IUQT4XW718dY5ID3vPUcmlu27CcKfY4P3h3I29SLJg==} - '@vitest/snapshot@4.1.8': - resolution: {integrity: sha512-acfZboRmAIf05DEKcBQy33VXojFJjtUdLyo7oOmV9kebb2xdU01UknNiPuPZoJZQyO7DF0gZdTGTpeAzET9QPQ==} + '@vitest/snapshot@4.1.9': + resolution: {integrity: sha512-Jc7RKGNBo8Z28WYIm0Niej4xdSPByRf6mU58VpHQkd6Zh05rlnA+twjbK5HyeIGHxrzsc3mJgS43uM0CZKzaIA==} - '@vitest/spy@4.1.8': - resolution: {integrity: sha512-6EevtBp6OZOPF7bmz36HrGMeP3txgVSrgebWxHOafDXGkhIzfXK14f8KF6MuFfgXXUeHxmpD3BQxkV00/3s5mA==} + '@vitest/spy@4.1.9': + resolution: {integrity: sha512-fHpsS6mIi+PiEW+vcRVOMkX1oSaPKne3VOclSFICPcGOmfKgXPU5iAah+wcNcj2xPrCCmfq99IDGf+EojhhvhA==} - '@vitest/utils@4.1.8': - resolution: {integrity: sha512-uOJamYALNhfJ6iolExyQM40yIQwDqYnkKtQ5VCiSe17E33H0aQ/u+1GlRuz4LZBk6Mm3sg90G9hEbmEt37C1Zg==} + '@vitest/utils@4.1.9': + resolution: {integrity: sha512-A51o8ymO5PpqlWNnBP9ZHPXDIpuMtTLlGSjN7la4US+LJzoUMyhwjA5QXlm39JexgwHKW4Xjs8Z2d3dLCXOeuA==} '@webassemblyjs/ast@1.14.1': resolution: {integrity: sha512-nuBEDgQfm1ccRp/8bCQrx1frohyufl4JlbMMZ4P1wpeOfDhF6FQkxZJ1b/e+PLwr6X1Nhw6OLme5usuBWYBvuQ==} @@ -4091,8 +4394,8 @@ packages: ajv@8.20.0: resolution: {integrity: sha512-Thbli+OlOj+iMPYFBVBfJ3OmCAnaSyNn4M1vz9T6Gka5Jt9ba/HIR56joy65tY6kx/FCF5VXNB819Y7/GUrBGA==} - algoliasearch@5.53.0: - resolution: {integrity: sha512-OGW1q6b91CRSSeiOnM8LxuR5NYJ2esvw66jUZ4IIvdv+ItNkx3pwLuyR+jaCdbGee4ov5WgUnyPryyh11xvByQ==} + algoliasearch@5.54.0: + resolution: {integrity: sha512-APAX4ajIOgsmYoUlGe++oNZkSTBgmXYM4maHC0OxC+Yo7xkaKQElV0ATZYCZA7jzrSJX1OBiqEs7mk+ZxXgYqA==} engines: {node: '>= 14.0.0'} ansi-colors@4.1.3: @@ -5057,8 +5360,8 @@ packages: resolution: {integrity: sha512-w+5mJ3GuFL+NjVtJlvydShqE1eN3h3PbI7/5LAsYJP/2qtuMXjfL2LpHSRqo4b4eSF5K/DH1JXKUAHSB2UW50g==} engines: {node: '>= 0.4'} - esbuild-wasm@0.28.0: - resolution: {integrity: sha512-5TRVKExcEmeMkccIZMzUq+Az6X2RoMAJyfl6SMMO1dMVhmvt0I2mx7gAb6zYi42n4d1ETcatFXazGKzA+aW7fg==} + esbuild-wasm@0.28.1: + resolution: {integrity: sha512-p/GD4E8oYRjg3kjdKrnMb0s4PzXgJF42e0MF4H0+ACyK/kIlFRp3e0fzOleIG+wBBm6MM3XQrbpe7soEA+vJIA==} engines: {node: '>=18'} hasBin: true @@ -5072,6 +5375,11 @@ packages: engines: {node: '>=18'} hasBin: true + esbuild@0.28.1: + resolution: {integrity: sha512-HrJrvZv5ayxBzPfwphOoNzkzOIIlifzk0KJrGK2c8R4+LKpMtpYLQeUdjnwjWv/LZlkH2laZk+4w78pi99D4Vw==} + engines: {node: '>=18'} + hasBin: true + escalade@3.2.0: resolution: {integrity: sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==} engines: {node: '>=6'} @@ -5143,8 +5451,8 @@ packages: resolution: {integrity: sha512-tD40eHxA35h0PEIZNeIjkHoDR4YjjJp34biM0mDvplBe//mB+IHCqHDGV7pxF+7MklTvighcCPPZC7ynWyjdTA==} engines: {node: ^20.19.0 || ^22.13.0 || >=24} - eslint@10.4.1: - resolution: {integrity: sha512-AyIKhnOBuOAdueD7RB3xB+YeAWScb9jHsJBgH2Hcde8InP5JYhqrRR6iTMHyTEwgENK54Cp44e4v8BwNhsuHuw==} + eslint@10.5.0: + resolution: {integrity: sha512-1y+7C+vi12bUK1IpZeaV3gsH9fHLBmPvYmPx42pvT/E9yG0IC8g3PUZZgp0+JLJl7ZDK0flc2gc+Aw9dpCvIsQ==} engines: {node: ^20.19.0 || ^22.13.0 || >=24} hasBin: true peerDependencies: @@ -5685,8 +5993,8 @@ packages: '@types/express': optional: true - http-proxy-middleware@4.0.0: - resolution: {integrity: sha512-wuHwaUtmC0XzJNHqRp41zXtt5ojpHbusXGhq6781VvnjWUYPu7opmOF3eomGNujT07kEOnHWZyV9UZzKimVCKA==} + http-proxy-middleware@4.1.1: + resolution: {integrity: sha512-KX5ZofGXLFXqFAkQoOWZ+rTtaLTut7m0gyL+QzJrdejtIZ+F4bPPDoe7reISg2+v0CAz5OfVwEJEhty7X+e57g==} engines: {node: ^22.15.0 || ^24.0.0 || >=26.0.0} http-proxy@1.18.1: @@ -5712,8 +6020,8 @@ packages: resolution: {integrity: sha512-vK9P5/iUfdl95AI+JVyUuIcVtd4ofvtrOr3HNtM2yxC9bnMbEdp3x01OhQNnjb8IJYi38VlTE3mBXwcfvywuSw==} engines: {node: '>= 14'} - https-proxy-agent@9.0.0: - resolution: {integrity: sha512-/MVmHp58WkOypgFhCLk4fzpPcFQvTJ/e6LBI7irpIO2HfxUbpmYoHF+KzipzJpxxzJu7aJNWQ0xojJ/dzV2G5g==} + https-proxy-agent@9.1.0: + resolution: {integrity: sha512-ag87y7cJJ9/3+GxFr8Oy4O5faDsGRGnBGsJj/YjOSsSx/5eadKLYTMPlzuR6obgoCDDm0abAAZitXXQkMOPSpA==} engines: {node: '>= 20'} httpxy@0.5.3: @@ -6078,9 +6386,6 @@ packages: jasmine-core@4.6.1: resolution: {integrity: sha512-VYz/BjjmC3klLJlLwA4Kw8ytk0zDSmbbDLNs794VnWmkcCB7I9aAL/D48VNQtmITyPvea2C3jdUMfc3kAoy0PQ==} - jasmine-core@6.2.0: - resolution: {integrity: sha512-b16WZG/pFEFj8qRW1ss7nDuNGYz9ji8BDGj7fJNrROauk5rj/diO3KPOuyIpcgUChdC+c0PfQ8iUk4nHE+EN4w==} - jasmine-core@6.3.0: resolution: {integrity: sha512-eMm5qBovNjNoGOcgE/W207+wrcK5zrQv0Rg/rWGboUJUmZp0dFCpHTyjpuDAfCwRCqg7f9U2q2jtv/aUuzdCQg==} @@ -6090,10 +6395,6 @@ packages: jasmine-spec-reporter@7.0.0: resolution: {integrity: sha512-OtC7JRasiTcjsaCBPtMO0Tl8glCejM4J4/dNuOJdA8lBjz4PmWjYQ6pzb0uzpBNAWJMDudYuj9OdXJWqM2QTJg==} - jasmine@6.2.0: - resolution: {integrity: sha512-dvYt7bidcu0JvvSbiUnSDW7UQQiflUwDr6C+5wzoZ0J7RY9u+UcoSIzyhMPj6fnU/tC7KinJ5QrjwD2Y9p4T4w==} - hasBin: true - jasmine@6.3.0: resolution: {integrity: sha512-u6L7yYtrtS1JALlp7f4k7Wz7o7ZKXauSKKkXc0L3qUkKrdaxYvNiMHhHp5gtTuVZZXVihXRxS7bWwDBX1wJ7EQ==} hasBin: true @@ -6269,6 +6570,11 @@ packages: engines: {node: '>=18'} hasBin: true + less@4.6.6: + resolution: {integrity: sha512-ooPSwQGQ2sVe8Dh1jVsbKKsRR2gd8lFK72BDkeSzjnD1T5aIHL65hCMfO0GVmtriKgDKrQv6xp9UrihUsWuAzA==} + engines: {node: '>=18'} + hasBin: true + levn@0.4.1: resolution: {integrity: sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==} engines: {node: '>= 0.8.0'} @@ -6405,6 +6711,10 @@ packages: resolution: {integrity: sha512-hXdUTZYIVOt1Ex//jAQi+wTZZpUpwBj/0QsOzqegb3rGMMeJiSEu5xLHnYfBrRV4RH2+OCSOO95Is/7x1WJ4bw==} engines: {node: '>=10'} + make-dir@5.1.0: + resolution: {integrity: sha512-IfpFq6UM39dUNiphpA6uDezNx/AvWyhwfICWPR3t1VspkgkMZrL+Rk1RbN1bx+aeNYwOrqGJgEgV3yotk+ZUVw==} + engines: {node: '>=18'} + make-fetch-happen@15.0.6: resolution: {integrity: sha512-Je0fLJ0F5atA7F+eIlLzk+Wkcl57JDf4kf+EW8xiP5E31xOQxkIxTbgf1Oi1Lw9tRI9UEMRdI5Vz2xTzoNU1Jw==} engines: {node: ^20.17.0 || >=22.9.0} @@ -6890,8 +7200,8 @@ packages: package-json-from-dist@1.0.1: resolution: {integrity: sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==} - pacote@21.5.0: - resolution: {integrity: sha512-VtZ0SB8mb5Tzw3dXDfVAIjhyVKUHZkS/ZH9/5mpKenwC9sFOXNI0JI7kEF7IMkwOnsWMFrvAZHzx1T5fmrp9FQ==} + pacote@21.5.1: + resolution: {integrity: sha512-KvcJ9iy3crysCsgqc4+PknH/w6jkrp8JN36mpZBPwNaDRwTfMZD37YzRazNstiZUOhuF5pno9f78n9mEJBavwg==} engines: {node: ^20.17.0 || >=22.9.0} hasBin: true @@ -7007,6 +7317,10 @@ packages: resolution: {integrity: sha512-7uU4ZnKeQq22t9AsmHGD2w4OYQGonwFnTypDypaWi7Qr2EvQIFVtG8J5D/3bE7W123Wdc9+v4CZDu5hJXVCtBg==} engines: {node: '>=20.x'} + piscina@5.2.0: + resolution: {integrity: sha512-DszUCKeVN/5G5QKo6jAVHL8fmKnkJvQ0ACiVgY7YGCq3TUB2oznAOayvZPIAdEThvhczkXR+qm3IHsNXpFCYfA==} + engines: {node: '>=20.x'} + pkce-challenge@5.0.1: resolution: {integrity: sha512-wQ0b/W4Fr01qtpHlqSqspcj3EhBvimsdh0KlHhH8HRZnMsEa0ea2fTULOXOS9ccQr3om+GcGRk4e+isrZWV8qQ==} engines: {node: '>=16.20.0'} @@ -7138,6 +7452,15 @@ packages: resolution: {integrity: sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==} engines: {node: '>= 0.10'} + proxy-agent-negotiate@1.1.0: + resolution: {integrity: sha512-N8IBcM3UgCVzz2L2Lqv8DVntDnnC8/hiV4nEDUPkqq72TPUgYWjQc+bdZlBPZK9LzPAvOY//gAt0S0DApoOXWQ==} + engines: {node: '>= 20'} + peerDependencies: + kerberos: ^2.0.0 + peerDependenciesMeta: + kerberos: + optional: true + prr@1.0.1: resolution: {integrity: sha512-yPw4Sng1gWghHQWj0B3ZggWUm4qVbPwPFcRG8KyxiU7J2OHFSoEHKS+EZ3fv5l1t9CyCiop6l/ZYeWbrgoQejw==} @@ -7336,8 +7659,8 @@ packages: resolution: {integrity: sha512-l0OE8wL34P4nJH/H2ffoaniAokM2qSmrtXHmlpvYr5AVVX8msAyW0l8NVJFDxlSK4u3Uh/f41cQheDVdnYijwQ==} hasBin: true - rolldown@1.0.3: - resolution: {integrity: sha512-i00lAJ2ks1BYr7rjNjKC7BcqAS7nVfiT3QX1SI5aY+AFHblCmaUf9OE9dbdzDvW6dJxbi2ZCZiy9v3CcwOiX3g==} + rolldown@1.1.1: + resolution: {integrity: sha512-IN750c0p+s3jqJIsFLRZrQazmbAB1kkQDTtQjSt/gbS2ywLhlv4R5Shazer0FZKmuo/BsO3/w2UoYnUjuOZqHg==} engines: {node: ^20.19.0 || >=22.12.0} hasBin: true @@ -7367,6 +7690,11 @@ packages: engines: {node: '>=18.0.0', npm: '>=8.0.0'} hasBin: true + rollup@4.62.0: + resolution: {integrity: sha512-nc72Wgq62I7rtDV4izT5/aaS0zxy3kttkinf9586ApknY3jZO9NYsmtc24fUckA0X7Q2v+ML4a15pdUlV5V/jA==} + engines: {node: '>=18.0.0', npm: '>=8.0.0'} + hasBin: true + router@2.2.0: resolution: {integrity: sha512-nLTrUKm2UyiL7rlhapu/Zl45FwNgkZGaCpZbIHajDYgwlJCOzLSk+cIPAnsEqV955GjILJnKbdQC1nVPz+gAYQ==} engines: {node: '>= 18'} @@ -7435,6 +7763,11 @@ packages: engines: {node: '>=20.19.0'} hasBin: true + sass@1.101.0: + resolution: {integrity: sha512-OL3GoQyoUdDt843DpVmDO6y2k1sc5IhUDSpu8XucEI+35neq5QivZ1iuegnpraEVTJXlQGK1gl27zKcTLEPbQw==} + engines: {node: '>=20.19.0'} + hasBin: true + sax@1.6.0: resolution: {integrity: sha512-6R3J5M4AcbtLUdZmRv2SygeVaM7IhrLXu9BmnOGmmACak8fiUtOsYNWUS4uK7upbmHIBbLBeFeI//477BKLBzA==} engines: {node: '>=11.0.0'} @@ -7472,11 +7805,6 @@ packages: engines: {node: '>=10'} hasBin: true - semver@7.8.1: - resolution: {integrity: sha512-rkVq3IXh+4FDGch+KwzX3aV9W3kO54GyEgpvBzSyctDA6Xtd7RJQV1xmXbeQp5v7+VzLOfVqiutSE6GICgPFvg==} - engines: {node: '>=10'} - hasBin: true - semver@7.8.4: resolution: {integrity: sha512-rUCObTnP32Q08R2uuIrt7r9PlEonuTmtuXYcW6s5kjdlj3xbnwe+21yXptAUYcMAABLkYYTtnmzb3w3EDZfueA==} engines: {node: '>=10'} @@ -8088,8 +8416,8 @@ packages: resolution: {integrity: sha512-uZsKNuzQxDMUY6M3pIMvy5tvlGmtq8XJ2oLAkfRKGNu+1VQAIvLy2xIVG5ATZl5wDXl/tddByAWCizRbOme+TA==} engines: {node: '>=20.18.1'} - undici@8.3.0: - resolution: {integrity: sha512-TkUDgb6tl7KOGZ+7e8E3d2FYgUQgF6z5YypqjWmixVQSQERFcVrVg0ySADm2LVLRh5ljAaHTCR5Fmz3Q34rB7Q==} + undici@8.4.1: + resolution: {integrity: sha512-RNHlB4fxZK0IrkhBsxhlbx7s8kFWwr7rzzOqj5nvZugw3ig3RsB7KW3zVlV0eu8POl+rx5d1hmL7rRg0z1owow==} engines: {node: '>=22.19.0'} unenv@1.10.0: @@ -8242,20 +8570,20 @@ packages: yaml: optional: true - vitest@4.1.8: - resolution: {integrity: sha512-flY6ScbCIt9HThs+C5HS7jvGOB560DJtk/Z15IQROTA6zEy49Nh8T/dofWTQL+n3vswqn87sbJNiuqw1SDp5Ig==} + vitest@4.1.9: + resolution: {integrity: sha512-nE3/LEyc0z87uHYLZebqCUOaJr2hdtuPp7BQ4BosVFnfltxgAvMG08NyrSGlPpOUWvR27c5flSmYFTNr78L9GQ==} engines: {node: ^20.0.0 || ^22.0.0 || >=24.0.0} hasBin: true peerDependencies: '@edge-runtime/vm': '*' '@opentelemetry/api': ^1.9.0 '@types/node': ^20.0.0 || ^22.0.0 || >=24.0.0 - '@vitest/browser-playwright': 4.1.8 - '@vitest/browser-preview': 4.1.8 - '@vitest/browser-webdriverio': 4.1.8 - '@vitest/coverage-istanbul': 4.1.8 - '@vitest/coverage-v8': 4.1.8 - '@vitest/ui': 4.1.8 + '@vitest/browser-playwright': 4.1.9 + '@vitest/browser-preview': 4.1.9 + '@vitest/browser-webdriverio': 4.1.9 + '@vitest/coverage-istanbul': 4.1.9 + '@vitest/coverage-v8': 4.1.9 + '@vitest/ui': 4.1.9 happy-dom: '*' jsdom: '*' peerDependenciesMeta: @@ -8294,6 +8622,10 @@ packages: resolution: {integrity: sha512-Zn5uXdcFNIA1+1Ei5McRd+iRzfhENPCe7LeABkJtNulSxjma+l7ltNx55BWZkRlwRnpOgHqxnjyaDgJnNXnqzg==} engines: {node: '>=10.13.0'} + watchpack@2.5.2: + resolution: {integrity: sha512-6i/00NBjP4yGPs+caKSyRfpTF/8Torsu0MOW3mMzIbhgISFder8i7xbqgHlLMwJrdiN8ndBV3UA1/AfzPSr+jg==} + engines: {node: '>=10.13.0'} + wbuf@1.7.3: resolution: {integrity: sha512-O84QOnr0icsbFGLS0O3bI5FswxzRr8/gHwWkDlQFskhSPryQXvrTMxjxGP4+iWYoauLoBvfDpkrOauZ+0iZpDA==} @@ -8335,8 +8667,8 @@ packages: webpack: optional: true - webpack-dev-server@5.2.4: - resolution: {integrity: sha512-GqDPGZN9bRqKBTkp4aWkobDDHMsrXKoGSdOH56smIri8qR0JG8gfL8/v/f/OZR3/OKXjG8uwJbFVhKm/FNU/UA==} + webpack-dev-server@5.2.5: + resolution: {integrity: sha512-4wZtCquSuv9CKX8oybo+mqxtxZqWz47uM1Ch94lxowBztOhWCbhqvRbfC/mODOwxgV2brY+JGZpHq58/SuVFYg==} engines: {node: '>= 18.12.0'} hasBin: true peerDependencies: @@ -8598,89 +8930,89 @@ snapshots: '@actions/io@3.0.2': {} - '@algolia/abtesting@1.19.0': + '@algolia/abtesting@1.20.0': dependencies: - '@algolia/client-common': 5.53.0 - '@algolia/requester-browser-xhr': 5.53.0 - '@algolia/requester-fetch': 5.53.0 - '@algolia/requester-node-http': 5.53.0 + '@algolia/client-common': 5.54.0 + '@algolia/requester-browser-xhr': 5.54.0 + '@algolia/requester-fetch': 5.54.0 + '@algolia/requester-node-http': 5.54.0 - '@algolia/client-abtesting@5.53.0': + '@algolia/client-abtesting@5.54.0': dependencies: - '@algolia/client-common': 5.53.0 - '@algolia/requester-browser-xhr': 5.53.0 - '@algolia/requester-fetch': 5.53.0 - '@algolia/requester-node-http': 5.53.0 + '@algolia/client-common': 5.54.0 + '@algolia/requester-browser-xhr': 5.54.0 + '@algolia/requester-fetch': 5.54.0 + '@algolia/requester-node-http': 5.54.0 - '@algolia/client-analytics@5.53.0': + '@algolia/client-analytics@5.54.0': dependencies: - '@algolia/client-common': 5.53.0 - '@algolia/requester-browser-xhr': 5.53.0 - '@algolia/requester-fetch': 5.53.0 - '@algolia/requester-node-http': 5.53.0 + '@algolia/client-common': 5.54.0 + '@algolia/requester-browser-xhr': 5.54.0 + '@algolia/requester-fetch': 5.54.0 + '@algolia/requester-node-http': 5.54.0 - '@algolia/client-common@5.53.0': {} + '@algolia/client-common@5.54.0': {} - '@algolia/client-insights@5.53.0': + '@algolia/client-insights@5.54.0': dependencies: - '@algolia/client-common': 5.53.0 - '@algolia/requester-browser-xhr': 5.53.0 - '@algolia/requester-fetch': 5.53.0 - '@algolia/requester-node-http': 5.53.0 + '@algolia/client-common': 5.54.0 + '@algolia/requester-browser-xhr': 5.54.0 + '@algolia/requester-fetch': 5.54.0 + '@algolia/requester-node-http': 5.54.0 - '@algolia/client-personalization@5.53.0': + '@algolia/client-personalization@5.54.0': dependencies: - '@algolia/client-common': 5.53.0 - '@algolia/requester-browser-xhr': 5.53.0 - '@algolia/requester-fetch': 5.53.0 - '@algolia/requester-node-http': 5.53.0 + '@algolia/client-common': 5.54.0 + '@algolia/requester-browser-xhr': 5.54.0 + '@algolia/requester-fetch': 5.54.0 + '@algolia/requester-node-http': 5.54.0 - '@algolia/client-query-suggestions@5.53.0': + '@algolia/client-query-suggestions@5.54.0': dependencies: - '@algolia/client-common': 5.53.0 - '@algolia/requester-browser-xhr': 5.53.0 - '@algolia/requester-fetch': 5.53.0 - '@algolia/requester-node-http': 5.53.0 + '@algolia/client-common': 5.54.0 + '@algolia/requester-browser-xhr': 5.54.0 + '@algolia/requester-fetch': 5.54.0 + '@algolia/requester-node-http': 5.54.0 - '@algolia/client-search@5.53.0': + '@algolia/client-search@5.54.0': dependencies: - '@algolia/client-common': 5.53.0 - '@algolia/requester-browser-xhr': 5.53.0 - '@algolia/requester-fetch': 5.53.0 - '@algolia/requester-node-http': 5.53.0 + '@algolia/client-common': 5.54.0 + '@algolia/requester-browser-xhr': 5.54.0 + '@algolia/requester-fetch': 5.54.0 + '@algolia/requester-node-http': 5.54.0 - '@algolia/ingestion@1.53.0': + '@algolia/ingestion@1.54.0': dependencies: - '@algolia/client-common': 5.53.0 - '@algolia/requester-browser-xhr': 5.53.0 - '@algolia/requester-fetch': 5.53.0 - '@algolia/requester-node-http': 5.53.0 + '@algolia/client-common': 5.54.0 + '@algolia/requester-browser-xhr': 5.54.0 + '@algolia/requester-fetch': 5.54.0 + '@algolia/requester-node-http': 5.54.0 - '@algolia/monitoring@1.53.0': + '@algolia/monitoring@1.54.0': dependencies: - '@algolia/client-common': 5.53.0 - '@algolia/requester-browser-xhr': 5.53.0 - '@algolia/requester-fetch': 5.53.0 - '@algolia/requester-node-http': 5.53.0 + '@algolia/client-common': 5.54.0 + '@algolia/requester-browser-xhr': 5.54.0 + '@algolia/requester-fetch': 5.54.0 + '@algolia/requester-node-http': 5.54.0 - '@algolia/recommend@5.53.0': + '@algolia/recommend@5.54.0': dependencies: - '@algolia/client-common': 5.53.0 - '@algolia/requester-browser-xhr': 5.53.0 - '@algolia/requester-fetch': 5.53.0 - '@algolia/requester-node-http': 5.53.0 + '@algolia/client-common': 5.54.0 + '@algolia/requester-browser-xhr': 5.54.0 + '@algolia/requester-fetch': 5.54.0 + '@algolia/requester-node-http': 5.54.0 - '@algolia/requester-browser-xhr@5.53.0': + '@algolia/requester-browser-xhr@5.54.0': dependencies: - '@algolia/client-common': 5.53.0 + '@algolia/client-common': 5.54.0 - '@algolia/requester-fetch@5.53.0': + '@algolia/requester-fetch@5.54.0': dependencies: - '@algolia/client-common': 5.53.0 + '@algolia/client-common': 5.54.0 - '@algolia/requester-node-http@5.53.0': + '@algolia/requester-node-http@5.54.0': dependencies: - '@algolia/client-common': 5.53.0 + '@algolia/client-common': 5.54.0 '@ampproject/remapping@2.3.0': dependencies: @@ -8710,12 +9042,12 @@ snapshots: '@angular/compiler-cli@22.1.0-next.0(@angular/compiler@22.1.0-next.0)(typescript@6.0.3)': dependencies: '@angular/compiler': 22.1.0-next.0 - '@babel/core': 7.29.7 + '@babel/core': 7.29.7(supports-color@10.2.2) '@jridgewell/sourcemap-codec': 1.5.5 chokidar: 5.0.0 convert-source-map: 1.9.0 reflect-metadata: 0.2.2 - semver: 7.8.1 + semver: 7.8.4 tslib: 2.8.1 yargs: 18.0.0 optionalDependencies: @@ -8749,7 +9081,7 @@ snapshots: dependencies: '@angular/compiler': 22.1.0-next.0 '@angular/compiler-cli': 22.1.0-next.0(@angular/compiler@22.1.0-next.0)(typescript@6.0.3) - '@babel/core': 7.29.7 + '@babel/core': 7.29.7(supports-color@10.2.2) '@types/babel__core': 7.20.5 tinyglobby: 0.2.17 yargs: 18.0.0 @@ -8886,7 +9218,7 @@ snapshots: '@babel/compat-data@7.29.7': {} - '@babel/core@7.29.7': + '@babel/core@7.29.7(supports-color@10.2.2)': dependencies: '@babel/code-frame': 7.29.7 '@babel/generator': 7.29.7 @@ -8928,7 +9260,7 @@ snapshots: '@babel/helper-create-class-features-plugin@7.29.7(@babel/core@7.29.7)': dependencies: - '@babel/core': 7.29.7 + '@babel/core': 7.29.7(supports-color@10.2.2) '@babel/helper-annotate-as-pure': 7.29.7 '@babel/helper-member-expression-to-functions': 7.29.7 '@babel/helper-optimise-call-expression': 7.29.7 @@ -8941,14 +9273,14 @@ snapshots: '@babel/helper-create-regexp-features-plugin@7.29.7(@babel/core@7.29.7)': dependencies: - '@babel/core': 7.29.7 + '@babel/core': 7.29.7(supports-color@10.2.2) '@babel/helper-annotate-as-pure': 7.29.7 regexpu-core: 6.4.0 semver: 6.3.1 - '@babel/helper-define-polyfill-provider@0.6.8(@babel/core@7.29.7)': + '@babel/helper-define-polyfill-provider@0.6.8(@babel/core@7.29.7)(supports-color@10.2.2)': dependencies: - '@babel/core': 7.29.7 + '@babel/core': 7.29.7(supports-color@10.2.2) '@babel/helper-compilation-targets': 7.29.7 '@babel/helper-plugin-utils': 7.29.7 debug: 4.4.3(supports-color@10.2.2) @@ -8975,7 +9307,7 @@ snapshots: '@babel/helper-module-transforms@7.29.7(@babel/core@7.29.7)': dependencies: - '@babel/core': 7.29.7 + '@babel/core': 7.29.7(supports-color@10.2.2) '@babel/helper-module-imports': 7.29.7 '@babel/helper-validator-identifier': 7.29.7 '@babel/traverse': 7.29.7 @@ -8990,7 +9322,7 @@ snapshots: '@babel/helper-remap-async-to-generator@7.29.7(@babel/core@7.29.7)': dependencies: - '@babel/core': 7.29.7 + '@babel/core': 7.29.7(supports-color@10.2.2) '@babel/helper-annotate-as-pure': 7.29.7 '@babel/helper-wrap-function': 7.29.7 '@babel/traverse': 7.29.7 @@ -8999,7 +9331,7 @@ snapshots: '@babel/helper-replace-supers@7.29.7(@babel/core@7.29.7)': dependencies: - '@babel/core': 7.29.7 + '@babel/core': 7.29.7(supports-color@10.2.2) '@babel/helper-member-expression-to-functions': 7.29.7 '@babel/helper-optimise-call-expression': 7.29.7 '@babel/traverse': 7.29.7 @@ -9042,7 +9374,7 @@ snapshots: '@babel/plugin-bugfix-firefox-class-in-computed-class-key@7.29.7(@babel/core@7.29.7)': dependencies: - '@babel/core': 7.29.7 + '@babel/core': 7.29.7(supports-color@10.2.2) '@babel/helper-plugin-utils': 7.29.7 '@babel/traverse': 7.29.7 transitivePeerDependencies: @@ -9050,17 +9382,17 @@ snapshots: '@babel/plugin-bugfix-safari-class-field-initializer-scope@7.29.7(@babel/core@7.29.7)': dependencies: - '@babel/core': 7.29.7 + '@babel/core': 7.29.7(supports-color@10.2.2) '@babel/helper-plugin-utils': 7.29.7 '@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression@7.29.7(@babel/core@7.29.7)': dependencies: - '@babel/core': 7.29.7 + '@babel/core': 7.29.7(supports-color@10.2.2) '@babel/helper-plugin-utils': 7.29.7 '@babel/plugin-bugfix-safari-rest-destructuring-rhs-array@7.29.7(@babel/core@7.29.7)': dependencies: - '@babel/core': 7.29.7 + '@babel/core': 7.29.7(supports-color@10.2.2) '@babel/helper-plugin-utils': 7.29.7 '@babel/helper-skip-transparent-expression-wrappers': 7.29.7 transitivePeerDependencies: @@ -9068,7 +9400,7 @@ snapshots: '@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining@7.29.7(@babel/core@7.29.7)': dependencies: - '@babel/core': 7.29.7 + '@babel/core': 7.29.7(supports-color@10.2.2) '@babel/helper-plugin-utils': 7.29.7 '@babel/helper-skip-transparent-expression-wrappers': 7.29.7 '@babel/plugin-transform-optional-chaining': 7.29.7(@babel/core@7.29.7) @@ -9077,7 +9409,7 @@ snapshots: '@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly@7.29.7(@babel/core@7.29.7)': dependencies: - '@babel/core': 7.29.7 + '@babel/core': 7.29.7(supports-color@10.2.2) '@babel/helper-plugin-utils': 7.29.7 '@babel/traverse': 7.29.7 transitivePeerDependencies: @@ -9085,32 +9417,32 @@ snapshots: '@babel/plugin-proposal-private-property-in-object@7.21.0-placeholder-for-preset-env.2(@babel/core@7.29.7)': dependencies: - '@babel/core': 7.29.7 + '@babel/core': 7.29.7(supports-color@10.2.2) '@babel/plugin-syntax-import-assertions@7.29.7(@babel/core@7.29.7)': dependencies: - '@babel/core': 7.29.7 + '@babel/core': 7.29.7(supports-color@10.2.2) '@babel/helper-plugin-utils': 7.29.7 '@babel/plugin-syntax-import-attributes@7.29.7(@babel/core@7.29.7)': dependencies: - '@babel/core': 7.29.7 + '@babel/core': 7.29.7(supports-color@10.2.2) '@babel/helper-plugin-utils': 7.29.7 '@babel/plugin-syntax-unicode-sets-regex@7.18.6(@babel/core@7.29.7)': dependencies: - '@babel/core': 7.29.7 + '@babel/core': 7.29.7(supports-color@10.2.2) '@babel/helper-create-regexp-features-plugin': 7.29.7(@babel/core@7.29.7) '@babel/helper-plugin-utils': 7.29.7 '@babel/plugin-transform-arrow-functions@7.29.7(@babel/core@7.29.7)': dependencies: - '@babel/core': 7.29.7 + '@babel/core': 7.29.7(supports-color@10.2.2) '@babel/helper-plugin-utils': 7.29.7 '@babel/plugin-transform-async-generator-functions@7.29.7(@babel/core@7.29.7)': dependencies: - '@babel/core': 7.29.7 + '@babel/core': 7.29.7(supports-color@10.2.2) '@babel/helper-plugin-utils': 7.29.7 '@babel/helper-remap-async-to-generator': 7.29.7(@babel/core@7.29.7) '@babel/traverse': 7.29.7 @@ -9119,7 +9451,7 @@ snapshots: '@babel/plugin-transform-async-to-generator@7.29.7(@babel/core@7.29.7)': dependencies: - '@babel/core': 7.29.7 + '@babel/core': 7.29.7(supports-color@10.2.2) '@babel/helper-module-imports': 7.29.7 '@babel/helper-plugin-utils': 7.29.7 '@babel/helper-remap-async-to-generator': 7.29.7(@babel/core@7.29.7) @@ -9128,17 +9460,17 @@ snapshots: '@babel/plugin-transform-block-scoped-functions@7.29.7(@babel/core@7.29.7)': dependencies: - '@babel/core': 7.29.7 + '@babel/core': 7.29.7(supports-color@10.2.2) '@babel/helper-plugin-utils': 7.29.7 '@babel/plugin-transform-block-scoping@7.29.7(@babel/core@7.29.7)': dependencies: - '@babel/core': 7.29.7 + '@babel/core': 7.29.7(supports-color@10.2.2) '@babel/helper-plugin-utils': 7.29.7 '@babel/plugin-transform-class-properties@7.29.7(@babel/core@7.29.7)': dependencies: - '@babel/core': 7.29.7 + '@babel/core': 7.29.7(supports-color@10.2.2) '@babel/helper-create-class-features-plugin': 7.29.7(@babel/core@7.29.7) '@babel/helper-plugin-utils': 7.29.7 transitivePeerDependencies: @@ -9146,7 +9478,7 @@ snapshots: '@babel/plugin-transform-class-static-block@7.29.7(@babel/core@7.29.7)': dependencies: - '@babel/core': 7.29.7 + '@babel/core': 7.29.7(supports-color@10.2.2) '@babel/helper-create-class-features-plugin': 7.29.7(@babel/core@7.29.7) '@babel/helper-plugin-utils': 7.29.7 transitivePeerDependencies: @@ -9154,7 +9486,7 @@ snapshots: '@babel/plugin-transform-classes@7.29.7(@babel/core@7.29.7)': dependencies: - '@babel/core': 7.29.7 + '@babel/core': 7.29.7(supports-color@10.2.2) '@babel/helper-annotate-as-pure': 7.29.7 '@babel/helper-compilation-targets': 7.29.7 '@babel/helper-globals': 7.29.7 @@ -9166,13 +9498,13 @@ snapshots: '@babel/plugin-transform-computed-properties@7.29.7(@babel/core@7.29.7)': dependencies: - '@babel/core': 7.29.7 + '@babel/core': 7.29.7(supports-color@10.2.2) '@babel/helper-plugin-utils': 7.29.7 '@babel/template': 7.29.7 '@babel/plugin-transform-destructuring@7.29.7(@babel/core@7.29.7)': dependencies: - '@babel/core': 7.29.7 + '@babel/core': 7.29.7(supports-color@10.2.2) '@babel/helper-plugin-utils': 7.29.7 '@babel/traverse': 7.29.7 transitivePeerDependencies: @@ -9180,29 +9512,29 @@ snapshots: '@babel/plugin-transform-dotall-regex@7.29.7(@babel/core@7.29.7)': dependencies: - '@babel/core': 7.29.7 + '@babel/core': 7.29.7(supports-color@10.2.2) '@babel/helper-create-regexp-features-plugin': 7.29.7(@babel/core@7.29.7) '@babel/helper-plugin-utils': 7.29.7 '@babel/plugin-transform-duplicate-keys@7.29.7(@babel/core@7.29.7)': dependencies: - '@babel/core': 7.29.7 + '@babel/core': 7.29.7(supports-color@10.2.2) '@babel/helper-plugin-utils': 7.29.7 '@babel/plugin-transform-duplicate-named-capturing-groups-regex@7.29.7(@babel/core@7.29.7)': dependencies: - '@babel/core': 7.29.7 + '@babel/core': 7.29.7(supports-color@10.2.2) '@babel/helper-create-regexp-features-plugin': 7.29.7(@babel/core@7.29.7) '@babel/helper-plugin-utils': 7.29.7 '@babel/plugin-transform-dynamic-import@7.29.7(@babel/core@7.29.7)': dependencies: - '@babel/core': 7.29.7 + '@babel/core': 7.29.7(supports-color@10.2.2) '@babel/helper-plugin-utils': 7.29.7 '@babel/plugin-transform-explicit-resource-management@7.29.7(@babel/core@7.29.7)': dependencies: - '@babel/core': 7.29.7 + '@babel/core': 7.29.7(supports-color@10.2.2) '@babel/helper-plugin-utils': 7.29.7 '@babel/plugin-transform-destructuring': 7.29.7(@babel/core@7.29.7) transitivePeerDependencies: @@ -9210,17 +9542,17 @@ snapshots: '@babel/plugin-transform-exponentiation-operator@7.29.7(@babel/core@7.29.7)': dependencies: - '@babel/core': 7.29.7 + '@babel/core': 7.29.7(supports-color@10.2.2) '@babel/helper-plugin-utils': 7.29.7 '@babel/plugin-transform-export-namespace-from@7.29.7(@babel/core@7.29.7)': dependencies: - '@babel/core': 7.29.7 + '@babel/core': 7.29.7(supports-color@10.2.2) '@babel/helper-plugin-utils': 7.29.7 '@babel/plugin-transform-for-of@7.29.7(@babel/core@7.29.7)': dependencies: - '@babel/core': 7.29.7 + '@babel/core': 7.29.7(supports-color@10.2.2) '@babel/helper-plugin-utils': 7.29.7 '@babel/helper-skip-transparent-expression-wrappers': 7.29.7 transitivePeerDependencies: @@ -9228,7 +9560,7 @@ snapshots: '@babel/plugin-transform-function-name@7.29.7(@babel/core@7.29.7)': dependencies: - '@babel/core': 7.29.7 + '@babel/core': 7.29.7(supports-color@10.2.2) '@babel/helper-compilation-targets': 7.29.7 '@babel/helper-plugin-utils': 7.29.7 '@babel/traverse': 7.29.7 @@ -9237,27 +9569,27 @@ snapshots: '@babel/plugin-transform-json-strings@7.29.7(@babel/core@7.29.7)': dependencies: - '@babel/core': 7.29.7 + '@babel/core': 7.29.7(supports-color@10.2.2) '@babel/helper-plugin-utils': 7.29.7 '@babel/plugin-transform-literals@7.29.7(@babel/core@7.29.7)': dependencies: - '@babel/core': 7.29.7 + '@babel/core': 7.29.7(supports-color@10.2.2) '@babel/helper-plugin-utils': 7.29.7 '@babel/plugin-transform-logical-assignment-operators@7.29.7(@babel/core@7.29.7)': dependencies: - '@babel/core': 7.29.7 + '@babel/core': 7.29.7(supports-color@10.2.2) '@babel/helper-plugin-utils': 7.29.7 '@babel/plugin-transform-member-expression-literals@7.29.7(@babel/core@7.29.7)': dependencies: - '@babel/core': 7.29.7 + '@babel/core': 7.29.7(supports-color@10.2.2) '@babel/helper-plugin-utils': 7.29.7 '@babel/plugin-transform-modules-amd@7.29.7(@babel/core@7.29.7)': dependencies: - '@babel/core': 7.29.7 + '@babel/core': 7.29.7(supports-color@10.2.2) '@babel/helper-module-transforms': 7.29.7(@babel/core@7.29.7) '@babel/helper-plugin-utils': 7.29.7 transitivePeerDependencies: @@ -9265,7 +9597,7 @@ snapshots: '@babel/plugin-transform-modules-commonjs@7.29.7(@babel/core@7.29.7)': dependencies: - '@babel/core': 7.29.7 + '@babel/core': 7.29.7(supports-color@10.2.2) '@babel/helper-module-transforms': 7.29.7(@babel/core@7.29.7) '@babel/helper-plugin-utils': 7.29.7 transitivePeerDependencies: @@ -9273,7 +9605,7 @@ snapshots: '@babel/plugin-transform-modules-systemjs@7.29.7(@babel/core@7.29.7)': dependencies: - '@babel/core': 7.29.7 + '@babel/core': 7.29.7(supports-color@10.2.2) '@babel/helper-module-transforms': 7.29.7(@babel/core@7.29.7) '@babel/helper-plugin-utils': 7.29.7 '@babel/helper-validator-identifier': 7.29.7 @@ -9283,7 +9615,7 @@ snapshots: '@babel/plugin-transform-modules-umd@7.29.7(@babel/core@7.29.7)': dependencies: - '@babel/core': 7.29.7 + '@babel/core': 7.29.7(supports-color@10.2.2) '@babel/helper-module-transforms': 7.29.7(@babel/core@7.29.7) '@babel/helper-plugin-utils': 7.29.7 transitivePeerDependencies: @@ -9291,28 +9623,28 @@ snapshots: '@babel/plugin-transform-named-capturing-groups-regex@7.29.7(@babel/core@7.29.7)': dependencies: - '@babel/core': 7.29.7 + '@babel/core': 7.29.7(supports-color@10.2.2) '@babel/helper-create-regexp-features-plugin': 7.29.7(@babel/core@7.29.7) '@babel/helper-plugin-utils': 7.29.7 '@babel/plugin-transform-new-target@7.29.7(@babel/core@7.29.7)': dependencies: - '@babel/core': 7.29.7 + '@babel/core': 7.29.7(supports-color@10.2.2) '@babel/helper-plugin-utils': 7.29.7 '@babel/plugin-transform-nullish-coalescing-operator@7.29.7(@babel/core@7.29.7)': dependencies: - '@babel/core': 7.29.7 + '@babel/core': 7.29.7(supports-color@10.2.2) '@babel/helper-plugin-utils': 7.29.7 '@babel/plugin-transform-numeric-separator@7.29.7(@babel/core@7.29.7)': dependencies: - '@babel/core': 7.29.7 + '@babel/core': 7.29.7(supports-color@10.2.2) '@babel/helper-plugin-utils': 7.29.7 '@babel/plugin-transform-object-rest-spread@7.29.7(@babel/core@7.29.7)': dependencies: - '@babel/core': 7.29.7 + '@babel/core': 7.29.7(supports-color@10.2.2) '@babel/helper-compilation-targets': 7.29.7 '@babel/helper-plugin-utils': 7.29.7 '@babel/plugin-transform-destructuring': 7.29.7(@babel/core@7.29.7) @@ -9323,7 +9655,7 @@ snapshots: '@babel/plugin-transform-object-super@7.29.7(@babel/core@7.29.7)': dependencies: - '@babel/core': 7.29.7 + '@babel/core': 7.29.7(supports-color@10.2.2) '@babel/helper-plugin-utils': 7.29.7 '@babel/helper-replace-supers': 7.29.7(@babel/core@7.29.7) transitivePeerDependencies: @@ -9331,12 +9663,12 @@ snapshots: '@babel/plugin-transform-optional-catch-binding@7.29.7(@babel/core@7.29.7)': dependencies: - '@babel/core': 7.29.7 + '@babel/core': 7.29.7(supports-color@10.2.2) '@babel/helper-plugin-utils': 7.29.7 '@babel/plugin-transform-optional-chaining@7.29.7(@babel/core@7.29.7)': dependencies: - '@babel/core': 7.29.7 + '@babel/core': 7.29.7(supports-color@10.2.2) '@babel/helper-plugin-utils': 7.29.7 '@babel/helper-skip-transparent-expression-wrappers': 7.29.7 transitivePeerDependencies: @@ -9344,12 +9676,12 @@ snapshots: '@babel/plugin-transform-parameters@7.29.7(@babel/core@7.29.7)': dependencies: - '@babel/core': 7.29.7 + '@babel/core': 7.29.7(supports-color@10.2.2) '@babel/helper-plugin-utils': 7.29.7 '@babel/plugin-transform-private-methods@7.29.7(@babel/core@7.29.7)': dependencies: - '@babel/core': 7.29.7 + '@babel/core': 7.29.7(supports-color@10.2.2) '@babel/helper-create-class-features-plugin': 7.29.7(@babel/core@7.29.7) '@babel/helper-plugin-utils': 7.29.7 transitivePeerDependencies: @@ -9357,7 +9689,7 @@ snapshots: '@babel/plugin-transform-private-property-in-object@7.29.7(@babel/core@7.29.7)': dependencies: - '@babel/core': 7.29.7 + '@babel/core': 7.29.7(supports-color@10.2.2) '@babel/helper-annotate-as-pure': 7.29.7 '@babel/helper-create-class-features-plugin': 7.29.7(@babel/core@7.29.7) '@babel/helper-plugin-utils': 7.29.7 @@ -9366,31 +9698,31 @@ snapshots: '@babel/plugin-transform-property-literals@7.29.7(@babel/core@7.29.7)': dependencies: - '@babel/core': 7.29.7 + '@babel/core': 7.29.7(supports-color@10.2.2) '@babel/helper-plugin-utils': 7.29.7 '@babel/plugin-transform-regenerator@7.29.7(@babel/core@7.29.7)': dependencies: - '@babel/core': 7.29.7 + '@babel/core': 7.29.7(supports-color@10.2.2) '@babel/helper-plugin-utils': 7.29.7 '@babel/plugin-transform-regexp-modifiers@7.29.7(@babel/core@7.29.7)': dependencies: - '@babel/core': 7.29.7 + '@babel/core': 7.29.7(supports-color@10.2.2) '@babel/helper-create-regexp-features-plugin': 7.29.7(@babel/core@7.29.7) '@babel/helper-plugin-utils': 7.29.7 '@babel/plugin-transform-reserved-words@7.29.7(@babel/core@7.29.7)': dependencies: - '@babel/core': 7.29.7 + '@babel/core': 7.29.7(supports-color@10.2.2) '@babel/helper-plugin-utils': 7.29.7 - '@babel/plugin-transform-runtime@7.29.7(@babel/core@7.29.7)': + '@babel/plugin-transform-runtime@7.29.7(@babel/core@7.29.7)(supports-color@10.2.2)': dependencies: - '@babel/core': 7.29.7 + '@babel/core': 7.29.7(supports-color@10.2.2) '@babel/helper-module-imports': 7.29.7 '@babel/helper-plugin-utils': 7.29.7 - babel-plugin-polyfill-corejs2: 0.4.17(@babel/core@7.29.7) + babel-plugin-polyfill-corejs2: 0.4.17(@babel/core@7.29.7)(supports-color@10.2.2) babel-plugin-polyfill-corejs3: 0.13.0(@babel/core@7.29.7) babel-plugin-polyfill-regenerator: 0.6.8(@babel/core@7.29.7) semver: 6.3.1 @@ -9399,12 +9731,12 @@ snapshots: '@babel/plugin-transform-shorthand-properties@7.29.7(@babel/core@7.29.7)': dependencies: - '@babel/core': 7.29.7 + '@babel/core': 7.29.7(supports-color@10.2.2) '@babel/helper-plugin-utils': 7.29.7 '@babel/plugin-transform-spread@7.29.7(@babel/core@7.29.7)': dependencies: - '@babel/core': 7.29.7 + '@babel/core': 7.29.7(supports-color@10.2.2) '@babel/helper-plugin-utils': 7.29.7 '@babel/helper-skip-transparent-expression-wrappers': 7.29.7 transitivePeerDependencies: @@ -9412,46 +9744,46 @@ snapshots: '@babel/plugin-transform-sticky-regex@7.29.7(@babel/core@7.29.7)': dependencies: - '@babel/core': 7.29.7 + '@babel/core': 7.29.7(supports-color@10.2.2) '@babel/helper-plugin-utils': 7.29.7 '@babel/plugin-transform-template-literals@7.29.7(@babel/core@7.29.7)': dependencies: - '@babel/core': 7.29.7 + '@babel/core': 7.29.7(supports-color@10.2.2) '@babel/helper-plugin-utils': 7.29.7 '@babel/plugin-transform-typeof-symbol@7.29.7(@babel/core@7.29.7)': dependencies: - '@babel/core': 7.29.7 + '@babel/core': 7.29.7(supports-color@10.2.2) '@babel/helper-plugin-utils': 7.29.7 '@babel/plugin-transform-unicode-escapes@7.29.7(@babel/core@7.29.7)': dependencies: - '@babel/core': 7.29.7 + '@babel/core': 7.29.7(supports-color@10.2.2) '@babel/helper-plugin-utils': 7.29.7 '@babel/plugin-transform-unicode-property-regex@7.29.7(@babel/core@7.29.7)': dependencies: - '@babel/core': 7.29.7 + '@babel/core': 7.29.7(supports-color@10.2.2) '@babel/helper-create-regexp-features-plugin': 7.29.7(@babel/core@7.29.7) '@babel/helper-plugin-utils': 7.29.7 '@babel/plugin-transform-unicode-regex@7.29.7(@babel/core@7.29.7)': dependencies: - '@babel/core': 7.29.7 + '@babel/core': 7.29.7(supports-color@10.2.2) '@babel/helper-create-regexp-features-plugin': 7.29.7(@babel/core@7.29.7) '@babel/helper-plugin-utils': 7.29.7 '@babel/plugin-transform-unicode-sets-regex@7.29.7(@babel/core@7.29.7)': dependencies: - '@babel/core': 7.29.7 + '@babel/core': 7.29.7(supports-color@10.2.2) '@babel/helper-create-regexp-features-plugin': 7.29.7(@babel/core@7.29.7) '@babel/helper-plugin-utils': 7.29.7 '@babel/preset-env@7.29.7(@babel/core@7.29.7)': dependencies: '@babel/compat-data': 7.29.7 - '@babel/core': 7.29.7 + '@babel/core': 7.29.7(supports-color@10.2.2) '@babel/helper-compilation-targets': 7.29.7 '@babel/helper-plugin-utils': 7.29.7 '@babel/helper-validator-option': 7.29.7 @@ -9517,7 +9849,7 @@ snapshots: '@babel/plugin-transform-unicode-regex': 7.29.7(@babel/core@7.29.7) '@babel/plugin-transform-unicode-sets-regex': 7.29.7(@babel/core@7.29.7) '@babel/preset-modules': 0.1.6-no-external-plugins(@babel/core@7.29.7) - babel-plugin-polyfill-corejs2: 0.4.17(@babel/core@7.29.7) + babel-plugin-polyfill-corejs2: 0.4.17(@babel/core@7.29.7)(supports-color@10.2.2) babel-plugin-polyfill-corejs3: 0.14.2(@babel/core@7.29.7) babel-plugin-polyfill-regenerator: 0.6.8(@babel/core@7.29.7) core-js-compat: 3.49.0 @@ -9527,7 +9859,7 @@ snapshots: '@babel/preset-modules@0.1.6-no-external-plugins(@babel/core@7.29.7)': dependencies: - '@babel/core': 7.29.7 + '@babel/core': 7.29.7(supports-color@10.2.2) '@babel/helper-plugin-utils': 7.29.7 '@babel/types': 7.29.7 esutils: 2.0.3 @@ -9575,7 +9907,7 @@ snapshots: dependencies: '@simple-libs/child-process-utils': 1.0.2 '@simple-libs/stream-utils': 1.2.0 - semver: 7.8.1 + semver: 7.8.4 optionalDependencies: conventional-commits-filter: 5.0.0 conventional-commits-parser: 6.4.0 @@ -9627,18 +9959,18 @@ snapshots: '@discoveryjs/json-ext@1.1.0': {} - '@emnapi/core@1.10.0': + '@emnapi/core@1.11.0': dependencies: - '@emnapi/wasi-threads': 1.2.1 + '@emnapi/wasi-threads': 1.2.2 tslib: 2.8.1 optional: true - '@emnapi/runtime@1.10.0': + '@emnapi/runtime@1.11.0': dependencies: tslib: 2.8.1 optional: true - '@emnapi/wasi-threads@1.2.1': + '@emnapi/wasi-threads@1.2.2': dependencies: tslib: 2.8.1 optional: true @@ -9649,168 +9981,246 @@ snapshots: '@esbuild/aix-ppc64@0.28.0': optional: true + '@esbuild/aix-ppc64@0.28.1': + optional: true + '@esbuild/android-arm64@0.27.7': optional: true '@esbuild/android-arm64@0.28.0': optional: true + '@esbuild/android-arm64@0.28.1': + optional: true + '@esbuild/android-arm@0.27.7': optional: true '@esbuild/android-arm@0.28.0': optional: true + '@esbuild/android-arm@0.28.1': + optional: true + '@esbuild/android-x64@0.27.7': optional: true '@esbuild/android-x64@0.28.0': optional: true + '@esbuild/android-x64@0.28.1': + optional: true + '@esbuild/darwin-arm64@0.27.7': optional: true '@esbuild/darwin-arm64@0.28.0': optional: true + '@esbuild/darwin-arm64@0.28.1': + optional: true + '@esbuild/darwin-x64@0.27.7': optional: true '@esbuild/darwin-x64@0.28.0': optional: true + '@esbuild/darwin-x64@0.28.1': + optional: true + '@esbuild/freebsd-arm64@0.27.7': optional: true '@esbuild/freebsd-arm64@0.28.0': optional: true + '@esbuild/freebsd-arm64@0.28.1': + optional: true + '@esbuild/freebsd-x64@0.27.7': optional: true '@esbuild/freebsd-x64@0.28.0': optional: true + '@esbuild/freebsd-x64@0.28.1': + optional: true + '@esbuild/linux-arm64@0.27.7': optional: true '@esbuild/linux-arm64@0.28.0': optional: true + '@esbuild/linux-arm64@0.28.1': + optional: true + '@esbuild/linux-arm@0.27.7': optional: true '@esbuild/linux-arm@0.28.0': optional: true + '@esbuild/linux-arm@0.28.1': + optional: true + '@esbuild/linux-ia32@0.27.7': optional: true '@esbuild/linux-ia32@0.28.0': optional: true + '@esbuild/linux-ia32@0.28.1': + optional: true + '@esbuild/linux-loong64@0.27.7': optional: true '@esbuild/linux-loong64@0.28.0': optional: true + '@esbuild/linux-loong64@0.28.1': + optional: true + '@esbuild/linux-mips64el@0.27.7': optional: true '@esbuild/linux-mips64el@0.28.0': optional: true + '@esbuild/linux-mips64el@0.28.1': + optional: true + '@esbuild/linux-ppc64@0.27.7': optional: true '@esbuild/linux-ppc64@0.28.0': optional: true + '@esbuild/linux-ppc64@0.28.1': + optional: true + '@esbuild/linux-riscv64@0.27.7': optional: true '@esbuild/linux-riscv64@0.28.0': optional: true + '@esbuild/linux-riscv64@0.28.1': + optional: true + '@esbuild/linux-s390x@0.27.7': optional: true '@esbuild/linux-s390x@0.28.0': optional: true + '@esbuild/linux-s390x@0.28.1': + optional: true + '@esbuild/linux-x64@0.27.7': optional: true '@esbuild/linux-x64@0.28.0': optional: true + '@esbuild/linux-x64@0.28.1': + optional: true + '@esbuild/netbsd-arm64@0.27.7': optional: true '@esbuild/netbsd-arm64@0.28.0': optional: true + '@esbuild/netbsd-arm64@0.28.1': + optional: true + '@esbuild/netbsd-x64@0.27.7': optional: true '@esbuild/netbsd-x64@0.28.0': optional: true + '@esbuild/netbsd-x64@0.28.1': + optional: true + '@esbuild/openbsd-arm64@0.27.7': optional: true '@esbuild/openbsd-arm64@0.28.0': optional: true + '@esbuild/openbsd-arm64@0.28.1': + optional: true + '@esbuild/openbsd-x64@0.27.7': optional: true '@esbuild/openbsd-x64@0.28.0': optional: true + '@esbuild/openbsd-x64@0.28.1': + optional: true + '@esbuild/openharmony-arm64@0.27.7': optional: true '@esbuild/openharmony-arm64@0.28.0': optional: true + '@esbuild/openharmony-arm64@0.28.1': + optional: true + '@esbuild/sunos-x64@0.27.7': optional: true '@esbuild/sunos-x64@0.28.0': optional: true + '@esbuild/sunos-x64@0.28.1': + optional: true + '@esbuild/win32-arm64@0.27.7': optional: true '@esbuild/win32-arm64@0.28.0': optional: true + '@esbuild/win32-arm64@0.28.1': + optional: true + '@esbuild/win32-ia32@0.27.7': optional: true '@esbuild/win32-ia32@0.28.0': optional: true + '@esbuild/win32-ia32@0.28.1': + optional: true + '@esbuild/win32-x64@0.27.7': optional: true '@esbuild/win32-x64@0.28.0': optional: true - '@eslint-community/eslint-utils@4.9.1(eslint@10.4.1(jiti@2.7.0))': + '@esbuild/win32-x64@0.28.1': + optional: true + + '@eslint-community/eslint-utils@4.9.1(eslint@10.5.0(jiti@2.7.0))': dependencies: - eslint: 10.4.1(jiti@2.7.0) + eslint: 10.5.0(jiti@2.7.0) eslint-visitor-keys: 3.4.3 '@eslint-community/regexpp@4.12.2': {} - '@eslint/compat@2.1.0(eslint@10.4.1(jiti@2.7.0))': + '@eslint/compat@2.1.0(eslint@10.5.0(jiti@2.7.0))': dependencies: '@eslint/core': 1.2.1 optionalDependencies: - eslint: 10.4.1(jiti@2.7.0) + eslint: 10.5.0(jiti@2.7.0) '@eslint/config-array@0.23.5': dependencies: @@ -9828,7 +10238,7 @@ snapshots: dependencies: '@types/json-schema': 7.0.15 - '@eslint/eslintrc@3.3.5': + '@eslint/eslintrc@3.3.5(supports-color@10.2.2)': dependencies: ajv: 6.15.0 debug: 4.4.3(supports-color@10.2.2) @@ -9842,9 +10252,9 @@ snapshots: transitivePeerDependencies: - supports-color - '@eslint/js@10.0.1(eslint@10.4.1(jiti@2.7.0))': + '@eslint/js@10.0.1(eslint@10.5.0(jiti@2.7.0))': optionalDependencies: - eslint: 10.4.1(jiti@2.7.0) + eslint: 10.5.0(jiti@2.7.0) '@eslint/object-schema@3.0.5': {} @@ -10628,8 +11038,8 @@ snapshots: cross-spawn: 7.0.6 eventsource: 3.0.7 eventsource-parser: 3.1.0 - express: 5.2.1 - express-rate-limit: 8.5.2(express@5.2.1) + express: 5.2.1(supports-color@10.2.2) + express-rate-limit: 8.5.2(express@5.2.1(supports-color@10.2.2)) hono: 4.12.23 jose: 6.2.3 json-schema-typed: 8.0.2 @@ -10739,10 +11149,10 @@ snapshots: '@napi-rs/nice-win32-x64-msvc': 1.1.1 optional: true - '@napi-rs/wasm-runtime@1.1.4(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)': + '@napi-rs/wasm-runtime@1.1.5(@emnapi/core@1.11.0)(@emnapi/runtime@1.11.0)': dependencies: - '@emnapi/core': 1.10.0 - '@emnapi/runtime': 1.10.0 + '@emnapi/core': 1.11.0 + '@emnapi/runtime': 1.11.0 '@tybys/wasm-util': 0.10.2 optional: true @@ -10772,7 +11182,7 @@ snapshots: '@npmcli/fs@5.0.0': dependencies: - semver: 7.8.1 + semver: 7.8.4 '@npmcli/git@7.0.2': dependencies: @@ -10782,7 +11192,7 @@ snapshots: lru-cache: 11.5.1 npm-pick-manifest: 11.0.3 proc-log: 6.1.0 - semver: 7.8.1 + semver: 7.8.4 which: 6.0.1 '@npmcli/installed-package-contents@4.0.0': @@ -10799,7 +11209,7 @@ snapshots: hosted-git-info: 9.0.3 json-parse-even-better-errors: 5.0.0 proc-log: 6.1.0 - semver: 7.8.1 + semver: 7.8.4 spdx-expression-parse: 4.0.0 '@npmcli/promise-spawn@9.0.1': @@ -10949,7 +11359,7 @@ snapshots: '@opentelemetry/semantic-conventions@1.41.1': {} - '@oxc-project/types@0.133.0': {} + '@oxc-project/types@0.135.0': {} '@parcel/watcher-android-arm64@2.5.6': optional: true @@ -11123,7 +11533,7 @@ snapshots: dependencies: '@pnpm/crypto.hash': 1000.2.2 '@pnpm/types': 1001.3.0 - semver: 7.8.1 + semver: 7.8.4 '@pnpm/graceful-fs@1000.1.0': dependencies: @@ -11158,64 +11568,64 @@ snapshots: modern-tar: 0.7.6 yargs: 17.7.2 - '@rolldown/binding-android-arm64@1.0.3': + '@rolldown/binding-android-arm64@1.1.1': optional: true - '@rolldown/binding-darwin-arm64@1.0.3': + '@rolldown/binding-darwin-arm64@1.1.1': optional: true - '@rolldown/binding-darwin-x64@1.0.3': + '@rolldown/binding-darwin-x64@1.1.1': optional: true - '@rolldown/binding-freebsd-x64@1.0.3': + '@rolldown/binding-freebsd-x64@1.1.1': optional: true - '@rolldown/binding-linux-arm-gnueabihf@1.0.3': + '@rolldown/binding-linux-arm-gnueabihf@1.1.1': optional: true - '@rolldown/binding-linux-arm64-gnu@1.0.3': + '@rolldown/binding-linux-arm64-gnu@1.1.1': optional: true - '@rolldown/binding-linux-arm64-musl@1.0.3': + '@rolldown/binding-linux-arm64-musl@1.1.1': optional: true - '@rolldown/binding-linux-ppc64-gnu@1.0.3': + '@rolldown/binding-linux-ppc64-gnu@1.1.1': optional: true - '@rolldown/binding-linux-s390x-gnu@1.0.3': + '@rolldown/binding-linux-s390x-gnu@1.1.1': optional: true - '@rolldown/binding-linux-x64-gnu@1.0.3': + '@rolldown/binding-linux-x64-gnu@1.1.1': optional: true - '@rolldown/binding-linux-x64-musl@1.0.3': + '@rolldown/binding-linux-x64-musl@1.1.1': optional: true - '@rolldown/binding-openharmony-arm64@1.0.3': + '@rolldown/binding-openharmony-arm64@1.1.1': optional: true - '@rolldown/binding-wasm32-wasi@1.0.3': + '@rolldown/binding-wasm32-wasi@1.1.1': dependencies: - '@emnapi/core': 1.10.0 - '@emnapi/runtime': 1.10.0 - '@napi-rs/wasm-runtime': 1.1.4(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0) + '@emnapi/core': 1.11.0 + '@emnapi/runtime': 1.11.0 + '@napi-rs/wasm-runtime': 1.1.5(@emnapi/core@1.11.0)(@emnapi/runtime@1.11.0) optional: true - '@rolldown/binding-win32-arm64-msvc@1.0.3': + '@rolldown/binding-win32-arm64-msvc@1.1.1': optional: true - '@rolldown/binding-win32-x64-msvc@1.0.3': + '@rolldown/binding-win32-x64-msvc@1.1.1': optional: true '@rolldown/pluginutils@1.0.1': {} - '@rollup/plugin-alias@6.0.0(rollup@4.61.0)': + '@rollup/plugin-alias@6.0.0(rollup@4.62.0)': optionalDependencies: - rollup: 4.61.0 + rollup: 4.62.0 - '@rollup/plugin-commonjs@29.0.3(rollup@4.61.0)': + '@rollup/plugin-commonjs@29.0.3(rollup@4.62.0)': dependencies: - '@rollup/pluginutils': 5.4.0(rollup@4.61.0) + '@rollup/pluginutils': 5.4.0(rollup@4.62.0) commondir: 1.0.1 estree-walker: 2.0.2 fdir: 6.5.0(picomatch@4.0.4) @@ -11223,7 +11633,7 @@ snapshots: magic-string: 0.30.21 picomatch: 4.0.4 optionalDependencies: - rollup: 4.61.0 + rollup: 4.62.0 '@rollup/plugin-json@6.1.0(rollup@4.61.0)': dependencies: @@ -11231,23 +11641,29 @@ snapshots: optionalDependencies: rollup: 4.61.0 - '@rollup/plugin-node-resolve@16.0.3(rollup@4.61.0)': + '@rollup/plugin-json@6.1.0(rollup@4.62.0)': dependencies: - '@rollup/pluginutils': 5.4.0(rollup@4.61.0) + '@rollup/pluginutils': 5.4.0(rollup@4.62.0) + optionalDependencies: + rollup: 4.62.0 + + '@rollup/plugin-node-resolve@16.0.3(rollup@4.62.0)': + dependencies: + '@rollup/pluginutils': 5.4.0(rollup@4.62.0) '@types/resolve': 1.20.2 deepmerge: 4.3.1 is-module: 1.0.0 resolve: 1.22.12 optionalDependencies: - rollup: 4.61.0 + rollup: 4.62.0 - '@rollup/pluginutils@5.3.0(rollup@4.61.0)': + '@rollup/pluginutils@5.3.0(rollup@4.62.0)': dependencies: '@types/estree': 1.0.9 estree-walker: 2.0.2 picomatch: 4.0.4 optionalDependencies: - rollup: 4.61.0 + rollup: 4.62.0 '@rollup/pluginutils@5.4.0(rollup@4.61.0)': dependencies: @@ -11257,87 +11673,176 @@ snapshots: optionalDependencies: rollup: 4.61.0 + '@rollup/pluginutils@5.4.0(rollup@4.62.0)': + dependencies: + '@types/estree': 1.0.9 + estree-walker: 2.0.2 + picomatch: 4.0.4 + optionalDependencies: + rollup: 4.62.0 + '@rollup/rollup-android-arm-eabi@4.61.0': optional: true + '@rollup/rollup-android-arm-eabi@4.62.0': + optional: true + '@rollup/rollup-android-arm64@4.61.0': optional: true + '@rollup/rollup-android-arm64@4.62.0': + optional: true + '@rollup/rollup-darwin-arm64@4.61.0': optional: true + '@rollup/rollup-darwin-arm64@4.62.0': + optional: true + '@rollup/rollup-darwin-x64@4.61.0': optional: true + '@rollup/rollup-darwin-x64@4.62.0': + optional: true + '@rollup/rollup-freebsd-arm64@4.61.0': optional: true + '@rollup/rollup-freebsd-arm64@4.62.0': + optional: true + '@rollup/rollup-freebsd-x64@4.61.0': optional: true + '@rollup/rollup-freebsd-x64@4.62.0': + optional: true + '@rollup/rollup-linux-arm-gnueabihf@4.61.0': optional: true + '@rollup/rollup-linux-arm-gnueabihf@4.62.0': + optional: true + '@rollup/rollup-linux-arm-musleabihf@4.61.0': optional: true + '@rollup/rollup-linux-arm-musleabihf@4.62.0': + optional: true + '@rollup/rollup-linux-arm64-gnu@4.61.0': optional: true + '@rollup/rollup-linux-arm64-gnu@4.62.0': + optional: true + '@rollup/rollup-linux-arm64-musl@4.61.0': optional: true + '@rollup/rollup-linux-arm64-musl@4.62.0': + optional: true + '@rollup/rollup-linux-loong64-gnu@4.61.0': optional: true + '@rollup/rollup-linux-loong64-gnu@4.62.0': + optional: true + '@rollup/rollup-linux-loong64-musl@4.61.0': optional: true + '@rollup/rollup-linux-loong64-musl@4.62.0': + optional: true + '@rollup/rollup-linux-ppc64-gnu@4.61.0': optional: true + '@rollup/rollup-linux-ppc64-gnu@4.62.0': + optional: true + '@rollup/rollup-linux-ppc64-musl@4.61.0': optional: true + '@rollup/rollup-linux-ppc64-musl@4.62.0': + optional: true + '@rollup/rollup-linux-riscv64-gnu@4.61.0': optional: true + '@rollup/rollup-linux-riscv64-gnu@4.62.0': + optional: true + '@rollup/rollup-linux-riscv64-musl@4.61.0': optional: true + '@rollup/rollup-linux-riscv64-musl@4.62.0': + optional: true + '@rollup/rollup-linux-s390x-gnu@4.61.0': optional: true + '@rollup/rollup-linux-s390x-gnu@4.62.0': + optional: true + '@rollup/rollup-linux-x64-gnu@4.61.0': optional: true + '@rollup/rollup-linux-x64-gnu@4.62.0': + optional: true + '@rollup/rollup-linux-x64-musl@4.61.0': optional: true + '@rollup/rollup-linux-x64-musl@4.62.0': + optional: true + '@rollup/rollup-openbsd-x64@4.61.0': optional: true + '@rollup/rollup-openbsd-x64@4.62.0': + optional: true + '@rollup/rollup-openharmony-arm64@4.61.0': optional: true + '@rollup/rollup-openharmony-arm64@4.62.0': + optional: true + '@rollup/rollup-win32-arm64-msvc@4.61.0': optional: true + '@rollup/rollup-win32-arm64-msvc@4.62.0': + optional: true + '@rollup/rollup-win32-ia32-msvc@4.61.0': optional: true + '@rollup/rollup-win32-ia32-msvc@4.62.0': + optional: true + '@rollup/rollup-win32-x64-gnu@4.61.0': optional: true + '@rollup/rollup-win32-x64-gnu@4.62.0': + optional: true + '@rollup/rollup-win32-x64-msvc@4.61.0': optional: true + '@rollup/rollup-win32-x64-msvc@4.62.0': + optional: true + '@rollup/wasm-node@4.61.0': dependencies: '@types/estree': 1.0.9 optionalDependencies: fsevents: 2.3.3 + '@rollup/wasm-node@4.62.0': + dependencies: + '@types/estree': 1.0.9 + optionalDependencies: + fsevents: 2.3.3 + '@rtsao/scc@1.1.0': {} '@sigstore/bundle@4.0.0': @@ -11384,11 +11889,11 @@ snapshots: '@standard-schema/spec@1.1.0': {} - '@stylistic/eslint-plugin@5.10.0(eslint@10.4.1(jiti@2.7.0))': + '@stylistic/eslint-plugin@5.10.0(eslint@10.5.0(jiti@2.7.0))': dependencies: - '@eslint-community/eslint-utils': 4.9.1(eslint@10.4.1(jiti@2.7.0)) + '@eslint-community/eslint-utils': 4.9.1(eslint@10.5.0(jiti@2.7.0)) '@typescript-eslint/types': 8.60.1 - eslint: 10.4.1(jiti@2.7.0) + eslint: 10.5.0(jiti@2.7.0) eslint-visitor-keys: 4.2.1 espree: 10.4.0 estraverse: 5.3.0 @@ -11398,9 +11903,9 @@ snapshots: dependencies: defer-to-connect: 2.0.1 - '@tony.ganchev/eslint-plugin-header@3.4.4(eslint@10.4.1(jiti@2.7.0))': + '@tony.ganchev/eslint-plugin-header@3.4.4(eslint@10.5.0(jiti@2.7.0))': dependencies: - eslint: 10.4.1(jiti@2.7.0) + eslint: 10.5.0(jiti@2.7.0) '@tufjs/canonical-json@2.0.0': {} @@ -11464,7 +11969,7 @@ snapshots: '@types/connect-history-api-fallback@1.5.4': dependencies: - '@types/express-serve-static-core': 4.19.8 + '@types/express-serve-static-core': 5.1.1 '@types/node': 22.19.20 '@types/connect@3.4.38': @@ -11549,10 +12054,10 @@ snapshots: '@types/less@3.0.8': {} - '@types/loader-utils@3.0.0(esbuild@0.28.0)': + '@types/loader-utils@3.0.0(esbuild@0.28.1)': dependencies: '@types/node': 22.19.20 - webpack: 5.107.2(esbuild@0.28.0) + webpack: 5.107.2(esbuild@0.28.1) transitivePeerDependencies: - '@minify-html/node' - '@swc/core' @@ -11696,15 +12201,15 @@ snapshots: '@types/yarnpkg__lockfile@1.1.9': {} - '@typescript-eslint/eslint-plugin@8.60.1(@typescript-eslint/parser@8.60.1(eslint@10.4.1(jiti@2.7.0))(typescript@6.0.3))(eslint@10.4.1(jiti@2.7.0))(typescript@6.0.3)': + '@typescript-eslint/eslint-plugin@8.61.0(@typescript-eslint/parser@8.61.0(eslint@10.5.0(jiti@2.7.0))(typescript@6.0.3))(eslint@10.5.0(jiti@2.7.0))(typescript@6.0.3)': dependencies: '@eslint-community/regexpp': 4.12.2 - '@typescript-eslint/parser': 8.60.1(eslint@10.4.1(jiti@2.7.0))(typescript@6.0.3) - '@typescript-eslint/scope-manager': 8.60.1 - '@typescript-eslint/type-utils': 8.60.1(eslint@10.4.1(jiti@2.7.0))(typescript@6.0.3) - '@typescript-eslint/utils': 8.60.1(eslint@10.4.1(jiti@2.7.0))(typescript@6.0.3) - '@typescript-eslint/visitor-keys': 8.60.1 - eslint: 10.4.1(jiti@2.7.0) + '@typescript-eslint/parser': 8.61.0(eslint@10.5.0(jiti@2.7.0))(typescript@6.0.3) + '@typescript-eslint/scope-manager': 8.61.0 + '@typescript-eslint/type-utils': 8.61.0(eslint@10.5.0(jiti@2.7.0))(typescript@6.0.3) + '@typescript-eslint/utils': 8.61.0(eslint@10.5.0(jiti@2.7.0))(typescript@6.0.3) + '@typescript-eslint/visitor-keys': 8.61.0 + eslint: 10.5.0(jiti@2.7.0) ignore: 7.0.5 natural-compare: 1.4.0 ts-api-utils: 2.5.0(typescript@6.0.3) @@ -11712,43 +12217,43 @@ snapshots: transitivePeerDependencies: - supports-color - '@typescript-eslint/parser@8.60.1(eslint@10.4.1(jiti@2.7.0))(typescript@6.0.3)': + '@typescript-eslint/parser@8.61.0(eslint@10.5.0(jiti@2.7.0))(typescript@6.0.3)': dependencies: - '@typescript-eslint/scope-manager': 8.60.1 - '@typescript-eslint/types': 8.60.1 - '@typescript-eslint/typescript-estree': 8.60.1(typescript@6.0.3) - '@typescript-eslint/visitor-keys': 8.60.1 + '@typescript-eslint/scope-manager': 8.61.0 + '@typescript-eslint/types': 8.61.0 + '@typescript-eslint/typescript-estree': 8.61.0(typescript@6.0.3) + '@typescript-eslint/visitor-keys': 8.61.0 debug: 4.4.3(supports-color@10.2.2) - eslint: 10.4.1(jiti@2.7.0) + eslint: 10.5.0(jiti@2.7.0) typescript: 6.0.3 transitivePeerDependencies: - supports-color - '@typescript-eslint/project-service@8.60.1(typescript@6.0.3)': + '@typescript-eslint/project-service@8.61.0(typescript@6.0.3)': dependencies: - '@typescript-eslint/tsconfig-utils': 8.60.1(typescript@6.0.3) - '@typescript-eslint/types': 8.60.1 + '@typescript-eslint/tsconfig-utils': 8.61.0(typescript@6.0.3) + '@typescript-eslint/types': 8.61.0 debug: 4.4.3(supports-color@10.2.2) typescript: 6.0.3 transitivePeerDependencies: - supports-color - '@typescript-eslint/scope-manager@8.60.1': + '@typescript-eslint/scope-manager@8.61.0': dependencies: - '@typescript-eslint/types': 8.60.1 - '@typescript-eslint/visitor-keys': 8.60.1 + '@typescript-eslint/types': 8.61.0 + '@typescript-eslint/visitor-keys': 8.61.0 - '@typescript-eslint/tsconfig-utils@8.60.1(typescript@6.0.3)': + '@typescript-eslint/tsconfig-utils@8.61.0(typescript@6.0.3)': dependencies: typescript: 6.0.3 - '@typescript-eslint/type-utils@8.60.1(eslint@10.4.1(jiti@2.7.0))(typescript@6.0.3)': + '@typescript-eslint/type-utils@8.61.0(eslint@10.5.0(jiti@2.7.0))(typescript@6.0.3)': dependencies: - '@typescript-eslint/types': 8.60.1 - '@typescript-eslint/typescript-estree': 8.60.1(typescript@6.0.3) - '@typescript-eslint/utils': 8.60.1(eslint@10.4.1(jiti@2.7.0))(typescript@6.0.3) + '@typescript-eslint/types': 8.61.0 + '@typescript-eslint/typescript-estree': 8.61.0(typescript@6.0.3) + '@typescript-eslint/utils': 8.61.0(eslint@10.5.0(jiti@2.7.0))(typescript@6.0.3) debug: 4.4.3(supports-color@10.2.2) - eslint: 10.4.1(jiti@2.7.0) + eslint: 10.5.0(jiti@2.7.0) ts-api-utils: 2.5.0(typescript@6.0.3) typescript: 6.0.3 transitivePeerDependencies: @@ -11756,38 +12261,40 @@ snapshots: '@typescript-eslint/types@8.60.1': {} - '@typescript-eslint/typescript-estree@8.60.1(typescript@6.0.3)': + '@typescript-eslint/types@8.61.0': {} + + '@typescript-eslint/typescript-estree@8.61.0(typescript@6.0.3)': dependencies: - '@typescript-eslint/project-service': 8.60.1(typescript@6.0.3) - '@typescript-eslint/tsconfig-utils': 8.60.1(typescript@6.0.3) - '@typescript-eslint/types': 8.60.1 - '@typescript-eslint/visitor-keys': 8.60.1 + '@typescript-eslint/project-service': 8.61.0(typescript@6.0.3) + '@typescript-eslint/tsconfig-utils': 8.61.0(typescript@6.0.3) + '@typescript-eslint/types': 8.61.0 + '@typescript-eslint/visitor-keys': 8.61.0 debug: 4.4.3(supports-color@10.2.2) minimatch: 10.2.5 - semver: 7.8.1 + semver: 7.8.4 tinyglobby: 0.2.17 ts-api-utils: 2.5.0(typescript@6.0.3) typescript: 6.0.3 transitivePeerDependencies: - supports-color - '@typescript-eslint/utils@8.60.1(eslint@10.4.1(jiti@2.7.0))(typescript@6.0.3)': + '@typescript-eslint/utils@8.61.0(eslint@10.5.0(jiti@2.7.0))(typescript@6.0.3)': dependencies: - '@eslint-community/eslint-utils': 4.9.1(eslint@10.4.1(jiti@2.7.0)) - '@typescript-eslint/scope-manager': 8.60.1 - '@typescript-eslint/types': 8.60.1 - '@typescript-eslint/typescript-estree': 8.60.1(typescript@6.0.3) - eslint: 10.4.1(jiti@2.7.0) + '@eslint-community/eslint-utils': 4.9.1(eslint@10.5.0(jiti@2.7.0)) + '@typescript-eslint/scope-manager': 8.61.0 + '@typescript-eslint/types': 8.61.0 + '@typescript-eslint/typescript-estree': 8.61.0(typescript@6.0.3) + eslint: 10.5.0(jiti@2.7.0) typescript: 6.0.3 transitivePeerDependencies: - supports-color - '@typescript-eslint/visitor-keys@8.60.1': + '@typescript-eslint/visitor-keys@8.61.0': dependencies: - '@typescript-eslint/types': 8.60.1 + '@typescript-eslint/types': 8.61.0 eslint-visitor-keys: 5.0.1 - '@verdaccio/auth@8.0.2': + '@verdaccio/auth@8.0.2(supports-color@10.2.2)': dependencies: '@verdaccio/config': 8.1.1 '@verdaccio/core': 8.1.1 @@ -11821,7 +12328,7 @@ snapshots: dependencies: lockfile: 1.0.4 - '@verdaccio/hooks@8.0.2': + '@verdaccio/hooks@8.0.2(supports-color@10.2.2)': dependencies: '@verdaccio/core': 8.1.1 '@verdaccio/logger': 8.0.2 @@ -11839,7 +12346,7 @@ snapshots: transitivePeerDependencies: - supports-color - '@verdaccio/local-storage-legacy@11.3.3': + '@verdaccio/local-storage-legacy@11.3.3(supports-color@10.2.2)': dependencies: '@verdaccio/core': 8.1.1 '@verdaccio/file-locking': 13.0.1 @@ -11878,11 +12385,11 @@ snapshots: transitivePeerDependencies: - supports-color - '@verdaccio/middleware@8.0.2': + '@verdaccio/middleware@8.0.2(supports-color@10.2.2)': dependencies: '@verdaccio/config': 8.1.1 '@verdaccio/core': 8.1.1 - '@verdaccio/url': 13.0.2 + '@verdaccio/url': 13.0.2(supports-color@10.2.2) debug: 4.4.3(supports-color@10.2.2) express: 4.22.1 express-rate-limit: 5.5.1 @@ -11891,7 +12398,7 @@ snapshots: transitivePeerDependencies: - supports-color - '@verdaccio/package-filter@13.0.2': + '@verdaccio/package-filter@13.0.2(supports-color@10.2.2)': dependencies: '@verdaccio/core': 8.1.1 debug: 4.4.3(supports-color@10.2.2) @@ -11899,7 +12406,7 @@ snapshots: transitivePeerDependencies: - supports-color - '@verdaccio/search-indexer@8.0.2': + '@verdaccio/search-indexer@8.0.2(supports-color@10.2.2)': dependencies: debug: 4.4.3(supports-color@10.2.2) fuse.js: 7.3.0 @@ -11917,10 +12424,10 @@ snapshots: '@verdaccio/streams@10.2.5': {} - '@verdaccio/tarball@13.0.2': + '@verdaccio/tarball@13.0.2(supports-color@10.2.2)': dependencies: '@verdaccio/core': 8.1.1 - '@verdaccio/url': 13.0.2 + '@verdaccio/url': 13.0.2(supports-color@10.2.2) debug: 4.4.3(supports-color@10.2.2) gunzip-maybe: 1.4.2 tar-stream: 3.1.7 @@ -11929,13 +12436,13 @@ snapshots: - react-native-b4a - supports-color - '@verdaccio/ui-theme@9.0.0-next-9.14': + '@verdaccio/ui-theme@9.0.0-next-9.14(supports-color@10.2.2)': dependencies: debug: 4.4.3(supports-color@10.2.2) transitivePeerDependencies: - supports-color - '@verdaccio/url@13.0.2': + '@verdaccio/url@13.0.2(supports-color@10.2.2)': dependencies: '@verdaccio/core': 8.1.1 debug: 4.4.3(supports-color@10.2.2) @@ -11949,14 +12456,14 @@ snapshots: lodash: 4.18.1 minimatch: 7.4.9 - '@vitejs/plugin-basic-ssl@2.3.0(vite@7.3.5(@types/node@24.13.2)(jiti@2.7.0)(less@4.6.4)(sass@1.100.0)(terser@5.48.0)(tsx@4.22.4)(yaml@2.9.0))': + '@vitejs/plugin-basic-ssl@2.3.0(vite@7.3.5(@types/node@24.13.2)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.48.0)(tsx@4.22.4)(yaml@2.9.0))': dependencies: - vite: 7.3.5(@types/node@24.13.2)(jiti@2.7.0)(less@4.6.4)(sass@1.100.0)(terser@5.48.0)(tsx@4.22.4)(yaml@2.9.0) + vite: 7.3.5(@types/node@24.13.2)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.48.0)(tsx@4.22.4)(yaml@2.9.0) - '@vitest/coverage-v8@4.1.8(vitest@4.1.8)': + '@vitest/coverage-v8@4.1.9(vitest@4.1.9)': dependencies: '@bcoe/v8-coverage': 1.0.2 - '@vitest/utils': 4.1.8 + '@vitest/utils': 4.1.9 ast-v8-to-istanbul: 1.0.3 istanbul-lib-coverage: 3.2.2 istanbul-lib-report: 3.0.1 @@ -11965,46 +12472,46 @@ snapshots: obug: 2.1.2 std-env: 4.1.0 tinyrainbow: 3.1.0 - vitest: 4.1.8(@opentelemetry/api@1.9.1)(@types/node@24.13.2)(@vitest/coverage-v8@4.1.8)(jiti@2.7.0)(jsdom@29.1.1)(less@4.6.4)(sass@1.100.0)(terser@5.48.0)(tsx@4.22.4)(yaml@2.9.0) + vitest: 4.1.9(@opentelemetry/api@1.9.1)(@types/node@24.13.2)(@vitest/coverage-v8@4.1.9)(jiti@2.7.0)(jsdom@29.1.1)(less@4.6.6)(sass@1.101.0)(terser@5.48.0)(tsx@4.22.4)(yaml@2.9.0) - '@vitest/expect@4.1.8': + '@vitest/expect@4.1.9': dependencies: '@standard-schema/spec': 1.1.0 '@types/chai': 5.2.3 - '@vitest/spy': 4.1.8 - '@vitest/utils': 4.1.8 + '@vitest/spy': 4.1.9 + '@vitest/utils': 4.1.9 chai: 6.2.2 tinyrainbow: 3.1.0 - '@vitest/mocker@4.1.8(vite@7.3.5(@types/node@24.13.2)(jiti@2.7.0)(less@4.6.4)(sass@1.100.0)(terser@5.48.0)(tsx@4.22.4)(yaml@2.9.0))': + '@vitest/mocker@4.1.9(vite@7.3.5(@types/node@24.13.2)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.48.0)(tsx@4.22.4)(yaml@2.9.0))': dependencies: - '@vitest/spy': 4.1.8 + '@vitest/spy': 4.1.9 estree-walker: 3.0.3 magic-string: 0.30.21 optionalDependencies: - vite: 7.3.5(@types/node@24.13.2)(jiti@2.7.0)(less@4.6.4)(sass@1.100.0)(terser@5.48.0)(tsx@4.22.4)(yaml@2.9.0) + vite: 7.3.5(@types/node@24.13.2)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.48.0)(tsx@4.22.4)(yaml@2.9.0) - '@vitest/pretty-format@4.1.8': + '@vitest/pretty-format@4.1.9': dependencies: tinyrainbow: 3.1.0 - '@vitest/runner@4.1.8': + '@vitest/runner@4.1.9': dependencies: - '@vitest/utils': 4.1.8 + '@vitest/utils': 4.1.9 pathe: 2.0.3 - '@vitest/snapshot@4.1.8': + '@vitest/snapshot@4.1.9': dependencies: - '@vitest/pretty-format': 4.1.8 - '@vitest/utils': 4.1.8 + '@vitest/pretty-format': 4.1.9 + '@vitest/utils': 4.1.9 magic-string: 0.30.21 pathe: 2.0.3 - '@vitest/spy@4.1.8': {} + '@vitest/spy@4.1.9': {} - '@vitest/utils@4.1.8': + '@vitest/utils@4.1.9': dependencies: - '@vitest/pretty-format': 4.1.8 + '@vitest/pretty-format': 4.1.9 convert-source-map: 2.0.0 tinyrainbow: 3.1.0 @@ -12128,7 +12635,7 @@ snapshots: loader-utils: 2.0.4 regex-parser: 2.3.1 - agent-base@6.0.2: + agent-base@6.0.2(supports-color@10.2.2): dependencies: debug: 4.4.3(supports-color@10.2.2) transitivePeerDependencies: @@ -12172,22 +12679,22 @@ snapshots: json-schema-traverse: 1.0.0 require-from-string: 2.0.2 - algoliasearch@5.53.0: - dependencies: - '@algolia/abtesting': 1.19.0 - '@algolia/client-abtesting': 5.53.0 - '@algolia/client-analytics': 5.53.0 - '@algolia/client-common': 5.53.0 - '@algolia/client-insights': 5.53.0 - '@algolia/client-personalization': 5.53.0 - '@algolia/client-query-suggestions': 5.53.0 - '@algolia/client-search': 5.53.0 - '@algolia/ingestion': 1.53.0 - '@algolia/monitoring': 1.53.0 - '@algolia/recommend': 5.53.0 - '@algolia/requester-browser-xhr': 5.53.0 - '@algolia/requester-fetch': 5.53.0 - '@algolia/requester-node-http': 5.53.0 + algoliasearch@5.54.0: + dependencies: + '@algolia/abtesting': 1.20.0 + '@algolia/client-abtesting': 5.54.0 + '@algolia/client-analytics': 5.54.0 + '@algolia/client-common': 5.54.0 + '@algolia/client-insights': 5.54.0 + '@algolia/client-personalization': 5.54.0 + '@algolia/client-query-suggestions': 5.54.0 + '@algolia/client-search': 5.54.0 + '@algolia/ingestion': 1.54.0 + '@algolia/monitoring': 1.54.0 + '@algolia/recommend': 5.54.0 + '@algolia/requester-browser-xhr': 5.54.0 + '@algolia/requester-fetch': 5.54.0 + '@algolia/requester-node-http': 5.54.0 ansi-colors@4.1.3: {} @@ -12329,42 +12836,42 @@ snapshots: b4a@1.8.1: {} - babel-loader@10.1.1(@babel/core@7.29.7)(webpack@5.107.2(esbuild@0.28.0)(postcss@8.5.15)): + babel-loader@10.1.1(@babel/core@7.29.7)(webpack@5.107.2(esbuild@0.28.1)(postcss@8.5.15)): dependencies: - '@babel/core': 7.29.7 + '@babel/core': 7.29.7(supports-color@10.2.2) find-up: 5.0.0 optionalDependencies: - webpack: 5.107.2(esbuild@0.28.0)(postcss@8.5.15) + webpack: 5.107.2(esbuild@0.28.1)(postcss@8.5.15) - babel-plugin-polyfill-corejs2@0.4.17(@babel/core@7.29.7): + babel-plugin-polyfill-corejs2@0.4.17(@babel/core@7.29.7)(supports-color@10.2.2): dependencies: '@babel/compat-data': 7.29.7 - '@babel/core': 7.29.7 - '@babel/helper-define-polyfill-provider': 0.6.8(@babel/core@7.29.7) + '@babel/core': 7.29.7(supports-color@10.2.2) + '@babel/helper-define-polyfill-provider': 0.6.8(@babel/core@7.29.7)(supports-color@10.2.2) semver: 6.3.1 transitivePeerDependencies: - supports-color babel-plugin-polyfill-corejs3@0.13.0(@babel/core@7.29.7): dependencies: - '@babel/core': 7.29.7 - '@babel/helper-define-polyfill-provider': 0.6.8(@babel/core@7.29.7) + '@babel/core': 7.29.7(supports-color@10.2.2) + '@babel/helper-define-polyfill-provider': 0.6.8(@babel/core@7.29.7)(supports-color@10.2.2) core-js-compat: 3.49.0 transitivePeerDependencies: - supports-color babel-plugin-polyfill-corejs3@0.14.2(@babel/core@7.29.7): dependencies: - '@babel/core': 7.29.7 - '@babel/helper-define-polyfill-provider': 0.6.8(@babel/core@7.29.7) + '@babel/core': 7.29.7(supports-color@10.2.2) + '@babel/helper-define-polyfill-provider': 0.6.8(@babel/core@7.29.7)(supports-color@10.2.2) core-js-compat: 3.49.0 transitivePeerDependencies: - supports-color babel-plugin-polyfill-regenerator@0.6.8(@babel/core@7.29.7): dependencies: - '@babel/core': 7.29.7 - '@babel/helper-define-polyfill-provider': 0.6.8(@babel/core@7.29.7) + '@babel/core': 7.29.7(supports-color@10.2.2) + '@babel/helper-define-polyfill-provider': 0.6.8(@babel/core@7.29.7)(supports-color@10.2.2) transitivePeerDependencies: - supports-color @@ -12461,7 +12968,7 @@ snapshots: transitivePeerDependencies: - supports-color - body-parser@2.2.2: + body-parser@2.2.2(supports-color@10.2.2): dependencies: bytes: 3.1.2 content-type: 1.0.5 @@ -12507,24 +13014,24 @@ snapshots: fresh: 0.5.2 mitt: 1.2.0 - browser-sync-ui@3.0.4(bufferutil@4.1.0)(utf-8-validate@6.0.6): + browser-sync-ui@3.0.4(bufferutil@4.1.0)(supports-color@10.2.2)(utf-8-validate@6.0.6): dependencies: async-each-series: 0.1.1 chalk: 4.1.2 connect-history-api-fallback: 1.6.0 immutable: 3.8.3 server-destroy: 1.0.1 - socket.io-client: 4.8.3(bufferutil@4.1.0)(utf-8-validate@6.0.6) + socket.io-client: 4.8.3(bufferutil@4.1.0)(supports-color@10.2.2)(utf-8-validate@6.0.6) stream-throttle: 0.1.3 transitivePeerDependencies: - bufferutil - supports-color - utf-8-validate - browser-sync@3.0.4(bufferutil@4.1.0)(utf-8-validate@6.0.6): + browser-sync@3.0.4(bufferutil@4.1.0)(supports-color@10.2.2)(utf-8-validate@6.0.6): dependencies: browser-sync-client: 3.0.4 - browser-sync-ui: 3.0.4(bufferutil@4.1.0)(utf-8-validate@6.0.6) + browser-sync-ui: 3.0.4(bufferutil@4.1.0)(supports-color@10.2.2)(utf-8-validate@6.0.6) bs-recipes: 1.3.4 chalk: 4.1.2 chokidar: 3.6.0 @@ -12548,7 +13055,7 @@ snapshots: serve-index: 1.9.2 serve-static: 1.16.3 server-destroy: 1.0.1 - socket.io: 4.8.3(bufferutil@4.1.0)(utf-8-validate@6.0.6) + socket.io: 4.8.3(bufferutil@4.1.0)(supports-color@10.2.2)(utf-8-validate@6.0.6) ua-parser-js: 1.0.41 yargs: 17.7.2 transitivePeerDependencies: @@ -12831,14 +13338,14 @@ snapshots: dependencies: is-what: 4.1.16 - copy-webpack-plugin@14.0.0(webpack@5.107.2(esbuild@0.28.0)(postcss@8.5.15)): + copy-webpack-plugin@14.0.0(webpack@5.107.2(esbuild@0.28.1)(postcss@8.5.15)): dependencies: glob-parent: 6.0.2 normalize-path: 3.0.0 schema-utils: 4.3.3 serialize-javascript: 7.0.5 tinyglobby: 0.2.17 - webpack: 5.107.2(esbuild@0.28.0)(postcss@8.5.15) + webpack: 5.107.2(esbuild@0.28.1)(postcss@8.5.15) core-js-compat@3.49.0: dependencies: @@ -12874,7 +13381,7 @@ snapshots: shebang-command: 2.0.0 which: 2.0.2 - css-loader@7.1.4(webpack@5.107.2(esbuild@0.28.0)(postcss@8.5.15)): + css-loader@7.1.4(webpack@5.107.2(esbuild@0.28.1)(postcss@8.5.15)): dependencies: icss-utils: 5.1.0(postcss@8.5.15) postcss: 8.5.15 @@ -12883,9 +13390,9 @@ snapshots: postcss-modules-scope: 3.2.1(postcss@8.5.15) postcss-modules-values: 4.0.0(postcss@8.5.15) postcss-value-parser: 4.2.0 - semver: 7.8.1 + semver: 7.8.4 optionalDependencies: - webpack: 5.107.2(esbuild@0.28.0)(postcss@8.5.15) + webpack: 5.107.2(esbuild@0.28.1)(postcss@8.5.15) css-select@6.0.0: dependencies: @@ -13119,7 +13626,7 @@ snapshots: dependencies: once: 1.4.0 - engine.io-client@6.6.5(bufferutil@4.1.0)(utf-8-validate@6.0.6): + engine.io-client@6.6.5(bufferutil@4.1.0)(supports-color@10.2.2)(utf-8-validate@6.0.6): dependencies: '@socket.io/component-emitter': 3.1.2 debug: 4.4.3(supports-color@10.2.2) @@ -13133,7 +13640,7 @@ snapshots: engine.io-parser@5.2.3: {} - engine.io@6.6.8(bufferutil@4.1.0)(utf-8-validate@6.0.6): + engine.io@6.6.8(bufferutil@4.1.0)(supports-color@10.2.2)(utf-8-validate@6.0.6): dependencies: '@types/cors': 2.8.19 '@types/node': 22.19.20 @@ -13267,7 +13774,7 @@ snapshots: is-date-object: 1.1.0 is-symbol: 1.1.1 - esbuild-wasm@0.28.0: {} + esbuild-wasm@0.28.1: {} esbuild@0.27.7: optionalDependencies: @@ -13327,15 +13834,44 @@ snapshots: '@esbuild/win32-ia32': 0.28.0 '@esbuild/win32-x64': 0.28.0 + esbuild@0.28.1: + optionalDependencies: + '@esbuild/aix-ppc64': 0.28.1 + '@esbuild/android-arm': 0.28.1 + '@esbuild/android-arm64': 0.28.1 + '@esbuild/android-x64': 0.28.1 + '@esbuild/darwin-arm64': 0.28.1 + '@esbuild/darwin-x64': 0.28.1 + '@esbuild/freebsd-arm64': 0.28.1 + '@esbuild/freebsd-x64': 0.28.1 + '@esbuild/linux-arm': 0.28.1 + '@esbuild/linux-arm64': 0.28.1 + '@esbuild/linux-ia32': 0.28.1 + '@esbuild/linux-loong64': 0.28.1 + '@esbuild/linux-mips64el': 0.28.1 + '@esbuild/linux-ppc64': 0.28.1 + '@esbuild/linux-riscv64': 0.28.1 + '@esbuild/linux-s390x': 0.28.1 + '@esbuild/linux-x64': 0.28.1 + '@esbuild/netbsd-arm64': 0.28.1 + '@esbuild/netbsd-x64': 0.28.1 + '@esbuild/openbsd-arm64': 0.28.1 + '@esbuild/openbsd-x64': 0.28.1 + '@esbuild/openharmony-arm64': 0.28.1 + '@esbuild/sunos-x64': 0.28.1 + '@esbuild/win32-arm64': 0.28.1 + '@esbuild/win32-ia32': 0.28.1 + '@esbuild/win32-x64': 0.28.1 + escalade@3.2.0: {} escape-html@1.0.3: {} escape-string-regexp@4.0.0: {} - eslint-config-prettier@10.1.8(eslint@10.4.1(jiti@2.7.0)): + eslint-config-prettier@10.1.8(eslint@10.5.0(jiti@2.7.0)): dependencies: - eslint: 10.4.1(jiti@2.7.0) + eslint: 10.5.0(jiti@2.7.0) eslint-import-resolver-node@0.3.10: dependencies: @@ -13345,17 +13881,17 @@ snapshots: transitivePeerDependencies: - supports-color - eslint-module-utils@2.13.0(@typescript-eslint/parser@8.60.1(eslint@10.4.1(jiti@2.7.0))(typescript@6.0.3))(eslint-import-resolver-node@0.3.10)(eslint@10.4.1(jiti@2.7.0)): + eslint-module-utils@2.13.0(@typescript-eslint/parser@8.61.0(eslint@10.5.0(jiti@2.7.0))(typescript@6.0.3))(eslint-import-resolver-node@0.3.10)(eslint@10.5.0(jiti@2.7.0)): dependencies: debug: 3.2.7 optionalDependencies: - '@typescript-eslint/parser': 8.60.1(eslint@10.4.1(jiti@2.7.0))(typescript@6.0.3) - eslint: 10.4.1(jiti@2.7.0) + '@typescript-eslint/parser': 8.61.0(eslint@10.5.0(jiti@2.7.0))(typescript@6.0.3) + eslint: 10.5.0(jiti@2.7.0) eslint-import-resolver-node: 0.3.10 transitivePeerDependencies: - supports-color - eslint-plugin-import@2.32.0(@typescript-eslint/parser@8.60.1(eslint@10.4.1(jiti@2.7.0))(typescript@6.0.3))(eslint@10.4.1(jiti@2.7.0)): + eslint-plugin-import@2.32.0(@typescript-eslint/parser@8.61.0(eslint@10.5.0(jiti@2.7.0))(typescript@6.0.3))(eslint@10.5.0(jiti@2.7.0)): dependencies: '@rtsao/scc': 1.1.0 array-includes: 3.1.9 @@ -13364,9 +13900,9 @@ snapshots: array.prototype.flatmap: 1.3.3 debug: 3.2.7 doctrine: 2.1.0 - eslint: 10.4.1(jiti@2.7.0) + eslint: 10.5.0(jiti@2.7.0) eslint-import-resolver-node: 0.3.10 - eslint-module-utils: 2.13.0(@typescript-eslint/parser@8.60.1(eslint@10.4.1(jiti@2.7.0))(typescript@6.0.3))(eslint-import-resolver-node@0.3.10)(eslint@10.4.1(jiti@2.7.0)) + eslint-module-utils: 2.13.0(@typescript-eslint/parser@8.61.0(eslint@10.5.0(jiti@2.7.0))(typescript@6.0.3))(eslint-import-resolver-node@0.3.10)(eslint@10.5.0(jiti@2.7.0)) hasown: 2.0.4 is-core-module: 2.16.2 is-glob: 4.0.3 @@ -13378,7 +13914,7 @@ snapshots: string.prototype.trimend: 1.0.10 tsconfig-paths: 3.15.0 optionalDependencies: - '@typescript-eslint/parser': 8.60.1(eslint@10.4.1(jiti@2.7.0))(typescript@6.0.3) + '@typescript-eslint/parser': 8.61.0(eslint@10.5.0(jiti@2.7.0))(typescript@6.0.3) transitivePeerDependencies: - eslint-import-resolver-typescript - eslint-import-resolver-webpack @@ -13402,9 +13938,9 @@ snapshots: eslint-visitor-keys@5.0.1: {} - eslint@10.4.1(jiti@2.7.0): + eslint@10.5.0(jiti@2.7.0): dependencies: - '@eslint-community/eslint-utils': 4.9.1(eslint@10.4.1(jiti@2.7.0)) + '@eslint-community/eslint-utils': 4.9.1(eslint@10.5.0(jiti@2.7.0)) '@eslint-community/regexpp': 4.12.2 '@eslint/config-array': 0.23.5 '@eslint/config-helpers': 0.6.0 @@ -13501,9 +14037,9 @@ snapshots: express-rate-limit@5.5.1: {} - express-rate-limit@8.5.2(express@5.2.1): + express-rate-limit@8.5.2(express@5.2.1(supports-color@10.2.2)): dependencies: - express: 5.2.1 + express: 5.2.1(supports-color@10.2.2) ip-address: 10.2.0 express@4.22.1: @@ -13578,10 +14114,10 @@ snapshots: transitivePeerDependencies: - supports-color - express@5.2.1: + express@5.2.1(supports-color@10.2.2): dependencies: accepts: 2.0.0 - body-parser: 2.2.2 + body-parser: 2.2.2(supports-color@10.2.2) content-disposition: 1.1.0 content-type: 1.0.5 cookie: 0.7.2 @@ -13591,7 +14127,7 @@ snapshots: encodeurl: 2.0.0 escape-html: 1.0.3 etag: 1.8.1 - finalhandler: 2.1.1 + finalhandler: 2.1.1(supports-color@10.2.2) fresh: 2.0.0 http-errors: 2.0.1 merge-descriptors: 2.0.0 @@ -13602,8 +14138,8 @@ snapshots: proxy-addr: 2.0.7 qs: 6.15.2 range-parser: 1.2.1 - router: 2.2.0 - send: 1.2.1 + router: 2.2.0(supports-color@10.2.2) + send: 1.2.1(supports-color@10.2.2) serve-static: 2.2.1 statuses: 2.0.2 type-is: 2.1.0 @@ -13704,7 +14240,7 @@ snapshots: transitivePeerDependencies: - supports-color - finalhandler@2.1.1: + finalhandler@2.1.1(supports-color@10.2.2): dependencies: debug: 4.4.3(supports-color@10.2.2) encodeurl: 2.0.0 @@ -14176,7 +14712,7 @@ snapshots: transitivePeerDependencies: - debug - http-proxy-middleware@4.0.0: + http-proxy-middleware@4.1.1: dependencies: debug: 4.4.3(supports-color@10.2.2) httpxy: 0.5.3 @@ -14207,9 +14743,9 @@ snapshots: quick-lru: 5.1.1 resolve-alpn: 1.2.1 - https-proxy-agent@5.0.1: + https-proxy-agent@5.0.1(supports-color@10.2.2): dependencies: - agent-base: 6.0.2 + agent-base: 6.0.2(supports-color@10.2.2) debug: 4.4.3(supports-color@10.2.2) transitivePeerDependencies: - supports-color @@ -14221,11 +14757,13 @@ snapshots: transitivePeerDependencies: - supports-color - https-proxy-agent@9.0.0: + https-proxy-agent@9.1.0: dependencies: agent-base: 9.0.0 debug: 4.4.3(supports-color@10.2.2) + proxy-agent-negotiate: 1.1.0 transitivePeerDependencies: + - kerberos - supports-color httpxy@0.5.3: {} @@ -14501,7 +15039,7 @@ snapshots: istanbul-lib-instrument@5.2.1: dependencies: - '@babel/core': 7.29.7 + '@babel/core': 7.29.7(supports-color@10.2.2) '@babel/parser': 7.29.7 '@istanbuljs/schema': 0.1.6 istanbul-lib-coverage: 3.2.2 @@ -14511,11 +15049,11 @@ snapshots: istanbul-lib-instrument@6.0.3: dependencies: - '@babel/core': 7.29.7 + '@babel/core': 7.29.7(supports-color@10.2.2) '@babel/parser': 7.29.7 '@istanbuljs/schema': 0.1.6 istanbul-lib-coverage: 3.2.2 - semver: 7.8.1 + semver: 7.8.4 transitivePeerDependencies: - supports-color @@ -14525,7 +15063,7 @@ snapshots: make-dir: 4.0.0 supports-color: 7.2.0 - istanbul-lib-source-maps@4.0.1: + istanbul-lib-source-maps@4.0.1(supports-color@10.2.2): dependencies: debug: 4.4.3(supports-color@10.2.2) istanbul-lib-coverage: 3.2.2 @@ -14546,8 +15084,6 @@ snapshots: jasmine-core@4.6.1: {} - jasmine-core@6.2.0: {} - jasmine-core@6.3.0: {} jasmine-reporters@2.5.2: @@ -14559,12 +15095,6 @@ snapshots: dependencies: colors: 1.4.0 - jasmine@6.2.0: - dependencies: - '@jasminejs/reporters': 1.0.0 - glob: 13.0.6 - jasmine-core: 6.2.0 - jasmine@6.3.0: dependencies: '@jasminejs/reporters': 1.0.0 @@ -14678,7 +15208,7 @@ snapshots: lodash.isstring: 4.0.1 lodash.once: 4.1.1 ms: 2.1.3 - semver: 7.8.1 + semver: 7.8.4 jsprim@2.0.2: dependencies: @@ -14702,33 +15232,33 @@ snapshots: dependencies: which: 1.3.1 - karma-coverage@2.2.1: + karma-coverage@2.2.1(supports-color@10.2.2): dependencies: istanbul-lib-coverage: 3.2.2 istanbul-lib-instrument: 5.2.1 istanbul-lib-report: 3.0.1 - istanbul-lib-source-maps: 4.0.1 + istanbul-lib-source-maps: 4.0.1(supports-color@10.2.2) istanbul-reports: 3.2.0 minimatch: 3.1.5 transitivePeerDependencies: - supports-color - karma-jasmine-html-reporter@2.2.0(jasmine-core@6.2.0)(karma-jasmine@5.1.0(karma@6.4.4(bufferutil@4.1.0)(utf-8-validate@6.0.6)))(karma@6.4.4(bufferutil@4.1.0)(utf-8-validate@6.0.6)): + karma-jasmine-html-reporter@2.2.0(jasmine-core@6.3.0)(karma-jasmine@5.1.0(karma@6.4.4(bufferutil@4.1.0)(supports-color@10.2.2)(utf-8-validate@6.0.6)))(karma@6.4.4(bufferutil@4.1.0)(supports-color@10.2.2)(utf-8-validate@6.0.6)): dependencies: - jasmine-core: 6.2.0 - karma: 6.4.4(bufferutil@4.1.0)(utf-8-validate@6.0.6) - karma-jasmine: 5.1.0(karma@6.4.4(bufferutil@4.1.0)(utf-8-validate@6.0.6)) + jasmine-core: 6.3.0 + karma: 6.4.4(bufferutil@4.1.0)(supports-color@10.2.2)(utf-8-validate@6.0.6) + karma-jasmine: 5.1.0(karma@6.4.4(bufferutil@4.1.0)(supports-color@10.2.2)(utf-8-validate@6.0.6)) - karma-jasmine@5.1.0(karma@6.4.4(bufferutil@4.1.0)(utf-8-validate@6.0.6)): + karma-jasmine@5.1.0(karma@6.4.4(bufferutil@4.1.0)(supports-color@10.2.2)(utf-8-validate@6.0.6)): dependencies: jasmine-core: 4.6.1 - karma: 6.4.4(bufferutil@4.1.0)(utf-8-validate@6.0.6) + karma: 6.4.4(bufferutil@4.1.0)(supports-color@10.2.2)(utf-8-validate@6.0.6) karma-source-map-support@1.4.0: dependencies: source-map-support: 0.5.21 - karma@6.4.4(bufferutil@4.1.0)(utf-8-validate@6.0.6): + karma@6.4.4(bufferutil@4.1.0)(supports-color@10.2.2)(utf-8-validate@6.0.6): dependencies: '@colors/colors': 1.5.0 body-parser: 1.20.5 @@ -14749,7 +15279,7 @@ snapshots: qjobs: 1.2.0 range-parser: 1.2.1 rimraf: 3.0.2 - socket.io: 4.8.3(bufferutil@4.1.0)(utf-8-validate@6.0.6) + socket.io: 4.8.3(bufferutil@4.1.0)(supports-color@10.2.2)(utf-8-validate@6.0.6) source-map: 0.6.1 tmp: 0.2.7 ua-parser-js: 0.7.41 @@ -14771,12 +15301,12 @@ snapshots: picocolors: 1.1.1 shell-quote: 1.8.4 - less-loader@13.0.0(less@4.6.4)(webpack@5.107.2(esbuild@0.28.0)(postcss@8.5.15)): + less-loader@13.0.0(less@4.6.6)(webpack@5.107.2(esbuild@0.28.1)(postcss@8.5.15)): dependencies: '@types/less': 3.0.8 - less: 4.6.4 + less: 4.6.6 optionalDependencies: - webpack: 5.107.2(esbuild@0.28.0)(postcss@8.5.15) + webpack: 5.107.2(esbuild@0.28.1)(postcss@8.5.15) less@4.6.4: dependencies: @@ -14791,16 +15321,29 @@ snapshots: needle: 3.5.0 source-map: 0.6.1 + less@4.6.6: + dependencies: + copy-anything: 3.0.5 + parse-node-version: 1.0.1 + optionalDependencies: + errno: 0.1.8 + graceful-fs: 4.2.11 + image-size: 0.5.5 + make-dir: 5.1.0 + mime: 1.6.0 + needle: 3.5.0 + source-map: 0.6.1 + levn@0.4.1: dependencies: prelude-ls: 1.2.1 type-check: 0.4.0 - license-webpack-plugin@4.0.2(webpack@5.107.2(esbuild@0.28.0)(postcss@8.5.15)): + license-webpack-plugin@4.0.2(webpack@5.107.2(esbuild@0.28.1)(postcss@8.5.15)): dependencies: webpack-sources: 3.5.0 optionalDependencies: - webpack: 5.107.2(esbuild@0.28.0)(postcss@8.5.15) + webpack: 5.107.2(esbuild@0.28.1)(postcss@8.5.15) lilconfig@3.1.3: {} @@ -14939,7 +15482,10 @@ snapshots: make-dir@4.0.0: dependencies: - semver: 7.8.1 + semver: 7.8.4 + + make-dir@5.1.0: + optional: true make-fetch-happen@15.0.6: dependencies: @@ -15024,11 +15570,11 @@ snapshots: mimic-response@3.1.0: {} - mini-css-extract-plugin@2.10.2(webpack@5.107.2(esbuild@0.28.0)(postcss@8.5.15)): + mini-css-extract-plugin@2.10.2(webpack@5.107.2(esbuild@0.28.1)(postcss@8.5.15)): dependencies: schema-utils: 4.3.3 tapable: 2.3.3 - webpack: 5.107.2(esbuild@0.28.0)(postcss@8.5.15) + webpack: 5.107.2(esbuild@0.28.1)(postcss@8.5.15) minimalistic-assert@1.0.1: {} @@ -15233,7 +15779,7 @@ snapshots: graceful-fs: 4.2.11 nopt: 9.0.0 proc-log: 6.1.0 - semver: 7.8.1 + semver: 7.8.4 tar: 7.5.16 tinyglobby: 0.2.17 undici: 6.26.0 @@ -15255,7 +15801,7 @@ snapshots: npm-install-checks@8.0.0: dependencies: - semver: 7.8.1 + semver: 7.8.4 npm-normalize-package-bin@5.0.0: {} @@ -15263,14 +15809,14 @@ snapshots: dependencies: hosted-git-info: 9.0.3 proc-log: 6.1.0 - semver: 7.8.1 + semver: 7.8.4 validate-npm-package-name: 7.0.2 npm-package-arg@14.0.0: dependencies: hosted-git-info: 10.1.1 proc-log: 7.0.0 - semver: 7.8.1 + semver: 7.8.4 validate-npm-package-name: 8.0.0 npm-packlist@10.0.4: @@ -15283,7 +15829,7 @@ snapshots: npm-install-checks: 8.0.0 npm-normalize-package-bin: 5.0.0 npm-package-arg: 13.0.2 - semver: 7.8.1 + semver: 7.8.4 npm-registry-fetch@19.1.1: dependencies: @@ -15457,7 +16003,7 @@ snapshots: package-json-from-dist@1.0.1: {} - pacote@21.5.0: + pacote@21.5.1: dependencies: '@gar/promise-retry': 1.0.3 '@npmcli/git': 7.0.2 @@ -15588,6 +16134,10 @@ snapshots: optionalDependencies: '@napi-rs/nice': 1.1.1 + piscina@5.2.0: + optionalDependencies: + '@napi-rs/nice': 1.1.1 + pkce-challenge@5.0.1: {} pkg-dir@8.0.0: @@ -15612,14 +16162,14 @@ snapshots: possible-typed-array-names@1.1.0: {} - postcss-loader@8.2.1(postcss@8.5.15)(typescript@6.0.3)(webpack@5.107.2(esbuild@0.28.0)(postcss@8.5.15)): + postcss-loader@8.2.1(postcss@8.5.15)(typescript@6.0.3)(webpack@5.107.2(esbuild@0.28.1)(postcss@8.5.15)): dependencies: cosmiconfig: 9.0.2(typescript@6.0.3) jiti: 2.7.0 postcss: 8.5.15 - semver: 7.8.1 + semver: 7.8.4 optionalDependencies: - webpack: 5.107.2(esbuild@0.28.0)(postcss@8.5.15) + webpack: 5.107.2(esbuild@0.28.1)(postcss@8.5.15) transitivePeerDependencies: - typescript @@ -15707,6 +16257,8 @@ snapshots: forwarded: 0.2.0 ipaddr.js: 1.9.1 + proxy-agent-negotiate@1.1.0: {} + prr@1.0.1: optional: true @@ -15969,32 +16521,32 @@ snapshots: dependencies: glob: 10.5.0 - rolldown@1.0.3: + rolldown@1.1.1: dependencies: - '@oxc-project/types': 0.133.0 + '@oxc-project/types': 0.135.0 '@rolldown/pluginutils': 1.0.1 optionalDependencies: - '@rolldown/binding-android-arm64': 1.0.3 - '@rolldown/binding-darwin-arm64': 1.0.3 - '@rolldown/binding-darwin-x64': 1.0.3 - '@rolldown/binding-freebsd-x64': 1.0.3 - '@rolldown/binding-linux-arm-gnueabihf': 1.0.3 - '@rolldown/binding-linux-arm64-gnu': 1.0.3 - '@rolldown/binding-linux-arm64-musl': 1.0.3 - '@rolldown/binding-linux-ppc64-gnu': 1.0.3 - '@rolldown/binding-linux-s390x-gnu': 1.0.3 - '@rolldown/binding-linux-x64-gnu': 1.0.3 - '@rolldown/binding-linux-x64-musl': 1.0.3 - '@rolldown/binding-openharmony-arm64': 1.0.3 - '@rolldown/binding-wasm32-wasi': 1.0.3 - '@rolldown/binding-win32-arm64-msvc': 1.0.3 - '@rolldown/binding-win32-x64-msvc': 1.0.3 + '@rolldown/binding-android-arm64': 1.1.1 + '@rolldown/binding-darwin-arm64': 1.1.1 + '@rolldown/binding-darwin-x64': 1.1.1 + '@rolldown/binding-freebsd-x64': 1.1.1 + '@rolldown/binding-linux-arm-gnueabihf': 1.1.1 + '@rolldown/binding-linux-arm64-gnu': 1.1.1 + '@rolldown/binding-linux-arm64-musl': 1.1.1 + '@rolldown/binding-linux-ppc64-gnu': 1.1.1 + '@rolldown/binding-linux-s390x-gnu': 1.1.1 + '@rolldown/binding-linux-x64-gnu': 1.1.1 + '@rolldown/binding-linux-x64-musl': 1.1.1 + '@rolldown/binding-openharmony-arm64': 1.1.1 + '@rolldown/binding-wasm32-wasi': 1.1.1 + '@rolldown/binding-win32-arm64-msvc': 1.1.1 + '@rolldown/binding-win32-x64-msvc': 1.1.1 rollup-license-plugin@3.2.1: dependencies: get-npm-tarball-url: 2.1.0 node-fetch: 3.3.2 - semver: 7.8.1 + semver: 7.8.4 spdx-expression-validate: 2.0.0 rollup-plugin-dts@6.4.1(rollup@4.61.0)(typescript@6.0.3): @@ -16008,10 +16560,21 @@ snapshots: optionalDependencies: '@babel/code-frame': 7.29.7 - rollup-plugin-sourcemaps2@0.5.7(@types/node@22.19.20)(rollup@4.61.0): + rollup-plugin-dts@6.4.1(rollup@4.62.0)(typescript@6.0.3): dependencies: - '@rollup/pluginutils': 5.3.0(rollup@4.61.0) - rollup: 4.61.0 + '@jridgewell/remapping': 2.3.5 + '@jridgewell/sourcemap-codec': 1.5.5 + convert-source-map: 2.0.0 + magic-string: 0.30.21 + rollup: 4.62.0 + typescript: 6.0.3 + optionalDependencies: + '@babel/code-frame': 7.29.7 + + rollup-plugin-sourcemaps2@0.5.7(@types/node@22.19.20)(rollup@4.62.0): + dependencies: + '@rollup/pluginutils': 5.3.0(rollup@4.62.0) + rollup: 4.62.0 optionalDependencies: '@types/node': 22.19.20 @@ -16046,7 +16609,38 @@ snapshots: '@rollup/rollup-win32-x64-msvc': 4.61.0 fsevents: 2.3.3 - router@2.2.0: + rollup@4.62.0: + dependencies: + '@types/estree': 1.0.9 + optionalDependencies: + '@rollup/rollup-android-arm-eabi': 4.62.0 + '@rollup/rollup-android-arm64': 4.62.0 + '@rollup/rollup-darwin-arm64': 4.62.0 + '@rollup/rollup-darwin-x64': 4.62.0 + '@rollup/rollup-freebsd-arm64': 4.62.0 + '@rollup/rollup-freebsd-x64': 4.62.0 + '@rollup/rollup-linux-arm-gnueabihf': 4.62.0 + '@rollup/rollup-linux-arm-musleabihf': 4.62.0 + '@rollup/rollup-linux-arm64-gnu': 4.62.0 + '@rollup/rollup-linux-arm64-musl': 4.62.0 + '@rollup/rollup-linux-loong64-gnu': 4.62.0 + '@rollup/rollup-linux-loong64-musl': 4.62.0 + '@rollup/rollup-linux-ppc64-gnu': 4.62.0 + '@rollup/rollup-linux-ppc64-musl': 4.62.0 + '@rollup/rollup-linux-riscv64-gnu': 4.62.0 + '@rollup/rollup-linux-riscv64-musl': 4.62.0 + '@rollup/rollup-linux-s390x-gnu': 4.62.0 + '@rollup/rollup-linux-x64-gnu': 4.62.0 + '@rollup/rollup-linux-x64-musl': 4.62.0 + '@rollup/rollup-openbsd-x64': 4.62.0 + '@rollup/rollup-openharmony-arm64': 4.62.0 + '@rollup/rollup-win32-arm64-msvc': 4.62.0 + '@rollup/rollup-win32-ia32-msvc': 4.62.0 + '@rollup/rollup-win32-x64-gnu': 4.62.0 + '@rollup/rollup-win32-x64-msvc': 4.62.0 + fsevents: 2.3.3 + + router@2.2.0(supports-color@10.2.2): dependencies: debug: 4.4.3(supports-color@10.2.2) depd: 2.0.0 @@ -16099,10 +16693,10 @@ snapshots: dependencies: truncate-utf8-bytes: 1.0.2 - sass-loader@17.0.0(sass@1.100.0)(webpack@5.107.2(esbuild@0.28.0)(postcss@8.5.15)): + sass-loader@17.0.0(sass@1.101.0)(webpack@5.107.2(esbuild@0.28.1)(postcss@8.5.15)): optionalDependencies: - sass: 1.100.0 - webpack: 5.107.2(esbuild@0.28.0)(postcss@8.5.15) + sass: 1.101.0 + webpack: 5.107.2(esbuild@0.28.1)(postcss@8.5.15) sass@1.100.0: dependencies: @@ -16112,6 +16706,14 @@ snapshots: optionalDependencies: '@parcel/watcher': 2.5.6 + sass@1.101.0: + dependencies: + chokidar: 5.0.0 + immutable: 5.1.6 + source-map-js: 1.2.1 + optionalDependencies: + '@parcel/watcher': 2.5.6 + sax@1.6.0: optional: true @@ -16142,8 +16744,6 @@ snapshots: semver@7.8.0: {} - semver@7.8.1: {} - semver@7.8.4: {} send@0.19.2: @@ -16164,7 +16764,7 @@ snapshots: transitivePeerDependencies: - supports-color - send@1.2.1: + send@1.2.1(supports-color@10.2.2): dependencies: debug: 4.4.3(supports-color@10.2.2) encodeurl: 2.0.0 @@ -16208,7 +16808,7 @@ snapshots: encodeurl: 2.0.0 escape-html: 1.0.3 parseurl: 1.3.3 - send: 1.2.1 + send: 1.2.1(supports-color@10.2.2) transitivePeerDependencies: - supports-color @@ -16309,7 +16909,7 @@ snapshots: smart-buffer@4.2.0: {} - socket.io-adapter@2.5.7(bufferutil@4.1.0)(utf-8-validate@6.0.6): + socket.io-adapter@2.5.7(bufferutil@4.1.0)(supports-color@10.2.2)(utf-8-validate@6.0.6): dependencies: debug: 4.4.3(supports-color@10.2.2) ws: 8.20.1(bufferutil@4.1.0)(utf-8-validate@6.0.6) @@ -16318,33 +16918,33 @@ snapshots: - supports-color - utf-8-validate - socket.io-client@4.8.3(bufferutil@4.1.0)(utf-8-validate@6.0.6): + socket.io-client@4.8.3(bufferutil@4.1.0)(supports-color@10.2.2)(utf-8-validate@6.0.6): dependencies: '@socket.io/component-emitter': 3.1.2 debug: 4.4.3(supports-color@10.2.2) - engine.io-client: 6.6.5(bufferutil@4.1.0)(utf-8-validate@6.0.6) - socket.io-parser: 4.2.6 + engine.io-client: 6.6.5(bufferutil@4.1.0)(supports-color@10.2.2)(utf-8-validate@6.0.6) + socket.io-parser: 4.2.6(supports-color@10.2.2) transitivePeerDependencies: - bufferutil - supports-color - utf-8-validate - socket.io-parser@4.2.6: + socket.io-parser@4.2.6(supports-color@10.2.2): dependencies: '@socket.io/component-emitter': 3.1.2 debug: 4.4.3(supports-color@10.2.2) transitivePeerDependencies: - supports-color - socket.io@4.8.3(bufferutil@4.1.0)(utf-8-validate@6.0.6): + socket.io@4.8.3(bufferutil@4.1.0)(supports-color@10.2.2)(utf-8-validate@6.0.6): dependencies: accepts: 1.3.8 base64id: 2.0.0 cors: 2.8.6 debug: 4.4.3(supports-color@10.2.2) - engine.io: 6.6.8(bufferutil@4.1.0)(utf-8-validate@6.0.6) - socket.io-adapter: 2.5.7(bufferutil@4.1.0)(utf-8-validate@6.0.6) - socket.io-parser: 4.2.6 + engine.io: 6.6.8(bufferutil@4.1.0)(supports-color@10.2.2)(utf-8-validate@6.0.6) + socket.io-adapter: 2.5.7(bufferutil@4.1.0)(supports-color@10.2.2)(utf-8-validate@6.0.6) + socket.io-parser: 4.2.6(supports-color@10.2.2) transitivePeerDependencies: - bufferutil - supports-color @@ -16379,11 +16979,11 @@ snapshots: source-map-js@1.2.1: {} - source-map-loader@5.0.0(webpack@5.107.2(esbuild@0.28.0)(postcss@8.5.15)): + source-map-loader@5.0.0(webpack@5.107.2(esbuild@0.28.1)(postcss@8.5.15)): dependencies: iconv-lite: 0.6.3 source-map-js: 1.2.1 - webpack: 5.107.2(esbuild@0.28.0)(postcss@8.5.15) + webpack: 5.107.2(esbuild@0.28.1)(postcss@8.5.15) source-map-support@0.5.21: dependencies: @@ -16646,26 +17246,26 @@ snapshots: - bare-abort-controller - react-native-b4a - terser-webpack-plugin@5.6.1(esbuild@0.28.0)(postcss@8.5.15)(webpack@5.107.2(esbuild@0.28.0)(postcss@8.5.15)): + terser-webpack-plugin@5.6.1(esbuild@0.28.1)(postcss@8.5.15)(webpack@5.107.2(esbuild@0.28.1)(postcss@8.5.15)): dependencies: '@jridgewell/trace-mapping': 0.3.31 jest-worker: 27.5.1 schema-utils: 4.3.3 terser: 5.48.0 - webpack: 5.107.2(esbuild@0.28.0)(postcss@8.5.15) + webpack: 5.107.2(esbuild@0.28.1)(postcss@8.5.15) optionalDependencies: - esbuild: 0.28.0 + esbuild: 0.28.1 postcss: 8.5.15 - terser-webpack-plugin@5.6.1(esbuild@0.28.0)(webpack@5.107.2(esbuild@0.28.0)): + terser-webpack-plugin@5.6.1(esbuild@0.28.1)(webpack@5.107.2(esbuild@0.28.1)): dependencies: '@jridgewell/trace-mapping': 0.3.31 jest-worker: 27.5.1 schema-utils: 4.3.3 terser: 5.48.0 - webpack: 5.107.2(esbuild@0.28.0) + webpack: 5.107.2(esbuild@0.28.1) optionalDependencies: - esbuild: 0.28.0 + esbuild: 0.28.1 terser@5.48.0: dependencies: @@ -16879,7 +17479,7 @@ snapshots: undici@7.27.2: {} - undici@8.3.0: {} + undici@8.4.1: {} unenv@1.10.0: dependencies: @@ -16952,18 +17552,18 @@ snapshots: vary@1.1.2: {} - verdaccio-audit@13.0.2(encoding@0.1.13): + verdaccio-audit@13.0.2(encoding@0.1.13)(supports-color@10.2.2): dependencies: '@verdaccio/config': 8.1.1 '@verdaccio/core': 8.1.1 express: 4.22.1 - https-proxy-agent: 5.0.1 + https-proxy-agent: 5.0.1(supports-color@10.2.2) node-fetch: 2.6.7(encoding@0.1.13) transitivePeerDependencies: - encoding - supports-color - verdaccio-auth-memory@13.0.2: + verdaccio-auth-memory@13.0.2(supports-color@10.2.2): dependencies: '@verdaccio/core': 8.1.1 debug: 4.4.3(supports-color@10.2.2) @@ -16982,24 +17582,24 @@ snapshots: transitivePeerDependencies: - supports-color - verdaccio@6.7.2(encoding@0.1.13): + verdaccio@6.7.2(encoding@0.1.13)(supports-color@10.2.2): dependencies: '@cypress/request': 3.0.10 - '@verdaccio/auth': 8.0.2 + '@verdaccio/auth': 8.0.2(supports-color@10.2.2) '@verdaccio/config': 8.1.1 '@verdaccio/core': 8.1.1 - '@verdaccio/hooks': 8.0.2 + '@verdaccio/hooks': 8.0.2(supports-color@10.2.2) '@verdaccio/loaders': 8.0.2 - '@verdaccio/local-storage-legacy': 11.3.3 + '@verdaccio/local-storage-legacy': 11.3.3(supports-color@10.2.2) '@verdaccio/logger': 8.0.2 - '@verdaccio/middleware': 8.0.2 - '@verdaccio/package-filter': 13.0.2 - '@verdaccio/search-indexer': 8.0.2 + '@verdaccio/middleware': 8.0.2(supports-color@10.2.2) + '@verdaccio/package-filter': 13.0.2(supports-color@10.2.2) + '@verdaccio/search-indexer': 8.0.2(supports-color@10.2.2) '@verdaccio/signature': 8.0.2 '@verdaccio/streams': 10.2.5 - '@verdaccio/tarball': 13.0.2 - '@verdaccio/ui-theme': 9.0.0-next-9.14 - '@verdaccio/url': 13.0.2 + '@verdaccio/tarball': 13.0.2(supports-color@10.2.2) + '@verdaccio/ui-theme': 9.0.0-next-9.14(supports-color@10.2.2) + '@verdaccio/url': 13.0.2(supports-color@10.2.2) '@verdaccio/utils': 8.1.2 JSONStream: 1.3.5 async: 3.2.6 @@ -17013,7 +17613,7 @@ snapshots: lru-cache: 7.18.3 mime: 3.0.0 semver: 7.8.0 - verdaccio-audit: 13.0.2(encoding@0.1.13) + verdaccio-audit: 13.0.2(encoding@0.1.13)(supports-color@10.2.2) verdaccio-htpasswd: 13.0.2 transitivePeerDependencies: - bare-abort-controller @@ -17027,7 +17627,7 @@ snapshots: core-util-is: 1.0.2 extsprintf: 1.3.0 - vite@7.3.5(@types/node@24.13.2)(jiti@2.7.0)(less@4.6.4)(sass@1.100.0)(terser@5.48.0)(tsx@4.22.4)(yaml@2.9.0): + vite@7.3.5(@types/node@24.13.2)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.48.0)(tsx@4.22.4)(yaml@2.9.0): dependencies: esbuild: 0.27.7 fdir: 6.5.0(picomatch@4.0.4) @@ -17039,21 +17639,21 @@ snapshots: '@types/node': 24.13.2 fsevents: 2.3.3 jiti: 2.7.0 - less: 4.6.4 - sass: 1.100.0 + less: 4.6.6 + sass: 1.101.0 terser: 5.48.0 tsx: 4.22.4 yaml: 2.9.0 - vitest@4.1.8(@opentelemetry/api@1.9.1)(@types/node@24.13.2)(@vitest/coverage-v8@4.1.8)(jiti@2.7.0)(jsdom@29.1.1)(less@4.6.4)(sass@1.100.0)(terser@5.48.0)(tsx@4.22.4)(yaml@2.9.0): + vitest@4.1.9(@opentelemetry/api@1.9.1)(@types/node@24.13.2)(@vitest/coverage-v8@4.1.9)(jiti@2.7.0)(jsdom@29.1.1)(less@4.6.6)(sass@1.101.0)(terser@5.48.0)(tsx@4.22.4)(yaml@2.9.0): dependencies: - '@vitest/expect': 4.1.8 - '@vitest/mocker': 4.1.8(vite@7.3.5(@types/node@24.13.2)(jiti@2.7.0)(less@4.6.4)(sass@1.100.0)(terser@5.48.0)(tsx@4.22.4)(yaml@2.9.0)) - '@vitest/pretty-format': 4.1.8 - '@vitest/runner': 4.1.8 - '@vitest/snapshot': 4.1.8 - '@vitest/spy': 4.1.8 - '@vitest/utils': 4.1.8 + '@vitest/expect': 4.1.9 + '@vitest/mocker': 4.1.9(vite@7.3.5(@types/node@24.13.2)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.48.0)(tsx@4.22.4)(yaml@2.9.0)) + '@vitest/pretty-format': 4.1.9 + '@vitest/runner': 4.1.9 + '@vitest/snapshot': 4.1.9 + '@vitest/spy': 4.1.9 + '@vitest/utils': 4.1.9 es-module-lexer: 2.1.0 expect-type: 1.3.0 magic-string: 0.30.21 @@ -17065,12 +17665,12 @@ snapshots: tinyexec: 1.2.4 tinyglobby: 0.2.17 tinyrainbow: 3.1.0 - vite: 7.3.5(@types/node@24.13.2)(jiti@2.7.0)(less@4.6.4)(sass@1.100.0)(terser@5.48.0)(tsx@4.22.4)(yaml@2.9.0) + vite: 7.3.5(@types/node@24.13.2)(jiti@2.7.0)(less@4.6.6)(sass@1.101.0)(terser@5.48.0)(tsx@4.22.4)(yaml@2.9.0) why-is-node-running: 2.3.0 optionalDependencies: '@opentelemetry/api': 1.9.1 '@types/node': 24.13.2 - '@vitest/coverage-v8': 4.1.8(vitest@4.1.8) + '@vitest/coverage-v8': 4.1.9(vitest@4.1.9) jsdom: 29.1.1 transitivePeerDependencies: - jiti @@ -17096,6 +17696,10 @@ snapshots: glob-to-regexp: 0.4.1 graceful-fs: 4.2.11 + watchpack@2.5.2: + dependencies: + graceful-fs: 4.2.11 + wbuf@1.7.3: dependencies: minimalistic-assert: 1.0.1 @@ -17113,7 +17717,7 @@ snapshots: webidl-conversions@8.0.1: {} - webpack-dev-middleware@7.4.5(tslib@2.8.1)(webpack@5.107.2(esbuild@0.28.0)(postcss@8.5.15)): + webpack-dev-middleware@7.4.5(tslib@2.8.1)(webpack@5.107.2(esbuild@0.28.1)(postcss@8.5.15)): dependencies: colorette: 2.0.20 memfs: 4.57.6(tslib@2.8.1) @@ -17122,11 +17726,11 @@ snapshots: range-parser: 1.2.1 schema-utils: 4.3.3 optionalDependencies: - webpack: 5.107.2(esbuild@0.28.0)(postcss@8.5.15) + webpack: 5.107.2(esbuild@0.28.1)(postcss@8.5.15) transitivePeerDependencies: - tslib - webpack-dev-middleware@7.4.5(tslib@2.8.1)(webpack@5.107.2(esbuild@0.28.0)): + webpack-dev-middleware@7.4.5(tslib@2.8.1)(webpack@5.107.2(esbuild@0.28.1)): dependencies: colorette: 2.0.20 memfs: 4.57.6(tslib@2.8.1) @@ -17135,11 +17739,11 @@ snapshots: range-parser: 1.2.1 schema-utils: 4.3.3 optionalDependencies: - webpack: 5.107.2(esbuild@0.28.0) + webpack: 5.107.2(esbuild@0.28.1) transitivePeerDependencies: - tslib - webpack-dev-middleware@8.0.3(tslib@2.8.1)(webpack@5.107.2(esbuild@0.28.0)(postcss@8.5.15)): + webpack-dev-middleware@8.0.3(tslib@2.8.1)(webpack@5.107.2(esbuild@0.28.1)(postcss@8.5.15)): dependencies: memfs: 4.57.6(tslib@2.8.1) mime-types: 3.0.2 @@ -17147,11 +17751,11 @@ snapshots: range-parser: 1.2.1 schema-utils: 4.3.3 optionalDependencies: - webpack: 5.107.2(esbuild@0.28.0)(postcss@8.5.15) + webpack: 5.107.2(esbuild@0.28.1)(postcss@8.5.15) transitivePeerDependencies: - tslib - webpack-dev-server@5.2.4(bufferutil@4.1.0)(tslib@2.8.1)(utf-8-validate@6.0.6)(webpack@5.107.2(esbuild@0.28.0)(postcss@8.5.15)): + webpack-dev-server@5.2.5(bufferutil@4.1.0)(tslib@2.8.1)(utf-8-validate@6.0.6)(webpack@5.107.2(esbuild@0.28.1)(postcss@8.5.15)): dependencies: '@types/bonjour': 3.5.13 '@types/connect-history-api-fallback': 1.5.4 @@ -17179,10 +17783,10 @@ snapshots: serve-index: 1.9.2 sockjs: 0.3.24 spdy: 4.0.2 - webpack-dev-middleware: 7.4.5(tslib@2.8.1)(webpack@5.107.2(esbuild@0.28.0)(postcss@8.5.15)) + webpack-dev-middleware: 7.4.5(tslib@2.8.1)(webpack@5.107.2(esbuild@0.28.1)(postcss@8.5.15)) ws: 8.21.0(bufferutil@4.1.0)(utf-8-validate@6.0.6) optionalDependencies: - webpack: 5.107.2(esbuild@0.28.0)(postcss@8.5.15) + webpack: 5.107.2(esbuild@0.28.1)(postcss@8.5.15) transitivePeerDependencies: - bufferutil - debug @@ -17190,7 +17794,7 @@ snapshots: - tslib - utf-8-validate - webpack-dev-server@5.2.4(bufferutil@4.1.0)(tslib@2.8.1)(utf-8-validate@6.0.6)(webpack@5.107.2(esbuild@0.28.0)): + webpack-dev-server@5.2.5(bufferutil@4.1.0)(tslib@2.8.1)(utf-8-validate@6.0.6)(webpack@5.107.2(esbuild@0.28.1)): dependencies: '@types/bonjour': 3.5.13 '@types/connect-history-api-fallback': 1.5.4 @@ -17218,10 +17822,10 @@ snapshots: serve-index: 1.9.2 sockjs: 0.3.24 spdy: 4.0.2 - webpack-dev-middleware: 7.4.5(tslib@2.8.1)(webpack@5.107.2(esbuild@0.28.0)) + webpack-dev-middleware: 7.4.5(tslib@2.8.1)(webpack@5.107.2(esbuild@0.28.1)) ws: 8.21.0(bufferutil@4.1.0)(utf-8-validate@6.0.6) optionalDependencies: - webpack: 5.107.2(esbuild@0.28.0) + webpack: 5.107.2(esbuild@0.28.1) transitivePeerDependencies: - bufferutil - debug @@ -17237,12 +17841,12 @@ snapshots: webpack-sources@3.5.0: {} - webpack-subresource-integrity@5.1.0(webpack@5.107.2(esbuild@0.28.0)(postcss@8.5.15)): + webpack-subresource-integrity@5.1.0(webpack@5.107.2(esbuild@0.28.1)(postcss@8.5.15)): dependencies: typed-assert: 1.0.9 - webpack: 5.107.2(esbuild@0.28.0)(postcss@8.5.15) + webpack: 5.107.2(esbuild@0.28.1)(postcss@8.5.15) - webpack@5.107.2(esbuild@0.28.0): + webpack@5.107.2(esbuild@0.28.1): dependencies: '@types/estree': 1.0.9 '@types/json-schema': 7.0.15 @@ -17264,7 +17868,7 @@ snapshots: neo-async: 2.6.2 schema-utils: 4.3.3 tapable: 2.3.3 - terser-webpack-plugin: 5.6.1(esbuild@0.28.0)(webpack@5.107.2(esbuild@0.28.0)) + terser-webpack-plugin: 5.6.1(esbuild@0.28.1)(webpack@5.107.2(esbuild@0.28.1)) watchpack: 2.5.1 webpack-sources: 3.5.0 transitivePeerDependencies: @@ -17281,7 +17885,7 @@ snapshots: - postcss - uglify-js - webpack@5.107.2(esbuild@0.28.0)(postcss@8.5.15): + webpack@5.107.2(esbuild@0.28.1)(postcss@8.5.15): dependencies: '@types/estree': 1.0.9 '@types/json-schema': 7.0.15 @@ -17303,7 +17907,7 @@ snapshots: neo-async: 2.6.2 schema-utils: 4.3.3 tapable: 2.3.3 - terser-webpack-plugin: 5.6.1(esbuild@0.28.0)(postcss@8.5.15)(webpack@5.107.2(esbuild@0.28.0)(postcss@8.5.15)) + terser-webpack-plugin: 5.6.1(esbuild@0.28.1)(postcss@8.5.15)(webpack@5.107.2(esbuild@0.28.1)(postcss@8.5.15)) watchpack: 2.5.1 webpack-sources: 3.5.0 transitivePeerDependencies: From 009db66cdd8795f01a961cfcc8ec0cdb6aac64ab Mon Sep 17 00:00:00 2001 From: Angular Robot Date: Tue, 16 Jun 2026 07:10:43 +0000 Subject: [PATCH 048/787] build: update pnpm to v11.7.0 See associated pull request for more information. --- MODULE.bazel | 4 ++-- package.json | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/MODULE.bazel b/MODULE.bazel index 6b21b34ca20c..5b6e56a15118 100644 --- a/MODULE.bazel +++ b/MODULE.bazel @@ -131,8 +131,8 @@ use_repo( pnpm = use_extension("@aspect_rules_js//npm:extensions.bzl", "pnpm") pnpm.pnpm( name = "pnpm", - pnpm_version = "11.5.3", - pnpm_version_integrity = "sha512-esHJGTQcITo03A0Cr7cUPFwmrCbujEeC3uqCG4rGTSE0oIH9iUHa5uKbu0j1jfwrf7zuzMB8svCdIZ00Kklp7Q==", + pnpm_version = "11.7.0", + pnpm_version_integrity = "sha512-GcyFLBIMcSV2DyRD7mvgyltA+fUFmN4aCaHxd1A+AQ5Xwjx3ZG4B52HeWb+HT7IqM5jDOrlpH8E+uUa28PTWIA==", ) use_repo(pnpm, "pnpm") diff --git a/package.json b/package.json index a60331058036..d3edf0c4a51a 100644 --- a/package.json +++ b/package.json @@ -28,12 +28,12 @@ "type": "git", "url": "git+https://github.com/angular/angular-cli.git" }, - "packageManager": "pnpm@11.5.3", + "packageManager": "pnpm@11.7.0", "engines": { "node": "^22.22.3 || ^24.15.0 || >=26.0.0", "npm": "Please use pnpm instead of NPM to install dependencies", "yarn": "Please use pnpm instead of Yarn to install dependencies", - "pnpm": "11.5.3" + "pnpm": "11.7.0" }, "author": "Angular Authors", "license": "MIT", From 37f1a749132d55a81cec231bd260ed280b10fc00 Mon Sep 17 00:00:00 2001 From: Jaime Burgos <73321943+SkyZeroZx@users.noreply.github.com> Date: Tue, 16 Jun 2026 08:03:41 -0500 Subject: [PATCH 049/787] fix(@angular/ssr): avoid caching non-SSG page lookups Only cache CommonEngine SSG lookup results after the target file is confirmed to be a prerendered SSG page. --- .../ssr/node/src/common-engine/common-engine.ts | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/packages/angular/ssr/node/src/common-engine/common-engine.ts b/packages/angular/ssr/node/src/common-engine/common-engine.ts index 0c97c20d891a..8db528f30f34 100644 --- a/packages/angular/ssr/node/src/common-engine/common-engine.ts +++ b/packages/angular/ssr/node/src/common-engine/common-engine.ts @@ -167,17 +167,19 @@ export class CommonEngine { if (pagePath === resolve(documentFilePath) || !(await exists(pagePath))) { // View matches with prerender path or file does not exist. - this.pageIsSSG.set(pagePath, false); - return undefined; } // Static file exists. const content = await fs.promises.readFile(pagePath, 'utf-8'); const isSSG = SSG_MARKER_REGEXP.test(content); - this.pageIsSSG.set(pagePath, isSSG); + if (isSSG) { + this.pageIsSSG.set(pagePath, true); + + return content; + } - return isSSG ? content : undefined; + return undefined; } private async renderApplication(opts: CommonEngineRenderOptions): Promise { From 151d4261b0d14e8666865dfc02ad10f283989fc6 Mon Sep 17 00:00:00 2001 From: Angular Robot Date: Tue, 16 Jun 2026 18:46:24 +0000 Subject: [PATCH 050/787] build: update cross-repo angular dependencies See associated pull request for more information. --- MODULE.bazel | 2 +- package.json | 2 +- pnpm-lock.yaml | 360 ++++++++++++++--------------- tests/e2e/ng-snapshot/package.json | 32 +-- 4 files changed, 198 insertions(+), 198 deletions(-) diff --git a/MODULE.bazel b/MODULE.bazel index 5b6e56a15118..77179ae29a31 100644 --- a/MODULE.bazel +++ b/MODULE.bazel @@ -26,7 +26,7 @@ git_override( bazel_dep(name = "devinfra") git_override( module_name = "devinfra", - commit = "023fc8fd55661b2ba24151350bd7460dafd8ae88", + commit = "e9faacd5b4df391f59989b6fb448b2c24115d592", remote = "https://github.com/angular/dev-infra.git", ) diff --git a/package.json b/package.json index d3edf0c4a51a..f1f5ced9ff5b 100644 --- a/package.json +++ b/package.json @@ -54,7 +54,7 @@ "@angular/forms": "22.1.0-next.0", "@angular/localize": "22.1.0-next.0", "@angular/material": "22.1.0-next.0", - "@angular/ng-dev": "https://github.com/angular/dev-infra-private-ng-dev-builds.git#cefe10420ad2ecdadd21129be75b71aa485baea6", + "@angular/ng-dev": "https://github.com/angular/dev-infra-private-ng-dev-builds.git#cdd4a4146520ed794b0342d0a86a0e2b31f129e3", "@angular/platform-browser": "22.1.0-next.0", "@angular/platform-server": "22.1.0-next.0", "@angular/router": "22.1.0-next.0", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 2a9699137447..063dfb959e7c 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -50,8 +50,8 @@ importers: specifier: 22.1.0-next.0 version: 22.1.0-next.0(25ca0260cba80497f59a6bedbf88cafa) '@angular/ng-dev': - specifier: https://github.com/angular/dev-infra-private-ng-dev-builds.git#cefe10420ad2ecdadd21129be75b71aa485baea6 - version: https://codeload.github.com/angular/dev-infra-private-ng-dev-builds/tar.gz/cefe10420ad2ecdadd21129be75b71aa485baea6(@modelcontextprotocol/sdk@1.29.0(zod@4.4.3)) + specifier: https://github.com/angular/dev-infra-private-ng-dev-builds.git#cdd4a4146520ed794b0342d0a86a0e2b31f129e3 + version: https://codeload.github.com/angular/dev-infra-private-ng-dev-builds/tar.gz/cdd4a4146520ed794b0342d0a86a0e2b31f129e3(@modelcontextprotocol/sdk@1.29.0(zod@4.4.3)) '@angular/platform-browser': specifier: 22.1.0-next.0 version: 22.1.0-next.0(@angular/animations@22.1.0-next.0(@angular/core@22.1.0-next.0(@angular/compiler@22.1.0-next.0)(rxjs@7.8.2)(zone.js@0.16.2)))(@angular/common@22.1.0-next.0(@angular/core@22.1.0-next.0(@angular/compiler@22.1.0-next.0)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2))(@angular/core@22.1.0-next.0(@angular/compiler@22.1.0-next.0)(rxjs@7.8.2)(zone.js@0.16.2)) @@ -66,7 +66,7 @@ importers: version: 22.1.0-next.0(@angular/core@22.1.0-next.0(@angular/compiler@22.1.0-next.0)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2) '@babel/core': specifier: 7.29.7 - version: 7.29.7(supports-color@10.2.2) + version: 7.29.7 '@bazel/bazelisk': specifier: 1.28.1 version: 1.28.1 @@ -81,7 +81,7 @@ importers: version: 2.1.0(eslint@10.5.0(jiti@2.7.0)) '@eslint/eslintrc': specifier: 3.3.5 - version: 3.3.5(supports-color@10.2.2) + version: 3.3.5 '@eslint/js': specifier: 10.0.1 version: 10.0.1(eslint@10.5.0(jiti@2.7.0)) @@ -201,7 +201,7 @@ importers: version: 2.32.0(@typescript-eslint/parser@8.61.0(eslint@10.5.0(jiti@2.7.0))(typescript@6.0.3))(eslint@10.5.0(jiti@2.7.0)) express: specifier: 5.2.1 - version: 5.2.1(supports-color@10.2.2) + version: 5.2.1 fast-glob: specifier: 3.3.3 version: 3.3.3 @@ -231,19 +231,19 @@ importers: version: 7.0.0 karma: specifier: ~6.4.0 - version: 6.4.4(bufferutil@4.1.0)(supports-color@10.2.2)(utf-8-validate@6.0.6) + version: 6.4.4(bufferutil@4.1.0)(utf-8-validate@6.0.6) karma-chrome-launcher: specifier: ~3.2.0 version: 3.2.0 karma-coverage: specifier: ~2.2.0 - version: 2.2.1(supports-color@10.2.2) + version: 2.2.1 karma-jasmine: specifier: ~5.1.0 - version: 5.1.0(karma@6.4.4(bufferutil@4.1.0)(supports-color@10.2.2)(utf-8-validate@6.0.6)) + version: 5.1.0(karma@6.4.4(bufferutil@4.1.0)(utf-8-validate@6.0.6)) karma-jasmine-html-reporter: specifier: ~2.2.0 - version: 2.2.0(jasmine-core@6.3.0)(karma-jasmine@5.1.0(karma@6.4.4(bufferutil@4.1.0)(supports-color@10.2.2)(utf-8-validate@6.0.6)))(karma@6.4.4(bufferutil@4.1.0)(supports-color@10.2.2)(utf-8-validate@6.0.6)) + version: 2.2.0(jasmine-core@6.3.0)(karma-jasmine@5.1.0(karma@6.4.4(bufferutil@4.1.0)(utf-8-validate@6.0.6)))(karma@6.4.4(bufferutil@4.1.0)(utf-8-validate@6.0.6)) karma-source-map-support: specifier: 1.4.0 version: 1.4.0 @@ -291,10 +291,10 @@ importers: version: 1.10.0 verdaccio: specifier: 6.7.2 - version: 6.7.2(encoding@0.1.13)(supports-color@10.2.2) + version: 6.7.2(encoding@0.1.13) verdaccio-auth-memory: specifier: ^13.0.0 - version: 13.0.2(supports-color@10.2.2) + version: 13.0.2 zone.js: specifier: ^0.16.0 version: 0.16.2 @@ -318,7 +318,7 @@ importers: version: 4.1.9(vitest@4.1.9) browser-sync: specifier: 3.0.4 - version: 3.0.4(bufferutil@4.1.0)(supports-color@10.2.2)(utf-8-validate@6.0.6) + version: 3.0.4(bufferutil@4.1.0)(utf-8-validate@6.0.6) istanbul-lib-instrument: specifier: 6.0.3 version: 6.0.3 @@ -345,7 +345,7 @@ importers: version: link:../../angular_devkit/architect '@babel/core': specifier: 7.29.7 - version: 7.29.7(supports-color@10.2.2) + version: 7.29.7 '@babel/helper-annotate-as-pure': specifier: 7.29.7 version: 7.29.7 @@ -579,7 +579,7 @@ importers: version: link:../../angular/build '@babel/core': specifier: 7.29.7 - version: 7.29.7(supports-color@10.2.2) + version: 7.29.7 '@babel/generator': specifier: 7.29.7 version: 7.29.7 @@ -597,7 +597,7 @@ importers: version: 7.29.7(@babel/core@7.29.7) '@babel/plugin-transform-runtime': specifier: 7.29.7 - version: 7.29.7(@babel/core@7.29.7)(supports-color@10.2.2) + version: 7.29.7(@babel/core@7.29.7) '@babel/preset-env': specifier: 7.29.7 version: 7.29.7(@babel/core@7.29.7) @@ -727,7 +727,7 @@ importers: version: link:../../angular/ssr browser-sync: specifier: 3.0.4 - version: 3.0.4(bufferutil@4.1.0)(supports-color@10.2.2)(utf-8-validate@6.0.6) + version: 3.0.4(bufferutil@4.1.0)(utf-8-validate@6.0.6) ng-packagr: specifier: 22.1.0-next.2 version: 22.1.0-next.2(@angular/compiler-cli@22.1.0-next.0(@angular/compiler@22.1.0-next.0)(typescript@6.0.3))(tslib@2.8.1)(typescript@6.0.3) @@ -1012,9 +1012,9 @@ packages: '@angular/platform-browser': ^22.0.0-0 || ^22.1.0-0 || ^22.2.0-0 || ^22.3.0-0 || ^23.0.0-0 rxjs: ^6.5.3 || ^7.4.0 - '@angular/ng-dev@https://codeload.github.com/angular/dev-infra-private-ng-dev-builds/tar.gz/cefe10420ad2ecdadd21129be75b71aa485baea6': - resolution: {gitHosted: true, integrity: sha512-w3tzwKpn+TNJL6RXw7D2puYVbLfo1SZco49vh8xym9hhUNa80MfLkaYS5yz8N0wpzucm2GfpT2vuAX0tnWNtwA==, tarball: https://codeload.github.com/angular/dev-infra-private-ng-dev-builds/tar.gz/cefe10420ad2ecdadd21129be75b71aa485baea6} - version: 0.0.0-023fc8fd55661b2ba24151350bd7460dafd8ae88 + '@angular/ng-dev@https://codeload.github.com/angular/dev-infra-private-ng-dev-builds/tar.gz/cdd4a4146520ed794b0342d0a86a0e2b31f129e3': + resolution: {gitHosted: true, integrity: sha512-77lzhDNz78hakS5ahbzVbcCKSJgwLSbDlCwQgLQWphzdaaMid0ILM5eHywGCkgBqzg6jrrScrEfN62io2eFz7A==, tarball: https://codeload.github.com/angular/dev-infra-private-ng-dev-builds/tar.gz/cdd4a4146520ed794b0342d0a86a0e2b31f129e3} + version: 0.0.0-e9faacd5b4df391f59989b6fb448b2c24115d592 hasBin: true '@angular/platform-browser@22.1.0-next.0': @@ -9042,7 +9042,7 @@ snapshots: '@angular/compiler-cli@22.1.0-next.0(@angular/compiler@22.1.0-next.0)(typescript@6.0.3)': dependencies: '@angular/compiler': 22.1.0-next.0 - '@babel/core': 7.29.7(supports-color@10.2.2) + '@babel/core': 7.29.7 '@jridgewell/sourcemap-codec': 1.5.5 chokidar: 5.0.0 convert-source-map: 1.9.0 @@ -9081,7 +9081,7 @@ snapshots: dependencies: '@angular/compiler': 22.1.0-next.0 '@angular/compiler-cli': 22.1.0-next.0(@angular/compiler@22.1.0-next.0)(typescript@6.0.3) - '@babel/core': 7.29.7(supports-color@10.2.2) + '@babel/core': 7.29.7 '@types/babel__core': 7.20.5 tinyglobby: 0.2.17 yargs: 18.0.0 @@ -9098,7 +9098,7 @@ snapshots: rxjs: 7.8.2 tslib: 2.8.1 - '@angular/ng-dev@https://codeload.github.com/angular/dev-infra-private-ng-dev-builds/tar.gz/cefe10420ad2ecdadd21129be75b71aa485baea6(@modelcontextprotocol/sdk@1.29.0(zod@4.4.3))': + '@angular/ng-dev@https://codeload.github.com/angular/dev-infra-private-ng-dev-builds/tar.gz/cdd4a4146520ed794b0342d0a86a0e2b31f129e3(@modelcontextprotocol/sdk@1.29.0(zod@4.4.3))': dependencies: '@actions/core': 3.0.1 '@conventional-changelog/git-client': 2.7.0(conventional-commits-filter@5.0.0)(conventional-commits-parser@6.4.0) @@ -9218,7 +9218,7 @@ snapshots: '@babel/compat-data@7.29.7': {} - '@babel/core@7.29.7(supports-color@10.2.2)': + '@babel/core@7.29.7': dependencies: '@babel/code-frame': 7.29.7 '@babel/generator': 7.29.7 @@ -9260,7 +9260,7 @@ snapshots: '@babel/helper-create-class-features-plugin@7.29.7(@babel/core@7.29.7)': dependencies: - '@babel/core': 7.29.7(supports-color@10.2.2) + '@babel/core': 7.29.7 '@babel/helper-annotate-as-pure': 7.29.7 '@babel/helper-member-expression-to-functions': 7.29.7 '@babel/helper-optimise-call-expression': 7.29.7 @@ -9273,14 +9273,14 @@ snapshots: '@babel/helper-create-regexp-features-plugin@7.29.7(@babel/core@7.29.7)': dependencies: - '@babel/core': 7.29.7(supports-color@10.2.2) + '@babel/core': 7.29.7 '@babel/helper-annotate-as-pure': 7.29.7 regexpu-core: 6.4.0 semver: 6.3.1 - '@babel/helper-define-polyfill-provider@0.6.8(@babel/core@7.29.7)(supports-color@10.2.2)': + '@babel/helper-define-polyfill-provider@0.6.8(@babel/core@7.29.7)': dependencies: - '@babel/core': 7.29.7(supports-color@10.2.2) + '@babel/core': 7.29.7 '@babel/helper-compilation-targets': 7.29.7 '@babel/helper-plugin-utils': 7.29.7 debug: 4.4.3(supports-color@10.2.2) @@ -9307,7 +9307,7 @@ snapshots: '@babel/helper-module-transforms@7.29.7(@babel/core@7.29.7)': dependencies: - '@babel/core': 7.29.7(supports-color@10.2.2) + '@babel/core': 7.29.7 '@babel/helper-module-imports': 7.29.7 '@babel/helper-validator-identifier': 7.29.7 '@babel/traverse': 7.29.7 @@ -9322,7 +9322,7 @@ snapshots: '@babel/helper-remap-async-to-generator@7.29.7(@babel/core@7.29.7)': dependencies: - '@babel/core': 7.29.7(supports-color@10.2.2) + '@babel/core': 7.29.7 '@babel/helper-annotate-as-pure': 7.29.7 '@babel/helper-wrap-function': 7.29.7 '@babel/traverse': 7.29.7 @@ -9331,7 +9331,7 @@ snapshots: '@babel/helper-replace-supers@7.29.7(@babel/core@7.29.7)': dependencies: - '@babel/core': 7.29.7(supports-color@10.2.2) + '@babel/core': 7.29.7 '@babel/helper-member-expression-to-functions': 7.29.7 '@babel/helper-optimise-call-expression': 7.29.7 '@babel/traverse': 7.29.7 @@ -9374,7 +9374,7 @@ snapshots: '@babel/plugin-bugfix-firefox-class-in-computed-class-key@7.29.7(@babel/core@7.29.7)': dependencies: - '@babel/core': 7.29.7(supports-color@10.2.2) + '@babel/core': 7.29.7 '@babel/helper-plugin-utils': 7.29.7 '@babel/traverse': 7.29.7 transitivePeerDependencies: @@ -9382,17 +9382,17 @@ snapshots: '@babel/plugin-bugfix-safari-class-field-initializer-scope@7.29.7(@babel/core@7.29.7)': dependencies: - '@babel/core': 7.29.7(supports-color@10.2.2) + '@babel/core': 7.29.7 '@babel/helper-plugin-utils': 7.29.7 '@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression@7.29.7(@babel/core@7.29.7)': dependencies: - '@babel/core': 7.29.7(supports-color@10.2.2) + '@babel/core': 7.29.7 '@babel/helper-plugin-utils': 7.29.7 '@babel/plugin-bugfix-safari-rest-destructuring-rhs-array@7.29.7(@babel/core@7.29.7)': dependencies: - '@babel/core': 7.29.7(supports-color@10.2.2) + '@babel/core': 7.29.7 '@babel/helper-plugin-utils': 7.29.7 '@babel/helper-skip-transparent-expression-wrappers': 7.29.7 transitivePeerDependencies: @@ -9400,7 +9400,7 @@ snapshots: '@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining@7.29.7(@babel/core@7.29.7)': dependencies: - '@babel/core': 7.29.7(supports-color@10.2.2) + '@babel/core': 7.29.7 '@babel/helper-plugin-utils': 7.29.7 '@babel/helper-skip-transparent-expression-wrappers': 7.29.7 '@babel/plugin-transform-optional-chaining': 7.29.7(@babel/core@7.29.7) @@ -9409,7 +9409,7 @@ snapshots: '@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly@7.29.7(@babel/core@7.29.7)': dependencies: - '@babel/core': 7.29.7(supports-color@10.2.2) + '@babel/core': 7.29.7 '@babel/helper-plugin-utils': 7.29.7 '@babel/traverse': 7.29.7 transitivePeerDependencies: @@ -9417,32 +9417,32 @@ snapshots: '@babel/plugin-proposal-private-property-in-object@7.21.0-placeholder-for-preset-env.2(@babel/core@7.29.7)': dependencies: - '@babel/core': 7.29.7(supports-color@10.2.2) + '@babel/core': 7.29.7 '@babel/plugin-syntax-import-assertions@7.29.7(@babel/core@7.29.7)': dependencies: - '@babel/core': 7.29.7(supports-color@10.2.2) + '@babel/core': 7.29.7 '@babel/helper-plugin-utils': 7.29.7 '@babel/plugin-syntax-import-attributes@7.29.7(@babel/core@7.29.7)': dependencies: - '@babel/core': 7.29.7(supports-color@10.2.2) + '@babel/core': 7.29.7 '@babel/helper-plugin-utils': 7.29.7 '@babel/plugin-syntax-unicode-sets-regex@7.18.6(@babel/core@7.29.7)': dependencies: - '@babel/core': 7.29.7(supports-color@10.2.2) + '@babel/core': 7.29.7 '@babel/helper-create-regexp-features-plugin': 7.29.7(@babel/core@7.29.7) '@babel/helper-plugin-utils': 7.29.7 '@babel/plugin-transform-arrow-functions@7.29.7(@babel/core@7.29.7)': dependencies: - '@babel/core': 7.29.7(supports-color@10.2.2) + '@babel/core': 7.29.7 '@babel/helper-plugin-utils': 7.29.7 '@babel/plugin-transform-async-generator-functions@7.29.7(@babel/core@7.29.7)': dependencies: - '@babel/core': 7.29.7(supports-color@10.2.2) + '@babel/core': 7.29.7 '@babel/helper-plugin-utils': 7.29.7 '@babel/helper-remap-async-to-generator': 7.29.7(@babel/core@7.29.7) '@babel/traverse': 7.29.7 @@ -9451,7 +9451,7 @@ snapshots: '@babel/plugin-transform-async-to-generator@7.29.7(@babel/core@7.29.7)': dependencies: - '@babel/core': 7.29.7(supports-color@10.2.2) + '@babel/core': 7.29.7 '@babel/helper-module-imports': 7.29.7 '@babel/helper-plugin-utils': 7.29.7 '@babel/helper-remap-async-to-generator': 7.29.7(@babel/core@7.29.7) @@ -9460,17 +9460,17 @@ snapshots: '@babel/plugin-transform-block-scoped-functions@7.29.7(@babel/core@7.29.7)': dependencies: - '@babel/core': 7.29.7(supports-color@10.2.2) + '@babel/core': 7.29.7 '@babel/helper-plugin-utils': 7.29.7 '@babel/plugin-transform-block-scoping@7.29.7(@babel/core@7.29.7)': dependencies: - '@babel/core': 7.29.7(supports-color@10.2.2) + '@babel/core': 7.29.7 '@babel/helper-plugin-utils': 7.29.7 '@babel/plugin-transform-class-properties@7.29.7(@babel/core@7.29.7)': dependencies: - '@babel/core': 7.29.7(supports-color@10.2.2) + '@babel/core': 7.29.7 '@babel/helper-create-class-features-plugin': 7.29.7(@babel/core@7.29.7) '@babel/helper-plugin-utils': 7.29.7 transitivePeerDependencies: @@ -9478,7 +9478,7 @@ snapshots: '@babel/plugin-transform-class-static-block@7.29.7(@babel/core@7.29.7)': dependencies: - '@babel/core': 7.29.7(supports-color@10.2.2) + '@babel/core': 7.29.7 '@babel/helper-create-class-features-plugin': 7.29.7(@babel/core@7.29.7) '@babel/helper-plugin-utils': 7.29.7 transitivePeerDependencies: @@ -9486,7 +9486,7 @@ snapshots: '@babel/plugin-transform-classes@7.29.7(@babel/core@7.29.7)': dependencies: - '@babel/core': 7.29.7(supports-color@10.2.2) + '@babel/core': 7.29.7 '@babel/helper-annotate-as-pure': 7.29.7 '@babel/helper-compilation-targets': 7.29.7 '@babel/helper-globals': 7.29.7 @@ -9498,13 +9498,13 @@ snapshots: '@babel/plugin-transform-computed-properties@7.29.7(@babel/core@7.29.7)': dependencies: - '@babel/core': 7.29.7(supports-color@10.2.2) + '@babel/core': 7.29.7 '@babel/helper-plugin-utils': 7.29.7 '@babel/template': 7.29.7 '@babel/plugin-transform-destructuring@7.29.7(@babel/core@7.29.7)': dependencies: - '@babel/core': 7.29.7(supports-color@10.2.2) + '@babel/core': 7.29.7 '@babel/helper-plugin-utils': 7.29.7 '@babel/traverse': 7.29.7 transitivePeerDependencies: @@ -9512,29 +9512,29 @@ snapshots: '@babel/plugin-transform-dotall-regex@7.29.7(@babel/core@7.29.7)': dependencies: - '@babel/core': 7.29.7(supports-color@10.2.2) + '@babel/core': 7.29.7 '@babel/helper-create-regexp-features-plugin': 7.29.7(@babel/core@7.29.7) '@babel/helper-plugin-utils': 7.29.7 '@babel/plugin-transform-duplicate-keys@7.29.7(@babel/core@7.29.7)': dependencies: - '@babel/core': 7.29.7(supports-color@10.2.2) + '@babel/core': 7.29.7 '@babel/helper-plugin-utils': 7.29.7 '@babel/plugin-transform-duplicate-named-capturing-groups-regex@7.29.7(@babel/core@7.29.7)': dependencies: - '@babel/core': 7.29.7(supports-color@10.2.2) + '@babel/core': 7.29.7 '@babel/helper-create-regexp-features-plugin': 7.29.7(@babel/core@7.29.7) '@babel/helper-plugin-utils': 7.29.7 '@babel/plugin-transform-dynamic-import@7.29.7(@babel/core@7.29.7)': dependencies: - '@babel/core': 7.29.7(supports-color@10.2.2) + '@babel/core': 7.29.7 '@babel/helper-plugin-utils': 7.29.7 '@babel/plugin-transform-explicit-resource-management@7.29.7(@babel/core@7.29.7)': dependencies: - '@babel/core': 7.29.7(supports-color@10.2.2) + '@babel/core': 7.29.7 '@babel/helper-plugin-utils': 7.29.7 '@babel/plugin-transform-destructuring': 7.29.7(@babel/core@7.29.7) transitivePeerDependencies: @@ -9542,17 +9542,17 @@ snapshots: '@babel/plugin-transform-exponentiation-operator@7.29.7(@babel/core@7.29.7)': dependencies: - '@babel/core': 7.29.7(supports-color@10.2.2) + '@babel/core': 7.29.7 '@babel/helper-plugin-utils': 7.29.7 '@babel/plugin-transform-export-namespace-from@7.29.7(@babel/core@7.29.7)': dependencies: - '@babel/core': 7.29.7(supports-color@10.2.2) + '@babel/core': 7.29.7 '@babel/helper-plugin-utils': 7.29.7 '@babel/plugin-transform-for-of@7.29.7(@babel/core@7.29.7)': dependencies: - '@babel/core': 7.29.7(supports-color@10.2.2) + '@babel/core': 7.29.7 '@babel/helper-plugin-utils': 7.29.7 '@babel/helper-skip-transparent-expression-wrappers': 7.29.7 transitivePeerDependencies: @@ -9560,7 +9560,7 @@ snapshots: '@babel/plugin-transform-function-name@7.29.7(@babel/core@7.29.7)': dependencies: - '@babel/core': 7.29.7(supports-color@10.2.2) + '@babel/core': 7.29.7 '@babel/helper-compilation-targets': 7.29.7 '@babel/helper-plugin-utils': 7.29.7 '@babel/traverse': 7.29.7 @@ -9569,27 +9569,27 @@ snapshots: '@babel/plugin-transform-json-strings@7.29.7(@babel/core@7.29.7)': dependencies: - '@babel/core': 7.29.7(supports-color@10.2.2) + '@babel/core': 7.29.7 '@babel/helper-plugin-utils': 7.29.7 '@babel/plugin-transform-literals@7.29.7(@babel/core@7.29.7)': dependencies: - '@babel/core': 7.29.7(supports-color@10.2.2) + '@babel/core': 7.29.7 '@babel/helper-plugin-utils': 7.29.7 '@babel/plugin-transform-logical-assignment-operators@7.29.7(@babel/core@7.29.7)': dependencies: - '@babel/core': 7.29.7(supports-color@10.2.2) + '@babel/core': 7.29.7 '@babel/helper-plugin-utils': 7.29.7 '@babel/plugin-transform-member-expression-literals@7.29.7(@babel/core@7.29.7)': dependencies: - '@babel/core': 7.29.7(supports-color@10.2.2) + '@babel/core': 7.29.7 '@babel/helper-plugin-utils': 7.29.7 '@babel/plugin-transform-modules-amd@7.29.7(@babel/core@7.29.7)': dependencies: - '@babel/core': 7.29.7(supports-color@10.2.2) + '@babel/core': 7.29.7 '@babel/helper-module-transforms': 7.29.7(@babel/core@7.29.7) '@babel/helper-plugin-utils': 7.29.7 transitivePeerDependencies: @@ -9597,7 +9597,7 @@ snapshots: '@babel/plugin-transform-modules-commonjs@7.29.7(@babel/core@7.29.7)': dependencies: - '@babel/core': 7.29.7(supports-color@10.2.2) + '@babel/core': 7.29.7 '@babel/helper-module-transforms': 7.29.7(@babel/core@7.29.7) '@babel/helper-plugin-utils': 7.29.7 transitivePeerDependencies: @@ -9605,7 +9605,7 @@ snapshots: '@babel/plugin-transform-modules-systemjs@7.29.7(@babel/core@7.29.7)': dependencies: - '@babel/core': 7.29.7(supports-color@10.2.2) + '@babel/core': 7.29.7 '@babel/helper-module-transforms': 7.29.7(@babel/core@7.29.7) '@babel/helper-plugin-utils': 7.29.7 '@babel/helper-validator-identifier': 7.29.7 @@ -9615,7 +9615,7 @@ snapshots: '@babel/plugin-transform-modules-umd@7.29.7(@babel/core@7.29.7)': dependencies: - '@babel/core': 7.29.7(supports-color@10.2.2) + '@babel/core': 7.29.7 '@babel/helper-module-transforms': 7.29.7(@babel/core@7.29.7) '@babel/helper-plugin-utils': 7.29.7 transitivePeerDependencies: @@ -9623,28 +9623,28 @@ snapshots: '@babel/plugin-transform-named-capturing-groups-regex@7.29.7(@babel/core@7.29.7)': dependencies: - '@babel/core': 7.29.7(supports-color@10.2.2) + '@babel/core': 7.29.7 '@babel/helper-create-regexp-features-plugin': 7.29.7(@babel/core@7.29.7) '@babel/helper-plugin-utils': 7.29.7 '@babel/plugin-transform-new-target@7.29.7(@babel/core@7.29.7)': dependencies: - '@babel/core': 7.29.7(supports-color@10.2.2) + '@babel/core': 7.29.7 '@babel/helper-plugin-utils': 7.29.7 '@babel/plugin-transform-nullish-coalescing-operator@7.29.7(@babel/core@7.29.7)': dependencies: - '@babel/core': 7.29.7(supports-color@10.2.2) + '@babel/core': 7.29.7 '@babel/helper-plugin-utils': 7.29.7 '@babel/plugin-transform-numeric-separator@7.29.7(@babel/core@7.29.7)': dependencies: - '@babel/core': 7.29.7(supports-color@10.2.2) + '@babel/core': 7.29.7 '@babel/helper-plugin-utils': 7.29.7 '@babel/plugin-transform-object-rest-spread@7.29.7(@babel/core@7.29.7)': dependencies: - '@babel/core': 7.29.7(supports-color@10.2.2) + '@babel/core': 7.29.7 '@babel/helper-compilation-targets': 7.29.7 '@babel/helper-plugin-utils': 7.29.7 '@babel/plugin-transform-destructuring': 7.29.7(@babel/core@7.29.7) @@ -9655,7 +9655,7 @@ snapshots: '@babel/plugin-transform-object-super@7.29.7(@babel/core@7.29.7)': dependencies: - '@babel/core': 7.29.7(supports-color@10.2.2) + '@babel/core': 7.29.7 '@babel/helper-plugin-utils': 7.29.7 '@babel/helper-replace-supers': 7.29.7(@babel/core@7.29.7) transitivePeerDependencies: @@ -9663,12 +9663,12 @@ snapshots: '@babel/plugin-transform-optional-catch-binding@7.29.7(@babel/core@7.29.7)': dependencies: - '@babel/core': 7.29.7(supports-color@10.2.2) + '@babel/core': 7.29.7 '@babel/helper-plugin-utils': 7.29.7 '@babel/plugin-transform-optional-chaining@7.29.7(@babel/core@7.29.7)': dependencies: - '@babel/core': 7.29.7(supports-color@10.2.2) + '@babel/core': 7.29.7 '@babel/helper-plugin-utils': 7.29.7 '@babel/helper-skip-transparent-expression-wrappers': 7.29.7 transitivePeerDependencies: @@ -9676,12 +9676,12 @@ snapshots: '@babel/plugin-transform-parameters@7.29.7(@babel/core@7.29.7)': dependencies: - '@babel/core': 7.29.7(supports-color@10.2.2) + '@babel/core': 7.29.7 '@babel/helper-plugin-utils': 7.29.7 '@babel/plugin-transform-private-methods@7.29.7(@babel/core@7.29.7)': dependencies: - '@babel/core': 7.29.7(supports-color@10.2.2) + '@babel/core': 7.29.7 '@babel/helper-create-class-features-plugin': 7.29.7(@babel/core@7.29.7) '@babel/helper-plugin-utils': 7.29.7 transitivePeerDependencies: @@ -9689,7 +9689,7 @@ snapshots: '@babel/plugin-transform-private-property-in-object@7.29.7(@babel/core@7.29.7)': dependencies: - '@babel/core': 7.29.7(supports-color@10.2.2) + '@babel/core': 7.29.7 '@babel/helper-annotate-as-pure': 7.29.7 '@babel/helper-create-class-features-plugin': 7.29.7(@babel/core@7.29.7) '@babel/helper-plugin-utils': 7.29.7 @@ -9698,31 +9698,31 @@ snapshots: '@babel/plugin-transform-property-literals@7.29.7(@babel/core@7.29.7)': dependencies: - '@babel/core': 7.29.7(supports-color@10.2.2) + '@babel/core': 7.29.7 '@babel/helper-plugin-utils': 7.29.7 '@babel/plugin-transform-regenerator@7.29.7(@babel/core@7.29.7)': dependencies: - '@babel/core': 7.29.7(supports-color@10.2.2) + '@babel/core': 7.29.7 '@babel/helper-plugin-utils': 7.29.7 '@babel/plugin-transform-regexp-modifiers@7.29.7(@babel/core@7.29.7)': dependencies: - '@babel/core': 7.29.7(supports-color@10.2.2) + '@babel/core': 7.29.7 '@babel/helper-create-regexp-features-plugin': 7.29.7(@babel/core@7.29.7) '@babel/helper-plugin-utils': 7.29.7 '@babel/plugin-transform-reserved-words@7.29.7(@babel/core@7.29.7)': dependencies: - '@babel/core': 7.29.7(supports-color@10.2.2) + '@babel/core': 7.29.7 '@babel/helper-plugin-utils': 7.29.7 - '@babel/plugin-transform-runtime@7.29.7(@babel/core@7.29.7)(supports-color@10.2.2)': + '@babel/plugin-transform-runtime@7.29.7(@babel/core@7.29.7)': dependencies: - '@babel/core': 7.29.7(supports-color@10.2.2) + '@babel/core': 7.29.7 '@babel/helper-module-imports': 7.29.7 '@babel/helper-plugin-utils': 7.29.7 - babel-plugin-polyfill-corejs2: 0.4.17(@babel/core@7.29.7)(supports-color@10.2.2) + babel-plugin-polyfill-corejs2: 0.4.17(@babel/core@7.29.7) babel-plugin-polyfill-corejs3: 0.13.0(@babel/core@7.29.7) babel-plugin-polyfill-regenerator: 0.6.8(@babel/core@7.29.7) semver: 6.3.1 @@ -9731,12 +9731,12 @@ snapshots: '@babel/plugin-transform-shorthand-properties@7.29.7(@babel/core@7.29.7)': dependencies: - '@babel/core': 7.29.7(supports-color@10.2.2) + '@babel/core': 7.29.7 '@babel/helper-plugin-utils': 7.29.7 '@babel/plugin-transform-spread@7.29.7(@babel/core@7.29.7)': dependencies: - '@babel/core': 7.29.7(supports-color@10.2.2) + '@babel/core': 7.29.7 '@babel/helper-plugin-utils': 7.29.7 '@babel/helper-skip-transparent-expression-wrappers': 7.29.7 transitivePeerDependencies: @@ -9744,46 +9744,46 @@ snapshots: '@babel/plugin-transform-sticky-regex@7.29.7(@babel/core@7.29.7)': dependencies: - '@babel/core': 7.29.7(supports-color@10.2.2) + '@babel/core': 7.29.7 '@babel/helper-plugin-utils': 7.29.7 '@babel/plugin-transform-template-literals@7.29.7(@babel/core@7.29.7)': dependencies: - '@babel/core': 7.29.7(supports-color@10.2.2) + '@babel/core': 7.29.7 '@babel/helper-plugin-utils': 7.29.7 '@babel/plugin-transform-typeof-symbol@7.29.7(@babel/core@7.29.7)': dependencies: - '@babel/core': 7.29.7(supports-color@10.2.2) + '@babel/core': 7.29.7 '@babel/helper-plugin-utils': 7.29.7 '@babel/plugin-transform-unicode-escapes@7.29.7(@babel/core@7.29.7)': dependencies: - '@babel/core': 7.29.7(supports-color@10.2.2) + '@babel/core': 7.29.7 '@babel/helper-plugin-utils': 7.29.7 '@babel/plugin-transform-unicode-property-regex@7.29.7(@babel/core@7.29.7)': dependencies: - '@babel/core': 7.29.7(supports-color@10.2.2) + '@babel/core': 7.29.7 '@babel/helper-create-regexp-features-plugin': 7.29.7(@babel/core@7.29.7) '@babel/helper-plugin-utils': 7.29.7 '@babel/plugin-transform-unicode-regex@7.29.7(@babel/core@7.29.7)': dependencies: - '@babel/core': 7.29.7(supports-color@10.2.2) + '@babel/core': 7.29.7 '@babel/helper-create-regexp-features-plugin': 7.29.7(@babel/core@7.29.7) '@babel/helper-plugin-utils': 7.29.7 '@babel/plugin-transform-unicode-sets-regex@7.29.7(@babel/core@7.29.7)': dependencies: - '@babel/core': 7.29.7(supports-color@10.2.2) + '@babel/core': 7.29.7 '@babel/helper-create-regexp-features-plugin': 7.29.7(@babel/core@7.29.7) '@babel/helper-plugin-utils': 7.29.7 '@babel/preset-env@7.29.7(@babel/core@7.29.7)': dependencies: '@babel/compat-data': 7.29.7 - '@babel/core': 7.29.7(supports-color@10.2.2) + '@babel/core': 7.29.7 '@babel/helper-compilation-targets': 7.29.7 '@babel/helper-plugin-utils': 7.29.7 '@babel/helper-validator-option': 7.29.7 @@ -9849,7 +9849,7 @@ snapshots: '@babel/plugin-transform-unicode-regex': 7.29.7(@babel/core@7.29.7) '@babel/plugin-transform-unicode-sets-regex': 7.29.7(@babel/core@7.29.7) '@babel/preset-modules': 0.1.6-no-external-plugins(@babel/core@7.29.7) - babel-plugin-polyfill-corejs2: 0.4.17(@babel/core@7.29.7)(supports-color@10.2.2) + babel-plugin-polyfill-corejs2: 0.4.17(@babel/core@7.29.7) babel-plugin-polyfill-corejs3: 0.14.2(@babel/core@7.29.7) babel-plugin-polyfill-regenerator: 0.6.8(@babel/core@7.29.7) core-js-compat: 3.49.0 @@ -9859,7 +9859,7 @@ snapshots: '@babel/preset-modules@0.1.6-no-external-plugins(@babel/core@7.29.7)': dependencies: - '@babel/core': 7.29.7(supports-color@10.2.2) + '@babel/core': 7.29.7 '@babel/helper-plugin-utils': 7.29.7 '@babel/types': 7.29.7 esutils: 2.0.3 @@ -10238,7 +10238,7 @@ snapshots: dependencies: '@types/json-schema': 7.0.15 - '@eslint/eslintrc@3.3.5(supports-color@10.2.2)': + '@eslint/eslintrc@3.3.5': dependencies: ajv: 6.15.0 debug: 4.4.3(supports-color@10.2.2) @@ -11038,8 +11038,8 @@ snapshots: cross-spawn: 7.0.6 eventsource: 3.0.7 eventsource-parser: 3.1.0 - express: 5.2.1(supports-color@10.2.2) - express-rate-limit: 8.5.2(express@5.2.1(supports-color@10.2.2)) + express: 5.2.1 + express-rate-limit: 8.5.2(express@5.2.1) hono: 4.12.23 jose: 6.2.3 json-schema-typed: 8.0.2 @@ -12294,7 +12294,7 @@ snapshots: '@typescript-eslint/types': 8.61.0 eslint-visitor-keys: 5.0.1 - '@verdaccio/auth@8.0.2(supports-color@10.2.2)': + '@verdaccio/auth@8.0.2': dependencies: '@verdaccio/config': 8.1.1 '@verdaccio/core': 8.1.1 @@ -12328,7 +12328,7 @@ snapshots: dependencies: lockfile: 1.0.4 - '@verdaccio/hooks@8.0.2(supports-color@10.2.2)': + '@verdaccio/hooks@8.0.2': dependencies: '@verdaccio/core': 8.1.1 '@verdaccio/logger': 8.0.2 @@ -12346,7 +12346,7 @@ snapshots: transitivePeerDependencies: - supports-color - '@verdaccio/local-storage-legacy@11.3.3(supports-color@10.2.2)': + '@verdaccio/local-storage-legacy@11.3.3': dependencies: '@verdaccio/core': 8.1.1 '@verdaccio/file-locking': 13.0.1 @@ -12385,11 +12385,11 @@ snapshots: transitivePeerDependencies: - supports-color - '@verdaccio/middleware@8.0.2(supports-color@10.2.2)': + '@verdaccio/middleware@8.0.2': dependencies: '@verdaccio/config': 8.1.1 '@verdaccio/core': 8.1.1 - '@verdaccio/url': 13.0.2(supports-color@10.2.2) + '@verdaccio/url': 13.0.2 debug: 4.4.3(supports-color@10.2.2) express: 4.22.1 express-rate-limit: 5.5.1 @@ -12398,7 +12398,7 @@ snapshots: transitivePeerDependencies: - supports-color - '@verdaccio/package-filter@13.0.2(supports-color@10.2.2)': + '@verdaccio/package-filter@13.0.2': dependencies: '@verdaccio/core': 8.1.1 debug: 4.4.3(supports-color@10.2.2) @@ -12406,7 +12406,7 @@ snapshots: transitivePeerDependencies: - supports-color - '@verdaccio/search-indexer@8.0.2(supports-color@10.2.2)': + '@verdaccio/search-indexer@8.0.2': dependencies: debug: 4.4.3(supports-color@10.2.2) fuse.js: 7.3.0 @@ -12424,10 +12424,10 @@ snapshots: '@verdaccio/streams@10.2.5': {} - '@verdaccio/tarball@13.0.2(supports-color@10.2.2)': + '@verdaccio/tarball@13.0.2': dependencies: '@verdaccio/core': 8.1.1 - '@verdaccio/url': 13.0.2(supports-color@10.2.2) + '@verdaccio/url': 13.0.2 debug: 4.4.3(supports-color@10.2.2) gunzip-maybe: 1.4.2 tar-stream: 3.1.7 @@ -12436,13 +12436,13 @@ snapshots: - react-native-b4a - supports-color - '@verdaccio/ui-theme@9.0.0-next-9.14(supports-color@10.2.2)': + '@verdaccio/ui-theme@9.0.0-next-9.14': dependencies: debug: 4.4.3(supports-color@10.2.2) transitivePeerDependencies: - supports-color - '@verdaccio/url@13.0.2(supports-color@10.2.2)': + '@verdaccio/url@13.0.2': dependencies: '@verdaccio/core': 8.1.1 debug: 4.4.3(supports-color@10.2.2) @@ -12635,7 +12635,7 @@ snapshots: loader-utils: 2.0.4 regex-parser: 2.3.1 - agent-base@6.0.2(supports-color@10.2.2): + agent-base@6.0.2: dependencies: debug: 4.4.3(supports-color@10.2.2) transitivePeerDependencies: @@ -12838,40 +12838,40 @@ snapshots: babel-loader@10.1.1(@babel/core@7.29.7)(webpack@5.107.2(esbuild@0.28.1)(postcss@8.5.15)): dependencies: - '@babel/core': 7.29.7(supports-color@10.2.2) + '@babel/core': 7.29.7 find-up: 5.0.0 optionalDependencies: webpack: 5.107.2(esbuild@0.28.1)(postcss@8.5.15) - babel-plugin-polyfill-corejs2@0.4.17(@babel/core@7.29.7)(supports-color@10.2.2): + babel-plugin-polyfill-corejs2@0.4.17(@babel/core@7.29.7): dependencies: '@babel/compat-data': 7.29.7 - '@babel/core': 7.29.7(supports-color@10.2.2) - '@babel/helper-define-polyfill-provider': 0.6.8(@babel/core@7.29.7)(supports-color@10.2.2) + '@babel/core': 7.29.7 + '@babel/helper-define-polyfill-provider': 0.6.8(@babel/core@7.29.7) semver: 6.3.1 transitivePeerDependencies: - supports-color babel-plugin-polyfill-corejs3@0.13.0(@babel/core@7.29.7): dependencies: - '@babel/core': 7.29.7(supports-color@10.2.2) - '@babel/helper-define-polyfill-provider': 0.6.8(@babel/core@7.29.7)(supports-color@10.2.2) + '@babel/core': 7.29.7 + '@babel/helper-define-polyfill-provider': 0.6.8(@babel/core@7.29.7) core-js-compat: 3.49.0 transitivePeerDependencies: - supports-color babel-plugin-polyfill-corejs3@0.14.2(@babel/core@7.29.7): dependencies: - '@babel/core': 7.29.7(supports-color@10.2.2) - '@babel/helper-define-polyfill-provider': 0.6.8(@babel/core@7.29.7)(supports-color@10.2.2) + '@babel/core': 7.29.7 + '@babel/helper-define-polyfill-provider': 0.6.8(@babel/core@7.29.7) core-js-compat: 3.49.0 transitivePeerDependencies: - supports-color babel-plugin-polyfill-regenerator@0.6.8(@babel/core@7.29.7): dependencies: - '@babel/core': 7.29.7(supports-color@10.2.2) - '@babel/helper-define-polyfill-provider': 0.6.8(@babel/core@7.29.7)(supports-color@10.2.2) + '@babel/core': 7.29.7 + '@babel/helper-define-polyfill-provider': 0.6.8(@babel/core@7.29.7) transitivePeerDependencies: - supports-color @@ -12968,7 +12968,7 @@ snapshots: transitivePeerDependencies: - supports-color - body-parser@2.2.2(supports-color@10.2.2): + body-parser@2.2.2: dependencies: bytes: 3.1.2 content-type: 1.0.5 @@ -13014,24 +13014,24 @@ snapshots: fresh: 0.5.2 mitt: 1.2.0 - browser-sync-ui@3.0.4(bufferutil@4.1.0)(supports-color@10.2.2)(utf-8-validate@6.0.6): + browser-sync-ui@3.0.4(bufferutil@4.1.0)(utf-8-validate@6.0.6): dependencies: async-each-series: 0.1.1 chalk: 4.1.2 connect-history-api-fallback: 1.6.0 immutable: 3.8.3 server-destroy: 1.0.1 - socket.io-client: 4.8.3(bufferutil@4.1.0)(supports-color@10.2.2)(utf-8-validate@6.0.6) + socket.io-client: 4.8.3(bufferutil@4.1.0)(utf-8-validate@6.0.6) stream-throttle: 0.1.3 transitivePeerDependencies: - bufferutil - supports-color - utf-8-validate - browser-sync@3.0.4(bufferutil@4.1.0)(supports-color@10.2.2)(utf-8-validate@6.0.6): + browser-sync@3.0.4(bufferutil@4.1.0)(utf-8-validate@6.0.6): dependencies: browser-sync-client: 3.0.4 - browser-sync-ui: 3.0.4(bufferutil@4.1.0)(supports-color@10.2.2)(utf-8-validate@6.0.6) + browser-sync-ui: 3.0.4(bufferutil@4.1.0)(utf-8-validate@6.0.6) bs-recipes: 1.3.4 chalk: 4.1.2 chokidar: 3.6.0 @@ -13055,7 +13055,7 @@ snapshots: serve-index: 1.9.2 serve-static: 1.16.3 server-destroy: 1.0.1 - socket.io: 4.8.3(bufferutil@4.1.0)(supports-color@10.2.2)(utf-8-validate@6.0.6) + socket.io: 4.8.3(bufferutil@4.1.0)(utf-8-validate@6.0.6) ua-parser-js: 1.0.41 yargs: 17.7.2 transitivePeerDependencies: @@ -13626,7 +13626,7 @@ snapshots: dependencies: once: 1.4.0 - engine.io-client@6.6.5(bufferutil@4.1.0)(supports-color@10.2.2)(utf-8-validate@6.0.6): + engine.io-client@6.6.5(bufferutil@4.1.0)(utf-8-validate@6.0.6): dependencies: '@socket.io/component-emitter': 3.1.2 debug: 4.4.3(supports-color@10.2.2) @@ -13640,7 +13640,7 @@ snapshots: engine.io-parser@5.2.3: {} - engine.io@6.6.8(bufferutil@4.1.0)(supports-color@10.2.2)(utf-8-validate@6.0.6): + engine.io@6.6.8(bufferutil@4.1.0)(utf-8-validate@6.0.6): dependencies: '@types/cors': 2.8.19 '@types/node': 22.19.20 @@ -14037,9 +14037,9 @@ snapshots: express-rate-limit@5.5.1: {} - express-rate-limit@8.5.2(express@5.2.1(supports-color@10.2.2)): + express-rate-limit@8.5.2(express@5.2.1): dependencies: - express: 5.2.1(supports-color@10.2.2) + express: 5.2.1 ip-address: 10.2.0 express@4.22.1: @@ -14114,10 +14114,10 @@ snapshots: transitivePeerDependencies: - supports-color - express@5.2.1(supports-color@10.2.2): + express@5.2.1: dependencies: accepts: 2.0.0 - body-parser: 2.2.2(supports-color@10.2.2) + body-parser: 2.2.2 content-disposition: 1.1.0 content-type: 1.0.5 cookie: 0.7.2 @@ -14127,7 +14127,7 @@ snapshots: encodeurl: 2.0.0 escape-html: 1.0.3 etag: 1.8.1 - finalhandler: 2.1.1(supports-color@10.2.2) + finalhandler: 2.1.1 fresh: 2.0.0 http-errors: 2.0.1 merge-descriptors: 2.0.0 @@ -14138,8 +14138,8 @@ snapshots: proxy-addr: 2.0.7 qs: 6.15.2 range-parser: 1.2.1 - router: 2.2.0(supports-color@10.2.2) - send: 1.2.1(supports-color@10.2.2) + router: 2.2.0 + send: 1.2.1 serve-static: 2.2.1 statuses: 2.0.2 type-is: 2.1.0 @@ -14240,7 +14240,7 @@ snapshots: transitivePeerDependencies: - supports-color - finalhandler@2.1.1(supports-color@10.2.2): + finalhandler@2.1.1: dependencies: debug: 4.4.3(supports-color@10.2.2) encodeurl: 2.0.0 @@ -14743,9 +14743,9 @@ snapshots: quick-lru: 5.1.1 resolve-alpn: 1.2.1 - https-proxy-agent@5.0.1(supports-color@10.2.2): + https-proxy-agent@5.0.1: dependencies: - agent-base: 6.0.2(supports-color@10.2.2) + agent-base: 6.0.2 debug: 4.4.3(supports-color@10.2.2) transitivePeerDependencies: - supports-color @@ -15039,7 +15039,7 @@ snapshots: istanbul-lib-instrument@5.2.1: dependencies: - '@babel/core': 7.29.7(supports-color@10.2.2) + '@babel/core': 7.29.7 '@babel/parser': 7.29.7 '@istanbuljs/schema': 0.1.6 istanbul-lib-coverage: 3.2.2 @@ -15049,7 +15049,7 @@ snapshots: istanbul-lib-instrument@6.0.3: dependencies: - '@babel/core': 7.29.7(supports-color@10.2.2) + '@babel/core': 7.29.7 '@babel/parser': 7.29.7 '@istanbuljs/schema': 0.1.6 istanbul-lib-coverage: 3.2.2 @@ -15063,7 +15063,7 @@ snapshots: make-dir: 4.0.0 supports-color: 7.2.0 - istanbul-lib-source-maps@4.0.1(supports-color@10.2.2): + istanbul-lib-source-maps@4.0.1: dependencies: debug: 4.4.3(supports-color@10.2.2) istanbul-lib-coverage: 3.2.2 @@ -15232,33 +15232,33 @@ snapshots: dependencies: which: 1.3.1 - karma-coverage@2.2.1(supports-color@10.2.2): + karma-coverage@2.2.1: dependencies: istanbul-lib-coverage: 3.2.2 istanbul-lib-instrument: 5.2.1 istanbul-lib-report: 3.0.1 - istanbul-lib-source-maps: 4.0.1(supports-color@10.2.2) + istanbul-lib-source-maps: 4.0.1 istanbul-reports: 3.2.0 minimatch: 3.1.5 transitivePeerDependencies: - supports-color - karma-jasmine-html-reporter@2.2.0(jasmine-core@6.3.0)(karma-jasmine@5.1.0(karma@6.4.4(bufferutil@4.1.0)(supports-color@10.2.2)(utf-8-validate@6.0.6)))(karma@6.4.4(bufferutil@4.1.0)(supports-color@10.2.2)(utf-8-validate@6.0.6)): + karma-jasmine-html-reporter@2.2.0(jasmine-core@6.3.0)(karma-jasmine@5.1.0(karma@6.4.4(bufferutil@4.1.0)(utf-8-validate@6.0.6)))(karma@6.4.4(bufferutil@4.1.0)(utf-8-validate@6.0.6)): dependencies: jasmine-core: 6.3.0 - karma: 6.4.4(bufferutil@4.1.0)(supports-color@10.2.2)(utf-8-validate@6.0.6) - karma-jasmine: 5.1.0(karma@6.4.4(bufferutil@4.1.0)(supports-color@10.2.2)(utf-8-validate@6.0.6)) + karma: 6.4.4(bufferutil@4.1.0)(utf-8-validate@6.0.6) + karma-jasmine: 5.1.0(karma@6.4.4(bufferutil@4.1.0)(utf-8-validate@6.0.6)) - karma-jasmine@5.1.0(karma@6.4.4(bufferutil@4.1.0)(supports-color@10.2.2)(utf-8-validate@6.0.6)): + karma-jasmine@5.1.0(karma@6.4.4(bufferutil@4.1.0)(utf-8-validate@6.0.6)): dependencies: jasmine-core: 4.6.1 - karma: 6.4.4(bufferutil@4.1.0)(supports-color@10.2.2)(utf-8-validate@6.0.6) + karma: 6.4.4(bufferutil@4.1.0)(utf-8-validate@6.0.6) karma-source-map-support@1.4.0: dependencies: source-map-support: 0.5.21 - karma@6.4.4(bufferutil@4.1.0)(supports-color@10.2.2)(utf-8-validate@6.0.6): + karma@6.4.4(bufferutil@4.1.0)(utf-8-validate@6.0.6): dependencies: '@colors/colors': 1.5.0 body-parser: 1.20.5 @@ -15279,7 +15279,7 @@ snapshots: qjobs: 1.2.0 range-parser: 1.2.1 rimraf: 3.0.2 - socket.io: 4.8.3(bufferutil@4.1.0)(supports-color@10.2.2)(utf-8-validate@6.0.6) + socket.io: 4.8.3(bufferutil@4.1.0)(utf-8-validate@6.0.6) source-map: 0.6.1 tmp: 0.2.7 ua-parser-js: 0.7.41 @@ -16640,7 +16640,7 @@ snapshots: '@rollup/rollup-win32-x64-msvc': 4.62.0 fsevents: 2.3.3 - router@2.2.0(supports-color@10.2.2): + router@2.2.0: dependencies: debug: 4.4.3(supports-color@10.2.2) depd: 2.0.0 @@ -16764,7 +16764,7 @@ snapshots: transitivePeerDependencies: - supports-color - send@1.2.1(supports-color@10.2.2): + send@1.2.1: dependencies: debug: 4.4.3(supports-color@10.2.2) encodeurl: 2.0.0 @@ -16808,7 +16808,7 @@ snapshots: encodeurl: 2.0.0 escape-html: 1.0.3 parseurl: 1.3.3 - send: 1.2.1(supports-color@10.2.2) + send: 1.2.1 transitivePeerDependencies: - supports-color @@ -16909,7 +16909,7 @@ snapshots: smart-buffer@4.2.0: {} - socket.io-adapter@2.5.7(bufferutil@4.1.0)(supports-color@10.2.2)(utf-8-validate@6.0.6): + socket.io-adapter@2.5.7(bufferutil@4.1.0)(utf-8-validate@6.0.6): dependencies: debug: 4.4.3(supports-color@10.2.2) ws: 8.20.1(bufferutil@4.1.0)(utf-8-validate@6.0.6) @@ -16918,33 +16918,33 @@ snapshots: - supports-color - utf-8-validate - socket.io-client@4.8.3(bufferutil@4.1.0)(supports-color@10.2.2)(utf-8-validate@6.0.6): + socket.io-client@4.8.3(bufferutil@4.1.0)(utf-8-validate@6.0.6): dependencies: '@socket.io/component-emitter': 3.1.2 debug: 4.4.3(supports-color@10.2.2) - engine.io-client: 6.6.5(bufferutil@4.1.0)(supports-color@10.2.2)(utf-8-validate@6.0.6) - socket.io-parser: 4.2.6(supports-color@10.2.2) + engine.io-client: 6.6.5(bufferutil@4.1.0)(utf-8-validate@6.0.6) + socket.io-parser: 4.2.6 transitivePeerDependencies: - bufferutil - supports-color - utf-8-validate - socket.io-parser@4.2.6(supports-color@10.2.2): + socket.io-parser@4.2.6: dependencies: '@socket.io/component-emitter': 3.1.2 debug: 4.4.3(supports-color@10.2.2) transitivePeerDependencies: - supports-color - socket.io@4.8.3(bufferutil@4.1.0)(supports-color@10.2.2)(utf-8-validate@6.0.6): + socket.io@4.8.3(bufferutil@4.1.0)(utf-8-validate@6.0.6): dependencies: accepts: 1.3.8 base64id: 2.0.0 cors: 2.8.6 debug: 4.4.3(supports-color@10.2.2) - engine.io: 6.6.8(bufferutil@4.1.0)(supports-color@10.2.2)(utf-8-validate@6.0.6) - socket.io-adapter: 2.5.7(bufferutil@4.1.0)(supports-color@10.2.2)(utf-8-validate@6.0.6) - socket.io-parser: 4.2.6(supports-color@10.2.2) + engine.io: 6.6.8(bufferutil@4.1.0)(utf-8-validate@6.0.6) + socket.io-adapter: 2.5.7(bufferutil@4.1.0)(utf-8-validate@6.0.6) + socket.io-parser: 4.2.6 transitivePeerDependencies: - bufferutil - supports-color @@ -17375,7 +17375,7 @@ snapshots: tsx@4.22.4: dependencies: - esbuild: 0.28.0 + esbuild: 0.28.1 optionalDependencies: fsevents: 2.3.3 @@ -17552,18 +17552,18 @@ snapshots: vary@1.1.2: {} - verdaccio-audit@13.0.2(encoding@0.1.13)(supports-color@10.2.2): + verdaccio-audit@13.0.2(encoding@0.1.13): dependencies: '@verdaccio/config': 8.1.1 '@verdaccio/core': 8.1.1 express: 4.22.1 - https-proxy-agent: 5.0.1(supports-color@10.2.2) + https-proxy-agent: 5.0.1 node-fetch: 2.6.7(encoding@0.1.13) transitivePeerDependencies: - encoding - supports-color - verdaccio-auth-memory@13.0.2(supports-color@10.2.2): + verdaccio-auth-memory@13.0.2: dependencies: '@verdaccio/core': 8.1.1 debug: 4.4.3(supports-color@10.2.2) @@ -17582,24 +17582,24 @@ snapshots: transitivePeerDependencies: - supports-color - verdaccio@6.7.2(encoding@0.1.13)(supports-color@10.2.2): + verdaccio@6.7.2(encoding@0.1.13): dependencies: '@cypress/request': 3.0.10 - '@verdaccio/auth': 8.0.2(supports-color@10.2.2) + '@verdaccio/auth': 8.0.2 '@verdaccio/config': 8.1.1 '@verdaccio/core': 8.1.1 - '@verdaccio/hooks': 8.0.2(supports-color@10.2.2) + '@verdaccio/hooks': 8.0.2 '@verdaccio/loaders': 8.0.2 - '@verdaccio/local-storage-legacy': 11.3.3(supports-color@10.2.2) + '@verdaccio/local-storage-legacy': 11.3.3 '@verdaccio/logger': 8.0.2 - '@verdaccio/middleware': 8.0.2(supports-color@10.2.2) - '@verdaccio/package-filter': 13.0.2(supports-color@10.2.2) - '@verdaccio/search-indexer': 8.0.2(supports-color@10.2.2) + '@verdaccio/middleware': 8.0.2 + '@verdaccio/package-filter': 13.0.2 + '@verdaccio/search-indexer': 8.0.2 '@verdaccio/signature': 8.0.2 '@verdaccio/streams': 10.2.5 - '@verdaccio/tarball': 13.0.2(supports-color@10.2.2) - '@verdaccio/ui-theme': 9.0.0-next-9.14(supports-color@10.2.2) - '@verdaccio/url': 13.0.2(supports-color@10.2.2) + '@verdaccio/tarball': 13.0.2 + '@verdaccio/ui-theme': 9.0.0-next-9.14 + '@verdaccio/url': 13.0.2 '@verdaccio/utils': 8.1.2 JSONStream: 1.3.5 async: 3.2.6 @@ -17613,7 +17613,7 @@ snapshots: lru-cache: 7.18.3 mime: 3.0.0 semver: 7.8.0 - verdaccio-audit: 13.0.2(encoding@0.1.13)(supports-color@10.2.2) + verdaccio-audit: 13.0.2(encoding@0.1.13) verdaccio-htpasswd: 13.0.2 transitivePeerDependencies: - bare-abort-controller @@ -17633,7 +17633,7 @@ snapshots: fdir: 6.5.0(picomatch@4.0.4) picomatch: 4.0.4 postcss: 8.5.15 - rollup: 4.61.0 + rollup: 4.62.0 tinyglobby: 0.2.17 optionalDependencies: '@types/node': 24.13.2 diff --git a/tests/e2e/ng-snapshot/package.json b/tests/e2e/ng-snapshot/package.json index ce9bad7829f6..317c5d63613a 100644 --- a/tests/e2e/ng-snapshot/package.json +++ b/tests/e2e/ng-snapshot/package.json @@ -2,21 +2,21 @@ "description": "snapshot versions of Angular for e2e testing", "private": true, "dependencies": { - "@angular/animations": "github:angular/animations-builds#f1a1ee8c782b879df1f346daf0c1c489dc6754c7", - "@angular/cdk": "github:angular/cdk-builds#0d5389dc4437bc9d9e5ceffa3be6610454f8f46b", - "@angular/common": "github:angular/common-builds#ead9c0df2d447397c75cff61ebee8ac46118fe04", - "@angular/compiler": "github:angular/compiler-builds#e0d7a09079b23ef2d3e15fe1e4f235fec12ecb3a", - "@angular/compiler-cli": "github:angular/compiler-cli-builds#199e266910ed6d3f1eb6da50bb46be836afb277f", - "@angular/core": "github:angular/core-builds#0e95bdf40db38f3389763a2d7578cd1ba139204c", - "@angular/forms": "github:angular/forms-builds#7c9da8a94ea07d58f6ab737b578e8c3287b1a77b", - "@angular/language-service": "github:angular/language-service-builds#5134fc1cde9fcb7243557b4d10f19c3bdfdc39d4", - "@angular/localize": "github:angular/localize-builds#ce5f3157dbf7559e60670bcb16e4ad5833df27cd", - "@angular/material": "github:angular/material-builds#d0d36e575c65f01b5860c75de27c786b1fa24345", - "@angular/material-moment-adapter": "github:angular/material-moment-adapter-builds#e556974205a895e999f27bc59481156d9c84417c", - "@angular/platform-browser": "github:angular/platform-browser-builds#1a15323bce1b483d6a85d740bbdd030d5d93246c", - "@angular/platform-browser-dynamic": "github:angular/platform-browser-dynamic-builds#a5fb144747c92312d2de659c7c385eec78953a84", - "@angular/platform-server": "github:angular/platform-server-builds#1383fcf921b2eb6f3687e7f2f8371bc193daaa55", - "@angular/router": "github:angular/router-builds#386b0b500207c76c8bd09a265f723ff0bb327845", - "@angular/service-worker": "github:angular/service-worker-builds#38a3ac76fb6cf87f7fdf1c15ecce8353b5e9811e" + "@angular/animations": "github:angular/animations-builds#78ea4153f81c8d3c98d29483193ef4226a3759dc", + "@angular/cdk": "github:angular/cdk-builds#9ebe86f6c45152f82b1a3b84cdcf8e54c0ff3462", + "@angular/common": "github:angular/common-builds#a3742c9b52392f480abf8db1b7af6700113a67e9", + "@angular/compiler": "github:angular/compiler-builds#16588f9fa5ece3248f1071daeaec5b4b60392ab2", + "@angular/compiler-cli": "github:angular/compiler-cli-builds#373c64af0eda1c5e852dbdc74c32bda1391d9f95", + "@angular/core": "github:angular/core-builds#b3743e6743000ec172b10799eb1cf016ef817233", + "@angular/forms": "github:angular/forms-builds#dc9cfca54f8c228f86b7a72cc562780c85993820", + "@angular/language-service": "github:angular/language-service-builds#a61378e20c4cc5d4eb2a60f15d3248a7d7e495a6", + "@angular/localize": "github:angular/localize-builds#3dce4bf75882e28b8214b74a61fa3bdd818ffbd0", + "@angular/material": "github:angular/material-builds#3a8e1fc8c1c4314930eb6304c45e32807892529c", + "@angular/material-moment-adapter": "github:angular/material-moment-adapter-builds#97ae9e6b28c3f7b7463c414c0531cab520353e92", + "@angular/platform-browser": "github:angular/platform-browser-builds#632300465d06b799cef930c55c93941e3a599083", + "@angular/platform-browser-dynamic": "github:angular/platform-browser-dynamic-builds#db266eb6e668a91382fe07f82fb9f20f263e45ce", + "@angular/platform-server": "github:angular/platform-server-builds#5f06cc18b9a45005ff9ff52393b69452dd73b1e2", + "@angular/router": "github:angular/router-builds#6c1acc31c42e58e95617a559bb4982446a04ec2c", + "@angular/service-worker": "github:angular/service-worker-builds#d1c5739f3b8b3d72486b8b07ed15e3964e8cd251" } } From bf73d2d2833af9fc30de4beaff99fef347193197 Mon Sep 17 00:00:00 2001 From: Charles Lyding <19598772+clydin@users.noreply.github.com> Date: Tue, 9 Jun 2026 21:17:59 -0400 Subject: [PATCH 051/787] refactor(@angular/cli): transition update command to use PackageManager abstraction Transition the update command's version resolver to utilize the registry methods from the PackageManager abstraction instead of directly querying the registry via pacote. This introduces a cached RegistryClient wrapper that retrieves package metadata and manifests on-demand. Update resolution helper functions are updated to be asynchronous to support the lazy-loading of registry documents. --- package.json | 3 - packages/angular/cli/BUILD.bazel | 6 - packages/angular/cli/package.json | 3 - .../angular/cli/src/commands/update/cli.ts | 9 +- .../src/commands/update/update-resolver.ts | 335 ++--- .../commands/update/update-resolver_spec.ts | 280 ++++- .../src/package-managers/package-metadata.ts | 2 +- .../cli/src/utilities/package-metadata.ts | 247 ---- pnpm-lock.yaml | 1117 ++++------------- 9 files changed, 670 insertions(+), 1332 deletions(-) delete mode 100644 packages/angular/cli/src/utilities/package-metadata.ts diff --git a/package.json b/package.json index f1f5ced9ff5b..36b31bc575d8 100644 --- a/package.json +++ b/package.json @@ -78,7 +78,6 @@ "@types/browser-sync": "^2.27.0", "@types/express": "~5.0.1", "@types/http-proxy": "^1.17.4", - "@types/ini": "^4.0.0", "@types/jasmine": "~6.0.0", "@types/jasmine-reporters": "^2", "@types/karma": "^6.3.0", @@ -87,14 +86,12 @@ "@types/lodash": "^4.17.0", "@types/node": "^22.12.0", "@types/npm-package-arg": "^6.1.0", - "@types/pacote": "^11.1.3", "@types/picomatch": "^4.0.0", "@types/progress": "^2.0.3", "@types/semver": "^7.3.12", "@types/watchpack": "^2.4.4", "@types/yargs": "^17.0.20", "@types/yargs-parser": "^21.0.0", - "@types/yarnpkg__lockfile": "^1.1.5", "@typescript-eslint/eslint-plugin": "8.61.0", "@typescript-eslint/parser": "8.61.0", "ajv": "8.20.0", diff --git a/packages/angular/cli/BUILD.bazel b/packages/angular/cli/BUILD.bazel index b73ed5fba5fe..613785018402 100644 --- a/packages/angular/cli/BUILD.bazel +++ b/packages/angular/cli/BUILD.bazel @@ -61,24 +61,18 @@ ts_project( ":node_modules/@inquirer/prompts", ":node_modules/@listr2/prompt-adapter-inquirer", ":node_modules/@modelcontextprotocol/sdk", - ":node_modules/@yarnpkg/lockfile", ":node_modules/algoliasearch", - ":node_modules/ini", ":node_modules/jsonc-parser", ":node_modules/listr2", ":node_modules/npm-package-arg", - ":node_modules/pacote", ":node_modules/parse5-html-rewriting-stream", ":node_modules/yargs", ":node_modules/zod", "//:node_modules/@angular/core", - "//:node_modules/@types/ini", "//:node_modules/@types/node", "//:node_modules/@types/npm-package-arg", - "//:node_modules/@types/pacote", "//:node_modules/@types/semver", "//:node_modules/@types/yargs", - "//:node_modules/@types/yarnpkg__lockfile", "//:node_modules/semver", "//:node_modules/typescript", ], diff --git a/packages/angular/cli/package.json b/packages/angular/cli/package.json index 9a22e424e4b5..680fc2a730c5 100644 --- a/packages/angular/cli/package.json +++ b/packages/angular/cli/package.json @@ -19,13 +19,10 @@ "@listr2/prompt-adapter-inquirer": "4.2.4", "@modelcontextprotocol/sdk": "1.29.0", "@schematics/angular": "workspace:0.0.0-PLACEHOLDER", - "@yarnpkg/lockfile": "1.1.0", "algoliasearch": "5.54.0", - "ini": "7.0.0", "jsonc-parser": "3.3.1", "listr2": "10.2.1", "npm-package-arg": "14.0.0", - "pacote": "21.5.1", "parse5-html-rewriting-stream": "8.0.1", "semver": "7.8.4", "yargs": "18.0.0", diff --git a/packages/angular/cli/src/commands/update/cli.ts b/packages/angular/cli/src/commands/update/cli.ts index 447782da0616..e10ff4b940b8 100644 --- a/packages/angular/cli/src/commands/update/cli.ts +++ b/packages/angular/cli/src/commands/update/cli.ts @@ -254,10 +254,16 @@ export default class UpdateCommandModule extends CommandModule string); +export class RegistryClient { + private metadataCache = new Map>(); + private manifestCache = new Map>(); + + constructor( + private packageManager: PackageManager, + private logger: logging.LoggerApi, + ) {} + + async getMetadata(packageName: string): Promise { + let promise = this.metadataCache.get(packageName); + if (!promise) { + promise = this.packageManager.getRegistryMetadata(packageName).catch((e) => { + this.metadataCache.delete(packageName); + throw e; + }); + this.metadataCache.set(packageName, promise); + } + + return promise; + } + + async getManifest(packageName: string, version: string): Promise { + const key = `${packageName}@${version}`; + let promise = this.manifestCache.get(key); + if (!promise) { + promise = this.packageManager.getRegistryManifest(packageName, version).catch((e) => { + this.manifestCache.delete(key); + throw e; + }); + this.manifestCache.set(key, promise); + } + + return promise; + } +} + +export async function getSatisfyingVersion( + registryClient: RegistryClient, + packageName: string, + versions: string[], + range: string, + next?: boolean, +): Promise { + const options = { includePrerelease: next || undefined }; + const candidates = versions.filter((v) => semver.satisfies(v, range, options)); + const sorted = semver.rsort(candidates); + + for (const version of sorted) { + const manifest = await registryClient.getManifest(packageName, version); + if (manifest && !manifest.deprecated) { + return version; + } + } + + // Fallback to deprecated versions if no non-deprecated version satisfies + for (const version of sorted) { + const manifest = await registryClient.getManifest(packageName, version); + if (manifest) { + return version; + } + } + + return null; +} + export function angularMajorCompatGuarantee(range: string) { let newRange = semver.validRange(range); if (!newRange) { @@ -54,7 +116,7 @@ export interface PackageVersionInfo { export interface PackageInfo { name: string; - npmPackageJson: NpmRepositoryPackageJson; + npmPackageJson: PackageMetadata; installed: PackageVersionInfo; target?: PackageVersionInfo; packageJsonRange: string; @@ -84,6 +146,7 @@ export interface UpdatePlan { packagesToUpdate: Map; // name -> target version range migrationsToRun: { package: string; collection: string; from: string; to: string }[]; packageInfoMap: Map; + registryClient: RegistryClient; } function _updatePeerVersion(infoMap: Map, name: string, range: string) { @@ -215,7 +278,7 @@ function _getUpdateMetadata( packageJson: PackageManifest, logger: logging.LoggerApi, ): UpdateMetadata { - const metadata = packageJson['ng-update']; + const metadata = packageJson['ng-update'] as Record | undefined; const result: UpdateMetadata = { packageGroup: {}, @@ -337,13 +400,11 @@ function _buildLocalPackageInfo( } const installedVersion = localPkgJson.version; - const npmPackageJson: NpmRepositoryPackageJson = { + const npmPackageJson: PackageMetadata = { name, - versions: { - [installedVersion]: localPkgJson, - }, + versions: [installedVersion], 'dist-tags': {}, - } as unknown as NpmRepositoryPackageJson; + }; const logger = new logging.NullLogger(); @@ -359,13 +420,14 @@ function _buildLocalPackageInfo( }; } -function _buildPackageInfo( +async function _buildPackageInfo( packages: Map, allDependencies: ReadonlyMap, - npmPackageJson: NpmRepositoryPackageJson, + npmPackageJson: PackageMetadata, workspaceRoot: string, + registryClient: RegistryClient, logger: logging.LoggerApi, -): PackageInfo { +): Promise { const name = npmPackageJson.name; const packageJsonRange = allDependencies.get(name); if (!packageJsonRange) { @@ -375,24 +437,13 @@ function _buildPackageInfo( const localPkgJson = getInstalledPackageJson(name, workspaceRoot); let installedVersion = localPkgJson?.version; - const packageVersionsNonDeprecated: string[] = []; - const packageVersionsDeprecated: string[] = []; - - for (const [version, { deprecated }] of Object.entries(npmPackageJson.versions ?? {})) { - if (deprecated) { - packageVersionsDeprecated.push(version); - } else { - packageVersionsNonDeprecated.push(version); - } - } - - const findSatisfyingVersion = (targetVersion: VersionRange): VersionRange | undefined => - ((semver.maxSatisfying(packageVersionsNonDeprecated, targetVersion) ?? - semver.maxSatisfying(packageVersionsDeprecated, targetVersion)) as VersionRange | null) ?? - undefined; - if (!installedVersion) { - installedVersion = findSatisfyingVersion(packageJsonRange); + installedVersion = (await getSatisfyingVersion( + registryClient, + name, + npmPackageJson.versions, + packageJsonRange, + )) as VersionRange | undefined; } if (!installedVersion) { @@ -401,8 +452,8 @@ function _buildPackageInfo( ); } - const versions = npmPackageJson.versions ?? {}; - const installedPackageJson = versions[installedVersion] || localPkgJson; + const installedPackageJson = + localPkgJson || (await registryClient.getManifest(name, installedVersion)); if (!installedPackageJson) { throw new Error( `An unexpected error happened; package ${name} has no version ${installedVersion}.`, @@ -417,7 +468,12 @@ function _buildPackageInfo( } else if (targetVersion == 'next') { targetVersion = distTags['latest'] as VersionRange; } else { - targetVersion = findSatisfyingVersion(targetVersion); + targetVersion = (await getSatisfyingVersion( + registryClient, + name, + npmPackageJson.versions, + targetVersion, + )) as VersionRange | undefined; } } @@ -426,13 +482,17 @@ function _buildPackageInfo( targetVersion = undefined; } - const target: PackageVersionInfo | undefined = targetVersion - ? { + let target: PackageVersionInfo | undefined; + if (targetVersion) { + const targetPackageJson = await registryClient.getManifest(name, targetVersion); + if (targetPackageJson) { + target = { version: targetVersion, - packageJson: versions[targetVersion], - updateMetadata: _getUpdateMetadata(versions[targetVersion], logger), - } - : undefined; + packageJson: targetPackageJson, + updateMetadata: _getUpdateMetadata(targetPackageJson, logger), + }; + } + } return { name, @@ -487,11 +547,12 @@ function _buildPackageList( return packages; } -function resolvePackageVersion( - metadata: NpmRepositoryPackageJson, +async function resolvePackageVersion( + registryClient: RegistryClient, + metadata: PackageMetadata, range: string, next = false, -): string | null { +): Promise { const distTags = metadata['dist-tags'] ?? {}; if (distTags[range]) { return distTags[range]; @@ -500,32 +561,16 @@ function resolvePackageVersion( return distTags['latest'] ?? null; } - const packageVersionsNonDeprecated: string[] = []; - const packageVersionsDeprecated: string[] = []; - for (const [v, { deprecated }] of Object.entries(metadata.versions ?? {})) { - if (deprecated) { - packageVersionsDeprecated.push(v); - } else { - packageVersionsNonDeprecated.push(v); - } - } - - return ( - semver.maxSatisfying(packageVersionsNonDeprecated, range, { - includePrerelease: next || undefined, - }) ?? - semver.maxSatisfying(packageVersionsDeprecated, range, { - includePrerelease: next || undefined, - }) - ); + return getSatisfyingVersion(registryClient, metadata.name, metadata.versions, range, next); } -function _addPackageGroup( +async function _addPackageGroup( packages: Map, allDependencies: ReadonlyMap, - metadata: NpmRepositoryPackageJson, + metadata: PackageMetadata, + registryClient: RegistryClient, logger: logging.LoggerApi, -): void { +): Promise { const maybePackage = packages.get(metadata.name); if (!maybePackage) { return; @@ -538,27 +583,20 @@ function _addPackageGroup( } else if (version === 'next') { version = distTags['latest'] as VersionRange; } else { - const packageVersionsNonDeprecated: string[] = []; - const packageVersionsDeprecated: string[] = []; - const versions = metadata.versions ?? {}; - for (const [v, { deprecated }] of Object.entries(versions)) { - if (deprecated) { - packageVersionsDeprecated.push(v); - } else { - packageVersionsNonDeprecated.push(v); - } - } version = - ((semver.maxSatisfying(packageVersionsNonDeprecated, version) ?? - semver.maxSatisfying(packageVersionsDeprecated, version)) as VersionRange | null) ?? - version; + ((await getSatisfyingVersion( + registryClient, + metadata.name, + metadata.versions, + version, + )) as VersionRange | null) ?? version; } - const versions = metadata.versions ?? {}; - if (!versions[version]) { + const packageJson = await registryClient.getManifest(metadata.name, version); + if (!packageJson) { return; } - const ngUpdateMetadata = versions[version]['ng-update']; + const ngUpdateMetadata = packageJson['ng-update']; if (!ngUpdateMetadata) { return; } @@ -607,9 +645,9 @@ function _addPackageGroup( async function _addPeerDependencies( packages: Map, allDependencies: ReadonlyMap, - npmPackageJson: NpmRepositoryPackageJson, + npmPackageJson: PackageMetadata, workspaceRoot: string, - fetchMetadata: (name: string) => Promise, + registryClient: RegistryClient, logger: logging.LoggerApi, ): Promise { const maybePackage = packages.get(npmPackageJson.name); @@ -619,8 +657,7 @@ async function _addPeerDependencies( const distTags = npmPackageJson['dist-tags'] ?? {}; const version = distTags[maybePackage] || maybePackage; - const versions = npmPackageJson.versions ?? {}; - const packageJson = versions[version]; + const packageJson = await registryClient.getManifest(npmPackageJson.name, version); if (!packageJson) { return; } @@ -638,20 +675,14 @@ async function _addPeerDependencies( } else { const packageJsonRange = allDependencies.get(peer); if (packageJsonRange) { - const peerMetadata = await fetchMetadata(peer); + const peerMetadata = await registryClient.getMetadata(peer); if (peerMetadata) { - const packageVersionsNonDeprecated: string[] = []; - const packageVersionsDeprecated: string[] = []; - for (const [v, { deprecated }] of Object.entries(peerMetadata.versions ?? {})) { - if (deprecated) { - packageVersionsDeprecated.push(v); - } else { - packageVersionsNonDeprecated.push(v); - } - } - const resolvedInstalledVersion = - semver.maxSatisfying(packageVersionsNonDeprecated, packageJsonRange) ?? - semver.maxSatisfying(packageVersionsDeprecated, packageJsonRange); + const resolvedInstalledVersion = await getSatisfyingVersion( + registryClient, + peer, + peerMetadata.versions, + packageJsonRange, + ); if (resolvedInstalledVersion && semver.satisfies(resolvedInstalledVersion, range)) { continue; @@ -684,6 +715,7 @@ function isPkgFromRegistry(name: string, specifier: string): boolean { export async function resolveUserUpdatePlan( options: UpdateResolverOptions, + packageManager: PackageManager, logger: logging.LoggerApi, ): Promise { const workspaceRoot = options.workspaceRoot ?? process.cwd(); @@ -733,25 +765,12 @@ export async function resolveUserUpdatePlan( const usingYarn = options.packageManager === 'yarn'; const packages = _buildPackageList(options, npmDeps, logger); - const npmPackageJsonMap = new Map(); + const registryClient = new RegistryClient(packageManager, logger); const getOrFetchPackageMetadata = async ( packageName: string, - ): Promise => { - let metadata = npmPackageJsonMap.get(packageName); - if (!metadata) { - const raw = await getNpmPackageJson(packageName, logger, { - registry: options.registry, - usingYarn, - verbose: options.verbose, - }); - if (raw.name) { - metadata = raw as NpmRepositoryPackageJson; - npmPackageJsonMap.set(packageName, metadata); - } - } - - return metadata ?? null; + ): Promise => { + return registryClient.getMetadata(packageName); }; if (packages.size === 0) { @@ -772,11 +791,16 @@ export async function resolveUserUpdatePlan( const metadata = await getOrFetchPackageMetadata(name); const spec = packages.get(name); if (metadata && spec) { - const resolvedVersion = resolvePackageVersion(metadata, spec, !!options.next); + const resolvedVersion = await resolvePackageVersion( + registryClient, + metadata, + spec, + !!options.next, + ); if (resolvedVersion) { packages.set(name, resolvedVersion as VersionRange); } - _addPackageGroup(packages, npmDeps, metadata, logger); + await _addPackageGroup(packages, npmDeps, metadata, registryClient, logger); } } } while (packages.size > lastGroupSize); @@ -785,7 +809,12 @@ export async function resolveUserUpdatePlan( const metadata = await getOrFetchPackageMetadata(name); const spec = packages.get(name); if (metadata && spec) { - const resolvedVersion = resolvePackageVersion(metadata, spec, !!options.next); + const resolvedVersion = await resolvePackageVersion( + registryClient, + metadata, + spec, + !!options.next, + ); if (resolvedVersion) { packages.set(name, resolvedVersion as VersionRange); } @@ -794,7 +823,7 @@ export async function resolveUserUpdatePlan( npmDeps, metadata, workspaceRoot, - getOrFetchPackageMetadata, + registryClient, logger, ); } @@ -802,25 +831,31 @@ export async function resolveUserUpdatePlan( } while (packages.size > lastPackagesSize); } - const packageInfoMap = new Map(); - for (const depName of npmDeps.keys()) { - const isUpdating = packages.has(depName); - const localPkgJson = getInstalledPackageJson(depName, workspaceRoot); - - if (isUpdating || !localPkgJson) { - const metadata = await getOrFetchPackageMetadata(depName); - if (metadata) { - packageInfoMap.set( - depName, - _buildPackageInfo(packages, npmDeps, metadata, workspaceRoot, logger), - ); - } else { - packageInfoMap.set(depName, _buildLocalPackageInfo(depName, npmDeps, workspaceRoot)); + const packageInfoEntries = await Promise.all( + Array.from(npmDeps.keys(), async (depName) => { + const isUpdating = packages.has(depName); + const localPkgJson = getInstalledPackageJson(depName, workspaceRoot); + + if (isUpdating || !localPkgJson) { + const metadata = await getOrFetchPackageMetadata(depName); + if (metadata) { + const info = await _buildPackageInfo( + packages, + npmDeps, + metadata, + workspaceRoot, + registryClient, + logger, + ); + + return [depName, info] as const; + } } - } else { - packageInfoMap.set(depName, _buildLocalPackageInfo(depName, npmDeps, workspaceRoot)); - } - } + + return [depName, _buildLocalPackageInfo(depName, npmDeps, workspaceRoot)] as const; + }), + ); + const packageInfoMap = new Map(packageInfoEntries); const packagesToUpdate = new Map(); const migrationsToRun: { package: string; collection: string; from: string; to: string }[] = []; @@ -852,22 +887,23 @@ export async function resolveUserUpdatePlan( packagesToUpdate, migrationsToRun, packageInfoMap, + registryClient, }; } -export function printUpdateUsageMessage( +export async function printUpdateUsageMessage( infoMap: Map, + registryClient: RegistryClient, logger: logging.LoggerApi, next = false, -) { +): Promise { const packageGroups = new Map(); - const packagesToUpdate = [...infoMap.entries()] - .map(([name, info]) => { + const mappedPackages = await Promise.all( + Array.from(infoMap.entries(), async ([name, info]) => { const distTags = info.npmPackageJson['dist-tags'] ?? {}; let tag = next ? (distTags['next'] ? 'next' : 'latest') : 'latest'; let version = distTags[tag] ?? info.installed.version; - const versions = info.npmPackageJson.versions ?? {}; - let target = versions[version]; + const versions = info.npmPackageJson.versions ?? []; const versionDiff = semver.diff(info.installed.version, version); if ( @@ -883,18 +919,19 @@ export function printUpdateUsageMessage( installedMajorVersion < toInstallMajorVersion - 1 ) { const nextMajorVersion = `${installedMajorVersion + 1}.`; - const nextMajorVersions = Object.keys(versions) + const nextMajorVersions = versions .filter((v) => v.startsWith(nextMajorVersion)) .sort((a, b) => (a > b ? -1 : 1)); if (nextMajorVersions.length) { version = nextMajorVersions[0]; - target = versions[version]; tag = ''; } } } + const target = info.target?.packageJson || (await registryClient.getManifest(name, version)); + return { name, info, @@ -902,21 +939,25 @@ export function printUpdateUsageMessage( tag, target, }; - }) + }), + ); + + const packagesToUpdate = mappedPackages .filter( ({ info, version, target }) => target?.['ng-update'] && semver.compare(info.installed.version, version) < 0, ) .map(({ name, info, version, tag, target }) => { // Look for packageGroup. - const ngUpdate = target['ng-update']; + const ngUpdate = target?.['ng-update'] as Record | undefined; const packageGroup = ngUpdate?.['packageGroup']; if (packageGroup) { const packageGroupNames = Array.isArray(packageGroup) ? packageGroup : Object.keys(packageGroup); const packageGroupName = - ngUpdate?.['packageGroupName'] || packageGroupNames.find((n) => infoMap.has(n)); + (ngUpdate?.['packageGroupName'] as string | undefined) || + packageGroupNames.find((n) => infoMap.has(n)); if (packageGroupName) { if (packageGroups.has(name)) { diff --git a/packages/angular/cli/src/commands/update/update-resolver_spec.ts b/packages/angular/cli/src/commands/update/update-resolver_spec.ts index 6953b9817906..ae410765bd4b 100644 --- a/packages/angular/cli/src/commands/update/update-resolver_spec.ts +++ b/packages/angular/cli/src/commands/update/update-resolver_spec.ts @@ -7,11 +7,14 @@ */ import { logging } from '@angular-devkit/core'; -import { existsSync, mkdirSync, mkdtempSync, readFileSync, rmSync, writeFileSync } from 'node:fs'; +import { mkdirSync, mkdtempSync, readFileSync, rmSync, writeFileSync } from 'node:fs'; import { tmpdir } from 'node:os'; import * as path from 'node:path'; import * as semver from 'semver'; +import type { PackageManager, PackageManifest } from '../../package-managers'; import { + RegistryClient, + UpdateResolverOptions, angularMajorCompatGuarantee, applyUpdatePlan, resolveUserUpdatePlan, @@ -47,6 +50,127 @@ describe('UpdateResolver', () => { rmSync(tempRoot, { recursive: true, force: true }); }); + const MOCK_REGISTRY: Record< + string, + { + metadata: { name: string; 'dist-tags': Record; versions: string[] }; + manifests: Record; + } + > = { + '@angular-devkit-tests/update-base': { + metadata: { + name: '@angular-devkit-tests/update-base', + 'dist-tags': { latest: '1.1.0' }, + versions: ['1.0.0', '1.1.0'], + }, + manifests: { + '1.0.0': { name: '@angular-devkit-tests/update-base', version: '1.0.0' }, + '1.1.0': { name: '@angular-devkit-tests/update-base', version: '1.1.0' }, + }, + }, + '@angular-devkit-tests/update-peer-dependencies-angular-5': { + metadata: { + name: '@angular-devkit-tests/update-peer-dependencies-angular-5', + 'dist-tags': { latest: '1.0.0' }, + versions: ['1.0.0'], + }, + manifests: { + '1.0.0': { + name: '@angular-devkit-tests/update-peer-dependencies-angular-5', + version: '1.0.0', + peerDependencies: { + '@angular/core': '^5.0.0', + }, + }, + }, + }, + '@angular-devkit-tests/update-package-group-1': { + metadata: { + name: '@angular-devkit-tests/update-package-group-1', + 'dist-tags': { latest: '1.2.0' }, + versions: ['1.0.0', '1.2.0'], + }, + manifests: { + '1.0.0': { name: '@angular-devkit-tests/update-package-group-1', version: '1.0.0' }, + '1.2.0': { + name: '@angular-devkit-tests/update-package-group-1', + version: '1.2.0', + 'ng-update': { + packageGroup: { + '@angular-devkit-tests/update-package-group-1': '', + '@angular-devkit-tests/update-package-group-2': '^2', + }, + }, + }, + }, + }, + '@angular-devkit-tests/update-package-group-2': { + metadata: { + name: '@angular-devkit-tests/update-package-group-2', + 'dist-tags': { latest: '2.0.0' }, + versions: ['1.0.0', '2.0.0'], + }, + manifests: { + '1.0.0': { name: '@angular-devkit-tests/update-package-group-2', version: '1.0.0' }, + '2.0.0': { + name: '@angular-devkit-tests/update-package-group-2', + version: '2.0.0', + 'ng-update': { + packageGroup: { + '@angular-devkit-tests/update-package-group-1': '^1', + '@angular-devkit-tests/update-package-group-2': '', + }, + }, + }, + }, + }, + '@angular/core': { + metadata: { + name: '@angular/core', + 'dist-tags': { latest: '6.0.0' }, + versions: ['5.1.0', '6.0.0'], + }, + manifests: { + '5.1.0': { name: '@angular/core', version: '5.1.0' }, + '6.0.0': { name: '@angular/core', version: '6.0.0' }, + }, + }, + 'rxjs': { + metadata: { + name: 'rxjs', + 'dist-tags': { latest: '5.5.0' }, + versions: ['5.5.0'], + }, + manifests: { + '5.5.0': { name: 'rxjs', version: '5.5.0' }, + }, + }, + 'zone.js': { + metadata: { + name: 'zone.js', + 'dist-tags': { latest: '0.8.26' }, + versions: ['0.8.26'], + }, + manifests: { + '0.8.26': { name: 'zone.js', version: '0.8.26' }, + }, + }, + }; + + async function resolvePlan(options: UpdateResolverOptions) { + const mockPackageManager = { + name: 'npm', + async getRegistryMetadata(packageName: string) { + return MOCK_REGISTRY[packageName]?.metadata ?? null; + }, + async getRegistryManifest(packageName: string, version: string) { + return MOCK_REGISTRY[packageName]?.manifests[version] ?? null; + }, + } as unknown as PackageManager; + + return resolveUserUpdatePlan(options, mockPackageManager, logger); + } + function createMockWorkspace( packageJson: Record, nodeModules: { [name: string]: { version: string; manifest?: Record } } = {}, @@ -70,13 +194,10 @@ describe('UpdateResolver', () => { }, }); - const plan = await resolveUserUpdatePlan( - { - packages: [], - workspaceRoot: tempRoot, - }, - logger, - ); + const plan = await resolvePlan({ + packages: [], + workspaceRoot: tempRoot, + }); expect(plan.packagesToUpdate.size).toBe(0); }); @@ -95,13 +216,10 @@ describe('UpdateResolver', () => { }, ); - const plan = await resolveUserUpdatePlan( - { - packages: ['@angular-devkit-tests/update-base'], - workspaceRoot: tempRoot, - }, - logger, - ); + const plan = await resolvePlan({ + packages: ['@angular-devkit-tests/update-base'], + workspaceRoot: tempRoot, + }); expect(plan.packagesToUpdate.get('@angular-devkit-tests/update-base')).toBe('1.1.0'); }); @@ -125,13 +243,10 @@ describe('UpdateResolver', () => { }, ); - const plan = await resolveUserUpdatePlan( - { - packages: ['@angular/core@^6.0.0'], - workspaceRoot: tempRoot, - }, - logger, - ); + const plan = await resolvePlan({ + packages: ['@angular/core@^6.0.0'], + workspaceRoot: tempRoot, + }); expect(plan.packagesToUpdate.get('@angular/core')?.[0]).toBe('6'); }); @@ -151,13 +266,10 @@ describe('UpdateResolver', () => { }, ); - const plan = await resolveUserUpdatePlan( - { - packages: ['@angular-devkit-tests/update-package-group-1'], - workspaceRoot: tempRoot, - }, - logger, - ); + const plan = await resolvePlan({ + packages: ['@angular-devkit-tests/update-package-group-1'], + workspaceRoot: tempRoot, + }); expect(plan.packagesToUpdate.get('@angular-devkit-tests/update-package-group-1')).toBe('1.2.0'); expect(plan.packagesToUpdate.get('@angular-devkit-tests/update-package-group-2')).toBe('2.0.0'); @@ -182,13 +294,10 @@ describe('UpdateResolver', () => { JSON.stringify({ name: '@angular-devkit-tests/update-base', version: '1.0.0' }, null, 2), ); - const plan = await resolveUserUpdatePlan( - { - packages: ['@angular-devkit-tests/update-base'], - workspaceRoot: tempRoot, - }, - logger, - ); + const plan = await resolvePlan({ + packages: ['@angular-devkit-tests/update-base'], + workspaceRoot: tempRoot, + }); await applyUpdatePlan(tempRoot, plan, logger); @@ -214,13 +323,10 @@ describe('UpdateResolver', () => { JSON.stringify({ name: '@angular-devkit-tests/update-base', version: '1.0.0' }, null, 2), ); - const plan = await resolveUserUpdatePlan( - { - packages: ['@angular-devkit-tests/update-base'], - workspaceRoot: tempRoot, - }, - logger, - ); + const plan = await resolvePlan({ + packages: ['@angular-devkit-tests/update-base'], + workspaceRoot: tempRoot, + }); await applyUpdatePlan(tempRoot, plan, logger); @@ -228,3 +334,91 @@ describe('UpdateResolver', () => { expect(result.endsWith('}')).toBeTrue(); }); }); + +describe('RegistryClient', () => { + const logger = new logging.NullLogger(); + + it('should cache metadata requests', async () => { + let callCount = 0; + const mockPackageManager = { + async getRegistryMetadata() { + callCount++; + + return { name: 'test-pkg', 'dist-tags': {}, versions: [] }; + }, + } as unknown as PackageManager; + + const client = new RegistryClient(mockPackageManager, logger); + const m1 = await client.getMetadata('test-pkg'); + const m2 = await client.getMetadata('test-pkg'); + + expect(callCount).toBe(1); + expect(m1).toEqual(m2); + }); + + it('should evict metadata requests from cache upon failure', async () => { + let callCount = 0; + const mockPackageManager = { + async getRegistryMetadata() { + callCount++; + if (callCount === 1) { + throw new Error('Transient error'); + } + + return { name: 'test-pkg', 'dist-tags': {}, versions: [] }; + }, + } as unknown as PackageManager; + + const client = new RegistryClient(mockPackageManager, logger); + + await expectAsync(client.getMetadata('test-pkg')).toBeRejectedWithError('Transient error'); + const m2 = await client.getMetadata('test-pkg'); + + expect(callCount).toBe(2); + expect(m2).not.toBeNull(); + expect(m2?.name).toBe('test-pkg'); + }); + + it('should cache manifest requests', async () => { + let callCount = 0; + const mockPackageManager = { + async getRegistryManifest() { + callCount++; + + return { name: 'test-pkg', version: '1.0.0' }; + }, + } as unknown as PackageManager; + + const client = new RegistryClient(mockPackageManager, logger); + const m1 = await client.getManifest('test-pkg', '1.0.0'); + const m2 = await client.getManifest('test-pkg', '1.0.0'); + + expect(callCount).toBe(1); + expect(m1).toEqual(m2); + }); + + it('should evict manifest requests from cache upon failure', async () => { + let callCount = 0; + const mockPackageManager = { + async getRegistryManifest() { + callCount++; + if (callCount === 1) { + throw new Error('Transient error'); + } + + return { name: 'test-pkg', version: '1.0.0' }; + }, + } as unknown as PackageManager; + + const client = new RegistryClient(mockPackageManager, logger); + + await expectAsync(client.getManifest('test-pkg', '1.0.0')).toBeRejectedWithError( + 'Transient error', + ); + const m2 = await client.getManifest('test-pkg', '1.0.0'); + + expect(callCount).toBe(2); + expect(m2).not.toBeNull(); + expect(m2?.version).toBe('1.0.0'); + }); +}); diff --git a/packages/angular/cli/src/package-managers/package-metadata.ts b/packages/angular/cli/src/package-managers/package-metadata.ts index 45c38ca2602b..b1e97e426eab 100644 --- a/packages/angular/cli/src/package-managers/package-metadata.ts +++ b/packages/angular/cli/src/package-managers/package-metadata.ts @@ -47,7 +47,7 @@ export interface NgUpdate { /** * A list of package names that should be updated together. */ - packageGroup?: string[]; + packageGroup?: string[] | Record; } /** diff --git a/packages/angular/cli/src/utilities/package-metadata.ts b/packages/angular/cli/src/utilities/package-metadata.ts deleted file mode 100644 index 05a739e898ae..000000000000 --- a/packages/angular/cli/src/utilities/package-metadata.ts +++ /dev/null @@ -1,247 +0,0 @@ -/** - * @license - * Copyright Google LLC All Rights Reserved. - * - * Use of this source code is governed by an MIT-style license that can be - * found in the LICENSE file at https://angular.dev/license - */ - -import { logging } from '@angular-devkit/core'; -import * as lockfile from '@yarnpkg/lockfile'; -import * as ini from 'ini'; -import { existsSync, readFileSync } from 'node:fs'; -import { homedir } from 'node:os'; -import * as path from 'node:path'; -import type { Manifest, Packument } from 'pacote'; - -export interface PackageMetadata extends Packument, NgPackageManifestProperties { - tags: Record; - versions: Record; -} - -export interface NpmRepositoryPackageJson extends PackageMetadata { - requestedName?: string; -} - -export type NgAddSaveDependency = 'dependencies' | 'devDependencies' | boolean; - -export interface PackageIdentifier { - type: 'git' | 'tag' | 'version' | 'range' | 'file' | 'directory' | 'remote'; - name: string; - scope: string | null; - registry: boolean; - raw: string; - fetchSpec: string; - rawSpec: string; -} - -export interface NgPackageManifestProperties { - 'ng-add'?: { - save?: NgAddSaveDependency; - }; - 'ng-update'?: { - migrations?: string; - packageGroup?: string[] | Record; - packageGroupName?: string; - requirements?: string[] | Record; - }; -} - -export interface PackageManifest extends Manifest, NgPackageManifestProperties { - deprecated?: boolean; - peerDependenciesMeta?: Record; -} - -type PackageManagerOptions = Record; - -let npmrc: PackageManagerOptions; -const npmPackageJsonCache = new Map>>(); - -function ensureNpmrc(logger: logging.LoggerApi, usingYarn: boolean, verbose: boolean): void { - if (!npmrc) { - try { - npmrc = readOptions(logger, false, verbose); - } catch {} - - if (usingYarn) { - try { - npmrc = { ...npmrc, ...readOptions(logger, true, verbose) }; - } catch {} - } - } -} - -function readOptions( - logger: logging.LoggerApi, - yarn = false, - showPotentials = false, -): PackageManagerOptions { - const cwd = process.cwd(); - const baseFilename = yarn ? 'yarnrc' : 'npmrc'; - const dotFilename = '.' + baseFilename; - - let globalPrefix: string; - if (process.env.PREFIX) { - globalPrefix = process.env.PREFIX; - } else { - globalPrefix = path.dirname(process.execPath); - if (process.platform !== 'win32') { - globalPrefix = path.dirname(globalPrefix); - } - } - - const defaultConfigLocations = [ - (!yarn && process.env.NPM_CONFIG_GLOBALCONFIG) || path.join(globalPrefix, 'etc', baseFilename), - (!yarn && process.env.NPM_CONFIG_USERCONFIG) || path.join(homedir(), dotFilename), - ]; - - const projectConfigLocations: string[] = [path.join(cwd, dotFilename)]; - if (yarn) { - const root = path.parse(cwd).root; - for (let curDir = path.dirname(cwd); curDir && curDir !== root; curDir = path.dirname(curDir)) { - projectConfigLocations.unshift(path.join(curDir, dotFilename)); - } - } - - if (showPotentials) { - logger.info(`Locating potential ${baseFilename} files:`); - } - - let rcOptions: PackageManagerOptions = {}; - for (const location of [...defaultConfigLocations, ...projectConfigLocations]) { - if (existsSync(location)) { - if (showPotentials) { - logger.info(`Trying '${location}'...found.`); - } - - const data = readFileSync(location, 'utf8'); - // Normalize RC options that are needed by 'npm-registry-fetch'. - // See: https://github.com/npm/npm-registry-fetch/blob/ebddbe78a5f67118c1f7af2e02c8a22bcaf9e850/index.js#L99-L126 - const rcConfig: PackageManagerOptions = yarn ? lockfile.parse(data) : ini.parse(data); - - rcOptions = normalizeOptions(rcConfig, location, rcOptions); - } - } - - const envVariablesOptions: PackageManagerOptions = {}; - for (const [key, value] of Object.entries(process.env)) { - if (!value) { - continue; - } - - let normalizedName = key.toLowerCase(); - if (normalizedName.startsWith('npm_config_')) { - normalizedName = normalizedName.substring(11); - } else if (yarn && normalizedName.startsWith('yarn_')) { - normalizedName = normalizedName.substring(5); - } else { - continue; - } - - if ( - normalizedName === 'registry' && - rcOptions['registry'] && - value === 'https://registry.yarnpkg.com' && - process.env['npm_config_user_agent']?.includes('yarn') - ) { - // When running `ng update` using yarn (`yarn ng update`), yarn will set the `npm_config_registry` env variable to `https://registry.yarnpkg.com` - // even when an RC file is present with a different repository. - // This causes the registry specified in the RC to always be overridden with the below logic. - continue; - } - - normalizedName = normalizedName.replace(/(?!^)_/g, '-'); // don't replace _ at the start of the key.s - envVariablesOptions[normalizedName] = value; - } - - return normalizeOptions(envVariablesOptions, undefined, rcOptions); -} - -function normalizeOptions( - rawOptions: PackageManagerOptions, - location = process.cwd(), - existingNormalizedOptions: PackageManagerOptions = {}, -): PackageManagerOptions { - const options = { ...existingNormalizedOptions }; - - for (const [key, value] of Object.entries(rawOptions)) { - let substitutedValue = value; - - // Substitute any environment variable references. - if (typeof value === 'string') { - substitutedValue = value.replace(/\$\{([^}]+)\}/, (_, name) => process.env[name] || ''); - } - - switch (key) { - case 'noproxy': - case 'no-proxy': - options['noProxy'] = substitutedValue; - break; - case 'maxsockets': - options['maxSockets'] = substitutedValue; - break; - case 'https-proxy': - case 'proxy': - options['proxy'] = substitutedValue; - break; - case 'strict-ssl': - options['strictSSL'] = substitutedValue; - break; - case 'local-address': - options['localAddress'] = substitutedValue; - break; - case 'cafile': - if (typeof substitutedValue === 'string') { - const cafile = path.resolve(path.dirname(location), substitutedValue); - try { - options['ca'] = readFileSync(cafile, 'utf8').replace(/\r?\n/g, '\n'); - } catch {} - } - break; - case 'before': - options['before'] = - typeof substitutedValue === 'string' ? new Date(substitutedValue) : substitutedValue; - break; - default: - options[key] = substitutedValue; - break; - } - } - - return options; -} - -export async function getNpmPackageJson( - packageName: string, - logger: logging.LoggerApi, - options: { - registry?: string; - usingYarn?: boolean; - verbose?: boolean; - } = {}, -): Promise> { - const cachedResponse = npmPackageJsonCache.get(packageName); - if (cachedResponse) { - return cachedResponse; - } - - const { usingYarn = false, verbose = false, registry } = options; - ensureNpmrc(logger, usingYarn, verbose); - const { packument } = await import('pacote'); - const response = packument(packageName, { - fullMetadata: true, - ...npmrc, - ...(registry ? { registry } : {}), - }).then((response) => { - // While pacote type declares that versions cannot be undefined this is not the case. - if (!response.versions) { - response.versions = {}; - } - - return response; - }); - - npmPackageJsonCache.set(packageName, response); - - return response; -} diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 063dfb959e7c..f308063f470a 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -66,7 +66,7 @@ importers: version: 22.1.0-next.0(@angular/core@22.1.0-next.0(@angular/compiler@22.1.0-next.0)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2) '@babel/core': specifier: 7.29.7 - version: 7.29.7 + version: 7.29.7(supports-color@10.2.2) '@bazel/bazelisk': specifier: 1.28.1 version: 1.28.1 @@ -78,13 +78,13 @@ importers: version: 0.28.0 '@eslint/compat': specifier: 2.1.0 - version: 2.1.0(eslint@10.5.0(jiti@2.7.0)) + version: 2.1.0(eslint@10.5.0(jiti@2.7.0)(supports-color@10.2.2)) '@eslint/eslintrc': specifier: 3.3.5 - version: 3.3.5 + version: 3.3.5(supports-color@10.2.2) '@eslint/js': specifier: 10.0.1 - version: 10.0.1(eslint@10.5.0(jiti@2.7.0)) + version: 10.0.1(eslint@10.5.0(jiti@2.7.0)(supports-color@10.2.2)) '@rollup/plugin-alias': specifier: ^6.0.0 version: 6.0.0(rollup@4.62.0) @@ -102,10 +102,10 @@ importers: version: 4.62.0 '@stylistic/eslint-plugin': specifier: ^5.0.0 - version: 5.10.0(eslint@10.5.0(jiti@2.7.0)) + version: 5.10.0(eslint@10.5.0(jiti@2.7.0)(supports-color@10.2.2)) '@tony.ganchev/eslint-plugin-header': specifier: ~3.4.0 - version: 3.4.4(eslint@10.5.0(jiti@2.7.0)) + version: 3.4.4(eslint@10.5.0(jiti@2.7.0)(supports-color@10.2.2)) '@types/babel__core': specifier: 7.20.5 version: 7.20.5 @@ -121,9 +121,6 @@ importers: '@types/http-proxy': specifier: ^1.17.4 version: 1.17.17 - '@types/ini': - specifier: ^4.0.0 - version: 4.1.1 '@types/jasmine': specifier: ~6.0.0 version: 6.0.0 @@ -148,9 +145,6 @@ importers: '@types/npm-package-arg': specifier: ^6.1.0 version: 6.1.4 - '@types/pacote': - specifier: ^11.1.3 - version: 11.1.8 '@types/picomatch': specifier: ^4.0.0 version: 4.0.3 @@ -169,15 +163,12 @@ importers: '@types/yargs-parser': specifier: ^21.0.0 version: 21.0.3 - '@types/yarnpkg__lockfile': - specifier: ^1.1.5 - version: 1.1.9 '@typescript-eslint/eslint-plugin': specifier: 8.61.0 - version: 8.61.0(@typescript-eslint/parser@8.61.0(eslint@10.5.0(jiti@2.7.0))(typescript@6.0.3))(eslint@10.5.0(jiti@2.7.0))(typescript@6.0.3) + version: 8.61.0(@typescript-eslint/parser@8.61.0(eslint@10.5.0(jiti@2.7.0)(supports-color@10.2.2))(supports-color@10.2.2)(typescript@6.0.3))(eslint@10.5.0(jiti@2.7.0)(supports-color@10.2.2))(supports-color@10.2.2)(typescript@6.0.3) '@typescript-eslint/parser': specifier: 8.61.0 - version: 8.61.0(eslint@10.5.0(jiti@2.7.0))(typescript@6.0.3) + version: 8.61.0(eslint@10.5.0(jiti@2.7.0)(supports-color@10.2.2))(supports-color@10.2.2)(typescript@6.0.3) ajv: specifier: 8.20.0 version: 8.20.0 @@ -192,16 +183,16 @@ importers: version: 0.28.1 eslint: specifier: 10.5.0 - version: 10.5.0(jiti@2.7.0) + version: 10.5.0(jiti@2.7.0)(supports-color@10.2.2) eslint-config-prettier: specifier: 10.1.8 - version: 10.1.8(eslint@10.5.0(jiti@2.7.0)) + version: 10.1.8(eslint@10.5.0(jiti@2.7.0)(supports-color@10.2.2)) eslint-plugin-import: specifier: 2.32.0 - version: 2.32.0(@typescript-eslint/parser@8.61.0(eslint@10.5.0(jiti@2.7.0))(typescript@6.0.3))(eslint@10.5.0(jiti@2.7.0)) + version: 2.32.0(@typescript-eslint/parser@8.61.0(eslint@10.5.0(jiti@2.7.0)(supports-color@10.2.2))(supports-color@10.2.2)(typescript@6.0.3))(eslint@10.5.0(jiti@2.7.0)(supports-color@10.2.2)) express: specifier: 5.2.1 - version: 5.2.1 + version: 5.2.1(supports-color@10.2.2) fast-glob: specifier: 3.3.3 version: 3.3.3 @@ -213,7 +204,7 @@ importers: version: 1.18.1 http-proxy-middleware: specifier: 4.1.1 - version: 4.1.1 + version: 4.1.1(supports-color@10.2.2) husky: specifier: 9.1.7 version: 9.1.7 @@ -231,19 +222,19 @@ importers: version: 7.0.0 karma: specifier: ~6.4.0 - version: 6.4.4(bufferutil@4.1.0)(utf-8-validate@6.0.6) + version: 6.4.4(bufferutil@4.1.0)(supports-color@10.2.2)(utf-8-validate@6.0.6) karma-chrome-launcher: specifier: ~3.2.0 version: 3.2.0 karma-coverage: specifier: ~2.2.0 - version: 2.2.1 + version: 2.2.1(supports-color@10.2.2) karma-jasmine: specifier: ~5.1.0 - version: 5.1.0(karma@6.4.4(bufferutil@4.1.0)(utf-8-validate@6.0.6)) + version: 5.1.0(karma@6.4.4(bufferutil@4.1.0)(supports-color@10.2.2)(utf-8-validate@6.0.6)) karma-jasmine-html-reporter: specifier: ~2.2.0 - version: 2.2.0(jasmine-core@6.3.0)(karma-jasmine@5.1.0(karma@6.4.4(bufferutil@4.1.0)(utf-8-validate@6.0.6)))(karma@6.4.4(bufferutil@4.1.0)(utf-8-validate@6.0.6)) + version: 2.2.0(jasmine-core@6.3.0)(karma-jasmine@5.1.0(karma@6.4.4(bufferutil@4.1.0)(supports-color@10.2.2)(utf-8-validate@6.0.6)))(karma@6.4.4(bufferutil@4.1.0)(supports-color@10.2.2)(utf-8-validate@6.0.6)) karma-source-map-support: specifier: 1.4.0 version: 1.4.0 @@ -291,10 +282,10 @@ importers: version: 1.10.0 verdaccio: specifier: 6.7.2 - version: 6.7.2(encoding@0.1.13) + version: 6.7.2(encoding@0.1.13)(supports-color@10.2.2) verdaccio-auth-memory: specifier: ^13.0.0 - version: 13.0.2 + version: 13.0.2(supports-color@10.2.2) zone.js: specifier: ^0.16.0 version: 0.16.2 @@ -318,7 +309,7 @@ importers: version: 4.1.9(vitest@4.1.9) browser-sync: specifier: 3.0.4 - version: 3.0.4(bufferutil@4.1.0)(utf-8-validate@6.0.6) + version: 3.0.4(bufferutil@4.1.0)(supports-color@10.2.2)(utf-8-validate@6.0.6) istanbul-lib-instrument: specifier: 6.0.3 version: 6.0.3 @@ -345,7 +336,7 @@ importers: version: link:../../angular_devkit/architect '@babel/core': specifier: 7.29.7 - version: 7.29.7 + version: 7.29.7(supports-color@10.2.2) '@babel/helper-annotate-as-pure': specifier: 7.29.7 version: 7.29.7 @@ -369,7 +360,7 @@ importers: version: 0.28.1 https-proxy-agent: specifier: 9.1.0 - version: 9.1.0 + version: 9.1.0(supports-color@10.2.2) jsonc-parser: specifier: 3.3.1 version: 3.3.1 @@ -471,15 +462,9 @@ importers: '@schematics/angular': specifier: workspace:0.0.0-PLACEHOLDER version: link:../../schematics/angular - '@yarnpkg/lockfile': - specifier: 1.1.0 - version: 1.1.0 algoliasearch: specifier: 5.54.0 version: 5.54.0 - ini: - specifier: 7.0.0 - version: 7.0.0 jsonc-parser: specifier: 3.3.1 version: 3.3.1 @@ -489,9 +474,6 @@ importers: npm-package-arg: specifier: 14.0.0 version: 14.0.0 - pacote: - specifier: 21.5.1 - version: 21.5.1 parse5-html-rewriting-stream: specifier: 8.0.1 version: 8.0.1 @@ -579,7 +561,7 @@ importers: version: link:../../angular/build '@babel/core': specifier: 7.29.7 - version: 7.29.7 + version: 7.29.7(supports-color@10.2.2) '@babel/generator': specifier: 7.29.7 version: 7.29.7 @@ -597,7 +579,7 @@ importers: version: 7.29.7(@babel/core@7.29.7) '@babel/plugin-transform-runtime': specifier: 7.29.7 - version: 7.29.7(@babel/core@7.29.7) + version: 7.29.7(@babel/core@7.29.7)(supports-color@10.2.2) '@babel/preset-env': specifier: 7.29.7 version: 7.29.7(@babel/core@7.29.7) @@ -633,7 +615,7 @@ importers: version: 0.28.1 http-proxy-middleware: specifier: 4.1.1 - version: 4.1.1 + version: 4.1.1(supports-color@10.2.2) istanbul-lib-instrument: specifier: 6.0.3 version: 6.0.3 @@ -714,7 +696,7 @@ importers: version: 8.0.3(tslib@2.8.1)(webpack@5.107.2(esbuild@0.28.1)(postcss@8.5.15)) webpack-dev-server: specifier: 5.2.5 - version: 5.2.5(bufferutil@4.1.0)(tslib@2.8.1)(utf-8-validate@6.0.6)(webpack@5.107.2(esbuild@0.28.1)(postcss@8.5.15)) + version: 5.2.5(bufferutil@4.1.0)(supports-color@10.2.2)(tslib@2.8.1)(utf-8-validate@6.0.6)(webpack@5.107.2(esbuild@0.28.1)(postcss@8.5.15)) webpack-merge: specifier: 6.0.1 version: 6.0.1 @@ -727,7 +709,7 @@ importers: version: link:../../angular/ssr browser-sync: specifier: 3.0.4 - version: 3.0.4(bufferutil@4.1.0)(utf-8-validate@6.0.6) + version: 3.0.4(bufferutil@4.1.0)(supports-color@10.2.2)(utf-8-validate@6.0.6) ng-packagr: specifier: 22.1.0-next.2 version: 22.1.0-next.2(@angular/compiler-cli@22.1.0-next.0(@angular/compiler@22.1.0-next.0)(typescript@6.0.3))(tslib@2.8.1)(typescript@6.0.3) @@ -2409,10 +2391,6 @@ packages: '@firebase/webchannel-wrapper@1.0.6': resolution: {integrity: sha512-Vr/Mqu79dMwGRAyGbJ4uN4+BtXB3/mRTdzetD1daWNeG8QaWuzhhbG77GltO5c0yYmYls8i250iX73624GJd7Q==} - '@gar/promise-retry@1.0.3': - resolution: {integrity: sha512-GmzA9ckNokPypTg10pgpeHNQe7ph+iIKKmhKu3Ob9ANkswreCx7R3cKmY781K8QK3AqVL3xVh9A42JvIAbkkSA==} - engines: {node: ^20.17.0 || >=22.9.0} - '@glideapps/ts-necessities@2.2.3': resolution: {integrity: sha512-gXi0awOZLHk3TbW55GZLCPP6O+y/b5X1pBXKBVckFONSwF1z1E5ND2BGJsghQFah+pW7pkkyFb2VhUQI2qhL5w==} @@ -2638,10 +2616,6 @@ packages: resolution: {integrity: sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==} engines: {node: '>=12'} - '@isaacs/fs-minipass@4.0.1': - resolution: {integrity: sha512-wgm9Ehl2jpeqP3zw/7mo3kRHFp5MEDhqAdwy1fTGkHAwnkGOVsgpvQhL8B5n1qlb01jV3n/bI0ZfZp5lWA1k4w==} - engines: {node: '>=18.0.0'} - '@istanbuljs/schema@0.1.6': resolution: {integrity: sha512-+Sg6GCR/wy1oSmQDFq4LQDAhm3ETKnorxN+y5nbLULOR3P0c14f2Wurzj3/xqPXtasLFfHd5iRFQ7AJt4KH2cw==} engines: {node: '>=8'} @@ -3015,43 +2989,6 @@ packages: resolution: {integrity: sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==} engines: {node: '>= 8'} - '@npmcli/agent@4.0.2': - resolution: {integrity: sha512-EUEuWAxnL07Sp5/iC/1X6Xj+XThUvnbei9zfRWZdEXa7lss9RTHMhAHBeg+MZ5To9s/gGaSI+UwZTPdYMvKSeg==} - engines: {node: ^20.17.0 || >=22.9.0} - - '@npmcli/fs@5.0.0': - resolution: {integrity: sha512-7OsC1gNORBEawOa5+j2pXN9vsicaIOH5cPXxoR6fJOmH6/EXpJB2CajXOu1fPRFun2m1lktEFX11+P89hqO/og==} - engines: {node: ^20.17.0 || >=22.9.0} - - '@npmcli/git@7.0.2': - resolution: {integrity: sha512-oeolHDjExNAJAnlYP2qzNjMX/Xi9bmu78C9dIGr4xjobrSKbuMYCph8lTzn4vnW3NjIqVmw/f8BCfouqyJXlRg==} - engines: {node: ^20.17.0 || >=22.9.0} - - '@npmcli/installed-package-contents@4.0.0': - resolution: {integrity: sha512-yNyAdkBxB72gtZ4GrwXCM0ZUedo9nIbOMKfGjt6Cu6DXf0p8y1PViZAKDC8q8kv/fufx0WTjRBdSlyrvnP7hmA==} - engines: {node: ^20.17.0 || >=22.9.0} - hasBin: true - - '@npmcli/node-gyp@5.0.0': - resolution: {integrity: sha512-uuG5HZFXLfyFKqg8QypsmgLQW7smiRjVc45bqD/ofZZcR/uxEjgQU8qDPv0s9TEeMUiAAU/GC5bR6++UdTirIQ==} - engines: {node: ^20.17.0 || >=22.9.0} - - '@npmcli/package-json@7.0.5': - resolution: {integrity: sha512-iVuTlG3ORq2iaVa1IWUxAO/jIp77tUKBhoMjuzYW2kL4MLN1bi/ofqkZ7D7OOwh8coAx1/S2ge0rMdGv8sLSOQ==} - engines: {node: ^20.17.0 || >=22.9.0} - - '@npmcli/promise-spawn@9.0.1': - resolution: {integrity: sha512-OLUaoqBuyxeTqUvjA3FZFiXUfYC1alp3Sa99gW3EUDz3tZ3CbXDdcZ7qWKBzicrJleIgucoWamWH1saAmH/l2Q==} - engines: {node: ^20.17.0 || >=22.9.0} - - '@npmcli/redact@4.0.0': - resolution: {integrity: sha512-gOBg5YHMfZy+TfHArfVogwgfBeQnKbbGo3pSUyK/gSI0AVu+pEiDVcKlQb0D8Mg1LNRZILZ6XG8I5dJ4KuAd9Q==} - engines: {node: ^20.17.0 || >=22.9.0} - - '@npmcli/run-script@10.0.4': - resolution: {integrity: sha512-mGUWr1uMnf0le2TwfOZY4SFxZGXGfm4Jtay/nwAa2FLNAKXUoUwaGwBMNH36UHPtinWfTSJ3nqFQr0091CxVGg==} - engines: {node: ^20.17.0 || >=22.9.0} - '@octokit/auth-app@8.2.0': resolution: {integrity: sha512-vVjdtQQwomrZ4V46B9LaCsxsySxGoHsyw6IYBov/TqJVROrlYdyNgw5q6tQbB7KZt53v1l1W53RiqTvpzL907g==} engines: {node: '>= 20'} @@ -3796,30 +3733,6 @@ packages: '@rtsao/scc@1.1.0': resolution: {integrity: sha512-zt6OdqaDoOnJ1ZYsCYGt9YmWzDXl4vQdKTyJev62gFhRGKdx7mcT54V9KIjg+d2wi9EXsPvAPKe7i7WjfVWB8g==} - '@sigstore/bundle@4.0.0': - resolution: {integrity: sha512-NwCl5Y0V6Di0NexvkTqdoVfmjTaQwoLM236r89KEojGmq/jMls8S+zb7yOwAPdXvbwfKDlP+lmXgAL4vKSQT+A==} - engines: {node: ^20.17.0 || >=22.9.0} - - '@sigstore/core@3.2.1': - resolution: {integrity: sha512-qRsxPnCrbC/puegGxKuynfnxgLiHqWStrSjxkoB4YKqq3Z3s4cyZyj42ZdWFAEblNP65C+rBH8EuREHIXoi83g==} - engines: {node: ^20.17.0 || >=22.9.0} - - '@sigstore/protobuf-specs@0.5.1': - resolution: {integrity: sha512-/ScWUhhoFasJsSRGTVBwId1loQjjnjAfE4djL6ZhrXRpNCmPTnUKF5Jokd58ILseOMjzET3UrMOtJPS9sYeI0g==} - engines: {node: ^18.17.0 || >=20.5.0} - - '@sigstore/sign@4.1.1': - resolution: {integrity: sha512-Hf4xglukg0XXQ2RiD5vSoLjdPe8OBUPA8XeVjUObheuDcWdYWrnH/BNmxZCzkAy68MzmNCxXLeurJvs6hcP2OQ==} - engines: {node: ^20.17.0 || >=22.9.0} - - '@sigstore/tuf@4.0.2': - resolution: {integrity: sha512-TCAzTy0xzdP79EnxSjq9KQ3eaR7+FmudLC6eRKknVKZbV7ZNlGLClAAQb/HMNJ5n2OBNk2GT1tEmU0xuPr+SLQ==} - engines: {node: ^20.17.0 || >=22.9.0} - - '@sigstore/verify@3.1.1': - resolution: {integrity: sha512-qv7+G3J2cc6wwFj3yKvXOamzqhMwSk1ogPGmhpS8iXllcPrJaIIBA+4HbttlHVu1pqWTdmaCH/WE7UOC51kdoA==} - engines: {node: ^20.17.0 || >=22.9.0} - '@simple-libs/child-process-utils@1.0.2': resolution: {integrity: sha512-/4R8QKnd/8agJynkNdJmNw2MBxuFTRcNFnE5Sg/G+jkSsV8/UBgULMzhizWWW42p8L5H7flImV2ATi79Ove2Tw==} engines: {node: '>=18'} @@ -3853,14 +3766,6 @@ packages: peerDependencies: eslint: '>=7.7.0' - '@tufjs/canonical-json@2.0.0': - resolution: {integrity: sha512-yVtV8zsdo8qFHe+/3kw81dSLyF7D576A5cCFCi4X7B39tWT7SekaEFUnvnWJHz+9qO7qJTah1JbrDjWKqFtdWA==} - engines: {node: ^16.14.0 || >=18.0.0} - - '@tufjs/models@4.1.0': - resolution: {integrity: sha512-Y8cK9aggNRsqJVaKUlEYs4s7CvQ1b1ta2DVPyAimb0I2qhzjNk+A+mxvll/klL0RlfuIUei8BF7YWiua4kQqww==} - engines: {node: ^20.17.0 || >=22.9.0} - '@tybys/wasm-util@0.10.2': resolution: {integrity: sha512-RoBvJ2X0wuKlWFIjrwffGw1IqZHKQqzIchKaadZZfnNpsAYp2mM0h36JtPCjNDAHGgYez/15uMBpfGwchhiMgg==} @@ -3945,9 +3850,6 @@ packages: '@types/http-proxy@1.17.17': resolution: {integrity: sha512-ED6LB+Z1AVylNTu7hdzuBqOgMnvG/ld6wGCG8wFnAzKX5uyW2K3WD52v0gnLCTK/VLpXtKckgWuyScYK6cSPaw==} - '@types/ini@4.1.1': - resolution: {integrity: sha512-MIyNUZipBTbyUNnhvuXJTY7B6qNI78meck9Jbv3wk0OgNwRyOOVEKDutAkOs1snB/tx0FafyR6/SN4Ps0hZPeg==} - '@types/jasmine-reporters@2.5.3': resolution: {integrity: sha512-8aojAUdgdiD9VQbllBJb/9gny3lOjz9T5gyMcbYlKe6npwGVsarbr8v2JYSFJSZSuFYXcPVzFG2lLX3ib0j/DA==} @@ -3978,9 +3880,6 @@ packages: '@types/mime@1.3.5': resolution: {integrity: sha512-/pyBZWSLD2n0dcHE3hq8s8ZvcETHtEuF+3E7XVt0Ig2nvsVQXdghHVcEkIWjy9A0wKfTn97a/PSDYohKIlnP/w==} - '@types/node-fetch@2.6.13': - resolution: {integrity: sha512-QGpRVpzSaUs30JBSGPjOg4Uveu384erbHBoT1zeONvyCfwQxIkUshLAOqN/k9EjGviPRmWTTe6aH2qySWKTVSw==} - '@types/node@22.19.20': resolution: {integrity: sha512-6tELRwSDYWW9EdZhbeZmYGZ1/7Djkt+Ah3/ScEYT9cDord7UJzasR/4D3VONg9tQI5CDp+/CZC1AXj2pCFOvpw==} @@ -3990,15 +3889,6 @@ packages: '@types/npm-package-arg@6.1.4': resolution: {integrity: sha512-vDgdbMy2QXHnAruzlv68pUtXCjmqUk3WrBAsRboRovsOmxbfn/WiYCjmecyKjGztnMps5dWp4Uq2prp+Ilo17Q==} - '@types/npm-registry-fetch@8.0.9': - resolution: {integrity: sha512-7NxvodR5Yrop3pb6+n8jhJNyzwOX0+6F+iagNEoi9u1CGxruYAwZD8pvGc9prIkL0+FdX5Xp0p80J9QPrGUp/g==} - - '@types/npmlog@7.0.0': - resolution: {integrity: sha512-hJWbrKFvxKyWwSUXjZMYTINsSOY6IclhvGOZ97M8ac2tmR9hMwmTnYaMdpGhvju9ctWLTPhCS+eLfQNluiEjQQ==} - - '@types/pacote@11.1.8': - resolution: {integrity: sha512-/XLR0VoTh2JEO0jJg1q/e6Rh9bxjBq9vorJuQmtT7rRrXSiWz7e7NsvXVYJQ0i8JxMlBMPPYDTnrRe7MZRFA8Q==} - '@types/parse-glob@3.0.32': resolution: {integrity: sha512-n4xmml2WKR12XeQprN8L/sfiVPa8FHS3k+fxp4kSr/PA2GsGUgFND+bvISJxM0y5QdvzNEGjEVU3eIrcKks/pA==} @@ -4050,9 +3940,6 @@ packages: '@types/sockjs@0.3.36': resolution: {integrity: sha512-MK9V6NzAS1+Ud7JV9lJLFqW85VbC9dq3LmwZCuBe4wBDgKC0Kj/jd8Xl+nSviU+Qc3+m7umHHyHg//2KSa0a0Q==} - '@types/ssri@7.1.5': - resolution: {integrity: sha512-odD/56S3B51liILSk5aXJlnYt99S6Rt9EFDDqGtJM26rKHApHcwyU/UoYHrzKkdkHMAIquGWCuHtQTbes+FRQw==} - '@types/stack-trace@0.0.33': resolution: {integrity: sha512-O7in6531Bbvlb2KEsJ0dq0CHZvc3iWSR5ZYMtvGgnHA56VgriAN/AU2LorfmcvAl2xc9N5fbCTRyMRRl8nd74g==} @@ -4321,10 +4208,6 @@ packages: resolution: {integrity: sha512-E+iruNOY8VV9s4JEbe1aNEm6MiszPRr/UfcHMz0TQh1BXSxHK+ASV1R6W4HpjBhSeS+54PIsAMCBmwD06LLsqQ==} hasBin: true - abbrev@4.0.0: - resolution: {integrity: sha512-a1wflyaL0tHtJSmLSOVybYhy22vRih4eduhhrkcjgrWGnRfrZtovJ2FRjxuTtkkj47O/baf0R86QU5OuYpz8fA==} - engines: {node: ^20.17.0 || >=22.9.0} - abort-controller@3.0.0: resolution: {integrity: sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg==} engines: {node: '>=6.5'} @@ -4749,10 +4632,6 @@ packages: resolution: {integrity: sha512-U1Z/ob71V/bXfVABvNr/Kumf5VyeQRBEm6Txb0PQ6S7V5GpBM3w4Cbqz/xPDicR5tN0uvDifng8C+5qECeGwyQ==} engines: {node: '>=6.0.0'} - cacache@20.0.4: - resolution: {integrity: sha512-M3Lab8NPYlZU2exsL3bMVvMrMqgwCnMWfdZbK28bn3pK6APT/Te/I8hjRPNu1uwORY9a1eEQoifXbKPQMfMTOA==} - engines: {node: ^20.17.0 || >=22.9.0} - cacheable-lookup@6.1.0: resolution: {integrity: sha512-KJ/Dmo1lDDhmW2XDPMo+9oiy/CeqosPguPCrgcVzKyZrL6pM1gU2GmPY/xo6OQPTUaA/c0kwHuywB4E6nmT9ww==} engines: {node: '>=10.6.0'} @@ -4809,10 +4688,6 @@ packages: resolution: {integrity: sha512-TQMmc3w+5AxjpL8iIiwebF73dRDF4fBIieAqGn9RGCWaEVwQ6Fb2cGe31Yns0RRIzii5goJ1Y7xbMwo1TxMplw==} engines: {node: '>= 20.19.0'} - chownr@3.0.0: - resolution: {integrity: sha512-+IxzY9BZOQd/XuYPRmrvEVjF/nqj5kgT4kEq7VofrDoM1MxoRjEWkrCC3EtLi59TVawxTAn+orJwFQcrqEN1+g==} - engines: {node: '>=18'} - chrome-trace-event@1.0.4: resolution: {integrity: sha512-rNjApaLzuwaOTjCiT8lSDdGN1APCiqkChLMJxJPWLunPAt5fy8xgU9/jNOchV84wfIxrA0lRQB7oCT8jrn/wrQ==} engines: {node: '>=6.0'} @@ -5531,9 +5406,6 @@ packages: resolution: {integrity: sha512-knvyeauYhqjOYvQ66MznSMs83wmHrCycNEN6Ao+2AeYEfxUIkuiVxdEa1qlGEPK+We3n0THiDciYSsCcgW/DoA==} engines: {node: '>=12.0.0'} - exponential-backoff@3.1.3: - resolution: {integrity: sha512-ZgEeZXj30q+I0EN+CbSSpIyPaJ5HVQD18Z1m+u1FXbAeT94mr1zw50q4q6jiiC447Nl/YTcIYSAftiGqetwXCA==} - express-rate-limit@5.5.1: resolution: {integrity: sha512-MTjE2eIbHv5DyfuFz4zLYWxpqVhEhkTiwFGuB74Q9CSou2WHO52nlE5y3Zlg6SIsiYUIPj6ifFxnkPz6O3sIUg==} @@ -5718,10 +5590,6 @@ packages: resolution: {integrity: sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==} engines: {node: '>=6 <7 || >=8'} - fs-minipass@3.0.3: - resolution: {integrity: sha512-XUBA9XClHbnJWSfBzjkm6RvPsyg3sryZt06BEQoXcF7EK/xpGaQYJgQKDJSUH5SGZ76Y7pFx1QBnXz09rU5Fbw==} - engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} - fs.realpath@1.0.0: resolution: {integrity: sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==} @@ -5943,10 +5811,6 @@ packages: resolution: {integrity: sha512-DeOnSPAvOndYKfw075gt8yZzQ7S2hNztw34zBTfhIzLhmBTswIBg5/y+pqu/VD5cYWm5goAFTusDmUEmKZ0PEQ==} engines: {node: ^22.22.2 || ^24.15.0 || >=26.0.0} - hosted-git-info@9.0.3: - resolution: {integrity: sha512-Hc+ghLoSt6QaYZUv0WBiIvmMDZuZZ7oaDvdH8MbfOO4lOsxdXLEvuC6ePoGs9H1X9oCLyq6+NVN0MKqD+ydxyg==} - engines: {node: ^20.17.0 || >=22.9.0} - hpack.js@2.1.6: resolution: {integrity: sha512-zJxVehUdMGIKsRaNt7apO2Gqp0BdqW5yaiGHXXmbpvxgBYVZnAql+BJb4RO5ad2MgpbZKn5G6nMnegrH1FcNYQ==} @@ -6060,10 +5924,6 @@ packages: ieee754@1.2.1: resolution: {integrity: sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==} - ignore-walk@8.0.0: - resolution: {integrity: sha512-FCeMZT4NiRQGh+YkeKMtWrOmBgWjHjMJ26WQWrRQyoyzqevdaGSakUaJW5xQYmjLlUVk2qUnCjYVBax9EKKg8A==} - engines: {node: ^20.17.0 || >=22.9.0} - ignore@5.3.2: resolution: {integrity: sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==} engines: {node: '>= 4'} @@ -6099,14 +5959,6 @@ packages: inherits@2.0.4: resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==} - ini@6.0.0: - resolution: {integrity: sha512-IBTdIkzZNOpqm7q3dRqJvMaldXjDHWkEDfrwGEQTs5eaQMWV+djAhR+wahyNNMAa+qpbDUhBMVt4ZKNwpPm7xQ==} - engines: {node: ^20.17.0 || >=22.9.0} - - ini@7.0.0: - resolution: {integrity: sha512-ifK0CgjALofS5bkrcTy4RaQ9Vx2Knf/eLeIO+NaswQEpH1UblrtTSCIvN71qQDMq0PeQ/SSPojvEJp9vvvfr+w==} - engines: {node: ^22.22.2 || ^24.15.0 || >=26.0.0} - injection-js@2.6.1: resolution: {integrity: sha512-dbR5bdhi7TWDoCye9cByZqeg/gAfamm8Vu3G1KZOTYkOif8WkuM8CD0oeDPtZYMzT5YH76JAFB7bkmyY9OJi2A==} @@ -6453,10 +6305,6 @@ packages: json-parse-even-better-errors@2.3.1: resolution: {integrity: sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==} - json-parse-even-better-errors@5.0.0: - resolution: {integrity: sha512-ZF1nxZ28VhQouRWhUcVlUIN3qwSgPuswK05s/HIaoetAoE/9tngVmCHjSxmSQPav1nd+lPtTL0YZ/2AFdR/iYQ==} - engines: {node: ^20.17.0 || >=22.9.0} - json-schema-traverse@0.4.1: resolution: {integrity: sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==} @@ -6715,10 +6563,6 @@ packages: resolution: {integrity: sha512-IfpFq6UM39dUNiphpA6uDezNx/AvWyhwfICWPR3t1VspkgkMZrL+Rk1RbN1bx+aeNYwOrqGJgEgV3yotk+ZUVw==} engines: {node: '>=18'} - make-fetch-happen@15.0.6: - resolution: {integrity: sha512-Je0fLJ0F5atA7F+eIlLzk+Wkcl57JDf4kf+EW8xiP5E31xOQxkIxTbgf1Oi1Lw9tRI9UEMRdI5Vz2xTzoNU1Jw==} - engines: {node: ^20.17.0 || >=22.9.0} - math-intrinsics@1.1.0: resolution: {integrity: sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==} engines: {node: '>= 0.4'} @@ -6835,38 +6679,10 @@ packages: minimist@1.2.8: resolution: {integrity: sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==} - minipass-collect@2.0.1: - resolution: {integrity: sha512-D7V8PO9oaz7PWGLbCACuI1qEOsq7UKfLotx/C0Aet43fCUB/wfQ7DYeq2oR/svFJGYDHPr38SHATeaj/ZoKHKw==} - engines: {node: '>=16 || 14 >=14.17'} - - minipass-fetch@5.0.2: - resolution: {integrity: sha512-2d0q2a8eCi2IRg/IGubCNRJoYbA1+YPXAzQVRFmB45gdGZafyivnZ5YSEfo3JikbjGxOdntGFvBQGqaSMXlAFQ==} - engines: {node: ^20.17.0 || >=22.9.0} - - minipass-flush@1.0.7: - resolution: {integrity: sha512-TbqTz9cUwWyHS2Dy89P3ocAGUGxKjjLuR9z8w4WUTGAVgEj17/4nhgo2Du56i0Fm3Pm30g4iA8Lcqctc76jCzA==} - engines: {node: '>= 8'} - - minipass-pipeline@1.2.4: - resolution: {integrity: sha512-xuIq7cIOt09RPRJ19gdi4b+RiNvDFYe5JH+ggNvBqGqpQXcru3PcRmOZuHBKWK1Txf9+cQ+HMVN4d6z46LZP7A==} - engines: {node: '>=8'} - - minipass-sized@2.0.0: - resolution: {integrity: sha512-zSsHhto5BcUVM2m1LurnXY6M//cGhVaegT71OfOXoprxT6o780GZd792ea6FfrQkuU4usHZIUczAQMRUE2plzA==} - engines: {node: '>=8'} - - minipass@3.3.6: - resolution: {integrity: sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==} - engines: {node: '>=8'} - minipass@7.1.3: resolution: {integrity: sha512-tEBHqDnIoM/1rXME1zgka9g6Q2lcoCkxHLuc7ODJ5BxbP5d4c2Z5cGgtXAku59200Cx7diuHTOYfSBD8n6mm8A==} engines: {node: '>=16 || 14 >=14.17'} - minizlib@3.1.0: - resolution: {integrity: sha512-KZxYo1BUkWD2TVFLr0MQoM8vUUigWD3LlD83a/75BqC+4qE0Hb1Vo5v1FgcfaNXvfXzr+5EhQ6ing/CaBijTlw==} - engines: {node: '>= 18'} - mitt@1.2.0: resolution: {integrity: sha512-r6lj77KlwqLhIUku9UWYes7KJtsczvolZkzp8hbaDPPaE24OmWl5s539Mytlj22siEQKosZ26qCBgda2PKwoJw==} @@ -7008,20 +6824,10 @@ packages: resolution: {integrity: sha512-LA4ZjwlnUblHVgq0oBF3Jl/6h/Nvs5fzBLwdEF4nuxnFdsfajde4WfxtJr3CaiH+F6ewcIB/q4jQ4UzPyid+CQ==} hasBin: true - node-gyp@12.4.0: - resolution: {integrity: sha512-OMcPNvqTCFUnNaBlmdgq+lfNqY7gTiSmNRDjY3uAXRyudeKZEZxu3CLtjMQrx4zZxCX2b/mpNqTtwuCJgXhHkw==} - engines: {node: ^20.17.0 || >=22.9.0} - hasBin: true - node-releases@2.0.47: resolution: {integrity: sha512-Uzmd6LXpouKo8EUK68IjH4+E01w/hXyV3R3g/geCJo+rXLNfh1xucB+LOzYEOQPSiUK3h/xZf0cQGcSsmyL2Og==} engines: {node: '>=18'} - nopt@9.0.0: - resolution: {integrity: sha512-Zhq3a+yFKrYwSBluL4H9XP3m3y5uvQkB/09CwDruCiRmR/UJYnn9W4R48ry0uGC70aeTPKLynBtscP9efFFcPw==} - engines: {node: ^20.17.0 || >=22.9.0} - hasBin: true - normalize-path@3.0.0: resolution: {integrity: sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==} engines: {node: '>=0.10.0'} @@ -7030,38 +6836,10 @@ packages: resolution: {integrity: sha512-DlL+XwOy3NxAQ8xuC0okPgK46iuVNAK01YN7RueYBqqFeGsBjV9XmCAzAdgt+667bCl5kPh9EqKKDwnaPG1I7A==} engines: {node: '>=10'} - npm-bundled@5.0.0: - resolution: {integrity: sha512-JLSpbzh6UUXIEoqPsYBvVNVmyrjVZ1fzEFbqxKkTJQkWBO3xFzFT+KDnSKQWwOQNbuWRwt5LSD6HOTLGIWzfrw==} - engines: {node: ^20.17.0 || >=22.9.0} - - npm-install-checks@8.0.0: - resolution: {integrity: sha512-ScAUdMpyzkbpxoNekQ3tNRdFI8SJ86wgKZSQZdUxT+bj0wVFpsEMWnkXP0twVe1gJyNF5apBWDJhhIbgrIViRA==} - engines: {node: ^20.17.0 || >=22.9.0} - - npm-normalize-package-bin@5.0.0: - resolution: {integrity: sha512-CJi3OS4JLsNMmr2u07OJlhcrPxCeOeP/4xq67aWNai6TNWWbTrlNDgl8NcFKVlcBKp18GPj+EzbNIgrBfZhsag==} - engines: {node: ^20.17.0 || >=22.9.0} - - npm-package-arg@13.0.2: - resolution: {integrity: sha512-IciCE3SY3uE84Ld8WZU23gAPPV9rIYod4F+rc+vJ7h7cwAJt9Vk6TVsK60ry7Uj3SRS3bqRRIGuTp9YVlk6WNA==} - engines: {node: ^20.17.0 || >=22.9.0} - npm-package-arg@14.0.0: resolution: {integrity: sha512-69XQh3k+dtGa1p+7RaR57IuG3rCko96xr/nUfN4yDYBXbTYICiWcOpsFKLN2GtGE9cyIljE+f1exnaYt9MvM+Q==} engines: {node: ^22.22.2 || ^24.15.0 || >=26.0.0} - npm-packlist@10.0.4: - resolution: {integrity: sha512-uMW73iajD8hiH4ZBxEV3HC+eTnppIqwakjOYuvgddnalIw2lJguKviK1pcUJDlIWm1wSJkchpDZDSVVsZEYRng==} - engines: {node: ^20.17.0 || >=22.9.0} - - npm-pick-manifest@11.0.3: - resolution: {integrity: sha512-buzyCfeoGY/PxKqmBqn1IUJrZnUi1VVJTdSSRPGI60tJdUhUoSQFhs0zycJokDdOznQentgrpf8LayEHyyYlqQ==} - engines: {node: ^20.17.0 || >=22.9.0} - - npm-registry-fetch@19.1.1: - resolution: {integrity: sha512-TakBap6OM1w0H73VZVDf44iFXsOS3h+L4wVMXmbWOQroZgFhMch0juN6XSzBNlD965yIKvWg2dfu7NSiaYLxtw==} - engines: {node: ^20.17.0 || >=22.9.0} - nth-check@2.1.1: resolution: {integrity: sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==} @@ -7177,10 +6955,6 @@ packages: resolution: {integrity: sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==} engines: {node: '>=10'} - p-map@7.0.4: - resolution: {integrity: sha512-tkAQEw8ysMzmkhgw8k+1U/iPhWNhykKnSk4Rd5zLoPJCuJaGRPo6YposrZgaxHKzDHdDWWZvE/Sk7hsL2X/CpQ==} - engines: {node: '>=18'} - p-queue@6.6.2: resolution: {integrity: sha512-RwFpb72c/BhQLEXIZ5K2e+AhgNVmIejGlTgiB9MzZ0e93GRvqZ7uSi0dvRF7/XIXDeNkra2fNHBxTyPDGySpjQ==} engines: {node: '>=8'} @@ -7200,11 +6974,6 @@ packages: package-json-from-dist@1.0.1: resolution: {integrity: sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==} - pacote@21.5.1: - resolution: {integrity: sha512-KvcJ9iy3crysCsgqc4+PknH/w6jkrp8JN36mpZBPwNaDRwTfMZD37YzRazNstiZUOhuF5pno9f78n9mEJBavwg==} - engines: {node: ^20.17.0 || >=22.9.0} - hasBin: true - pako@0.2.9: resolution: {integrity: sha512-NUcwaKxUxWrZLpDG+z/xZaCgQITkA/Dv4V/T6bw7VON6l1Xz/VnrBqrYjZQ12TamKHzITTfOEIYUj48y2KXImA==} @@ -7415,10 +7184,6 @@ packages: engines: {node: '>=14'} hasBin: true - proc-log@6.1.0: - resolution: {integrity: sha512-iG+GYldRf2BQ0UDUAd6JQ/RwzaQy6mXmsk/IzlYyal4A4SNFw54MeH4/tLkF4I5WoWG9SQwuqWzS99jaFQHBuQ==} - engines: {node: ^20.17.0 || >=22.9.0} - proc-log@7.0.0: resolution: {integrity: sha512-FYgfaA69XZ93zaXLoMNQ+ViDXGGBgR8aLh03txzcFhV+9xOXx7+8DLCULrKKpR9+GsH9ZfHm82aSUPpozX0Ztg==} engines: {node: ^22.22.2 || ^24.15.0 || >=26.0.0} @@ -7894,10 +7659,6 @@ packages: resolution: {integrity: sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==} engines: {node: '>=14'} - sigstore@4.1.1: - resolution: {integrity: sha512-endqECJkfhozrXMK5ngu/UAA0xVcVEFdnHJCElGaExypjW+HK5i6zu3NteLoaX/iFbRUbC3+DjttQs0GARr+5w==} - engines: {node: ^20.17.0 || >=22.9.0} - slash@3.0.0: resolution: {integrity: sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==} engines: {node: '>=8'} @@ -7910,10 +7671,6 @@ packages: resolution: {integrity: sha512-stxByr12oeeOyY2BlviTNQlYV5xOj47GirPr4yA1hE9JCtxfQN0+tVbkxwCtYDQWhEKWFHsEK48ORg5jrouCAg==} engines: {node: '>=20'} - smart-buffer@4.2.0: - resolution: {integrity: sha512-94hK0Hh8rPqQl2xXc3HsaBoOXKV20MToPkcXvwbISWLEs+64sBq5kFgn2kJDHb1Pry9yrP0dxrCI9RRci7RXKg==} - engines: {node: '>= 6.0.0', npm: '>= 3.0.0'} - socket.io-adapter@2.5.7: resolution: {integrity: sha512-e0LyK91f3cUxTmv95/KzoLg47+zF+s/sbxRGDNsyG4dmIP8ZSX8ax6byOxfJXeNNtS/8AZlfD+uP7gBeR7DLlg==} @@ -7932,14 +7689,6 @@ packages: sockjs@0.3.24: resolution: {integrity: sha512-GJgLTZ7vYb/JtPSSZ10hsOYIvEYsjbNU+zPdIHcUaWVNUEPivzxku31865sSSud0Da0W4lEeOPlmw93zLQchuQ==} - socks-proxy-agent@8.0.5: - resolution: {integrity: sha512-HehCEsotFqbPW9sJ8WVYB6UbmIMv7kUUORIF2Nncq4VQvBfNBLibW9YZR5dlYCSUhwcD628pRllm7n+E+YTzJw==} - engines: {node: '>= 14'} - - socks@2.8.9: - resolution: {integrity: sha512-LJhUYUvItdQ0LkJTmPeaEObWXAqFyfmP85x0tch/ez9cahmhlBBLbIqDFnvBnUJGagb0JbIQrkBs1wJ+yRYpEw==} - engines: {node: '>= 10.0.0', npm: '>= 3.0.0'} - sonic-boom@3.8.1: resolution: {integrity: sha512-y4Z8LCDBuum+PBP3lSV7RHrXscqksve/bi0as7mhwVnBW+/wUqKT/2Kb7um8yqcFy0duYbbPxzt89Zy2nOCaxg==} @@ -7973,9 +7722,6 @@ packages: spdx-expression-parse@3.0.1: resolution: {integrity: sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==} - spdx-expression-parse@4.0.0: - resolution: {integrity: sha512-Clya5JIij/7C6bRR22+tnGXbc4VKlibKSVj2iHvVeX5iMW7s1SIQlqu699JkODJJIhh/pUu8L0/VLh8xflD+LQ==} - spdx-expression-validate@2.0.0: resolution: {integrity: sha512-b3wydZLM+Tc6CFvaRDBOF9d76oGIHNCLYFeHbftFXUWjnfZWganmDmvtM5sm1cRwJc/VDBMLyGGrsLFd1vOxbg==} @@ -8008,10 +7754,6 @@ packages: resolution: {integrity: sha512-bSf16tAFkGeRlUNDjXu8FzaMQt6g2HZJrun7mtMbIPOddxt3GLMSz5VWUWcqTJUPfLEaDIepGxv+bYQW49596A==} engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} - ssri@13.0.1: - resolution: {integrity: sha512-QUiRf1+u9wPTL/76GTYlKttDEBWV1ga9ZXW8BG6kfdeyyM8LGPix9gROyg9V2+P0xNyF3X2Go526xKFdMZrHSQ==} - engines: {node: ^20.17.0 || >=22.9.0} - stack-trace@0.0.10: resolution: {integrity: sha512-KGzahc7puUKkzyMt+IqAep+TVNbKP+k2Lmwhub39m1AsTSkaDutx56aDCo+HLDzf/D26BIHTJWNiTG1KAJiQCg==} @@ -8147,10 +7889,6 @@ packages: tar-stream@3.2.0: resolution: {integrity: sha512-ojzvCvVaNp6aOTFmG7jaRD0meowIAuPc3cMMhSgKiVWws1GyHbGd/xvnyuRKcKlMpt3qvxx6r0hreCNITP9hIg==} - tar@7.5.16: - resolution: {integrity: sha512-56adEpPMouktRlBLXiaYFFzZ/3+JXa8P9n7WbR+ibIjtviN55mEaOkiysCnPnWm+7kkui1Dn8J9l+g6zV8731w==} - engines: {node: '>=18'} - teeny-request@10.1.3: resolution: {integrity: sha512-5yDliI1uWkYPo7W+Zvrxg6YmoWuj5iC5EydewqrRTvc68nyMTZhlPPlLg6cptUGfbQAb+N9XDPDPzF6N081lug==} engines: {node: '>=18'} @@ -8326,10 +8064,6 @@ packages: resolution: {integrity: sha512-axr3IdNuVIxnaK5XGEUFTu3YmAQ6lllgrvqfEoR16g/HGnYY/6We4oWENtAnzK6/LpJ2ur9PAb80RBt7/U4ugw==} engines: {node: '>= 6.0.0'} - tuf-js@4.1.0: - resolution: {integrity: sha512-50QV99kCKH5P/Vs4E2Gzp7BopNV+KzTXqWeaxrfu5IQJBOULRsTIS9seSsOVT8ZnGXzCyx55nYWAi4qJzpZKEQ==} - engines: {node: ^20.17.0 || >=22.9.0} - tunnel-agent@0.6.0: resolution: {integrity: sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w==} @@ -8493,10 +8227,6 @@ packages: deprecated: uuid@10 and below is no longer supported. For ESM codebases, update to uuid@latest. For CommonJS codebases, use uuid@11 (but be aware this version will likely be deprecated in 2028). hasBin: true - validate-npm-package-name@7.0.2: - resolution: {integrity: sha512-hVDIBwsRruT73PbK7uP5ebUt+ezEtCmzZz3F59BSr2F6OVFnJ/6h8liuvdLrQ88Xmnk6/+xGGuq+pG9WwTuy3A==} - engines: {node: ^20.17.0 || >=22.9.0} - validate-npm-package-name@8.0.0: resolution: {integrity: sha512-SCv6OOV6Xj2/3cXy3dGmADluJTNcL3o7hZAglNPTe+WYuEuvxgJzxPrSDLZhF+CwyQOubqgecjMmTJGMVLWjYQ==} engines: {node: ^22.22.2 || ^24.15.0 || >=26.0.0} @@ -8752,11 +8482,6 @@ packages: engines: {node: '>= 8'} hasBin: true - which@6.0.1: - resolution: {integrity: sha512-oGLe46MIrCRqX7ytPUf66EAYvdeMIZYn3WaocqqKZAxrBpkqHfL/qvTyJ/bTk5+AqHCjXmrv3CEWgy368zhRUg==} - engines: {node: ^20.17.0 || >=22.9.0} - hasBin: true - which@7.0.0: resolution: {integrity: sha512-RancgH2dmbLdHl6LRhEqvklWMgl/Hdnun0Y90KhBOLkMefg8Qa7/Zel8Sm+8HEcP6DEjzsWzpkuBQEZok58isA==} engines: {node: ^22.22.2 || ^24.15.0 || >=26.0.0} @@ -8854,13 +8579,6 @@ packages: yallist@3.1.1: resolution: {integrity: sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==} - yallist@4.0.0: - resolution: {integrity: sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==} - - yallist@5.0.0: - resolution: {integrity: sha512-YgvUTfwqyc7UXVMrB+SImsVYSmTS8X/tSrtdNZMImM+n7+QTriRXyXim0mBrTXNeqzVF0KWGgHPeiyViFFrNDw==} - engines: {node: '>=18'} - yaml@2.9.0: resolution: {integrity: sha512-2AvhNX3mb8zd6Zy7INTtSpl1F15HW6Wnqj0srWlkKLcpYl/gMIMJiyuGq2KeI2YFxUPjdlB+3Lc10seMLtL4cA==} engines: {node: '>= 14.6'} @@ -9042,7 +8760,7 @@ snapshots: '@angular/compiler-cli@22.1.0-next.0(@angular/compiler@22.1.0-next.0)(typescript@6.0.3)': dependencies: '@angular/compiler': 22.1.0-next.0 - '@babel/core': 7.29.7 + '@babel/core': 7.29.7(supports-color@10.2.2) '@jridgewell/sourcemap-codec': 1.5.5 chokidar: 5.0.0 convert-source-map: 1.9.0 @@ -9081,7 +8799,7 @@ snapshots: dependencies: '@angular/compiler': 22.1.0-next.0 '@angular/compiler-cli': 22.1.0-next.0(@angular/compiler@22.1.0-next.0)(typescript@6.0.3) - '@babel/core': 7.29.7 + '@babel/core': 7.29.7(supports-color@10.2.2) '@types/babel__core': 7.20.5 tinyglobby: 0.2.17 yargs: 18.0.0 @@ -9218,7 +8936,7 @@ snapshots: '@babel/compat-data@7.29.7': {} - '@babel/core@7.29.7': + '@babel/core@7.29.7(supports-color@10.2.2)': dependencies: '@babel/code-frame': 7.29.7 '@babel/generator': 7.29.7 @@ -9260,7 +8978,7 @@ snapshots: '@babel/helper-create-class-features-plugin@7.29.7(@babel/core@7.29.7)': dependencies: - '@babel/core': 7.29.7 + '@babel/core': 7.29.7(supports-color@10.2.2) '@babel/helper-annotate-as-pure': 7.29.7 '@babel/helper-member-expression-to-functions': 7.29.7 '@babel/helper-optimise-call-expression': 7.29.7 @@ -9273,14 +8991,14 @@ snapshots: '@babel/helper-create-regexp-features-plugin@7.29.7(@babel/core@7.29.7)': dependencies: - '@babel/core': 7.29.7 + '@babel/core': 7.29.7(supports-color@10.2.2) '@babel/helper-annotate-as-pure': 7.29.7 regexpu-core: 6.4.0 semver: 6.3.1 - '@babel/helper-define-polyfill-provider@0.6.8(@babel/core@7.29.7)': + '@babel/helper-define-polyfill-provider@0.6.8(@babel/core@7.29.7)(supports-color@10.2.2)': dependencies: - '@babel/core': 7.29.7 + '@babel/core': 7.29.7(supports-color@10.2.2) '@babel/helper-compilation-targets': 7.29.7 '@babel/helper-plugin-utils': 7.29.7 debug: 4.4.3(supports-color@10.2.2) @@ -9307,7 +9025,7 @@ snapshots: '@babel/helper-module-transforms@7.29.7(@babel/core@7.29.7)': dependencies: - '@babel/core': 7.29.7 + '@babel/core': 7.29.7(supports-color@10.2.2) '@babel/helper-module-imports': 7.29.7 '@babel/helper-validator-identifier': 7.29.7 '@babel/traverse': 7.29.7 @@ -9322,7 +9040,7 @@ snapshots: '@babel/helper-remap-async-to-generator@7.29.7(@babel/core@7.29.7)': dependencies: - '@babel/core': 7.29.7 + '@babel/core': 7.29.7(supports-color@10.2.2) '@babel/helper-annotate-as-pure': 7.29.7 '@babel/helper-wrap-function': 7.29.7 '@babel/traverse': 7.29.7 @@ -9331,7 +9049,7 @@ snapshots: '@babel/helper-replace-supers@7.29.7(@babel/core@7.29.7)': dependencies: - '@babel/core': 7.29.7 + '@babel/core': 7.29.7(supports-color@10.2.2) '@babel/helper-member-expression-to-functions': 7.29.7 '@babel/helper-optimise-call-expression': 7.29.7 '@babel/traverse': 7.29.7 @@ -9374,7 +9092,7 @@ snapshots: '@babel/plugin-bugfix-firefox-class-in-computed-class-key@7.29.7(@babel/core@7.29.7)': dependencies: - '@babel/core': 7.29.7 + '@babel/core': 7.29.7(supports-color@10.2.2) '@babel/helper-plugin-utils': 7.29.7 '@babel/traverse': 7.29.7 transitivePeerDependencies: @@ -9382,17 +9100,17 @@ snapshots: '@babel/plugin-bugfix-safari-class-field-initializer-scope@7.29.7(@babel/core@7.29.7)': dependencies: - '@babel/core': 7.29.7 + '@babel/core': 7.29.7(supports-color@10.2.2) '@babel/helper-plugin-utils': 7.29.7 '@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression@7.29.7(@babel/core@7.29.7)': dependencies: - '@babel/core': 7.29.7 + '@babel/core': 7.29.7(supports-color@10.2.2) '@babel/helper-plugin-utils': 7.29.7 '@babel/plugin-bugfix-safari-rest-destructuring-rhs-array@7.29.7(@babel/core@7.29.7)': dependencies: - '@babel/core': 7.29.7 + '@babel/core': 7.29.7(supports-color@10.2.2) '@babel/helper-plugin-utils': 7.29.7 '@babel/helper-skip-transparent-expression-wrappers': 7.29.7 transitivePeerDependencies: @@ -9400,7 +9118,7 @@ snapshots: '@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining@7.29.7(@babel/core@7.29.7)': dependencies: - '@babel/core': 7.29.7 + '@babel/core': 7.29.7(supports-color@10.2.2) '@babel/helper-plugin-utils': 7.29.7 '@babel/helper-skip-transparent-expression-wrappers': 7.29.7 '@babel/plugin-transform-optional-chaining': 7.29.7(@babel/core@7.29.7) @@ -9409,7 +9127,7 @@ snapshots: '@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly@7.29.7(@babel/core@7.29.7)': dependencies: - '@babel/core': 7.29.7 + '@babel/core': 7.29.7(supports-color@10.2.2) '@babel/helper-plugin-utils': 7.29.7 '@babel/traverse': 7.29.7 transitivePeerDependencies: @@ -9417,32 +9135,32 @@ snapshots: '@babel/plugin-proposal-private-property-in-object@7.21.0-placeholder-for-preset-env.2(@babel/core@7.29.7)': dependencies: - '@babel/core': 7.29.7 + '@babel/core': 7.29.7(supports-color@10.2.2) '@babel/plugin-syntax-import-assertions@7.29.7(@babel/core@7.29.7)': dependencies: - '@babel/core': 7.29.7 + '@babel/core': 7.29.7(supports-color@10.2.2) '@babel/helper-plugin-utils': 7.29.7 '@babel/plugin-syntax-import-attributes@7.29.7(@babel/core@7.29.7)': dependencies: - '@babel/core': 7.29.7 + '@babel/core': 7.29.7(supports-color@10.2.2) '@babel/helper-plugin-utils': 7.29.7 '@babel/plugin-syntax-unicode-sets-regex@7.18.6(@babel/core@7.29.7)': dependencies: - '@babel/core': 7.29.7 + '@babel/core': 7.29.7(supports-color@10.2.2) '@babel/helper-create-regexp-features-plugin': 7.29.7(@babel/core@7.29.7) '@babel/helper-plugin-utils': 7.29.7 '@babel/plugin-transform-arrow-functions@7.29.7(@babel/core@7.29.7)': dependencies: - '@babel/core': 7.29.7 + '@babel/core': 7.29.7(supports-color@10.2.2) '@babel/helper-plugin-utils': 7.29.7 '@babel/plugin-transform-async-generator-functions@7.29.7(@babel/core@7.29.7)': dependencies: - '@babel/core': 7.29.7 + '@babel/core': 7.29.7(supports-color@10.2.2) '@babel/helper-plugin-utils': 7.29.7 '@babel/helper-remap-async-to-generator': 7.29.7(@babel/core@7.29.7) '@babel/traverse': 7.29.7 @@ -9451,7 +9169,7 @@ snapshots: '@babel/plugin-transform-async-to-generator@7.29.7(@babel/core@7.29.7)': dependencies: - '@babel/core': 7.29.7 + '@babel/core': 7.29.7(supports-color@10.2.2) '@babel/helper-module-imports': 7.29.7 '@babel/helper-plugin-utils': 7.29.7 '@babel/helper-remap-async-to-generator': 7.29.7(@babel/core@7.29.7) @@ -9460,17 +9178,17 @@ snapshots: '@babel/plugin-transform-block-scoped-functions@7.29.7(@babel/core@7.29.7)': dependencies: - '@babel/core': 7.29.7 + '@babel/core': 7.29.7(supports-color@10.2.2) '@babel/helper-plugin-utils': 7.29.7 '@babel/plugin-transform-block-scoping@7.29.7(@babel/core@7.29.7)': dependencies: - '@babel/core': 7.29.7 + '@babel/core': 7.29.7(supports-color@10.2.2) '@babel/helper-plugin-utils': 7.29.7 '@babel/plugin-transform-class-properties@7.29.7(@babel/core@7.29.7)': dependencies: - '@babel/core': 7.29.7 + '@babel/core': 7.29.7(supports-color@10.2.2) '@babel/helper-create-class-features-plugin': 7.29.7(@babel/core@7.29.7) '@babel/helper-plugin-utils': 7.29.7 transitivePeerDependencies: @@ -9478,7 +9196,7 @@ snapshots: '@babel/plugin-transform-class-static-block@7.29.7(@babel/core@7.29.7)': dependencies: - '@babel/core': 7.29.7 + '@babel/core': 7.29.7(supports-color@10.2.2) '@babel/helper-create-class-features-plugin': 7.29.7(@babel/core@7.29.7) '@babel/helper-plugin-utils': 7.29.7 transitivePeerDependencies: @@ -9486,7 +9204,7 @@ snapshots: '@babel/plugin-transform-classes@7.29.7(@babel/core@7.29.7)': dependencies: - '@babel/core': 7.29.7 + '@babel/core': 7.29.7(supports-color@10.2.2) '@babel/helper-annotate-as-pure': 7.29.7 '@babel/helper-compilation-targets': 7.29.7 '@babel/helper-globals': 7.29.7 @@ -9498,13 +9216,13 @@ snapshots: '@babel/plugin-transform-computed-properties@7.29.7(@babel/core@7.29.7)': dependencies: - '@babel/core': 7.29.7 + '@babel/core': 7.29.7(supports-color@10.2.2) '@babel/helper-plugin-utils': 7.29.7 '@babel/template': 7.29.7 '@babel/plugin-transform-destructuring@7.29.7(@babel/core@7.29.7)': dependencies: - '@babel/core': 7.29.7 + '@babel/core': 7.29.7(supports-color@10.2.2) '@babel/helper-plugin-utils': 7.29.7 '@babel/traverse': 7.29.7 transitivePeerDependencies: @@ -9512,29 +9230,29 @@ snapshots: '@babel/plugin-transform-dotall-regex@7.29.7(@babel/core@7.29.7)': dependencies: - '@babel/core': 7.29.7 + '@babel/core': 7.29.7(supports-color@10.2.2) '@babel/helper-create-regexp-features-plugin': 7.29.7(@babel/core@7.29.7) '@babel/helper-plugin-utils': 7.29.7 '@babel/plugin-transform-duplicate-keys@7.29.7(@babel/core@7.29.7)': dependencies: - '@babel/core': 7.29.7 + '@babel/core': 7.29.7(supports-color@10.2.2) '@babel/helper-plugin-utils': 7.29.7 '@babel/plugin-transform-duplicate-named-capturing-groups-regex@7.29.7(@babel/core@7.29.7)': dependencies: - '@babel/core': 7.29.7 + '@babel/core': 7.29.7(supports-color@10.2.2) '@babel/helper-create-regexp-features-plugin': 7.29.7(@babel/core@7.29.7) '@babel/helper-plugin-utils': 7.29.7 '@babel/plugin-transform-dynamic-import@7.29.7(@babel/core@7.29.7)': dependencies: - '@babel/core': 7.29.7 + '@babel/core': 7.29.7(supports-color@10.2.2) '@babel/helper-plugin-utils': 7.29.7 '@babel/plugin-transform-explicit-resource-management@7.29.7(@babel/core@7.29.7)': dependencies: - '@babel/core': 7.29.7 + '@babel/core': 7.29.7(supports-color@10.2.2) '@babel/helper-plugin-utils': 7.29.7 '@babel/plugin-transform-destructuring': 7.29.7(@babel/core@7.29.7) transitivePeerDependencies: @@ -9542,17 +9260,17 @@ snapshots: '@babel/plugin-transform-exponentiation-operator@7.29.7(@babel/core@7.29.7)': dependencies: - '@babel/core': 7.29.7 + '@babel/core': 7.29.7(supports-color@10.2.2) '@babel/helper-plugin-utils': 7.29.7 '@babel/plugin-transform-export-namespace-from@7.29.7(@babel/core@7.29.7)': dependencies: - '@babel/core': 7.29.7 + '@babel/core': 7.29.7(supports-color@10.2.2) '@babel/helper-plugin-utils': 7.29.7 '@babel/plugin-transform-for-of@7.29.7(@babel/core@7.29.7)': dependencies: - '@babel/core': 7.29.7 + '@babel/core': 7.29.7(supports-color@10.2.2) '@babel/helper-plugin-utils': 7.29.7 '@babel/helper-skip-transparent-expression-wrappers': 7.29.7 transitivePeerDependencies: @@ -9560,7 +9278,7 @@ snapshots: '@babel/plugin-transform-function-name@7.29.7(@babel/core@7.29.7)': dependencies: - '@babel/core': 7.29.7 + '@babel/core': 7.29.7(supports-color@10.2.2) '@babel/helper-compilation-targets': 7.29.7 '@babel/helper-plugin-utils': 7.29.7 '@babel/traverse': 7.29.7 @@ -9569,27 +9287,27 @@ snapshots: '@babel/plugin-transform-json-strings@7.29.7(@babel/core@7.29.7)': dependencies: - '@babel/core': 7.29.7 + '@babel/core': 7.29.7(supports-color@10.2.2) '@babel/helper-plugin-utils': 7.29.7 '@babel/plugin-transform-literals@7.29.7(@babel/core@7.29.7)': dependencies: - '@babel/core': 7.29.7 + '@babel/core': 7.29.7(supports-color@10.2.2) '@babel/helper-plugin-utils': 7.29.7 '@babel/plugin-transform-logical-assignment-operators@7.29.7(@babel/core@7.29.7)': dependencies: - '@babel/core': 7.29.7 + '@babel/core': 7.29.7(supports-color@10.2.2) '@babel/helper-plugin-utils': 7.29.7 '@babel/plugin-transform-member-expression-literals@7.29.7(@babel/core@7.29.7)': dependencies: - '@babel/core': 7.29.7 + '@babel/core': 7.29.7(supports-color@10.2.2) '@babel/helper-plugin-utils': 7.29.7 '@babel/plugin-transform-modules-amd@7.29.7(@babel/core@7.29.7)': dependencies: - '@babel/core': 7.29.7 + '@babel/core': 7.29.7(supports-color@10.2.2) '@babel/helper-module-transforms': 7.29.7(@babel/core@7.29.7) '@babel/helper-plugin-utils': 7.29.7 transitivePeerDependencies: @@ -9597,7 +9315,7 @@ snapshots: '@babel/plugin-transform-modules-commonjs@7.29.7(@babel/core@7.29.7)': dependencies: - '@babel/core': 7.29.7 + '@babel/core': 7.29.7(supports-color@10.2.2) '@babel/helper-module-transforms': 7.29.7(@babel/core@7.29.7) '@babel/helper-plugin-utils': 7.29.7 transitivePeerDependencies: @@ -9605,7 +9323,7 @@ snapshots: '@babel/plugin-transform-modules-systemjs@7.29.7(@babel/core@7.29.7)': dependencies: - '@babel/core': 7.29.7 + '@babel/core': 7.29.7(supports-color@10.2.2) '@babel/helper-module-transforms': 7.29.7(@babel/core@7.29.7) '@babel/helper-plugin-utils': 7.29.7 '@babel/helper-validator-identifier': 7.29.7 @@ -9615,7 +9333,7 @@ snapshots: '@babel/plugin-transform-modules-umd@7.29.7(@babel/core@7.29.7)': dependencies: - '@babel/core': 7.29.7 + '@babel/core': 7.29.7(supports-color@10.2.2) '@babel/helper-module-transforms': 7.29.7(@babel/core@7.29.7) '@babel/helper-plugin-utils': 7.29.7 transitivePeerDependencies: @@ -9623,28 +9341,28 @@ snapshots: '@babel/plugin-transform-named-capturing-groups-regex@7.29.7(@babel/core@7.29.7)': dependencies: - '@babel/core': 7.29.7 + '@babel/core': 7.29.7(supports-color@10.2.2) '@babel/helper-create-regexp-features-plugin': 7.29.7(@babel/core@7.29.7) '@babel/helper-plugin-utils': 7.29.7 '@babel/plugin-transform-new-target@7.29.7(@babel/core@7.29.7)': dependencies: - '@babel/core': 7.29.7 + '@babel/core': 7.29.7(supports-color@10.2.2) '@babel/helper-plugin-utils': 7.29.7 '@babel/plugin-transform-nullish-coalescing-operator@7.29.7(@babel/core@7.29.7)': dependencies: - '@babel/core': 7.29.7 + '@babel/core': 7.29.7(supports-color@10.2.2) '@babel/helper-plugin-utils': 7.29.7 '@babel/plugin-transform-numeric-separator@7.29.7(@babel/core@7.29.7)': dependencies: - '@babel/core': 7.29.7 + '@babel/core': 7.29.7(supports-color@10.2.2) '@babel/helper-plugin-utils': 7.29.7 '@babel/plugin-transform-object-rest-spread@7.29.7(@babel/core@7.29.7)': dependencies: - '@babel/core': 7.29.7 + '@babel/core': 7.29.7(supports-color@10.2.2) '@babel/helper-compilation-targets': 7.29.7 '@babel/helper-plugin-utils': 7.29.7 '@babel/plugin-transform-destructuring': 7.29.7(@babel/core@7.29.7) @@ -9655,7 +9373,7 @@ snapshots: '@babel/plugin-transform-object-super@7.29.7(@babel/core@7.29.7)': dependencies: - '@babel/core': 7.29.7 + '@babel/core': 7.29.7(supports-color@10.2.2) '@babel/helper-plugin-utils': 7.29.7 '@babel/helper-replace-supers': 7.29.7(@babel/core@7.29.7) transitivePeerDependencies: @@ -9663,12 +9381,12 @@ snapshots: '@babel/plugin-transform-optional-catch-binding@7.29.7(@babel/core@7.29.7)': dependencies: - '@babel/core': 7.29.7 + '@babel/core': 7.29.7(supports-color@10.2.2) '@babel/helper-plugin-utils': 7.29.7 '@babel/plugin-transform-optional-chaining@7.29.7(@babel/core@7.29.7)': dependencies: - '@babel/core': 7.29.7 + '@babel/core': 7.29.7(supports-color@10.2.2) '@babel/helper-plugin-utils': 7.29.7 '@babel/helper-skip-transparent-expression-wrappers': 7.29.7 transitivePeerDependencies: @@ -9676,12 +9394,12 @@ snapshots: '@babel/plugin-transform-parameters@7.29.7(@babel/core@7.29.7)': dependencies: - '@babel/core': 7.29.7 + '@babel/core': 7.29.7(supports-color@10.2.2) '@babel/helper-plugin-utils': 7.29.7 '@babel/plugin-transform-private-methods@7.29.7(@babel/core@7.29.7)': dependencies: - '@babel/core': 7.29.7 + '@babel/core': 7.29.7(supports-color@10.2.2) '@babel/helper-create-class-features-plugin': 7.29.7(@babel/core@7.29.7) '@babel/helper-plugin-utils': 7.29.7 transitivePeerDependencies: @@ -9689,7 +9407,7 @@ snapshots: '@babel/plugin-transform-private-property-in-object@7.29.7(@babel/core@7.29.7)': dependencies: - '@babel/core': 7.29.7 + '@babel/core': 7.29.7(supports-color@10.2.2) '@babel/helper-annotate-as-pure': 7.29.7 '@babel/helper-create-class-features-plugin': 7.29.7(@babel/core@7.29.7) '@babel/helper-plugin-utils': 7.29.7 @@ -9698,31 +9416,31 @@ snapshots: '@babel/plugin-transform-property-literals@7.29.7(@babel/core@7.29.7)': dependencies: - '@babel/core': 7.29.7 + '@babel/core': 7.29.7(supports-color@10.2.2) '@babel/helper-plugin-utils': 7.29.7 '@babel/plugin-transform-regenerator@7.29.7(@babel/core@7.29.7)': dependencies: - '@babel/core': 7.29.7 + '@babel/core': 7.29.7(supports-color@10.2.2) '@babel/helper-plugin-utils': 7.29.7 '@babel/plugin-transform-regexp-modifiers@7.29.7(@babel/core@7.29.7)': dependencies: - '@babel/core': 7.29.7 + '@babel/core': 7.29.7(supports-color@10.2.2) '@babel/helper-create-regexp-features-plugin': 7.29.7(@babel/core@7.29.7) '@babel/helper-plugin-utils': 7.29.7 '@babel/plugin-transform-reserved-words@7.29.7(@babel/core@7.29.7)': dependencies: - '@babel/core': 7.29.7 + '@babel/core': 7.29.7(supports-color@10.2.2) '@babel/helper-plugin-utils': 7.29.7 - '@babel/plugin-transform-runtime@7.29.7(@babel/core@7.29.7)': + '@babel/plugin-transform-runtime@7.29.7(@babel/core@7.29.7)(supports-color@10.2.2)': dependencies: - '@babel/core': 7.29.7 + '@babel/core': 7.29.7(supports-color@10.2.2) '@babel/helper-module-imports': 7.29.7 '@babel/helper-plugin-utils': 7.29.7 - babel-plugin-polyfill-corejs2: 0.4.17(@babel/core@7.29.7) + babel-plugin-polyfill-corejs2: 0.4.17(@babel/core@7.29.7)(supports-color@10.2.2) babel-plugin-polyfill-corejs3: 0.13.0(@babel/core@7.29.7) babel-plugin-polyfill-regenerator: 0.6.8(@babel/core@7.29.7) semver: 6.3.1 @@ -9731,12 +9449,12 @@ snapshots: '@babel/plugin-transform-shorthand-properties@7.29.7(@babel/core@7.29.7)': dependencies: - '@babel/core': 7.29.7 + '@babel/core': 7.29.7(supports-color@10.2.2) '@babel/helper-plugin-utils': 7.29.7 '@babel/plugin-transform-spread@7.29.7(@babel/core@7.29.7)': dependencies: - '@babel/core': 7.29.7 + '@babel/core': 7.29.7(supports-color@10.2.2) '@babel/helper-plugin-utils': 7.29.7 '@babel/helper-skip-transparent-expression-wrappers': 7.29.7 transitivePeerDependencies: @@ -9744,46 +9462,46 @@ snapshots: '@babel/plugin-transform-sticky-regex@7.29.7(@babel/core@7.29.7)': dependencies: - '@babel/core': 7.29.7 + '@babel/core': 7.29.7(supports-color@10.2.2) '@babel/helper-plugin-utils': 7.29.7 '@babel/plugin-transform-template-literals@7.29.7(@babel/core@7.29.7)': dependencies: - '@babel/core': 7.29.7 + '@babel/core': 7.29.7(supports-color@10.2.2) '@babel/helper-plugin-utils': 7.29.7 '@babel/plugin-transform-typeof-symbol@7.29.7(@babel/core@7.29.7)': dependencies: - '@babel/core': 7.29.7 + '@babel/core': 7.29.7(supports-color@10.2.2) '@babel/helper-plugin-utils': 7.29.7 '@babel/plugin-transform-unicode-escapes@7.29.7(@babel/core@7.29.7)': dependencies: - '@babel/core': 7.29.7 + '@babel/core': 7.29.7(supports-color@10.2.2) '@babel/helper-plugin-utils': 7.29.7 '@babel/plugin-transform-unicode-property-regex@7.29.7(@babel/core@7.29.7)': dependencies: - '@babel/core': 7.29.7 + '@babel/core': 7.29.7(supports-color@10.2.2) '@babel/helper-create-regexp-features-plugin': 7.29.7(@babel/core@7.29.7) '@babel/helper-plugin-utils': 7.29.7 '@babel/plugin-transform-unicode-regex@7.29.7(@babel/core@7.29.7)': dependencies: - '@babel/core': 7.29.7 + '@babel/core': 7.29.7(supports-color@10.2.2) '@babel/helper-create-regexp-features-plugin': 7.29.7(@babel/core@7.29.7) '@babel/helper-plugin-utils': 7.29.7 '@babel/plugin-transform-unicode-sets-regex@7.29.7(@babel/core@7.29.7)': dependencies: - '@babel/core': 7.29.7 + '@babel/core': 7.29.7(supports-color@10.2.2) '@babel/helper-create-regexp-features-plugin': 7.29.7(@babel/core@7.29.7) '@babel/helper-plugin-utils': 7.29.7 '@babel/preset-env@7.29.7(@babel/core@7.29.7)': dependencies: '@babel/compat-data': 7.29.7 - '@babel/core': 7.29.7 + '@babel/core': 7.29.7(supports-color@10.2.2) '@babel/helper-compilation-targets': 7.29.7 '@babel/helper-plugin-utils': 7.29.7 '@babel/helper-validator-option': 7.29.7 @@ -9849,7 +9567,7 @@ snapshots: '@babel/plugin-transform-unicode-regex': 7.29.7(@babel/core@7.29.7) '@babel/plugin-transform-unicode-sets-regex': 7.29.7(@babel/core@7.29.7) '@babel/preset-modules': 0.1.6-no-external-plugins(@babel/core@7.29.7) - babel-plugin-polyfill-corejs2: 0.4.17(@babel/core@7.29.7) + babel-plugin-polyfill-corejs2: 0.4.17(@babel/core@7.29.7)(supports-color@10.2.2) babel-plugin-polyfill-corejs3: 0.14.2(@babel/core@7.29.7) babel-plugin-polyfill-regenerator: 0.6.8(@babel/core@7.29.7) core-js-compat: 3.49.0 @@ -9859,7 +9577,7 @@ snapshots: '@babel/preset-modules@0.1.6-no-external-plugins(@babel/core@7.29.7)': dependencies: - '@babel/core': 7.29.7 + '@babel/core': 7.29.7(supports-color@10.2.2) '@babel/helper-plugin-utils': 7.29.7 '@babel/types': 7.29.7 esutils: 2.0.3 @@ -10209,20 +9927,20 @@ snapshots: '@esbuild/win32-x64@0.28.1': optional: true - '@eslint-community/eslint-utils@4.9.1(eslint@10.5.0(jiti@2.7.0))': + '@eslint-community/eslint-utils@4.9.1(eslint@10.5.0(jiti@2.7.0)(supports-color@10.2.2))': dependencies: - eslint: 10.5.0(jiti@2.7.0) + eslint: 10.5.0(jiti@2.7.0)(supports-color@10.2.2) eslint-visitor-keys: 3.4.3 '@eslint-community/regexpp@4.12.2': {} - '@eslint/compat@2.1.0(eslint@10.5.0(jiti@2.7.0))': + '@eslint/compat@2.1.0(eslint@10.5.0(jiti@2.7.0)(supports-color@10.2.2))': dependencies: '@eslint/core': 1.2.1 optionalDependencies: - eslint: 10.5.0(jiti@2.7.0) + eslint: 10.5.0(jiti@2.7.0)(supports-color@10.2.2) - '@eslint/config-array@0.23.5': + '@eslint/config-array@0.23.5(supports-color@10.2.2)': dependencies: '@eslint/object-schema': 3.0.5 debug: 4.4.3(supports-color@10.2.2) @@ -10238,7 +9956,7 @@ snapshots: dependencies: '@types/json-schema': 7.0.15 - '@eslint/eslintrc@3.3.5': + '@eslint/eslintrc@3.3.5(supports-color@10.2.2)': dependencies: ajv: 6.15.0 debug: 4.4.3(supports-color@10.2.2) @@ -10252,9 +9970,9 @@ snapshots: transitivePeerDependencies: - supports-color - '@eslint/js@10.0.1(eslint@10.5.0(jiti@2.7.0))': + '@eslint/js@10.0.1(eslint@10.5.0(jiti@2.7.0)(supports-color@10.2.2))': optionalDependencies: - eslint: 10.5.0(jiti@2.7.0) + eslint: 10.5.0(jiti@2.7.0)(supports-color@10.2.2) '@eslint/object-schema@3.0.5': {} @@ -10585,8 +10303,6 @@ snapshots: '@firebase/webchannel-wrapper@1.0.6': {} - '@gar/promise-retry@1.0.3': {} - '@glideapps/ts-necessities@2.2.3': {} '@google-cloud/common@6.0.1(supports-color@10.2.2)': @@ -10836,10 +10552,6 @@ snapshots: wrap-ansi: 8.1.0 wrap-ansi-cjs: wrap-ansi@7.0.0 - '@isaacs/fs-minipass@4.0.1': - dependencies: - minipass: 7.1.3 - '@istanbuljs/schema@0.1.6': {} '@jasminejs/reporters@1.0.0': {} @@ -11038,8 +10750,8 @@ snapshots: cross-spawn: 7.0.6 eventsource: 3.0.7 eventsource-parser: 3.1.0 - express: 5.2.1 - express-rate-limit: 8.5.2(express@5.2.1) + express: 5.2.1(supports-color@10.2.2) + express-rate-limit: 8.5.2(express@5.2.1(supports-color@10.2.2)) hono: 4.12.23 jose: 6.2.3 json-schema-typed: 8.0.2 @@ -11170,62 +10882,6 @@ snapshots: '@nodelib/fs.scandir': 2.1.5 fastq: 1.20.1 - '@npmcli/agent@4.0.2': - dependencies: - agent-base: 7.1.4 - http-proxy-agent: 7.0.2(supports-color@10.2.2) - https-proxy-agent: 7.0.6(supports-color@10.2.2) - lru-cache: 11.5.1 - socks-proxy-agent: 8.0.5 - transitivePeerDependencies: - - supports-color - - '@npmcli/fs@5.0.0': - dependencies: - semver: 7.8.4 - - '@npmcli/git@7.0.2': - dependencies: - '@gar/promise-retry': 1.0.3 - '@npmcli/promise-spawn': 9.0.1 - ini: 6.0.0 - lru-cache: 11.5.1 - npm-pick-manifest: 11.0.3 - proc-log: 6.1.0 - semver: 7.8.4 - which: 6.0.1 - - '@npmcli/installed-package-contents@4.0.0': - dependencies: - npm-bundled: 5.0.0 - npm-normalize-package-bin: 5.0.0 - - '@npmcli/node-gyp@5.0.0': {} - - '@npmcli/package-json@7.0.5': - dependencies: - '@npmcli/git': 7.0.2 - glob: 13.0.6 - hosted-git-info: 9.0.3 - json-parse-even-better-errors: 5.0.0 - proc-log: 6.1.0 - semver: 7.8.4 - spdx-expression-parse: 4.0.0 - - '@npmcli/promise-spawn@9.0.1': - dependencies: - which: 6.0.1 - - '@npmcli/redact@4.0.0': {} - - '@npmcli/run-script@10.0.4': - dependencies: - '@npmcli/node-gyp': 5.0.0 - '@npmcli/package-json': 7.0.5 - '@npmcli/promise-spawn': 9.0.1 - node-gyp: 12.4.0 - proc-log: 6.1.0 - '@octokit/auth-app@8.2.0': dependencies: '@octokit/auth-oauth-app': 9.0.3 @@ -11845,38 +11501,6 @@ snapshots: '@rtsao/scc@1.1.0': {} - '@sigstore/bundle@4.0.0': - dependencies: - '@sigstore/protobuf-specs': 0.5.1 - - '@sigstore/core@3.2.1': {} - - '@sigstore/protobuf-specs@0.5.1': {} - - '@sigstore/sign@4.1.1': - dependencies: - '@gar/promise-retry': 1.0.3 - '@sigstore/bundle': 4.0.0 - '@sigstore/core': 3.2.1 - '@sigstore/protobuf-specs': 0.5.1 - make-fetch-happen: 15.0.6 - proc-log: 6.1.0 - transitivePeerDependencies: - - supports-color - - '@sigstore/tuf@4.0.2': - dependencies: - '@sigstore/protobuf-specs': 0.5.1 - tuf-js: 4.1.0 - transitivePeerDependencies: - - supports-color - - '@sigstore/verify@3.1.1': - dependencies: - '@sigstore/bundle': 4.0.0 - '@sigstore/core': 3.2.1 - '@sigstore/protobuf-specs': 0.5.1 - '@simple-libs/child-process-utils@1.0.2': dependencies: '@simple-libs/stream-utils': 1.2.0 @@ -11889,11 +11513,11 @@ snapshots: '@standard-schema/spec@1.1.0': {} - '@stylistic/eslint-plugin@5.10.0(eslint@10.5.0(jiti@2.7.0))': + '@stylistic/eslint-plugin@5.10.0(eslint@10.5.0(jiti@2.7.0)(supports-color@10.2.2))': dependencies: - '@eslint-community/eslint-utils': 4.9.1(eslint@10.5.0(jiti@2.7.0)) + '@eslint-community/eslint-utils': 4.9.1(eslint@10.5.0(jiti@2.7.0)(supports-color@10.2.2)) '@typescript-eslint/types': 8.60.1 - eslint: 10.5.0(jiti@2.7.0) + eslint: 10.5.0(jiti@2.7.0)(supports-color@10.2.2) eslint-visitor-keys: 4.2.1 espree: 10.4.0 estraverse: 5.3.0 @@ -11903,16 +11527,9 @@ snapshots: dependencies: defer-to-connect: 2.0.1 - '@tony.ganchev/eslint-plugin-header@3.4.4(eslint@10.5.0(jiti@2.7.0))': - dependencies: - eslint: 10.5.0(jiti@2.7.0) - - '@tufjs/canonical-json@2.0.0': {} - - '@tufjs/models@4.1.0': + '@tony.ganchev/eslint-plugin-header@3.4.4(eslint@10.5.0(jiti@2.7.0)(supports-color@10.2.2))': dependencies: - '@tufjs/canonical-json': 2.0.0 - minimatch: 10.2.5 + eslint: 10.5.0(jiti@2.7.0)(supports-color@10.2.2) '@tybys/wasm-util@0.10.2': dependencies: @@ -12033,8 +11650,6 @@ snapshots: dependencies: '@types/node': 22.19.20 - '@types/ini@4.1.1': {} - '@types/jasmine-reporters@2.5.3': dependencies: '@types/jasmine': 6.0.0 @@ -12081,11 +11696,6 @@ snapshots: '@types/mime@1.3.5': {} - '@types/node-fetch@2.6.13': - dependencies: - '@types/node': 22.19.20 - form-data: 4.0.5 - '@types/node@22.19.20': dependencies: undici-types: 6.21.0 @@ -12096,25 +11706,6 @@ snapshots: '@types/npm-package-arg@6.1.4': {} - '@types/npm-registry-fetch@8.0.9': - dependencies: - '@types/node': 22.19.20 - '@types/node-fetch': 2.6.13 - '@types/npm-package-arg': 6.1.4 - '@types/npmlog': 7.0.0 - '@types/ssri': 7.1.5 - - '@types/npmlog@7.0.0': - dependencies: - '@types/node': 22.19.20 - - '@types/pacote@11.1.8': - dependencies: - '@types/node': 22.19.20 - '@types/npm-registry-fetch': 8.0.9 - '@types/npmlog': 7.0.0 - '@types/ssri': 7.1.5 - '@types/parse-glob@3.0.32': {} '@types/picomatch@4.0.3': {} @@ -12172,10 +11763,6 @@ snapshots: dependencies: '@types/node': 22.19.20 - '@types/ssri@7.1.5': - dependencies: - '@types/node': 22.19.20 - '@types/stack-trace@0.0.33': {} '@types/tar-stream@3.1.4': @@ -12201,15 +11788,15 @@ snapshots: '@types/yarnpkg__lockfile@1.1.9': {} - '@typescript-eslint/eslint-plugin@8.61.0(@typescript-eslint/parser@8.61.0(eslint@10.5.0(jiti@2.7.0))(typescript@6.0.3))(eslint@10.5.0(jiti@2.7.0))(typescript@6.0.3)': + '@typescript-eslint/eslint-plugin@8.61.0(@typescript-eslint/parser@8.61.0(eslint@10.5.0(jiti@2.7.0)(supports-color@10.2.2))(supports-color@10.2.2)(typescript@6.0.3))(eslint@10.5.0(jiti@2.7.0)(supports-color@10.2.2))(supports-color@10.2.2)(typescript@6.0.3)': dependencies: '@eslint-community/regexpp': 4.12.2 - '@typescript-eslint/parser': 8.61.0(eslint@10.5.0(jiti@2.7.0))(typescript@6.0.3) + '@typescript-eslint/parser': 8.61.0(eslint@10.5.0(jiti@2.7.0)(supports-color@10.2.2))(supports-color@10.2.2)(typescript@6.0.3) '@typescript-eslint/scope-manager': 8.61.0 - '@typescript-eslint/type-utils': 8.61.0(eslint@10.5.0(jiti@2.7.0))(typescript@6.0.3) - '@typescript-eslint/utils': 8.61.0(eslint@10.5.0(jiti@2.7.0))(typescript@6.0.3) + '@typescript-eslint/type-utils': 8.61.0(eslint@10.5.0(jiti@2.7.0)(supports-color@10.2.2))(supports-color@10.2.2)(typescript@6.0.3) + '@typescript-eslint/utils': 8.61.0(eslint@10.5.0(jiti@2.7.0)(supports-color@10.2.2))(typescript@6.0.3) '@typescript-eslint/visitor-keys': 8.61.0 - eslint: 10.5.0(jiti@2.7.0) + eslint: 10.5.0(jiti@2.7.0)(supports-color@10.2.2) ignore: 7.0.5 natural-compare: 1.4.0 ts-api-utils: 2.5.0(typescript@6.0.3) @@ -12217,19 +11804,19 @@ snapshots: transitivePeerDependencies: - supports-color - '@typescript-eslint/parser@8.61.0(eslint@10.5.0(jiti@2.7.0))(typescript@6.0.3)': + '@typescript-eslint/parser@8.61.0(eslint@10.5.0(jiti@2.7.0)(supports-color@10.2.2))(supports-color@10.2.2)(typescript@6.0.3)': dependencies: '@typescript-eslint/scope-manager': 8.61.0 '@typescript-eslint/types': 8.61.0 - '@typescript-eslint/typescript-estree': 8.61.0(typescript@6.0.3) + '@typescript-eslint/typescript-estree': 8.61.0(supports-color@10.2.2)(typescript@6.0.3) '@typescript-eslint/visitor-keys': 8.61.0 debug: 4.4.3(supports-color@10.2.2) - eslint: 10.5.0(jiti@2.7.0) + eslint: 10.5.0(jiti@2.7.0)(supports-color@10.2.2) typescript: 6.0.3 transitivePeerDependencies: - supports-color - '@typescript-eslint/project-service@8.61.0(typescript@6.0.3)': + '@typescript-eslint/project-service@8.61.0(supports-color@10.2.2)(typescript@6.0.3)': dependencies: '@typescript-eslint/tsconfig-utils': 8.61.0(typescript@6.0.3) '@typescript-eslint/types': 8.61.0 @@ -12247,13 +11834,13 @@ snapshots: dependencies: typescript: 6.0.3 - '@typescript-eslint/type-utils@8.61.0(eslint@10.5.0(jiti@2.7.0))(typescript@6.0.3)': + '@typescript-eslint/type-utils@8.61.0(eslint@10.5.0(jiti@2.7.0)(supports-color@10.2.2))(supports-color@10.2.2)(typescript@6.0.3)': dependencies: '@typescript-eslint/types': 8.61.0 - '@typescript-eslint/typescript-estree': 8.61.0(typescript@6.0.3) - '@typescript-eslint/utils': 8.61.0(eslint@10.5.0(jiti@2.7.0))(typescript@6.0.3) + '@typescript-eslint/typescript-estree': 8.61.0(supports-color@10.2.2)(typescript@6.0.3) + '@typescript-eslint/utils': 8.61.0(eslint@10.5.0(jiti@2.7.0)(supports-color@10.2.2))(typescript@6.0.3) debug: 4.4.3(supports-color@10.2.2) - eslint: 10.5.0(jiti@2.7.0) + eslint: 10.5.0(jiti@2.7.0)(supports-color@10.2.2) ts-api-utils: 2.5.0(typescript@6.0.3) typescript: 6.0.3 transitivePeerDependencies: @@ -12263,9 +11850,9 @@ snapshots: '@typescript-eslint/types@8.61.0': {} - '@typescript-eslint/typescript-estree@8.61.0(typescript@6.0.3)': + '@typescript-eslint/typescript-estree@8.61.0(supports-color@10.2.2)(typescript@6.0.3)': dependencies: - '@typescript-eslint/project-service': 8.61.0(typescript@6.0.3) + '@typescript-eslint/project-service': 8.61.0(supports-color@10.2.2)(typescript@6.0.3) '@typescript-eslint/tsconfig-utils': 8.61.0(typescript@6.0.3) '@typescript-eslint/types': 8.61.0 '@typescript-eslint/visitor-keys': 8.61.0 @@ -12278,13 +11865,13 @@ snapshots: transitivePeerDependencies: - supports-color - '@typescript-eslint/utils@8.61.0(eslint@10.5.0(jiti@2.7.0))(typescript@6.0.3)': + '@typescript-eslint/utils@8.61.0(eslint@10.5.0(jiti@2.7.0)(supports-color@10.2.2))(typescript@6.0.3)': dependencies: - '@eslint-community/eslint-utils': 4.9.1(eslint@10.5.0(jiti@2.7.0)) + '@eslint-community/eslint-utils': 4.9.1(eslint@10.5.0(jiti@2.7.0)(supports-color@10.2.2)) '@typescript-eslint/scope-manager': 8.61.0 '@typescript-eslint/types': 8.61.0 - '@typescript-eslint/typescript-estree': 8.61.0(typescript@6.0.3) - eslint: 10.5.0(jiti@2.7.0) + '@typescript-eslint/typescript-estree': 8.61.0(supports-color@10.2.2)(typescript@6.0.3) + eslint: 10.5.0(jiti@2.7.0)(supports-color@10.2.2) typescript: 6.0.3 transitivePeerDependencies: - supports-color @@ -12294,7 +11881,7 @@ snapshots: '@typescript-eslint/types': 8.61.0 eslint-visitor-keys: 5.0.1 - '@verdaccio/auth@8.0.2': + '@verdaccio/auth@8.0.2(supports-color@10.2.2)': dependencies: '@verdaccio/config': 8.1.1 '@verdaccio/core': 8.1.1 @@ -12328,7 +11915,7 @@ snapshots: dependencies: lockfile: 1.0.4 - '@verdaccio/hooks@8.0.2': + '@verdaccio/hooks@8.0.2(supports-color@10.2.2)': dependencies: '@verdaccio/core': 8.1.1 '@verdaccio/logger': 8.0.2 @@ -12346,7 +11933,7 @@ snapshots: transitivePeerDependencies: - supports-color - '@verdaccio/local-storage-legacy@11.3.3': + '@verdaccio/local-storage-legacy@11.3.3(supports-color@10.2.2)': dependencies: '@verdaccio/core': 8.1.1 '@verdaccio/file-locking': 13.0.1 @@ -12385,11 +11972,11 @@ snapshots: transitivePeerDependencies: - supports-color - '@verdaccio/middleware@8.0.2': + '@verdaccio/middleware@8.0.2(supports-color@10.2.2)': dependencies: '@verdaccio/config': 8.1.1 '@verdaccio/core': 8.1.1 - '@verdaccio/url': 13.0.2 + '@verdaccio/url': 13.0.2(supports-color@10.2.2) debug: 4.4.3(supports-color@10.2.2) express: 4.22.1 express-rate-limit: 5.5.1 @@ -12398,7 +11985,7 @@ snapshots: transitivePeerDependencies: - supports-color - '@verdaccio/package-filter@13.0.2': + '@verdaccio/package-filter@13.0.2(supports-color@10.2.2)': dependencies: '@verdaccio/core': 8.1.1 debug: 4.4.3(supports-color@10.2.2) @@ -12406,7 +11993,7 @@ snapshots: transitivePeerDependencies: - supports-color - '@verdaccio/search-indexer@8.0.2': + '@verdaccio/search-indexer@8.0.2(supports-color@10.2.2)': dependencies: debug: 4.4.3(supports-color@10.2.2) fuse.js: 7.3.0 @@ -12424,10 +12011,10 @@ snapshots: '@verdaccio/streams@10.2.5': {} - '@verdaccio/tarball@13.0.2': + '@verdaccio/tarball@13.0.2(supports-color@10.2.2)': dependencies: '@verdaccio/core': 8.1.1 - '@verdaccio/url': 13.0.2 + '@verdaccio/url': 13.0.2(supports-color@10.2.2) debug: 4.4.3(supports-color@10.2.2) gunzip-maybe: 1.4.2 tar-stream: 3.1.7 @@ -12436,13 +12023,13 @@ snapshots: - react-native-b4a - supports-color - '@verdaccio/ui-theme@9.0.0-next-9.14': + '@verdaccio/ui-theme@9.0.0-next-9.14(supports-color@10.2.2)': dependencies: debug: 4.4.3(supports-color@10.2.2) transitivePeerDependencies: - supports-color - '@verdaccio/url@13.0.2': + '@verdaccio/url@13.0.2(supports-color@10.2.2)': dependencies: '@verdaccio/core': 8.1.1 debug: 4.4.3(supports-color@10.2.2) @@ -12604,8 +12191,6 @@ snapshots: jsonparse: 1.3.1 through: 2.3.8 - abbrev@4.0.0: {} - abort-controller@3.0.0: dependencies: event-target-shim: 5.0.1 @@ -12635,7 +12220,7 @@ snapshots: loader-utils: 2.0.4 regex-parser: 2.3.1 - agent-base@6.0.2: + agent-base@6.0.2(supports-color@10.2.2): dependencies: debug: 4.4.3(supports-color@10.2.2) transitivePeerDependencies: @@ -12838,40 +12423,40 @@ snapshots: babel-loader@10.1.1(@babel/core@7.29.7)(webpack@5.107.2(esbuild@0.28.1)(postcss@8.5.15)): dependencies: - '@babel/core': 7.29.7 + '@babel/core': 7.29.7(supports-color@10.2.2) find-up: 5.0.0 optionalDependencies: webpack: 5.107.2(esbuild@0.28.1)(postcss@8.5.15) - babel-plugin-polyfill-corejs2@0.4.17(@babel/core@7.29.7): + babel-plugin-polyfill-corejs2@0.4.17(@babel/core@7.29.7)(supports-color@10.2.2): dependencies: '@babel/compat-data': 7.29.7 - '@babel/core': 7.29.7 - '@babel/helper-define-polyfill-provider': 0.6.8(@babel/core@7.29.7) + '@babel/core': 7.29.7(supports-color@10.2.2) + '@babel/helper-define-polyfill-provider': 0.6.8(@babel/core@7.29.7)(supports-color@10.2.2) semver: 6.3.1 transitivePeerDependencies: - supports-color babel-plugin-polyfill-corejs3@0.13.0(@babel/core@7.29.7): dependencies: - '@babel/core': 7.29.7 - '@babel/helper-define-polyfill-provider': 0.6.8(@babel/core@7.29.7) + '@babel/core': 7.29.7(supports-color@10.2.2) + '@babel/helper-define-polyfill-provider': 0.6.8(@babel/core@7.29.7)(supports-color@10.2.2) core-js-compat: 3.49.0 transitivePeerDependencies: - supports-color babel-plugin-polyfill-corejs3@0.14.2(@babel/core@7.29.7): dependencies: - '@babel/core': 7.29.7 - '@babel/helper-define-polyfill-provider': 0.6.8(@babel/core@7.29.7) + '@babel/core': 7.29.7(supports-color@10.2.2) + '@babel/helper-define-polyfill-provider': 0.6.8(@babel/core@7.29.7)(supports-color@10.2.2) core-js-compat: 3.49.0 transitivePeerDependencies: - supports-color babel-plugin-polyfill-regenerator@0.6.8(@babel/core@7.29.7): dependencies: - '@babel/core': 7.29.7 - '@babel/helper-define-polyfill-provider': 0.6.8(@babel/core@7.29.7) + '@babel/core': 7.29.7(supports-color@10.2.2) + '@babel/helper-define-polyfill-provider': 0.6.8(@babel/core@7.29.7)(supports-color@10.2.2) transitivePeerDependencies: - supports-color @@ -12968,7 +12553,7 @@ snapshots: transitivePeerDependencies: - supports-color - body-parser@2.2.2: + body-parser@2.2.2(supports-color@10.2.2): dependencies: bytes: 3.1.2 content-type: 1.0.5 @@ -13014,24 +12599,24 @@ snapshots: fresh: 0.5.2 mitt: 1.2.0 - browser-sync-ui@3.0.4(bufferutil@4.1.0)(utf-8-validate@6.0.6): + browser-sync-ui@3.0.4(bufferutil@4.1.0)(supports-color@10.2.2)(utf-8-validate@6.0.6): dependencies: async-each-series: 0.1.1 chalk: 4.1.2 connect-history-api-fallback: 1.6.0 immutable: 3.8.3 server-destroy: 1.0.1 - socket.io-client: 4.8.3(bufferutil@4.1.0)(utf-8-validate@6.0.6) + socket.io-client: 4.8.3(bufferutil@4.1.0)(supports-color@10.2.2)(utf-8-validate@6.0.6) stream-throttle: 0.1.3 transitivePeerDependencies: - bufferutil - supports-color - utf-8-validate - browser-sync@3.0.4(bufferutil@4.1.0)(utf-8-validate@6.0.6): + browser-sync@3.0.4(bufferutil@4.1.0)(supports-color@10.2.2)(utf-8-validate@6.0.6): dependencies: browser-sync-client: 3.0.4 - browser-sync-ui: 3.0.4(bufferutil@4.1.0)(utf-8-validate@6.0.6) + browser-sync-ui: 3.0.4(bufferutil@4.1.0)(supports-color@10.2.2)(utf-8-validate@6.0.6) bs-recipes: 1.3.4 chalk: 4.1.2 chokidar: 3.6.0 @@ -13055,7 +12640,7 @@ snapshots: serve-index: 1.9.2 serve-static: 1.16.3 server-destroy: 1.0.1 - socket.io: 4.8.3(bufferutil@4.1.0)(utf-8-validate@6.0.6) + socket.io: 4.8.3(bufferutil@4.1.0)(supports-color@10.2.2)(utf-8-validate@6.0.6) ua-parser-js: 1.0.41 yargs: 17.7.2 transitivePeerDependencies: @@ -13099,19 +12684,6 @@ snapshots: bytestreamjs@2.0.1: {} - cacache@20.0.4: - dependencies: - '@npmcli/fs': 5.0.0 - fs-minipass: 3.0.3 - glob: 13.0.6 - lru-cache: 11.5.1 - minipass: 7.1.3 - minipass-collect: 2.0.1 - minipass-flush: 1.0.7 - minipass-pipeline: 1.2.4 - p-map: 7.0.4 - ssri: 13.0.1 - cacheable-lookup@6.1.0: {} cacheable-request@7.0.2: @@ -13182,8 +12754,6 @@ snapshots: dependencies: readdirp: 5.0.0 - chownr@3.0.0: {} - chrome-trace-event@1.0.4: {} chromium-bidi@16.0.1(devtools-protocol@0.0.1624250): @@ -13626,7 +13196,7 @@ snapshots: dependencies: once: 1.4.0 - engine.io-client@6.6.5(bufferutil@4.1.0)(utf-8-validate@6.0.6): + engine.io-client@6.6.5(bufferutil@4.1.0)(supports-color@10.2.2)(utf-8-validate@6.0.6): dependencies: '@socket.io/component-emitter': 3.1.2 debug: 4.4.3(supports-color@10.2.2) @@ -13640,7 +13210,7 @@ snapshots: engine.io-parser@5.2.3: {} - engine.io@6.6.8(bufferutil@4.1.0)(utf-8-validate@6.0.6): + engine.io@6.6.8(bufferutil@4.1.0)(supports-color@10.2.2)(utf-8-validate@6.0.6): dependencies: '@types/cors': 2.8.19 '@types/node': 22.19.20 @@ -13869,9 +13439,9 @@ snapshots: escape-string-regexp@4.0.0: {} - eslint-config-prettier@10.1.8(eslint@10.5.0(jiti@2.7.0)): + eslint-config-prettier@10.1.8(eslint@10.5.0(jiti@2.7.0)(supports-color@10.2.2)): dependencies: - eslint: 10.5.0(jiti@2.7.0) + eslint: 10.5.0(jiti@2.7.0)(supports-color@10.2.2) eslint-import-resolver-node@0.3.10: dependencies: @@ -13881,17 +13451,17 @@ snapshots: transitivePeerDependencies: - supports-color - eslint-module-utils@2.13.0(@typescript-eslint/parser@8.61.0(eslint@10.5.0(jiti@2.7.0))(typescript@6.0.3))(eslint-import-resolver-node@0.3.10)(eslint@10.5.0(jiti@2.7.0)): + eslint-module-utils@2.13.0(@typescript-eslint/parser@8.61.0(eslint@10.5.0(jiti@2.7.0)(supports-color@10.2.2))(supports-color@10.2.2)(typescript@6.0.3))(eslint-import-resolver-node@0.3.10)(eslint@10.5.0(jiti@2.7.0)(supports-color@10.2.2)): dependencies: debug: 3.2.7 optionalDependencies: - '@typescript-eslint/parser': 8.61.0(eslint@10.5.0(jiti@2.7.0))(typescript@6.0.3) - eslint: 10.5.0(jiti@2.7.0) + '@typescript-eslint/parser': 8.61.0(eslint@10.5.0(jiti@2.7.0)(supports-color@10.2.2))(supports-color@10.2.2)(typescript@6.0.3) + eslint: 10.5.0(jiti@2.7.0)(supports-color@10.2.2) eslint-import-resolver-node: 0.3.10 transitivePeerDependencies: - supports-color - eslint-plugin-import@2.32.0(@typescript-eslint/parser@8.61.0(eslint@10.5.0(jiti@2.7.0))(typescript@6.0.3))(eslint@10.5.0(jiti@2.7.0)): + eslint-plugin-import@2.32.0(@typescript-eslint/parser@8.61.0(eslint@10.5.0(jiti@2.7.0)(supports-color@10.2.2))(supports-color@10.2.2)(typescript@6.0.3))(eslint@10.5.0(jiti@2.7.0)(supports-color@10.2.2)): dependencies: '@rtsao/scc': 1.1.0 array-includes: 3.1.9 @@ -13900,9 +13470,9 @@ snapshots: array.prototype.flatmap: 1.3.3 debug: 3.2.7 doctrine: 2.1.0 - eslint: 10.5.0(jiti@2.7.0) + eslint: 10.5.0(jiti@2.7.0)(supports-color@10.2.2) eslint-import-resolver-node: 0.3.10 - eslint-module-utils: 2.13.0(@typescript-eslint/parser@8.61.0(eslint@10.5.0(jiti@2.7.0))(typescript@6.0.3))(eslint-import-resolver-node@0.3.10)(eslint@10.5.0(jiti@2.7.0)) + eslint-module-utils: 2.13.0(@typescript-eslint/parser@8.61.0(eslint@10.5.0(jiti@2.7.0)(supports-color@10.2.2))(supports-color@10.2.2)(typescript@6.0.3))(eslint-import-resolver-node@0.3.10)(eslint@10.5.0(jiti@2.7.0)(supports-color@10.2.2)) hasown: 2.0.4 is-core-module: 2.16.2 is-glob: 4.0.3 @@ -13914,7 +13484,7 @@ snapshots: string.prototype.trimend: 1.0.10 tsconfig-paths: 3.15.0 optionalDependencies: - '@typescript-eslint/parser': 8.61.0(eslint@10.5.0(jiti@2.7.0))(typescript@6.0.3) + '@typescript-eslint/parser': 8.61.0(eslint@10.5.0(jiti@2.7.0)(supports-color@10.2.2))(supports-color@10.2.2)(typescript@6.0.3) transitivePeerDependencies: - eslint-import-resolver-typescript - eslint-import-resolver-webpack @@ -13938,11 +13508,11 @@ snapshots: eslint-visitor-keys@5.0.1: {} - eslint@10.5.0(jiti@2.7.0): + eslint@10.5.0(jiti@2.7.0)(supports-color@10.2.2): dependencies: - '@eslint-community/eslint-utils': 4.9.1(eslint@10.5.0(jiti@2.7.0)) + '@eslint-community/eslint-utils': 4.9.1(eslint@10.5.0(jiti@2.7.0)(supports-color@10.2.2)) '@eslint-community/regexpp': 4.12.2 - '@eslint/config-array': 0.23.5 + '@eslint/config-array': 0.23.5(supports-color@10.2.2) '@eslint/config-helpers': 0.6.0 '@eslint/core': 1.2.1 '@eslint/plugin-kit': 0.7.2 @@ -14033,13 +13603,11 @@ snapshots: expect-type@1.3.0: {} - exponential-backoff@3.1.3: {} - express-rate-limit@5.5.1: {} - express-rate-limit@8.5.2(express@5.2.1): + express-rate-limit@8.5.2(express@5.2.1(supports-color@10.2.2)): dependencies: - express: 5.2.1 + express: 5.2.1(supports-color@10.2.2) ip-address: 10.2.0 express@4.22.1: @@ -14114,10 +13682,10 @@ snapshots: transitivePeerDependencies: - supports-color - express@5.2.1: + express@5.2.1(supports-color@10.2.2): dependencies: accepts: 2.0.0 - body-parser: 2.2.2 + body-parser: 2.2.2(supports-color@10.2.2) content-disposition: 1.1.0 content-type: 1.0.5 cookie: 0.7.2 @@ -14127,7 +13695,7 @@ snapshots: encodeurl: 2.0.0 escape-html: 1.0.3 etag: 1.8.1 - finalhandler: 2.1.1 + finalhandler: 2.1.1(supports-color@10.2.2) fresh: 2.0.0 http-errors: 2.0.1 merge-descriptors: 2.0.0 @@ -14138,8 +13706,8 @@ snapshots: proxy-addr: 2.0.7 qs: 6.15.2 range-parser: 1.2.1 - router: 2.2.0 - send: 1.2.1 + router: 2.2.0(supports-color@10.2.2) + send: 1.2.1(supports-color@10.2.2) serve-static: 2.2.1 statuses: 2.0.2 type-is: 2.1.0 @@ -14240,7 +13808,7 @@ snapshots: transitivePeerDependencies: - supports-color - finalhandler@2.1.1: + finalhandler@2.1.1(supports-color@10.2.2): dependencies: debug: 4.4.3(supports-color@10.2.2) encodeurl: 2.0.0 @@ -14359,10 +13927,6 @@ snapshots: jsonfile: 4.0.0 universalify: 0.1.2 - fs-minipass@3.0.3: - dependencies: - minipass: 7.1.3 - fs.realpath@1.0.0: {} fsevents@2.3.3: @@ -14643,10 +14207,6 @@ snapshots: dependencies: lru-cache: 11.5.1 - hosted-git-info@9.0.3: - dependencies: - lru-cache: 11.5.1 - hpack.js@2.1.6: dependencies: inherits: 2.0.4 @@ -14712,7 +14272,7 @@ snapshots: transitivePeerDependencies: - debug - http-proxy-middleware@4.1.1: + http-proxy-middleware@4.1.1(supports-color@10.2.2): dependencies: debug: 4.4.3(supports-color@10.2.2) httpxy: 0.5.3 @@ -14743,9 +14303,9 @@ snapshots: quick-lru: 5.1.1 resolve-alpn: 1.2.1 - https-proxy-agent@5.0.1: + https-proxy-agent@5.0.1(supports-color@10.2.2): dependencies: - agent-base: 6.0.2 + agent-base: 6.0.2(supports-color@10.2.2) debug: 4.4.3(supports-color@10.2.2) transitivePeerDependencies: - supports-color @@ -14757,7 +14317,7 @@ snapshots: transitivePeerDependencies: - supports-color - https-proxy-agent@9.1.0: + https-proxy-agent@9.1.0(supports-color@10.2.2): dependencies: agent-base: 9.0.0 debug: 4.4.3(supports-color@10.2.2) @@ -14792,10 +14352,6 @@ snapshots: ieee754@1.2.1: {} - ignore-walk@8.0.0: - dependencies: - minimatch: 10.2.5 - ignore@5.3.2: {} ignore@7.0.5: {} @@ -14821,10 +14377,6 @@ snapshots: inherits@2.0.4: {} - ini@6.0.0: {} - - ini@7.0.0: {} - injection-js@2.6.1: dependencies: tslib: 2.8.1 @@ -15039,7 +14591,7 @@ snapshots: istanbul-lib-instrument@5.2.1: dependencies: - '@babel/core': 7.29.7 + '@babel/core': 7.29.7(supports-color@10.2.2) '@babel/parser': 7.29.7 '@istanbuljs/schema': 0.1.6 istanbul-lib-coverage: 3.2.2 @@ -15049,7 +14601,7 @@ snapshots: istanbul-lib-instrument@6.0.3: dependencies: - '@babel/core': 7.29.7 + '@babel/core': 7.29.7(supports-color@10.2.2) '@babel/parser': 7.29.7 '@istanbuljs/schema': 0.1.6 istanbul-lib-coverage: 3.2.2 @@ -15063,7 +14615,7 @@ snapshots: make-dir: 4.0.0 supports-color: 7.2.0 - istanbul-lib-source-maps@4.0.1: + istanbul-lib-source-maps@4.0.1(supports-color@10.2.2): dependencies: debug: 4.4.3(supports-color@10.2.2) istanbul-lib-coverage: 3.2.2 @@ -15163,8 +14715,6 @@ snapshots: json-parse-even-better-errors@2.3.1: {} - json-parse-even-better-errors@5.0.0: {} - json-schema-traverse@0.4.1: {} json-schema-traverse@1.0.0: {} @@ -15232,33 +14782,33 @@ snapshots: dependencies: which: 1.3.1 - karma-coverage@2.2.1: + karma-coverage@2.2.1(supports-color@10.2.2): dependencies: istanbul-lib-coverage: 3.2.2 istanbul-lib-instrument: 5.2.1 istanbul-lib-report: 3.0.1 - istanbul-lib-source-maps: 4.0.1 + istanbul-lib-source-maps: 4.0.1(supports-color@10.2.2) istanbul-reports: 3.2.0 minimatch: 3.1.5 transitivePeerDependencies: - supports-color - karma-jasmine-html-reporter@2.2.0(jasmine-core@6.3.0)(karma-jasmine@5.1.0(karma@6.4.4(bufferutil@4.1.0)(utf-8-validate@6.0.6)))(karma@6.4.4(bufferutil@4.1.0)(utf-8-validate@6.0.6)): + karma-jasmine-html-reporter@2.2.0(jasmine-core@6.3.0)(karma-jasmine@5.1.0(karma@6.4.4(bufferutil@4.1.0)(supports-color@10.2.2)(utf-8-validate@6.0.6)))(karma@6.4.4(bufferutil@4.1.0)(supports-color@10.2.2)(utf-8-validate@6.0.6)): dependencies: jasmine-core: 6.3.0 - karma: 6.4.4(bufferutil@4.1.0)(utf-8-validate@6.0.6) - karma-jasmine: 5.1.0(karma@6.4.4(bufferutil@4.1.0)(utf-8-validate@6.0.6)) + karma: 6.4.4(bufferutil@4.1.0)(supports-color@10.2.2)(utf-8-validate@6.0.6) + karma-jasmine: 5.1.0(karma@6.4.4(bufferutil@4.1.0)(supports-color@10.2.2)(utf-8-validate@6.0.6)) - karma-jasmine@5.1.0(karma@6.4.4(bufferutil@4.1.0)(utf-8-validate@6.0.6)): + karma-jasmine@5.1.0(karma@6.4.4(bufferutil@4.1.0)(supports-color@10.2.2)(utf-8-validate@6.0.6)): dependencies: jasmine-core: 4.6.1 - karma: 6.4.4(bufferutil@4.1.0)(utf-8-validate@6.0.6) + karma: 6.4.4(bufferutil@4.1.0)(supports-color@10.2.2)(utf-8-validate@6.0.6) karma-source-map-support@1.4.0: dependencies: source-map-support: 0.5.21 - karma@6.4.4(bufferutil@4.1.0)(utf-8-validate@6.0.6): + karma@6.4.4(bufferutil@4.1.0)(supports-color@10.2.2)(utf-8-validate@6.0.6): dependencies: '@colors/colors': 1.5.0 body-parser: 1.20.5 @@ -15279,7 +14829,7 @@ snapshots: qjobs: 1.2.0 range-parser: 1.2.1 rimraf: 3.0.2 - socket.io: 4.8.3(bufferutil@4.1.0)(utf-8-validate@6.0.6) + socket.io: 4.8.3(bufferutil@4.1.0)(supports-color@10.2.2)(utf-8-validate@6.0.6) source-map: 0.6.1 tmp: 0.2.7 ua-parser-js: 0.7.41 @@ -15487,23 +15037,6 @@ snapshots: make-dir@5.1.0: optional: true - make-fetch-happen@15.0.6: - dependencies: - '@gar/promise-retry': 1.0.3 - '@npmcli/agent': 4.0.2 - '@npmcli/redact': 4.0.0 - cacache: 20.0.4 - http-cache-semantics: 4.2.0 - minipass: 7.1.3 - minipass-fetch: 5.0.2 - minipass-flush: 1.0.7 - minipass-pipeline: 1.2.4 - negotiator: 1.0.0 - proc-log: 6.1.0 - ssri: 13.0.1 - transitivePeerDependencies: - - supports-color - math-intrinsics@1.1.0: {} mdn-data@2.27.1: {} @@ -15596,40 +15129,8 @@ snapshots: minimist@1.2.8: {} - minipass-collect@2.0.1: - dependencies: - minipass: 7.1.3 - - minipass-fetch@5.0.2: - dependencies: - minipass: 7.1.3 - minipass-sized: 2.0.0 - minizlib: 3.1.0 - optionalDependencies: - iconv-lite: 0.7.2 - - minipass-flush@1.0.7: - dependencies: - minipass: 3.3.6 - - minipass-pipeline@1.2.4: - dependencies: - minipass: 3.3.6 - - minipass-sized@2.0.0: - dependencies: - minipass: 7.1.3 - - minipass@3.3.6: - dependencies: - yallist: 4.0.0 - minipass@7.1.3: {} - minizlib@3.1.0: - dependencies: - minipass: 7.1.3 - mitt@1.2.0: {} mitt@3.0.1: {} @@ -15772,46 +15273,12 @@ snapshots: node-gyp-build@4.8.4: {} - node-gyp@12.4.0: - dependencies: - env-paths: 2.2.1 - exponential-backoff: 3.1.3 - graceful-fs: 4.2.11 - nopt: 9.0.0 - proc-log: 6.1.0 - semver: 7.8.4 - tar: 7.5.16 - tinyglobby: 0.2.17 - undici: 6.26.0 - which: 6.0.1 - node-releases@2.0.47: {} - nopt@9.0.0: - dependencies: - abbrev: 4.0.0 - normalize-path@3.0.0: {} normalize-url@6.1.0: {} - npm-bundled@5.0.0: - dependencies: - npm-normalize-package-bin: 5.0.0 - - npm-install-checks@8.0.0: - dependencies: - semver: 7.8.4 - - npm-normalize-package-bin@5.0.0: {} - - npm-package-arg@13.0.2: - dependencies: - hosted-git-info: 9.0.3 - proc-log: 6.1.0 - semver: 7.8.4 - validate-npm-package-name: 7.0.2 - npm-package-arg@14.0.0: dependencies: hosted-git-info: 10.1.1 @@ -15819,31 +15286,6 @@ snapshots: semver: 7.8.4 validate-npm-package-name: 8.0.0 - npm-packlist@10.0.4: - dependencies: - ignore-walk: 8.0.0 - proc-log: 6.1.0 - - npm-pick-manifest@11.0.3: - dependencies: - npm-install-checks: 8.0.0 - npm-normalize-package-bin: 5.0.0 - npm-package-arg: 13.0.2 - semver: 7.8.4 - - npm-registry-fetch@19.1.1: - dependencies: - '@npmcli/redact': 4.0.0 - jsonparse: 1.3.1 - make-fetch-happen: 15.0.6 - minipass: 7.1.3 - minipass-fetch: 5.0.2 - minizlib: 3.1.0 - npm-package-arg: 13.0.2 - proc-log: 6.1.0 - transitivePeerDependencies: - - supports-color - nth-check@2.1.1: dependencies: boolbase: 1.0.0 @@ -15979,8 +15421,6 @@ snapshots: dependencies: p-limit: 3.1.0 - p-map@7.0.4: {} - p-queue@6.6.2: dependencies: eventemitter3: 4.0.7 @@ -16003,28 +15443,6 @@ snapshots: package-json-from-dist@1.0.1: {} - pacote@21.5.1: - dependencies: - '@gar/promise-retry': 1.0.3 - '@npmcli/git': 7.0.2 - '@npmcli/installed-package-contents': 4.0.0 - '@npmcli/package-json': 7.0.5 - '@npmcli/promise-spawn': 9.0.1 - '@npmcli/run-script': 10.0.4 - cacache: 20.0.4 - fs-minipass: 3.0.3 - minipass: 7.1.3 - npm-package-arg: 13.0.2 - npm-packlist: 10.0.4 - npm-pick-manifest: 11.0.3 - npm-registry-fetch: 19.1.1 - proc-log: 6.1.0 - sigstore: 4.1.1 - ssri: 13.0.1 - tar: 7.5.16 - transitivePeerDependencies: - - supports-color - pako@0.2.9: {} pako@1.0.11: {} @@ -16219,8 +15637,6 @@ snapshots: prettier@3.8.3: {} - proc-log@6.1.0: {} - proc-log@7.0.0: {} process-nextick-args@2.0.1: {} @@ -16640,7 +16056,7 @@ snapshots: '@rollup/rollup-win32-x64-msvc': 4.62.0 fsevents: 2.3.3 - router@2.2.0: + router@2.2.0(supports-color@10.2.2): dependencies: debug: 4.4.3(supports-color@10.2.2) depd: 2.0.0 @@ -16764,7 +16180,7 @@ snapshots: transitivePeerDependencies: - supports-color - send@1.2.1: + send@1.2.1(supports-color@10.2.2): dependencies: debug: 4.4.3(supports-color@10.2.2) encodeurl: 2.0.0 @@ -16808,7 +16224,7 @@ snapshots: encodeurl: 2.0.0 escape-html: 1.0.3 parseurl: 1.3.3 - send: 1.2.1 + send: 1.2.1(supports-color@10.2.2) transitivePeerDependencies: - supports-color @@ -16884,17 +16300,6 @@ snapshots: signal-exit@4.1.0: {} - sigstore@4.1.1: - dependencies: - '@sigstore/bundle': 4.0.0 - '@sigstore/core': 3.2.1 - '@sigstore/protobuf-specs': 0.5.1 - '@sigstore/sign': 4.1.1 - '@sigstore/tuf': 4.0.2 - '@sigstore/verify': 3.1.1 - transitivePeerDependencies: - - supports-color - slash@3.0.0: {} slice-ansi@7.1.2: @@ -16907,9 +16312,7 @@ snapshots: ansi-styles: 6.2.3 is-fullwidth-code-point: 5.1.0 - smart-buffer@4.2.0: {} - - socket.io-adapter@2.5.7(bufferutil@4.1.0)(utf-8-validate@6.0.6): + socket.io-adapter@2.5.7(bufferutil@4.1.0)(supports-color@10.2.2)(utf-8-validate@6.0.6): dependencies: debug: 4.4.3(supports-color@10.2.2) ws: 8.20.1(bufferutil@4.1.0)(utf-8-validate@6.0.6) @@ -16918,33 +16321,33 @@ snapshots: - supports-color - utf-8-validate - socket.io-client@4.8.3(bufferutil@4.1.0)(utf-8-validate@6.0.6): + socket.io-client@4.8.3(bufferutil@4.1.0)(supports-color@10.2.2)(utf-8-validate@6.0.6): dependencies: '@socket.io/component-emitter': 3.1.2 debug: 4.4.3(supports-color@10.2.2) - engine.io-client: 6.6.5(bufferutil@4.1.0)(utf-8-validate@6.0.6) - socket.io-parser: 4.2.6 + engine.io-client: 6.6.5(bufferutil@4.1.0)(supports-color@10.2.2)(utf-8-validate@6.0.6) + socket.io-parser: 4.2.6(supports-color@10.2.2) transitivePeerDependencies: - bufferutil - supports-color - utf-8-validate - socket.io-parser@4.2.6: + socket.io-parser@4.2.6(supports-color@10.2.2): dependencies: '@socket.io/component-emitter': 3.1.2 debug: 4.4.3(supports-color@10.2.2) transitivePeerDependencies: - supports-color - socket.io@4.8.3(bufferutil@4.1.0)(utf-8-validate@6.0.6): + socket.io@4.8.3(bufferutil@4.1.0)(supports-color@10.2.2)(utf-8-validate@6.0.6): dependencies: accepts: 1.3.8 base64id: 2.0.0 cors: 2.8.6 debug: 4.4.3(supports-color@10.2.2) - engine.io: 6.6.8(bufferutil@4.1.0)(utf-8-validate@6.0.6) - socket.io-adapter: 2.5.7(bufferutil@4.1.0)(utf-8-validate@6.0.6) - socket.io-parser: 4.2.6 + engine.io: 6.6.8(bufferutil@4.1.0)(supports-color@10.2.2)(utf-8-validate@6.0.6) + socket.io-adapter: 2.5.7(bufferutil@4.1.0)(supports-color@10.2.2)(utf-8-validate@6.0.6) + socket.io-parser: 4.2.6(supports-color@10.2.2) transitivePeerDependencies: - bufferutil - supports-color @@ -16956,19 +16359,6 @@ snapshots: uuid: 8.3.2 websocket-driver: 0.7.5 - socks-proxy-agent@8.0.5: - dependencies: - agent-base: 7.1.4 - debug: 4.4.3(supports-color@10.2.2) - socks: 2.8.9 - transitivePeerDependencies: - - supports-color - - socks@2.8.9: - dependencies: - ip-address: 10.2.0 - smart-buffer: 4.2.0 - sonic-boom@3.8.1: dependencies: atomic-sleep: 1.0.0 @@ -17001,18 +16391,13 @@ snapshots: spdx-exceptions: 2.5.0 spdx-license-ids: 3.0.23 - spdx-expression-parse@4.0.0: - dependencies: - spdx-exceptions: 2.5.0 - spdx-license-ids: 3.0.23 - spdx-expression-validate@2.0.0: dependencies: spdx-expression-parse: 3.0.1 spdx-license-ids@3.0.23: {} - spdy-transport@3.0.0: + spdy-transport@3.0.0(supports-color@10.2.2): dependencies: debug: 4.4.3(supports-color@10.2.2) detect-node: 2.1.0 @@ -17023,13 +16408,13 @@ snapshots: transitivePeerDependencies: - supports-color - spdy@4.0.2: + spdy@4.0.2(supports-color@10.2.2): dependencies: debug: 4.4.3(supports-color@10.2.2) handle-thing: 2.0.1 http-deceiver: 1.2.7 select-hose: 2.0.0 - spdy-transport: 3.0.0 + spdy-transport: 3.0.0(supports-color@10.2.2) transitivePeerDependencies: - supports-color @@ -17060,10 +16445,6 @@ snapshots: dependencies: minipass: 7.1.3 - ssri@13.0.1: - dependencies: - minipass: 7.1.3 - stack-trace@0.0.10: {} stackback@0.0.2: {} @@ -17222,14 +16603,6 @@ snapshots: - bare-buffer - react-native-b4a - tar@7.5.16: - dependencies: - '@isaacs/fs-minipass': 4.0.1 - chownr: 3.0.0 - minipass: 7.1.3 - minizlib: 3.1.0 - yallist: 5.0.0 - teeny-request@10.1.3(supports-color@10.2.2): dependencies: http-proxy-agent: 7.0.2(supports-color@10.2.2) @@ -17383,14 +16756,6 @@ snapshots: dependencies: tslib: 1.14.1 - tuf-js@4.1.0: - dependencies: - '@tufjs/models': 4.1.0 - debug: 4.4.3(supports-color@10.2.2) - make-fetch-happen: 15.0.6 - transitivePeerDependencies: - - supports-color - tunnel-agent@0.6.0: dependencies: safe-buffer: 5.2.1 @@ -17544,26 +16909,24 @@ snapshots: uuid@8.3.2: {} - validate-npm-package-name@7.0.2: {} - validate-npm-package-name@8.0.0: {} validator@13.15.26: {} vary@1.1.2: {} - verdaccio-audit@13.0.2(encoding@0.1.13): + verdaccio-audit@13.0.2(encoding@0.1.13)(supports-color@10.2.2): dependencies: '@verdaccio/config': 8.1.1 '@verdaccio/core': 8.1.1 express: 4.22.1 - https-proxy-agent: 5.0.1 + https-proxy-agent: 5.0.1(supports-color@10.2.2) node-fetch: 2.6.7(encoding@0.1.13) transitivePeerDependencies: - encoding - supports-color - verdaccio-auth-memory@13.0.2: + verdaccio-auth-memory@13.0.2(supports-color@10.2.2): dependencies: '@verdaccio/core': 8.1.1 debug: 4.4.3(supports-color@10.2.2) @@ -17582,24 +16945,24 @@ snapshots: transitivePeerDependencies: - supports-color - verdaccio@6.7.2(encoding@0.1.13): + verdaccio@6.7.2(encoding@0.1.13)(supports-color@10.2.2): dependencies: '@cypress/request': 3.0.10 - '@verdaccio/auth': 8.0.2 + '@verdaccio/auth': 8.0.2(supports-color@10.2.2) '@verdaccio/config': 8.1.1 '@verdaccio/core': 8.1.1 - '@verdaccio/hooks': 8.0.2 + '@verdaccio/hooks': 8.0.2(supports-color@10.2.2) '@verdaccio/loaders': 8.0.2 - '@verdaccio/local-storage-legacy': 11.3.3 + '@verdaccio/local-storage-legacy': 11.3.3(supports-color@10.2.2) '@verdaccio/logger': 8.0.2 - '@verdaccio/middleware': 8.0.2 - '@verdaccio/package-filter': 13.0.2 - '@verdaccio/search-indexer': 8.0.2 + '@verdaccio/middleware': 8.0.2(supports-color@10.2.2) + '@verdaccio/package-filter': 13.0.2(supports-color@10.2.2) + '@verdaccio/search-indexer': 8.0.2(supports-color@10.2.2) '@verdaccio/signature': 8.0.2 '@verdaccio/streams': 10.2.5 - '@verdaccio/tarball': 13.0.2 - '@verdaccio/ui-theme': 9.0.0-next-9.14 - '@verdaccio/url': 13.0.2 + '@verdaccio/tarball': 13.0.2(supports-color@10.2.2) + '@verdaccio/ui-theme': 9.0.0-next-9.14(supports-color@10.2.2) + '@verdaccio/url': 13.0.2(supports-color@10.2.2) '@verdaccio/utils': 8.1.2 JSONStream: 1.3.5 async: 3.2.6 @@ -17613,7 +16976,7 @@ snapshots: lru-cache: 7.18.3 mime: 3.0.0 semver: 7.8.0 - verdaccio-audit: 13.0.2(encoding@0.1.13) + verdaccio-audit: 13.0.2(encoding@0.1.13)(supports-color@10.2.2) verdaccio-htpasswd: 13.0.2 transitivePeerDependencies: - bare-abort-controller @@ -17755,7 +17118,7 @@ snapshots: transitivePeerDependencies: - tslib - webpack-dev-server@5.2.5(bufferutil@4.1.0)(tslib@2.8.1)(utf-8-validate@6.0.6)(webpack@5.107.2(esbuild@0.28.1)(postcss@8.5.15)): + webpack-dev-server@5.2.5(bufferutil@4.1.0)(supports-color@10.2.2)(tslib@2.8.1)(utf-8-validate@6.0.6)(webpack@5.107.2(esbuild@0.28.1)(postcss@8.5.15)): dependencies: '@types/bonjour': 3.5.13 '@types/connect-history-api-fallback': 1.5.4 @@ -17782,7 +17145,7 @@ snapshots: selfsigned: 5.5.0 serve-index: 1.9.2 sockjs: 0.3.24 - spdy: 4.0.2 + spdy: 4.0.2(supports-color@10.2.2) webpack-dev-middleware: 7.4.5(tslib@2.8.1)(webpack@5.107.2(esbuild@0.28.1)(postcss@8.5.15)) ws: 8.21.0(bufferutil@4.1.0)(utf-8-validate@6.0.6) optionalDependencies: @@ -17821,7 +17184,7 @@ snapshots: selfsigned: 5.5.0 serve-index: 1.9.2 sockjs: 0.3.24 - spdy: 4.0.2 + spdy: 4.0.2(supports-color@10.2.2) webpack-dev-middleware: 7.4.5(tslib@2.8.1)(webpack@5.107.2(esbuild@0.28.1)) ws: 8.21.0(bufferutil@4.1.0)(utf-8-validate@6.0.6) optionalDependencies: @@ -17996,10 +17359,6 @@ snapshots: dependencies: isexe: 2.0.0 - which@6.0.1: - dependencies: - isexe: 4.0.0 - which@7.0.0: dependencies: isexe: 4.0.0 @@ -18074,10 +17433,6 @@ snapshots: yallist@3.1.1: {} - yallist@4.0.0: {} - - yallist@5.0.0: {} - yaml@2.9.0: {} yargs-parser@20.2.9: {} From c7c80473fa14c5070118ad02343299c6b10b753d Mon Sep 17 00:00:00 2001 From: Charles Lyding <19598772+clydin@users.noreply.github.com> Date: Mon, 15 Jun 2026 09:11:52 -0400 Subject: [PATCH 052/787] test(@angular/cli): configure always-auth for Yarn Classic v1 registry authentication Configure always-auth in the written .npmrc and .yarnrc test profiles within createNpmConfigForAuthentication. By default, Yarn Classic (v1) does not send the Authorization header on GET requests (such as retrieving manifest metadata via yarn info) unless always-auth is enabled. When ng update uses the PackageManager abstraction under Yarn Classic v1, this ensures the necessary authorization headers are sent to secure registry endpoints. --- tests/e2e/tests/update/update-secure-registry.ts | 2 +- tests/e2e/utils/registry.ts | 6 ++++++ 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/tests/e2e/tests/update/update-secure-registry.ts b/tests/e2e/tests/update/update-secure-registry.ts index 3c0a9d468e44..47a9db657cd8 100644 --- a/tests/e2e/tests/update/update-secure-registry.ts +++ b/tests/e2e/tests/update/update-secure-registry.ts @@ -34,6 +34,6 @@ export default async function () { await createNpmConfigForAuthentication(true, true); const error = await expectToFail(() => exec('yarn', 'ng', 'update', ...extraArgs)); - assert.match(error.message, /not allowed to access package/); + assert.match(error.message, /not allowed to access package|status code 403/); } } diff --git a/tests/e2e/utils/registry.ts b/tests/e2e/utils/registry.ts index d8d75b566fb9..552ce4c20358 100644 --- a/tests/e2e/utils/registry.ts +++ b/tests/e2e/utils/registry.ts @@ -75,10 +75,13 @@ export async function createNpmConfigForAuthentication( scopedAuthentication ? ` ${registry}/:_auth="${token}" +${registry}/:always-auth=true +always-auth=true registry=http:${registry} ` : ` _auth="${token}" +always-auth=true registry=http:${registry} `, ); @@ -88,10 +91,13 @@ registry=http:${registry} scopedAuthentication ? ` ${registry}/:_auth "${token}" +${registry}/:always-auth true +always-auth true registry http:${registry} ` : ` _auth "${token}" +always-auth true registry http:${registry} `, ); From 48f90f5d5e5dd6369b2ccf044a722271c82dffd6 Mon Sep 17 00:00:00 2001 From: Charles Lyding <19598772+clydin@users.noreply.github.com> Date: Mon, 15 Jun 2026 09:39:33 -0400 Subject: [PATCH 053/787] fix(@angular/cli): prevent Yarn registry environment variable override When running scripts via Yarn Classic (such as yarn ng update), Yarn automatically injects npm_config_registry=https://registry.yarnpkg.com into the child process environment. When the PackageManager abstraction spawns child CLI subprocesses (such as yarn info), those child processes inherit the injected registry environment variable. Because environment variables take highest precedence, this previously caused spawned subprocesses to ignore local .yarnrc files and query the public CDN mirror. Strip npm_config_registry and NPM_CONFIG_REGISTRY from the child process environment when running under Yarn so that spawned subprocesses correctly respect local repository registry settings. --- .../angular/cli/src/package-managers/host.ts | 29 ++++++++++++++----- 1 file changed, 22 insertions(+), 7 deletions(-) diff --git a/packages/angular/cli/src/package-managers/host.ts b/packages/angular/cli/src/package-managers/host.ts index cee68015f677..90f426f9ab71 100644 --- a/packages/angular/cli/src/package-managers/host.ts +++ b/packages/angular/cli/src/package-managers/host.ts @@ -129,18 +129,33 @@ export const NodeJS_HOST: Host = { const isWin32 = platform() === 'win32'; return new Promise((resolve, reject) => { + const env: Record = { + ...process.env, + ...options.env, + // NPM updater notifier will prevents the child process from closing until it timeout after 3 minutes. + NO_UPDATE_NOTIFIER: '1', + NPM_CONFIG_UPDATE_NOTIFIER: 'false', + }; + + // When running via Yarn Classic (`yarn run `; @@ -268,9 +276,11 @@ export async function augmentIndexHtml( if (isString(baseHref)) { updateAttribute(tag, 'href', baseHref); } + if (subResourceIntegrityTag) { rewriter.emitRaw(subResourceIntegrityTag); } + break; case 'link': if (readAttribute(tag, 'rel') === 'preconnect') { diff --git a/packages/angular/build/src/utils/index-file/augment-index-html_spec.ts b/packages/angular/build/src/utils/index-file/augment-index-html_spec.ts index f2801ab3202a..df292b8771a3 100644 --- a/packages/angular/build/src/utils/index-file/augment-index-html_spec.ts +++ b/packages/angular/build/src/utils/index-file/augment-index-html_spec.ts @@ -468,10 +468,10 @@ describe('augment-index-html', () => { const match = content.match(/'), + }); + + expect(errors).toEqual([]); + expect(warnings).toEqual([]); + expect(findFile(outputFiles, 'main.js').text).toBe( + 'export const greeting = "Bonjour \\"mon ami\\" \\\\ \' \\n ";\n', + ); + }); + + it('inlines translations containing placeholders', async () => { + const source = 'export const welcome = (name) => $localize`:@@welcome:Hello ${name}!`;\n'; + const { outputFiles, errors, warnings } = await createInliner([ + browserFile('main.js', source), + ]).inlineForLocale('fr', { + welcome: { + messageParts: ['Bonjour ', ' !'], + placeholderNames: ['PH'], + text: 'Bonjour {$PH} !', + }, + }); + + expect(errors).toEqual([]); + expect(warnings).toEqual([]); + expect(findFile(outputFiles, 'main.js').text).toBe( + 'export const welcome = (name) => `Bonjour ${name} !`;\n', + ); + }); + + it('inlines multiple localize calls within the same file', async () => { + const source = + 'export const a = $localize`:@@greeting:Hello`;\nexport const b = $localize`:@@farewell:Goodbye`;\n'; + const { outputFiles, errors, warnings } = await createInliner([ + browserFile('main.js', source), + ]).inlineForLocale('fr', { + greeting: translationFor('Bonjour'), + farewell: translationFor('Au revoir'), + }); + + expect(errors).toEqual([]); + expect(warnings).toEqual([]); + expect(findFile(outputFiles, 'main.js').text).toBe( + 'export const a = "Bonjour";\nexport const b = "Au revoir";\n', + ); + }); + + it('inlines translations across multiple files using multiple worker threads in parallel', async () => { + inliner = new I18nInliner( + { + missingTranslation: 'warning', + outputFiles: [ + browserFile('main.js', GREETING_SOURCE), + browserFile('chunk1.js', GREETING_SOURCE), + browserFile('chunk2.js', GREETING_SOURCE), + browserFile('chunk3.js', GREETING_SOURCE), + ], + }, + 4, + ); + + const { outputFiles, errors, warnings } = await inliner.inlineForLocale('fr', { + greeting: translationFor('Bonjour'), + }); + + expect(errors).toEqual([]); + expect(warnings).toEqual([]); + for (const name of ['main.js', 'chunk1.js', 'chunk2.js', 'chunk3.js']) { + expect(findFile(outputFiles, name).text).toBe('export const greeting = "Bonjour";\n'); + } + }); + it('leaves files without localize calls unmodified', async () => { const { outputFiles } = await createInliner([ browserFile('main.js', GREETING_SOURCE), From 7106676e64ee234641b1b3cbd88fc058703d4d3e Mon Sep 17 00:00:00 2001 From: Alan Agius <17563226+alan-agius4@users.noreply.github.com> Date: Wed, 5 Aug 2026 18:22:39 +0000 Subject: [PATCH 254/787] fix(@angular/cli): disable searching current directory for bare executable names on Windows Set NoDefaultCurrentDirectoryInExePath environment variable early in CLI initialization so Windows CreateProcess does not search process.cwd() when resolving bare command names. Fixes #33755 --- packages/angular/cli/lib/init.ts | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/packages/angular/cli/lib/init.ts b/packages/angular/cli/lib/init.ts index ab6e9cf48589..3cd0188b7894 100644 --- a/packages/angular/cli/lib/init.ts +++ b/packages/angular/cli/lib/init.ts @@ -39,6 +39,9 @@ let forceExit = false; // Ignore failure to change directory } } + + // Ensure Windows CreateProcess does not search the current directory for bare executable names. + process.env['NoDefaultCurrentDirectoryInExePath'] = '1'; } /** @@ -48,6 +51,7 @@ let forceExit = false; * See: https://github.com/browserslist/browserslist/blob/819c4337456996d19db6ba953014579329e9c6e1/node.js#L324 */ process.env.BROWSERSLIST_IGNORE_OLD_DATA = '1'; + const rawCommandName = process.argv[2]; /** From 368535a0bf6df062cc099b697eb5b7085925d71d Mon Sep 17 00:00:00 2001 From: Angular Robot Date: Wed, 5 Aug 2026 16:54:22 +0000 Subject: [PATCH 255/787] build: update cross-repo angular dependencies See associated pull request for more information. --- package.json | 4 ++-- pnpm-lock.yaml | 24 +++++++++++----------- tests/e2e/ng-snapshot/package.json | 32 +++++++++++++++--------------- 3 files changed, 30 insertions(+), 30 deletions(-) diff --git a/package.json b/package.json index c9f634207208..b3c0d806cb6e 100644 --- a/package.json +++ b/package.json @@ -47,13 +47,13 @@ }, "devDependencies": { "@angular/animations": "22.2.0-next.0", - "@angular/cdk": "22.1.0-rc.0", + "@angular/cdk": "22.2.0-next.0", "@angular/common": "22.2.0-next.0", "@angular/compiler": "22.2.0-next.0", "@angular/core": "22.2.0-next.0", "@angular/forms": "22.2.0-next.0", "@angular/localize": "22.2.0-next.0", - "@angular/material": "22.1.0-rc.0", + "@angular/material": "22.2.0-next.0", "@angular/ng-dev": "https://github.com/angular/dev-infra-private-ng-dev-builds.git#dcf9b6776377d5d301e054111add3ef80f433b70", "@angular/platform-browser": "22.2.0-next.0", "@angular/platform-server": "22.2.0-next.0", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 6c60a1312dd8..f26c9fa085e9 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -29,8 +29,8 @@ importers: specifier: 22.2.0-next.0 version: 22.2.0-next.0(@angular/core@22.2.0-next.0(@angular/compiler@22.2.0-next.0)(rxjs@7.8.2)(zone.js@0.16.2)) '@angular/cdk': - specifier: 22.1.0-rc.0 - version: 22.1.0-rc.0(@angular/common@22.2.0-next.0(@angular/core@22.2.0-next.0(@angular/compiler@22.2.0-next.0)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2))(@angular/core@22.2.0-next.0(@angular/compiler@22.2.0-next.0)(rxjs@7.8.2)(zone.js@0.16.2))(@angular/platform-browser@22.2.0-next.0(@angular/animations@22.2.0-next.0(@angular/core@22.2.0-next.0(@angular/compiler@22.2.0-next.0)(rxjs@7.8.2)(zone.js@0.16.2)))(@angular/common@22.2.0-next.0(@angular/core@22.2.0-next.0(@angular/compiler@22.2.0-next.0)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2))(@angular/core@22.2.0-next.0(@angular/compiler@22.2.0-next.0)(rxjs@7.8.2)(zone.js@0.16.2)))(rxjs@7.8.2) + specifier: 22.2.0-next.0 + version: 22.2.0-next.0(@angular/common@22.2.0-next.0(@angular/core@22.2.0-next.0(@angular/compiler@22.2.0-next.0)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2))(@angular/core@22.2.0-next.0(@angular/compiler@22.2.0-next.0)(rxjs@7.8.2)(zone.js@0.16.2))(@angular/platform-browser@22.2.0-next.0(@angular/animations@22.2.0-next.0(@angular/core@22.2.0-next.0(@angular/compiler@22.2.0-next.0)(rxjs@7.8.2)(zone.js@0.16.2)))(@angular/common@22.2.0-next.0(@angular/core@22.2.0-next.0(@angular/compiler@22.2.0-next.0)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2))(@angular/core@22.2.0-next.0(@angular/compiler@22.2.0-next.0)(rxjs@7.8.2)(zone.js@0.16.2)))(rxjs@7.8.2) '@angular/common': specifier: 22.2.0-next.0 version: 22.2.0-next.0(@angular/core@22.2.0-next.0(@angular/compiler@22.2.0-next.0)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2) @@ -47,8 +47,8 @@ importers: specifier: 22.2.0-next.0 version: 22.2.0-next.0(@angular/compiler-cli@22.2.0-next.0(@angular/compiler@22.2.0-next.0)(typescript@6.0.3))(@angular/compiler@22.2.0-next.0) '@angular/material': - specifier: 22.1.0-rc.0 - version: 22.1.0-rc.0(1d924d51246212fc2acfd8877e0b8722) + specifier: 22.2.0-next.0 + version: 22.2.0-next.0(08785ac9bff56240de0a5940322ae01f) '@angular/ng-dev': specifier: https://github.com/angular/dev-infra-private-ng-dev-builds.git#dcf9b6776377d5d301e054111add3ef80f433b70 version: https://codeload.github.com/angular/dev-infra-private-ng-dev-builds/tar.gz/dcf9b6776377d5d301e054111add3ef80f433b70 @@ -865,8 +865,8 @@ packages: peerDependencies: '@angular/core': 22.2.0-next.0 - '@angular/cdk@22.1.0-rc.0': - resolution: {integrity: sha512-E0IbkeugB0fjXFHT2fjb3Cicqz8wt8SEAY/8GqtmP/CC5U9sXuzWLnH8JjkR/96i05WgNT0PfBnycYZEkI59Pw==} + '@angular/cdk@22.2.0-next.0': + resolution: {integrity: sha512-l+Cniyp/qodyEMmWcYpXQ0zEOWzZ/zY+7ERn0dBGmjR3SJx3lPT+gqc6c99BSB9eOy4wldmxyLckpvKiNMSJoA==} peerDependencies: '@angular/common': ^22.0.0-0 || ^22.1.0-0 || ^22.2.0-0 || ^22.3.0-0 || ^23.0.0-0 '@angular/core': ^22.0.0-0 || ^22.1.0-0 || ^22.2.0-0 || ^22.3.0-0 || ^23.0.0-0 @@ -925,10 +925,10 @@ packages: '@angular/compiler': 22.2.0-next.0 '@angular/compiler-cli': 22.2.0-next.0 - '@angular/material@22.1.0-rc.0': - resolution: {integrity: sha512-bvnbsUA7UwIilDpZzfrm/537J5U1G5Ddzup0gZFhkFzrOAGhekNyfb5reGOt9ya1AzkorL+Cdh52rTUTglNnSA==} + '@angular/material@22.2.0-next.0': + resolution: {integrity: sha512-knu75htSySpbPmH21njiNB19b4zXgVc9T/hWIF0WWorjpDKVLqgvHDJdxo34XYT764Hp32L7YxJwiwu08/e8eA==} peerDependencies: - '@angular/cdk': 22.1.0-rc.0 + '@angular/cdk': 22.2.0-next.0 '@angular/common': ^22.0.0-0 || ^22.1.0-0 || ^22.2.0-0 || ^22.3.0-0 || ^23.0.0-0 '@angular/core': ^22.0.0-0 || ^22.1.0-0 || ^22.2.0-0 || ^22.3.0-0 || ^23.0.0-0 '@angular/forms': ^22.0.0-0 || ^22.1.0-0 || ^22.2.0-0 || ^22.3.0-0 || ^23.0.0-0 @@ -8347,7 +8347,7 @@ snapshots: '@angular/core': 22.2.0-next.0(@angular/compiler@22.2.0-next.0)(rxjs@7.8.2)(zone.js@0.16.2) tslib: 2.8.1 - '@angular/cdk@22.1.0-rc.0(@angular/common@22.2.0-next.0(@angular/core@22.2.0-next.0(@angular/compiler@22.2.0-next.0)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2))(@angular/core@22.2.0-next.0(@angular/compiler@22.2.0-next.0)(rxjs@7.8.2)(zone.js@0.16.2))(@angular/platform-browser@22.2.0-next.0(@angular/animations@22.2.0-next.0(@angular/core@22.2.0-next.0(@angular/compiler@22.2.0-next.0)(rxjs@7.8.2)(zone.js@0.16.2)))(@angular/common@22.2.0-next.0(@angular/core@22.2.0-next.0(@angular/compiler@22.2.0-next.0)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2))(@angular/core@22.2.0-next.0(@angular/compiler@22.2.0-next.0)(rxjs@7.8.2)(zone.js@0.16.2)))(rxjs@7.8.2)': + '@angular/cdk@22.2.0-next.0(@angular/common@22.2.0-next.0(@angular/core@22.2.0-next.0(@angular/compiler@22.2.0-next.0)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2))(@angular/core@22.2.0-next.0(@angular/compiler@22.2.0-next.0)(rxjs@7.8.2)(zone.js@0.16.2))(@angular/platform-browser@22.2.0-next.0(@angular/animations@22.2.0-next.0(@angular/core@22.2.0-next.0(@angular/compiler@22.2.0-next.0)(rxjs@7.8.2)(zone.js@0.16.2)))(@angular/common@22.2.0-next.0(@angular/core@22.2.0-next.0(@angular/compiler@22.2.0-next.0)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2))(@angular/core@22.2.0-next.0(@angular/compiler@22.2.0-next.0)(rxjs@7.8.2)(zone.js@0.16.2)))(rxjs@7.8.2)': dependencies: '@angular/common': 22.2.0-next.0(@angular/core@22.2.0-next.0(@angular/compiler@22.2.0-next.0)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2) '@angular/core': 22.2.0-next.0(@angular/compiler@22.2.0-next.0)(rxjs@7.8.2)(zone.js@0.16.2) @@ -8406,9 +8406,9 @@ snapshots: tinyglobby: 0.2.17 yargs: 18.1.0 - '@angular/material@22.1.0-rc.0(1d924d51246212fc2acfd8877e0b8722)': + '@angular/material@22.2.0-next.0(08785ac9bff56240de0a5940322ae01f)': dependencies: - '@angular/cdk': 22.1.0-rc.0(@angular/common@22.2.0-next.0(@angular/core@22.2.0-next.0(@angular/compiler@22.2.0-next.0)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2))(@angular/core@22.2.0-next.0(@angular/compiler@22.2.0-next.0)(rxjs@7.8.2)(zone.js@0.16.2))(@angular/platform-browser@22.2.0-next.0(@angular/animations@22.2.0-next.0(@angular/core@22.2.0-next.0(@angular/compiler@22.2.0-next.0)(rxjs@7.8.2)(zone.js@0.16.2)))(@angular/common@22.2.0-next.0(@angular/core@22.2.0-next.0(@angular/compiler@22.2.0-next.0)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2))(@angular/core@22.2.0-next.0(@angular/compiler@22.2.0-next.0)(rxjs@7.8.2)(zone.js@0.16.2)))(rxjs@7.8.2) + '@angular/cdk': 22.2.0-next.0(@angular/common@22.2.0-next.0(@angular/core@22.2.0-next.0(@angular/compiler@22.2.0-next.0)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2))(@angular/core@22.2.0-next.0(@angular/compiler@22.2.0-next.0)(rxjs@7.8.2)(zone.js@0.16.2))(@angular/platform-browser@22.2.0-next.0(@angular/animations@22.2.0-next.0(@angular/core@22.2.0-next.0(@angular/compiler@22.2.0-next.0)(rxjs@7.8.2)(zone.js@0.16.2)))(@angular/common@22.2.0-next.0(@angular/core@22.2.0-next.0(@angular/compiler@22.2.0-next.0)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2))(@angular/core@22.2.0-next.0(@angular/compiler@22.2.0-next.0)(rxjs@7.8.2)(zone.js@0.16.2)))(rxjs@7.8.2) '@angular/common': 22.2.0-next.0(@angular/core@22.2.0-next.0(@angular/compiler@22.2.0-next.0)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2) '@angular/core': 22.2.0-next.0(@angular/compiler@22.2.0-next.0)(rxjs@7.8.2)(zone.js@0.16.2) '@angular/forms': 22.2.0-next.0(@angular/common@22.2.0-next.0(@angular/core@22.2.0-next.0(@angular/compiler@22.2.0-next.0)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2))(@angular/core@22.2.0-next.0(@angular/compiler@22.2.0-next.0)(rxjs@7.8.2)(zone.js@0.16.2))(@angular/platform-browser@22.2.0-next.0(@angular/animations@22.2.0-next.0(@angular/core@22.2.0-next.0(@angular/compiler@22.2.0-next.0)(rxjs@7.8.2)(zone.js@0.16.2)))(@angular/common@22.2.0-next.0(@angular/core@22.2.0-next.0(@angular/compiler@22.2.0-next.0)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2))(@angular/core@22.2.0-next.0(@angular/compiler@22.2.0-next.0)(rxjs@7.8.2)(zone.js@0.16.2)))(rxjs@7.8.2) diff --git a/tests/e2e/ng-snapshot/package.json b/tests/e2e/ng-snapshot/package.json index 352804392464..6fce7aa3d6a9 100644 --- a/tests/e2e/ng-snapshot/package.json +++ b/tests/e2e/ng-snapshot/package.json @@ -2,21 +2,21 @@ "description": "snapshot versions of Angular for e2e testing", "private": true, "dependencies": { - "@angular/animations": "github:angular/animations-builds#0e7ff3554caf6d3d4f960a26febbfb6b6d756615", - "@angular/cdk": "github:angular/cdk-builds#318c54859a534fcba8c27661d229688a7e97d0b1", - "@angular/common": "github:angular/common-builds#49b4ac49211d1d070eecf4fa841416ea8ab76824", - "@angular/compiler": "github:angular/compiler-builds#9c17a8f0723623334ecef12c4f283386f3e32fb0", - "@angular/compiler-cli": "github:angular/compiler-cli-builds#c02569ab47b1a91cfbdd16d107e948fc7a3c4743", - "@angular/core": "github:angular/core-builds#809df2fb8d59910f8a1333bb35f2f22491b0ec1f", - "@angular/forms": "github:angular/forms-builds#b9b74fc3cc070af39fd56031ea4fdfb234ed712f", - "@angular/language-service": "github:angular/language-service-builds#06ad60c1eb4437e15542f4b5debe14ce57543f2c", - "@angular/localize": "github:angular/localize-builds#db7b32d752c69bbd0e35c1e6bf4426be2ddff00c", - "@angular/material": "github:angular/material-builds#8d26607e3f632b78ecb09ae93d229ed3c05776b2", - "@angular/material-moment-adapter": "github:angular/material-moment-adapter-builds#26e4a977aa158b30801e8b1f52e467624948a181", - "@angular/platform-browser": "github:angular/platform-browser-builds#f8040fb8a9e7943ca05eff8780c9b64d29519aa9", - "@angular/platform-browser-dynamic": "github:angular/platform-browser-dynamic-builds#002ce4a00a52c4987463b3ac34c9b32b11240971", - "@angular/platform-server": "github:angular/platform-server-builds#d0169883f344e678f90f9645df887debf6d6ff92", - "@angular/router": "github:angular/router-builds#ac54692555b70315f17f0c20d4ea5b326177c203", - "@angular/service-worker": "github:angular/service-worker-builds#a147d674eae2a01932d6d26a4f959e97f5c8187f" + "@angular/animations": "github:angular/animations-builds#8cf373fe77fe5bfa2976f8558cfbb02062fbf989", + "@angular/cdk": "github:angular/cdk-builds#537272e3b83d918eeca3469e56401814c7afa979", + "@angular/common": "github:angular/common-builds#66ad2d9beb92e2d4fde4bb1ae6f1ce9b42991f7c", + "@angular/compiler": "github:angular/compiler-builds#06db09af5df5b3cdf4a894d9fbcdf0c4845193b6", + "@angular/compiler-cli": "github:angular/compiler-cli-builds#96a827e4195bfb9da30d1b3669088baf140a4f02", + "@angular/core": "github:angular/core-builds#223af9a51f3a9f2a3d9bc6c7597a711d7bb7dc41", + "@angular/forms": "github:angular/forms-builds#e143909758d73d57a86766de433353a691609177", + "@angular/language-service": "github:angular/language-service-builds#5eb911b370b48f545bcf1178862362232da6a45a", + "@angular/localize": "github:angular/localize-builds#0e49c7f61bcbf8b7a5897ae0af906f1716ad819d", + "@angular/material": "github:angular/material-builds#0f7dcb3b1f8048d0347c19a734ed86c6e18b230b", + "@angular/material-moment-adapter": "github:angular/material-moment-adapter-builds#cd490fbfd3fe43611fe143c05b560f9050e276e7", + "@angular/platform-browser": "github:angular/platform-browser-builds#7cb5471e8a115af74442d88f6b1d78206b4f8f2f", + "@angular/platform-browser-dynamic": "github:angular/platform-browser-dynamic-builds#9d30dfb7f30b35b8d804e32b50d3284986d9d356", + "@angular/platform-server": "github:angular/platform-server-builds#0aa94d94a4848dd791f4650de09bd17375c2ddc2", + "@angular/router": "github:angular/router-builds#956b0916aed436d1adf2ea3c6d621d303d8bb0da", + "@angular/service-worker": "github:angular/service-worker-builds#1ca1d994d055310e6f170c891379ad0395e21c0b" } } From 04b532772f6347d341b182135dee1758616a69d6 Mon Sep 17 00:00:00 2001 From: Akash Patel <2557058+imaksp@users.noreply.github.com> Date: Thu, 6 Aug 2026 16:59:45 +0530 Subject: [PATCH 256/787] fix(@angular/build): count statically imported chunks in the initial total `optimizeChunks` removes every used chunk from `initialFiles` and then re-walks the optimized graph to restore the ones the main entry still imports statically. The walk builds an `InitialFileRecord` for each import but never stores it, so the entries are analyzed and then dropped. Because the records were deleted just above, `existingRecord` is always undefined, and the map ends up holding only the configured entry points. Chunks the browser must fetch before the application can run are therefore excluded from "Initial total" and reported under "Lazy chunk files" instead. On a large application this understated the initial payload by roughly 3x: 377.35 kB reported against 1.35 MB actually required, with a 919 kB statically imported chunk listed as lazy. `BundlerContext#bundle` performs the equivalent walk and does call `initialFiles.set` before pushing the entry; this aligns the optimizer with it. Fixes #33773 --- .../angular/build/src/builders/application/chunk-optimizer.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/angular/build/src/builders/application/chunk-optimizer.ts b/packages/angular/build/src/builders/application/chunk-optimizer.ts index 7d7a6e56b829..2241a4204999 100644 --- a/packages/angular/build/src/builders/application/chunk-optimizer.ts +++ b/packages/angular/build/src/builders/application/chunk-optimizer.ts @@ -418,6 +418,7 @@ export async function optimizeChunks( const record = createInitialFileRecord(entryRecord.depth + 1); + original.initialFiles.set(importPath, record); entriesToAnalyze.push([importPath, record]); } } From 199a864df97fc8c20b8d4e1fc8b891c61140671a Mon Sep 17 00:00:00 2001 From: Alan Agius <17563226+alan-agius4@users.noreply.github.com> Date: Thu, 6 Aug 2026 07:51:36 +0000 Subject: [PATCH 257/787] fix(@angular/build): prevent syntax corruption for Crockford-style enum IIFE When transforming Crockford-style TypeScript enum IIFEs, ensure all leading and trailing parentheses of the expression statement are removed when moving the IIFE call expression to the var initializer. Fixes #33785 --- .../oxc/adjust-typescript-enums_oxc_spec.ts | 79 +++++++++++++++++++ .../build/src/tools/oxc/oxc-transform.ts | 6 +- 2 files changed, 82 insertions(+), 3 deletions(-) diff --git a/packages/angular/build/src/tools/oxc/adjust-typescript-enums_oxc_spec.ts b/packages/angular/build/src/tools/oxc/adjust-typescript-enums_oxc_spec.ts index c074f315d35f..82877cb3b2e3 100644 --- a/packages/angular/build/src/tools/oxc/adjust-typescript-enums_oxc_spec.ts +++ b/packages/angular/build/src/tools/oxc/adjust-typescript-enums_oxc_spec.ts @@ -300,4 +300,83 @@ describe('adjust-typescript-enums oxc-transform implementation', () => { `, }), ); + + it( + 'handles TypeScript enums wrapped in parentheses', + testCase({ + input: ` + var ChangeDetectionStrategy; + ((function (ChangeDetectionStrategy) { + ChangeDetectionStrategy[ChangeDetectionStrategy["OnPush"] = 0] = "OnPush"; + ChangeDetectionStrategy[ChangeDetectionStrategy["Default"] = 1] = "Default"; + })(ChangeDetectionStrategy || (ChangeDetectionStrategy = {}))); + `, + expected: ` + var ChangeDetectionStrategy = /*#__PURE__*/ (function (ChangeDetectionStrategy) { + ChangeDetectionStrategy[(ChangeDetectionStrategy["OnPush"] = 0)] = "OnPush"; + ChangeDetectionStrategy[(ChangeDetectionStrategy["Default"] = 1)] = "Default"; + return ChangeDetectionStrategy; + })(ChangeDetectionStrategy || {}); + `, + }), + ); + + it( + 'wraps Crockford-style TypeScript enum IIFE without leaving dangling parentheses', + testCase({ + input: ` + var HDirection; + (function (HDirection) { + HDirection[HDirection['Backwards'] = -1] = 'Backwards'; + HDirection[HDirection['Forwards'] = 1] = 'Forwards'; + }(HDirection || (HDirection = {}))); + const nextStatement = true; + `, + expected: ` + var HDirection = /*#__PURE__*/ (function (HDirection) { + HDirection[(HDirection['Backwards'] = -1)] = 'Backwards'; + HDirection[(HDirection['Forwards'] = 1)] = 'Forwards'; + return HDirection; + }(HDirection || {})); + + const nextStatement = true; + `, + }), + ); + + it( + 'wraps TypeScript enum IIFE with multiple nested parentheses', + testCase({ + input: ` + var Foo; + (((function (Foo) { + Foo[Foo['A'] = 0] = 'A'; + }(Foo || (Foo = {}))))); + `, + expected: ` + var Foo = /*#__PURE__*/ (function (Foo) { + Foo[(Foo['A'] = 0)] = 'A'; + return Foo; + }(Foo || {})); + `, + }), + ); + + it( + 'wraps Crockford-style TypeScript enum IIFE with chained export assignments', + testCase({ + input: ` + var Foo; + (function (Foo) { + Foo[Foo['A'] = 0] = 'A'; + }(Foo || (Foo = exports.Foo = {}))); + `, + expected: ` + var Foo = /*#__PURE__*/ (function (Foo) { + Foo[(Foo['A'] = 0)] = 'A'; + return Foo; + }(Foo || (exports.Foo = {}))); + `, + }), + ); }); diff --git a/packages/angular/build/src/tools/oxc/oxc-transform.ts b/packages/angular/build/src/tools/oxc/oxc-transform.ts index 7f373ff09f08..14e5a6b0ea97 100644 --- a/packages/angular/build/src/tools/oxc/oxc-transform.ts +++ b/packages/angular/build/src/tools/oxc/oxc-transform.ts @@ -412,9 +412,10 @@ export function transform(filename: string, code: string, options: OxcTransformO continue; } - // 1. Remove only the trailing characters/semicolon of the expression statement + // 1. Remove leading/trailing characters/parentheses of the expression statement + s.remove(nextStatement.start, nextExpr.start); s.remove(nextExpr.end, nextStatement.end); - markEdited(nextExpr.end, nextStatement.end); + markEdited(nextStatement.start, nextStatement.end); // 2. Add return statement inside IIFE body s.appendRight(callee.body.end - 1, `; return ${paramName};`); @@ -435,7 +436,6 @@ export function transform(filename: string, code: string, options: OxcTransformO // 4. Move IIFE to the var initializer s.move(nextExpr.start, nextExpr.end, decl.id.end); s.appendLeft(decl.id.end, ' = /*#__PURE__*/ '); - markEdited(nextExpr.start, nextExpr.end); } } From 715852b8aa948b7100d510114508b20d66c98321 Mon Sep 17 00:00:00 2001 From: Charles Lyding <19598772+clydin@users.noreply.github.com> Date: Wed, 5 Aug 2026 20:19:49 -0400 Subject: [PATCH 258/787] refactor(@angular/build): defer sourcemap remapping in javascript transformer worker Refactor the JavaScript transformer worker to collect intermediate decoded source maps in memory across pipeline passes and execute sourcemap remapping only once at the end of transformation. In addition, cache the oxc-transform module at module scope to avoid allocating dynamic import promises for every transformed file, and update oxc-linker and oxc-transform to directly return raw DecodedSourceMap objects without internal input sourcemap loading or intermediate remapping. --- .../src/tools/angular/linker/oxc-linker.ts | 16 +- .../tools/angular/linker/oxc-linker_spec.ts | 36 +-- .../esbuild/javascript-transformer-worker.ts | 73 ++++-- .../esbuild/javascript-transformer_spec.ts | 242 ++++++++++++++++++ .../build/src/tools/oxc/oxc-transform.ts | 18 +- .../build/src/tools/oxc/oxc-transform_spec.ts | 29 +-- 6 files changed, 305 insertions(+), 109 deletions(-) create mode 100644 packages/angular/build/src/tools/esbuild/javascript-transformer_spec.ts diff --git a/packages/angular/build/src/tools/angular/linker/oxc-linker.ts b/packages/angular/build/src/tools/angular/linker/oxc-linker.ts index 6743fb720c21..7d085502978b 100644 --- a/packages/angular/build/src/tools/angular/linker/oxc-linker.ts +++ b/packages/angular/build/src/tools/angular/linker/oxc-linker.ts @@ -7,7 +7,6 @@ */ import type { DecodedSourceMap } from '@ampproject/remapping'; -import remapping from '@ampproject/remapping'; import { ConsoleLogger, LogLevel } from '@angular/compiler-cli'; import type { DeclarationScope } from '@angular/compiler-cli/linker'; import { FileLinker, LinkerEnvironment, needsLinking } from '@angular/compiler-cli/linker'; @@ -18,7 +17,6 @@ import type { import type { CallExpression, Node } from '@oxc-project/types'; import MagicString from 'magic-string'; import { parseSync, visitorKeys } from 'oxc-parser'; -import { loadInputSourceMap } from '../../../utils/source-map'; import { OxcAstHost } from './oxc-ast-host'; import { StringAstFactory } from './string-ast-factory'; @@ -168,18 +166,10 @@ export function linkWithOxc(filename: string, code: string, options: OxcLinkerOp return { code, map: undefined }; } - let map: string | undefined; + let map: DecodedSourceMap | undefined; if (options.sourcemap) { - const inputMap = loadInputSourceMap(filename, code); - if (inputMap) { - const rawMap = s.generateDecodedMap({ hires: true, source: filename }); - map = remapping( - [{ ...rawMap, version: 3 } satisfies DecodedSourceMap, inputMap], - () => null, - ).toString(); - } else { - map = s.generateMap({ hires: true, source: filename }).toString(); - } + const rawMap = s.generateDecodedMap({ hires: true, source: filename }); + map = { ...rawMap, version: 3 }; } return { diff --git a/packages/angular/build/src/tools/angular/linker/oxc-linker_spec.ts b/packages/angular/build/src/tools/angular/linker/oxc-linker_spec.ts index 6b1ae742581a..5f5cf6d84fe9 100644 --- a/packages/angular/build/src/tools/angular/linker/oxc-linker_spec.ts +++ b/packages/angular/build/src/tools/angular/linker/oxc-linker_spec.ts @@ -54,7 +54,7 @@ describe('linkWithOxc', () => { expect(result.code).not.toContain('i0.ɵɵngDeclareComponent'); }); - it('should generate a sourcemap when sourcemap option is enabled', () => { + it('should generate a decoded sourcemap when sourcemap option is enabled', () => { const input = ` import * as i0 from "@angular/core"; export class MyDirective {} @@ -69,37 +69,7 @@ describe('linkWithOxc', () => { const result = linkWithOxc('test.js', input, { sourcemap: true }); expect(result.map).toBeDefined(); - const parsedMap = JSON.parse(result.map as string); - expect(parsedMap.version).toBe(3); - expect(parsedMap.sources).toContain('test.js'); - }); - - it('should remap with input sourcemap when sourcemap option is enabled and inputMap is present', () => { - const inputMap = { - version: 3, - sources: ['original.ts'], - sourcesContent: ['// original content'], - mappings: 'AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA', - names: [], - }; - const base64Map = Buffer.from(JSON.stringify(inputMap)).toString('base64'); - const input = ` - import * as i0 from "@angular/core"; - export class MyDirective {} - MyDirective.ɵdir = i0.ɵɵngDeclareDirective({ - minVersion: "12.0.0", - version: "14.0.0", - ngImport: i0, - type: MyDirective, - selector: "[my-dir]" - }); - //# sourceMappingURL=data:application/json;base64,${base64Map} - `; - - const result = linkWithOxc('test.js', input, { sourcemap: true }); - expect(result.map).toBeDefined(); - const parsedMap = JSON.parse(result.map as string); - expect(parsedMap.version).toBe(3); - expect(parsedMap.sources).toContain('original.ts'); + expect(result.map?.version).toBe(3); + expect(result.map?.sources).toContain('test.js'); }); }); diff --git a/packages/angular/build/src/tools/esbuild/javascript-transformer-worker.ts b/packages/angular/build/src/tools/esbuild/javascript-transformer-worker.ts index ffc5feb6e008..7dfefbb2de55 100644 --- a/packages/angular/build/src/tools/esbuild/javascript-transformer-worker.ts +++ b/packages/angular/build/src/tools/esbuild/javascript-transformer-worker.ts @@ -6,6 +6,7 @@ * found in the LICENSE file at https://angular.dev/license */ +import remapping, { type DecodedSourceMap, type EncodedSourceMap } from '@ampproject/remapping'; import { type PluginItem, transformAsync } from '@babel/core'; import { createRequire } from 'node:module'; import Piscina from 'piscina'; @@ -39,7 +40,7 @@ async function instrumentCoverage( filename: string, data: string, useInputSourcemap: boolean, -): Promise { +): Promise<{ code: string; map?: EncodedSourceMap }> { try { let resolvedPath = 'istanbul-lib-instrument'; try { @@ -63,15 +64,14 @@ async function instrumentCoverage( filename, inputSourceMap as Parameters[2], ); - const lastMap = instrumenter.lastSourceMap(); - - if (useInputSourcemap && lastMap) { - const inlineMap = Buffer.from(JSON.stringify(lastMap)).toString('base64'); - - return instrumentedCode + `\n//# sourceMappingURL=data:application/json;base64,${inlineMap}`; - } - - return removeSourceMappingURL(instrumentedCode); + const lastMap = useInputSourcemap + ? (instrumenter.lastSourceMap() as EncodedSourceMap) + : undefined; + + return { + code: instrumentedCode, + map: lastMap ?? undefined, + }; } catch (error) { throw new Error( `The 'istanbul-lib-instrument' package is required for code coverage but was not found. Please install the package.`, @@ -97,6 +97,11 @@ export default async function transformJavaScript( */ let oxcLinkerModule: typeof import('../angular/linker/oxc-linker.js') | undefined; +/** + * Cached instance of the OXC transform module. + */ +let oxcTransformModule: typeof import('../oxc/oxc-transform.js') | undefined; + async function transformJavaScriptImpl( filename: string, data: string, @@ -108,9 +113,13 @@ async function transformJavaScriptImpl( (!!options.thirdPartySourcemaps || !/[\\/]node_modules[\\/]/.test(filename)); let code = data; + const maps: (DecodedSourceMap | EncodedSourceMap)[] = []; + let coverageMap: EncodedSourceMap | undefined; if (options.instrumentForCoverage) { - code = await instrumentCoverage(filename, code, useInputSourcemap); + const result = await instrumentCoverage(filename, code, useInputSourcemap); + code = result.code; + coverageMap = result.map; } if (shouldLink) { @@ -120,8 +129,8 @@ async function transformJavaScriptImpl( const result = await transformAsync(code, { filename, - inputSourceMap: (useInputSourcemap ? undefined : false) as undefined, - sourceMaps: useInputSourcemap ? 'inline' : false, + inputSourceMap: false, + sourceMaps: !!useInputSourcemap, compact: false, configFile: false, babelrc: false, @@ -144,6 +153,9 @@ async function transformJavaScriptImpl( }); code = result?.code ?? code; + if (result?.map) { + maps.push(result.map as EncodedSourceMap); + } } else { oxcLinkerModule ??= await import('../angular/linker/oxc-linker.js'); const result = oxcLinkerModule.linkWithOxc(filename, code, { @@ -152,39 +164,52 @@ async function transformJavaScriptImpl( skipCheck: true, }); code = result.code; - if (useInputSourcemap && result.map) { - code = removeSourceMappingURL(code); - const base64Map = Buffer.from(result.map).toString('base64'); - code += `\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,${base64Map}`; + if (result.map) { + maps.push(result.map); } } } // Run advanced optimizations using our fast oxc-transform if (options.advancedOptimizations) { - const { transform } = await import('../oxc/oxc-transform.js'); + oxcTransformModule ??= await import('../oxc/oxc-transform.js'); const sideEffectFree = options.sideEffects === false; const safeAngularPackage = sideEffectFree && /[\\/]node_modules[\\/]@angular[\\/]/.test(filename); const topLevelSafeMode = !safeAngularPackage; - const result = transform(filename, code, { + const result = oxcTransformModule.transform(filename, code, { sourcemap: useInputSourcemap, sideEffects: options.sideEffects, topLevelSafeMode, }); code = result.code; + if (result.map) { + maps.push(result.map); + } + } - if (useInputSourcemap && result.map) { - // Strip old source map comment if Babel added one + if (useInputSourcemap) { + const baseMap = coverageMap ?? loadInputSourceMap(filename, data); + if (maps.length > 0 || coverageMap) { code = removeSourceMappingURL(code); - const base64Map = Buffer.from(result.map).toString('base64'); - code += `\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,${base64Map}`; + const remappingChain: (DecodedSourceMap | EncodedSourceMap)[] = maps.reverse(); + if (baseMap) { + remappingChain.push(baseMap); + } + + if (remappingChain.length > 0) { + const finalMap = remapping(remappingChain, () => null).toString(); + const base64Map = Buffer.from(finalMap).toString('base64'); + code += `\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,${base64Map}`; + } } + + return code; } // Strip sourcemaps if they should not be used - return useInputSourcemap ? code : removeSourceMappingURL(code); + return removeSourceMappingURL(code); } function requiresLinking(path: string, source: string): boolean { diff --git a/packages/angular/build/src/tools/esbuild/javascript-transformer_spec.ts b/packages/angular/build/src/tools/esbuild/javascript-transformer_spec.ts new file mode 100644 index 000000000000..5fa0c708675b --- /dev/null +++ b/packages/angular/build/src/tools/esbuild/javascript-transformer_spec.ts @@ -0,0 +1,242 @@ +/** + * @license + * Copyright Google LLC All Rights Reserved. + * + * Use of this source code is governed by an MIT-style license that can be + * found in the LICENSE file at https://angular.dev/license + */ + +import { JavaScriptTransformer } from './javascript-transformer'; + +describe('JavaScriptTransformer sourcemaps', () => { + let transformer: JavaScriptTransformer; + + afterEach(async () => { + await transformer?.close(); + }); + + function extractSourcemap(code: string): Record | null { + const match = code.match( + /\/\/# sourceMappingURL=data:application\/json;charset=utf-8;base64,(.+)/, + ); + if (!match) { + return null; + } + + return JSON.parse(Buffer.from(match[1], 'base64').toString('utf-8')); + } + + it('should remap correctly when only advanced optimizations are applied', async () => { + transformer = new JavaScriptTransformer( + { + sourcemap: true, + advancedOptimizations: true, + }, + 1, + ); + + const inputMap = { + version: 3, + sources: ['src/app.ts'], + sourcesContent: ['const x = new SomeClass();'], + mappings: 'AAAA', + names: [], + }; + const base64Map = Buffer.from(JSON.stringify(inputMap)).toString('base64'); + const input = `var x = new SomeClass();\n//# sourceMappingURL=data:application/json;base64,${base64Map}`; + + const result = await transformer.transformData('src/app.js', input, true); + const text = Buffer.from(result).toString('utf-8'); + const map = extractSourcemap(text); + + expect(map).toBeDefined(); + expect(map?.['version']).toBe(3); + expect(map?.['sources']).toContain('src/app.ts'); + expect(typeof map?.['mappings']).toBe('string'); + expect((map?.['mappings'] as string).length).toBeGreaterThan(0); + }); + + it('should remap correctly when only linking is applied', async () => { + transformer = new JavaScriptTransformer( + { + sourcemap: true, + thirdPartySourcemaps: true, + }, + 1, + ); + + const inputMap = { + version: 3, + sources: ['node_modules/my-lib/directive.ts'], + sourcesContent: ['export class MyDirective {}'], + mappings: 'AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA', + names: [], + }; + const base64Map = Buffer.from(JSON.stringify(inputMap)).toString('base64'); + const input = ` + import * as i0 from "@angular/core"; + export class MyDirective {} + MyDirective.ɵdir = i0.ɵɵngDeclareDirective({ + minVersion: "12.0.0", + version: "14.0.0", + ngImport: i0, + type: MyDirective, + selector: "[my-dir]" + }); + //# sourceMappingURL=data:application/json;base64,${base64Map} + `; + + const result = await transformer.transformData( + 'node_modules/my-lib/directive.js', + input, + false, + ); + const text = Buffer.from(result).toString('utf-8'); + const map = extractSourcemap(text); + + expect(map).toBeDefined(); + expect(map?.['version']).toBe(3); + expect(map?.['sources']).toContain('node_modules/my-lib/directive.ts'); + expect(typeof map?.['mappings']).toBe('string'); + expect((map?.['mappings'] as string).length).toBeGreaterThan(0); + }); + + it('should defer and chain remapping when both linking and advanced optimizations are applied', async () => { + transformer = new JavaScriptTransformer( + { + sourcemap: true, + thirdPartySourcemaps: true, + advancedOptimizations: true, + }, + 1, + ); + + const inputMap = { + version: 3, + sources: ['node_modules/my-lib/component.ts'], + sourcesContent: ['export class MyComponent {}'], + mappings: 'AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA', + names: [], + }; + const base64Map = Buffer.from(JSON.stringify(inputMap)).toString('base64'); + const input = ` + import * as i0 from "@angular/core"; + export class MyComponent {} + MyComponent.ɵcmp = i0.ɵɵngDeclareComponent({ + minVersion: "12.0.0", + version: "14.0.0", + ngImport: i0, + type: MyComponent, + selector: "my-cmp", + template: "
" + }); + //# sourceMappingURL=data:application/json;base64,${base64Map} + `; + + const result = await transformer.transformData( + 'node_modules/my-lib/component.js', + input, + false, + ); + const text = Buffer.from(result).toString('utf-8'); + const map = extractSourcemap(text); + + expect(map).toBeDefined(); + expect(map?.['version']).toBe(3); + expect(map?.['sources']).toContain('node_modules/my-lib/component.ts'); + expect(typeof map?.['mappings']).toBe('string'); + expect((map?.['mappings'] as string).length).toBeGreaterThan(0); + }); + + it('should produce a valid sourcemap when no input sourcemap is present', async () => { + transformer = new JavaScriptTransformer( + { + sourcemap: true, + advancedOptimizations: true, + }, + 1, + ); + + const input = 'var x = new SomeClass();'; + const result = await transformer.transformData('src/app.js', input, true); + const text = Buffer.from(result).toString('utf-8'); + const map = extractSourcemap(text); + + expect(map).toBeDefined(); + expect(map?.['version']).toBe(3); + expect(map?.['sources']).toContain('src/app.js'); + expect(typeof map?.['mappings']).toBe('string'); + expect((map?.['mappings'] as string).length).toBeGreaterThan(0); + }); + + it('should remap correctly when coverage instrumentation is applied with an input sourcemap', async () => { + transformer = new JavaScriptTransformer( + { + sourcemap: true, + }, + 1, + ); + + const inputMap = { + version: 3, + sources: ['src/counter.ts'], + sourcesContent: ['export function add(a: number, b: number) { return a + b; }'], + mappings: 'AAAA', + names: [], + }; + const base64Map = Buffer.from(JSON.stringify(inputMap)).toString('base64'); + const input = `export function add(a, b) { return a + b; }\n//# sourceMappingURL=data:application/json;base64,${base64Map}`; + + const result = await transformer.transformData( + 'src/counter.js', + input, + true, + undefined, + true /* instrumentForCoverage */, + ); + const text = Buffer.from(result).toString('utf-8'); + const map = extractSourcemap(text); + + expect(map).toBeDefined(); + expect(map?.['version']).toBe(3); + expect(map?.['sources']).toContain('src/counter.ts'); + expect(typeof map?.['mappings']).toBe('string'); + expect((map?.['mappings'] as string).length).toBeGreaterThan(0); + }); + + it('should defer and chain remapping when coverage instrumentation and advanced optimizations are applied', async () => { + transformer = new JavaScriptTransformer( + { + sourcemap: true, + advancedOptimizations: true, + }, + 1, + ); + + const inputMap = { + version: 3, + sources: ['src/app.ts'], + sourcesContent: ['const x = new SomeClass();'], + mappings: 'AAAA', + names: [], + }; + const base64Map = Buffer.from(JSON.stringify(inputMap)).toString('base64'); + const input = `var x = new SomeClass();\n//# sourceMappingURL=data:application/json;base64,${base64Map}`; + + const result = await transformer.transformData( + 'src/app.js', + input, + true, + undefined, + true /* instrumentForCoverage */, + ); + const text = Buffer.from(result).toString('utf-8'); + const map = extractSourcemap(text); + + expect(map).toBeDefined(); + expect(map?.['version']).toBe(3); + expect(map?.['sources']).toContain('src/app.ts'); + expect(typeof map?.['mappings']).toBe('string'); + expect((map?.['mappings'] as string).length).toBeGreaterThan(0); + }); +}); diff --git a/packages/angular/build/src/tools/oxc/oxc-transform.ts b/packages/angular/build/src/tools/oxc/oxc-transform.ts index 14e5a6b0ea97..bec14cd40385 100644 --- a/packages/angular/build/src/tools/oxc/oxc-transform.ts +++ b/packages/angular/build/src/tools/oxc/oxc-transform.ts @@ -6,11 +6,10 @@ * found in the LICENSE file at https://angular.dev/license */ -import remapping, { type DecodedSourceMap } from '@ampproject/remapping'; +import type { DecodedSourceMap } from '@ampproject/remapping'; import type { BindingIdentifier, Class, Node } from '@oxc-project/types'; import { MagicString } from 'magic-string'; import { Visitor, parseSync } from 'oxc-parser'; -import { loadInputSourceMap } from '../../utils/source-map'; export interface OxcTransformOptions { sourcemap?: boolean; @@ -747,19 +746,10 @@ export function transform(filename: string, code: string, options: OxcTransformO visitor.visit(program); - let map: string | undefined; + let map: DecodedSourceMap | undefined; if (options.sourcemap) { - const inputMap = loadInputSourceMap(filename, code); - - if (inputMap) { - const rawMap = s.generateDecodedMap({ hires: true, source: filename }); - map = remapping( - [{ ...rawMap, version: 3 } satisfies DecodedSourceMap, inputMap], - () => null, - ).toString(); - } else { - map = s.generateMap({ hires: true, source: filename }).toString(); - } + const rawMap = s.generateDecodedMap({ hires: true, source: filename }); + map = { ...rawMap, version: 3 }; } return { diff --git a/packages/angular/build/src/tools/oxc/oxc-transform_spec.ts b/packages/angular/build/src/tools/oxc/oxc-transform_spec.ts index ee37c7fec1fb..daa4cf554634 100644 --- a/packages/angular/build/src/tools/oxc/oxc-transform_spec.ts +++ b/packages/angular/build/src/tools/oxc/oxc-transform_spec.ts @@ -9,34 +9,13 @@ import { transform } from './oxc-transform'; describe('oxc-transform sourcemaps', () => { - it('should generate a sourcemap when sourcemap option is enabled without inputMap', () => { + it('should generate a decoded sourcemap when sourcemap option is enabled', () => { const input = 'var result = new SomeClass();'; const result = transform('test.js', input, { sourcemap: true }); expect(result.map).toBeDefined(); - const parsedMap = JSON.parse(result.map as string); - expect(parsedMap.version).toBe(3); - expect(parsedMap.sources).toContain('test.js'); - expect(parsedMap.mappings.length).toBeGreaterThan(0); - }); - - it('should remap with input sourcemap when sourcemap option is enabled and inputMap is present', () => { - const inputMap = { - version: 3, - sources: ['original.ts'], - sourcesContent: ['const result = new SomeClass();'], - mappings: 'AAAA', - names: [], - }; - const base64Map = Buffer.from(JSON.stringify(inputMap)).toString('base64'); - const input = `var result = new SomeClass();\n//# sourceMappingURL=data:application/json;base64,${base64Map}`; - - const result = transform('test.js', input, { sourcemap: true }); - - expect(result.map).toBeDefined(); - const parsedMap = JSON.parse(result.map as string); - expect(parsedMap.version).toBe(3); - expect(parsedMap.sources).toContain('original.ts'); - expect(parsedMap.mappings.length).toBeGreaterThan(0); + expect(result.map?.version).toBe(3); + expect(result.map?.sources).toContain('test.js'); + expect(result.map?.mappings.length).toBeGreaterThan(0); }); }); From 5ee54207e2ee648c0f46622179f990cb392be79d Mon Sep 17 00:00:00 2001 From: Charles Lyding <19598772+clydin@users.noreply.github.com> Date: Thu, 6 Aug 2026 11:15:08 -0400 Subject: [PATCH 259/787] refactor(@angular/build): bypass worker dispatch for untransformed files in JS transformer Make transformData symmetrical to accept both string and Uint8Array inputs, allowing transformFile to directly delegate to transformData after reading from disk or cache. When no transformations are required, untransformed files bypass worker pool dispatch, thread synchronization, and string decoding overhead. In addition, introduce a fast byte-level check on raw ASCII bytes using a pre-allocated comment buffer to immediately return untouched buffers when no sourcemap comment exists. --- .../esbuild/javascript-transformer-worker.ts | 4 + .../tools/esbuild/javascript-transformer.ts | 93 ++++++++++++------- .../esbuild/javascript-transformer_spec.ts | 52 +++++++++++ 3 files changed, 115 insertions(+), 34 deletions(-) diff --git a/packages/angular/build/src/tools/esbuild/javascript-transformer-worker.ts b/packages/angular/build/src/tools/esbuild/javascript-transformer-worker.ts index 7dfefbb2de55..49ba241d99b3 100644 --- a/packages/angular/build/src/tools/esbuild/javascript-transformer-worker.ts +++ b/packages/angular/build/src/tools/esbuild/javascript-transformer-worker.ts @@ -89,6 +89,10 @@ export default async function transformJavaScript( const transformedData = await transformJavaScriptImpl(filename, textData, options); // Transfer the data via `move` instead of cloning + if (transformedData === textData && typeof data !== 'string') { + return Piscina.move(data); + } + return Piscina.move(textEncoder.encode(transformedData)); } diff --git a/packages/angular/build/src/tools/esbuild/javascript-transformer.ts b/packages/angular/build/src/tools/esbuild/javascript-transformer.ts index de4103f57559..bb5c432c25b8 100644 --- a/packages/angular/build/src/tools/esbuild/javascript-transformer.ts +++ b/packages/angular/build/src/tools/esbuild/javascript-transformer.ts @@ -13,6 +13,8 @@ import { removeSourceMappingURL } from '../../utils/source-map'; import { WorkerPool, WorkerPoolOptions } from '../../utils/worker-pool'; import { Cache } from './cache'; +const SOURCEMAP_COMMENT_BYTES = Buffer.from('sourceMappingURL='); + /** * Transformation options that should apply to all transformed files and data. */ @@ -132,12 +134,10 @@ export class JavaScriptTransformer { return this.#runWithThrottle(async () => { const data = await readFile(filename); - let result; - let cacheKey; + let cacheKey: string | undefined; if (this.cache) { // Create a cache key from the file data and options that effect the output. // NOTE: If additional options are added, this may need to be updated. - // TODO: Consider xxhash or similar instead of SHA256 const hash = createHash('sha256'); hash.update(`${!!skipLinker}--${!!sideEffects}`); hash.update(data); @@ -145,37 +145,28 @@ export class JavaScriptTransformer { cacheKey = hash.digest('hex'); try { - result = await this.cache?.get(cacheKey); + const cached = await this.cache.get(cacheKey); + if (cached !== undefined) { + return cached; + } } catch { // Failure to get the value should not fail the transform } } - if (result === undefined) { - // If there is no cache or no cached entry, process the file - result = (await this.#ensureWorkerPool().run( - { - filename, - data, - skipLinker, - sideEffects, - instrumentForCoverage, - ...this.#commonOptions, - }, - { - // The below is disable as with Yarn PNP this causes build failures with the below message - // `Unable to deserialize cloned data`. - transferList: process.versions.pnp ? undefined : [data.buffer], - }, - )) as Uint8Array; - - // If there is a cache then store the result - if (this.cache && cacheKey) { - try { - await this.cache.put(cacheKey, result); - } catch { - // Failure to store the value in the cache should not fail the transform - } + const result = await this.transformData( + filename, + data, + !!skipLinker, + sideEffects, + instrumentForCoverage, + ); + + if (this.cache && cacheKey) { + try { + await this.cache.put(cacheKey, result); + } catch { + // Failure to store the value in the cache should not fail the transform } } @@ -194,7 +185,7 @@ export class JavaScriptTransformer { */ async transformData( filename: string, - data: string, + data: string | Uint8Array, skipLinker: boolean, sideEffects?: boolean, instrumentForCoverage?: boolean, @@ -206,18 +197,52 @@ export class JavaScriptTransformer { this.#commonOptions.sourcemap && (!!this.#commonOptions.thirdPartySourcemaps || !/[\\/]node_modules[\\/]/.test(filename)); - return Buffer.from(keepSourcemap ? data : removeSourceMappingURL(data), 'utf-8'); + if (typeof data === 'string') { + return Buffer.from(keepSourcemap ? data : removeSourceMappingURL(data), 'utf-8'); + } + + if (keepSourcemap) { + return data; + } + + const dataBuffer = Buffer.isBuffer(data) + ? data + : Buffer.from(data.buffer, data.byteOffset, data.byteLength); + + // Fast check on raw ASCII bytes to avoid UTF-8 string decoding if no comment exists. + if (dataBuffer.indexOf(SOURCEMAP_COMMENT_BYTES) === -1) { + return data; + } + + const text = dataBuffer.toString('utf-8'); + const stripped = removeSourceMappingURL(text); + + return stripped === text ? data : Buffer.from(stripped, 'utf-8'); } - return this.#runWithThrottle(() => - this.#ensureWorkerPool().run({ + // Only standalone (non-pooled) ArrayBuffers can be transferred across worker threads. + // Node.js shares an internal 8KB ArrayBuffer pool for small buffers, and transferring + // a pooled buffer will throw a DataCloneError because detaching it invalidates other slices. + // In addition, SharedArrayBuffers cannot be transferred, and Yarn PnP has deserialization issues. + const isTransferable = + typeof data !== 'string' && + data.buffer instanceof ArrayBuffer && + data.byteOffset === 0 && + data.byteLength === data.buffer.byteLength && + !process.versions.pnp; + + return this.#ensureWorkerPool().run( + { filename, data, skipLinker, sideEffects, instrumentForCoverage, ...this.#commonOptions, - }), + }, + { + transferList: isTransferable ? [data.buffer] : undefined, + }, ); } diff --git a/packages/angular/build/src/tools/esbuild/javascript-transformer_spec.ts b/packages/angular/build/src/tools/esbuild/javascript-transformer_spec.ts index 5fa0c708675b..5cf7383ab7d0 100644 --- a/packages/angular/build/src/tools/esbuild/javascript-transformer_spec.ts +++ b/packages/angular/build/src/tools/esbuild/javascript-transformer_spec.ts @@ -239,4 +239,56 @@ describe('JavaScriptTransformer sourcemaps', () => { expect(typeof map?.['mappings']).toBe('string'); expect((map?.['mappings'] as string).length).toBeGreaterThan(0); }); + + it('should accept a Uint8Array input in transformData', async () => { + transformer = new JavaScriptTransformer( + { + sourcemap: true, + advancedOptimizations: true, + }, + 1, + ); + + const inputBuffer = Buffer.from('var x = new SomeClass();', 'utf-8'); + const result = await transformer.transformData('src/app.js', inputBuffer, true); + const text = Buffer.from(result).toString('utf-8'); + const map = extractSourcemap(text); + + expect(map).toBeDefined(); + expect(map?.['version']).toBe(3); + expect(map?.['sources']).toContain('src/app.js'); + expect(typeof map?.['mappings']).toBe('string'); + }); + + it('should strip trailing sourcemap comments from Uint8Array input on fast-path', async () => { + transformer = new JavaScriptTransformer( + { + sourcemap: false, + }, + 1, + ); + + const inputBuffer = Buffer.from( + 'console.log("hello");\n//# sourceMappingURL=app.js.map', + 'utf-8', + ); + const result = await transformer.transformData('node_modules/my-lib/lib.js', inputBuffer, true); + const text = Buffer.from(result).toString('utf-8'); + + expect(text).toBe('console.log("hello");\n'); + }); + + it('should return Uint8Array input untouched on fast-path when no sourcemap comment is present', async () => { + transformer = new JavaScriptTransformer( + { + sourcemap: false, + }, + 1, + ); + + const inputBuffer = Buffer.from('console.log("hello");\nconst x = 1;', 'utf-8'); + const result = await transformer.transformData('node_modules/my-lib/lib.js', inputBuffer, true); + + expect(result).toBe(inputBuffer); + }); }); From cda88307108ac1b6207451ce3960539d0bb58c15 Mon Sep 17 00:00:00 2001 From: Charles Lyding <19598772+clydin@users.noreply.github.com> Date: Thu, 6 Aug 2026 13:31:43 -0400 Subject: [PATCH 260/787] refactor(@angular/build): use xxhash-wasm for fast non-cryptographic content hashing Replace OpenSSL SHA-256 with xxhash-wasm for internal non-cryptographic hashing across the build system. This includes JavaScript transformer cache keys, persistent load result disk caches, incremental TypeScript compiler source file versioning, i18n inlining cache keys, stylesheet compilation configuration hashes, and dev server asset ETags. By utilizing a 64-bit non-cryptographic hash backed by WebAssembly, hashing throughput is significantly increased while eliminating V8 OpenSSL C++ context allocations and garbage collection churn during cold and incremental builds. --- packages/angular/build/BUILD.bazel | 1 + packages/angular/build/package.json | 3 +- .../src/builders/application/build-action.ts | 3 + .../src/builders/dev-server/vite/server.ts | 2 + .../src/builders/unit-test/test-discovery.ts | 5 +- .../builders/unit-test/test-discovery_spec.ts | 11 ++- .../build/src/tools/angular/angular-host.ts | 6 +- .../angular/compilation/parallel-worker.ts | 2 + .../tools/esbuild/angular/compiler-plugin.ts | 9 +-- .../esbuild/angular/component-stylesheets.ts | 11 ++- .../tools/esbuild/application-code-bundle.ts | 4 +- .../build/src/tools/esbuild/bundler-files.ts | 8 +- .../build/src/tools/esbuild/i18n-inliner.ts | 21 +++--- .../tools/esbuild/javascript-transformer.ts | 12 +-- .../esbuild/persistent-load-result-cache.ts | 26 +++---- .../stylesheets/stylesheet-cache-key.ts | 58 +++++++-------- .../stylesheets/stylesheet-cache-key_spec.ts | 5 ++ .../vite/middlewares/assets-middleware.ts | 6 +- packages/angular/build/src/utils/hash.ts | 74 +++++++++++++++++++ packages/angular/build/src/utils/hash_spec.ts | 60 +++++++++++++++ pnpm-lock.yaml | 8 ++ 21 files changed, 244 insertions(+), 91 deletions(-) create mode 100644 packages/angular/build/src/utils/hash.ts create mode 100644 packages/angular/build/src/utils/hash_spec.ts diff --git a/packages/angular/build/BUILD.bazel b/packages/angular/build/BUILD.bazel index b2f0cdfd63f1..d2203baebb43 100644 --- a/packages/angular/build/BUILD.bazel +++ b/packages/angular/build/BUILD.bazel @@ -109,6 +109,7 @@ ts_project( ":node_modules/vite", ":node_modules/vitest", ":node_modules/watchpack", + ":node_modules/xxhash-wasm", "//:node_modules/@angular/common", "//:node_modules/@angular/compiler", "//:node_modules/@angular/compiler-cli", diff --git a/packages/angular/build/package.json b/packages/angular/build/package.json index 9b1fdce6b518..baa0faf2a35a 100644 --- a/packages/angular/build/package.json +++ b/packages/angular/build/package.json @@ -41,7 +41,8 @@ "source-map-support": "0.5.21", "tinyglobby": "0.2.17", "vite": "8.2.0", - "watchpack": "2.5.2" + "watchpack": "2.5.2", + "xxhash-wasm": "1.1.0" }, "optionalDependencies": { "lmdb": "3.5.6" diff --git a/packages/angular/build/src/builders/application/build-action.ts b/packages/angular/build/src/builders/application/build-action.ts index dbec8d687b9f..07ed300789d2 100644 --- a/packages/angular/build/src/builders/application/build-action.ts +++ b/packages/angular/build/src/builders/application/build-action.ts @@ -15,6 +15,7 @@ import { shutdownSassWorkerPool } from '../../tools/esbuild/stylesheets/sass-lan import { logMessages, withNoProgress, withSpinner } from '../../tools/esbuild/utils'; import { ChangedFiles } from '../../tools/esbuild/watcher'; import { shouldWatchRoot } from '../../utils/environment-options'; +import { initializeHash } from '../../utils/hash'; import { NormalizedCachedOptions } from '../../utils/normalize-cache'; import { toPosixPath } from '../../utils/path'; import { NormalizedApplicationBuildOptions, NormalizedOutputOptions } from './options'; @@ -78,6 +79,8 @@ export async function* runEsBuildBuildAction( incrementalResults, } = options; + await initializeHash(); + const withProgress: typeof withSpinner = progress ? withSpinner : withNoProgress; // Initial build diff --git a/packages/angular/build/src/builders/dev-server/vite/server.ts b/packages/angular/build/src/builders/dev-server/vite/server.ts index 868590edab95..b1826383fccb 100644 --- a/packages/angular/build/src/builders/dev-server/vite/server.ts +++ b/packages/angular/build/src/builders/dev-server/vite/server.ts @@ -22,6 +22,7 @@ import { } from '../../../tools/vite/plugins'; import { RolldownLoaderOption, getDepOptimizationConfig } from '../../../tools/vite/utils'; import { loadProxyConfiguration } from '../../../utils'; +import { initializeHash } from '../../../utils/hash'; import { type ApplicationBuilderInternalOptions, JavaScriptTransformer } from '../internal'; import type { NormalizedDevServerOptions } from '../options'; import { DevServerExternalResultMetadata, OutputAssetRecord, OutputFileRecord } from './utils'; @@ -147,6 +148,7 @@ export async function setupServer( indexHtmlTransformer?: (content: string) => Promise, thirdPartySourcemaps = false, ): Promise { + await initializeHash(); const { normalizePath } = (await import('vite' as string)) as typeof Vite; // Path will not exist on disk and only used to provide separate path for Vite requests diff --git a/packages/angular/build/src/builders/unit-test/test-discovery.ts b/packages/angular/build/src/builders/unit-test/test-discovery.ts index 7bad7079dc90..f2fc8c221646 100644 --- a/packages/angular/build/src/builders/unit-test/test-discovery.ts +++ b/packages/angular/build/src/builders/unit-test/test-discovery.ts @@ -6,11 +6,11 @@ * found in the LICENSE file at https://angular.dev/license */ -import { createHash } from 'node:crypto'; import { type PathLike, constants, promises as fs } from 'node:fs'; import os from 'node:os'; import { basename, dirname, extname, isAbsolute, join, relative } from 'node:path'; import { glob, isDynamicPattern } from 'tinyglobby'; +import { calculateHash, initializeHash } from '../../utils/hash'; import { toPosixPath } from '../../utils/path'; /** @@ -41,6 +41,7 @@ export async function findTests( workspaceRoot: string, projectSourceRoot: string, ): Promise { + await initializeHash(); const resolvedTestFiles = new Set(); const dynamicPatterns: string[] = []; @@ -194,7 +195,7 @@ function truncateName(name: string, originalPath: string): string { return name; } - const hash = createHash('sha256').update(originalPath).digest('hex').substring(0, 8); + const hash = calculateHash(originalPath).substring(0, 8); const availableLength = MAX_FILENAME_LENGTH - hash.length - 2; // 2 for '-' separators const prefixLength = Math.floor(availableLength / 2); const suffixLength = availableLength - prefixLength; diff --git a/packages/angular/build/src/builders/unit-test/test-discovery_spec.ts b/packages/angular/build/src/builders/unit-test/test-discovery_spec.ts index dcee1718a976..764924d9552b 100644 --- a/packages/angular/build/src/builders/unit-test/test-discovery_spec.ts +++ b/packages/angular/build/src/builders/unit-test/test-discovery_spec.ts @@ -6,9 +6,14 @@ * found in the LICENSE file at https://angular.dev/license */ +import { initializeHash } from '../../utils/hash'; import { generateNameFromPath, getTestEntrypoints } from './test-discovery'; describe('getTestEntrypoints', () => { + beforeAll(async () => { + await initializeHash(); + }); + const workspaceRoot = '/project'; const projectSourceRoot = '/project/src'; const options = { workspaceRoot, projectSourceRoot }; @@ -81,6 +86,10 @@ describe('getTestEntrypoints', () => { }); describe('generateNameFromPath', () => { + beforeAll(async () => { + await initializeHash(); + }); + const roots = ['/project/src/', '/project/']; it('should generate a dash-cased name from a simple path', () => { @@ -127,7 +136,7 @@ describe('generateNameFromPath', () => { expect(result.length).toBeLessThanOrEqual(128); expect(result).toBe( - 'a-very-long-path-that-definitely-exceeds-the-maximum-allowe-9cf40291-me-in-order-to-trigger-the-truncation-logic-in-the-function', + 'a-very-long-path-that-definitely-exceeds-the-maximum-allowe-4af8113d-me-in-order-to-trigger-the-truncation-logic-in-the-function', ); // eslint-disable-line max-len }); diff --git a/packages/angular/build/src/tools/angular/angular-host.ts b/packages/angular/build/src/tools/angular/angular-host.ts index 874d66fe2b41..22ac345d413e 100644 --- a/packages/angular/build/src/tools/angular/angular-host.ts +++ b/packages/angular/build/src/tools/angular/angular-host.ts @@ -8,9 +8,9 @@ import type * as ng from '@angular/compiler-cli'; import assert from 'node:assert'; -import { createHash } from 'node:crypto'; import nodePath from 'node:path'; import type ts from 'typescript'; +import { calculateHash } from '../../utils/hash'; export type AngularCompilerOptions = ng.CompilerOptions; export type AngularCompilerHost = ng.CompilerHost; @@ -46,7 +46,7 @@ export function ensureSourceFileVersions(program: ts.Program): void { for (const file of files) { if (file.version === undefined) { - file.version = createHash('sha256').update(file.text).digest('hex'); + file.version = calculateHash(file.text); } } @@ -227,7 +227,7 @@ export function createAngularCompilerHost( // For external stylesheets, create a unique identifier and store the mapping let externalId = hostOptions.externalStylesheets.get(resolvedPath); if (externalId === undefined) { - externalId = createHash('sha256').update(resolvedPath).digest('hex'); + externalId = calculateHash(resolvedPath); hostOptions.externalStylesheets.set(resolvedPath, externalId); } diff --git a/packages/angular/build/src/tools/angular/compilation/parallel-worker.ts b/packages/angular/build/src/tools/angular/compilation/parallel-worker.ts index 9e41b7940989..95719bf1e3b2 100644 --- a/packages/angular/build/src/tools/angular/compilation/parallel-worker.ts +++ b/packages/angular/build/src/tools/angular/compilation/parallel-worker.ts @@ -10,6 +10,7 @@ import type { PartialMessage } from 'esbuild'; import assert from 'node:assert'; import { randomUUID } from 'node:crypto'; import { type MessagePort, receiveMessageOnPort } from 'node:worker_threads'; +import { initializeHash } from '../../../utils/hash'; import { SourceFileCache } from '../../esbuild/angular/source-file-cache'; import { getAndClearCumulativeDurations } from '../../esbuild/profiling'; import type { AngularCompilation, DiagnosticModes } from './angular-compilation'; @@ -33,6 +34,7 @@ let compilation: AngularCompilation | undefined; const sourceFileCache = new SourceFileCache(); export async function initialize(request: InitRequest) { + await initializeHash(); compilation ??= request.jit ? new JitCompilation(request.browserOnlyBuild) : new AotCompilation(request.browserOnlyBuild); diff --git a/packages/angular/build/src/tools/esbuild/angular/compiler-plugin.ts b/packages/angular/build/src/tools/esbuild/angular/compiler-plugin.ts index 131547f78366..e38b43533790 100644 --- a/packages/angular/build/src/tools/esbuild/angular/compiler-plugin.ts +++ b/packages/angular/build/src/tools/esbuild/angular/compiler-plugin.ts @@ -18,10 +18,10 @@ import type { PluginBuild, } from 'esbuild'; import assert from 'node:assert'; -import { createHash } from 'node:crypto'; import { readFile } from 'node:fs/promises'; import * as path from 'node:path'; import { maxWorkers, useTypeChecking } from '../../../utils/environment-options'; +import { calculateHash, initializeHash } from '../../../utils/hash'; import { AngularHostOptions } from '../../angular/angular-host'; import { AngularCompilation, DiagnosticModes, NoopCompilation } from '../../angular/compilation'; import { type PersistentCacheStore, createPersistentCacheStore } from '../cache'; @@ -149,6 +149,7 @@ export function createCompilerPlugin( // eslint-disable-next-line max-lines-per-function build.onStart(async () => { + await initializeHash(); angularCompilationContext.markAsInProgress(); const result: OnStartResult = { @@ -205,11 +206,7 @@ export function createCompilerPlugin( // invalid the output and force a full page reload for HMR cases. The containing file and order // of the style within the containing file is used. pluginOptions.externalRuntimeStyles - ? createHash('sha256') - .update(containingFile) - .update((order ?? 0).toString()) - .update(className ?? '') - .digest('hex') + ? calculateHash(`${containingFile}${order ?? 0}${className ?? ''}`) : undefined, ); // Adjust result source for inline styles. diff --git a/packages/angular/build/src/tools/esbuild/angular/component-stylesheets.ts b/packages/angular/build/src/tools/esbuild/angular/component-stylesheets.ts index 79008d140729..60c80ce057c6 100644 --- a/packages/angular/build/src/tools/esbuild/angular/component-stylesheets.ts +++ b/packages/angular/build/src/tools/esbuild/angular/component-stylesheets.ts @@ -7,8 +7,8 @@ */ import assert from 'node:assert'; -import { createHash } from 'node:crypto'; import path from 'node:path'; +import { createContentHash } from '../../../utils/hash'; import { BundleContextResult, BundlerContext } from '../bundler-context'; import { type BuildOutputFile, BuildOutputFileType } from '../bundler-files'; import { MemoryCache } from '../cache'; @@ -103,11 +103,10 @@ export class ComponentStylesheetBundler { ): Promise { // Use a hash of the inline stylesheet content to ensure a consistent identifier. External stylesheets will resolve // to the actual stylesheet file path. - // TODO: Consider xxhash instead for hashing - const id = createHash('sha256') - .update(data) - .update(externalId ?? '') - .digest('hex'); + const hasher = createContentHash(); + hasher.update(data); + hasher.update(externalId ?? ''); + const id = hasher.digest(); const entry = [language, id, filename].join(';'); const bundlerContext = await this.#inlineContexts.getOrCreate(entry, () => { diff --git a/packages/angular/build/src/tools/esbuild/application-code-bundle.ts b/packages/angular/build/src/tools/esbuild/application-code-bundle.ts index 37ff846c7400..4e6ddc0fee21 100644 --- a/packages/angular/build/src/tools/esbuild/application-code-bundle.ts +++ b/packages/angular/build/src/tools/esbuild/application-code-bundle.ts @@ -8,11 +8,11 @@ import type { BuildOptions, Plugin } from 'esbuild'; import assert from 'node:assert'; -import { createHash } from 'node:crypto'; import { extname, relative } from 'node:path'; import type { NormalizedApplicationBuildOptions } from '../../builders/application/options'; import { Platform } from '../../builders/application/schema'; import { allowMangle } from '../../utils/environment-options'; +import { calculateHash } from '../../utils/hash'; import { toPosixPath } from '../../utils/path'; import { SERVER_APP_ENGINE_MANIFEST_FILENAME, @@ -566,7 +566,7 @@ function getEsBuildCommonOptions(options: NormalizedApplicationBuildOptions): Bu '', ); - footer = { js: `/**i18n:${createHash('sha256').update(i18nHash).digest('hex')}*/` }; + footer = { js: `/**i18n:${calculateHash(i18nHash)}*/` }; } // Core conditions that are always included diff --git a/packages/angular/build/src/tools/esbuild/bundler-files.ts b/packages/angular/build/src/tools/esbuild/bundler-files.ts index ac33d471a395..168c41e65940 100644 --- a/packages/angular/build/src/tools/esbuild/bundler-files.ts +++ b/packages/angular/build/src/tools/esbuild/bundler-files.ts @@ -7,7 +7,7 @@ */ import type { OutputFile } from 'esbuild'; -import { createHash } from 'node:crypto'; +import { calculateHash } from '../../utils/hash'; export interface InitialFileRecord { entrypoint: boolean; @@ -63,9 +63,7 @@ export function createOutputFile( return this.contents.byteLength; }, get hash(): string { - cachedHash ??= createHash('sha256') - .update(cachedText ?? this.contents) - .digest('hex'); + cachedHash ??= calculateHash(cachedText ?? this.contents); return cachedHash; }, @@ -97,7 +95,7 @@ export function createOutputFile( return cachedText; }, get hash(): string { - cachedHash ??= createHash('sha256').update(this.contents).digest('hex'); + cachedHash ??= calculateHash(this.contents); return cachedHash; }, diff --git a/packages/angular/build/src/tools/esbuild/i18n-inliner.ts b/packages/angular/build/src/tools/esbuild/i18n-inliner.ts index 071097315e5b..678511612afb 100644 --- a/packages/angular/build/src/tools/esbuild/i18n-inliner.ts +++ b/packages/angular/build/src/tools/esbuild/i18n-inliner.ts @@ -7,9 +7,9 @@ */ import assert from 'node:assert'; -import { createHash } from 'node:crypto'; import { extname, join } from 'node:path'; import { serialize } from 'node:v8'; +import { calculateHash, createContentHash } from '../../utils/hash'; import { WorkerPool } from '../../utils/worker-pool'; import { type BuildOutputFile, BuildOutputFileType, createOutputFile } from './bundler-files'; import { type PersistentCacheStore, createPersistentCacheStore } from './cache'; @@ -147,7 +147,7 @@ export class I18nInliner { // Request inlining for each file that contains localize calls const requests = []; - let fileCacheKeyBase: Uint8Array | undefined; + let fileCacheKeyBase: string | undefined; for (const [filename, file] of this.#localizeFiles) { let cacheKey: string | undefined; @@ -160,17 +160,16 @@ export class I18nInliner { // The options are digested here so that each file's key is derived from a fixed number // of bytes. Hashing the options directly would re-hash the full set of messages, which // can be several megabytes, once for every file. - fileCacheKeyBase ??= createHash('sha256') - .update(JSON.stringify({ locale, translation, missingTranslation, shouldOptimize })) - .digest(); + fileCacheKeyBase ??= calculateHash( + JSON.stringify({ locale, translation, missingTranslation, shouldOptimize }), + ); // NOTE: If additional options are added, this may need to be updated. - // TODO: Consider xxhash or similar instead of SHA256 - cacheKey = createHash('sha256') - .update(file.hash) - .update(filename) - .update(fileCacheKeyBase) - .digest('hex'); + const hasher = createContentHash(); + hasher.update(file.hash); + hasher.update(filename); + hasher.update(fileCacheKeyBase); + cacheKey = hasher.digest(); // Failure to get the value should not fail the transform cacheResultPromise = this.#cache.get(cacheKey).catch(() => null); diff --git a/packages/angular/build/src/tools/esbuild/javascript-transformer.ts b/packages/angular/build/src/tools/esbuild/javascript-transformer.ts index bb5c432c25b8..32a0b2b8d07d 100644 --- a/packages/angular/build/src/tools/esbuild/javascript-transformer.ts +++ b/packages/angular/build/src/tools/esbuild/javascript-transformer.ts @@ -6,8 +6,8 @@ * found in the LICENSE file at https://angular.dev/license */ -import { createHash } from 'node:crypto'; import { readFile } from 'node:fs/promises'; +import { createContentHash } from '../../utils/hash'; import { IMPORT_EXEC_ARGV } from '../../utils/server-rendering/esm-in-memory-loader/utils'; import { removeSourceMappingURL } from '../../utils/source-map'; import { WorkerPool, WorkerPoolOptions } from '../../utils/worker-pool'; @@ -138,11 +138,11 @@ export class JavaScriptTransformer { if (this.cache) { // Create a cache key from the file data and options that effect the output. // NOTE: If additional options are added, this may need to be updated. - const hash = createHash('sha256'); - hash.update(`${!!skipLinker}--${!!sideEffects}`); - hash.update(data); - hash.update(this.#fileCacheKeyBase); - cacheKey = hash.digest('hex'); + const hasher = createContentHash(); + hasher.update(`${!!skipLinker}--${!!sideEffects}`); + hasher.update(data); + hasher.update(this.#fileCacheKeyBase); + cacheKey = hasher.digest(); try { const cached = await this.cache.get(cacheKey); diff --git a/packages/angular/build/src/tools/esbuild/persistent-load-result-cache.ts b/packages/angular/build/src/tools/esbuild/persistent-load-result-cache.ts index 82f2b70ed25d..9d1e3ff5cfba 100644 --- a/packages/angular/build/src/tools/esbuild/persistent-load-result-cache.ts +++ b/packages/angular/build/src/tools/esbuild/persistent-load-result-cache.ts @@ -28,10 +28,10 @@ */ import type { Loader, OnLoadResult, PartialMessage } from 'esbuild'; -import { createHash } from 'node:crypto'; import { readFile, stat } from 'node:fs/promises'; import { isAbsolute } from 'node:path'; import { fileURLToPath } from 'node:url'; +import { calculateHash, createContentHash } from '../../utils/hash'; import type { Cache as PersistentCacheStore } from './cache'; import { LoadResultCache, MemoryLoadResultCache } from './load-result-cache'; @@ -70,10 +70,6 @@ export interface CachedLoadResultEntry { errors?: PartialMessage[]; } -function hashContent(content: string | Uint8Array): string { - return createHash('sha256').update(content).digest('hex'); -} - /** * Calculates a unique cache key by updating the hash incrementally. * This prevents implicit string coercion of large binary content buffers. @@ -83,13 +79,14 @@ function calculateCacheKey( path: string, content: string | Uint8Array, ): string { - return createHash('sha256') - .update(globalConfigHash) - .update('\0') - .update(path) - .update('\0') - .update(content) - .digest('hex'); + const hasher = createContentHash(); + hasher.update(globalConfigHash); + hasher.update('\0'); + hasher.update(path); + hasher.update('\0'); + hasher.update(content); + + return hasher.digest(); } /** @@ -193,7 +190,7 @@ async function validateAndHealCacheEntry( // 3. Slow Path for dependencies: content hash fallback const currentContent = await readFile(filePath); - const currentHash = hashContent(currentContent); + const currentHash = calculateHash(currentContent); if (currentHash === expected.hash) { // Heal cache entry with new metadata watchFilesMetadata[filePath] = { @@ -244,8 +241,9 @@ async function computeMetadataForWatchFiles( knownContent !== undefined ? knownContent : readFile(filePath), stat(filePath), ]); + const hash = calculateHash(content); watchFilesMetadata[filePath] = { - hash: hashContent(content), + hash, mtimeMs: stats.mtimeMs, size: stats.size, }; diff --git a/packages/angular/build/src/tools/esbuild/stylesheets/stylesheet-cache-key.ts b/packages/angular/build/src/tools/esbuild/stylesheets/stylesheet-cache-key.ts index 75b0915daa64..22397ab189b3 100644 --- a/packages/angular/build/src/tools/esbuild/stylesheets/stylesheet-cache-key.ts +++ b/packages/angular/build/src/tools/esbuild/stylesheets/stylesheet-cache-key.ts @@ -6,7 +6,7 @@ * found in the LICENSE file at https://angular.dev/license */ -import { createHash } from 'node:crypto'; +import { calculateHash } from '../../../utils/hash'; import type { BundleStylesheetOptions } from './bundle-options'; /** @@ -39,34 +39,30 @@ export function calculateGlobalStylesheetConfigHash( options: BundleStylesheetOptions, packageVersion: string = '', ): string { - return createHash('sha256') - .update( - JSON.stringify({ - optimization: options.optimization, - sourcemap: options.sourcemap, - sourcesContent: options.sourcesContent, - includePaths: options.includePaths, - sassOptions: options.sass - ? { - futureDeprecations: options.sass.futureDeprecations, - fatalDeprecations: options.sass.fatalDeprecations, - silenceDeprecations: options.sass.silenceDeprecations, - } - : undefined, - target: options.target, - publicPath: options.publicPath, - outputNames: options.outputNames, - inlineFonts: options.inlineFonts, - preserveSymlinks: options.preserveSymlinks, - externalDependencies: options.externalDependencies, - postcssConfig: options.postcssConfiguration?.configPath - ? options.postcssConfiguration.configPath - : '', - tailwindConfig: options.tailwindConfiguration?.file - ? options.tailwindConfiguration.file - : '', - packageVersion, - }), - ) - .digest('hex'); + return calculateHash( + JSON.stringify({ + optimization: options.optimization, + sourcemap: options.sourcemap, + sourcesContent: options.sourcesContent, + includePaths: options.includePaths, + sassOptions: options.sass + ? { + futureDeprecations: options.sass.futureDeprecations, + fatalDeprecations: options.sass.fatalDeprecations, + silenceDeprecations: options.sass.silenceDeprecations, + } + : undefined, + target: options.target, + publicPath: options.publicPath, + outputNames: options.outputNames, + inlineFonts: options.inlineFonts, + preserveSymlinks: options.preserveSymlinks, + externalDependencies: options.externalDependencies, + postcssConfig: options.postcssConfiguration?.configPath + ? options.postcssConfiguration.configPath + : '', + tailwindConfig: options.tailwindConfiguration?.file ? options.tailwindConfiguration.file : '', + packageVersion, + }), + ); } diff --git a/packages/angular/build/src/tools/esbuild/stylesheets/stylesheet-cache-key_spec.ts b/packages/angular/build/src/tools/esbuild/stylesheets/stylesheet-cache-key_spec.ts index 4e674b968fdd..c524a2d0c36b 100644 --- a/packages/angular/build/src/tools/esbuild/stylesheets/stylesheet-cache-key_spec.ts +++ b/packages/angular/build/src/tools/esbuild/stylesheets/stylesheet-cache-key_spec.ts @@ -6,10 +6,15 @@ * found in the LICENSE file at https://angular.dev/license */ +import { initializeHash } from '../../../utils/hash'; import type { BundleStylesheetOptions } from './bundle-options'; import { calculateGlobalStylesheetConfigHash } from './stylesheet-cache-key'; describe('Stylesheet Global Config Hash', () => { + beforeAll(async () => { + await initializeHash(); + }); + const baseOptions: BundleStylesheetOptions = { workspaceRoot: '/root', optimization: true, diff --git a/packages/angular/build/src/tools/vite/middlewares/assets-middleware.ts b/packages/angular/build/src/tools/vite/middlewares/assets-middleware.ts index cf98614bc55b..02f54756eaff 100644 --- a/packages/angular/build/src/tools/vite/middlewares/assets-middleware.ts +++ b/packages/angular/build/src/tools/vite/middlewares/assets-middleware.ts @@ -7,7 +7,6 @@ */ import { lookup as lookupMimeType } from 'mrmime'; -import { createHash } from 'node:crypto'; import { readFileSync } from 'node:fs'; import type { ServerResponse } from 'node:http'; import { extname } from 'node:path'; @@ -15,6 +14,7 @@ import type { Connect, ViteDevServer } from 'vite' with { 'resolution-mode': 'import', }; import { ResultFile } from '../../../builders/application/results'; +import { calculateHash } from '../../../utils/hash'; import { AngularMemoryOutputFiles, AngularOutputAssets, pathnameWithoutBasePath } from '../utils'; export interface ComponentStyleRecord { @@ -50,7 +50,7 @@ export function createAngularAssetsMiddleware( // This is a workaround to serve extensionless, CSS, JS and TS files without Vite transformations. if (!extension || JS_TS_REGEXP.test(extension) || CSS_PREPROCESSOR_REGEXP.test(extension)) { const contents = readFileSync(asset.source); - const etag = `W/${createHash('sha256').update(contents).digest('hex')}`; + const etag = `W/${calculateHash(contents)}`; if (checkAndHandleEtag(req, res, etag)) { return; } @@ -238,7 +238,7 @@ export function createBuildAssetsMiddleware( const contents = outputFile.origin === 'memory' ? outputFile.contents : readHandler(outputFile.inputPath); - const etag = `W/${createHash('sha256').update(contents).digest('hex')}`; + const etag = `W/${calculateHash(contents)}`; if (checkAndHandleEtag(req, res, etag)) { return; } diff --git a/packages/angular/build/src/utils/hash.ts b/packages/angular/build/src/utils/hash.ts new file mode 100644 index 000000000000..fdc5565afbb1 --- /dev/null +++ b/packages/angular/build/src/utils/hash.ts @@ -0,0 +1,74 @@ +/** + * @license + * Copyright Google LLC All Rights Reserved. + * + * Use of this source code is governed by an MIT-style license that can be + * found in the LICENSE file at https://angular.dev/license + */ + +import assert from 'node:assert'; +import type { XXHashAPI } from 'xxhash-wasm'; + +let xxhashInstance: XXHashAPI | undefined; +let xxhashPromise: Promise | undefined; + +/** + * Initializes the xxHash WASM instance early to ensure synchronous hashing uses xxHash. + */ +export async function initializeHash(): Promise { + if (xxhashInstance) { + return; + } + + xxhashPromise ??= import('xxhash-wasm').then((m) => m.default()); + xxhashInstance = await xxhashPromise; +} + +function getXxhash(): XXHashAPI { + assert( + xxhashInstance, + 'Hash utility must be initialized by awaiting `initializeHash()` before use.', + ); + + return xxhashInstance; +} + +/** + * Calculates a fast 64-bit non-cryptographic hash of the provided content. + * Suitable for cache keys, ETags, and change detection. + */ +export function calculateHash(data: string | Uint8Array): string { + const instance = getXxhash(); + + if (typeof data === 'string') { + return instance.h64ToString(data); + } + + return instance.h64Raw(data).toString(16).padStart(16, '0'); +} + +export interface ContentHasher { + update(data: string | Uint8Array): ContentHasher; + digest(): string; +} + +/** + * Creates a streaming 64-bit non-cryptographic content hasher. + */ +export function createContentHash(): ContentHasher { + const instance = getXxhash(); + const hasher = instance.create64(); + + const contentHasher: ContentHasher = { + update(data: string | Uint8Array): ContentHasher { + hasher.update(data); + + return contentHasher; + }, + digest(): string { + return hasher.digest().toString(16).padStart(16, '0'); + }, + }; + + return contentHasher; +} diff --git a/packages/angular/build/src/utils/hash_spec.ts b/packages/angular/build/src/utils/hash_spec.ts new file mode 100644 index 000000000000..77fcbc909403 --- /dev/null +++ b/packages/angular/build/src/utils/hash_spec.ts @@ -0,0 +1,60 @@ +/** + * @license + * Copyright Google LLC All Rights Reserved. + * + * Use of this source code is governed by an MIT-style license that can be + * found in the LICENSE file at https://angular.dev/license + */ + +import { calculateHash, createContentHash, initializeHash } from './hash'; + +describe('hash utility', () => { + beforeAll(async () => { + await initializeHash(); + }); + + it('should calculate identical 64-bit hex hash for string and Buffer with same content', () => { + const text = 'export const message = "hello world";'; + const buffer = Buffer.from(text, 'utf-8'); + + const stringHash = calculateHash(text); + const bufferHash = calculateHash(buffer); + + expect(typeof stringHash).toBe('string'); + expect(stringHash.length).toBe(16); + expect(stringHash).toBe(bufferHash); + }); + + it('should calculate different hashes for different contents', () => { + const hash1 = calculateHash('const a = 1;'); + const hash2 = calculateHash('const a = 2;'); + + expect(hash1).not.toBe(hash2); + }); + + it('should support streaming multi-part hashing matching combined single-shot hash', () => { + const part1 = 'header: '; + const part2 = 'body content: '; + const part3 = 'footer'; + + const hasher = createContentHash(); + hasher.update(part1); + hasher.update(part2); + hasher.update(Buffer.from(part3, 'utf-8')); + const streamingHash = hasher.digest(); + + const singleShotHash = calculateHash(part1 + part2 + part3); + + expect(streamingHash.length).toBe(16); + expect(streamingHash).toBe(singleShotHash); + }); + + it('should handle Uint8Array chunks in streaming hasher', () => { + const hasher = createContentHash(); + hasher.update(new Uint8Array([1, 2, 3, 4])).update('some-string'); + const digest = hasher.digest(); + + expect(typeof digest).toBe('string'); + expect(digest.length).toBe(16); + }); +}); diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index f26c9fa085e9..32052321a9c3 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -400,6 +400,9 @@ importers: watchpack: specifier: 2.5.2 version: 2.5.2 + xxhash-wasm: + specifier: 1.1.0 + version: 1.1.0 devDependencies: '@angular-devkit/core': specifier: workspace:* @@ -8257,6 +8260,9 @@ packages: resolution: {integrity: sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==} engines: {node: '>=0.4'} + xxhash-wasm@1.1.0: + resolution: {integrity: sha512-147y/6YNh+tlp6nd/2pWq38i9h6mz/EuQ6njIrmW8D1BS5nCqs0P6DG+m6zTGnNz5I+uhZ0SHxBs9BsPrwcKDA==} + y18n@5.0.8: resolution: {integrity: sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==} engines: {node: '>=10'} @@ -16665,6 +16671,8 @@ snapshots: xtend@4.0.2: {} + xxhash-wasm@1.1.0: {} + y18n@5.0.8: {} yallist@3.1.1: {} From 3c7ac1518b062f14409b4d3c6c3e65c956424ad9 Mon Sep 17 00:00:00 2001 From: Alan Agius <17563226+alan-agius4@users.noreply.github.com> Date: Fri, 7 Aug 2026 09:57:15 +0000 Subject: [PATCH 261/787] fix(@angular/build): return only lowest version per target engine Only the lowest version for each browser and Node.js target is returned to avoid issues with esbuild and Rolldown when multiple versions of the same target engine are specified. In addition, target resolution logic is moved to `src/tools/esbuild/target.ts`. See: https://github.com/evanw/esbuild/issues/4509 See: https://github.com/rolldown/rolldown/issues/10633 --- packages/angular/build/BUILD.bazel | 2 +- .../src/builders/application/execute-build.ts | 7 +- .../builders/application/setup-bundling.ts | 2 +- .../build/src/builders/dev-server/internal.ts | 2 +- .../src/builders/dev-server/vite/index.ts | 14 +-- packages/angular/build/src/private.ts | 2 +- .../angular/build/src/tools/esbuild/target.ts | 116 ++++++++++++++++++ .../build/src/tools/esbuild/target_spec.ts | 80 ++++++++++++ .../angular/build/src/tools/esbuild/utils.ts | 68 +--------- 9 files changed, 208 insertions(+), 85 deletions(-) create mode 100644 packages/angular/build/src/tools/esbuild/target.ts create mode 100644 packages/angular/build/src/tools/esbuild/target_spec.ts diff --git a/packages/angular/build/BUILD.bazel b/packages/angular/build/BUILD.bazel index d2203baebb43..fca820c8f2ed 100644 --- a/packages/angular/build/BUILD.bazel +++ b/packages/angular/build/BUILD.bazel @@ -338,7 +338,7 @@ npm_package( ], stamp_files = [ "src/utils/version.js", - "src/tools/esbuild/utils.js", + "src/tools/esbuild/target.js", "src/utils/normalize-cache.js", "src/utils/supported-browsers.js", ], diff --git a/packages/angular/build/src/builders/application/execute-build.ts b/packages/angular/build/src/builders/application/execute-build.ts index faa61c6e523b..53aaec882cbf 100644 --- a/packages/angular/build/src/builders/application/execute-build.ts +++ b/packages/angular/build/src/builders/application/execute-build.ts @@ -18,11 +18,8 @@ import { checkCommonJSModules } from '../../tools/esbuild/commonjs-checker'; import { LOCALE_DATA_BASE_MODULE } from '../../tools/esbuild/i18n-locale-plugin'; import { extractLicenses } from '../../tools/esbuild/license-extractor'; import { profileAsync } from '../../tools/esbuild/profiling'; -import { - calculateEstimatedTransferSizes, - logBuildStats, - transformSupportedBrowsersToTargets, -} from '../../tools/esbuild/utils'; +import { transformSupportedBrowsersToTargets } from '../../tools/esbuild/target'; +import { calculateEstimatedTransferSizes, logBuildStats } from '../../tools/esbuild/utils'; import { BudgetCalculatorResult, checkBudgets } from '../../utils/bundle-calculator'; import { optimizeChunksThreshold } from '../../utils/environment-options'; import { resolveAssets } from '../../utils/resolve-assets'; diff --git a/packages/angular/build/src/builders/application/setup-bundling.ts b/packages/angular/build/src/builders/application/setup-bundling.ts index bb53c0bae902..79209ba0eaf9 100644 --- a/packages/angular/build/src/builders/application/setup-bundling.ts +++ b/packages/angular/build/src/builders/application/setup-bundling.ts @@ -19,7 +19,7 @@ import { import { BundlerContext } from '../../tools/esbuild/bundler-context'; import { createGlobalScriptsBundleOptions } from '../../tools/esbuild/global-scripts'; import { createGlobalStylesBundleOptions } from '../../tools/esbuild/global-styles'; -import { getSupportedNodeTargets } from '../../tools/esbuild/utils'; +import { getSupportedNodeTargets } from '../../tools/esbuild/target'; import type { NormalizedApplicationBuildOptions } from './options'; /** diff --git a/packages/angular/build/src/builders/dev-server/internal.ts b/packages/angular/build/src/builders/dev-server/internal.ts index 4e5e97e5cf14..96587acb5cff 100644 --- a/packages/angular/build/src/builders/dev-server/internal.ts +++ b/packages/angular/build/src/builders/dev-server/internal.ts @@ -13,7 +13,7 @@ export { getFeatureSupport, isZonelessApp } from '../../tools/esbuild/utils'; export { type IndexHtmlTransform } from '../../utils/index-file/index-html-generator'; export { purgeStaleBuildCache } from '../../utils/purge-cache'; export { getSupportedBrowsers } from '../../utils/supported-browsers'; -export { transformSupportedBrowsersToTargets } from '../../tools/esbuild/utils'; +export { transformSupportedBrowsersToTargets } from '../../tools/esbuild/target'; export { buildApplicationInternal } from '../../builders/application'; export type { ApplicationBuilderInternalOptions } from '../../builders/application/options'; export type { ExternalResultMetadata } from '../../tools/esbuild/bundler-execution-result'; diff --git a/packages/angular/build/src/builders/dev-server/vite/index.ts b/packages/angular/build/src/builders/dev-server/vite/index.ts index eeffb6531969..94192ec41b8c 100644 --- a/packages/angular/build/src/builders/dev-server/vite/index.ts +++ b/packages/angular/build/src/builders/dev-server/vite/index.ts @@ -389,15 +389,11 @@ export async function* serveWithVite( ? browserOptions.polyfills : [browserOptions.polyfills]; - // TODO(alanagius): This is a workaround for https://github.com/rolldown/rolldown/issues/10633 - const target = isZonelessApp(polyfills) ? ['es2022'] : ['es2016']; - - // Once the above issue is fixed, uncomment the below code. - // const target = transformSupportedBrowsersToTargets(browsers); - // if (!isZonelessApp(polyfills)) { - // // Rolldown doesn't have an option to support Zone.js/async-await, so we need to support es2016. - // target.push('es2016'); - // } + const target = transformSupportedBrowsersToTargets(browsers); + if (!isZonelessApp(polyfills)) { + // Rolldown doesn't have an option to support Zone.js/async-await, so we need to support es2016. + target.push('es2016'); + } let ssrMode: ServerSsrMode = ServerSsrMode.NoSsr; if ( diff --git a/packages/angular/build/src/private.ts b/packages/angular/build/src/private.ts index f1eb9dccb459..1e99d84c9832 100644 --- a/packages/angular/build/src/private.ts +++ b/packages/angular/build/src/private.ts @@ -34,7 +34,7 @@ export { // Tools export type { ExternalResultMetadata } from './tools/esbuild/bundler-execution-result'; export { emitFilesToDisk } from './tools/esbuild/utils'; -export { transformSupportedBrowsersToTargets } from './tools/esbuild/utils'; +export { transformSupportedBrowsersToTargets } from './tools/esbuild/target'; export { SassWorkerImplementation } from './tools/sass/sass-service'; export { SourceFileCache } from './tools/esbuild/angular/source-file-cache'; diff --git a/packages/angular/build/src/tools/esbuild/target.ts b/packages/angular/build/src/tools/esbuild/target.ts new file mode 100644 index 000000000000..2925905276b7 --- /dev/null +++ b/packages/angular/build/src/tools/esbuild/target.ts @@ -0,0 +1,116 @@ +/** + * @license + * Copyright Google LLC All Rights Reserved. + * + * Use of this source code is governed by an MIT-style license that can be + * found in the LICENSE file at https://angular.dev/license + */ + +import { coerce, compare, minVersion } from 'semver'; + +/** + * Compares two target version strings. + * + * This function is used to determine the lowest version for a given browser target. + * + * @param a The first version string. + * @param b The second version string. + * @returns A negative value if `a` is lower than `b`, a positive value if `a` is higher than `b`, and 0 if they are equal. + */ +function compareTargetVersions(a: string, b: string): number { + const aVersion = coerce(a); + const bVersion = coerce(b); + + if (!aVersion || !bVersion) { + return aVersion ? -1 : bVersion ? 1 : 0; + } + + return compare(aVersion, bVersion); +} + +// https://esbuild.github.io/api/#target +const ESBUILD_SUPPORTED_BROWSERS: ReadonlySet = new Set([ + 'chrome', + 'edge', + 'firefox', + 'ie', + 'ios', + 'node', + 'opera', + 'safari', +]); + +/** + * Transform browserlists result to esbuild target. + * + * Only the lowest version for each browser is returned to avoid issues with esbuild and rolldown + * when multiple versions of the same target engine are specified. + * + * @see https://esbuild.github.io/api/#target + * @see https://github.com/evanw/esbuild/issues/4509 + * @see https://github.com/rolldown/rolldown/issues/10633 + */ +export function transformSupportedBrowsersToTargets(supportedBrowsers: string[]): string[] { + const browsers = new Map(); + + for (const browser of supportedBrowsers) { + let [browserName, version] = browser.toLowerCase().split(' '); + if (!browserName || !version) { + continue; + } + + // browserslist uses the name `ios_saf` for iOS Safari whereas esbuild uses `ios` + if (browserName === 'ios_saf') { + browserName = 'ios'; + } + + if (!ESBUILD_SUPPORTED_BROWSERS.has(browserName)) { + continue; + } + + // browserslist uses ranges `15.2-15.3` versions but only the lowest is required + // to perform minimum supported feature checks. esbuild also expects a single version. + [version] = version.split('-'); + + if (browserName === 'safari' && version === 'tp') { + // esbuild only supports numeric versions so `TP` is converted to a high number (999) since + // a Technology Preview (TP) of Safari is assumed to support all currently known features. + version = '999'; + } else if (!version.includes('.')) { + // A lone major version is considered by esbuild to include all minor versions. However, + // browserslist does not and is also inconsistent in its `.0` version naming. For example, + // Safari 15.0 is named `safari 15` but Safari 16.0 is named `safari 16.0`. + version += '.0'; + } + + const current = browsers.get(browserName); + if (!current || compareTargetVersions(version, current) < 0) { + browsers.set(browserName, version); + } + } + + return Array.from(browsers, ([browserName, version]) => browserName + version); +} + +const SUPPORTED_NODE_VERSIONS = '0.0.0-ENGINES-NODE'; + +/** + * Transform supported Node.js versions to esbuild target. + * + * Only the lowest Node.js version is returned to avoid issues with esbuild and rolldown + * when multiple versions of the same target engine are specified. + * + * @see https://esbuild.github.io/api/#target + * @see https://github.com/evanw/esbuild/issues/4509 + * @see https://github.com/rolldown/rolldown/issues/10633 + */ +export function getSupportedNodeTargets(): string[] { + if (SUPPORTED_NODE_VERSIONS.charAt(0) === '0') { + // Unlike `pkg_npm`, `ts_library` which is used to run unit tests does not support substitutions. + return []; + } + + const parsed = minVersion(SUPPORTED_NODE_VERSIONS); + + return parsed ? ['node' + parsed.version] : []; +} diff --git a/packages/angular/build/src/tools/esbuild/target_spec.ts b/packages/angular/build/src/tools/esbuild/target_spec.ts new file mode 100644 index 000000000000..e5a375a1412b --- /dev/null +++ b/packages/angular/build/src/tools/esbuild/target_spec.ts @@ -0,0 +1,80 @@ +/** + * @license + * Copyright Google LLC All Rights Reserved. + * + * Use of this source code is governed by an MIT-style license that can be + * found in the LICENSE file at https://angular.dev/license + */ + +import { getSupportedNodeTargets, transformSupportedBrowsersToTargets } from './target'; + +describe('esbuild target', () => { + describe('transformSupportedBrowsersToTargets', () => { + it('should return the smallest version for each browser', () => { + const targets = transformSupportedBrowsersToTargets([ + 'chrome 122', + 'chrome 120', + 'chrome 121', + 'firefox 116', + 'firefox 115', + 'safari 17.0', + 'safari 16.4', + ]); + + expect(targets).toEqual(['chrome120.0', 'firefox115.0', 'safari16.4']); + }); + + it('should handle version ranges and pick the lowest version', () => { + const targets = transformSupportedBrowsersToTargets([ + 'ios_saf 15.4', + 'ios_saf 15.2-15.3', + 'ios_saf 16.0', + ]); + + expect(targets).toEqual(['ios15.2']); + }); + + it('should handle Safari TP (Technology Preview)', () => { + const targetsWithOlderSafari = transformSupportedBrowsersToTargets([ + 'safari TP', + 'safari 16.4', + ]); + expect(targetsWithOlderSafari).toEqual(['safari16.4']); + + const targetsWithOnlyTP = transformSupportedBrowsersToTargets(['safari TP']); + expect(targetsWithOnlyTP).toEqual(['safari999']); + }); + + it('should ignore browsers not supported by esbuild', () => { + const targets = transformSupportedBrowsersToTargets([ + 'android 4.4', + 'samsung 22', + 'kaios 2.5', + 'chrome 115', + ]); + + expect(targets).toEqual(['chrome115.0']); + }); + + it('should return empty array for empty supportedBrowsers', () => { + const targets = transformSupportedBrowsersToTargets([]); + expect(targets).toEqual([]); + }); + + it('should handle malformed or incomplete browser strings gracefully', () => { + const targets = transformSupportedBrowsersToTargets(['chrome', 'firefox ', '']); + expect(targets).toEqual([]); + }); + + it('should handle single major versions by appending .0', () => { + const targets = transformSupportedBrowsersToTargets(['chrome 120', 'edge 120']); + expect(targets).toEqual(['chrome120.0', 'edge120.0']); + }); + }); + + describe('getSupportedNodeTargets', () => { + it('should return empty array when node versions are not stamped', () => { + expect(getSupportedNodeTargets()).toEqual([]); + }); + }); +}); diff --git a/packages/angular/build/src/tools/esbuild/utils.ts b/packages/angular/build/src/tools/esbuild/utils.ts index 6d76623f1493..e4881e184862 100644 --- a/packages/angular/build/src/tools/esbuild/utils.ts +++ b/packages/angular/build/src/tools/esbuild/utils.ts @@ -12,7 +12,6 @@ import { Listr } from 'listr2'; import { basename, join } from 'node:path'; import { pathToFileURL } from 'node:url'; import { brotliCompress } from 'node:zlib'; -import { coerce } from 'semver'; import { NormalizedApplicationBuildOptions } from '../../builders/application/options'; import { OutputMode } from '../../builders/application/schema'; import { BudgetCalculatorResult } from '../../utils/bundle-calculator'; @@ -213,7 +212,7 @@ export async function emitFilesToDisk( writeFileCallback: (file: T) => Promise, ): Promise { // Write files in groups of MAX_CONCURRENT_WRITES to avoid too many open files - for (let fileIndex = 0; fileIndex < files.length; ) { + for (let fileIndex = 0; fileIndex < files.length;) { const groupMax = Math.min(fileIndex + MAX_CONCURRENT_WRITES, files.length); const actions = []; @@ -225,71 +224,6 @@ export async function emitFilesToDisk( } } -/** - * Transform browserlists result to esbuild target. - * @see https://esbuild.github.io/api/#target - */ -export function transformSupportedBrowsersToTargets(supportedBrowsers: string[]): string[] { - const transformed: string[] = []; - - // https://esbuild.github.io/api/#target - const esBuildSupportedBrowsers = new Set([ - 'chrome', - 'edge', - 'firefox', - 'ie', - 'ios', - 'node', - 'opera', - 'safari', - ]); - - for (const browser of supportedBrowsers) { - let [browserName, version] = browser.toLowerCase().split(' '); - - // browserslist uses the name `ios_saf` for iOS Safari whereas esbuild uses `ios` - if (browserName === 'ios_saf') { - browserName = 'ios'; - } - - // browserslist uses ranges `15.2-15.3` versions but only the lowest is required - // to perform minimum supported feature checks. esbuild also expects a single version. - [version] = version.split('-'); - - if (esBuildSupportedBrowsers.has(browserName)) { - if (browserName === 'safari' && version === 'tp') { - // esbuild only supports numeric versions so `TP` is converted to a high number (999) since - // a Technology Preview (TP) of Safari is assumed to support all currently known features. - version = '999'; - } else if (!version.includes('.')) { - // A lone major version is considered by esbuild to include all minor versions. However, - // browserslist does not and is also inconsistent in its `.0` version naming. For example, - // Safari 15.0 is named `safari 15` but Safari 16.0 is named `safari 16.0`. - version += '.0'; - } - - transformed.push(browserName + version); - } - } - - return transformed; -} - -const SUPPORTED_NODE_VERSIONS = '0.0.0-ENGINES-NODE'; - -/** - * Transform supported Node.js versions to esbuild target. - * @see https://esbuild.github.io/api/#target - */ -export function getSupportedNodeTargets(): string[] { - if (SUPPORTED_NODE_VERSIONS.charAt(0) === '0') { - // Unlike `pkg_npm`, `ts_library` which is used to run unit tests does not support substitutions. - return []; - } - - return SUPPORTED_NODE_VERSIONS.split('||').map((v) => 'node' + coerce(v)?.version); -} - interface BuildManifest { errors: string[]; warnings: string[]; From a55a6b78e89debb9c93c83375c54f6716bc26c65 Mon Sep 17 00:00:00 2001 From: Alan Agius <17563226+alan-agius4@users.noreply.github.com> Date: Fri, 7 Aug 2026 14:12:43 +0000 Subject: [PATCH 262/787] perf(@angular/build): batch last_accessed updates in sqlite cache store Previously, every `get()` call on `SqliteCacheStore` immediately executed an `UPDATE` statement to refresh the `last_accessed` timestamp for the requested cache key. In SQLite WAL mode, each unbatched `UPDATE` starts an implicit write transaction, acquiring exclusive write locks on the WAL and causing repeated disk I/O and fsync operations during cache reads. During parallel builds, this serialized concurrent read operations and introduced unnecessary overhead on hot read paths. To resolve this: - `last_accessed` updates are buffered in an in-memory `Set` and flushed inside a single explicit transaction (`BEGIN TRANSACTION; ... COMMIT;`), periodically debounced (every 500ms or when batch reaches 100 entries) and before pruning on `close()`. - Flushes on `close()` ensure that recently accessed items have their timestamps persisted prior to TTL and LRU size pruning. - SQLite PRAGMAs (`busy_timeout = 5000`, `temp_store = MEMORY`, `mmap_size = 268435456`) are tuned to reduce lock contention and leverage memory-mapped I/O. - The debounced timer uses `unref()` to ensure it does not hold the Node.js process event loop open. --- .../src/tools/esbuild/sqlite-cache-store.ts | 55 ++++++++++++++++++- 1 file changed, 54 insertions(+), 1 deletion(-) diff --git a/packages/angular/build/src/tools/esbuild/sqlite-cache-store.ts b/packages/angular/build/src/tools/esbuild/sqlite-cache-store.ts index 3d594668d44f..4f50515749df 100644 --- a/packages/angular/build/src/tools/esbuild/sqlite-cache-store.ts +++ b/packages/angular/build/src/tools/esbuild/sqlite-cache-store.ts @@ -15,6 +15,8 @@ export class SqliteCacheStore implements PersistentCacheStore { #hasStmt: StatementSync | undefined; #setStmt: StatementSync | undefined; #updateAccessedStmt: StatementSync | undefined; + readonly #pendingAccessedKeys = new Set(); + #flushTimeout: NodeJS.Timeout | undefined; constructor( readonly cachePath: string, @@ -29,6 +31,9 @@ export class SqliteCacheStore implements PersistentCacheStore { this.#db.exec('PRAGMA auto_vacuum = FULL;'); this.#db.exec('PRAGMA journal_mode = WAL;'); this.#db.exec('PRAGMA synchronous = NORMAL;'); + this.#db.exec('PRAGMA busy_timeout = 5000;'); + this.#db.exec('PRAGMA temp_store = MEMORY;'); + this.#db.exec('PRAGMA mmap_size = 268435456;'); this.#db.exec( 'CREATE TABLE IF NOT EXISTS cache (key TEXT PRIMARY KEY, value TEXT, last_accessed INTEGER NOT NULL) WITHOUT ROWID;', ); @@ -46,13 +51,51 @@ export class SqliteCacheStore implements PersistentCacheStore { return this.#db; } + #queueAccessUpdate(key: string): void { + this.#pendingAccessedKeys.add(key); + + if (this.#pendingAccessedKeys.size >= 100) { + this.#flushAccessUpdates(); + } else if (!this.#flushTimeout) { + this.#flushTimeout = setTimeout(() => this.#flushAccessUpdates(), 500); + this.#flushTimeout.unref?.(); + } + } + + #flushAccessUpdates(): void { + if (this.#flushTimeout) { + clearTimeout(this.#flushTimeout); + this.#flushTimeout = undefined; + } + + if (!this.#db || this.#pendingAccessedKeys.size === 0 || !this.#updateAccessedStmt) { + return; + } + + try { + this.#db.exec('BEGIN IMMEDIATE TRANSACTION;'); + for (const key of this.#pendingAccessedKeys) { + this.#updateAccessedStmt.run(key); + } + this.#db.exec('COMMIT;'); + } catch { + try { + this.#db.exec('ROLLBACK;'); + } catch { + // Ignore rollback errors if transaction was not active + } + } finally { + this.#pendingAccessedKeys.clear(); + } + } + // eslint-disable-next-line @typescript-eslint/no-explicit-any async get(key: string): Promise { this.#ensureDb(); const row = this.#getStmt?.get(key) as { value: string } | undefined; if (row) { - this.#updateAccessedStmt?.run(key); + this.#queueAccessUpdate(key); try { return JSON.parse(row.value); @@ -72,6 +115,7 @@ export class SqliteCacheStore implements PersistentCacheStore { async set(key: string, value: unknown): Promise { this.#ensureDb(); + this.#pendingAccessedKeys.delete(key); this.#setStmt?.run(key, JSON.stringify(value)); return this; @@ -84,6 +128,9 @@ export class SqliteCacheStore implements PersistentCacheStore { close(): void { if (this.#db) { try { + // Flush any pending access updates in one transaction before pruning + this.#flushAccessUpdates(); + // 1. Delete items older than N days this.#db .prepare("DELETE FROM cache WHERE last_accessed < unixepoch('now', ?);") @@ -103,6 +150,12 @@ export class SqliteCacheStore implements PersistentCacheStore { } catch { // Pruning errors should not block build success } finally { + if (this.#flushTimeout) { + clearTimeout(this.#flushTimeout); + this.#flushTimeout = undefined; + } + this.#pendingAccessedKeys.clear(); + this.#getStmt = undefined; this.#hasStmt = undefined; this.#setStmt = undefined; From ecf8c0822e5d56b44a0be4be8fccb41373135d3e Mon Sep 17 00:00:00 2001 From: herdiyanitdev <82978131+herdiyana256@users.noreply.github.com> Date: Fri, 7 Aug 2026 21:55:27 +0700 Subject: [PATCH 263/787] fix(@angular/cli): serialize configuration as a single argv token in run_target strategies (#33657) * fix(@angular/cli): serialize configuration as a single argv token in run_target strategies build-target-strategy.ts, generic-target-strategy.ts, and unit-test-strategy.ts all pushed the configuration value as a separate argv element after '-c'. Since the ng CLI's argument parser does not consume a following token as the value of a string option when that token itself starts with a dash, a configuration value crafted to look like a flag (e.g. "--outputPath=...") is instead parsed as an independent, legitimately-declared option of the target's builder, silently overriding it. Serialize configuration as a single '--configuration=value' token, matching the format serializeOptions() already uses for every other option, which is not affected by this because the value is bound to the key within one argv element. Updated the two existing spec assertions that checked the old argv shape. * fix(@angular/cli): apply prettier formatting to unit-test-strategy_spec.ts --- .../mcp/tools/run-target/build-target-strategy.ts | 2 +- .../mcp/tools/run-target/generic-target-strategy.ts | 2 +- .../commands/mcp/tools/run-target/run-target_spec.ts | 4 ++-- .../mcp/tools/run-target/unit-test-strategy.ts | 2 +- .../mcp/tools/run-target/unit-test-strategy_spec.ts | 10 +++++++++- 5 files changed, 14 insertions(+), 6 deletions(-) diff --git a/packages/angular/cli/src/commands/mcp/tools/run-target/build-target-strategy.ts b/packages/angular/cli/src/commands/mcp/tools/run-target/build-target-strategy.ts index 1fbd8f83e47a..2e280927f466 100644 --- a/packages/angular/cli/src/commands/mcp/tools/run-target/build-target-strategy.ts +++ b/packages/angular/cli/src/commands/mcp/tools/run-target/build-target-strategy.ts @@ -29,7 +29,7 @@ export class BuildTargetStrategy implements TargetStrategy { ): Promise { const args = ['build', input.projectName]; if (input.configuration) { - args.push('-c', input.configuration); + args.push(`--configuration=${input.configuration}`); } args.push(...serializeOptions(input.options)); diff --git a/packages/angular/cli/src/commands/mcp/tools/run-target/generic-target-strategy.ts b/packages/angular/cli/src/commands/mcp/tools/run-target/generic-target-strategy.ts index e2cbc816c330..365253131248 100644 --- a/packages/angular/cli/src/commands/mcp/tools/run-target/generic-target-strategy.ts +++ b/packages/angular/cli/src/commands/mcp/tools/run-target/generic-target-strategy.ts @@ -46,7 +46,7 @@ export class GenericTargetStrategy implements TargetStrategy { } if (input.configuration) { - args.push('-c', input.configuration); + args.push(`--configuration=${input.configuration}`); } let options = input.options; diff --git a/packages/angular/cli/src/commands/mcp/tools/run-target/run-target_spec.ts b/packages/angular/cli/src/commands/mcp/tools/run-target/run-target_spec.ts index 67b1fffef27e..91ccbac4584a 100644 --- a/packages/angular/cli/src/commands/mcp/tools/run-target/run-target_spec.ts +++ b/packages/angular/cli/src/commands/mcp/tools/run-target/run-target_spec.ts @@ -42,7 +42,7 @@ describe('Run Target Tool', () => { mockContext.workspace.extensions['defaultProject'] = 'my-app'; await runTarget({ target: 'build', configuration: 'production' }, mockContext); expect(mockHost.executeNgCommand).toHaveBeenCalledWith( - ['build', 'my-app', '-c', 'production'], + ['build', 'my-app', '--configuration=production'], { cwd: '/test', }, @@ -53,7 +53,7 @@ describe('Run Target Tool', () => { mockContext.workspace.extensions['defaultProject'] = 'my-app'; await runTarget({ target: 'storybook', configuration: 'docs' }, mockContext); expect(mockHost.executeNgCommand).toHaveBeenCalledWith( - ['run', 'my-app:storybook', '-c', 'docs'], + ['run', 'my-app:storybook', '--configuration=docs'], { cwd: '/test' }, ); }); diff --git a/packages/angular/cli/src/commands/mcp/tools/run-target/unit-test-strategy.ts b/packages/angular/cli/src/commands/mcp/tools/run-target/unit-test-strategy.ts index 77ca5797e71c..1023cdd7956c 100644 --- a/packages/angular/cli/src/commands/mcp/tools/run-target/unit-test-strategy.ts +++ b/packages/angular/cli/src/commands/mcp/tools/run-target/unit-test-strategy.ts @@ -28,7 +28,7 @@ export class UnitTestTargetStrategy implements TargetStrategy { ): Promise { const args = ['test', input.projectName]; if (input.configuration) { - args.push('-c', input.configuration); + args.push(`--configuration=${input.configuration}`); } const builder = input.targetDefinition?.builder; diff --git a/packages/angular/cli/src/commands/mcp/tools/run-target/unit-test-strategy_spec.ts b/packages/angular/cli/src/commands/mcp/tools/run-target/unit-test-strategy_spec.ts index f1467f0002c9..4e63eed148a0 100644 --- a/packages/angular/cli/src/commands/mcp/tools/run-target/unit-test-strategy_spec.ts +++ b/packages/angular/cli/src/commands/mcp/tools/run-target/unit-test-strategy_spec.ts @@ -65,7 +65,15 @@ describe('UnitTestTargetStrategy', () => { ); expect(mockHost.executeNgCommand).toHaveBeenCalledWith( - ['test', 'my-app', '-c', 'ci', '--browsers', 'ChromeHeadless', '--watch', 'false'], + [ + 'test', + 'my-app', + '--configuration=ci', + '--browsers', + 'ChromeHeadless', + '--watch', + 'false', + ], { cwd: '/test' }, ); }); From 6a3446770a8fbfecc7265eb2a6d764e2f1614b3a Mon Sep 17 00:00:00 2001 From: Alan Agius <17563226+alan-agius4@users.noreply.github.com> Date: Fri, 7 Aug 2026 14:14:15 +0000 Subject: [PATCH 264/787] fix(@angular/ssr): destroy platform when response stream is cancelled Ensures PlatformRef is properly destroyed when an active response stream is cancelled or encounters an error during rendering to prevent memory leaks. --- packages/angular/ssr/src/app.ts | 16 ++++++++++++---- packages/angular/ssr/src/utils/ng.ts | 15 ++++++++++++--- packages/angular/ssr/test/app_spec.ts | 11 +++++++++++ 3 files changed, 35 insertions(+), 7 deletions(-) diff --git a/packages/angular/ssr/src/app.ts b/packages/angular/ssr/src/app.ts index a9ca7dd05fe3..3e0f33be8ba7 100644 --- a/packages/angular/ssr/src/app.ts +++ b/packages/angular/ssr/src/app.ts @@ -366,10 +366,18 @@ export class AngularServerApp { // Use a stream to send the response before finishing rendering and inling critical CSS, improving performance via header flushing. const stream = new ReadableStream({ start: async (controller) => { - const renderedHtml = await result.content(); - const finalHtml = await this.inlineCriticalCssWithCache(renderedHtml, url); - controller.enqueue(finalHtml); - controller.close(); + try { + const renderedHtml = await result.content(); + const finalHtml = await this.inlineCriticalCssWithCache(renderedHtml, url); + controller.enqueue(finalHtml); + controller.close(); + } catch (error) { + result.destroy(); + controller.error(error); + } + }, + cancel: () => { + result.destroy(); }, }); diff --git a/packages/angular/ssr/src/utils/ng.ts b/packages/angular/ssr/src/utils/ng.ts index 55d054bd2387..4ae3a7f4ed0f 100644 --- a/packages/angular/ssr/src/utils/ng.ts +++ b/packages/angular/ssr/src/utils/ng.ts @@ -34,8 +34,7 @@ import { addTrailingSlash, joinUrlParts, stripIndexHtmlFromURL, stripTrailingSla * - A function that returns a `Promise`, which resolves with the root application reference. */ export type AngularBootstrap = - | Type - | ((context: BootstrapContext) => Promise); + Type | ((context: BootstrapContext) => Promise); /** * Renders an Angular application or module to an HTML string. @@ -60,7 +59,12 @@ export async function renderAngular( serverContext: string, ): Promise< | { hasNavigationError: true } - | { hasNavigationError: boolean; redirectTo?: string; content: () => Promise } + | { + hasNavigationError: boolean; + redirectTo?: string; + content: () => Promise; + destroy: () => void; + } > { // A request to `http://www.example.com/page/index.html` will render the Angular route corresponding to `http://www.example.com/page`. const urlToRender = stripIndexHtmlFromURL(url); @@ -134,6 +138,7 @@ export async function renderAngular( } return { + destroy: () => void asyncDestroyPlatform(platformRef), hasNavigationError, redirectTo, content: () => @@ -177,6 +182,10 @@ export function isNgModule(value: AngularBootstrap): value is Type { * @param platformRef - The platform reference to be destroyed. */ function asyncDestroyPlatform(platformRef: PlatformRef): Promise { + if (platformRef.destroyed) { + return Promise.resolve(); + } + return new Promise((resolve) => { setTimeout(() => { if (!platformRef.destroyed) { diff --git a/packages/angular/ssr/test/app_spec.ts b/packages/angular/ssr/test/app_spec.ts index de4b1bcb988e..1e3d40d3ede8 100644 --- a/packages/angular/ssr/test/app_spec.ts +++ b/packages/angular/ssr/test/app_spec.ts @@ -14,6 +14,7 @@ import '@angular/compiler'; import { APP_BASE_HREF } from '@angular/common'; import { Component, PlatformRef, REQUEST, RESPONSE_INIT, inject } from '@angular/core'; import { ActivatedRoute, CanActivateFn, Router } from '@angular/router'; +import { setTimeout } from 'node:timers/promises'; import { AngularServerApp } from '../src/app'; import { RenderMode } from '../src/routes/route-config'; import { setAngularAppTestingManifest } from './testing-utils'; @@ -365,6 +366,16 @@ describe('AngularServerApp', () => { expect(await response?.text()).toContain('Home works'); }); + it('should destroy the platform when the response stream is cancelled', async () => { + const destroySpy = spyOn(PlatformRef.prototype, 'destroy').and.callThrough(); + const response = await app.handle(new Request('http://localhost/home')); + expect(response?.body).toBeInstanceOf(ReadableStream); + await response?.body?.cancel(); + // Wait for the macrotask queue to clear since destroy is called asynchronously + await setTimeout(0); + expect(destroySpy).toHaveBeenCalled(); + }); + describe('APP_BASE_HREF / X-Forwarded-Prefix', () => { const headers = new Headers({ 'X-Forwarded-Prefix': '/base/' }); From b6269a8169046a78281808dcf92054140912a77d Mon Sep 17 00:00:00 2001 From: Alan Agius <17563226+alan-agius4@users.noreply.github.com> Date: Fri, 7 Aug 2026 14:13:06 +0000 Subject: [PATCH 265/787] perf(@angular/build): optimize template string size calculation in server manifest Calculates normalized byte lengths for server assets directly using Node.js Buffer.byteLength to avoid script compilation with vm.runInThisContext. --- .../build/src/utils/server-rendering/manifest.ts | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/packages/angular/build/src/utils/server-rendering/manifest.ts b/packages/angular/build/src/utils/server-rendering/manifest.ts index bd294b1e7e4b..1ee430a76333 100644 --- a/packages/angular/build/src/utils/server-rendering/manifest.ts +++ b/packages/angular/build/src/utils/server-rendering/manifest.ts @@ -7,8 +7,8 @@ */ import type { Metafile } from 'esbuild'; +import { Buffer } from 'node:buffer'; import { extname } from 'node:path'; -import { runInThisContext } from 'node:vm'; import { NormalizedApplicationBuildOptions } from '../../builders/application/options'; import { type BuildOutputFile, @@ -174,9 +174,14 @@ export function generateAngularServerAppManifest( ), ); - // This is needed because JavaScript engines script parser convert `\r\n` to `\n` in template literals, - // which can result in an incorrect byte length. - const size = runInThisContext(`new TextEncoder().encode(\`${escapedContent}\`).byteLength`); + // JavaScript engine script parsers normalize `\r\n` (2 bytes in UTF-8) to `\n` (1 byte in UTF-8) in template literals. + // Subtracting the count of `\r\n` occurrences avoids allocating any temporary strings or match arrays for large assets. + let size = Buffer.byteLength(file.text); + let pos = file.text.indexOf('\r\n'); + while (pos !== -1) { + size--; + pos = file.text.indexOf('\r\n', pos + 2); + } serverAssets[file.path] = `{size: ${size}, hash: '${file.hash}', text: () => import('./${jsChunkFilePath}').then(m => m.default)}`; From 19c91e48d4b8a95a76dfe4bffd105130b416843d Mon Sep 17 00:00:00 2001 From: Alan Agius <17563226+alan-agius4@users.noreply.github.com> Date: Fri, 7 Aug 2026 14:12:54 +0000 Subject: [PATCH 266/787] perf(@angular/build): use Map for chunk asset size lookups in budget calculator Caches chunk asset sizes in a Map to reduce asset size lookups from repeated linear array searches to constant time during budget calculation. --- .../build/src/utils/bundle-calculator.ts | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/packages/angular/build/src/utils/bundle-calculator.ts b/packages/angular/build/src/utils/bundle-calculator.ts index 3349a8a40830..71a75dafde02 100644 --- a/packages/angular/build/src/utils/bundle-calculator.ts +++ b/packages/angular/build/src/utils/bundle-calculator.ts @@ -152,6 +152,8 @@ function calculateSizes(budget: BudgetEntry, stats: BudgetStats): Size[] { } abstract class Calculator { + private assetMap?: ReadonlyMap; + constructor( protected budget: BudgetEntry, protected chunks: BudgetChunk[], @@ -167,15 +169,24 @@ abstract class Calculator { return 0; } + if (!this.assetMap) { + const map = new Map(); + for (const asset of this.assets) { + map.set(asset.name, asset.size); + } + this.assetMap = map; + } + const assetMap = this.assetMap; + return chunk.files .filter((file) => !file.endsWith('.map')) .map((file) => { - const asset = this.assets.find((asset) => asset.name === file); - if (!asset) { + const assetSize = assetMap.get(file); + if (assetSize === undefined) { throw new Error(`Could not find asset for file: ${file}`); } - return asset.size; + return assetSize; }) .reduce((l, r) => l + r, 0); } From a6ef9cfbeace725d58c0f7f65640ef6de9b39c33 Mon Sep 17 00:00:00 2001 From: Charles Lyding <19598772+clydin@users.noreply.github.com> Date: Fri, 24 Jul 2026 13:48:01 -0400 Subject: [PATCH 267/787] perf(@angular/build): replace watchpack with @parcel/watcher and chokidar This change replaces the watchpack file watching dependency in @angular/build with @parcel/watcher as the primary native file watcher, while falling back to chokidar for polling or unsupported environments. By leveraging @parcel/watcher's native C++ bindings (FSEvents, ReadDirectoryChangesW, inotify), file system watching is offloaded directly to OS kernel APIs, significantly reducing CPU and memory footprint during watch mode. Additionally, external directory watches are dynamically subsumed to minimize active native file handles, while early path filtering and event coalescing prevent redundant incremental rebuild triggers. --- package.json | 1 - packages/angular/build/BUILD.bazel | 4 +- packages/angular/build/package.json | 3 +- .../src/builders/application/build-action.ts | 7 +- .../build/src/tools/esbuild/watcher.ts | 597 ++++++++++++++++-- .../build/src/tools/esbuild/watcher_spec.ts | 452 +++++++++++++ .../angular_devkit/build_angular/BUILD.bazel | 1 - pnpm-lock.yaml | 33 +- 8 files changed, 1005 insertions(+), 93 deletions(-) create mode 100644 packages/angular/build/src/tools/esbuild/watcher_spec.ts diff --git a/package.json b/package.json index b3c0d806cb6e..d205330e9f8b 100644 --- a/package.json +++ b/package.json @@ -89,7 +89,6 @@ "@types/picomatch": "^4.0.0", "@types/progress": "^2.0.3", "@types/semver": "^7.3.12", - "@types/watchpack": "^2.4.4", "@types/yargs": "^17.0.20", "@types/yargs-parser": "^21.0.0", "@typescript-eslint/eslint-plugin": "8.66.0", diff --git a/packages/angular/build/BUILD.bazel b/packages/angular/build/BUILD.bazel index fca820c8f2ed..75eedd6a7f5f 100644 --- a/packages/angular/build/BUILD.bazel +++ b/packages/angular/build/BUILD.bazel @@ -84,9 +84,11 @@ ts_project( ":node_modules/@babel/core", ":node_modules/@inquirer/confirm", ":node_modules/@oxc-project/types", + ":node_modules/@parcel/watcher", ":node_modules/@vitejs/plugin-basic-ssl", ":node_modules/beasties", ":node_modules/browserslist", + ":node_modules/chokidar", ":node_modules/https-proxy-agent", ":node_modules/istanbul-lib-instrument", ":node_modules/jsonc-parser", @@ -108,7 +110,6 @@ ts_project( ":node_modules/tinyglobby", ":node_modules/vite", ":node_modules/vitest", - ":node_modules/watchpack", ":node_modules/xxhash-wasm", "//:node_modules/@angular/common", "//:node_modules/@angular/compiler", @@ -124,7 +125,6 @@ ts_project( "//:node_modules/@types/node", "//:node_modules/@types/picomatch", "//:node_modules/@types/semver", - "//:node_modules/@types/watchpack", "//:node_modules/esbuild", "//:node_modules/esbuild-wasm", "//:node_modules/karma", diff --git a/packages/angular/build/package.json b/packages/angular/build/package.json index baa0faf2a35a..5aeb7590cee1 100644 --- a/packages/angular/build/package.json +++ b/packages/angular/build/package.json @@ -22,9 +22,11 @@ "@angular-devkit/architect": "workspace:0.0.0-EXPERIMENTAL-PLACEHOLDER", "@babel/core": "8.0.1", "@inquirer/confirm": "6.1.1", + "@parcel/watcher": "2.6.0", "@vitejs/plugin-basic-ssl": "2.3.0", "beasties": "0.4.3", "browserslist": "^4.26.0", + "chokidar": "5.0.0", "esbuild": "0.28.1", "https-proxy-agent": "9.1.0", "jsonc-parser": "3.3.1", @@ -41,7 +43,6 @@ "source-map-support": "0.5.21", "tinyglobby": "0.2.17", "vite": "8.2.0", - "watchpack": "2.5.2", "xxhash-wasm": "1.1.0" }, "optionalDependencies": { diff --git a/packages/angular/build/src/builders/application/build-action.ts b/packages/angular/build/src/builders/application/build-action.ts index 07ed300789d2..af0ce30f687d 100644 --- a/packages/angular/build/src/builders/application/build-action.ts +++ b/packages/angular/build/src/builders/application/build-action.ts @@ -42,6 +42,7 @@ const packageWatchFiles = [ '.pnp.data.json', ]; +// eslint-disable-next-line max-lines-per-function export async function* runEsBuildBuildAction( action: (rebuildState?: RebuildState) => Promise, options: { @@ -116,11 +117,12 @@ export async function* runEsBuildBuildAction( // Setup a watcher const { createWatcher } = await import('../../tools/esbuild/watcher'); - watcher = createWatcher({ + watcher = await createWatcher({ polling: typeof poll === 'number', interval: poll, followSymlinks: preserveSymlinks, ignored, + cwd: workspaceRoot, }); // Setup abort support @@ -218,6 +220,9 @@ export async function* runEsBuildBuildAction( // Remove any stale locations if the build was successful if (staleWatchFiles?.size) { watcher.remove([...staleWatchFiles]); + for (const staleFile of staleWatchFiles) { + currentWatchFiles.delete(staleFile); + } } for (const outputResult of emitOutputResults( diff --git a/packages/angular/build/src/tools/esbuild/watcher.ts b/packages/angular/build/src/tools/esbuild/watcher.ts index cf9e1d94cb87..2ba0764d9023 100644 --- a/packages/angular/build/src/tools/esbuild/watcher.ts +++ b/packages/angular/build/src/tools/esbuild/watcher.ts @@ -6,7 +6,11 @@ * found in the LICENSE file at https://angular.dev/license */ -import WatchPack from 'watchpack'; +import type * as ParcelWatcher from '@parcel/watcher'; +import type * as Chokidar from 'chokidar'; +import * as fs from 'node:fs'; +import * as path from 'node:path'; +import { toPosixPath } from '../../utils/path'; export class ChangedFiles { readonly added = new Set(); @@ -14,7 +18,7 @@ export class ChangedFiles { readonly removed = new Set(); get all(): string[] { - return [...this.added, ...this.modified, ...this.removed]; + return Array.from(new Set([...this.added, ...this.modified, ...this.removed])); } toDebugString(): string { @@ -34,102 +38,571 @@ export interface BuildWatcher extends AsyncIterableIterator { close(): Promise; } -export function createWatcher(options?: { +export interface WatcherOptions { polling?: boolean; interval?: number; ignored?: string[]; followSymlinks?: boolean; -}): BuildWatcher { - const watcher = new WatchPack({ - poll: options?.polling ? (options?.interval ?? true) : false, - ignored: options?.ignored, - followSymlinks: options?.followSymlinks, - aggregateTimeout: 250, - }); - const watchedFiles = new Set(); + cwd?: string; +} + +/** + * Probes the filesystem at the specified target directory to determine whether it is case-sensitive. + */ +function isFileSystemCaseSensitive(targetDir: string = process.cwd()): boolean { + try { + const resolved = path.resolve(targetDir); + if (!fs.existsSync(resolved)) { + return process.platform !== 'win32' && process.platform !== 'darwin'; + } - const nextQueue: ((value?: ChangedFiles) => void)[] = []; - let currentChangedFiles: ChangedFiles | undefined; + // Invert the casing of the target directory path. + const altCase = + resolved === resolved.toLowerCase() ? resolved.toUpperCase() : resolved.toLowerCase(); - watcher.on('aggregated', (changes, removals) => { - const changedFiles = currentChangedFiles ?? new ChangedFiles(); - for (const file of changes) { - changedFiles.modified.add(file); + // If the path contains no alphabetic characters (e.g. root '/'), invert-casing + // produces the exact same string. Fall back to platform-specific defaults in this case. + if (resolved === altCase) { + return process.platform !== 'win32' && process.platform !== 'darwin'; } - for (const file of removals) { - changedFiles.removed.add(file); + + // If both the original path and the inverted-casing path exist on disk, + // the filesystem is case-insensitive (returns false). + return !fs.existsSync(altCase); + } catch { + // If an error occurs (e.g., permission denied), default to the platform-specific + // behavior (case-insensitive on Windows/macOS, sensitive on Linux/Unix). + return process.platform !== 'win32' && process.platform !== 'darwin'; + } +} + +/** + * Normalizes a file system path string to POSIX format (forward slashes '/') + * and strips trailing slashes (except root '/' or Windows drive root 'C:/'). + */ +export function toPosixPathNormalized(pathString: string): string { + let posixPath = toPosixPath(pathString); + if (posixPath.length > 1 && posixPath.endsWith('/') && !/^[a-zA-Z]:\/$/.test(posixPath)) { + posixPath = posixPath.slice(0, -1); + } + + return posixPath; +} + +/** + * Returns a lookup key for set lookups and matching, lowercasing on case-insensitive file systems. + */ +function toLookupKey(posixPath: string, isCaseSensitive: boolean): string { + return isCaseSensitive ? posixPath : posixPath.toLowerCase(); +} + +/** + * Returns the parent directory of a normalized POSIX path, correctly handling Windows drive roots. + */ +export function getDirectoryPath(posixPath: string): string { + const lastSlash = posixPath.lastIndexOf('/'); + if (lastSlash === -1) { + return '.'; + } + const dir = posixPath.slice(0, lastSlash); + if (dir === '' || dir.endsWith(':')) { + return dir + '/'; + } + + return dir; +} + +/** + * Determines whether a file path lookup key or any of its parent directories are present in watchedFiles. + */ +function isPathWatched(fileLookupKey: string, watchedFiles: Set): boolean { + if (watchedFiles.has(fileLookupKey)) { + return true; + } + + let current = fileLookupKey; + while (true) { + const parent = getDirectoryPath(current); + if (parent === current) { + break; + } + if (watchedFiles.has(parent)) { + return true; } + current = parent; + } - const next = nextQueue.shift(); - if (next) { - currentChangedFiles = undefined; - next(changedFiles); - } else { - currentChangedFiles = changedFiles; + return false; +} + +class WatcherQueue { + private readonly nextQueue: ((value?: ChangedFiles) => void)[] = []; + private currentChangedFiles: ChangedFiles | undefined; + private isClosed = false; + private timeoutId: NodeJS.Timeout | undefined; + + addChange(type: 'added' | 'modified' | 'removed', file: string): void { + if (this.isClosed) { + return; + } + + const changedFiles = (this.currentChangedFiles ??= new ChangedFiles()); + changedFiles[type].add(file); + this.scheduleFlush(); + } + + addChanges( + changes: ReadonlyArray<{ type: 'added' | 'modified' | 'removed'; file: string }>, + ): void { + if (this.isClosed || changes.length === 0) { + return; + } + + const changedFiles = (this.currentChangedFiles ??= new ChangedFiles()); + for (const { type, file } of changes) { + changedFiles[type].add(file); + } + this.scheduleFlush(); + } + + private scheduleFlush(): void { + if (this.timeoutId) { + clearTimeout(this.timeoutId); + } + this.timeoutId = setTimeout(() => { + this.timeoutId = undefined; + this.flush(); + }, 250); + } + + private flush(): void { + if ( + this.currentChangedFiles && + this.currentChangedFiles.all.length > 0 && + this.nextQueue.length > 0 + ) { + const next = this.nextQueue.shift(); + if (next) { + const result = this.currentChangedFiles; + this.currentChangedFiles = undefined; + next(result); + } + } + } + + async next(): Promise> { + if ( + this.currentChangedFiles && + this.currentChangedFiles.all.length > 0 && + this.nextQueue.length === 0 && + !this.timeoutId + ) { + const result = { value: this.currentChangedFiles }; + this.currentChangedFiles = undefined; + + return result; + } + + if (this.isClosed) { + return { done: true, value: undefined as unknown as ChangedFiles }; + } + + return new Promise((resolve) => { + this.nextQueue.push((value) => + resolve(value ? { value } : { done: true, value: undefined as unknown as ChangedFiles }), + ); + }); + } + + close(): void { + if (this.isClosed) { + return; + } + + if (this.timeoutId) { + clearTimeout(this.timeoutId); + this.timeoutId = undefined; + } + + this.isClosed = true; + this.currentChangedFiles = undefined; + + let next; + while ((next = this.nextQueue.shift()) !== undefined) { + next(); + } + } +} + +export async function createWatcher(options?: WatcherOptions): Promise { + if (options?.polling) { + return createChokidarWatcher(options); + } + + try { + const parcelWatcher = await import('@parcel/watcher'); + + return await createParcelWatcher(options, parcelWatcher); + } catch { + return createChokidarWatcher(options); + } +} + +/** + * Checks whether a file path is located inside a parent directory. + * + * Input Expectations: + * - Both `file` and `dir` must be normalized POSIX-style paths (using forward slashes '/'). + * - Both paths must share the same casing normalization (e.g., lowercased on case-insensitive file systems). + */ +export function isPathInside(file: string, dir: string): boolean { + if (file === dir) { + return false; + } + + const dirWithSlash = dir.endsWith('/') ? dir : dir + '/'; + + return file.startsWith(dirWithSlash); +} + +class ParcelExternalManager { + private readonly extraSubscriptions = new Map(); + private readonly pendingSubscriptions = new Map< + string, + Promise + >(); + private readonly externalDirFiles = new Map }>(); + + constructor( + private readonly parcelWatcher: typeof ParcelWatcher, + private readonly options: WatcherOptions | undefined, + private readonly rootDirLookupKey: string, + private readonly handleEvents: (events: ParcelWatcher.Event[]) => void, + ) {} + + async ensureWatched(posixPath: string, lookupKey: string): Promise { + if (isPathInside(lookupKey, this.rootDirLookupKey) || lookupKey === this.rootDirLookupKey) { + return; + } + + const dirPath = getDirectoryPath(posixPath); + const dirKey = getDirectoryPath(lookupKey); + let dirEntry = this.externalDirFiles.get(dirKey); + if (!dirEntry) { + dirEntry = { dirPath, files: new Set() }; + this.externalDirFiles.set(dirKey, dirEntry); + } + dirEntry.files.add(lookupKey); + + await this.ensureDirWatched(dirPath, dirKey); + } + + removeFile(lookupKey: string): void { + if (isPathInside(lookupKey, this.rootDirLookupKey) || lookupKey === this.rootDirLookupKey) { + return; } - }); - return { + const dirKey = getDirectoryPath(lookupKey); + const dirEntry = this.externalDirFiles.get(dirKey); + if (dirEntry) { + dirEntry.files.delete(lookupKey); + if (dirEntry.files.size === 0) { + this.externalDirFiles.delete(dirKey); + const sub = this.extraSubscriptions.get(dirKey); + if (sub) { + this.extraSubscriptions.delete(dirKey); + sub.unsubscribe().catch(() => {}); + + for (const [remainingDirKey, remainingDirEntry] of this.externalDirFiles.entries()) { + if (!this.isCoveredByExistingExternal(remainingDirKey)) { + this.ensureDirWatched(remainingDirEntry.dirPath, remainingDirKey).catch(() => {}); + } + } + } + } + } + } + + async close(): Promise { + try { + if (this.pendingSubscriptions.size > 0) { + await Promise.allSettled(Array.from(this.pendingSubscriptions.values())); + } + if (this.extraSubscriptions.size > 0) { + await Promise.allSettled( + Array.from(this.extraSubscriptions.values()).map((sub) => sub.unsubscribe()), + ); + } + } finally { + this.extraSubscriptions.clear(); + this.pendingSubscriptions.clear(); + this.externalDirFiles.clear(); + } + } + + private isCoveredByExistingExternal(dirLookupKey: string): boolean { + for (const existingDir of this.extraSubscriptions.keys()) { + if (dirLookupKey === existingDir || isPathInside(dirLookupKey, existingDir)) { + return true; + } + } + for (const pendingDir of this.pendingSubscriptions.keys()) { + if (dirLookupKey === pendingDir || isPathInside(dirLookupKey, pendingDir)) { + return true; + } + } + + return false; + } + + private async ensureDirWatched(dirPath: string, dirKey: string): Promise { + if (this.isCoveredByExistingExternal(dirKey)) { + return; + } + + const subPromise = this.parcelWatcher.subscribe( + dirPath, + (err, events) => { + if (!err) { + this.handleEvents(events); + } + }, + { + ignore: this.options?.ignored, + }, + ); + + this.pendingSubscriptions.set(dirKey, subPromise); + + try { + const sub = await subPromise; + if (this.externalDirFiles.has(dirKey) && !this.isCoveredByExistingExternal(dirKey)) { + this.extraSubscriptions.set(dirKey, sub); + + // Subsume any nested child subscriptions that are now covered by this parent subscription + for (const [childDir, childSub] of this.extraSubscriptions.entries()) { + if (childDir !== dirKey && isPathInside(childDir, dirKey)) { + this.extraSubscriptions.delete(childDir); + childSub.unsubscribe().catch(() => {}); + } + } + } else { + sub.unsubscribe().catch(() => {}); + } + } catch { + // Ignore subscription errors for missing or restricted external directories + } finally { + this.pendingSubscriptions.delete(dirKey); + } + } +} + +async function createParcelWatcher( + options: WatcherOptions | undefined, + parcelWatcher: typeof ParcelWatcher, +): Promise { + const watchedFiles = new Set(); + const queue = new WatcherQueue(); + + const isCaseSensitive = isFileSystemCaseSensitive(options?.cwd); + const rootDirPosix = toPosixPathNormalized(options?.cwd ?? process.cwd()); + const rootDirLookupKey = toLookupKey(rootDirPosix, isCaseSensitive); + const initTime = Date.now(); + + const handleEvents = (events: ParcelWatcher.Event[]) => { + const changes: { type: 'added' | 'modified' | 'removed'; file: string }[] = []; + for (const event of events) { + const posixPath = toPosixPathNormalized(event.path); + const lookupKey = toLookupKey(posixPath, isCaseSensitive); + if (!isPathWatched(lookupKey, watchedFiles)) { + continue; + } + + if (event.type !== 'delete') { + const stat = fs.statSync(event.path, { throwIfNoEntry: false }); + // Ignore historical events from before watcher initialization, but allow a 1000 ms window + // to account for coarse filesystem timestamp resolution (e.g., ext4/overlayfs integer second + // mtime truncation on Linux) where files modified during startup may have truncated .000 ms mtimes. + if (stat && stat.mtimeMs < initTime - 1000) { + continue; + } + } + + const type = + event.type === 'create' ? 'added' : event.type === 'delete' ? 'removed' : 'modified'; + changes.push({ type, file: event.path }); + } + + if (changes.length > 0) { + queue.addChanges(changes); + } + }; + + const subscription = await parcelWatcher.subscribe( + rootDirPosix, + (err, events) => { + if (!err) { + handleEvents(events); + } + }, + { + ignore: options?.ignored, + }, + ); + + const externalManager = new ParcelExternalManager( + parcelWatcher, + options, + rootDirLookupKey, + handleEvents, + ); + + const buildWatcher: BuildWatcher = { [Symbol.asyncIterator]() { return this; }, - async next() { - if (currentChangedFiles && nextQueue.length === 0) { - const result = { value: currentChangedFiles }; - currentChangedFiles = undefined; + next() { + return queue.next(); + }, - return result; + add(paths) { + const targets = typeof paths === 'string' ? [paths] : paths; + for (const file of targets) { + const posixPath = toPosixPathNormalized(file); + const lookupKey = toLookupKey(posixPath, isCaseSensitive); + if (!watchedFiles.has(lookupKey)) { + watchedFiles.add(lookupKey); + void externalManager.ensureWatched(posixPath, lookupKey); + } } + }, - return new Promise((resolve) => { - nextQueue.push((value) => resolve(value ? { value } : { done: true, value })); - }); + remove(paths) { + const targets = typeof paths === 'string' ? [paths] : paths; + for (const file of targets) { + const posixPath = toPosixPathNormalized(file); + const lookupKey = toLookupKey(posixPath, isCaseSensitive); + if (watchedFiles.delete(lookupKey)) { + externalManager.removeFile(lookupKey); + } + } }, - add(paths) { - const previousSize = watchedFiles.size; - if (typeof paths === 'string') { - watchedFiles.add(paths); - } else { - for (const file of paths) { - watchedFiles.add(file); + async close() { + try { + if (subscription) { + await subscription.unsubscribe(); } + await externalManager.close(); + } finally { + queue.close(); + } + }, + }; + + return buildWatcher; +} + +async function createChokidarWatcher( + options?: WatcherOptions, + chokidarModule?: typeof Chokidar, +): Promise { + const chokidar = chokidarModule ?? (await import('chokidar')); + const watchedFiles = new Set(); + const queue = new WatcherQueue(); + + const rootDir = options?.cwd ?? process.cwd(); + const isCaseSensitive = isFileSystemCaseSensitive(rootDir); + const rootDirPosix = toPosixPathNormalized(rootDir); + const rootDirLookupKey = toLookupKey(rootDirPosix, isCaseSensitive); + + const watcher = chokidar.watch(rootDir, { + ignoreInitial: true, + ignored: options?.ignored, + followSymlinks: options?.followSymlinks, + usePolling: !!options?.polling, + interval: options?.interval, + }); + const initTime = Date.now(); + + const handleEvent = (type: 'added' | 'modified' | 'removed', rawPath: string) => { + const posixPath = toPosixPathNormalized(rawPath); + const lookupKey = toLookupKey(posixPath, isCaseSensitive); + if (!isPathWatched(lookupKey, watchedFiles)) { + return; + } + + if (type !== 'removed') { + const stat = fs.statSync(rawPath, { throwIfNoEntry: false }); + // Ignore historical events from before watcher initialization, but allow a 1000 ms window + // to account for coarse filesystem timestamp resolution (e.g., ext4/overlayfs integer second + // mtime truncation on Linux) where files modified during startup may have truncated .000 ms mtimes. + if (stat && stat.mtimeMs < initTime - 1000) { + return; } + } + + queue.addChange(type, rawPath); + }; - if (previousSize !== watchedFiles.size) { - watcher.watch({ - files: watchedFiles, - }); + watcher.on('add', (path) => handleEvent('added', path)); + watcher.on('change', (path) => handleEvent('modified', path)); + watcher.on('unlink', (path) => handleEvent('removed', path)); + + const buildWatcher: BuildWatcher = { + [Symbol.asyncIterator]() { + return this; + }, + + next() { + return queue.next(); + }, + + add(paths) { + const targets = typeof paths === 'string' ? [paths] : paths; + const newPaths: string[] = []; + for (const p of targets) { + const posixPath = toPosixPathNormalized(p); + const lookupKey = toLookupKey(posixPath, isCaseSensitive); + if (!watchedFiles.has(lookupKey)) { + watchedFiles.add(lookupKey); + if (!isPathInside(lookupKey, rootDirLookupKey) && lookupKey !== rootDirLookupKey) { + newPaths.push(posixPath); + } + } + } + if (newPaths.length > 0) { + watcher.add(newPaths); } }, remove(paths) { - const previousSize = watchedFiles.size; - if (typeof paths === 'string') { - watchedFiles.delete(paths); - } else { - for (const file of paths) { - watchedFiles.delete(file); + const targets = typeof paths === 'string' ? [paths] : paths; + const removePaths: string[] = []; + for (const p of targets) { + const posixPath = toPosixPathNormalized(p); + const lookupKey = toLookupKey(posixPath, isCaseSensitive); + if (watchedFiles.has(lookupKey)) { + watchedFiles.delete(lookupKey); + if (!isPathInside(lookupKey, rootDirLookupKey) && lookupKey !== rootDirLookupKey) { + removePaths.push(posixPath); + } } } - - if (previousSize !== watchedFiles.size) { - watcher.watch({ - files: watchedFiles, - }); + if (removePaths.length > 0) { + watcher.unwatch(removePaths); } }, async close() { try { - watcher.close(); + await watcher.close(); } finally { - let next; - while ((next = nextQueue.shift()) !== undefined) { - next(); - } + queue.close(); } }, }; + + return buildWatcher; } diff --git a/packages/angular/build/src/tools/esbuild/watcher_spec.ts b/packages/angular/build/src/tools/esbuild/watcher_spec.ts new file mode 100644 index 000000000000..92f7dcaf5d38 --- /dev/null +++ b/packages/angular/build/src/tools/esbuild/watcher_spec.ts @@ -0,0 +1,452 @@ +/** + * @license + * Copyright Google LLC All Rights Reserved. + * + * Use of this source code is governed by an MIT-style license that can be + * found in the LICENSE file at https://angular.dev/license + */ + +import * as fs from 'node:fs'; +import * as os from 'node:os'; +import * as path from 'node:path'; +import { setTimeout } from 'node:timers/promises'; +import { + ChangedFiles, + createWatcher, + getDirectoryPath, + isPathInside, + toPosixPathNormalized, +} from './watcher'; + +describe('Watcher', () => { + describe('toPosixPathNormalized', () => { + it('should strip trailing slashes for standard directories', () => { + expect(toPosixPathNormalized('/src/app/')).toBe('/src/app'); + expect(toPosixPathNormalized('C:/src/app/')).toBe('C:/src/app'); + }); + + it('should preserve single root slash', () => { + expect(toPosixPathNormalized('/')).toBe('/'); + }); + + it('should preserve trailing slash for Windows drive root', () => { + expect(toPosixPathNormalized('C:/')).toBe('C:/'); + expect(toPosixPathNormalized('c:/')).toBe('c:/'); + }); + }); + + describe('getDirectoryPath', () => { + it('should return parent directory for POSIX paths', () => { + expect(getDirectoryPath('/src/app/main.ts')).toBe('/src/app'); + expect(getDirectoryPath('/src/app')).toBe('/src'); + expect(getDirectoryPath('/src')).toBe('/'); + expect(getDirectoryPath('/')).toBe('/'); + }); + + it('should correctly handle Windows drive roots', () => { + expect(getDirectoryPath('C:/src/app/main.ts')).toBe('C:/src/app'); + expect(getDirectoryPath('C:/src')).toBe('C:/'); + expect(getDirectoryPath('C:/')).toBe('C:/'); + expect(getDirectoryPath('c:/')).toBe('c:/'); + }); + + it('should return dot for relative paths without slash', () => { + expect(getDirectoryPath('main.ts')).toBe('.'); + }); + }); + + describe('isPathInside', () => { + it('should return true for a file inside a directory', () => { + expect(isPathInside('/src/app/main.ts', '/src/app')).toBeTrue(); + }); + + it('should return false when file and dir are identical', () => { + expect(isPathInside('/src/app', '/src/app')).toBeFalse(); + }); + + it('should return false for sibling directories with matching prefix', () => { + expect(isPathInside('/src/app-other/main.ts', '/src/app')).toBeFalse(); + }); + + it('should handle Windows drive letters on the same drive', () => { + expect(isPathInside('c:/src/app/main.ts', 'c:/src/app')).toBeTrue(); + }); + + it('should return false for Windows drive letters on different drives', () => { + expect(isPathInside('d:/src/app/main.ts', 'c:/src/app')).toBeFalse(); + }); + + it('should handle root directory correctly', () => { + expect(isPathInside('/src/main.ts', '/')).toBeTrue(); + }); + + it('should handle Windows drive root directory correctly', () => { + expect(isPathInside('c:/src/main.ts', 'c:/')).toBeTrue(); + }); + }); + + describe('ChangedFiles', () => { + it('should track added, modified, and removed files', () => { + const changes = new ChangedFiles(); + changes.added.add('/src/app.component.ts'); + changes.modified.add('/src/main.ts'); + changes.removed.add('/src/old.ts'); + + expect(changes.all).toEqual(['/src/app.component.ts', '/src/main.ts', '/src/old.ts']); + }); + + it('should deduplicate files present in multiple sets in .all', () => { + const changes = new ChangedFiles(); + changes.added.add('/src/main.ts'); + changes.modified.add('/src/main.ts'); + + expect(changes.all).toEqual(['/src/main.ts']); + }); + + it('should format debug string correctly', () => { + const changes = new ChangedFiles(); + changes.modified.add('/src/main.ts'); + + const debug = JSON.parse(changes.toDebugString()); + expect(debug).toEqual({ + added: [], + modified: ['/src/main.ts'], + removed: [], + }); + }); + }); + + describe('createWatcher', () => { + let tempDir: string; + + beforeEach(() => { + tempDir = fs.realpathSync(fs.mkdtempSync(path.join(os.tmpdir(), 'watcher-spec-'))); + }); + + afterEach(() => { + if (fs.existsSync(tempDir)) { + fs.rmSync(tempDir, { recursive: true, force: true }); + } + }); + + it('should instantiate and close watcher without error', async () => { + const watcher = await createWatcher({ cwd: tempDir }); + expect(watcher).toBeDefined(); + + watcher.add(path.join(tempDir, 'main.ts')); + watcher.remove(path.join(tempDir, 'main.ts')); + + await watcher.close(); + }); + + it('should support array of paths in add and remove', async () => { + const watcher = await createWatcher({ cwd: tempDir }); + const file1 = path.join(tempDir, 'a.ts'); + const file2 = path.join(tempDir, 'b.ts'); + + watcher.add([file1, file2]); + watcher.remove([file1, file2]); + + await watcher.close(); + }); + + it('should support polling option', async () => { + const watcher = await createWatcher({ polling: true, interval: 100, cwd: tempDir }); + expect(watcher).toBeDefined(); + + watcher.add(path.join(tempDir, 'main.ts')); + await watcher.close(); + }); + + it('should emit changes when a watched file is modified (chokidar polling)', async () => { + const testFile = path.join(tempDir, 'test.txt'); + fs.writeFileSync(testFile, 'initial'); + + const watcher = await createWatcher({ polling: true, interval: 50, cwd: tempDir }); + watcher.add(testFile); + + // Wait a short moment for watcher setup and mtime tick + await setTimeout(100); + + const iterator = watcher[Symbol.asyncIterator](); + const nextPromise = iterator.next(); + + // Trigger change + fs.writeFileSync(testFile, 'updated'); + + const result = await nextPromise; + expect(result.done).toBeFalsy(); + expect(result.value?.all.length).toBeGreaterThan(0); + + await watcher.close(); + }, 10000); + + it('should preserve original path character casing in emitted changes', async () => { + const casedFile = path.join(tempDir, 'App.Component.ts'); + fs.writeFileSync(casedFile, 'initial'); + + const watcher = await createWatcher({ polling: true, interval: 50, cwd: tempDir }); + watcher.add(casedFile); + + await setTimeout(100); + + const iterator = watcher[Symbol.asyncIterator](); + const nextPromise = iterator.next(); + + fs.writeFileSync(casedFile, 'updated'); + + const result = await nextPromise; + expect(result.done).toBeFalsy(); + const emittedFiles = result.value?.all ?? []; + expect(emittedFiles.some((f: string) => f.includes('App.Component.ts'))).toBeTrue(); + + await watcher.close(); + }, 10000); + + it('should emit changes when watching a directory containing modified files', async () => { + const subDir = path.join(tempDir, 'sub'); + fs.mkdirSync(subDir); + const testFile = path.join(subDir, 'nested.txt'); + fs.writeFileSync(testFile, 'initial'); + + const watcher = await createWatcher({ polling: true, interval: 50, cwd: tempDir }); + watcher.add(subDir); + + await setTimeout(100); + + const iterator = watcher[Symbol.asyncIterator](); + const nextPromise = iterator.next(); + + fs.writeFileSync(testFile, 'updated'); + + const result = await nextPromise; + expect(result.done).toBeFalsy(); + expect(result.value?.all.length).toBeGreaterThan(0); + + await watcher.close(); + }, 10000); + + it('should support watching paths outside cwd', async () => { + const externalDir = fs.mkdtempSync(path.join(os.tmpdir(), 'external-watcher-spec-')); + const externalFile = path.join(externalDir, 'external.txt'); + fs.writeFileSync(externalFile, 'initial'); + + try { + const watcher = await createWatcher({ polling: true, interval: 50, cwd: tempDir }); + watcher.add(externalFile); + + await setTimeout(100); + + const iterator = watcher[Symbol.asyncIterator](); + const nextPromise = iterator.next(); + + fs.writeFileSync(externalFile, 'updated'); + + const result = await nextPromise; + expect(result.done).toBeFalsy(); + expect(result.value?.all.some((f: string) => f.includes('external.txt'))).toBeTrue(); + + await watcher.close(); + } finally { + fs.rmSync(externalDir, { recursive: true, force: true }); + } + }, 10000); + + it('should handle adding multiple external files in the same directory concurrently', async () => { + const externalDir = fs.mkdtempSync(path.join(os.tmpdir(), 'external-watcher-spec-')); + const file1 = path.join(externalDir, 'file1.txt'); + const file2 = path.join(externalDir, 'file2.txt'); + fs.writeFileSync(file1, 'initial1'); + fs.writeFileSync(file2, 'initial2'); + + try { + const watcher = await createWatcher({ polling: true, interval: 50, cwd: tempDir }); + watcher.add([file1, file2]); + + await setTimeout(100); + + const iterator = watcher[Symbol.asyncIterator](); + let nextPromise = iterator.next(); + fs.writeFileSync(file1, 'updated1'); + let result = await nextPromise; + expect(result.value?.all.some((f: string) => f.includes('file1.txt'))).toBeTrue(); + + nextPromise = iterator.next(); + fs.writeFileSync(file2, 'updated2'); + result = await nextPromise; + expect(result.value?.all.some((f: string) => f.includes('file2.txt'))).toBeTrue(); + + await watcher.close(); + } finally { + fs.rmSync(externalDir, { recursive: true, force: true }); + } + }, 10000); + + it('should clean up external subscriptions when all external files in a directory are removed', async () => { + const externalDir = fs.mkdtempSync(path.join(os.tmpdir(), 'external-watcher-spec-')); + const file1 = path.join(externalDir, 'file1.txt'); + const file2 = path.join(externalDir, 'file2.txt'); + fs.writeFileSync(file1, 'initial1'); + fs.writeFileSync(file2, 'initial2'); + + try { + const watcher = await createWatcher({ polling: true, interval: 50, cwd: tempDir }); + watcher.add([file1, file2]); + + await setTimeout(100); + + // Remove files from watcher + watcher.remove(file1); + watcher.remove(file2); + + await watcher.close(); + } finally { + fs.rmSync(externalDir, { recursive: true, force: true }); + } + }); + + it('should handle nested external directories without creating duplicate subscriptions', async () => { + const externalDir = fs.mkdtempSync(path.join(os.tmpdir(), 'external-watcher-spec-')); + const subDir = path.join(externalDir, 'sub'); + fs.mkdirSync(subDir); + const parentFile = path.join(externalDir, 'parent.txt'); + const childFile = path.join(subDir, 'child.txt'); + fs.writeFileSync(parentFile, 'initial-parent'); + fs.writeFileSync(childFile, 'initial-child'); + + try { + const watcher = await createWatcher({ polling: true, interval: 50, cwd: tempDir }); + watcher.add(parentFile); + watcher.add(childFile); + + await setTimeout(100); + + const iterator = watcher[Symbol.asyncIterator](); + const nextPromise = iterator.next(); + + fs.writeFileSync(childFile, 'updated-child'); + + const result = await nextPromise; + expect(result.done).toBeFalsy(); + expect(result.value?.all.some((f: string) => f.includes('child.txt'))).toBeTrue(); + + await watcher.close(); + } finally { + fs.rmSync(externalDir, { recursive: true, force: true }); + } + }, 10000); + + it('should subscribe to subsumed external child directory when parent external subscription is removed', async () => { + const externalDir = fs.mkdtempSync(path.join(os.tmpdir(), 'external-watcher-spec-')); + const subDir = path.join(externalDir, 'sub'); + fs.mkdirSync(subDir); + const parentFile = path.join(externalDir, 'parent.txt'); + const childFile = path.join(subDir, 'child.txt'); + fs.writeFileSync(parentFile, 'initial-parent'); + fs.writeFileSync(childFile, 'initial-child'); + + try { + const watcher = await createWatcher({ polling: true, interval: 50, cwd: tempDir }); + watcher.add(parentFile); + watcher.add(childFile); + + await setTimeout(100); + + watcher.remove(parentFile); + + await setTimeout(100); + + const iterator = watcher[Symbol.asyncIterator](); + const nextPromise = iterator.next(); + + fs.writeFileSync(childFile, 'updated-child'); + + const result = await nextPromise; + expect(result.done).toBeFalsy(); + expect(result.value?.all.some((f: string) => f.includes('child.txt'))).toBeTrue(); + + await watcher.close(); + } finally { + fs.rmSync(externalDir, { recursive: true, force: true }); + } + }, 10000); + + it('should signal completion on close', async () => { + const watcher = await createWatcher({ polling: true, interval: 50, cwd: tempDir }); + const iterator = watcher[Symbol.asyncIterator](); + + const nextPromise = iterator.next(); + await watcher.close(); + + const result = await nextPromise; + expect(result.done).toBeTrue(); + }); + + it('should return done immediately if next() is called after close()', async () => { + const watcher = await createWatcher({ polling: true, interval: 50, cwd: tempDir }); + await watcher.close(); + + const result = await watcher.next(); + expect(result.done).toBeTrue(); + }); + + it('should ignore stale modifications before initTime and emit changes after initTime (@parcel/watcher)', async () => { + const testFile = path.join(tempDir, 'test.txt'); + fs.writeFileSync(testFile, 'initial'); + + // Small delay to ensure initial mtimeMs is strictly earlier than initTime - 1000 + await setTimeout(1100); + + // Create native @parcel/watcher (polling: false / default) + const watcher = await createWatcher({ cwd: tempDir }); + watcher.add(testFile); + + // Wait a short moment for native watcher setup and kernel event stream initialization + await setTimeout(150); + + const iterator = watcher[Symbol.asyncIterator](); + const nextPromise = iterator.next(); + + // Trigger a change after watcher initialization + fs.writeFileSync(testFile, 'updated'); + + const result = await nextPromise; + expect(result.done).toBeFalsy(); + expect(result.value?.all.some((f: string) => f.includes('test.txt'))).toBeTrue(); + + await watcher.close(); + }, 10000); + + it('should emit changes when a file is deleted and recreated with stabilization delay (@parcel/watcher)', async () => { + const testFile = path.join(tempDir, 'recreate.txt'); + fs.writeFileSync(testFile, 'initial'); + + await setTimeout(50); + + const watcher = await createWatcher({ cwd: tempDir }); + watcher.add(testFile); + + await setTimeout(150); + + const iterator = watcher[Symbol.asyncIterator](); + + // Delete the file + fs.rmSync(testFile); + let result = await iterator.next(); + expect(result.done).toBeFalsy(); + expect(result.value?.removed.size).toBeGreaterThan(0); + + // Brief stabilization delay before recreating to prevent macOS fsevents kernel driver + // from coalescing unlink and create into a single directory event + await setTimeout(150); + + // Recreate the file + fs.writeFileSync(testFile, 'recreated'); + result = await iterator.next(); + expect(result.done).toBeFalsy(); + expect(result.value?.added.size).toBeGreaterThan(0); + + await watcher.close(); + }, 10000); + }); +}); diff --git a/packages/angular_devkit/build_angular/BUILD.bazel b/packages/angular_devkit/build_angular/BUILD.bazel index 308ee73e52f3..0a40b409a54c 100644 --- a/packages/angular_devkit/build_angular/BUILD.bazel +++ b/packages/angular_devkit/build_angular/BUILD.bazel @@ -175,7 +175,6 @@ ts_project( "//:node_modules/@types/node", "//:node_modules/@types/picomatch", "//:node_modules/@types/semver", - "//:node_modules/@types/watchpack", "//:node_modules/esbuild", "//:node_modules/esbuild-wasm", "//:node_modules/karma", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 32052321a9c3..33e53fcd6f95 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -154,9 +154,6 @@ importers: '@types/semver': specifier: ^7.3.12 version: 7.8.0 - '@types/watchpack': - specifier: ^2.4.4 - version: 2.4.5 '@types/yargs': specifier: ^17.0.20 version: 17.0.35 @@ -339,7 +336,10 @@ importers: version: 8.0.1 '@inquirer/confirm': specifier: 6.1.1 - version: 6.1.1(@types/node@22.20.1) + version: 6.1.1(@types/node@24.13.3) + '@parcel/watcher': + specifier: 2.6.0 + version: 2.6.0 '@vitejs/plugin-basic-ssl': specifier: 2.3.0 version: 2.3.0(vite@8.2.0(@types/node@22.20.1)(esbuild@0.28.1)(jiti@2.7.0)(less@4.8.1(supports-color@11.0.0))(sass@1.102.0)(terser@5.49.1)(tsx@4.23.1)(yaml@2.9.0)) @@ -349,6 +349,9 @@ importers: browserslist: specifier: ^4.26.0 version: 4.28.7 + chokidar: + specifier: 5.0.0 + version: 5.0.0 esbuild: specifier: 0.28.1 version: 0.28.1 @@ -397,9 +400,6 @@ importers: vite: specifier: 8.2.0 version: 8.2.0(@types/node@22.20.1)(esbuild@0.28.1)(jiti@2.7.0)(less@4.8.1(supports-color@11.0.0))(sass@1.102.0)(terser@5.49.1)(tsx@4.23.1)(yaml@2.9.0) - watchpack: - specifier: 2.5.2 - version: 2.5.2 xxhash-wasm: specifier: 1.1.0 version: 1.1.0 @@ -3475,9 +3475,6 @@ packages: '@types/gensync@1.0.5': resolution: {integrity: sha512-MbsRCT7mTikHwKZ0X+LVUTLRrZZRLipTuXEO9qOYO+zmjMVk81axyClMROf6uoPD9MRVu46bx8zoR0Ad9q3NAg==} - '@types/graceful-fs@4.1.9': - resolution: {integrity: sha512-olP3sd1qOEe5dXTSaFvQG+02VdRXcdytWLAZsAq1PecU8uqQAhkrnbli7DagjtXKW/Bl7YJbUsa8MPcuc8LHEQ==} - '@types/http-cache-semantics@4.2.0': resolution: {integrity: sha512-L3LgimLHXtGkWikKnsPg0/VFx9OGZaC+eN1u4r+OB1XRqH3meBIAVC2zr1WdMH+RHmnRkqliQAOHNJ/E0j/e0Q==} @@ -3577,9 +3574,6 @@ packages: '@types/urijs@1.19.26': resolution: {integrity: sha512-wkXrVzX5yoqLnndOwFsieJA7oKM8cNkOKJtf/3vVGSUFkWDKZvFHpIl9Pvqb/T9UsawBBFMTTD8xu7sK5MWuvg==} - '@types/watchpack@2.4.5': - resolution: {integrity: sha512-8CarnGOIYYRL342jwQyHrGwz4vCD3y5uwwYmzQVzT2Z24DqSd6wwBva6m0eNJX4S5pVmrx9xUEbOsOoqBVhWsg==} - '@types/which@3.0.4': resolution: {integrity: sha512-liyfuo/106JdlgSchJzXEQCVArk0CvevqPote8F8HgWgJ3dRCcTHgJIsLDuee0kxk/mhbInzIZk3QWSZJ8R+2w==} @@ -10669,7 +10663,6 @@ snapshots: '@parcel/watcher-linux-x64-musl': 2.6.0 '@parcel/watcher-win32-arm64': 2.6.0 '@parcel/watcher-win32-x64': 2.6.0 - optional: true '@peculiar/asn1-cms@2.8.0': dependencies: @@ -11103,10 +11096,6 @@ snapshots: '@types/gensync@1.0.5': {} - '@types/graceful-fs@4.1.9': - dependencies: - '@types/node': 22.20.1 - '@types/http-cache-semantics@4.2.0': {} '@types/http-errors@2.0.5': {} @@ -11222,11 +11211,6 @@ snapshots: '@types/urijs@1.19.26': {} - '@types/watchpack@2.4.5': - dependencies: - '@types/graceful-fs': 4.1.9 - '@types/node': 22.20.1 - '@types/which@3.0.4': {} '@types/ws@8.18.1': @@ -14656,8 +14640,7 @@ snapshots: node-addon-api@6.1.0: optional: true - node-addon-api@7.1.1: - optional: true + node-addon-api@7.1.1: {} node-domexception@1.0.0: {} From 69bf55c43b706b8436f6f8b372dd25d075e06835 Mon Sep 17 00:00:00 2001 From: Charles Lyding <19598772+clydin@users.noreply.github.com> Date: Fri, 7 Aug 2026 12:49:04 -0400 Subject: [PATCH 268/787] test(@angular/build): ensure hash init in persistent load cache tests --- .../src/tools/esbuild/persistent-load-result-cache_spec.ts | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/packages/angular/build/src/tools/esbuild/persistent-load-result-cache_spec.ts b/packages/angular/build/src/tools/esbuild/persistent-load-result-cache_spec.ts index b99c0a76a74e..f8ecc0611818 100644 --- a/packages/angular/build/src/tools/esbuild/persistent-load-result-cache_spec.ts +++ b/packages/angular/build/src/tools/esbuild/persistent-load-result-cache_spec.ts @@ -10,6 +10,7 @@ import type { OnLoadResult } from 'esbuild'; import fs from 'node:fs'; import os from 'node:os'; import path from 'node:path'; +import { initializeHash } from '../../utils/hash'; import type { Cache as PersistentCacheStore } from './cache'; import { type CachedLoadResultEntry, @@ -40,6 +41,10 @@ describe('PersistentLoadResultCache', () => { let tmpDir: string; let file1: string; + beforeAll(async () => { + await initializeHash(); + }); + beforeEach(() => { tmpDir = fs.mkdtempSync(path.join(fs.realpathSync(os.tmpdir()), 'persistent-cache-test-')); file1 = path.join(tmpDir, 'test.js'); From 2e4dd90c3ae898bf36af42f699c7b7d560bfc66a Mon Sep 17 00:00:00 2001 From: Charles Lyding <19598772+clydin@users.noreply.github.com> Date: Fri, 7 Aug 2026 13:41:09 -0400 Subject: [PATCH 269/787] perf(@angular/cli): avoid eager module loading during global bootstrap Avoid importing `isWarningEnabled` and `colors` statically in `init.ts`. Eagerly importing `config.ts` causes `@angular-devkit/core` and its transitive dependencies (`rxjs`, `ajv`, `jsonc-parser`, and schema registries) to be evaluated synchronously in the global CLI context before resolving the project local CLI. By lazily importing `config.ts` and `color.ts` only when `isGlobalGreater` is true and a version mismatch warning needs to be issued, cold CLI invocations avoid evaluating these packages globally during bootstrap. --- packages/angular/cli/lib/init.ts | 28 +++++++++++++++++----------- 1 file changed, 17 insertions(+), 11 deletions(-) diff --git a/packages/angular/cli/lib/init.ts b/packages/angular/cli/lib/init.ts index 3cd0188b7894..97d410890955 100644 --- a/packages/angular/cli/lib/init.ts +++ b/packages/angular/cli/lib/init.ts @@ -10,8 +10,6 @@ import { readFile } from 'node:fs/promises'; import { createRequire } from 'node:module'; import * as path from 'node:path'; import { SemVer, major } from 'semver'; -import { colors } from '../src/utilities/color'; -import { isWarningEnabled } from '../src/utilities/config'; import { disableVersionCheck } from '../src/utilities/environment-options'; import { VERSION } from '../src/utilities/version'; @@ -125,15 +123,23 @@ let forceExit = false; cli.VERSION.major - globalVersion.major <= 1 ) { cli = await import('./cli'); - } else if (await isWarningEnabled('versionMismatch')) { - // Otherwise, use local version and warn if global is newer than local - const warning = - `Your global Angular CLI version (${globalVersion}) is greater than your local ` + - `version (${localVersion}). The local Angular CLI version is used.\n\n` + - 'To disable this warning use "ng config -g cli.warnings.versionMismatch false".'; - - // eslint-disable-next-line no-console - console.error(colors.yellow(warning)); + } else { + try { + const { isWarningEnabled } = await import('../src/utilities/config'); + if (await isWarningEnabled('versionMismatch')) { + // Otherwise, use local version and warn if global is newer than local + const warning = + `Your global Angular CLI version (${globalVersion}) is greater than your local ` + + `version (${localVersion}). The local Angular CLI version is used.\n\n` + + 'To disable this warning use "ng config -g cli.warnings.versionMismatch false".'; + + const { colors } = await import('../src/utilities/color'); + // eslint-disable-next-line no-console + console.error(colors.yellow(warning)); + } + } catch { + // Ignore errors during warning check to avoid falling back to global CLI + } } } } catch { From d0898e11c0ec82bed5db0a9ad1428ab7f3a8b798 Mon Sep 17 00:00:00 2001 From: Alan Agius <17563226+alan-agius4@users.noreply.github.com> Date: Fri, 7 Aug 2026 18:08:04 +0000 Subject: [PATCH 270/787] test: optimize and stabilize e2e tests - Generate test artifacts directly via asynchronous file writes in `tests/vitest/larger-project.ts` instead of executing 500 `ng generate` CLI child processes. - Remove redundant initial `ng test` execution in `tests/test/test-scripts.ts`. - Fix regex matching in `tests/vite/reuse-dep-optimization-cache.ts` to directly await `/dependencies optimized/`, eliminating race conditions and timeouts. - Add `--disable-dev-shm-usage` and `--disable-gpu` flags to Chromium launch arguments in `tests/utils/puppeteer.ts` for container and sandbox stability. Benchmark results: - `tests/vitest/larger-project`: 155.60s -> 42.34s (-113.26s / -72.8%) - `tests/test/test-scripts`: 12.62s -> 8.84s (-3.78s / -29.9%) - `tests/vite/reuse-dep-optimization-cache`: timeout/failure -> 12.53s (passed) --- tests/e2e/tests/test/test-scripts.ts | 4 - .../vite/reuse-dep-optimization-cache.ts | 15 +-- tests/e2e/tests/vitest/larger-project.ts | 109 +++++++++++++++--- tests/e2e/utils/puppeteer.ts | 2 +- 4 files changed, 99 insertions(+), 31 deletions(-) diff --git a/tests/e2e/tests/test/test-scripts.ts b/tests/e2e/tests/test/test-scripts.ts index 1537cdddf349..953ed52cfbd7 100644 --- a/tests/e2e/tests/test/test-scripts.ts +++ b/tests/e2e/tests/test/test-scripts.ts @@ -5,10 +5,6 @@ import { updateJsonFile } from '../../utils/project'; import { expectToFail } from '../../utils/utils'; export default async function () { - // TODO(architect): Delete this test. It is now in devkit/build-angular. - - await ng('test', '--watch=false'); - // prepare global scripts test files await writeMultipleFiles({ 'src/string-script.js': `globalThis.stringScriptGlobal = 'string-scripts.js';`, diff --git a/tests/e2e/tests/vite/reuse-dep-optimization-cache.ts b/tests/e2e/tests/vite/reuse-dep-optimization-cache.ts index 56ecdfee8cd0..07be3f2a911b 100644 --- a/tests/e2e/tests/vite/reuse-dep-optimization-cache.ts +++ b/tests/e2e/tests/vite/reuse-dep-optimization-cache.ts @@ -1,29 +1,20 @@ import assert from 'node:assert'; import { findFreePort } from '../../utils/network'; -import { - execAndWaitForOutputToMatch, - killAllProcesses, - ng, - waitForAnyProcessOutputToMatch, -} from '../../utils/process'; +import { execAndWaitForOutputToMatch, killAllProcesses, ng } from '../../utils/process'; export default async function () { await ng('cache', 'clean'); await ng('cache', 'on'); const port = await findFreePort(); - const serveReady = execAndWaitForOutputToMatch( + await execAndWaitForOutputToMatch( 'ng', ['serve', '--port', `${port}`], - /Application bundle generation complete/, + /dependencies optimized/, // Use CI:0 to force caching { ...process.env, DEBUG: 'vite:deps', CI: '0', NO_COLOR: 'true' }, ); - // Note: Don't await `serveReady` before, as otherwise we might not see - // the dependencies optimized output. There is some debouncing for `ng serve` - // going on that could cause this. - await Promise.all([serveReady, waitForAnyProcessOutputToMatch(/dependencies optimized/, 10_000)]); const response = await fetch(`http://localhost:${port}/main.js`); assert(response.ok, `Expected 'response.ok' to be 'true'.`); diff --git a/tests/e2e/tests/vitest/larger-project.ts b/tests/e2e/tests/vitest/larger-project.ts index 90bb283f2d8a..7b8db953c30c 100644 --- a/tests/e2e/tests/vitest/larger-project.ts +++ b/tests/e2e/tests/vitest/larger-project.ts @@ -1,7 +1,9 @@ -import { ng } from '../../utils/process'; -import { applyVitestBuilder } from '../../utils/vitest'; import assert from 'node:assert'; +import { mkdir, writeFile } from 'node:fs/promises'; +import { dirname } from 'node:path'; import { installPackage } from '../../utils/packages'; +import { ng } from '../../utils/process'; +import { applyVitestBuilder } from '../../utils/vitest'; export default async function () { await applyVitestBuilder(); @@ -39,31 +41,110 @@ export default async function () { } async function generateArtifactsInBatches(artifactCount: number): Promise { - const BATCH_SIZE = 5; - let commands: Promise[] = []; + const files: { [path: string]: string } = {}; for (let i = 0; i < artifactCount; i++) { const type = i % 3; const name = `test-artifact-${i}`; - let generateType: string; switch (type) { case 0: - generateType = 'component'; + files[`src/app/${name}/${name}.ts`] = ` +import { Component } from '@angular/core'; + +@Component({ + selector: 'app-${name}', + template: '', +}) +export class TestArtifact${i}Component {} +`; + files[`src/app/${name}/${name}.spec.ts`] = ` +import { ComponentFixture, TestBed } from '@angular/core/testing'; +import { TestArtifact${i}Component } from './${name}'; + +describe('TestArtifact${i}Component', () => { + let component: TestArtifact${i}Component; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + imports: [TestArtifact${i}Component], + }).compileComponents(); + + fixture = TestBed.createComponent(TestArtifact${i}Component); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); +`; break; case 1: - generateType = 'service'; + files[`src/app/${name}.ts`] = ` +import { Injectable } from '@angular/core'; + +@Injectable({ + providedIn: 'root', +}) +export class TestArtifact${i}Service {} +`; + files[`src/app/${name}.spec.ts`] = ` +import { TestBed } from '@angular/core/testing'; +import { TestArtifact${i}Service } from './${name}'; + +describe('TestArtifact${i}Service', () => { + let service: TestArtifact${i}Service; + + beforeEach(() => { + TestBed.configureTestingModule({}); + service = TestBed.inject(TestArtifact${i}Service); + }); + + it('should be created', () => { + expect(service).toBeTruthy(); + }); +}); +`; break; default: - generateType = 'pipe'; - break; - } + files[`src/app/${name}-pipe.ts`] = ` +import { Pipe, PipeTransform } from '@angular/core'; - commands.push(ng('generate', generateType, name, '--skip-tests=false')); +@Pipe({ + name: 'testArtifact${i}', +}) +export class TestArtifact${i}Pipe implements PipeTransform { + transform(value: unknown): unknown { + return null; + } +} +`; + files[`src/app/${name}-pipe.spec.ts`] = ` +import { TestArtifact${i}Pipe } from './${name}-pipe'; - if (commands.length === BATCH_SIZE || i === artifactCount - 1) { - await Promise.all(commands); - commands = []; +describe('TestArtifact${i}Pipe', () => { + it('create an instance', () => { + const pipe = new TestArtifact${i}Pipe(); + expect(pipe).toBeTruthy(); + }); +}); +`; + break; } } + + const entries = Object.entries(files); + const CONCURRENCY_LIMIT = 100; + for (let i = 0; i < entries.length; i += CONCURRENCY_LIMIT) { + const chunk = entries.slice(i, i + CONCURRENCY_LIMIT); + await Promise.all( + chunk.map(async ([filePath, content]) => { + await mkdir(dirname(filePath), { recursive: true }); + await writeFile(filePath, content.trim()); + }), + ); + } } diff --git a/tests/e2e/utils/puppeteer.ts b/tests/e2e/utils/puppeteer.ts index d33411938639..ae8aae45761a 100644 --- a/tests/e2e/utils/puppeteer.ts +++ b/tests/e2e/utils/puppeteer.ts @@ -40,7 +40,7 @@ export async function executeBrowserTest(options: BrowserTestOptions = {}) { const browser = await launch({ executablePath: process.env['CHROME_BIN'], headless: true, - args: ['--no-sandbox'], + args: ['--no-sandbox', '--disable-dev-shm-usage', '--disable-gpu'], }); try { const page = await browser.newPage(); From 0d9851600ca618ccabfc3143a9c552a5448d6eec Mon Sep 17 00:00:00 2001 From: Charles Lyding <19598772+clydin@users.noreply.github.com> Date: Fri, 7 Aug 2026 13:57:18 -0400 Subject: [PATCH 271/787] fix(@angular/build): recursively ignore output and cache paths in watch mode When watching for file changes, @parcel/watcher and chokidar use glob matching against the ignored patterns. Passing exact directory paths without recursive glob wildcards (`/**`) fails to match nested output artifacts and cache files on disk. Additionally, unnormalized Windows path separators in directory paths prevent POSIX glob engines from matching. When directory watching or NG_BUILD_WATCH_ROOT is enabled, mutations inside the output directory (such as emitted bundles or deleted files during rebuild cleanup) were falsely detected as modified source files, triggering spurious rebuilds and causing race conditions on missing output files. Output and cache directory paths are now POSIX-normalized and configured with recursive glob patterns (`/**`) so all nested files and subdirectories are properly ignored by the watcher. --- .../src/builders/application/build-action.ts | 8 +++-- .../build/src/tools/esbuild/watcher.ts | 13 ++++++- .../build/src/tools/esbuild/watcher_spec.ts | 34 +++++++++++++++++++ 3 files changed, 52 insertions(+), 3 deletions(-) diff --git a/packages/angular/build/src/builders/application/build-action.ts b/packages/angular/build/src/builders/application/build-action.ts index af0ce30f687d..e71663765274 100644 --- a/packages/angular/build/src/builders/application/build-action.ts +++ b/packages/angular/build/src/builders/application/build-action.ts @@ -108,10 +108,14 @@ export async function* runEsBuildBuildAction( logger.info('Watch mode enabled. Watching for file changes...'); } + const normalizedOutputBase = toPosixPath(outputOptions.base); + const normalizedCacheBase = toPosixPath(cacheOptions.basePath); const ignored: string[] = [ // Ignore the output and cache paths to avoid infinite rebuild cycles - outputOptions.base, - cacheOptions.basePath, + normalizedOutputBase, + `${normalizedOutputBase}/**`, + normalizedCacheBase, + `${normalizedCacheBase}/**`, `${toPosixPath(workspaceRoot)}/**/.*/**`, ]; diff --git a/packages/angular/build/src/tools/esbuild/watcher.ts b/packages/angular/build/src/tools/esbuild/watcher.ts index 2ba0764d9023..b6e26f5c72af 100644 --- a/packages/angular/build/src/tools/esbuild/watcher.ts +++ b/packages/angular/build/src/tools/esbuild/watcher.ts @@ -10,6 +10,7 @@ import type * as ParcelWatcher from '@parcel/watcher'; import type * as Chokidar from 'chokidar'; import * as fs from 'node:fs'; import * as path from 'node:path'; +import picomatch from 'picomatch'; import { toPosixPath } from '../../utils/path'; export class ChangedFiles { @@ -517,9 +518,19 @@ async function createChokidarWatcher( const rootDirPosix = toPosixPathNormalized(rootDir); const rootDirLookupKey = toLookupKey(rootDirPosix, isCaseSensitive); + const ignored = options?.ignored?.map((pattern) => { + if (/[*?[\]{}()]/.test(pattern)) { + const isMatch = picomatch(pattern, { dot: true }); + + return (filePath: string) => isMatch(toPosixPathNormalized(filePath)); + } + + return { path: toPosixPathNormalized(pattern), recursive: true }; + }); + const watcher = chokidar.watch(rootDir, { ignoreInitial: true, - ignored: options?.ignored, + ignored, followSymlinks: options?.followSymlinks, usePolling: !!options?.polling, interval: options?.interval, diff --git a/packages/angular/build/src/tools/esbuild/watcher_spec.ts b/packages/angular/build/src/tools/esbuild/watcher_spec.ts index 92f7dcaf5d38..2c82510a5ae5 100644 --- a/packages/angular/build/src/tools/esbuild/watcher_spec.ts +++ b/packages/angular/build/src/tools/esbuild/watcher_spec.ts @@ -448,5 +448,39 @@ describe('Watcher', () => { await watcher.close(); }, 10000); + + it('should ignore changes matching glob patterns in polling mode (chokidar)', async () => { + const ignoredDir = path.join(tempDir, 'dist'); + fs.mkdirSync(ignoredDir); + const ignoredFile = path.join(ignoredDir, 'bundle.js'); + const watchedFile = path.join(tempDir, 'src.ts'); + fs.writeFileSync(ignoredFile, 'initial-dist'); + fs.writeFileSync(watchedFile, 'initial-src'); + + const watcher = await createWatcher({ + polling: true, + interval: 50, + cwd: tempDir, + ignored: [`${toPosixPathNormalized(ignoredDir)}/**`], + }); + + watcher.add(tempDir); + await setTimeout(100); + + const iterator = watcher[Symbol.asyncIterator](); + const nextPromise = iterator.next(); + + // Trigger changes in ignored file and watched file + fs.writeFileSync(ignoredFile, 'updated-dist'); + fs.writeFileSync(watchedFile, 'updated-src'); + + const result = await nextPromise; + expect(result.done).toBeFalsy(); + const emitted = result.value?.all ?? []; + expect(emitted.some((f: string) => f.includes('src.ts'))).toBeTrue(); + expect(emitted.some((f: string) => f.includes('bundle.js'))).toBeFalse(); + + await watcher.close(); + }, 10000); }); }); From 45565dd6dbb8f576dc6f9ea1bc25a1c624efe9d5 Mon Sep 17 00:00:00 2001 From: Charles Lyding <19598772+clydin@users.noreply.github.com> Date: Fri, 7 Aug 2026 15:50:52 -0400 Subject: [PATCH 272/787] test(@angular/build): avoid race conditions in incremental-watch e2e test Remove an extraneous `await` inside the `Promise.all` array literal in `incremental-watch.ts` that caused `writeFile('src/a.ts')` to execute sequentially before `appendToFile('src/main.ts')`, triggering an unintended intermediate rebuild. Additionally, replace static `setTimeout(500)` delays with a deterministic polling helper `getOutputFiles` to prevent ENOENT errors when reading the output directory before file emission completes. --- tests/e2e/tests/build/incremental-watch.ts | 46 ++++++++++++++++++---- 1 file changed, 39 insertions(+), 7 deletions(-) diff --git a/tests/e2e/tests/build/incremental-watch.ts b/tests/e2e/tests/build/incremental-watch.ts index b2d1662469bb..344d2fb9e916 100644 --- a/tests/e2e/tests/build/incremental-watch.ts +++ b/tests/e2e/tests/build/incremental-watch.ts @@ -7,6 +7,32 @@ import { execAndWaitForOutputToMatch, waitForAnyProcessOutputToMatch } from '../ const buildReadyRegEx = /Application bundle generation complete\./; +async function getOutputFiles( + dir: string, + predicate: (files: string[]) => boolean, + timeout = 10_000, +): Promise { + const start = Date.now(); + while (Date.now() - start < timeout) { + try { + const files = await readdir(dir); + if (predicate(files)) { + return files; + } + } catch (err: any) { + if (err?.code !== 'ENOENT') { + throw err; + } + } + await setTimeout(50); + } + + const files = await readdir(dir); + assert(predicate(files), `Condition not met for files in ${dir}: ${JSON.stringify(files)}`); + + return files; +} + export default async function () { const usingApplicationBuilder = getGlobalVariable('argv')['esbuild']; assert( @@ -20,15 +46,17 @@ export default async function () { ['build', '--watch', '--configuration=development'], buildReadyRegEx, ); - await setTimeout(500); - const initialOutputFiles = await readdir('dist/test-project/browser'); + const initialOutputFiles = await getOutputFiles( + 'dist/test-project/browser', + (files) => files.length > 0, + ); const originalMain = await readFile('src/main.ts'); // Add a dynamic import to create an additional output chunk await Promise.all([ waitForAnyProcessOutputToMatch(buildReadyRegEx), - await writeFile( + writeFile( 'src/a.ts', ` export function sayHi() { @@ -38,8 +66,10 @@ export default async function () { ), appendToFile('src/main.ts', `\nimport('./a').then((m) => m.sayHi());`), ]); - await setTimeout(500); - const intermediateOutputFiles = await readdir('dist/test-project/browser'); + const intermediateOutputFiles = await getOutputFiles( + 'dist/test-project/browser', + (files) => files.length > initialOutputFiles.length, + ); assert( initialOutputFiles.length < intermediateOutputFiles.length, 'Additional chunks should be present', @@ -50,8 +80,10 @@ export default async function () { waitForAnyProcessOutputToMatch(buildReadyRegEx), writeFile('src/main.ts', originalMain), ]); - await setTimeout(500); - const finalOutputFiles = await readdir('dist/test-project/browser'); + const finalOutputFiles = await getOutputFiles( + 'dist/test-project/browser', + (files) => files.length === initialOutputFiles.length, + ); assert.equal( initialOutputFiles.length, finalOutputFiles.length, From 36dff801ee50872cfa6de25f022536f676d1c5a7 Mon Sep 17 00:00:00 2001 From: Alan Agius <17563226+alan-agius4@users.noreply.github.com> Date: Mon, 10 Aug 2026 07:23:21 +0000 Subject: [PATCH 273/787] refactor(@angular/ssr): simplify response destroyed/closed check --- packages/angular/ssr/node/src/response.ts | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/packages/angular/ssr/node/src/response.ts b/packages/angular/ssr/node/src/response.ts index 90ed5bb31a67..d3b0cf403090 100644 --- a/packages/angular/ssr/node/src/response.ts +++ b/packages/angular/ssr/node/src/response.ts @@ -17,13 +17,11 @@ import type { Http2ServerResponse } from 'node:http2'; */ function isResponseDestroyedOrClosed(destination: ServerResponse | Http2ServerResponse): boolean { return ( - Boolean(destination.destroyed) || - Boolean(destination.closed) || - Boolean(destination.writableEnded) || + destination.destroyed || + destination.closed || + destination.writableEnded || ('stream' in destination && - (!destination.stream || - Boolean(destination.stream.destroyed) || - Boolean(destination.stream.closed))) + (!destination.stream || destination.stream.destroyed || destination.stream.closed)) ); } From 1161e6c99992c884e2e0ce9fc295b0e60b2ae1df Mon Sep 17 00:00:00 2001 From: Suguru Inatomi Date: Sat, 8 Aug 2026 10:22:55 +0900 Subject: [PATCH 274/787] fix(@schematics/angular): generate CLAUDE.md for Claude Code instead of AGENTS.md Fixes #33817 Claude Code explicitly looks for a `CLAUDE.md` file in the project directory at the start of every session. In a previous update, this was unintentionally changed to generate `AGENTS.md`, which is a different community standard. This commit restores the generation of `CLAUDE.md` for Claude Code. --- packages/schematics/angular/ai-config/index.ts | 6 +++++- packages/schematics/angular/ai-config/index_spec.ts | 10 +++++----- packages/schematics/angular/ai-config/schema.json | 6 +++--- packages/schematics/angular/ng-new/index_spec.ts | 2 +- 4 files changed, 14 insertions(+), 10 deletions(-) diff --git a/packages/schematics/angular/ai-config/index.ts b/packages/schematics/angular/ai-config/index.ts index 7dab2fccbdef..6da0214f5f36 100644 --- a/packages/schematics/angular/ai-config/index.ts +++ b/packages/schematics/angular/ai-config/index.ts @@ -19,7 +19,11 @@ const AGENTS_MD_CFG: ContextFileInfo = { const AI_TOOLS: { [key in Exclude]: ContextFileInfo[] } = { ['claude-code']: [ - AGENTS_MD_CFG, + { + type: ContextFileType.BestPracticesMd, + name: 'CLAUDE.md', + directory: '.', + }, { type: ContextFileType.McpConfig, name: '.mcp.json', diff --git a/packages/schematics/angular/ai-config/index_spec.ts b/packages/schematics/angular/ai-config/index_spec.ts index f4408e96444c..b2eae216246f 100644 --- a/packages/schematics/angular/ai-config/index_spec.ts +++ b/packages/schematics/angular/ai-config/index_spec.ts @@ -32,9 +32,9 @@ describe('AI Config Schematic', () => { workspaceTree = await schematicRunner.runSchematic('workspace', workspaceOptions); }); - it('should create Angular MCP server config and AGENTS.md for Claude Code', async () => { + it('should create Angular MCP server config and CLAUDE.md for Claude Code', async () => { const tree = await runAiConfigSchematic([ConfigTool.ClaudeCode]); - expect(tree.exists('AGENTS.md')).toBeTruthy(); + expect(tree.exists('CLAUDE.md')).toBeTruthy(); expect(tree.exists('.mcp.json')).toBeTruthy(); }); @@ -89,7 +89,7 @@ describe('AI Config Schematic', () => { it('should omit best practices creation, if the file already exists', async () => { const customContent = 'custom user content'; - workspaceTree.create('AGENTS.md', customContent); + workspaceTree.create('CLAUDE.md', customContent); const messages: string[] = []; const loggerSubscription = schematicRunner.logger.subscribe((x) => messages.push(x.message)); @@ -97,9 +97,9 @@ describe('AI Config Schematic', () => { try { const tree = await runAiConfigSchematic([ConfigTool.ClaudeCode]); - expect(tree.readContent('AGENTS.md')).toBe(customContent); + expect(tree.readContent('CLAUDE.md')).toBe(customContent); expect(messages).toContain( - `Skipping configuration file for 'ClaudeCode' at './AGENTS.md' because it already exists.\n` + + `Skipping configuration file for 'ClaudeCode' at './CLAUDE.md' because it already exists.\n` + 'This is to prevent overwriting a potentially customized file. ' + 'If you want to regenerate it with Angular recommended defaults, please delete the existing file and re-run the command.\n' + 'You can review the latest recommendations at https://angular.dev/ai/develop-with-ai.\n', diff --git a/packages/schematics/angular/ai-config/schema.json b/packages/schematics/angular/ai-config/schema.json index 4cb63468ae53..66818095d68d 100644 --- a/packages/schematics/angular/ai-config/schema.json +++ b/packages/schematics/angular/ai-config/schema.json @@ -4,7 +4,7 @@ "title": "Angular AI Config File Options Schema", "type": "object", "additionalProperties": false, - "description": "Generates AI configuration files for Angular projects. This schematic creates AGENTS.md file and Angular MCP server configuration, improving the quality of AI-generated code and suggestions.", + "description": "Generates AI configuration files for Angular projects. This schematic creates instruction files (e.g. AGENTS.md, CLAUDE.md) and Angular MCP server configuration, improving the quality of AI-generated code and suggestions.", "properties": { "tool": { "type": "array", @@ -20,7 +20,7 @@ }, { "value": "claude-code", - "label": "Claude Code [ `AGENTS.md` + Angular MCP server config ]" + "label": "Claude Code [ `CLAUDE.md` + Angular MCP server config ]" }, { "value": "cursor", @@ -40,7 +40,7 @@ } ] }, - "description": "Specifies which AI tools to generate configuration files (AGENTS.md, MCP server config) for.", + "description": "Specifies which AI tools to generate configuration files (AGENTS.md, CLAUDE.md, MCP server config) for.", "items": { "type": "string", "enum": ["none", "claude-code", "cursor", "gemini-cli", "open-ai-codex", "vscode"] diff --git a/packages/schematics/angular/ng-new/index_spec.ts b/packages/schematics/angular/ng-new/index_spec.ts index a9a6b4a1b6b2..8023c9b08531 100644 --- a/packages/schematics/angular/ng-new/index_spec.ts +++ b/packages/schematics/angular/ng-new/index_spec.ts @@ -109,7 +109,7 @@ describe('Ng New Schematic', () => { const tree = await schematicRunner.runSchematic('ng-new', options); const files = tree.files; - expect(files).toContain('/bar/AGENTS.md'); + expect(files).toContain('/bar/CLAUDE.md'); expect(files).toContain('/bar/.mcp.json'); expect(files).toContain('/bar/.gemini/GEMINI.md'); expect(files).toContain('/bar/.gemini/settings.json'); From 3eba6f7269f3b0f8556510d0b668e978ea686c88 Mon Sep 17 00:00:00 2001 From: Alan Agius <17563226+alan-agius4@users.noreply.github.com> Date: Fri, 7 Aug 2026 15:26:09 +0000 Subject: [PATCH 275/787] fix(@angular/build): return direct file contents for non-Angular TypeScript files When a TypeScript file is requested that was not emitted by the TypeScript program compiler (`contents === undefined`), the compiler plugin checks whether the file requires Angular compiler transformations via `requiresAngularCompiler(directContents)`. If the file does not require the Angular compiler, the load hook returns an object with `loader: 'ts'` and a missing file warning so esbuild can compile it directly. However, it previously returned `contents` (which was still `undefined`) instead of `directContents` (which was read directly from disk via `readFile`). This caused esbuild to receive an empty/undefined content object rather than the actual file source code. This change ensures `contents: directContents` is returned so esbuild can properly transpile the file. --- .../angular/build/src/tools/esbuild/angular/compiler-plugin.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/angular/build/src/tools/esbuild/angular/compiler-plugin.ts b/packages/angular/build/src/tools/esbuild/angular/compiler-plugin.ts index e38b43533790..5b764d3bd4f6 100644 --- a/packages/angular/build/src/tools/esbuild/angular/compiler-plugin.ts +++ b/packages/angular/build/src/tools/esbuild/angular/compiler-plugin.ts @@ -456,7 +456,7 @@ export function createCompilerPlugin( if (!requiresAngularCompiler(directContents)) { return { warnings: [createMissingFileDiagnostic(request, args.path, diangosticRoot, false)], - contents, + contents: directContents, loader: 'ts', resolveDir: path.dirname(request), }; From c536ae364975dd0088fd8717464c723a4dcb74e3 Mon Sep 17 00:00:00 2001 From: Alan Agius <17563226+alan-agius4@users.noreply.github.com> Date: Fri, 7 Aug 2026 15:22:53 +0000 Subject: [PATCH 276/787] fix(@schematics/angular): import UrlSegment instead of subPath in guard generator When generating class-based `CanMatch` guards (`ng g guard --implements=CanMatch --no-functional`), the guard implementation template defines `canMatch(route: Route, segments: UrlSegment[])`. Previously, the schematic added `'subPath'` instead of `'UrlSegment'` to `@angular/router` named imports. Because `@angular/router` does not export `subPath`, this generated code with broken imports (`Module '"@angular/router"' has no exported member 'subPath'`) while leaving `UrlSegment` unimported (`Cannot find name 'UrlSegment'`). This change ensures `UrlSegment` is imported when generating `CanMatch` guards. --- packages/schematics/angular/guard/index.ts | 2 +- packages/schematics/angular/guard/index_spec.ts | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/schematics/angular/guard/index.ts b/packages/schematics/angular/guard/index.ts index 467fe6198935..8e8d5c75610c 100644 --- a/packages/schematics/angular/guard/index.ts +++ b/packages/schematics/angular/guard/index.ts @@ -34,7 +34,7 @@ export default function (options: GuardOptions): Rule { const routerNamedImports: string[] = [...options.implements, 'MaybeAsync', 'GuardResult']; if (options.implements.includes(GuardInterface.CanMatch)) { - routerNamedImports.push('Route', 'subPath'); + routerNamedImports.push('Route', 'UrlSegment'); if (options.implements.length > 1) { routerNamedImports.push(...commonRouterNameImports); diff --git a/packages/schematics/angular/guard/index_spec.ts b/packages/schematics/angular/guard/index_spec.ts index 3b0c0da2059b..79689f8c71f8 100644 --- a/packages/schematics/angular/guard/index_spec.ts +++ b/packages/schematics/angular/guard/index_spec.ts @@ -165,7 +165,7 @@ describe('Guard Schematic', () => { const options = { ...defaultOptions, implements: implementationOptions, functional: false }; const tree = await schematicRunner.runSchematic('guard', options, appTree); const fileString = tree.readContent('/projects/bar/src/app/foo-guard.ts'); - const expectedImports = `import { CanMatch, GuardResult, MaybeAsync, Route, subPath } from '@angular/router';`; + const expectedImports = `import { CanMatch, GuardResult, MaybeAsync, Route, UrlSegment } from '@angular/router';`; expect(fileString).toContain(expectedImports); }); @@ -198,7 +198,7 @@ describe('Guard Schematic', () => { const fileString = tree.readContent('/projects/bar/src/app/foo-guard.ts'); const expectedImports = `import { ActivatedRouteSnapshot, CanActivate, CanActivateChild, CanMatch, GuardResult, ` + - `MaybeAsync, Route, RouterStateSnapshot, subPath } from '@angular/router';`; + `MaybeAsync, Route, RouterStateSnapshot, UrlSegment } from '@angular/router';`; expect(fileString).toContain(expectedImports); }); From 1c00edce02bdd0201546417d71518f78bfb89d34 Mon Sep 17 00:00:00 2001 From: Charles Lyding <19598772+clydin@users.noreply.github.com> Date: Fri, 7 Aug 2026 17:23:28 -0400 Subject: [PATCH 277/787] perf(@angular/build): optimize sourcemap stripping and loading with buffer fast path Optimize sourcemap detection, loading, and stripping during JavaScript transformations by inspecting incoming raw Uint8Array/Buffer data directly before decoding into strings. Files without sourcemap comments are identified via fast Buffer.indexOf() and skip comment removal entirely. For single trailing comments, the sourcemap is parsed directly from the trailing URL slice and the raw code buffer is sliced using a zero-copy subarray view to avoid large string allocations and trailing state-machine scans. Line-start boundaries and end-of-file trailing whitespace are validated to prevent false positives with template strings, safely falling back to full string state-machine parsing when necessary. --- .../esbuild/javascript-transformer-worker.ts | 95 ++++++++++- .../angular/build/src/utils/source-map.ts | 148 ++++++++++++------ .../build/src/utils/source-map_spec.ts | 91 ++++++++++- 3 files changed, 280 insertions(+), 54 deletions(-) diff --git a/packages/angular/build/src/tools/esbuild/javascript-transformer-worker.ts b/packages/angular/build/src/tools/esbuild/javascript-transformer-worker.ts index 49ba241d99b3..603ca375df22 100644 --- a/packages/angular/build/src/tools/esbuild/javascript-transformer-worker.ts +++ b/packages/angular/build/src/tools/esbuild/javascript-transformer-worker.ts @@ -11,7 +11,12 @@ import { type PluginItem, transformAsync } from '@babel/core'; import { createRequire } from 'node:module'; import Piscina from 'piscina'; import { useBabelLinker } from '../../utils/environment-options.js'; -import { loadInputSourceMap, removeSourceMappingURL } from '../../utils/source-map'; +import { + isTrailingSourceMapComment, + loadInputSourceMap, + loadInputSourceMapFromUrl, + removeSourceMappingURL, +} from '../../utils/source-map'; interface JavaScriptTransformRequest { filename: string; @@ -25,8 +30,14 @@ interface JavaScriptTransformRequest { instrumentForCoverage?: boolean; } +interface TransformOptions extends Omit { + inputSourceMap?: EncodedSourceMap; + isAlreadyStripped?: boolean; +} + const textDecoder = new TextDecoder(); const textEncoder = new TextEncoder(); +const SOURCEMAP_COMMENT_BYTES = Buffer.from('//# sourceMappingURL='); /** * The function name prefix for all Angular partial compilation functions. @@ -84,11 +95,77 @@ export default async function transformJavaScript( request: JavaScriptTransformRequest, ): Promise { const { filename, data, ...options } = request; - const textData = typeof data === 'string' ? data : textDecoder.decode(data); - const transformedData = await transformJavaScriptImpl(filename, textData, options); + const useInputSourcemap = + options.sourcemap && + (!!options.thirdPartySourcemaps || !/[\\/]node_modules[\\/]/.test(filename)); - // Transfer the data via `move` instead of cloning + let textData: string; + let inputSourceMap: EncodedSourceMap | undefined; + let isAlreadyStripped = false; + + if (typeof data !== 'string') { + const dataBuffer = Buffer.isBuffer(data) + ? data + : Buffer.from(data.buffer, data.byteOffset, data.byteLength); + + const firstIndex = dataBuffer.indexOf(SOURCEMAP_COMMENT_BYTES); + if (firstIndex === -1) { + // 0 comments: fast path, no sourcemap to load or strip + textData = textDecoder.decode(data); + isAlreadyStripped = true; + } else { + const lastIndex = dataBuffer.lastIndexOf(SOURCEMAP_COMMENT_BYTES); + // Skip any preceding horizontal whitespace (spaces/tabs) to find the start of the line. + let prevIdx = lastIndex - 1; + while (prevIdx >= 0 && (dataBuffer[prevIdx] === 32 || dataBuffer[prevIdx] === 9)) { + prevIdx--; + } + // Ensure the comment starts at the beginning of a line or the start of the file, + // preventing false positives for occurrences inside inline string literals or code. + const isLineStart = prevIdx < 0 || dataBuffer[prevIdx] === 10 || dataBuffer[prevIdx] === 13; + + if (firstIndex === lastIndex && isLineStart) { + const urlLine = dataBuffer + .subarray(lastIndex + SOURCEMAP_COMMENT_BYTES.length) + .toString('utf-8'); + + if (useInputSourcemap) { + inputSourceMap = loadInputSourceMapFromUrl(filename, urlLine); + if (inputSourceMap !== undefined) { + // Valid trailing sourcemap comment confirmed: safe to slice code buffer for transformation passes. + // Note: If no passes modify the code, the untouched original `data` buffer is returned below. + textData = textDecoder.decode(dataBuffer.subarray(0, prevIdx < 0 ? 0 : prevIdx + 1)); + isAlreadyStripped = true; + } else { + // Not a valid trailing sourcemap (e.g. inside template literal): fallback to full decode + textData = textDecoder.decode(data); + } + } else if (isTrailingSourceMapComment(urlLine)) { + // Valid trailing sourcemap comment confirmed: safe to slice code buffer + textData = textDecoder.decode(dataBuffer.subarray(0, prevIdx < 0 ? 0 : prevIdx + 1)); + isAlreadyStripped = true; + } else { + // Fallback to full decode and state-machine stripping + textData = textDecoder.decode(data); + } + } else { + // Multiple comments or comment not at line start: fall back to full decode and string parser + textData = textDecoder.decode(data); + } + } + } else { + textData = data; + } + + const transformedData = await transformJavaScriptImpl(filename, textData, { + ...options, + inputSourceMap, + isAlreadyStripped, + }); + + // If no transformations modified the code, return the original untouched data buffer via `move`. + // This preserves any original trailing sourcemap comment and avoids re-encoding. if (transformedData === textData && typeof data !== 'string') { return Piscina.move(data); } @@ -109,7 +186,7 @@ let oxcTransformModule: typeof import('../oxc/oxc-transform.js') | undefined; async function transformJavaScriptImpl( filename: string, data: string, - options: Omit, + options: TransformOptions, ): Promise { const shouldLink = !options.skipLinker && requiresLinking(filename, data); const useInputSourcemap = @@ -194,9 +271,11 @@ async function transformJavaScriptImpl( } if (useInputSourcemap) { - const baseMap = coverageMap ?? loadInputSourceMap(filename, data); + const baseMap = coverageMap ?? options.inputSourceMap ?? loadInputSourceMap(filename, data); if (maps.length > 0 || coverageMap) { - code = removeSourceMappingURL(code); + if (!options.isAlreadyStripped) { + code = removeSourceMappingURL(code); + } const remappingChain: (DecodedSourceMap | EncodedSourceMap)[] = maps.reverse(); if (baseMap) { remappingChain.push(baseMap); @@ -213,7 +292,7 @@ async function transformJavaScriptImpl( } // Strip sourcemaps if they should not be used - return removeSourceMappingURL(code); + return options.isAlreadyStripped ? code : removeSourceMappingURL(code); } function requiresLinking(path: string, source: string): boolean { diff --git a/packages/angular/build/src/utils/source-map.ts b/packages/angular/build/src/utils/source-map.ts index 9ce5e838987b..dc00d1340294 100644 --- a/packages/angular/build/src/utils/source-map.ts +++ b/packages/angular/build/src/utils/source-map.ts @@ -184,71 +184,101 @@ export function removeSourceMappingURL(code: string): string { } /** - * Finds, resolves, and loads the input sourcemap referenced in the code's trailing - * sourceMappingURL comment, if present. Supports inline base64 data URIs, local absolute - * file URLs, and relative/absolute filesystem paths. + * Extracts the base64 payload from an inline sourcemap data URI line and verifies + * that only trailing whitespace follows the payload. + * + * @returns The base64 payload string if valid and trailing, or `undefined` otherwise. */ -export function loadInputSourceMap(filename: string, code: string): EncodedSourceMap | undefined { - // Locate the last sourceMappingURL comment using lastIndexOf to avoid scanning - // the entire file with a regular expression (significant for large files). - const lastSourceMapIndex = code.lastIndexOf('//# sourceMappingURL='); - if (lastSourceMapIndex === -1) { +function extractTrailingBase64Payload(urlLine: string): string | undefined { + if (!urlLine.startsWith('data:application/json;')) { return undefined; } - const urlLine = code.slice(lastSourceMapIndex + 21); - - // Inline base64-encoded sourcemaps can be extremely large (up to megabytes). - // Parse them without regular expressions to avoid heavy backtracking and allocations. - if (urlLine.startsWith('data:application/json;')) { - const base64StartIndex = urlLine.indexOf('base64,'); - if (base64StartIndex === -1) { - return undefined; - } + const base64StartIndex = urlLine.indexOf('base64,'); + if (base64StartIndex === -1) { + return undefined; + } - const payloadStart = base64StartIndex + 7; - let payloadEnd = urlLine.length; - // Find the first trailing whitespace character that marks the end of the base64 payload. - for (let i = payloadStart; i < urlLine.length; i++) { - const char = urlLine[i]; - if (char === ' ' || char === '\r' || char === '\n' || char === '\t') { - payloadEnd = i; - break; - } + const payloadStart = base64StartIndex + 7; + let payloadEnd = urlLine.length; + // Find the first trailing whitespace character that marks the end of the base64 payload. + for (let i = payloadStart; i < urlLine.length; i++) { + const char = urlLine[i]; + if (char === ' ' || char === '\r' || char === '\n' || char === '\t') { + payloadEnd = i; + break; } + } - // Verify that everything after the base64 payload is trailing whitespace - // to ensure this is a valid trailing sourceMappingURL comment at the end of the file. - for (let i = payloadEnd; i < urlLine.length; i++) { - const char = urlLine[i]; - if (char !== ' ' && char !== '\r' && char !== '\n' && char !== '\t') { - return undefined; - } + // Verify that everything after the base64 payload is trailing whitespace + // to ensure this is a valid trailing sourceMappingURL comment at the end of the file. + for (let i = payloadEnd; i < urlLine.length; i++) { + const char = urlLine[i]; + if (char !== ' ' && char !== '\r' && char !== '\n' && char !== '\t') { + return undefined; } + } - try { - // Extract the base64 payload and decode it directly into binary memory. - const base64Content = urlLine.slice(payloadStart, payloadEnd); + return urlLine.slice(payloadStart, payloadEnd); +} - return JSON.parse(Buffer.from(base64Content, 'base64').toString('utf-8')) as EncodedSourceMap; - } catch { - return undefined; - } +/** + * Extracts the URL from an external sourcemap comment line and verifies + * that only trailing whitespace follows the URL. + * + * @returns The URL string if valid and trailing, or `undefined` otherwise. + */ +function extractTrailingUrl(urlLine: string): string | undefined { + if (urlLine.startsWith('data:')) { + return undefined; } - // Non-inline sourcemap comments (always small, typically < 200 characters). - const urlMatch = /^([^\r\n\s]+)/.exec(urlLine); + const urlMatch = /^([^\r\n\s'"`]+)/.exec(urlLine); if (!urlMatch) { return undefined; } - const url = urlMatch[1]; - const remaining = urlLine.slice(url.length); - // Verify there is only whitespace after the URL to the end of the file. + const remaining = urlLine.slice(urlMatch[1].length); if (!/^\s*$/.test(remaining)) { return undefined; } + return urlMatch[1]; +} + +/** + * Checks whether a `//# sourceMappingURL=` URL line snippet represents a valid trailing comment at the end of the file. + */ +export function isTrailingSourceMapComment(urlLine: string): boolean { + return ( + extractTrailingBase64Payload(urlLine) !== undefined || extractTrailingUrl(urlLine) !== undefined + ); +} + +/** + * Resolves and loads the input sourcemap referenced in a `//# sourceMappingURL=` URL line snippet. + * Supports inline base64 data URIs, local absolute file URLs, and relative/absolute filesystem paths. + */ +export function loadInputSourceMapFromUrl( + filename: string, + urlLine: string, +): EncodedSourceMap | undefined { + // Inline base64-encoded sourcemaps can be extremely large (up to megabytes). + // Parse them without regular expressions to avoid heavy backtracking and allocations. + const base64Payload = extractTrailingBase64Payload(urlLine); + if (base64Payload !== undefined) { + try { + return JSON.parse(Buffer.from(base64Payload, 'base64').toString('utf-8')) as EncodedSourceMap; + } catch { + return undefined; + } + } + + const url = extractTrailingUrl(urlLine); + if (!url) { + return undefined; + } + if (url.startsWith('file://')) { // Local absolute file URL scheme. try { @@ -269,3 +299,31 @@ export function loadInputSourceMap(filename: string, code: string): EncodedSourc return undefined; } + +/** + * Finds, resolves, and loads the input sourcemap referenced in the code's trailing + * sourceMappingURL comment, if present. Supports inline base64 data URIs, local absolute + * file URLs, and relative/absolute filesystem paths. + */ +export function loadInputSourceMap(filename: string, code: string): EncodedSourceMap | undefined { + // Locate the last sourceMappingURL comment using lastIndexOf to avoid scanning + // the entire file with a regular expression (significant for large files). + const lastSourceMapIndex = code.lastIndexOf('//# sourceMappingURL='); + if (lastSourceMapIndex === -1) { + return undefined; + } + + if (lastSourceMapIndex > 0) { + // Skip any preceding horizontal whitespace (spaces/tabs) to find the start of the line. + let prevIdx = lastSourceMapIndex - 1; + while (prevIdx >= 0 && (code[prevIdx] === ' ' || code[prevIdx] === '\t')) { + prevIdx--; + } + // Ensure the comment starts at the beginning of a line, preventing false positives within code or strings. + if (prevIdx >= 0 && code[prevIdx] !== '\n' && code[prevIdx] !== '\r') { + return undefined; + } + } + + return loadInputSourceMapFromUrl(filename, code.slice(lastSourceMapIndex + 21)); +} diff --git a/packages/angular/build/src/utils/source-map_spec.ts b/packages/angular/build/src/utils/source-map_spec.ts index b34d5bc57a98..8840315c019d 100644 --- a/packages/angular/build/src/utils/source-map_spec.ts +++ b/packages/angular/build/src/utils/source-map_spec.ts @@ -6,7 +6,12 @@ * found in the LICENSE file at https://angular.dev/license */ -import { removeSourceMappingURL } from './source-map'; +import { + isTrailingSourceMapComment, + loadInputSourceMap, + loadInputSourceMapFromUrl, + removeSourceMappingURL, +} from './source-map'; describe('removeSourceMappingURL', () => { it('should remove top-level sourcemap comments', () => { @@ -98,3 +103,87 @@ describe('removeSourceMappingURL', () => { expect(removeSourceMappingURL(code)).toBe('console.log("hello");\r\n\r\nconst next = 2;'); }); }); + +describe('loadInputSourceMapFromUrl', () => { + it('should decode inline base64 sourcemaps', () => { + const map = { version: 3, sources: ['foo.ts'], mappings: 'AAAA;' }; + const base64 = Buffer.from(JSON.stringify(map)).toString('base64'); + const urlLine = `data:application/json;charset=utf-8;base64,${base64}\n`; + + expect(loadInputSourceMapFromUrl('/src/foo.js', urlLine)).toEqual(map as never); + }); + + it('should return undefined for invalid base64 payloads', () => { + expect( + loadInputSourceMapFromUrl('/src/foo.js', 'data:application/json;base64,invalid!!!'), + ).toBeUndefined(); + }); + + it('should return undefined when no base64 marker is found in data URI', () => { + expect( + loadInputSourceMapFromUrl('/src/foo.js', 'data:application/json;utf8,{}'), + ).toBeUndefined(); + }); +}); + +describe('loadInputSourceMap', () => { + it('should extract and decode sourcemap from source string', () => { + const map = { version: 3, sources: ['foo.ts'], mappings: 'AAAA;' }; + const base64 = Buffer.from(JSON.stringify(map)).toString('base64'); + const code = `console.log("hello");\n//# sourceMappingURL=data:application/json;base64,${base64}\n`; + + expect(loadInputSourceMap('/src/foo.js', code)).toEqual(map as never); + }); + + it('should return undefined when no sourceMappingURL comment is present', () => { + expect(loadInputSourceMap('/src/foo.js', 'console.log("hello");')).toBeUndefined(); + }); + + it('should return undefined for comments inside template strings with code after them', () => { + const map = { version: 3, sources: ['foo.ts'], mappings: 'AAAA;' }; + const base64 = Buffer.from(JSON.stringify(map)).toString('base64'); + const code = `const str = \`\n//# sourceMappingURL=data:application/json;base64,${base64}\n\`;\nconsole.log(str);`; + + expect(loadInputSourceMap('/src/foo.js', code)).toBeUndefined(); + }); + + it('should return undefined for comments inside template strings ending with backticks', () => { + const map = { version: 3, sources: ['foo.ts'], mappings: 'AAAA;' }; + const base64 = Buffer.from(JSON.stringify(map)).toString('base64'); + const code = `const str = \`\n//# sourceMappingURL=data:application/json;base64,${base64}\n\`;`; + + expect(loadInputSourceMap('/src/foo.js', code)).toBeUndefined(); + }); + + it('should return undefined for single-line template literals', () => { + const map = { version: 3, sources: ['foo.ts'], mappings: 'AAAA;' }; + const base64 = Buffer.from(JSON.stringify(map)).toString('base64'); + const code = `const str = \`//# sourceMappingURL=data:application/json;base64,${base64}\`;`; + + expect(loadInputSourceMap('/src/foo.js', code)).toBeUndefined(); + }); +}); + +describe('isTrailingSourceMapComment', () => { + it('should return true for valid inline data URIs at end of file', () => { + const map = { version: 3, sources: ['foo.ts'], mappings: 'AAAA;' }; + const base64 = Buffer.from(JSON.stringify(map)).toString('base64'); + const urlLine = `data:application/json;charset=utf-8;base64,${base64}\n`; + + expect(isTrailingSourceMapComment(urlLine)).toBe(true); + }); + + it('should return true for external sourcemap URLs at end of file', () => { + expect(isTrailingSourceMapComment('main.js.map\n')).toBe(true); + expect(isTrailingSourceMapComment('main.js.map')).toBe(true); + }); + + it('should return false when followed by non-whitespace characters', () => { + expect(isTrailingSourceMapComment('main.js.map\n`;\nconsole.log("hi");')).toBe(false); + expect(isTrailingSourceMapComment('main.js.map`;')).toBe(false); + }); + + it('should return false for invalid data URI format', () => { + expect(isTrailingSourceMapComment('data:application/json;utf8,{}')).toBe(false); + }); +}); From f62a10254e8117f85bfa6814ab4375f0d14c7f65 Mon Sep 17 00:00:00 2001 From: Charles Lyding <19598772+clydin@users.noreply.github.com> Date: Fri, 7 Aug 2026 15:41:28 -0400 Subject: [PATCH 278/787] refactor(@angular/cli): use Node.js styleText for color helpers Replaces listr2 re-exports in the CLI color helper with Node.js built-in `styleText` utilities from `node:util`. Previously, importing colors from `utilities/color.ts` eagerly pulled in `listr2` along with its transitive dependencies (`wrap-ansi`, `string-width`, `get-east-asian-width`), introducing synchronous ESM module evaluation and ANSI formatting overhead during early CLI startup. --- .../src/commands/update/utilities/migration.ts | 3 ++- packages/angular/cli/src/utilities/color.ts | 17 ++++++++++++++++- 2 files changed, 18 insertions(+), 2 deletions(-) diff --git a/packages/angular/cli/src/commands/update/utilities/migration.ts b/packages/angular/cli/src/commands/update/utilities/migration.ts index 21331364bc2f..83a1492eaa10 100644 --- a/packages/angular/cli/src/commands/update/utilities/migration.ts +++ b/packages/angular/cli/src/commands/update/utilities/migration.ts @@ -13,10 +13,11 @@ import { FileSystemSchematicDescription, NodeWorkflow, } from '@angular-devkit/schematics/tools'; +import { figures } from 'listr2'; import { SpawnSyncReturns } from 'node:child_process'; import * as semver from 'semver'; import { subscribeToWorkflow } from '../../../command-builder/utilities/schematic-workflow'; -import { colors, figures } from '../../../utilities/color'; +import { colors } from '../../../utilities/color'; import { assertIsError } from '../../../utilities/error'; import { writeErrorToLogFile } from '../../../utilities/log-file'; import { formatFiles } from '../../../utilities/prettier'; diff --git a/packages/angular/cli/src/utilities/color.ts b/packages/angular/cli/src/utilities/color.ts index 3915d99ce248..13333dbc4b57 100644 --- a/packages/angular/cli/src/utilities/color.ts +++ b/packages/angular/cli/src/utilities/color.ts @@ -7,8 +7,23 @@ */ import { WriteStream } from 'node:tty'; +import { styleText } from 'node:util'; -export { color as colors, figures } from 'listr2'; +export const colors = Object.freeze({ + black: (text: string) => styleText('black', text), + blue: (text: string) => styleText('blue', text), + bold: (text: string) => styleText('bold', text), + cyan: (text: string) => styleText('cyan', text), + dim: (text: string) => styleText('dim', text), + gray: (text: string) => styleText('gray', text), + green: (text: string) => styleText('green', text), + italic: (text: string) => styleText('italic', text), + magenta: (text: string) => styleText('magenta', text), + red: (text: string) => styleText('red', text), + underline: (text: string) => styleText('underline', text), + white: (text: string) => styleText('white', text), + yellow: (text: string) => styleText('yellow', text), +}); export function supportColor(stream: NodeJS.WritableStream = process.stdout): boolean { if (stream instanceof WriteStream) { From 0ae3c1ba9213536c9945b351a0ec6fdcf43deb5a Mon Sep 17 00:00:00 2001 From: Angular Robot Date: Mon, 10 Aug 2026 19:12:56 +0000 Subject: [PATCH 279/787] build: update cross-repo angular dependencies See associated pull request for more information. --- .../assistant-to-the-branch-manager.yml | 2 +- .github/workflows/ci.yml | 52 +- .github/workflows/dev-infra.yml | 6 +- .github/workflows/perf.yml | 6 +- .github/workflows/pr.yml | 44 +- MODULE.bazel | 6 +- MODULE.bazel.lock | 35 +- package.json | 24 +- packages/angular/ssr/package.json | 12 +- packages/ngtools/webpack/package.json | 4 +- pnpm-lock.yaml | 900 +++++++++--------- tests/e2e/ng-snapshot/package.json | 32 +- 12 files changed, 574 insertions(+), 549 deletions(-) diff --git a/.github/workflows/assistant-to-the-branch-manager.yml b/.github/workflows/assistant-to-the-branch-manager.yml index 4a9daab0a148..f21e2612ef53 100644 --- a/.github/workflows/assistant-to-the-branch-manager.yml +++ b/.github/workflows/assistant-to-the-branch-manager.yml @@ -18,6 +18,6 @@ jobs: - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: persist-credentials: false - - uses: angular/dev-infra/github-actions/branch-manager@0b701b31038419ad73422a9d9d3dff43a725a0d2 # main + - uses: angular/dev-infra/github-actions/branch-manager@04230133d395dfb032d782b8e63b4fcbbd406aa5 # main with: angular-robot-key: ${{ secrets.ANGULAR_ROBOT_PRIVATE_KEY }} diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 05fa1692e7c8..eb33533f00e2 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -21,9 +21,9 @@ jobs: runs-on: ubuntu-latest steps: - name: Initialize environment - uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@0b701b31038419ad73422a9d9d3dff43a725a0d2 # main + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@04230133d395dfb032d782b8e63b4fcbbd406aa5 # main - name: Setup Bazel - uses: angular/dev-infra/github-actions/bazel/setup@0b701b31038419ad73422a9d9d3dff43a725a0d2 # main + uses: angular/dev-infra/github-actions/bazel/setup@04230133d395dfb032d782b8e63b4fcbbd406aa5 # main - name: Install node modules run: pnpm install --frozen-lockfile - name: Generate JSON schema types @@ -44,11 +44,11 @@ jobs: runs-on: ubuntu-latest steps: - name: Initialize environment - uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@0b701b31038419ad73422a9d9d3dff43a725a0d2 # main + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@04230133d395dfb032d782b8e63b4fcbbd406aa5 # main - name: Setup Bazel - uses: angular/dev-infra/github-actions/bazel/setup@0b701b31038419ad73422a9d9d3dff43a725a0d2 # main + uses: angular/dev-infra/github-actions/bazel/setup@04230133d395dfb032d782b8e63b4fcbbd406aa5 # main - name: Setup Bazel RBE - uses: angular/dev-infra/github-actions/bazel/configure-remote@0b701b31038419ad73422a9d9d3dff43a725a0d2 # main + uses: angular/dev-infra/github-actions/bazel/configure-remote@04230133d395dfb032d782b8e63b4fcbbd406aa5 # main with: google_credential: ${{ secrets.RBE_TRUSTED_BUILDS_USER }} - name: Install node modules @@ -61,11 +61,11 @@ jobs: runs-on: ubuntu-latest steps: - name: Initialize environment - uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@0b701b31038419ad73422a9d9d3dff43a725a0d2 # main + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@04230133d395dfb032d782b8e63b4fcbbd406aa5 # main - name: Setup Bazel - uses: angular/dev-infra/github-actions/bazel/setup@0b701b31038419ad73422a9d9d3dff43a725a0d2 # main + uses: angular/dev-infra/github-actions/bazel/setup@04230133d395dfb032d782b8e63b4fcbbd406aa5 # main - name: Setup Bazel RBE - uses: angular/dev-infra/github-actions/bazel/configure-remote@0b701b31038419ad73422a9d9d3dff43a725a0d2 # main + uses: angular/dev-infra/github-actions/bazel/configure-remote@04230133d395dfb032d782b8e63b4fcbbd406aa5 # main with: google_credential: ${{ secrets.RBE_TRUSTED_BUILDS_USER }} - name: Install node modules @@ -84,13 +84,13 @@ jobs: runs-on: ubuntu-latest steps: - name: Initialize environment - uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@0b701b31038419ad73422a9d9d3dff43a725a0d2 # main + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@04230133d395dfb032d782b8e63b4fcbbd406aa5 # main - name: Install node modules run: pnpm install --frozen-lockfile - name: Setup Bazel - uses: angular/dev-infra/github-actions/bazel/setup@0b701b31038419ad73422a9d9d3dff43a725a0d2 # main + uses: angular/dev-infra/github-actions/bazel/setup@04230133d395dfb032d782b8e63b4fcbbd406aa5 # main - name: Setup Bazel RBE - uses: angular/dev-infra/github-actions/bazel/configure-remote@0b701b31038419ad73422a9d9d3dff43a725a0d2 # main + uses: angular/dev-infra/github-actions/bazel/configure-remote@04230133d395dfb032d782b8e63b4fcbbd406aa5 # main with: google_credential: ${{ secrets.RBE_TRUSTED_BUILDS_USER }} - name: Run CLI E2E tests @@ -100,11 +100,11 @@ jobs: runs-on: ubuntu-latest steps: - name: Initialize environment - uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@0b701b31038419ad73422a9d9d3dff43a725a0d2 # main + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@04230133d395dfb032d782b8e63b4fcbbd406aa5 # main - name: Setup Bazel - uses: angular/dev-infra/github-actions/bazel/setup@0b701b31038419ad73422a9d9d3dff43a725a0d2 # main + uses: angular/dev-infra/github-actions/bazel/setup@04230133d395dfb032d782b8e63b4fcbbd406aa5 # main - name: Setup Bazel RBE - uses: angular/dev-infra/github-actions/bazel/configure-remote@0b701b31038419ad73422a9d9d3dff43a725a0d2 # main + uses: angular/dev-infra/github-actions/bazel/configure-remote@04230133d395dfb032d782b8e63b4fcbbd406aa5 # main with: google_credential: ${{ secrets.RBE_TRUSTED_BUILDS_USER }} - name: Install node modules @@ -137,7 +137,7 @@ jobs: runs-on: windows-2025 steps: - name: Initialize environment - uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@0b701b31038419ad73422a9d9d3dff43a725a0d2 # main + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@04230133d395dfb032d782b8e63b4fcbbd406aa5 # main - name: Install node modules run: pnpm install --frozen-lockfile - name: Download built Windows E2E tests @@ -164,13 +164,13 @@ jobs: runs-on: ubuntu-latest steps: - name: Initialize environment - uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@0b701b31038419ad73422a9d9d3dff43a725a0d2 # main + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@04230133d395dfb032d782b8e63b4fcbbd406aa5 # main - name: Install node modules run: pnpm install --frozen-lockfile - name: Setup Bazel - uses: angular/dev-infra/github-actions/bazel/setup@0b701b31038419ad73422a9d9d3dff43a725a0d2 # main + uses: angular/dev-infra/github-actions/bazel/setup@04230133d395dfb032d782b8e63b4fcbbd406aa5 # main - name: Setup Bazel RBE - uses: angular/dev-infra/github-actions/bazel/configure-remote@0b701b31038419ad73422a9d9d3dff43a725a0d2 # main + uses: angular/dev-infra/github-actions/bazel/configure-remote@04230133d395dfb032d782b8e63b4fcbbd406aa5 # main with: google_credential: ${{ secrets.RBE_TRUSTED_BUILDS_USER }} - name: Run CLI E2E tests @@ -188,13 +188,13 @@ jobs: runs-on: ubuntu-latest steps: - name: Initialize environment - uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@0b701b31038419ad73422a9d9d3dff43a725a0d2 # main + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@04230133d395dfb032d782b8e63b4fcbbd406aa5 # main - name: Install node modules run: pnpm install --frozen-lockfile - name: Setup Bazel - uses: angular/dev-infra/github-actions/bazel/setup@0b701b31038419ad73422a9d9d3dff43a725a0d2 # main + uses: angular/dev-infra/github-actions/bazel/setup@04230133d395dfb032d782b8e63b4fcbbd406aa5 # main - name: Setup Bazel RBE - uses: angular/dev-infra/github-actions/bazel/configure-remote@0b701b31038419ad73422a9d9d3dff43a725a0d2 # main + uses: angular/dev-infra/github-actions/bazel/configure-remote@04230133d395dfb032d782b8e63b4fcbbd406aa5 # main with: google_credential: ${{ secrets.RBE_TRUSTED_BUILDS_USER }} - name: Run CLI E2E tests @@ -208,13 +208,13 @@ jobs: SAUCE_TUNNEL_IDENTIFIER: angular-cli-${{ github.workflow }}-${{ github.run_number }} steps: - name: Initialize environment - uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@0b701b31038419ad73422a9d9d3dff43a725a0d2 # main + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@04230133d395dfb032d782b8e63b4fcbbd406aa5 # main - name: Install node modules run: pnpm install --frozen-lockfile - name: Setup Bazel - uses: angular/dev-infra/github-actions/bazel/setup@0b701b31038419ad73422a9d9d3dff43a725a0d2 # main + uses: angular/dev-infra/github-actions/bazel/setup@04230133d395dfb032d782b8e63b4fcbbd406aa5 # main - name: Setup Bazel RBE - uses: angular/dev-infra/github-actions/bazel/configure-remote@0b701b31038419ad73422a9d9d3dff43a725a0d2 # main + uses: angular/dev-infra/github-actions/bazel/configure-remote@04230133d395dfb032d782b8e63b4fcbbd406aa5 # main with: google_credential: ${{ secrets.RBE_TRUSTED_BUILDS_USER }} - name: Start Sauce Connect @@ -245,11 +245,11 @@ jobs: CIRCLE_BRANCH: ${{ github.ref_name }} steps: - name: Initialize environment - uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@0b701b31038419ad73422a9d9d3dff43a725a0d2 # main + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@04230133d395dfb032d782b8e63b4fcbbd406aa5 # main - name: Install node modules run: pnpm install --frozen-lockfile - name: Setup Bazel - uses: angular/dev-infra/github-actions/bazel/setup@0b701b31038419ad73422a9d9d3dff43a725a0d2 # main + uses: angular/dev-infra/github-actions/bazel/setup@04230133d395dfb032d782b8e63b4fcbbd406aa5 # main - run: pnpm admin snapshots --verbose env: SNAPSHOT_BUILDS_GITHUB_TOKEN: ${{ secrets.SNAPSHOT_BUILDS_GITHUB_TOKEN }} diff --git a/.github/workflows/dev-infra.yml b/.github/workflows/dev-infra.yml index 0be73a55a51a..2c9e701b95e2 100644 --- a/.github/workflows/dev-infra.yml +++ b/.github/workflows/dev-infra.yml @@ -16,21 +16,21 @@ jobs: if: github.event_name == 'pull_request_target' runs-on: ubuntu-latest steps: - - uses: angular/dev-infra/github-actions/labeling/pull-request@0b701b31038419ad73422a9d9d3dff43a725a0d2 # main + - uses: angular/dev-infra/github-actions/labeling/pull-request@04230133d395dfb032d782b8e63b4fcbbd406aa5 # main with: angular-robot-key: ${{ secrets.ANGULAR_ROBOT_PRIVATE_KEY }} post_approval_changes: if: github.event_name == 'pull_request_target' runs-on: ubuntu-latest steps: - - uses: angular/dev-infra/github-actions/post-approval-changes@0b701b31038419ad73422a9d9d3dff43a725a0d2 # main + - uses: angular/dev-infra/github-actions/post-approval-changes@04230133d395dfb032d782b8e63b4fcbbd406aa5 # main with: angular-robot-key: ${{ secrets.ANGULAR_ROBOT_PRIVATE_KEY }} issue_labels: if: github.event_name == 'issues' runs-on: ubuntu-latest steps: - - uses: angular/dev-infra/github-actions/labeling/issue@0b701b31038419ad73422a9d9d3dff43a725a0d2 # main + - uses: angular/dev-infra/github-actions/labeling/issue@04230133d395dfb032d782b8e63b4fcbbd406aa5 # main with: angular-robot-key: ${{ secrets.ANGULAR_ROBOT_PRIVATE_KEY }} google-generative-ai-key: ${{ secrets.GOOGLE_GENERATIVE_AI_KEY }} diff --git a/.github/workflows/perf.yml b/.github/workflows/perf.yml index 5bca0fe665c8..591414f2e95a 100644 --- a/.github/workflows/perf.yml +++ b/.github/workflows/perf.yml @@ -22,7 +22,7 @@ jobs: workflows: ${{ steps.workflows.outputs.workflows }} steps: - name: Initialize environment - uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@0b701b31038419ad73422a9d9d3dff43a725a0d2 # main + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@04230133d395dfb032d782b8e63b4fcbbd406aa5 # main - name: Install node modules run: pnpm install --frozen-lockfile - id: workflows @@ -40,9 +40,9 @@ jobs: workflow: ${{ fromJSON(needs.list.outputs.workflows) }} steps: - name: Initialize environment - uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@0b701b31038419ad73422a9d9d3dff43a725a0d2 # main + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@04230133d395dfb032d782b8e63b4fcbbd406aa5 # main - name: Setup Bazel - uses: angular/dev-infra/github-actions/bazel/setup@0b701b31038419ad73422a9d9d3dff43a725a0d2 # main + uses: angular/dev-infra/github-actions/bazel/setup@04230133d395dfb032d782b8e63b4fcbbd406aa5 # main - name: Install node modules run: pnpm install --frozen-lockfile # We utilize the google-github-actions/auth action to allow us to get an active credential using workflow diff --git a/.github/workflows/pr.yml b/.github/workflows/pr.yml index 7fdaf0758a26..ad9364286682 100644 --- a/.github/workflows/pr.yml +++ b/.github/workflows/pr.yml @@ -34,9 +34,9 @@ jobs: runs-on: ubuntu-latest steps: - name: Initialize environment - uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@0b701b31038419ad73422a9d9d3dff43a725a0d2 # main + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@04230133d395dfb032d782b8e63b4fcbbd406aa5 # main - name: Setup Bazel - uses: angular/dev-infra/github-actions/bazel/setup@0b701b31038419ad73422a9d9d3dff43a725a0d2 # main + uses: angular/dev-infra/github-actions/bazel/setup@04230133d395dfb032d782b8e63b4fcbbd406aa5 # main - name: Setup ESLint Caching uses: actions/cache@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0 with: @@ -66,17 +66,17 @@ jobs: # it has been merged. run: pnpm ng-dev format changed --check ${{ github.event.pull_request.base.sha }} - name: Check Package Licenses - uses: angular/dev-infra/github-actions/linting/licenses@0b701b31038419ad73422a9d9d3dff43a725a0d2 # main + uses: angular/dev-infra/github-actions/linting/licenses@04230133d395dfb032d782b8e63b4fcbbd406aa5 # main build: runs-on: ubuntu-latest steps: - name: Initialize environment - uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@0b701b31038419ad73422a9d9d3dff43a725a0d2 # main + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@04230133d395dfb032d782b8e63b4fcbbd406aa5 # main - name: Setup Bazel - uses: angular/dev-infra/github-actions/bazel/setup@0b701b31038419ad73422a9d9d3dff43a725a0d2 # main + uses: angular/dev-infra/github-actions/bazel/setup@04230133d395dfb032d782b8e63b4fcbbd406aa5 # main - name: Setup Bazel RBE - uses: angular/dev-infra/github-actions/bazel/configure-remote@0b701b31038419ad73422a9d9d3dff43a725a0d2 # main + uses: angular/dev-infra/github-actions/bazel/configure-remote@04230133d395dfb032d782b8e63b4fcbbd406aa5 # main - name: Install node modules run: pnpm install --frozen-lockfile - name: Build release targets @@ -93,11 +93,11 @@ jobs: runs-on: ubuntu-latest steps: - name: Initialize environment - uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@0b701b31038419ad73422a9d9d3dff43a725a0d2 # main + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@04230133d395dfb032d782b8e63b4fcbbd406aa5 # main - name: Setup Bazel - uses: angular/dev-infra/github-actions/bazel/setup@0b701b31038419ad73422a9d9d3dff43a725a0d2 # main + uses: angular/dev-infra/github-actions/bazel/setup@04230133d395dfb032d782b8e63b4fcbbd406aa5 # main - name: Setup Bazel RBE - uses: angular/dev-infra/github-actions/bazel/configure-remote@0b701b31038419ad73422a9d9d3dff43a725a0d2 # main + uses: angular/dev-infra/github-actions/bazel/configure-remote@04230133d395dfb032d782b8e63b4fcbbd406aa5 # main - name: Install node modules run: pnpm install --frozen-lockfile - name: Run module and package tests @@ -114,13 +114,13 @@ jobs: runs-on: ubuntu-latest steps: - name: Initialize environment - uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@0b701b31038419ad73422a9d9d3dff43a725a0d2 # main + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@04230133d395dfb032d782b8e63b4fcbbd406aa5 # main - name: Install node modules run: pnpm install --frozen-lockfile - name: Setup Bazel - uses: angular/dev-infra/github-actions/bazel/setup@0b701b31038419ad73422a9d9d3dff43a725a0d2 # main + uses: angular/dev-infra/github-actions/bazel/setup@04230133d395dfb032d782b8e63b4fcbbd406aa5 # main - name: Setup Bazel RBE - uses: angular/dev-infra/github-actions/bazel/configure-remote@0b701b31038419ad73422a9d9d3dff43a725a0d2 # main + uses: angular/dev-infra/github-actions/bazel/configure-remote@04230133d395dfb032d782b8e63b4fcbbd406aa5 # main - name: Run CLI E2E tests run: pnpm bazel test --test_env=E2E_SHARD_TOTAL=6 --test_env=E2E_SHARD_INDEX=${{ matrix.shard }} --config=e2e //tests:e2e.${{ matrix.subset }}_node${{ matrix.node }} @@ -128,11 +128,11 @@ jobs: runs-on: ubuntu-latest steps: - name: Initialize environment - uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@0b701b31038419ad73422a9d9d3dff43a725a0d2 # main + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@04230133d395dfb032d782b8e63b4fcbbd406aa5 # main - name: Setup Bazel - uses: angular/dev-infra/github-actions/bazel/setup@0b701b31038419ad73422a9d9d3dff43a725a0d2 # main + uses: angular/dev-infra/github-actions/bazel/setup@04230133d395dfb032d782b8e63b4fcbbd406aa5 # main - name: Setup Bazel RBE - uses: angular/dev-infra/github-actions/bazel/configure-remote@0b701b31038419ad73422a9d9d3dff43a725a0d2 # main + uses: angular/dev-infra/github-actions/bazel/configure-remote@04230133d395dfb032d782b8e63b4fcbbd406aa5 # main - name: Install node modules run: pnpm install --frozen-lockfile - name: Build E2E tests for Windows on Linux @@ -156,7 +156,7 @@ jobs: runs-on: windows-2025 steps: - name: Initialize environment - uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@0b701b31038419ad73422a9d9d3dff43a725a0d2 # main + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@04230133d395dfb032d782b8e63b4fcbbd406aa5 # main - name: Install node modules run: pnpm install --frozen-lockfile - name: Download built Windows E2E tests @@ -183,13 +183,13 @@ jobs: runs-on: ubuntu-latest steps: - name: Initialize environment - uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@0b701b31038419ad73422a9d9d3dff43a725a0d2 # main + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@04230133d395dfb032d782b8e63b4fcbbd406aa5 # main - name: Install node modules run: pnpm install --frozen-lockfile - name: Setup Bazel - uses: angular/dev-infra/github-actions/bazel/setup@0b701b31038419ad73422a9d9d3dff43a725a0d2 # main + uses: angular/dev-infra/github-actions/bazel/setup@04230133d395dfb032d782b8e63b4fcbbd406aa5 # main - name: Setup Bazel RBE - uses: angular/dev-infra/github-actions/bazel/configure-remote@0b701b31038419ad73422a9d9d3dff43a725a0d2 # main + uses: angular/dev-infra/github-actions/bazel/configure-remote@04230133d395dfb032d782b8e63b4fcbbd406aa5 # main - name: Run CLI E2E tests run: pnpm bazel test --test_env=E2E_SHARD_TOTAL=3 --test_env=E2E_SHARD_INDEX=${{ matrix.shard }} --config=e2e //tests:e2e.${{ matrix.subset }}_node${{ matrix.node }} @@ -205,12 +205,12 @@ jobs: runs-on: ubuntu-latest steps: - name: Initialize environment - uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@0b701b31038419ad73422a9d9d3dff43a725a0d2 # main + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@04230133d395dfb032d782b8e63b4fcbbd406aa5 # main - name: Install node modules run: pnpm install --frozen-lockfile - name: Setup Bazel - uses: angular/dev-infra/github-actions/bazel/setup@0b701b31038419ad73422a9d9d3dff43a725a0d2 # main + uses: angular/dev-infra/github-actions/bazel/setup@04230133d395dfb032d782b8e63b4fcbbd406aa5 # main - name: Setup Bazel RBE - uses: angular/dev-infra/github-actions/bazel/configure-remote@0b701b31038419ad73422a9d9d3dff43a725a0d2 # main + uses: angular/dev-infra/github-actions/bazel/configure-remote@04230133d395dfb032d782b8e63b4fcbbd406aa5 # main - name: Run CLI E2E tests run: pnpm bazel test --test_env=E2E_SHARD_TOTAL=6 --test_env=E2E_SHARD_INDEX=${{ matrix.shard }} --config=e2e //tests:e2e.snapshots.${{ matrix.subset }}_node${{ matrix.node }} diff --git a/MODULE.bazel b/MODULE.bazel index 19944fcccb15..4e27b01981b4 100644 --- a/MODULE.bazel +++ b/MODULE.bazel @@ -19,21 +19,21 @@ bazel_dep(name = "aspect_rules_jasmine", version = "2.0.4") bazel_dep(name = "rules_angular") git_override( module_name = "rules_angular", - commit = "a0bbcceea19b7888114eeafe3f52f9822ca2b34a", + commit = "20a373d609c4f5765b9ad367a205f3a635dd2cda", remote = "https://github.com/angular/rules_angular.git", ) bazel_dep(name = "devinfra") git_override( module_name = "devinfra", - commit = "0b701b31038419ad73422a9d9d3dff43a725a0d2", + commit = "04230133d395dfb032d782b8e63b4fcbbd406aa5", remote = "https://github.com/angular/dev-infra.git", ) bazel_dep(name = "rules_browsers") git_override( module_name = "rules_browsers", - commit = "7fe4598226334b0809d3054f6948d72df4b5ed59", + commit = "37853f23de9a9a70f53c02a9baa27e08d7d12003", remote = "https://github.com/angular/rules_browsers.git", ) diff --git a/MODULE.bazel.lock b/MODULE.bazel.lock index 36db732d1e78..5dea915111bc 100644 --- a/MODULE.bazel.lock +++ b/MODULE.bazel.lock @@ -52,7 +52,6 @@ "https://bcr.bazel.build/modules/bazel_lib/3.0.0-rc.0/MODULE.bazel": "d6e00979a98ac14ada5e31c8794708b41434d461e7e7ca39b59b765e6d233b18", "https://bcr.bazel.build/modules/bazel_lib/3.0.0/MODULE.bazel": "22b70b80ac89ad3f3772526cd9feee2fa412c2b01933fea7ed13238a448d370d", "https://bcr.bazel.build/modules/bazel_lib/3.2.2/MODULE.bazel": "e2c890c8a515d6bca9c66d47718aa9e44b458fde64ec7204b8030bf2d349058c", - "https://bcr.bazel.build/modules/bazel_lib/3.5.0/MODULE.bazel": "1eba0ba67d418d99fb682c36147a9e1725abbc8fc25544be64702e32eda2be29", "https://bcr.bazel.build/modules/bazel_lib/3.7.1/MODULE.bazel": "b6fd9b2f8fab956420c11836f416efac4a70e20804ae384ebe62773a4ed70046", "https://bcr.bazel.build/modules/bazel_lib/3.7.1/source.json": "635fdaa28b50c04febc5e60ef51bc913d3bc87bfbaac7045449273c2341648cb", "https://bcr.bazel.build/modules/bazel_skylib/1.0.3/MODULE.bazel": "bcb0fd896384802d1ad283b4e4eb4d718eebd8cb820b0a2c3a347fb971afd9d8", @@ -540,7 +539,7 @@ }, "@@rules_browsers+//browsers:extensions.bzl%browsers": { "general": { - "bzlTransitiveDigest": "w4tgtXA7WLl79lEQFfedhl7OVEGAKFqAFLnlI5c/Rtk=", + "bzlTransitiveDigest": "4TUvIB8juKCShOmy6m77drIdimJqOTEPwfzMxkWD5a4=", "usagesDigest": "FmXYJVoVJlnfUU8x8gObSvu4qWcco/9Faw61aC/wBF0=", "recordedFileInputs": {}, "recordedDirentsInputs": {}, @@ -549,9 +548,9 @@ "rules_browsers_chrome_linux": { "repoRuleId": "@@rules_browsers+//browsers/private:browser_repo.bzl%browser_repo", "attributes": { - "sha256": "7220f7149a01e85e631cb949b03fd472eba72fe0a92c6d8dab7833dd94e0c72c", + "sha256": "5b132ebe0be5c0c15cb5222c33e04e37ae21ed3e00d84c68e905f80f29221c50", "urls": [ - "https://storage.googleapis.com/chrome-for-testing-public/153.0.7981.3/linux64/chrome-headless-shell-linux64.zip" + "https://storage.googleapis.com/chrome-for-testing-public/153.0.7993.0/linux64/chrome-headless-shell-linux64.zip" ], "named_files": { "CHROME-HEADLESS-SHELL": "chrome-headless-shell-linux64/chrome-headless-shell" @@ -567,9 +566,9 @@ "rules_browsers_chrome_mac": { "repoRuleId": "@@rules_browsers+//browsers/private:browser_repo.bzl%browser_repo", "attributes": { - "sha256": "0d80d90379960943f3dc9f5eb966876010dd950736c97386e375581a56baf7c7", + "sha256": "522e62dbfce61fddd413fb76a65e699b6f5bdce4045e4398d1e2fb1ef73ff6f3", "urls": [ - "https://storage.googleapis.com/chrome-for-testing-public/153.0.7981.3/mac-x64/chrome-headless-shell-mac-x64.zip" + "https://storage.googleapis.com/chrome-for-testing-public/153.0.7993.0/mac-x64/chrome-headless-shell-mac-x64.zip" ], "named_files": { "CHROME-HEADLESS-SHELL": "chrome-headless-shell-mac-x64/chrome-headless-shell" @@ -585,9 +584,9 @@ "rules_browsers_chrome_mac_arm": { "repoRuleId": "@@rules_browsers+//browsers/private:browser_repo.bzl%browser_repo", "attributes": { - "sha256": "7fad05ead762524231ed026cf40385cba80cb3daab2973622f3533308fc045fa", + "sha256": "b68d54b63ab30042874a87ad81a135360fa87e1d4763df2431b30b4d59878b4e", "urls": [ - "https://storage.googleapis.com/chrome-for-testing-public/153.0.7981.3/mac-arm64/chrome-headless-shell-mac-arm64.zip" + "https://storage.googleapis.com/chrome-for-testing-public/153.0.7993.0/mac-arm64/chrome-headless-shell-mac-arm64.zip" ], "named_files": { "CHROME-HEADLESS-SHELL": "chrome-headless-shell-mac-arm64/chrome-headless-shell" @@ -603,9 +602,9 @@ "rules_browsers_chrome_win64": { "repoRuleId": "@@rules_browsers+//browsers/private:browser_repo.bzl%browser_repo", "attributes": { - "sha256": "2c08f3f53115434e3dd623e2e1f1f54896fa4b2cbaf86518d7f4708dc80fe67d", + "sha256": "0fd5b488d41686cb7cb0be1feb861f1e4cb44d9c5e67a4c5328a385742aa6a8e", "urls": [ - "https://storage.googleapis.com/chrome-for-testing-public/153.0.7981.3/win64/chrome-headless-shell-win64.zip" + "https://storage.googleapis.com/chrome-for-testing-public/153.0.7993.0/win64/chrome-headless-shell-win64.zip" ], "named_files": { "CHROME-HEADLESS-SHELL": "chrome-headless-shell-win64/chrome-headless-shell.exe" @@ -621,9 +620,9 @@ "rules_browsers_chromedriver_linux": { "repoRuleId": "@@rules_browsers+//browsers/private:browser_repo.bzl%browser_repo", "attributes": { - "sha256": "8bab44616dd81669a7a99d77c6b7e952ee3ec3bfd01ddf864cf795a880cfbd92", + "sha256": "69139f654d93c12d04209713c725b33ea7074a1e35c47aaf98f419c4a00b4e9b", "urls": [ - "https://storage.googleapis.com/chrome-for-testing-public/153.0.7981.3/linux64/chromedriver-linux64.zip" + "https://storage.googleapis.com/chrome-for-testing-public/153.0.7993.0/linux64/chromedriver-linux64.zip" ], "named_files": { "CHROMEDRIVER": "chromedriver-linux64/chromedriver" @@ -637,9 +636,9 @@ "rules_browsers_chromedriver_mac": { "repoRuleId": "@@rules_browsers+//browsers/private:browser_repo.bzl%browser_repo", "attributes": { - "sha256": "d1f8618664ec5b0433c19b36eef91b55671a1adf595ffd012da8b859c32dc7b1", + "sha256": "b56b49cb41658c25405757b3c01a5412403e3744ee6935c5f9f59bf2b907bcf6", "urls": [ - "https://storage.googleapis.com/chrome-for-testing-public/153.0.7981.3/mac-x64/chromedriver-mac-x64.zip" + "https://storage.googleapis.com/chrome-for-testing-public/153.0.7993.0/mac-x64/chromedriver-mac-x64.zip" ], "named_files": { "CHROMEDRIVER": "chromedriver-mac-x64/chromedriver" @@ -653,9 +652,9 @@ "rules_browsers_chromedriver_mac_arm": { "repoRuleId": "@@rules_browsers+//browsers/private:browser_repo.bzl%browser_repo", "attributes": { - "sha256": "3c8b50af153cf6e8de8f2ec9f4b9a1ce717cd76a3ca6c82f9e736d7b705bdbe2", + "sha256": "e2bd843b45ba197632d29eeef188940488779684207eb3118a5a78c26aef9659", "urls": [ - "https://storage.googleapis.com/chrome-for-testing-public/153.0.7981.3/mac-arm64/chromedriver-mac-arm64.zip" + "https://storage.googleapis.com/chrome-for-testing-public/153.0.7993.0/mac-arm64/chromedriver-mac-arm64.zip" ], "named_files": { "CHROMEDRIVER": "chromedriver-mac-arm64/chromedriver" @@ -669,9 +668,9 @@ "rules_browsers_chromedriver_win64": { "repoRuleId": "@@rules_browsers+//browsers/private:browser_repo.bzl%browser_repo", "attributes": { - "sha256": "2fdba8a5036173c57627b38df844e2f9c6634dd027eaa5a5f306033e14414e08", + "sha256": "2f56f10ba3989d8b5c44c22cff080c2cc436314f8f8babbcc151bb95b34de841", "urls": [ - "https://storage.googleapis.com/chrome-for-testing-public/153.0.7981.3/win64/chromedriver-win64.zip" + "https://storage.googleapis.com/chrome-for-testing-public/153.0.7993.0/win64/chromedriver-win64.zip" ], "named_files": { "CHROMEDRIVER": "chromedriver-win64/chromedriver.exe" diff --git a/package.json b/package.json index d205330e9f8b..ae8598898ce5 100644 --- a/package.json +++ b/package.json @@ -42,23 +42,23 @@ }, "homepage": "https://github.com/angular/angular-cli", "dependencies": { - "@angular/compiler-cli": "22.2.0-next.0", + "@angular/compiler-cli": "22.2.0-next.1", "typescript": "6.0.3" }, "devDependencies": { - "@angular/animations": "22.2.0-next.0", + "@angular/animations": "22.2.0-next.1", "@angular/cdk": "22.2.0-next.0", - "@angular/common": "22.2.0-next.0", - "@angular/compiler": "22.2.0-next.0", - "@angular/core": "22.2.0-next.0", - "@angular/forms": "22.2.0-next.0", - "@angular/localize": "22.2.0-next.0", + "@angular/common": "22.2.0-next.1", + "@angular/compiler": "22.2.0-next.1", + "@angular/core": "22.2.0-next.1", + "@angular/forms": "22.2.0-next.1", + "@angular/localize": "22.2.0-next.1", "@angular/material": "22.2.0-next.0", - "@angular/ng-dev": "https://github.com/angular/dev-infra-private-ng-dev-builds.git#dcf9b6776377d5d301e054111add3ef80f433b70", - "@angular/platform-browser": "22.2.0-next.0", - "@angular/platform-server": "22.2.0-next.0", - "@angular/router": "22.2.0-next.0", - "@angular/service-worker": "22.2.0-next.0", + "@angular/ng-dev": "https://github.com/angular/dev-infra-private-ng-dev-builds.git#c71d9b6af7560faa3d002534d416a8045111adae", + "@angular/platform-browser": "22.2.0-next.1", + "@angular/platform-server": "22.2.0-next.1", + "@angular/router": "22.2.0-next.1", + "@angular/service-worker": "22.2.0-next.1", "@babel/core": "8.0.1", "@bazel/bazelisk": "1.28.1", "@bazel/buildifier": "8.2.1", diff --git a/packages/angular/ssr/package.json b/packages/angular/ssr/package.json index d1ad2c16d2d7..303cfaa36d82 100644 --- a/packages/angular/ssr/package.json +++ b/packages/angular/ssr/package.json @@ -37,12 +37,12 @@ }, "devDependencies": { "@angular-devkit/schematics": "workspace:*", - "@angular/common": "22.2.0-next.0", - "@angular/compiler": "22.2.0-next.0", - "@angular/core": "22.2.0-next.0", - "@angular/platform-browser": "22.2.0-next.0", - "@angular/platform-server": "22.2.0-next.0", - "@angular/router": "22.2.0-next.0", + "@angular/common": "22.2.0-next.1", + "@angular/compiler": "22.2.0-next.1", + "@angular/core": "22.2.0-next.1", + "@angular/platform-browser": "22.2.0-next.1", + "@angular/platform-server": "22.2.0-next.1", + "@angular/router": "22.2.0-next.1", "@schematics/angular": "workspace:*", "beasties": "0.4.3" }, diff --git a/packages/ngtools/webpack/package.json b/packages/ngtools/webpack/package.json index 8eef88646405..bb226ae9aabd 100644 --- a/packages/ngtools/webpack/package.json +++ b/packages/ngtools/webpack/package.json @@ -17,8 +17,8 @@ }, "devDependencies": { "@angular-devkit/core": "workspace:0.0.0-PLACEHOLDER", - "@angular/compiler": "22.2.0-next.0", - "@angular/compiler-cli": "22.2.0-next.0", + "@angular/compiler": "22.2.0-next.1", + "@angular/compiler-cli": "22.2.0-next.1", "typescript": "6.0.3", "webpack": "5.109.2" } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 33e53fcd6f95..e88d0bc40181 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -14,8 +14,8 @@ importers: .: dependencies: '@angular/compiler-cli': - specifier: 22.2.0-next.0 - version: 22.2.0-next.0(@angular/compiler@22.2.0-next.0)(typescript@6.0.3) + specifier: 22.2.0-next.1 + version: 22.2.0-next.1(@angular/compiler@22.2.0-next.1)(typescript@6.0.3) typescript: specifier: 6.0.3 version: 6.0.3 @@ -26,44 +26,44 @@ importers: built: true devDependencies: '@angular/animations': - specifier: 22.2.0-next.0 - version: 22.2.0-next.0(@angular/core@22.2.0-next.0(@angular/compiler@22.2.0-next.0)(rxjs@7.8.2)(zone.js@0.16.2)) + specifier: 22.2.0-next.1 + version: 22.2.0-next.1(@angular/core@22.2.0-next.1(@angular/compiler@22.2.0-next.1)(rxjs@7.8.2)(zone.js@0.16.2)) '@angular/cdk': specifier: 22.2.0-next.0 - version: 22.2.0-next.0(@angular/common@22.2.0-next.0(@angular/core@22.2.0-next.0(@angular/compiler@22.2.0-next.0)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2))(@angular/core@22.2.0-next.0(@angular/compiler@22.2.0-next.0)(rxjs@7.8.2)(zone.js@0.16.2))(@angular/platform-browser@22.2.0-next.0(@angular/animations@22.2.0-next.0(@angular/core@22.2.0-next.0(@angular/compiler@22.2.0-next.0)(rxjs@7.8.2)(zone.js@0.16.2)))(@angular/common@22.2.0-next.0(@angular/core@22.2.0-next.0(@angular/compiler@22.2.0-next.0)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2))(@angular/core@22.2.0-next.0(@angular/compiler@22.2.0-next.0)(rxjs@7.8.2)(zone.js@0.16.2)))(rxjs@7.8.2) + version: 22.2.0-next.0(@angular/common@22.2.0-next.1(@angular/core@22.2.0-next.1(@angular/compiler@22.2.0-next.1)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2))(@angular/core@22.2.0-next.1(@angular/compiler@22.2.0-next.1)(rxjs@7.8.2)(zone.js@0.16.2))(@angular/platform-browser@22.2.0-next.1(@angular/animations@22.2.0-next.1(@angular/core@22.2.0-next.1(@angular/compiler@22.2.0-next.1)(rxjs@7.8.2)(zone.js@0.16.2)))(@angular/common@22.2.0-next.1(@angular/core@22.2.0-next.1(@angular/compiler@22.2.0-next.1)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2))(@angular/core@22.2.0-next.1(@angular/compiler@22.2.0-next.1)(rxjs@7.8.2)(zone.js@0.16.2)))(rxjs@7.8.2) '@angular/common': - specifier: 22.2.0-next.0 - version: 22.2.0-next.0(@angular/core@22.2.0-next.0(@angular/compiler@22.2.0-next.0)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2) + specifier: 22.2.0-next.1 + version: 22.2.0-next.1(@angular/core@22.2.0-next.1(@angular/compiler@22.2.0-next.1)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2) '@angular/compiler': - specifier: 22.2.0-next.0 - version: 22.2.0-next.0 + specifier: 22.2.0-next.1 + version: 22.2.0-next.1 '@angular/core': - specifier: 22.2.0-next.0 - version: 22.2.0-next.0(@angular/compiler@22.2.0-next.0)(rxjs@7.8.2)(zone.js@0.16.2) + specifier: 22.2.0-next.1 + version: 22.2.0-next.1(@angular/compiler@22.2.0-next.1)(rxjs@7.8.2)(zone.js@0.16.2) '@angular/forms': - specifier: 22.2.0-next.0 - version: 22.2.0-next.0(@angular/common@22.2.0-next.0(@angular/core@22.2.0-next.0(@angular/compiler@22.2.0-next.0)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2))(@angular/core@22.2.0-next.0(@angular/compiler@22.2.0-next.0)(rxjs@7.8.2)(zone.js@0.16.2))(@angular/platform-browser@22.2.0-next.0(@angular/animations@22.2.0-next.0(@angular/core@22.2.0-next.0(@angular/compiler@22.2.0-next.0)(rxjs@7.8.2)(zone.js@0.16.2)))(@angular/common@22.2.0-next.0(@angular/core@22.2.0-next.0(@angular/compiler@22.2.0-next.0)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2))(@angular/core@22.2.0-next.0(@angular/compiler@22.2.0-next.0)(rxjs@7.8.2)(zone.js@0.16.2)))(rxjs@7.8.2) + specifier: 22.2.0-next.1 + version: 22.2.0-next.1(@angular/common@22.2.0-next.1(@angular/core@22.2.0-next.1(@angular/compiler@22.2.0-next.1)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2))(@angular/core@22.2.0-next.1(@angular/compiler@22.2.0-next.1)(rxjs@7.8.2)(zone.js@0.16.2))(@angular/platform-browser@22.2.0-next.1(@angular/animations@22.2.0-next.1(@angular/core@22.2.0-next.1(@angular/compiler@22.2.0-next.1)(rxjs@7.8.2)(zone.js@0.16.2)))(@angular/common@22.2.0-next.1(@angular/core@22.2.0-next.1(@angular/compiler@22.2.0-next.1)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2))(@angular/core@22.2.0-next.1(@angular/compiler@22.2.0-next.1)(rxjs@7.8.2)(zone.js@0.16.2)))(rxjs@7.8.2) '@angular/localize': - specifier: 22.2.0-next.0 - version: 22.2.0-next.0(@angular/compiler-cli@22.2.0-next.0(@angular/compiler@22.2.0-next.0)(typescript@6.0.3))(@angular/compiler@22.2.0-next.0) + specifier: 22.2.0-next.1 + version: 22.2.0-next.1(@angular/compiler-cli@22.2.0-next.1(@angular/compiler@22.2.0-next.1)(typescript@6.0.3))(@angular/compiler@22.2.0-next.1) '@angular/material': specifier: 22.2.0-next.0 - version: 22.2.0-next.0(08785ac9bff56240de0a5940322ae01f) + version: 22.2.0-next.0(bde3c53bf3d1c9d6d40d1d641ef3b318) '@angular/ng-dev': - specifier: https://github.com/angular/dev-infra-private-ng-dev-builds.git#dcf9b6776377d5d301e054111add3ef80f433b70 - version: https://codeload.github.com/angular/dev-infra-private-ng-dev-builds/tar.gz/dcf9b6776377d5d301e054111add3ef80f433b70 + specifier: https://github.com/angular/dev-infra-private-ng-dev-builds.git#c71d9b6af7560faa3d002534d416a8045111adae + version: https://codeload.github.com/angular/dev-infra-private-ng-dev-builds/tar.gz/c71d9b6af7560faa3d002534d416a8045111adae '@angular/platform-browser': - specifier: 22.2.0-next.0 - version: 22.2.0-next.0(@angular/animations@22.2.0-next.0(@angular/core@22.2.0-next.0(@angular/compiler@22.2.0-next.0)(rxjs@7.8.2)(zone.js@0.16.2)))(@angular/common@22.2.0-next.0(@angular/core@22.2.0-next.0(@angular/compiler@22.2.0-next.0)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2))(@angular/core@22.2.0-next.0(@angular/compiler@22.2.0-next.0)(rxjs@7.8.2)(zone.js@0.16.2)) + specifier: 22.2.0-next.1 + version: 22.2.0-next.1(@angular/animations@22.2.0-next.1(@angular/core@22.2.0-next.1(@angular/compiler@22.2.0-next.1)(rxjs@7.8.2)(zone.js@0.16.2)))(@angular/common@22.2.0-next.1(@angular/core@22.2.0-next.1(@angular/compiler@22.2.0-next.1)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2))(@angular/core@22.2.0-next.1(@angular/compiler@22.2.0-next.1)(rxjs@7.8.2)(zone.js@0.16.2)) '@angular/platform-server': - specifier: 22.2.0-next.0 - version: 22.2.0-next.0(@angular/common@22.2.0-next.0(@angular/core@22.2.0-next.0(@angular/compiler@22.2.0-next.0)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2))(@angular/compiler@22.2.0-next.0)(@angular/core@22.2.0-next.0(@angular/compiler@22.2.0-next.0)(rxjs@7.8.2)(zone.js@0.16.2))(@angular/platform-browser@22.2.0-next.0(@angular/animations@22.2.0-next.0(@angular/core@22.2.0-next.0(@angular/compiler@22.2.0-next.0)(rxjs@7.8.2)(zone.js@0.16.2)))(@angular/common@22.2.0-next.0(@angular/core@22.2.0-next.0(@angular/compiler@22.2.0-next.0)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2))(@angular/core@22.2.0-next.0(@angular/compiler@22.2.0-next.0)(rxjs@7.8.2)(zone.js@0.16.2)))(rxjs@7.8.2) + specifier: 22.2.0-next.1 + version: 22.2.0-next.1(@angular/common@22.2.0-next.1(@angular/core@22.2.0-next.1(@angular/compiler@22.2.0-next.1)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2))(@angular/compiler@22.2.0-next.1)(@angular/core@22.2.0-next.1(@angular/compiler@22.2.0-next.1)(rxjs@7.8.2)(zone.js@0.16.2))(@angular/platform-browser@22.2.0-next.1(@angular/animations@22.2.0-next.1(@angular/core@22.2.0-next.1(@angular/compiler@22.2.0-next.1)(rxjs@7.8.2)(zone.js@0.16.2)))(@angular/common@22.2.0-next.1(@angular/core@22.2.0-next.1(@angular/compiler@22.2.0-next.1)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2))(@angular/core@22.2.0-next.1(@angular/compiler@22.2.0-next.1)(rxjs@7.8.2)(zone.js@0.16.2)))(rxjs@7.8.2) '@angular/router': - specifier: 22.2.0-next.0 - version: 22.2.0-next.0(@angular/common@22.2.0-next.0(@angular/core@22.2.0-next.0(@angular/compiler@22.2.0-next.0)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2))(@angular/core@22.2.0-next.0(@angular/compiler@22.2.0-next.0)(rxjs@7.8.2)(zone.js@0.16.2))(@angular/platform-browser@22.2.0-next.0(@angular/animations@22.2.0-next.0(@angular/core@22.2.0-next.0(@angular/compiler@22.2.0-next.0)(rxjs@7.8.2)(zone.js@0.16.2)))(@angular/common@22.2.0-next.0(@angular/core@22.2.0-next.0(@angular/compiler@22.2.0-next.0)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2))(@angular/core@22.2.0-next.0(@angular/compiler@22.2.0-next.0)(rxjs@7.8.2)(zone.js@0.16.2)))(rxjs@7.8.2) + specifier: 22.2.0-next.1 + version: 22.2.0-next.1(@angular/common@22.2.0-next.1(@angular/core@22.2.0-next.1(@angular/compiler@22.2.0-next.1)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2))(@angular/core@22.2.0-next.1(@angular/compiler@22.2.0-next.1)(rxjs@7.8.2)(zone.js@0.16.2))(@angular/platform-browser@22.2.0-next.1(@angular/animations@22.2.0-next.1(@angular/core@22.2.0-next.1(@angular/compiler@22.2.0-next.1)(rxjs@7.8.2)(zone.js@0.16.2)))(@angular/common@22.2.0-next.1(@angular/core@22.2.0-next.1(@angular/compiler@22.2.0-next.1)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2))(@angular/core@22.2.0-next.1(@angular/compiler@22.2.0-next.1)(rxjs@7.8.2)(zone.js@0.16.2)))(rxjs@7.8.2) '@angular/service-worker': - specifier: 22.2.0-next.0 - version: 22.2.0-next.0(@angular/core@22.2.0-next.0(@angular/compiler@22.2.0-next.0)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2) + specifier: 22.2.0-next.1 + version: 22.2.0-next.1(@angular/core@22.2.0-next.1(@angular/compiler@22.2.0-next.1)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2) '@babel/core': specifier: 8.0.1 version: 8.0.1 @@ -315,13 +315,13 @@ importers: version: 30.0.1 ng-packagr: specifier: 22.2.0-next.2 - version: 22.2.0-next.2(@angular/compiler-cli@22.2.0-next.0(@angular/compiler@22.2.0-next.0)(typescript@6.0.3))(supports-color@11.0.0)(tslib@2.8.1)(typescript@6.0.3) + version: 22.2.0-next.2(@angular/compiler-cli@22.2.0-next.1(@angular/compiler@22.2.0-next.1)(typescript@6.0.3))(supports-color@11.0.0)(tslib@2.8.1)(typescript@6.0.3) rxjs: specifier: 7.8.2 version: 7.8.2 vitest: specifier: 4.1.10 - version: 4.1.10(@opentelemetry/api@1.9.1)(@types/node@22.20.1)(@vitest/coverage-v8@4.1.10)(esbuild@0.28.1)(jiti@2.7.0)(jsdom@30.0.1)(less@4.8.1(supports-color@11.0.0))(sass@1.102.0)(terser@5.49.1)(tsx@4.23.1)(yaml@2.9.0) + version: 4.1.10(@opentelemetry/api@1.9.1)(@types/node@22.20.1)(@vitest/coverage-v8@4.1.10)(esbuild@0.28.1)(jiti@2.7.0)(jsdom@30.0.1)(less@4.8.1(supports-color@11.0.0))(sass@1.102.0)(terser@5.49.1)(tsx@4.23.7)(yaml@2.9.0) packages/angular/build: dependencies: @@ -336,13 +336,13 @@ importers: version: 8.0.1 '@inquirer/confirm': specifier: 6.1.1 - version: 6.1.1(@types/node@24.13.3) + version: 6.1.1(@types/node@22.20.1) '@parcel/watcher': specifier: 2.6.0 version: 2.6.0 '@vitejs/plugin-basic-ssl': specifier: 2.3.0 - version: 2.3.0(vite@8.2.0(@types/node@22.20.1)(esbuild@0.28.1)(jiti@2.7.0)(less@4.8.1(supports-color@11.0.0))(sass@1.102.0)(terser@5.49.1)(tsx@4.23.1)(yaml@2.9.0)) + version: 2.3.0(vite@8.2.0(@types/node@22.20.1)(esbuild@0.28.1)(jiti@2.7.0)(less@4.8.1(supports-color@11.0.0))(sass@1.102.0)(terser@5.49.1)(tsx@4.23.7)(yaml@2.9.0)) beasties: specifier: 0.4.3 version: 0.4.3 @@ -399,7 +399,7 @@ importers: version: 0.2.17 vite: specifier: 8.2.0 - version: 8.2.0(@types/node@22.20.1)(esbuild@0.28.1)(jiti@2.7.0)(less@4.8.1(supports-color@11.0.0))(sass@1.102.0)(terser@5.49.1)(tsx@4.23.1)(yaml@2.9.0) + version: 8.2.0(@types/node@22.20.1)(esbuild@0.28.1)(jiti@2.7.0)(less@4.8.1(supports-color@11.0.0))(sass@1.102.0)(terser@5.49.1)(tsx@4.23.7)(yaml@2.9.0) xxhash-wasm: specifier: 1.1.0 version: 1.1.0 @@ -424,7 +424,7 @@ importers: version: 4.8.1(supports-color@11.0.0) ng-packagr: specifier: 22.2.0-next.2 - version: 22.2.0-next.2(@angular/compiler-cli@22.2.0-next.0(@angular/compiler@22.2.0-next.0)(typescript@6.0.3))(supports-color@11.0.0)(tslib@2.8.1)(typescript@6.0.3) + version: 22.2.0-next.2(@angular/compiler-cli@22.2.0-next.1(@angular/compiler@22.2.0-next.1)(typescript@6.0.3))(supports-color@11.0.0)(tslib@2.8.1)(typescript@6.0.3) postcss: specifier: 8.5.25 version: 8.5.25 @@ -436,7 +436,7 @@ importers: version: 7.8.2 vitest: specifier: 4.1.10 - version: 4.1.10(@opentelemetry/api@1.9.1)(@types/node@22.20.1)(@vitest/coverage-v8@4.1.10)(esbuild@0.28.1)(jiti@2.7.0)(jsdom@30.0.1)(less@4.8.1(supports-color@11.0.0))(sass@1.102.0)(terser@5.49.1)(tsx@4.23.1)(yaml@2.9.0) + version: 4.1.10(@opentelemetry/api@1.9.1)(@types/node@22.20.1)(@vitest/coverage-v8@4.1.10)(esbuild@0.28.1)(jiti@2.7.0)(jsdom@30.0.1)(less@4.8.1(supports-color@11.0.0))(sass@1.102.0)(terser@5.49.1)(tsx@4.23.7)(yaml@2.9.0) optionalDependencies: lmdb: specifier: 3.5.6 @@ -509,23 +509,23 @@ importers: specifier: workspace:* version: link:../../angular_devkit/schematics '@angular/common': - specifier: 22.2.0-next.0 - version: 22.2.0-next.0(@angular/core@22.2.0-next.0(@angular/compiler@22.2.0-next.0)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2) + specifier: 22.2.0-next.1 + version: 22.2.0-next.1(@angular/core@22.2.0-next.1(@angular/compiler@22.2.0-next.1)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2) '@angular/compiler': - specifier: 22.2.0-next.0 - version: 22.2.0-next.0 + specifier: 22.2.0-next.1 + version: 22.2.0-next.1 '@angular/core': - specifier: 22.2.0-next.0 - version: 22.2.0-next.0(@angular/compiler@22.2.0-next.0)(rxjs@7.8.2)(zone.js@0.16.2) + specifier: 22.2.0-next.1 + version: 22.2.0-next.1(@angular/compiler@22.2.0-next.1)(rxjs@7.8.2)(zone.js@0.16.2) '@angular/platform-browser': - specifier: 22.2.0-next.0 - version: 22.2.0-next.0(@angular/animations@22.2.0-next.0(@angular/core@22.2.0-next.0(@angular/compiler@22.2.0-next.0)(rxjs@7.8.2)(zone.js@0.16.2)))(@angular/common@22.2.0-next.0(@angular/core@22.2.0-next.0(@angular/compiler@22.2.0-next.0)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2))(@angular/core@22.2.0-next.0(@angular/compiler@22.2.0-next.0)(rxjs@7.8.2)(zone.js@0.16.2)) + specifier: 22.2.0-next.1 + version: 22.2.0-next.1(@angular/animations@22.2.0-next.1(@angular/core@22.2.0-next.1(@angular/compiler@22.2.0-next.1)(rxjs@7.8.2)(zone.js@0.16.2)))(@angular/common@22.2.0-next.1(@angular/core@22.2.0-next.1(@angular/compiler@22.2.0-next.1)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2))(@angular/core@22.2.0-next.1(@angular/compiler@22.2.0-next.1)(rxjs@7.8.2)(zone.js@0.16.2)) '@angular/platform-server': - specifier: 22.2.0-next.0 - version: 22.2.0-next.0(@angular/common@22.2.0-next.0(@angular/core@22.2.0-next.0(@angular/compiler@22.2.0-next.0)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2))(@angular/compiler@22.2.0-next.0)(@angular/core@22.2.0-next.0(@angular/compiler@22.2.0-next.0)(rxjs@7.8.2)(zone.js@0.16.2))(@angular/platform-browser@22.2.0-next.0(@angular/animations@22.2.0-next.0(@angular/core@22.2.0-next.0(@angular/compiler@22.2.0-next.0)(rxjs@7.8.2)(zone.js@0.16.2)))(@angular/common@22.2.0-next.0(@angular/core@22.2.0-next.0(@angular/compiler@22.2.0-next.0)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2))(@angular/core@22.2.0-next.0(@angular/compiler@22.2.0-next.0)(rxjs@7.8.2)(zone.js@0.16.2)))(rxjs@7.8.2) + specifier: 22.2.0-next.1 + version: 22.2.0-next.1(@angular/common@22.2.0-next.1(@angular/core@22.2.0-next.1(@angular/compiler@22.2.0-next.1)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2))(@angular/compiler@22.2.0-next.1)(@angular/core@22.2.0-next.1(@angular/compiler@22.2.0-next.1)(rxjs@7.8.2)(zone.js@0.16.2))(@angular/platform-browser@22.2.0-next.1(@angular/animations@22.2.0-next.1(@angular/core@22.2.0-next.1(@angular/compiler@22.2.0-next.1)(rxjs@7.8.2)(zone.js@0.16.2)))(@angular/common@22.2.0-next.1(@angular/core@22.2.0-next.1(@angular/compiler@22.2.0-next.1)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2))(@angular/core@22.2.0-next.1(@angular/compiler@22.2.0-next.1)(rxjs@7.8.2)(zone.js@0.16.2)))(rxjs@7.8.2) '@angular/router': - specifier: 22.2.0-next.0 - version: 22.2.0-next.0(@angular/common@22.2.0-next.0(@angular/core@22.2.0-next.0(@angular/compiler@22.2.0-next.0)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2))(@angular/core@22.2.0-next.0(@angular/compiler@22.2.0-next.0)(rxjs@7.8.2)(zone.js@0.16.2))(@angular/platform-browser@22.2.0-next.0(@angular/animations@22.2.0-next.0(@angular/core@22.2.0-next.0(@angular/compiler@22.2.0-next.0)(rxjs@7.8.2)(zone.js@0.16.2)))(@angular/common@22.2.0-next.0(@angular/core@22.2.0-next.0(@angular/compiler@22.2.0-next.0)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2))(@angular/core@22.2.0-next.0(@angular/compiler@22.2.0-next.0)(rxjs@7.8.2)(zone.js@0.16.2)))(rxjs@7.8.2) + specifier: 22.2.0-next.1 + version: 22.2.0-next.1(@angular/common@22.2.0-next.1(@angular/core@22.2.0-next.1(@angular/compiler@22.2.0-next.1)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2))(@angular/core@22.2.0-next.1(@angular/compiler@22.2.0-next.1)(rxjs@7.8.2)(zone.js@0.16.2))(@angular/platform-browser@22.2.0-next.1(@angular/animations@22.2.0-next.1(@angular/core@22.2.0-next.1(@angular/compiler@22.2.0-next.1)(rxjs@7.8.2)(zone.js@0.16.2)))(@angular/common@22.2.0-next.1(@angular/core@22.2.0-next.1(@angular/compiler@22.2.0-next.1)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2))(@angular/core@22.2.0-next.1(@angular/compiler@22.2.0-next.1)(rxjs@7.8.2)(zone.js@0.16.2)))(rxjs@7.8.2) '@schematics/angular': specifier: workspace:* version: link:../../schematics/angular @@ -712,7 +712,7 @@ importers: version: 3.0.4(bufferutil@4.1.0)(debug@4.4.3(supports-color@11.0.0))(supports-color@11.0.0)(utf-8-validate@6.0.6) ng-packagr: specifier: 22.2.0-next.2 - version: 22.2.0-next.2(@angular/compiler-cli@22.2.0-next.0(@angular/compiler@22.2.0-next.0)(typescript@6.0.3))(supports-color@11.0.0)(tslib@2.8.1)(typescript@6.0.3) + version: 22.2.0-next.2(@angular/compiler-cli@22.2.0-next.1(@angular/compiler@22.2.0-next.1)(typescript@6.0.3))(supports-color@11.0.0)(tslib@2.8.1)(typescript@6.0.3) undici: specifier: 8.10.0 version: 8.10.0 @@ -804,11 +804,11 @@ importers: specifier: workspace:0.0.0-PLACEHOLDER version: link:../../angular_devkit/core '@angular/compiler': - specifier: 22.2.0-next.0 - version: 22.2.0-next.0 + specifier: 22.2.0-next.1 + version: 22.2.0-next.1 '@angular/compiler-cli': - specifier: 22.2.0-next.0 - version: 22.2.0-next.0(@angular/compiler@22.2.0-next.0)(typescript@6.0.3) + specifier: 22.2.0-next.1 + version: 22.2.0-next.1(@angular/compiler@22.2.0-next.1)(typescript@6.0.3) typescript: specifier: 6.0.3 version: 6.0.3 @@ -861,12 +861,11 @@ packages: resolution: {integrity: sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==} engines: {node: '>=6.0.0'} - '@angular/animations@22.2.0-next.0': - resolution: {integrity: sha512-L0uG7GtCtWuXA+ZRT+9vbQI2ojacCseMlUZ8Y1KcfXjl50rtlmsjjgmLDWLTKGHUG5fT18grfX01SQp03tnNlg==} + '@angular/animations@22.2.0-next.1': + resolution: {integrity: sha512-U/bJC3EaGW1AN7d95xvyYJ2XoC4jPLjLk6sI2KV5cKuCN0MnPX7WFa5qG+k/2KseXnaWqcEc5mLXC7oi1DkT0Q==} engines: {node: ^22.22.3 || ^24.15.0 || >=26.0.0} - deprecated: '@angular/animations is deprecated. Use `animate.enter` and `animate.leave` instead. For more information see: https://v22.angular.dev/guide/animations.' peerDependencies: - '@angular/core': 22.2.0-next.0 + '@angular/core': 22.2.0-next.1 '@angular/cdk@22.2.0-next.0': resolution: {integrity: sha512-l+Cniyp/qodyEMmWcYpXQ0zEOWzZ/zY+7ERn0dBGmjR3SJx3lPT+gqc6c99BSB9eOy4wldmxyLckpvKiNMSJoA==} @@ -876,33 +875,33 @@ packages: '@angular/platform-browser': ^22.0.0-0 || ^22.1.0-0 || ^22.2.0-0 || ^22.3.0-0 || ^23.0.0-0 rxjs: ^6.5.3 || ^7.4.0 - '@angular/common@22.2.0-next.0': - resolution: {integrity: sha512-EMhmI+JxYVUw1bA6adhrWbcjkuHCt4SJbSX6JL2vYmwyeM0c2Fn/J883ajfKcl8VNfqpyKVlD9SuLzZ2ynH3OA==} + '@angular/common@22.2.0-next.1': + resolution: {integrity: sha512-LgLizDgJcXirUwWP2tEJ9MpUIi2RYnvT/SED9pus2t6JnlBoS1WocH7AkLfBQrsLckSv+g/3w82eGdwvwb0Zvg==} engines: {node: ^22.22.3 || ^24.15.0 || >=26.0.0} peerDependencies: - '@angular/core': 22.2.0-next.0 + '@angular/core': 22.2.0-next.1 rxjs: ^6.5.3 || ^7.4.0 - '@angular/compiler-cli@22.2.0-next.0': - resolution: {integrity: sha512-YIZLmFVxbKQBUTjGSuPUEAzfMAxFSBtNFT8+EUja0rLX1eV1UEz3ScnvDYbjrM3WLEl58jqiv3AAOd2/cg7rNw==} + '@angular/compiler-cli@22.2.0-next.1': + resolution: {integrity: sha512-wuqRIV8Mw85f0pz/VJfCsa9uJVfXjOdaLRP3pI51jZbHA2/eb/1MyL6HcAHk+SDesjtaDj0O4JMqyp6hR6DHJg==} engines: {node: ^22.22.3 || ^24.15.0 || >=26.0.0} hasBin: true peerDependencies: - '@angular/compiler': 22.2.0-next.0 + '@angular/compiler': 22.2.0-next.1 typescript: '>=6.0 <6.1' peerDependenciesMeta: typescript: optional: true - '@angular/compiler@22.2.0-next.0': - resolution: {integrity: sha512-bhdoJLlsrUJwsYO2Ean8L49Go43v+b2a99eGBOrP+2DStb3jSBtc0STdrB9oMwhOGmo/hsQ1xRlm5O8I6o0KjA==} + '@angular/compiler@22.2.0-next.1': + resolution: {integrity: sha512-rI10E7GcztbbW1j2CvvGYLdpZRYP3/u0AZSc+sjXi9KOUrSqzQ06qZF+opG1R4fXK+ExRhIdhtt5K3PpImuURQ==} engines: {node: ^22.22.3 || ^24.15.0 || >=26.0.0} - '@angular/core@22.2.0-next.0': - resolution: {integrity: sha512-H0T3UlRMSiw9Nvzj6cExb/n04vcxpg/ypbSoaGhih12OQH06A+2Oz5GJTj3jfo8rha023XqKJjxYGVmKNRtbfA==} + '@angular/core@22.2.0-next.1': + resolution: {integrity: sha512-oVfjuVhS2zdfQD+3iH2doQ12Md+v5QMyn1xlvmqU79TWcRsyjps4sqErQBkQjM+InKWl4mrL+PSYiWX0w8ZhYA==} engines: {node: ^22.22.3 || ^24.15.0 || >=26.0.0} peerDependencies: - '@angular/compiler': 22.2.0-next.0 + '@angular/compiler': 22.2.0-next.1 rxjs: ^6.5.3 || ^7.4.0 zone.js: ~0.15.0 || ~0.16.0 peerDependenciesMeta: @@ -911,22 +910,22 @@ packages: zone.js: optional: true - '@angular/forms@22.2.0-next.0': - resolution: {integrity: sha512-Uy6NRas4WNbJ5als+qNcZ0N4SRo/ldAohl2gPNrWzuDRQOb/aocVrPQZJQhu8i4fv7c37DU8uH9Szk3IBU9F4g==} + '@angular/forms@22.2.0-next.1': + resolution: {integrity: sha512-PXN3Q9RNms2AGBDmBpGEnezZbFHvAhHUI9TjI0qVIJnf+4O65fNY/3YWgRV9J2YPgLqn+mTBZ0mbcGZh1OaMbA==} engines: {node: ^22.22.3 || ^24.15.0 || >=26.0.0} peerDependencies: - '@angular/common': 22.2.0-next.0 - '@angular/core': 22.2.0-next.0 - '@angular/platform-browser': 22.2.0-next.0 + '@angular/common': 22.2.0-next.1 + '@angular/core': 22.2.0-next.1 + '@angular/platform-browser': 22.2.0-next.1 rxjs: ^6.5.3 || ^7.4.0 - '@angular/localize@22.2.0-next.0': - resolution: {integrity: sha512-2CVUA9mLGHPl9Kb98Apj7Gfc904e75kJ8g4X04QSkjWibOwvBf1XpHd1lS0giPjyx/ZbJrXEoldzTQtWL8vIQw==} + '@angular/localize@22.2.0-next.1': + resolution: {integrity: sha512-YiWgksugSV4Exm8vMXJUBp5ceklY9SpLwPJqUjzxUXxpVIQeYwKHbfCJrogVh6yJDcgtNEJ+UL2gcNzDOdfd4w==} engines: {node: ^22.22.3 || ^24.15.0 || >=26.0.0} hasBin: true peerDependencies: - '@angular/compiler': 22.2.0-next.0 - '@angular/compiler-cli': 22.2.0-next.0 + '@angular/compiler': 22.2.0-next.1 + '@angular/compiler-cli': 22.2.0-next.1 '@angular/material@22.2.0-next.0': resolution: {integrity: sha512-knu75htSySpbPmH21njiNB19b4zXgVc9T/hWIF0WWorjpDKVLqgvHDJdxo34XYT764Hp32L7YxJwiwu08/e8eA==} @@ -938,47 +937,47 @@ packages: '@angular/platform-browser': ^22.0.0-0 || ^22.1.0-0 || ^22.2.0-0 || ^22.3.0-0 || ^23.0.0-0 rxjs: ^6.5.3 || ^7.4.0 - '@angular/ng-dev@https://codeload.github.com/angular/dev-infra-private-ng-dev-builds/tar.gz/dcf9b6776377d5d301e054111add3ef80f433b70': - resolution: {gitHosted: true, integrity: sha512-0g6HpWQk3yfpDvOWO9O0HgjGQR/SJQ+e5KRUZV/yWorJuI73zHoaTPhVGzLKnvo9UF0oY++VvkKmpww0iuCo0Q==, tarball: https://codeload.github.com/angular/dev-infra-private-ng-dev-builds/tar.gz/dcf9b6776377d5d301e054111add3ef80f433b70} - version: 0.0.0-0b701b31038419ad73422a9d9d3dff43a725a0d2 + '@angular/ng-dev@https://codeload.github.com/angular/dev-infra-private-ng-dev-builds/tar.gz/c71d9b6af7560faa3d002534d416a8045111adae': + resolution: {gitHosted: true, integrity: sha512-/32ipAQZed8P+Sgp4Hqk++iJpQVcwwvaCgRCD2fVJi1q17t9qUP+F66uthOE+MTQktgdTXg1Ayi3YWwJWBapnw==, tarball: https://codeload.github.com/angular/dev-infra-private-ng-dev-builds/tar.gz/c71d9b6af7560faa3d002534d416a8045111adae} + version: 0.0.0-92c6b596e59e320c9edbc6d6490c1047264c4a0d hasBin: true - '@angular/platform-browser@22.2.0-next.0': - resolution: {integrity: sha512-qhZoQExwr9cp+U7Dlg6Gmd4OwQoG7fzG7mt7jjpjX5u1EhWMnegaqGN6rk0udiAm5FiDzzgBtikBEk7elN0pvg==} + '@angular/platform-browser@22.2.0-next.1': + resolution: {integrity: sha512-jfemRcrDuPMz6KVseWK7yuzBRC5v85oa8jVhggaVJVzHH9diGAnMkoMJEtPOLDlB2LhtQuUlniOQWMydDUta4g==} engines: {node: ^22.22.3 || ^24.15.0 || >=26.0.0} peerDependencies: - '@angular/animations': 22.2.0-next.0 - '@angular/common': 22.2.0-next.0 - '@angular/core': 22.2.0-next.0 + '@angular/animations': 22.2.0-next.1 + '@angular/common': 22.2.0-next.1 + '@angular/core': 22.2.0-next.1 peerDependenciesMeta: '@angular/animations': optional: true - '@angular/platform-server@22.2.0-next.0': - resolution: {integrity: sha512-ufCXxsTHp8CzwzTSuqGM/B52y+F3PuDcsHF/K58ipVL7rTb2bVuo73rFePeHHG079egvKyC6moqceX5yK0OAZQ==} + '@angular/platform-server@22.2.0-next.1': + resolution: {integrity: sha512-i21sVMfPvnT1lACnJEeWopOIC3mI6oGTRRTC3nMBfYjolbboyO6CkqdUl+PPA7GxCPVFzpwmrBbf2SdjXFoXxg==} engines: {node: ^22.22.3 || ^24.15.0 || >=26.0.0} peerDependencies: - '@angular/common': 22.2.0-next.0 - '@angular/compiler': 22.2.0-next.0 - '@angular/core': 22.2.0-next.0 - '@angular/platform-browser': 22.2.0-next.0 + '@angular/common': 22.2.0-next.1 + '@angular/compiler': 22.2.0-next.1 + '@angular/core': 22.2.0-next.1 + '@angular/platform-browser': 22.2.0-next.1 rxjs: ^6.5.3 || ^7.4.0 - '@angular/router@22.2.0-next.0': - resolution: {integrity: sha512-QhRnVjFXjnfhTmBXPD/yK6FIAR/sKd5sYUjQZ0KLKYo8ig8PS/CnsIEUfm2WUyPG5dDPL3RnFf+BvHOuo5kfDg==} + '@angular/router@22.2.0-next.1': + resolution: {integrity: sha512-JjQEm0A/TBSFAzw7QjrkmSYOODW9hIg0mJIC1xBV4Fjd7itZfCSnHKP2hmoWvs1ie8BwcvOE/YRNc+MSjsDGUA==} engines: {node: ^22.22.3 || ^24.15.0 || >=26.0.0} peerDependencies: - '@angular/common': 22.2.0-next.0 - '@angular/core': 22.2.0-next.0 - '@angular/platform-browser': 22.2.0-next.0 + '@angular/common': 22.2.0-next.1 + '@angular/core': 22.2.0-next.1 + '@angular/platform-browser': 22.2.0-next.1 rxjs: ^6.5.3 || ^7.4.0 - '@angular/service-worker@22.2.0-next.0': - resolution: {integrity: sha512-+41io1mpCnAl88gQd+vhVmWRg62udPJq0QzUOI90Noz7Yi9OGv6J+1zVdSZYLlYBodSjyZaqOZze89uCubzpQg==} + '@angular/service-worker@22.2.0-next.1': + resolution: {integrity: sha512-0Gh8/+pf7ZsSPS6IYPeFvh8v7SarVXexzYqrffjjQkwCJrN67B/AoYVG/99mPTe1ch7AQ6mxCrtoGmw4CNmZGw==} engines: {node: ^22.22.3 || ^24.15.0 || >=26.0.0} hasBin: true peerDependencies: - '@angular/core': 22.2.0-next.0 + '@angular/core': 22.2.0-next.1 rxjs: ^6.5.3 || ^7.4.0 '@asamuzakjp/css-color@6.0.5': @@ -1842,30 +1841,32 @@ packages: '@noble/hashes': optional: true - '@firebase/ai@2.13.1': - resolution: {integrity: sha512-RhT/VViTPBSplhQSuEp62HhLvfsV+LowMh8ZUo5MMRDzG7oFtSget4Kmg5oHP50hDVyWQuQj6to9iPFEZk08Tw==} + '@firebase/ai@2.14.0': + resolution: {integrity: sha512-TYEQqCQUTyVHuG/HVi9vau6F9kvEaS49o/hmdn/yUuN6ZXQkwIml2nNJTIBfjNl/r9LOxwUNILgcOY16nxObug==} engines: {node: '>=20.0.0'} peerDependencies: '@firebase/app': 0.x '@firebase/app-types': 0.x - '@firebase/analytics-compat@0.2.28': - resolution: {integrity: sha512-lIAlqUUbBu93FJMlQfslryQtBwwzdzvp23ePC6FNgymXk6Ook5v4Uvc0vdutvoIeqmyA3LfP0ZeRFK8+11kOOQ==} + '@firebase/analytics-compat@0.2.29': + resolution: {integrity: sha512-allztvCvCUlItZzD97TiRAtGoFJzR1FQFmLxbaLc6PvgscqD9cl5NdKPTtka6keShVYXvCZJpzWcRoH4TME8rw==} peerDependencies: + '@firebase/app': 0.x '@firebase/app-compat': 0.x '@firebase/analytics-types@0.8.4': resolution: {integrity: sha512-zQ+XTgkwH6CY/eUSHJRP7e4LxM30RCxlCmob5sy2axs25GE3Ny0XdgpDscMTHHQIGqWkxPXad4w2Mw9sCgT8zQ==} - '@firebase/analytics@0.10.22': - resolution: {integrity: sha512-8BSaq/QRGU1+xyi8L2PTLTJU7MH9aMA72RQdIxrbhWFauOZY9OXo8f2YDN/972xA8d588tlnNVEQ2Mo69pT9Ow==} + '@firebase/analytics@0.10.23': + resolution: {integrity: sha512-34ALWXzWA6PTRUA5hipZmsm1RKzeecw5J1+qTCXsiMzwLqONC+GuTIQSdmm91MmTAEA+wG1Q5t0IFahcYQOqAA==} peerDependencies: '@firebase/app': 0.x - '@firebase/app-check-compat@0.4.5': - resolution: {integrity: sha512-JI17mVcZs34zO6ZeSCrw4U2iohqy+n6GIzkbmsA+TbVjmvFLkUKt3bs5M+qRBteQm/0IWzqSHYFzEQLzDTQebg==} + '@firebase/app-check-compat@0.4.6': + resolution: {integrity: sha512-2pzNEZEkX84jSqy6TH6FI1HSLA1lc7kakRUybBbKjg9YhIttPlW/XX3N9CDtChji2PTTPWVPZiWhB10exHfA+A==} engines: {node: '>=20.0.0'} peerDependencies: + '@firebase/app': 0.x '@firebase/app-compat': 0.x '@firebase/app-check-interop-types@0.3.4': @@ -1874,27 +1875,28 @@ packages: '@firebase/app-check-types@0.5.4': resolution: {integrity: sha512-xV7JsIyzVr15aA7f3Pi0rB9gdBuVubs89FGA8VkRYA4g0l78poADgdfrScgf7NndSg9mm7cR7PJyY0+t22KaGw==} - '@firebase/app-check@0.12.0': - resolution: {integrity: sha512-wMeT6HLWRAuW7Cp/5UjWBGKgjPNxWNOoNf4PRIv0weljoGMZVeqbUY7wNBWTI2/31cX1NlXx8gQruDLsUShB3Q==} + '@firebase/app-check@0.13.0': + resolution: {integrity: sha512-AbMttBKazQvGVXBZhQdVAdPzRhwHyJAY3Ghu5y2C7IZKIDIppzNYz0shTZ1mP4FBJa+28BuC4t+5h1Q6pT3Asg==} engines: {node: '>=20.0.0'} peerDependencies: '@firebase/app': 0.x - '@firebase/app-compat@0.5.15': - resolution: {integrity: sha512-HaiSM9TwbGIR4b7F6+UncHWlqdH89eeY7VUskaOGOlI2PxHS5Z+6hHsYGvNLy0SHDE6zyXO+3QSA6a4aqQxsqA==} + '@firebase/app-compat@0.5.16': + resolution: {integrity: sha512-shQq37O8qELDzvsVwYPlDXwD1zlcrZ0m2bpBF5ov2HSbY8x+AHsnL5TtJ2e1JAfkQN05qHao1AfabS69PN6GiA==} engines: {node: '>=20.0.0'} '@firebase/app-types@0.9.5': resolution: {integrity: sha512-YevqTjvo7Iujsa9Dwowmd6dSoElhzmD63ZSrq6bzjvQ6POjYgNjOFHLmNIgJs48eNO093NCERibuFnxbfOvU7A==} - '@firebase/app@0.15.1': - resolution: {integrity: sha512-iD9+Z5HcPo0Uop5f72/VYMeXwKucBhW7iFrISkJFvQ+lSZikTNgTz0FgAtaaTkAG0pEZSnCymA2Fu49n0rcufQ==} + '@firebase/app@0.16.0': + resolution: {integrity: sha512-G+ZGEyVP8YTb3ay6A+XpcYgFH3sTESHcnHU/EyTktodqhz2BHkLq+QEP7IVwjiMX0cxYwpVKip0/wC0KZcn9vQ==} engines: {node: '>=20.0.0'} - '@firebase/auth-compat@0.6.8': - resolution: {integrity: sha512-llcBREUC4iSNKZ6rvwud7Oz9Q7aAWU6KuQLa6pdu7Q+QAQsy4JLw6yFgxwtmzabsgznHmmcsX2UjHLLzqUxi3Q==} + '@firebase/auth-compat@0.6.9': + resolution: {integrity: sha512-/hHeTBmQ61+N5J1RECls+WfskZTY78JXr7aO5EMOfUpqJvDqvoS+568k0rp6Ss/4UWwBjadILs+H+SGy1zCS3A==} engines: {node: '>=20.0.0'} peerDependencies: + '@firebase/app': 0.x '@firebase/app-compat': 0.x '@firebase/auth-interop-types@0.2.5': @@ -1906,8 +1908,8 @@ packages: '@firebase/app-types': 0.x '@firebase/util': 1.x - '@firebase/auth@1.13.3': - resolution: {integrity: sha512-bqiq4uubDN2YyQkdvSWPQeJyXAv2O76ImF41En9b6UhV5JuBVYDoHYrrrE3NzIuGkpFMKagfhMRP4Vz6t+yQSQ==} + '@firebase/auth@1.13.4': + resolution: {integrity: sha512-s+NS1aV0DDyyfoIMeSz53HXnVTv7ufJjJfrP63XyaWHweJ5vOoxKWrTm5tO7S7PDqvyOa/Wi3oP0dgAo6JTMMA==} engines: {node: '>=20.0.0'} peerDependencies: '@firebase/app': 0.x @@ -1916,30 +1918,39 @@ packages: '@react-native-async-storage/async-storage': optional: true - '@firebase/component@0.7.3': - resolution: {integrity: sha512-wFofIaa2879ogD/WvkjYXJxRmfnL0scen6ORgaC3na1FNOR9ASIUANQdhqQcmWu/h77/pVHY7ch5flewa5Bcew==} + '@firebase/component@0.7.4': + resolution: {integrity: sha512-tLpOaaCol9ugUIYp2R3CbWPPA8Ajg/papX/XHEy8U52b/QXH3BbX8tTJX9aShDCjp+9sMAxMLD94i7lresdugQ==} engines: {node: '>=20.0.0'} - '@firebase/data-connect@0.7.1': - resolution: {integrity: sha512-2LbUU8mmSA63HknxQMmWHjpzuNLBKflvVwQc2tpoVKg0biWleNEJX031ELks0vzFs+dDjOUkCJR72RP6mQHFOg==} + '@firebase/data-connect@0.7.3': + resolution: {integrity: sha512-nHBFk3Ntl+NZCRIUG2d5j7I69P0otjyQ/duhVKLbw4+5cNke/F6RK1pdE5Jnf831/QOTs2Bd00LlxlZ+jNsb9w==} peerDependencies: '@firebase/app': 0.x - '@firebase/database-compat@2.1.4': - resolution: {integrity: sha512-3pK35F1MAgmqFJQlf2nhQl44vtAXQO1uaCaQOEUI9kCRtLFqi7N+QRKR7lFZPg+xIZIyubgxQaxY69YgfZRZWg==} + '@firebase/database-compat@2.1.6': + resolution: {integrity: sha512-mu7S/75UIajB1A5M9Vfojk69LttW55uABp9nHEtWrV/mIaSEwvoaIe9GySsEzS2EKFK5/3f5okcAuUbihhYeJg==} engines: {node: '>=20.0.0'} + peerDependencies: + '@firebase/app': 0.x + '@firebase/app-compat': 0.x + peerDependenciesMeta: + '@firebase/app': + optional: true + '@firebase/app-compat': + optional: true - '@firebase/database-types@1.0.20': - resolution: {integrity: sha512-kegbOk/w8iU64pr0q6k2ItyNGjnQBMHFhwS7ohdWI4W+pc0/zhhdGXTdFj6X1oxItRjPoYOsSQmERgBkn/ihxw==} + '@firebase/database-types@1.0.21': + resolution: {integrity: sha512-SX1jUqhttKgg/m9dYRTvqU9QvucBooziWfA986r4cpsbi4zlsvewe424j3Vpduwd6DG1MSAMfBVT2VqA61FnkA==} - '@firebase/database@1.1.3': - resolution: {integrity: sha512-XwWCa+E4TvNGpGwXrycLRNfdogADwFcvuhyow6wDWma9W54roaQIhe+4PM0KiLsIftBdSCGI7OKCXrdSRHbIhw==} + '@firebase/database@1.1.4': + resolution: {integrity: sha512-D+j4+8uhGtNd1tVD+X+c8JrC4ppStGJKyujSQt2NPwdN26QcCk0BeIxue+UqspHkHiFHyQOimwlzjLewGq6S+A==} engines: {node: '>=20.0.0'} - '@firebase/firestore-compat@0.4.11': - resolution: {integrity: sha512-W7o1WdwWq5aABK5Up2ncSvTQs/QGLR/fy7cVpFBNqhsXtxoMtflHf2xBIG6+aoptcuGAobddq4g2Sq27wqHaYw==} + '@firebase/firestore-compat@0.4.12': + resolution: {integrity: sha512-k2uX81Ao/S0jnFcWGPOQpKK1cPlJHvD9WIqh/RE1XBDP2yg5zhE4rHhSg1rtB11k39q3nKon9XLNDDrPjGclag==} engines: {node: '>=20.0.0'} peerDependencies: + '@firebase/app': 0.x '@firebase/app-compat': 0.x '@firebase/firestore-types@3.0.4': @@ -1948,30 +1959,32 @@ packages: '@firebase/app-types': 0.x '@firebase/util': 1.x - '@firebase/firestore@4.16.0': - resolution: {integrity: sha512-qdHMHMvMr0nRMuZyWNR/ArWa0YlPE3C4eAbmxTASJMYXAesKPL0Y54p70moggrNPzaK7MSIIq5RDJJyntQyIYA==} + '@firebase/firestore@4.17.0': + resolution: {integrity: sha512-P9tof6pyO1bnLlMWbux+5O7WFJqlb7OTPMKxxOiXKYiQl7mxykAvxr1BFCgWeEXUU7DZxQncyJ040B0IhFVZCg==} engines: {node: '>=20.0.0'} peerDependencies: '@firebase/app': 0.x - '@firebase/functions-compat@0.4.5': - resolution: {integrity: sha512-10qlUXGY25G5/1g9UihqksPp2po+ZqSE7LEizsrdUP7vrTmkysXxGSZCDyojSEp6mQe/ecRDdDDI+z4XRdb4wQ==} + '@firebase/functions-compat@0.4.6': + resolution: {integrity: sha512-dj9sOet+FIU91jeU4A3vGJoXHty7NqkSfjRLCwLgJXPDk1m72KFuxD3nlFgw/yXx/Fr7UjqzbxZ0LrIOdpx7+w==} engines: {node: '>=20.0.0'} peerDependencies: + '@firebase/app': 0.x '@firebase/app-compat': 0.x '@firebase/functions-types@0.6.4': resolution: {integrity: sha512-zV6kgqtduR4rUAdC/ilS7kmb93XD7bEZoJDlVBZqlOw2uGGGCNBQBuleww2rr0Ulr3L9o2TDjumEt68/l1f9DQ==} - '@firebase/functions@0.13.5': - resolution: {integrity: sha512-bWCx713f4kE/uFV7gdFOLBS7lDoiZj48MRkbAqe35gkXcCeWF4QjRNO07Jhmve7EJIoQOBczL29y2r8VRuN1kw==} + '@firebase/functions@0.13.6': + resolution: {integrity: sha512-9obLnzeQUivK5lmtGFOU2ucQ38BjTp+jpPtbfFp/mDsdVCvEpRqdWNvMMQ6aQwR4vcVc/utsvngm5BRkXbc7ZA==} engines: {node: '>=20.0.0'} peerDependencies: '@firebase/app': 0.x - '@firebase/installations-compat@0.2.22': - resolution: {integrity: sha512-C/zpAuTP5S9OgKSPvXRupw3hoY/JZSlA1wFjD/Sb7LIQE0FNbcMdO8Y4KXVEkjVzma/DDDDIAzxEXqKMAzc88w==} + '@firebase/installations-compat@0.2.23': + resolution: {integrity: sha512-isaXmjb9roM83eVeXAe+ZRNKYNsSo2s0aNM+cy04AAGEyVL/d8Aa11GwEXovRFeYjl9+1yRAOxRDTOukZRwTxA==} peerDependencies: + '@firebase/app': 0.x '@firebase/app-compat': 0.x '@firebase/installations-types@0.5.4': @@ -1979,8 +1992,8 @@ packages: peerDependencies: '@firebase/app-types': 0.x - '@firebase/installations@0.6.22': - resolution: {integrity: sha512-ef6nn3GGQTdReCfotRMG77PJZu8CqEbiK5pEoBnM0gTu/Z9v0i/az2p3HABsa/1beQmmyh1OsOjf7P5+pgwdZw==} + '@firebase/installations@0.6.23': + resolution: {integrity: sha512-MBkbcQfd+3qHjW+slsH4s7jH5qTdGlYpwqmxEZ7QcIpgDxu1SKyU0f+mCZhCt1BCacLNiOWF5L0R06N0LtlfMg==} peerDependencies: '@firebase/app': 0.x @@ -1988,49 +2001,53 @@ packages: resolution: {integrity: sha512-vZKLsqE1ABOy8OjQiE7cUTFn4gvaqlk88yp8N94Pk/sDpq61YqZGqmVFZTvOyflTwuYFcWirBdYGoJgbDaXKYQ==} engines: {node: '>=20.0.0'} - '@firebase/messaging-compat@0.2.27': - resolution: {integrity: sha512-JNOiu1PPgdHzEPEtoFiNxQuu0x9bm4bfETSQCpGfcTlgWkhlSK7uh7nlsjC10TQLUNgYetLmuutaYTh8aeYLVA==} + '@firebase/messaging-compat@0.2.28': + resolution: {integrity: sha512-/AmMqHRnSQhPsdeED3ocs+s30/tpFvZDiiwIYY2uXFRvLujo1fnbPOeCFoe4Y+dRy1LCSjpvJf+dy5ZTsxi1yg==} peerDependencies: + '@firebase/app': 0.x '@firebase/app-compat': 0.x '@firebase/messaging-interop-types@0.2.5': resolution: {integrity: sha512-tUEKnaAP2Y/MNIqgnriPpV6e5l13Vs/+p2yrd6NGlncPJT9O3a8muYZtdnWe+IJ4fgKLHJVC79n/asxk/N5Msw==} - '@firebase/messaging@0.13.0': - resolution: {integrity: sha512-GZoo0uGRvEbszo83xcgbjJp4FpkmBEr4l8Z4hi8gl+P1Spn/MTK3HapanMzSX4yUHuTEiF5hasWRxOaz+o5sxQ==} + '@firebase/messaging@0.13.1': + resolution: {integrity: sha512-kL8fdjbNBI7hprlXJrUjktDWosrpT4JtfwXtVVevImPF/rBRAsC+LS/jIs+kgQVuotnvMhaBCgAFipBoY9YU9g==} peerDependencies: '@firebase/app': 0.x - '@firebase/performance-compat@0.2.25': - resolution: {integrity: sha512-q6NjTXpIPoFuUmCmMN/maCdTgzT6aExs9xZo+PxfVLj6uLVGvpyAD6XWjmcrb7jChsFBYbq7E5dyNDF7Zhy9kA==} + '@firebase/performance-compat@0.2.26': + resolution: {integrity: sha512-jgoocXLN6ao26xWQ8pzosmzQ33uLzGBJQPNK0NTbVy1XvIHr5pfgBf9hWLOxsWe+R7sJq5bjD+8ybXprmt61mA==} peerDependencies: + '@firebase/app': 0.x '@firebase/app-compat': 0.x '@firebase/performance-types@0.2.4': resolution: {integrity: sha512-kJSEk7b0uhpcPRyL4SQ/GPujLqk52XNKcXlnsKDbWGAb9vugcLvOU3u6zfEdwd+d8hWJb5S5ZizV1JFFI0nkKg==} - '@firebase/performance@0.7.12': - resolution: {integrity: sha512-fe7nV8teUU3OBHlMUZ9Lw4gLhCW2k4m5Uc3pfWGV+fl8uwJQBGp9Q3lqsJ+HSrFu3Q2pJyLAgrClPGSKyDeYgQ==} + '@firebase/performance@0.7.13': + resolution: {integrity: sha512-1u6fuXP9cj0s+lkTFAspr/ttfPebPbEdpx+5Wdr4mPZbp8qH2KCMxOddEAR1ZMRa5GI0E7hDYSnolEmbqOFOAg==} peerDependencies: '@firebase/app': 0.x - '@firebase/remote-config-compat@0.2.27': - resolution: {integrity: sha512-FYwYWwSbUdza/pRX4NpSBm/Pimntum3jEIBpnDn5Ey1jHNWgjxrE8Z5SB4mCHd5wGCoYd3koJzxARl/VWIEx0Q==} + '@firebase/remote-config-compat@0.2.28': + resolution: {integrity: sha512-kEO9Gn6fbmVj7eNUtZ6d59mLgUDUD0qo7aCicGOWNfuRWTaUv3CF9DMYychO61zaEQ3cfA+CEny4V1E8A1gRGA==} peerDependencies: + '@firebase/app': 0.x '@firebase/app-compat': 0.x '@firebase/remote-config-types@0.5.1': resolution: {integrity: sha512-cX/1LT6KQwkXzck2eSzeKnuvXZCyr8qaPpDcikoJs7jmI+oBOXixpDLeDtWj1U6GNMkIoXrEDNoyT2Ypcyp5/A==} - '@firebase/remote-config@0.9.0': - resolution: {integrity: sha512-aNn6/eJhsSC+gXSToiXiYPv3ypLP9lFtzl+/q9kSOBPB7D6rae0Rt2uENZZLXGYbEgHYKQblOhijJAXGbbJjtQ==} + '@firebase/remote-config@0.9.1': + resolution: {integrity: sha512-nzQUSJnk1zAZEl2Q5O3I7Z61cYLK5JI4H6wyyOiHkVZ+bmgy1YXNNMptNbVjixMQ/eCzgA6nZRaC+1eBcJGUFA==} peerDependencies: '@firebase/app': 0.x - '@firebase/storage-compat@0.4.3': - resolution: {integrity: sha512-gruVqjtUGX8tEoeNbaWXZm0Zfcfcb7fvmDmBxV8yPAbWvExRnZYLO2+qw9idxNE7BvPXt5csyjSYHy//dAizxw==} + '@firebase/storage-compat@0.4.4': + resolution: {integrity: sha512-qSRgCB9f2R/nCp8t/8OC101cIFBFeUazlRInOMdzbnLzvrQBzEfx19SrR4pvdj/0+M+P/y8AK/a2s+3EB+B1Pw==} engines: {node: '>=20.0.0'} peerDependencies: + '@firebase/app': 0.x '@firebase/app-compat': 0.x '@firebase/storage-types@0.8.4': @@ -2039,14 +2056,14 @@ packages: '@firebase/app-types': 0.x '@firebase/util': 1.x - '@firebase/storage@0.14.3': - resolution: {integrity: sha512-YX4/YL6P6/fufSSeGnVhjWddcIXbFq2cWIhMKFTZo1E/Rtcl2mJj/BYUQTwJfcE1Tl8un1FOya4L05jcSLN/Eg==} + '@firebase/storage@0.14.4': + resolution: {integrity: sha512-jfzEWZb3Fpsq3FwAB2ifoc8mcSh935qXdDou3TpyjDWa45hhNcZUv8/w28/10njByhfK7snbakKN30nwnzQ3/w==} engines: {node: '>=20.0.0'} peerDependencies: '@firebase/app': 0.x - '@firebase/util@1.15.1': - resolution: {integrity: sha512-LUdM4Wg7YM9Pq/49nGYySJA0CSQEKnGffFzWV8+6gXN7mGxn+FL1IqvFbuZUtAQcfZgHYDwCE1wwlK7rB7gl2g==} + '@firebase/util@1.15.2': + resolution: {integrity: sha512-974pWIZVLDMc5GW5YAsj8y0XxULxIy/sPUy7tsxmWbF93KRIyh9xpuHlh0zDL+shUcf5nHDjFOg9YLiQ763eiA==} engines: {node: '>=20.0.0'} '@firebase/webchannel-wrapper@1.0.6': @@ -2083,8 +2100,8 @@ packages: resolution: {integrity: sha512-IJn+8A3QZJfe7FUtWqHVNo3xJs7KFpurCWGWCiCz3oEh+BkRymKZ1QxfAbU2yGMDzTytLGQ2IV6T2r3cuo75/w==} engines: {node: '>=18'} - '@google/genai@2.13.0': - resolution: {integrity: sha512-GM7C8Kaomvjz05x5JEO6+l3d/pciL9LxAG9dUjJLD7nTPZ9X0Cfsf2Z7eET6UjgWyUmxXCHtYnQoQ77F9+ZIOQ==} + '@google/genai@2.15.0': + resolution: {integrity: sha512-Q41TvqwBQ9NcmWdh6qxY5qrpg+0FaVHD7febQoH007pykxzco4ohScBUP4BBBy+Q8j5D8euIBSRIBDfWuNVCKA==} engines: {node: '>=20.0.0'} peerDependencies: '@modelcontextprotocol/sdk': ^1.25.2 @@ -2646,8 +2663,8 @@ packages: resolution: {integrity: sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==} engines: {node: '>= 8'} - '@octokit/auth-app@8.2.0': - resolution: {integrity: sha512-vVjdtQQwomrZ4V46B9LaCsxsySxGoHsyw6IYBov/TqJVROrlYdyNgw5q6tQbB7KZt53v1l1W53RiqTvpzL907g==} + '@octokit/auth-app@8.3.0': + resolution: {integrity: sha512-/UaKmJCsOc5XBZwhnFiGNdLH/FkDF8lYtBn1QlKxtX7IpgaRB/XOXjixFtERAknyUZHxp3oDuoiG0En4VptJSg==} engines: {node: '>= 20'} '@octokit/auth-oauth-app@9.0.4': @@ -2670,6 +2687,10 @@ packages: resolution: {integrity: sha512-DhGl4xMVFGVIyMwswXeyzdL4uXD5OGILGX5N8Y+f6W7LhC1Ze2poSNrkF/fedpVDHEEZ+PHFW0vL14I+mm8K3Q==} engines: {node: '>= 20'} + '@octokit/core@7.0.7': + resolution: {integrity: sha512-DcB0M3KFgr9ECI328lhBMVsyFT2DnmNucSBTqEN3exyNKUzkkpUSCHmTRcunF41Eou2TIQKW4seewri8ON9bSA==} + engines: {node: '>= 20'} + '@octokit/endpoint@11.0.4': resolution: {integrity: sha512-f1cOWoHPmxryJFknxbtDdjODWfV8A9tc8Aae6ermXPNgHFZ/x91AtHIz4gicEjL8hkJiip+u21QHJORfBv/qiA==} engines: {node: '>= 20'} @@ -2681,6 +2702,10 @@ packages: resolution: {integrity: sha512-grAEuupr/C1rALFnXTv6ZQhFuL1D8G5y8CN04RgrO4FIPMrtm+mcZzFG7dcBm+nq+1ppNixu+Jd78aeJOYxlGA==} engines: {node: '>= 20'} + '@octokit/graphql@9.0.4': + resolution: {integrity: sha512-5s15CCiY8XXQ+FG+b1YQcl6Z2FA++nwAz/tg2VUrTmnMncP+2nnGUEYANImdnxsA2Fnq+Mbl7hDjUTw7cFAwcg==} + engines: {node: '>= 20'} + '@octokit/oauth-authorization-url@8.0.0': resolution: {integrity: sha512-7QoLPRh/ssEA/HuHBHdVdSgF8xNLz/Bc5m9fZkArJE5bb6NmVkDm3anKxXPmN1zh6b5WKZPRr3697xKT/yM3qQ==} engines: {node: '>= 20'} @@ -2725,10 +2750,6 @@ packages: peerDependencies: '@octokit/core': '>=6' - '@octokit/request-error@7.1.0': - resolution: {integrity: sha512-KMQIfq5sOPpkQYajXHwnhjCC0slzCNScLHs9JafXc4RAJI+9f+jNDlBNaIMTvazOPLgb4BnlhGJOTbnN0wIjPw==} - engines: {node: '>= 20'} - '@octokit/request-error@7.1.1': resolution: {integrity: sha512-+eaY7G2VVpSf2pc5Gn1+mph837V/d/TYTJAgWL9Tb0ogGYcpN3IlAVFgjL+Vv93F/sevrxkvsYCedtpLdcFLzA==} engines: {node: '>= 20'} @@ -3550,9 +3571,6 @@ packages: '@types/retry@0.12.0': resolution: {integrity: sha512-wWKOClTTiizcZhXnPY4wikVAwmdYHp8q6DmC+EJUzAMsycb7HB32Kh9RN4+0gExjmPmZSAQjgURXIGATPegAvA==} - '@types/semver@7.7.1': - resolution: {integrity: sha512-FmgJfu+MOcQ370SD0ev7EI8TlCAfKYU+B4m5T3yXc1CiRN94g/SZPtsCkk506aUDtlMnFZvasDwHHUcZUEaYuA==} - '@types/semver@7.8.0': resolution: {integrity: sha512-1mAINjtQCXXeLkJ9ehXkwOcBpqtLxiVtKhpUf83DdRNdQKV0iXZpaHYqRr7nj+wvxuJzoAmAwXI+sCNMv1CzLQ==} @@ -4562,8 +4580,8 @@ packages: resolution: {integrity: sha512-cs+LadpH7Kpw0M3k8wurk+sOVVDAENA0iK4OBOrkL94j5lEVYRJ4j3zd2bhY9qgzyrPqthdcYT3axzRN7AliMg==} engines: {node: '>=22'} - conventional-commits-parser@7.1.1: - resolution: {integrity: sha512-B0f42jI++V5Vb7qK+DDw68r0dNxz5hk+RdKUkx2NOi39emc9hsHa3u2M3doF7QQhRFzCrAj7uM90teG+RBTaYQ==} + conventional-commits-parser@7.1.2: + resolution: {integrity: sha512-O+x4N2yH+ijvqWlIyTHsXTAP+algNWgGbjY2duCe8w2vUMvUB95cLRslCPfTMQyLAKlet3bhZTdu6ozn4M+QJQ==} engines: {node: '>=22'} hasBin: true @@ -5232,8 +5250,8 @@ packages: resolution: {integrity: sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==} engines: {node: '>=10'} - firebase@12.16.0: - resolution: {integrity: sha512-CNw6hFBdONkzF8UGLDx/RDRY9gVa5VmJNHd7qi4gdmA3ZuLkuOrhmWefB2l+FN+OxFpN77Itq7aO6zlTi780ag==} + firebase@12.17.1: + resolution: {integrity: sha512-dhp41ye9jMQvhx5FwjMkf/hjDHJApl7gXmvzOZGvP0M7c/GZGUnQ4qvsvlOBkF0Pa7wAwHMdcpL0ON2pXCQ4Sw==} flat-cache@4.0.1: resolution: {integrity: sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw==} @@ -6560,8 +6578,8 @@ packages: tailwindcss: optional: true - nock@14.0.16: - resolution: {integrity: sha512-8r4KEc6nT1D/fdLD/R1BO1CPaVEL8o40u/guFRJlXabN7vr3RmMqyjsY5Krt0nMwhsOAwXQ/mtN5vy5Jh3aErg==} + nock@14.0.17: + resolution: {integrity: sha512-EjRr1weMa4ALQX35AgZTEnP+weJJjlW1KGDiNM2IQC2069YDHas4f4B4UUYR+TTLyKWxJvOz2wObDKQs/LNreA==} engines: {node: '>=18.20.0 <20 || >=20.12.1'} node-addon-api@6.1.0: @@ -7056,8 +7074,9 @@ packages: resolution: {integrity: sha512-K5zQjDllxWkf7Z5xJdV0/B0WTNqx6vxG70zJE4N0kBs4LovmEYWJzQGxC9bS9RAKu3bgM40lrd5zoLJ12MQ5BA==} engines: {node: '>= 0.10'} - re2js@0.4.3: - resolution: {integrity: sha512-EuNmh7jurhHEE8Ge/lBo9JuMLb3qf866Xjjfyovw3wPc7+hlqDkZq4LwhrCQMEI+ARWfrKrHozEndzlpNT0WDg==} + re2js@2.8.6: + resolution: {integrity: sha512-xLgQil4kIUCrAzVk9fRSkxkFNwmygLFjVxXrLc65aE1F0+Zsb8rxumFBy4XKyvgMCTL6kilDq3EZ0piE2dP/Dg==} + engines: {node: '>=18.0.0'} readable-stream@2.3.8: resolution: {integrity: sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==} @@ -7763,8 +7782,8 @@ packages: tslib@2.8.1: resolution: {integrity: sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==} - tsx@4.23.1: - resolution: {integrity: sha512-GQHnkIfxyx1wYCOS/wonik5MVRZU9hi1TEZmzGZSCJB1y9YgoZ8H6itNE/u4suE+yLmOzuE4E5S4TZ/ZX2wcWQ==} + tsx@4.23.7: + resolution: {integrity: sha512-3f/u/+UDCNQ7iwUZW9FCMnNGIHzElGJYh0S/yy8IvWSsn5O7fEO/897FaG7FA2W8yryiRyuwXZ1PYLAKYaqSuQ==} engines: {node: '>=18.0.0'} hasBin: true @@ -8342,29 +8361,29 @@ snapshots: '@jridgewell/gen-mapping': 0.3.13 '@jridgewell/trace-mapping': 0.3.31 - '@angular/animations@22.2.0-next.0(@angular/core@22.2.0-next.0(@angular/compiler@22.2.0-next.0)(rxjs@7.8.2)(zone.js@0.16.2))': + '@angular/animations@22.2.0-next.1(@angular/core@22.2.0-next.1(@angular/compiler@22.2.0-next.1)(rxjs@7.8.2)(zone.js@0.16.2))': dependencies: - '@angular/core': 22.2.0-next.0(@angular/compiler@22.2.0-next.0)(rxjs@7.8.2)(zone.js@0.16.2) + '@angular/core': 22.2.0-next.1(@angular/compiler@22.2.0-next.1)(rxjs@7.8.2)(zone.js@0.16.2) tslib: 2.8.1 - '@angular/cdk@22.2.0-next.0(@angular/common@22.2.0-next.0(@angular/core@22.2.0-next.0(@angular/compiler@22.2.0-next.0)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2))(@angular/core@22.2.0-next.0(@angular/compiler@22.2.0-next.0)(rxjs@7.8.2)(zone.js@0.16.2))(@angular/platform-browser@22.2.0-next.0(@angular/animations@22.2.0-next.0(@angular/core@22.2.0-next.0(@angular/compiler@22.2.0-next.0)(rxjs@7.8.2)(zone.js@0.16.2)))(@angular/common@22.2.0-next.0(@angular/core@22.2.0-next.0(@angular/compiler@22.2.0-next.0)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2))(@angular/core@22.2.0-next.0(@angular/compiler@22.2.0-next.0)(rxjs@7.8.2)(zone.js@0.16.2)))(rxjs@7.8.2)': + '@angular/cdk@22.2.0-next.0(@angular/common@22.2.0-next.1(@angular/core@22.2.0-next.1(@angular/compiler@22.2.0-next.1)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2))(@angular/core@22.2.0-next.1(@angular/compiler@22.2.0-next.1)(rxjs@7.8.2)(zone.js@0.16.2))(@angular/platform-browser@22.2.0-next.1(@angular/animations@22.2.0-next.1(@angular/core@22.2.0-next.1(@angular/compiler@22.2.0-next.1)(rxjs@7.8.2)(zone.js@0.16.2)))(@angular/common@22.2.0-next.1(@angular/core@22.2.0-next.1(@angular/compiler@22.2.0-next.1)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2))(@angular/core@22.2.0-next.1(@angular/compiler@22.2.0-next.1)(rxjs@7.8.2)(zone.js@0.16.2)))(rxjs@7.8.2)': dependencies: - '@angular/common': 22.2.0-next.0(@angular/core@22.2.0-next.0(@angular/compiler@22.2.0-next.0)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2) - '@angular/core': 22.2.0-next.0(@angular/compiler@22.2.0-next.0)(rxjs@7.8.2)(zone.js@0.16.2) - '@angular/platform-browser': 22.2.0-next.0(@angular/animations@22.2.0-next.0(@angular/core@22.2.0-next.0(@angular/compiler@22.2.0-next.0)(rxjs@7.8.2)(zone.js@0.16.2)))(@angular/common@22.2.0-next.0(@angular/core@22.2.0-next.0(@angular/compiler@22.2.0-next.0)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2))(@angular/core@22.2.0-next.0(@angular/compiler@22.2.0-next.0)(rxjs@7.8.2)(zone.js@0.16.2)) + '@angular/common': 22.2.0-next.1(@angular/core@22.2.0-next.1(@angular/compiler@22.2.0-next.1)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2) + '@angular/core': 22.2.0-next.1(@angular/compiler@22.2.0-next.1)(rxjs@7.8.2)(zone.js@0.16.2) + '@angular/platform-browser': 22.2.0-next.1(@angular/animations@22.2.0-next.1(@angular/core@22.2.0-next.1(@angular/compiler@22.2.0-next.1)(rxjs@7.8.2)(zone.js@0.16.2)))(@angular/common@22.2.0-next.1(@angular/core@22.2.0-next.1(@angular/compiler@22.2.0-next.1)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2))(@angular/core@22.2.0-next.1(@angular/compiler@22.2.0-next.1)(rxjs@7.8.2)(zone.js@0.16.2)) parse5: 8.0.1 rxjs: 7.8.2 tslib: 2.8.1 - '@angular/common@22.2.0-next.0(@angular/core@22.2.0-next.0(@angular/compiler@22.2.0-next.0)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2)': + '@angular/common@22.2.0-next.1(@angular/core@22.2.0-next.1(@angular/compiler@22.2.0-next.1)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2)': dependencies: - '@angular/core': 22.2.0-next.0(@angular/compiler@22.2.0-next.0)(rxjs@7.8.2)(zone.js@0.16.2) + '@angular/core': 22.2.0-next.1(@angular/compiler@22.2.0-next.1)(rxjs@7.8.2)(zone.js@0.16.2) rxjs: 7.8.2 tslib: 2.8.1 - '@angular/compiler-cli@22.2.0-next.0(@angular/compiler@22.2.0-next.0)(typescript@6.0.3)': + '@angular/compiler-cli@22.2.0-next.1(@angular/compiler@22.2.0-next.1)(typescript@6.0.3)': dependencies: - '@angular/compiler': 22.2.0-next.0 + '@angular/compiler': 22.2.0-next.1 '@babel/core': 8.0.1 '@jridgewell/sourcemap-codec': 1.5.5 chokidar: 5.0.0 @@ -8376,62 +8395,62 @@ snapshots: optionalDependencies: typescript: 6.0.3 - '@angular/compiler@22.2.0-next.0': + '@angular/compiler@22.2.0-next.1': dependencies: tslib: 2.8.1 - '@angular/core@22.2.0-next.0(@angular/compiler@22.2.0-next.0)(rxjs@7.8.2)(zone.js@0.16.2)': + '@angular/core@22.2.0-next.1(@angular/compiler@22.2.0-next.1)(rxjs@7.8.2)(zone.js@0.16.2)': dependencies: rxjs: 7.8.2 tslib: 2.8.1 optionalDependencies: - '@angular/compiler': 22.2.0-next.0 + '@angular/compiler': 22.2.0-next.1 zone.js: 0.16.2 - '@angular/forms@22.2.0-next.0(@angular/common@22.2.0-next.0(@angular/core@22.2.0-next.0(@angular/compiler@22.2.0-next.0)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2))(@angular/core@22.2.0-next.0(@angular/compiler@22.2.0-next.0)(rxjs@7.8.2)(zone.js@0.16.2))(@angular/platform-browser@22.2.0-next.0(@angular/animations@22.2.0-next.0(@angular/core@22.2.0-next.0(@angular/compiler@22.2.0-next.0)(rxjs@7.8.2)(zone.js@0.16.2)))(@angular/common@22.2.0-next.0(@angular/core@22.2.0-next.0(@angular/compiler@22.2.0-next.0)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2))(@angular/core@22.2.0-next.0(@angular/compiler@22.2.0-next.0)(rxjs@7.8.2)(zone.js@0.16.2)))(rxjs@7.8.2)': + '@angular/forms@22.2.0-next.1(@angular/common@22.2.0-next.1(@angular/core@22.2.0-next.1(@angular/compiler@22.2.0-next.1)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2))(@angular/core@22.2.0-next.1(@angular/compiler@22.2.0-next.1)(rxjs@7.8.2)(zone.js@0.16.2))(@angular/platform-browser@22.2.0-next.1(@angular/animations@22.2.0-next.1(@angular/core@22.2.0-next.1(@angular/compiler@22.2.0-next.1)(rxjs@7.8.2)(zone.js@0.16.2)))(@angular/common@22.2.0-next.1(@angular/core@22.2.0-next.1(@angular/compiler@22.2.0-next.1)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2))(@angular/core@22.2.0-next.1(@angular/compiler@22.2.0-next.1)(rxjs@7.8.2)(zone.js@0.16.2)))(rxjs@7.8.2)': dependencies: - '@angular/common': 22.2.0-next.0(@angular/core@22.2.0-next.0(@angular/compiler@22.2.0-next.0)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2) - '@angular/core': 22.2.0-next.0(@angular/compiler@22.2.0-next.0)(rxjs@7.8.2)(zone.js@0.16.2) - '@angular/platform-browser': 22.2.0-next.0(@angular/animations@22.2.0-next.0(@angular/core@22.2.0-next.0(@angular/compiler@22.2.0-next.0)(rxjs@7.8.2)(zone.js@0.16.2)))(@angular/common@22.2.0-next.0(@angular/core@22.2.0-next.0(@angular/compiler@22.2.0-next.0)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2))(@angular/core@22.2.0-next.0(@angular/compiler@22.2.0-next.0)(rxjs@7.8.2)(zone.js@0.16.2)) + '@angular/common': 22.2.0-next.1(@angular/core@22.2.0-next.1(@angular/compiler@22.2.0-next.1)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2) + '@angular/core': 22.2.0-next.1(@angular/compiler@22.2.0-next.1)(rxjs@7.8.2)(zone.js@0.16.2) + '@angular/platform-browser': 22.2.0-next.1(@angular/animations@22.2.0-next.1(@angular/core@22.2.0-next.1(@angular/compiler@22.2.0-next.1)(rxjs@7.8.2)(zone.js@0.16.2)))(@angular/common@22.2.0-next.1(@angular/core@22.2.0-next.1(@angular/compiler@22.2.0-next.1)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2))(@angular/core@22.2.0-next.1(@angular/compiler@22.2.0-next.1)(rxjs@7.8.2)(zone.js@0.16.2)) '@standard-schema/spec': 1.1.0 rxjs: 7.8.2 tslib: 2.8.1 zod: 4.4.3 - '@angular/localize@22.2.0-next.0(@angular/compiler-cli@22.2.0-next.0(@angular/compiler@22.2.0-next.0)(typescript@6.0.3))(@angular/compiler@22.2.0-next.0)': + '@angular/localize@22.2.0-next.1(@angular/compiler-cli@22.2.0-next.1(@angular/compiler@22.2.0-next.1)(typescript@6.0.3))(@angular/compiler@22.2.0-next.1)': dependencies: - '@angular/compiler': 22.2.0-next.0 - '@angular/compiler-cli': 22.2.0-next.0(@angular/compiler@22.2.0-next.0)(typescript@6.0.3) + '@angular/compiler': 22.2.0-next.1 + '@angular/compiler-cli': 22.2.0-next.1(@angular/compiler@22.2.0-next.1)(typescript@6.0.3) '@babel/core': 8.0.1 tinyglobby: 0.2.17 yargs: 18.1.0 - '@angular/material@22.2.0-next.0(08785ac9bff56240de0a5940322ae01f)': + '@angular/material@22.2.0-next.0(bde3c53bf3d1c9d6d40d1d641ef3b318)': dependencies: - '@angular/cdk': 22.2.0-next.0(@angular/common@22.2.0-next.0(@angular/core@22.2.0-next.0(@angular/compiler@22.2.0-next.0)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2))(@angular/core@22.2.0-next.0(@angular/compiler@22.2.0-next.0)(rxjs@7.8.2)(zone.js@0.16.2))(@angular/platform-browser@22.2.0-next.0(@angular/animations@22.2.0-next.0(@angular/core@22.2.0-next.0(@angular/compiler@22.2.0-next.0)(rxjs@7.8.2)(zone.js@0.16.2)))(@angular/common@22.2.0-next.0(@angular/core@22.2.0-next.0(@angular/compiler@22.2.0-next.0)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2))(@angular/core@22.2.0-next.0(@angular/compiler@22.2.0-next.0)(rxjs@7.8.2)(zone.js@0.16.2)))(rxjs@7.8.2) - '@angular/common': 22.2.0-next.0(@angular/core@22.2.0-next.0(@angular/compiler@22.2.0-next.0)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2) - '@angular/core': 22.2.0-next.0(@angular/compiler@22.2.0-next.0)(rxjs@7.8.2)(zone.js@0.16.2) - '@angular/forms': 22.2.0-next.0(@angular/common@22.2.0-next.0(@angular/core@22.2.0-next.0(@angular/compiler@22.2.0-next.0)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2))(@angular/core@22.2.0-next.0(@angular/compiler@22.2.0-next.0)(rxjs@7.8.2)(zone.js@0.16.2))(@angular/platform-browser@22.2.0-next.0(@angular/animations@22.2.0-next.0(@angular/core@22.2.0-next.0(@angular/compiler@22.2.0-next.0)(rxjs@7.8.2)(zone.js@0.16.2)))(@angular/common@22.2.0-next.0(@angular/core@22.2.0-next.0(@angular/compiler@22.2.0-next.0)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2))(@angular/core@22.2.0-next.0(@angular/compiler@22.2.0-next.0)(rxjs@7.8.2)(zone.js@0.16.2)))(rxjs@7.8.2) - '@angular/platform-browser': 22.2.0-next.0(@angular/animations@22.2.0-next.0(@angular/core@22.2.0-next.0(@angular/compiler@22.2.0-next.0)(rxjs@7.8.2)(zone.js@0.16.2)))(@angular/common@22.2.0-next.0(@angular/core@22.2.0-next.0(@angular/compiler@22.2.0-next.0)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2))(@angular/core@22.2.0-next.0(@angular/compiler@22.2.0-next.0)(rxjs@7.8.2)(zone.js@0.16.2)) + '@angular/cdk': 22.2.0-next.0(@angular/common@22.2.0-next.1(@angular/core@22.2.0-next.1(@angular/compiler@22.2.0-next.1)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2))(@angular/core@22.2.0-next.1(@angular/compiler@22.2.0-next.1)(rxjs@7.8.2)(zone.js@0.16.2))(@angular/platform-browser@22.2.0-next.1(@angular/animations@22.2.0-next.1(@angular/core@22.2.0-next.1(@angular/compiler@22.2.0-next.1)(rxjs@7.8.2)(zone.js@0.16.2)))(@angular/common@22.2.0-next.1(@angular/core@22.2.0-next.1(@angular/compiler@22.2.0-next.1)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2))(@angular/core@22.2.0-next.1(@angular/compiler@22.2.0-next.1)(rxjs@7.8.2)(zone.js@0.16.2)))(rxjs@7.8.2) + '@angular/common': 22.2.0-next.1(@angular/core@22.2.0-next.1(@angular/compiler@22.2.0-next.1)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2) + '@angular/core': 22.2.0-next.1(@angular/compiler@22.2.0-next.1)(rxjs@7.8.2)(zone.js@0.16.2) + '@angular/forms': 22.2.0-next.1(@angular/common@22.2.0-next.1(@angular/core@22.2.0-next.1(@angular/compiler@22.2.0-next.1)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2))(@angular/core@22.2.0-next.1(@angular/compiler@22.2.0-next.1)(rxjs@7.8.2)(zone.js@0.16.2))(@angular/platform-browser@22.2.0-next.1(@angular/animations@22.2.0-next.1(@angular/core@22.2.0-next.1(@angular/compiler@22.2.0-next.1)(rxjs@7.8.2)(zone.js@0.16.2)))(@angular/common@22.2.0-next.1(@angular/core@22.2.0-next.1(@angular/compiler@22.2.0-next.1)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2))(@angular/core@22.2.0-next.1(@angular/compiler@22.2.0-next.1)(rxjs@7.8.2)(zone.js@0.16.2)))(rxjs@7.8.2) + '@angular/platform-browser': 22.2.0-next.1(@angular/animations@22.2.0-next.1(@angular/core@22.2.0-next.1(@angular/compiler@22.2.0-next.1)(rxjs@7.8.2)(zone.js@0.16.2)))(@angular/common@22.2.0-next.1(@angular/core@22.2.0-next.1(@angular/compiler@22.2.0-next.1)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2))(@angular/core@22.2.0-next.1(@angular/compiler@22.2.0-next.1)(rxjs@7.8.2)(zone.js@0.16.2)) rxjs: 7.8.2 tslib: 2.8.1 - '@angular/ng-dev@https://codeload.github.com/angular/dev-infra-private-ng-dev-builds/tar.gz/dcf9b6776377d5d301e054111add3ef80f433b70': + '@angular/ng-dev@https://codeload.github.com/angular/dev-infra-private-ng-dev-builds/tar.gz/c71d9b6af7560faa3d002534d416a8045111adae': dependencies: '@actions/core': 3.0.1 - '@conventional-changelog/git-client': 3.1.0(conventional-commits-filter@6.0.1)(conventional-commits-parser@7.1.1) + '@conventional-changelog/git-client': 3.1.0(conventional-commits-filter@6.0.1)(conventional-commits-parser@7.1.2) '@google-cloud/spanner': 8.0.0(supports-color@11.0.0) - '@google/genai': 2.13.0(bufferutil@4.1.0)(supports-color@11.0.0)(utf-8-validate@6.0.6) + '@google/genai': 2.15.0(bufferutil@4.1.0)(supports-color@11.0.0)(utf-8-validate@6.0.6) '@inquirer/prompts': 8.5.2(@types/node@24.13.3) '@inquirer/type': 4.0.7(@types/node@24.13.3) - '@octokit/auth-app': 8.2.0 - '@octokit/core': 7.0.6 - '@octokit/graphql': 9.0.3 + '@octokit/auth-app': 8.3.0 + '@octokit/core': 7.0.7 + '@octokit/graphql': 9.0.4 '@octokit/graphql-schema': 15.26.1 '@octokit/openapi-types': 28.0.0 - '@octokit/plugin-paginate-rest': 15.0.0(@octokit/core@7.0.6) - '@octokit/plugin-rest-endpoint-methods': 18.0.0(@octokit/core@7.0.6) - '@octokit/request-error': 7.1.0 + '@octokit/plugin-paginate-rest': 15.0.0(@octokit/core@7.0.7) + '@octokit/plugin-rest-endpoint-methods': 18.0.0(@octokit/core@7.0.7) + '@octokit/request-error': 7.1.1 '@octokit/rest': 22.0.1 '@octokit/types': 17.0.0 '@pnpm/dependency-path': 1001.1.10 @@ -8441,7 +8460,7 @@ snapshots: '@types/folder-hash': 4.0.4 '@types/jasmine': 6.0.0 '@types/node': 24.13.3 - '@types/semver': 7.7.1 + '@types/semver': 7.8.0 '@types/which': 3.0.4 '@types/yargs': 17.0.35 '@types/yarnpkg__lockfile': 1.1.9 @@ -8449,11 +8468,11 @@ snapshots: bufferutil: 4.1.0 cli-progress: 3.12.0 conventional-commits-filter: 6.0.1 - conventional-commits-parser: 7.1.1 + conventional-commits-parser: 7.1.2 ejs: 6.0.1 encoding: 0.1.13 fast-glob: 3.3.3 - firebase: 12.16.0 + firebase: 12.17.1 folder-hash: 4.1.3(supports-color@11.0.0) jasmine: 6.3.0 jasmine-core: 6.3.0 @@ -8461,10 +8480,10 @@ snapshots: jsonc-parser: 3.3.1 minimatch: 10.2.6 multimatch: 8.0.0 - nock: 14.0.16 + nock: 14.0.17 semver: 7.8.5 supports-color: 11.0.0 - tsx: 4.23.1 + tsx: 4.23.7 typed-graphqlify: 3.1.6 typescript: 6.0.3 utf-8-validate: 6.0.6 @@ -8476,35 +8495,35 @@ snapshots: - '@modelcontextprotocol/sdk' - '@react-native-async-storage/async-storage' - '@angular/platform-browser@22.2.0-next.0(@angular/animations@22.2.0-next.0(@angular/core@22.2.0-next.0(@angular/compiler@22.2.0-next.0)(rxjs@7.8.2)(zone.js@0.16.2)))(@angular/common@22.2.0-next.0(@angular/core@22.2.0-next.0(@angular/compiler@22.2.0-next.0)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2))(@angular/core@22.2.0-next.0(@angular/compiler@22.2.0-next.0)(rxjs@7.8.2)(zone.js@0.16.2))': + '@angular/platform-browser@22.2.0-next.1(@angular/animations@22.2.0-next.1(@angular/core@22.2.0-next.1(@angular/compiler@22.2.0-next.1)(rxjs@7.8.2)(zone.js@0.16.2)))(@angular/common@22.2.0-next.1(@angular/core@22.2.0-next.1(@angular/compiler@22.2.0-next.1)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2))(@angular/core@22.2.0-next.1(@angular/compiler@22.2.0-next.1)(rxjs@7.8.2)(zone.js@0.16.2))': dependencies: - '@angular/common': 22.2.0-next.0(@angular/core@22.2.0-next.0(@angular/compiler@22.2.0-next.0)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2) - '@angular/core': 22.2.0-next.0(@angular/compiler@22.2.0-next.0)(rxjs@7.8.2)(zone.js@0.16.2) + '@angular/common': 22.2.0-next.1(@angular/core@22.2.0-next.1(@angular/compiler@22.2.0-next.1)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2) + '@angular/core': 22.2.0-next.1(@angular/compiler@22.2.0-next.1)(rxjs@7.8.2)(zone.js@0.16.2) tslib: 2.8.1 optionalDependencies: - '@angular/animations': 22.2.0-next.0(@angular/core@22.2.0-next.0(@angular/compiler@22.2.0-next.0)(rxjs@7.8.2)(zone.js@0.16.2)) + '@angular/animations': 22.2.0-next.1(@angular/core@22.2.0-next.1(@angular/compiler@22.2.0-next.1)(rxjs@7.8.2)(zone.js@0.16.2)) - '@angular/platform-server@22.2.0-next.0(@angular/common@22.2.0-next.0(@angular/core@22.2.0-next.0(@angular/compiler@22.2.0-next.0)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2))(@angular/compiler@22.2.0-next.0)(@angular/core@22.2.0-next.0(@angular/compiler@22.2.0-next.0)(rxjs@7.8.2)(zone.js@0.16.2))(@angular/platform-browser@22.2.0-next.0(@angular/animations@22.2.0-next.0(@angular/core@22.2.0-next.0(@angular/compiler@22.2.0-next.0)(rxjs@7.8.2)(zone.js@0.16.2)))(@angular/common@22.2.0-next.0(@angular/core@22.2.0-next.0(@angular/compiler@22.2.0-next.0)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2))(@angular/core@22.2.0-next.0(@angular/compiler@22.2.0-next.0)(rxjs@7.8.2)(zone.js@0.16.2)))(rxjs@7.8.2)': + '@angular/platform-server@22.2.0-next.1(@angular/common@22.2.0-next.1(@angular/core@22.2.0-next.1(@angular/compiler@22.2.0-next.1)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2))(@angular/compiler@22.2.0-next.1)(@angular/core@22.2.0-next.1(@angular/compiler@22.2.0-next.1)(rxjs@7.8.2)(zone.js@0.16.2))(@angular/platform-browser@22.2.0-next.1(@angular/animations@22.2.0-next.1(@angular/core@22.2.0-next.1(@angular/compiler@22.2.0-next.1)(rxjs@7.8.2)(zone.js@0.16.2)))(@angular/common@22.2.0-next.1(@angular/core@22.2.0-next.1(@angular/compiler@22.2.0-next.1)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2))(@angular/core@22.2.0-next.1(@angular/compiler@22.2.0-next.1)(rxjs@7.8.2)(zone.js@0.16.2)))(rxjs@7.8.2)': dependencies: - '@angular/common': 22.2.0-next.0(@angular/core@22.2.0-next.0(@angular/compiler@22.2.0-next.0)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2) - '@angular/compiler': 22.2.0-next.0 - '@angular/core': 22.2.0-next.0(@angular/compiler@22.2.0-next.0)(rxjs@7.8.2)(zone.js@0.16.2) - '@angular/platform-browser': 22.2.0-next.0(@angular/animations@22.2.0-next.0(@angular/core@22.2.0-next.0(@angular/compiler@22.2.0-next.0)(rxjs@7.8.2)(zone.js@0.16.2)))(@angular/common@22.2.0-next.0(@angular/core@22.2.0-next.0(@angular/compiler@22.2.0-next.0)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2))(@angular/core@22.2.0-next.0(@angular/compiler@22.2.0-next.0)(rxjs@7.8.2)(zone.js@0.16.2)) + '@angular/common': 22.2.0-next.1(@angular/core@22.2.0-next.1(@angular/compiler@22.2.0-next.1)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2) + '@angular/compiler': 22.2.0-next.1 + '@angular/core': 22.2.0-next.1(@angular/compiler@22.2.0-next.1)(rxjs@7.8.2)(zone.js@0.16.2) + '@angular/platform-browser': 22.2.0-next.1(@angular/animations@22.2.0-next.1(@angular/core@22.2.0-next.1(@angular/compiler@22.2.0-next.1)(rxjs@7.8.2)(zone.js@0.16.2)))(@angular/common@22.2.0-next.1(@angular/core@22.2.0-next.1(@angular/compiler@22.2.0-next.1)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2))(@angular/core@22.2.0-next.1(@angular/compiler@22.2.0-next.1)(rxjs@7.8.2)(zone.js@0.16.2)) rxjs: 7.8.2 tslib: 2.8.1 xhr2: 0.2.1 - '@angular/router@22.2.0-next.0(@angular/common@22.2.0-next.0(@angular/core@22.2.0-next.0(@angular/compiler@22.2.0-next.0)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2))(@angular/core@22.2.0-next.0(@angular/compiler@22.2.0-next.0)(rxjs@7.8.2)(zone.js@0.16.2))(@angular/platform-browser@22.2.0-next.0(@angular/animations@22.2.0-next.0(@angular/core@22.2.0-next.0(@angular/compiler@22.2.0-next.0)(rxjs@7.8.2)(zone.js@0.16.2)))(@angular/common@22.2.0-next.0(@angular/core@22.2.0-next.0(@angular/compiler@22.2.0-next.0)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2))(@angular/core@22.2.0-next.0(@angular/compiler@22.2.0-next.0)(rxjs@7.8.2)(zone.js@0.16.2)))(rxjs@7.8.2)': + '@angular/router@22.2.0-next.1(@angular/common@22.2.0-next.1(@angular/core@22.2.0-next.1(@angular/compiler@22.2.0-next.1)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2))(@angular/core@22.2.0-next.1(@angular/compiler@22.2.0-next.1)(rxjs@7.8.2)(zone.js@0.16.2))(@angular/platform-browser@22.2.0-next.1(@angular/animations@22.2.0-next.1(@angular/core@22.2.0-next.1(@angular/compiler@22.2.0-next.1)(rxjs@7.8.2)(zone.js@0.16.2)))(@angular/common@22.2.0-next.1(@angular/core@22.2.0-next.1(@angular/compiler@22.2.0-next.1)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2))(@angular/core@22.2.0-next.1(@angular/compiler@22.2.0-next.1)(rxjs@7.8.2)(zone.js@0.16.2)))(rxjs@7.8.2)': dependencies: - '@angular/common': 22.2.0-next.0(@angular/core@22.2.0-next.0(@angular/compiler@22.2.0-next.0)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2) - '@angular/core': 22.2.0-next.0(@angular/compiler@22.2.0-next.0)(rxjs@7.8.2)(zone.js@0.16.2) - '@angular/platform-browser': 22.2.0-next.0(@angular/animations@22.2.0-next.0(@angular/core@22.2.0-next.0(@angular/compiler@22.2.0-next.0)(rxjs@7.8.2)(zone.js@0.16.2)))(@angular/common@22.2.0-next.0(@angular/core@22.2.0-next.0(@angular/compiler@22.2.0-next.0)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2))(@angular/core@22.2.0-next.0(@angular/compiler@22.2.0-next.0)(rxjs@7.8.2)(zone.js@0.16.2)) + '@angular/common': 22.2.0-next.1(@angular/core@22.2.0-next.1(@angular/compiler@22.2.0-next.1)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2) + '@angular/core': 22.2.0-next.1(@angular/compiler@22.2.0-next.1)(rxjs@7.8.2)(zone.js@0.16.2) + '@angular/platform-browser': 22.2.0-next.1(@angular/animations@22.2.0-next.1(@angular/core@22.2.0-next.1(@angular/compiler@22.2.0-next.1)(rxjs@7.8.2)(zone.js@0.16.2)))(@angular/common@22.2.0-next.1(@angular/core@22.2.0-next.1(@angular/compiler@22.2.0-next.1)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2))(@angular/core@22.2.0-next.1(@angular/compiler@22.2.0-next.1)(rxjs@7.8.2)(zone.js@0.16.2)) rxjs: 7.8.2 tslib: 2.8.1 - '@angular/service-worker@22.2.0-next.0(@angular/core@22.2.0-next.0(@angular/compiler@22.2.0-next.0)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2)': + '@angular/service-worker@22.2.0-next.1(@angular/core@22.2.0-next.1(@angular/compiler@22.2.0-next.1)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2)': dependencies: - '@angular/core': 22.2.0-next.0(@angular/compiler@22.2.0-next.0)(rxjs@7.8.2)(zone.js@0.16.2) + '@angular/core': 22.2.0-next.1(@angular/compiler@22.2.0-next.1)(rxjs@7.8.2)(zone.js@0.16.2) rxjs: 7.8.2 tslib: 2.8.1 @@ -9210,14 +9229,14 @@ snapshots: '@colors/colors@1.5.0': {} - '@conventional-changelog/git-client@3.1.0(conventional-commits-filter@6.0.1)(conventional-commits-parser@7.1.1)': + '@conventional-changelog/git-client@3.1.0(conventional-commits-filter@6.0.1)(conventional-commits-parser@7.1.2)': dependencies: '@simple-libs/child-process-utils': 2.0.0 '@simple-libs/stream-utils': 2.0.0 semver: 7.8.5 optionalDependencies: conventional-commits-filter: 6.0.1 - conventional-commits-parser: 7.1.1 + conventional-commits-parser: 7.1.2 '@csstools/color-helpers@6.1.0': {} @@ -9399,221 +9418,221 @@ snapshots: '@exodus/bytes@1.15.1': {} - '@firebase/ai@2.13.1(@firebase/app-types@0.9.5)(@firebase/app@0.15.1)': + '@firebase/ai@2.14.0(@firebase/app-types@0.9.5)(@firebase/app@0.16.0)': dependencies: - '@firebase/app': 0.15.1 + '@firebase/app': 0.16.0 '@firebase/app-check-interop-types': 0.3.4 '@firebase/app-types': 0.9.5 - '@firebase/component': 0.7.3 + '@firebase/component': 0.7.4 '@firebase/logger': 0.5.1 - '@firebase/util': 1.15.1 + '@firebase/util': 1.15.2 tslib: 2.8.1 - '@firebase/analytics-compat@0.2.28(@firebase/app-compat@0.5.15)(@firebase/app@0.15.1)': + '@firebase/analytics-compat@0.2.29(@firebase/app-compat@0.5.16)(@firebase/app@0.16.0)': dependencies: - '@firebase/analytics': 0.10.22(@firebase/app@0.15.1) + '@firebase/analytics': 0.10.23(@firebase/app@0.16.0) '@firebase/analytics-types': 0.8.4 - '@firebase/app-compat': 0.5.15 - '@firebase/component': 0.7.3 - '@firebase/util': 1.15.1 + '@firebase/app': 0.16.0 + '@firebase/app-compat': 0.5.16 + '@firebase/component': 0.7.4 + '@firebase/util': 1.15.2 tslib: 2.8.1 - transitivePeerDependencies: - - '@firebase/app' '@firebase/analytics-types@0.8.4': {} - '@firebase/analytics@0.10.22(@firebase/app@0.15.1)': + '@firebase/analytics@0.10.23(@firebase/app@0.16.0)': dependencies: - '@firebase/app': 0.15.1 - '@firebase/component': 0.7.3 - '@firebase/installations': 0.6.22(@firebase/app@0.15.1) + '@firebase/app': 0.16.0 + '@firebase/component': 0.7.4 + '@firebase/installations': 0.6.23(@firebase/app@0.16.0) '@firebase/logger': 0.5.1 - '@firebase/util': 1.15.1 + '@firebase/util': 1.15.2 tslib: 2.8.1 - '@firebase/app-check-compat@0.4.5(@firebase/app-compat@0.5.15)(@firebase/app@0.15.1)': + '@firebase/app-check-compat@0.4.6(@firebase/app-compat@0.5.16)(@firebase/app@0.16.0)': dependencies: - '@firebase/app-check': 0.12.0(@firebase/app@0.15.1) + '@firebase/app': 0.16.0 + '@firebase/app-check': 0.13.0(@firebase/app@0.16.0) '@firebase/app-check-types': 0.5.4 - '@firebase/app-compat': 0.5.15 - '@firebase/component': 0.7.3 + '@firebase/app-compat': 0.5.16 + '@firebase/component': 0.7.4 '@firebase/logger': 0.5.1 - '@firebase/util': 1.15.1 + '@firebase/util': 1.15.2 tslib: 2.8.1 - transitivePeerDependencies: - - '@firebase/app' '@firebase/app-check-interop-types@0.3.4': {} '@firebase/app-check-types@0.5.4': {} - '@firebase/app-check@0.12.0(@firebase/app@0.15.1)': + '@firebase/app-check@0.13.0(@firebase/app@0.16.0)': dependencies: - '@firebase/app': 0.15.1 - '@firebase/component': 0.7.3 + '@firebase/app': 0.16.0 + '@firebase/component': 0.7.4 '@firebase/logger': 0.5.1 - '@firebase/util': 1.15.1 + '@firebase/util': 1.15.2 tslib: 2.8.1 - '@firebase/app-compat@0.5.15': + '@firebase/app-compat@0.5.16': dependencies: - '@firebase/app': 0.15.1 - '@firebase/component': 0.7.3 + '@firebase/app': 0.16.0 + '@firebase/component': 0.7.4 '@firebase/logger': 0.5.1 - '@firebase/util': 1.15.1 + '@firebase/util': 1.15.2 tslib: 2.8.1 '@firebase/app-types@0.9.5': dependencies: '@firebase/logger': 0.5.1 - '@firebase/app@0.15.1': + '@firebase/app@0.16.0': dependencies: - '@firebase/component': 0.7.3 + '@firebase/component': 0.7.4 '@firebase/logger': 0.5.1 - '@firebase/util': 1.15.1 + '@firebase/util': 1.15.2 idb: 7.1.1 tslib: 2.8.1 - '@firebase/auth-compat@0.6.8(@firebase/app-compat@0.5.15)(@firebase/app-types@0.9.5)(@firebase/app@0.15.1)': + '@firebase/auth-compat@0.6.9(@firebase/app-compat@0.5.16)(@firebase/app-types@0.9.5)(@firebase/app@0.16.0)': dependencies: - '@firebase/app-compat': 0.5.15 - '@firebase/auth': 1.13.3(@firebase/app@0.15.1) - '@firebase/auth-types': 0.13.1(@firebase/app-types@0.9.5)(@firebase/util@1.15.1) - '@firebase/component': 0.7.3 - '@firebase/util': 1.15.1 + '@firebase/app': 0.16.0 + '@firebase/app-compat': 0.5.16 + '@firebase/auth': 1.13.4(@firebase/app@0.16.0) + '@firebase/auth-types': 0.13.1(@firebase/app-types@0.9.5)(@firebase/util@1.15.2) + '@firebase/component': 0.7.4 + '@firebase/util': 1.15.2 tslib: 2.8.1 transitivePeerDependencies: - - '@firebase/app' - '@firebase/app-types' - '@react-native-async-storage/async-storage' '@firebase/auth-interop-types@0.2.5': {} - '@firebase/auth-types@0.13.1(@firebase/app-types@0.9.5)(@firebase/util@1.15.1)': + '@firebase/auth-types@0.13.1(@firebase/app-types@0.9.5)(@firebase/util@1.15.2)': dependencies: '@firebase/app-types': 0.9.5 - '@firebase/util': 1.15.1 + '@firebase/util': 1.15.2 - '@firebase/auth@1.13.3(@firebase/app@0.15.1)': + '@firebase/auth@1.13.4(@firebase/app@0.16.0)': dependencies: - '@firebase/app': 0.15.1 - '@firebase/component': 0.7.3 + '@firebase/app': 0.16.0 + '@firebase/component': 0.7.4 '@firebase/logger': 0.5.1 - '@firebase/util': 1.15.1 + '@firebase/util': 1.15.2 tslib: 2.8.1 - '@firebase/component@0.7.3': + '@firebase/component@0.7.4': dependencies: - '@firebase/util': 1.15.1 + '@firebase/util': 1.15.2 tslib: 2.8.1 - '@firebase/data-connect@0.7.1(@firebase/app@0.15.1)': + '@firebase/data-connect@0.7.3(@firebase/app@0.16.0)': dependencies: - '@firebase/app': 0.15.1 + '@firebase/app': 0.16.0 '@firebase/auth-interop-types': 0.2.5 - '@firebase/component': 0.7.3 + '@firebase/component': 0.7.4 '@firebase/logger': 0.5.1 - '@firebase/util': 1.15.1 + '@firebase/util': 1.15.2 tslib: 2.8.1 - '@firebase/database-compat@2.1.4': + '@firebase/database-compat@2.1.6(@firebase/app-compat@0.5.16)(@firebase/app@0.16.0)': dependencies: - '@firebase/component': 0.7.3 - '@firebase/database': 1.1.3 - '@firebase/database-types': 1.0.20 + '@firebase/component': 0.7.4 + '@firebase/database': 1.1.4 + '@firebase/database-types': 1.0.21 '@firebase/logger': 0.5.1 - '@firebase/util': 1.15.1 + '@firebase/util': 1.15.2 tslib: 2.8.1 + optionalDependencies: + '@firebase/app': 0.16.0 + '@firebase/app-compat': 0.5.16 - '@firebase/database-types@1.0.20': + '@firebase/database-types@1.0.21': dependencies: '@firebase/app-types': 0.9.5 - '@firebase/util': 1.15.1 + '@firebase/util': 1.15.2 - '@firebase/database@1.1.3': + '@firebase/database@1.1.4': dependencies: '@firebase/app-check-interop-types': 0.3.4 '@firebase/auth-interop-types': 0.2.5 - '@firebase/component': 0.7.3 + '@firebase/component': 0.7.4 '@firebase/logger': 0.5.1 - '@firebase/util': 1.15.1 + '@firebase/util': 1.15.2 faye-websocket: 0.11.4 tslib: 2.8.1 - '@firebase/firestore-compat@0.4.11(@firebase/app-compat@0.5.15)(@firebase/app-types@0.9.5)(@firebase/app@0.15.1)': + '@firebase/firestore-compat@0.4.12(@firebase/app-compat@0.5.16)(@firebase/app-types@0.9.5)(@firebase/app@0.16.0)': dependencies: - '@firebase/app-compat': 0.5.15 - '@firebase/component': 0.7.3 - '@firebase/firestore': 4.16.0(@firebase/app@0.15.1) - '@firebase/firestore-types': 3.0.4(@firebase/app-types@0.9.5)(@firebase/util@1.15.1) - '@firebase/util': 1.15.1 + '@firebase/app': 0.16.0 + '@firebase/app-compat': 0.5.16 + '@firebase/component': 0.7.4 + '@firebase/firestore': 4.17.0(@firebase/app@0.16.0) + '@firebase/firestore-types': 3.0.4(@firebase/app-types@0.9.5)(@firebase/util@1.15.2) + '@firebase/util': 1.15.2 tslib: 2.8.1 transitivePeerDependencies: - - '@firebase/app' - '@firebase/app-types' - '@firebase/firestore-types@3.0.4(@firebase/app-types@0.9.5)(@firebase/util@1.15.1)': + '@firebase/firestore-types@3.0.4(@firebase/app-types@0.9.5)(@firebase/util@1.15.2)': dependencies: '@firebase/app-types': 0.9.5 - '@firebase/util': 1.15.1 + '@firebase/util': 1.15.2 - '@firebase/firestore@4.16.0(@firebase/app@0.15.1)': + '@firebase/firestore@4.17.0(@firebase/app@0.16.0)': dependencies: - '@firebase/app': 0.15.1 - '@firebase/component': 0.7.3 + '@firebase/app': 0.16.0 + '@firebase/component': 0.7.4 '@firebase/logger': 0.5.1 - '@firebase/util': 1.15.1 + '@firebase/util': 1.15.2 '@firebase/webchannel-wrapper': 1.0.6 '@grpc/grpc-js': 1.9.16 '@grpc/proto-loader': 0.7.15 - re2js: 0.4.3 + re2js: 2.8.6 tslib: 2.8.1 - '@firebase/functions-compat@0.4.5(@firebase/app-compat@0.5.15)(@firebase/app@0.15.1)': + '@firebase/functions-compat@0.4.6(@firebase/app-compat@0.5.16)(@firebase/app@0.16.0)': dependencies: - '@firebase/app-compat': 0.5.15 - '@firebase/component': 0.7.3 - '@firebase/functions': 0.13.5(@firebase/app@0.15.1) + '@firebase/app': 0.16.0 + '@firebase/app-compat': 0.5.16 + '@firebase/component': 0.7.4 + '@firebase/functions': 0.13.6(@firebase/app@0.16.0) '@firebase/functions-types': 0.6.4 - '@firebase/util': 1.15.1 + '@firebase/util': 1.15.2 tslib: 2.8.1 - transitivePeerDependencies: - - '@firebase/app' '@firebase/functions-types@0.6.4': {} - '@firebase/functions@0.13.5(@firebase/app@0.15.1)': + '@firebase/functions@0.13.6(@firebase/app@0.16.0)': dependencies: - '@firebase/app': 0.15.1 + '@firebase/app': 0.16.0 '@firebase/app-check-interop-types': 0.3.4 '@firebase/auth-interop-types': 0.2.5 - '@firebase/component': 0.7.3 + '@firebase/component': 0.7.4 '@firebase/messaging-interop-types': 0.2.5 - '@firebase/util': 1.15.1 + '@firebase/util': 1.15.2 tslib: 2.8.1 - '@firebase/installations-compat@0.2.22(@firebase/app-compat@0.5.15)(@firebase/app-types@0.9.5)(@firebase/app@0.15.1)': + '@firebase/installations-compat@0.2.23(@firebase/app-compat@0.5.16)(@firebase/app-types@0.9.5)(@firebase/app@0.16.0)': dependencies: - '@firebase/app-compat': 0.5.15 - '@firebase/component': 0.7.3 - '@firebase/installations': 0.6.22(@firebase/app@0.15.1) + '@firebase/app': 0.16.0 + '@firebase/app-compat': 0.5.16 + '@firebase/component': 0.7.4 + '@firebase/installations': 0.6.23(@firebase/app@0.16.0) '@firebase/installations-types': 0.5.4(@firebase/app-types@0.9.5) - '@firebase/util': 1.15.1 + '@firebase/util': 1.15.2 tslib: 2.8.1 transitivePeerDependencies: - - '@firebase/app' - '@firebase/app-types' '@firebase/installations-types@0.5.4(@firebase/app-types@0.9.5)': dependencies: '@firebase/app-types': 0.9.5 - '@firebase/installations@0.6.22(@firebase/app@0.15.1)': + '@firebase/installations@0.6.23(@firebase/app@0.16.0)': dependencies: - '@firebase/app': 0.15.1 - '@firebase/component': 0.7.3 - '@firebase/util': 1.15.1 + '@firebase/app': 0.16.0 + '@firebase/component': 0.7.4 + '@firebase/util': 1.15.2 idb: 7.1.1 tslib: 2.8.1 @@ -9621,100 +9640,97 @@ snapshots: dependencies: tslib: 2.8.1 - '@firebase/messaging-compat@0.2.27(@firebase/app-compat@0.5.15)(@firebase/app@0.15.1)': + '@firebase/messaging-compat@0.2.28(@firebase/app-compat@0.5.16)(@firebase/app@0.16.0)': dependencies: - '@firebase/app-compat': 0.5.15 - '@firebase/component': 0.7.3 - '@firebase/messaging': 0.13.0(@firebase/app@0.15.1) - '@firebase/util': 1.15.1 + '@firebase/app': 0.16.0 + '@firebase/app-compat': 0.5.16 + '@firebase/component': 0.7.4 + '@firebase/messaging': 0.13.1(@firebase/app@0.16.0) + '@firebase/util': 1.15.2 tslib: 2.8.1 - transitivePeerDependencies: - - '@firebase/app' '@firebase/messaging-interop-types@0.2.5': {} - '@firebase/messaging@0.13.0(@firebase/app@0.15.1)': + '@firebase/messaging@0.13.1(@firebase/app@0.16.0)': dependencies: - '@firebase/app': 0.15.1 - '@firebase/component': 0.7.3 - '@firebase/installations': 0.6.22(@firebase/app@0.15.1) + '@firebase/app': 0.16.0 + '@firebase/component': 0.7.4 + '@firebase/installations': 0.6.23(@firebase/app@0.16.0) '@firebase/messaging-interop-types': 0.2.5 - '@firebase/util': 1.15.1 + '@firebase/util': 1.15.2 idb: 7.1.1 tslib: 2.8.1 - '@firebase/performance-compat@0.2.25(@firebase/app-compat@0.5.15)(@firebase/app@0.15.1)': + '@firebase/performance-compat@0.2.26(@firebase/app-compat@0.5.16)(@firebase/app@0.16.0)': dependencies: - '@firebase/app-compat': 0.5.15 - '@firebase/component': 0.7.3 + '@firebase/app': 0.16.0 + '@firebase/app-compat': 0.5.16 + '@firebase/component': 0.7.4 '@firebase/logger': 0.5.1 - '@firebase/performance': 0.7.12(@firebase/app@0.15.1) + '@firebase/performance': 0.7.13(@firebase/app@0.16.0) '@firebase/performance-types': 0.2.4 - '@firebase/util': 1.15.1 + '@firebase/util': 1.15.2 tslib: 2.8.1 - transitivePeerDependencies: - - '@firebase/app' '@firebase/performance-types@0.2.4': {} - '@firebase/performance@0.7.12(@firebase/app@0.15.1)': + '@firebase/performance@0.7.13(@firebase/app@0.16.0)': dependencies: - '@firebase/app': 0.15.1 - '@firebase/component': 0.7.3 - '@firebase/installations': 0.6.22(@firebase/app@0.15.1) + '@firebase/app': 0.16.0 + '@firebase/component': 0.7.4 + '@firebase/installations': 0.6.23(@firebase/app@0.16.0) '@firebase/logger': 0.5.1 - '@firebase/util': 1.15.1 + '@firebase/util': 1.15.2 tslib: 2.8.1 web-vitals: 4.2.4 - '@firebase/remote-config-compat@0.2.27(@firebase/app-compat@0.5.15)(@firebase/app@0.15.1)': + '@firebase/remote-config-compat@0.2.28(@firebase/app-compat@0.5.16)(@firebase/app@0.16.0)': dependencies: - '@firebase/app-compat': 0.5.15 - '@firebase/component': 0.7.3 + '@firebase/app': 0.16.0 + '@firebase/app-compat': 0.5.16 + '@firebase/component': 0.7.4 '@firebase/logger': 0.5.1 - '@firebase/remote-config': 0.9.0(@firebase/app@0.15.1) + '@firebase/remote-config': 0.9.1(@firebase/app@0.16.0) '@firebase/remote-config-types': 0.5.1 - '@firebase/util': 1.15.1 + '@firebase/util': 1.15.2 tslib: 2.8.1 - transitivePeerDependencies: - - '@firebase/app' '@firebase/remote-config-types@0.5.1': {} - '@firebase/remote-config@0.9.0(@firebase/app@0.15.1)': + '@firebase/remote-config@0.9.1(@firebase/app@0.16.0)': dependencies: - '@firebase/app': 0.15.1 - '@firebase/component': 0.7.3 - '@firebase/installations': 0.6.22(@firebase/app@0.15.1) + '@firebase/app': 0.16.0 + '@firebase/component': 0.7.4 + '@firebase/installations': 0.6.23(@firebase/app@0.16.0) '@firebase/logger': 0.5.1 - '@firebase/util': 1.15.1 + '@firebase/util': 1.15.2 tslib: 2.8.1 - '@firebase/storage-compat@0.4.3(@firebase/app-compat@0.5.15)(@firebase/app-types@0.9.5)(@firebase/app@0.15.1)': + '@firebase/storage-compat@0.4.4(@firebase/app-compat@0.5.16)(@firebase/app-types@0.9.5)(@firebase/app@0.16.0)': dependencies: - '@firebase/app-compat': 0.5.15 - '@firebase/component': 0.7.3 - '@firebase/storage': 0.14.3(@firebase/app@0.15.1) - '@firebase/storage-types': 0.8.4(@firebase/app-types@0.9.5)(@firebase/util@1.15.1) - '@firebase/util': 1.15.1 + '@firebase/app': 0.16.0 + '@firebase/app-compat': 0.5.16 + '@firebase/component': 0.7.4 + '@firebase/storage': 0.14.4(@firebase/app@0.16.0) + '@firebase/storage-types': 0.8.4(@firebase/app-types@0.9.5)(@firebase/util@1.15.2) + '@firebase/util': 1.15.2 tslib: 2.8.1 transitivePeerDependencies: - - '@firebase/app' - '@firebase/app-types' - '@firebase/storage-types@0.8.4(@firebase/app-types@0.9.5)(@firebase/util@1.15.1)': + '@firebase/storage-types@0.8.4(@firebase/app-types@0.9.5)(@firebase/util@1.15.2)': dependencies: '@firebase/app-types': 0.9.5 - '@firebase/util': 1.15.1 + '@firebase/util': 1.15.2 - '@firebase/storage@0.14.3(@firebase/app@0.15.1)': + '@firebase/storage@0.14.4(@firebase/app@0.16.0)': dependencies: - '@firebase/app': 0.15.1 - '@firebase/component': 0.7.3 - '@firebase/util': 1.15.1 + '@firebase/app': 0.16.0 + '@firebase/component': 0.7.4 + '@firebase/util': 1.15.2 tslib: 2.8.1 - '@firebase/util@1.15.1': + '@firebase/util@1.15.2': dependencies: tslib: 2.8.1 @@ -9781,7 +9797,7 @@ snapshots: transitivePeerDependencies: - supports-color - '@google/genai@2.13.0(bufferutil@4.1.0)(supports-color@11.0.0)(utf-8-validate@6.0.6)': + '@google/genai@2.15.0(bufferutil@4.1.0)(supports-color@11.0.0)(utf-8-validate@6.0.6)': dependencies: google-auth-library: 10.9.1(supports-color@11.0.0) p-retry: 4.6.2 @@ -10394,13 +10410,13 @@ snapshots: '@nodelib/fs.scandir': 2.1.5 fastq: 1.20.1 - '@octokit/auth-app@8.2.0': + '@octokit/auth-app@8.3.0': dependencies: '@octokit/auth-oauth-app': 9.0.4 '@octokit/auth-oauth-user': 6.0.3 '@octokit/request': 10.0.13 '@octokit/request-error': 7.1.1 - '@octokit/types': 16.0.0 + '@octokit/types': 17.0.0 toad-cache: 3.7.4 universal-github-app-jwt: 2.2.2 universal-user-agent: 7.0.3 @@ -10440,6 +10456,16 @@ snapshots: before-after-hook: 4.0.0 universal-user-agent: 7.0.3 + '@octokit/core@7.0.7': + dependencies: + '@octokit/auth-token': 6.0.0 + '@octokit/graphql': 9.0.4 + '@octokit/request': 10.0.13 + '@octokit/request-error': 7.1.1 + '@octokit/types': 17.0.0 + before-after-hook: 4.0.0 + universal-user-agent: 7.0.3 + '@octokit/endpoint@11.0.4': dependencies: '@octokit/types': 17.0.0 @@ -10456,6 +10482,12 @@ snapshots: '@octokit/types': 16.0.0 universal-user-agent: 7.0.3 + '@octokit/graphql@9.0.4': + dependencies: + '@octokit/request': 10.0.13 + '@octokit/types': 17.0.0 + universal-user-agent: 7.0.3 + '@octokit/oauth-authorization-url@8.0.0': {} '@octokit/oauth-methods@6.0.3': @@ -10474,9 +10506,9 @@ snapshots: '@octokit/core': 7.0.6 '@octokit/types': 16.0.0 - '@octokit/plugin-paginate-rest@15.0.0(@octokit/core@7.0.6)': + '@octokit/plugin-paginate-rest@15.0.0(@octokit/core@7.0.7)': dependencies: - '@octokit/core': 7.0.6 + '@octokit/core': 7.0.7 '@octokit/types': 17.0.0 '@octokit/plugin-request-log@6.0.0(@octokit/core@7.0.6)': @@ -10488,15 +10520,11 @@ snapshots: '@octokit/core': 7.0.6 '@octokit/types': 16.0.0 - '@octokit/plugin-rest-endpoint-methods@18.0.0(@octokit/core@7.0.6)': + '@octokit/plugin-rest-endpoint-methods@18.0.0(@octokit/core@7.0.7)': dependencies: - '@octokit/core': 7.0.6 + '@octokit/core': 7.0.7 '@octokit/types': 17.0.0 - '@octokit/request-error@7.1.0': - dependencies: - '@octokit/types': 16.0.0 - '@octokit/request-error@7.1.1': dependencies: '@octokit/types': 17.0.0 @@ -11186,8 +11214,6 @@ snapshots: '@types/retry@0.12.0': {} - '@types/semver@7.7.1': {} - '@types/semver@7.8.0': {} '@types/send@1.2.1': @@ -11481,9 +11507,9 @@ snapshots: lodash: 4.18.1 minimatch: 10.2.5 - '@vitejs/plugin-basic-ssl@2.3.0(vite@8.2.0(@types/node@22.20.1)(esbuild@0.28.1)(jiti@2.7.0)(less@4.8.1(supports-color@11.0.0))(sass@1.102.0)(terser@5.49.1)(tsx@4.23.1)(yaml@2.9.0))': + '@vitejs/plugin-basic-ssl@2.3.0(vite@8.2.0(@types/node@22.20.1)(esbuild@0.28.1)(jiti@2.7.0)(less@4.8.1(supports-color@11.0.0))(sass@1.102.0)(terser@5.49.1)(tsx@4.23.7)(yaml@2.9.0))': dependencies: - vite: 8.2.0(@types/node@22.20.1)(esbuild@0.28.1)(jiti@2.7.0)(less@4.8.1(supports-color@11.0.0))(sass@1.102.0)(terser@5.49.1)(tsx@4.23.1)(yaml@2.9.0) + vite: 8.2.0(@types/node@22.20.1)(esbuild@0.28.1)(jiti@2.7.0)(less@4.8.1(supports-color@11.0.0))(sass@1.102.0)(terser@5.49.1)(tsx@4.23.7)(yaml@2.9.0) '@vitest/coverage-v8@4.1.10(vitest@4.1.10)': dependencies: @@ -11497,7 +11523,7 @@ snapshots: obug: 2.1.4 std-env: 4.2.0 tinyrainbow: 3.1.1 - vitest: 4.1.10(@opentelemetry/api@1.9.1)(@types/node@22.20.1)(@vitest/coverage-v8@4.1.10)(esbuild@0.28.1)(jiti@2.7.0)(jsdom@30.0.1)(less@4.8.1(supports-color@11.0.0))(sass@1.102.0)(terser@5.49.1)(tsx@4.23.1)(yaml@2.9.0) + vitest: 4.1.10(@opentelemetry/api@1.9.1)(@types/node@22.20.1)(@vitest/coverage-v8@4.1.10)(esbuild@0.28.1)(jiti@2.7.0)(jsdom@30.0.1)(less@4.8.1(supports-color@11.0.0))(sass@1.102.0)(terser@5.49.1)(tsx@4.23.7)(yaml@2.9.0) '@vitest/expect@4.1.10': dependencies: @@ -11508,13 +11534,13 @@ snapshots: chai: 6.2.2 tinyrainbow: 3.1.1 - '@vitest/mocker@4.1.10(vite@8.2.0(@types/node@22.20.1)(esbuild@0.28.1)(jiti@2.7.0)(less@4.8.1(supports-color@11.0.0))(sass@1.102.0)(terser@5.49.1)(tsx@4.23.1)(yaml@2.9.0))': + '@vitest/mocker@4.1.10(vite@8.2.0(@types/node@22.20.1)(esbuild@0.28.1)(jiti@2.7.0)(less@4.8.1(supports-color@11.0.0))(sass@1.102.0)(terser@5.49.1)(tsx@4.23.7)(yaml@2.9.0))': dependencies: '@vitest/spy': 4.1.10 estree-walker: 3.0.3 magic-string: 0.30.21 optionalDependencies: - vite: 8.2.0(@types/node@22.20.1)(esbuild@0.28.1)(jiti@2.7.0)(less@4.8.1(supports-color@11.0.0))(sass@1.102.0)(terser@5.49.1)(tsx@4.23.1)(yaml@2.9.0) + vite: 8.2.0(@types/node@22.20.1)(esbuild@0.28.1)(jiti@2.7.0)(less@4.8.1(supports-color@11.0.0))(sass@1.102.0)(terser@5.49.1)(tsx@4.23.7)(yaml@2.9.0) '@vitest/pretty-format@4.1.10': dependencies: @@ -12346,7 +12372,7 @@ snapshots: conventional-commits-filter@6.0.1: {} - conventional-commits-parser@7.1.1: + conventional-commits-parser@7.1.2: dependencies: '@simple-libs/stream-utils': 2.0.0 argue-cli: 3.1.0 @@ -13188,36 +13214,36 @@ snapshots: locate-path: 6.0.0 path-exists: 4.0.0 - firebase@12.16.0: + firebase@12.17.1: dependencies: - '@firebase/ai': 2.13.1(@firebase/app-types@0.9.5)(@firebase/app@0.15.1) - '@firebase/analytics': 0.10.22(@firebase/app@0.15.1) - '@firebase/analytics-compat': 0.2.28(@firebase/app-compat@0.5.15)(@firebase/app@0.15.1) - '@firebase/app': 0.15.1 - '@firebase/app-check': 0.12.0(@firebase/app@0.15.1) - '@firebase/app-check-compat': 0.4.5(@firebase/app-compat@0.5.15)(@firebase/app@0.15.1) - '@firebase/app-compat': 0.5.15 + '@firebase/ai': 2.14.0(@firebase/app-types@0.9.5)(@firebase/app@0.16.0) + '@firebase/analytics': 0.10.23(@firebase/app@0.16.0) + '@firebase/analytics-compat': 0.2.29(@firebase/app-compat@0.5.16)(@firebase/app@0.16.0) + '@firebase/app': 0.16.0 + '@firebase/app-check': 0.13.0(@firebase/app@0.16.0) + '@firebase/app-check-compat': 0.4.6(@firebase/app-compat@0.5.16)(@firebase/app@0.16.0) + '@firebase/app-compat': 0.5.16 '@firebase/app-types': 0.9.5 - '@firebase/auth': 1.13.3(@firebase/app@0.15.1) - '@firebase/auth-compat': 0.6.8(@firebase/app-compat@0.5.15)(@firebase/app-types@0.9.5)(@firebase/app@0.15.1) - '@firebase/data-connect': 0.7.1(@firebase/app@0.15.1) - '@firebase/database': 1.1.3 - '@firebase/database-compat': 2.1.4 - '@firebase/firestore': 4.16.0(@firebase/app@0.15.1) - '@firebase/firestore-compat': 0.4.11(@firebase/app-compat@0.5.15)(@firebase/app-types@0.9.5)(@firebase/app@0.15.1) - '@firebase/functions': 0.13.5(@firebase/app@0.15.1) - '@firebase/functions-compat': 0.4.5(@firebase/app-compat@0.5.15)(@firebase/app@0.15.1) - '@firebase/installations': 0.6.22(@firebase/app@0.15.1) - '@firebase/installations-compat': 0.2.22(@firebase/app-compat@0.5.15)(@firebase/app-types@0.9.5)(@firebase/app@0.15.1) - '@firebase/messaging': 0.13.0(@firebase/app@0.15.1) - '@firebase/messaging-compat': 0.2.27(@firebase/app-compat@0.5.15)(@firebase/app@0.15.1) - '@firebase/performance': 0.7.12(@firebase/app@0.15.1) - '@firebase/performance-compat': 0.2.25(@firebase/app-compat@0.5.15)(@firebase/app@0.15.1) - '@firebase/remote-config': 0.9.0(@firebase/app@0.15.1) - '@firebase/remote-config-compat': 0.2.27(@firebase/app-compat@0.5.15)(@firebase/app@0.15.1) - '@firebase/storage': 0.14.3(@firebase/app@0.15.1) - '@firebase/storage-compat': 0.4.3(@firebase/app-compat@0.5.15)(@firebase/app-types@0.9.5)(@firebase/app@0.15.1) - '@firebase/util': 1.15.1 + '@firebase/auth': 1.13.4(@firebase/app@0.16.0) + '@firebase/auth-compat': 0.6.9(@firebase/app-compat@0.5.16)(@firebase/app-types@0.9.5)(@firebase/app@0.16.0) + '@firebase/data-connect': 0.7.3(@firebase/app@0.16.0) + '@firebase/database': 1.1.4 + '@firebase/database-compat': 2.1.6(@firebase/app-compat@0.5.16)(@firebase/app@0.16.0) + '@firebase/firestore': 4.17.0(@firebase/app@0.16.0) + '@firebase/firestore-compat': 0.4.12(@firebase/app-compat@0.5.16)(@firebase/app-types@0.9.5)(@firebase/app@0.16.0) + '@firebase/functions': 0.13.6(@firebase/app@0.16.0) + '@firebase/functions-compat': 0.4.6(@firebase/app-compat@0.5.16)(@firebase/app@0.16.0) + '@firebase/installations': 0.6.23(@firebase/app@0.16.0) + '@firebase/installations-compat': 0.2.23(@firebase/app-compat@0.5.16)(@firebase/app-types@0.9.5)(@firebase/app@0.16.0) + '@firebase/messaging': 0.13.1(@firebase/app@0.16.0) + '@firebase/messaging-compat': 0.2.28(@firebase/app-compat@0.5.16)(@firebase/app@0.16.0) + '@firebase/performance': 0.7.13(@firebase/app@0.16.0) + '@firebase/performance-compat': 0.2.26(@firebase/app-compat@0.5.16)(@firebase/app@0.16.0) + '@firebase/remote-config': 0.9.1(@firebase/app@0.16.0) + '@firebase/remote-config-compat': 0.2.28(@firebase/app-compat@0.5.16)(@firebase/app@0.16.0) + '@firebase/storage': 0.14.4(@firebase/app@0.16.0) + '@firebase/storage-compat': 0.4.4(@firebase/app-compat@0.5.16)(@firebase/app-types@0.9.5)(@firebase/app@0.16.0) + '@firebase/util': 1.15.2 transitivePeerDependencies: - '@react-native-async-storage/async-storage' @@ -14600,10 +14626,10 @@ snapshots: neo-async@2.6.2: {} - ng-packagr@22.2.0-next.2(@angular/compiler-cli@22.2.0-next.0(@angular/compiler@22.2.0-next.0)(typescript@6.0.3))(supports-color@11.0.0)(tslib@2.8.1)(typescript@6.0.3): + ng-packagr@22.2.0-next.2(@angular/compiler-cli@22.2.0-next.1(@angular/compiler@22.2.0-next.1)(typescript@6.0.3))(supports-color@11.0.0)(tslib@2.8.1)(typescript@6.0.3): dependencies: '@ampproject/remapping': 2.3.0 - '@angular/compiler-cli': 22.2.0-next.0(@angular/compiler@22.2.0-next.0)(typescript@6.0.3) + '@angular/compiler-cli': 22.2.0-next.1(@angular/compiler@22.2.0-next.1)(typescript@6.0.3) ajv: 8.20.0 browserslist: 4.28.7 chokidar: 5.0.0 @@ -14631,7 +14657,7 @@ snapshots: - supports-color - vue-tsc - nock@14.0.16: + nock@14.0.17: dependencies: '@mswjs/interceptors': 0.41.9 json-stringify-safe: 5.0.1 @@ -15182,7 +15208,7 @@ snapshots: iconv-lite: 0.7.3 unpipe: 1.0.0 - re2js@0.4.3: {} + re2js@2.8.6: {} readable-stream@2.3.8: dependencies: @@ -16053,7 +16079,7 @@ snapshots: tslib@2.8.1: {} - tsx@4.23.1: + tsx@4.23.7: dependencies: esbuild: 0.28.1 optionalDependencies: @@ -16300,7 +16326,7 @@ snapshots: core-util-is: 1.0.2 extsprintf: 1.3.0 - vite@8.2.0(@types/node@22.20.1)(esbuild@0.28.1)(jiti@2.7.0)(less@4.8.1(supports-color@11.0.0))(sass@1.102.0)(terser@5.49.1)(tsx@4.23.1)(yaml@2.9.0): + vite@8.2.0(@types/node@22.20.1)(esbuild@0.28.1)(jiti@2.7.0)(less@4.8.1(supports-color@11.0.0))(sass@1.102.0)(terser@5.49.1)(tsx@4.23.7)(yaml@2.9.0): dependencies: lightningcss: 1.33.0 picomatch: 4.0.5 @@ -16315,13 +16341,13 @@ snapshots: less: 4.8.1(supports-color@11.0.0) sass: 1.102.0 terser: 5.49.1 - tsx: 4.23.1 + tsx: 4.23.7 yaml: 2.9.0 - vitest@4.1.10(@opentelemetry/api@1.9.1)(@types/node@22.20.1)(@vitest/coverage-v8@4.1.10)(esbuild@0.28.1)(jiti@2.7.0)(jsdom@30.0.1)(less@4.8.1(supports-color@11.0.0))(sass@1.102.0)(terser@5.49.1)(tsx@4.23.1)(yaml@2.9.0): + vitest@4.1.10(@opentelemetry/api@1.9.1)(@types/node@22.20.1)(@vitest/coverage-v8@4.1.10)(esbuild@0.28.1)(jiti@2.7.0)(jsdom@30.0.1)(less@4.8.1(supports-color@11.0.0))(sass@1.102.0)(terser@5.49.1)(tsx@4.23.7)(yaml@2.9.0): dependencies: '@vitest/expect': 4.1.10 - '@vitest/mocker': 4.1.10(vite@8.2.0(@types/node@22.20.1)(esbuild@0.28.1)(jiti@2.7.0)(less@4.8.1(supports-color@11.0.0))(sass@1.102.0)(terser@5.49.1)(tsx@4.23.1)(yaml@2.9.0)) + '@vitest/mocker': 4.1.10(vite@8.2.0(@types/node@22.20.1)(esbuild@0.28.1)(jiti@2.7.0)(less@4.8.1(supports-color@11.0.0))(sass@1.102.0)(terser@5.49.1)(tsx@4.23.7)(yaml@2.9.0)) '@vitest/pretty-format': 4.1.10 '@vitest/runner': 4.1.10 '@vitest/snapshot': 4.1.10 @@ -16338,7 +16364,7 @@ snapshots: tinyexec: 1.3.0 tinyglobby: 0.2.17 tinyrainbow: 3.1.1 - vite: 8.2.0(@types/node@22.20.1)(esbuild@0.28.1)(jiti@2.7.0)(less@4.8.1(supports-color@11.0.0))(sass@1.102.0)(terser@5.49.1)(tsx@4.23.1)(yaml@2.9.0) + vite: 8.2.0(@types/node@22.20.1)(esbuild@0.28.1)(jiti@2.7.0)(less@4.8.1(supports-color@11.0.0))(sass@1.102.0)(terser@5.49.1)(tsx@4.23.7)(yaml@2.9.0) why-is-node-running: 2.3.0 optionalDependencies: '@opentelemetry/api': 1.9.1 diff --git a/tests/e2e/ng-snapshot/package.json b/tests/e2e/ng-snapshot/package.json index 6fce7aa3d6a9..b425b4d0a929 100644 --- a/tests/e2e/ng-snapshot/package.json +++ b/tests/e2e/ng-snapshot/package.json @@ -2,21 +2,21 @@ "description": "snapshot versions of Angular for e2e testing", "private": true, "dependencies": { - "@angular/animations": "github:angular/animations-builds#8cf373fe77fe5bfa2976f8558cfbb02062fbf989", - "@angular/cdk": "github:angular/cdk-builds#537272e3b83d918eeca3469e56401814c7afa979", - "@angular/common": "github:angular/common-builds#66ad2d9beb92e2d4fde4bb1ae6f1ce9b42991f7c", - "@angular/compiler": "github:angular/compiler-builds#06db09af5df5b3cdf4a894d9fbcdf0c4845193b6", - "@angular/compiler-cli": "github:angular/compiler-cli-builds#96a827e4195bfb9da30d1b3669088baf140a4f02", - "@angular/core": "github:angular/core-builds#223af9a51f3a9f2a3d9bc6c7597a711d7bb7dc41", - "@angular/forms": "github:angular/forms-builds#e143909758d73d57a86766de433353a691609177", - "@angular/language-service": "github:angular/language-service-builds#5eb911b370b48f545bcf1178862362232da6a45a", - "@angular/localize": "github:angular/localize-builds#0e49c7f61bcbf8b7a5897ae0af906f1716ad819d", - "@angular/material": "github:angular/material-builds#0f7dcb3b1f8048d0347c19a734ed86c6e18b230b", - "@angular/material-moment-adapter": "github:angular/material-moment-adapter-builds#cd490fbfd3fe43611fe143c05b560f9050e276e7", - "@angular/platform-browser": "github:angular/platform-browser-builds#7cb5471e8a115af74442d88f6b1d78206b4f8f2f", - "@angular/platform-browser-dynamic": "github:angular/platform-browser-dynamic-builds#9d30dfb7f30b35b8d804e32b50d3284986d9d356", - "@angular/platform-server": "github:angular/platform-server-builds#0aa94d94a4848dd791f4650de09bd17375c2ddc2", - "@angular/router": "github:angular/router-builds#956b0916aed436d1adf2ea3c6d621d303d8bb0da", - "@angular/service-worker": "github:angular/service-worker-builds#1ca1d994d055310e6f170c891379ad0395e21c0b" + "@angular/animations": "github:angular/animations-builds#521e83b77cef9357cc3f31675c0a9358dfba2ac0", + "@angular/cdk": "github:angular/cdk-builds#cd9b1387b890e1e032ca9511f643a360a6292919", + "@angular/common": "github:angular/common-builds#ef79afafcb0fe8ac4a9ad7ba6678c71470ac68a9", + "@angular/compiler": "github:angular/compiler-builds#66c497ef5416fadef51784c43cfab64965f8527d", + "@angular/compiler-cli": "github:angular/compiler-cli-builds#4f92a79192840f7deba06eb96ce2ba92af6fb46e", + "@angular/core": "github:angular/core-builds#d645d8cca5d4a209d5b86dc2154e15288c58cec5", + "@angular/forms": "github:angular/forms-builds#b8c7756a574710420a3a61ce3891d933243559eb", + "@angular/language-service": "github:angular/language-service-builds#9249de91ccb22cc9777672b9cea58eb9db361174", + "@angular/localize": "github:angular/localize-builds#85e4b2af2127ba3791bb5c0ff1970efec1ae3d06", + "@angular/material": "github:angular/material-builds#189f6e896cf4198779ac1b494719e530106cffc5", + "@angular/material-moment-adapter": "github:angular/material-moment-adapter-builds#24ef2e6996111588eb71267683a8457456cb00c2", + "@angular/platform-browser": "github:angular/platform-browser-builds#21ad1c71d68efa80ac4be0f599113537e1fe2ec0", + "@angular/platform-browser-dynamic": "github:angular/platform-browser-dynamic-builds#c350d90c660c9c9d0caaeef69910a47461a4d1ae", + "@angular/platform-server": "github:angular/platform-server-builds#b66441d388fd65f5f00035826eb91c2d5a9b80d1", + "@angular/router": "github:angular/router-builds#38c9931aa53a6664a2661d9a1c10260393b8499f", + "@angular/service-worker": "github:angular/service-worker-builds#b05d7dbccd8ba2f81997a20869fa6a658a267861" } } From 75849f6c0f70cd7edb2ef494a6b636d2ab555cd3 Mon Sep 17 00:00:00 2001 From: Angular Robot Date: Tue, 11 Aug 2026 06:29:37 +0000 Subject: [PATCH 280/787] build: update all non-major dependencies See associated pull request for more information. --- package.json | 6 +- packages/angular/build/package.json | 8 +- .../angular_devkit/build_angular/package.json | 8 +- pnpm-lock.yaml | 800 ++++++++++++++---- 4 files changed, 632 insertions(+), 190 deletions(-) diff --git a/package.json b/package.json index ae8598898ce5..08aa473545d2 100644 --- a/package.json +++ b/package.json @@ -95,9 +95,9 @@ "@typescript-eslint/parser": "8.66.0", "ajv": "8.20.0", "buffer": "6.0.3", - "esbuild": "0.28.1", - "esbuild-wasm": "0.28.1", - "eslint": "10.8.0", + "esbuild": "0.28.2", + "esbuild-wasm": "0.28.2", + "eslint": "10.8.1", "eslint-config-prettier": "10.1.8", "eslint-plugin-import": "2.32.0", "express": "5.2.1", diff --git a/packages/angular/build/package.json b/packages/angular/build/package.json index 5aeb7590cee1..96ffd3f3fffd 100644 --- a/packages/angular/build/package.json +++ b/packages/angular/build/package.json @@ -27,7 +27,7 @@ "beasties": "0.4.3", "browserslist": "^4.26.0", "chokidar": "5.0.0", - "esbuild": "0.28.1", + "esbuild": "0.28.2", "https-proxy-agent": "9.1.0", "jsonc-parser": "3.3.1", "listr2": "11.0.0", @@ -37,12 +37,12 @@ "parse5-html-rewriting-stream": "8.0.1", "picomatch": "4.0.5", "piscina": "5.3.0", - "rolldown": "1.2.2", + "rolldown": "1.2.3", "sass": "1.102.0", "semver": "7.8.5", "source-map-support": "0.5.21", "tinyglobby": "0.2.17", - "vite": "8.2.0", + "vite": "8.2.1", "xxhash-wasm": "1.1.0" }, "optionalDependencies": { @@ -56,7 +56,7 @@ "jsdom": "30.0.1", "less": "4.8.1", "ng-packagr": "22.2.0-next.2", - "postcss": "8.5.25", + "postcss": "8.5.26", "rollup": "4.62.4", "rxjs": "7.8.2", "vitest": "4.1.10" diff --git a/packages/angular_devkit/build_angular/package.json b/packages/angular_devkit/build_angular/package.json index 3835fe864087..58bb3e6590d6 100644 --- a/packages/angular_devkit/build_angular/package.json +++ b/packages/angular_devkit/build_angular/package.json @@ -28,7 +28,7 @@ "browserslist": "^4.26.0", "copy-webpack-plugin": "14.0.0", "css-loader": "7.1.4", - "esbuild-wasm": "0.28.1", + "esbuild-wasm": "0.28.2", "http-proxy-middleware": "4.2.0", "istanbul-lib-instrument": "6.0.3", "jsonc-parser": "3.3.1", @@ -42,7 +42,7 @@ "ora": "9.4.1", "picomatch": "4.0.5", "piscina": "5.3.0", - "postcss": "8.5.25", + "postcss": "8.5.26", "postcss-loader": "8.2.1", "resolve-url-loader": "5.0.0", "rxjs": "7.8.2", @@ -51,7 +51,7 @@ "semver": "7.8.5", "source-map-loader": "5.0.0", "source-map-support": "0.5.21", - "terser": "5.49.1", + "terser": "5.49.2", "tinyglobby": "0.2.17", "tslib": "2.8.1", "webpack": "5.109.2", @@ -61,7 +61,7 @@ "webpack-subresource-integrity": "5.1.0" }, "optionalDependencies": { - "esbuild": "0.28.1" + "esbuild": "0.28.2" }, "devDependencies": { "@angular/ssr": "workspace:*", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index e88d0bc40181..f47d78bc6d77 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -78,13 +78,13 @@ importers: version: 0.28.0 '@eslint/compat': specifier: 2.1.0 - version: 2.1.0(eslint@10.8.0(jiti@2.7.0)(supports-color@11.0.0)) + version: 2.1.0(eslint@10.8.1(jiti@2.7.0)(supports-color@11.0.0)) '@eslint/eslintrc': specifier: 3.3.6 version: 3.3.6(supports-color@11.0.0) '@eslint/js': specifier: 10.0.1 - version: 10.0.1(eslint@10.8.0(jiti@2.7.0)(supports-color@11.0.0)) + version: 10.0.1(eslint@10.8.1(jiti@2.7.0)(supports-color@11.0.0)) '@rollup/plugin-alias': specifier: ^6.0.0 version: 6.0.0(rollup@4.62.4) @@ -102,10 +102,10 @@ importers: version: 4.62.4 '@stylistic/eslint-plugin': specifier: ^5.0.0 - version: 5.10.0(eslint@10.8.0(jiti@2.7.0)(supports-color@11.0.0)) + version: 5.10.0(eslint@10.8.1(jiti@2.7.0)(supports-color@11.0.0)) '@tony.ganchev/eslint-plugin-header': specifier: ~3.4.0 - version: 3.4.4(eslint@10.8.0(jiti@2.7.0)(supports-color@11.0.0)) + version: 3.4.4(eslint@10.8.1(jiti@2.7.0)(supports-color@11.0.0)) '@types/babel__core': specifier: 7.20.5 version: 7.20.5 @@ -135,7 +135,7 @@ importers: version: 3.0.8 '@types/loader-utils': specifier: ^3.0.0 - version: 3.0.0(esbuild@0.28.1) + version: 3.0.0(esbuild@0.28.2) '@types/lodash': specifier: ^4.17.0 version: 4.17.25 @@ -162,10 +162,10 @@ importers: version: 21.0.3 '@typescript-eslint/eslint-plugin': specifier: 8.66.0 - version: 8.66.0(@typescript-eslint/parser@8.66.0(eslint@10.8.0(jiti@2.7.0)(supports-color@11.0.0))(supports-color@11.0.0)(typescript@6.0.3))(eslint@10.8.0(jiti@2.7.0)(supports-color@11.0.0))(supports-color@11.0.0)(typescript@6.0.3) + version: 8.66.0(@typescript-eslint/parser@8.66.0(eslint@10.8.1(jiti@2.7.0)(supports-color@11.0.0))(supports-color@11.0.0)(typescript@6.0.3))(eslint@10.8.1(jiti@2.7.0)(supports-color@11.0.0))(supports-color@11.0.0)(typescript@6.0.3) '@typescript-eslint/parser': specifier: 8.66.0 - version: 8.66.0(eslint@10.8.0(jiti@2.7.0)(supports-color@11.0.0))(supports-color@11.0.0)(typescript@6.0.3) + version: 8.66.0(eslint@10.8.1(jiti@2.7.0)(supports-color@11.0.0))(supports-color@11.0.0)(typescript@6.0.3) ajv: specifier: 8.20.0 version: 8.20.0 @@ -173,20 +173,20 @@ importers: specifier: 6.0.3 version: 6.0.3 esbuild: - specifier: 0.28.1 - version: 0.28.1 + specifier: 0.28.2 + version: 0.28.2 esbuild-wasm: - specifier: 0.28.1 - version: 0.28.1 + specifier: 0.28.2 + version: 0.28.2 eslint: - specifier: 10.8.0 - version: 10.8.0(jiti@2.7.0)(supports-color@11.0.0) + specifier: 10.8.1 + version: 10.8.1(jiti@2.7.0)(supports-color@11.0.0) eslint-config-prettier: specifier: 10.1.8 - version: 10.1.8(eslint@10.8.0(jiti@2.7.0)(supports-color@11.0.0)) + version: 10.1.8(eslint@10.8.1(jiti@2.7.0)(supports-color@11.0.0)) eslint-plugin-import: specifier: 2.32.0 - version: 2.32.0(@typescript-eslint/parser@8.66.0(eslint@10.8.0(jiti@2.7.0)(supports-color@11.0.0))(supports-color@11.0.0)(typescript@6.0.3))(eslint@10.8.0(jiti@2.7.0)(supports-color@11.0.0))(supports-color@11.0.0) + version: 2.32.0(@typescript-eslint/parser@8.66.0(eslint@10.8.1(jiti@2.7.0)(supports-color@11.0.0))(supports-color@11.0.0)(typescript@6.0.3))(eslint@10.8.1(jiti@2.7.0)(supports-color@11.0.0))(supports-color@11.0.0) express: specifier: 5.2.1 version: 5.2.1(supports-color@11.0.0) @@ -321,7 +321,7 @@ importers: version: 7.8.2 vitest: specifier: 4.1.10 - version: 4.1.10(@opentelemetry/api@1.9.1)(@types/node@22.20.1)(@vitest/coverage-v8@4.1.10)(esbuild@0.28.1)(jiti@2.7.0)(jsdom@30.0.1)(less@4.8.1(supports-color@11.0.0))(sass@1.102.0)(terser@5.49.1)(tsx@4.23.7)(yaml@2.9.0) + version: 4.1.10(@opentelemetry/api@1.9.1)(@types/node@22.20.1)(@vitest/coverage-v8@4.1.10)(esbuild@0.28.2)(jiti@2.7.0)(jsdom@30.0.1)(less@4.8.1(supports-color@11.0.0))(sass@1.102.0)(terser@5.49.2)(tsx@4.23.7)(yaml@2.9.0) packages/angular/build: dependencies: @@ -342,7 +342,7 @@ importers: version: 2.6.0 '@vitejs/plugin-basic-ssl': specifier: 2.3.0 - version: 2.3.0(vite@8.2.0(@types/node@22.20.1)(esbuild@0.28.1)(jiti@2.7.0)(less@4.8.1(supports-color@11.0.0))(sass@1.102.0)(terser@5.49.1)(tsx@4.23.7)(yaml@2.9.0)) + version: 2.3.0(vite@8.2.1(@types/node@22.20.1)(esbuild@0.28.2)(jiti@2.7.0)(less@4.8.1(supports-color@11.0.0))(sass@1.102.0)(terser@5.49.2)(tsx@4.23.7)(yaml@2.9.0)) beasties: specifier: 0.4.3 version: 0.4.3 @@ -353,8 +353,8 @@ importers: specifier: 5.0.0 version: 5.0.0 esbuild: - specifier: 0.28.1 - version: 0.28.1 + specifier: 0.28.2 + version: 0.28.2 https-proxy-agent: specifier: 9.1.0 version: 9.1.0(supports-color@11.0.0) @@ -383,8 +383,8 @@ importers: specifier: 5.3.0 version: 5.3.0 rolldown: - specifier: 1.2.2 - version: 1.2.2 + specifier: 1.2.3 + version: 1.2.3 sass: specifier: 1.102.0 version: 1.102.0 @@ -398,8 +398,8 @@ importers: specifier: 0.2.17 version: 0.2.17 vite: - specifier: 8.2.0 - version: 8.2.0(@types/node@22.20.1)(esbuild@0.28.1)(jiti@2.7.0)(less@4.8.1(supports-color@11.0.0))(sass@1.102.0)(terser@5.49.1)(tsx@4.23.7)(yaml@2.9.0) + specifier: 8.2.1 + version: 8.2.1(@types/node@22.20.1)(esbuild@0.28.2)(jiti@2.7.0)(less@4.8.1(supports-color@11.0.0))(sass@1.102.0)(terser@5.49.2)(tsx@4.23.7)(yaml@2.9.0) xxhash-wasm: specifier: 1.1.0 version: 1.1.0 @@ -426,8 +426,8 @@ importers: specifier: 22.2.0-next.2 version: 22.2.0-next.2(@angular/compiler-cli@22.2.0-next.1(@angular/compiler@22.2.0-next.1)(typescript@6.0.3))(supports-color@11.0.0)(tslib@2.8.1)(typescript@6.0.3) postcss: - specifier: 8.5.25 - version: 8.5.25 + specifier: 8.5.26 + version: 8.5.26 rollup: specifier: 4.62.4 version: 4.62.4 @@ -436,7 +436,7 @@ importers: version: 7.8.2 vitest: specifier: 4.1.10 - version: 4.1.10(@opentelemetry/api@1.9.1)(@types/node@22.20.1)(@vitest/coverage-v8@4.1.10)(esbuild@0.28.1)(jiti@2.7.0)(jsdom@30.0.1)(less@4.8.1(supports-color@11.0.0))(sass@1.102.0)(terser@5.49.1)(tsx@4.23.7)(yaml@2.9.0) + version: 4.1.10(@opentelemetry/api@1.9.1)(@types/node@22.20.1)(@vitest/coverage-v8@4.1.10)(esbuild@0.28.2)(jiti@2.7.0)(jsdom@30.0.1)(less@4.8.1(supports-color@11.0.0))(sass@1.102.0)(terser@5.49.2)(tsx@4.23.7)(yaml@2.9.0) optionalDependencies: lmdb: specifier: 3.5.6 @@ -597,22 +597,22 @@ importers: version: 4.1.3 autoprefixer: specifier: 10.5.4 - version: 10.5.4(postcss@8.5.25) + version: 10.5.4(postcss@8.5.26) babel-loader: specifier: 10.1.1 - version: 10.1.1(@babel/core@8.0.1)(webpack@5.109.2(esbuild@0.28.1)(lightningcss@1.33.0)(postcss@8.5.25)(uglify-js@3.19.3)) + version: 10.1.1(@babel/core@8.0.1)(webpack@5.109.2(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.26)(uglify-js@3.19.3)) browserslist: specifier: ^4.26.0 version: 4.28.7 copy-webpack-plugin: specifier: 14.0.0 - version: 14.0.0(webpack@5.109.2(esbuild@0.28.1)(lightningcss@1.33.0)(postcss@8.5.25)(uglify-js@3.19.3)) + version: 14.0.0(webpack@5.109.2(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.26)(uglify-js@3.19.3)) css-loader: specifier: 7.1.4 - version: 7.1.4(webpack@5.109.2(esbuild@0.28.1)(lightningcss@1.33.0)(postcss@8.5.25)(uglify-js@3.19.3)) + version: 7.1.4(webpack@5.109.2(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.26)(uglify-js@3.19.3)) esbuild-wasm: - specifier: 0.28.1 - version: 0.28.1 + specifier: 0.28.2 + version: 0.28.2 http-proxy-middleware: specifier: 4.2.0 version: 4.2.0(supports-color@11.0.0) @@ -630,16 +630,16 @@ importers: version: 4.8.1(supports-color@11.0.0) less-loader: specifier: 13.0.0 - version: 13.0.0(less@4.8.1(supports-color@11.0.0))(webpack@5.109.2(esbuild@0.28.1)(lightningcss@1.33.0)(postcss@8.5.25)(uglify-js@3.19.3)) + version: 13.0.0(less@4.8.1(supports-color@11.0.0))(webpack@5.109.2(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.26)(uglify-js@3.19.3)) license-webpack-plugin: specifier: 4.0.2 - version: 4.0.2(webpack@5.109.2(esbuild@0.28.1)(lightningcss@1.33.0)(postcss@8.5.25)(uglify-js@3.19.3)) + version: 4.0.2(webpack@5.109.2(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.26)(uglify-js@3.19.3)) loader-utils: specifier: 3.3.1 version: 3.3.1 mini-css-extract-plugin: specifier: 2.10.2 - version: 2.10.2(webpack@5.109.2(esbuild@0.28.1)(lightningcss@1.33.0)(postcss@8.5.25)(uglify-js@3.19.3)) + version: 2.10.2(webpack@5.109.2(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.26)(uglify-js@3.19.3)) open: specifier: 11.0.0 version: 11.0.0 @@ -653,11 +653,11 @@ importers: specifier: 5.3.0 version: 5.3.0 postcss: - specifier: 8.5.25 - version: 8.5.25 + specifier: 8.5.26 + version: 8.5.26 postcss-loader: specifier: 8.2.1 - version: 8.2.1(postcss@8.5.25)(typescript@6.0.3)(webpack@5.109.2(esbuild@0.28.1)(lightningcss@1.33.0)(postcss@8.5.25)(uglify-js@3.19.3)) + version: 8.2.1(postcss@8.5.26)(typescript@6.0.3)(webpack@5.109.2(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.26)(uglify-js@3.19.3)) resolve-url-loader: specifier: 5.0.0 version: 5.0.0 @@ -669,19 +669,19 @@ importers: version: 1.102.0 sass-loader: specifier: 17.0.0 - version: 17.0.0(sass@1.102.0)(webpack@5.109.2(esbuild@0.28.1)(lightningcss@1.33.0)(postcss@8.5.25)(uglify-js@3.19.3)) + version: 17.0.0(sass@1.102.0)(webpack@5.109.2(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.26)(uglify-js@3.19.3)) semver: specifier: 7.8.5 version: 7.8.5 source-map-loader: specifier: 5.0.0 - version: 5.0.0(webpack@5.109.2(esbuild@0.28.1)(lightningcss@1.33.0)(postcss@8.5.25)(uglify-js@3.19.3)) + version: 5.0.0(webpack@5.109.2(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.26)(uglify-js@3.19.3)) source-map-support: specifier: 0.5.21 version: 0.5.21 terser: - specifier: 5.49.1 - version: 5.49.1 + specifier: 5.49.2 + version: 5.49.2 tinyglobby: specifier: 0.2.17 version: 0.2.17 @@ -690,19 +690,19 @@ importers: version: 2.8.1 webpack: specifier: 5.109.2 - version: 5.109.2(esbuild@0.28.1)(lightningcss@1.33.0)(postcss@8.5.25)(uglify-js@3.19.3) + version: 5.109.2(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.26)(uglify-js@3.19.3) webpack-dev-middleware: specifier: 8.1.1 - version: 8.1.1(tslib@2.8.1)(webpack@5.109.2(esbuild@0.28.1)(lightningcss@1.33.0)(postcss@8.5.25)(uglify-js@3.19.3)) + version: 8.1.1(tslib@2.8.1)(webpack@5.109.2(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.26)(uglify-js@3.19.3)) webpack-dev-server: specifier: 6.0.0 - version: 6.0.0(bufferutil@4.1.0)(supports-color@11.0.0)(tslib@2.8.1)(utf-8-validate@6.0.6)(webpack@5.109.2(esbuild@0.28.1)(lightningcss@1.33.0)(postcss@8.5.25)(uglify-js@3.19.3)) + version: 6.0.0(bufferutil@4.1.0)(supports-color@11.0.0)(tslib@2.8.1)(utf-8-validate@6.0.6)(webpack@5.109.2(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.26)(uglify-js@3.19.3)) webpack-merge: specifier: 6.0.1 version: 6.0.1 webpack-subresource-integrity: specifier: 5.1.0 - version: 5.1.0(webpack@5.109.2(esbuild@0.28.1)(lightningcss@1.33.0)(postcss@8.5.25)(uglify-js@3.19.3)) + version: 5.1.0(webpack@5.109.2(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.26)(uglify-js@3.19.3)) devDependencies: '@angular/ssr': specifier: workspace:* @@ -718,8 +718,8 @@ importers: version: 8.10.0 optionalDependencies: esbuild: - specifier: 0.28.1 - version: 0.28.1 + specifier: 0.28.2 + version: 0.28.2 packages/angular_devkit/build_webpack: dependencies: @@ -738,10 +738,10 @@ importers: version: link:../../ngtools/webpack webpack: specifier: 5.109.2 - version: 5.109.2(esbuild@0.28.1)(lightningcss@1.33.0)(postcss@8.5.25)(uglify-js@3.19.3) + version: 5.109.2(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.26)(uglify-js@3.19.3) webpack-dev-server: specifier: 6.0.0 - version: 6.0.0(bufferutil@4.1.0)(supports-color@11.0.0)(tslib@2.8.1)(utf-8-validate@6.0.6)(webpack@5.109.2(esbuild@0.28.1)(lightningcss@1.33.0)(postcss@8.5.25)(uglify-js@3.19.3)) + version: 6.0.0(bufferutil@4.1.0)(supports-color@11.0.0)(tslib@2.8.1)(utf-8-validate@6.0.6)(webpack@5.109.2(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.26)(uglify-js@3.19.3)) packages/angular_devkit/core: dependencies: @@ -814,7 +814,7 @@ importers: version: 6.0.3 webpack: specifier: 5.109.2 - version: 5.109.2(esbuild@0.28.1)(lightningcss@1.33.0)(postcss@8.5.25)(uglify-js@3.19.3) + version: 5.109.2(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.26)(uglify-js@3.19.3) packages/schematics/angular: dependencies: @@ -1630,156 +1630,312 @@ packages: cpu: [ppc64] os: [aix] + '@esbuild/aix-ppc64@0.28.2': + resolution: {integrity: sha512-XExcO+dvLKvVtNTibSTBej1NCAbaGhWn9Ww1ZPx80qsahhPFe/8jgWP0IchNe0F3HwkU7n8ejhH8bjonqht8mQ==} + engines: {node: '>=18'} + cpu: [ppc64] + os: [aix] + '@esbuild/android-arm64@0.28.1': resolution: {integrity: sha512-34EGEbCIAgosYz6goLcopX6Mo7NyGv9tfwEM2/7Ce2VcVRk568iSvniGWcUXIy7wEDR1wzolcxcriFVrWYcwBg==} engines: {node: '>=18'} cpu: [arm64] os: [android] + '@esbuild/android-arm64@0.28.2': + resolution: {integrity: sha512-5YfKeeI8qWfBZIX+u2xZC3Zlb3Os/gLS2sbEKM+I4ZOcsWmHS2WLysCcQZDAFRslDUU5Oiq44gf6PYN1vGwG5A==} + engines: {node: '>=18'} + cpu: [arm64] + os: [android] + '@esbuild/android-arm@0.28.1': resolution: {integrity: sha512-0k2F129Xdio1TdJfzJ8sy1Q47vUD2NnwdhiAf7drUN1EBTfPf4hsFCtmMgu/6m8JSzsBrlmVjudMBQqOfG8usQ==} engines: {node: '>=18'} cpu: [arm] os: [android] + '@esbuild/android-arm@0.28.2': + resolution: {integrity: sha512-kXXoiPVVGQcnIYGOeaovwOURpniDBpSq4A03qkQ+BMQqtGG6HYap3xne9C1O1yo4TR3qxlCX5IqqmX6fFo2Lqg==} + engines: {node: '>=18'} + cpu: [arm] + os: [android] + '@esbuild/android-x64@0.28.1': resolution: {integrity: sha512-dbwY7ltSMDWsRatcRpCnES4F+im88OCUgGZjy52shC7GqHRE/cYlxNbB4Z4UpJswpcc4Qxd2oE/ufM0p61IKng==} engines: {node: '>=18'} cpu: [x64] os: [android] + '@esbuild/android-x64@0.28.2': + resolution: {integrity: sha512-O387ite7SzUyCcy3JQX4P4bLtEA7bLLkx+esve5JHnyYfNTxcVpXZo9jhdB0lTKN44gztELTdU7nS8Nr16Fs1Q==} + engines: {node: '>=18'} + cpu: [x64] + os: [android] + '@esbuild/darwin-arm64@0.28.1': resolution: {integrity: sha512-TZbWkQY7kvTAXbXUT7uVACR5cMHsDiSz9z7ZKAX/RTq/WJEk3QyRr0wZpNhBDX+/0CtdqUIJlOiodQcta6tY3Q==} engines: {node: '>=18'} cpu: [arm64] os: [darwin] + '@esbuild/darwin-arm64@0.28.2': + resolution: {integrity: sha512-n4KqkOQrraxHJcgjM1RvwbigfQKIKJVpM7xp+KsxiyUSrRdIXnt73VhrPAx0fV44hgfmIVKjxMN9J1t5jySVkw==} + engines: {node: '>=18'} + cpu: [arm64] + os: [darwin] + '@esbuild/darwin-x64@0.28.1': resolution: {integrity: sha512-zfdzgK9ACBNZLI/CyHTOx81SyNbM6YXn7rxSgX97VjyiPl9W1i4Ka4fgKECEoFCKGpvBj5qArWIGgQjOwkgskQ==} engines: {node: '>=18'} cpu: [x64] os: [darwin] + '@esbuild/darwin-x64@0.28.2': + resolution: {integrity: sha512-uq6suIWYP37qzGddBKPw5QEQPi6HiLGsO7UmkpfyaYNQ3D+rN6w6WfwH+nuqcGXWvawGwxOEroO4YGnFh95azw==} + engines: {node: '>=18'} + cpu: [x64] + os: [darwin] + '@esbuild/freebsd-arm64@0.28.1': resolution: {integrity: sha512-wG2EA8ENdEI0qhkSZMjfqrdY+ziCYCPMmtZjjIwOmXFjmyzEHn+UUxk5of+SYsjtfs3VpnlC7QLzSI5hY/rOAw==} engines: {node: '>=18'} cpu: [arm64] os: [freebsd] + '@esbuild/freebsd-arm64@0.28.2': + resolution: {integrity: sha512-n+I0BTSRIoy+d6RPKnEVwql5UwBJolytvY4mAOIEJorKlqgPII8ix6slVVrfZ5Tnj7glIZvloylbB/EJPMWEXw==} + engines: {node: '>=18'} + cpu: [arm64] + os: [freebsd] + '@esbuild/freebsd-x64@0.28.1': resolution: {integrity: sha512-i7dZ9vQgnvSCzi/rYCXNgtF/U+eKZNJBzu3eTQbRgHnM7tNSizLOkRFAl3qzVc/Op/u5YkHHa4pf/3DOYHthLQ==} engines: {node: '>=18'} cpu: [x64] os: [freebsd] + '@esbuild/freebsd-x64@0.28.2': + resolution: {integrity: sha512-78XJTJkvPs0kz2w61301PJjXl4g7q3JqiYMZ/M/yVI73EHBrCRTgkhu9oqG7vPqq+a/yadEW8aD+agKlk5xrmg==} + engines: {node: '>=18'} + cpu: [x64] + os: [freebsd] + '@esbuild/linux-arm64@0.28.1': resolution: {integrity: sha512-yHs+0uc8+nvEAfAfxrWQKK5peSNzBc4PegcMO0EJ2hT71uA7vB8Ihg2e77R2P7SG5uYjPbHlLLmve4LLLRCf0g==} engines: {node: '>=18'} cpu: [arm64] os: [linux] + '@esbuild/linux-arm64@0.28.2': + resolution: {integrity: sha512-pW4AC0P3it8c7do9MVM4p51FzHzdM/TZrerurgRcHJ2WTa1VQ1CIq18xncfpBJw4ojkiZZrKW2yIBWBP92j6Ug==} + engines: {node: '>=18'} + cpu: [arm64] + os: [linux] + '@esbuild/linux-arm@0.28.1': resolution: {integrity: sha512-qVXBOHQS+d5Y722GwJzJUtOLlX7km3CraOaGormF1pDtPd2C/l1SHRPgjLunLGe51Sh5YYWKMFDyV4SxgMQYTQ==} engines: {node: '>=18'} cpu: [arm] os: [linux] + '@esbuild/linux-arm@0.28.2': + resolution: {integrity: sha512-XlDnu2q5yoqems+xay6wSAcg9DDD7K9RLKZEBOMZm3ckNpJBvOX20tSfby8KfrrhINDyv9V2YVZKY/SpoGJI8w==} + engines: {node: '>=18'} + cpu: [arm] + os: [linux] + '@esbuild/linux-ia32@0.28.1': resolution: {integrity: sha512-d1z4ZuP0ajrfz/FhGT4vv278rX8KnPPJx8i5+AtK7TYbx9Le9F1hyzurZpkEyjkGa9dUGhQow4C1NmeGvqxN2w==} engines: {node: '>=18'} cpu: [ia32] os: [linux] + '@esbuild/linux-ia32@0.28.2': + resolution: {integrity: sha512-CYbnj78HsIeA+DhgUKgFCfvNsTHFhMMrinUrMZpDXJXKN8T3XViTZ/+wtHeVxEWY8ewSzTFN+nRmSwO2tZaLUQ==} + engines: {node: '>=18'} + cpu: [ia32] + os: [linux] + '@esbuild/linux-loong64@0.28.1': resolution: {integrity: sha512-M5sRjUVZrkm1OAPR3dlOYzNmN+loZKGVi1VUQGrwuqLcbR6qeAz+famMhjASeH3YVKvZz+zT1jlh/keC3Rj/lg==} engines: {node: '>=18'} cpu: [loong64] os: [linux] + '@esbuild/linux-loong64@0.28.2': + resolution: {integrity: sha512-buwkd8nsph4R+ajRvw0qM5Hja/TXQow3ptzWO2EbG/cqcIkHloRrdlBtQlshyYGTNFvfkfJ5tpPLVkY4DtsPfQ==} + engines: {node: '>=18'} + cpu: [loong64] + os: [linux] + '@esbuild/linux-mips64el@0.28.1': resolution: {integrity: sha512-mRObBZeHh2OxcBFPWE/FjylkRgZdYuiTR3vaTozquCGOH14iP9oN4x4Ge81CoIDYQrXmIxpFumJBu5MtZpnQJQ==} engines: {node: '>=18'} cpu: [mips64el] os: [linux] + '@esbuild/linux-mips64el@0.28.2': + resolution: {integrity: sha512-ZVykbDyk7519VwiNb9Lcj9m8XM6v5V9uKPvrEMkkEedVewf+0itkhahp4HDpgERXhwLRpWFypsGbG/J8s0QjJA==} + engines: {node: '>=18'} + cpu: [mips64el] + os: [linux] + '@esbuild/linux-ppc64@0.28.1': resolution: {integrity: sha512-slScBsMAb3GFDcdrCgLwZtPYRoH2H/youv10QiZyRjmsP48fznoveWytSgCI/R0ZcUgpc0ZhIUEx6LHts8yrfQ==} engines: {node: '>=18'} cpu: [ppc64] os: [linux] + '@esbuild/linux-ppc64@0.28.2': + resolution: {integrity: sha512-CAXl+Dtd9UUuJd8pKKdwh6MLm3MUMiqMPmhZ3tTSXPqfyQ3vDl6R5hZdZ/kYojK4ofXtdfSv1tFq8XzWx3heNQ==} + engines: {node: '>=18'} + cpu: [ppc64] + os: [linux] + '@esbuild/linux-riscv64@0.28.1': resolution: {integrity: sha512-kw0owk1o0GFETUJyW0jc0G4Yzs0BHZn0JDZ8JRT088vjJYX777BAs1fDGxAC+q831qOs2DTC96mNsG2opdfyyQ==} engines: {node: '>=18'} cpu: [riscv64] os: [linux] + '@esbuild/linux-riscv64@0.28.2': + resolution: {integrity: sha512-GeXCej4IQtU1B+QlDV8W/RRvbzI3O/Stss+/bCXv4lZls5WGRtu2a+3JkA3i4qIUlMXpcHebWpF8AkJhATowuA==} + engines: {node: '>=18'} + cpu: [riscv64] + os: [linux] + '@esbuild/linux-s390x@0.28.1': resolution: {integrity: sha512-/lAIjX8aYFRByhh6L5rYtPEDRqa9de/4V/juOXcta5frjvzXO4/sqEtyytse0g3zZFuWu5cDN0MkLz2qRDD2Ag==} engines: {node: '>=18'} cpu: [s390x] os: [linux] + '@esbuild/linux-s390x@0.28.2': + resolution: {integrity: sha512-3H1weTYZPxt/WOhByszQZybS9w5lKzUn1FDMsgEChbHWQwHYQQRfBxgCcZvPhjHfKyJjIievvMmEUawJrdY9Dg==} + engines: {node: '>=18'} + cpu: [s390x] + os: [linux] + '@esbuild/linux-x64@0.28.1': resolution: {integrity: sha512-u/anNYF2mmVOEDwLtnQ1wOr3EZ9sTNGLWrsYGYwHWzGA3Si84IOkHXlbWTD1NB+9/1lcnweYKO54uhxZydNzfA==} engines: {node: '>=18'} cpu: [x64] os: [linux] + '@esbuild/linux-x64@0.28.2': + resolution: {integrity: sha512-4xTZr1FUmSoQW4XIWmit3tzQrUTZM+N3P0XV8xROKYF50XfI7xeO90+1bZvNwxIufQ9hDQVRJH5YhgPVF8A/HQ==} + engines: {node: '>=18'} + cpu: [x64] + os: [linux] + '@esbuild/netbsd-arm64@0.28.1': resolution: {integrity: sha512-oks0DYbLwWMmaakTsCb+zL4E+aHRVLom9IJZOAthMQEPiQmydXHkziYEsGYRx0uNV/IjEKGAV941JzH02pflqw==} engines: {node: '>=18'} cpu: [arm64] os: [netbsd] + '@esbuild/netbsd-arm64@0.28.2': + resolution: {integrity: sha512-sSATRjPeDBg3pdgHoQfoYBob11Kk1FGa9lui5RIHZCoCkJa9QKlvl3/vKz2usCmYYjs7ymJR/2Nnsqe+Hjt5nw==} + engines: {node: '>=18'} + cpu: [arm64] + os: [netbsd] + '@esbuild/netbsd-x64@0.28.1': resolution: {integrity: sha512-aeL6lAnN89Hz43Mlh1G8ARasbuoYvSITDEx0tHh5b7jJnHcssqgjy9Yx430GDpmCa6OyrKoS0aNRjKundRizGg==} engines: {node: '>=18'} cpu: [x64] os: [netbsd] + '@esbuild/netbsd-x64@0.28.2': + resolution: {integrity: sha512-lqnzCV+mM0gIADaKihiCg6ifgfU2L3h5E33rNQBN1Y4MaVGnzryzmvvf7UHxprpQdE8hpqLolJ9Rl+SkIRDpyw==} + engines: {node: '>=18'} + cpu: [x64] + os: [netbsd] + '@esbuild/openbsd-arm64@0.28.1': resolution: {integrity: sha512-MEFJe5C3R8pwXdZ5Y21oo6m7ePiS0d9pWucn99O/wvyJZChoIQKrQDxKrGeW8F5+T0okTHesAmDeiHDTIq0V/Q==} engines: {node: '>=18'} cpu: [arm64] os: [openbsd] + '@esbuild/openbsd-arm64@0.28.2': + resolution: {integrity: sha512-AL2qJILH7lNjrDmCQDvdxMfAUIv8KMNZOvrwAQ8i8//ntL9FflhOyMJ8OZSMBb8/AWXe3/5v5S20y3zCoZWKoQ==} + engines: {node: '>=18'} + cpu: [arm64] + os: [openbsd] + '@esbuild/openbsd-x64@0.28.1': resolution: {integrity: sha512-i/ZLIOafE0Z8cI/XANJAixoJL/uRAoS2xOA3rb0xN+KK0K177cMAsQYkzHtBrtMXAKuAc7HGgcWiZ/sRC1Nxgw==} engines: {node: '>=18'} cpu: [x64] os: [openbsd] + '@esbuild/openbsd-x64@0.28.2': + resolution: {integrity: sha512-QtiuPytchRyC4rwUKhexJdQKvDuZ6hWloi3igqPQNUJCS1/v9EiO3UTOXR6A3FoMo4fnAKbWJdqaIwhOzh8qEw==} + engines: {node: '>=18'} + cpu: [x64] + os: [openbsd] + '@esbuild/openharmony-arm64@0.28.1': resolution: {integrity: sha512-ge+Z7EXFNt2BO1oAMsVpiQ8EwndV9i1xXerAeTIK7AtPs3bKFXQM7nlRxDSIUIMeueR1CNXxqztLzdNeReKBJg==} engines: {node: '>=18'} cpu: [arm64] os: [openharmony] + '@esbuild/openharmony-arm64@0.28.2': + resolution: {integrity: sha512-WkhYDmpTjLvGlScA1rwjRUmhl4k8oXR3cIbtqWmELgU/dFeHHlEllxDvdWcNJV9rbzCexB5vz8gtNewWLgCT7Q==} + engines: {node: '>=18'} + cpu: [arm64] + os: [openharmony] + '@esbuild/sunos-x64@0.28.1': resolution: {integrity: sha512-BEjgtECkL3vY+SaSQ6nzVfiALUeFxpawyp8Jmf5PtYhf1Ug40N1h/hxlhts+f1FvSvarEigdxS3BlSMI2PJLcQ==} engines: {node: '>=18'} cpu: [x64] os: [sunos] + '@esbuild/sunos-x64@0.28.2': + resolution: {integrity: sha512-GPMSkTOtMnv2U2F8gxe4Io6qmVs+YKyp832Etqqxr0hFngmXQ3rzwytelm3GIn7T4VviRUlf3sOgBOiTdvaf7g==} + engines: {node: '>=18'} + cpu: [x64] + os: [sunos] + '@esbuild/win32-arm64@0.28.1': resolution: {integrity: sha512-lCv9eK/H6ZJWbE7bh2nw54CZ9M2nupBxJcTsdk/QQnWkdSjKGuxmmH8/GWrlT1eMmZfn4dGcCjRte397WqfQXA==} engines: {node: '>=18'} cpu: [arm64] os: [win32] + '@esbuild/win32-arm64@0.28.2': + resolution: {integrity: sha512-PIhhEkE9uPBleRBrQEJpUn7MBnibZzbGzYWPmY3x+YoVg/95zbjB4CxPPOQ8l5tYYM4mMaCthF8/1DIfBQQyWQ==} + engines: {node: '>=18'} + cpu: [arm64] + os: [win32] + '@esbuild/win32-ia32@0.28.1': resolution: {integrity: sha512-zvb/mB2bSCoJOpoCBgYKKpX6YM6mJBlBUVUtVj41DlZJVEB6/0CKlRYxP5wWl1C1ILiCoAU5wZZ4q1P3qeS6Eg==} engines: {node: '>=18'} cpu: [ia32] os: [win32] + '@esbuild/win32-ia32@0.28.2': + resolution: {integrity: sha512-YmJbfTlvU7Sdn9BB+4PRES4oB6pxgS37MAONj+hBr/cpXS1aBPKXxNnDbu+QCWPj0o9dgyxeq79g6c5P8KeuYA==} + engines: {node: '>=18'} + cpu: [ia32] + os: [win32] + '@esbuild/win32-x64@0.28.1': resolution: {integrity: sha512-bm4Mowrv+GXMlpWX++EcXw/iLyd1o3+bJkC2DkWXYVvgZCqD/bSj9ctZeAMC3cIxgjRVR2Dufaiu4YPxr5gW1A==} engines: {node: '>=18'} cpu: [x64] os: [win32] + '@esbuild/win32-x64@0.28.2': + resolution: {integrity: sha512-5ebpxr3nWMzrL/rnUI755Jkuee0bHL/Gq0WTF9lvcpv73wAp5eu8MfBUgWK9bhWvZjj7yX8etf/8tI8Ney695g==} + engines: {node: '>=18'} + cpu: [x64] + os: [win32] + '@eslint-community/eslint-utils@4.10.1': resolution: {integrity: sha512-cuadcxVFE8sDK6iWJbs8Sn0av2Nrh2QSGQhVlBW9AaAHqHwjWsZHT8LJ4hFGPh7ASBV2deFdM7H/DPjulmh8rg==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} @@ -3117,30 +3273,60 @@ packages: cpu: [arm64] os: [android] + '@rolldown/binding-android-arm64@1.2.3': + resolution: {integrity: sha512-zrJtHDcaZJ1Fp7xf4hNl+7seH9Cn/N5TwLYkhgXREtBwAd/jaqW3uqeHxpDugJLVICWg4eW44kOQEGJ1r6jCGw==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [android] + '@rolldown/binding-darwin-arm64@1.2.2': resolution: {integrity: sha512-9u9Xv6c1AJZT0FfwH5vrMG5Jjcwhc1MlyrPu0XfTqkzsmqfks2M6W/o5XwAJgVVN/jHpqqngC1WevHKKTIUtIA==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [darwin] + '@rolldown/binding-darwin-arm64@1.2.3': + resolution: {integrity: sha512-ieIiibVCp0tX7TLu2cafoNPv8wJyYi01ekXpbf8q2j7F4rGAhhXb/eQh7ge9DRBY78GwmRQtvjZDux7EDbA8kA==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [darwin] + '@rolldown/binding-darwin-x64@1.2.2': resolution: {integrity: sha512-9W1mbGZAfW3oqd85bhBkmpyHCCzL1TeG/zFFP3vg7b0rlly8cxOcre5nXwz+LHazCwac2MNWgPdPCHndABjpWQ==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [darwin] + '@rolldown/binding-darwin-x64@1.2.3': + resolution: {integrity: sha512-Zh9tCon19eDXJoihx0rqKhMUlMYqzwj3aPsSuHmI4RWZh62dWUL+DJN4C5YQya5TcQBJU/Fe8+rY0jhXTQITqA==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [x64] + os: [darwin] + '@rolldown/binding-freebsd-x64@1.2.2': resolution: {integrity: sha512-0p1lhiCSCyaerFwtrdZQUx7NqGk6LQnaRKWX7tFQqwQgvX0rjM15cIkm3pax1UpEakK14C4mOxx/jSqCBdBRqQ==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [freebsd] + '@rolldown/binding-freebsd-x64@1.2.3': + resolution: {integrity: sha512-nGbJWewA1wrXXZiQhjAT5rhibGfns5ZNkDVqxsO6zJ3f3YvpoDNNmGMSbbhLuXKjNScaBJVOAboztAWVespQMg==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [x64] + os: [freebsd] + '@rolldown/binding-linux-arm-gnueabihf@1.2.2': resolution: {integrity: sha512-e+cOJXrJ2L3zx6YzqPg+f6Wbk3V1cKB8bOhbaYdVYN3DdquzNdRAmrbETz1qnt5yp/c7JNlNjmITiA2cVneQ7w==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm] os: [linux] + '@rolldown/binding-linux-arm-gnueabihf@1.2.3': + resolution: {integrity: sha512-QNniJr5Kml0kDEB98jiDOJjXNroxIIi0IXIbdYzY26Xt1pVbeP62+KnoIZLwirOymX/0jDk/2gI/bNUv7A7OIw==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm] + os: [linux] + '@rolldown/binding-linux-arm64-gnu@1.2.2': resolution: {integrity: sha512-JsSMsj6sNat/MuhG5fnBD7QgbtpHKVe30x5/bAVirDHdhoQRXJkF6xc0Jqk8O4fiCUQAzMOoH9wZi3m60c8wtg==} engines: {node: ^20.19.0 || >=22.12.0} @@ -3148,6 +3334,13 @@ packages: os: [linux] libc: [glibc] + '@rolldown/binding-linux-arm64-gnu@1.2.3': + resolution: {integrity: sha512-TkqEAcmmvH3I/q4114NB4RVt6241Dao48pF45uLcFGrwAaIn0iITgTAKP/dLjbN0R4buJjGb91+UHSoFmpgIWw==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [linux] + libc: [glibc] + '@rolldown/binding-linux-arm64-musl@1.2.2': resolution: {integrity: sha512-B5G/zJdHaoJn9vD50eGHWkiWfmq8Uhi3IiLPJTzmZTrAalk1bztUikSXo0qga18ibE0IXboyeMUnhPjhAJ45wQ==} engines: {node: ^20.19.0 || >=22.12.0} @@ -3155,6 +3348,13 @@ packages: os: [linux] libc: [musl] + '@rolldown/binding-linux-arm64-musl@1.2.3': + resolution: {integrity: sha512-NHqjnxpsndf4MPymxteFAWHHfkTL8HjWh1KB7z23ofZ6QO2euONuxDXjat69dKZRALnGypg8k8SsK8vZJoXv1Q==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [linux] + libc: [musl] + '@rolldown/binding-linux-ppc64-gnu@1.2.2': resolution: {integrity: sha512-6mC/awzKka8W6EoekjegpfGkjz8jXWDX63pqu/HYVpyKtZfu65Jsh4QAH3Kej3CAv/c1oGX7psTmFEbr0mDxLA==} engines: {node: ^20.19.0 || >=22.12.0} @@ -3162,6 +3362,13 @@ packages: os: [linux] libc: [glibc] + '@rolldown/binding-linux-ppc64-gnu@1.2.3': + resolution: {integrity: sha512-6tbrbwfz5GB9DQ4Jwo6hy9v+vR31xZlvzZ6n5Xut6Hhx5PvrA9q/HsK8KMaYQp063iqZGXwNvZtYNLD7EM/x0w==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [ppc64] + os: [linux] + libc: [glibc] + '@rolldown/binding-linux-s390x-gnu@1.2.2': resolution: {integrity: sha512-412MX9fJLdA1IK28EZnc8jYv2HRTleOZgfLQumJ5zy7OeJLZlg/CETwFaXjNmGVxG51cFHpKLqb5LKvBC+HsHA==} engines: {node: ^20.19.0 || >=22.12.0} @@ -3169,6 +3376,13 @@ packages: os: [linux] libc: [glibc] + '@rolldown/binding-linux-s390x-gnu@1.2.3': + resolution: {integrity: sha512-oyuXxXmoZHjXC917IAPFAAv4wWAa0cM9afk8nx1+9/jNNOX1uPf8yDA6p7G0RypOfw/X0PQt5IfoquY1um+zSg==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [s390x] + os: [linux] + libc: [glibc] + '@rolldown/binding-linux-x64-gnu@1.2.2': resolution: {integrity: sha512-Q/+HI/ToJafZ1iCqGgVQXUEkIjufHCTF0gBQ2a5o3cg7GJ2h0qyq3nvvSmU+bGda2/7ygXpTY4TM6gO9OhQ0ZA==} engines: {node: ^20.19.0 || >=22.12.0} @@ -3176,6 +3390,13 @@ packages: os: [linux] libc: [glibc] + '@rolldown/binding-linux-x64-gnu@1.2.3': + resolution: {integrity: sha512-TytMwF2KVGqP2tgd0I1OY0PAv78dZRAYcF5ssDzjM34SUXCED3uXvSd5+lHoC0bTD6eEdFz7LdQNCO1y0oVk9w==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [x64] + os: [linux] + libc: [glibc] + '@rolldown/binding-linux-x64-musl@1.2.2': resolution: {integrity: sha512-ZKp/w41n6wCvxzxQHtQSbuphfX3Y4cCvbjkKHusrLx4lh+JWLTU7StSltO/DKARISzbj368d+qUaCjI8K2wzXw==} engines: {node: ^20.19.0 || >=22.12.0} @@ -3183,24 +3404,49 @@ packages: os: [linux] libc: [musl] + '@rolldown/binding-linux-x64-musl@1.2.3': + resolution: {integrity: sha512-/E9m3qstrJFVPoULV25mVQblSNExY2+kBsYe4sy0Tn0yOOgJ8wZbZt3KnRbF/XeU2Gl1STKUQnDNTqhIE5MD4A==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [x64] + os: [linux] + libc: [musl] + '@rolldown/binding-openharmony-arm64@1.2.2': resolution: {integrity: sha512-pxE6xD4KS3eAROkKK5yrhB9/3+vhlhVGMvlQLbdpzrBGDbKrnzx3RLwPaHvasLo6jgaiBLn7e04Df9C4tYhjmA==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [openharmony] + '@rolldown/binding-openharmony-arm64@1.2.3': + resolution: {integrity: sha512-Kr0OcsoQI816i6HOl3vFHpd1K0eZyh76zgfj4c1nTyaTsd5r2Mj1lwM4R90y/qaCfmTn9eHy0SKwi98eitRxug==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [openharmony] + '@rolldown/binding-win32-arm64-msvc@1.2.2': resolution: {integrity: sha512-4MqEue5re+xIZzAWsB8sj0P1kqZySWqIuN4t6QaIO/YA6SFwySOLruvWQFzfmqk8LBK2P30KCSJwf6mJCZZ5/A==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [win32] + '@rolldown/binding-win32-arm64-msvc@1.2.3': + resolution: {integrity: sha512-hOtMwTqnME+/gJcH/PCZ0wn0zPUjiWOgkHpxbSJpfGKMezHltx1S7/k1SitzVa7Ww2cqrDDaFbZEhcJZO8o+Jw==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [win32] + '@rolldown/binding-win32-x64-msvc@1.2.2': resolution: {integrity: sha512-NweNxxD0Nf9t8v7kodun45Ijp3EIwYY+uydPP6qBEYvfBqhIjN6dZMzlQja3tqX/aLs3F3Uz+AxDpKgRhpOZQg==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [win32] + '@rolldown/binding-win32-x64-msvc@1.2.3': + resolution: {integrity: sha512-ekcqMMkI2PlhYnfzQnB/cEdYUVVJViWvoUyLrbzgDoi3Snfc1mVBwdnc306ufA5ejy8JSPjT2RlW1nQSjW7efg==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [x64] + os: [win32] + '@rolldown/pluginutils@1.0.1': resolution: {integrity: sha512-2j9bGt5Jh8hj+vPtgzPtl72j0yRxHAyumoo6TNfAjsLB04UtpSvPbPcDcBMxz7n+9CYB0c1GxQFxYRg2jimqGw==} @@ -4998,8 +5244,8 @@ packages: resolution: {integrity: sha512-yPDz7wqpg1/mmHLmS3tcfTfbw5f1eryXvyghYBffGdERwe+mV7ZcWzTR8LR17Kvqt3qfPurjlonmnq3MKXIOXw==} engines: {node: '>= 0.4'} - esbuild-wasm@0.28.1: - resolution: {integrity: sha512-p/GD4E8oYRjg3kjdKrnMb0s4PzXgJF42e0MF4H0+ACyK/kIlFRp3e0fzOleIG+wBBm6MM3XQrbpe7soEA+vJIA==} + esbuild-wasm@0.28.2: + resolution: {integrity: sha512-GccVwhv3mmOUVQHCQm2Ox/rby8n/EqUwvZxE6Pjfikrq/lWw9g9WX/u9EykWnpot3Ko6j426DgQdea2xWKIAQA==} engines: {node: '>=18'} hasBin: true @@ -5008,6 +5254,11 @@ packages: engines: {node: '>=18'} hasBin: true + esbuild@0.28.2: + resolution: {integrity: sha512-HKVLS8dvII+xoKW9kmqxbRKrnWEXfJJr/FZhhJmiqIB0e053QNYFqOBouTMO/k5sID4MvCiUCvv8b9M4h32wIA==} + engines: {node: '>=18'} + hasBin: true + escalade@3.2.0: resolution: {integrity: sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==} engines: {node: '>=6'} @@ -5079,8 +5330,8 @@ packages: resolution: {integrity: sha512-tD40eHxA35h0PEIZNeIjkHoDR4YjjJp34biM0mDvplBe//mB+IHCqHDGV7pxF+7MklTvighcCPPZC7ynWyjdTA==} engines: {node: ^20.19.0 || ^22.13.0 || >=24} - eslint@10.8.0: - resolution: {integrity: sha512-nuKKvN+oIBO0koN7Tm7dlkmnkc21mtt0QJLwAKzjLq14y6lRTdVG36MZHJ8eQHwdJMwZbQNMlPOYedMq/oVJvQ==} + eslint@10.8.1: + resolution: {integrity: sha512-wqA7W2jbsC/BnV9Iv1UZpKVFkO1AdNoSmYW8NWG4HNOBbkAMvIqDZ27pI2f07dqn583NcIC44ckjAcOXDL1QbQ==} engines: {node: ^20.19.0 || ^22.13.0 || >=24} hasBin: true peerDependencies: @@ -6537,6 +6788,11 @@ packages: engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} hasBin: true + nanoid@3.3.18: + resolution: {integrity: sha512-DTg4MJbGMWkfi6VZFdNt2/caMbQy4Ou+Op/hJQvGEWcnVfoA1QA+xzRKAzw9jD6+GVOOeYr/mIcuDSdug6F6+w==} + engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} + hasBin: true + natural-compare@1.4.0: resolution: {integrity: sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==} @@ -6946,6 +7202,10 @@ packages: resolution: {integrity: sha512-DTPx3RWSSnWyzLxQnlH0rJP+EW5ekl16ZU4/psbIhA0e53kJfdgaN5vKM+xP7yJtXVu+nfdVFmlgFDEKAe4Pyw==} engines: {node: ^10 || ^12 || >=14} + postcss@8.5.26: + resolution: {integrity: sha512-u82N74LFzG8ca+dD8puPnplTXoGH4fTPpVGuIbt36G3qvNlkvfD0lEAZSxaly3KX8TS/L1A1gsCEmvKmBcVbkQ==} + engines: {node: ^10 || ^12 || >=14} + powershell-utils@0.1.0: resolution: {integrity: sha512-dM0jVuXJPsDN6DvRpea484tCUaMiXWjuCn++HGTqUWzGDjv5tZkEZldAJ/UMlqRYGFrD/etByo4/xOuC/snX2A==} engines: {node: '>=20'} @@ -7232,6 +7492,11 @@ packages: engines: {node: ^20.19.0 || >=22.12.0} hasBin: true + rolldown@1.2.3: + resolution: {integrity: sha512-rn9wpmxplLf7NLNyCk9FyWh3FM43DbY8jOzCdEPzH7uflhTftRbCEpqi6Ly2osgoU8OwObtmavMbWLaWy4LX7A==} + engines: {node: ^20.19.0 || >=22.12.0} + hasBin: true + rollup-license-plugin@3.2.1: resolution: {integrity: sha512-66iiym49fU6YDJW4DPEYbmUwm4emHXP048lJM9YkecADYGO4cKf0gQZ13U/IqRN00DXbKz0g7O3yOt8m4BNFew==} engines: {node: '>=18.0.0'} @@ -7666,8 +7931,8 @@ packages: teex@1.0.1: resolution: {integrity: sha512-eYE6iEI62Ni1H8oIa7KlDU6uQBtqr4Eajni3wX7rpfXD8ysFx8z0+dri+KWEPWpBsxXfxu58x/0jvTVT1ekOSg==} - terser@5.49.1: - resolution: {integrity: sha512-7A2xlQ5EnGT8KPA92dUh6RbRYTVw8hEaEN9L1K68l4UOXFuV511NnAqObGoRqGOQofQcMypisu1s3xawCEHrvA==} + terser@5.49.2: + resolution: {integrity: sha512-rGbJiKeQ4WDe3EXlDAIaQcwftVfv2Q8o1awFNfvXolJYKkb1AuZY1RTOmqx4LJXZENbWZA7eIsYGHuEzHsi1nQ==} engines: {node: '>=10'} hasBin: true @@ -7986,8 +8251,8 @@ packages: resolution: {integrity: sha512-ZZKSmDAEFOijERBLkmYfJ+vmk3w+7hOLYDNkRCuRuMJGEmqYNCNLyBBFwWKVMhfwaEF3WOd0Zlw86U/WC/+nYw==} engines: {'0': node >=0.6.0} - vite@8.2.0: - resolution: {integrity: sha512-pn+CFpM0lwDeKwmOq1ZaBK/9sjorZcgqxki6MbY/jPEVd9vichIlmlD4HmQ5wdP5EgqQCFRaACBxMC7uEGc6lQ==} + vite@8.2.1: + resolution: {integrity: sha512-EU/eS7BH3XROHh2YnBefjM6DBKA6ZeMZEYQbj7NLWg5wHYlhB8B/Mayd5XsgWq+NFYccDOTemRpdETWR6Ka/lw==} engines: {node: ^20.19.0 || >=22.12.0} hasBin: true peerDependencies: @@ -9287,93 +9552,171 @@ snapshots: '@esbuild/aix-ppc64@0.28.1': optional: true + '@esbuild/aix-ppc64@0.28.2': + optional: true + '@esbuild/android-arm64@0.28.1': optional: true + '@esbuild/android-arm64@0.28.2': + optional: true + '@esbuild/android-arm@0.28.1': optional: true + '@esbuild/android-arm@0.28.2': + optional: true + '@esbuild/android-x64@0.28.1': optional: true + '@esbuild/android-x64@0.28.2': + optional: true + '@esbuild/darwin-arm64@0.28.1': optional: true + '@esbuild/darwin-arm64@0.28.2': + optional: true + '@esbuild/darwin-x64@0.28.1': optional: true + '@esbuild/darwin-x64@0.28.2': + optional: true + '@esbuild/freebsd-arm64@0.28.1': optional: true + '@esbuild/freebsd-arm64@0.28.2': + optional: true + '@esbuild/freebsd-x64@0.28.1': optional: true + '@esbuild/freebsd-x64@0.28.2': + optional: true + '@esbuild/linux-arm64@0.28.1': optional: true + '@esbuild/linux-arm64@0.28.2': + optional: true + '@esbuild/linux-arm@0.28.1': optional: true + '@esbuild/linux-arm@0.28.2': + optional: true + '@esbuild/linux-ia32@0.28.1': optional: true + '@esbuild/linux-ia32@0.28.2': + optional: true + '@esbuild/linux-loong64@0.28.1': optional: true + '@esbuild/linux-loong64@0.28.2': + optional: true + '@esbuild/linux-mips64el@0.28.1': optional: true + '@esbuild/linux-mips64el@0.28.2': + optional: true + '@esbuild/linux-ppc64@0.28.1': optional: true + '@esbuild/linux-ppc64@0.28.2': + optional: true + '@esbuild/linux-riscv64@0.28.1': optional: true + '@esbuild/linux-riscv64@0.28.2': + optional: true + '@esbuild/linux-s390x@0.28.1': optional: true + '@esbuild/linux-s390x@0.28.2': + optional: true + '@esbuild/linux-x64@0.28.1': optional: true + '@esbuild/linux-x64@0.28.2': + optional: true + '@esbuild/netbsd-arm64@0.28.1': optional: true + '@esbuild/netbsd-arm64@0.28.2': + optional: true + '@esbuild/netbsd-x64@0.28.1': optional: true + '@esbuild/netbsd-x64@0.28.2': + optional: true + '@esbuild/openbsd-arm64@0.28.1': optional: true + '@esbuild/openbsd-arm64@0.28.2': + optional: true + '@esbuild/openbsd-x64@0.28.1': optional: true + '@esbuild/openbsd-x64@0.28.2': + optional: true + '@esbuild/openharmony-arm64@0.28.1': optional: true + '@esbuild/openharmony-arm64@0.28.2': + optional: true + '@esbuild/sunos-x64@0.28.1': optional: true + '@esbuild/sunos-x64@0.28.2': + optional: true + '@esbuild/win32-arm64@0.28.1': optional: true + '@esbuild/win32-arm64@0.28.2': + optional: true + '@esbuild/win32-ia32@0.28.1': optional: true + '@esbuild/win32-ia32@0.28.2': + optional: true + '@esbuild/win32-x64@0.28.1': optional: true - '@eslint-community/eslint-utils@4.10.1(eslint@10.8.0(jiti@2.7.0)(supports-color@11.0.0))': + '@esbuild/win32-x64@0.28.2': + optional: true + + '@eslint-community/eslint-utils@4.10.1(eslint@10.8.1(jiti@2.7.0)(supports-color@11.0.0))': dependencies: - eslint: 10.8.0(jiti@2.7.0)(supports-color@11.0.0) + eslint: 10.8.1(jiti@2.7.0)(supports-color@11.0.0) eslint-visitor-keys: 3.4.3 '@eslint-community/regexpp@4.12.2': {} - '@eslint/compat@2.1.0(eslint@10.8.0(jiti@2.7.0)(supports-color@11.0.0))': + '@eslint/compat@2.1.0(eslint@10.8.1(jiti@2.7.0)(supports-color@11.0.0))': dependencies: '@eslint/core': 1.2.1 optionalDependencies: - eslint: 10.8.0(jiti@2.7.0)(supports-color@11.0.0) + eslint: 10.8.1(jiti@2.7.0)(supports-color@11.0.0) '@eslint/config-array@0.23.5(supports-color@11.0.0)': dependencies: @@ -9405,9 +9748,9 @@ snapshots: transitivePeerDependencies: - supports-color - '@eslint/js@10.0.1(eslint@10.8.0(jiti@2.7.0)(supports-color@11.0.0))': + '@eslint/js@10.0.1(eslint@10.8.1(jiti@2.7.0)(supports-color@11.0.0))': optionalDependencies: - eslint: 10.8.0(jiti@2.7.0)(supports-color@11.0.0) + eslint: 10.8.1(jiti@2.7.0)(supports-color@11.0.0) '@eslint/object-schema@3.0.5': {} @@ -10839,45 +11182,87 @@ snapshots: '@rolldown/binding-android-arm64@1.2.2': optional: true + '@rolldown/binding-android-arm64@1.2.3': + optional: true + '@rolldown/binding-darwin-arm64@1.2.2': optional: true + '@rolldown/binding-darwin-arm64@1.2.3': + optional: true + '@rolldown/binding-darwin-x64@1.2.2': optional: true + '@rolldown/binding-darwin-x64@1.2.3': + optional: true + '@rolldown/binding-freebsd-x64@1.2.2': optional: true + '@rolldown/binding-freebsd-x64@1.2.3': + optional: true + '@rolldown/binding-linux-arm-gnueabihf@1.2.2': optional: true + '@rolldown/binding-linux-arm-gnueabihf@1.2.3': + optional: true + '@rolldown/binding-linux-arm64-gnu@1.2.2': optional: true + '@rolldown/binding-linux-arm64-gnu@1.2.3': + optional: true + '@rolldown/binding-linux-arm64-musl@1.2.2': optional: true + '@rolldown/binding-linux-arm64-musl@1.2.3': + optional: true + '@rolldown/binding-linux-ppc64-gnu@1.2.2': optional: true + '@rolldown/binding-linux-ppc64-gnu@1.2.3': + optional: true + '@rolldown/binding-linux-s390x-gnu@1.2.2': optional: true + '@rolldown/binding-linux-s390x-gnu@1.2.3': + optional: true + '@rolldown/binding-linux-x64-gnu@1.2.2': optional: true + '@rolldown/binding-linux-x64-gnu@1.2.3': + optional: true + '@rolldown/binding-linux-x64-musl@1.2.2': optional: true + '@rolldown/binding-linux-x64-musl@1.2.3': + optional: true + '@rolldown/binding-openharmony-arm64@1.2.2': optional: true + '@rolldown/binding-openharmony-arm64@1.2.3': + optional: true + '@rolldown/binding-win32-arm64-msvc@1.2.2': optional: true + '@rolldown/binding-win32-arm64-msvc@1.2.3': + optional: true + '@rolldown/binding-win32-x64-msvc@1.2.2': optional: true + '@rolldown/binding-win32-x64-msvc@1.2.3': + optional: true + '@rolldown/pluginutils@1.0.1': {} '@rollup/plugin-alias@6.0.0(rollup@4.62.4)': @@ -11018,19 +11403,19 @@ snapshots: '@standard-schema/spec@1.1.0': {} - '@stylistic/eslint-plugin@5.10.0(eslint@10.8.0(jiti@2.7.0)(supports-color@11.0.0))': + '@stylistic/eslint-plugin@5.10.0(eslint@10.8.1(jiti@2.7.0)(supports-color@11.0.0))': dependencies: - '@eslint-community/eslint-utils': 4.10.1(eslint@10.8.0(jiti@2.7.0)(supports-color@11.0.0)) + '@eslint-community/eslint-utils': 4.10.1(eslint@10.8.1(jiti@2.7.0)(supports-color@11.0.0)) '@typescript-eslint/types': 8.65.0 - eslint: 10.8.0(jiti@2.7.0)(supports-color@11.0.0) + eslint: 10.8.1(jiti@2.7.0)(supports-color@11.0.0) eslint-visitor-keys: 4.2.1 espree: 10.4.0 estraverse: 5.3.0 picomatch: 4.0.5 - '@tony.ganchev/eslint-plugin-header@3.4.4(eslint@10.8.0(jiti@2.7.0)(supports-color@11.0.0))': + '@tony.ganchev/eslint-plugin-header@3.4.4(eslint@10.8.1(jiti@2.7.0)(supports-color@11.0.0))': dependencies: - eslint: 10.8.0(jiti@2.7.0)(supports-color@11.0.0) + eslint: 10.8.1(jiti@2.7.0)(supports-color@11.0.0) '@types/babel__core@7.20.5': dependencies: @@ -11153,10 +11538,10 @@ snapshots: '@types/less@3.0.8': {} - '@types/loader-utils@3.0.0(esbuild@0.28.1)': + '@types/loader-utils@3.0.0(esbuild@0.28.2)': dependencies: '@types/node': 22.20.1 - webpack: 5.109.2(esbuild@0.28.1) + webpack: 5.109.2(esbuild@0.28.2) transitivePeerDependencies: - '@minify-html/node' - '@swc/core' @@ -11251,15 +11636,15 @@ snapshots: '@types/yarnpkg__lockfile@1.1.9': {} - '@typescript-eslint/eslint-plugin@8.66.0(@typescript-eslint/parser@8.66.0(eslint@10.8.0(jiti@2.7.0)(supports-color@11.0.0))(supports-color@11.0.0)(typescript@6.0.3))(eslint@10.8.0(jiti@2.7.0)(supports-color@11.0.0))(supports-color@11.0.0)(typescript@6.0.3)': + '@typescript-eslint/eslint-plugin@8.66.0(@typescript-eslint/parser@8.66.0(eslint@10.8.1(jiti@2.7.0)(supports-color@11.0.0))(supports-color@11.0.0)(typescript@6.0.3))(eslint@10.8.1(jiti@2.7.0)(supports-color@11.0.0))(supports-color@11.0.0)(typescript@6.0.3)': dependencies: '@eslint-community/regexpp': 4.12.2 - '@typescript-eslint/parser': 8.66.0(eslint@10.8.0(jiti@2.7.0)(supports-color@11.0.0))(supports-color@11.0.0)(typescript@6.0.3) + '@typescript-eslint/parser': 8.66.0(eslint@10.8.1(jiti@2.7.0)(supports-color@11.0.0))(supports-color@11.0.0)(typescript@6.0.3) '@typescript-eslint/scope-manager': 8.66.0 - '@typescript-eslint/type-utils': 8.66.0(eslint@10.8.0(jiti@2.7.0)(supports-color@11.0.0))(supports-color@11.0.0)(typescript@6.0.3) - '@typescript-eslint/utils': 8.66.0(eslint@10.8.0(jiti@2.7.0)(supports-color@11.0.0))(supports-color@11.0.0)(typescript@6.0.3) + '@typescript-eslint/type-utils': 8.66.0(eslint@10.8.1(jiti@2.7.0)(supports-color@11.0.0))(supports-color@11.0.0)(typescript@6.0.3) + '@typescript-eslint/utils': 8.66.0(eslint@10.8.1(jiti@2.7.0)(supports-color@11.0.0))(supports-color@11.0.0)(typescript@6.0.3) '@typescript-eslint/visitor-keys': 8.66.0 - eslint: 10.8.0(jiti@2.7.0)(supports-color@11.0.0) + eslint: 10.8.1(jiti@2.7.0)(supports-color@11.0.0) ignore: 7.0.6 natural-compare: 1.4.0 ts-api-utils: 2.5.0(typescript@6.0.3) @@ -11267,14 +11652,14 @@ snapshots: transitivePeerDependencies: - supports-color - '@typescript-eslint/parser@8.66.0(eslint@10.8.0(jiti@2.7.0)(supports-color@11.0.0))(supports-color@11.0.0)(typescript@6.0.3)': + '@typescript-eslint/parser@8.66.0(eslint@10.8.1(jiti@2.7.0)(supports-color@11.0.0))(supports-color@11.0.0)(typescript@6.0.3)': dependencies: '@typescript-eslint/scope-manager': 8.66.0 '@typescript-eslint/types': 8.66.0 '@typescript-eslint/typescript-estree': 8.66.0(supports-color@11.0.0)(typescript@6.0.3) '@typescript-eslint/visitor-keys': 8.66.0 debug: 4.4.3(supports-color@11.0.0) - eslint: 10.8.0(jiti@2.7.0)(supports-color@11.0.0) + eslint: 10.8.1(jiti@2.7.0)(supports-color@11.0.0) typescript: 6.0.3 transitivePeerDependencies: - supports-color @@ -11297,13 +11682,13 @@ snapshots: dependencies: typescript: 6.0.3 - '@typescript-eslint/type-utils@8.66.0(eslint@10.8.0(jiti@2.7.0)(supports-color@11.0.0))(supports-color@11.0.0)(typescript@6.0.3)': + '@typescript-eslint/type-utils@8.66.0(eslint@10.8.1(jiti@2.7.0)(supports-color@11.0.0))(supports-color@11.0.0)(typescript@6.0.3)': dependencies: '@typescript-eslint/types': 8.66.0 '@typescript-eslint/typescript-estree': 8.66.0(supports-color@11.0.0)(typescript@6.0.3) - '@typescript-eslint/utils': 8.66.0(eslint@10.8.0(jiti@2.7.0)(supports-color@11.0.0))(supports-color@11.0.0)(typescript@6.0.3) + '@typescript-eslint/utils': 8.66.0(eslint@10.8.1(jiti@2.7.0)(supports-color@11.0.0))(supports-color@11.0.0)(typescript@6.0.3) debug: 4.4.3(supports-color@11.0.0) - eslint: 10.8.0(jiti@2.7.0)(supports-color@11.0.0) + eslint: 10.8.1(jiti@2.7.0)(supports-color@11.0.0) ts-api-utils: 2.5.0(typescript@6.0.3) typescript: 6.0.3 transitivePeerDependencies: @@ -11328,13 +11713,13 @@ snapshots: transitivePeerDependencies: - supports-color - '@typescript-eslint/utils@8.66.0(eslint@10.8.0(jiti@2.7.0)(supports-color@11.0.0))(supports-color@11.0.0)(typescript@6.0.3)': + '@typescript-eslint/utils@8.66.0(eslint@10.8.1(jiti@2.7.0)(supports-color@11.0.0))(supports-color@11.0.0)(typescript@6.0.3)': dependencies: - '@eslint-community/eslint-utils': 4.10.1(eslint@10.8.0(jiti@2.7.0)(supports-color@11.0.0)) + '@eslint-community/eslint-utils': 4.10.1(eslint@10.8.1(jiti@2.7.0)(supports-color@11.0.0)) '@typescript-eslint/scope-manager': 8.66.0 '@typescript-eslint/types': 8.66.0 '@typescript-eslint/typescript-estree': 8.66.0(supports-color@11.0.0)(typescript@6.0.3) - eslint: 10.8.0(jiti@2.7.0)(supports-color@11.0.0) + eslint: 10.8.1(jiti@2.7.0)(supports-color@11.0.0) typescript: 6.0.3 transitivePeerDependencies: - supports-color @@ -11507,9 +11892,9 @@ snapshots: lodash: 4.18.1 minimatch: 10.2.5 - '@vitejs/plugin-basic-ssl@2.3.0(vite@8.2.0(@types/node@22.20.1)(esbuild@0.28.1)(jiti@2.7.0)(less@4.8.1(supports-color@11.0.0))(sass@1.102.0)(terser@5.49.1)(tsx@4.23.7)(yaml@2.9.0))': + '@vitejs/plugin-basic-ssl@2.3.0(vite@8.2.1(@types/node@22.20.1)(esbuild@0.28.2)(jiti@2.7.0)(less@4.8.1(supports-color@11.0.0))(sass@1.102.0)(terser@5.49.2)(tsx@4.23.7)(yaml@2.9.0))': dependencies: - vite: 8.2.0(@types/node@22.20.1)(esbuild@0.28.1)(jiti@2.7.0)(less@4.8.1(supports-color@11.0.0))(sass@1.102.0)(terser@5.49.1)(tsx@4.23.7)(yaml@2.9.0) + vite: 8.2.1(@types/node@22.20.1)(esbuild@0.28.2)(jiti@2.7.0)(less@4.8.1(supports-color@11.0.0))(sass@1.102.0)(terser@5.49.2)(tsx@4.23.7)(yaml@2.9.0) '@vitest/coverage-v8@4.1.10(vitest@4.1.10)': dependencies: @@ -11523,7 +11908,7 @@ snapshots: obug: 2.1.4 std-env: 4.2.0 tinyrainbow: 3.1.1 - vitest: 4.1.10(@opentelemetry/api@1.9.1)(@types/node@22.20.1)(@vitest/coverage-v8@4.1.10)(esbuild@0.28.1)(jiti@2.7.0)(jsdom@30.0.1)(less@4.8.1(supports-color@11.0.0))(sass@1.102.0)(terser@5.49.1)(tsx@4.23.7)(yaml@2.9.0) + vitest: 4.1.10(@opentelemetry/api@1.9.1)(@types/node@22.20.1)(@vitest/coverage-v8@4.1.10)(esbuild@0.28.2)(jiti@2.7.0)(jsdom@30.0.1)(less@4.8.1(supports-color@11.0.0))(sass@1.102.0)(terser@5.49.2)(tsx@4.23.7)(yaml@2.9.0) '@vitest/expect@4.1.10': dependencies: @@ -11534,13 +11919,13 @@ snapshots: chai: 6.2.2 tinyrainbow: 3.1.1 - '@vitest/mocker@4.1.10(vite@8.2.0(@types/node@22.20.1)(esbuild@0.28.1)(jiti@2.7.0)(less@4.8.1(supports-color@11.0.0))(sass@1.102.0)(terser@5.49.1)(tsx@4.23.7)(yaml@2.9.0))': + '@vitest/mocker@4.1.10(vite@8.2.1(@types/node@22.20.1)(esbuild@0.28.2)(jiti@2.7.0)(less@4.8.1(supports-color@11.0.0))(sass@1.102.0)(terser@5.49.2)(tsx@4.23.7)(yaml@2.9.0))': dependencies: '@vitest/spy': 4.1.10 estree-walker: 3.0.3 magic-string: 0.30.21 optionalDependencies: - vite: 8.2.0(@types/node@22.20.1)(esbuild@0.28.1)(jiti@2.7.0)(less@4.8.1(supports-color@11.0.0))(sass@1.102.0)(terser@5.49.1)(tsx@4.23.7)(yaml@2.9.0) + vite: 8.2.1(@types/node@22.20.1)(esbuild@0.28.2)(jiti@2.7.0)(less@4.8.1(supports-color@11.0.0))(sass@1.102.0)(terser@5.49.2)(tsx@4.23.7)(yaml@2.9.0) '@vitest/pretty-format@4.1.10': dependencies: @@ -11914,13 +12299,13 @@ snapshots: atomic-sleep@1.0.0: {} - autoprefixer@10.5.4(postcss@8.5.25): + autoprefixer@10.5.4(postcss@8.5.26): dependencies: browserslist: 4.28.7 caniuse-lite: 1.0.30001806 fraction.js: 5.3.4 picocolors: 1.1.1 - postcss: 8.5.25 + postcss: 8.5.26 postcss-value-parser: 4.2.0 available-typed-arrays@1.0.7: @@ -11933,12 +12318,12 @@ snapshots: b4a@1.8.1: {} - babel-loader@10.1.1(@babel/core@8.0.1)(webpack@5.109.2(esbuild@0.28.1)(lightningcss@1.33.0)(postcss@8.5.25)(uglify-js@3.19.3)): + babel-loader@10.1.1(@babel/core@8.0.1)(webpack@5.109.2(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.26)(uglify-js@3.19.3)): dependencies: '@babel/core': 8.0.1 find-up: 5.0.0 optionalDependencies: - webpack: 5.109.2(esbuild@0.28.1)(lightningcss@1.33.0)(postcss@8.5.25)(uglify-js@3.19.3) + webpack: 5.109.2(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.26)(uglify-js@3.19.3) babel-plugin-polyfill-corejs3@1.0.0(@babel/core@8.0.1): dependencies: @@ -12001,9 +12386,9 @@ snapshots: domhandler: 5.0.3 htmlparser2: 10.1.0 picocolors: 1.1.1 - postcss: 8.5.25 + postcss: 8.5.26 postcss-media-query-parser: 0.2.3 - postcss-safe-parser: 7.0.1(postcss@8.5.25) + postcss-safe-parser: 7.0.1(postcss@8.5.26) before-after-hook@4.0.0: {} @@ -12391,14 +12776,14 @@ snapshots: dependencies: is-what: 4.1.16 - copy-webpack-plugin@14.0.0(webpack@5.109.2(esbuild@0.28.1)(lightningcss@1.33.0)(postcss@8.5.25)(uglify-js@3.19.3)): + copy-webpack-plugin@14.0.0(webpack@5.109.2(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.26)(uglify-js@3.19.3)): dependencies: glob-parent: 6.0.2 normalize-path: 3.0.0 schema-utils: 4.3.3 serialize-javascript: 7.0.7 tinyglobby: 0.2.17 - webpack: 5.109.2(esbuild@0.28.1)(lightningcss@1.33.0)(postcss@8.5.25)(uglify-js@3.19.3) + webpack: 5.109.2(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.26)(uglify-js@3.19.3) core-js-compat@3.49.0: dependencies: @@ -12428,18 +12813,18 @@ snapshots: shebang-command: 2.0.0 which: 2.0.2 - css-loader@7.1.4(webpack@5.109.2(esbuild@0.28.1)(lightningcss@1.33.0)(postcss@8.5.25)(uglify-js@3.19.3)): + css-loader@7.1.4(webpack@5.109.2(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.26)(uglify-js@3.19.3)): dependencies: - icss-utils: 5.1.0(postcss@8.5.25) - postcss: 8.5.25 - postcss-modules-extract-imports: 3.1.0(postcss@8.5.25) - postcss-modules-local-by-default: 4.2.0(postcss@8.5.25) - postcss-modules-scope: 3.2.1(postcss@8.5.25) - postcss-modules-values: 4.0.0(postcss@8.5.25) + icss-utils: 5.1.0(postcss@8.5.26) + postcss: 8.5.26 + postcss-modules-extract-imports: 3.1.0(postcss@8.5.26) + postcss-modules-local-by-default: 4.2.0(postcss@8.5.26) + postcss-modules-scope: 3.2.1(postcss@8.5.26) + postcss-modules-values: 4.0.0(postcss@8.5.26) postcss-value-parser: 4.2.0 semver: 7.8.5 optionalDependencies: - webpack: 5.109.2(esbuild@0.28.1)(lightningcss@1.33.0)(postcss@8.5.25)(uglify-js@3.19.3) + webpack: 5.109.2(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.26)(uglify-js@3.19.3) css-select@6.0.0: dependencies: @@ -12834,7 +13219,7 @@ snapshots: is-date-object: 1.1.0 is-symbol: 1.1.1 - esbuild-wasm@0.28.1: {} + esbuild-wasm@0.28.2: {} esbuild@0.28.1: optionalDependencies: @@ -12865,15 +13250,44 @@ snapshots: '@esbuild/win32-ia32': 0.28.1 '@esbuild/win32-x64': 0.28.1 + esbuild@0.28.2: + optionalDependencies: + '@esbuild/aix-ppc64': 0.28.2 + '@esbuild/android-arm': 0.28.2 + '@esbuild/android-arm64': 0.28.2 + '@esbuild/android-x64': 0.28.2 + '@esbuild/darwin-arm64': 0.28.2 + '@esbuild/darwin-x64': 0.28.2 + '@esbuild/freebsd-arm64': 0.28.2 + '@esbuild/freebsd-x64': 0.28.2 + '@esbuild/linux-arm': 0.28.2 + '@esbuild/linux-arm64': 0.28.2 + '@esbuild/linux-ia32': 0.28.2 + '@esbuild/linux-loong64': 0.28.2 + '@esbuild/linux-mips64el': 0.28.2 + '@esbuild/linux-ppc64': 0.28.2 + '@esbuild/linux-riscv64': 0.28.2 + '@esbuild/linux-s390x': 0.28.2 + '@esbuild/linux-x64': 0.28.2 + '@esbuild/netbsd-arm64': 0.28.2 + '@esbuild/netbsd-x64': 0.28.2 + '@esbuild/openbsd-arm64': 0.28.2 + '@esbuild/openbsd-x64': 0.28.2 + '@esbuild/openharmony-arm64': 0.28.2 + '@esbuild/sunos-x64': 0.28.2 + '@esbuild/win32-arm64': 0.28.2 + '@esbuild/win32-ia32': 0.28.2 + '@esbuild/win32-x64': 0.28.2 + escalade@3.2.0: {} escape-html@1.0.3: {} escape-string-regexp@4.0.0: {} - eslint-config-prettier@10.1.8(eslint@10.8.0(jiti@2.7.0)(supports-color@11.0.0)): + eslint-config-prettier@10.1.8(eslint@10.8.1(jiti@2.7.0)(supports-color@11.0.0)): dependencies: - eslint: 10.8.0(jiti@2.7.0)(supports-color@11.0.0) + eslint: 10.8.1(jiti@2.7.0)(supports-color@11.0.0) eslint-import-resolver-node@0.3.10(supports-color@11.0.0): dependencies: @@ -12883,17 +13297,17 @@ snapshots: transitivePeerDependencies: - supports-color - eslint-module-utils@2.14.0(@typescript-eslint/parser@8.66.0(eslint@10.8.0(jiti@2.7.0)(supports-color@11.0.0))(supports-color@11.0.0)(typescript@6.0.3))(eslint-import-resolver-node@0.3.10(supports-color@11.0.0))(eslint@10.8.0(jiti@2.7.0)(supports-color@11.0.0))(supports-color@11.0.0): + eslint-module-utils@2.14.0(@typescript-eslint/parser@8.66.0(eslint@10.8.1(jiti@2.7.0)(supports-color@11.0.0))(supports-color@11.0.0)(typescript@6.0.3))(eslint-import-resolver-node@0.3.10(supports-color@11.0.0))(eslint@10.8.1(jiti@2.7.0)(supports-color@11.0.0))(supports-color@11.0.0): dependencies: debug: 3.2.7(supports-color@11.0.0) optionalDependencies: - '@typescript-eslint/parser': 8.66.0(eslint@10.8.0(jiti@2.7.0)(supports-color@11.0.0))(supports-color@11.0.0)(typescript@6.0.3) - eslint: 10.8.0(jiti@2.7.0)(supports-color@11.0.0) + '@typescript-eslint/parser': 8.66.0(eslint@10.8.1(jiti@2.7.0)(supports-color@11.0.0))(supports-color@11.0.0)(typescript@6.0.3) + eslint: 10.8.1(jiti@2.7.0)(supports-color@11.0.0) eslint-import-resolver-node: 0.3.10(supports-color@11.0.0) transitivePeerDependencies: - supports-color - eslint-plugin-import@2.32.0(@typescript-eslint/parser@8.66.0(eslint@10.8.0(jiti@2.7.0)(supports-color@11.0.0))(supports-color@11.0.0)(typescript@6.0.3))(eslint@10.8.0(jiti@2.7.0)(supports-color@11.0.0))(supports-color@11.0.0): + eslint-plugin-import@2.32.0(@typescript-eslint/parser@8.66.0(eslint@10.8.1(jiti@2.7.0)(supports-color@11.0.0))(supports-color@11.0.0)(typescript@6.0.3))(eslint@10.8.1(jiti@2.7.0)(supports-color@11.0.0))(supports-color@11.0.0): dependencies: '@rtsao/scc': 1.1.0 array-includes: 3.1.9 @@ -12902,9 +13316,9 @@ snapshots: array.prototype.flatmap: 1.3.3 debug: 3.2.7(supports-color@11.0.0) doctrine: 2.1.0 - eslint: 10.8.0(jiti@2.7.0)(supports-color@11.0.0) + eslint: 10.8.1(jiti@2.7.0)(supports-color@11.0.0) eslint-import-resolver-node: 0.3.10(supports-color@11.0.0) - eslint-module-utils: 2.14.0(@typescript-eslint/parser@8.66.0(eslint@10.8.0(jiti@2.7.0)(supports-color@11.0.0))(supports-color@11.0.0)(typescript@6.0.3))(eslint-import-resolver-node@0.3.10(supports-color@11.0.0))(eslint@10.8.0(jiti@2.7.0)(supports-color@11.0.0))(supports-color@11.0.0) + eslint-module-utils: 2.14.0(@typescript-eslint/parser@8.66.0(eslint@10.8.1(jiti@2.7.0)(supports-color@11.0.0))(supports-color@11.0.0)(typescript@6.0.3))(eslint-import-resolver-node@0.3.10(supports-color@11.0.0))(eslint@10.8.1(jiti@2.7.0)(supports-color@11.0.0))(supports-color@11.0.0) hasown: 2.0.4 is-core-module: 2.16.2 is-glob: 4.0.3 @@ -12916,7 +13330,7 @@ snapshots: string.prototype.trimend: 1.0.10 tsconfig-paths: 3.15.0 optionalDependencies: - '@typescript-eslint/parser': 8.66.0(eslint@10.8.0(jiti@2.7.0)(supports-color@11.0.0))(supports-color@11.0.0)(typescript@6.0.3) + '@typescript-eslint/parser': 8.66.0(eslint@10.8.1(jiti@2.7.0)(supports-color@11.0.0))(supports-color@11.0.0)(typescript@6.0.3) transitivePeerDependencies: - eslint-import-resolver-typescript - eslint-import-resolver-webpack @@ -12940,9 +13354,9 @@ snapshots: eslint-visitor-keys@5.0.1: {} - eslint@10.8.0(jiti@2.7.0)(supports-color@11.0.0): + eslint@10.8.1(jiti@2.7.0)(supports-color@11.0.0): dependencies: - '@eslint-community/eslint-utils': 4.10.1(eslint@10.8.0(jiti@2.7.0)(supports-color@11.0.0)) + '@eslint-community/eslint-utils': 4.10.1(eslint@10.8.1(jiti@2.7.0)(supports-color@11.0.0)) '@eslint-community/regexpp': 4.12.2 '@eslint/config-array': 0.23.5(supports-color@11.0.0) '@eslint/config-helpers': 0.7.0 @@ -13706,9 +14120,9 @@ snapshots: dependencies: safer-buffer: 2.1.2 - icss-utils@5.1.0(postcss@8.5.25): + icss-utils@5.1.0(postcss@8.5.26): dependencies: - postcss: 8.5.25 + postcss: 8.5.26 idb@7.1.1: {} @@ -14212,12 +14626,12 @@ snapshots: picocolors: 1.1.1 shell-quote: 1.10.0 - less-loader@13.0.0(less@4.8.1(supports-color@11.0.0))(webpack@5.109.2(esbuild@0.28.1)(lightningcss@1.33.0)(postcss@8.5.25)(uglify-js@3.19.3)): + less-loader@13.0.0(less@4.8.1(supports-color@11.0.0))(webpack@5.109.2(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.26)(uglify-js@3.19.3)): dependencies: '@types/less': 3.0.8 less: 4.8.1(supports-color@11.0.0) optionalDependencies: - webpack: 5.109.2(esbuild@0.28.1)(lightningcss@1.33.0)(postcss@8.5.25)(uglify-js@3.19.3) + webpack: 5.109.2(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.26)(uglify-js@3.19.3) less@4.8.1(supports-color@11.0.0): dependencies: @@ -14239,11 +14653,11 @@ snapshots: prelude-ls: 1.2.1 type-check: 0.4.0 - license-webpack-plugin@4.0.2(webpack@5.109.2(esbuild@0.28.1)(lightningcss@1.33.0)(postcss@8.5.25)(uglify-js@3.19.3)): + license-webpack-plugin@4.0.2(webpack@5.109.2(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.26)(uglify-js@3.19.3)): dependencies: webpack-sources: 3.5.1 optionalDependencies: - webpack: 5.109.2(esbuild@0.28.1)(lightningcss@1.33.0)(postcss@8.5.25)(uglify-js@3.19.3) + webpack: 5.109.2(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.26)(uglify-js@3.19.3) lightningcss-android-arm64@1.33.0: optional: true @@ -14498,11 +14912,11 @@ snapshots: mimic-response@4.0.0: {} - mini-css-extract-plugin@2.10.2(webpack@5.109.2(esbuild@0.28.1)(lightningcss@1.33.0)(postcss@8.5.25)(uglify-js@3.19.3)): + mini-css-extract-plugin@2.10.2(webpack@5.109.2(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.26)(uglify-js@3.19.3)): dependencies: schema-utils: 4.3.3 tapable: 2.3.3 - webpack: 5.109.2(esbuild@0.28.1)(lightningcss@1.33.0)(postcss@8.5.25)(uglify-js@3.19.3) + webpack: 5.109.2(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.26)(uglify-js@3.19.3) minimatch@10.2.5: dependencies: @@ -14526,28 +14940,28 @@ snapshots: minimist@1.2.8: {} - minimizer-webpack-plugin@5.6.1(esbuild@0.28.1)(lightningcss@1.33.0)(postcss@8.5.25)(uglify-js@3.19.3)(webpack@5.109.2(esbuild@0.28.1)(lightningcss@1.33.0)(postcss@8.5.25)(uglify-js@3.19.3)): + minimizer-webpack-plugin@5.6.1(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.26)(uglify-js@3.19.3)(webpack@5.109.2(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.26)(uglify-js@3.19.3)): dependencies: '@jridgewell/trace-mapping': 0.3.31 jest-worker: 27.5.1 schema-utils: 4.3.3 - terser: 5.49.1 - webpack: 5.109.2(esbuild@0.28.1)(lightningcss@1.33.0)(postcss@8.5.25)(uglify-js@3.19.3) + terser: 5.49.2 + webpack: 5.109.2(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.26)(uglify-js@3.19.3) optionalDependencies: - esbuild: 0.28.1 + esbuild: 0.28.2 lightningcss: 1.33.0 - postcss: 8.5.25 + postcss: 8.5.26 uglify-js: 3.19.3 - minimizer-webpack-plugin@5.6.1(esbuild@0.28.1)(webpack@5.109.2(esbuild@0.28.1)): + minimizer-webpack-plugin@5.6.1(esbuild@0.28.2)(webpack@5.109.2(esbuild@0.28.2)): dependencies: '@jridgewell/trace-mapping': 0.3.31 jest-worker: 27.5.1 schema-utils: 4.3.3 - terser: 5.49.1 - webpack: 5.109.2(esbuild@0.28.1) + terser: 5.49.2 + webpack: 5.109.2(esbuild@0.28.2) optionalDependencies: - esbuild: 0.28.1 + esbuild: 0.28.2 minipass@7.1.3: {} @@ -14601,6 +15015,8 @@ snapshots: nanoid@3.3.16: {} + nanoid@3.3.18: {} + natural-compare@1.4.0: {} needle@2.9.1(supports-color@11.0.0): @@ -14635,16 +15051,16 @@ snapshots: chokidar: 5.0.0 commander: 15.0.0 dependency-graph: 1.0.0 - esbuild: 0.28.1 + esbuild: 0.28.2 find-cache-directory: 6.0.0 injection-js: 2.6.1 jsonc-parser: 3.3.1 less: 4.8.1(supports-color@11.0.0) ora: 9.4.1 piscina: 5.3.0 - postcss: 8.5.25 - rolldown: 1.2.2 - rolldown-plugin-dts: 0.27.14(rolldown@1.2.2)(typescript@6.0.3) + postcss: 8.5.26 + rolldown: 1.2.3 + rolldown-plugin-dts: 0.27.14(rolldown@1.2.3)(typescript@6.0.3) rxjs: 7.8.2 sass: 1.102.0 tinyglobby: 0.2.17 @@ -15006,43 +15422,43 @@ snapshots: possible-typed-array-names@1.1.0: {} - postcss-loader@8.2.1(postcss@8.5.25)(typescript@6.0.3)(webpack@5.109.2(esbuild@0.28.1)(lightningcss@1.33.0)(postcss@8.5.25)(uglify-js@3.19.3)): + postcss-loader@8.2.1(postcss@8.5.26)(typescript@6.0.3)(webpack@5.109.2(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.26)(uglify-js@3.19.3)): dependencies: cosmiconfig: 9.0.2(typescript@6.0.3) jiti: 2.7.0 - postcss: 8.5.25 + postcss: 8.5.26 semver: 7.8.5 optionalDependencies: - webpack: 5.109.2(esbuild@0.28.1)(lightningcss@1.33.0)(postcss@8.5.25)(uglify-js@3.19.3) + webpack: 5.109.2(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.26)(uglify-js@3.19.3) transitivePeerDependencies: - typescript postcss-media-query-parser@0.2.3: {} - postcss-modules-extract-imports@3.1.0(postcss@8.5.25): + postcss-modules-extract-imports@3.1.0(postcss@8.5.26): dependencies: - postcss: 8.5.25 + postcss: 8.5.26 - postcss-modules-local-by-default@4.2.0(postcss@8.5.25): + postcss-modules-local-by-default@4.2.0(postcss@8.5.26): dependencies: - icss-utils: 5.1.0(postcss@8.5.25) - postcss: 8.5.25 + icss-utils: 5.1.0(postcss@8.5.26) + postcss: 8.5.26 postcss-selector-parser: 7.1.4 postcss-value-parser: 4.2.0 - postcss-modules-scope@3.2.1(postcss@8.5.25): + postcss-modules-scope@3.2.1(postcss@8.5.26): dependencies: - postcss: 8.5.25 + postcss: 8.5.26 postcss-selector-parser: 7.1.4 - postcss-modules-values@4.0.0(postcss@8.5.25): + postcss-modules-values@4.0.0(postcss@8.5.26): dependencies: - icss-utils: 5.1.0(postcss@8.5.25) - postcss: 8.5.25 + icss-utils: 5.1.0(postcss@8.5.26) + postcss: 8.5.26 - postcss-safe-parser@7.0.1(postcss@8.5.25): + postcss-safe-parser@7.0.1(postcss@8.5.26): dependencies: - postcss: 8.5.25 + postcss: 8.5.26 postcss-selector-parser@7.1.4: dependencies: @@ -15057,6 +15473,12 @@ snapshots: picocolors: 1.1.1 source-map-js: 1.2.1 + postcss@8.5.26: + dependencies: + nanoid: 3.3.18 + picocolors: 1.1.1 + source-map-js: 1.2.1 + powershell-utils@0.1.0: {} prelude-ls@1.2.1: {} @@ -15312,7 +15734,7 @@ snapshots: adjust-sourcemap-loader: 4.0.0 convert-source-map: 1.9.0 loader-utils: 2.0.4 - postcss: 8.5.25 + postcss: 8.5.26 source-map: 0.6.1 resolve@1.22.12: @@ -15368,12 +15790,12 @@ snapshots: dependencies: glob: 10.5.0 - rolldown-plugin-dts@0.27.14(rolldown@1.2.2)(typescript@6.0.3): + rolldown-plugin-dts@0.27.14(rolldown@1.2.3)(typescript@6.0.3): dependencies: dts-resolver: 3.0.0 get-tsconfig: 5.0.0-beta.5 obug: 2.1.4 - rolldown: 1.2.2 + rolldown: 1.2.3 yuku-ast: 0.8.3 yuku-codegen: 0.8.3 yuku-parser: 0.8.3 @@ -15402,6 +15824,26 @@ snapshots: '@rolldown/binding-win32-arm64-msvc': 1.2.2 '@rolldown/binding-win32-x64-msvc': 1.2.2 + rolldown@1.2.3: + dependencies: + '@oxc-project/types': 0.143.0 + '@rolldown/pluginutils': 1.0.1 + optionalDependencies: + '@rolldown/binding-android-arm64': 1.2.3 + '@rolldown/binding-darwin-arm64': 1.2.3 + '@rolldown/binding-darwin-x64': 1.2.3 + '@rolldown/binding-freebsd-x64': 1.2.3 + '@rolldown/binding-linux-arm-gnueabihf': 1.2.3 + '@rolldown/binding-linux-arm64-gnu': 1.2.3 + '@rolldown/binding-linux-arm64-musl': 1.2.3 + '@rolldown/binding-linux-ppc64-gnu': 1.2.3 + '@rolldown/binding-linux-s390x-gnu': 1.2.3 + '@rolldown/binding-linux-x64-gnu': 1.2.3 + '@rolldown/binding-linux-x64-musl': 1.2.3 + '@rolldown/binding-openharmony-arm64': 1.2.3 + '@rolldown/binding-win32-arm64-msvc': 1.2.3 + '@rolldown/binding-win32-x64-msvc': 1.2.3 + rollup-license-plugin@3.2.1: dependencies: get-npm-tarball-url: 2.1.0 @@ -15512,10 +15954,10 @@ snapshots: dependencies: truncate-utf8-bytes: 1.0.2 - sass-loader@17.0.0(sass@1.102.0)(webpack@5.109.2(esbuild@0.28.1)(lightningcss@1.33.0)(postcss@8.5.25)(uglify-js@3.19.3)): + sass-loader@17.0.0(sass@1.102.0)(webpack@5.109.2(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.26)(uglify-js@3.19.3)): optionalDependencies: sass: 1.102.0 - webpack: 5.109.2(esbuild@0.28.1)(lightningcss@1.33.0)(postcss@8.5.25)(uglify-js@3.19.3) + webpack: 5.109.2(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.26)(uglify-js@3.19.3) sass@1.102.0: dependencies: @@ -15744,11 +16186,11 @@ snapshots: source-map-js@1.2.1: {} - source-map-loader@5.0.0(webpack@5.109.2(esbuild@0.28.1)(lightningcss@1.33.0)(postcss@8.5.25)(uglify-js@3.19.3)): + source-map-loader@5.0.0(webpack@5.109.2(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.26)(uglify-js@3.19.3)): dependencies: iconv-lite: 0.6.3 source-map-js: 1.2.1 - webpack: 5.109.2(esbuild@0.28.1)(lightningcss@1.33.0)(postcss@8.5.25)(uglify-js@3.19.3) + webpack: 5.109.2(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.26)(uglify-js@3.19.3) source-map-support@0.5.21: dependencies: @@ -15973,7 +16415,7 @@ snapshots: - bare-abort-controller - react-native-b4a - terser@5.49.1: + terser@5.49.2: dependencies: '@jridgewell/source-map': 0.3.11 acorn: 8.18.0 @@ -16326,7 +16768,7 @@ snapshots: core-util-is: 1.0.2 extsprintf: 1.3.0 - vite@8.2.0(@types/node@22.20.1)(esbuild@0.28.1)(jiti@2.7.0)(less@4.8.1(supports-color@11.0.0))(sass@1.102.0)(terser@5.49.1)(tsx@4.23.7)(yaml@2.9.0): + vite@8.2.1(@types/node@22.20.1)(esbuild@0.28.2)(jiti@2.7.0)(less@4.8.1(supports-color@11.0.0))(sass@1.102.0)(terser@5.49.2)(tsx@4.23.7)(yaml@2.9.0): dependencies: lightningcss: 1.33.0 picomatch: 4.0.5 @@ -16335,19 +16777,19 @@ snapshots: tinyglobby: 0.2.17 optionalDependencies: '@types/node': 22.20.1 - esbuild: 0.28.1 + esbuild: 0.28.2 fsevents: 2.3.3 jiti: 2.7.0 less: 4.8.1(supports-color@11.0.0) sass: 1.102.0 - terser: 5.49.1 + terser: 5.49.2 tsx: 4.23.7 yaml: 2.9.0 - vitest@4.1.10(@opentelemetry/api@1.9.1)(@types/node@22.20.1)(@vitest/coverage-v8@4.1.10)(esbuild@0.28.1)(jiti@2.7.0)(jsdom@30.0.1)(less@4.8.1(supports-color@11.0.0))(sass@1.102.0)(terser@5.49.1)(tsx@4.23.7)(yaml@2.9.0): + vitest@4.1.10(@opentelemetry/api@1.9.1)(@types/node@22.20.1)(@vitest/coverage-v8@4.1.10)(esbuild@0.28.2)(jiti@2.7.0)(jsdom@30.0.1)(less@4.8.1(supports-color@11.0.0))(sass@1.102.0)(terser@5.49.2)(tsx@4.23.7)(yaml@2.9.0): dependencies: '@vitest/expect': 4.1.10 - '@vitest/mocker': 4.1.10(vite@8.2.0(@types/node@22.20.1)(esbuild@0.28.1)(jiti@2.7.0)(less@4.8.1(supports-color@11.0.0))(sass@1.102.0)(terser@5.49.1)(tsx@4.23.7)(yaml@2.9.0)) + '@vitest/mocker': 4.1.10(vite@8.2.1(@types/node@22.20.1)(esbuild@0.28.2)(jiti@2.7.0)(less@4.8.1(supports-color@11.0.0))(sass@1.102.0)(terser@5.49.2)(tsx@4.23.7)(yaml@2.9.0)) '@vitest/pretty-format': 4.1.10 '@vitest/runner': 4.1.10 '@vitest/snapshot': 4.1.10 @@ -16364,7 +16806,7 @@ snapshots: tinyexec: 1.3.0 tinyglobby: 0.2.17 tinyrainbow: 3.1.1 - vite: 8.2.0(@types/node@22.20.1)(esbuild@0.28.1)(jiti@2.7.0)(less@4.8.1(supports-color@11.0.0))(sass@1.102.0)(terser@5.49.1)(tsx@4.23.7)(yaml@2.9.0) + vite: 8.2.1(@types/node@22.20.1)(esbuild@0.28.2)(jiti@2.7.0)(less@4.8.1(supports-color@11.0.0))(sass@1.102.0)(terser@5.49.2)(tsx@4.23.7)(yaml@2.9.0) why-is-node-running: 2.3.0 optionalDependencies: '@opentelemetry/api': 1.9.1 @@ -16408,18 +16850,18 @@ snapshots: webidl-conversions@8.0.1: {} - webpack-dev-middleware@8.1.1(tslib@2.8.1)(webpack@5.109.2(esbuild@0.28.1)(lightningcss@1.33.0)(postcss@8.5.25)(uglify-js@3.19.3)): + webpack-dev-middleware@8.1.1(tslib@2.8.1)(webpack@5.109.2(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.26)(uglify-js@3.19.3)): dependencies: memfs: 4.64.0(tslib@2.8.1) mime-types: 3.0.2 range-parser: 1.3.0 schema-utils: 4.3.3 optionalDependencies: - webpack: 5.109.2(esbuild@0.28.1)(lightningcss@1.33.0)(postcss@8.5.25)(uglify-js@3.19.3) + webpack: 5.109.2(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.26)(uglify-js@3.19.3) transitivePeerDependencies: - tslib - webpack-dev-server@6.0.0(bufferutil@4.1.0)(supports-color@11.0.0)(tslib@2.8.1)(utf-8-validate@6.0.6)(webpack@5.109.2(esbuild@0.28.1)(lightningcss@1.33.0)(postcss@8.5.25)(uglify-js@3.19.3)): + webpack-dev-server@6.0.0(bufferutil@4.1.0)(supports-color@11.0.0)(tslib@2.8.1)(utf-8-validate@6.0.6)(webpack@5.109.2(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.26)(uglify-js@3.19.3)): dependencies: '@types/bonjour': 3.5.13 '@types/connect-history-api-fallback': 1.5.4 @@ -16444,10 +16886,10 @@ snapshots: selfsigned: 5.5.0 serve-index: 1.9.2(supports-color@11.0.0) tinyglobby: 0.2.17 - webpack-dev-middleware: 8.1.1(tslib@2.8.1)(webpack@5.109.2(esbuild@0.28.1)(lightningcss@1.33.0)(postcss@8.5.25)(uglify-js@3.19.3)) + webpack-dev-middleware: 8.1.1(tslib@2.8.1)(webpack@5.109.2(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.26)(uglify-js@3.19.3)) ws: 8.21.1(bufferutil@4.1.0)(utf-8-validate@6.0.6) optionalDependencies: - webpack: 5.109.2(esbuild@0.28.1)(lightningcss@1.33.0)(postcss@8.5.25)(uglify-js@3.19.3) + webpack: 5.109.2(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.26)(uglify-js@3.19.3) transitivePeerDependencies: - bufferutil - supports-color @@ -16462,12 +16904,12 @@ snapshots: webpack-sources@3.5.1: {} - webpack-subresource-integrity@5.1.0(webpack@5.109.2(esbuild@0.28.1)(lightningcss@1.33.0)(postcss@8.5.25)(uglify-js@3.19.3)): + webpack-subresource-integrity@5.1.0(webpack@5.109.2(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.26)(uglify-js@3.19.3)): dependencies: typed-assert: 1.0.9 - webpack: 5.109.2(esbuild@0.28.1)(lightningcss@1.33.0)(postcss@8.5.25)(uglify-js@3.19.3) + webpack: 5.109.2(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.26)(uglify-js@3.19.3) - webpack@5.109.2(esbuild@0.28.1): + webpack@5.109.2(esbuild@0.28.2): dependencies: '@types/estree': 1.0.9 '@types/json-schema': 7.0.15 @@ -16483,7 +16925,7 @@ snapshots: events: 3.3.0 graceful-fs: 4.2.11 mime-db: 1.54.0 - minimizer-webpack-plugin: 5.6.1(esbuild@0.28.1)(webpack@5.109.2(esbuild@0.28.1)) + minimizer-webpack-plugin: 5.6.1(esbuild@0.28.2)(webpack@5.109.2(esbuild@0.28.2)) neo-async: 2.6.2 schema-utils: 4.3.3 tapable: 2.3.3 @@ -16503,7 +16945,7 @@ snapshots: - postcss - uglify-js - webpack@5.109.2(esbuild@0.28.1)(lightningcss@1.33.0)(postcss@8.5.25)(uglify-js@3.19.3): + webpack@5.109.2(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.26)(uglify-js@3.19.3): dependencies: '@types/estree': 1.0.9 '@types/json-schema': 7.0.15 @@ -16519,7 +16961,7 @@ snapshots: events: 3.3.0 graceful-fs: 4.2.11 mime-db: 1.54.0 - minimizer-webpack-plugin: 5.6.1(esbuild@0.28.1)(lightningcss@1.33.0)(postcss@8.5.25)(uglify-js@3.19.3)(webpack@5.109.2(esbuild@0.28.1)(lightningcss@1.33.0)(postcss@8.5.25)(uglify-js@3.19.3)) + minimizer-webpack-plugin: 5.6.1(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.26)(uglify-js@3.19.3)(webpack@5.109.2(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.26)(uglify-js@3.19.3)) neo-async: 2.6.2 schema-utils: 4.3.3 tapable: 2.3.3 From 7112b75ce9800e0a442cac07d55d80e45c9087a9 Mon Sep 17 00:00:00 2001 From: Charles Lyding <19598772+clydin@users.noreply.github.com> Date: Mon, 10 Aug 2026 14:29:48 -0400 Subject: [PATCH 281/787] refactor(@angular/build): bypass worker dispatch for non-Angular files with byte-level linker pre-check MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit In AOT compilation mode, JavaScript files loaded from node_modules are processed with `skipLinker: false`. Previously, `requiresLinking` was only evaluated inside worker threads after string decoding, forcing every 3rd-party dependency to be dispatched to the Piscina worker pool even when no linking or transformations were needed (such as during development server runs). This commit introduces a fast byte-level pre-check for the Angular partial declaration prefix (`ɵɵngDeclare`) directly in `JavaScriptTransformer.transformData` on the main thread. By scanning incoming raw buffers with `Buffer.indexOf` before thread dispatch, files that do not require linking (and have no advanced optimizations or coverage enabled) can bypass worker thread scheduling, message serialization, and string decoding entirely. --- .../esbuild/javascript-transformer-worker.ts | 23 +---- .../tools/esbuild/javascript-transformer.ts | 33 +++++++- .../esbuild/javascript-transformer_spec.ts | 83 +++++++++++++++++++ 3 files changed, 115 insertions(+), 24 deletions(-) diff --git a/packages/angular/build/src/tools/esbuild/javascript-transformer-worker.ts b/packages/angular/build/src/tools/esbuild/javascript-transformer-worker.ts index 603ca375df22..74ff839ffdab 100644 --- a/packages/angular/build/src/tools/esbuild/javascript-transformer-worker.ts +++ b/packages/angular/build/src/tools/esbuild/javascript-transformer-worker.ts @@ -39,14 +39,6 @@ const textDecoder = new TextDecoder(); const textEncoder = new TextEncoder(); const SOURCEMAP_COMMENT_BYTES = Buffer.from('//# sourceMappingURL='); -/** - * The function name prefix for all Angular partial compilation functions. - * Used to determine if linking of a JavaScript file is required. - * If any additional declarations are added or otherwise changed in the linker, - * the names MUST begin with this prefix. - */ -const LINKER_DECLARATION_PREFIX = 'ɵɵngDeclare'; - async function instrumentCoverage( filename: string, data: string, @@ -188,7 +180,7 @@ async function transformJavaScriptImpl( data: string, options: TransformOptions, ): Promise { - const shouldLink = !options.skipLinker && requiresLinking(filename, data); + const shouldLink = !options.skipLinker; const useInputSourcemap = options.sourcemap && (!!options.thirdPartySourcemaps || !/[\\/]node_modules[\\/]/.test(filename)); @@ -294,16 +286,3 @@ async function transformJavaScriptImpl( // Strip sourcemaps if they should not be used return options.isAlreadyStripped ? code : removeSourceMappingURL(code); } - -function requiresLinking(path: string, source: string): boolean { - // @angular/core and @angular/compiler will cause false positives - // Also, TypeScript files do not require linking - if (/[\\/]@angular[\\/](?:compiler|core)|\.tsx?$/.test(path)) { - return false; - } - - // Check if the source code includes one of the declaration functions. - // There is a low chance of a false positive but the names are fairly unique - // and the result would be an unnecessary no-op additional plugin pass. - return source.includes(LINKER_DECLARATION_PREFIX); -} diff --git a/packages/angular/build/src/tools/esbuild/javascript-transformer.ts b/packages/angular/build/src/tools/esbuild/javascript-transformer.ts index 32a0b2b8d07d..489c6ca8af8b 100644 --- a/packages/angular/build/src/tools/esbuild/javascript-transformer.ts +++ b/packages/angular/build/src/tools/esbuild/javascript-transformer.ts @@ -14,6 +14,33 @@ import { WorkerPool, WorkerPoolOptions } from '../../utils/worker-pool'; import { Cache } from './cache'; const SOURCEMAP_COMMENT_BYTES = Buffer.from('sourceMappingURL='); +const LINKER_DECLARATION_PREFIX = 'ɵɵngDeclare'; +const LINKER_DECLARATION_PREFIX_BYTES = Buffer.from(LINKER_DECLARATION_PREFIX, 'utf-8'); + +/** + * Determines whether JavaScript code requires Angular linker processing. + * + * @param path The full path to the file. + * @param data The data (string or Buffer) of the file. + * @returns True if the code contains an Angular partial declaration; otherwise false. + */ +function requiresLinking(path: string, data: string | Uint8Array): boolean { + // @angular/core and @angular/compiler will cause false positives + // Also, TypeScript files do not require linking + if (/[\\/]@angular[\\/](?:compiler|core)[\\/]|\.[cm]?tsx?$/.test(path)) { + return false; + } + + if (typeof data === 'string') { + return data.includes(LINKER_DECLARATION_PREFIX); + } + + const dataBuffer = Buffer.isBuffer(data) + ? data + : Buffer.from(data.buffer, data.byteOffset, data.byteLength); + + return dataBuffer.includes(LINKER_DECLARATION_PREFIX_BYTES); +} /** * Transformation options that should apply to all transformed files and data. @@ -190,9 +217,11 @@ export class JavaScriptTransformer { sideEffects?: boolean, instrumentForCoverage?: boolean, ): Promise { + const shouldLink = !skipLinker && requiresLinking(filename, data); + // Perform a quick test to determine if the data needs any transformations. // This allows directly returning the data without the worker communication overhead. - if (skipLinker && !this.#commonOptions.advancedOptimizations && !instrumentForCoverage) { + if (!shouldLink && !this.#commonOptions.advancedOptimizations && !instrumentForCoverage) { const keepSourcemap = this.#commonOptions.sourcemap && (!!this.#commonOptions.thirdPartySourcemaps || !/[\\/]node_modules[\\/]/.test(filename)); @@ -235,7 +264,7 @@ export class JavaScriptTransformer { { filename, data, - skipLinker, + skipLinker: !shouldLink, sideEffects, instrumentForCoverage, ...this.#commonOptions, diff --git a/packages/angular/build/src/tools/esbuild/javascript-transformer_spec.ts b/packages/angular/build/src/tools/esbuild/javascript-transformer_spec.ts index 5cf7383ab7d0..b1cdeec07b44 100644 --- a/packages/angular/build/src/tools/esbuild/javascript-transformer_spec.ts +++ b/packages/angular/build/src/tools/esbuild/javascript-transformer_spec.ts @@ -291,4 +291,87 @@ describe('JavaScriptTransformer sourcemaps', () => { expect(result).toBe(inputBuffer); }); + + it('should return Uint8Array untouched when skipLinker is false but file contains no linker declarations', async () => { + transformer = new JavaScriptTransformer( + { + sourcemap: false, + }, + 1, + ); + + const inputBuffer = Buffer.from('console.log("no linking required");\nconst x = 1;', 'utf-8'); + const result = await transformer.transformData( + 'node_modules/my-lib/lib.js', + inputBuffer, + false, // skipLinker: false + ); + + expect(result).toBe(inputBuffer); + }); + + it('should bypass worker and skip linking for @angular/core and @angular/compiler paths', async () => { + transformer = new JavaScriptTransformer( + { + sourcemap: false, + }, + 1, + ); + + const inputBuffer = Buffer.from('export const ɵɵngDeclareDirective = () => {};', 'utf-8'); + const result = await transformer.transformData( + 'node_modules/@angular/core/fesm2022/core.mjs', + inputBuffer, + false, + ); + + expect(result).toBe(inputBuffer); + }); + + it('should bypass worker and skip linking for TypeScript file extensions (.ts, .tsx, .mts, .cts)', async () => { + transformer = new JavaScriptTransformer( + { + sourcemap: false, + }, + 1, + ); + + const inputBuffer = Buffer.from('export const ɵɵngDeclareDirective = () => {};', 'utf-8'); + + for (const ext of ['.ts', '.tsx', '.mts', '.cts']) { + const result = await transformer.transformData(`src/app/directive${ext}`, inputBuffer, false); + + expect(result).toBe(inputBuffer); + } + }); + + it('should not exclude packages with similar prefixes such as @angular/compiler-cli', async () => { + transformer = new JavaScriptTransformer( + { + sourcemap: false, + }, + 1, + ); + + const input = ` + import * as i0 from "@angular/core"; + export class MyDirective {} + MyDirective.ɵdir = i0.ɵɵngDeclareDirective({ + minVersion: "12.0.0", + version: "14.0.0", + ngImport: i0, + type: MyDirective, + selector: "[my-dir]" + }); + `; + + const result = await transformer.transformData( + 'node_modules/@angular/compiler-cli/test.js', + input, + false, + ); + const text = Buffer.from(result).toString('utf-8'); + + expect(text).not.toContain('i0.ɵɵngDeclareDirective'); + }); }); From 2274babb662b8da2189f1ae9faaa528838052c32 Mon Sep 17 00:00:00 2001 From: Alan Agius <17563226+alan-agius4@users.noreply.github.com> Date: Tue, 11 Aug 2026 08:26:00 +0000 Subject: [PATCH 282/787] fix(@angular/build): normalize setupFiles paths to POSIX for vitest runner On Windows, absolute paths generated by joining the workspace root and the configured setup files contain backslashes. This causes a mismatch during test execution when the Vitest in-memory loading plugin resolves paths in POSIX format (with forward slashes) and attempts to look them up in the entry point mapping, leading to failed import resolutions. Normalizing `setupFiles` paths to POSIX at the options normalization stage ensures consistency across the entire build and execution pipeline, resolving the import resolution errors on Windows. Closes #33749 --- packages/angular/build/src/builders/unit-test/options.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/angular/build/src/builders/unit-test/options.ts b/packages/angular/build/src/builders/unit-test/options.ts index 1206bb2c1f21..7d57716214b1 100644 --- a/packages/angular/build/src/builders/unit-test/options.ts +++ b/packages/angular/build/src/builders/unit-test/options.ts @@ -10,7 +10,7 @@ import { type BuilderContext, targetFromTargetString } from '@angular-devkit/arc import { constants, promises as fs } from 'node:fs'; import path from 'node:path'; import { normalizeCacheOptions } from '../../utils/normalize-cache'; -import { canonicalizePath } from '../../utils/path'; +import { canonicalizePath, toPosixPath } from '../../utils/path'; import { getProjectRootPaths } from '../../utils/project-metadata'; import { isTTY } from '../../utils/tty'; import { Runner, type Schema as UnitTestBuilderOptions } from './schema'; @@ -143,7 +143,7 @@ export async function normalizeOptions( quiet: options.quiet ?? (process.env['CI'] ? false : true), providersFile: options.providersFile && path.join(workspaceRoot, options.providersFile), setupFiles: options.setupFiles - ? options.setupFiles.map((setupFile) => path.join(workspaceRoot, setupFile)) + ? options.setupFiles.map((setupFile) => toPosixPath(path.join(workspaceRoot, setupFile))) : [], dumpVirtualFiles: options.dumpVirtualFiles, listTests: options.listTests, From 6a21ad683ee73e2e75c9fe3d51ad2813a3dbeaf3 Mon Sep 17 00:00:00 2001 From: Charles Lyding <19598772+clydin@users.noreply.github.com> Date: Mon, 10 Aug 2026 22:00:45 -0400 Subject: [PATCH 283/787] refactor(@angular/build): centralize sourcemap buffer slicing and removal Extract and centralize trailing sourcemap comment inspection, extraction, and buffer slicing into the shared source-map utility module. Previously, buffer scanning and removal logic was duplicated between the main-thread transformer fast path and the worker script. The `removeSourceMappingURL` function is overloaded to accept both `string` and `Uint8Array` / `Buffer` inputs natively. When given raw byte buffers, it uses a zero-copy fast path to strip single trailing sourcemap comments directly from the buffer without decoding into a JavaScript string, falling back to the state-machine parser only when multiple or non-trailing comments are present. --- .../esbuild/javascript-transformer-worker.ts | 58 ++++-------- .../tools/esbuild/javascript-transformer.ts | 19 +--- .../angular/build/src/utils/source-map.ts | 92 +++++++++++++++++-- .../build/src/utils/source-map_spec.ts | 36 ++++++++ 4 files changed, 140 insertions(+), 65 deletions(-) diff --git a/packages/angular/build/src/tools/esbuild/javascript-transformer-worker.ts b/packages/angular/build/src/tools/esbuild/javascript-transformer-worker.ts index 74ff839ffdab..b6d9e46e834c 100644 --- a/packages/angular/build/src/tools/esbuild/javascript-transformer-worker.ts +++ b/packages/angular/build/src/tools/esbuild/javascript-transformer-worker.ts @@ -12,6 +12,7 @@ import { createRequire } from 'node:module'; import Piscina from 'piscina'; import { useBabelLinker } from '../../utils/environment-options.js'; import { + findTrailingSourceMapComment, isTrailingSourceMapComment, loadInputSourceMap, loadInputSourceMapFromUrl, @@ -37,7 +38,6 @@ interface TransformOptions extends Omit= 0 && (dataBuffer[prevIdx] === 32 || dataBuffer[prevIdx] === 9)) { - prevIdx--; - } - // Ensure the comment starts at the beginning of a line or the start of the file, - // preventing false positives for occurrences inside inline string literals or code. - const isLineStart = prevIdx < 0 || dataBuffer[prevIdx] === 10 || dataBuffer[prevIdx] === 13; - - if (firstIndex === lastIndex && isLineStart) { - const urlLine = dataBuffer - .subarray(lastIndex + SOURCEMAP_COMMENT_BYTES.length) - .toString('utf-8'); - - if (useInputSourcemap) { - inputSourceMap = loadInputSourceMapFromUrl(filename, urlLine); - if (inputSourceMap !== undefined) { - // Valid trailing sourcemap comment confirmed: safe to slice code buffer for transformation passes. - // Note: If no passes modify the code, the untouched original `data` buffer is returned below. - textData = textDecoder.decode(dataBuffer.subarray(0, prevIdx < 0 ? 0 : prevIdx + 1)); - isAlreadyStripped = true; - } else { - // Not a valid trailing sourcemap (e.g. inside template literal): fallback to full decode - textData = textDecoder.decode(data); - } - } else if (isTrailingSourceMapComment(urlLine)) { - // Valid trailing sourcemap comment confirmed: safe to slice code buffer - textData = textDecoder.decode(dataBuffer.subarray(0, prevIdx < 0 ? 0 : prevIdx + 1)); + } else if (trailing !== undefined) { + if (useInputSourcemap) { + inputSourceMap = loadInputSourceMapFromUrl(filename, trailing.urlLine); + if (inputSourceMap !== undefined) { + // Valid trailing sourcemap comment confirmed: safe to slice code buffer for transformation passes. + // Note: If no passes modify the code, the untouched original `data` buffer is returned below. + textData = textDecoder.decode(trailing.code); isAlreadyStripped = true; } else { - // Fallback to full decode and state-machine stripping + // Not a valid trailing sourcemap (e.g. inside template literal): fallback to full decode textData = textDecoder.decode(data); } + } else if (isTrailingSourceMapComment(trailing.urlLine)) { + // Valid trailing sourcemap comment confirmed: safe to slice code buffer + textData = textDecoder.decode(trailing.code); + isAlreadyStripped = true; } else { - // Multiple comments or comment not at line start: fall back to full decode and string parser + // Fallback to full decode and state-machine stripping textData = textDecoder.decode(data); } + } else { + // Multiple comments or comment not at line start: fall back to full decode and string parser + textData = textDecoder.decode(data); } } else { textData = data; diff --git a/packages/angular/build/src/tools/esbuild/javascript-transformer.ts b/packages/angular/build/src/tools/esbuild/javascript-transformer.ts index 489c6ca8af8b..397fb11a86fb 100644 --- a/packages/angular/build/src/tools/esbuild/javascript-transformer.ts +++ b/packages/angular/build/src/tools/esbuild/javascript-transformer.ts @@ -13,7 +13,6 @@ import { removeSourceMappingURL } from '../../utils/source-map'; import { WorkerPool, WorkerPoolOptions } from '../../utils/worker-pool'; import { Cache } from './cache'; -const SOURCEMAP_COMMENT_BYTES = Buffer.from('sourceMappingURL='); const LINKER_DECLARATION_PREFIX = 'ɵɵngDeclare'; const LINKER_DECLARATION_PREFIX_BYTES = Buffer.from(LINKER_DECLARATION_PREFIX, 'utf-8'); @@ -230,23 +229,7 @@ export class JavaScriptTransformer { return Buffer.from(keepSourcemap ? data : removeSourceMappingURL(data), 'utf-8'); } - if (keepSourcemap) { - return data; - } - - const dataBuffer = Buffer.isBuffer(data) - ? data - : Buffer.from(data.buffer, data.byteOffset, data.byteLength); - - // Fast check on raw ASCII bytes to avoid UTF-8 string decoding if no comment exists. - if (dataBuffer.indexOf(SOURCEMAP_COMMENT_BYTES) === -1) { - return data; - } - - const text = dataBuffer.toString('utf-8'); - const stripped = removeSourceMappingURL(text); - - return stripped === text ? data : Buffer.from(stripped, 'utf-8'); + return keepSourcemap ? data : removeSourceMappingURL(data); } // Only standalone (non-pooled) ArrayBuffers can be transferred across worker threads. diff --git a/packages/angular/build/src/utils/source-map.ts b/packages/angular/build/src/utils/source-map.ts index dc00d1340294..4fa97dd222c1 100644 --- a/packages/angular/build/src/utils/source-map.ts +++ b/packages/angular/build/src/utils/source-map.ts @@ -11,17 +11,90 @@ import { existsSync, readFileSync } from 'node:fs'; import { dirname, resolve } from 'node:path'; import { fileURLToPath } from 'node:url'; +export const SOURCEMAP_COMMENT_PREFIX = '//# sourceMappingURL='; +export const SOURCEMAP_COMMENT_BYTES = Buffer.from(SOURCEMAP_COMMENT_PREFIX); + +/** + * Checks for a single trailing `//# sourceMappingURL=` comment on a raw buffer. + * + * @param data The raw byte buffer to inspect. + * @returns An object containing the sliced code buffer and URL snippet if a single trailing comment exists, + * `null` if no sourcemap comment exists in the buffer, or `undefined` if multiple/non-trailing comments exist. + */ +export function findTrailingSourceMapComment( + data: Uint8Array, +): { code: Uint8Array; urlLine: string } | null | undefined { + const dataBuffer = Buffer.isBuffer(data) + ? data + : Buffer.from(data.buffer, data.byteOffset, data.byteLength); + + const firstIndex = dataBuffer.indexOf(SOURCEMAP_COMMENT_BYTES); + if (firstIndex === -1) { + return null; + } + + const lastIndex = dataBuffer.lastIndexOf(SOURCEMAP_COMMENT_BYTES); + // Skip any preceding horizontal whitespace (spaces/tabs) to find the start of the line. + let prevIdx = lastIndex - 1; + while (prevIdx >= 0 && (dataBuffer[prevIdx] === 32 || dataBuffer[prevIdx] === 9)) { + prevIdx--; + } + // Ensure the comment starts at the beginning of a line or the start of the file, + // preventing false positives for occurrences inside inline string literals or code. + const isLineStart = prevIdx < 0 || dataBuffer[prevIdx] === 10 || dataBuffer[prevIdx] === 13; + + if (firstIndex === lastIndex && isLineStart) { + const urlLine = dataBuffer + .subarray(lastIndex + SOURCEMAP_COMMENT_BYTES.length) + .toString('utf-8'); + + return { + code: dataBuffer.subarray(0, prevIdx < 0 ? 0 : prevIdx + 1), + urlLine, + }; + } + + return undefined; +} + /** * Removes `//# sourceMappingURL=` comments safely from the given JavaScript code, * ignoring any occurrences that are inside string literals, template literals, or block comments. * - * It uses a lightweight state-machine parser to accurately handle nested template literals. + * For raw Uint8Array / Buffer inputs, it optimizes performance by inspecting trailing byte sequences + * to slice the buffer directly without full string decoding. * - * @param code The JavaScript source code. + * @param code The JavaScript source code as a string or Uint8Array. * @returns The code with top-level sourcemap comments removed. */ -export function removeSourceMappingURL(code: string): string { - if (!code.includes('//# sourceMappingURL=')) { +export function removeSourceMappingURL(code: string): string; +export function removeSourceMappingURL(code: Uint8Array): Uint8Array; +export function removeSourceMappingURL(code: string | Uint8Array): string | Uint8Array { + if (typeof code === 'string') { + return removeSourceMappingURLFromString(code); + } + + const trailing = findTrailingSourceMapComment(code); + if (trailing === null) { + return code; + } + + if (trailing && isTrailingSourceMapComment(trailing.urlLine)) { + return trailing.code; + } + + // Fallback to full decode and state-machine stripping for multiple comments or non-trailing comments + const dataBuffer = Buffer.isBuffer(code) + ? code + : Buffer.from(code.buffer, code.byteOffset, code.byteLength); + const text = dataBuffer.toString('utf-8'); + const stripped = removeSourceMappingURLFromString(text); + + return stripped === text ? code : Buffer.from(stripped, 'utf-8'); +} + +function removeSourceMappingURLFromString(code: string): string { + if (!code.includes(SOURCEMAP_COMMENT_PREFIX)) { return code; } @@ -64,12 +137,12 @@ export function removeSourceMappingURL(code: string): string { } } - if (!isEscaped && code.startsWith('//# sourceMappingURL=', i)) { + if (!isEscaped && code.startsWith(SOURCEMAP_COMMENT_PREFIX, i)) { if (i > lastCopiedIndex) { result.push(code.slice(lastCopiedIndex, i)); } // Skip the rest of the comment line up to the newline - i += 21; + i += SOURCEMAP_COMMENT_PREFIX.length; while (i < len && code[i] !== '\n' && code[i] !== '\r') { i++; } @@ -308,7 +381,7 @@ export function loadInputSourceMapFromUrl( export function loadInputSourceMap(filename: string, code: string): EncodedSourceMap | undefined { // Locate the last sourceMappingURL comment using lastIndexOf to avoid scanning // the entire file with a regular expression (significant for large files). - const lastSourceMapIndex = code.lastIndexOf('//# sourceMappingURL='); + const lastSourceMapIndex = code.lastIndexOf(SOURCEMAP_COMMENT_PREFIX); if (lastSourceMapIndex === -1) { return undefined; } @@ -325,5 +398,8 @@ export function loadInputSourceMap(filename: string, code: string): EncodedSourc } } - return loadInputSourceMapFromUrl(filename, code.slice(lastSourceMapIndex + 21)); + return loadInputSourceMapFromUrl( + filename, + code.slice(lastSourceMapIndex + SOURCEMAP_COMMENT_PREFIX.length), + ); } diff --git a/packages/angular/build/src/utils/source-map_spec.ts b/packages/angular/build/src/utils/source-map_spec.ts index 8840315c019d..a5680d61fa4f 100644 --- a/packages/angular/build/src/utils/source-map_spec.ts +++ b/packages/angular/build/src/utils/source-map_spec.ts @@ -102,6 +102,42 @@ describe('removeSourceMappingURL', () => { const code = 'console.log("hello");\r\n//# sourceMappingURL=main.js.map\r\nconst next = 2;'; expect(removeSourceMappingURL(code)).toBe('console.log("hello");\r\n\r\nconst next = 2;'); }); + + describe('with Uint8Array / Buffer inputs', () => { + it('should strip trailing sourcemap comment from Uint8Array buffer', () => { + const buffer = Buffer.from( + 'console.log("hello");\n//# sourceMappingURL=main.js.map', + 'utf-8', + ); + const result = removeSourceMappingURL(buffer); + + expect(Buffer.from(result).toString('utf-8')).toBe('console.log("hello");\n'); + }); + + it('should return exact input buffer when no sourcemap comment is present', () => { + const buffer = Buffer.from('console.log("hello");\nconst x = 1;', 'utf-8'); + const result = removeSourceMappingURL(buffer); + + expect(result).toBe(buffer); + }); + + it('should handle multiple sourcemap comments in a buffer via fallback', () => { + const buffer = Buffer.from( + '//# sourceMappingURL=first.js.map\nconsole.log("mid");\n//# sourceMappingURL=second.js.map', + 'utf-8', + ); + const result = removeSourceMappingURL(buffer); + + expect(Buffer.from(result).toString('utf-8')).toBe('\nconsole.log("mid");\n'); + }); + + it('should not strip sourcemap comments inside template strings in a buffer', () => { + const buffer = Buffer.from('const str = `\n//# sourceMappingURL=inline.js.map\n`;', 'utf-8'); + const result = removeSourceMappingURL(buffer); + + expect(Buffer.from(result).toString('utf-8')).toBe(buffer.toString('utf-8')); + }); + }); }); describe('loadInputSourceMapFromUrl', () => { From 06bdcadcb32d63a1906024eb2c5ac6967e9bf290 Mon Sep 17 00:00:00 2001 From: Alan Agius <17563226+alan-agius4@users.noreply.github.com> Date: Tue, 11 Aug 2026 16:47:01 +0000 Subject: [PATCH 284/787] ci: limit schematics dependencies rule to minor and patch updates Add `matchUpdateTypes` to target only minor and patch updates in the schematics dependencies Renovate group configuration. --- renovate.json | 1 + 1 file changed, 1 insertion(+) diff --git a/renovate.json b/renovate.json index 49d7aa1a4f46..ffc86a850807 100644 --- a/renovate.json +++ b/renovate.json @@ -20,6 +20,7 @@ "packages/schematics/angular/utility/latest-versions/package.json" ], "matchPackageNames": ["*"], + "matchUpdateTypes": ["minor", "patch"], "groupName": "schematics dependencies", "lockFileMaintenance": { "enabled": false From cabe95c5241e19614de3923fbc9d52494b91bea0 Mon Sep 17 00:00:00 2001 From: Charles Lyding <19598772+clydin@users.noreply.github.com> Date: Tue, 11 Aug 2026 14:02:30 -0400 Subject: [PATCH 285/787] refactor(@angular/build): pre-warm transformer worker pool and pass static options via workerData Eagerly instantiate the worker pool in the JavaScriptTransformer constructor and set minThreads equal to maxThreads so worker threads are pre-warmed upfront during build context setup. Pass global, static transformer options (sourcemap, thirdPartySourcemaps, advancedOptimizations, and jit) once during pool initialization via Piscina's workerData option instead of redundantly serializing them in per-file IPC task payloads. --- .../esbuild/javascript-transformer-worker.ts | 43 ++++++++----------- .../tools/esbuild/javascript-transformer.ts | 4 +- 2 files changed, 21 insertions(+), 26 deletions(-) diff --git a/packages/angular/build/src/tools/esbuild/javascript-transformer-worker.ts b/packages/angular/build/src/tools/esbuild/javascript-transformer-worker.ts index b6d9e46e834c..4d951ec8e963 100644 --- a/packages/angular/build/src/tools/esbuild/javascript-transformer-worker.ts +++ b/packages/angular/build/src/tools/esbuild/javascript-transformer-worker.ts @@ -9,6 +9,7 @@ import remapping, { type DecodedSourceMap, type EncodedSourceMap } from '@ampproject/remapping'; import { type PluginItem, transformAsync } from '@babel/core'; import { createRequire } from 'node:module'; +import { workerData } from 'node:worker_threads'; import Piscina from 'piscina'; import { useBabelLinker } from '../../utils/environment-options.js'; import { @@ -18,16 +19,15 @@ import { loadInputSourceMapFromUrl, removeSourceMappingURL, } from '../../utils/source-map'; +import { linkWithOxc } from '../angular/linker/oxc-linker.js'; +import { transform as transformWithOxc } from '../oxc/oxc-transform.js'; +import type { JavaScriptTransformerOptions } from './javascript-transformer'; interface JavaScriptTransformRequest { filename: string; data: string | Uint8Array; - sourcemap: boolean; - thirdPartySourcemaps: boolean; - advancedOptimizations: boolean; skipLinker?: boolean; sideEffects?: boolean; - jit: boolean; instrumentForCoverage?: boolean; } @@ -36,6 +36,13 @@ interface TransformOptions extends Omit; + const textDecoder = new TextDecoder(); const textEncoder = new TextEncoder(); @@ -89,8 +96,7 @@ export default async function transformJavaScript( const { filename, data, ...options } = request; const useInputSourcemap = - options.sourcemap && - (!!options.thirdPartySourcemaps || !/[\\/]node_modules[\\/]/.test(filename)); + sourcemap && (!!thirdPartySourcemaps || !/[\\/]node_modules[\\/]/.test(filename)); let textData: string; let inputSourceMap: EncodedSourceMap | undefined; @@ -145,16 +151,6 @@ export default async function transformJavaScript( return Piscina.move(textEncoder.encode(transformedData)); } -/** - * Cached instance of the OXC linker module. - */ -let oxcLinkerModule: typeof import('../angular/linker/oxc-linker.js') | undefined; - -/** - * Cached instance of the OXC transform module. - */ -let oxcTransformModule: typeof import('../oxc/oxc-transform.js') | undefined; - async function transformJavaScriptImpl( filename: string, data: string, @@ -162,8 +158,7 @@ async function transformJavaScriptImpl( ): Promise { const shouldLink = !options.skipLinker; const useInputSourcemap = - options.sourcemap && - (!!options.thirdPartySourcemaps || !/[\\/]node_modules[\\/]/.test(filename)); + sourcemap && (!!thirdPartySourcemaps || !/[\\/]node_modules[\\/]/.test(filename)); let code = data; const maps: (DecodedSourceMap | EncodedSourceMap)[] = []; @@ -198,7 +193,7 @@ async function transformJavaScriptImpl( relative: (_from: string, to: string) => to, } as never, logger: new ConsoleLogger(LogLevel.info), - linkerJitMode: options.jit, + linkerJitMode: jit, // This is a workaround until https://github.com/angular/angular/issues/42769 is fixed. sourceMapping: false, }) as PluginItem, @@ -210,10 +205,9 @@ async function transformJavaScriptImpl( maps.push(result.map as EncodedSourceMap); } } else { - oxcLinkerModule ??= await import('../angular/linker/oxc-linker.js'); - const result = oxcLinkerModule.linkWithOxc(filename, code, { + const result = linkWithOxc(filename, code, { sourcemap: useInputSourcemap, - jit: options.jit, + jit, skipCheck: true, }); code = result.code; @@ -224,14 +218,13 @@ async function transformJavaScriptImpl( } // Run advanced optimizations using our fast oxc-transform - if (options.advancedOptimizations) { - oxcTransformModule ??= await import('../oxc/oxc-transform.js'); + if (advancedOptimizations) { const sideEffectFree = options.sideEffects === false; const safeAngularPackage = sideEffectFree && /[\\/]node_modules[\\/]@angular[\\/]/.test(filename); const topLevelSafeMode = !safeAngularPackage; - const result = oxcTransformModule.transform(filename, code, { + const result = transformWithOxc(filename, code, { sourcemap: useInputSourcemap, sideEffects: options.sideEffects, topLevelSafeMode, diff --git a/packages/angular/build/src/tools/esbuild/javascript-transformer.ts b/packages/angular/build/src/tools/esbuild/javascript-transformer.ts index 397fb11a86fb..3ba0dfff45b1 100644 --- a/packages/angular/build/src/tools/esbuild/javascript-transformer.ts +++ b/packages/angular/build/src/tools/esbuild/javascript-transformer.ts @@ -93,6 +93,7 @@ export class JavaScriptTransformer { jit, }; this.#fileCacheKeyBase = Buffer.from(JSON.stringify(this.#commonOptions), 'utf-8'); + this.#workerPool = this.#ensureWorkerPool(); } /** @@ -130,6 +131,8 @@ export class JavaScriptTransformer { const workerPoolOptions: WorkerPoolOptions = { filename: require.resolve('./javascript-transformer-worker'), maxThreads: this.maxThreads, + minThreads: this.maxThreads, + workerData: this.#commonOptions, }; // Prevent passing SSR `--import` (loader-hooks) from parent to child worker. @@ -250,7 +253,6 @@ export class JavaScriptTransformer { skipLinker: !shouldLink, sideEffects, instrumentForCoverage, - ...this.#commonOptions, }, { transferList: isTransferable ? [data.buffer] : undefined, From 72fdaaf972e0d49d9284d4bbc382f96716b7f7cb Mon Sep 17 00:00:00 2001 From: Angular Robot Date: Tue, 11 Aug 2026 07:15:47 +0000 Subject: [PATCH 286/787] build: lock file maintenance See associated pull request for more information. --- MODULE.bazel.lock | 2 +- pnpm-lock.yaml | 1037 ++++++++++++--------------------------------- 2 files changed, 279 insertions(+), 760 deletions(-) diff --git a/MODULE.bazel.lock b/MODULE.bazel.lock index 5dea915111bc..6c81cac53afa 100644 --- a/MODULE.bazel.lock +++ b/MODULE.bazel.lock @@ -455,7 +455,7 @@ "aspect_rules_jasmine": "2.0.4", "aspect_tools_telemetry": "0.4.2" }, - "last_notice": 1 + "last_notice": 0 } } }, diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index f47d78bc6d77..418a9edd3348 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -348,7 +348,7 @@ importers: version: 0.4.3 browserslist: specifier: ^4.26.0 - version: 4.28.7 + version: 4.28.8 chokidar: specifier: 5.0.0 version: 5.0.0 @@ -603,7 +603,7 @@ importers: version: 10.1.1(@babel/core@8.0.1)(webpack@5.109.2(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.26)(uglify-js@3.19.3)) browserslist: specifier: ^4.26.0 - version: 4.28.7 + version: 4.28.8 copy-webpack-plugin: specifier: 14.0.0 version: 14.0.0(webpack@5.109.2(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.26)(uglify-js@3.19.3)) @@ -693,10 +693,10 @@ importers: version: 5.109.2(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.26)(uglify-js@3.19.3) webpack-dev-middleware: specifier: 8.1.1 - version: 8.1.1(tslib@2.8.1)(webpack@5.109.2(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.26)(uglify-js@3.19.3)) + version: 8.1.1(webpack@5.109.2(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.26)(uglify-js@3.19.3)) webpack-dev-server: specifier: 6.0.0 - version: 6.0.0(bufferutil@4.1.0)(supports-color@11.0.0)(tslib@2.8.1)(utf-8-validate@6.0.6)(webpack@5.109.2(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.26)(uglify-js@3.19.3)) + version: 6.0.0(bufferutil@4.1.0)(supports-color@11.0.0)(utf-8-validate@6.0.6)(webpack@5.109.2(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.26)(uglify-js@3.19.3)) webpack-merge: specifier: 6.0.1 version: 6.0.1 @@ -741,7 +741,7 @@ importers: version: 5.109.2(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.26)(uglify-js@3.19.3) webpack-dev-server: specifier: 6.0.0 - version: 6.0.0(bufferutil@4.1.0)(supports-color@11.0.0)(tslib@2.8.1)(utf-8-validate@6.0.6)(webpack@5.109.2(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.26)(uglify-js@3.19.3)) + version: 6.0.0(bufferutil@4.1.0)(supports-color@11.0.0)(utf-8-validate@6.0.6)(webpack@5.109.2(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.26)(uglify-js@3.19.3)) packages/angular_devkit/core: dependencies: @@ -980,8 +980,8 @@ packages: '@angular/core': 22.2.0-next.1 rxjs: ^6.5.3 || ^7.4.0 - '@asamuzakjp/css-color@6.0.5': - resolution: {integrity: sha512-mbhpPMmnw/kwW19aRNmSUl1QzLbdGo1SCuE49BT98MNwqF6zaHb3o2owssFc/PEO/4t2UjqtCNwocuDtJornzA==} + '@asamuzakjp/css-color@6.0.7': + resolution: {integrity: sha512-vC/bk1Lz7Tn/EfU9/apOTBk80/8dyGyWMowPoV1tJ52muDGsDqt2HPT2klrFUiY60MQmQv9q8yIht15JnBgDGw==} engines: {node: ^22.13.0 || >=24.0.0} '@asamuzakjp/dom-selector@8.3.2': @@ -1624,312 +1624,156 @@ packages: resolution: {integrity: sha512-Xc3VhU02wqZ1HvHRJUwL09HkZSTvidqY5Ya0NXBSYOxAp+Ln9dcJr9fySI+CkONzP3PekQo9WdzCv0PGER/mOA==} engines: {node: '>=14.17.0'} - '@esbuild/aix-ppc64@0.28.1': - resolution: {integrity: sha512-Svl7tq8k/08+p6CXPpRjQ1fKX+1odH/BQbb48fV6fj3CWHhsoIOoY87w1oHXm0qEpkIK3ZfVgp0hed3XBXzXMQ==} - engines: {node: '>=18'} - cpu: [ppc64] - os: [aix] - '@esbuild/aix-ppc64@0.28.2': resolution: {integrity: sha512-XExcO+dvLKvVtNTibSTBej1NCAbaGhWn9Ww1ZPx80qsahhPFe/8jgWP0IchNe0F3HwkU7n8ejhH8bjonqht8mQ==} engines: {node: '>=18'} cpu: [ppc64] os: [aix] - '@esbuild/android-arm64@0.28.1': - resolution: {integrity: sha512-34EGEbCIAgosYz6goLcopX6Mo7NyGv9tfwEM2/7Ce2VcVRk568iSvniGWcUXIy7wEDR1wzolcxcriFVrWYcwBg==} - engines: {node: '>=18'} - cpu: [arm64] - os: [android] - '@esbuild/android-arm64@0.28.2': resolution: {integrity: sha512-5YfKeeI8qWfBZIX+u2xZC3Zlb3Os/gLS2sbEKM+I4ZOcsWmHS2WLysCcQZDAFRslDUU5Oiq44gf6PYN1vGwG5A==} engines: {node: '>=18'} cpu: [arm64] os: [android] - '@esbuild/android-arm@0.28.1': - resolution: {integrity: sha512-0k2F129Xdio1TdJfzJ8sy1Q47vUD2NnwdhiAf7drUN1EBTfPf4hsFCtmMgu/6m8JSzsBrlmVjudMBQqOfG8usQ==} - engines: {node: '>=18'} - cpu: [arm] - os: [android] - '@esbuild/android-arm@0.28.2': resolution: {integrity: sha512-kXXoiPVVGQcnIYGOeaovwOURpniDBpSq4A03qkQ+BMQqtGG6HYap3xne9C1O1yo4TR3qxlCX5IqqmX6fFo2Lqg==} engines: {node: '>=18'} cpu: [arm] os: [android] - '@esbuild/android-x64@0.28.1': - resolution: {integrity: sha512-dbwY7ltSMDWsRatcRpCnES4F+im88OCUgGZjy52shC7GqHRE/cYlxNbB4Z4UpJswpcc4Qxd2oE/ufM0p61IKng==} - engines: {node: '>=18'} - cpu: [x64] - os: [android] - '@esbuild/android-x64@0.28.2': resolution: {integrity: sha512-O387ite7SzUyCcy3JQX4P4bLtEA7bLLkx+esve5JHnyYfNTxcVpXZo9jhdB0lTKN44gztELTdU7nS8Nr16Fs1Q==} engines: {node: '>=18'} cpu: [x64] os: [android] - '@esbuild/darwin-arm64@0.28.1': - resolution: {integrity: sha512-TZbWkQY7kvTAXbXUT7uVACR5cMHsDiSz9z7ZKAX/RTq/WJEk3QyRr0wZpNhBDX+/0CtdqUIJlOiodQcta6tY3Q==} - engines: {node: '>=18'} - cpu: [arm64] - os: [darwin] - '@esbuild/darwin-arm64@0.28.2': resolution: {integrity: sha512-n4KqkOQrraxHJcgjM1RvwbigfQKIKJVpM7xp+KsxiyUSrRdIXnt73VhrPAx0fV44hgfmIVKjxMN9J1t5jySVkw==} engines: {node: '>=18'} cpu: [arm64] os: [darwin] - '@esbuild/darwin-x64@0.28.1': - resolution: {integrity: sha512-zfdzgK9ACBNZLI/CyHTOx81SyNbM6YXn7rxSgX97VjyiPl9W1i4Ka4fgKECEoFCKGpvBj5qArWIGgQjOwkgskQ==} - engines: {node: '>=18'} - cpu: [x64] - os: [darwin] - '@esbuild/darwin-x64@0.28.2': resolution: {integrity: sha512-uq6suIWYP37qzGddBKPw5QEQPi6HiLGsO7UmkpfyaYNQ3D+rN6w6WfwH+nuqcGXWvawGwxOEroO4YGnFh95azw==} engines: {node: '>=18'} cpu: [x64] os: [darwin] - '@esbuild/freebsd-arm64@0.28.1': - resolution: {integrity: sha512-wG2EA8ENdEI0qhkSZMjfqrdY+ziCYCPMmtZjjIwOmXFjmyzEHn+UUxk5of+SYsjtfs3VpnlC7QLzSI5hY/rOAw==} - engines: {node: '>=18'} - cpu: [arm64] - os: [freebsd] - '@esbuild/freebsd-arm64@0.28.2': resolution: {integrity: sha512-n+I0BTSRIoy+d6RPKnEVwql5UwBJolytvY4mAOIEJorKlqgPII8ix6slVVrfZ5Tnj7glIZvloylbB/EJPMWEXw==} engines: {node: '>=18'} cpu: [arm64] os: [freebsd] - '@esbuild/freebsd-x64@0.28.1': - resolution: {integrity: sha512-i7dZ9vQgnvSCzi/rYCXNgtF/U+eKZNJBzu3eTQbRgHnM7tNSizLOkRFAl3qzVc/Op/u5YkHHa4pf/3DOYHthLQ==} - engines: {node: '>=18'} - cpu: [x64] - os: [freebsd] - '@esbuild/freebsd-x64@0.28.2': resolution: {integrity: sha512-78XJTJkvPs0kz2w61301PJjXl4g7q3JqiYMZ/M/yVI73EHBrCRTgkhu9oqG7vPqq+a/yadEW8aD+agKlk5xrmg==} engines: {node: '>=18'} cpu: [x64] os: [freebsd] - '@esbuild/linux-arm64@0.28.1': - resolution: {integrity: sha512-yHs+0uc8+nvEAfAfxrWQKK5peSNzBc4PegcMO0EJ2hT71uA7vB8Ihg2e77R2P7SG5uYjPbHlLLmve4LLLRCf0g==} - engines: {node: '>=18'} - cpu: [arm64] - os: [linux] - '@esbuild/linux-arm64@0.28.2': resolution: {integrity: sha512-pW4AC0P3it8c7do9MVM4p51FzHzdM/TZrerurgRcHJ2WTa1VQ1CIq18xncfpBJw4ojkiZZrKW2yIBWBP92j6Ug==} engines: {node: '>=18'} cpu: [arm64] os: [linux] - '@esbuild/linux-arm@0.28.1': - resolution: {integrity: sha512-qVXBOHQS+d5Y722GwJzJUtOLlX7km3CraOaGormF1pDtPd2C/l1SHRPgjLunLGe51Sh5YYWKMFDyV4SxgMQYTQ==} - engines: {node: '>=18'} - cpu: [arm] - os: [linux] - '@esbuild/linux-arm@0.28.2': resolution: {integrity: sha512-XlDnu2q5yoqems+xay6wSAcg9DDD7K9RLKZEBOMZm3ckNpJBvOX20tSfby8KfrrhINDyv9V2YVZKY/SpoGJI8w==} engines: {node: '>=18'} cpu: [arm] os: [linux] - '@esbuild/linux-ia32@0.28.1': - resolution: {integrity: sha512-d1z4ZuP0ajrfz/FhGT4vv278rX8KnPPJx8i5+AtK7TYbx9Le9F1hyzurZpkEyjkGa9dUGhQow4C1NmeGvqxN2w==} - engines: {node: '>=18'} - cpu: [ia32] - os: [linux] - '@esbuild/linux-ia32@0.28.2': resolution: {integrity: sha512-CYbnj78HsIeA+DhgUKgFCfvNsTHFhMMrinUrMZpDXJXKN8T3XViTZ/+wtHeVxEWY8ewSzTFN+nRmSwO2tZaLUQ==} engines: {node: '>=18'} cpu: [ia32] os: [linux] - '@esbuild/linux-loong64@0.28.1': - resolution: {integrity: sha512-M5sRjUVZrkm1OAPR3dlOYzNmN+loZKGVi1VUQGrwuqLcbR6qeAz+famMhjASeH3YVKvZz+zT1jlh/keC3Rj/lg==} - engines: {node: '>=18'} - cpu: [loong64] - os: [linux] - '@esbuild/linux-loong64@0.28.2': resolution: {integrity: sha512-buwkd8nsph4R+ajRvw0qM5Hja/TXQow3ptzWO2EbG/cqcIkHloRrdlBtQlshyYGTNFvfkfJ5tpPLVkY4DtsPfQ==} engines: {node: '>=18'} cpu: [loong64] os: [linux] - '@esbuild/linux-mips64el@0.28.1': - resolution: {integrity: sha512-mRObBZeHh2OxcBFPWE/FjylkRgZdYuiTR3vaTozquCGOH14iP9oN4x4Ge81CoIDYQrXmIxpFumJBu5MtZpnQJQ==} - engines: {node: '>=18'} - cpu: [mips64el] - os: [linux] - '@esbuild/linux-mips64el@0.28.2': resolution: {integrity: sha512-ZVykbDyk7519VwiNb9Lcj9m8XM6v5V9uKPvrEMkkEedVewf+0itkhahp4HDpgERXhwLRpWFypsGbG/J8s0QjJA==} engines: {node: '>=18'} cpu: [mips64el] os: [linux] - '@esbuild/linux-ppc64@0.28.1': - resolution: {integrity: sha512-slScBsMAb3GFDcdrCgLwZtPYRoH2H/youv10QiZyRjmsP48fznoveWytSgCI/R0ZcUgpc0ZhIUEx6LHts8yrfQ==} - engines: {node: '>=18'} - cpu: [ppc64] - os: [linux] - '@esbuild/linux-ppc64@0.28.2': resolution: {integrity: sha512-CAXl+Dtd9UUuJd8pKKdwh6MLm3MUMiqMPmhZ3tTSXPqfyQ3vDl6R5hZdZ/kYojK4ofXtdfSv1tFq8XzWx3heNQ==} engines: {node: '>=18'} cpu: [ppc64] os: [linux] - '@esbuild/linux-riscv64@0.28.1': - resolution: {integrity: sha512-kw0owk1o0GFETUJyW0jc0G4Yzs0BHZn0JDZ8JRT088vjJYX777BAs1fDGxAC+q831qOs2DTC96mNsG2opdfyyQ==} - engines: {node: '>=18'} - cpu: [riscv64] - os: [linux] - '@esbuild/linux-riscv64@0.28.2': resolution: {integrity: sha512-GeXCej4IQtU1B+QlDV8W/RRvbzI3O/Stss+/bCXv4lZls5WGRtu2a+3JkA3i4qIUlMXpcHebWpF8AkJhATowuA==} engines: {node: '>=18'} cpu: [riscv64] os: [linux] - '@esbuild/linux-s390x@0.28.1': - resolution: {integrity: sha512-/lAIjX8aYFRByhh6L5rYtPEDRqa9de/4V/juOXcta5frjvzXO4/sqEtyytse0g3zZFuWu5cDN0MkLz2qRDD2Ag==} - engines: {node: '>=18'} - cpu: [s390x] - os: [linux] - '@esbuild/linux-s390x@0.28.2': resolution: {integrity: sha512-3H1weTYZPxt/WOhByszQZybS9w5lKzUn1FDMsgEChbHWQwHYQQRfBxgCcZvPhjHfKyJjIievvMmEUawJrdY9Dg==} engines: {node: '>=18'} cpu: [s390x] os: [linux] - '@esbuild/linux-x64@0.28.1': - resolution: {integrity: sha512-u/anNYF2mmVOEDwLtnQ1wOr3EZ9sTNGLWrsYGYwHWzGA3Si84IOkHXlbWTD1NB+9/1lcnweYKO54uhxZydNzfA==} - engines: {node: '>=18'} - cpu: [x64] - os: [linux] - '@esbuild/linux-x64@0.28.2': resolution: {integrity: sha512-4xTZr1FUmSoQW4XIWmit3tzQrUTZM+N3P0XV8xROKYF50XfI7xeO90+1bZvNwxIufQ9hDQVRJH5YhgPVF8A/HQ==} engines: {node: '>=18'} cpu: [x64] os: [linux] - '@esbuild/netbsd-arm64@0.28.1': - resolution: {integrity: sha512-oks0DYbLwWMmaakTsCb+zL4E+aHRVLom9IJZOAthMQEPiQmydXHkziYEsGYRx0uNV/IjEKGAV941JzH02pflqw==} - engines: {node: '>=18'} - cpu: [arm64] - os: [netbsd] - '@esbuild/netbsd-arm64@0.28.2': resolution: {integrity: sha512-sSATRjPeDBg3pdgHoQfoYBob11Kk1FGa9lui5RIHZCoCkJa9QKlvl3/vKz2usCmYYjs7ymJR/2Nnsqe+Hjt5nw==} engines: {node: '>=18'} cpu: [arm64] os: [netbsd] - '@esbuild/netbsd-x64@0.28.1': - resolution: {integrity: sha512-aeL6lAnN89Hz43Mlh1G8ARasbuoYvSITDEx0tHh5b7jJnHcssqgjy9Yx430GDpmCa6OyrKoS0aNRjKundRizGg==} - engines: {node: '>=18'} - cpu: [x64] - os: [netbsd] - '@esbuild/netbsd-x64@0.28.2': resolution: {integrity: sha512-lqnzCV+mM0gIADaKihiCg6ifgfU2L3h5E33rNQBN1Y4MaVGnzryzmvvf7UHxprpQdE8hpqLolJ9Rl+SkIRDpyw==} engines: {node: '>=18'} cpu: [x64] os: [netbsd] - '@esbuild/openbsd-arm64@0.28.1': - resolution: {integrity: sha512-MEFJe5C3R8pwXdZ5Y21oo6m7ePiS0d9pWucn99O/wvyJZChoIQKrQDxKrGeW8F5+T0okTHesAmDeiHDTIq0V/Q==} - engines: {node: '>=18'} - cpu: [arm64] - os: [openbsd] - '@esbuild/openbsd-arm64@0.28.2': resolution: {integrity: sha512-AL2qJILH7lNjrDmCQDvdxMfAUIv8KMNZOvrwAQ8i8//ntL9FflhOyMJ8OZSMBb8/AWXe3/5v5S20y3zCoZWKoQ==} engines: {node: '>=18'} cpu: [arm64] os: [openbsd] - '@esbuild/openbsd-x64@0.28.1': - resolution: {integrity: sha512-i/ZLIOafE0Z8cI/XANJAixoJL/uRAoS2xOA3rb0xN+KK0K177cMAsQYkzHtBrtMXAKuAc7HGgcWiZ/sRC1Nxgw==} - engines: {node: '>=18'} - cpu: [x64] - os: [openbsd] - '@esbuild/openbsd-x64@0.28.2': resolution: {integrity: sha512-QtiuPytchRyC4rwUKhexJdQKvDuZ6hWloi3igqPQNUJCS1/v9EiO3UTOXR6A3FoMo4fnAKbWJdqaIwhOzh8qEw==} engines: {node: '>=18'} cpu: [x64] os: [openbsd] - '@esbuild/openharmony-arm64@0.28.1': - resolution: {integrity: sha512-ge+Z7EXFNt2BO1oAMsVpiQ8EwndV9i1xXerAeTIK7AtPs3bKFXQM7nlRxDSIUIMeueR1CNXxqztLzdNeReKBJg==} - engines: {node: '>=18'} - cpu: [arm64] - os: [openharmony] - '@esbuild/openharmony-arm64@0.28.2': resolution: {integrity: sha512-WkhYDmpTjLvGlScA1rwjRUmhl4k8oXR3cIbtqWmELgU/dFeHHlEllxDvdWcNJV9rbzCexB5vz8gtNewWLgCT7Q==} engines: {node: '>=18'} cpu: [arm64] os: [openharmony] - '@esbuild/sunos-x64@0.28.1': - resolution: {integrity: sha512-BEjgtECkL3vY+SaSQ6nzVfiALUeFxpawyp8Jmf5PtYhf1Ug40N1h/hxlhts+f1FvSvarEigdxS3BlSMI2PJLcQ==} - engines: {node: '>=18'} - cpu: [x64] - os: [sunos] - '@esbuild/sunos-x64@0.28.2': resolution: {integrity: sha512-GPMSkTOtMnv2U2F8gxe4Io6qmVs+YKyp832Etqqxr0hFngmXQ3rzwytelm3GIn7T4VviRUlf3sOgBOiTdvaf7g==} engines: {node: '>=18'} cpu: [x64] os: [sunos] - '@esbuild/win32-arm64@0.28.1': - resolution: {integrity: sha512-lCv9eK/H6ZJWbE7bh2nw54CZ9M2nupBxJcTsdk/QQnWkdSjKGuxmmH8/GWrlT1eMmZfn4dGcCjRte397WqfQXA==} - engines: {node: '>=18'} - cpu: [arm64] - os: [win32] - '@esbuild/win32-arm64@0.28.2': resolution: {integrity: sha512-PIhhEkE9uPBleRBrQEJpUn7MBnibZzbGzYWPmY3x+YoVg/95zbjB4CxPPOQ8l5tYYM4mMaCthF8/1DIfBQQyWQ==} engines: {node: '>=18'} cpu: [arm64] os: [win32] - '@esbuild/win32-ia32@0.28.1': - resolution: {integrity: sha512-zvb/mB2bSCoJOpoCBgYKKpX6YM6mJBlBUVUtVj41DlZJVEB6/0CKlRYxP5wWl1C1ILiCoAU5wZZ4q1P3qeS6Eg==} - engines: {node: '>=18'} - cpu: [ia32] - os: [win32] - '@esbuild/win32-ia32@0.28.2': resolution: {integrity: sha512-YmJbfTlvU7Sdn9BB+4PRES4oB6pxgS37MAONj+hBr/cpXS1aBPKXxNnDbu+QCWPj0o9dgyxeq79g6c5P8KeuYA==} engines: {node: '>=18'} cpu: [ia32] os: [win32] - '@esbuild/win32-x64@0.28.1': - resolution: {integrity: sha512-bm4Mowrv+GXMlpWX++EcXw/iLyd1o3+bJkC2DkWXYVvgZCqD/bSj9ctZeAMC3cIxgjRVR2Dufaiu4YPxr5gW1A==} - engines: {node: '>=18'} - cpu: [x64] - os: [win32] - '@esbuild/win32-x64@0.28.2': resolution: {integrity: sha512-5ebpxr3nWMzrL/rnUI755Jkuee0bHL/Gq0WTF9lvcpv73wAp5eu8MfBUgWK9bhWvZjj7yX8etf/8tI8Ney695g==} engines: {node: '>=18'} @@ -2509,50 +2353,50 @@ packages: peerDependencies: tslib: '2' - '@jsonjoy.com/fs-core@4.64.0': - resolution: {integrity: sha512-zs2TAq7Six5jgMuoMNjpspAvOP3mhtgq/k1UyQodEzCtQi/N83y2/y+zcvnZSGp/Rxq96DBN+bValOBQAyn/ew==} + '@jsonjoy.com/fs-core@4.68.0': + resolution: {integrity: sha512-OAioDU3UGV34ECVTB4pt641OfUzuyDuyUmgrlVM+Fp9g4YyavZrB4xxWuupYrU66+81+um9D0DAzYhjXto5ysQ==} engines: {node: '>=10.0'} peerDependencies: tslib: '2' - '@jsonjoy.com/fs-fsa@4.64.0': - resolution: {integrity: sha512-nMWOVbkLFyEgmXZih3wyvxA9XpgyyqyfrINMHvEFqhi7uqfRl7c9ERJt6yX7vgMPrB9Uo+OJO+Spa0cFzPD01w==} + '@jsonjoy.com/fs-fsa@4.68.0': + resolution: {integrity: sha512-dC6VeW8uqXMF9Hkqb7qYST/t165XCHG+bNwwMzRetoNZRxJC8anr5XCJSAk5B+YLHGn6SP+noNltU6OFg/oa7A==} engines: {node: '>=10.0'} peerDependencies: tslib: '2' - '@jsonjoy.com/fs-node-builtins@4.64.0': - resolution: {integrity: sha512-/o7WRFhUWaM/fOrslwLZGnzn4RmRILykn+lAL+mNObqqRNw+CQSiij6hpCeZ+C7buhdoVo7go/OYqzaSUfDYmA==} + '@jsonjoy.com/fs-node-builtins@4.68.0': + resolution: {integrity: sha512-j3bb+k4NuqpqXQzinCLeagS7LGLCUvPqA6TnpaBkBqhnPjbzETYiQFpD7pWaV8cGOhhZcAv9dmpzk5mxNb1qsg==} engines: {node: '>=10.0'} peerDependencies: tslib: '2' - '@jsonjoy.com/fs-node-to-fsa@4.64.0': - resolution: {integrity: sha512-WDD9WVs0hb7UAEKTgZW2f66WDrbj7gIIWwpP3spbLyXa0rghtUaFTB8L4gdR3ZCWwiKIsj38/CNijpVmpnuPUw==} + '@jsonjoy.com/fs-node-to-fsa@4.68.0': + resolution: {integrity: sha512-dtLpmLQxw3IBcGxoK9tVvftwmQLl9qmQyivt8DZpeEwDUcQkxk2CLMZERXtmOlF1mWXfT9CqtjjMiswkb03rKw==} engines: {node: '>=10.0'} peerDependencies: tslib: '2' - '@jsonjoy.com/fs-node-utils@4.64.0': - resolution: {integrity: sha512-k5Indsx9hWW9xSF7Y6oSKKwtCUNhzZxadub3owhIlitc+iMRVlPPdX2duTKQWBL3qNWpXya8jykgaaWpheeS4w==} + '@jsonjoy.com/fs-node-utils@4.68.0': + resolution: {integrity: sha512-Q84pogSfRaz0WNrBBy+HzBmhNu4m6tWoM0po8bLwW4pKvrwrSadOgFpm1sku08sfg0QAtUubkWuZEBDpNI3toQ==} engines: {node: '>=10.0'} peerDependencies: tslib: '2' - '@jsonjoy.com/fs-node@4.64.0': - resolution: {integrity: sha512-dO+NNkODbUli4uV42bcNrrLvq5rE7SNpdZ5TNd0dtbLsAaNK3MDiIC9lUi+brboGoIjW6vd2fB1qao60nrk5xA==} + '@jsonjoy.com/fs-node@4.68.0': + resolution: {integrity: sha512-xYDlpSk3UDHjcI0kiz6kNJ/oVTEzlS7kUzAoAsgJh2/+yOtYV/eZW7M8O9Fj+ED3BDONYKt7+8OiPlWl6xpFeA==} engines: {node: '>=10.0'} peerDependencies: tslib: '2' - '@jsonjoy.com/fs-print@4.64.0': - resolution: {integrity: sha512-PHZFccchvkhWrwPWHjmVAhbC3vSHCtyZvlZfJJ3ho2bnzl450hXri6/8e6pbkWdH+SkmLXNml0sV8e5HDAfxKw==} + '@jsonjoy.com/fs-print@4.68.0': + resolution: {integrity: sha512-sdy9F6N9QEcyAcU8OxEQmB91mlgiyuMphTFeijQ+qFgigCOeT16lW3X1dCWNzD7wwKLOKXnnYqsFyeq4LWSlYQ==} engines: {node: '>=10.0'} peerDependencies: tslib: '2' - '@jsonjoy.com/fs-snapshot@4.64.0': - resolution: {integrity: sha512-oM7UDeL83q6NBzzsfKAsYKXKVXlykKFqqOLh4xZZKAzzROTlInkPbc6LTDGThEOnPiFiUzA7tYziHG9xavd76Q==} + '@jsonjoy.com/fs-snapshot@4.68.0': + resolution: {integrity: sha512-eV44t9KY9LH47aPR1a4Nv4xYxM1vQ+OKEw9Mx/3zkuxGOILwmtFddlh5HakdMFpFHwuFNPw1s+NGq2eVYFpQRA==} engines: {node: '>=10.0'} peerDependencies: tslib: '2' @@ -2839,10 +2683,6 @@ packages: resolution: {integrity: sha512-P4YJBPdPSpWTQ1NU4XYdvHvXJJDxM6YwpS0FZHRgP7YFkdVxsWcpWGy/NVqlAA7PcPCnMacXlRm1y2PFZRWL/w==} engines: {node: '>= 20'} - '@octokit/core@7.0.6': - resolution: {integrity: sha512-DhGl4xMVFGVIyMwswXeyzdL4uXD5OGILGX5N8Y+f6W7LhC1Ze2poSNrkF/fedpVDHEEZ+PHFW0vL14I+mm8K3Q==} - engines: {node: '>= 20'} - '@octokit/core@7.0.7': resolution: {integrity: sha512-DcB0M3KFgr9ECI328lhBMVsyFT2DnmNucSBTqEN3exyNKUzkkpUSCHmTRcunF41Eou2TIQKW4seewri8ON9bSA==} engines: {node: '>= 20'} @@ -2854,10 +2694,6 @@ packages: '@octokit/graphql-schema@15.26.1': resolution: {integrity: sha512-RFDC2MpRBd4AxSRvUeBIVeBU7ojN/SxDfALUd7iVYOSeEK3gZaqR2MGOysj4Zh2xj2RY5fQAUT+Oqq7hWTraMA==} - '@octokit/graphql@9.0.3': - resolution: {integrity: sha512-grAEuupr/C1rALFnXTv6ZQhFuL1D8G5y8CN04RgrO4FIPMrtm+mcZzFG7dcBm+nq+1ppNixu+Jd78aeJOYxlGA==} - engines: {node: '>= 20'} - '@octokit/graphql@9.0.4': resolution: {integrity: sha512-5s15CCiY8XXQ+FG+b1YQcl6Z2FA++nwAz/tg2VUrTmnMncP+2nnGUEYANImdnxsA2Fnq+Mbl7hDjUTw7cFAwcg==} engines: {node: '>= 20'} @@ -2866,8 +2702,8 @@ packages: resolution: {integrity: sha512-7QoLPRh/ssEA/HuHBHdVdSgF8xNLz/Bc5m9fZkArJE5bb6NmVkDm3anKxXPmN1zh6b5WKZPRr3697xKT/yM3qQ==} engines: {node: '>= 20'} - '@octokit/oauth-methods@6.0.3': - resolution: {integrity: sha512-t7MBs34Ja16BBZlOSAFslFh4wBMuofD83wVLG9zIuuEGMv/U12XAJ8ESOifgEcC1ptjhNA3sorLA9BCtVfgPuw==} + '@octokit/oauth-methods@6.0.4': + resolution: {integrity: sha512-96RsnxS7Hk/BQhUA1Qo2pmcYP6LWQRWMdo7bVbNE7ZCkFLhSUYBXVUj9tVnvhl4jzbwHYt/dcIG+ioY427b2sg==} engines: {node: '>= 20'} '@octokit/openapi-types@27.0.0': @@ -3075,9 +2911,6 @@ packages: cpu: [x64] os: [win32] - '@oxc-project/types@0.142.0': - resolution: {integrity: sha512-7W+2q5AKQVU36fkaryontrHn3YDt1RyUYXatw9i5H8ocYe2sPKSFB6eS8WNPeRKiN1qAWWZUPm7gwFzJGrccqQ==} - '@oxc-project/types@0.143.0': resolution: {integrity: sha512-u6JZdLBTLotrNC9Vd6vPssINdzcCzleKAH6EJKImQb7GtYvX5keN2dxkoK44stCc4tffE6QQRtZTXVSzsLUlWA==} @@ -3267,73 +3100,36 @@ packages: yauzl: optional: true - '@rolldown/binding-android-arm64@1.2.2': - resolution: {integrity: sha512-l7x215OGvo1s52JWmR8U/DAVzEDWBCIbTm28aeJV/WDTSHgcKXaZTuBT0hJMs5NggilfJTW3clZVvd24yfKJxA==} - engines: {node: ^20.19.0 || >=22.12.0} - cpu: [arm64] - os: [android] - '@rolldown/binding-android-arm64@1.2.3': resolution: {integrity: sha512-zrJtHDcaZJ1Fp7xf4hNl+7seH9Cn/N5TwLYkhgXREtBwAd/jaqW3uqeHxpDugJLVICWg4eW44kOQEGJ1r6jCGw==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [android] - '@rolldown/binding-darwin-arm64@1.2.2': - resolution: {integrity: sha512-9u9Xv6c1AJZT0FfwH5vrMG5Jjcwhc1MlyrPu0XfTqkzsmqfks2M6W/o5XwAJgVVN/jHpqqngC1WevHKKTIUtIA==} - engines: {node: ^20.19.0 || >=22.12.0} - cpu: [arm64] - os: [darwin] - '@rolldown/binding-darwin-arm64@1.2.3': resolution: {integrity: sha512-ieIiibVCp0tX7TLu2cafoNPv8wJyYi01ekXpbf8q2j7F4rGAhhXb/eQh7ge9DRBY78GwmRQtvjZDux7EDbA8kA==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [darwin] - '@rolldown/binding-darwin-x64@1.2.2': - resolution: {integrity: sha512-9W1mbGZAfW3oqd85bhBkmpyHCCzL1TeG/zFFP3vg7b0rlly8cxOcre5nXwz+LHazCwac2MNWgPdPCHndABjpWQ==} - engines: {node: ^20.19.0 || >=22.12.0} - cpu: [x64] - os: [darwin] - '@rolldown/binding-darwin-x64@1.2.3': resolution: {integrity: sha512-Zh9tCon19eDXJoihx0rqKhMUlMYqzwj3aPsSuHmI4RWZh62dWUL+DJN4C5YQya5TcQBJU/Fe8+rY0jhXTQITqA==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [darwin] - '@rolldown/binding-freebsd-x64@1.2.2': - resolution: {integrity: sha512-0p1lhiCSCyaerFwtrdZQUx7NqGk6LQnaRKWX7tFQqwQgvX0rjM15cIkm3pax1UpEakK14C4mOxx/jSqCBdBRqQ==} - engines: {node: ^20.19.0 || >=22.12.0} - cpu: [x64] - os: [freebsd] - '@rolldown/binding-freebsd-x64@1.2.3': resolution: {integrity: sha512-nGbJWewA1wrXXZiQhjAT5rhibGfns5ZNkDVqxsO6zJ3f3YvpoDNNmGMSbbhLuXKjNScaBJVOAboztAWVespQMg==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [freebsd] - '@rolldown/binding-linux-arm-gnueabihf@1.2.2': - resolution: {integrity: sha512-e+cOJXrJ2L3zx6YzqPg+f6Wbk3V1cKB8bOhbaYdVYN3DdquzNdRAmrbETz1qnt5yp/c7JNlNjmITiA2cVneQ7w==} - engines: {node: ^20.19.0 || >=22.12.0} - cpu: [arm] - os: [linux] - '@rolldown/binding-linux-arm-gnueabihf@1.2.3': resolution: {integrity: sha512-QNniJr5Kml0kDEB98jiDOJjXNroxIIi0IXIbdYzY26Xt1pVbeP62+KnoIZLwirOymX/0jDk/2gI/bNUv7A7OIw==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm] os: [linux] - '@rolldown/binding-linux-arm64-gnu@1.2.2': - resolution: {integrity: sha512-JsSMsj6sNat/MuhG5fnBD7QgbtpHKVe30x5/bAVirDHdhoQRXJkF6xc0Jqk8O4fiCUQAzMOoH9wZi3m60c8wtg==} - engines: {node: ^20.19.0 || >=22.12.0} - cpu: [arm64] - os: [linux] - libc: [glibc] - '@rolldown/binding-linux-arm64-gnu@1.2.3': resolution: {integrity: sha512-TkqEAcmmvH3I/q4114NB4RVt6241Dao48pF45uLcFGrwAaIn0iITgTAKP/dLjbN0R4buJjGb91+UHSoFmpgIWw==} engines: {node: ^20.19.0 || >=22.12.0} @@ -3341,13 +3137,6 @@ packages: os: [linux] libc: [glibc] - '@rolldown/binding-linux-arm64-musl@1.2.2': - resolution: {integrity: sha512-B5G/zJdHaoJn9vD50eGHWkiWfmq8Uhi3IiLPJTzmZTrAalk1bztUikSXo0qga18ibE0IXboyeMUnhPjhAJ45wQ==} - engines: {node: ^20.19.0 || >=22.12.0} - cpu: [arm64] - os: [linux] - libc: [musl] - '@rolldown/binding-linux-arm64-musl@1.2.3': resolution: {integrity: sha512-NHqjnxpsndf4MPymxteFAWHHfkTL8HjWh1KB7z23ofZ6QO2euONuxDXjat69dKZRALnGypg8k8SsK8vZJoXv1Q==} engines: {node: ^20.19.0 || >=22.12.0} @@ -3355,13 +3144,6 @@ packages: os: [linux] libc: [musl] - '@rolldown/binding-linux-ppc64-gnu@1.2.2': - resolution: {integrity: sha512-6mC/awzKka8W6EoekjegpfGkjz8jXWDX63pqu/HYVpyKtZfu65Jsh4QAH3Kej3CAv/c1oGX7psTmFEbr0mDxLA==} - engines: {node: ^20.19.0 || >=22.12.0} - cpu: [ppc64] - os: [linux] - libc: [glibc] - '@rolldown/binding-linux-ppc64-gnu@1.2.3': resolution: {integrity: sha512-6tbrbwfz5GB9DQ4Jwo6hy9v+vR31xZlvzZ6n5Xut6Hhx5PvrA9q/HsK8KMaYQp063iqZGXwNvZtYNLD7EM/x0w==} engines: {node: ^20.19.0 || >=22.12.0} @@ -3369,13 +3151,6 @@ packages: os: [linux] libc: [glibc] - '@rolldown/binding-linux-s390x-gnu@1.2.2': - resolution: {integrity: sha512-412MX9fJLdA1IK28EZnc8jYv2HRTleOZgfLQumJ5zy7OeJLZlg/CETwFaXjNmGVxG51cFHpKLqb5LKvBC+HsHA==} - engines: {node: ^20.19.0 || >=22.12.0} - cpu: [s390x] - os: [linux] - libc: [glibc] - '@rolldown/binding-linux-s390x-gnu@1.2.3': resolution: {integrity: sha512-oyuXxXmoZHjXC917IAPFAAv4wWAa0cM9afk8nx1+9/jNNOX1uPf8yDA6p7G0RypOfw/X0PQt5IfoquY1um+zSg==} engines: {node: ^20.19.0 || >=22.12.0} @@ -3383,13 +3158,6 @@ packages: os: [linux] libc: [glibc] - '@rolldown/binding-linux-x64-gnu@1.2.2': - resolution: {integrity: sha512-Q/+HI/ToJafZ1iCqGgVQXUEkIjufHCTF0gBQ2a5o3cg7GJ2h0qyq3nvvSmU+bGda2/7ygXpTY4TM6gO9OhQ0ZA==} - engines: {node: ^20.19.0 || >=22.12.0} - cpu: [x64] - os: [linux] - libc: [glibc] - '@rolldown/binding-linux-x64-gnu@1.2.3': resolution: {integrity: sha512-TytMwF2KVGqP2tgd0I1OY0PAv78dZRAYcF5ssDzjM34SUXCED3uXvSd5+lHoC0bTD6eEdFz7LdQNCO1y0oVk9w==} engines: {node: ^20.19.0 || >=22.12.0} @@ -3397,13 +3165,6 @@ packages: os: [linux] libc: [glibc] - '@rolldown/binding-linux-x64-musl@1.2.2': - resolution: {integrity: sha512-ZKp/w41n6wCvxzxQHtQSbuphfX3Y4cCvbjkKHusrLx4lh+JWLTU7StSltO/DKARISzbj368d+qUaCjI8K2wzXw==} - engines: {node: ^20.19.0 || >=22.12.0} - cpu: [x64] - os: [linux] - libc: [musl] - '@rolldown/binding-linux-x64-musl@1.2.3': resolution: {integrity: sha512-/E9m3qstrJFVPoULV25mVQblSNExY2+kBsYe4sy0Tn0yOOgJ8wZbZt3KnRbF/XeU2Gl1STKUQnDNTqhIE5MD4A==} engines: {node: ^20.19.0 || >=22.12.0} @@ -3411,36 +3172,18 @@ packages: os: [linux] libc: [musl] - '@rolldown/binding-openharmony-arm64@1.2.2': - resolution: {integrity: sha512-pxE6xD4KS3eAROkKK5yrhB9/3+vhlhVGMvlQLbdpzrBGDbKrnzx3RLwPaHvasLo6jgaiBLn7e04Df9C4tYhjmA==} - engines: {node: ^20.19.0 || >=22.12.0} - cpu: [arm64] - os: [openharmony] - '@rolldown/binding-openharmony-arm64@1.2.3': resolution: {integrity: sha512-Kr0OcsoQI816i6HOl3vFHpd1K0eZyh76zgfj4c1nTyaTsd5r2Mj1lwM4R90y/qaCfmTn9eHy0SKwi98eitRxug==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [openharmony] - '@rolldown/binding-win32-arm64-msvc@1.2.2': - resolution: {integrity: sha512-4MqEue5re+xIZzAWsB8sj0P1kqZySWqIuN4t6QaIO/YA6SFwySOLruvWQFzfmqk8LBK2P30KCSJwf6mJCZZ5/A==} - engines: {node: ^20.19.0 || >=22.12.0} - cpu: [arm64] - os: [win32] - '@rolldown/binding-win32-arm64-msvc@1.2.3': resolution: {integrity: sha512-hOtMwTqnME+/gJcH/PCZ0wn0zPUjiWOgkHpxbSJpfGKMezHltx1S7/k1SitzVa7Ww2cqrDDaFbZEhcJZO8o+Jw==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [win32] - '@rolldown/binding-win32-x64-msvc@1.2.2': - resolution: {integrity: sha512-NweNxxD0Nf9t8v7kodun45Ijp3EIwYY+uydPP6qBEYvfBqhIjN6dZMzlQja3tqX/aLs3F3Uz+AxDpKgRhpOZQg==} - engines: {node: ^20.19.0 || >=22.12.0} - cpu: [x64] - os: [win32] - '@rolldown/binding-win32-x64-msvc@1.2.3': resolution: {integrity: sha512-ekcqMMkI2PlhYnfzQnB/cEdYUVVJViWvoUyLrbzgDoi3Snfc1mVBwdnc306ufA5ejy8JSPjT2RlW1nQSjW7efg==} engines: {node: ^20.19.0 || >=22.12.0} @@ -3891,10 +3634,6 @@ packages: eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 typescript: '>=4.8.4 <6.1.0' - '@typescript-eslint/types@8.65.0': - resolution: {integrity: sha512-JSSwWNy+H0E/01jJEM+hrX6N0OFDzFzeIhHFSAS01tlVaevpG8cFyYRPhS5yjGOvBUx3sqQHVMjCL1CAZZMxBg==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@typescript-eslint/types@8.66.0': resolution: {integrity: sha512-H6gcYaSDOyvL3AD/jHUtUFo2jqGgn/F6nuyuZSu0QTesxL+cP4dQoIMrODRofuJC09g64+WgZ6tE19Y1N2YIFQ==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} @@ -4093,140 +3832,140 @@ packages: '@yarnpkg/lockfile@1.1.0': resolution: {integrity: sha512-GpSwvyXOcOOlV70vbnzjj4fW5xW/FdUF6nQEt1ENy7m4ZCczi1+/buVUPAqmGfqznsORNFzUMjctTIp8a9tuCQ==} - '@yuku-codegen/binding-android-arm64@0.8.3': - resolution: {integrity: sha512-/EKnnqwvN7xYoVDhQEIEJTdPDwGW1wkFz/2Eku3ES/IJd4lcQh/OaIDFBmoJKvpe12enrb1TIoYh1fxasGXolA==} + '@yuku-codegen/binding-android-arm64@0.8.4': + resolution: {integrity: sha512-rsYkGl2kOkDRsh1mxriYnk1qBS78vjlBJ3+T2XwtwKwqOliy2n+2Ae0EDxJ/uX1DZLm3KkBZarGO5isEnmHchA==} cpu: [arm64] os: [android] - '@yuku-codegen/binding-darwin-arm64@0.8.3': - resolution: {integrity: sha512-DFAOliF5YIPv3ayNHGOJhIun6Af4kMaL/YXxf8ZtD1qrOIMFnX/AQBhwfvLalhwmmxuGA8AUteaKRHBvdKZFVA==} + '@yuku-codegen/binding-darwin-arm64@0.8.4': + resolution: {integrity: sha512-tNLKzPF3FYmEcHSYvWp/LEpjHHAtDR13hwo6/gdCkYMi9x59CWn2obczKzWNe7kDor4/1AMZuJDEVRpFkTSefw==} cpu: [arm64] os: [darwin] - '@yuku-codegen/binding-darwin-x64@0.8.3': - resolution: {integrity: sha512-WlMh4/oEibaTzE9j5Zq8qnsrH4Ii4kWdcDv/Pj2Rb/MYSrKghtg+bxbWpPe/6zJD21p9zZBApQUxl8ECpZOJuQ==} + '@yuku-codegen/binding-darwin-x64@0.8.4': + resolution: {integrity: sha512-tK7LWzXNb5JbZpnoCNHB0nEhPFss/LwwehM6m/f0oYDan+iZgFZXzdoy80JdE7dVxjTZDIhUNPx8X8xbIdaoxA==} cpu: [x64] os: [darwin] - '@yuku-codegen/binding-freebsd-x64@0.8.3': - resolution: {integrity: sha512-hoDOpPP0FTxPSD+6w0Gs4p8iL1yXe6jjIXcdzNxyT1KE6B3JI6O0gTIWQISJ+8QyNpNjIwBb7nHCdRavktJM6A==} + '@yuku-codegen/binding-freebsd-x64@0.8.4': + resolution: {integrity: sha512-5MUV4d7g2p5Hd8GiXW6ynTRgYjm4Dw4eM2gaWRZ4crkGetzNx+HlPxcEfGtVNPqH5Qaa4Z2REtzdsdgvaE6/Ng==} cpu: [x64] os: [freebsd] - '@yuku-codegen/binding-linux-arm-gnu@0.8.3': - resolution: {integrity: sha512-nNW0GGMJyF04pK4A7Kq7WAYtUWU9uI5ugDAoXl9yHpd3IIZ8UI+zFlM01e+ZGWnQcdxYYLumeRe/EjzZT9bVfQ==} + '@yuku-codegen/binding-linux-arm-gnu@0.8.4': + resolution: {integrity: sha512-g6LnHrR0Rfqq5cXs7olwR2+LlVDc876pw7Hh7YXbukVSiBxQkaxqsEO/trO25z2g99zWzgXwoYvQZ1TnwA2wEw==} cpu: [arm] os: [linux] libc: [glibc] - '@yuku-codegen/binding-linux-arm-musl@0.8.3': - resolution: {integrity: sha512-/jpxKhO8AV5TmXgT3R2Gv3YctKRUhyDzd5bQw8TiJ3O4z7qerHzoW2kE40fPAO3L434/IZtZbdhr8HuOqiwECA==} + '@yuku-codegen/binding-linux-arm-musl@0.8.4': + resolution: {integrity: sha512-7XAPHrROPEFuJWXEGZeLZQN4xR8ENQ65+HSCtCHjSzCwGgnX53GUjM9ExVcHopV0a5g4vu57v2wwtyWIM5iNOQ==} cpu: [arm] os: [linux] libc: [musl] - '@yuku-codegen/binding-linux-arm64-gnu@0.8.3': - resolution: {integrity: sha512-CYhLJfnCknabfLvUjsanxC5s3BBtZHUwfzdDL7GcqShIRQh2qqgG7pPfFrFJ6Jp56kkjKXkfluFGn9nnIv0nZg==} + '@yuku-codegen/binding-linux-arm64-gnu@0.8.4': + resolution: {integrity: sha512-fnBm7NLuuwFXy7F1vRIuyOc+RW9ADUjuCKVGY87Dj8jtr9XgESNrwb+B9VLSFY7nZ0rCdK/Sm1fBqJpI7eLdKQ==} cpu: [arm64] os: [linux] libc: [glibc] - '@yuku-codegen/binding-linux-arm64-musl@0.8.3': - resolution: {integrity: sha512-c6gEdnI0MgA7/rVw6CACMciSbAcxVwLyD/jSBbMLWUeqqbysCNGrGPAHdpSaadpz3W1bd+OdXt9XWjfm66708w==} + '@yuku-codegen/binding-linux-arm64-musl@0.8.4': + resolution: {integrity: sha512-6vTw4ZHO9nm4SUkw36uG+UE6/qifZ0E8HIef7Mx/U/c2Zxu3JLBfXtU7U/NN2GMkDmcJkgwjXfpQoYw4Ch5Y1w==} cpu: [arm64] os: [linux] libc: [musl] - '@yuku-codegen/binding-linux-x64-gnu@0.8.3': - resolution: {integrity: sha512-CRVZ9Rw5lIah/PpWeShWv7XiUCMY15N6rZRA2sEZrQvc5Az7Dv9/wsDMa6oBMkfQLXuDkFo4G1QOYyWbebjejg==} + '@yuku-codegen/binding-linux-x64-gnu@0.8.4': + resolution: {integrity: sha512-+vuC3V3Lw+DB4oJgHV9pVDfQZlsZJnxmbdods7HzxgEALU3P5+czwdAcw3wfh7Ebabt0Ny8eLUb1k9RV5OB/+w==} cpu: [x64] os: [linux] libc: [glibc] - '@yuku-codegen/binding-linux-x64-musl@0.8.3': - resolution: {integrity: sha512-G12Nhecjmv7OlbCX6Y4HU4wYYePd111kTE+yTjbitnt+P3m8bNegtYG4ZGo4scGTq8cKsLF4xcda1XNzCUA6nQ==} + '@yuku-codegen/binding-linux-x64-musl@0.8.4': + resolution: {integrity: sha512-QH60PE4eZecmgNGa1/T1cKPhrfxt6ANtu4lrQ1FZ50F9b0GS9WjGmIjrfdSUeQa+f2Iqk3oEFSJdgVHBg1KPNg==} cpu: [x64] os: [linux] libc: [musl] - '@yuku-codegen/binding-win32-arm64@0.8.3': - resolution: {integrity: sha512-i8bpXWaMlik9DvFl+89emEx3RZFtSd21Vlt0UrnPvUC7h8NGElP2SwQcdcG+pPmihFIYJAoIuJLw7YdQcFcDkA==} + '@yuku-codegen/binding-win32-arm64@0.8.4': + resolution: {integrity: sha512-6r68c0nKZPIBRXZIBiD7zjlEukBR+xRxpTOVj4n1Fsjcdh4YbbJfjFfmIzdbo9jXR1xL+dPueDVdsRGOUH5MoQ==} cpu: [arm64] os: [win32] - '@yuku-codegen/binding-win32-x64@0.8.3': - resolution: {integrity: sha512-vlYymeTSsx+qxZoNvdl6KehgYDaQC4Sk/9KUnM3V2mriyCwSdhW7lqdpQGl+RLGsDTxyuRGjzGIjgRWk3lohmA==} + '@yuku-codegen/binding-win32-x64@0.8.4': + resolution: {integrity: sha512-i+BW77LPjNqe7Apq50J3OeEaVfga3G+eT2bKjb6bj4yO99fil/jnKb4ZDH4JLvby/Q7hRa6VicL2EZ7iS+ifzA==} cpu: [x64] os: [win32] - '@yuku-parser/binding-android-arm64@0.8.3': - resolution: {integrity: sha512-vySYRsMeul9ssvxeHdxgS9ZUIcq7gqljWNqgokjJE0uQWvVvOprihJ6hOsiifVqWsla0BMc3vAFBvNS9QqCw7g==} + '@yuku-parser/binding-android-arm64@0.8.4': + resolution: {integrity: sha512-+HIMmv08Zrh9ugIAEMnKBMMePOl7CDxrjc8Vui1+GG2TJHM1yI1+3wo1pnXB6Nj2IiHugDkQw8ycUI6SA2EUkQ==} cpu: [arm64] os: [android] - '@yuku-parser/binding-darwin-arm64@0.8.3': - resolution: {integrity: sha512-+wpB/wqhiZ685Y77I+lj6v9pHSAJ3Y+QMHJmvch0Q0ahIMbNwtKk3s54MhtjCMKO1qpjPbyN/PjuHDg2hbKaVQ==} + '@yuku-parser/binding-darwin-arm64@0.8.4': + resolution: {integrity: sha512-Elf/B/2m3OsyvxoQnBk8Dtu+9csHkzBNs5Yv9GbHjT3x0kVKNWjFusyZgm41VwxcPDqdpRi8tWxNX7OqXkmf/A==} cpu: [arm64] os: [darwin] - '@yuku-parser/binding-darwin-x64@0.8.3': - resolution: {integrity: sha512-jKqiWejj4zVy7pPtEGu4/Ty+pG1h7ooQOXIkm7shKZTSwTU9X8X+eoH11uIeKHZi2SQWV0GhNz0J56eerseysQ==} + '@yuku-parser/binding-darwin-x64@0.8.4': + resolution: {integrity: sha512-CjZuMoXnL5XUkVpDqh4WDPwpAw8CwmtHHnTerGkS45So/sNuwkXdyIAEqqIZfaLopi5W/V9NApAT2md9XizjsQ==} cpu: [x64] os: [darwin] - '@yuku-parser/binding-freebsd-x64@0.8.3': - resolution: {integrity: sha512-FC7zSwzFzd4z9bsId07CiHLR+Iw6yW/LzIQhL5AUtPUuVXLgEyx0rilgbRUYkl1CT3GJcLpkh63WuPZUSgCDzw==} + '@yuku-parser/binding-freebsd-x64@0.8.4': + resolution: {integrity: sha512-ibLKORdz71iI4Vs+fyFgvwQ51P5XcxJIyQLa8cSEWqwptRdo+BTcZHIQEcZnFDPUuvmJ19RRH9CoiJdfhr7pZw==} cpu: [x64] os: [freebsd] - '@yuku-parser/binding-linux-arm-gnu@0.8.3': - resolution: {integrity: sha512-So61j88b9/ygDnUPlWCm1EUPw4HSxAyDjrNHKgud5N3aRDQ3kw94nW7TriXbo7GBXID9oBHCMNm1r1Fof/Df5Q==} + '@yuku-parser/binding-linux-arm-gnu@0.8.4': + resolution: {integrity: sha512-Fo3r5fYhGDcFnl+KN+L9PgtiQPS4AIE1n1mG1o5jZ11p7g5yZ/1EjLFmSHAUsoXreun8KjTsFjEL7P1Sb93PZQ==} cpu: [arm] os: [linux] libc: [glibc] - '@yuku-parser/binding-linux-arm-musl@0.8.3': - resolution: {integrity: sha512-Nmnn20yJvSSKL8ZdtqReBRSGCDkSMqR5jEk/Sk/cdIdZmqVD49Z6M7w2GbMjdrxMI1MBPbsWFMMWxa93cd5t5g==} + '@yuku-parser/binding-linux-arm-musl@0.8.4': + resolution: {integrity: sha512-BEB31vUEgXPWf7WkoMPSzzJhpC/wWCBXyysRCCPsw47BJ/OtbQsvJbxX9fFDuSRLy3kbyIV/WbdUTgbQ9COxiw==} cpu: [arm] os: [linux] libc: [musl] - '@yuku-parser/binding-linux-arm64-gnu@0.8.3': - resolution: {integrity: sha512-Lfgw7AXJ0rxu6BMPGgfc8HLJWEIr8BHhCzcQp/75k+NM90uCLkHlBNqIg/K42KlSvBgAvu9euOvjdswib+4qJA==} + '@yuku-parser/binding-linux-arm64-gnu@0.8.4': + resolution: {integrity: sha512-xGLCRcHn9xVz7JVNyyKtiNJSf503qtUmih9XVSsghgzOmiKUMnHObs69OMMwXN3788tg1jsl11fNjjQlB8idMA==} cpu: [arm64] os: [linux] libc: [glibc] - '@yuku-parser/binding-linux-arm64-musl@0.8.3': - resolution: {integrity: sha512-cfRyu87xsJ0tFkHNsnMC4Rq6+xsFJ6i2dc4VAH52d2qLvykEJU/Mdi3ul1O2PyOApX/LoLT3uQZ0fWs3D5XE4w==} + '@yuku-parser/binding-linux-arm64-musl@0.8.4': + resolution: {integrity: sha512-3kNRi8NJT2q6FQRVCUFHIQ99+kXdi8cVJEEUi6+xtFqpMgNrZNnbgAj28ILsDC7zmclaU+v47eUCeJoKLSCbww==} cpu: [arm64] os: [linux] libc: [musl] - '@yuku-parser/binding-linux-x64-gnu@0.8.3': - resolution: {integrity: sha512-GcQQCUuYxbm6P1n+io/A50rvWKDeWHutIp6rW0ycDOZuEQjOb8hDVgS88+NDyOnd9FfS0/Z6GXopcRFDyKpzOg==} + '@yuku-parser/binding-linux-x64-gnu@0.8.4': + resolution: {integrity: sha512-isi62oMy94Z3OXwGs2l2rkqRiRyqLmfHeTRHpA/uWZbsNhnm7IdVvkF7e7wHNKAtd5jwGzOqYSroxKv2fOm7Cw==} cpu: [x64] os: [linux] libc: [glibc] - '@yuku-parser/binding-linux-x64-musl@0.8.3': - resolution: {integrity: sha512-rMkImBGZzg7GZlj8krYtdiezyjYI4igjKWMut5T65jHyNWFigMQrEpn9mDIBflloW9FKhGE3mN6yTZ/N+4HRwg==} + '@yuku-parser/binding-linux-x64-musl@0.8.4': + resolution: {integrity: sha512-9RsEw2xYHqU/pjSRBTOupWN3sF8uz9stjJdARfz6o0llvF+yfrj5QHmTiocGGBeAI80fvKmDtr2RIQClUzAPcA==} cpu: [x64] os: [linux] libc: [musl] - '@yuku-parser/binding-win32-arm64@0.8.3': - resolution: {integrity: sha512-/2Pl2cAzCXWxah8FqJapEj/ikpt9cEutEZFCa0hnbfrshkn5+C+aBM3ZDq62d1jsgQjBMmqr5HVhJUA4OAG/Tg==} + '@yuku-parser/binding-win32-arm64@0.8.4': + resolution: {integrity: sha512-VEZHo9rEGOBKR20sA3vCO00aQvwWND5aLu7YxeX+YupMZJh9hd1f17AbClJN37Q2iL1PCHht+wDTOKX6tZYqXg==} cpu: [arm64] os: [win32] - '@yuku-parser/binding-win32-x64@0.8.3': - resolution: {integrity: sha512-Ntnvjoan9jnfLhn7Kn3h8j/bhsbVdQSVmKUqFULKtmwImLCJVHOJbLL4qbEJyrOQ7r/FBL1/c/dRvx/AQWzzXg==} + '@yuku-parser/binding-win32-x64@0.8.4': + resolution: {integrity: sha512-PeH3VzN1feGjPtDpVEAqf000fPT+nxtw/696LKp/5Z9RJi/MaXpB636QC+5QtrAPSoEnIkyEe+c+mq2QLZPWBA==} cpu: [x64] os: [win32] - '@yuku-toolchain/types@0.8.3': - resolution: {integrity: sha512-9LN3HYs3A9qSPVFunsxlbfwBcUgexti3TmhOzIxB/UH8zFuaHQJXTRDcN17DW6cp1GsyZtiZA7f18uIra36Jag==} + '@yuku-toolchain/types@0.8.4': + resolution: {integrity: sha512-p7JE8flrj7ijZ/qLjHi4UwKqMarMD6zumbKXhrjp2I2iLJOuTYiQyci2U36VlXcUlNyzsY7E/mLnKCHotbzJVw==} JSONStream@1.3.5: resolution: {integrity: sha512-E+iruNOY8VV9s4JEbe1aNEm6MiszPRr/UfcHMz0TQh1BXSxHK+ASV1R6W4HpjBhSeS+54PIsAMCBmwD06LLsqQ==} @@ -4477,9 +4216,9 @@ packages: bare-abort-controller: optional: true - bare-fs@4.7.4: - resolution: {integrity: sha512-y1kC+ffIx/tPLdTE693uNjHfzTfr+ravR5tvWlMXe25nELbkqV400S71qHDwbkAQ1FVEZobB1NFRzFbCCcyBCQ==} - engines: {bare: '>=1.16.0'} + bare-fs@4.8.0: + resolution: {integrity: sha512-fM+MhCvdQhZ7NV6S95a07gPSqjIYKn6mFaXfx266wN3ajZGl/+1AzH+ubkXQ0fFZvOe2nk9VHkzdYkQE5zMV3Q==} + engines: {bare: '>=1.28.0'} peerDependencies: bare-buffer: '*' peerDependenciesMeta: @@ -4503,8 +4242,8 @@ packages: bare-events: optional: true - bare-url@2.4.7: - resolution: {integrity: sha512-o8CRCiJtib+ycO3mE4A5UChtGX4dDP2XxsWVu9P+Zc3H8tcmKwNVEDoDTXmwN+uuMhfKeT7/i7Y26xS8W7ohoA==} + bare-url@2.5.1: + resolution: {integrity: sha512-cD5ciQuKlx+eumTCfqbfiL+fhQm+dHbVNB/cX4+d+I/nx4JsVop9VoFEPAs5RJ6I84QR6bZIBjpd2kjDOYeWcg==} base64-js@1.5.1: resolution: {integrity: sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==} @@ -4513,8 +4252,8 @@ packages: resolution: {integrity: sha512-lGe34o6EHj9y3Kts9R4ZYs/Gr+6N7MCaMlIFA3F1R2O5/m7K06AxfSeO5530PEERE6/WyEg3lsuyw4GHlPZHog==} engines: {node: ^4.5.0 || >= 5.9} - baseline-browser-mapping@2.11.11: - resolution: {integrity: sha512-/yImnXwyTvgMkhgekLHok/Rx5vO6E0BmStWlSqKWMVm2a2ITuZ1Tn+9bgLS+gZRdZmWtd8nxuhHpdmCUOWsTQQ==} + baseline-browser-mapping@2.11.13: + resolution: {integrity: sha512-k9HNuUVMlqVjQ9UHzfPjIqiDbWw7WqT1AoT7GL8VwvF3r0ZfArtgiSPAlmupyNquNgOJHTuH4CKYf8ttMTWBTQ==} engines: {node: '>=6.0.0'} hasBin: true @@ -4596,8 +4335,8 @@ packages: browserify-zlib@0.1.4: resolution: {integrity: sha512-19OEpq7vWgsH6WkvkBJQDFvJS1uPcbFOQ4v9CU839dO+ZZXUZO6XpE6hNCqvlIIj+4fZvRiJ6DsAQ382GwiyTQ==} - browserslist@4.28.7: - resolution: {integrity: sha512-JxV13hNrFxqjOc8alRbq9dK1MM79NEXYpma2B2J4wAtpWS5zIEIKqWPGCl7N4o7Uc7B7itylh7SuDujATRyyTw==} + browserslist@4.28.8: + resolution: {integrity: sha512-V2NpofLblG64mfOtSgDhOJESZEGogzDMBv/q+W6oc4LXWP/q75eOXoOaaOu1EOadB9U4Bwx/e0yzbvwKH8zalA==} engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7} hasBin: true @@ -4657,8 +4396,8 @@ packages: resolution: {integrity: sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==} engines: {node: '>=6'} - caniuse-lite@1.0.30001806: - resolution: {integrity: sha512-72Cuvd95zbSYPKq6Fhg8eDJRlzgWDf7/mtoZv6Qe/DYNCEBdNxoA3+rZAU2ZhGCpZlns3EssFavaZomckT5Uuw==} + caniuse-lite@1.0.30001809: + resolution: {integrity: sha512-xxWVywk6a6Arlk+hymeycyn/VgqEfLDxupvhH/xiY5SJ/18kmi9o6MiO320DCUzypORHLtvh0I4i04tUhCNHNQ==} caseless@0.12.0: resolution: {integrity: sha512-4tYFyifaFfGacoiObjJegolkwSU4xQNGbVgUiNYVUxbQ2x2lUsFvY4hVgVzGiIe6WLOPqycWXA40l+PWsxthUw==} @@ -4858,8 +4597,9 @@ packages: peerDependencies: webpack: ^5.1.0 - core-js-compat@3.49.0: - resolution: {integrity: sha512-VQXt1jr9cBz03b331DFDCCP90b3fanciLkgiOoy8SBHy06gNf+vQ1A3WFLqG7I8TipYIKeYK9wxd0tUrvHcOZA==} + core-js-compat@3.50.0: + resolution: {integrity: sha512-XGpFGbMLHwSt74YLTKho7Ib242qi6O8MSX+sRokV4oz7iKXvQWGYZthjIhjRGMxjzVkAubBO512dKGYcefmX3Q==} + engines: {node: '>=6.4.0'} core-util-is@1.0.2: resolution: {integrity: sha512-3lqz5YjWTYnW6dlDa5TLaTCcShfar1e40rmcJVwCBJC6mWlFuj0eCHIElmG1g5kyuJ/GD+8Wn4FFCcz4gJPfaQ==} @@ -5124,8 +4864,8 @@ packages: engines: {node: '>=0.12.18'} hasBin: true - electron-to-chromium@1.5.399: - resolution: {integrity: sha512-lEcqhErbHjXRvd41rnWLpzbyU/IXfIYo7QwaFWmxGeLiLyY2TBCdHnWY88vB+p3ubnihRypDm66panXl7TylLA==} + electron-to-chromium@1.5.403: + resolution: {integrity: sha512-MQsYmdaLzvaCX5j+ZZBr5Fm6uCCnPQcRtlvmvRlWqrXy+BH2O4ffXIAScF+JQznQWB9brWp4lSD9Z4yNmaf2BA==} emoji-regex@10.6.0: resolution: {integrity: sha512-toUI84YS5YmxW219erniWD0CIVOo46xGKColeNQRgOzDorgBi1v4D71/OFzgD9GO2UGKIv1C3Sp8DAn0+j5w7A==} @@ -5249,11 +4989,6 @@ packages: engines: {node: '>=18'} hasBin: true - esbuild@0.28.1: - resolution: {integrity: sha512-HrJrvZv5ayxBzPfwphOoNzkzOIIlifzk0KJrGK2c8R4+LKpMtpYLQeUdjnwjWv/LZlkH2laZk+4w78pi99D4Vw==} - engines: {node: '>=18'} - hasBin: true - esbuild@0.28.2: resolution: {integrity: sha512-HKVLS8dvII+xoKW9kmqxbRKrnWEXfJJr/FZhhJmiqIB0e053QNYFqOBouTMO/k5sID4MvCiUCvv8b9M4h32wIA==} engines: {node: '>=18'} @@ -5921,8 +5656,8 @@ packages: resolution: {integrity: sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==} engines: {node: '>= 0.10'} - ipaddr.js@2.4.0: - resolution: {integrity: sha512-9VGk3HGanVE6JoZXHiCpnGy5X0jYDnN4EA4lntFPj+1vIWlFhIylq2CrrCOJH9EAhc5CYhq18F2Av2tgoAPsYQ==} + ipaddr.js@2.5.0: + resolution: {integrity: sha512-aq+t5NAc+cS6rZQQVWC2x98CPqGtKKTMDd4Gaodv0wShnItdKg/51djkGJ1hqH+Oy0ivDftCbSLCQob8zso01w==} engines: {node: '>= 10'} is-array-buffer@3.0.5: @@ -6594,10 +6329,8 @@ packages: resolution: {integrity: sha512-yz3xRaG20c6/BOzvYoDaGtPmGscs7YivItZEEqe6GbwNfHuxu9YNmvnEkMzKldAGY4/80pRcQRZSEnhquk9XuQ==} engines: {node: '>= 0.8'} - memfs@4.64.0: - resolution: {integrity: sha512-Kw72fgY7Wn+sD8KmtNWSafl1dz0UvAsE/PHs3YVfLiaZuA3HxNm9sRLqAu0ATiBGJvME1PxZXbBZPv5GycDeAw==} - peerDependencies: - tslib: '2' + memfs@4.68.0: + resolution: {integrity: sha512-qlU8XrIfXUuZcmXk/GODL47KXXnhSbbaWtW5z+L7cLFfIQbgAOWzL5lqUYn39kfJh+BHLaD/siaM94/UTweGow==} merge-descriptors@1.0.3: resolution: {integrity: sha512-gaNvAS7TZ897/rVaZ0nMtAyxNyi/pdbjbAwUpFQpN70GqnVfOiXpeUUMKRBmzXaSQ8DdTX4/0ms62r2K+hE6mQ==} @@ -6783,11 +6516,6 @@ packages: resolution: {integrity: sha512-dkEJPVvun4FryqBmZ5KhDo0K9iDXAwn08tMLDinNdRBNPcYEDiWYysLcc6k3mjTMlbP9KyylvRpd4wFtwrT9rw==} engines: {node: ^20.17.0 || >=22.9.0} - nanoid@3.3.16: - resolution: {integrity: sha512-bzlKTyNJ7+LdGIIwy8ijFpIqEQIvafahV7eYykJ8Cvh42EdJeODoJ6gUJXpQJvej1BddH8OqTXZNE/KfbWAu8Q==} - engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} - hasBin: true - nanoid@3.3.18: resolution: {integrity: sha512-DTg4MJbGMWkfi6VZFdNt2/caMbQy4Ou+Op/hJQvGEWcnVfoA1QA+xzRKAzw9jD6+GVOOeYr/mIcuDSdug6F6+w==} engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} @@ -6877,8 +6605,8 @@ packages: resolution: {integrity: sha512-LA4ZjwlnUblHVgq0oBF3Jl/6h/Nvs5fzBLwdEF4nuxnFdsfajde4WfxtJr3CaiH+F6ewcIB/q4jQ4UzPyid+CQ==} hasBin: true - node-releases@2.0.51: - resolution: {integrity: sha512-wRNIrw4DmVLKQlbgOMdkMx27Wrpzes2hh5Jtbi2bjPd+4wJstWIqP5A+lscnqbm0xxmT5Bpg8Lec5ItEBwx6BQ==} + node-releases@2.0.53: + resolution: {integrity: sha512-D9UOmYG3UH1V+ENW56t5QXBwJw1YEY18ruVeus89Rw+SyIgjPkCO84bRzO3uNIYosJbNwiabWVn48o3uJLjxFQ==} engines: {node: '>=18'} normalize-path@3.0.0: @@ -7191,17 +6919,13 @@ packages: peerDependencies: postcss: ^8.4.31 - postcss-selector-parser@7.1.4: - resolution: {integrity: sha512-HeP7D2wyhkR+XaK6v4W8oRF62Dsz4flyuczALJp61GckGm42u1saSSJ/0auvcBqxs3jMRFEcPK34At/0JBKdOg==} + postcss-selector-parser@7.1.5: + resolution: {integrity: sha512-KvvtD7SrlBP7dlgkBghEE3r84CABm5SmV2aNcG4oCA+qDnJ/tvKonFVvwWAyyWUEwxuNawdfEAZKP9zM3oZ2Uw==} engines: {node: '>=4'} postcss-value-parser@4.2.0: resolution: {integrity: sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==} - postcss@8.5.25: - resolution: {integrity: sha512-DTPx3RWSSnWyzLxQnlH0rJP+EW5ekl16ZU4/psbIhA0e53kJfdgaN5vKM+xP7yJtXVu+nfdVFmlgFDEKAe4Pyw==} - engines: {node: ^10 || ^12 || >=14} - postcss@8.5.26: resolution: {integrity: sha512-u82N74LFzG8ca+dD8puPnplTXoGH4fTPpVGuIbt36G3qvNlkvfD0lEAZSxaly3KX8TS/L1A1gsCEmvKmBcVbkQ==} engines: {node: ^10 || ^12 || >=14} @@ -7292,8 +7016,8 @@ packages: pvtsutils@1.3.6: resolution: {integrity: sha512-PLgQXQ6H2FWCaeRak8vvk1GW462lMxB5s3Jm673N82zI4vqtVUPuZdffdZbPDFRoU8kAhItWFtPCWiPpp4/EDg==} - pvutils@1.1.5: - resolution: {integrity: sha512-KTqnxsgGiQ6ZAzZCVlJH5eOjSnvlyEgx1m8bkRJfOhmGRqfo5KLvmAlACQkrjEtOQ4B7wF9TdSLIs9O90MX9xA==} + pvutils@1.2.0: + resolution: {integrity: sha512-BbubeCEyTuQjVMakvJQ/Sxbc93F2pwmbsxONT/ZRrwU7Ua38d8unYTwXpTVLAKJ4BDuH9IGztCjQcd/N/39Dvg==} engines: {node: '>=16.0.0'} qjobs@1.2.0: @@ -7357,8 +7081,8 @@ packages: resolution: {integrity: sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==} engines: {node: '>=8.10.0'} - readdirp@5.0.0: - resolution: {integrity: sha512-9u/XQ1pvrQtYyMpZe7DXKv2p5CNvyVwzUB6uhLAnQwHMSgKMBR62lc7AHljaeteeHXn11XTAaLLUVZYVZyuRBQ==} + readdirp@5.1.1: + resolution: {integrity: sha512-Kko+Y5XQ6fM+Ce3dq3m9YGxnacYZYl9cA1wZjaF3Vbry2L3i1qVg8+CAgNPsXRArPMUMCaOR7oa9Nqntc43JKA==} engines: {node: '>= 20.19.0'} real-require@0.2.0: @@ -7487,11 +7211,6 @@ packages: vue-tsc: optional: true - rolldown@1.2.2: - resolution: {integrity: sha512-opwpo1tQBAcpSUJDt94B7hhLNGOKjCdE//XXjeLrnx9b83bjnw45tXdg1b09yEw/VLFBJGZpwRULMmOZo7ol+A==} - engines: {node: ^20.19.0 || >=22.12.0} - hasBin: true - rolldown@1.2.3: resolution: {integrity: sha512-rn9wpmxplLf7NLNyCk9FyWh3FM43DbY8jOzCdEPzH7uflhTftRbCEpqi6Ly2osgoU8OwObtmavMbWLaWy4LX7A==} engines: {node: ^20.19.0 || >=22.12.0} @@ -7628,8 +7347,8 @@ packages: resolution: {integrity: sha512-1gnZf7DFcoIcajTjTwjwuDjzuz4PPcY2StKPlsGAQ1+YH20IRVrBaXSWmdjowTJ6u8Rc01PoYOGHXfP1mYcZNQ==} engines: {node: '>= 18'} - serialize-javascript@7.0.7: - resolution: {integrity: sha512-YAy8Od6KV+uuwUuU50np8fGB/Aues6Y0nAhA9y/hId74PlKUcme4pXcBD46NWKr1Q4osN/iseZ17YqO1XfmI8g==} + serialize-javascript@7.1.0: + resolution: {integrity: sha512-RNEqWOyhhUQYN9V1GfHwu9AR/g+NTciH6Z5u3/no6X3/w+04J2lVDL+svFQVXgXrEGBMG2puMVN3gq2SNGuTGw==} engines: {node: '>=20.0.0'} serve-index@1.9.2: @@ -8192,8 +7911,8 @@ packages: resolution: {integrity: sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==} engines: {node: '>= 0.8'} - update-browserslist-db@1.2.3: - resolution: {integrity: sha512-Js0m9cx+qOgDxo0eMiFGEueWztz+d4+M3rGlmKPT+T4IS/jP4ylw3Nwpu6cpTTP8R1MAC1kF4VbdLt3ARf209w==} + update-browserslist-db@1.3.0: + resolution: {integrity: sha512-x/M6q3w4Ybp91CNaS4S69UnliqR3BzRpOT6LWbksjth0S/+jhfaPJsWjt/TewpT8j9eLIojUf5jr29WextHroA==} hasBin: true peerDependencies: browserslist: '>= 4.21.0' @@ -8503,8 +8222,8 @@ packages: wrappy@1.0.2: resolution: {integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==} - ws@8.21.1: - resolution: {integrity: sha512-+0NTnW77fFN/DjQi6k/Sq/Yvk4Sgajw7urW8V+asjXnRgDs9gyGkdb7EzgfhA4goXsRIZKE28fzIXBHEzhuiWw==} + ws@8.21.3: + resolution: {integrity: sha512-201TZ/kPWxoPr/OKWjquZR1SWKXcvxdH+e1xrx89b3YbmzLMFCLfnaG1HFIgWzJOEWZ7MvpK++odZufgYR50Rw==} engines: {node: '>=10.0.0'} peerDependencies: bufferutil: ^4.0.1 @@ -8585,14 +8304,14 @@ packages: resolution: {integrity: sha512-xYqdZFUK/VYazNl/oCDYN+3WloWQwMfZxBoiNt6qNyk+xfOdi598muWE42rNZFp1kNOiqW936q5RhUdnpqElSg==} engines: {node: '>=18'} - yuku-ast@0.8.3: - resolution: {integrity: sha512-8x34yU5uhHUnJXzy2Qvjvec/vE9BzS0/2khVT1MsLmSLO/P8Q1Wp8IxHv+IhD+HMYETk6kherOSvP4JPWw2joQ==} + yuku-ast@0.8.4: + resolution: {integrity: sha512-s7EWfWIQkaGmsGnyr/BU0jli9YTN5TvrKIsSmALyRD9elumDQInuhv0BrVObENKVCxr9W3Ikmnx5u02KvfuUmw==} - yuku-codegen@0.8.3: - resolution: {integrity: sha512-okdo5bb+TfebQa4JOjz9QxeT34D6CcBxu8dxaPUdFEKRdLkp+D2Fah2OanepK+XTyPXdmAJzAo9iXvYvZ/5rmg==} + yuku-codegen@0.8.4: + resolution: {integrity: sha512-1Rw+NYcmB1xkHAWlsIpbwIv/Fr50idtEbLf7OjDA+90dny6PM4Krz7Fs0TT+w2PBdjaldZpN4ye5wR4Dhlm8vA==} - yuku-parser@0.8.3: - resolution: {integrity: sha512-KPQcpF9aj77ywlJBIkQWCQ9DObdxnCA8AJdUOmA5CZZx042Xt4+dvbQmPJfWxF3E+KG5dVAZ2fBKuDJ8VsKWgA==} + yuku-parser@0.8.4: + resolution: {integrity: sha512-sw41wouvT5rUmLIp87hmvm5vtF+MRSI3x6yjq6xqpYmtkQj+Ht6N7xRQ8lMhLv8N7JAzughGj0Rfi0jQRSu9HQ==} zod@3.25.76: resolution: {integrity: sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ==} @@ -8792,7 +8511,7 @@ snapshots: rxjs: 7.8.2 tslib: 2.8.1 - '@asamuzakjp/css-color@6.0.5': + '@asamuzakjp/css-color@6.0.7': dependencies: '@csstools/css-calc': 3.3.0(@csstools/css-parser-algorithms@4.0.0(@csstools/css-tokenizer@4.0.0))(@csstools/css-tokenizer@4.0.0) '@csstools/css-color-parser': 4.1.10(@csstools/css-parser-algorithms@4.0.0(@csstools/css-tokenizer@4.0.0))(@csstools/css-tokenizer@4.0.0) @@ -8886,7 +8605,7 @@ snapshots: dependencies: '@babel/compat-data': 7.29.7 '@babel/helper-validator-option': 7.29.7 - browserslist: 4.28.7 + browserslist: 4.28.8 lru-cache: 5.1.1 semver: 6.3.1 @@ -8894,7 +8613,7 @@ snapshots: dependencies: '@babel/compat-data': 8.0.0 '@babel/helper-validator-option': 8.0.0 - browserslist: 4.28.7 + browserslist: 4.28.8 lru-cache: 11.5.2 semver: 7.8.5 @@ -9422,7 +9141,7 @@ snapshots: '@babel/plugin-transform-unicode-sets-regex': 8.0.1(@babel/core@8.0.1) '@babel/preset-modules': 0.2.0(@babel/core@8.0.1) babel-plugin-polyfill-corejs3: 1.0.0(@babel/core@8.0.1) - core-js-compat: 3.49.0 + core-js-compat: 3.50.0 semver: 7.8.5 '@babel/preset-modules@0.2.0(@babel/core@8.0.1)': @@ -9549,159 +9268,81 @@ snapshots: '@discoveryjs/json-ext@1.1.0': {} - '@esbuild/aix-ppc64@0.28.1': - optional: true - '@esbuild/aix-ppc64@0.28.2': optional: true - '@esbuild/android-arm64@0.28.1': - optional: true - '@esbuild/android-arm64@0.28.2': optional: true - '@esbuild/android-arm@0.28.1': - optional: true - '@esbuild/android-arm@0.28.2': optional: true - '@esbuild/android-x64@0.28.1': - optional: true - '@esbuild/android-x64@0.28.2': optional: true - '@esbuild/darwin-arm64@0.28.1': - optional: true - '@esbuild/darwin-arm64@0.28.2': optional: true - '@esbuild/darwin-x64@0.28.1': - optional: true - '@esbuild/darwin-x64@0.28.2': optional: true - '@esbuild/freebsd-arm64@0.28.1': - optional: true - '@esbuild/freebsd-arm64@0.28.2': optional: true - '@esbuild/freebsd-x64@0.28.1': - optional: true - '@esbuild/freebsd-x64@0.28.2': optional: true - '@esbuild/linux-arm64@0.28.1': - optional: true - '@esbuild/linux-arm64@0.28.2': optional: true - '@esbuild/linux-arm@0.28.1': - optional: true - '@esbuild/linux-arm@0.28.2': optional: true - '@esbuild/linux-ia32@0.28.1': - optional: true - '@esbuild/linux-ia32@0.28.2': optional: true - '@esbuild/linux-loong64@0.28.1': - optional: true - '@esbuild/linux-loong64@0.28.2': optional: true - '@esbuild/linux-mips64el@0.28.1': - optional: true - '@esbuild/linux-mips64el@0.28.2': optional: true - '@esbuild/linux-ppc64@0.28.1': - optional: true - '@esbuild/linux-ppc64@0.28.2': optional: true - '@esbuild/linux-riscv64@0.28.1': - optional: true - '@esbuild/linux-riscv64@0.28.2': optional: true - '@esbuild/linux-s390x@0.28.1': - optional: true - '@esbuild/linux-s390x@0.28.2': optional: true - '@esbuild/linux-x64@0.28.1': - optional: true - '@esbuild/linux-x64@0.28.2': optional: true - '@esbuild/netbsd-arm64@0.28.1': - optional: true - '@esbuild/netbsd-arm64@0.28.2': optional: true - '@esbuild/netbsd-x64@0.28.1': - optional: true - '@esbuild/netbsd-x64@0.28.2': optional: true - '@esbuild/openbsd-arm64@0.28.1': - optional: true - '@esbuild/openbsd-arm64@0.28.2': optional: true - '@esbuild/openbsd-x64@0.28.1': - optional: true - '@esbuild/openbsd-x64@0.28.2': optional: true - '@esbuild/openharmony-arm64@0.28.1': - optional: true - '@esbuild/openharmony-arm64@0.28.2': optional: true - '@esbuild/sunos-x64@0.28.1': - optional: true - '@esbuild/sunos-x64@0.28.2': optional: true - '@esbuild/win32-arm64@0.28.1': - optional: true - '@esbuild/win32-arm64@0.28.2': optional: true - '@esbuild/win32-ia32@0.28.1': - optional: true - '@esbuild/win32-ia32@0.28.2': optional: true - '@esbuild/win32-x64@0.28.1': - optional: true - '@esbuild/win32-x64@0.28.2': optional: true @@ -10145,7 +9786,7 @@ snapshots: google-auth-library: 10.9.1(supports-color@11.0.0) p-retry: 4.6.2 protobufjs: 7.6.5 - ws: 8.21.1(bufferutil@4.1.0)(utf-8-validate@6.0.6) + ws: 8.21.3(bufferutil@4.1.0)(utf-8-validate@6.0.6) transitivePeerDependencies: - bufferutil - supports-color @@ -10491,59 +10132,59 @@ snapshots: dependencies: tslib: 2.8.1 - '@jsonjoy.com/fs-core@4.64.0(tslib@2.8.1)': + '@jsonjoy.com/fs-core@4.68.0(tslib@2.8.1)': dependencies: - '@jsonjoy.com/fs-node-builtins': 4.64.0(tslib@2.8.1) - '@jsonjoy.com/fs-node-utils': 4.64.0(tslib@2.8.1) + '@jsonjoy.com/fs-node-builtins': 4.68.0(tslib@2.8.1) + '@jsonjoy.com/fs-node-utils': 4.68.0(tslib@2.8.1) thingies: 2.6.1(tslib@2.8.1) tslib: 2.8.1 - '@jsonjoy.com/fs-fsa@4.64.0(tslib@2.8.1)': + '@jsonjoy.com/fs-fsa@4.68.0(tslib@2.8.1)': dependencies: - '@jsonjoy.com/fs-core': 4.64.0(tslib@2.8.1) - '@jsonjoy.com/fs-node-builtins': 4.64.0(tslib@2.8.1) - '@jsonjoy.com/fs-node-utils': 4.64.0(tslib@2.8.1) + '@jsonjoy.com/fs-core': 4.68.0(tslib@2.8.1) + '@jsonjoy.com/fs-node-builtins': 4.68.0(tslib@2.8.1) + '@jsonjoy.com/fs-node-utils': 4.68.0(tslib@2.8.1) thingies: 2.6.1(tslib@2.8.1) tslib: 2.8.1 - '@jsonjoy.com/fs-node-builtins@4.64.0(tslib@2.8.1)': + '@jsonjoy.com/fs-node-builtins@4.68.0(tslib@2.8.1)': dependencies: tslib: 2.8.1 - '@jsonjoy.com/fs-node-to-fsa@4.64.0(tslib@2.8.1)': + '@jsonjoy.com/fs-node-to-fsa@4.68.0(tslib@2.8.1)': dependencies: - '@jsonjoy.com/fs-fsa': 4.64.0(tslib@2.8.1) - '@jsonjoy.com/fs-node-builtins': 4.64.0(tslib@2.8.1) - '@jsonjoy.com/fs-node-utils': 4.64.0(tslib@2.8.1) + '@jsonjoy.com/fs-fsa': 4.68.0(tslib@2.8.1) + '@jsonjoy.com/fs-node-builtins': 4.68.0(tslib@2.8.1) + '@jsonjoy.com/fs-node-utils': 4.68.0(tslib@2.8.1) tslib: 2.8.1 - '@jsonjoy.com/fs-node-utils@4.64.0(tslib@2.8.1)': + '@jsonjoy.com/fs-node-utils@4.68.0(tslib@2.8.1)': dependencies: - '@jsonjoy.com/fs-node-builtins': 4.64.0(tslib@2.8.1) + '@jsonjoy.com/fs-node-builtins': 4.68.0(tslib@2.8.1) glob-to-regex.js: 1.2.0(tslib@2.8.1) tslib: 2.8.1 - '@jsonjoy.com/fs-node@4.64.0(tslib@2.8.1)': + '@jsonjoy.com/fs-node@4.68.0(tslib@2.8.1)': dependencies: - '@jsonjoy.com/fs-core': 4.64.0(tslib@2.8.1) - '@jsonjoy.com/fs-node-builtins': 4.64.0(tslib@2.8.1) - '@jsonjoy.com/fs-node-utils': 4.64.0(tslib@2.8.1) - '@jsonjoy.com/fs-print': 4.64.0(tslib@2.8.1) - '@jsonjoy.com/fs-snapshot': 4.64.0(tslib@2.8.1) + '@jsonjoy.com/fs-core': 4.68.0(tslib@2.8.1) + '@jsonjoy.com/fs-node-builtins': 4.68.0(tslib@2.8.1) + '@jsonjoy.com/fs-node-utils': 4.68.0(tslib@2.8.1) + '@jsonjoy.com/fs-print': 4.68.0(tslib@2.8.1) + '@jsonjoy.com/fs-snapshot': 4.68.0(tslib@2.8.1) glob-to-regex.js: 1.2.0(tslib@2.8.1) thingies: 2.6.1(tslib@2.8.1) tslib: 2.8.1 - '@jsonjoy.com/fs-print@4.64.0(tslib@2.8.1)': + '@jsonjoy.com/fs-print@4.68.0(tslib@2.8.1)': dependencies: - '@jsonjoy.com/fs-node-utils': 4.64.0(tslib@2.8.1) + '@jsonjoy.com/fs-node-utils': 4.68.0(tslib@2.8.1) tree-dump: 1.1.0(tslib@2.8.1) tslib: 2.8.1 - '@jsonjoy.com/fs-snapshot@4.64.0(tslib@2.8.1)': + '@jsonjoy.com/fs-snapshot@4.68.0(tslib@2.8.1)': dependencies: '@jsonjoy.com/buffers': 17.67.0(tslib@2.8.1) - '@jsonjoy.com/fs-node-utils': 4.64.0(tslib@2.8.1) + '@jsonjoy.com/fs-node-utils': 4.68.0(tslib@2.8.1) '@jsonjoy.com/json-pack': 17.67.0(tslib@2.8.1) '@jsonjoy.com/util': 17.67.0(tslib@2.8.1) tslib: 2.8.1 @@ -10774,7 +10415,7 @@ snapshots: '@octokit/auth-oauth-device@8.0.4': dependencies: - '@octokit/oauth-methods': 6.0.3 + '@octokit/oauth-methods': 6.0.4 '@octokit/request': 10.0.13 '@octokit/types': 17.0.0 universal-user-agent: 7.0.3 @@ -10782,23 +10423,13 @@ snapshots: '@octokit/auth-oauth-user@6.0.3': dependencies: '@octokit/auth-oauth-device': 8.0.4 - '@octokit/oauth-methods': 6.0.3 + '@octokit/oauth-methods': 6.0.4 '@octokit/request': 10.0.13 '@octokit/types': 17.0.0 universal-user-agent: 7.0.3 '@octokit/auth-token@6.0.0': {} - '@octokit/core@7.0.6': - dependencies: - '@octokit/auth-token': 6.0.0 - '@octokit/graphql': 9.0.3 - '@octokit/request': 10.0.13 - '@octokit/request-error': 7.1.1 - '@octokit/types': 16.0.0 - before-after-hook: 4.0.0 - universal-user-agent: 7.0.3 - '@octokit/core@7.0.7': dependencies: '@octokit/auth-token': 6.0.0 @@ -10819,12 +10450,6 @@ snapshots: graphql: 16.14.2 graphql-tag: 2.12.7(graphql@16.14.2) - '@octokit/graphql@9.0.3': - dependencies: - '@octokit/request': 10.0.13 - '@octokit/types': 16.0.0 - universal-user-agent: 7.0.3 - '@octokit/graphql@9.0.4': dependencies: '@octokit/request': 10.0.13 @@ -10833,7 +10458,7 @@ snapshots: '@octokit/oauth-authorization-url@8.0.0': {} - '@octokit/oauth-methods@6.0.3': + '@octokit/oauth-methods@6.0.4': dependencies: '@octokit/oauth-authorization-url': 8.0.0 '@octokit/request': 10.0.13 @@ -10844,9 +10469,9 @@ snapshots: '@octokit/openapi-types@28.0.0': {} - '@octokit/plugin-paginate-rest@14.0.0(@octokit/core@7.0.6)': + '@octokit/plugin-paginate-rest@14.0.0(@octokit/core@7.0.7)': dependencies: - '@octokit/core': 7.0.6 + '@octokit/core': 7.0.7 '@octokit/types': 16.0.0 '@octokit/plugin-paginate-rest@15.0.0(@octokit/core@7.0.7)': @@ -10854,13 +10479,13 @@ snapshots: '@octokit/core': 7.0.7 '@octokit/types': 17.0.0 - '@octokit/plugin-request-log@6.0.0(@octokit/core@7.0.6)': + '@octokit/plugin-request-log@6.0.0(@octokit/core@7.0.7)': dependencies: - '@octokit/core': 7.0.6 + '@octokit/core': 7.0.7 - '@octokit/plugin-rest-endpoint-methods@17.0.0(@octokit/core@7.0.6)': + '@octokit/plugin-rest-endpoint-methods@17.0.0(@octokit/core@7.0.7)': dependencies: - '@octokit/core': 7.0.6 + '@octokit/core': 7.0.7 '@octokit/types': 16.0.0 '@octokit/plugin-rest-endpoint-methods@18.0.0(@octokit/core@7.0.7)': @@ -10883,10 +10508,10 @@ snapshots: '@octokit/rest@22.0.1': dependencies: - '@octokit/core': 7.0.6 - '@octokit/plugin-paginate-rest': 14.0.0(@octokit/core@7.0.6) - '@octokit/plugin-request-log': 6.0.0(@octokit/core@7.0.6) - '@octokit/plugin-rest-endpoint-methods': 17.0.0(@octokit/core@7.0.6) + '@octokit/core': 7.0.7 + '@octokit/plugin-paginate-rest': 14.0.0(@octokit/core@7.0.7) + '@octokit/plugin-request-log': 6.0.0(@octokit/core@7.0.7) + '@octokit/plugin-rest-endpoint-methods': 17.0.0(@octokit/core@7.0.7) '@octokit/types@16.0.0': dependencies: @@ -10975,8 +10600,6 @@ snapshots: '@oxc-parser/binding-win32-x64-msvc@0.143.0': optional: true - '@oxc-project/types@0.142.0': {} - '@oxc-project/types@0.143.0': {} '@parcel/watcher-android-arm64@2.6.0': @@ -11179,87 +10802,45 @@ snapshots: modern-tar: 0.7.7 yargs: 18.1.0 - '@rolldown/binding-android-arm64@1.2.2': - optional: true - '@rolldown/binding-android-arm64@1.2.3': optional: true - '@rolldown/binding-darwin-arm64@1.2.2': - optional: true - '@rolldown/binding-darwin-arm64@1.2.3': optional: true - '@rolldown/binding-darwin-x64@1.2.2': - optional: true - '@rolldown/binding-darwin-x64@1.2.3': optional: true - '@rolldown/binding-freebsd-x64@1.2.2': - optional: true - '@rolldown/binding-freebsd-x64@1.2.3': optional: true - '@rolldown/binding-linux-arm-gnueabihf@1.2.2': - optional: true - '@rolldown/binding-linux-arm-gnueabihf@1.2.3': optional: true - '@rolldown/binding-linux-arm64-gnu@1.2.2': - optional: true - '@rolldown/binding-linux-arm64-gnu@1.2.3': optional: true - '@rolldown/binding-linux-arm64-musl@1.2.2': - optional: true - '@rolldown/binding-linux-arm64-musl@1.2.3': optional: true - '@rolldown/binding-linux-ppc64-gnu@1.2.2': - optional: true - '@rolldown/binding-linux-ppc64-gnu@1.2.3': optional: true - '@rolldown/binding-linux-s390x-gnu@1.2.2': - optional: true - '@rolldown/binding-linux-s390x-gnu@1.2.3': optional: true - '@rolldown/binding-linux-x64-gnu@1.2.2': - optional: true - '@rolldown/binding-linux-x64-gnu@1.2.3': optional: true - '@rolldown/binding-linux-x64-musl@1.2.2': - optional: true - '@rolldown/binding-linux-x64-musl@1.2.3': optional: true - '@rolldown/binding-openharmony-arm64@1.2.2': - optional: true - '@rolldown/binding-openharmony-arm64@1.2.3': optional: true - '@rolldown/binding-win32-arm64-msvc@1.2.2': - optional: true - '@rolldown/binding-win32-arm64-msvc@1.2.3': optional: true - '@rolldown/binding-win32-x64-msvc@1.2.2': - optional: true - '@rolldown/binding-win32-x64-msvc@1.2.3': optional: true @@ -11406,7 +10987,7 @@ snapshots: '@stylistic/eslint-plugin@5.10.0(eslint@10.8.1(jiti@2.7.0)(supports-color@11.0.0))': dependencies: '@eslint-community/eslint-utils': 4.10.1(eslint@10.8.1(jiti@2.7.0)(supports-color@11.0.0)) - '@typescript-eslint/types': 8.65.0 + '@typescript-eslint/types': 8.66.0 eslint: 10.8.1(jiti@2.7.0)(supports-color@11.0.0) eslint-visitor-keys: 4.2.1 espree: 10.4.0 @@ -11694,8 +11275,6 @@ snapshots: transitivePeerDependencies: - supports-color - '@typescript-eslint/types@8.65.0': {} - '@typescript-eslint/types@8.66.0': {} '@typescript-eslint/typescript-estree@8.66.0(supports-color@11.0.0)(typescript@6.0.3)': @@ -12035,79 +11614,79 @@ snapshots: '@yarnpkg/lockfile@1.1.0': {} - '@yuku-codegen/binding-android-arm64@0.8.3': + '@yuku-codegen/binding-android-arm64@0.8.4': optional: true - '@yuku-codegen/binding-darwin-arm64@0.8.3': + '@yuku-codegen/binding-darwin-arm64@0.8.4': optional: true - '@yuku-codegen/binding-darwin-x64@0.8.3': + '@yuku-codegen/binding-darwin-x64@0.8.4': optional: true - '@yuku-codegen/binding-freebsd-x64@0.8.3': + '@yuku-codegen/binding-freebsd-x64@0.8.4': optional: true - '@yuku-codegen/binding-linux-arm-gnu@0.8.3': + '@yuku-codegen/binding-linux-arm-gnu@0.8.4': optional: true - '@yuku-codegen/binding-linux-arm-musl@0.8.3': + '@yuku-codegen/binding-linux-arm-musl@0.8.4': optional: true - '@yuku-codegen/binding-linux-arm64-gnu@0.8.3': + '@yuku-codegen/binding-linux-arm64-gnu@0.8.4': optional: true - '@yuku-codegen/binding-linux-arm64-musl@0.8.3': + '@yuku-codegen/binding-linux-arm64-musl@0.8.4': optional: true - '@yuku-codegen/binding-linux-x64-gnu@0.8.3': + '@yuku-codegen/binding-linux-x64-gnu@0.8.4': optional: true - '@yuku-codegen/binding-linux-x64-musl@0.8.3': + '@yuku-codegen/binding-linux-x64-musl@0.8.4': optional: true - '@yuku-codegen/binding-win32-arm64@0.8.3': + '@yuku-codegen/binding-win32-arm64@0.8.4': optional: true - '@yuku-codegen/binding-win32-x64@0.8.3': + '@yuku-codegen/binding-win32-x64@0.8.4': optional: true - '@yuku-parser/binding-android-arm64@0.8.3': + '@yuku-parser/binding-android-arm64@0.8.4': optional: true - '@yuku-parser/binding-darwin-arm64@0.8.3': + '@yuku-parser/binding-darwin-arm64@0.8.4': optional: true - '@yuku-parser/binding-darwin-x64@0.8.3': + '@yuku-parser/binding-darwin-x64@0.8.4': optional: true - '@yuku-parser/binding-freebsd-x64@0.8.3': + '@yuku-parser/binding-freebsd-x64@0.8.4': optional: true - '@yuku-parser/binding-linux-arm-gnu@0.8.3': + '@yuku-parser/binding-linux-arm-gnu@0.8.4': optional: true - '@yuku-parser/binding-linux-arm-musl@0.8.3': + '@yuku-parser/binding-linux-arm-musl@0.8.4': optional: true - '@yuku-parser/binding-linux-arm64-gnu@0.8.3': + '@yuku-parser/binding-linux-arm64-gnu@0.8.4': optional: true - '@yuku-parser/binding-linux-arm64-musl@0.8.3': + '@yuku-parser/binding-linux-arm64-musl@0.8.4': optional: true - '@yuku-parser/binding-linux-x64-gnu@0.8.3': + '@yuku-parser/binding-linux-x64-gnu@0.8.4': optional: true - '@yuku-parser/binding-linux-x64-musl@0.8.3': + '@yuku-parser/binding-linux-x64-musl@0.8.4': optional: true - '@yuku-parser/binding-win32-arm64@0.8.3': + '@yuku-parser/binding-win32-arm64@0.8.4': optional: true - '@yuku-parser/binding-win32-x64@0.8.3': + '@yuku-parser/binding-win32-x64@0.8.4': optional: true - '@yuku-toolchain/types@0.8.3': {} + '@yuku-toolchain/types@0.8.4': {} JSONStream@1.3.5: dependencies: @@ -12272,7 +11851,7 @@ snapshots: asn1js@3.0.10: dependencies: pvtsutils: 1.3.6 - pvutils: 1.1.5 + pvutils: 1.2.0 tslib: 2.8.1 assert-plus@1.0.0: {} @@ -12301,8 +11880,8 @@ snapshots: autoprefixer@10.5.4(postcss@8.5.26): dependencies: - browserslist: 4.28.7 - caniuse-lite: 1.0.30001806 + browserslist: 4.28.8 + caniuse-lite: 1.0.30001809 fraction.js: 5.3.4 picocolors: 1.1.1 postcss: 8.5.26 @@ -12329,7 +11908,7 @@ snapshots: dependencies: '@babel/core': 8.0.1 '@babel/helper-define-polyfill-provider': 1.0.0(@babel/core@8.0.1) - core-js-compat: 3.49.0 + core-js-compat: 3.50.0 balanced-match@1.0.2: {} @@ -12337,12 +11916,12 @@ snapshots: bare-events@2.9.1: {} - bare-fs@4.7.4: + bare-fs@4.8.0: dependencies: bare-events: 2.9.1 bare-path: 3.1.1 bare-stream: 2.13.3(bare-events@2.9.1) - bare-url: 2.4.7 + bare-url: 2.5.1 fast-fifo: 1.3.2 transitivePeerDependencies: - bare-abort-controller @@ -12360,7 +11939,7 @@ snapshots: transitivePeerDependencies: - react-native-b4a - bare-url@2.4.7: + bare-url@2.5.1: dependencies: bare-path: 3.1.1 @@ -12368,7 +11947,7 @@ snapshots: base64id@2.0.0: {} - baseline-browser-mapping@2.11.11: {} + baseline-browser-mapping@2.11.13: {} batch@0.6.1: {} @@ -12521,13 +12100,13 @@ snapshots: dependencies: pako: 0.2.9 - browserslist@4.28.7: + browserslist@4.28.8: dependencies: - baseline-browser-mapping: 2.11.11 - caniuse-lite: 1.0.30001806 - electron-to-chromium: 1.5.399 - node-releases: 2.0.51 - update-browserslist-db: 1.2.3(browserslist@4.28.7) + baseline-browser-mapping: 2.11.13 + caniuse-lite: 1.0.30001809 + electron-to-chromium: 1.5.403 + node-releases: 2.0.53 + update-browserslist-db: 1.3.0(browserslist@4.28.8) bs-recipes@1.3.4: {} @@ -12585,7 +12164,7 @@ snapshots: callsites@3.1.0: {} - caniuse-lite@1.0.30001806: {} + caniuse-lite@1.0.30001809: {} caseless@0.12.0: {} @@ -12622,7 +12201,7 @@ snapshots: chokidar@5.0.0: dependencies: - readdirp: 5.0.0 + readdirp: 5.1.1 chrome-trace-event@1.0.4: {} @@ -12781,13 +12360,13 @@ snapshots: glob-parent: 6.0.2 normalize-path: 3.0.0 schema-utils: 4.3.3 - serialize-javascript: 7.0.7 + serialize-javascript: 7.1.0 tinyglobby: 0.2.17 webpack: 5.109.2(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.26)(uglify-js@3.19.3) - core-js-compat@3.49.0: + core-js-compat@3.50.0: dependencies: - browserslist: 4.28.7 + browserslist: 4.28.8 core-util-is@1.0.2: {} @@ -13037,7 +12616,7 @@ snapshots: ejs@6.0.1: {} - electron-to-chromium@1.5.399: {} + electron-to-chromium@1.5.403: {} emoji-regex@10.6.0: {} @@ -13066,7 +12645,7 @@ snapshots: '@socket.io/component-emitter': 3.1.2 debug: 4.4.3(supports-color@11.0.0) engine.io-parser: 5.2.3 - ws: 8.21.1(bufferutil@4.1.0)(utf-8-validate@6.0.6) + ws: 8.21.3(bufferutil@4.1.0)(utf-8-validate@6.0.6) xmlhttprequest-ssl: 2.1.2 transitivePeerDependencies: - bufferutil @@ -13086,7 +12665,7 @@ snapshots: cors: 2.8.6 debug: 4.4.3(supports-color@11.0.0) engine.io-parser: 5.2.3 - ws: 8.21.1(bufferutil@4.1.0)(utf-8-validate@6.0.6) + ws: 8.21.3(bufferutil@4.1.0)(utf-8-validate@6.0.6) transitivePeerDependencies: - bufferutil - supports-color @@ -13221,35 +12800,6 @@ snapshots: esbuild-wasm@0.28.2: {} - esbuild@0.28.1: - optionalDependencies: - '@esbuild/aix-ppc64': 0.28.1 - '@esbuild/android-arm': 0.28.1 - '@esbuild/android-arm64': 0.28.1 - '@esbuild/android-x64': 0.28.1 - '@esbuild/darwin-arm64': 0.28.1 - '@esbuild/darwin-x64': 0.28.1 - '@esbuild/freebsd-arm64': 0.28.1 - '@esbuild/freebsd-x64': 0.28.1 - '@esbuild/linux-arm': 0.28.1 - '@esbuild/linux-arm64': 0.28.1 - '@esbuild/linux-ia32': 0.28.1 - '@esbuild/linux-loong64': 0.28.1 - '@esbuild/linux-mips64el': 0.28.1 - '@esbuild/linux-ppc64': 0.28.1 - '@esbuild/linux-riscv64': 0.28.1 - '@esbuild/linux-s390x': 0.28.1 - '@esbuild/linux-x64': 0.28.1 - '@esbuild/netbsd-arm64': 0.28.1 - '@esbuild/netbsd-x64': 0.28.1 - '@esbuild/openbsd-arm64': 0.28.1 - '@esbuild/openbsd-x64': 0.28.1 - '@esbuild/openharmony-arm64': 0.28.1 - '@esbuild/sunos-x64': 0.28.1 - '@esbuild/win32-arm64': 0.28.1 - '@esbuild/win32-ia32': 0.28.1 - '@esbuild/win32-x64': 0.28.1 - esbuild@0.28.2: optionalDependencies: '@esbuild/aix-ppc64': 0.28.2 @@ -14164,7 +13714,7 @@ snapshots: ipaddr.js@1.9.1: {} - ipaddr.js@2.4.0: {} + ipaddr.js@2.5.0: {} is-array-buffer@3.0.5: dependencies: @@ -14454,7 +14004,7 @@ snapshots: jsdom@30.0.1: dependencies: - '@asamuzakjp/css-color': 6.0.5 + '@asamuzakjp/css-color': 6.0.7 '@asamuzakjp/dom-selector': 8.3.2 '@bramus/specificity': 2.4.2 '@csstools/css-syntax-patches-for-csstree': 1.1.7(css-tree@3.2.1) @@ -14858,16 +14408,16 @@ snapshots: media-typer@1.1.1: {} - memfs@4.64.0(tslib@2.8.1): + memfs@4.68.0: dependencies: - '@jsonjoy.com/fs-core': 4.64.0(tslib@2.8.1) - '@jsonjoy.com/fs-fsa': 4.64.0(tslib@2.8.1) - '@jsonjoy.com/fs-node': 4.64.0(tslib@2.8.1) - '@jsonjoy.com/fs-node-builtins': 4.64.0(tslib@2.8.1) - '@jsonjoy.com/fs-node-to-fsa': 4.64.0(tslib@2.8.1) - '@jsonjoy.com/fs-node-utils': 4.64.0(tslib@2.8.1) - '@jsonjoy.com/fs-print': 4.64.0(tslib@2.8.1) - '@jsonjoy.com/fs-snapshot': 4.64.0(tslib@2.8.1) + '@jsonjoy.com/fs-core': 4.68.0(tslib@2.8.1) + '@jsonjoy.com/fs-fsa': 4.68.0(tslib@2.8.1) + '@jsonjoy.com/fs-node': 4.68.0(tslib@2.8.1) + '@jsonjoy.com/fs-node-builtins': 4.68.0(tslib@2.8.1) + '@jsonjoy.com/fs-node-to-fsa': 4.68.0(tslib@2.8.1) + '@jsonjoy.com/fs-node-utils': 4.68.0(tslib@2.8.1) + '@jsonjoy.com/fs-print': 4.68.0(tslib@2.8.1) + '@jsonjoy.com/fs-snapshot': 4.68.0(tslib@2.8.1) '@jsonjoy.com/json-pack': 1.21.0(tslib@2.8.1) '@jsonjoy.com/util': 1.9.0(tslib@2.8.1) glob-to-regex.js: 1.2.0(tslib@2.8.1) @@ -15013,8 +14563,6 @@ snapshots: mute-stream@3.0.0: {} - nanoid@3.3.16: {} - nanoid@3.3.18: {} natural-compare@1.4.0: {} @@ -15047,7 +14595,7 @@ snapshots: '@ampproject/remapping': 2.3.0 '@angular/compiler-cli': 22.2.0-next.1(@angular/compiler@22.2.0-next.1)(typescript@6.0.3) ajv: 8.20.0 - browserslist: 4.28.7 + browserslist: 4.28.8 chokidar: 5.0.0 commander: 15.0.0 dependency-graph: 1.0.0 @@ -15114,7 +14662,7 @@ snapshots: node-gyp-build@4.8.4: {} - node-releases@2.0.51: {} + node-releases@2.0.53: {} normalize-path@3.0.0: {} @@ -15410,7 +14958,7 @@ snapshots: asn1js: 3.0.10 bytestreamjs: 2.0.1 pvtsutils: 1.3.6 - pvutils: 1.1.5 + pvutils: 1.2.0 tslib: 2.8.1 pluralize@8.0.0: {} @@ -15443,13 +14991,13 @@ snapshots: dependencies: icss-utils: 5.1.0(postcss@8.5.26) postcss: 8.5.26 - postcss-selector-parser: 7.1.4 + postcss-selector-parser: 7.1.5 postcss-value-parser: 4.2.0 postcss-modules-scope@3.2.1(postcss@8.5.26): dependencies: postcss: 8.5.26 - postcss-selector-parser: 7.1.4 + postcss-selector-parser: 7.1.5 postcss-modules-values@4.0.0(postcss@8.5.26): dependencies: @@ -15460,19 +15008,13 @@ snapshots: dependencies: postcss: 8.5.26 - postcss-selector-parser@7.1.4: + postcss-selector-parser@7.1.5: dependencies: cssesc: 3.0.0 util-deprecate: 1.0.2 postcss-value-parser@4.2.0: {} - postcss@8.5.25: - dependencies: - nanoid: 3.3.16 - picocolors: 1.1.1 - source-map-js: 1.2.1 - postcss@8.5.26: dependencies: nanoid: 3.3.18 @@ -15556,7 +15098,7 @@ snapshots: devtools-protocol: 0.0.1653615 typed-query-selector: 2.12.2 webdriver-bidi-protocol: 0.4.2 - ws: 8.21.1(bufferutil@4.1.0)(utf-8-validate@6.0.6) + ws: 8.21.3(bufferutil@4.1.0)(utf-8-validate@6.0.6) transitivePeerDependencies: - bufferutil - proxy-agent @@ -15581,7 +15123,7 @@ snapshots: dependencies: tslib: 2.8.1 - pvutils@1.1.5: {} + pvutils@1.2.0: {} qjobs@1.2.0: {} @@ -15668,7 +15210,7 @@ snapshots: dependencies: picomatch: 2.3.2 - readdirp@5.0.0: {} + readdirp@5.1.1: {} real-require@0.2.0: {} @@ -15796,34 +15338,14 @@ snapshots: get-tsconfig: 5.0.0-beta.5 obug: 2.1.4 rolldown: 1.2.3 - yuku-ast: 0.8.3 - yuku-codegen: 0.8.3 - yuku-parser: 0.8.3 + yuku-ast: 0.8.4 + yuku-codegen: 0.8.4 + yuku-parser: 0.8.4 optionalDependencies: typescript: 6.0.3 transitivePeerDependencies: - oxc-resolver - rolldown@1.2.2: - dependencies: - '@oxc-project/types': 0.142.0 - '@rolldown/pluginutils': 1.0.1 - optionalDependencies: - '@rolldown/binding-android-arm64': 1.2.2 - '@rolldown/binding-darwin-arm64': 1.2.2 - '@rolldown/binding-darwin-x64': 1.2.2 - '@rolldown/binding-freebsd-x64': 1.2.2 - '@rolldown/binding-linux-arm-gnueabihf': 1.2.2 - '@rolldown/binding-linux-arm64-gnu': 1.2.2 - '@rolldown/binding-linux-arm64-musl': 1.2.2 - '@rolldown/binding-linux-ppc64-gnu': 1.2.2 - '@rolldown/binding-linux-s390x-gnu': 1.2.2 - '@rolldown/binding-linux-x64-gnu': 1.2.2 - '@rolldown/binding-linux-x64-musl': 1.2.2 - '@rolldown/binding-openharmony-arm64': 1.2.2 - '@rolldown/binding-win32-arm64-msvc': 1.2.2 - '@rolldown/binding-win32-x64-msvc': 1.2.2 - rolldown@1.2.3: dependencies: '@oxc-project/types': 0.143.0 @@ -16024,7 +15546,7 @@ snapshots: transitivePeerDependencies: - supports-color - serialize-javascript@7.0.7: {} + serialize-javascript@7.1.0: {} serve-index@1.9.2(supports-color@11.0.0): dependencies: @@ -16138,7 +15660,7 @@ snapshots: socket.io-adapter@2.5.8(bufferutil@4.1.0)(supports-color@11.0.0)(utf-8-validate@6.0.6): dependencies: debug: 4.4.3(supports-color@11.0.0) - ws: 8.21.1(bufferutil@4.1.0)(utf-8-validate@6.0.6) + ws: 8.21.3(bufferutil@4.1.0)(utf-8-validate@6.0.6) transitivePeerDependencies: - bufferutil - supports-color @@ -16391,7 +15913,7 @@ snapshots: tar-stream@3.2.0: dependencies: b4a: 1.8.1 - bare-fs: 4.7.4 + bare-fs: 4.8.0 fast-fifo: 1.3.2 streamx: 2.28.0 transitivePeerDependencies: @@ -16523,7 +16045,7 @@ snapshots: tsx@4.23.7: dependencies: - esbuild: 0.28.1 + esbuild: 0.28.2 optionalDependencies: fsevents: 2.3.3 @@ -16664,9 +16186,9 @@ snapshots: unpipe@1.0.0: {} - update-browserslist-db@1.2.3(browserslist@4.28.7): + update-browserslist-db@1.3.0(browserslist@4.28.8): dependencies: - browserslist: 4.28.7 + browserslist: 4.28.8 escalade: 3.2.0 picocolors: 1.1.1 @@ -16772,8 +16294,8 @@ snapshots: dependencies: lightningcss: 1.33.0 picomatch: 4.0.5 - postcss: 8.5.25 - rolldown: 1.2.2 + postcss: 8.5.26 + rolldown: 1.2.3 tinyglobby: 0.2.17 optionalDependencies: '@types/node': 22.20.1 @@ -16850,18 +16372,16 @@ snapshots: webidl-conversions@8.0.1: {} - webpack-dev-middleware@8.1.1(tslib@2.8.1)(webpack@5.109.2(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.26)(uglify-js@3.19.3)): + webpack-dev-middleware@8.1.1(webpack@5.109.2(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.26)(uglify-js@3.19.3)): dependencies: - memfs: 4.64.0(tslib@2.8.1) + memfs: 4.68.0 mime-types: 3.0.2 range-parser: 1.3.0 schema-utils: 4.3.3 optionalDependencies: webpack: 5.109.2(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.26)(uglify-js@3.19.3) - transitivePeerDependencies: - - tslib - webpack-dev-server@6.0.0(bufferutil@4.1.0)(supports-color@11.0.0)(tslib@2.8.1)(utf-8-validate@6.0.6)(webpack@5.109.2(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.26)(uglify-js@3.19.3)): + webpack-dev-server@6.0.0(bufferutil@4.1.0)(supports-color@11.0.0)(utf-8-validate@6.0.6)(webpack@5.109.2(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.26)(uglify-js@3.19.3)): dependencies: '@types/bonjour': 3.5.13 '@types/connect-history-api-fallback': 1.5.4 @@ -16878,7 +16398,7 @@ snapshots: express: 5.2.1(supports-color@11.0.0) graceful-fs: 4.2.11 http-proxy-middleware: 4.2.0(supports-color@11.0.0) - ipaddr.js: 2.4.0 + ipaddr.js: 2.5.0 launch-editor: 2.14.1 open: 11.0.0 p-retry: 8.0.0 @@ -16886,14 +16406,13 @@ snapshots: selfsigned: 5.5.0 serve-index: 1.9.2(supports-color@11.0.0) tinyglobby: 0.2.17 - webpack-dev-middleware: 8.1.1(tslib@2.8.1)(webpack@5.109.2(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.26)(uglify-js@3.19.3)) - ws: 8.21.1(bufferutil@4.1.0)(utf-8-validate@6.0.6) + webpack-dev-middleware: 8.1.1(webpack@5.109.2(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.26)(uglify-js@3.19.3)) + ws: 8.21.3(bufferutil@4.1.0)(utf-8-validate@6.0.6) optionalDependencies: webpack: 5.109.2(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.26)(uglify-js@3.19.3) transitivePeerDependencies: - bufferutil - supports-color - - tslib - utf-8-validate webpack-merge@6.0.1: @@ -16917,7 +16436,7 @@ snapshots: '@webassemblyjs/wasm-edit': 1.14.1 '@webassemblyjs/wasm-parser': 1.14.1 acorn: 8.18.0 - browserslist: 4.28.7 + browserslist: 4.28.8 chrome-trace-event: 1.0.4 enhanced-resolve: 5.24.5 es-module-lexer: 2.3.1 @@ -16953,7 +16472,7 @@ snapshots: '@webassemblyjs/wasm-edit': 1.14.1 '@webassemblyjs/wasm-parser': 1.14.1 acorn: 8.18.0 - browserslist: 4.28.7 + browserslist: 4.28.8 chrome-trace-event: 1.0.4 enhanced-resolve: 5.24.5 es-module-lexer: 2.3.1 @@ -17102,7 +16621,7 @@ snapshots: wrappy@1.0.2: {} - ws@8.21.1(bufferutil@4.1.0)(utf-8-validate@6.0.6): + ws@8.21.3(bufferutil@4.1.0)(utf-8-validate@6.0.6): optionalDependencies: bufferutil: 4.1.0 utf-8-validate: 6.0.6 @@ -17169,44 +16688,44 @@ snapshots: yoctocolors@2.2.0: {} - yuku-ast@0.8.3: + yuku-ast@0.8.4: dependencies: - '@yuku-toolchain/types': 0.8.3 + '@yuku-toolchain/types': 0.8.4 - yuku-codegen@0.8.3: + yuku-codegen@0.8.4: dependencies: - '@yuku-toolchain/types': 0.8.3 + '@yuku-toolchain/types': 0.8.4 optionalDependencies: - '@yuku-codegen/binding-android-arm64': 0.8.3 - '@yuku-codegen/binding-darwin-arm64': 0.8.3 - '@yuku-codegen/binding-darwin-x64': 0.8.3 - '@yuku-codegen/binding-freebsd-x64': 0.8.3 - '@yuku-codegen/binding-linux-arm-gnu': 0.8.3 - '@yuku-codegen/binding-linux-arm-musl': 0.8.3 - '@yuku-codegen/binding-linux-arm64-gnu': 0.8.3 - '@yuku-codegen/binding-linux-arm64-musl': 0.8.3 - '@yuku-codegen/binding-linux-x64-gnu': 0.8.3 - '@yuku-codegen/binding-linux-x64-musl': 0.8.3 - '@yuku-codegen/binding-win32-arm64': 0.8.3 - '@yuku-codegen/binding-win32-x64': 0.8.3 - - yuku-parser@0.8.3: - dependencies: - '@yuku-toolchain/types': 0.8.3 - yuku-ast: 0.8.3 + '@yuku-codegen/binding-android-arm64': 0.8.4 + '@yuku-codegen/binding-darwin-arm64': 0.8.4 + '@yuku-codegen/binding-darwin-x64': 0.8.4 + '@yuku-codegen/binding-freebsd-x64': 0.8.4 + '@yuku-codegen/binding-linux-arm-gnu': 0.8.4 + '@yuku-codegen/binding-linux-arm-musl': 0.8.4 + '@yuku-codegen/binding-linux-arm64-gnu': 0.8.4 + '@yuku-codegen/binding-linux-arm64-musl': 0.8.4 + '@yuku-codegen/binding-linux-x64-gnu': 0.8.4 + '@yuku-codegen/binding-linux-x64-musl': 0.8.4 + '@yuku-codegen/binding-win32-arm64': 0.8.4 + '@yuku-codegen/binding-win32-x64': 0.8.4 + + yuku-parser@0.8.4: + dependencies: + '@yuku-toolchain/types': 0.8.4 + yuku-ast: 0.8.4 optionalDependencies: - '@yuku-parser/binding-android-arm64': 0.8.3 - '@yuku-parser/binding-darwin-arm64': 0.8.3 - '@yuku-parser/binding-darwin-x64': 0.8.3 - '@yuku-parser/binding-freebsd-x64': 0.8.3 - '@yuku-parser/binding-linux-arm-gnu': 0.8.3 - '@yuku-parser/binding-linux-arm-musl': 0.8.3 - '@yuku-parser/binding-linux-arm64-gnu': 0.8.3 - '@yuku-parser/binding-linux-arm64-musl': 0.8.3 - '@yuku-parser/binding-linux-x64-gnu': 0.8.3 - '@yuku-parser/binding-linux-x64-musl': 0.8.3 - '@yuku-parser/binding-win32-arm64': 0.8.3 - '@yuku-parser/binding-win32-x64': 0.8.3 + '@yuku-parser/binding-android-arm64': 0.8.4 + '@yuku-parser/binding-darwin-arm64': 0.8.4 + '@yuku-parser/binding-darwin-x64': 0.8.4 + '@yuku-parser/binding-freebsd-x64': 0.8.4 + '@yuku-parser/binding-linux-arm-gnu': 0.8.4 + '@yuku-parser/binding-linux-arm-musl': 0.8.4 + '@yuku-parser/binding-linux-arm64-gnu': 0.8.4 + '@yuku-parser/binding-linux-arm64-musl': 0.8.4 + '@yuku-parser/binding-linux-x64-gnu': 0.8.4 + '@yuku-parser/binding-linux-x64-musl': 0.8.4 + '@yuku-parser/binding-win32-arm64': 0.8.4 + '@yuku-parser/binding-win32-x64': 0.8.4 zod@3.25.76: {} From a56a691af9da968c46fdbb25fa8d99f5c54188f3 Mon Sep 17 00:00:00 2001 From: Angular Robot Date: Tue, 11 Aug 2026 18:29:28 +0000 Subject: [PATCH 287/787] build: update dependency jsdom to v30 See associated pull request for more information. --- .../schematics/angular/utility/latest-versions/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/schematics/angular/utility/latest-versions/package.json b/packages/schematics/angular/utility/latest-versions/package.json index 96b002df8b92..92aca6a12183 100644 --- a/packages/schematics/angular/utility/latest-versions/package.json +++ b/packages/schematics/angular/utility/latest-versions/package.json @@ -16,7 +16,7 @@ "karma-jasmine-html-reporter": "~2.2.0", "karma-jasmine": "~5.1.0", "karma": "~6.4.0", - "jsdom": "^28.0.0", + "jsdom": "^30.0.0", "less": "^4.2.0", "postcss": "^8.5.3", "prettier": "^3.8.1", From 01d89fb02cba2af3814789c4951be821009eeb15 Mon Sep 17 00:00:00 2001 From: Angular Robot Date: Wed, 12 Aug 2026 09:47:15 +0000 Subject: [PATCH 288/787] build: update cross-repo angular dependencies See associated pull request for more information. --- tests/e2e/ng-snapshot/package.json | 32 +++++++++++++++--------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/tests/e2e/ng-snapshot/package.json b/tests/e2e/ng-snapshot/package.json index b425b4d0a929..cda05c14524e 100644 --- a/tests/e2e/ng-snapshot/package.json +++ b/tests/e2e/ng-snapshot/package.json @@ -2,21 +2,21 @@ "description": "snapshot versions of Angular for e2e testing", "private": true, "dependencies": { - "@angular/animations": "github:angular/animations-builds#521e83b77cef9357cc3f31675c0a9358dfba2ac0", - "@angular/cdk": "github:angular/cdk-builds#cd9b1387b890e1e032ca9511f643a360a6292919", - "@angular/common": "github:angular/common-builds#ef79afafcb0fe8ac4a9ad7ba6678c71470ac68a9", - "@angular/compiler": "github:angular/compiler-builds#66c497ef5416fadef51784c43cfab64965f8527d", - "@angular/compiler-cli": "github:angular/compiler-cli-builds#4f92a79192840f7deba06eb96ce2ba92af6fb46e", - "@angular/core": "github:angular/core-builds#d645d8cca5d4a209d5b86dc2154e15288c58cec5", - "@angular/forms": "github:angular/forms-builds#b8c7756a574710420a3a61ce3891d933243559eb", - "@angular/language-service": "github:angular/language-service-builds#9249de91ccb22cc9777672b9cea58eb9db361174", - "@angular/localize": "github:angular/localize-builds#85e4b2af2127ba3791bb5c0ff1970efec1ae3d06", - "@angular/material": "github:angular/material-builds#189f6e896cf4198779ac1b494719e530106cffc5", - "@angular/material-moment-adapter": "github:angular/material-moment-adapter-builds#24ef2e6996111588eb71267683a8457456cb00c2", - "@angular/platform-browser": "github:angular/platform-browser-builds#21ad1c71d68efa80ac4be0f599113537e1fe2ec0", - "@angular/platform-browser-dynamic": "github:angular/platform-browser-dynamic-builds#c350d90c660c9c9d0caaeef69910a47461a4d1ae", - "@angular/platform-server": "github:angular/platform-server-builds#b66441d388fd65f5f00035826eb91c2d5a9b80d1", - "@angular/router": "github:angular/router-builds#38c9931aa53a6664a2661d9a1c10260393b8499f", - "@angular/service-worker": "github:angular/service-worker-builds#b05d7dbccd8ba2f81997a20869fa6a658a267861" + "@angular/animations": "github:angular/animations-builds#cf2ec5af8a4a8dadacce5be2f96a453842f7f90a", + "@angular/cdk": "github:angular/cdk-builds#07799f06e6928c1f05acb33a41bc8461932bda57", + "@angular/common": "github:angular/common-builds#5e26e29114bb870784405f940cb8226c50df6a77", + "@angular/compiler": "github:angular/compiler-builds#e9d2fa722fc4f00d82bcc63c842133476a4dc96f", + "@angular/compiler-cli": "github:angular/compiler-cli-builds#e511b19996cfdb8c552cccc95e17a1af2b509f85", + "@angular/core": "github:angular/core-builds#76b8a976542628eb465f00c044c322e0a71597bb", + "@angular/forms": "github:angular/forms-builds#3c6be983edb9068c47164ac72e4b09640a8a64bc", + "@angular/language-service": "github:angular/language-service-builds#a22cd6c1c9d59f4b6a8db500e43b3ba470d7f308", + "@angular/localize": "github:angular/localize-builds#200d3ad4a53945f8763ecaa39a25fc7647a9db98", + "@angular/material": "github:angular/material-builds#4070f117b4ed1731d5baa3eafc966c18843150dc", + "@angular/material-moment-adapter": "github:angular/material-moment-adapter-builds#3cb5c085aa13369bc3d4e280e6a92cb58a71b7fc", + "@angular/platform-browser": "github:angular/platform-browser-builds#b2a6528a4e1790430e45274395bbd18eab8eabec", + "@angular/platform-browser-dynamic": "github:angular/platform-browser-dynamic-builds#1990f26fa35883d83038d670a67d626d431008e3", + "@angular/platform-server": "github:angular/platform-server-builds#b5820a9bca65205c659c8a637b6e00228a3a89cc", + "@angular/router": "github:angular/router-builds#0d8517df48781d4d444cb941b113809908759504", + "@angular/service-worker": "github:angular/service-worker-builds#71a961887bd5db07d5a8294b2f71742fce3bb1a7" } } From 71eca4c39c5f4ec1b2b2f2050d45a7c2c04e8ff3 Mon Sep 17 00:00:00 2001 From: Angular Robot Date: Tue, 11 Aug 2026 16:38:49 +0000 Subject: [PATCH 289/787] build: update dependency node to v24 See associated pull request for more information. --- .nvmrc | 2 +- MODULE.bazel | 16 ++++++++-------- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/.nvmrc b/.nvmrc index c94711948a66..60ade1ae01e8 100644 --- a/.nvmrc +++ b/.nvmrc @@ -1 +1 @@ -22.23.2 +24.19.0 diff --git a/MODULE.bazel b/MODULE.bazel index 4e27b01981b4..705bed3d1bf6 100644 --- a/MODULE.bazel +++ b/MODULE.bazel @@ -40,15 +40,15 @@ git_override( node = use_extension("@rules_nodejs//nodejs:extensions.bzl", "node") node.toolchain( node_repositories = { - "22.23.2-darwin_arm64": ("node-v22.23.2-darwin-arm64.tar.gz", "node-v22.23.2-darwin-arm64", "61130f394c1630d211dd50aecc4353d379480f36d3ac913cd85dbba1aed585c6"), - "22.23.2-darwin_amd64": ("node-v22.23.2-darwin-x64.tar.gz", "node-v22.23.2-darwin-x64", "58e99022c2ff89395576cc7fd4d98cea24bb68081475d5f88b801ee8729fb026"), - "22.23.2-linux_arm64": ("node-v22.23.2-linux-arm64.tar.xz", "node-v22.23.2-linux-arm64", "fff4078c5def658577f92c88db7db3bc0072924bfb93fe52c1e744a54e94abb8"), - "22.23.2-linux_ppc64le": ("node-v22.23.2-linux-ppc64le.tar.xz", "node-v22.23.2-linux-ppc64le", "e2ba10110ad34096c051fe47134fcd12175ecc48e7e879d7d4c78b70cf66442c"), - "22.23.2-linux_s390x": ("node-v22.23.2-linux-s390x.tar.xz", "node-v22.23.2-linux-s390x", "50aa0935c7caee2f95434f84c2c19f16e4f223257eadb341a3a2d5aaa545bbe6"), - "22.23.2-linux_amd64": ("node-v22.23.2-linux-x64.tar.xz", "node-v22.23.2-linux-x64", "d60acfe00a2932254bb0ad20e01b0d74397a0875595de719654b214f4b03f307"), - "22.23.2-windows_amd64": ("node-v22.23.2-win-x64.zip", "node-v22.23.2-win-x64", "1177b4137ba5adaa56354ae40f1080c7450e8ae09cecb47da459d1c52ac99f97"), + "24.19.0-darwin_arm64": ("node-v24.19.0-darwin-arm64.tar.gz", "node-v24.19.0-darwin-arm64", "8294b7aa9b03997481c06babf1e8b270c859358f27da57a11509afe537ac381d"), + "24.19.0-darwin_amd64": ("node-v24.19.0-darwin-x64.tar.gz", "node-v24.19.0-darwin-x64", "d1b5e999db158c62fe8f7267a4476b035d8bd93b1a605bac24a3f0dd166e3316"), + "24.19.0-linux_arm64": ("node-v24.19.0-linux-arm64.tar.xz", "node-v24.19.0-linux-arm64", "01443c1e1a29e531ccad5a46fefa6df490d2189c49f7955904aecdbb0fe86fdc"), + "24.19.0-linux_ppc64le": ("node-v24.19.0-linux-ppc64le.tar.xz", "node-v24.19.0-linux-ppc64le", "c510c6ce12f07010f771e6edb22a3fe23f4f2e6f40b1ffd4941aed0646a0d8b3"), + "24.19.0-linux_s390x": ("node-v24.19.0-linux-s390x.tar.xz", "node-v24.19.0-linux-s390x", "a4792e65962ffa0af42627aacf1122a60c3c88dbf4e4184f06820d66f9da8ba4"), + "24.19.0-linux_amd64": ("node-v24.19.0-linux-x64.tar.xz", "node-v24.19.0-linux-x64", "14b342e71204f811bde6153be8e04b62aef63c236fef92b55f9c83154b409647"), + "24.19.0-windows_amd64": ("node-v24.19.0-win-x64.zip", "node-v24.19.0-win-x64", "57f71ab3652e797d84acddc79c81cc9ff1c6ddb2a1974cdb83f00fee9bff4c73"), }, - node_version = "22.23.2", + node_version = "24.19.0", ) use_repo( node, From 7e7790d1a3c21d107670213d1c6e0ea6f5bdb0fa Mon Sep 17 00:00:00 2001 From: Doug Parker Date: Wed, 12 Aug 2026 11:33:38 -0700 Subject: [PATCH 290/787] docs: release notes for the v20.3.34 release --- CHANGELOG.md | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1ff82d9e52d9..4127839d9051 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,21 @@ + + +# 20.3.34 (2026-08-12) + +### @angular/cli + +| Commit | Type | Description | +| --------------------------------------------------------------------------------------------------- | ---- | ------------------------------------------------------ | +| [3962517b9](https://github.com/angular/angular-cli/commit/3962517b95c76016ff7bcb53662704dff18c0552) | fix | update dependency @modelcontextprotocol/sdk to v1.30.0 | + +### @angular-devkit/build-angular + +| Commit | Type | Description | +| --------------------------------------------------------------------------------------------------- | ---- | --------------------- | +| [f348efe8b](https://github.com/angular/angular-cli/commit/f348efe8b6d9c9d7014afb331eecda0a9478ba0a) | fix | bump undici to 7.29.0 | + + + # 22.2.0-next.2 (2026-08-05) From ec5aecce95dccaa957441fa1a35480cab41d0288 Mon Sep 17 00:00:00 2001 From: Doug Parker Date: Wed, 12 Aug 2026 14:25:51 -0700 Subject: [PATCH 291/787] docs: release notes for the v21.2.21 release --- CHANGELOG.md | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4127839d9051..8ce92e3ecd89 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,21 @@ + + +# 21.2.21 (2026-08-12) + +### @angular/cli + +| Commit | Type | Description | +| --------------------------------------------------------------------------------------------------- | ---- | ------------------------------------------------------ | +| [ba5d16cac](https://github.com/angular/angular-cli/commit/ba5d16cacab4139897d1f0cf4161562b1bd00553) | fix | update dependency @modelcontextprotocol/sdk to v1.30.0 | + +### @angular/build + +| Commit | Type | Description | +| --------------------------------------------------------------------------------------------------- | ---- | --------------------- | +| [f7f60e69e](https://github.com/angular/angular-cli/commit/f7f60e69e77cda60378543a9ca9cc2c76c0bf34f) | fix | bump undici to 7.29.0 | + + + # 20.3.34 (2026-08-12) From a6449989eb1ae90987552ad9d7d0b55bf7ead88f Mon Sep 17 00:00:00 2001 From: Charles Lyding <19598772+clydin@users.noreply.github.com> Date: Wed, 12 Aug 2026 15:13:20 -0400 Subject: [PATCH 292/787] refactor(@angular/build): lazy load beasties in critical css processor Beasties and its transitive dependencies (postcss, css-select, htmlparser2, domutils, dom-serializer, and postcss parsers) were previously imported statically at the top level of the critical CSS utility. This change converts beasties to a dynamic import that is resolved on first use within the process method of InlineCriticalCssProcessor. Deferring the loading of beasties eliminates synchronous module statting, file reading, and V8 bytecode parsing overhead from the initial CLI setup phase. --- .../utils/index-file/inline-critical-css.ts | 283 ++++++++++-------- 1 file changed, 160 insertions(+), 123 deletions(-) diff --git a/packages/angular/build/src/utils/index-file/inline-critical-css.ts b/packages/angular/build/src/utils/index-file/inline-critical-css.ts index e5106f39cf6b..716d34bf037e 100644 --- a/packages/angular/build/src/utils/index-file/inline-critical-css.ts +++ b/packages/angular/build/src/utils/index-file/inline-critical-css.ts @@ -6,7 +6,6 @@ * found in the LICENSE file at https://angular.dev/license */ -import Beasties from 'beasties'; import { readFile } from 'node:fs/promises'; /** @@ -95,147 +94,184 @@ interface PartialDocument { querySelector(selector: string): PartialHTMLElement | null; } -/* eslint-disable @typescript-eslint/no-unsafe-declaration-merging */ - -// We use Typescript declaration merging because `embedLinkedStylesheet` it's not declared in -// the `Beasties` types which means that we can't call the `super` implementation. interface BeastiesBase { embedLinkedStylesheet(link: PartialHTMLElement, document: PartialDocument): Promise; + readFile(path: string): Promise; + process(html: string): Promise; } -class BeastiesBase extends Beasties {} -/* eslint-enable @typescript-eslint/no-unsafe-declaration-merging */ - -class BeastiesExtended extends BeastiesBase { - readonly warnings: string[] = []; - readonly errors: string[] = []; - private addedCspScriptsDocuments = new WeakSet(); - private documentNonces = new WeakMap(); - - constructor( - private readonly optionsExtended: InlineCriticalCssProcessorOptions & - InlineCriticalCssProcessOptions, - ) { - super({ - logger: { - warn: (s: string) => this.warnings.push(s), - error: (s: string) => this.errors.push(s), - info: () => {}, - }, - logLevel: 'warn', - path: optionsExtended.outputPath, - publicPath: optionsExtended.deployUrl, - compress: !!optionsExtended.minify, - pruneSource: false, - reduceInlineStyles: false, - mergeStylesheets: false, - // Note: if `preload` changes to anything other than `media`, the logic in - // `embedLinkedStylesheet` will have to be updated. - preload: 'media', - noscriptFallback: true, - inlineFonts: true, - }); - } - public override readFile(path: string): Promise { - const readAsset = this.optionsExtended.readAsset; +interface BeastiesExtendedInstance { + readonly warnings: string[]; + readonly errors: string[]; + process(html: string): Promise; +} - return readAsset ? readAsset(path) : readFile(path, 'utf-8'); +let beastiesClassPromise: + | Promise< + new ( + options: InlineCriticalCssProcessorOptions & InlineCriticalCssProcessOptions, + ) => BeastiesExtendedInstance + > + | undefined; + +async function getBeastiesClass(): Promise< + new ( + options: InlineCriticalCssProcessorOptions & InlineCriticalCssProcessOptions, + ) => BeastiesExtendedInstance +> { + if (beastiesClassPromise) { + return beastiesClassPromise; } - /** - * Override of the Beasties `embedLinkedStylesheet` method - * that makes it work with Angular's CSP APIs. - */ - override async embedLinkedStylesheet( - link: PartialHTMLElement, - document: PartialDocument, - ): Promise { - if (link.getAttribute('media') === 'print' && link.next?.name === 'noscript') { - // Workaround for https://github.com/GoogleChromeLabs/critters/issues/64 - // NB: this is only needed for the webpack based builders. - const media = link.getAttribute('onload')?.match(MEDIA_SET_HANDLER_PATTERN); - if (media) { - link.removeAttribute('onload'); - link.setAttribute('media', media[1]); - link?.next?.remove(); - } - } - - const returnValue = await super.embedLinkedStylesheet(link, document); - const cspNonce = this.findCspNonce(document); - - if (cspNonce || this.optionsExtended.autoCsp) { - const beastiesMedia = link.getAttribute('onload')?.match(MEDIA_SET_HANDLER_PATTERN); + beastiesClassPromise = import('beasties').then(({ default: Beasties }) => { + return class BeastiesExtended + extends (Beasties as unknown as new (options: unknown) => BeastiesBase) + implements BeastiesExtendedInstance + { + private _warnings?: string[]; + private _errors?: string[]; - if (beastiesMedia) { - // If there's a Beasties-generated `onload` handler and the file has an Angular CSP nonce, - // we have to remove the handler, because it's incompatible with CSP. We save the value - // in a different attribute and we generate a script tag with the nonce that uses - // `addEventListener` to apply the media query instead. - link.removeAttribute('onload'); - link.setAttribute(CSP_MEDIA_ATTR, beastiesMedia[1]); - this.conditionallyInsertCspLoadingScript(document, cspNonce, link); + get warnings(): string[] { + return (this._warnings ??= []); } - // Ideally we would hook in at the time Beasties inserts the `style` tags, but there isn't - // a way of doing that at the moment so we fall back to doing it any time a `link` tag is - // inserted. We mitigate it by only iterating the direct children of the `` which - // should be pretty shallow. - if (cspNonce) { - document.head.children.forEach((child) => { - if (child.tagName === 'style' && !child.hasAttribute('nonce')) { - child.setAttribute('nonce', cspNonce); - } + get errors(): string[] { + return (this._errors ??= []); + } + private addedCspScriptsDocuments = new WeakSet(); + private documentNonces = new WeakMap(); + + constructor( + private readonly optionsExtended: InlineCriticalCssProcessorOptions & + InlineCriticalCssProcessOptions, + ) { + super({ + logger: { + warn: (s: string) => this.warnings.push(s), + error: (s: string) => this.errors.push(s), + info: () => {}, + }, + logLevel: 'warn', + path: optionsExtended.outputPath, + publicPath: optionsExtended.deployUrl, + compress: !!optionsExtended.minify, + pruneSource: false, + reduceInlineStyles: false, + mergeStylesheets: false, + // Note: if `preload` changes to anything other than `media`, the logic in + // `embedLinkedStylesheet` will have to be updated. + preload: 'media', + noscriptFallback: true, + inlineFonts: true, }); } - } - return returnValue; - } + public override readFile(path: string): Promise { + const readAsset = this.optionsExtended.readAsset; - /** - * Finds the CSP nonce for a specific document. - */ - private findCspNonce(document: PartialDocument): string | null { - if (this.documentNonces.has(document)) { - // eslint-disable-next-line @typescript-eslint/no-non-null-assertion - return this.documentNonces.get(document)!; - } + return readAsset ? readAsset(path) : readFile(path, 'utf-8'); + } - // HTML attribute are case-insensitive, but the parser used by Beasties is case-sensitive. - const nonceElement = document.querySelector('[ngCspNonce], [ngcspnonce]'); - const cspNonce = - nonceElement?.getAttribute('ngCspNonce') || nonceElement?.getAttribute('ngcspnonce') || null; + /** + * Override of the Beasties `embedLinkedStylesheet` method + * that makes it work with Angular's CSP APIs. + */ + override async embedLinkedStylesheet( + link: PartialHTMLElement, + document: PartialDocument, + ): Promise { + if (link.getAttribute('media') === 'print' && link.next?.name === 'noscript') { + // Workaround for https://github.com/GoogleChromeLabs/critters/issues/64 + // NB: this is only needed for the webpack based builders. + const media = link.getAttribute('onload')?.match(MEDIA_SET_HANDLER_PATTERN); + if (media) { + link.removeAttribute('onload'); + link.setAttribute('media', media[1]); + link?.next?.remove(); + } + } + + const returnValue = await super.embedLinkedStylesheet(link, document); + const cspNonce = this.findCspNonce(document); + + if (cspNonce || this.optionsExtended.autoCsp) { + const beastiesMedia = link.getAttribute('onload')?.match(MEDIA_SET_HANDLER_PATTERN); + + if (beastiesMedia) { + // If there's a Beasties-generated `onload` handler and the file has an Angular CSP nonce, + // we have to remove the handler, because it's incompatible with CSP. We save the value + // in a different attribute and we generate a script tag with the nonce that uses + // `addEventListener` to apply the media query instead. + link.removeAttribute('onload'); + link.setAttribute(CSP_MEDIA_ATTR, beastiesMedia[1]); + this.conditionallyInsertCspLoadingScript(document, cspNonce, link); + } - this.documentNonces.set(document, cspNonce); + // Ideally we would hook in at the time Beasties inserts the `style` tags, but there isn't + // a way of doing that at the moment so we fall back to doing it any time a `link` tag is + // inserted. We mitigate it by only iterating the direct children of the `` which + // should be pretty shallow. + if (cspNonce) { + document.head.children.forEach((child) => { + if (child.tagName === 'style' && !child.hasAttribute('nonce')) { + child.setAttribute('nonce', cspNonce); + } + }); + } + } - return cspNonce; - } + return returnValue; + } - /** - * Inserts the `script` tag that swaps the critical CSS at runtime, - * if one hasn't been inserted into the document already. - */ - private conditionallyInsertCspLoadingScript( - document: PartialDocument, - nonce: string | null, - link: PartialHTMLElement, - ): void { - if (this.addedCspScriptsDocuments.has(document)) { - return; - } + /** + * Finds the CSP nonce for a specific document. + */ + private findCspNonce(document: PartialDocument): string | null { + if (this.documentNonces.has(document)) { + // eslint-disable-next-line @typescript-eslint/no-non-null-assertion + return this.documentNonces.get(document)!; + } + + // HTML attribute are case-insensitive, but the parser used by Beasties is case-sensitive. + const nonceElement = document.querySelector('[ngCspNonce], [ngcspnonce]'); + const cspNonce = + nonceElement?.getAttribute('ngCspNonce') || + nonceElement?.getAttribute('ngcspnonce') || + null; + + this.documentNonces.set(document, cspNonce); + + return cspNonce; + } - const script = document.createElement('script'); - script.textContent = LINK_LOAD_SCRIPT_CONTENT; - if (nonce) { - script.setAttribute('nonce', nonce); - } + /** + * Inserts the `script` tag that swaps the critical CSS at runtime, + * if one hasn't been inserted into the document already. + */ + private conditionallyInsertCspLoadingScript( + document: PartialDocument, + nonce: string | null, + link: PartialHTMLElement, + ): void { + if (this.addedCspScriptsDocuments.has(document)) { + return; + } + + const script = document.createElement('script'); + script.textContent = LINK_LOAD_SCRIPT_CONTENT; + if (nonce) { + script.setAttribute('nonce', nonce); + } + + // Prepend the script to the head since it needs to + // run as early as possible, before the `link` tags. + document.head.insertBefore(script, link); + this.addedCspScriptsDocuments.add(document); + } + }; + }); - // Prepend the script to the head since it needs to - // run as early as possible, before the `link` tags. - document.head.insertBefore(script, link); - this.addedCspScriptsDocuments.add(document); - } + return beastiesClassPromise; } export class InlineCriticalCssProcessor { @@ -245,7 +281,8 @@ export class InlineCriticalCssProcessor { html: string, options: InlineCriticalCssProcessOptions, ): Promise<{ content: string; warnings: string[]; errors: string[] }> { - const beasties = new BeastiesExtended({ ...this.options, ...options }); + const BeastiesClass = await getBeastiesClass(); + const beasties = new BeastiesClass({ ...this.options, ...options }); const content = await beasties.process(html); return { From 553eb56ba97d06fc9ae5dce97b2a6732999863a5 Mon Sep 17 00:00:00 2001 From: Doug Parker Date: Thu, 13 Aug 2026 09:32:08 -0700 Subject: [PATCH 293/787] docs: release notes for the v22.1.4 release --- CHANGELOG.md | 45 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 45 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8ce92e3ecd89..a9f907a2c3fd 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,48 @@ + + +# 22.1.4 (2026-08-13) + +### @angular/cli + +| Commit | Type | Description | +| --------------------------------------------------------------------------------------------------- | ---- | ------------------------------------------------------------------------------------------------------------------------------------- | +| [67a29899b](https://github.com/angular/angular-cli/commit/67a29899b07f760bac9582cbc6175966cce1c5d2) | fix | disable searching current directory for bare executable names on Windows | +| [1b0ba5c17](https://github.com/angular/angular-cli/commit/1b0ba5c17f0be2679b31bad1bee8b435315dac1a) | fix | serialize configuration as a single argv token in run_target strategies ([#33657](https://github.com/angular/angular-cli/pull/33657)) | +| [9440432d2](https://github.com/angular/angular-cli/commit/9440432d273c044965508d80e808c2fe123af0aa) | perf | avoid eager module loading during global bootstrap | + +### @schematics/angular + +| Commit | Type | Description | +| --------------------------------------------------------------------------------------------------- | ---- | ------------------------------------------------------- | +| [d4a48e3ab](https://github.com/angular/angular-cli/commit/d4a48e3abe320e090eefe17cb70abdf8e7eafaed) | fix | generate CLAUDE.md for Claude Code instead of AGENTS.md | +| [d451f15b2](https://github.com/angular/angular-cli/commit/d451f15b2838a8282363dcb30161dd5dc858750f) | fix | import UrlSegment instead of subPath in guard generator | + +### @angular/build + +| Commit | Type | Description | +| --------------------------------------------------------------------------------------------------- | ---- | ----------------------------------------------------------------- | +| [46fcb29d6](https://github.com/angular/angular-cli/commit/46fcb29d6c1ded962de95449d63716c13950f59a) | fix | count statically imported chunks in the initial total | +| [796b57684](https://github.com/angular/angular-cli/commit/796b576843191a4d5c74e4f9363ec0e46ae3a881) | fix | normalize setupFiles paths to POSIX for vitest runner | +| [c805e5cfb](https://github.com/angular/angular-cli/commit/c805e5cfb308d02a1944ef446d0a01af8a7ec6d2) | fix | prevent syntax corruption for Crockford-style enum IIFE | +| [cc6c17716](https://github.com/angular/angular-cli/commit/cc6c17716df5c411efca5e6f4c960f0565f45d90) | fix | prevent syntax corruption in oxc transform | +| [a142f6f83](https://github.com/angular/angular-cli/commit/a142f6f83d2f501b64f2404909ef9325bbfa70fb) | fix | return direct file contents for non-Angular TypeScript files | +| [956c6578d](https://github.com/angular/angular-cli/commit/956c6578d31d8482c04dc45723d7ab3b4fe355a5) | fix | return only lowest version per target engine | +| [689b5b116](https://github.com/angular/angular-cli/commit/689b5b116717140da98494e61ac5ea5ad7b68d73) | fix | set target for Rolldown dependency prebundling in Vite dev server | +| [70461f6ed](https://github.com/angular/angular-cli/commit/70461f6ed2e30aeaad2b93400ad00d9274665967) | perf | avoid encoding the inline source map before remapping | +| [22cce7563](https://github.com/angular/angular-cli/commit/22cce7563e82f17373b69e590d3e445767bd9264) | perf | batch last_accessed updates in sqlite cache store | +| [ab2ed18d5](https://github.com/angular/angular-cli/commit/ab2ed18d5739e8565403062ca74aa2d5cb3b95ec) | perf | hash the i18n inline cache key options once per locale | +| [34516ff73](https://github.com/angular/angular-cli/commit/34516ff736185e20ef8239b1fed8eda1f0193f62) | perf | optimize template string size calculation in server manifest | +| [712971c37](https://github.com/angular/angular-cli/commit/712971c370738beaebff18f6995859b1713ed8ae) | perf | share i18n translations with the inliner workers by reference | +| [78f8c5fef](https://github.com/angular/angular-cli/commit/78f8c5fef44dc6ff466b17c98fa1d01222cb1781) | perf | use Map for chunk asset size lookups in budget calculator | + +### @angular/ssr + +| Commit | Type | Description | +| --------------------------------------------------------------------------------------------------- | ---- | -------------------------------------------------- | +| [2331c1047](https://github.com/angular/angular-cli/commit/2331c10476830e7a53e0f2fa4a2f37dad58e2d5d) | fix | destroy platform when response stream is cancelled | + + + # 21.2.21 (2026-08-12) From 314bfbe920a7f42d4529aa498196eda7679ab8f4 Mon Sep 17 00:00:00 2001 From: Doug Parker Date: Thu, 13 Aug 2026 09:46:47 -0700 Subject: [PATCH 294/787] release: cut the v22.2.0-next.3 release --- CHANGELOG.md | 48 ++++++++++++++++++++++++++++++++++++++++++++++++ package.json | 2 +- 2 files changed, 49 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index a9f907a2c3fd..fca9a3af30cf 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,51 @@ + + +# 22.2.0-next.3 (2026-08-13) + +### @angular/cli + +| Commit | Type | Description | +| --------------------------------------------------------------------------------------------------- | ---- | ------------------------------------------------------------------------------------------------------------------------------------- | +| [7106676e6](https://github.com/angular/angular-cli/commit/7106676e64ee234641b1b3cbd88fc058703d4d3e) | fix | disable searching current directory for bare executable names on Windows | +| [ecf8c0822](https://github.com/angular/angular-cli/commit/ecf8c0822e5d56b44a0be4be8fccb41373135d3e) | fix | serialize configuration as a single argv token in run_target strategies ([#33657](https://github.com/angular/angular-cli/pull/33657)) | +| [2e4dd90c3](https://github.com/angular/angular-cli/commit/2e4dd90c3ae898bf36af42f699c7b7d560bfc66a) | perf | avoid eager module loading during global bootstrap | + +### @schematics/angular + +| Commit | Type | Description | +| --------------------------------------------------------------------------------------------------- | ---- | ------------------------------------------------------- | +| [1161e6c99](https://github.com/angular/angular-cli/commit/1161e6c99992c884e2e0ce9fc295b0e60b2ae1df) | fix | generate CLAUDE.md for Claude Code instead of AGENTS.md | +| [c536ae364](https://github.com/angular/angular-cli/commit/c536ae364975dd0088fd8717464c723a4dcb74e3) | fix | import UrlSegment instead of subPath in guard generator | + +### @angular/build + +| Commit | Type | Description | +| --------------------------------------------------------------------------------------------------- | ---- | ----------------------------------------------------------------- | +| [04b532772](https://github.com/angular/angular-cli/commit/04b532772f6347d341b182135dee1758616a69d6) | fix | count statically imported chunks in the initial total | +| [2274babb6](https://github.com/angular/angular-cli/commit/2274babb662b8da2189f1ae9faaa528838052c32) | fix | normalize setupFiles paths to POSIX for vitest runner | +| [199a864df](https://github.com/angular/angular-cli/commit/199a864df97fc8c20b8d4e1fc8b891c61140671a) | fix | prevent syntax corruption for Crockford-style enum IIFE | +| [0d9851600](https://github.com/angular/angular-cli/commit/0d9851600ca618ccabfc3143a9c552a5448d6eec) | fix | recursively ignore output and cache paths in watch mode | +| [3eba6f726](https://github.com/angular/angular-cli/commit/3eba6f7269f3b0f8556510d0b668e978ea686c88) | fix | return direct file contents for non-Angular TypeScript files | +| [3c7ac1518](https://github.com/angular/angular-cli/commit/3c7ac1518b062f14409b4d3c6c3e65c956424ad9) | fix | return only lowest version per target engine | +| [3e9fed9a6](https://github.com/angular/angular-cli/commit/3e9fed9a6a1d24f30812ca29ca621d9d9a14496f) | fix | set target for Rolldown dependency prebundling in Vite dev server | +| [87551ad5c](https://github.com/angular/angular-cli/commit/87551ad5c53f90cbdc68fdb5e47007b9436c7f75) | perf | avoid encoding intermediate source maps before remapping | +| [194be2088](https://github.com/angular/angular-cli/commit/194be2088587918ed7b47ed606ea587a7116608a) | perf | avoid encoding the inline source map before remapping | +| [a55a6b78e](https://github.com/angular/angular-cli/commit/a55a6b78e89debb9c93c83375c54f6716bc26c65) | perf | batch last_accessed updates in sqlite cache store | +| [33b305416](https://github.com/angular/angular-cli/commit/33b3054169929dc98f93a758a90da5d26cf522f7) | perf | hash the i18n inline cache key options once per locale | +| [1c00edce0](https://github.com/angular/angular-cli/commit/1c00edce02bdd0201546417d71518f78bfb89d34) | perf | optimize sourcemap stripping and loading with buffer fast path | +| [b6269a816](https://github.com/angular/angular-cli/commit/b6269a8169046a78281808dcf92054140912a77d) | perf | optimize template string size calculation in server manifest | +| [a6ef9cfbe](https://github.com/angular/angular-cli/commit/a6ef9cfbeace725d58c0f7f65640ef6de9b39c33) | perf | replace watchpack with @parcel/watcher and chokidar | +| [596847f89](https://github.com/angular/angular-cli/commit/596847f89913684a84465d004aa3d6c7e1a40b06) | perf | share i18n translations with the inliner workers by reference | +| [19c91e48d](https://github.com/angular/angular-cli/commit/19c91e48d4b8a95a76dfe4bffd105130b416843d) | perf | use Map for chunk asset size lookups in budget calculator | + +### @angular/ssr + +| Commit | Type | Description | +| --------------------------------------------------------------------------------------------------- | ---- | -------------------------------------------------- | +| [6a3446770](https://github.com/angular/angular-cli/commit/6a3446770a8fbfecc7265eb2a6d764e2f1614b3a) | fix | destroy platform when response stream is cancelled | + + + # 22.1.4 (2026-08-13) diff --git a/package.json b/package.json index 08aa473545d2..a8e89fd6f580 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@angular/devkit-repo", - "version": "22.2.0-next.2", + "version": "22.2.0-next.3", "private": true, "description": "Software Development Kit for Angular", "keywords": [ From 34e1e0bb5d5ccf374f51a1b241158f6f2ea0dd42 Mon Sep 17 00:00:00 2001 From: Herdiyan Adam Putra Date: Sat, 25 Jul 2026 00:00:22 +0700 Subject: [PATCH 295/787] fix(@angular/cli): enforce MCP roots in get_best_practices tool getVersionSpecificBestPractices() resolves an npm package (and reads a file path declared in that package's package.json) starting from a caller-supplied workspacePath, without checking it against the client's declared MCP roots. Every other workspace-path-consuming MCP tool (run_target, devserver_start/stop/wait_for_build) validates this through resolveWorkspaceAndProject()'s isAllowedWorkspacePath() check; this tool never did. Export isAllowedWorkspacePath() from workspace-utils.ts and call it in getVersionSpecificBestPractices() before resolving anything, falling back to the bundled guide when the path is outside the allowed roots, matching this file's existing fallback behavior for every other failure case. --- .../src/commands/mcp/tools/best-practices.ts | 20 +++++++++++++++++-- .../cli/src/commands/mcp/workspace-utils.ts | 2 +- 2 files changed, 19 insertions(+), 3 deletions(-) diff --git a/packages/angular/cli/src/commands/mcp/tools/best-practices.ts b/packages/angular/cli/src/commands/mcp/tools/best-practices.ts index dca61eb700b3..3733a9c61641 100644 --- a/packages/angular/cli/src/commands/mcp/tools/best-practices.ts +++ b/packages/angular/cli/src/commands/mcp/tools/best-practices.ts @@ -20,6 +20,7 @@ import { createRequire } from 'node:module'; import { dirname, isAbsolute, join, relative, resolve } from 'node:path'; import { z } from 'zod'; import { VERSION } from '../../../utilities/version'; +import { isAllowedWorkspacePath } from '../workspace-utils'; import { type McpToolContext, declareTool } from './tool-registry'; const bestPracticesInputSchema = z.object({ @@ -86,13 +87,24 @@ async function getBundledBestPractices(): Promise { * * @param workspacePath The absolute path to the user's `angular.json` file. * @param logger The MCP tool context logger for reporting warnings. + * @param server The MCP server context, used to enforce the client's declared roots. * @returns A promise that resolves to an object containing the guide's content and source, * or `undefined` if the guide could not be resolved. */ async function getVersionSpecificBestPractices( workspacePath: string, logger: McpToolContext['logger'], + server: McpToolContext['server'], ): Promise<{ content: string; source: string } | undefined> { + if (server && !(await isAllowedWorkspacePath(server, workspacePath))) { + logger.warn( + `Workspace path is outside the allowed MCP roots: ${workspacePath}. ` + + 'Falling back to the bundled guide.', + ); + + return undefined; + } + // 1. Resolve the path to package.json let pkgJsonPath: string; try { @@ -175,7 +187,7 @@ async function getVersionSpecificBestPractices( * @param context The MCP tool context, containing the logger. * @returns An async function that serves as the tool's executor. */ -function createBestPracticesHandler({ logger }: McpToolContext) { +function createBestPracticesHandler({ logger, server }: McpToolContext) { let bundledBestPractices: Promise; return async (input: BestPracticesInput) => { @@ -184,7 +196,11 @@ function createBestPracticesHandler({ logger }: McpToolContext) { // First, try to get the version-specific guide. if (input.workspacePath) { - const versionSpecific = await getVersionSpecificBestPractices(input.workspacePath, logger); + const versionSpecific = await getVersionSpecificBestPractices( + input.workspacePath, + logger, + server, + ); if (versionSpecific) { content = versionSpecific.content; source = versionSpecific.source; diff --git a/packages/angular/cli/src/commands/mcp/workspace-utils.ts b/packages/angular/cli/src/commands/mcp/workspace-utils.ts index 6cc245ff1dbc..94c4c55655c0 100644 --- a/packages/angular/cli/src/commands/mcp/workspace-utils.ts +++ b/packages/angular/cli/src/commands/mcp/workspace-utils.ts @@ -110,7 +110,7 @@ async function getAllowedWorkspaceRoots(server: McpToolContext['server']): Promi .filter((root): root is string => root !== null); } -async function isAllowedWorkspacePath( +export async function isAllowedWorkspacePath( server: McpToolContext['server'], workspacePath: string, ): Promise { From 2b060630c66ce688b7ecbe51d282955869e5d4b0 Mon Sep 17 00:00:00 2001 From: Herdiyan Adam Putra Date: Sat, 25 Jul 2026 00:08:14 +0700 Subject: [PATCH 296/787] fix(@angular/cli): handle errors from isAllowedWorkspacePath in best-practices tool isAllowedWorkspacePath can throw if the workspace path does not exist (realpathSync) or if listRoots() fails against the connected client. Wrap the check in a try-catch and fall back to the bundled guide on any failure, matching this function's existing fallback behavior. --- .../src/commands/mcp/tools/best-practices.ts | 23 ++++++++++++++----- 1 file changed, 17 insertions(+), 6 deletions(-) diff --git a/packages/angular/cli/src/commands/mcp/tools/best-practices.ts b/packages/angular/cli/src/commands/mcp/tools/best-practices.ts index 3733a9c61641..51fe43c4e648 100644 --- a/packages/angular/cli/src/commands/mcp/tools/best-practices.ts +++ b/packages/angular/cli/src/commands/mcp/tools/best-practices.ts @@ -96,13 +96,24 @@ async function getVersionSpecificBestPractices( logger: McpToolContext['logger'], server: McpToolContext['server'], ): Promise<{ content: string; source: string } | undefined> { - if (server && !(await isAllowedWorkspacePath(server, workspacePath))) { - logger.warn( - `Workspace path is outside the allowed MCP roots: ${workspacePath}. ` + - 'Falling back to the bundled guide.', - ); + if (server) { + try { + if (!(await isAllowedWorkspacePath(server, workspacePath))) { + logger.warn( + `Workspace path is outside the allowed MCP roots: ${workspacePath}. ` + + 'Falling back to the bundled guide.', + ); - return undefined; + return undefined; + } + } catch (e) { + logger.warn( + `Failed to verify workspace path '${workspacePath}': ` + + `${e instanceof Error ? e.message : e}. Falling back to the bundled guide.`, + ); + + return undefined; + } } // 1. Resolve the path to package.json From 24fd8fce2a3ff035acdc5f3e036eb4ba21f71a76 Mon Sep 17 00:00:00 2001 From: Herdiyan Adam Putra Date: Tue, 11 Aug 2026 23:36:30 +0700 Subject: [PATCH 297/787] fix(@angular/cli): throw on out-of-roots workspace in best-practices tool Aligns get_best_practices with resolveWorkspaceAndProject, which throws when a caller-supplied workspacePath falls outside the client's declared MCP roots rather than silently falling back. The try/catch now wraps only the isAllowedWorkspacePath call so genuine verification failures (e.g. a non-existent path) still fall back to the bundled guide, while a path outside the roots surfaces an actionable error pointing at list_projects. --- .../src/commands/mcp/tools/best-practices.ts | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/packages/angular/cli/src/commands/mcp/tools/best-practices.ts b/packages/angular/cli/src/commands/mcp/tools/best-practices.ts index 51fe43c4e648..0b40c5c0c207 100644 --- a/packages/angular/cli/src/commands/mcp/tools/best-practices.ts +++ b/packages/angular/cli/src/commands/mcp/tools/best-practices.ts @@ -97,15 +97,9 @@ async function getVersionSpecificBestPractices( server: McpToolContext['server'], ): Promise<{ content: string; source: string } | undefined> { if (server) { + let isAllowed: boolean; try { - if (!(await isAllowedWorkspacePath(server, workspacePath))) { - logger.warn( - `Workspace path is outside the allowed MCP roots: ${workspacePath}. ` + - 'Falling back to the bundled guide.', - ); - - return undefined; - } + isAllowed = await isAllowedWorkspacePath(server, workspacePath); } catch (e) { logger.warn( `Failed to verify workspace path '${workspacePath}': ` + @@ -114,6 +108,13 @@ async function getVersionSpecificBestPractices( return undefined; } + + if (!isAllowed) { + throw new Error( + `Workspace path is outside the allowed MCP roots: ${workspacePath}. ` + + "You can use 'list_projects' to find available workspaces.", + ); + } } // 1. Resolve the path to package.json From 0ffe2d27f256a5755809fa4788e4adb97c65b806 Mon Sep 17 00:00:00 2001 From: Jon Marozick Date: Sun, 2 Aug 2026 10:43:10 -0500 Subject: [PATCH 298/787] fix(@angular/build): disable code splitting for unit test builds Every spec file is its own entry point, so esbuild code splitting hoists any module reached from more than one spec into a chunk shared between them. A module placed in a shared chunk is wrapped in a lazy `__esm` initializer, so its exported value is only assigned once that initializer runs, and importing chunks read the export as a live ESM binding. The unit test runners load the generated output through a module runner rather than the browser's own ESM implementation, and that does not reliably preserve those bindings. An importing chunk can therefore observe the export as `undefined`. A component whose class field initializer reads a `const` exported from a module that was hoisted into a shared chunk fails with a `TypeError`, while the same value read later, or read from within the shared chunk itself, is correct. It only appears once a project has more than one spec file, because a single entry point inlines everything and never splits. Test bundles are never downloaded by a browser, so splitting has nothing to optimize here. This disables it for the unit test build only, via an internal option, leaving application builds unaffected. The regression test mirrors the reproduction's exact shape: a shared const read during class-field initialization from a spec with an async test callback, under zone.js polyfills. That combination is load-bearing: zone.js downlevels async, the spec then imports the `__async` helper, and esbuild emits the spec entry CommonJS-wrapped with the component module behind a lazy `__esm` initializer. The fixture file set was verified to fail against an unpatched 21.2.19 build and pass with this change applied. --- .../build/src/builders/application/options.ts | 16 ++ .../unit-test/runners/vitest/build-options.ts | 6 + .../behavior/vitest-shared-chunk-init_spec.ts | 172 ++++++++++++++++++ .../tools/esbuild/application-code-bundle.ts | 6 + 4 files changed, 200 insertions(+) create mode 100644 packages/angular/build/src/builders/unit-test/tests/behavior/vitest-shared-chunk-init_spec.ts diff --git a/packages/angular/build/src/builders/application/options.ts b/packages/angular/build/src/builders/application/options.ts index b3c180843f70..abe3298aa093 100644 --- a/packages/angular/build/src/builders/application/options.ts +++ b/packages/angular/build/src/builders/application/options.ts @@ -126,6 +126,20 @@ interface InternalOptions { * Suppress build summary and stats table. */ quiet?: boolean; + + /** + * Disables esbuild code splitting for the browser code bundle. + * + * Splitting emits shared chunks whose exports are read across chunk boundaries as live ESM + * bindings. A module hoisted into a shared chunk is wrapped in a lazy initializer, so its exported + * value is only assigned once that initializer runs. Runners that load the generated output + * through a module runner rather than the browser's own ESM implementation do not reliably + * preserve those bindings, and an importing chunk can observe the export as `undefined`. + * + * Test bundles are never downloaded by a browser, so there is nothing for splitting to optimize + * there. Used exclusively for tests and shouldn't be used for other kinds of builds. + */ + disableCodeSplitting?: boolean; } /** Full set of options for `application` builder. */ @@ -439,6 +453,7 @@ export async function normalizeOptions( partialSSRBuild = false, externalRuntimeStyles, instrumentForCoverage, + disableCodeSplitting, } = options; // Return all the normalized options @@ -475,6 +490,7 @@ export async function normalizeOptions( watch, workspaceRoot, entryPoints, + disableCodeSplitting, optimizationOptions, outputOptions, outExtension, diff --git a/packages/angular/build/src/builders/unit-test/runners/vitest/build-options.ts b/packages/angular/build/src/builders/unit-test/runners/vitest/build-options.ts index 7f0f67fc0c2e..3936f44b09fd 100644 --- a/packages/angular/build/src/builders/unit-test/runners/vitest/build-options.ts +++ b/packages/angular/build/src/builders/unit-test/runners/vitest/build-options.ts @@ -257,6 +257,12 @@ export async function getVitestBuildOptions( outputHashing: adjustOutputHashing(baseBuildOptions.outputHashing), optimization: false, entryPoints, + // Every spec file is its own entry point, so splitting hoists any module shared between two + // specs into a chunk whose exports are then read across a chunk boundary. Those reads rely on + // live ESM bindings, and a module placed in a shared chunk is only assigned its exported value + // when that chunk's lazy initializer runs, so an importing chunk can read `undefined`. Nothing + // downloads these bundles, so there is no benefit to weigh against that. + disableCodeSplitting: true, // Enable support for vitest browser prebundling. Excludes can be controlled with a runnerConfig // and the `optimizeDeps.exclude` option. externalPackages: true, diff --git a/packages/angular/build/src/builders/unit-test/tests/behavior/vitest-shared-chunk-init_spec.ts b/packages/angular/build/src/builders/unit-test/tests/behavior/vitest-shared-chunk-init_spec.ts new file mode 100644 index 000000000000..13870ba36eba --- /dev/null +++ b/packages/angular/build/src/builders/unit-test/tests/behavior/vitest-shared-chunk-init_spec.ts @@ -0,0 +1,172 @@ +/** + * @license + * Copyright Google LLC All Rights Reserved. + * + * Use of this source code is governed by an MIT-style license that can be + * found in the LICENSE file at https://angular.dev/license + */ + +import { execute } from '../../index'; +import { + BASE_OPTIONS, + describeBuilder, + UNIT_TEST_BUILDER_INFO, + setupApplicationTarget, +} from '../setup'; + +describeBuilder(execute, UNIT_TEST_BUILDER_INFO, (harness) => { + describe('Behavior: "Vitest shared chunk initialization"', () => { + // Regression test for https://github.com/angular/angular-cli/issues/33728. + // + // Without `disableCodeSplitting`, esbuild hoists a module imported by more than one spec + // entry point into a shared chunk behind a lazy `__esm` initializer, and a class-field + // initializer in another chunk reads the exported value as `undefined` under the jsdom + // runner. All four trigger conditions are required and encoded below: + // 1. two spec entry points import the shared module (so it lands in a shared chunk); + // 2. a component in one entry reads the export during class-field initialization; + // 3. that component's spec file contains an `async` test callback (no `await` needed); + // 4. zone.js is in the polyfills (the `setupApplicationTarget` default), which downlevels + // async and makes esbuild emit the spec entry CommonJS-wrapped. + // + // NOTE: the failure this guards against is sensitive to inert content — adding a top-level + // side effect (even a `console.log`) to the shared or importing module below defused it + // during reduction. Mirror https://github.com/jonmarozick/ng-shared-chunk-repro when + // modifying these fixtures. + it('should provide shared-module exports to class-field initializers in async specs', async () => { + setupApplicationTarget(harness); + + harness.useTarget('test', { + ...BASE_OPTIONS, + }); + + // Keep the default project's spec deterministic; a third spec entry that does not touch + // the shared module does not affect the reproduction (verified in a fresh workspace). + await harness.writeFile( + 'src/app/app.component.spec.ts', + ` + import { describe, it, expect } from 'vitest'; + + describe('AppComponent placeholder', () => { + it('runs', () => { + expect(1 + 1).toBe(2); + }); + }); + `, + ); + + // The shared `const`. Reached from both spec entry points, so it is hoisted into a chunk + // shared between them. + await harness.writeFile( + 'src/environments/env-config.ts', + ` + export interface DealerConfig { + dealerId: string; + clientKey: string; + } + + export const DEALERS: DealerConfig[] = [ + { dealerId: 'dealer-one', clientKey: 'KEY-ONE' }, + { dealerId: 'dealer-two', clientKey: 'KEY-TWO' }, + { dealerId: 'dealer-three', clientKey: 'KEY-THREE' }, + { dealerId: 'dealer-four', clientKey: 'KEY-FOUR' }, + ]; + `, + ); + + // Reached by both spec entries, so it and env-config.ts land in the shared chunk. Reads the + // const inside a method — after module initialization — and is the passing control. + await harness.writeFile( + 'src/app/features/lead-generator/services/lead.service.ts', + ` + import { Injectable } from '@angular/core'; + + import { DEALERS } from '../../../../environments/env-config'; + + @Injectable({ providedIn: 'root' }) + export class LeadService { + resolveClientKey(dealerId: string, clientKey?: string): string { + return clientKey ?? DEALERS.find((d) => d.dealerId === dealerId)?.clientKey ?? ''; + } + } + `, + ); + + await harness.writeFile( + 'src/app/features/lead-generator/services/index.ts', + `export * from './lead.service';\n`, + ); + + // Spec entry point 1 — the second importer that causes the chunk to be shared at all. + await harness.writeFile( + 'src/app/features/lead-generator/services/lead.service.spec.ts', + ` + import { describe, it, expect } from 'vitest'; + import { TestBed } from '@angular/core/testing'; + + import { LeadService } from './lead.service'; + + describe('LeadService', () => { + it('reads DEALERS inside a method', () => { + TestBed.configureTestingModule({ providers: [LeadService] }); + + expect(TestBed.inject(LeadService).resolveClientKey('dealer-one')).toBe('KEY-ONE'); + }); + }); + `, + ); + + // In the other chunk; reads the shared export eagerly during class-field initialization. + await harness.writeFile( + 'src/app/features/lead-generator/lead-generator.container.ts', + ` + import { Component, inject } from '@angular/core'; + + import { LeadService } from './services'; + import { DEALERS, DealerConfig } from '../../../environments/env-config'; + + @Component({ + selector: 'app-lead-generator', + standalone: true, + template: '', + }) + export class LeadGeneratorContainer { + private readonly leadService = inject(LeadService); + + readonly dealers: DealerConfig[] = DEALERS; + readonly dealerOptions = this.dealers.map((d) => d.dealerId); + + hasService(): boolean { + return this.leadService != null; + } + } + `, + ); + + // Spec entry point 2 — the failing case without the fix. The `async` is load-bearing: + // zone.js makes the builder downlevel it, the spec then imports the `__async` helper, and + // esbuild emits this entry CommonJS-wrapped with the component module behind a lazy + // `__esm` initializer. No `await` is needed; a synchronous callback hides the defect. + await harness.writeFile( + 'src/app/features/lead-generator/lead-generator.container.spec.ts', + ` + import { describe, it, expect } from 'vitest'; + import { TestBed } from '@angular/core/testing'; + + import { LeadGeneratorContainer } from './lead-generator.container'; + + describe('LeadGeneratorContainer', () => { + it('reads DEALERS in a class-field initialiser', async () => { + const fixture = TestBed.createComponent(LeadGeneratorContainer); + + expect(fixture.componentInstance.dealers.length).toBe(4); + }); + }); + `, + ); + + const { result } = await harness.executeOnce(); + + expect(result?.success).toBeTrue(); + }); + }); +}); diff --git a/packages/angular/build/src/tools/esbuild/application-code-bundle.ts b/packages/angular/build/src/tools/esbuild/application-code-bundle.ts index 4e6ddc0fee21..ba1c6e1c69f7 100644 --- a/packages/angular/build/src/tools/esbuild/application-code-bundle.ts +++ b/packages/angular/build/src/tools/esbuild/application-code-bundle.ts @@ -71,6 +71,12 @@ export function createBrowserCodeBundleOptions( supported: getFeatureSupport(zoneless), }; + if (options.disableCodeSplitting) { + // Splitting emits shared chunks that are read across chunk boundaries as live ESM bindings, + // which the unit-test runners' module loading does not reliably preserve. + buildOptions.splitting = false; + } + buildOptions.plugins ??= []; buildOptions.plugins.push( createWasmPlugin({ allowAsync: zoneless, cache: loadCache }), From 8b1f4aca3ad4c313ce20f9c15901261d06c0947d Mon Sep 17 00:00:00 2001 From: Angular Robot Date: Thu, 13 Aug 2026 11:11:18 +0000 Subject: [PATCH 299/787] build: update all non-major dependencies See associated pull request for more information. --- package.json | 10 +- packages/angular/build/package.json | 8 +- .../angular_devkit/build_angular/package.json | 2 +- .../angular_devkit/schematics/package.json | 2 +- pnpm-lock.yaml | 545 +++++++++--------- 5 files changed, 287 insertions(+), 280 deletions(-) diff --git a/package.json b/package.json index a8e89fd6f580..91ef1456cb23 100644 --- a/package.json +++ b/package.json @@ -91,8 +91,8 @@ "@types/semver": "^7.3.12", "@types/yargs": "^17.0.20", "@types/yargs-parser": "^21.0.0", - "@typescript-eslint/eslint-plugin": "8.66.0", - "@typescript-eslint/parser": "8.66.0", + "@typescript-eslint/eslint-plugin": "8.67.0", + "@typescript-eslint/parser": "8.67.0", "ajv": "8.20.0", "buffer": "6.0.3", "esbuild": "0.28.2", @@ -102,7 +102,7 @@ "eslint-plugin-import": "2.32.0", "express": "5.2.1", "fast-glob": "3.3.3", - "globals": "17.9.0", + "globals": "17.11.0", "http-proxy": "^1.18.1", "http-proxy-middleware": "4.2.0", "husky": "9.1.7", @@ -117,9 +117,9 @@ "karma-jasmine-html-reporter": "~2.2.0", "karma-source-map-support": "1.4.0", "lodash": "^4.17.21", - "magic-string": "1.1.0", + "magic-string": "1.1.1", "prettier": "^3.0.0", - "puppeteer": "25.5.0", + "puppeteer": "25.6.0", "quicktype-core": "26.0.0", "rollup": "4.62.4", "rollup-license-plugin": "~3.2.0", diff --git a/packages/angular/build/package.json b/packages/angular/build/package.json index 96ffd3f3fffd..0a3cc5cfad99 100644 --- a/packages/angular/build/package.json +++ b/packages/angular/build/package.json @@ -31,13 +31,13 @@ "https-proxy-agent": "9.1.0", "jsonc-parser": "3.3.1", "listr2": "11.0.0", - "magic-string": "1.1.0", + "magic-string": "1.1.1", "mrmime": "2.0.1", - "oxc-parser": "0.143.0", + "oxc-parser": "0.144.0", "parse5-html-rewriting-stream": "8.0.1", "picomatch": "4.0.5", "piscina": "5.3.0", - "rolldown": "1.2.3", + "rolldown": "1.2.4", "sass": "1.102.0", "semver": "7.8.5", "source-map-support": "0.5.21", @@ -51,7 +51,7 @@ "devDependencies": { "@angular-devkit/core": "workspace:*", "@angular/ssr": "workspace:*", - "@oxc-project/types": "0.143.0", + "@oxc-project/types": "0.144.0", "istanbul-lib-instrument": "6.0.3", "jsdom": "30.0.1", "less": "4.8.1", diff --git a/packages/angular_devkit/build_angular/package.json b/packages/angular_devkit/build_angular/package.json index 58bb3e6590d6..cf5aa84e20d0 100644 --- a/packages/angular_devkit/build_angular/package.json +++ b/packages/angular_devkit/build_angular/package.json @@ -51,7 +51,7 @@ "semver": "7.8.5", "source-map-loader": "5.0.0", "source-map-support": "0.5.21", - "terser": "5.49.2", + "terser": "5.50.0", "tinyglobby": "0.2.17", "tslib": "2.8.1", "webpack": "5.109.2", diff --git a/packages/angular_devkit/schematics/package.json b/packages/angular_devkit/schematics/package.json index 40e641caa240..44d07e4739fc 100644 --- a/packages/angular_devkit/schematics/package.json +++ b/packages/angular_devkit/schematics/package.json @@ -15,7 +15,7 @@ "dependencies": { "@angular-devkit/core": "workspace:0.0.0-PLACEHOLDER", "jsonc-parser": "3.3.1", - "magic-string": "1.1.0", + "magic-string": "1.1.1", "ora": "9.4.1", "rxjs": "7.8.2" } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 418a9edd3348..9afe493732be 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -161,11 +161,11 @@ importers: specifier: ^21.0.0 version: 21.0.3 '@typescript-eslint/eslint-plugin': - specifier: 8.66.0 - version: 8.66.0(@typescript-eslint/parser@8.66.0(eslint@10.8.1(jiti@2.7.0)(supports-color@11.0.0))(supports-color@11.0.0)(typescript@6.0.3))(eslint@10.8.1(jiti@2.7.0)(supports-color@11.0.0))(supports-color@11.0.0)(typescript@6.0.3) + specifier: 8.67.0 + version: 8.67.0(@typescript-eslint/parser@8.67.0(eslint@10.8.1(jiti@2.7.0)(supports-color@11.0.0))(supports-color@11.0.0)(typescript@6.0.3))(eslint@10.8.1(jiti@2.7.0)(supports-color@11.0.0))(supports-color@11.0.0)(typescript@6.0.3) '@typescript-eslint/parser': - specifier: 8.66.0 - version: 8.66.0(eslint@10.8.1(jiti@2.7.0)(supports-color@11.0.0))(supports-color@11.0.0)(typescript@6.0.3) + specifier: 8.67.0 + version: 8.67.0(eslint@10.8.1(jiti@2.7.0)(supports-color@11.0.0))(supports-color@11.0.0)(typescript@6.0.3) ajv: specifier: 8.20.0 version: 8.20.0 @@ -186,7 +186,7 @@ importers: version: 10.1.8(eslint@10.8.1(jiti@2.7.0)(supports-color@11.0.0)) eslint-plugin-import: specifier: 2.32.0 - version: 2.32.0(@typescript-eslint/parser@8.66.0(eslint@10.8.1(jiti@2.7.0)(supports-color@11.0.0))(supports-color@11.0.0)(typescript@6.0.3))(eslint@10.8.1(jiti@2.7.0)(supports-color@11.0.0))(supports-color@11.0.0) + version: 2.32.0(@typescript-eslint/parser@8.67.0(eslint@10.8.1(jiti@2.7.0)(supports-color@11.0.0))(supports-color@11.0.0)(typescript@6.0.3))(eslint@10.8.1(jiti@2.7.0)(supports-color@11.0.0))(supports-color@11.0.0) express: specifier: 5.2.1 version: 5.2.1(supports-color@11.0.0) @@ -194,8 +194,8 @@ importers: specifier: 3.3.3 version: 3.3.3 globals: - specifier: 17.9.0 - version: 17.9.0 + specifier: 17.11.0 + version: 17.11.0 http-proxy: specifier: ^1.18.1 version: 1.18.1(debug@4.4.3(supports-color@11.0.0)) @@ -239,14 +239,14 @@ importers: specifier: ^4.17.21 version: 4.18.1 magic-string: - specifier: 1.1.0 - version: 1.1.0 + specifier: 1.1.1 + version: 1.1.1 prettier: specifier: ^3.0.0 version: 3.9.6 puppeteer: - specifier: 25.5.0 - version: 25.5.0(bufferutil@4.1.0)(utf-8-validate@6.0.6) + specifier: 25.6.0 + version: 25.6.0(bufferutil@4.1.0)(utf-8-validate@6.0.6) quicktype-core: specifier: 26.0.0 version: 26.0.0 @@ -321,7 +321,7 @@ importers: version: 7.8.2 vitest: specifier: 4.1.10 - version: 4.1.10(@opentelemetry/api@1.9.1)(@types/node@22.20.1)(@vitest/coverage-v8@4.1.10)(esbuild@0.28.2)(jiti@2.7.0)(jsdom@30.0.1)(less@4.8.1(supports-color@11.0.0))(sass@1.102.0)(terser@5.49.2)(tsx@4.23.7)(yaml@2.9.0) + version: 4.1.10(@opentelemetry/api@1.9.1)(@types/node@22.20.1)(@vitest/coverage-v8@4.1.10)(esbuild@0.28.2)(jiti@2.7.0)(jsdom@30.0.1)(less@4.8.1(supports-color@11.0.0))(sass@1.102.0)(terser@5.50.0)(tsx@4.23.7)(yaml@2.9.0) packages/angular/build: dependencies: @@ -342,7 +342,7 @@ importers: version: 2.6.0 '@vitejs/plugin-basic-ssl': specifier: 2.3.0 - version: 2.3.0(vite@8.2.1(@types/node@22.20.1)(esbuild@0.28.2)(jiti@2.7.0)(less@4.8.1(supports-color@11.0.0))(sass@1.102.0)(terser@5.49.2)(tsx@4.23.7)(yaml@2.9.0)) + version: 2.3.0(vite@8.2.1(@types/node@22.20.1)(esbuild@0.28.2)(jiti@2.7.0)(less@4.8.1(supports-color@11.0.0))(sass@1.102.0)(terser@5.50.0)(tsx@4.23.7)(yaml@2.9.0)) beasties: specifier: 0.4.3 version: 0.4.3 @@ -365,14 +365,14 @@ importers: specifier: 11.0.0 version: 11.0.0 magic-string: - specifier: 1.1.0 - version: 1.1.0 + specifier: 1.1.1 + version: 1.1.1 mrmime: specifier: 2.0.1 version: 2.0.1 oxc-parser: - specifier: 0.143.0 - version: 0.143.0 + specifier: 0.144.0 + version: 0.144.0 parse5-html-rewriting-stream: specifier: 8.0.1 version: 8.0.1 @@ -383,8 +383,8 @@ importers: specifier: 5.3.0 version: 5.3.0 rolldown: - specifier: 1.2.3 - version: 1.2.3 + specifier: 1.2.4 + version: 1.2.4 sass: specifier: 1.102.0 version: 1.102.0 @@ -399,7 +399,7 @@ importers: version: 0.2.17 vite: specifier: 8.2.1 - version: 8.2.1(@types/node@22.20.1)(esbuild@0.28.2)(jiti@2.7.0)(less@4.8.1(supports-color@11.0.0))(sass@1.102.0)(terser@5.49.2)(tsx@4.23.7)(yaml@2.9.0) + version: 8.2.1(@types/node@22.20.1)(esbuild@0.28.2)(jiti@2.7.0)(less@4.8.1(supports-color@11.0.0))(sass@1.102.0)(terser@5.50.0)(tsx@4.23.7)(yaml@2.9.0) xxhash-wasm: specifier: 1.1.0 version: 1.1.0 @@ -411,8 +411,8 @@ importers: specifier: workspace:* version: link:../ssr '@oxc-project/types': - specifier: 0.143.0 - version: 0.143.0 + specifier: 0.144.0 + version: 0.144.0 istanbul-lib-instrument: specifier: 6.0.3 version: 6.0.3(supports-color@11.0.0) @@ -436,7 +436,7 @@ importers: version: 7.8.2 vitest: specifier: 4.1.10 - version: 4.1.10(@opentelemetry/api@1.9.1)(@types/node@22.20.1)(@vitest/coverage-v8@4.1.10)(esbuild@0.28.2)(jiti@2.7.0)(jsdom@30.0.1)(less@4.8.1(supports-color@11.0.0))(sass@1.102.0)(terser@5.49.2)(tsx@4.23.7)(yaml@2.9.0) + version: 4.1.10(@opentelemetry/api@1.9.1)(@types/node@22.20.1)(@vitest/coverage-v8@4.1.10)(esbuild@0.28.2)(jiti@2.7.0)(jsdom@30.0.1)(less@4.8.1(supports-color@11.0.0))(sass@1.102.0)(terser@5.50.0)(tsx@4.23.7)(yaml@2.9.0) optionalDependencies: lmdb: specifier: 3.5.6 @@ -680,8 +680,8 @@ importers: specifier: 0.5.21 version: 0.5.21 terser: - specifier: 5.49.2 - version: 5.49.2 + specifier: 5.50.0 + version: 5.50.0 tinyglobby: specifier: 0.2.17 version: 0.2.17 @@ -777,8 +777,8 @@ importers: specifier: 3.3.1 version: 3.3.1 magic-string: - specifier: 1.1.0 - version: 1.1.0 + specifier: 1.1.1 + version: 1.1.1 ora: specifier: 9.4.1 version: 9.4.1 @@ -2789,130 +2789,130 @@ packages: resolution: {integrity: sha512-eSYWTm620tTk45EKSedaUL8MFYI8hW164hIXsgIHyxu3VobUB3fFCu5t0hQby6OoWRPsG1KkKUG2M5UadiLiVg==} engines: {node: '>=14'} - '@oxc-parser/binding-android-arm-eabi@0.143.0': - resolution: {integrity: sha512-n9uozULWflPqBtdmI8lAabLqGKNgLVNN0ZH8HfgCwpKGNtzRzauB76jTiW/3YLkcA7N1zskpi9GdVnZuu1SAvg==} + '@oxc-parser/binding-android-arm-eabi@0.144.0': + resolution: {integrity: sha512-IaoGBEp/huvja99PxI/b72TbKFzA/UzxxAka7f233dc/Tg/rRTX9Qn8IquFLWwWf4IddN/5TaJ8S4Subbjq7wQ==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm] os: [android] - '@oxc-parser/binding-android-arm64@0.143.0': - resolution: {integrity: sha512-9BbdjHETk6O3zH/DDid9IgBtF0GlpLabNKN231uraXpRDSfY+iiZxTP5bk1Z63GBownVdhdINFIeddmMz4MzpQ==} + '@oxc-parser/binding-android-arm64@0.144.0': + resolution: {integrity: sha512-u6fJu8XQXP99+9pYO3jq7F1D7V9fyFuDBShYFlr+gY+GcJzhveeN/zoMfuXxX6XBquJO0kjqKd7BjhJ7pClWXQ==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [android] - '@oxc-parser/binding-darwin-arm64@0.143.0': - resolution: {integrity: sha512-gh+6ecoHUy4/sUcolBl/1qPXKBbYNxFY0Pk0ujgQvINTMSftJY7o4yb8gOkDJPeZeB8+a+u7xTe6umoP8N5HFA==} + '@oxc-parser/binding-darwin-arm64@0.144.0': + resolution: {integrity: sha512-o9xGSmMQcboJLjwI+acFf6xa7nYdp0/nRFE8ry4Xrt8OviQ9ITFDBUkAXVJMOLchSV9Pu981GxJuW0mt4i6vQQ==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [darwin] - '@oxc-parser/binding-darwin-x64@0.143.0': - resolution: {integrity: sha512-qd1hl2d+lXgHv/VQ/M9qm8TrMC5T4RqDBwtOnl+1D0QMjwcz+8AaB4JSg8STgeag0GP6a6L74XEGAsrTSJWNzQ==} + '@oxc-parser/binding-darwin-x64@0.144.0': + resolution: {integrity: sha512-2yNm4tX++W3KLbyziVhs5alSb74a3C1uNDu/1P/AQj1ux8yZYuvbCAeJCCrGkr8J18ZmnBAzDthdTZBEAEb71w==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [darwin] - '@oxc-parser/binding-freebsd-x64@0.143.0': - resolution: {integrity: sha512-M5XXcNa7aOqLPKTR41msfghKu2yQ4xWvCm11/gwU0JzOzHNk5sgW//rVEjJ+LO48+VDAMzXTSzurUVxIDKwozw==} + '@oxc-parser/binding-freebsd-x64@0.144.0': + resolution: {integrity: sha512-TG4CjY1OjynplkF9nAQ9m9zboPJksnbAF+U/9xQGSXyIt+5sQRitwfQrUgjrG17/up9G8k/boNjLD2zp4xq1Kw==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [freebsd] - '@oxc-parser/binding-linux-arm-gnueabihf@0.143.0': - resolution: {integrity: sha512-T/GXusuOkPNQhCQCSBbcU/N8j0rAypuDBl1IyFK+lyYT594XsVz80clPC/OtbSSpBGyJxj8uYEfctxVuxVYoww==} + '@oxc-parser/binding-linux-arm-gnueabihf@0.144.0': + resolution: {integrity: sha512-i0T9NagVmqc+rbSyBr5mDKj7TCMIBRrSteQlQJt1WhWIH/sZeOP9GB09H9w98YdinuZkDIPmO7Fz0jDC7bMvSA==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm] os: [linux] - '@oxc-parser/binding-linux-arm-musleabihf@0.143.0': - resolution: {integrity: sha512-oKu4RcBlXSqo3OC62dp6YTnQaZIurNDpCX3BnAM3+bJxt7s8J2TJKMnC0UYer1qhlRaDCg6wkTaTw+2IlsZ12w==} + '@oxc-parser/binding-linux-arm-musleabihf@0.144.0': + resolution: {integrity: sha512-YUsEqM3WMS3mOON+TFf7RzS0QthzEifx7tpUQu0GSF2MsT+D6t154ZBs6WhWaCZNl0GuVDEvndCyEAUBHzSHGw==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm] os: [linux] - '@oxc-parser/binding-linux-arm64-gnu@0.143.0': - resolution: {integrity: sha512-WJBbD186AZmMGaSIhlktC+rPl8L3peCTXAh88Ih9uEvK0en2mPojGyCGYiL6mHtV1RPV3JyfJW5t6n5hh0lXhA==} + '@oxc-parser/binding-linux-arm64-gnu@0.144.0': + resolution: {integrity: sha512-LlWH4kt+IET3qIAe0e0IFLNlQ3CVUAfN//UFsA6N0/FghMh/FBk1e+wzvgG+t8WSnXkvf8B1TovquS2EJras9g==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [linux] libc: [glibc] - '@oxc-parser/binding-linux-arm64-musl@0.143.0': - resolution: {integrity: sha512-t1AcYOwEzgceadT4v5e+vaCCb0AncCA3v5AyzfBAz/tMq11qzVccXKzNHtkWdjBsgvTKwRkaUF3QvT4kot8vcQ==} + '@oxc-parser/binding-linux-arm64-musl@0.144.0': + resolution: {integrity: sha512-ajXbXIWBWUD4U3IQxr2p6DiXwD7GPHEBLa+JteKhIfvLmBEBdTjO28lP+5r3AF2qal8cxLERfTnGs64Z22ZuXw==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [linux] libc: [musl] - '@oxc-parser/binding-linux-ppc64-gnu@0.143.0': - resolution: {integrity: sha512-RsnO/NoD8376LMJq8JS8TwI0ieNaFRTuNe2GVJntQg6gwZNMENZsEbknHdVwjpOmxdGLGodcwaGSbAeRr5Bgjw==} + '@oxc-parser/binding-linux-ppc64-gnu@0.144.0': + resolution: {integrity: sha512-/+sDzL/4cWEwdqenKo/DX3gkkxu7H7ytFAtealDey/Gd59yPWn64obVk6wXKVjVfXMciUUUTySxZG9AIMX3RNQ==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [ppc64] os: [linux] libc: [glibc] - '@oxc-parser/binding-linux-riscv64-gnu@0.143.0': - resolution: {integrity: sha512-48fSVfR9TZi5CASZFyv0VC6z6BCoeihFsX031mAD/oSH7d9PYsPgIqza7d9mjP7Z2KTEpTFyH6SIu0Ui6R1vdg==} + '@oxc-parser/binding-linux-riscv64-gnu@0.144.0': + resolution: {integrity: sha512-dMVhPBbrd8y6aeLd7Ihn9OZhKO8QgCQVtLBTRgbmf4lKrcR61SpaQRJPJuocTc/Cn5SJMm+alHYPnzkbOGM7Dg==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [riscv64] os: [linux] libc: [glibc] - '@oxc-parser/binding-linux-riscv64-musl@0.143.0': - resolution: {integrity: sha512-T8CpdD+SfE01DnIOD4HpVxu0ZJOfMJ/VhCvikKfaXAxkZ+9veyLM/D2hpi7Y2hFUyPmVQO3FNZHmYzV/WlVR4g==} + '@oxc-parser/binding-linux-riscv64-musl@0.144.0': + resolution: {integrity: sha512-jQ8O0+b6J2IhJgm0DnqEJq8hG9OocmF1b4TBWCk08CRWqTmLZj/+lYs7w3OA60nb2SiqOmthQyJPacrCi7y+oQ==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [riscv64] os: [linux] libc: [musl] - '@oxc-parser/binding-linux-s390x-gnu@0.143.0': - resolution: {integrity: sha512-QLdeMsCcacenPEFsfxnBUDF1y6opyz5+fmOz9bfD5Y7fiGCMupUCuB3KTPQhNwshIG1P9fPqar9MHxuBDd4bwQ==} + '@oxc-parser/binding-linux-s390x-gnu@0.144.0': + resolution: {integrity: sha512-/mZxZtcGrzuvqPLPV7gjavbROYs/dHy6+yQ2Sl/2to/+qoC/v6CcruGFnfQPzQbXXTYReXJzLb5QY9KmgCbJOg==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [s390x] os: [linux] libc: [glibc] - '@oxc-parser/binding-linux-x64-gnu@0.143.0': - resolution: {integrity: sha512-659ujfqLy6k7cuH3sbzhd8b+ztSq+i6E2E9pG78Q0BmHjAExfGIdgc8cGgMdwAozDXeZFHkJ+LXYJdWsaGdgyw==} + '@oxc-parser/binding-linux-x64-gnu@0.144.0': + resolution: {integrity: sha512-/caRGFHcarHZlBrucBwQwBbzqhD+UfZZ/r7soocS0/mp6/5KTq+1Zl/OQx5lFLcN+GpUPYszbrvQU9MCFLEzJg==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [linux] libc: [glibc] - '@oxc-parser/binding-linux-x64-musl@0.143.0': - resolution: {integrity: sha512-/Mw/9j4TfZcnKphPrzOE6t4MMknXadcAAuVUlDRTF/ETWB5xOgQvOJV2Mh9We/bWxZdoxaGAdc+hy4GuYwQ2yQ==} + '@oxc-parser/binding-linux-x64-musl@0.144.0': + resolution: {integrity: sha512-qFtwAo6BWuWDjh57QDdZdYi746GW0mIeoZSGK2jJqlxIjo389Y/7lrriTOI+ou7tTvusOrSYGQZ+e+nDswt2vQ==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [linux] libc: [musl] - '@oxc-parser/binding-openharmony-arm64@0.143.0': - resolution: {integrity: sha512-8rIKWR2BFuifbIK/1XB9wTaSdtuJ25dlE7ZQYDnEwj/2xH2vHsxnvIjHT3ZjSVuLLwGGlSslIG/fbOJ8TV8rTw==} + '@oxc-parser/binding-openharmony-arm64@0.144.0': + resolution: {integrity: sha512-n+NgMGWWEYpH+rlkMhDvLR2k8vJDHQp3j8SoS86IS6J0hc4kuDaiYAAvu9dF86xjeGYy+h9WLj12sylmBJV9sg==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [openharmony] - '@oxc-parser/binding-win32-arm64-msvc@0.143.0': - resolution: {integrity: sha512-5U9kQYMfRRI6Zq7KDxgbIP0RMnKrfn3gLepRMgJuRkPSUALTiRCk9d/uyhb4lGDjUdzwK7mBkKqhLgzBPCmLpQ==} + '@oxc-parser/binding-win32-arm64-msvc@0.144.0': + resolution: {integrity: sha512-fShxpJiCBOdG4+jBAvahTTFUDI5djXc/+IPC1ldeC8LbyCW0h9m/7oP8DRZWI7WT2Ahv8sHtZz4ugECylCFpTA==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [win32] - '@oxc-parser/binding-win32-ia32-msvc@0.143.0': - resolution: {integrity: sha512-25P7AaHk4R88Yv2XH4gToDVmh0cOu+bEURQU10CRrmvgabfRArSGAP5osmwUKeSUHj0VS50upbpbRWWW/m7mHA==} + '@oxc-parser/binding-win32-ia32-msvc@0.144.0': + resolution: {integrity: sha512-vFrYV+C3lJhIiSdNhdkZHnZ0YIClgTSluXaPMYjlGslVPD+uJg6K1s2xNL/X/gdBcy9IIbjbp0vNBwQhdMMdkw==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [ia32] os: [win32] - '@oxc-parser/binding-win32-x64-msvc@0.143.0': - resolution: {integrity: sha512-ORMh3JE1s6V7ySicdRK7vgaDQnn5o+UHg9ct989PlWHbel8O9ARrmWXM6kZjrBMtNucxNayQ8g69G0VfWzhANw==} + '@oxc-parser/binding-win32-x64-msvc@0.144.0': + resolution: {integrity: sha512-0ASbKSwdeihMekyy7y4jC0CwW3XBDZk5Sw64m/W7IReVQHaduqLYssF9KCJA2oHG9oldnl/1CMxqCoImXfqQkA==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [win32] - '@oxc-project/types@0.143.0': - resolution: {integrity: sha512-u6JZdLBTLotrNC9Vd6vPssINdzcCzleKAH6EJKImQb7GtYvX5keN2dxkoK44stCc4tffE6QQRtZTXVSzsLUlWA==} + '@oxc-project/types@0.144.0': + resolution: {integrity: sha512-nuhZIOLuI6TFQ32I/WnUx+SCPY7SdSKwgnFHydAuoS1+Z4BRcaP+RRJmGzl9lw+0OFF7UmaESf7KQRXaNLHypg==} '@parcel/watcher-android-arm64@2.6.0': resolution: {integrity: sha512-trgpLSCKRC/huFjXX/Smh+0sWe4+YtKfktIToiMl59ghz7z+qkH6kMvNnUbLyRs9N11t8l4svSCs1+5B3rOAhA==} @@ -3087,8 +3087,8 @@ packages: '@protobufjs/utf8@1.1.2': resolution: {integrity: sha512-b1UQwcEZ4yCnMCD8DAL1VlbvBJE9/IX4FTIp7BG1xYpf29SLazLSrqUkj4w7Y5y7cCVP6E5tcqqcI0xemPkHug==} - '@puppeteer/browsers@3.1.0': - resolution: {integrity: sha512-RDLpio3fH/qrj5k4DVY6eyiN8tCS0Zovd/6jW//n605oeqkWcUjn+3k+9ZtZBnbwMpsu0F7xDIiKXvVmG5c5Bw==} + '@puppeteer/browsers@3.2.0': + resolution: {integrity: sha512-LlBrE8oqGfU7b1Nk2d5Q1SbuPhZxTj0cJEMDPEws28OjNMELlflekmPPuf4FnK03x0ZRjKaYwJElUcKK4kyqJA==} engines: {node: '>=22.12.0'} hasBin: true peerDependencies: @@ -3100,92 +3100,92 @@ packages: yauzl: optional: true - '@rolldown/binding-android-arm64@1.2.3': - resolution: {integrity: sha512-zrJtHDcaZJ1Fp7xf4hNl+7seH9Cn/N5TwLYkhgXREtBwAd/jaqW3uqeHxpDugJLVICWg4eW44kOQEGJ1r6jCGw==} + '@rolldown/binding-android-arm64@1.2.4': + resolution: {integrity: sha512-jHC2cnyKz5xU2fhECtFl8OZ83cYNt13GZQD+0uMJ/X3o+ijmd56okHhTUwxVSHPx1IRVIJEZ1/1pPzeLCU6XKA==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [android] - '@rolldown/binding-darwin-arm64@1.2.3': - resolution: {integrity: sha512-ieIiibVCp0tX7TLu2cafoNPv8wJyYi01ekXpbf8q2j7F4rGAhhXb/eQh7ge9DRBY78GwmRQtvjZDux7EDbA8kA==} + '@rolldown/binding-darwin-arm64@1.2.4': + resolution: {integrity: sha512-Dc5mPD8F5F/FS8i01syd7FTF6yB2fVthH/TRkjwJkzUK6EpoxHtqvZQP5Zwq80/5z19TWYHIg1KOHboCgVx/aQ==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [darwin] - '@rolldown/binding-darwin-x64@1.2.3': - resolution: {integrity: sha512-Zh9tCon19eDXJoihx0rqKhMUlMYqzwj3aPsSuHmI4RWZh62dWUL+DJN4C5YQya5TcQBJU/Fe8+rY0jhXTQITqA==} + '@rolldown/binding-darwin-x64@1.2.4': + resolution: {integrity: sha512-fpDm4oBo6SqLvWUYCmFhdde3U9KH2fRNNMeAnAPAIwxRL345xutL0EtEUcuoxsoazdJGv/MuDBQHlCDrtbvqOg==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [darwin] - '@rolldown/binding-freebsd-x64@1.2.3': - resolution: {integrity: sha512-nGbJWewA1wrXXZiQhjAT5rhibGfns5ZNkDVqxsO6zJ3f3YvpoDNNmGMSbbhLuXKjNScaBJVOAboztAWVespQMg==} + '@rolldown/binding-freebsd-x64@1.2.4': + resolution: {integrity: sha512-rSJoreDE/HoIzoaib6MTp5jQtCTdMHKIvItAKT/ImS6Y6Ww76oUaeMyp4Vc/fAgd/ehji068IxetHXAnqUwN9A==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [freebsd] - '@rolldown/binding-linux-arm-gnueabihf@1.2.3': - resolution: {integrity: sha512-QNniJr5Kml0kDEB98jiDOJjXNroxIIi0IXIbdYzY26Xt1pVbeP62+KnoIZLwirOymX/0jDk/2gI/bNUv7A7OIw==} + '@rolldown/binding-linux-arm-gnueabihf@1.2.4': + resolution: {integrity: sha512-/jm8OGHgn7oGaJu3i/qZI9spUGcJ+y/lk43ttQ/iO1tOd9NissG6o97bighBCiL+BKRngmcDuR6ikfwYdJmVuQ==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm] os: [linux] - '@rolldown/binding-linux-arm64-gnu@1.2.3': - resolution: {integrity: sha512-TkqEAcmmvH3I/q4114NB4RVt6241Dao48pF45uLcFGrwAaIn0iITgTAKP/dLjbN0R4buJjGb91+UHSoFmpgIWw==} + '@rolldown/binding-linux-arm64-gnu@1.2.4': + resolution: {integrity: sha512-tIP06BeD9EqvECBrPZ+sqdPlYrT+aYaAiu1wYziVx5elRK/ftm33JxVDy2bXGbr6J0CrtirCkR87/X5a2euEng==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [linux] libc: [glibc] - '@rolldown/binding-linux-arm64-musl@1.2.3': - resolution: {integrity: sha512-NHqjnxpsndf4MPymxteFAWHHfkTL8HjWh1KB7z23ofZ6QO2euONuxDXjat69dKZRALnGypg8k8SsK8vZJoXv1Q==} + '@rolldown/binding-linux-arm64-musl@1.2.4': + resolution: {integrity: sha512-Ql1Q0EQqVThvn9VAVlwNzsUvbSFtCMGjLpRRi4pk5i7NZZ4n5ISiLMjHYtus4VQ2PvkSw24zyaCVsiS+sXPj1w==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [linux] libc: [musl] - '@rolldown/binding-linux-ppc64-gnu@1.2.3': - resolution: {integrity: sha512-6tbrbwfz5GB9DQ4Jwo6hy9v+vR31xZlvzZ6n5Xut6Hhx5PvrA9q/HsK8KMaYQp063iqZGXwNvZtYNLD7EM/x0w==} + '@rolldown/binding-linux-ppc64-gnu@1.2.4': + resolution: {integrity: sha512-GjbjXD4XXfN19D0LZNbmiCBUoDiRACsYHr0yaIbbn8aFsXjHZifcYqu/W5Er5X2X990WjHXFrxarn5chzItorQ==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [ppc64] os: [linux] libc: [glibc] - '@rolldown/binding-linux-s390x-gnu@1.2.3': - resolution: {integrity: sha512-oyuXxXmoZHjXC917IAPFAAv4wWAa0cM9afk8nx1+9/jNNOX1uPf8yDA6p7G0RypOfw/X0PQt5IfoquY1um+zSg==} + '@rolldown/binding-linux-s390x-gnu@1.2.4': + resolution: {integrity: sha512-p5WR0NOwaRmJ/B1b6IjEFLLivwEsf3PrdBIhRbhTCQisbo2SvHHpG4ELB/+FgQNnB88LTOF86upmJmbvZdQ2lw==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [s390x] os: [linux] libc: [glibc] - '@rolldown/binding-linux-x64-gnu@1.2.3': - resolution: {integrity: sha512-TytMwF2KVGqP2tgd0I1OY0PAv78dZRAYcF5ssDzjM34SUXCED3uXvSd5+lHoC0bTD6eEdFz7LdQNCO1y0oVk9w==} + '@rolldown/binding-linux-x64-gnu@1.2.4': + resolution: {integrity: sha512-4/GyVjmhR+Tc6HLJvwc1sOhPqAZtySiSMesOZyX6JQ5XBxoTDEMKQzvo07NIK6nTon/SivlZqvhzvuVBNQhObQ==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [linux] libc: [glibc] - '@rolldown/binding-linux-x64-musl@1.2.3': - resolution: {integrity: sha512-/E9m3qstrJFVPoULV25mVQblSNExY2+kBsYe4sy0Tn0yOOgJ8wZbZt3KnRbF/XeU2Gl1STKUQnDNTqhIE5MD4A==} + '@rolldown/binding-linux-x64-musl@1.2.4': + resolution: {integrity: sha512-l9eeLsCNvPpmSXUej0etw/J1eqV0Jj1D5G/xG6YTijmE6dkv6E2QezgWbTfQk63v952DPqrjOCoiqxq7Bw0YUQ==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [linux] libc: [musl] - '@rolldown/binding-openharmony-arm64@1.2.3': - resolution: {integrity: sha512-Kr0OcsoQI816i6HOl3vFHpd1K0eZyh76zgfj4c1nTyaTsd5r2Mj1lwM4R90y/qaCfmTn9eHy0SKwi98eitRxug==} + '@rolldown/binding-openharmony-arm64@1.2.4': + resolution: {integrity: sha512-e0F355MSTMm3+UOqtV3L24gFUp2N5m1f8L/7d56deik6va+AXdrt9F8LbzGpeWGWRbZEDq4m8NVnJDeBtf9DZg==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [openharmony] - '@rolldown/binding-win32-arm64-msvc@1.2.3': - resolution: {integrity: sha512-hOtMwTqnME+/gJcH/PCZ0wn0zPUjiWOgkHpxbSJpfGKMezHltx1S7/k1SitzVa7Ww2cqrDDaFbZEhcJZO8o+Jw==} + '@rolldown/binding-win32-arm64-msvc@1.2.4': + resolution: {integrity: sha512-AWLi0uBRYh6QlE7OKhiz+phZC0qwtij2QZmhmOdsLdFn64m7oMpooE9ICE3lhm9xMb4SpDo2WbHcxX1iFLFtqw==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [win32] - '@rolldown/binding-win32-x64-msvc@1.2.3': - resolution: {integrity: sha512-ekcqMMkI2PlhYnfzQnB/cEdYUVVJViWvoUyLrbzgDoi3Snfc1mVBwdnc306ufA5ejy8JSPjT2RlW1nQSjW7efg==} + '@rolldown/binding-win32-x64-msvc@1.2.4': + resolution: {integrity: sha512-UwSDJOg3dqCAejWdxclJjCsh3Qq4vLYMDxmyHqo1btz3stK2VqgwNd3mm5tuIwzSlGIQ/1H9Hr+Zn09mrezNqQ==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [win32] @@ -3596,39 +3596,39 @@ packages: '@types/yarnpkg__lockfile@1.1.9': resolution: {integrity: sha512-GD4Fk15UoP5NLCNor51YdfL9MSdldKCqOC9EssrRw3HVfar9wUZ5y8Lfnp+qVD6hIinLr8ygklDYnmlnlQo12Q==} - '@typescript-eslint/eslint-plugin@8.66.0': - resolution: {integrity: sha512-p088eaGrzYz1s+7cov0aMOCkNGTJlVxF4jgubf28c8L0Cv9Rloj8YBHnv4hXLq6IIEE1AsjNWavO+k+8kP2Y0A==} + '@typescript-eslint/eslint-plugin@8.67.0': + resolution: {integrity: sha512-Un7Heoyj65NREbKAyIrFxeM143NZpExWmy1Nep4DLeQOeLlTeumPjoNKnBrU5D5moWXbPJgRa5Uwcdu0faVNGQ==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: - '@typescript-eslint/parser': ^8.66.0 + '@typescript-eslint/parser': ^8.67.0 eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 typescript: '>=4.8.4 <6.1.0' - '@typescript-eslint/parser@8.66.0': - resolution: {integrity: sha512-X6ypGChaWYk6PBtUg2BwuTZEFFcHJAtGTVJ9/lCTOufhZ4i9fNolQNnktq+kkMCwMj7V8Svsq7+TxSDslmhE0g==} + '@typescript-eslint/parser@8.67.0': + resolution: {integrity: sha512-fUBfTuuEulWqX6V8+O3PtScV01tzYYRUDTAirHFKoRAt7nOzoGiPt0M/bB47wWNy0coOOcgEwAMUtBpykMxl6w==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 typescript: '>=4.8.4 <6.1.0' - '@typescript-eslint/project-service@8.66.0': - resolution: {integrity: sha512-7MthGPTt4BP69lSryqpqq8HQqxuzynssckL/jyDyk3+TNMQ3y2jFWkptCrktWvBrP+EH787Nl5N5Qpw7WZg+5g==} + '@typescript-eslint/project-service@8.67.0': + resolution: {integrity: sha512-cvE8c7ulYeXN9fYuszhCeCsbzyVEXuhrRCybnBre7TUmqb5nRmBfQAwCj0O3WJFDeyAZt4VYv51vMCC9LHSdYw==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: typescript: '>=4.8.4 <6.1.0' - '@typescript-eslint/scope-manager@8.66.0': - resolution: {integrity: sha512-8TGcH25j9zqJ/IULB/ppyhRvxA8QYfFEZ7nfbg6/BN9spDgb8fPWQXlE5l8TWBL50EtUx007uZ1o9VOwrq2/9g==} + '@typescript-eslint/scope-manager@8.67.0': + resolution: {integrity: sha512-EgvsleTwS4E+WzzSvem8fAUubLwatMNF1B5hHSLQxcvs7q2dtRhGyujHwLJSYlG41niJ7GP24Aha2+0mb1b2kg==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@typescript-eslint/tsconfig-utils@8.66.0': - resolution: {integrity: sha512-9D5gLYZG4rOjcoag8MQ/fWI8WqA9wcPDyOGyWtWFhvM1lHRbliqUSPIY5J3zqCU1tvSwzXxnnjhQhz5Ne7mJ4g==} + '@typescript-eslint/tsconfig-utils@8.67.0': + resolution: {integrity: sha512-vV+LUSv5njUWsknE71fqKTlXUva+R76SaeORd6Zojcunk/6DvKFXONU3BrAs2H49mbygUXt6gbYunzwqNwlhdg==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: typescript: '>=4.8.4 <6.1.0' - '@typescript-eslint/type-utils@8.66.0': - resolution: {integrity: sha512-LG2dWfjZQQp0ADtAu/EWJVayefGL2UEZ3CDeI44D9v3rXB/WYUqE/jpO28KrEKul5AySrmI+Zh1v6v+xW2U9+g==} + '@typescript-eslint/type-utils@8.67.0': + resolution: {integrity: sha512-aVWDXbRmdXO9siTfX4ditQI1T9+zVcNazT48EJCD0v40/9RIFoUgZ05CmGEq9H2gixRpjUn/iplwvlcvutJW/Q==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 @@ -3638,21 +3638,25 @@ packages: resolution: {integrity: sha512-H6gcYaSDOyvL3AD/jHUtUFo2jqGgn/F6nuyuZSu0QTesxL+cP4dQoIMrODRofuJC09g64+WgZ6tE19Y1N2YIFQ==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@typescript-eslint/typescript-estree@8.66.0': - resolution: {integrity: sha512-8/x4INiiQb10jGgXYD7116/zQ+OL84ZIFn0za68wwFHCanT/VLbBEroWht8RV8fn0/ZCAoazHLQgwUC0UQcDfg==} + '@typescript-eslint/types@8.67.0': + resolution: {integrity: sha512-sBtgslww8nsMYUjhdPBiSyUqSzT8uR6g93A2QXnQC8+cGdjz0CyaOdqHDRJb1AtORbZCNUJBBeFA/tNR2uQmww==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@typescript-eslint/typescript-estree@8.67.0': + resolution: {integrity: sha512-EKQBCE9yNlRJYm7jdTW5AhDacDUmSwQb0FAJAmK2EKYrNXIsa2vxcSZx6PvJ/dEdI6lS+Y9W+EXckLj0iPFGcw==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: typescript: '>=4.8.4 <6.1.0' - '@typescript-eslint/utils@8.66.0': - resolution: {integrity: sha512-jasearZPolBw5NJNYGMwxzHMF83niVWmMU1VdHzG1CyfI2VS7f7nZltnKtHcg20hW+7Uo5GfK4MeDPoU3qI8EA==} + '@typescript-eslint/utils@8.67.0': + resolution: {integrity: sha512-U9D1FdwEWBwok3hxxSdhclMb0twvt9QnjIQ0VfQ1AiX2epnpSgv2ubVDsayOFyY8K6FX+AQ7E0FKWVG3iKsj1A==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 typescript: '>=4.8.4 <6.1.0' - '@typescript-eslint/visitor-keys@8.66.0': - resolution: {integrity: sha512-dkKR8q+lKciskj1Y3vthHktl+3cMLWGyVUP23bRiPZ5O9BRT++4EqDDV+TVeIKBL1VXVEqrJlz8MYbcnvJcAlg==} + '@typescript-eslint/visitor-keys@8.67.0': + resolution: {integrity: sha512-fkv8dHRDqfGtTHuJeebdrQ7cX6Ad4WAS00rgHh9UGvMycF1mjBfsxry1XsLIFhWZ6Judlh6UdzK+TYlbpCXgnA==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} '@verdaccio/auth@8.1.1': @@ -3822,6 +3826,7 @@ packages: '@xmldom/xmldom@0.8.13': resolution: {integrity: sha512-KRYzxepc14G/CEpEGc3Yn+JKaAeT63smlDr+vjB8jRfgTBBI9wRj/nkQEO+ucV8p8I9bfKLWp37uHgFrbntPvw==} engines: {node: '>=10.0.0'} + deprecated: this version has critical issues, please update to the latest version '@xtuc/ieee754@1.2.0': resolution: {integrity: sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA==} @@ -5417,8 +5422,8 @@ packages: resolution: {integrity: sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==} engines: {node: '>=18'} - globals@17.9.0: - resolution: {integrity: sha512-m/MvAW61QVU5VDNF1Vj8axt016h8w7L5TU1e9zlab7XIttAT2YAlCwl75K1fOqvMM9apmD7lbCIRhpfkhmxhCg==} + globals@17.11.0: + resolution: {integrity: sha512-Z2I8hM+PbJDXQDq3Icgpzv+mPdwr68iZUU9d5WW4FuXfDUQfkZaZuvjMv42/5crNyw154+9+VWXbYrUgDXbxNw==} engines: {node: '>=18'} globalthis@1.0.4: @@ -6300,8 +6305,8 @@ packages: magic-string@0.30.21: resolution: {integrity: sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==} - magic-string@1.1.0: - resolution: {integrity: sha512-kS3VHe0nEPST2saQV4Rbkchcd3UBRkVTQHo1D3h/ZTwFDhai/mfKkmtPAtD129EOI7K3HlHIsFOt0WrI2/oU9g==} + magic-string@1.1.1: + resolution: {integrity: sha512-qFemKPzc3ttrYVaMmnSkGtGc5nE6Ncl4bj7c9IE6C9OUIRXjf6PzJ+UZ1xhVIjYc7dolHq3qKzpAJPZUbvNj+A==} magicast@0.5.4: resolution: {integrity: sha512-llBEhWm1SacoRwgHUoQJYtwp4PBLF4faQi5TCpIGyGs9n4y5+juI0tDgyKIfpqxckRHaHzouUEph3THklWh03w==} @@ -6483,8 +6488,8 @@ packages: engines: {node: '>=10'} hasBin: true - modern-tar@0.7.7: - resolution: {integrity: sha512-t9VmxaqrmANnEOBhpSDI6HD192Ge48k8vmWqQQL7hSFEqHEYwZbbsu49+aKLWZeRvFs3j1pMhXOqqF4kPlvjkQ==} + modern-tar@0.8.4: + resolution: {integrity: sha512-gN54ddmyzEg10orwZ2u4OOv+bjpMWdIl5jIkodK97bMq8QBSL5c0D7YX0lT1Ooz+99S7+PvFbnxzdjgHo1r41g==} engines: {node: '>=18.0.0'} mrmime@2.0.1: @@ -6713,8 +6718,8 @@ packages: resolution: {integrity: sha512-19YVAg7T+WTrxggPukVq7DjTv6+PJ867TmhCvBsYwmbFCsZd344rq2Ld1p0wo8f8Qrrhgp82c6FJRqdXWtSEhg==} engines: {node: '>= 0.4'} - oxc-parser@0.143.0: - resolution: {integrity: sha512-ov0NzaDCOInknS7mP1cwKdJERt3utPW8ldjtdUXQ8Ty0GEFD08wk422vCUN0d7pST6kqtV7dxoI9w1Zi0l/9TA==} + oxc-parser@0.144.0: + resolution: {integrity: sha512-eacM4wMgGWXctHubY262yo+50E76qtQBqe+uK73YEV1IT3qP12Acbnf9Nc8t+agIAdnko9iVT4KF83/d0EjY5w==} engines: {node: ^20.19.0 || >=22.12.0} p-finally@1.0.0: @@ -7004,12 +7009,12 @@ packages: resolution: {integrity: sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==} engines: {node: '>=6'} - puppeteer-core@25.5.0: - resolution: {integrity: sha512-XPNT0dQJtphqQ4I29zxlG4IIPbg1iEHAQKWuQgtMJGXjACV77pZSmJvDi51IIIfd+DTKICcopJwUx4upVQ4XbA==} + puppeteer-core@25.6.0: + resolution: {integrity: sha512-GJ67rjZdVQzZmD2Ab0cgttfQN9j387QYMv3t6MN3/4nmjursNt6M5Utj4/T/4y0AwNrSwJzjw6Q/zuWFEIizOg==} engines: {node: '>=22.12.0'} - puppeteer@25.5.0: - resolution: {integrity: sha512-qpp73xblxNr+bF0nSXTodM3v+zcK5IPo/GkjLsdUqRf/qpLJp/1KxBUbstoMMnwnPw9xD6OMei8kmYf6CLWfGw==} + puppeteer@25.6.0: + resolution: {integrity: sha512-TXUolDddU4AwISjOOrGk2AhJDpbM/ZDt2KvGIqz74EOk+8bKwXFo+acUvP1sQx3hUda7owOeNuuT1UnJT1o0qA==} engines: {node: '>=22.12.0'} hasBin: true @@ -7211,8 +7216,8 @@ packages: vue-tsc: optional: true - rolldown@1.2.3: - resolution: {integrity: sha512-rn9wpmxplLf7NLNyCk9FyWh3FM43DbY8jOzCdEPzH7uflhTftRbCEpqi6Ly2osgoU8OwObtmavMbWLaWy4LX7A==} + rolldown@1.2.4: + resolution: {integrity: sha512-rSr7irW0K7QRWzjdJXqZowkcRdDtjRduh43rBltnVKd0VFq839l1lJoDvGJb6gl7+4rTTCrPWu+YfujUL8Ug7w==} engines: {node: ^20.19.0 || >=22.12.0} hasBin: true @@ -7650,8 +7655,8 @@ packages: teex@1.0.1: resolution: {integrity: sha512-eYE6iEI62Ni1H8oIa7KlDU6uQBtqr4Eajni3wX7rpfXD8ysFx8z0+dri+KWEPWpBsxXfxu58x/0jvTVT1ekOSg==} - terser@5.49.2: - resolution: {integrity: sha512-rGbJiKeQ4WDe3EXlDAIaQcwftVfv2Q8o1awFNfvXolJYKkb1AuZY1RTOmqx4LJXZENbWZA7eIsYGHuEzHsi1nQ==} + terser@5.50.0: + resolution: {integrity: sha512-CN9BVxWhgS/hRxtUMjtC2uRWSTcSfQFHMDWma6sKKfIivCD91sM+FOPfvwoaRMqCSrUpe1nv3jDamd9eEQ4y+w==} engines: {node: '>=10'} hasBin: true @@ -10543,64 +10548,64 @@ snapshots: '@opentelemetry/semantic-conventions@1.43.0': {} - '@oxc-parser/binding-android-arm-eabi@0.143.0': + '@oxc-parser/binding-android-arm-eabi@0.144.0': optional: true - '@oxc-parser/binding-android-arm64@0.143.0': + '@oxc-parser/binding-android-arm64@0.144.0': optional: true - '@oxc-parser/binding-darwin-arm64@0.143.0': + '@oxc-parser/binding-darwin-arm64@0.144.0': optional: true - '@oxc-parser/binding-darwin-x64@0.143.0': + '@oxc-parser/binding-darwin-x64@0.144.0': optional: true - '@oxc-parser/binding-freebsd-x64@0.143.0': + '@oxc-parser/binding-freebsd-x64@0.144.0': optional: true - '@oxc-parser/binding-linux-arm-gnueabihf@0.143.0': + '@oxc-parser/binding-linux-arm-gnueabihf@0.144.0': optional: true - '@oxc-parser/binding-linux-arm-musleabihf@0.143.0': + '@oxc-parser/binding-linux-arm-musleabihf@0.144.0': optional: true - '@oxc-parser/binding-linux-arm64-gnu@0.143.0': + '@oxc-parser/binding-linux-arm64-gnu@0.144.0': optional: true - '@oxc-parser/binding-linux-arm64-musl@0.143.0': + '@oxc-parser/binding-linux-arm64-musl@0.144.0': optional: true - '@oxc-parser/binding-linux-ppc64-gnu@0.143.0': + '@oxc-parser/binding-linux-ppc64-gnu@0.144.0': optional: true - '@oxc-parser/binding-linux-riscv64-gnu@0.143.0': + '@oxc-parser/binding-linux-riscv64-gnu@0.144.0': optional: true - '@oxc-parser/binding-linux-riscv64-musl@0.143.0': + '@oxc-parser/binding-linux-riscv64-musl@0.144.0': optional: true - '@oxc-parser/binding-linux-s390x-gnu@0.143.0': + '@oxc-parser/binding-linux-s390x-gnu@0.144.0': optional: true - '@oxc-parser/binding-linux-x64-gnu@0.143.0': + '@oxc-parser/binding-linux-x64-gnu@0.144.0': optional: true - '@oxc-parser/binding-linux-x64-musl@0.143.0': + '@oxc-parser/binding-linux-x64-musl@0.144.0': optional: true - '@oxc-parser/binding-openharmony-arm64@0.143.0': + '@oxc-parser/binding-openharmony-arm64@0.144.0': optional: true - '@oxc-parser/binding-win32-arm64-msvc@0.143.0': + '@oxc-parser/binding-win32-arm64-msvc@0.144.0': optional: true - '@oxc-parser/binding-win32-ia32-msvc@0.143.0': + '@oxc-parser/binding-win32-ia32-msvc@0.144.0': optional: true - '@oxc-parser/binding-win32-x64-msvc@0.143.0': + '@oxc-parser/binding-win32-x64-msvc@0.144.0': optional: true - '@oxc-project/types@0.143.0': {} + '@oxc-project/types@0.144.0': {} '@parcel/watcher-android-arm64@2.6.0': optional: true @@ -10797,51 +10802,51 @@ snapshots: '@protobufjs/utf8@1.1.2': {} - '@puppeteer/browsers@3.1.0': + '@puppeteer/browsers@3.2.0': dependencies: - modern-tar: 0.7.7 + modern-tar: 0.8.4 yargs: 18.1.0 - '@rolldown/binding-android-arm64@1.2.3': + '@rolldown/binding-android-arm64@1.2.4': optional: true - '@rolldown/binding-darwin-arm64@1.2.3': + '@rolldown/binding-darwin-arm64@1.2.4': optional: true - '@rolldown/binding-darwin-x64@1.2.3': + '@rolldown/binding-darwin-x64@1.2.4': optional: true - '@rolldown/binding-freebsd-x64@1.2.3': + '@rolldown/binding-freebsd-x64@1.2.4': optional: true - '@rolldown/binding-linux-arm-gnueabihf@1.2.3': + '@rolldown/binding-linux-arm-gnueabihf@1.2.4': optional: true - '@rolldown/binding-linux-arm64-gnu@1.2.3': + '@rolldown/binding-linux-arm64-gnu@1.2.4': optional: true - '@rolldown/binding-linux-arm64-musl@1.2.3': + '@rolldown/binding-linux-arm64-musl@1.2.4': optional: true - '@rolldown/binding-linux-ppc64-gnu@1.2.3': + '@rolldown/binding-linux-ppc64-gnu@1.2.4': optional: true - '@rolldown/binding-linux-s390x-gnu@1.2.3': + '@rolldown/binding-linux-s390x-gnu@1.2.4': optional: true - '@rolldown/binding-linux-x64-gnu@1.2.3': + '@rolldown/binding-linux-x64-gnu@1.2.4': optional: true - '@rolldown/binding-linux-x64-musl@1.2.3': + '@rolldown/binding-linux-x64-musl@1.2.4': optional: true - '@rolldown/binding-openharmony-arm64@1.2.3': + '@rolldown/binding-openharmony-arm64@1.2.4': optional: true - '@rolldown/binding-win32-arm64-msvc@1.2.3': + '@rolldown/binding-win32-arm64-msvc@1.2.4': optional: true - '@rolldown/binding-win32-x64-msvc@1.2.3': + '@rolldown/binding-win32-x64-msvc@1.2.4': optional: true '@rolldown/pluginutils@1.0.1': {} @@ -11217,14 +11222,14 @@ snapshots: '@types/yarnpkg__lockfile@1.1.9': {} - '@typescript-eslint/eslint-plugin@8.66.0(@typescript-eslint/parser@8.66.0(eslint@10.8.1(jiti@2.7.0)(supports-color@11.0.0))(supports-color@11.0.0)(typescript@6.0.3))(eslint@10.8.1(jiti@2.7.0)(supports-color@11.0.0))(supports-color@11.0.0)(typescript@6.0.3)': + '@typescript-eslint/eslint-plugin@8.67.0(@typescript-eslint/parser@8.67.0(eslint@10.8.1(jiti@2.7.0)(supports-color@11.0.0))(supports-color@11.0.0)(typescript@6.0.3))(eslint@10.8.1(jiti@2.7.0)(supports-color@11.0.0))(supports-color@11.0.0)(typescript@6.0.3)': dependencies: '@eslint-community/regexpp': 4.12.2 - '@typescript-eslint/parser': 8.66.0(eslint@10.8.1(jiti@2.7.0)(supports-color@11.0.0))(supports-color@11.0.0)(typescript@6.0.3) - '@typescript-eslint/scope-manager': 8.66.0 - '@typescript-eslint/type-utils': 8.66.0(eslint@10.8.1(jiti@2.7.0)(supports-color@11.0.0))(supports-color@11.0.0)(typescript@6.0.3) - '@typescript-eslint/utils': 8.66.0(eslint@10.8.1(jiti@2.7.0)(supports-color@11.0.0))(supports-color@11.0.0)(typescript@6.0.3) - '@typescript-eslint/visitor-keys': 8.66.0 + '@typescript-eslint/parser': 8.67.0(eslint@10.8.1(jiti@2.7.0)(supports-color@11.0.0))(supports-color@11.0.0)(typescript@6.0.3) + '@typescript-eslint/scope-manager': 8.67.0 + '@typescript-eslint/type-utils': 8.67.0(eslint@10.8.1(jiti@2.7.0)(supports-color@11.0.0))(supports-color@11.0.0)(typescript@6.0.3) + '@typescript-eslint/utils': 8.67.0(eslint@10.8.1(jiti@2.7.0)(supports-color@11.0.0))(supports-color@11.0.0)(typescript@6.0.3) + '@typescript-eslint/visitor-keys': 8.67.0 eslint: 10.8.1(jiti@2.7.0)(supports-color@11.0.0) ignore: 7.0.6 natural-compare: 1.4.0 @@ -11233,41 +11238,41 @@ snapshots: transitivePeerDependencies: - supports-color - '@typescript-eslint/parser@8.66.0(eslint@10.8.1(jiti@2.7.0)(supports-color@11.0.0))(supports-color@11.0.0)(typescript@6.0.3)': + '@typescript-eslint/parser@8.67.0(eslint@10.8.1(jiti@2.7.0)(supports-color@11.0.0))(supports-color@11.0.0)(typescript@6.0.3)': dependencies: - '@typescript-eslint/scope-manager': 8.66.0 - '@typescript-eslint/types': 8.66.0 - '@typescript-eslint/typescript-estree': 8.66.0(supports-color@11.0.0)(typescript@6.0.3) - '@typescript-eslint/visitor-keys': 8.66.0 + '@typescript-eslint/scope-manager': 8.67.0 + '@typescript-eslint/types': 8.67.0 + '@typescript-eslint/typescript-estree': 8.67.0(supports-color@11.0.0)(typescript@6.0.3) + '@typescript-eslint/visitor-keys': 8.67.0 debug: 4.4.3(supports-color@11.0.0) eslint: 10.8.1(jiti@2.7.0)(supports-color@11.0.0) typescript: 6.0.3 transitivePeerDependencies: - supports-color - '@typescript-eslint/project-service@8.66.0(supports-color@11.0.0)(typescript@6.0.3)': + '@typescript-eslint/project-service@8.67.0(supports-color@11.0.0)(typescript@6.0.3)': dependencies: - '@typescript-eslint/tsconfig-utils': 8.66.0(typescript@6.0.3) - '@typescript-eslint/types': 8.66.0 + '@typescript-eslint/tsconfig-utils': 8.67.0(typescript@6.0.3) + '@typescript-eslint/types': 8.67.0 debug: 4.4.3(supports-color@11.0.0) typescript: 6.0.3 transitivePeerDependencies: - supports-color - '@typescript-eslint/scope-manager@8.66.0': + '@typescript-eslint/scope-manager@8.67.0': dependencies: - '@typescript-eslint/types': 8.66.0 - '@typescript-eslint/visitor-keys': 8.66.0 + '@typescript-eslint/types': 8.67.0 + '@typescript-eslint/visitor-keys': 8.67.0 - '@typescript-eslint/tsconfig-utils@8.66.0(typescript@6.0.3)': + '@typescript-eslint/tsconfig-utils@8.67.0(typescript@6.0.3)': dependencies: typescript: 6.0.3 - '@typescript-eslint/type-utils@8.66.0(eslint@10.8.1(jiti@2.7.0)(supports-color@11.0.0))(supports-color@11.0.0)(typescript@6.0.3)': + '@typescript-eslint/type-utils@8.67.0(eslint@10.8.1(jiti@2.7.0)(supports-color@11.0.0))(supports-color@11.0.0)(typescript@6.0.3)': dependencies: - '@typescript-eslint/types': 8.66.0 - '@typescript-eslint/typescript-estree': 8.66.0(supports-color@11.0.0)(typescript@6.0.3) - '@typescript-eslint/utils': 8.66.0(eslint@10.8.1(jiti@2.7.0)(supports-color@11.0.0))(supports-color@11.0.0)(typescript@6.0.3) + '@typescript-eslint/types': 8.67.0 + '@typescript-eslint/typescript-estree': 8.67.0(supports-color@11.0.0)(typescript@6.0.3) + '@typescript-eslint/utils': 8.67.0(eslint@10.8.1(jiti@2.7.0)(supports-color@11.0.0))(supports-color@11.0.0)(typescript@6.0.3) debug: 4.4.3(supports-color@11.0.0) eslint: 10.8.1(jiti@2.7.0)(supports-color@11.0.0) ts-api-utils: 2.5.0(typescript@6.0.3) @@ -11277,12 +11282,14 @@ snapshots: '@typescript-eslint/types@8.66.0': {} - '@typescript-eslint/typescript-estree@8.66.0(supports-color@11.0.0)(typescript@6.0.3)': + '@typescript-eslint/types@8.67.0': {} + + '@typescript-eslint/typescript-estree@8.67.0(supports-color@11.0.0)(typescript@6.0.3)': dependencies: - '@typescript-eslint/project-service': 8.66.0(supports-color@11.0.0)(typescript@6.0.3) - '@typescript-eslint/tsconfig-utils': 8.66.0(typescript@6.0.3) - '@typescript-eslint/types': 8.66.0 - '@typescript-eslint/visitor-keys': 8.66.0 + '@typescript-eslint/project-service': 8.67.0(supports-color@11.0.0)(typescript@6.0.3) + '@typescript-eslint/tsconfig-utils': 8.67.0(typescript@6.0.3) + '@typescript-eslint/types': 8.67.0 + '@typescript-eslint/visitor-keys': 8.67.0 debug: 4.4.3(supports-color@11.0.0) minimatch: 10.2.6 semver: 7.8.5 @@ -11292,20 +11299,20 @@ snapshots: transitivePeerDependencies: - supports-color - '@typescript-eslint/utils@8.66.0(eslint@10.8.1(jiti@2.7.0)(supports-color@11.0.0))(supports-color@11.0.0)(typescript@6.0.3)': + '@typescript-eslint/utils@8.67.0(eslint@10.8.1(jiti@2.7.0)(supports-color@11.0.0))(supports-color@11.0.0)(typescript@6.0.3)': dependencies: '@eslint-community/eslint-utils': 4.10.1(eslint@10.8.1(jiti@2.7.0)(supports-color@11.0.0)) - '@typescript-eslint/scope-manager': 8.66.0 - '@typescript-eslint/types': 8.66.0 - '@typescript-eslint/typescript-estree': 8.66.0(supports-color@11.0.0)(typescript@6.0.3) + '@typescript-eslint/scope-manager': 8.67.0 + '@typescript-eslint/types': 8.67.0 + '@typescript-eslint/typescript-estree': 8.67.0(supports-color@11.0.0)(typescript@6.0.3) eslint: 10.8.1(jiti@2.7.0)(supports-color@11.0.0) typescript: 6.0.3 transitivePeerDependencies: - supports-color - '@typescript-eslint/visitor-keys@8.66.0': + '@typescript-eslint/visitor-keys@8.67.0': dependencies: - '@typescript-eslint/types': 8.66.0 + '@typescript-eslint/types': 8.67.0 eslint-visitor-keys: 5.0.1 '@verdaccio/auth@8.1.1(supports-color@11.0.0)': @@ -11471,9 +11478,9 @@ snapshots: lodash: 4.18.1 minimatch: 10.2.5 - '@vitejs/plugin-basic-ssl@2.3.0(vite@8.2.1(@types/node@22.20.1)(esbuild@0.28.2)(jiti@2.7.0)(less@4.8.1(supports-color@11.0.0))(sass@1.102.0)(terser@5.49.2)(tsx@4.23.7)(yaml@2.9.0))': + '@vitejs/plugin-basic-ssl@2.3.0(vite@8.2.1(@types/node@22.20.1)(esbuild@0.28.2)(jiti@2.7.0)(less@4.8.1(supports-color@11.0.0))(sass@1.102.0)(terser@5.50.0)(tsx@4.23.7)(yaml@2.9.0))': dependencies: - vite: 8.2.1(@types/node@22.20.1)(esbuild@0.28.2)(jiti@2.7.0)(less@4.8.1(supports-color@11.0.0))(sass@1.102.0)(terser@5.49.2)(tsx@4.23.7)(yaml@2.9.0) + vite: 8.2.1(@types/node@22.20.1)(esbuild@0.28.2)(jiti@2.7.0)(less@4.8.1(supports-color@11.0.0))(sass@1.102.0)(terser@5.50.0)(tsx@4.23.7)(yaml@2.9.0) '@vitest/coverage-v8@4.1.10(vitest@4.1.10)': dependencies: @@ -11487,7 +11494,7 @@ snapshots: obug: 2.1.4 std-env: 4.2.0 tinyrainbow: 3.1.1 - vitest: 4.1.10(@opentelemetry/api@1.9.1)(@types/node@22.20.1)(@vitest/coverage-v8@4.1.10)(esbuild@0.28.2)(jiti@2.7.0)(jsdom@30.0.1)(less@4.8.1(supports-color@11.0.0))(sass@1.102.0)(terser@5.49.2)(tsx@4.23.7)(yaml@2.9.0) + vitest: 4.1.10(@opentelemetry/api@1.9.1)(@types/node@22.20.1)(@vitest/coverage-v8@4.1.10)(esbuild@0.28.2)(jiti@2.7.0)(jsdom@30.0.1)(less@4.8.1(supports-color@11.0.0))(sass@1.102.0)(terser@5.50.0)(tsx@4.23.7)(yaml@2.9.0) '@vitest/expect@4.1.10': dependencies: @@ -11498,13 +11505,13 @@ snapshots: chai: 6.2.2 tinyrainbow: 3.1.1 - '@vitest/mocker@4.1.10(vite@8.2.1(@types/node@22.20.1)(esbuild@0.28.2)(jiti@2.7.0)(less@4.8.1(supports-color@11.0.0))(sass@1.102.0)(terser@5.49.2)(tsx@4.23.7)(yaml@2.9.0))': + '@vitest/mocker@4.1.10(vite@8.2.1(@types/node@22.20.1)(esbuild@0.28.2)(jiti@2.7.0)(less@4.8.1(supports-color@11.0.0))(sass@1.102.0)(terser@5.50.0)(tsx@4.23.7)(yaml@2.9.0))': dependencies: '@vitest/spy': 4.1.10 estree-walker: 3.0.3 magic-string: 0.30.21 optionalDependencies: - vite: 8.2.1(@types/node@22.20.1)(esbuild@0.28.2)(jiti@2.7.0)(less@4.8.1(supports-color@11.0.0))(sass@1.102.0)(terser@5.49.2)(tsx@4.23.7)(yaml@2.9.0) + vite: 8.2.1(@types/node@22.20.1)(esbuild@0.28.2)(jiti@2.7.0)(less@4.8.1(supports-color@11.0.0))(sass@1.102.0)(terser@5.50.0)(tsx@4.23.7)(yaml@2.9.0) '@vitest/pretty-format@4.1.10': dependencies: @@ -12847,17 +12854,17 @@ snapshots: transitivePeerDependencies: - supports-color - eslint-module-utils@2.14.0(@typescript-eslint/parser@8.66.0(eslint@10.8.1(jiti@2.7.0)(supports-color@11.0.0))(supports-color@11.0.0)(typescript@6.0.3))(eslint-import-resolver-node@0.3.10(supports-color@11.0.0))(eslint@10.8.1(jiti@2.7.0)(supports-color@11.0.0))(supports-color@11.0.0): + eslint-module-utils@2.14.0(@typescript-eslint/parser@8.67.0(eslint@10.8.1(jiti@2.7.0)(supports-color@11.0.0))(supports-color@11.0.0)(typescript@6.0.3))(eslint-import-resolver-node@0.3.10(supports-color@11.0.0))(eslint@10.8.1(jiti@2.7.0)(supports-color@11.0.0))(supports-color@11.0.0): dependencies: debug: 3.2.7(supports-color@11.0.0) optionalDependencies: - '@typescript-eslint/parser': 8.66.0(eslint@10.8.1(jiti@2.7.0)(supports-color@11.0.0))(supports-color@11.0.0)(typescript@6.0.3) + '@typescript-eslint/parser': 8.67.0(eslint@10.8.1(jiti@2.7.0)(supports-color@11.0.0))(supports-color@11.0.0)(typescript@6.0.3) eslint: 10.8.1(jiti@2.7.0)(supports-color@11.0.0) eslint-import-resolver-node: 0.3.10(supports-color@11.0.0) transitivePeerDependencies: - supports-color - eslint-plugin-import@2.32.0(@typescript-eslint/parser@8.66.0(eslint@10.8.1(jiti@2.7.0)(supports-color@11.0.0))(supports-color@11.0.0)(typescript@6.0.3))(eslint@10.8.1(jiti@2.7.0)(supports-color@11.0.0))(supports-color@11.0.0): + eslint-plugin-import@2.32.0(@typescript-eslint/parser@8.67.0(eslint@10.8.1(jiti@2.7.0)(supports-color@11.0.0))(supports-color@11.0.0)(typescript@6.0.3))(eslint@10.8.1(jiti@2.7.0)(supports-color@11.0.0))(supports-color@11.0.0): dependencies: '@rtsao/scc': 1.1.0 array-includes: 3.1.9 @@ -12868,7 +12875,7 @@ snapshots: doctrine: 2.1.0 eslint: 10.8.1(jiti@2.7.0)(supports-color@11.0.0) eslint-import-resolver-node: 0.3.10(supports-color@11.0.0) - eslint-module-utils: 2.14.0(@typescript-eslint/parser@8.66.0(eslint@10.8.1(jiti@2.7.0)(supports-color@11.0.0))(supports-color@11.0.0)(typescript@6.0.3))(eslint-import-resolver-node@0.3.10(supports-color@11.0.0))(eslint@10.8.1(jiti@2.7.0)(supports-color@11.0.0))(supports-color@11.0.0) + eslint-module-utils: 2.14.0(@typescript-eslint/parser@8.67.0(eslint@10.8.1(jiti@2.7.0)(supports-color@11.0.0))(supports-color@11.0.0)(typescript@6.0.3))(eslint-import-resolver-node@0.3.10(supports-color@11.0.0))(eslint@10.8.1(jiti@2.7.0)(supports-color@11.0.0))(supports-color@11.0.0) hasown: 2.0.4 is-core-module: 2.16.2 is-glob: 4.0.3 @@ -12880,7 +12887,7 @@ snapshots: string.prototype.trimend: 1.0.10 tsconfig-paths: 3.15.0 optionalDependencies: - '@typescript-eslint/parser': 8.66.0(eslint@10.8.1(jiti@2.7.0)(supports-color@11.0.0))(supports-color@11.0.0)(typescript@6.0.3) + '@typescript-eslint/parser': 8.67.0(eslint@10.8.1(jiti@2.7.0)(supports-color@11.0.0))(supports-color@11.0.0)(typescript@6.0.3) transitivePeerDependencies: - eslint-import-resolver-typescript - eslint-import-resolver-webpack @@ -13415,7 +13422,7 @@ snapshots: globals@14.0.0: {} - globals@17.9.0: {} + globals@17.11.0: {} globalthis@1.0.4: dependencies: @@ -14383,7 +14390,7 @@ snapshots: dependencies: '@jridgewell/sourcemap-codec': 1.5.5 - magic-string@1.1.0: + magic-string@1.1.1: dependencies: '@jridgewell/sourcemap-codec': 1.5.5 @@ -14495,7 +14502,7 @@ snapshots: '@jridgewell/trace-mapping': 0.3.31 jest-worker: 27.5.1 schema-utils: 4.3.3 - terser: 5.49.2 + terser: 5.50.0 webpack: 5.109.2(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.26)(uglify-js@3.19.3) optionalDependencies: esbuild: 0.28.2 @@ -14508,7 +14515,7 @@ snapshots: '@jridgewell/trace-mapping': 0.3.31 jest-worker: 27.5.1 schema-utils: 4.3.3 - terser: 5.49.2 + terser: 5.50.0 webpack: 5.109.2(esbuild@0.28.2) optionalDependencies: esbuild: 0.28.2 @@ -14525,7 +14532,7 @@ snapshots: mkdirp@1.0.4: {} - modern-tar@0.7.7: {} + modern-tar@0.8.4: {} mrmime@2.0.1: {} @@ -14607,8 +14614,8 @@ snapshots: ora: 9.4.1 piscina: 5.3.0 postcss: 8.5.26 - rolldown: 1.2.3 - rolldown-plugin-dts: 0.27.14(rolldown@1.2.3)(typescript@6.0.3) + rolldown: 1.2.4 + rolldown-plugin-dts: 0.27.14(rolldown@1.2.4)(typescript@6.0.3) rxjs: 7.8.2 sass: 1.102.0 tinyglobby: 0.2.17 @@ -14790,29 +14797,29 @@ snapshots: object-keys: 1.1.1 safe-push-apply: 1.0.0 - oxc-parser@0.143.0: + oxc-parser@0.144.0: dependencies: - '@oxc-project/types': 0.143.0 + '@oxc-project/types': 0.144.0 optionalDependencies: - '@oxc-parser/binding-android-arm-eabi': 0.143.0 - '@oxc-parser/binding-android-arm64': 0.143.0 - '@oxc-parser/binding-darwin-arm64': 0.143.0 - '@oxc-parser/binding-darwin-x64': 0.143.0 - '@oxc-parser/binding-freebsd-x64': 0.143.0 - '@oxc-parser/binding-linux-arm-gnueabihf': 0.143.0 - '@oxc-parser/binding-linux-arm-musleabihf': 0.143.0 - '@oxc-parser/binding-linux-arm64-gnu': 0.143.0 - '@oxc-parser/binding-linux-arm64-musl': 0.143.0 - '@oxc-parser/binding-linux-ppc64-gnu': 0.143.0 - '@oxc-parser/binding-linux-riscv64-gnu': 0.143.0 - '@oxc-parser/binding-linux-riscv64-musl': 0.143.0 - '@oxc-parser/binding-linux-s390x-gnu': 0.143.0 - '@oxc-parser/binding-linux-x64-gnu': 0.143.0 - '@oxc-parser/binding-linux-x64-musl': 0.143.0 - '@oxc-parser/binding-openharmony-arm64': 0.143.0 - '@oxc-parser/binding-win32-arm64-msvc': 0.143.0 - '@oxc-parser/binding-win32-ia32-msvc': 0.143.0 - '@oxc-parser/binding-win32-x64-msvc': 0.143.0 + '@oxc-parser/binding-android-arm-eabi': 0.144.0 + '@oxc-parser/binding-android-arm64': 0.144.0 + '@oxc-parser/binding-darwin-arm64': 0.144.0 + '@oxc-parser/binding-darwin-x64': 0.144.0 + '@oxc-parser/binding-freebsd-x64': 0.144.0 + '@oxc-parser/binding-linux-arm-gnueabihf': 0.144.0 + '@oxc-parser/binding-linux-arm-musleabihf': 0.144.0 + '@oxc-parser/binding-linux-arm64-gnu': 0.144.0 + '@oxc-parser/binding-linux-arm64-musl': 0.144.0 + '@oxc-parser/binding-linux-ppc64-gnu': 0.144.0 + '@oxc-parser/binding-linux-riscv64-gnu': 0.144.0 + '@oxc-parser/binding-linux-riscv64-musl': 0.144.0 + '@oxc-parser/binding-linux-s390x-gnu': 0.144.0 + '@oxc-parser/binding-linux-x64-gnu': 0.144.0 + '@oxc-parser/binding-linux-x64-musl': 0.144.0 + '@oxc-parser/binding-openharmony-arm64': 0.144.0 + '@oxc-parser/binding-win32-arm64-msvc': 0.144.0 + '@oxc-parser/binding-win32-ia32-msvc': 0.144.0 + '@oxc-parser/binding-win32-x64-msvc': 0.144.0 p-finally@1.0.0: {} @@ -15091,9 +15098,9 @@ snapshots: punycode@2.3.1: {} - puppeteer-core@25.5.0(bufferutil@4.1.0)(utf-8-validate@6.0.6): + puppeteer-core@25.6.0(bufferutil@4.1.0)(utf-8-validate@6.0.6): dependencies: - '@puppeteer/browsers': 3.1.0 + '@puppeteer/browsers': 3.2.0 chromium-bidi: 17.0.2(devtools-protocol@0.0.1653615) devtools-protocol: 0.0.1653615 typed-query-selector: 2.12.2 @@ -15105,13 +15112,13 @@ snapshots: - utf-8-validate - yauzl - puppeteer@25.5.0(bufferutil@4.1.0)(utf-8-validate@6.0.6): + puppeteer@25.6.0(bufferutil@4.1.0)(utf-8-validate@6.0.6): dependencies: - '@puppeteer/browsers': 3.1.0 + '@puppeteer/browsers': 3.2.0 chromium-bidi: 17.0.2(devtools-protocol@0.0.1653615) devtools-protocol: 0.0.1653615 lilconfig: 3.1.3 - puppeteer-core: 25.5.0(bufferutil@4.1.0)(utf-8-validate@6.0.6) + puppeteer-core: 25.6.0(bufferutil@4.1.0)(utf-8-validate@6.0.6) typed-query-selector: 2.12.2 transitivePeerDependencies: - bufferutil @@ -15332,12 +15339,12 @@ snapshots: dependencies: glob: 10.5.0 - rolldown-plugin-dts@0.27.14(rolldown@1.2.3)(typescript@6.0.3): + rolldown-plugin-dts@0.27.14(rolldown@1.2.4)(typescript@6.0.3): dependencies: dts-resolver: 3.0.0 get-tsconfig: 5.0.0-beta.5 obug: 2.1.4 - rolldown: 1.2.3 + rolldown: 1.2.4 yuku-ast: 0.8.4 yuku-codegen: 0.8.4 yuku-parser: 0.8.4 @@ -15346,25 +15353,25 @@ snapshots: transitivePeerDependencies: - oxc-resolver - rolldown@1.2.3: + rolldown@1.2.4: dependencies: - '@oxc-project/types': 0.143.0 + '@oxc-project/types': 0.144.0 '@rolldown/pluginutils': 1.0.1 optionalDependencies: - '@rolldown/binding-android-arm64': 1.2.3 - '@rolldown/binding-darwin-arm64': 1.2.3 - '@rolldown/binding-darwin-x64': 1.2.3 - '@rolldown/binding-freebsd-x64': 1.2.3 - '@rolldown/binding-linux-arm-gnueabihf': 1.2.3 - '@rolldown/binding-linux-arm64-gnu': 1.2.3 - '@rolldown/binding-linux-arm64-musl': 1.2.3 - '@rolldown/binding-linux-ppc64-gnu': 1.2.3 - '@rolldown/binding-linux-s390x-gnu': 1.2.3 - '@rolldown/binding-linux-x64-gnu': 1.2.3 - '@rolldown/binding-linux-x64-musl': 1.2.3 - '@rolldown/binding-openharmony-arm64': 1.2.3 - '@rolldown/binding-win32-arm64-msvc': 1.2.3 - '@rolldown/binding-win32-x64-msvc': 1.2.3 + '@rolldown/binding-android-arm64': 1.2.4 + '@rolldown/binding-darwin-arm64': 1.2.4 + '@rolldown/binding-darwin-x64': 1.2.4 + '@rolldown/binding-freebsd-x64': 1.2.4 + '@rolldown/binding-linux-arm-gnueabihf': 1.2.4 + '@rolldown/binding-linux-arm64-gnu': 1.2.4 + '@rolldown/binding-linux-arm64-musl': 1.2.4 + '@rolldown/binding-linux-ppc64-gnu': 1.2.4 + '@rolldown/binding-linux-s390x-gnu': 1.2.4 + '@rolldown/binding-linux-x64-gnu': 1.2.4 + '@rolldown/binding-linux-x64-musl': 1.2.4 + '@rolldown/binding-openharmony-arm64': 1.2.4 + '@rolldown/binding-win32-arm64-msvc': 1.2.4 + '@rolldown/binding-win32-x64-msvc': 1.2.4 rollup-license-plugin@3.2.1: dependencies: @@ -15937,7 +15944,7 @@ snapshots: - bare-abort-controller - react-native-b4a - terser@5.49.2: + terser@5.50.0: dependencies: '@jridgewell/source-map': 0.3.11 acorn: 8.18.0 @@ -16290,12 +16297,12 @@ snapshots: core-util-is: 1.0.2 extsprintf: 1.3.0 - vite@8.2.1(@types/node@22.20.1)(esbuild@0.28.2)(jiti@2.7.0)(less@4.8.1(supports-color@11.0.0))(sass@1.102.0)(terser@5.49.2)(tsx@4.23.7)(yaml@2.9.0): + vite@8.2.1(@types/node@22.20.1)(esbuild@0.28.2)(jiti@2.7.0)(less@4.8.1(supports-color@11.0.0))(sass@1.102.0)(terser@5.50.0)(tsx@4.23.7)(yaml@2.9.0): dependencies: lightningcss: 1.33.0 picomatch: 4.0.5 postcss: 8.5.26 - rolldown: 1.2.3 + rolldown: 1.2.4 tinyglobby: 0.2.17 optionalDependencies: '@types/node': 22.20.1 @@ -16304,14 +16311,14 @@ snapshots: jiti: 2.7.0 less: 4.8.1(supports-color@11.0.0) sass: 1.102.0 - terser: 5.49.2 + terser: 5.50.0 tsx: 4.23.7 yaml: 2.9.0 - vitest@4.1.10(@opentelemetry/api@1.9.1)(@types/node@22.20.1)(@vitest/coverage-v8@4.1.10)(esbuild@0.28.2)(jiti@2.7.0)(jsdom@30.0.1)(less@4.8.1(supports-color@11.0.0))(sass@1.102.0)(terser@5.49.2)(tsx@4.23.7)(yaml@2.9.0): + vitest@4.1.10(@opentelemetry/api@1.9.1)(@types/node@22.20.1)(@vitest/coverage-v8@4.1.10)(esbuild@0.28.2)(jiti@2.7.0)(jsdom@30.0.1)(less@4.8.1(supports-color@11.0.0))(sass@1.102.0)(terser@5.50.0)(tsx@4.23.7)(yaml@2.9.0): dependencies: '@vitest/expect': 4.1.10 - '@vitest/mocker': 4.1.10(vite@8.2.1(@types/node@22.20.1)(esbuild@0.28.2)(jiti@2.7.0)(less@4.8.1(supports-color@11.0.0))(sass@1.102.0)(terser@5.49.2)(tsx@4.23.7)(yaml@2.9.0)) + '@vitest/mocker': 4.1.10(vite@8.2.1(@types/node@22.20.1)(esbuild@0.28.2)(jiti@2.7.0)(less@4.8.1(supports-color@11.0.0))(sass@1.102.0)(terser@5.50.0)(tsx@4.23.7)(yaml@2.9.0)) '@vitest/pretty-format': 4.1.10 '@vitest/runner': 4.1.10 '@vitest/snapshot': 4.1.10 @@ -16328,7 +16335,7 @@ snapshots: tinyexec: 1.3.0 tinyglobby: 0.2.17 tinyrainbow: 3.1.1 - vite: 8.2.1(@types/node@22.20.1)(esbuild@0.28.2)(jiti@2.7.0)(less@4.8.1(supports-color@11.0.0))(sass@1.102.0)(terser@5.49.2)(tsx@4.23.7)(yaml@2.9.0) + vite: 8.2.1(@types/node@22.20.1)(esbuild@0.28.2)(jiti@2.7.0)(less@4.8.1(supports-color@11.0.0))(sass@1.102.0)(terser@5.50.0)(tsx@4.23.7)(yaml@2.9.0) why-is-node-running: 2.3.0 optionalDependencies: '@opentelemetry/api': 1.9.1 From 9dbaf349dd638e89acd4a52219326eaeedad3b67 Mon Sep 17 00:00:00 2001 From: Angular Robot Date: Thu, 13 Aug 2026 10:43:47 +0000 Subject: [PATCH 300/787] build: update pnpm to v11.21.0 See associated pull request for more information. --- MODULE.bazel | 4 ++-- package.json | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/MODULE.bazel b/MODULE.bazel index 705bed3d1bf6..e0443d524d55 100644 --- a/MODULE.bazel +++ b/MODULE.bazel @@ -131,8 +131,8 @@ use_repo( pnpm = use_extension("@aspect_rules_js//npm:extensions.bzl", "pnpm") pnpm.pnpm( name = "pnpm", - pnpm_version = "11.20.0", - pnpm_version_integrity = "sha512-mm8zCpW2ZEbqCI+vFSFAWooB8H/ecSTMmVjf7VLUu0NnN+ZbCPhfN7Rvy6N1CSVYrFEmK4FoRLIvY0Bu0Wa/7g==", + pnpm_version = "11.21.0", + pnpm_version_integrity = "sha512-UhcFvOaJkk6scvWjWHEi82JonvZXHlW6gAdv1jfBETLs/62ib61Op5xIW/3b/T1aKlsFgFp36JPeceyKbMo7sQ==", ) use_repo(pnpm, "pnpm") diff --git a/package.json b/package.json index 91ef1456cb23..d4a9d8d057bc 100644 --- a/package.json +++ b/package.json @@ -28,12 +28,12 @@ "type": "git", "url": "git+https://github.com/angular/angular-cli.git" }, - "packageManager": "pnpm@11.20.0", + "packageManager": "pnpm@11.21.0", "engines": { "node": "^22.22.3 || ^24.15.0 || >=26.0.0", "npm": "Please use pnpm instead of NPM to install dependencies", "yarn": "Please use pnpm instead of Yarn to install dependencies", - "pnpm": "11.20.0" + "pnpm": "11.21.0" }, "author": "Angular Authors", "license": "MIT", From d6fd243207ad1c3e242b8592698afa986320cc6c Mon Sep 17 00:00:00 2001 From: Charles Lyding <19598772+clydin@users.noreply.github.com> Date: Wed, 12 Aug 2026 10:03:48 -0400 Subject: [PATCH 301/787] perf(@angular/build): traverse AST with iterative post-order walker in i18n inliner Replace the oxc-parser Visitor class in the i18n inliner worker with a lightweight, non-recursive post-order AST walker based on visitorKeys. oxc-parser's Visitor class caches visitor callback objects in a module-global array across invocations, which causes all per-request MagicString instances, source code buffers, and diagnostics closures to be retained for the lifetime of the worker thread. In multi-locale builds, this leads to continuous heap accumulation and out-of-memory errors on memory-constrained CI runners. The custom walker uses an iterative two-pass array traversal on the V8 heap to guarantee bottom-up evaluation without recursion or stack overflow risks. This ensures nested $localize template expressions are transformed and written to MagicString before outer templates evaluate their expressions, while eliminating all module-global caching and memory retention across file transformations. --- .../src/tools/esbuild/i18n-inliner-worker.ts | 63 ++++++++++++++++--- .../src/tools/esbuild/i18n-inliner_spec.ts | 21 +++++++ 2 files changed, 76 insertions(+), 8 deletions(-) diff --git a/packages/angular/build/src/tools/esbuild/i18n-inliner-worker.ts b/packages/angular/build/src/tools/esbuild/i18n-inliner-worker.ts index bfec753f6b2d..7d230f479c11 100644 --- a/packages/angular/build/src/tools/esbuild/i18n-inliner-worker.ts +++ b/packages/angular/build/src/tools/esbuild/i18n-inliner-worker.ts @@ -7,11 +7,12 @@ */ import remapping, { type DecodedSourceMap, type SourceMapInput } from '@ampproject/remapping'; +import type { Node } from '@oxc-project/types'; import { MagicString } from 'magic-string'; import assert from 'node:assert'; import { deserialize } from 'node:v8'; import { workerData } from 'node:worker_threads'; -import { Visitor, parseSync } from 'oxc-parser'; +import { parseSync, visitorKeys } from 'oxc-parser'; /** * The options passed to the inliner for each file request @@ -180,6 +181,55 @@ async function loadLocalizeTools(): Promise { return localizeToolsModule; } +/** + * Traverses ESTree AST nodes in post-order (bottom-up) without recursion. + * Bottom-up traversal ensures that nested `$localize` expressions are transformed and + * written to MagicString before outer containing templates are evaluated. + * + * @param root The root AST node to traverse. + * @param onExit Callback invoked on each AST node in post-order. + */ +function walkAstPostOrder(root: Node, onExit: (node: Node) => void): void { + const traverseStack: Node[] = [root]; + const postOrderNodes: Node[] = []; + + while (traverseStack.length > 0) { + const current = traverseStack.pop(); + if (!current) { + continue; + } + + postOrderNodes.push(current); + + const keys = visitorKeys[current.type]; + if (!keys) { + continue; + } + + for (let i = 0; i < keys.length; i++) { + const child = (current as unknown as Record)[keys[i]]; + if (!child) { + continue; + } + + if (Array.isArray(child)) { + for (const item of child) { + if (item) { + traverseStack.push(item); + } + } + } else { + traverseStack.push(child); + } + } + } + + // Process collected nodes in reverse order to achieve bottom-up (post-order) traversal + for (let i = postOrderNodes.length - 1; i >= 0; i--) { + onExit(postOrderNodes[i]); + } +} + /** * Transforms a JavaScript file using OXC and Magic-String to inline the request locale and translation. * @param code A string containing the JavaScript code to transform. @@ -206,13 +256,12 @@ async function transformWithOxc( const { Diagnostics, translate } = await loadLocalizeTools(); const diagnostics = new Diagnostics(); - const visitor = new Visitor({ - Literal(node) { + walkAstPostOrder(program, (node) => { + if (node.type === 'Literal') { if (typeof node.value === 'string' && node.value === '___NG_LOCALE_INSERT___') { magicString.overwrite(node.start, node.end, JSON.stringify(options.locale)); } - }, - 'TaggedTemplateExpression:exit'(node) { + } else if (node.type === 'TaggedTemplateExpression') { if (node.tag.type === 'Identifier' && node.tag.name === '$localize') { const cooked = node.quasi.quasis.map((q) => q.value.cooked); const raw = node.quasi.quasis.map((q) => q.value.raw); @@ -252,11 +301,9 @@ async function transformWithOxc( magicString.overwrite(node.start, node.end, replacement); } - }, + } }); - visitor.visit(program); - const outputCode = magicString.toString(); let outputMap; if (map && magicString.hasChanged()) { diff --git a/packages/angular/build/src/tools/esbuild/i18n-inliner_spec.ts b/packages/angular/build/src/tools/esbuild/i18n-inliner_spec.ts index 67a2fe5883a2..e89acc41c161 100644 --- a/packages/angular/build/src/tools/esbuild/i18n-inliner_spec.ts +++ b/packages/angular/build/src/tools/esbuild/i18n-inliner_spec.ts @@ -274,4 +274,25 @@ describe('I18nInliner', () => { expect(findFile(outputFiles, 'other.js').text).toBe('export const answer = 42;\n'); }); + + it('inlines nested $localize calls in post-order', async () => { + const source = + 'export const msg = $localize`:@@outer:You selected ${$localize`:@@inner:Apple`} for delivery.`;\n'; + const { outputFiles, errors, warnings } = await createInliner([ + browserFile('main.js', source), + ]).inlineForLocale('fr', { + inner: translationFor('Pomme'), + outer: { + messageParts: ['Vous avez sélectionné ', ' pour la livraison.'], + placeholderNames: ['PH'], + text: 'Vous avez sélectionné {$PH} pour la livraison.', + }, + }); + + expect(errors).toEqual([]); + expect(warnings).toEqual([]); + expect(findFile(outputFiles, 'main.js').text).toBe( + 'export const msg = `Vous avez sélectionné ${"Pomme"} pour la livraison.`;\n', + ); + }); }); From 8d731ec4465f6d65a29817680ecb29f507ba588f Mon Sep 17 00:00:00 2001 From: Angular Robot Date: Thu, 13 Aug 2026 06:51:32 +0000 Subject: [PATCH 302/787] build: update bazel dependencies See associated pull request for more information. --- MODULE.bazel | 8 ++++---- MODULE.bazel.lock | 30 ++++++++++++++++++------------ 2 files changed, 22 insertions(+), 16 deletions(-) diff --git a/MODULE.bazel b/MODULE.bazel index e0443d524d55..13363a8bf513 100644 --- a/MODULE.bazel +++ b/MODULE.bazel @@ -7,14 +7,14 @@ module( bazel_dep(name = "platforms", version = "1.1.0") bazel_dep(name = "yq.bzl", version = "0.3.6") bazel_dep(name = "rules_nodejs", version = "6.7.5") -bazel_dep(name = "aspect_rules_js", version = "3.3.1") -bazel_dep(name = "aspect_rules_ts", version = "3.9.2") -bazel_dep(name = "rules_pkg", version = "1.2.0") +bazel_dep(name = "aspect_rules_js", version = "3.4.0") +bazel_dep(name = "aspect_rules_ts", version = "3.10.0") +bazel_dep(name = "rules_pkg", version = "1.3.0") bazel_dep(name = "rules_cc", version = "0.2.22") bazel_dep(name = "jq.bzl", version = "0.6.1") bazel_dep(name = "bazel_lib", version = "3.7.1") bazel_dep(name = "bazel_skylib", version = "1.9.2") -bazel_dep(name = "aspect_rules_esbuild", version = "0.26.0") +bazel_dep(name = "aspect_rules_esbuild", version = "0.27.0") bazel_dep(name = "aspect_rules_jasmine", version = "2.0.4") bazel_dep(name = "rules_angular") git_override( diff --git a/MODULE.bazel.lock b/MODULE.bazel.lock index 6c81cac53afa..4542fcb3d759 100644 --- a/MODULE.bazel.lock +++ b/MODULE.bazel.lock @@ -19,15 +19,18 @@ "https://bcr.bazel.build/modules/aspect_bazel_lib/2.7.7/MODULE.bazel": "491f8681205e31bb57892d67442ce448cda4f472a8e6b3dc062865e29a64f89c", "https://bcr.bazel.build/modules/aspect_bazel_lib/2.8.1/MODULE.bazel": "812d2dd42f65dca362152101fbec418029cc8fd34cbad1a2fde905383d705838", "https://bcr.bazel.build/modules/aspect_rules_esbuild/0.26.0/MODULE.bazel": "6c902d97038c3ab07b6c4e67c97abc61b20182fcfa84fa7dee82fc724f12e455", - "https://bcr.bazel.build/modules/aspect_rules_esbuild/0.26.0/source.json": "4cc3ece7ab661bb391a9e24fe55c4b567d60a9ea9d9e91d772dad373cbcb6217", + "https://bcr.bazel.build/modules/aspect_rules_esbuild/0.27.0/MODULE.bazel": "877dafc0b925f8af19e8bc2abed04a757bb565c57c1866e8851ac4d15ed5e6d2", + "https://bcr.bazel.build/modules/aspect_rules_esbuild/0.27.0/source.json": "21f8738b3e62310ef43b7cef4284e1bafd69bd8e4e50251b71b20bbfed4372d8", "https://bcr.bazel.build/modules/aspect_rules_jasmine/2.0.4/MODULE.bazel": "fbb819eb8b7e5d7f67fdd38f7cecb413e287594cd666ce192c72c8828527775a", "https://bcr.bazel.build/modules/aspect_rules_jasmine/2.0.4/source.json": "81ffb708333cd98ec3c0b4cc004f4d5cf92a16914b5196a2892c45141bba7cff", "https://bcr.bazel.build/modules/aspect_rules_js/2.0.0/MODULE.bazel": "b45b507574aa60a92796e3e13c195cd5744b3b8aff516a9c0cb5ae6a048161c5", "https://bcr.bazel.build/modules/aspect_rules_js/3.0.3/MODULE.bazel": "28a30e8fc33bf64a67835d64d124f6e05a7d59648dcb27b110fb3502f761e503", "https://bcr.bazel.build/modules/aspect_rules_js/3.3.1/MODULE.bazel": "3e02b51b503ba8dda69b043290f6cc11add9aeb8db0bf1f6c861c396c7ddc5b2", - "https://bcr.bazel.build/modules/aspect_rules_js/3.3.1/source.json": "d5e0736539b00bdd33015bb336877ad5a4d16f1d1d4af13ffeade395106cabd7", + "https://bcr.bazel.build/modules/aspect_rules_js/3.4.0/MODULE.bazel": "88844ac411e1961f4574a92f3c5be5b20d1c6997778c6b88316c5c3b4b60e284", + "https://bcr.bazel.build/modules/aspect_rules_js/3.4.0/source.json": "85e5822f00dcbe64a1eda1324119e289c8c03cacb5c3695dffee16397b529078", + "https://bcr.bazel.build/modules/aspect_rules_ts/3.10.0/MODULE.bazel": "69d06f57f30f4a2b6e53471584a9559d3b7cd7f891e1699876991230c7cabb95", + "https://bcr.bazel.build/modules/aspect_rules_ts/3.10.0/source.json": "56f28a3ddb55ceaaf57a1ef8d7195136789ca1d72d0c8a6a9eeaad313be4099d", "https://bcr.bazel.build/modules/aspect_rules_ts/3.9.2/MODULE.bazel": "feeb6c45b69c995eca3e5ca5872658c80df658022e01044eca00cf472bb89142", - "https://bcr.bazel.build/modules/aspect_rules_ts/3.9.2/source.json": "cf3075502f798f71a9c5707a7684eaf0b86da11ed440fd90ea34385dc297676a", "https://bcr.bazel.build/modules/aspect_tools_telemetry/0.2.8/MODULE.bazel": "aa975a83e72bcaac62ee61ab12b788ea324a1d05c4aab28aadb202f647881679", "https://bcr.bazel.build/modules/aspect_tools_telemetry/0.3.3/MODULE.bazel": "37c764292861c2f70314efa9846bb6dbb44fc0308903b3285da6528305450183", "https://bcr.bazel.build/modules/aspect_tools_telemetry/0.4.2/MODULE.bazel": "f31aa84151d31e98cffd43eb7217ccff5ec52bdd5f2d10db8f053aeb23342eca", @@ -52,6 +55,7 @@ "https://bcr.bazel.build/modules/bazel_lib/3.0.0-rc.0/MODULE.bazel": "d6e00979a98ac14ada5e31c8794708b41434d461e7e7ca39b59b765e6d233b18", "https://bcr.bazel.build/modules/bazel_lib/3.0.0/MODULE.bazel": "22b70b80ac89ad3f3772526cd9feee2fa412c2b01933fea7ed13238a448d370d", "https://bcr.bazel.build/modules/bazel_lib/3.2.2/MODULE.bazel": "e2c890c8a515d6bca9c66d47718aa9e44b458fde64ec7204b8030bf2d349058c", + "https://bcr.bazel.build/modules/bazel_lib/3.7.0/MODULE.bazel": "d7c10ed67f0f7f1fda179db8f86c22642581bd614882e1a50545fbe069525173", "https://bcr.bazel.build/modules/bazel_lib/3.7.1/MODULE.bazel": "b6fd9b2f8fab956420c11836f416efac4a70e20804ae384ebe62773a4ed70046", "https://bcr.bazel.build/modules/bazel_lib/3.7.1/source.json": "635fdaa28b50c04febc5e60ef51bc913d3bc87bfbaac7045449273c2341648cb", "https://bcr.bazel.build/modules/bazel_skylib/1.0.3/MODULE.bazel": "bcb0fd896384802d1ad283b4e4eb4d718eebd8cb820b0a2c3a347fb971afd9d8", @@ -68,6 +72,7 @@ "https://bcr.bazel.build/modules/bazel_skylib/1.8.0/MODULE.bazel": "2fb3fb53675f6adfc1ca5bfbd5cfb655ae350fba4706d924a8ec7e3ba945671c", "https://bcr.bazel.build/modules/bazel_skylib/1.8.1/MODULE.bazel": "88ade7293becda963e0e3ea33e7d54d3425127e0a326e0d17da085a5f1f03ff6", "https://bcr.bazel.build/modules/bazel_skylib/1.8.2/MODULE.bazel": "69ad6927098316848b34a9142bcc975e018ba27f08c4ff403f50c1b6e646ca67", + "https://bcr.bazel.build/modules/bazel_skylib/1.9.0/MODULE.bazel": "72997b29dfd95c3fa0d0c48322d05590418edef451f8db8db5509c57875fb4b7", "https://bcr.bazel.build/modules/bazel_skylib/1.9.2/MODULE.bazel": "8c51259b0f4481475586dbfede7591e57b75702e637f840f6138eec80c34b270", "https://bcr.bazel.build/modules/bazel_skylib/1.9.2/source.json": "41cbde7546542dee2f26e3f10bf1c4ac57909943194b7ac48cc5238a01893aa8", "https://bcr.bazel.build/modules/buildozer/7.1.2/MODULE.bazel": "2e8dd40ede9c454042645fd8d8d0cd1527966aa5c919de86661e62953cd73d84", @@ -171,7 +176,8 @@ "https://bcr.bazel.build/modules/rules_pkg/0.7.0/MODULE.bazel": "df99f03fc7934a4737122518bb87e667e62d780b610910f0447665a7e2be62dc", "https://bcr.bazel.build/modules/rules_pkg/1.0.1/MODULE.bazel": "5b1df97dbc29623bccdf2b0dcd0f5cb08e2f2c9050aab1092fd39a41e82686ff", "https://bcr.bazel.build/modules/rules_pkg/1.2.0/MODULE.bazel": "c7db3c2b407e673c7a39e3625dc05dc9f12d6682cbd82a3a5924a13b491eda7e", - "https://bcr.bazel.build/modules/rules_pkg/1.2.0/source.json": "9062e00845bf91a4247465d371baa837adf9b6ff44c542f73ba084f07667e1dc", + "https://bcr.bazel.build/modules/rules_pkg/1.3.0/MODULE.bazel": "ae0bdefbacc990c91f843206c90cf0f4be620639a5bf22119043599ba86d51a3", + "https://bcr.bazel.build/modules/rules_pkg/1.3.0/source.json": "58ae84c545141762f7c434c0ce78bfb55ef0be08d84863e7f0503fff135fe4e2", "https://bcr.bazel.build/modules/rules_proto/4.0.0/MODULE.bazel": "a7a7b6ce9bee418c1a760b3d84f83a299ad6952f9903c67f19e4edd964894e06", "https://bcr.bazel.build/modules/rules_proto/5.3.0-21.7/MODULE.bazel": "e8dff86b0971688790ae75528fe1813f71809b5afd57facb44dad9e8eca631b7", "https://bcr.bazel.build/modules/rules_proto/6.0.0/MODULE.bazel": "b531d7f09f58dce456cd61b4579ce8c86b38544da75184eadaf0a7cb7966453f", @@ -222,8 +228,8 @@ "moduleExtensions": { "@@aspect_rules_esbuild+//esbuild:extensions.bzl%esbuild": { "general": { - "bzlTransitiveDigest": "DfFT9JjdwDXEFWTCpbJTMqiSwGOU02Jq1C1XgMbRhec=", - "usagesDigest": "LSQ+zZp7JNgnBONTxxXnwGr4NTh2qtQYk7qwXXz5qWo=", + "bzlTransitiveDigest": "eGsGosHZTHOEZx11j7nDLNMHxCkESoe1oypcL3+G6GI=", + "usagesDigest": "LZ71sshnfqI8R/HeWwBTwawxIa7KnitayBl2hYrqPo4=", "recordedFileInputs": {}, "recordedDirentsInputs": {}, "envVariables": {}, @@ -438,7 +444,7 @@ "@@aspect_tools_telemetry+//:extension.bzl%telemetry": { "general": { "bzlTransitiveDigest": "4w9RM0xjdKo1crk5zL20a/TuhqO0P1z1LsuXDneBXD4=", - "usagesDigest": "q7mSkkDF8zaV9mtEPYuvConVymuL69UDTnd+J5Pgo0w=", + "usagesDigest": "VoGyqZ+r/3juGZUfSXD4FAe965Z3XS4WANRrYH79+1Q=", "recordedFileInputs": {}, "recordedDirentsInputs": {}, "envVariables": { @@ -449,13 +455,13 @@ "repoRuleId": "@@aspect_tools_telemetry+//:extension.bzl%tel_repository", "attributes": { "deps": { - "aspect_rules_js": "3.3.1", - "aspect_rules_ts": "3.9.2", - "aspect_rules_esbuild": "0.26.0", + "aspect_rules_js": "3.4.0", + "aspect_rules_ts": "3.10.0", + "aspect_rules_esbuild": "0.27.0", "aspect_rules_jasmine": "2.0.4", "aspect_tools_telemetry": "0.4.2" }, - "last_notice": 0 + "last_notice": 1 } } }, @@ -1175,7 +1181,7 @@ "@@yq.bzl+//yq:extensions.bzl%yq": { "general": { "bzlTransitiveDigest": "UfFMy8CWK4/dVo/tfaSAIYUiDGNAPes5eRllx9O9Q9Q=", - "usagesDigest": "hKjC8oZmSZDlZ1NsPZgCEomqFtqBXEQo88wUuHfg4F4=", + "usagesDigest": "9kbJ6OfvQpAM3otgkGgS5xpOHOoVgV5ZJ9jSgMgUG2g=", "recordedFileInputs": {}, "recordedDirentsInputs": {}, "envVariables": {}, From 7946e22b76d470c992b4f19b7e3396f86430a96d Mon Sep 17 00:00:00 2001 From: Charles Lyding <19598772+clydin@users.noreply.github.com> Date: Thu, 13 Aug 2026 15:59:58 -0400 Subject: [PATCH 303/787] refactor(@angular/build): separate metadata extraction in i18n inliner worker Separate the AST parsing and call-site collection from the inlining transformation in `i18n-inliner-worker.ts`. Introducing `extractLocalizeMetadata` and `inlineLocalize` establishes the foundation for caching file metadata and reusing AST information across multiple locales in subsequent changes. --- .../src/tools/esbuild/i18n-inliner-worker.ts | 203 +++++++++++++----- .../src/tools/esbuild/i18n-inliner_spec.ts | 12 ++ 2 files changed, 162 insertions(+), 53 deletions(-) diff --git a/packages/angular/build/src/tools/esbuild/i18n-inliner-worker.ts b/packages/angular/build/src/tools/esbuild/i18n-inliner-worker.ts index 7d230f479c11..17f2424407a4 100644 --- a/packages/angular/build/src/tools/esbuild/i18n-inliner-worker.ts +++ b/packages/angular/build/src/tools/esbuild/i18n-inliner-worker.ts @@ -231,79 +231,157 @@ function walkAstPostOrder(root: Node, onExit: (node: Node) => void): void { } /** - * Transforms a JavaScript file using OXC and Magic-String to inline the request locale and translation. - * @param code A string containing the JavaScript code to transform. - * @param map A sourcemap object for the provided JavaScript code. - * @param options The inline request options to use. - * @param translation The translation messages to inline, or undefined for an untranslated locale. - * @returns An object containing the code, map, and diagnostics from the transformation. + * Metadata for a `$localize` tagged template expression extracted from the AST. */ -async function transformWithOxc( - code: string, - map: SourceMapInput | undefined, - options: InlineFileRequest, - translation: Record | undefined, -) { - const { program } = parseSync(options.filename, code, { +interface LocalizeCallSite { + start: number; + end: number; + messageParts: TemplateStringsArray; + expressions: { start: number; end: number }[]; +} + +/** + * Metadata extracted from a JavaScript file AST needed for localization inlining. + */ +interface FileLocalizeMetadata { + callSites: LocalizeCallSite[]; + localeInsertSites: { start: number; end: number }[]; + diagnostics?: string[]; +} + +/** + * Extracts localization call sites and locale insertion points from JavaScript code using OXC. + * + * @param filename The name of the file being processed. + * @param code The JavaScript source code. + * @returns The extracted localization metadata. + */ +function extractLocalizeMetadata(filename: string, code: string): FileLocalizeMetadata { + const { program } = parseSync(filename, code, { sourceType: 'unambiguous', }); if (!program) { - throw new Error(`Unknown error occurred parsing file "${options.filename}" with OXC.`); + throw new Error(`Unknown error occurred parsing file "${filename}" with OXC.`); } - const magicString = new MagicString(code); - const { Diagnostics, translate } = await loadLocalizeTools(); - const diagnostics = new Diagnostics(); + const callSites: LocalizeCallSite[] = []; + const localeInsertSites: { start: number; end: number }[] = []; + let diagnostics: string[] | undefined; walkAstPostOrder(program, (node) => { if (node.type === 'Literal') { if (typeof node.value === 'string' && node.value === '___NG_LOCALE_INSERT___') { - magicString.overwrite(node.start, node.end, JSON.stringify(options.locale)); + localeInsertSites.push({ start: node.start, end: node.end }); } } else if (node.type === 'TaggedTemplateExpression') { if (node.tag.type === 'Identifier' && node.tag.name === '$localize') { - const cooked = node.quasi.quasis.map((q) => q.value.cooked); - const raw = node.quasi.quasis.map((q) => q.value.raw); - const messageParts = Object.assign(cooked, { raw }) as unknown as TemplateStringsArray; - - const [translatedParts, translatedSubstitutions] = translate( - diagnostics, - translation || {}, - messageParts, - node.quasi.expressions.map((_, index) => index), - translation === undefined ? 'ignore' : missingTranslation, - ); - - // Reconstruct the new template/string literal replacement - let replacement: string; - if (translatedSubstitutions.length === 0) { - replacement = JSON.stringify(translatedParts[0]); - } else { - replacement = '`'; - for (let i = 0; i < translatedParts.length; i++) { - const escapedPart = JSON.stringify(translatedParts[i]) - .slice(1, -1) - .replace(/\\"/g, '"') - .replace(/`/g, '\\`') - .replace(/\$\{/g, '\\${'); - replacement += escapedPart; - - if (i < translatedSubstitutions.length) { - const originalIndex = translatedSubstitutions[i]; - const exprNode = node.quasi.expressions[originalIndex]; - const exprCode = magicString.slice(exprNode.start, exprNode.end); - replacement += '${' + exprCode + '}'; - } + const cooked: string[] = []; + const raw: string[] = []; + let hasMalformedEscape = false; + + for (const q of node.quasi.quasis) { + if (q.value.cooked === null || q.value.cooked === undefined) { + hasMalformedEscape = true; + (diagnostics ??= []).push( + `Malformed escape sequence in $localize template literal in file "${filename}".`, + ); + break; } - replacement += '`'; + cooked.push(q.value.cooked); + raw.push(q.value.raw); } - magicString.overwrite(node.start, node.end, replacement); + if (!hasMalformedEscape) { + const messageParts = Object.assign(cooked, { raw }); + const expressions = node.quasi.expressions.map((expr) => ({ + start: expr.start, + end: expr.end, + })); + + callSites.push({ + start: node.start, + end: node.end, + messageParts, + expressions, + }); + } } } }); + return { callSites, localeInsertSites, diagnostics }; +} + +/** + * Inlines translations into code using previously extracted localization metadata. + * + * @param code The source code to transform. + * @param map Optional source map for the source code. + * @param metadata Extracted localization metadata. + * @param locale The target locale identifier. + * @param translation The translation messages dictionary, or undefined for untranslated locale. + * @param filename The name of the file being transformed. + * @returns The transformed code, optional remapped source map, and diagnostics. + */ +async function inlineLocalize( + code: string, + map: SourceMapInput | undefined, + metadata: FileLocalizeMetadata, + locale: string, + translation: Record | undefined, + filename: string, +) { + const magicString = new MagicString(code); + const { Diagnostics, translate } = await loadLocalizeTools(); + const diagnostics = new Diagnostics(); + + if (metadata.diagnostics) { + for (const message of metadata.diagnostics) { + diagnostics.error(message); + } + } + + for (const site of metadata.localeInsertSites) { + magicString.overwrite(site.start, site.end, JSON.stringify(locale)); + } + + for (const callSite of metadata.callSites) { + const [translatedParts, translatedSubstitutions] = translate( + diagnostics, + translation || {}, + callSite.messageParts, + callSite.expressions.map((_, index) => index), + translation === undefined ? 'ignore' : missingTranslation, + ); + + // Reconstruct the new template/string literal replacement + let replacement: string; + if (translatedSubstitutions.length === 0) { + replacement = JSON.stringify(translatedParts[0]); + } else { + replacement = '`'; + for (let i = 0; i < translatedParts.length; i++) { + const escapedPart = JSON.stringify(translatedParts[i]) + .slice(1, -1) + .replace(/\\"/g, '"') + .replace(/`/g, '\\`') + .replace(/\$\{/g, '\\${'); + replacement += escapedPart; + + if (i < translatedSubstitutions.length) { + const originalIndex = translatedSubstitutions[i]; + const expr = callSite.expressions[originalIndex]; + const exprCode = magicString.slice(expr.start, expr.end); + replacement += '${' + exprCode + '}'; + } + } + replacement += '`'; + } + + magicString.overwrite(callSite.start, callSite.end, replacement); + } + const outputCode = magicString.toString(); let outputMap; if (map && magicString.hasChanged()) { @@ -311,7 +389,7 @@ async function transformWithOxc( // inputs. Encoding the mappings only for remapping to immediately decode them again doubles // the peak memory of the largest structure involved in inlining a file. const rawMap = magicString.generateDecodedMap({ - source: options.filename, + source: filename, includeContent: true, hires: 'boundary', }); @@ -324,3 +402,22 @@ async function transformWithOxc( diagnostics, }; } + +/** + * Transforms a JavaScript file using OXC and Magic-String to inline the request locale and translation. + * @param code A string containing the JavaScript code to transform. + * @param map A sourcemap object for the provided JavaScript code. + * @param options The inline request options to use. + * @param translation The translation messages to inline, or undefined for an untranslated locale. + * @returns An object containing the code, map, and diagnostics from the transformation. + */ +async function transformWithOxc( + code: string, + map: SourceMapInput | undefined, + options: InlineFileRequest | InlineCodeRequest, + translation: Record | undefined, +) { + const metadata = extractLocalizeMetadata(options.filename, code); + + return inlineLocalize(code, map, metadata, options.locale, translation, options.filename); +} diff --git a/packages/angular/build/src/tools/esbuild/i18n-inliner_spec.ts b/packages/angular/build/src/tools/esbuild/i18n-inliner_spec.ts index e89acc41c161..609774ced508 100644 --- a/packages/angular/build/src/tools/esbuild/i18n-inliner_spec.ts +++ b/packages/angular/build/src/tools/esbuild/i18n-inliner_spec.ts @@ -295,4 +295,16 @@ describe('I18nInliner', () => { 'export const msg = `Vous avez sélectionné ${"Pomme"} pour la livraison.`;\n', ); }); + + it('reports an error diagnostic when a $localize template has a malformed escape sequence', async () => { + const source = 'export const msg = $localize`:@@id:\\unicode:`;\n'; + const { errors } = await createInliner([browserFile('main.js', source)]).inlineForLocale( + 'fr', + {}, + ); + + expect(errors).toEqual([ + 'Malformed escape sequence in $localize template literal in file "main.js".', + ]); + }); }); From 359d09c0060fe95c44d15f49a764a2028aa0fc7e Mon Sep 17 00:00:00 2001 From: Charles Lyding <19598772+clydin@users.noreply.github.com> Date: Thu, 13 Aug 2026 17:45:38 -0400 Subject: [PATCH 304/787] refactor(@angular/build): decouple compilation abstraction from TypeScript Decouple the AngularCompilation base class and related compilation interfaces from TypeScript-specific AST types (ts.SourceFile) and diagnostics, allowing non-TypeScript and on-demand preprocessor/transformer compilation implementations. This introduces AngularCompilationResult, AngularCompilationOptions, and FileTransformResult while making collectDiagnostics optional on AngularCompilation so that non-TypeScript compilations can bypass TypeScript diagnostic loading. An optional transformFile hook is also added to AngularCompilation for on-demand transformation during bundling, and createCompilerPlugin is updated to support on-demand streaming transforms in build.onLoad while skipping upfront emit in build.onStart. AotCompilation, JitCompilation, NoopCompilation, and ParallelCompilation are updated to conform to AngularCompilationResult, and createAngularCompilation now supports explicit compilation modes. --- .../compilation/angular-compilation.ts | 54 ++++++--- .../compilation/angular-compilation_spec.ts | 109 ++++++++++++++++++ .../angular/compilation/aot-compilation.ts | 21 ++-- .../src/tools/angular/compilation/factory.ts | 19 ++- .../src/tools/angular/compilation/index.ts | 11 +- .../angular/compilation/jit-compilation.ts | 19 +-- .../angular/compilation/noop-compilation.ts | 15 +-- .../compilation/parallel-compilation.ts | 15 ++- .../angular/compilation/parallel-worker.ts | 8 +- .../tools/esbuild/angular/compiler-plugin.ts | 69 ++++++++--- 10 files changed, 260 insertions(+), 80 deletions(-) create mode 100644 packages/angular/build/src/tools/angular/compilation/angular-compilation_spec.ts diff --git a/packages/angular/build/src/tools/angular/compilation/angular-compilation.ts b/packages/angular/build/src/tools/angular/compilation/angular-compilation.ts index 00a17ccc453e..4c17bb6e60de 100644 --- a/packages/angular/build/src/tools/angular/compilation/angular-compilation.ts +++ b/packages/angular/build/src/tools/angular/compilation/angular-compilation.ts @@ -19,6 +19,28 @@ export interface EmitFileResult { dependencies?: readonly string[]; } +export interface FileTransformResult { + contents: string; + watchFiles?: readonly string[]; +} + +export interface AngularCompilationOptions { + allowJs?: boolean; + isolatedModules?: boolean; + sourceMap?: boolean; + inlineSourceMap?: boolean; + _useTypeScriptTranspilation?: boolean; + [key: string]: unknown; +} + +export interface AngularCompilationResult { + compilerOptions: AngularCompilationOptions; + referencedFiles: readonly string[]; + externalStylesheets?: ReadonlyMap; + templateUpdates?: ReadonlyMap; + componentResourcesDependencies?: ReadonlyMap; +} + export enum DiagnosticModes { None = 0, Option = 1 << 0, @@ -70,24 +92,25 @@ export abstract class AngularCompilation { tsconfig: string, hostOptions: AngularHostOptions, compilerOptionsTransformer?: (compilerOptions: ng.CompilerOptions) => ng.CompilerOptions, - ): Promise<{ - affectedFiles: ReadonlySet; - compilerOptions: ng.CompilerOptions; - referencedFiles: readonly string[]; - externalStylesheets?: ReadonlyMap; - templateUpdates?: ReadonlyMap; - componentResourcesDependencies?: ReadonlyMap; - }>; - - abstract emitAffectedFiles(): Iterable | Promise>; - - protected abstract collectDiagnostics( + ): Promise; + + emitAffectedFiles(): Iterable | Promise> { + return []; + } + + transformFile?(filename: string, content: string): Promise; + + protected collectDiagnostics?( modes: DiagnosticModes, ): Iterable | Promise>; async diagnoseFiles( modes = DiagnosticModes.All, ): Promise<{ errors?: PartialMessage[]; warnings?: PartialMessage[] }> { + if (!this.collectDiagnostics) { + return {}; + } + const result: { errors?: PartialMessage[]; warnings?: PartialMessage[] } = {}; // Avoid loading typescript until actually needed. @@ -95,7 +118,12 @@ export abstract class AngularCompilation { const typescript = await AngularCompilation.loadTypescript(); await profileAsync('NG_DIAGNOSTICS_TOTAL', async () => { - for (const diagnostic of await this.collectDiagnostics(modes)) { + const diagnostics = await this.collectDiagnostics?.(modes); + if (!diagnostics) { + return; + } + + for (const diagnostic of diagnostics) { const message = convertTypeScriptDiagnostic(typescript, diagnostic); if (diagnostic.category === typescript.DiagnosticCategory.Error) { (result.errors ??= []).push(message); diff --git a/packages/angular/build/src/tools/angular/compilation/angular-compilation_spec.ts b/packages/angular/build/src/tools/angular/compilation/angular-compilation_spec.ts new file mode 100644 index 000000000000..a9e93b701e5f --- /dev/null +++ b/packages/angular/build/src/tools/angular/compilation/angular-compilation_spec.ts @@ -0,0 +1,109 @@ +/** + * @license + * Copyright Google LLC All Rights Reserved. + * + * Use of this source code is governed by an MIT-style license that can be + * found in the LICENSE file at https://angular.dev/license + */ + +import type { AngularHostOptions } from '../angular-host'; +import { + AngularCompilation, + AngularCompilationResult, + NoopCompilation, + createAngularCompilation, +} from './index'; + +describe('AngularCompilation', () => { + class CustomTransformCompilation extends AngularCompilation { + override async initialize(): Promise { + return { + compilerOptions: { allowJs: false }, + referencedFiles: ['/src/main.ts'], + }; + } + + override async transformFile(filename: string, content: string) { + if (filename.endsWith('.ts')) { + return { + contents: content + '\n// transformed', + watchFiles: ['/src/dep.ts'], + }; + } + + return null; + } + } + + it('allows implementing on-demand transformFile without collectDiagnostics', async () => { + const compilation = new CustomTransformCompilation(); + const initResult = await compilation.initialize(); + + expect(initResult.referencedFiles).toEqual(['/src/main.ts']); + expect(initResult.compilerOptions.allowJs).toBe(false); + + const transformResult = await compilation.transformFile?.( + '/src/main.ts', + 'console.log("hello");', + ); + expect(transformResult).toEqual({ + contents: 'console.log("hello");\n// transformed', + watchFiles: ['/src/dep.ts'], + }); + + const diagnostics = await compilation.diagnoseFiles(); + expect(diagnostics).toEqual({}); + }); + + describe('NoopCompilation', () => { + it('initializes with empty referencedFiles and compiler options', async () => { + const compilation = new NoopCompilation(); + const mockHostOptions = {} as AngularHostOptions; + const result = await compilation.initialize('tsconfig.json', mockHostOptions, (opts) => ({ + ...opts, + customOption: true, + })); + + expect(result.referencedFiles).toEqual([]); + expect(result.compilerOptions['customOption']).toBe(true); + }); + + it('throws when calling collectDiagnostics or emitAffectedFiles', () => { + const compilation = new NoopCompilation(); + expect(() => + (compilation as unknown as { collectDiagnostics(): unknown }).collectDiagnostics(), + ).toThrowError('Not available when using noop compilation.'); + expect(() => compilation.emitAffectedFiles()).toThrowError( + 'Not available when using noop compilation.', + ); + }); + }); + + describe('createAngularCompilation', () => { + it('creates JitCompilation when mode is "jit"', async () => { + const compilation = await createAngularCompilation('jit', true, false); + expect(compilation.constructor.name).toBe('JitCompilation'); + }); + + it('creates AotCompilation when mode is "aot"', async () => { + const compilation = await createAngularCompilation('aot', true, false); + expect(compilation.constructor.name).toBe('AotCompilation'); + }); + + it('creates JitCompilation when mode is boolean true (legacy)', async () => { + const compilation = await createAngularCompilation(true, true, false); + expect(compilation.constructor.name).toBe('JitCompilation'); + }); + + it('creates AotCompilation when mode is boolean false (legacy)', async () => { + const compilation = await createAngularCompilation(false, true, false); + expect(compilation.constructor.name).toBe('AotCompilation'); + }); + + it('throws when mode is "transform"', async () => { + await expectAsync(createAngularCompilation('transform', true, false)).toBeRejectedWithError( + 'Transform compilation mode is not supported.', + ); + }); + }); +}); diff --git a/packages/angular/build/src/tools/angular/compilation/aot-compilation.ts b/packages/angular/build/src/tools/angular/compilation/aot-compilation.ts index cd4e1cdae7dd..61a9e4949fd4 100644 --- a/packages/angular/build/src/tools/angular/compilation/aot-compilation.ts +++ b/packages/angular/build/src/tools/angular/compilation/aot-compilation.ts @@ -20,7 +20,12 @@ import { import { replaceBootstrap } from '../transformers/jit-bootstrap-transformer'; import { lazyRoutesTransformer } from '../transformers/lazy-routes-transformer'; import { createWorkerTransformer } from '../transformers/web-worker-transformer'; -import { AngularCompilation, DiagnosticModes, EmitFileResult } from './angular-compilation'; +import { + AngularCompilation, + AngularCompilationResult, + DiagnosticModes, + EmitFileResult, +} from './angular-compilation'; import { collectHmrCandidates } from './hmr-candidates'; import { printSourceFileWithMap } from './typescript-printer'; @@ -59,14 +64,7 @@ export class AotCompilation extends AngularCompilation { tsconfig: string, hostOptions: AngularHostOptions, compilerOptionsTransformer?: (compilerOptions: ng.CompilerOptions) => ng.CompilerOptions, - ): Promise<{ - affectedFiles: ReadonlySet; - compilerOptions: ng.CompilerOptions; - referencedFiles: readonly string[]; - externalStylesheets?: ReadonlyMap; - templateUpdates?: ReadonlyMap; - componentResourcesDependencies?: ReadonlyMap; - }> { + ): Promise { // Dynamically load the Angular compiler CLI package const { NgtscProgram, OptimizeFor } = await AngularCompilation.loadCompilerCli(); @@ -231,7 +229,6 @@ export class AotCompilation extends AngularCompilation { ); return { - affectedFiles, compilerOptions, referencedFiles, externalStylesheets: hostOptions.externalStylesheets, @@ -240,7 +237,7 @@ export class AotCompilation extends AngularCompilation { }; } - *collectDiagnostics(modes: DiagnosticModes): Iterable { + protected override *collectDiagnostics(modes: DiagnosticModes): Iterable { assert(this.#state, 'Angular compilation must be initialized prior to collecting diagnostics.'); const { affectedFiles, @@ -313,7 +310,7 @@ export class AotCompilation extends AngularCompilation { } } - emitAffectedFiles(): Iterable { + override emitAffectedFiles(): Iterable { assert(this.#state, 'Angular compilation must be initialized prior to emitting files.'); const { affectedFiles, diff --git a/packages/angular/build/src/tools/angular/compilation/factory.ts b/packages/angular/build/src/tools/angular/compilation/factory.ts index ebfa7aa7edc4..3944979f1ee5 100644 --- a/packages/angular/build/src/tools/angular/compilation/factory.ts +++ b/packages/angular/build/src/tools/angular/compilation/factory.ts @@ -9,26 +9,35 @@ import { useParallelTs } from '../../../utils/environment-options'; import type { AngularCompilation } from './angular-compilation'; +export type AngularCompilationMode = 'aot' | 'jit' | 'transform'; + /** * Creates an Angular compilation object that can be used to perform Angular application - * compilation either for AOT or JIT mode. By default a parallel compilation is created + * compilation either for AOT, JIT, or on-demand transform mode. By default a parallel compilation is created * that uses a Node.js worker thread. - * @param jit True, for Angular JIT compilation; False, for Angular AOT compilation. + * @param mode True or 'jit' for JIT mode; False or 'aot' for AOT compilation; 'transform' for on-demand transformation. * @param browserOnlyBuild True, for browser only builds; False, for browser and server builds. + * @param parallel True to execute compilation in a worker thread. * @returns An instance of an Angular compilation object. */ export async function createAngularCompilation( - jit: boolean, + mode: boolean | AngularCompilationMode, browserOnlyBuild: boolean, parallel: boolean = useParallelTs, ): Promise { + if (mode === 'transform') { + throw new Error('Transform compilation mode is not supported.'); + } + + const isJit = mode === true || mode === 'jit'; + if (parallel) { const { ParallelCompilation } = await import('./parallel-compilation'); - return new ParallelCompilation(jit, browserOnlyBuild); + return new ParallelCompilation(isJit, browserOnlyBuild); } - if (jit) { + if (isJit) { const { JitCompilation } = await import('./jit-compilation'); return new JitCompilation(browserOnlyBuild); diff --git a/packages/angular/build/src/tools/angular/compilation/index.ts b/packages/angular/build/src/tools/angular/compilation/index.ts index d2611e0d156d..213f55cac326 100644 --- a/packages/angular/build/src/tools/angular/compilation/index.ts +++ b/packages/angular/build/src/tools/angular/compilation/index.ts @@ -6,6 +6,13 @@ * found in the LICENSE file at https://angular.dev/license */ -export { AngularCompilation, DiagnosticModes } from './angular-compilation'; -export { createAngularCompilation } from './factory'; +export { + AngularCompilation, + type AngularCompilationOptions, + type AngularCompilationResult, + DiagnosticModes, + type EmitFileResult, + type FileTransformResult, +} from './angular-compilation'; +export { createAngularCompilation, type AngularCompilationMode } from './factory'; export { NoopCompilation } from './noop-compilation'; diff --git a/packages/angular/build/src/tools/angular/compilation/jit-compilation.ts b/packages/angular/build/src/tools/angular/compilation/jit-compilation.ts index 5d920d961ba1..ffbfb9dfd7e6 100644 --- a/packages/angular/build/src/tools/angular/compilation/jit-compilation.ts +++ b/packages/angular/build/src/tools/angular/compilation/jit-compilation.ts @@ -14,7 +14,12 @@ import { AngularHostOptions, createAngularCompilerHost } from '../angular-host'; import { createJitResourceTransformer } from '../transformers/jit-resource-transformer'; import { lazyRoutesTransformer } from '../transformers/lazy-routes-transformer'; import { createWorkerTransformer } from '../transformers/web-worker-transformer'; -import { AngularCompilation, DiagnosticModes, EmitFileResult } from './angular-compilation'; +import { + AngularCompilation, + AngularCompilationResult, + DiagnosticModes, + EmitFileResult, +} from './angular-compilation'; class JitCompilationState { constructor( @@ -37,11 +42,7 @@ export class JitCompilation extends AngularCompilation { tsconfig: string, hostOptions: AngularHostOptions, compilerOptionsTransformer?: (compilerOptions: ng.CompilerOptions) => ng.CompilerOptions, - ): Promise<{ - affectedFiles: ReadonlySet; - compilerOptions: ng.CompilerOptions; - referencedFiles: readonly string[]; - }> { + ): Promise { // Dynamically load the Angular compiler CLI package const { constructorParametersDownlevelTransform } = await import('@angular/compiler-cli/private/tooling'); @@ -85,10 +86,10 @@ export class JitCompilation extends AngularCompilation { .getSourceFiles() .map((sourceFile) => sourceFile.fileName); - return { affectedFiles, compilerOptions, referencedFiles }; + return { compilerOptions, referencedFiles }; } - *collectDiagnostics(modes: DiagnosticModes): Iterable { + protected override *collectDiagnostics(modes: DiagnosticModes): Iterable { assert(this.#state, 'Compilation must be initialized prior to collecting diagnostics.'); const { typeScriptProgram } = this.#state; @@ -110,7 +111,7 @@ export class JitCompilation extends AngularCompilation { } } - emitAffectedFiles(): Iterable { + override emitAffectedFiles(): Iterable { assert(this.#state, 'Compilation must be initialized prior to emitting files.'); const { compilerHost, diff --git a/packages/angular/build/src/tools/angular/compilation/noop-compilation.ts b/packages/angular/build/src/tools/angular/compilation/noop-compilation.ts index e2c597b4d315..a2bb722d10a8 100644 --- a/packages/angular/build/src/tools/angular/compilation/noop-compilation.ts +++ b/packages/angular/build/src/tools/angular/compilation/noop-compilation.ts @@ -7,33 +7,28 @@ */ import type * as ng from '@angular/compiler-cli'; -import type ts from 'typescript'; import { AngularHostOptions } from '../angular-host'; -import { AngularCompilation } from './angular-compilation'; +import { AngularCompilation, AngularCompilationResult } from './angular-compilation'; export class NoopCompilation extends AngularCompilation { async initialize( tsconfig: string, hostOptions: AngularHostOptions, compilerOptionsTransformer?: (compilerOptions: ng.CompilerOptions) => ng.CompilerOptions, - ): Promise<{ - affectedFiles: ReadonlySet; - compilerOptions: ng.CompilerOptions; - referencedFiles: readonly string[]; - }> { + ): Promise { // Load the compiler configuration and transform as needed const { options: originalCompilerOptions } = await this.loadConfiguration(tsconfig); const compilerOptions = compilerOptionsTransformer?.(originalCompilerOptions) ?? originalCompilerOptions; - return { affectedFiles: new Set(), compilerOptions, referencedFiles: [] }; + return { compilerOptions, referencedFiles: [] }; } - collectDiagnostics(): never { + protected override collectDiagnostics(): never { throw new Error('Not available when using noop compilation.'); } - emitAffectedFiles(): never { + override emitAffectedFiles(): never { throw new Error('Not available when using noop compilation.'); } } diff --git a/packages/angular/build/src/tools/angular/compilation/parallel-compilation.ts b/packages/angular/build/src/tools/angular/compilation/parallel-compilation.ts index a0dd58179ba2..af7602d72630 100644 --- a/packages/angular/build/src/tools/angular/compilation/parallel-compilation.ts +++ b/packages/angular/build/src/tools/angular/compilation/parallel-compilation.ts @@ -10,11 +10,15 @@ import type { CompilerOptions } from '@angular/compiler-cli'; import type { PartialMessage } from 'esbuild'; import { createRequire } from 'node:module'; import { MessageChannel } from 'node:worker_threads'; -import type { SourceFile } from 'typescript'; import { WorkerPool } from '../../../utils/worker-pool'; import { mergeCumulativeDurations } from '../../esbuild/profiling'; import type { AngularHostOptions } from '../angular-host'; -import { AngularCompilation, DiagnosticModes, EmitFileResult } from './angular-compilation'; +import { + AngularCompilation, + AngularCompilationResult, + DiagnosticModes, + EmitFileResult, +} from './angular-compilation'; /** * An Angular compilation which uses a Node.js Worker thread to load and execute @@ -47,12 +51,7 @@ export class ParallelCompilation extends AngularCompilation { tsconfig: string, hostOptions: AngularHostOptions, compilerOptionsTransformer?: (compilerOptions: CompilerOptions) => CompilerOptions, - ): Promise<{ - affectedFiles: ReadonlySet; - compilerOptions: CompilerOptions; - referencedFiles: readonly string[]; - externalStylesheets?: ReadonlyMap; - }> { + ): Promise { const stylesheetChannel = new MessageChannel(); // The request identifier is required because Angular can issue multiple concurrent requests stylesheetChannel.port1.on( diff --git a/packages/angular/build/src/tools/angular/compilation/parallel-worker.ts b/packages/angular/build/src/tools/angular/compilation/parallel-worker.ts index 95719bf1e3b2..ee3345d83388 100644 --- a/packages/angular/build/src/tools/angular/compilation/parallel-worker.ts +++ b/packages/angular/build/src/tools/angular/compilation/parallel-worker.ts @@ -13,7 +13,11 @@ import { type MessagePort, receiveMessageOnPort } from 'node:worker_threads'; import { initializeHash } from '../../../utils/hash'; import { SourceFileCache } from '../../esbuild/angular/source-file-cache'; import { getAndClearCumulativeDurations } from '../../esbuild/profiling'; -import type { AngularCompilation, DiagnosticModes } from './angular-compilation'; +import type { + AngularCompilation, + AngularCompilationResult, + DiagnosticModes, +} from './angular-compilation'; import { AotCompilation } from './aot-compilation'; import { JitCompilation } from './jit-compilation'; @@ -33,7 +37,7 @@ let compilation: AngularCompilation | undefined; const sourceFileCache = new SourceFileCache(); -export async function initialize(request: InitRequest) { +export async function initialize(request: InitRequest): Promise { await initializeHash(); compilation ??= request.jit ? new JitCompilation(request.browserOnlyBuild) diff --git a/packages/angular/build/src/tools/esbuild/angular/compiler-plugin.ts b/packages/angular/build/src/tools/esbuild/angular/compiler-plugin.ts index 5b764d3bd4f6..0406d4628889 100644 --- a/packages/angular/build/src/tools/esbuild/angular/compiler-plugin.ts +++ b/packages/angular/build/src/tools/esbuild/angular/compiler-plugin.ts @@ -362,24 +362,26 @@ export function createCompilerPlugin( } } - // Update TypeScript file output cache for all affected files - try { - await profileAsync('NG_EMIT_TS', async () => { - for (const { filename, contents } of await compilation.emitAffectedFiles()) { - typeScriptFileCache.set(path.normalize(filename), contents); - } - }); - } catch (error) { - (result.errors ??= []).push({ - text: 'Angular compilation emit failed.', - location: null, - notes: [ - { - text: error instanceof Error ? (error.stack ?? error.message) : `${error}`, - location: null, - }, - ], - }); + // Update TypeScript file output cache for all affected files if not using on-demand transforms + if (!compilation.transformFile) { + try { + await profileAsync('NG_EMIT_TS', async () => { + for (const { filename, contents } of await compilation.emitAffectedFiles()) { + typeScriptFileCache.set(path.normalize(filename), contents); + } + }); + } catch (error) { + (result.errors ??= []).push({ + text: 'Angular compilation emit failed.', + location: null, + notes: [ + { + text: error instanceof Error ? (error.stack ?? error.message) : `${error}`, + location: null, + }, + ], + }); + } } const diagnostics = await compilation.diagnoseFiles( @@ -434,6 +436,35 @@ export function createCompilerPlugin( // cache is later stored to disk, then the options that affect transform output // would need to be added to the key as well as a check for any change of content. let contents = typeScriptFileCache.get(request); + let directContents: string | undefined; + + if (contents === undefined && compilation.transformFile) { + try { + directContents = await readFile(request, 'utf-8'); + const transformResult = await compilation.transformFile(request, directContents); + if (transformResult) { + contents = transformResult.contents; + if (transformResult.watchFiles) { + referencedFileTracker.add(request, transformResult.watchFiles); + } + } + } catch (error) { + return { + errors: [ + { + text: 'Angular compilation transform failed.', + location: { file: request }, + notes: [ + { + text: error instanceof Error ? (error.stack ?? error.message) : `${error}`, + location: null, + }, + ], + }, + ], + }; + } + } if (contents === undefined) { // If the Angular compilation had errors the file may not have been emitted. @@ -452,7 +483,7 @@ export function createCompilerPlugin( // Evaluate whether the file requires the Angular compiler transpilation. // If not, issue a warning but allow bundler to process the file (no type-checking). - const directContents = await readFile(request, 'utf-8'); + directContents ??= await readFile(request, 'utf-8'); if (!requiresAngularCompiler(directContents)) { return { warnings: [createMissingFileDiagnostic(request, args.path, diangosticRoot, false)], From 50994d76e59a4b632f1782c51cd60f80c9cd50fb Mon Sep 17 00:00:00 2001 From: Alan Agius Date: Fri, 14 Aug 2026 15:43:40 +0200 Subject: [PATCH 305/787] fix(@angular/build): preserve integrity and crossorigin in autoCsp loader When both `subresourceIntegrity` and `security.autoCsp` are enabled, initial entry scripts had their ``); @@ -166,12 +166,12 @@ describe('auto-csp', () => { // Loader script for main.js and main2.js appear after 'foo' and before 'bar'. expect(result).toMatch( // eslint-disable-next-line max-len - /console.log\('foo'\);<\/script>\s* +
Some text
+ + + `); + + const csps = getCsps(result); + expect(csps).toHaveSize(1); + expect(csps[0]).toMatch(CSP_SINGLE_HASH_REGEX); + expect(result).toContain( + `const scripts = [['./main.js', 'module', false, false, "sha384-xyz123", "anonymous"]];`, + ); + }); + + it('should preserve only integrity attribute when crossorigin is omitted', async () => { + const result = await autoCsp(` + + + + + +
Some text
+ + + `); + + const csps = getCsps(result); + expect(csps).toHaveSize(1); + expect(csps[0]).toMatch(CSP_SINGLE_HASH_REGEX); + expect(result).toContain( + `const scripts = [['./main.js', '', false, false, "sha384-xyz123", null]];`, + ); + }); + + it('should map empty crossorigin attribute to anonymous', async () => { + const result = await autoCsp(` + + + + + +
Some text
+ + + `); + + const csps = getCsps(result); + expect(csps).toHaveSize(1); + expect(csps[0]).toMatch(CSP_SINGLE_HASH_REGEX); + expect(result).toContain( + `const scripts = [['./main.js', '', false, false, null, "anonymous"]];`, + ); + }); }); From d827ba9005b86b23d05ee7c62c0823367aa245c1 Mon Sep 17 00:00:00 2001 From: Charles Lyding <19598772+clydin@users.noreply.github.com> Date: Thu, 13 Aug 2026 14:56:08 -0400 Subject: [PATCH 306/787] refactor(@angular/build): use translation integrity for i18n inlining cache keys Avoid full JSON serialization and hashing of the in-memory translation dictionary for each locale when computing persistent cache keys. Instead, use the combined translation file integrity hashes and the installed `@angular/localize` package version when available, falling back to the in-memory translation object if integrity is absent. --- .../build/src/builders/application/i18n.ts | 25 +++++++++++++- .../build/src/tools/esbuild/i18n-inliner.ts | 11 ++++++- .../src/tools/esbuild/i18n-inliner_spec.ts | 33 +++++++++++++++++++ .../angular/build/src/utils/i18n-options.ts | 1 + 4 files changed, 68 insertions(+), 2 deletions(-) diff --git a/packages/angular/build/src/builders/application/i18n.ts b/packages/angular/build/src/builders/application/i18n.ts index c83f1a29a30a..137336497885 100644 --- a/packages/angular/build/src/builders/application/i18n.ts +++ b/packages/angular/build/src/builders/application/i18n.ts @@ -8,6 +8,7 @@ import { BuilderContext } from '@angular-devkit/architect'; import type { Metafile } from 'esbuild'; +import { readFile } from 'node:fs/promises'; import { join } from 'node:path'; import { ExecutionResult, @@ -18,6 +19,7 @@ import { I18nInliner } from '../../tools/esbuild/i18n-inliner'; import { maxWorkers } from '../../utils/environment-options'; import { loadTranslations } from '../../utils/i18n-options'; import { createTranslationLoader } from '../../utils/load-translations'; +import { createProjectResolver } from '../../utils/resolve-project'; import { executePostBundleSteps } from './execute-post-bundle'; import { NormalizedApplicationBuildOptions, getLocaleBaseHref } from './options'; @@ -48,6 +50,7 @@ export async function inlineI18n( outputFiles: executionResult.outputFiles, shouldOptimize: optimizationOptions.scripts, persistentCachePath: cacheOptions.enabled ? cacheOptions.path : undefined, + localizeVersion: i18nOptions.localizeVersion, }, maxWorkers, ); @@ -72,10 +75,21 @@ export async function inlineI18n( try { for (const locale of i18nOptions.inlineLocales) { + const localeDescription = i18nOptions.locales[locale]; + let translationIntegrity: string | undefined = ''; + for (const file of localeDescription.files) { + if (!file.integrity) { + translationIntegrity = undefined; + break; + } + translationIntegrity += (translationIntegrity ? '|' : '') + file.integrity; + } + // A locale specific set of files is returned from the inliner. const localeInlineResult = await inliner.inlineForLocale( locale, - i18nOptions.locales[locale].translation, + localeDescription.translation, + translationIntegrity, ); const localeOutputFiles = localeInlineResult.outputFiles; inlineResult.errors.push(...localeInlineResult.errors); @@ -176,6 +190,15 @@ export async function loadActiveTranslations( context: BuilderContext, i18n: NormalizedApplicationBuildOptions['i18nOptions'], ) { + if (!i18n.localizeVersion) { + try { + const projectResolve = createProjectResolver(context.workspaceRoot); + const manifestPath = projectResolve('@angular/localize/package.json'); + const manifest = JSON.parse(await readFile(manifestPath, 'utf-8')) as { version?: string }; + i18n.localizeVersion = manifest.version; + } catch {} + } + // Load locale data and translations (if present) let loader; for (const [locale, desc] of Object.entries(i18n.locales)) { diff --git a/packages/angular/build/src/tools/esbuild/i18n-inliner.ts b/packages/angular/build/src/tools/esbuild/i18n-inliner.ts index 678511612afb..a65d28516cce 100644 --- a/packages/angular/build/src/tools/esbuild/i18n-inliner.ts +++ b/packages/angular/build/src/tools/esbuild/i18n-inliner.ts @@ -42,6 +42,7 @@ export interface I18nInlinerOptions { outputFiles: BuildOutputFile[]; shouldOptimize?: boolean; persistentCachePath?: string; + localizeVersion?: string; } /** @@ -131,11 +132,13 @@ export class I18nInliner { * of the localize function keyword. * @param locale The string representing the locale to inline. * @param translation The translation messages to use when inlining. + * @param translationIntegrity An optional integrity value for the translation messages to use for caching. * @returns A promise that resolves to an array of OutputFiles representing a translated result. */ async inlineForLocale( locale: string, translation: Record | undefined, + translationIntegrity?: string, ): Promise<{ outputFiles: BuildOutputFile[]; errors: string[]; warnings: string[] }> { await this.initCache(); @@ -161,7 +164,13 @@ export class I18nInliner { // of bytes. Hashing the options directly would re-hash the full set of messages, which // can be several megabytes, once for every file. fileCacheKeyBase ??= calculateHash( - JSON.stringify({ locale, translation, missingTranslation, shouldOptimize }), + JSON.stringify({ + locale, + translation: translationIntegrity ?? translation, + missingTranslation, + shouldOptimize, + localizeVersion: this.options.localizeVersion, + }), ); // NOTE: If additional options are added, this may need to be updated. diff --git a/packages/angular/build/src/tools/esbuild/i18n-inliner_spec.ts b/packages/angular/build/src/tools/esbuild/i18n-inliner_spec.ts index 609774ced508..94f390e2334c 100644 --- a/packages/angular/build/src/tools/esbuild/i18n-inliner_spec.ts +++ b/packages/angular/build/src/tools/esbuild/i18n-inliner_spec.ts @@ -307,4 +307,37 @@ describe('I18nInliner', () => { 'Malformed escape sequence in $localize template literal in file "main.js".', ]); }); + + it('inlines the translations of a locale when translationIntegrity is provided', async () => { + const { outputFiles, errors, warnings } = await createInliner([ + browserFile('main.js', GREETING_SOURCE), + ]).inlineForLocale('fr', { greeting: translationFor('Bonjour') }, 'sha256-test-integrity'); + + expect(errors).toEqual([]); + expect(warnings).toEqual([]); + expect(findFile(outputFiles, 'main.js').text).toContain('"Bonjour"'); + expect(findFile(outputFiles, 'main.js').text).not.toContain('$localize'); + }); + + it('inlines the translations of a locale when localizeVersion is configured in options', async () => { + inliner = new I18nInliner( + { + missingTranslation: 'warning', + outputFiles: [browserFile('main.js', GREETING_SOURCE)], + localizeVersion: '20.2.0', + }, + 1, + ); + + const { outputFiles, errors, warnings } = await inliner.inlineForLocale( + 'fr', + { greeting: translationFor('Bonjour') }, + 'sha256-test-integrity', + ); + + expect(errors).toEqual([]); + expect(warnings).toEqual([]); + expect(findFile(outputFiles, 'main.js').text).toContain('"Bonjour"'); + expect(findFile(outputFiles, 'main.js').text).not.toContain('$localize'); + }); }); diff --git a/packages/angular/build/src/utils/i18n-options.ts b/packages/angular/build/src/utils/i18n-options.ts index 822683bef03d..6a288622d053 100644 --- a/packages/angular/build/src/utils/i18n-options.ts +++ b/packages/angular/build/src/utils/i18n-options.ts @@ -28,6 +28,7 @@ export interface I18nOptions { flatOutput?: boolean; readonly shouldInline: boolean; hasDefinedSourceLocale?: boolean; + localizeVersion?: string; } function normalizeTranslationFileOption( From 7302341eb9e73141c2a6f9cd38d0939e2570c038 Mon Sep 17 00:00:00 2001 From: Charles Lyding <19598772+clydin@users.noreply.github.com> Date: Fri, 14 Aug 2026 10:12:35 -0400 Subject: [PATCH 307/787] refactor(@angular/build): encapsulate TypeScript source file AST caching in compilation classes Move the `ts.SourceFile` AST cache out of `SourceFileCache` and directly into `AotCompilation` and `JitCompilation`. This removes the `Map` inheritance from `SourceFileCache` and removes the `sourceFileCache` property from `AngularHostOptions`, further decoupling the bundler plugin and generic host interfaces from TypeScript AST structures. --- .../build/src/tools/angular/angular-host.ts | 6 +-- .../angular/compilation/aot-compilation.ts | 44 +++++++++++++------ .../angular/compilation/jit-compilation.ts | 35 ++++++++------- .../angular/compilation/parallel-worker.ts | 16 ++++--- .../tools/esbuild/angular/compiler-plugin.ts | 1 - .../esbuild/angular/source-file-cache.ts | 21 ++------- 6 files changed, 66 insertions(+), 57 deletions(-) diff --git a/packages/angular/build/src/tools/angular/angular-host.ts b/packages/angular/build/src/tools/angular/angular-host.ts index 22ac345d413e..9322b5683dc5 100644 --- a/packages/angular/build/src/tools/angular/angular-host.ts +++ b/packages/angular/build/src/tools/angular/angular-host.ts @@ -17,7 +17,6 @@ export type AngularCompilerHost = ng.CompilerHost; export interface AngularHostOptions { fileReplacements?: Record; - sourceFileCache?: Map; modifiedFiles?: Set; externalStylesheets?: Map; transformStylesheet( @@ -165,6 +164,7 @@ export function createAngularCompilerHost( compilerOptions: AngularCompilerOptions, hostOptions: AngularHostOptions, packageJsonCache: ts.PackageJsonInfoCache | undefined, + sourceFileCache?: Map, ): AngularCompilerHost { // Create TypeScript compiler host const host: AngularCompilerHost = typescript.createIncrementalCompilerHost(compilerOptions); @@ -254,8 +254,8 @@ export function createAngularCompilerHost( } // Augment TypeScript Host with source file caching if provided - if (hostOptions.sourceFileCache) { - augmentHostWithCaching(host, hostOptions.sourceFileCache); + if (sourceFileCache) { + augmentHostWithCaching(host, sourceFileCache); } return host; diff --git a/packages/angular/build/src/tools/angular/compilation/aot-compilation.ts b/packages/angular/build/src/tools/angular/compilation/aot-compilation.ts index 61a9e4949fd4..42df6a40e778 100644 --- a/packages/angular/build/src/tools/angular/compilation/aot-compilation.ts +++ b/packages/angular/build/src/tools/angular/compilation/aot-compilation.ts @@ -11,6 +11,7 @@ import assert from 'node:assert'; import { relative } from 'node:path'; import ts from 'typescript'; import { useTypeChecking } from '../../../utils/environment-options'; +import { toPosixPath } from '../../../utils/path'; import { profileAsync, profileSync } from '../../esbuild/profiling'; import { AngularHostOptions, @@ -55,6 +56,7 @@ class AngularCompilationState { export class AotCompilation extends AngularCompilation { #state?: AngularCompilationState; + readonly #sourceFiles = new Map(); constructor(private readonly browserOnlyBuild: boolean) { super(); @@ -97,27 +99,37 @@ export class AotCompilation extends AngularCompilation { let staleSourceFiles; let clearPackageJsonCache = false; - if (hostOptions.modifiedFiles && this.#state) { + if (hostOptions.modifiedFiles) { for (const modifiedFile of hostOptions.modifiedFiles) { - // Clear package.json cache if a node modules file was modified - if (!clearPackageJsonCache && modifiedFile.includes('node_modules')) { - clearPackageJsonCache = true; - packageJsonCache?.clear(); - } + this.#sourceFiles.delete(toPosixPath(modifiedFile)); - // Collect stale source files for HMR analysis of inline component resources - if (useHmr) { - const sourceFile = this.#state.typeScriptProgram.getSourceFile(modifiedFile); - if (sourceFile) { - staleSourceFiles ??= new Map(); - staleSourceFiles.set(modifiedFile, sourceFile); + if (this.#state) { + // Clear package.json cache if a node modules file was modified + if (!clearPackageJsonCache && modifiedFile.includes('node_modules')) { + clearPackageJsonCache = true; + packageJsonCache?.clear(); + } + + // Collect stale source files for HMR analysis of inline component resources + if (useHmr) { + const sourceFile = this.#state.typeScriptProgram.getSourceFile(modifiedFile); + if (sourceFile) { + staleSourceFiles ??= new Map(); + staleSourceFiles.set(modifiedFile, sourceFile); + } } } } } // Create Angular compiler host - const host = createAngularCompilerHost(ts, compilerOptions, hostOptions, packageJsonCache); + const host = createAngularCompilerHost( + ts, + compilerOptions, + hostOptions, + packageJsonCache, + this.#sourceFiles, + ); // Create the Angular specific program that contains the Angular compiler const angularProgram = profileSync( @@ -451,6 +463,12 @@ export class AotCompilation extends AngularCompilation { return emittedFiles.values(); } + + override async update(files: Set): Promise { + for (const file of files) { + this.#sourceFiles.delete(toPosixPath(file)); + } + } } function findAffectedFiles( diff --git a/packages/angular/build/src/tools/angular/compilation/jit-compilation.ts b/packages/angular/build/src/tools/angular/compilation/jit-compilation.ts index ffbfb9dfd7e6..955c90502cb0 100644 --- a/packages/angular/build/src/tools/angular/compilation/jit-compilation.ts +++ b/packages/angular/build/src/tools/angular/compilation/jit-compilation.ts @@ -9,6 +9,7 @@ import type * as ng from '@angular/compiler-cli'; import assert from 'node:assert'; import ts from 'typescript'; +import { toPosixPath } from '../../../utils/path'; import { profileSync } from '../../esbuild/profiling'; import { AngularHostOptions, createAngularCompilerHost } from '../angular-host'; import { createJitResourceTransformer } from '../transformers/jit-resource-transformer'; @@ -33,6 +34,7 @@ class JitCompilationState { export class JitCompilation extends AngularCompilation { #state?: JitCompilationState; + readonly #sourceFiles = new Map(); constructor(private readonly browserOnlyBuild: boolean) { super(); @@ -56,8 +58,20 @@ export class JitCompilation extends AngularCompilation { const compilerOptions = compilerOptionsTransformer?.(originalCompilerOptions) ?? originalCompilerOptions; + if (hostOptions.modifiedFiles) { + for (const modifiedFile of hostOptions.modifiedFiles) { + this.#sourceFiles.delete(toPosixPath(modifiedFile)); + } + } + // Create Angular compiler host - const host = createAngularCompilerHost(ts, compilerOptions, hostOptions, undefined); + const host = createAngularCompilerHost( + ts, + compilerOptions, + hostOptions, + undefined, + this.#sourceFiles, + ); // Create the TypeScript Program const typeScriptProgram = profileSync('TS_CREATE_PROGRAM', () => @@ -70,10 +84,6 @@ export class JitCompilation extends AngularCompilation { ), ); - const affectedFiles = profileSync('TS_FIND_AFFECTED', () => - findAffectedFiles(typeScriptProgram), - ); - this.#state = new JitCompilationState( host, typeScriptProgram, @@ -157,17 +167,10 @@ export class JitCompilation extends AngularCompilation { return emittedFiles; } -} - -function findAffectedFiles( - builder: ts.EmitAndSemanticDiagnosticsBuilderProgram, -): Set { - const affectedFiles = new Set(); - let result; - while ((result = builder.getSemanticDiagnosticsOfNextAffectedFile())) { - affectedFiles.add(result.affected as ts.SourceFile); + override async update(files: Set): Promise { + for (const file of files) { + this.#sourceFiles.delete(toPosixPath(file)); + } } - - return affectedFiles; } diff --git a/packages/angular/build/src/tools/angular/compilation/parallel-worker.ts b/packages/angular/build/src/tools/angular/compilation/parallel-worker.ts index ee3345d83388..d592b5fb4777 100644 --- a/packages/angular/build/src/tools/angular/compilation/parallel-worker.ts +++ b/packages/angular/build/src/tools/angular/compilation/parallel-worker.ts @@ -11,7 +11,6 @@ import assert from 'node:assert'; import { randomUUID } from 'node:crypto'; import { type MessagePort, receiveMessageOnPort } from 'node:worker_threads'; import { initializeHash } from '../../../utils/hash'; -import { SourceFileCache } from '../../esbuild/angular/source-file-cache'; import { getAndClearCumulativeDurations } from '../../esbuild/profiling'; import type { AngularCompilation, @@ -35,9 +34,12 @@ export interface InitRequest { let compilation: AngularCompilation | undefined; -const sourceFileCache = new SourceFileCache(); +const modifiedFiles = new Set(); export async function initialize(request: InitRequest): Promise { + const currentModifiedFiles = new Set(modifiedFiles); + modifiedFiles.clear(); + await initializeHash(); compilation ??= request.jit ? new JitCompilation(request.browserOnlyBuild) @@ -62,8 +64,7 @@ export async function initialize(request: InitRequest): Promise((resolve, reject) => @@ -151,6 +152,9 @@ export async function emit() { return [...files]; } -export function update(files: Set): void { - sourceFileCache.invalidate(files); +export async function update(files: Set): Promise { + for (const file of files) { + modifiedFiles.add(file); + } + await compilation?.update?.(files); } diff --git a/packages/angular/build/src/tools/esbuild/angular/compiler-plugin.ts b/packages/angular/build/src/tools/esbuild/angular/compiler-plugin.ts index 0406d4628889..b0ff0593cecc 100644 --- a/packages/angular/build/src/tools/esbuild/angular/compiler-plugin.ts +++ b/packages/angular/build/src/tools/esbuild/angular/compiler-plugin.ts @@ -187,7 +187,6 @@ export function createCompilerPlugin( const hostOptions: AngularHostOptions = { fileReplacements: pluginOptions.fileReplacements, modifiedFiles, - sourceFileCache: pluginOptions.sourceFileCache, async transformStylesheet(data, containingFile, stylesheetFile, order, className) { let stylesheetResult; let resultSource = stylesheetFile ?? containingFile; diff --git a/packages/angular/build/src/tools/esbuild/angular/source-file-cache.ts b/packages/angular/build/src/tools/esbuild/angular/source-file-cache.ts index a408650a4f4f..136fbb651ba2 100644 --- a/packages/angular/build/src/tools/esbuild/angular/source-file-cache.ts +++ b/packages/angular/build/src/tools/esbuild/angular/source-file-cache.ts @@ -6,32 +6,24 @@ * found in the LICENSE file at https://angular.dev/license */ -import { platform } from 'node:os'; import * as path from 'node:path'; -import type ts from 'typescript'; import { MemoryLoadResultCache } from '../load-result-cache'; -const USING_WINDOWS = platform() === 'win32'; -const WINDOWS_SEP_REGEXP = new RegExp(`\\${path.win32.sep}`, 'g'); - -export class SourceFileCache extends Map { +export class SourceFileCache { readonly modifiedFiles = new Set(); readonly typeScriptFileCache = new Map(); readonly loadResultCache = new MemoryLoadResultCache(); referencedFiles?: readonly string[]; - constructor(readonly persistentCachePath?: string) { - super(); - } + constructor(readonly persistentCachePath?: string) {} /** * Releases all cached content. The cached data is only needed for incremental * rebuilds and can include the emitted contents of every TypeScript file in the * program. The cache is repopulated if a build is performed after this is called. */ - override clear(): void { - super.clear(); + clear(): void { this.modifiedFiles.clear(); this.typeScriptFileCache.clear(); this.loadResultCache.clear(); @@ -50,13 +42,6 @@ export class SourceFileCache extends Map { file = path.normalize(file); invalid = this.loadResultCache.invalidate(file) || invalid; invalid = extraWatchFiles.has(file) || invalid; - - // Normalize separators to allow matching TypeScript Host paths - if (USING_WINDOWS) { - file = file.replace(WINDOWS_SEP_REGEXP, path.posix.sep); - } - - invalid = this.delete(file) || invalid; this.modifiedFiles.add(file); } From ce1b60f89699c3a76496a0489e5f2b9e4fe62429 Mon Sep 17 00:00:00 2001 From: Charles Lyding <19598772+clydin@users.noreply.github.com> Date: Fri, 14 Aug 2026 13:51:51 -0400 Subject: [PATCH 308/787] fix(@schematics/angular): transform fail() to expect.fail() in refactor-jasmine-vitest Previously, fail() calls in Jasmine specs were transformed into throw new Error(...). In Vitest, expect.fail(...) is the idiomatic assertion method to explicitly fail a test with an AssertionError, properly formatting test failures in test runner output and avoiding generic unhandled exception throws. This update converts fail(...) call expressions to expect.fail(...), registers expect in the pending Vitest value imports, and moves the transformer into the call expression transformers pipeline. --- .../test-file-transformer.integration_spec.ts | 4 +- .../jasmine-vitest/test-file-transformer.ts | 24 +++---- .../test-file-transformer_add-imports_spec.ts | 20 ++++++ .../transformers/jasmine-misc.ts | 68 ++++++++++++------- .../transformers/jasmine-misc_spec.ts | 22 ++++-- .../jasmine-vitest/utils/todo-notes.ts | 6 ++ 6 files changed, 100 insertions(+), 44 deletions(-) diff --git a/packages/schematics/angular/refactor/jasmine-vitest/test-file-transformer.integration_spec.ts b/packages/schematics/angular/refactor/jasmine-vitest/test-file-transformer.integration_spec.ts index 5b30e9f24f4b..ce667dce1afc 100644 --- a/packages/schematics/angular/refactor/jasmine-vitest/test-file-transformer.integration_spec.ts +++ b/packages/schematics/angular/refactor/jasmine-vitest/test-file-transformer.integration_spec.ts @@ -392,14 +392,14 @@ describe('Jasmine to Vitest Transformer - Integration Tests', () => { it('should handle fail()', () => { if (true) { - throw new Error('This should not have happened'); + expect.fail('This should not have happened'); } }); it('should handle fail() with a specific error', () => { try { expect(1).toBe(2); - throw new Error('Expected test to fail'); + expect.fail('Expected test to fail'); } catch (err) { expect(err.message).toBe('1 !== 2'); } diff --git a/packages/schematics/angular/refactor/jasmine-vitest/test-file-transformer.ts b/packages/schematics/angular/refactor/jasmine-vitest/test-file-transformer.ts index f652368b03f7..e436434f134a 100644 --- a/packages/schematics/angular/refactor/jasmine-vitest/test-file-transformer.ts +++ b/packages/schematics/angular/refactor/jasmine-vitest/test-file-transformer.ts @@ -144,6 +144,7 @@ const callExpressionTransformers = [ // **Stage 3: Global Functions & Cleanup** // These handle global Jasmine functions and catch-alls for unsupported APIs. + transformFail, transformTimerMocks, transformUnsupportedGlobalFunctions, transformUnsupportedJasmineCalls, @@ -168,7 +169,6 @@ const expressionStatementTransformers = [ transformCalledOnceWith, transformArrayWithExactContents, transformExpectNothing, - transformFail, transformJasmineMembers, ]; @@ -227,18 +227,16 @@ export function transformJasmineToVitest( } for (const transformer of callExpressionTransformers) { - if ( - !( - (options.browserMode && transformer === transformToHaveClass) || - (options.fakeAsync === false && - [ - transformFakeAsyncFlush, - transformFakeAsyncFlushMicrotasks, - transformFakeAsyncTick, - transformFakeAsyncTest, - ].includes(transformer)) - ) - ) { + if (!( + (options.browserMode && transformer === transformToHaveClass) || + (options.fakeAsync === false && + [ + transformFakeAsyncFlush, + transformFakeAsyncFlushMicrotasks, + transformFakeAsyncTick, + transformFakeAsyncTest, + ].includes(transformer)) + )) { transformedNode = transformer(transformedNode, refactorCtx); } } diff --git a/packages/schematics/angular/refactor/jasmine-vitest/test-file-transformer_add-imports_spec.ts b/packages/schematics/angular/refactor/jasmine-vitest/test-file-transformer_add-imports_spec.ts index f4b10d485920..cbe05226ef7b 100644 --- a/packages/schematics/angular/refactor/jasmine-vitest/test-file-transformer_add-imports_spec.ts +++ b/packages/schematics/angular/refactor/jasmine-vitest/test-file-transformer_add-imports_spec.ts @@ -178,4 +178,24 @@ describe('Jasmine to Vitest Transformer - addImports option', () => { `; await expectTransformation(input, expected, true); }); + + it('should add import for `expect` when `fail()` is used and addImports is true', async () => { + const input = ` + describe('My Suite', () => { + it('fails', () => { + fail('Something went wrong'); + }); + }); + `; + const expected = ` + import { describe, expect, it } from 'vitest'; + + describe('My Suite', () => { + it('fails', () => { + expect.fail('Something went wrong'); + }); + }); + `; + await expectTransformation(input, expected, true); + }); }); diff --git a/packages/schematics/angular/refactor/jasmine-vitest/transformers/jasmine-misc.ts b/packages/schematics/angular/refactor/jasmine-vitest/transformers/jasmine-misc.ts index f71353cc9783..fe7e944e53e1 100644 --- a/packages/schematics/angular/refactor/jasmine-vitest/transformers/jasmine-misc.ts +++ b/packages/schematics/angular/refactor/jasmine-vitest/transformers/jasmine-misc.ts @@ -90,29 +90,53 @@ export function transformTimerMocks(node: ts.Node, ctx: RefactorContext): ts.Nod return node; } -export function transformFail(node: ts.Node, { sourceFile, reporter }: RefactorContext): ts.Node { +export function transformFail( + node: ts.Node, + { sourceFile, reporter, pendingVitestValueImports }: RefactorContext, +): ts.Node { if ( - ts.isExpressionStatement(node) && - ts.isCallExpression(node.expression) && - ts.isIdentifier(node.expression.expression) && - node.expression.expression.text === 'fail' + ts.isCallExpression(node) && + ts.isIdentifier(node.expression) && + node.expression.text === 'fail' ) { - reporter.reportTransformation(sourceFile, node, 'Transformed `fail()` to `throw new Error()`.'); - - const arg = node.expression.arguments[0]; - let throwExpression: ts.Expression; - - if (arg && ts.isNewExpression(arg)) { - throwExpression = arg; - } else { - throwExpression = ts.factory.createNewExpression( - ts.factory.createIdentifier('Error'), - undefined, - arg ? [arg] : [], - ); + addVitestValueImport(pendingVitestValueImports, 'expect'); + reporter.reportTransformation(sourceFile, node, 'Transformed `fail()` to `expect.fail()`.'); + + const arg = node.arguments[0]; + let replacementArg: ts.Expression | undefined = arg; + let hasNonStringArg = false; + + if (arg) { + if (ts.isNewExpression(arg)) { + replacementArg = arg.arguments && arg.arguments.length > 0 ? arg.arguments[0] : undefined; + } else if ( + !ts.isStringLiteral(arg) && + !ts.isNoSubstitutionTemplateLiteral(arg) && + !ts.isTemplateExpression(arg) + ) { + replacementArg = ts.factory.createCallExpression( + ts.factory.createIdentifier('String'), + undefined, + [arg], + ); + hasNonStringArg = true; + } } - const replacement = ts.factory.createThrowStatement(throwExpression); + const replacement = ts.factory.createCallExpression( + ts.factory.createPropertyAccessExpression( + ts.factory.createIdentifier('expect'), + ts.factory.createIdentifier('fail'), + ), + undefined, + replacementArg ? [replacementArg] : [], + ); + + if (hasNonStringArg) { + const category = 'fail-non-string-argument'; + reporter.recordTodo(category, sourceFile, node); + addTodoComment(replacement, category); + } return ts.setOriginalNode(ts.setTextRange(replacement, node), node); } @@ -197,11 +221,7 @@ const UNSUPPORTED_GLOBAL_FUNCTION_CATEGORIES = new Set([ function isUnsupportedGlobalFunction( methodName: string, ): methodName is - | 'setSpecProperty' - | 'setSuiteProperty' - | 'throwUnless' - | 'throwUnlessAsync' - | 'getSpecProperty' { + 'setSpecProperty' | 'setSuiteProperty' | 'throwUnless' | 'throwUnlessAsync' | 'getSpecProperty' { return UNSUPPORTED_GLOBAL_FUNCTION_CATEGORIES.has(methodName as TodoCategory); } diff --git a/packages/schematics/angular/refactor/jasmine-vitest/transformers/jasmine-misc_spec.ts b/packages/schematics/angular/refactor/jasmine-vitest/transformers/jasmine-misc_spec.ts index a5b29f2d2b6a..49cb2d54475a 100644 --- a/packages/schematics/angular/refactor/jasmine-vitest/transformers/jasmine-misc_spec.ts +++ b/packages/schematics/angular/refactor/jasmine-vitest/transformers/jasmine-misc_spec.ts @@ -59,19 +59,31 @@ jasmine.clock().withMock(noop);`, describe('transformFail', () => { const testCases = [ { - description: 'should transform fail() to throw new Error()', + description: 'should transform fail() to expect.fail()', input: `fail('This should not happen');`, - expected: `throw new Error('This should not happen');`, + expected: `expect.fail('This should not happen');`, }, { - description: 'should transform fail() without a message to throw new Error()', + description: 'should transform fail() without a message to expect.fail()', input: `fail();`, - expected: `throw new Error();`, + expected: `expect.fail();`, }, { description: 'should transform fail() with an Error object', input: `fail(new TypeError('Invalid input'));`, - expected: `throw new TypeError('Invalid input');`, + expected: `expect.fail('Invalid input');`, + }, + { + description: 'should transform fail() with an empty Error object', + input: `fail(new Error());`, + expected: `expect.fail();`, + }, + { + description: 'should transform fail() with a non-string argument and add a TODO note', + input: `fail(err);`, + // eslint-disable-next-line max-len + expected: `// TODO: vitest-migration: expect.fail() only accepts a string message. Verify that converting this argument with String() produces the expected failure output. See: https://vitest.dev/api/expect.html#expect-fail +expect.fail(String(err));`, }, ]; diff --git a/packages/schematics/angular/refactor/jasmine-vitest/utils/todo-notes.ts b/packages/schematics/angular/refactor/jasmine-vitest/utils/todo-notes.ts index 598606d7bde6..0179a0314277 100644 --- a/packages/schematics/angular/refactor/jasmine-vitest/utils/todo-notes.ts +++ b/packages/schematics/angular/refactor/jasmine-vitest/utils/todo-notes.ts @@ -64,6 +64,12 @@ export const TODO_NOTES = { message: 'expect().nothing() has been removed because it is redundant in Vitest. Tests without assertions pass by default.', }, + 'fail-non-string-argument': { + message: + 'expect.fail() only accepts a string message. ' + + 'Verify that converting this argument with String() produces the expected failure output.', + url: 'https://vitest.dev/api/expect.html#expect-fail', + }, 'unsupported-jasmine-member': { message: (context: { name: string }): string => `jasmine.${context.name} is not supported.`, }, From c7d345c4fd3f25546b482578ffba76cf1821df1e Mon Sep 17 00:00:00 2001 From: Angular Robot Date: Mon, 17 Aug 2026 13:08:48 +0000 Subject: [PATCH 309/787] build: update cross-repo angular dependencies See associated pull request for more information. --- .../assistant-to-the-branch-manager.yml | 2 +- .github/workflows/ci.yml | 52 +-- .github/workflows/dev-infra.yml | 6 +- .github/workflows/perf.yml | 6 +- .github/workflows/pr.yml | 44 +-- MODULE.bazel | 6 +- MODULE.bazel.lock | 13 +- modules/testing/builder/package.json | 2 +- package.json | 28 +- packages/angular/build/package.json | 2 +- packages/angular/ssr/package.json | 12 +- .../angular_devkit/build_angular/package.json | 2 +- packages/ngtools/webpack/package.json | 4 +- pnpm-lock.yaml | 361 +++++++++--------- tests/e2e/ng-snapshot/package.json | 32 +- 15 files changed, 282 insertions(+), 290 deletions(-) diff --git a/.github/workflows/assistant-to-the-branch-manager.yml b/.github/workflows/assistant-to-the-branch-manager.yml index f21e2612ef53..5466bf10b602 100644 --- a/.github/workflows/assistant-to-the-branch-manager.yml +++ b/.github/workflows/assistant-to-the-branch-manager.yml @@ -18,6 +18,6 @@ jobs: - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: persist-credentials: false - - uses: angular/dev-infra/github-actions/branch-manager@04230133d395dfb032d782b8e63b4fcbbd406aa5 # main + - uses: angular/dev-infra/github-actions/branch-manager@630fa0aa7ce9b7127b1ec4464b6af02d34f8154b # main with: angular-robot-key: ${{ secrets.ANGULAR_ROBOT_PRIVATE_KEY }} diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index eb33533f00e2..d8ccecaa8a26 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -21,9 +21,9 @@ jobs: runs-on: ubuntu-latest steps: - name: Initialize environment - uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@04230133d395dfb032d782b8e63b4fcbbd406aa5 # main + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@630fa0aa7ce9b7127b1ec4464b6af02d34f8154b # main - name: Setup Bazel - uses: angular/dev-infra/github-actions/bazel/setup@04230133d395dfb032d782b8e63b4fcbbd406aa5 # main + uses: angular/dev-infra/github-actions/bazel/setup@630fa0aa7ce9b7127b1ec4464b6af02d34f8154b # main - name: Install node modules run: pnpm install --frozen-lockfile - name: Generate JSON schema types @@ -44,11 +44,11 @@ jobs: runs-on: ubuntu-latest steps: - name: Initialize environment - uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@04230133d395dfb032d782b8e63b4fcbbd406aa5 # main + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@630fa0aa7ce9b7127b1ec4464b6af02d34f8154b # main - name: Setup Bazel - uses: angular/dev-infra/github-actions/bazel/setup@04230133d395dfb032d782b8e63b4fcbbd406aa5 # main + uses: angular/dev-infra/github-actions/bazel/setup@630fa0aa7ce9b7127b1ec4464b6af02d34f8154b # main - name: Setup Bazel RBE - uses: angular/dev-infra/github-actions/bazel/configure-remote@04230133d395dfb032d782b8e63b4fcbbd406aa5 # main + uses: angular/dev-infra/github-actions/bazel/configure-remote@630fa0aa7ce9b7127b1ec4464b6af02d34f8154b # main with: google_credential: ${{ secrets.RBE_TRUSTED_BUILDS_USER }} - name: Install node modules @@ -61,11 +61,11 @@ jobs: runs-on: ubuntu-latest steps: - name: Initialize environment - uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@04230133d395dfb032d782b8e63b4fcbbd406aa5 # main + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@630fa0aa7ce9b7127b1ec4464b6af02d34f8154b # main - name: Setup Bazel - uses: angular/dev-infra/github-actions/bazel/setup@04230133d395dfb032d782b8e63b4fcbbd406aa5 # main + uses: angular/dev-infra/github-actions/bazel/setup@630fa0aa7ce9b7127b1ec4464b6af02d34f8154b # main - name: Setup Bazel RBE - uses: angular/dev-infra/github-actions/bazel/configure-remote@04230133d395dfb032d782b8e63b4fcbbd406aa5 # main + uses: angular/dev-infra/github-actions/bazel/configure-remote@630fa0aa7ce9b7127b1ec4464b6af02d34f8154b # main with: google_credential: ${{ secrets.RBE_TRUSTED_BUILDS_USER }} - name: Install node modules @@ -84,13 +84,13 @@ jobs: runs-on: ubuntu-latest steps: - name: Initialize environment - uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@04230133d395dfb032d782b8e63b4fcbbd406aa5 # main + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@630fa0aa7ce9b7127b1ec4464b6af02d34f8154b # main - name: Install node modules run: pnpm install --frozen-lockfile - name: Setup Bazel - uses: angular/dev-infra/github-actions/bazel/setup@04230133d395dfb032d782b8e63b4fcbbd406aa5 # main + uses: angular/dev-infra/github-actions/bazel/setup@630fa0aa7ce9b7127b1ec4464b6af02d34f8154b # main - name: Setup Bazel RBE - uses: angular/dev-infra/github-actions/bazel/configure-remote@04230133d395dfb032d782b8e63b4fcbbd406aa5 # main + uses: angular/dev-infra/github-actions/bazel/configure-remote@630fa0aa7ce9b7127b1ec4464b6af02d34f8154b # main with: google_credential: ${{ secrets.RBE_TRUSTED_BUILDS_USER }} - name: Run CLI E2E tests @@ -100,11 +100,11 @@ jobs: runs-on: ubuntu-latest steps: - name: Initialize environment - uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@04230133d395dfb032d782b8e63b4fcbbd406aa5 # main + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@630fa0aa7ce9b7127b1ec4464b6af02d34f8154b # main - name: Setup Bazel - uses: angular/dev-infra/github-actions/bazel/setup@04230133d395dfb032d782b8e63b4fcbbd406aa5 # main + uses: angular/dev-infra/github-actions/bazel/setup@630fa0aa7ce9b7127b1ec4464b6af02d34f8154b # main - name: Setup Bazel RBE - uses: angular/dev-infra/github-actions/bazel/configure-remote@04230133d395dfb032d782b8e63b4fcbbd406aa5 # main + uses: angular/dev-infra/github-actions/bazel/configure-remote@630fa0aa7ce9b7127b1ec4464b6af02d34f8154b # main with: google_credential: ${{ secrets.RBE_TRUSTED_BUILDS_USER }} - name: Install node modules @@ -137,7 +137,7 @@ jobs: runs-on: windows-2025 steps: - name: Initialize environment - uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@04230133d395dfb032d782b8e63b4fcbbd406aa5 # main + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@630fa0aa7ce9b7127b1ec4464b6af02d34f8154b # main - name: Install node modules run: pnpm install --frozen-lockfile - name: Download built Windows E2E tests @@ -164,13 +164,13 @@ jobs: runs-on: ubuntu-latest steps: - name: Initialize environment - uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@04230133d395dfb032d782b8e63b4fcbbd406aa5 # main + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@630fa0aa7ce9b7127b1ec4464b6af02d34f8154b # main - name: Install node modules run: pnpm install --frozen-lockfile - name: Setup Bazel - uses: angular/dev-infra/github-actions/bazel/setup@04230133d395dfb032d782b8e63b4fcbbd406aa5 # main + uses: angular/dev-infra/github-actions/bazel/setup@630fa0aa7ce9b7127b1ec4464b6af02d34f8154b # main - name: Setup Bazel RBE - uses: angular/dev-infra/github-actions/bazel/configure-remote@04230133d395dfb032d782b8e63b4fcbbd406aa5 # main + uses: angular/dev-infra/github-actions/bazel/configure-remote@630fa0aa7ce9b7127b1ec4464b6af02d34f8154b # main with: google_credential: ${{ secrets.RBE_TRUSTED_BUILDS_USER }} - name: Run CLI E2E tests @@ -188,13 +188,13 @@ jobs: runs-on: ubuntu-latest steps: - name: Initialize environment - uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@04230133d395dfb032d782b8e63b4fcbbd406aa5 # main + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@630fa0aa7ce9b7127b1ec4464b6af02d34f8154b # main - name: Install node modules run: pnpm install --frozen-lockfile - name: Setup Bazel - uses: angular/dev-infra/github-actions/bazel/setup@04230133d395dfb032d782b8e63b4fcbbd406aa5 # main + uses: angular/dev-infra/github-actions/bazel/setup@630fa0aa7ce9b7127b1ec4464b6af02d34f8154b # main - name: Setup Bazel RBE - uses: angular/dev-infra/github-actions/bazel/configure-remote@04230133d395dfb032d782b8e63b4fcbbd406aa5 # main + uses: angular/dev-infra/github-actions/bazel/configure-remote@630fa0aa7ce9b7127b1ec4464b6af02d34f8154b # main with: google_credential: ${{ secrets.RBE_TRUSTED_BUILDS_USER }} - name: Run CLI E2E tests @@ -208,13 +208,13 @@ jobs: SAUCE_TUNNEL_IDENTIFIER: angular-cli-${{ github.workflow }}-${{ github.run_number }} steps: - name: Initialize environment - uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@04230133d395dfb032d782b8e63b4fcbbd406aa5 # main + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@630fa0aa7ce9b7127b1ec4464b6af02d34f8154b # main - name: Install node modules run: pnpm install --frozen-lockfile - name: Setup Bazel - uses: angular/dev-infra/github-actions/bazel/setup@04230133d395dfb032d782b8e63b4fcbbd406aa5 # main + uses: angular/dev-infra/github-actions/bazel/setup@630fa0aa7ce9b7127b1ec4464b6af02d34f8154b # main - name: Setup Bazel RBE - uses: angular/dev-infra/github-actions/bazel/configure-remote@04230133d395dfb032d782b8e63b4fcbbd406aa5 # main + uses: angular/dev-infra/github-actions/bazel/configure-remote@630fa0aa7ce9b7127b1ec4464b6af02d34f8154b # main with: google_credential: ${{ secrets.RBE_TRUSTED_BUILDS_USER }} - name: Start Sauce Connect @@ -245,11 +245,11 @@ jobs: CIRCLE_BRANCH: ${{ github.ref_name }} steps: - name: Initialize environment - uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@04230133d395dfb032d782b8e63b4fcbbd406aa5 # main + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@630fa0aa7ce9b7127b1ec4464b6af02d34f8154b # main - name: Install node modules run: pnpm install --frozen-lockfile - name: Setup Bazel - uses: angular/dev-infra/github-actions/bazel/setup@04230133d395dfb032d782b8e63b4fcbbd406aa5 # main + uses: angular/dev-infra/github-actions/bazel/setup@630fa0aa7ce9b7127b1ec4464b6af02d34f8154b # main - run: pnpm admin snapshots --verbose env: SNAPSHOT_BUILDS_GITHUB_TOKEN: ${{ secrets.SNAPSHOT_BUILDS_GITHUB_TOKEN }} diff --git a/.github/workflows/dev-infra.yml b/.github/workflows/dev-infra.yml index 2c9e701b95e2..a5f9bc649f1d 100644 --- a/.github/workflows/dev-infra.yml +++ b/.github/workflows/dev-infra.yml @@ -16,21 +16,21 @@ jobs: if: github.event_name == 'pull_request_target' runs-on: ubuntu-latest steps: - - uses: angular/dev-infra/github-actions/labeling/pull-request@04230133d395dfb032d782b8e63b4fcbbd406aa5 # main + - uses: angular/dev-infra/github-actions/labeling/pull-request@630fa0aa7ce9b7127b1ec4464b6af02d34f8154b # main with: angular-robot-key: ${{ secrets.ANGULAR_ROBOT_PRIVATE_KEY }} post_approval_changes: if: github.event_name == 'pull_request_target' runs-on: ubuntu-latest steps: - - uses: angular/dev-infra/github-actions/post-approval-changes@04230133d395dfb032d782b8e63b4fcbbd406aa5 # main + - uses: angular/dev-infra/github-actions/post-approval-changes@630fa0aa7ce9b7127b1ec4464b6af02d34f8154b # main with: angular-robot-key: ${{ secrets.ANGULAR_ROBOT_PRIVATE_KEY }} issue_labels: if: github.event_name == 'issues' runs-on: ubuntu-latest steps: - - uses: angular/dev-infra/github-actions/labeling/issue@04230133d395dfb032d782b8e63b4fcbbd406aa5 # main + - uses: angular/dev-infra/github-actions/labeling/issue@630fa0aa7ce9b7127b1ec4464b6af02d34f8154b # main with: angular-robot-key: ${{ secrets.ANGULAR_ROBOT_PRIVATE_KEY }} google-generative-ai-key: ${{ secrets.GOOGLE_GENERATIVE_AI_KEY }} diff --git a/.github/workflows/perf.yml b/.github/workflows/perf.yml index 591414f2e95a..a941fa92e40d 100644 --- a/.github/workflows/perf.yml +++ b/.github/workflows/perf.yml @@ -22,7 +22,7 @@ jobs: workflows: ${{ steps.workflows.outputs.workflows }} steps: - name: Initialize environment - uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@04230133d395dfb032d782b8e63b4fcbbd406aa5 # main + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@630fa0aa7ce9b7127b1ec4464b6af02d34f8154b # main - name: Install node modules run: pnpm install --frozen-lockfile - id: workflows @@ -40,9 +40,9 @@ jobs: workflow: ${{ fromJSON(needs.list.outputs.workflows) }} steps: - name: Initialize environment - uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@04230133d395dfb032d782b8e63b4fcbbd406aa5 # main + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@630fa0aa7ce9b7127b1ec4464b6af02d34f8154b # main - name: Setup Bazel - uses: angular/dev-infra/github-actions/bazel/setup@04230133d395dfb032d782b8e63b4fcbbd406aa5 # main + uses: angular/dev-infra/github-actions/bazel/setup@630fa0aa7ce9b7127b1ec4464b6af02d34f8154b # main - name: Install node modules run: pnpm install --frozen-lockfile # We utilize the google-github-actions/auth action to allow us to get an active credential using workflow diff --git a/.github/workflows/pr.yml b/.github/workflows/pr.yml index ad9364286682..6cfb86456745 100644 --- a/.github/workflows/pr.yml +++ b/.github/workflows/pr.yml @@ -34,9 +34,9 @@ jobs: runs-on: ubuntu-latest steps: - name: Initialize environment - uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@04230133d395dfb032d782b8e63b4fcbbd406aa5 # main + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@630fa0aa7ce9b7127b1ec4464b6af02d34f8154b # main - name: Setup Bazel - uses: angular/dev-infra/github-actions/bazel/setup@04230133d395dfb032d782b8e63b4fcbbd406aa5 # main + uses: angular/dev-infra/github-actions/bazel/setup@630fa0aa7ce9b7127b1ec4464b6af02d34f8154b # main - name: Setup ESLint Caching uses: actions/cache@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0 with: @@ -66,17 +66,17 @@ jobs: # it has been merged. run: pnpm ng-dev format changed --check ${{ github.event.pull_request.base.sha }} - name: Check Package Licenses - uses: angular/dev-infra/github-actions/linting/licenses@04230133d395dfb032d782b8e63b4fcbbd406aa5 # main + uses: angular/dev-infra/github-actions/linting/licenses@630fa0aa7ce9b7127b1ec4464b6af02d34f8154b # main build: runs-on: ubuntu-latest steps: - name: Initialize environment - uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@04230133d395dfb032d782b8e63b4fcbbd406aa5 # main + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@630fa0aa7ce9b7127b1ec4464b6af02d34f8154b # main - name: Setup Bazel - uses: angular/dev-infra/github-actions/bazel/setup@04230133d395dfb032d782b8e63b4fcbbd406aa5 # main + uses: angular/dev-infra/github-actions/bazel/setup@630fa0aa7ce9b7127b1ec4464b6af02d34f8154b # main - name: Setup Bazel RBE - uses: angular/dev-infra/github-actions/bazel/configure-remote@04230133d395dfb032d782b8e63b4fcbbd406aa5 # main + uses: angular/dev-infra/github-actions/bazel/configure-remote@630fa0aa7ce9b7127b1ec4464b6af02d34f8154b # main - name: Install node modules run: pnpm install --frozen-lockfile - name: Build release targets @@ -93,11 +93,11 @@ jobs: runs-on: ubuntu-latest steps: - name: Initialize environment - uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@04230133d395dfb032d782b8e63b4fcbbd406aa5 # main + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@630fa0aa7ce9b7127b1ec4464b6af02d34f8154b # main - name: Setup Bazel - uses: angular/dev-infra/github-actions/bazel/setup@04230133d395dfb032d782b8e63b4fcbbd406aa5 # main + uses: angular/dev-infra/github-actions/bazel/setup@630fa0aa7ce9b7127b1ec4464b6af02d34f8154b # main - name: Setup Bazel RBE - uses: angular/dev-infra/github-actions/bazel/configure-remote@04230133d395dfb032d782b8e63b4fcbbd406aa5 # main + uses: angular/dev-infra/github-actions/bazel/configure-remote@630fa0aa7ce9b7127b1ec4464b6af02d34f8154b # main - name: Install node modules run: pnpm install --frozen-lockfile - name: Run module and package tests @@ -114,13 +114,13 @@ jobs: runs-on: ubuntu-latest steps: - name: Initialize environment - uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@04230133d395dfb032d782b8e63b4fcbbd406aa5 # main + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@630fa0aa7ce9b7127b1ec4464b6af02d34f8154b # main - name: Install node modules run: pnpm install --frozen-lockfile - name: Setup Bazel - uses: angular/dev-infra/github-actions/bazel/setup@04230133d395dfb032d782b8e63b4fcbbd406aa5 # main + uses: angular/dev-infra/github-actions/bazel/setup@630fa0aa7ce9b7127b1ec4464b6af02d34f8154b # main - name: Setup Bazel RBE - uses: angular/dev-infra/github-actions/bazel/configure-remote@04230133d395dfb032d782b8e63b4fcbbd406aa5 # main + uses: angular/dev-infra/github-actions/bazel/configure-remote@630fa0aa7ce9b7127b1ec4464b6af02d34f8154b # main - name: Run CLI E2E tests run: pnpm bazel test --test_env=E2E_SHARD_TOTAL=6 --test_env=E2E_SHARD_INDEX=${{ matrix.shard }} --config=e2e //tests:e2e.${{ matrix.subset }}_node${{ matrix.node }} @@ -128,11 +128,11 @@ jobs: runs-on: ubuntu-latest steps: - name: Initialize environment - uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@04230133d395dfb032d782b8e63b4fcbbd406aa5 # main + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@630fa0aa7ce9b7127b1ec4464b6af02d34f8154b # main - name: Setup Bazel - uses: angular/dev-infra/github-actions/bazel/setup@04230133d395dfb032d782b8e63b4fcbbd406aa5 # main + uses: angular/dev-infra/github-actions/bazel/setup@630fa0aa7ce9b7127b1ec4464b6af02d34f8154b # main - name: Setup Bazel RBE - uses: angular/dev-infra/github-actions/bazel/configure-remote@04230133d395dfb032d782b8e63b4fcbbd406aa5 # main + uses: angular/dev-infra/github-actions/bazel/configure-remote@630fa0aa7ce9b7127b1ec4464b6af02d34f8154b # main - name: Install node modules run: pnpm install --frozen-lockfile - name: Build E2E tests for Windows on Linux @@ -156,7 +156,7 @@ jobs: runs-on: windows-2025 steps: - name: Initialize environment - uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@04230133d395dfb032d782b8e63b4fcbbd406aa5 # main + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@630fa0aa7ce9b7127b1ec4464b6af02d34f8154b # main - name: Install node modules run: pnpm install --frozen-lockfile - name: Download built Windows E2E tests @@ -183,13 +183,13 @@ jobs: runs-on: ubuntu-latest steps: - name: Initialize environment - uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@04230133d395dfb032d782b8e63b4fcbbd406aa5 # main + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@630fa0aa7ce9b7127b1ec4464b6af02d34f8154b # main - name: Install node modules run: pnpm install --frozen-lockfile - name: Setup Bazel - uses: angular/dev-infra/github-actions/bazel/setup@04230133d395dfb032d782b8e63b4fcbbd406aa5 # main + uses: angular/dev-infra/github-actions/bazel/setup@630fa0aa7ce9b7127b1ec4464b6af02d34f8154b # main - name: Setup Bazel RBE - uses: angular/dev-infra/github-actions/bazel/configure-remote@04230133d395dfb032d782b8e63b4fcbbd406aa5 # main + uses: angular/dev-infra/github-actions/bazel/configure-remote@630fa0aa7ce9b7127b1ec4464b6af02d34f8154b # main - name: Run CLI E2E tests run: pnpm bazel test --test_env=E2E_SHARD_TOTAL=3 --test_env=E2E_SHARD_INDEX=${{ matrix.shard }} --config=e2e //tests:e2e.${{ matrix.subset }}_node${{ matrix.node }} @@ -205,12 +205,12 @@ jobs: runs-on: ubuntu-latest steps: - name: Initialize environment - uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@04230133d395dfb032d782b8e63b4fcbbd406aa5 # main + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@630fa0aa7ce9b7127b1ec4464b6af02d34f8154b # main - name: Install node modules run: pnpm install --frozen-lockfile - name: Setup Bazel - uses: angular/dev-infra/github-actions/bazel/setup@04230133d395dfb032d782b8e63b4fcbbd406aa5 # main + uses: angular/dev-infra/github-actions/bazel/setup@630fa0aa7ce9b7127b1ec4464b6af02d34f8154b # main - name: Setup Bazel RBE - uses: angular/dev-infra/github-actions/bazel/configure-remote@04230133d395dfb032d782b8e63b4fcbbd406aa5 # main + uses: angular/dev-infra/github-actions/bazel/configure-remote@630fa0aa7ce9b7127b1ec4464b6af02d34f8154b # main - name: Run CLI E2E tests run: pnpm bazel test --test_env=E2E_SHARD_TOTAL=6 --test_env=E2E_SHARD_INDEX=${{ matrix.shard }} --config=e2e //tests:e2e.snapshots.${{ matrix.subset }}_node${{ matrix.node }} diff --git a/MODULE.bazel b/MODULE.bazel index 13363a8bf513..b69e4a74b0cf 100644 --- a/MODULE.bazel +++ b/MODULE.bazel @@ -19,21 +19,21 @@ bazel_dep(name = "aspect_rules_jasmine", version = "2.0.4") bazel_dep(name = "rules_angular") git_override( module_name = "rules_angular", - commit = "20a373d609c4f5765b9ad367a205f3a635dd2cda", + commit = "c1d74dbcda5f0ee9529dc78c485f34628c3985d5", remote = "https://github.com/angular/rules_angular.git", ) bazel_dep(name = "devinfra") git_override( module_name = "devinfra", - commit = "04230133d395dfb032d782b8e63b4fcbbd406aa5", + commit = "630fa0aa7ce9b7127b1ec4464b6af02d34f8154b", remote = "https://github.com/angular/dev-infra.git", ) bazel_dep(name = "rules_browsers") git_override( module_name = "rules_browsers", - commit = "37853f23de9a9a70f53c02a9baa27e08d7d12003", + commit = "5836240755b286b6224ecccb7045c318b1279def", remote = "https://github.com/angular/rules_browsers.git", ) diff --git a/MODULE.bazel.lock b/MODULE.bazel.lock index 4542fcb3d759..c78713d22533 100644 --- a/MODULE.bazel.lock +++ b/MODULE.bazel.lock @@ -18,19 +18,15 @@ "https://bcr.bazel.build/modules/aspect_bazel_lib/2.22.5/source.json": "ac2c3213df8f985785f1d0aeb7f0f73d5324e6e67d593d9b9470fb74a25d4a9b", "https://bcr.bazel.build/modules/aspect_bazel_lib/2.7.7/MODULE.bazel": "491f8681205e31bb57892d67442ce448cda4f472a8e6b3dc062865e29a64f89c", "https://bcr.bazel.build/modules/aspect_bazel_lib/2.8.1/MODULE.bazel": "812d2dd42f65dca362152101fbec418029cc8fd34cbad1a2fde905383d705838", - "https://bcr.bazel.build/modules/aspect_rules_esbuild/0.26.0/MODULE.bazel": "6c902d97038c3ab07b6c4e67c97abc61b20182fcfa84fa7dee82fc724f12e455", "https://bcr.bazel.build/modules/aspect_rules_esbuild/0.27.0/MODULE.bazel": "877dafc0b925f8af19e8bc2abed04a757bb565c57c1866e8851ac4d15ed5e6d2", "https://bcr.bazel.build/modules/aspect_rules_esbuild/0.27.0/source.json": "21f8738b3e62310ef43b7cef4284e1bafd69bd8e4e50251b71b20bbfed4372d8", "https://bcr.bazel.build/modules/aspect_rules_jasmine/2.0.4/MODULE.bazel": "fbb819eb8b7e5d7f67fdd38f7cecb413e287594cd666ce192c72c8828527775a", "https://bcr.bazel.build/modules/aspect_rules_jasmine/2.0.4/source.json": "81ffb708333cd98ec3c0b4cc004f4d5cf92a16914b5196a2892c45141bba7cff", "https://bcr.bazel.build/modules/aspect_rules_js/2.0.0/MODULE.bazel": "b45b507574aa60a92796e3e13c195cd5744b3b8aff516a9c0cb5ae6a048161c5", - "https://bcr.bazel.build/modules/aspect_rules_js/3.0.3/MODULE.bazel": "28a30e8fc33bf64a67835d64d124f6e05a7d59648dcb27b110fb3502f761e503", - "https://bcr.bazel.build/modules/aspect_rules_js/3.3.1/MODULE.bazel": "3e02b51b503ba8dda69b043290f6cc11add9aeb8db0bf1f6c861c396c7ddc5b2", "https://bcr.bazel.build/modules/aspect_rules_js/3.4.0/MODULE.bazel": "88844ac411e1961f4574a92f3c5be5b20d1c6997778c6b88316c5c3b4b60e284", "https://bcr.bazel.build/modules/aspect_rules_js/3.4.0/source.json": "85e5822f00dcbe64a1eda1324119e289c8c03cacb5c3695dffee16397b529078", "https://bcr.bazel.build/modules/aspect_rules_ts/3.10.0/MODULE.bazel": "69d06f57f30f4a2b6e53471584a9559d3b7cd7f891e1699876991230c7cabb95", "https://bcr.bazel.build/modules/aspect_rules_ts/3.10.0/source.json": "56f28a3ddb55ceaaf57a1ef8d7195136789ca1d72d0c8a6a9eeaad313be4099d", - "https://bcr.bazel.build/modules/aspect_rules_ts/3.9.2/MODULE.bazel": "feeb6c45b69c995eca3e5ca5872658c80df658022e01044eca00cf472bb89142", "https://bcr.bazel.build/modules/aspect_tools_telemetry/0.2.8/MODULE.bazel": "aa975a83e72bcaac62ee61ab12b788ea324a1d05c4aab28aadb202f647881679", "https://bcr.bazel.build/modules/aspect_tools_telemetry/0.3.3/MODULE.bazel": "37c764292861c2f70314efa9846bb6dbb44fc0308903b3285da6528305450183", "https://bcr.bazel.build/modules/aspect_tools_telemetry/0.4.2/MODULE.bazel": "f31aa84151d31e98cffd43eb7217ccff5ec52bdd5f2d10db8f053aeb23342eca", @@ -54,7 +50,6 @@ "https://bcr.bazel.build/modules/bazel_features/1.9.1/MODULE.bazel": "8f679097876a9b609ad1f60249c49d68bfab783dd9be012faf9d82547b14815a", "https://bcr.bazel.build/modules/bazel_lib/3.0.0-rc.0/MODULE.bazel": "d6e00979a98ac14ada5e31c8794708b41434d461e7e7ca39b59b765e6d233b18", "https://bcr.bazel.build/modules/bazel_lib/3.0.0/MODULE.bazel": "22b70b80ac89ad3f3772526cd9feee2fa412c2b01933fea7ed13238a448d370d", - "https://bcr.bazel.build/modules/bazel_lib/3.2.2/MODULE.bazel": "e2c890c8a515d6bca9c66d47718aa9e44b458fde64ec7204b8030bf2d349058c", "https://bcr.bazel.build/modules/bazel_lib/3.7.0/MODULE.bazel": "d7c10ed67f0f7f1fda179db8f86c22642581bd614882e1a50545fbe069525173", "https://bcr.bazel.build/modules/bazel_lib/3.7.1/MODULE.bazel": "b6fd9b2f8fab956420c11836f416efac4a70e20804ae384ebe62773a4ed70046", "https://bcr.bazel.build/modules/bazel_lib/3.7.1/source.json": "635fdaa28b50c04febc5e60ef51bc913d3bc87bfbaac7045449273c2341648cb", @@ -175,7 +170,6 @@ "https://bcr.bazel.build/modules/rules_nodejs/6.7.5/source.json": "d60ee5a76258b1c8f99545ed24172b44d43ba64ca1a2dfc04371ef203df19fdf", "https://bcr.bazel.build/modules/rules_pkg/0.7.0/MODULE.bazel": "df99f03fc7934a4737122518bb87e667e62d780b610910f0447665a7e2be62dc", "https://bcr.bazel.build/modules/rules_pkg/1.0.1/MODULE.bazel": "5b1df97dbc29623bccdf2b0dcd0f5cb08e2f2c9050aab1092fd39a41e82686ff", - "https://bcr.bazel.build/modules/rules_pkg/1.2.0/MODULE.bazel": "c7db3c2b407e673c7a39e3625dc05dc9f12d6682cbd82a3a5924a13b491eda7e", "https://bcr.bazel.build/modules/rules_pkg/1.3.0/MODULE.bazel": "ae0bdefbacc990c91f843206c90cf0f4be620639a5bf22119043599ba86d51a3", "https://bcr.bazel.build/modules/rules_pkg/1.3.0/source.json": "58ae84c545141762f7c434c0ce78bfb55ef0be08d84863e7f0503fff135fe4e2", "https://bcr.bazel.build/modules/rules_proto/4.0.0/MODULE.bazel": "a7a7b6ce9bee418c1a760b3d84f83a299ad6952f9903c67f19e4edd964894e06", @@ -191,7 +185,6 @@ "https://bcr.bazel.build/modules/rules_python/0.31.0/MODULE.bazel": "93a43dc47ee570e6ec9f5779b2e64c1476a6ce921c48cc9a1678a91dd5f8fd58", "https://bcr.bazel.build/modules/rules_python/0.4.0/MODULE.bazel": "9208ee05fd48bf09ac60ed269791cf17fb343db56c8226a720fbb1cdf467166c", "https://bcr.bazel.build/modules/rules_python/0.40.0/MODULE.bazel": "9d1a3cd88ed7d8e39583d9ffe56ae8a244f67783ae89b60caafc9f5cf318ada7", - "https://bcr.bazel.build/modules/rules_python/1.0.0/MODULE.bazel": "898a3d999c22caa585eb062b600f88654bf92efb204fa346fb55f6f8edffca43", "https://bcr.bazel.build/modules/rules_python/1.7.0/MODULE.bazel": "d01f995ecd137abf30238ad9ce97f8fc3ac57289c8b24bd0bf53324d937a14f8", "https://bcr.bazel.build/modules/rules_python/1.7.0/source.json": "028a084b65dcf8f4dc4f82f8778dbe65df133f234b316828a82e060d81bdce32", "https://bcr.bazel.build/modules/rules_shell/0.2.0/MODULE.bazel": "fda8a652ab3c7d8fee214de05e7a9916d8b28082234e8d2c0094505c5268ed3c", @@ -207,14 +200,12 @@ "https://bcr.bazel.build/modules/stardoc/0.7.2/MODULE.bazel": "fc152419aa2ea0f51c29583fab1e8c99ddefd5b3778421845606ee628629e0e5", "https://bcr.bazel.build/modules/stardoc/0.7.2/source.json": "58b029e5e901d6802967754adf0a9056747e8176f017cfe3607c0851f4d42216", "https://bcr.bazel.build/modules/tar.bzl/0.10.4/MODULE.bazel": "e8f9ff79199e8d9eaad7f1b0a77ad74b30bb82d794b87d8ca942bead5de83ae9", - "https://bcr.bazel.build/modules/tar.bzl/0.10.7/MODULE.bazel": "e06d0072c8adef7b9efbeec951d7e6b4b7e6bfa5845c3d8f402289c7b5d6331c", - "https://bcr.bazel.build/modules/tar.bzl/0.10.7/source.json": "c660155f239fcfadfb85f0b9ff304b95390632c15e3f6cb718cd3e08f2bb5c86", + "https://bcr.bazel.build/modules/tar.bzl/0.10.8/MODULE.bazel": "443884cabe241f640cfef256b1de2ccb116752895532900a4be9500e1124323f", + "https://bcr.bazel.build/modules/tar.bzl/0.10.8/source.json": "4173be64b38e471d92d2eb139a6496311de6de75e710f04edce78c43122c5419", "https://bcr.bazel.build/modules/tar.bzl/0.2.1/MODULE.bazel": "52d1c00a80a8cc67acbd01649e83d8dd6a9dc426a6c0b754a04fe8c219c76468", "https://bcr.bazel.build/modules/tar.bzl/0.5.1/MODULE.bazel": "7c2eb3dcfc53b0f3d6f9acdfd911ca803eaf92aadf54f8ca6e4c1f3aee288351", - "https://bcr.bazel.build/modules/tar.bzl/0.6.0/MODULE.bazel": "a3584b4edcfafcabd9b0ef9819808f05b372957bbdff41601429d5fd0aac2e7c", "https://bcr.bazel.build/modules/upb/0.0.0-20220923-a547704/MODULE.bazel": "7298990c00040a0e2f121f6c32544bab27d4452f80d9ce51349b1a28f3005c43", "https://bcr.bazel.build/modules/yq.bzl/0.1.1/MODULE.bazel": "9039681f9bcb8958ee2c87ffc74bdafba9f4369096a2b5634b88abc0eaefa072", - "https://bcr.bazel.build/modules/yq.bzl/0.3.2/MODULE.bazel": "0384efa70e8033d842ea73aa4b7199fa099709e236a7264345c03937166670b6", "https://bcr.bazel.build/modules/yq.bzl/0.3.4/MODULE.bazel": "d3a270662f5d766cd7229732d65a5a5bc485240c3007343dd279edfb60c9ae27", "https://bcr.bazel.build/modules/yq.bzl/0.3.6/MODULE.bazel": "985c2a0cb4ad9994bb0e33cc7fae931c91105eeefe3faa355b8f4c258d0607c0", "https://bcr.bazel.build/modules/yq.bzl/0.3.6/source.json": "678aaf6e291164f3cd761bb3e872e8a151248f413dbb63c5524a50b82a5bc890", diff --git a/modules/testing/builder/package.json b/modules/testing/builder/package.json index 1a7fa852247a..bcbbd0c6de59 100644 --- a/modules/testing/builder/package.json +++ b/modules/testing/builder/package.json @@ -8,7 +8,7 @@ "browser-sync": "3.0.4", "istanbul-lib-instrument": "6.0.3", "jsdom": "30.0.1", - "ng-packagr": "22.2.0-next.2", + "ng-packagr": "22.2.0-next.3", "rxjs": "7.8.2", "vitest": "4.1.10" } diff --git a/package.json b/package.json index d4a9d8d057bc..ad336b03eab5 100644 --- a/package.json +++ b/package.json @@ -42,23 +42,23 @@ }, "homepage": "https://github.com/angular/angular-cli", "dependencies": { - "@angular/compiler-cli": "22.2.0-next.1", + "@angular/compiler-cli": "22.2.0-next.2", "typescript": "6.0.3" }, "devDependencies": { - "@angular/animations": "22.2.0-next.1", - "@angular/cdk": "22.2.0-next.0", - "@angular/common": "22.2.0-next.1", - "@angular/compiler": "22.2.0-next.1", - "@angular/core": "22.2.0-next.1", - "@angular/forms": "22.2.0-next.1", - "@angular/localize": "22.2.0-next.1", - "@angular/material": "22.2.0-next.0", - "@angular/ng-dev": "https://github.com/angular/dev-infra-private-ng-dev-builds.git#c71d9b6af7560faa3d002534d416a8045111adae", - "@angular/platform-browser": "22.2.0-next.1", - "@angular/platform-server": "22.2.0-next.1", - "@angular/router": "22.2.0-next.1", - "@angular/service-worker": "22.2.0-next.1", + "@angular/animations": "22.2.0-next.2", + "@angular/cdk": "22.2.0-next.1", + "@angular/common": "22.2.0-next.2", + "@angular/compiler": "22.2.0-next.2", + "@angular/core": "22.2.0-next.2", + "@angular/forms": "22.2.0-next.2", + "@angular/localize": "22.2.0-next.2", + "@angular/material": "22.2.0-next.1", + "@angular/ng-dev": "https://github.com/angular/dev-infra-private-ng-dev-builds.git#fe8d168ef720af0b12276b21f820b2c93e3d342e", + "@angular/platform-browser": "22.2.0-next.2", + "@angular/platform-server": "22.2.0-next.2", + "@angular/router": "22.2.0-next.2", + "@angular/service-worker": "22.2.0-next.2", "@babel/core": "8.0.1", "@bazel/bazelisk": "1.28.1", "@bazel/buildifier": "8.2.1", diff --git a/packages/angular/build/package.json b/packages/angular/build/package.json index 0a3cc5cfad99..c0292af85e9c 100644 --- a/packages/angular/build/package.json +++ b/packages/angular/build/package.json @@ -55,7 +55,7 @@ "istanbul-lib-instrument": "6.0.3", "jsdom": "30.0.1", "less": "4.8.1", - "ng-packagr": "22.2.0-next.2", + "ng-packagr": "22.2.0-next.3", "postcss": "8.5.26", "rollup": "4.62.4", "rxjs": "7.8.2", diff --git a/packages/angular/ssr/package.json b/packages/angular/ssr/package.json index 303cfaa36d82..dcfe379438ff 100644 --- a/packages/angular/ssr/package.json +++ b/packages/angular/ssr/package.json @@ -37,12 +37,12 @@ }, "devDependencies": { "@angular-devkit/schematics": "workspace:*", - "@angular/common": "22.2.0-next.1", - "@angular/compiler": "22.2.0-next.1", - "@angular/core": "22.2.0-next.1", - "@angular/platform-browser": "22.2.0-next.1", - "@angular/platform-server": "22.2.0-next.1", - "@angular/router": "22.2.0-next.1", + "@angular/common": "22.2.0-next.2", + "@angular/compiler": "22.2.0-next.2", + "@angular/core": "22.2.0-next.2", + "@angular/platform-browser": "22.2.0-next.2", + "@angular/platform-server": "22.2.0-next.2", + "@angular/router": "22.2.0-next.2", "@schematics/angular": "workspace:*", "beasties": "0.4.3" }, diff --git a/packages/angular_devkit/build_angular/package.json b/packages/angular_devkit/build_angular/package.json index cf5aa84e20d0..fd9718dd3986 100644 --- a/packages/angular_devkit/build_angular/package.json +++ b/packages/angular_devkit/build_angular/package.json @@ -66,7 +66,7 @@ "devDependencies": { "@angular/ssr": "workspace:*", "browser-sync": "3.0.4", - "ng-packagr": "22.2.0-next.2", + "ng-packagr": "22.2.0-next.3", "undici": "8.10.0" }, "peerDependencies": { diff --git a/packages/ngtools/webpack/package.json b/packages/ngtools/webpack/package.json index bb226ae9aabd..911a2dca9d50 100644 --- a/packages/ngtools/webpack/package.json +++ b/packages/ngtools/webpack/package.json @@ -17,8 +17,8 @@ }, "devDependencies": { "@angular-devkit/core": "workspace:0.0.0-PLACEHOLDER", - "@angular/compiler": "22.2.0-next.1", - "@angular/compiler-cli": "22.2.0-next.1", + "@angular/compiler": "22.2.0-next.2", + "@angular/compiler-cli": "22.2.0-next.2", "typescript": "6.0.3", "webpack": "5.109.2" } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 9afe493732be..7f1641ea068d 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -14,8 +14,8 @@ importers: .: dependencies: '@angular/compiler-cli': - specifier: 22.2.0-next.1 - version: 22.2.0-next.1(@angular/compiler@22.2.0-next.1)(typescript@6.0.3) + specifier: 22.2.0-next.2 + version: 22.2.0-next.2(@angular/compiler@22.2.0-next.2)(typescript@6.0.3) typescript: specifier: 6.0.3 version: 6.0.3 @@ -26,44 +26,44 @@ importers: built: true devDependencies: '@angular/animations': - specifier: 22.2.0-next.1 - version: 22.2.0-next.1(@angular/core@22.2.0-next.1(@angular/compiler@22.2.0-next.1)(rxjs@7.8.2)(zone.js@0.16.2)) + specifier: 22.2.0-next.2 + version: 22.2.0-next.2(@angular/core@22.2.0-next.2(@angular/compiler@22.2.0-next.2)(rxjs@7.8.2)(zone.js@0.16.2)) '@angular/cdk': - specifier: 22.2.0-next.0 - version: 22.2.0-next.0(@angular/common@22.2.0-next.1(@angular/core@22.2.0-next.1(@angular/compiler@22.2.0-next.1)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2))(@angular/core@22.2.0-next.1(@angular/compiler@22.2.0-next.1)(rxjs@7.8.2)(zone.js@0.16.2))(@angular/platform-browser@22.2.0-next.1(@angular/animations@22.2.0-next.1(@angular/core@22.2.0-next.1(@angular/compiler@22.2.0-next.1)(rxjs@7.8.2)(zone.js@0.16.2)))(@angular/common@22.2.0-next.1(@angular/core@22.2.0-next.1(@angular/compiler@22.2.0-next.1)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2))(@angular/core@22.2.0-next.1(@angular/compiler@22.2.0-next.1)(rxjs@7.8.2)(zone.js@0.16.2)))(rxjs@7.8.2) - '@angular/common': specifier: 22.2.0-next.1 - version: 22.2.0-next.1(@angular/core@22.2.0-next.1(@angular/compiler@22.2.0-next.1)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2) + version: 22.2.0-next.1(@angular/common@22.2.0-next.2(@angular/core@22.2.0-next.2(@angular/compiler@22.2.0-next.2)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2))(@angular/core@22.2.0-next.2(@angular/compiler@22.2.0-next.2)(rxjs@7.8.2)(zone.js@0.16.2))(@angular/platform-browser@22.2.0-next.2(@angular/animations@22.2.0-next.2(@angular/core@22.2.0-next.2(@angular/compiler@22.2.0-next.2)(rxjs@7.8.2)(zone.js@0.16.2)))(@angular/common@22.2.0-next.2(@angular/core@22.2.0-next.2(@angular/compiler@22.2.0-next.2)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2))(@angular/core@22.2.0-next.2(@angular/compiler@22.2.0-next.2)(rxjs@7.8.2)(zone.js@0.16.2)))(rxjs@7.8.2) + '@angular/common': + specifier: 22.2.0-next.2 + version: 22.2.0-next.2(@angular/core@22.2.0-next.2(@angular/compiler@22.2.0-next.2)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2) '@angular/compiler': - specifier: 22.2.0-next.1 - version: 22.2.0-next.1 + specifier: 22.2.0-next.2 + version: 22.2.0-next.2 '@angular/core': - specifier: 22.2.0-next.1 - version: 22.2.0-next.1(@angular/compiler@22.2.0-next.1)(rxjs@7.8.2)(zone.js@0.16.2) + specifier: 22.2.0-next.2 + version: 22.2.0-next.2(@angular/compiler@22.2.0-next.2)(rxjs@7.8.2)(zone.js@0.16.2) '@angular/forms': - specifier: 22.2.0-next.1 - version: 22.2.0-next.1(@angular/common@22.2.0-next.1(@angular/core@22.2.0-next.1(@angular/compiler@22.2.0-next.1)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2))(@angular/core@22.2.0-next.1(@angular/compiler@22.2.0-next.1)(rxjs@7.8.2)(zone.js@0.16.2))(@angular/platform-browser@22.2.0-next.1(@angular/animations@22.2.0-next.1(@angular/core@22.2.0-next.1(@angular/compiler@22.2.0-next.1)(rxjs@7.8.2)(zone.js@0.16.2)))(@angular/common@22.2.0-next.1(@angular/core@22.2.0-next.1(@angular/compiler@22.2.0-next.1)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2))(@angular/core@22.2.0-next.1(@angular/compiler@22.2.0-next.1)(rxjs@7.8.2)(zone.js@0.16.2)))(rxjs@7.8.2) + specifier: 22.2.0-next.2 + version: 22.2.0-next.2(@angular/common@22.2.0-next.2(@angular/core@22.2.0-next.2(@angular/compiler@22.2.0-next.2)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2))(@angular/core@22.2.0-next.2(@angular/compiler@22.2.0-next.2)(rxjs@7.8.2)(zone.js@0.16.2))(@angular/platform-browser@22.2.0-next.2(@angular/animations@22.2.0-next.2(@angular/core@22.2.0-next.2(@angular/compiler@22.2.0-next.2)(rxjs@7.8.2)(zone.js@0.16.2)))(@angular/common@22.2.0-next.2(@angular/core@22.2.0-next.2(@angular/compiler@22.2.0-next.2)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2))(@angular/core@22.2.0-next.2(@angular/compiler@22.2.0-next.2)(rxjs@7.8.2)(zone.js@0.16.2)))(rxjs@7.8.2) '@angular/localize': - specifier: 22.2.0-next.1 - version: 22.2.0-next.1(@angular/compiler-cli@22.2.0-next.1(@angular/compiler@22.2.0-next.1)(typescript@6.0.3))(@angular/compiler@22.2.0-next.1) + specifier: 22.2.0-next.2 + version: 22.2.0-next.2(@angular/compiler-cli@22.2.0-next.2(@angular/compiler@22.2.0-next.2)(typescript@6.0.3))(@angular/compiler@22.2.0-next.2) '@angular/material': - specifier: 22.2.0-next.0 - version: 22.2.0-next.0(bde3c53bf3d1c9d6d40d1d641ef3b318) + specifier: 22.2.0-next.1 + version: 22.2.0-next.1(7f44ad9ccd852341470f4234c3737d66) '@angular/ng-dev': - specifier: https://github.com/angular/dev-infra-private-ng-dev-builds.git#c71d9b6af7560faa3d002534d416a8045111adae - version: https://codeload.github.com/angular/dev-infra-private-ng-dev-builds/tar.gz/c71d9b6af7560faa3d002534d416a8045111adae + specifier: https://github.com/angular/dev-infra-private-ng-dev-builds.git#fe8d168ef720af0b12276b21f820b2c93e3d342e + version: https://codeload.github.com/angular/dev-infra-private-ng-dev-builds/tar.gz/fe8d168ef720af0b12276b21f820b2c93e3d342e '@angular/platform-browser': - specifier: 22.2.0-next.1 - version: 22.2.0-next.1(@angular/animations@22.2.0-next.1(@angular/core@22.2.0-next.1(@angular/compiler@22.2.0-next.1)(rxjs@7.8.2)(zone.js@0.16.2)))(@angular/common@22.2.0-next.1(@angular/core@22.2.0-next.1(@angular/compiler@22.2.0-next.1)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2))(@angular/core@22.2.0-next.1(@angular/compiler@22.2.0-next.1)(rxjs@7.8.2)(zone.js@0.16.2)) + specifier: 22.2.0-next.2 + version: 22.2.0-next.2(@angular/animations@22.2.0-next.2(@angular/core@22.2.0-next.2(@angular/compiler@22.2.0-next.2)(rxjs@7.8.2)(zone.js@0.16.2)))(@angular/common@22.2.0-next.2(@angular/core@22.2.0-next.2(@angular/compiler@22.2.0-next.2)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2))(@angular/core@22.2.0-next.2(@angular/compiler@22.2.0-next.2)(rxjs@7.8.2)(zone.js@0.16.2)) '@angular/platform-server': - specifier: 22.2.0-next.1 - version: 22.2.0-next.1(@angular/common@22.2.0-next.1(@angular/core@22.2.0-next.1(@angular/compiler@22.2.0-next.1)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2))(@angular/compiler@22.2.0-next.1)(@angular/core@22.2.0-next.1(@angular/compiler@22.2.0-next.1)(rxjs@7.8.2)(zone.js@0.16.2))(@angular/platform-browser@22.2.0-next.1(@angular/animations@22.2.0-next.1(@angular/core@22.2.0-next.1(@angular/compiler@22.2.0-next.1)(rxjs@7.8.2)(zone.js@0.16.2)))(@angular/common@22.2.0-next.1(@angular/core@22.2.0-next.1(@angular/compiler@22.2.0-next.1)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2))(@angular/core@22.2.0-next.1(@angular/compiler@22.2.0-next.1)(rxjs@7.8.2)(zone.js@0.16.2)))(rxjs@7.8.2) + specifier: 22.2.0-next.2 + version: 22.2.0-next.2(@angular/common@22.2.0-next.2(@angular/core@22.2.0-next.2(@angular/compiler@22.2.0-next.2)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2))(@angular/compiler@22.2.0-next.2)(@angular/core@22.2.0-next.2(@angular/compiler@22.2.0-next.2)(rxjs@7.8.2)(zone.js@0.16.2))(@angular/platform-browser@22.2.0-next.2(@angular/animations@22.2.0-next.2(@angular/core@22.2.0-next.2(@angular/compiler@22.2.0-next.2)(rxjs@7.8.2)(zone.js@0.16.2)))(@angular/common@22.2.0-next.2(@angular/core@22.2.0-next.2(@angular/compiler@22.2.0-next.2)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2))(@angular/core@22.2.0-next.2(@angular/compiler@22.2.0-next.2)(rxjs@7.8.2)(zone.js@0.16.2)))(rxjs@7.8.2) '@angular/router': - specifier: 22.2.0-next.1 - version: 22.2.0-next.1(@angular/common@22.2.0-next.1(@angular/core@22.2.0-next.1(@angular/compiler@22.2.0-next.1)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2))(@angular/core@22.2.0-next.1(@angular/compiler@22.2.0-next.1)(rxjs@7.8.2)(zone.js@0.16.2))(@angular/platform-browser@22.2.0-next.1(@angular/animations@22.2.0-next.1(@angular/core@22.2.0-next.1(@angular/compiler@22.2.0-next.1)(rxjs@7.8.2)(zone.js@0.16.2)))(@angular/common@22.2.0-next.1(@angular/core@22.2.0-next.1(@angular/compiler@22.2.0-next.1)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2))(@angular/core@22.2.0-next.1(@angular/compiler@22.2.0-next.1)(rxjs@7.8.2)(zone.js@0.16.2)))(rxjs@7.8.2) + specifier: 22.2.0-next.2 + version: 22.2.0-next.2(@angular/common@22.2.0-next.2(@angular/core@22.2.0-next.2(@angular/compiler@22.2.0-next.2)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2))(@angular/core@22.2.0-next.2(@angular/compiler@22.2.0-next.2)(rxjs@7.8.2)(zone.js@0.16.2))(@angular/platform-browser@22.2.0-next.2(@angular/animations@22.2.0-next.2(@angular/core@22.2.0-next.2(@angular/compiler@22.2.0-next.2)(rxjs@7.8.2)(zone.js@0.16.2)))(@angular/common@22.2.0-next.2(@angular/core@22.2.0-next.2(@angular/compiler@22.2.0-next.2)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2))(@angular/core@22.2.0-next.2(@angular/compiler@22.2.0-next.2)(rxjs@7.8.2)(zone.js@0.16.2)))(rxjs@7.8.2) '@angular/service-worker': - specifier: 22.2.0-next.1 - version: 22.2.0-next.1(@angular/core@22.2.0-next.1(@angular/compiler@22.2.0-next.1)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2) + specifier: 22.2.0-next.2 + version: 22.2.0-next.2(@angular/core@22.2.0-next.2(@angular/compiler@22.2.0-next.2)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2) '@babel/core': specifier: 8.0.1 version: 8.0.1 @@ -314,14 +314,14 @@ importers: specifier: 30.0.1 version: 30.0.1 ng-packagr: - specifier: 22.2.0-next.2 - version: 22.2.0-next.2(@angular/compiler-cli@22.2.0-next.1(@angular/compiler@22.2.0-next.1)(typescript@6.0.3))(supports-color@11.0.0)(tslib@2.8.1)(typescript@6.0.3) + specifier: 22.2.0-next.3 + version: 22.2.0-next.3(@angular/compiler-cli@22.2.0-next.2(@angular/compiler@22.2.0-next.2)(typescript@6.0.3))(supports-color@11.0.0)(tslib@2.8.1)(typescript@6.0.3) rxjs: specifier: 7.8.2 version: 7.8.2 vitest: specifier: 4.1.10 - version: 4.1.10(@opentelemetry/api@1.9.1)(@types/node@22.20.1)(@vitest/coverage-v8@4.1.10)(esbuild@0.28.2)(jiti@2.7.0)(jsdom@30.0.1)(less@4.8.1(supports-color@11.0.0))(sass@1.102.0)(terser@5.50.0)(tsx@4.23.7)(yaml@2.9.0) + version: 4.1.10(@opentelemetry/api@1.9.1)(@types/node@22.20.1)(@vitest/coverage-v8@4.1.10)(esbuild@0.28.2)(jiti@2.7.0)(jsdom@30.0.1)(less@4.8.1(supports-color@11.0.0))(sass@1.102.0)(terser@5.50.0)(tsx@4.23.12)(yaml@2.9.0) packages/angular/build: dependencies: @@ -342,7 +342,7 @@ importers: version: 2.6.0 '@vitejs/plugin-basic-ssl': specifier: 2.3.0 - version: 2.3.0(vite@8.2.1(@types/node@22.20.1)(esbuild@0.28.2)(jiti@2.7.0)(less@4.8.1(supports-color@11.0.0))(sass@1.102.0)(terser@5.50.0)(tsx@4.23.7)(yaml@2.9.0)) + version: 2.3.0(vite@8.2.1(@types/node@22.20.1)(esbuild@0.28.2)(jiti@2.7.0)(less@4.8.1(supports-color@11.0.0))(sass@1.102.0)(terser@5.50.0)(tsx@4.23.12)(yaml@2.9.0)) beasties: specifier: 0.4.3 version: 0.4.3 @@ -399,7 +399,7 @@ importers: version: 0.2.17 vite: specifier: 8.2.1 - version: 8.2.1(@types/node@22.20.1)(esbuild@0.28.2)(jiti@2.7.0)(less@4.8.1(supports-color@11.0.0))(sass@1.102.0)(terser@5.50.0)(tsx@4.23.7)(yaml@2.9.0) + version: 8.2.1(@types/node@22.20.1)(esbuild@0.28.2)(jiti@2.7.0)(less@4.8.1(supports-color@11.0.0))(sass@1.102.0)(terser@5.50.0)(tsx@4.23.12)(yaml@2.9.0) xxhash-wasm: specifier: 1.1.0 version: 1.1.0 @@ -423,8 +423,8 @@ importers: specifier: 4.8.1 version: 4.8.1(supports-color@11.0.0) ng-packagr: - specifier: 22.2.0-next.2 - version: 22.2.0-next.2(@angular/compiler-cli@22.2.0-next.1(@angular/compiler@22.2.0-next.1)(typescript@6.0.3))(supports-color@11.0.0)(tslib@2.8.1)(typescript@6.0.3) + specifier: 22.2.0-next.3 + version: 22.2.0-next.3(@angular/compiler-cli@22.2.0-next.2(@angular/compiler@22.2.0-next.2)(typescript@6.0.3))(supports-color@11.0.0)(tslib@2.8.1)(typescript@6.0.3) postcss: specifier: 8.5.26 version: 8.5.26 @@ -436,7 +436,7 @@ importers: version: 7.8.2 vitest: specifier: 4.1.10 - version: 4.1.10(@opentelemetry/api@1.9.1)(@types/node@22.20.1)(@vitest/coverage-v8@4.1.10)(esbuild@0.28.2)(jiti@2.7.0)(jsdom@30.0.1)(less@4.8.1(supports-color@11.0.0))(sass@1.102.0)(terser@5.50.0)(tsx@4.23.7)(yaml@2.9.0) + version: 4.1.10(@opentelemetry/api@1.9.1)(@types/node@22.20.1)(@vitest/coverage-v8@4.1.10)(esbuild@0.28.2)(jiti@2.7.0)(jsdom@30.0.1)(less@4.8.1(supports-color@11.0.0))(sass@1.102.0)(terser@5.50.0)(tsx@4.23.12)(yaml@2.9.0) optionalDependencies: lmdb: specifier: 3.5.6 @@ -509,23 +509,23 @@ importers: specifier: workspace:* version: link:../../angular_devkit/schematics '@angular/common': - specifier: 22.2.0-next.1 - version: 22.2.0-next.1(@angular/core@22.2.0-next.1(@angular/compiler@22.2.0-next.1)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2) + specifier: 22.2.0-next.2 + version: 22.2.0-next.2(@angular/core@22.2.0-next.2(@angular/compiler@22.2.0-next.2)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2) '@angular/compiler': - specifier: 22.2.0-next.1 - version: 22.2.0-next.1 + specifier: 22.2.0-next.2 + version: 22.2.0-next.2 '@angular/core': - specifier: 22.2.0-next.1 - version: 22.2.0-next.1(@angular/compiler@22.2.0-next.1)(rxjs@7.8.2)(zone.js@0.16.2) + specifier: 22.2.0-next.2 + version: 22.2.0-next.2(@angular/compiler@22.2.0-next.2)(rxjs@7.8.2)(zone.js@0.16.2) '@angular/platform-browser': - specifier: 22.2.0-next.1 - version: 22.2.0-next.1(@angular/animations@22.2.0-next.1(@angular/core@22.2.0-next.1(@angular/compiler@22.2.0-next.1)(rxjs@7.8.2)(zone.js@0.16.2)))(@angular/common@22.2.0-next.1(@angular/core@22.2.0-next.1(@angular/compiler@22.2.0-next.1)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2))(@angular/core@22.2.0-next.1(@angular/compiler@22.2.0-next.1)(rxjs@7.8.2)(zone.js@0.16.2)) + specifier: 22.2.0-next.2 + version: 22.2.0-next.2(@angular/animations@22.2.0-next.2(@angular/core@22.2.0-next.2(@angular/compiler@22.2.0-next.2)(rxjs@7.8.2)(zone.js@0.16.2)))(@angular/common@22.2.0-next.2(@angular/core@22.2.0-next.2(@angular/compiler@22.2.0-next.2)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2))(@angular/core@22.2.0-next.2(@angular/compiler@22.2.0-next.2)(rxjs@7.8.2)(zone.js@0.16.2)) '@angular/platform-server': - specifier: 22.2.0-next.1 - version: 22.2.0-next.1(@angular/common@22.2.0-next.1(@angular/core@22.2.0-next.1(@angular/compiler@22.2.0-next.1)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2))(@angular/compiler@22.2.0-next.1)(@angular/core@22.2.0-next.1(@angular/compiler@22.2.0-next.1)(rxjs@7.8.2)(zone.js@0.16.2))(@angular/platform-browser@22.2.0-next.1(@angular/animations@22.2.0-next.1(@angular/core@22.2.0-next.1(@angular/compiler@22.2.0-next.1)(rxjs@7.8.2)(zone.js@0.16.2)))(@angular/common@22.2.0-next.1(@angular/core@22.2.0-next.1(@angular/compiler@22.2.0-next.1)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2))(@angular/core@22.2.0-next.1(@angular/compiler@22.2.0-next.1)(rxjs@7.8.2)(zone.js@0.16.2)))(rxjs@7.8.2) + specifier: 22.2.0-next.2 + version: 22.2.0-next.2(@angular/common@22.2.0-next.2(@angular/core@22.2.0-next.2(@angular/compiler@22.2.0-next.2)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2))(@angular/compiler@22.2.0-next.2)(@angular/core@22.2.0-next.2(@angular/compiler@22.2.0-next.2)(rxjs@7.8.2)(zone.js@0.16.2))(@angular/platform-browser@22.2.0-next.2(@angular/animations@22.2.0-next.2(@angular/core@22.2.0-next.2(@angular/compiler@22.2.0-next.2)(rxjs@7.8.2)(zone.js@0.16.2)))(@angular/common@22.2.0-next.2(@angular/core@22.2.0-next.2(@angular/compiler@22.2.0-next.2)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2))(@angular/core@22.2.0-next.2(@angular/compiler@22.2.0-next.2)(rxjs@7.8.2)(zone.js@0.16.2)))(rxjs@7.8.2) '@angular/router': - specifier: 22.2.0-next.1 - version: 22.2.0-next.1(@angular/common@22.2.0-next.1(@angular/core@22.2.0-next.1(@angular/compiler@22.2.0-next.1)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2))(@angular/core@22.2.0-next.1(@angular/compiler@22.2.0-next.1)(rxjs@7.8.2)(zone.js@0.16.2))(@angular/platform-browser@22.2.0-next.1(@angular/animations@22.2.0-next.1(@angular/core@22.2.0-next.1(@angular/compiler@22.2.0-next.1)(rxjs@7.8.2)(zone.js@0.16.2)))(@angular/common@22.2.0-next.1(@angular/core@22.2.0-next.1(@angular/compiler@22.2.0-next.1)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2))(@angular/core@22.2.0-next.1(@angular/compiler@22.2.0-next.1)(rxjs@7.8.2)(zone.js@0.16.2)))(rxjs@7.8.2) + specifier: 22.2.0-next.2 + version: 22.2.0-next.2(@angular/common@22.2.0-next.2(@angular/core@22.2.0-next.2(@angular/compiler@22.2.0-next.2)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2))(@angular/core@22.2.0-next.2(@angular/compiler@22.2.0-next.2)(rxjs@7.8.2)(zone.js@0.16.2))(@angular/platform-browser@22.2.0-next.2(@angular/animations@22.2.0-next.2(@angular/core@22.2.0-next.2(@angular/compiler@22.2.0-next.2)(rxjs@7.8.2)(zone.js@0.16.2)))(@angular/common@22.2.0-next.2(@angular/core@22.2.0-next.2(@angular/compiler@22.2.0-next.2)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2))(@angular/core@22.2.0-next.2(@angular/compiler@22.2.0-next.2)(rxjs@7.8.2)(zone.js@0.16.2)))(rxjs@7.8.2) '@schematics/angular': specifier: workspace:* version: link:../../schematics/angular @@ -711,8 +711,8 @@ importers: specifier: 3.0.4 version: 3.0.4(bufferutil@4.1.0)(debug@4.4.3(supports-color@11.0.0))(supports-color@11.0.0)(utf-8-validate@6.0.6) ng-packagr: - specifier: 22.2.0-next.2 - version: 22.2.0-next.2(@angular/compiler-cli@22.2.0-next.1(@angular/compiler@22.2.0-next.1)(typescript@6.0.3))(supports-color@11.0.0)(tslib@2.8.1)(typescript@6.0.3) + specifier: 22.2.0-next.3 + version: 22.2.0-next.3(@angular/compiler-cli@22.2.0-next.2(@angular/compiler@22.2.0-next.2)(typescript@6.0.3))(supports-color@11.0.0)(tslib@2.8.1)(typescript@6.0.3) undici: specifier: 8.10.0 version: 8.10.0 @@ -804,11 +804,11 @@ importers: specifier: workspace:0.0.0-PLACEHOLDER version: link:../../angular_devkit/core '@angular/compiler': - specifier: 22.2.0-next.1 - version: 22.2.0-next.1 + specifier: 22.2.0-next.2 + version: 22.2.0-next.2 '@angular/compiler-cli': - specifier: 22.2.0-next.1 - version: 22.2.0-next.1(@angular/compiler@22.2.0-next.1)(typescript@6.0.3) + specifier: 22.2.0-next.2 + version: 22.2.0-next.2(@angular/compiler@22.2.0-next.2)(typescript@6.0.3) typescript: specifier: 6.0.3 version: 6.0.3 @@ -861,47 +861,48 @@ packages: resolution: {integrity: sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==} engines: {node: '>=6.0.0'} - '@angular/animations@22.2.0-next.1': - resolution: {integrity: sha512-U/bJC3EaGW1AN7d95xvyYJ2XoC4jPLjLk6sI2KV5cKuCN0MnPX7WFa5qG+k/2KseXnaWqcEc5mLXC7oi1DkT0Q==} + '@angular/animations@22.2.0-next.2': + resolution: {integrity: sha512-3ULxhRd4PKVNHa4b0EFDY5N0UTyh9BT0QZ3T51AVZvHEzrZh9yXzY6UxZnLZl9Vaw6gA9a3sfV4j+nlVlU8T4A==} engines: {node: ^22.22.3 || ^24.15.0 || >=26.0.0} + deprecated: '@angular/animations is deprecated. Use `animate.enter` and `animate.leave` instead. For more information see: https://v22.angular.dev/guide/animations.' peerDependencies: - '@angular/core': 22.2.0-next.1 + '@angular/core': 22.2.0-next.2 - '@angular/cdk@22.2.0-next.0': - resolution: {integrity: sha512-l+Cniyp/qodyEMmWcYpXQ0zEOWzZ/zY+7ERn0dBGmjR3SJx3lPT+gqc6c99BSB9eOy4wldmxyLckpvKiNMSJoA==} + '@angular/cdk@22.2.0-next.1': + resolution: {integrity: sha512-4oiNpIiv89+0OPVmNKo17tmRUGumvT9+saaS+V2knTDSGmPEkvGo1APXP2dnzOQR5xuScdqsfXM0QXrkMH6otg==} peerDependencies: '@angular/common': ^22.0.0-0 || ^22.1.0-0 || ^22.2.0-0 || ^22.3.0-0 || ^23.0.0-0 '@angular/core': ^22.0.0-0 || ^22.1.0-0 || ^22.2.0-0 || ^22.3.0-0 || ^23.0.0-0 '@angular/platform-browser': ^22.0.0-0 || ^22.1.0-0 || ^22.2.0-0 || ^22.3.0-0 || ^23.0.0-0 rxjs: ^6.5.3 || ^7.4.0 - '@angular/common@22.2.0-next.1': - resolution: {integrity: sha512-LgLizDgJcXirUwWP2tEJ9MpUIi2RYnvT/SED9pus2t6JnlBoS1WocH7AkLfBQrsLckSv+g/3w82eGdwvwb0Zvg==} + '@angular/common@22.2.0-next.2': + resolution: {integrity: sha512-CPpjyvGwoSrZPbBACNJ+Ij5V2fXQ4GQLnJHBKLFHlMukNDRVOEBORnvde7zQDLW6b2p1/c8TQUEENS+2rPmJMQ==} engines: {node: ^22.22.3 || ^24.15.0 || >=26.0.0} peerDependencies: - '@angular/core': 22.2.0-next.1 + '@angular/core': 22.2.0-next.2 rxjs: ^6.5.3 || ^7.4.0 - '@angular/compiler-cli@22.2.0-next.1': - resolution: {integrity: sha512-wuqRIV8Mw85f0pz/VJfCsa9uJVfXjOdaLRP3pI51jZbHA2/eb/1MyL6HcAHk+SDesjtaDj0O4JMqyp6hR6DHJg==} + '@angular/compiler-cli@22.2.0-next.2': + resolution: {integrity: sha512-6OhigdUH65DlTmeEWHr6xosDl61tFPdSYwKf4IFAExWrko2MV48OL1tyjCoqgCxVwU+j989DgPCv7AMbcdBYuw==} engines: {node: ^22.22.3 || ^24.15.0 || >=26.0.0} hasBin: true peerDependencies: - '@angular/compiler': 22.2.0-next.1 + '@angular/compiler': 22.2.0-next.2 typescript: '>=6.0 <6.1' peerDependenciesMeta: typescript: optional: true - '@angular/compiler@22.2.0-next.1': - resolution: {integrity: sha512-rI10E7GcztbbW1j2CvvGYLdpZRYP3/u0AZSc+sjXi9KOUrSqzQ06qZF+opG1R4fXK+ExRhIdhtt5K3PpImuURQ==} + '@angular/compiler@22.2.0-next.2': + resolution: {integrity: sha512-aU7mOSLoZ3PiEhVMWvBbBN3/8BYHa12tbznnd6AGNWeid3I+IoRaGGP1S56D0nkg5jqS2UMQvwcdCT+Xft/0jA==} engines: {node: ^22.22.3 || ^24.15.0 || >=26.0.0} - '@angular/core@22.2.0-next.1': - resolution: {integrity: sha512-oVfjuVhS2zdfQD+3iH2doQ12Md+v5QMyn1xlvmqU79TWcRsyjps4sqErQBkQjM+InKWl4mrL+PSYiWX0w8ZhYA==} + '@angular/core@22.2.0-next.2': + resolution: {integrity: sha512-2vMX+uqYtwDwXGgKCUkm+6nBfKlLtTjTm3ojWuf2PJx0jKD5BFOW+RruzCN7bDy7a1Q2vt3lp6gcsdYGSJbHDg==} engines: {node: ^22.22.3 || ^24.15.0 || >=26.0.0} peerDependencies: - '@angular/compiler': 22.2.0-next.1 + '@angular/compiler': 22.2.0-next.2 rxjs: ^6.5.3 || ^7.4.0 zone.js: ~0.15.0 || ~0.16.0 peerDependenciesMeta: @@ -910,74 +911,74 @@ packages: zone.js: optional: true - '@angular/forms@22.2.0-next.1': - resolution: {integrity: sha512-PXN3Q9RNms2AGBDmBpGEnezZbFHvAhHUI9TjI0qVIJnf+4O65fNY/3YWgRV9J2YPgLqn+mTBZ0mbcGZh1OaMbA==} + '@angular/forms@22.2.0-next.2': + resolution: {integrity: sha512-X/ZAf1TNiA/iwB9HCLEQ4U1rnb+rRtD3NJChKsArPa8eV1OIAJLFFzGLD6xWxwfIwOkdjRHnVKvalmymE3hfHg==} engines: {node: ^22.22.3 || ^24.15.0 || >=26.0.0} peerDependencies: - '@angular/common': 22.2.0-next.1 - '@angular/core': 22.2.0-next.1 - '@angular/platform-browser': 22.2.0-next.1 + '@angular/common': 22.2.0-next.2 + '@angular/core': 22.2.0-next.2 + '@angular/platform-browser': 22.2.0-next.2 rxjs: ^6.5.3 || ^7.4.0 - '@angular/localize@22.2.0-next.1': - resolution: {integrity: sha512-YiWgksugSV4Exm8vMXJUBp5ceklY9SpLwPJqUjzxUXxpVIQeYwKHbfCJrogVh6yJDcgtNEJ+UL2gcNzDOdfd4w==} + '@angular/localize@22.2.0-next.2': + resolution: {integrity: sha512-l3QmUKbpJ+E1P1ewj2oxSnXp1wgqBfUSqwMtxCNd/+f14gJKRPiKh2hCchGDz4Jo3qxivp/CBXNkKA7BLP3LUw==} engines: {node: ^22.22.3 || ^24.15.0 || >=26.0.0} hasBin: true peerDependencies: - '@angular/compiler': 22.2.0-next.1 - '@angular/compiler-cli': 22.2.0-next.1 + '@angular/compiler': 22.2.0-next.2 + '@angular/compiler-cli': 22.2.0-next.2 - '@angular/material@22.2.0-next.0': - resolution: {integrity: sha512-knu75htSySpbPmH21njiNB19b4zXgVc9T/hWIF0WWorjpDKVLqgvHDJdxo34XYT764Hp32L7YxJwiwu08/e8eA==} + '@angular/material@22.2.0-next.1': + resolution: {integrity: sha512-qHtAzMC1wtxqIuXvY40PvNgaG4qVCe6GwoljfbqQpTYGKq7w+0fhXz6orw1oRNZU7sXPv1jP+M25YLJIaJoCiQ==} peerDependencies: - '@angular/cdk': 22.2.0-next.0 + '@angular/cdk': 22.2.0-next.1 '@angular/common': ^22.0.0-0 || ^22.1.0-0 || ^22.2.0-0 || ^22.3.0-0 || ^23.0.0-0 '@angular/core': ^22.0.0-0 || ^22.1.0-0 || ^22.2.0-0 || ^22.3.0-0 || ^23.0.0-0 '@angular/forms': ^22.0.0-0 || ^22.1.0-0 || ^22.2.0-0 || ^22.3.0-0 || ^23.0.0-0 '@angular/platform-browser': ^22.0.0-0 || ^22.1.0-0 || ^22.2.0-0 || ^22.3.0-0 || ^23.0.0-0 rxjs: ^6.5.3 || ^7.4.0 - '@angular/ng-dev@https://codeload.github.com/angular/dev-infra-private-ng-dev-builds/tar.gz/c71d9b6af7560faa3d002534d416a8045111adae': - resolution: {gitHosted: true, integrity: sha512-/32ipAQZed8P+Sgp4Hqk++iJpQVcwwvaCgRCD2fVJi1q17t9qUP+F66uthOE+MTQktgdTXg1Ayi3YWwJWBapnw==, tarball: https://codeload.github.com/angular/dev-infra-private-ng-dev-builds/tar.gz/c71d9b6af7560faa3d002534d416a8045111adae} - version: 0.0.0-92c6b596e59e320c9edbc6d6490c1047264c4a0d + '@angular/ng-dev@https://codeload.github.com/angular/dev-infra-private-ng-dev-builds/tar.gz/fe8d168ef720af0b12276b21f820b2c93e3d342e': + resolution: {gitHosted: true, integrity: sha512-6sQRCd29gx7lREERjAupLXS6orZKqCwNssMKW2YQYBYwulyLTK4G31M2yu5+m2Izly7VsfVQyeOVk+ZmD9j2jA==, tarball: https://codeload.github.com/angular/dev-infra-private-ng-dev-builds/tar.gz/fe8d168ef720af0b12276b21f820b2c93e3d342e} + version: 0.0.0-630fa0aa7ce9b7127b1ec4464b6af02d34f8154b hasBin: true - '@angular/platform-browser@22.2.0-next.1': - resolution: {integrity: sha512-jfemRcrDuPMz6KVseWK7yuzBRC5v85oa8jVhggaVJVzHH9diGAnMkoMJEtPOLDlB2LhtQuUlniOQWMydDUta4g==} + '@angular/platform-browser@22.2.0-next.2': + resolution: {integrity: sha512-/ivDdcWiGCktx/vpcOV7mZ2/GxJ6cx1oL+phCw/2OPZay9zAoPfTkWSZxrad+XPlEx838OhhE3Ezafos1yq7UQ==} engines: {node: ^22.22.3 || ^24.15.0 || >=26.0.0} peerDependencies: - '@angular/animations': 22.2.0-next.1 - '@angular/common': 22.2.0-next.1 - '@angular/core': 22.2.0-next.1 + '@angular/animations': 22.2.0-next.2 + '@angular/common': 22.2.0-next.2 + '@angular/core': 22.2.0-next.2 peerDependenciesMeta: '@angular/animations': optional: true - '@angular/platform-server@22.2.0-next.1': - resolution: {integrity: sha512-i21sVMfPvnT1lACnJEeWopOIC3mI6oGTRRTC3nMBfYjolbboyO6CkqdUl+PPA7GxCPVFzpwmrBbf2SdjXFoXxg==} + '@angular/platform-server@22.2.0-next.2': + resolution: {integrity: sha512-RDkHud6HSYg5jPpkHzUAj6v1Vo7h/9UlcDOFIwNmBLSbejw0GCZHcrK+OJwo/mJKMbSuTT9zMhMypxbZUKU6TA==} engines: {node: ^22.22.3 || ^24.15.0 || >=26.0.0} peerDependencies: - '@angular/common': 22.2.0-next.1 - '@angular/compiler': 22.2.0-next.1 - '@angular/core': 22.2.0-next.1 - '@angular/platform-browser': 22.2.0-next.1 + '@angular/common': 22.2.0-next.2 + '@angular/compiler': 22.2.0-next.2 + '@angular/core': 22.2.0-next.2 + '@angular/platform-browser': 22.2.0-next.2 rxjs: ^6.5.3 || ^7.4.0 - '@angular/router@22.2.0-next.1': - resolution: {integrity: sha512-JjQEm0A/TBSFAzw7QjrkmSYOODW9hIg0mJIC1xBV4Fjd7itZfCSnHKP2hmoWvs1ie8BwcvOE/YRNc+MSjsDGUA==} + '@angular/router@22.2.0-next.2': + resolution: {integrity: sha512-p9tpL7zLEVciOpO8BHcCJaRIM66tIBe+7FqdqCkssA/hBpZKiFkhGRD6N+KaN7lxIe77tnXgYGxKZpXkr9KJOw==} engines: {node: ^22.22.3 || ^24.15.0 || >=26.0.0} peerDependencies: - '@angular/common': 22.2.0-next.1 - '@angular/core': 22.2.0-next.1 - '@angular/platform-browser': 22.2.0-next.1 + '@angular/common': 22.2.0-next.2 + '@angular/core': 22.2.0-next.2 + '@angular/platform-browser': 22.2.0-next.2 rxjs: ^6.5.3 || ^7.4.0 - '@angular/service-worker@22.2.0-next.1': - resolution: {integrity: sha512-0Gh8/+pf7ZsSPS6IYPeFvh8v7SarVXexzYqrffjjQkwCJrN67B/AoYVG/99mPTe1ch7AQ6mxCrtoGmw4CNmZGw==} + '@angular/service-worker@22.2.0-next.2': + resolution: {integrity: sha512-B+P/w2+V6TAWegrxYNZ7Qs/6fPd8/xfqtL2MKW+tYg1VsMT0rzspl9zCyPwTZy4kZTqS/w/Rj6NCYO1JSnlvKQ==} engines: {node: ^22.22.3 || ^24.15.0 || >=26.0.0} hasBin: true peerDependencies: - '@angular/core': 22.2.0-next.1 + '@angular/core': 22.2.0-next.2 rxjs: ^6.5.3 || ^7.4.0 '@asamuzakjp/css-color@6.0.7': @@ -1568,12 +1569,12 @@ packages: resolution: {integrity: sha512-ooWCrlZP11i8GImSjTHYHLkvFDP48nS4+204nGb1RiX/WXYHmJA2III9/e2DWVabCESdW7hBAEzHRqUn9OUVvQ==} engines: {node: '>=0.1.90'} - '@conventional-changelog/git-client@3.1.0': - resolution: {integrity: sha512-Tqa/gHco2WJWa740NRjOrfKVvzIqxkZpecb8bemaQ8sKM5PXb1UK4uTyTb/1wIqNuOVaDOFxyBdhTIQZn6gdjQ==} + '@conventional-changelog/git-client@3.1.2': + resolution: {integrity: sha512-jZqwnJwf7nboIlAcw/mkOjVa6DexCcUOgT2oOQgkoi3z9vR8tGFkcMy2BFcYwjhL9sYcDDXkRQDayiDieCoW7A==} engines: {node: '>=22'} peerDependencies: conventional-commits-filter: ^6.0.1 - conventional-commits-parser: ^7.0.1 + conventional-commits-parser: ^7.1.2 peerDependenciesMeta: conventional-commits-filter: optional: true @@ -2100,8 +2101,8 @@ packages: resolution: {integrity: sha512-IJn+8A3QZJfe7FUtWqHVNo3xJs7KFpurCWGWCiCz3oEh+BkRymKZ1QxfAbU2yGMDzTytLGQ2IV6T2r3cuo75/w==} engines: {node: '>=18'} - '@google/genai@2.15.0': - resolution: {integrity: sha512-Q41TvqwBQ9NcmWdh6qxY5qrpg+0FaVHD7febQoH007pykxzco4ohScBUP4BBBy+Q8j5D8euIBSRIBDfWuNVCKA==} + '@google/genai@2.17.0': + resolution: {integrity: sha512-Cnw71bRtYXnGkN/K1YLb4Wz3yPwIe/7c5kw4VkbXAX508A9HHZCTMsBUhaAjTHDfD9Tn2veHxyJXK1Dxxtcx4g==} engines: {node: '>=20.0.0'} peerDependencies: '@modelcontextprotocol/sdk': ^1.25.2 @@ -6554,12 +6555,12 @@ packages: neo-async@2.6.2: resolution: {integrity: sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==} - ng-packagr@22.2.0-next.2: - resolution: {integrity: sha512-769/f4DvfQEm+SMNdKM9R/D/bulIHTwDJBPj7e3CE0fI/EjVNEigv1l3j00Ipm+AAEAZhxX5Q0A4JY0fmwKpJg==} + ng-packagr@22.2.0-next.3: + resolution: {integrity: sha512-bWjugQxxaZt1yWN/TxDCPbHwfuqHaAjD7blIZd7YDLAd32424JHWLFKqQwzi93NYYCUadSg8CU+LGiczZkuFsA==} engines: {node: ^22.22.3 || ^24.15.0 || >=26.0.0} hasBin: true peerDependencies: - '@angular/compiler-cli': ^22.0.0 || ^22.1.0-next || ^22.2.0-next + '@angular/compiler-cli': ^22.2.0-next tailwindcss: ^2.0.0 || ^3.0.0 || ^4.0.0 tslib: ^2.3.0 typescript: '>=6.0 <6.1' @@ -7197,13 +7198,13 @@ packages: resolution: {integrity: sha512-l0OE8wL34P4nJH/H2ffoaniAokM2qSmrtXHmlpvYr5AVVX8msAyW0l8NVJFDxlSK4u3Uh/f41cQheDVdnYijwQ==} hasBin: true - rolldown-plugin-dts@0.27.14: - resolution: {integrity: sha512-ZvuDDwoIpRK9RPxDXratCpklFO9QZZWndf/sd0VBFb4LEj0jj07UcHK9OCh7V4XiFz2Z89ziyBC2K6tJiDjrbw==} - engines: {node: ^22.18.0 || >=24.11.0} + rolldown-plugin-dts@0.28.2: + resolution: {integrity: sha512-U0Ng45ZaESZ7rJtQtgCWkJYCpMgH42yIj3xv9HGAsh/dJ8XBhjI4lcqh4NOWx8+CAxoY2HWg8VYINML2yE9A5A==} + engines: {node: ^22.18.0 || ^24.11.0 || >=26.0.0} peerDependencies: '@typescript/native-preview': '*' '@volar/typescript': ~2.4.0 - rolldown: ^1.0.0 + rolldown: ^1.2.0 typescript: ^5.0.0 || ^6.0.0 || ~7.0.0 vue-tsc: ~3.2.0 || ~3.3.0 peerDependenciesMeta: @@ -7771,8 +7772,8 @@ packages: tslib@2.8.1: resolution: {integrity: sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==} - tsx@4.23.7: - resolution: {integrity: sha512-3f/u/+UDCNQ7iwUZW9FCMnNGIHzElGJYh0S/yy8IvWSsn5O7fEO/897FaG7FA2W8yryiRyuwXZ1PYLAKYaqSuQ==} + tsx@4.23.12: + resolution: {integrity: sha512-FDf4L4sYzKtzWYhU/Xm0AQFdTjdIxNo9ElTf2mxXM6k8YMHXzYUe4yODVaXP4V9uMFbVg8c0qyBccK2OOxb45Q==} engines: {node: '>=18.0.0'} hasBin: true @@ -8350,29 +8351,29 @@ snapshots: '@jridgewell/gen-mapping': 0.3.13 '@jridgewell/trace-mapping': 0.3.31 - '@angular/animations@22.2.0-next.1(@angular/core@22.2.0-next.1(@angular/compiler@22.2.0-next.1)(rxjs@7.8.2)(zone.js@0.16.2))': + '@angular/animations@22.2.0-next.2(@angular/core@22.2.0-next.2(@angular/compiler@22.2.0-next.2)(rxjs@7.8.2)(zone.js@0.16.2))': dependencies: - '@angular/core': 22.2.0-next.1(@angular/compiler@22.2.0-next.1)(rxjs@7.8.2)(zone.js@0.16.2) + '@angular/core': 22.2.0-next.2(@angular/compiler@22.2.0-next.2)(rxjs@7.8.2)(zone.js@0.16.2) tslib: 2.8.1 - '@angular/cdk@22.2.0-next.0(@angular/common@22.2.0-next.1(@angular/core@22.2.0-next.1(@angular/compiler@22.2.0-next.1)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2))(@angular/core@22.2.0-next.1(@angular/compiler@22.2.0-next.1)(rxjs@7.8.2)(zone.js@0.16.2))(@angular/platform-browser@22.2.0-next.1(@angular/animations@22.2.0-next.1(@angular/core@22.2.0-next.1(@angular/compiler@22.2.0-next.1)(rxjs@7.8.2)(zone.js@0.16.2)))(@angular/common@22.2.0-next.1(@angular/core@22.2.0-next.1(@angular/compiler@22.2.0-next.1)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2))(@angular/core@22.2.0-next.1(@angular/compiler@22.2.0-next.1)(rxjs@7.8.2)(zone.js@0.16.2)))(rxjs@7.8.2)': + '@angular/cdk@22.2.0-next.1(@angular/common@22.2.0-next.2(@angular/core@22.2.0-next.2(@angular/compiler@22.2.0-next.2)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2))(@angular/core@22.2.0-next.2(@angular/compiler@22.2.0-next.2)(rxjs@7.8.2)(zone.js@0.16.2))(@angular/platform-browser@22.2.0-next.2(@angular/animations@22.2.0-next.2(@angular/core@22.2.0-next.2(@angular/compiler@22.2.0-next.2)(rxjs@7.8.2)(zone.js@0.16.2)))(@angular/common@22.2.0-next.2(@angular/core@22.2.0-next.2(@angular/compiler@22.2.0-next.2)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2))(@angular/core@22.2.0-next.2(@angular/compiler@22.2.0-next.2)(rxjs@7.8.2)(zone.js@0.16.2)))(rxjs@7.8.2)': dependencies: - '@angular/common': 22.2.0-next.1(@angular/core@22.2.0-next.1(@angular/compiler@22.2.0-next.1)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2) - '@angular/core': 22.2.0-next.1(@angular/compiler@22.2.0-next.1)(rxjs@7.8.2)(zone.js@0.16.2) - '@angular/platform-browser': 22.2.0-next.1(@angular/animations@22.2.0-next.1(@angular/core@22.2.0-next.1(@angular/compiler@22.2.0-next.1)(rxjs@7.8.2)(zone.js@0.16.2)))(@angular/common@22.2.0-next.1(@angular/core@22.2.0-next.1(@angular/compiler@22.2.0-next.1)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2))(@angular/core@22.2.0-next.1(@angular/compiler@22.2.0-next.1)(rxjs@7.8.2)(zone.js@0.16.2)) + '@angular/common': 22.2.0-next.2(@angular/core@22.2.0-next.2(@angular/compiler@22.2.0-next.2)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2) + '@angular/core': 22.2.0-next.2(@angular/compiler@22.2.0-next.2)(rxjs@7.8.2)(zone.js@0.16.2) + '@angular/platform-browser': 22.2.0-next.2(@angular/animations@22.2.0-next.2(@angular/core@22.2.0-next.2(@angular/compiler@22.2.0-next.2)(rxjs@7.8.2)(zone.js@0.16.2)))(@angular/common@22.2.0-next.2(@angular/core@22.2.0-next.2(@angular/compiler@22.2.0-next.2)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2))(@angular/core@22.2.0-next.2(@angular/compiler@22.2.0-next.2)(rxjs@7.8.2)(zone.js@0.16.2)) parse5: 8.0.1 rxjs: 7.8.2 tslib: 2.8.1 - '@angular/common@22.2.0-next.1(@angular/core@22.2.0-next.1(@angular/compiler@22.2.0-next.1)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2)': + '@angular/common@22.2.0-next.2(@angular/core@22.2.0-next.2(@angular/compiler@22.2.0-next.2)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2)': dependencies: - '@angular/core': 22.2.0-next.1(@angular/compiler@22.2.0-next.1)(rxjs@7.8.2)(zone.js@0.16.2) + '@angular/core': 22.2.0-next.2(@angular/compiler@22.2.0-next.2)(rxjs@7.8.2)(zone.js@0.16.2) rxjs: 7.8.2 tslib: 2.8.1 - '@angular/compiler-cli@22.2.0-next.1(@angular/compiler@22.2.0-next.1)(typescript@6.0.3)': + '@angular/compiler-cli@22.2.0-next.2(@angular/compiler@22.2.0-next.2)(typescript@6.0.3)': dependencies: - '@angular/compiler': 22.2.0-next.1 + '@angular/compiler': 22.2.0-next.2 '@babel/core': 8.0.1 '@jridgewell/sourcemap-codec': 1.5.5 chokidar: 5.0.0 @@ -8384,52 +8385,52 @@ snapshots: optionalDependencies: typescript: 6.0.3 - '@angular/compiler@22.2.0-next.1': + '@angular/compiler@22.2.0-next.2': dependencies: tslib: 2.8.1 - '@angular/core@22.2.0-next.1(@angular/compiler@22.2.0-next.1)(rxjs@7.8.2)(zone.js@0.16.2)': + '@angular/core@22.2.0-next.2(@angular/compiler@22.2.0-next.2)(rxjs@7.8.2)(zone.js@0.16.2)': dependencies: rxjs: 7.8.2 tslib: 2.8.1 optionalDependencies: - '@angular/compiler': 22.2.0-next.1 + '@angular/compiler': 22.2.0-next.2 zone.js: 0.16.2 - '@angular/forms@22.2.0-next.1(@angular/common@22.2.0-next.1(@angular/core@22.2.0-next.1(@angular/compiler@22.2.0-next.1)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2))(@angular/core@22.2.0-next.1(@angular/compiler@22.2.0-next.1)(rxjs@7.8.2)(zone.js@0.16.2))(@angular/platform-browser@22.2.0-next.1(@angular/animations@22.2.0-next.1(@angular/core@22.2.0-next.1(@angular/compiler@22.2.0-next.1)(rxjs@7.8.2)(zone.js@0.16.2)))(@angular/common@22.2.0-next.1(@angular/core@22.2.0-next.1(@angular/compiler@22.2.0-next.1)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2))(@angular/core@22.2.0-next.1(@angular/compiler@22.2.0-next.1)(rxjs@7.8.2)(zone.js@0.16.2)))(rxjs@7.8.2)': + '@angular/forms@22.2.0-next.2(@angular/common@22.2.0-next.2(@angular/core@22.2.0-next.2(@angular/compiler@22.2.0-next.2)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2))(@angular/core@22.2.0-next.2(@angular/compiler@22.2.0-next.2)(rxjs@7.8.2)(zone.js@0.16.2))(@angular/platform-browser@22.2.0-next.2(@angular/animations@22.2.0-next.2(@angular/core@22.2.0-next.2(@angular/compiler@22.2.0-next.2)(rxjs@7.8.2)(zone.js@0.16.2)))(@angular/common@22.2.0-next.2(@angular/core@22.2.0-next.2(@angular/compiler@22.2.0-next.2)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2))(@angular/core@22.2.0-next.2(@angular/compiler@22.2.0-next.2)(rxjs@7.8.2)(zone.js@0.16.2)))(rxjs@7.8.2)': dependencies: - '@angular/common': 22.2.0-next.1(@angular/core@22.2.0-next.1(@angular/compiler@22.2.0-next.1)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2) - '@angular/core': 22.2.0-next.1(@angular/compiler@22.2.0-next.1)(rxjs@7.8.2)(zone.js@0.16.2) - '@angular/platform-browser': 22.2.0-next.1(@angular/animations@22.2.0-next.1(@angular/core@22.2.0-next.1(@angular/compiler@22.2.0-next.1)(rxjs@7.8.2)(zone.js@0.16.2)))(@angular/common@22.2.0-next.1(@angular/core@22.2.0-next.1(@angular/compiler@22.2.0-next.1)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2))(@angular/core@22.2.0-next.1(@angular/compiler@22.2.0-next.1)(rxjs@7.8.2)(zone.js@0.16.2)) + '@angular/common': 22.2.0-next.2(@angular/core@22.2.0-next.2(@angular/compiler@22.2.0-next.2)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2) + '@angular/core': 22.2.0-next.2(@angular/compiler@22.2.0-next.2)(rxjs@7.8.2)(zone.js@0.16.2) + '@angular/platform-browser': 22.2.0-next.2(@angular/animations@22.2.0-next.2(@angular/core@22.2.0-next.2(@angular/compiler@22.2.0-next.2)(rxjs@7.8.2)(zone.js@0.16.2)))(@angular/common@22.2.0-next.2(@angular/core@22.2.0-next.2(@angular/compiler@22.2.0-next.2)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2))(@angular/core@22.2.0-next.2(@angular/compiler@22.2.0-next.2)(rxjs@7.8.2)(zone.js@0.16.2)) '@standard-schema/spec': 1.1.0 rxjs: 7.8.2 tslib: 2.8.1 zod: 4.4.3 - '@angular/localize@22.2.0-next.1(@angular/compiler-cli@22.2.0-next.1(@angular/compiler@22.2.0-next.1)(typescript@6.0.3))(@angular/compiler@22.2.0-next.1)': + '@angular/localize@22.2.0-next.2(@angular/compiler-cli@22.2.0-next.2(@angular/compiler@22.2.0-next.2)(typescript@6.0.3))(@angular/compiler@22.2.0-next.2)': dependencies: - '@angular/compiler': 22.2.0-next.1 - '@angular/compiler-cli': 22.2.0-next.1(@angular/compiler@22.2.0-next.1)(typescript@6.0.3) + '@angular/compiler': 22.2.0-next.2 + '@angular/compiler-cli': 22.2.0-next.2(@angular/compiler@22.2.0-next.2)(typescript@6.0.3) '@babel/core': 8.0.1 tinyglobby: 0.2.17 yargs: 18.1.0 - '@angular/material@22.2.0-next.0(bde3c53bf3d1c9d6d40d1d641ef3b318)': + '@angular/material@22.2.0-next.1(7f44ad9ccd852341470f4234c3737d66)': dependencies: - '@angular/cdk': 22.2.0-next.0(@angular/common@22.2.0-next.1(@angular/core@22.2.0-next.1(@angular/compiler@22.2.0-next.1)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2))(@angular/core@22.2.0-next.1(@angular/compiler@22.2.0-next.1)(rxjs@7.8.2)(zone.js@0.16.2))(@angular/platform-browser@22.2.0-next.1(@angular/animations@22.2.0-next.1(@angular/core@22.2.0-next.1(@angular/compiler@22.2.0-next.1)(rxjs@7.8.2)(zone.js@0.16.2)))(@angular/common@22.2.0-next.1(@angular/core@22.2.0-next.1(@angular/compiler@22.2.0-next.1)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2))(@angular/core@22.2.0-next.1(@angular/compiler@22.2.0-next.1)(rxjs@7.8.2)(zone.js@0.16.2)))(rxjs@7.8.2) - '@angular/common': 22.2.0-next.1(@angular/core@22.2.0-next.1(@angular/compiler@22.2.0-next.1)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2) - '@angular/core': 22.2.0-next.1(@angular/compiler@22.2.0-next.1)(rxjs@7.8.2)(zone.js@0.16.2) - '@angular/forms': 22.2.0-next.1(@angular/common@22.2.0-next.1(@angular/core@22.2.0-next.1(@angular/compiler@22.2.0-next.1)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2))(@angular/core@22.2.0-next.1(@angular/compiler@22.2.0-next.1)(rxjs@7.8.2)(zone.js@0.16.2))(@angular/platform-browser@22.2.0-next.1(@angular/animations@22.2.0-next.1(@angular/core@22.2.0-next.1(@angular/compiler@22.2.0-next.1)(rxjs@7.8.2)(zone.js@0.16.2)))(@angular/common@22.2.0-next.1(@angular/core@22.2.0-next.1(@angular/compiler@22.2.0-next.1)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2))(@angular/core@22.2.0-next.1(@angular/compiler@22.2.0-next.1)(rxjs@7.8.2)(zone.js@0.16.2)))(rxjs@7.8.2) - '@angular/platform-browser': 22.2.0-next.1(@angular/animations@22.2.0-next.1(@angular/core@22.2.0-next.1(@angular/compiler@22.2.0-next.1)(rxjs@7.8.2)(zone.js@0.16.2)))(@angular/common@22.2.0-next.1(@angular/core@22.2.0-next.1(@angular/compiler@22.2.0-next.1)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2))(@angular/core@22.2.0-next.1(@angular/compiler@22.2.0-next.1)(rxjs@7.8.2)(zone.js@0.16.2)) + '@angular/cdk': 22.2.0-next.1(@angular/common@22.2.0-next.2(@angular/core@22.2.0-next.2(@angular/compiler@22.2.0-next.2)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2))(@angular/core@22.2.0-next.2(@angular/compiler@22.2.0-next.2)(rxjs@7.8.2)(zone.js@0.16.2))(@angular/platform-browser@22.2.0-next.2(@angular/animations@22.2.0-next.2(@angular/core@22.2.0-next.2(@angular/compiler@22.2.0-next.2)(rxjs@7.8.2)(zone.js@0.16.2)))(@angular/common@22.2.0-next.2(@angular/core@22.2.0-next.2(@angular/compiler@22.2.0-next.2)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2))(@angular/core@22.2.0-next.2(@angular/compiler@22.2.0-next.2)(rxjs@7.8.2)(zone.js@0.16.2)))(rxjs@7.8.2) + '@angular/common': 22.2.0-next.2(@angular/core@22.2.0-next.2(@angular/compiler@22.2.0-next.2)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2) + '@angular/core': 22.2.0-next.2(@angular/compiler@22.2.0-next.2)(rxjs@7.8.2)(zone.js@0.16.2) + '@angular/forms': 22.2.0-next.2(@angular/common@22.2.0-next.2(@angular/core@22.2.0-next.2(@angular/compiler@22.2.0-next.2)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2))(@angular/core@22.2.0-next.2(@angular/compiler@22.2.0-next.2)(rxjs@7.8.2)(zone.js@0.16.2))(@angular/platform-browser@22.2.0-next.2(@angular/animations@22.2.0-next.2(@angular/core@22.2.0-next.2(@angular/compiler@22.2.0-next.2)(rxjs@7.8.2)(zone.js@0.16.2)))(@angular/common@22.2.0-next.2(@angular/core@22.2.0-next.2(@angular/compiler@22.2.0-next.2)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2))(@angular/core@22.2.0-next.2(@angular/compiler@22.2.0-next.2)(rxjs@7.8.2)(zone.js@0.16.2)))(rxjs@7.8.2) + '@angular/platform-browser': 22.2.0-next.2(@angular/animations@22.2.0-next.2(@angular/core@22.2.0-next.2(@angular/compiler@22.2.0-next.2)(rxjs@7.8.2)(zone.js@0.16.2)))(@angular/common@22.2.0-next.2(@angular/core@22.2.0-next.2(@angular/compiler@22.2.0-next.2)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2))(@angular/core@22.2.0-next.2(@angular/compiler@22.2.0-next.2)(rxjs@7.8.2)(zone.js@0.16.2)) rxjs: 7.8.2 tslib: 2.8.1 - '@angular/ng-dev@https://codeload.github.com/angular/dev-infra-private-ng-dev-builds/tar.gz/c71d9b6af7560faa3d002534d416a8045111adae': + '@angular/ng-dev@https://codeload.github.com/angular/dev-infra-private-ng-dev-builds/tar.gz/fe8d168ef720af0b12276b21f820b2c93e3d342e': dependencies: '@actions/core': 3.0.1 - '@conventional-changelog/git-client': 3.1.0(conventional-commits-filter@6.0.1)(conventional-commits-parser@7.1.2) + '@conventional-changelog/git-client': 3.1.2(conventional-commits-filter@6.0.1)(conventional-commits-parser@7.1.2) '@google-cloud/spanner': 8.0.0(supports-color@11.0.0) - '@google/genai': 2.15.0(bufferutil@4.1.0)(supports-color@11.0.0)(utf-8-validate@6.0.6) + '@google/genai': 2.17.0(bufferutil@4.1.0)(supports-color@11.0.0)(utf-8-validate@6.0.6) '@inquirer/prompts': 8.5.2(@types/node@24.13.3) '@inquirer/type': 4.0.7(@types/node@24.13.3) '@octokit/auth-app': 8.3.0 @@ -8472,7 +8473,7 @@ snapshots: nock: 14.0.17 semver: 7.8.5 supports-color: 11.0.0 - tsx: 4.23.7 + tsx: 4.23.12 typed-graphqlify: 3.1.6 typescript: 6.0.3 utf-8-validate: 6.0.6 @@ -8484,35 +8485,35 @@ snapshots: - '@modelcontextprotocol/sdk' - '@react-native-async-storage/async-storage' - '@angular/platform-browser@22.2.0-next.1(@angular/animations@22.2.0-next.1(@angular/core@22.2.0-next.1(@angular/compiler@22.2.0-next.1)(rxjs@7.8.2)(zone.js@0.16.2)))(@angular/common@22.2.0-next.1(@angular/core@22.2.0-next.1(@angular/compiler@22.2.0-next.1)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2))(@angular/core@22.2.0-next.1(@angular/compiler@22.2.0-next.1)(rxjs@7.8.2)(zone.js@0.16.2))': + '@angular/platform-browser@22.2.0-next.2(@angular/animations@22.2.0-next.2(@angular/core@22.2.0-next.2(@angular/compiler@22.2.0-next.2)(rxjs@7.8.2)(zone.js@0.16.2)))(@angular/common@22.2.0-next.2(@angular/core@22.2.0-next.2(@angular/compiler@22.2.0-next.2)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2))(@angular/core@22.2.0-next.2(@angular/compiler@22.2.0-next.2)(rxjs@7.8.2)(zone.js@0.16.2))': dependencies: - '@angular/common': 22.2.0-next.1(@angular/core@22.2.0-next.1(@angular/compiler@22.2.0-next.1)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2) - '@angular/core': 22.2.0-next.1(@angular/compiler@22.2.0-next.1)(rxjs@7.8.2)(zone.js@0.16.2) + '@angular/common': 22.2.0-next.2(@angular/core@22.2.0-next.2(@angular/compiler@22.2.0-next.2)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2) + '@angular/core': 22.2.0-next.2(@angular/compiler@22.2.0-next.2)(rxjs@7.8.2)(zone.js@0.16.2) tslib: 2.8.1 optionalDependencies: - '@angular/animations': 22.2.0-next.1(@angular/core@22.2.0-next.1(@angular/compiler@22.2.0-next.1)(rxjs@7.8.2)(zone.js@0.16.2)) + '@angular/animations': 22.2.0-next.2(@angular/core@22.2.0-next.2(@angular/compiler@22.2.0-next.2)(rxjs@7.8.2)(zone.js@0.16.2)) - '@angular/platform-server@22.2.0-next.1(@angular/common@22.2.0-next.1(@angular/core@22.2.0-next.1(@angular/compiler@22.2.0-next.1)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2))(@angular/compiler@22.2.0-next.1)(@angular/core@22.2.0-next.1(@angular/compiler@22.2.0-next.1)(rxjs@7.8.2)(zone.js@0.16.2))(@angular/platform-browser@22.2.0-next.1(@angular/animations@22.2.0-next.1(@angular/core@22.2.0-next.1(@angular/compiler@22.2.0-next.1)(rxjs@7.8.2)(zone.js@0.16.2)))(@angular/common@22.2.0-next.1(@angular/core@22.2.0-next.1(@angular/compiler@22.2.0-next.1)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2))(@angular/core@22.2.0-next.1(@angular/compiler@22.2.0-next.1)(rxjs@7.8.2)(zone.js@0.16.2)))(rxjs@7.8.2)': + '@angular/platform-server@22.2.0-next.2(@angular/common@22.2.0-next.2(@angular/core@22.2.0-next.2(@angular/compiler@22.2.0-next.2)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2))(@angular/compiler@22.2.0-next.2)(@angular/core@22.2.0-next.2(@angular/compiler@22.2.0-next.2)(rxjs@7.8.2)(zone.js@0.16.2))(@angular/platform-browser@22.2.0-next.2(@angular/animations@22.2.0-next.2(@angular/core@22.2.0-next.2(@angular/compiler@22.2.0-next.2)(rxjs@7.8.2)(zone.js@0.16.2)))(@angular/common@22.2.0-next.2(@angular/core@22.2.0-next.2(@angular/compiler@22.2.0-next.2)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2))(@angular/core@22.2.0-next.2(@angular/compiler@22.2.0-next.2)(rxjs@7.8.2)(zone.js@0.16.2)))(rxjs@7.8.2)': dependencies: - '@angular/common': 22.2.0-next.1(@angular/core@22.2.0-next.1(@angular/compiler@22.2.0-next.1)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2) - '@angular/compiler': 22.2.0-next.1 - '@angular/core': 22.2.0-next.1(@angular/compiler@22.2.0-next.1)(rxjs@7.8.2)(zone.js@0.16.2) - '@angular/platform-browser': 22.2.0-next.1(@angular/animations@22.2.0-next.1(@angular/core@22.2.0-next.1(@angular/compiler@22.2.0-next.1)(rxjs@7.8.2)(zone.js@0.16.2)))(@angular/common@22.2.0-next.1(@angular/core@22.2.0-next.1(@angular/compiler@22.2.0-next.1)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2))(@angular/core@22.2.0-next.1(@angular/compiler@22.2.0-next.1)(rxjs@7.8.2)(zone.js@0.16.2)) + '@angular/common': 22.2.0-next.2(@angular/core@22.2.0-next.2(@angular/compiler@22.2.0-next.2)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2) + '@angular/compiler': 22.2.0-next.2 + '@angular/core': 22.2.0-next.2(@angular/compiler@22.2.0-next.2)(rxjs@7.8.2)(zone.js@0.16.2) + '@angular/platform-browser': 22.2.0-next.2(@angular/animations@22.2.0-next.2(@angular/core@22.2.0-next.2(@angular/compiler@22.2.0-next.2)(rxjs@7.8.2)(zone.js@0.16.2)))(@angular/common@22.2.0-next.2(@angular/core@22.2.0-next.2(@angular/compiler@22.2.0-next.2)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2))(@angular/core@22.2.0-next.2(@angular/compiler@22.2.0-next.2)(rxjs@7.8.2)(zone.js@0.16.2)) rxjs: 7.8.2 tslib: 2.8.1 xhr2: 0.2.1 - '@angular/router@22.2.0-next.1(@angular/common@22.2.0-next.1(@angular/core@22.2.0-next.1(@angular/compiler@22.2.0-next.1)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2))(@angular/core@22.2.0-next.1(@angular/compiler@22.2.0-next.1)(rxjs@7.8.2)(zone.js@0.16.2))(@angular/platform-browser@22.2.0-next.1(@angular/animations@22.2.0-next.1(@angular/core@22.2.0-next.1(@angular/compiler@22.2.0-next.1)(rxjs@7.8.2)(zone.js@0.16.2)))(@angular/common@22.2.0-next.1(@angular/core@22.2.0-next.1(@angular/compiler@22.2.0-next.1)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2))(@angular/core@22.2.0-next.1(@angular/compiler@22.2.0-next.1)(rxjs@7.8.2)(zone.js@0.16.2)))(rxjs@7.8.2)': + '@angular/router@22.2.0-next.2(@angular/common@22.2.0-next.2(@angular/core@22.2.0-next.2(@angular/compiler@22.2.0-next.2)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2))(@angular/core@22.2.0-next.2(@angular/compiler@22.2.0-next.2)(rxjs@7.8.2)(zone.js@0.16.2))(@angular/platform-browser@22.2.0-next.2(@angular/animations@22.2.0-next.2(@angular/core@22.2.0-next.2(@angular/compiler@22.2.0-next.2)(rxjs@7.8.2)(zone.js@0.16.2)))(@angular/common@22.2.0-next.2(@angular/core@22.2.0-next.2(@angular/compiler@22.2.0-next.2)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2))(@angular/core@22.2.0-next.2(@angular/compiler@22.2.0-next.2)(rxjs@7.8.2)(zone.js@0.16.2)))(rxjs@7.8.2)': dependencies: - '@angular/common': 22.2.0-next.1(@angular/core@22.2.0-next.1(@angular/compiler@22.2.0-next.1)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2) - '@angular/core': 22.2.0-next.1(@angular/compiler@22.2.0-next.1)(rxjs@7.8.2)(zone.js@0.16.2) - '@angular/platform-browser': 22.2.0-next.1(@angular/animations@22.2.0-next.1(@angular/core@22.2.0-next.1(@angular/compiler@22.2.0-next.1)(rxjs@7.8.2)(zone.js@0.16.2)))(@angular/common@22.2.0-next.1(@angular/core@22.2.0-next.1(@angular/compiler@22.2.0-next.1)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2))(@angular/core@22.2.0-next.1(@angular/compiler@22.2.0-next.1)(rxjs@7.8.2)(zone.js@0.16.2)) + '@angular/common': 22.2.0-next.2(@angular/core@22.2.0-next.2(@angular/compiler@22.2.0-next.2)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2) + '@angular/core': 22.2.0-next.2(@angular/compiler@22.2.0-next.2)(rxjs@7.8.2)(zone.js@0.16.2) + '@angular/platform-browser': 22.2.0-next.2(@angular/animations@22.2.0-next.2(@angular/core@22.2.0-next.2(@angular/compiler@22.2.0-next.2)(rxjs@7.8.2)(zone.js@0.16.2)))(@angular/common@22.2.0-next.2(@angular/core@22.2.0-next.2(@angular/compiler@22.2.0-next.2)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2))(@angular/core@22.2.0-next.2(@angular/compiler@22.2.0-next.2)(rxjs@7.8.2)(zone.js@0.16.2)) rxjs: 7.8.2 tslib: 2.8.1 - '@angular/service-worker@22.2.0-next.1(@angular/core@22.2.0-next.1(@angular/compiler@22.2.0-next.1)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2)': + '@angular/service-worker@22.2.0-next.2(@angular/core@22.2.0-next.2(@angular/compiler@22.2.0-next.2)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2)': dependencies: - '@angular/core': 22.2.0-next.1(@angular/compiler@22.2.0-next.1)(rxjs@7.8.2)(zone.js@0.16.2) + '@angular/core': 22.2.0-next.2(@angular/compiler@22.2.0-next.2)(rxjs@7.8.2)(zone.js@0.16.2) rxjs: 7.8.2 tslib: 2.8.1 @@ -9218,7 +9219,7 @@ snapshots: '@colors/colors@1.5.0': {} - '@conventional-changelog/git-client@3.1.0(conventional-commits-filter@6.0.1)(conventional-commits-parser@7.1.2)': + '@conventional-changelog/git-client@3.1.2(conventional-commits-filter@6.0.1)(conventional-commits-parser@7.1.2)': dependencies: '@simple-libs/child-process-utils': 2.0.0 '@simple-libs/stream-utils': 2.0.0 @@ -9786,7 +9787,7 @@ snapshots: transitivePeerDependencies: - supports-color - '@google/genai@2.15.0(bufferutil@4.1.0)(supports-color@11.0.0)(utf-8-validate@6.0.6)': + '@google/genai@2.17.0(bufferutil@4.1.0)(supports-color@11.0.0)(utf-8-validate@6.0.6)': dependencies: google-auth-library: 10.9.1(supports-color@11.0.0) p-retry: 4.6.2 @@ -11478,9 +11479,9 @@ snapshots: lodash: 4.18.1 minimatch: 10.2.5 - '@vitejs/plugin-basic-ssl@2.3.0(vite@8.2.1(@types/node@22.20.1)(esbuild@0.28.2)(jiti@2.7.0)(less@4.8.1(supports-color@11.0.0))(sass@1.102.0)(terser@5.50.0)(tsx@4.23.7)(yaml@2.9.0))': + '@vitejs/plugin-basic-ssl@2.3.0(vite@8.2.1(@types/node@22.20.1)(esbuild@0.28.2)(jiti@2.7.0)(less@4.8.1(supports-color@11.0.0))(sass@1.102.0)(terser@5.50.0)(tsx@4.23.12)(yaml@2.9.0))': dependencies: - vite: 8.2.1(@types/node@22.20.1)(esbuild@0.28.2)(jiti@2.7.0)(less@4.8.1(supports-color@11.0.0))(sass@1.102.0)(terser@5.50.0)(tsx@4.23.7)(yaml@2.9.0) + vite: 8.2.1(@types/node@22.20.1)(esbuild@0.28.2)(jiti@2.7.0)(less@4.8.1(supports-color@11.0.0))(sass@1.102.0)(terser@5.50.0)(tsx@4.23.12)(yaml@2.9.0) '@vitest/coverage-v8@4.1.10(vitest@4.1.10)': dependencies: @@ -11494,7 +11495,7 @@ snapshots: obug: 2.1.4 std-env: 4.2.0 tinyrainbow: 3.1.1 - vitest: 4.1.10(@opentelemetry/api@1.9.1)(@types/node@22.20.1)(@vitest/coverage-v8@4.1.10)(esbuild@0.28.2)(jiti@2.7.0)(jsdom@30.0.1)(less@4.8.1(supports-color@11.0.0))(sass@1.102.0)(terser@5.50.0)(tsx@4.23.7)(yaml@2.9.0) + vitest: 4.1.10(@opentelemetry/api@1.9.1)(@types/node@22.20.1)(@vitest/coverage-v8@4.1.10)(esbuild@0.28.2)(jiti@2.7.0)(jsdom@30.0.1)(less@4.8.1(supports-color@11.0.0))(sass@1.102.0)(terser@5.50.0)(tsx@4.23.12)(yaml@2.9.0) '@vitest/expect@4.1.10': dependencies: @@ -11505,13 +11506,13 @@ snapshots: chai: 6.2.2 tinyrainbow: 3.1.1 - '@vitest/mocker@4.1.10(vite@8.2.1(@types/node@22.20.1)(esbuild@0.28.2)(jiti@2.7.0)(less@4.8.1(supports-color@11.0.0))(sass@1.102.0)(terser@5.50.0)(tsx@4.23.7)(yaml@2.9.0))': + '@vitest/mocker@4.1.10(vite@8.2.1(@types/node@22.20.1)(esbuild@0.28.2)(jiti@2.7.0)(less@4.8.1(supports-color@11.0.0))(sass@1.102.0)(terser@5.50.0)(tsx@4.23.12)(yaml@2.9.0))': dependencies: '@vitest/spy': 4.1.10 estree-walker: 3.0.3 magic-string: 0.30.21 optionalDependencies: - vite: 8.2.1(@types/node@22.20.1)(esbuild@0.28.2)(jiti@2.7.0)(less@4.8.1(supports-color@11.0.0))(sass@1.102.0)(terser@5.50.0)(tsx@4.23.7)(yaml@2.9.0) + vite: 8.2.1(@types/node@22.20.1)(esbuild@0.28.2)(jiti@2.7.0)(less@4.8.1(supports-color@11.0.0))(sass@1.102.0)(terser@5.50.0)(tsx@4.23.12)(yaml@2.9.0) '@vitest/pretty-format@4.1.10': dependencies: @@ -14597,10 +14598,10 @@ snapshots: neo-async@2.6.2: {} - ng-packagr@22.2.0-next.2(@angular/compiler-cli@22.2.0-next.1(@angular/compiler@22.2.0-next.1)(typescript@6.0.3))(supports-color@11.0.0)(tslib@2.8.1)(typescript@6.0.3): + ng-packagr@22.2.0-next.3(@angular/compiler-cli@22.2.0-next.2(@angular/compiler@22.2.0-next.2)(typescript@6.0.3))(supports-color@11.0.0)(tslib@2.8.1)(typescript@6.0.3): dependencies: '@ampproject/remapping': 2.3.0 - '@angular/compiler-cli': 22.2.0-next.1(@angular/compiler@22.2.0-next.1)(typescript@6.0.3) + '@angular/compiler-cli': 22.2.0-next.2(@angular/compiler@22.2.0-next.2)(typescript@6.0.3) ajv: 8.20.0 browserslist: 4.28.8 chokidar: 5.0.0 @@ -14615,7 +14616,7 @@ snapshots: piscina: 5.3.0 postcss: 8.5.26 rolldown: 1.2.4 - rolldown-plugin-dts: 0.27.14(rolldown@1.2.4)(typescript@6.0.3) + rolldown-plugin-dts: 0.28.2(rolldown@1.2.4)(typescript@6.0.3) rxjs: 7.8.2 sass: 1.102.0 tinyglobby: 0.2.17 @@ -15339,7 +15340,7 @@ snapshots: dependencies: glob: 10.5.0 - rolldown-plugin-dts@0.27.14(rolldown@1.2.4)(typescript@6.0.3): + rolldown-plugin-dts@0.28.2(rolldown@1.2.4)(typescript@6.0.3): dependencies: dts-resolver: 3.0.0 get-tsconfig: 5.0.0-beta.5 @@ -16050,7 +16051,7 @@ snapshots: tslib@2.8.1: {} - tsx@4.23.7: + tsx@4.23.12: dependencies: esbuild: 0.28.2 optionalDependencies: @@ -16297,7 +16298,7 @@ snapshots: core-util-is: 1.0.2 extsprintf: 1.3.0 - vite@8.2.1(@types/node@22.20.1)(esbuild@0.28.2)(jiti@2.7.0)(less@4.8.1(supports-color@11.0.0))(sass@1.102.0)(terser@5.50.0)(tsx@4.23.7)(yaml@2.9.0): + vite@8.2.1(@types/node@22.20.1)(esbuild@0.28.2)(jiti@2.7.0)(less@4.8.1(supports-color@11.0.0))(sass@1.102.0)(terser@5.50.0)(tsx@4.23.12)(yaml@2.9.0): dependencies: lightningcss: 1.33.0 picomatch: 4.0.5 @@ -16312,13 +16313,13 @@ snapshots: less: 4.8.1(supports-color@11.0.0) sass: 1.102.0 terser: 5.50.0 - tsx: 4.23.7 + tsx: 4.23.12 yaml: 2.9.0 - vitest@4.1.10(@opentelemetry/api@1.9.1)(@types/node@22.20.1)(@vitest/coverage-v8@4.1.10)(esbuild@0.28.2)(jiti@2.7.0)(jsdom@30.0.1)(less@4.8.1(supports-color@11.0.0))(sass@1.102.0)(terser@5.50.0)(tsx@4.23.7)(yaml@2.9.0): + vitest@4.1.10(@opentelemetry/api@1.9.1)(@types/node@22.20.1)(@vitest/coverage-v8@4.1.10)(esbuild@0.28.2)(jiti@2.7.0)(jsdom@30.0.1)(less@4.8.1(supports-color@11.0.0))(sass@1.102.0)(terser@5.50.0)(tsx@4.23.12)(yaml@2.9.0): dependencies: '@vitest/expect': 4.1.10 - '@vitest/mocker': 4.1.10(vite@8.2.1(@types/node@22.20.1)(esbuild@0.28.2)(jiti@2.7.0)(less@4.8.1(supports-color@11.0.0))(sass@1.102.0)(terser@5.50.0)(tsx@4.23.7)(yaml@2.9.0)) + '@vitest/mocker': 4.1.10(vite@8.2.1(@types/node@22.20.1)(esbuild@0.28.2)(jiti@2.7.0)(less@4.8.1(supports-color@11.0.0))(sass@1.102.0)(terser@5.50.0)(tsx@4.23.12)(yaml@2.9.0)) '@vitest/pretty-format': 4.1.10 '@vitest/runner': 4.1.10 '@vitest/snapshot': 4.1.10 @@ -16335,7 +16336,7 @@ snapshots: tinyexec: 1.3.0 tinyglobby: 0.2.17 tinyrainbow: 3.1.1 - vite: 8.2.1(@types/node@22.20.1)(esbuild@0.28.2)(jiti@2.7.0)(less@4.8.1(supports-color@11.0.0))(sass@1.102.0)(terser@5.50.0)(tsx@4.23.7)(yaml@2.9.0) + vite: 8.2.1(@types/node@22.20.1)(esbuild@0.28.2)(jiti@2.7.0)(less@4.8.1(supports-color@11.0.0))(sass@1.102.0)(terser@5.50.0)(tsx@4.23.12)(yaml@2.9.0) why-is-node-running: 2.3.0 optionalDependencies: '@opentelemetry/api': 1.9.1 diff --git a/tests/e2e/ng-snapshot/package.json b/tests/e2e/ng-snapshot/package.json index cda05c14524e..a8f75125d9ab 100644 --- a/tests/e2e/ng-snapshot/package.json +++ b/tests/e2e/ng-snapshot/package.json @@ -2,21 +2,21 @@ "description": "snapshot versions of Angular for e2e testing", "private": true, "dependencies": { - "@angular/animations": "github:angular/animations-builds#cf2ec5af8a4a8dadacce5be2f96a453842f7f90a", - "@angular/cdk": "github:angular/cdk-builds#07799f06e6928c1f05acb33a41bc8461932bda57", - "@angular/common": "github:angular/common-builds#5e26e29114bb870784405f940cb8226c50df6a77", - "@angular/compiler": "github:angular/compiler-builds#e9d2fa722fc4f00d82bcc63c842133476a4dc96f", - "@angular/compiler-cli": "github:angular/compiler-cli-builds#e511b19996cfdb8c552cccc95e17a1af2b509f85", - "@angular/core": "github:angular/core-builds#76b8a976542628eb465f00c044c322e0a71597bb", - "@angular/forms": "github:angular/forms-builds#3c6be983edb9068c47164ac72e4b09640a8a64bc", - "@angular/language-service": "github:angular/language-service-builds#a22cd6c1c9d59f4b6a8db500e43b3ba470d7f308", - "@angular/localize": "github:angular/localize-builds#200d3ad4a53945f8763ecaa39a25fc7647a9db98", - "@angular/material": "github:angular/material-builds#4070f117b4ed1731d5baa3eafc966c18843150dc", - "@angular/material-moment-adapter": "github:angular/material-moment-adapter-builds#3cb5c085aa13369bc3d4e280e6a92cb58a71b7fc", - "@angular/platform-browser": "github:angular/platform-browser-builds#b2a6528a4e1790430e45274395bbd18eab8eabec", - "@angular/platform-browser-dynamic": "github:angular/platform-browser-dynamic-builds#1990f26fa35883d83038d670a67d626d431008e3", - "@angular/platform-server": "github:angular/platform-server-builds#b5820a9bca65205c659c8a637b6e00228a3a89cc", - "@angular/router": "github:angular/router-builds#0d8517df48781d4d444cb941b113809908759504", - "@angular/service-worker": "github:angular/service-worker-builds#71a961887bd5db07d5a8294b2f71742fce3bb1a7" + "@angular/animations": "github:angular/animations-builds#316c84ff609bd60bd8e68a7a568d2ef9721fe0b6", + "@angular/cdk": "github:angular/cdk-builds#445a5a7b0b463a3bfda71c36f3631c60d8789791", + "@angular/common": "github:angular/common-builds#88897d953d1536c9b21f63683e4c64f7cc3de95c", + "@angular/compiler": "github:angular/compiler-builds#68079220681fccae119518abb118282e9edd442e", + "@angular/compiler-cli": "github:angular/compiler-cli-builds#cbdb69028d5bf1c216ef879ebda156d714a87798", + "@angular/core": "github:angular/core-builds#e761242e59fc7c15762d22a65d0d735919a46955", + "@angular/forms": "github:angular/forms-builds#acd664701770abb63878d3f412be116fbd005fa4", + "@angular/language-service": "github:angular/language-service-builds#71c927e4dc87023b7e719e11d6198f3557c46808", + "@angular/localize": "github:angular/localize-builds#947193a6e8a45616d742681ec418cd45990fb6a2", + "@angular/material": "github:angular/material-builds#6b4a1bcbdfac14a16386130370451993771162b5", + "@angular/material-moment-adapter": "github:angular/material-moment-adapter-builds#2aeb092a67a59fa0e8a3efdceec165166803811a", + "@angular/platform-browser": "github:angular/platform-browser-builds#47eb4cd3c3716344928a4190fa002e0a25c22bea", + "@angular/platform-browser-dynamic": "github:angular/platform-browser-dynamic-builds#a4c26f0799c893d59f0428a3d0ca9cb3b969e6eb", + "@angular/platform-server": "github:angular/platform-server-builds#9274f986a698d71233251744f88953ebba9cca72", + "@angular/router": "github:angular/router-builds#25a09cd2bd3ded54edba3371870df4f9fe72bcba", + "@angular/service-worker": "github:angular/service-worker-builds#29d297bddd794b1a457d97859feba871d3b7ead9" } } From 780320b36bdf73773fb4cc4a854381ac3bead372 Mon Sep 17 00:00:00 2001 From: Charles Lyding <19598772+clydin@users.noreply.github.com> Date: Fri, 14 Aug 2026 15:38:52 -0400 Subject: [PATCH 310/787] refactor(@angular/build): cache file data and translations in i18n inliner worker Add in-memory caching for decoded file contents, sourcemaps, and extracted localization AST metadata within the i18n inliner worker. Additionally, replace the single active translation slot with a per-locale map to retain deserialized translation tables across interleaved file requests. --- .../src/tools/esbuild/i18n-inliner-worker.ts | 108 +++++++++++------- 1 file changed, 64 insertions(+), 44 deletions(-) diff --git a/packages/angular/build/src/tools/esbuild/i18n-inliner-worker.ts b/packages/angular/build/src/tools/esbuild/i18n-inliner-worker.ts index 17f2424407a4..b95f4eae53a9 100644 --- a/packages/angular/build/src/tools/esbuild/i18n-inliner-worker.ts +++ b/packages/angular/build/src/tools/esbuild/i18n-inliner-worker.ts @@ -65,18 +65,52 @@ interface InlineCodeRequest { } // Extract the application files and common options used for inline requests from the Worker context -const { files, missingTranslation, shouldOptimize } = (workerData || {}) as { +const { files, missingTranslation } = (workerData || {}) as { files: ReadonlyMap; missingTranslation: 'error' | 'warning' | 'ignore'; - shouldOptimize: boolean; }; /** - * The translation messages deserialized for the locale most recently requested of this Worker. - * Locales are inlined one at a time, so retaining only the active locale is enough to avoid - * deserializing the messages once per file while holding at most one set of messages in memory. + * Cached file data including code and extracted localization metadata. */ -let activeTranslation: { locale: string; messages: Promise> } | undefined; +interface CachedFileData { + code: string; + metadata: FileLocalizeMetadata; +} + +/** + * Cache of file data promises keyed by filename. + */ +const fileDataCache = new Map>(); + +/** + * Cache of deserialized translation messages keyed by locale. + */ +const deserializedTranslations = new Map>>(); + +/** + * Retrieves the cached file data for a filename, loading and extracting it on the first request. + * + * @param filename The name of the file to load. + * @returns The cached code and localization metadata. + */ +function getFileData(filename: string): Promise { + let fileDataPromise = fileDataCache.get(filename); + if (!fileDataPromise) { + fileDataPromise = (async () => { + const data = files.get(filename); + assert(data !== undefined, `Invalid inline request for file '${filename}'.`); + + const code = await data.text(); + const metadata = extractLocalizeMetadata(filename, code); + + return { code, metadata }; + })(); + fileDataCache.set(filename, fileDataPromise); + } + + return fileDataPromise; +} /** * Deserializes the translation messages for an inline request, reusing the result for any @@ -92,18 +126,15 @@ function loadTranslation( return undefined; } - if (activeTranslation?.locale !== locale) { - activeTranslation = { - locale, - // Deserializing within the stored promise ensures that concurrent requests for a locale - // share the one deserialization instead of each performing their own. - messages: translation - .arrayBuffer() - .then((buffer) => deserialize(new Uint8Array(buffer)) as Record), - }; + let messagesPromise = deserializedTranslations.get(locale); + if (!messagesPromise) { + messagesPromise = translation + .arrayBuffer() + .then((buffer) => deserialize(new Uint8Array(buffer)) as Record); + deserializedTranslations.set(locale, messagesPromise); } - return activeTranslation.messages; + return messagesPromise; } /** @@ -114,17 +145,22 @@ function loadTranslation( * @returns An object containing the inlined file and optional map content. */ export default async function inlineFile(request: InlineFileRequest) { - const data = files.get(request.filename); + const { code, metadata } = await getFileData(request.filename); - assert(data !== undefined, `Invalid inline request for file '${request.filename}'.`); + // Sourcemaps are parsed on demand per request rather than cached long-term to prevent + // monotonic memory growth as a worker processes multiple files across the build. + // When multi-locale batching is implemented, the sourcemap can be parsed once per batch and released + // upon batch completion. + const rawMap = await files.get(request.filename + '.map')?.text(); + const map = rawMap ? (JSON.parse(rawMap) as SourceMapInput) : undefined; - const code = await data.text(); - const map = await files.get(request.filename + '.map')?.text(); - const result = await transformWithOxc( + const result = await inlineLocalize( code, - map && (JSON.parse(map) as SourceMapInput), - request, + map, + metadata, + request.locale, await loadTranslation(request), + request.filename, ); return { @@ -143,11 +179,14 @@ export default async function inlineFile(request: InlineFileRequest) { * @returns An object containing the inlined code. */ export async function inlineCode(request: InlineCodeRequest) { - const result = await transformWithOxc( + const metadata = extractLocalizeMetadata(request.filename, request.code); + const result = await inlineLocalize( request.code, undefined, - request, + metadata, + request.locale, await loadTranslation(request), + request.filename, ); return { @@ -402,22 +441,3 @@ async function inlineLocalize( diagnostics, }; } - -/** - * Transforms a JavaScript file using OXC and Magic-String to inline the request locale and translation. - * @param code A string containing the JavaScript code to transform. - * @param map A sourcemap object for the provided JavaScript code. - * @param options The inline request options to use. - * @param translation The translation messages to inline, or undefined for an untranslated locale. - * @returns An object containing the code, map, and diagnostics from the transformation. - */ -async function transformWithOxc( - code: string, - map: SourceMapInput | undefined, - options: InlineFileRequest | InlineCodeRequest, - translation: Record | undefined, -) { - const metadata = extractLocalizeMetadata(options.filename, code); - - return inlineLocalize(code, map, metadata, options.locale, translation, options.filename); -} From ef5c47fe63b44276769114dbe3078327d83897b9 Mon Sep 17 00:00:00 2001 From: Angular Robot Date: Mon, 17 Aug 2026 06:01:58 +0000 Subject: [PATCH 311/787] build: update pnpm to v11.22.0 See associated pull request for more information. --- MODULE.bazel | 4 ++-- package.json | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/MODULE.bazel b/MODULE.bazel index b69e4a74b0cf..cb1a08fd5963 100644 --- a/MODULE.bazel +++ b/MODULE.bazel @@ -131,8 +131,8 @@ use_repo( pnpm = use_extension("@aspect_rules_js//npm:extensions.bzl", "pnpm") pnpm.pnpm( name = "pnpm", - pnpm_version = "11.21.0", - pnpm_version_integrity = "sha512-UhcFvOaJkk6scvWjWHEi82JonvZXHlW6gAdv1jfBETLs/62ib61Op5xIW/3b/T1aKlsFgFp36JPeceyKbMo7sQ==", + pnpm_version = "11.22.0", + pnpm_version_integrity = "sha512-H/hwxMYTPf2I+yr8Rt0T1H8JyXlLQ4xv20fKmMrzvBY4HuC+k6CRuOOCTPAfiJ9G19niCRD7C+GrD7W6qA3WIQ==", ) use_repo(pnpm, "pnpm") diff --git a/package.json b/package.json index ad336b03eab5..0884c412256f 100644 --- a/package.json +++ b/package.json @@ -28,12 +28,12 @@ "type": "git", "url": "git+https://github.com/angular/angular-cli.git" }, - "packageManager": "pnpm@11.21.0", + "packageManager": "pnpm@11.22.0", "engines": { "node": "^22.22.3 || ^24.15.0 || >=26.0.0", "npm": "Please use pnpm instead of NPM to install dependencies", "yarn": "Please use pnpm instead of Yarn to install dependencies", - "pnpm": "11.21.0" + "pnpm": "11.22.0" }, "author": "Angular Authors", "license": "MIT", From 1ee0beca7b243cc4c06eb42b25d216d7b256b097 Mon Sep 17 00:00:00 2001 From: Maruthan G Date: Thu, 2 Jul 2026 20:40:06 +0530 Subject: [PATCH 312/787] fix(@angular/build): correct misleading error message for top-level await When top-level await is used in an application that includes Zone.js, esbuild reports that top-level await is not available in the configured target environment even though the actual cause is the async/await downleveling required for Zone.js support. The error is now augmented with a note explaining the Zone.js limitation and pointing to the zoneless guide. Closes #28904 --- .../src/builders/application/execute-build.ts | 28 +++++++- .../behavior/top-level-await-error_spec.ts | 67 +++++++++++++++++++ 2 files changed, 94 insertions(+), 1 deletion(-) create mode 100644 packages/angular/build/src/builders/application/tests/behavior/top-level-await-error_spec.ts diff --git a/packages/angular/build/src/builders/application/execute-build.ts b/packages/angular/build/src/builders/application/execute-build.ts index 53aaec882cbf..d0213a9b8a79 100644 --- a/packages/angular/build/src/builders/application/execute-build.ts +++ b/packages/angular/build/src/builders/application/execute-build.ts @@ -19,7 +19,11 @@ import { LOCALE_DATA_BASE_MODULE } from '../../tools/esbuild/i18n-locale-plugin' import { extractLicenses } from '../../tools/esbuild/license-extractor'; import { profileAsync } from '../../tools/esbuild/profiling'; import { transformSupportedBrowsersToTargets } from '../../tools/esbuild/target'; -import { calculateEstimatedTransferSizes, logBuildStats } from '../../tools/esbuild/utils'; +import { + calculateEstimatedTransferSizes, + isZonelessApp, + logBuildStats, +} from '../../tools/esbuild/utils'; import { BudgetCalculatorResult, checkBudgets } from '../../utils/bundle-calculator'; import { optimizeChunksThreshold } from '../../utils/environment-options'; import { resolveAssets } from '../../utils/resolve-assets'; @@ -33,6 +37,10 @@ import { inlineI18n, loadActiveTranslations } from './i18n'; import { NormalizedApplicationBuildOptions } from './options'; import { createComponentStyleBundler, setupBundlerContexts } from './setup-bundling'; +/** The esbuild error text prefix used to detect top-level await errors. */ +const TOP_LEVEL_AWAIT_ERROR_TEXT = + 'Top-level await is not available in the configured target environment'; + // eslint-disable-next-line max-lines-per-function export async function executeBuild( options: NormalizedApplicationBuildOptions, @@ -170,6 +178,24 @@ export async function executeBuild( // Return if the bundling has errors if (bundlingResult.errors) { + // If Zone.js is used, augment top-level await errors with a more helpful message. + // esbuild's default error mentions "target environment" with browser versions, but + // the actual reason is that async/await is downleveled for Zone.js compatibility. + if (!isZonelessApp(options.polyfills)) { + for (const error of bundlingResult.errors) { + if (error.text?.startsWith(TOP_LEVEL_AWAIT_ERROR_TEXT)) { + error.notes ??= []; + error.notes.push({ + text: + 'Top-level await is not supported in applications that use Zone.js. ' + + 'Consider removing Zone.js or moving this code into an async function. \n' + + 'For more information about zoneless Angular applications, visit: https://angular.dev/guide/zoneless', + location: null, + }); + } + } + } + executionResult.addErrors(bundlingResult.errors); return executionResult; diff --git a/packages/angular/build/src/builders/application/tests/behavior/top-level-await-error_spec.ts b/packages/angular/build/src/builders/application/tests/behavior/top-level-await-error_spec.ts new file mode 100644 index 000000000000..b0220529ee28 --- /dev/null +++ b/packages/angular/build/src/builders/application/tests/behavior/top-level-await-error_spec.ts @@ -0,0 +1,67 @@ +/** + * @license + * Copyright Google LLC All Rights Reserved. + * + * Use of this source code is governed by an MIT-style license that can be + * found in the LICENSE file at https://angular.dev/license + */ + +import { buildApplication } from '../../index'; +import { APPLICATION_BUILDER_INFO, BASE_OPTIONS, describeBuilder } from '../setup'; + +describeBuilder(buildApplication, APPLICATION_BUILDER_INFO, (harness) => { + describe('Behavior: "Top-level await error message"', () => { + it('should show a Zone.js-specific error when top-level await is used with Zone.js', async () => { + await harness.writeFile( + 'src/main.ts', + ` + // The export makes this file a module, which is required for top-level await. + export const value = await Promise.resolve('test'); + console.log(value); + `, + ); + + harness.useTarget('build', { + ...BASE_OPTIONS, + polyfills: ['zone.js'], + }); + + const { result, logs } = await harness.executeOnce({ outputLogsOnFailure: false }); + expect(result?.success).toBeFalse(); + expect(logs).toContain( + jasmine.objectContaining({ + message: jasmine.stringMatching( + 'Top-level await is not supported in applications that use Zone.js', + ), + }), + ); + }); + + it('should not show a Zone.js-specific error when top-level await is used without Zone.js', async () => { + await harness.writeFile( + 'src/main.ts', + ` + // The export makes this file a module, which is required for top-level await. + export const value = await Promise.resolve('test'); + console.log(value); + `, + ); + + harness.useTarget('build', { + ...BASE_OPTIONS, + polyfills: [], + }); + + const { result, logs } = await harness.executeOnce({ outputLogsOnFailure: false }); + expect(result?.success).toBeTrue(); + expect(logs).not.toContain( + jasmine.objectContaining({ + level: 'error', + message: jasmine.stringContaining( + 'Top-level await is not supported in applications that use Zone.js', + ), + }), + ); + }); + }); +}); From a13b9828acfe0aa3a9b2c608720a00d5b8775745 Mon Sep 17 00:00:00 2001 From: Russel Porosky Date: Sun, 24 May 2026 09:01:27 -0600 Subject: [PATCH 313/787] refactor(@angular-devkit/schematics): add consistent spacing and ordering * add consistent spacing and tags around `<%`, `%>, and operators * reorder component decorator properties to be alphabetical * remove empty constructors * change spacing to ensure all outputs are consistently styled --- .../src/app/app__suffix__.spec.ts.template | 5 +-- .../src/app/app__suffix__.ts.template | 8 ++--- .../app__typeSeparator__module.ts.template | 7 ++--- .../files/module-files/src/main.ts.template | 6 ++-- .../src/app/app.config.ts.template | 7 ++--- .../src/app/app__suffix__.spec.ts.template | 5 +-- .../src/app/app__suffix__.ts.template | 12 +++---- ...ze__.__type@dasherize__.__style__.template | 2 +- ...rize__.__type@dasherize__.spec.ts.template | 5 ++- ...dasherize__.__type@dasherize__.ts.template | 31 +++++++++---------- ...dasherize__.__type@dasherize__.ts.template | 4 +-- ...e____typeSeparator__guard.spec.ts.template | 1 - ...e____typeSeparator__guard.spec.ts.template | 1 - ...ypeSeparator__interceptor.spec.ts.template | 1 - ...____typeSeparator__interceptor.ts.template | 3 -- ...ypeSeparator__interceptor.spec.ts.template | 1 - ...sherize____typeSeparator__pipe.ts.template | 6 ++-- ...__typeSeparator__resolver.spec.ts.template | 1 - ...__typeSeparator__resolver.spec.ts.template | 1 - .../app/app.module.server.ts.template | 1 - ...rize__.__type@dasherize__.spec.ts.template | 1 - ...dasherize__.__type@dasherize__.ts.template | 1 - 22 files changed, 47 insertions(+), 63 deletions(-) diff --git a/packages/schematics/angular/application/files/module-files/src/app/app__suffix__.spec.ts.template b/packages/schematics/angular/application/files/module-files/src/app/app__suffix__.spec.ts.template index dfe31b1010c6..b12a559c7068 100644 --- a/packages/schematics/angular/application/files/module-files/src/app/app__suffix__.spec.ts.template +++ b/packages/schematics/angular/application/files/module-files/src/app/app__suffix__.spec.ts.template @@ -11,7 +11,8 @@ describe('App', () => { declarations: [ App ], - }).compileComponents(); + }) + .compileComponents(); }); it('should create the app', () => { @@ -20,7 +21,7 @@ describe('App', () => { expect(app).toBeTruthy(); }); - it('should render title', <% if(zoneless) { %>async <% } %>() => { + it('should render title', <% if (zoneless) { %>async <% } %>() => { const fixture = TestBed.createComponent(App); <%= zoneless ? 'await fixture.whenStable();' : 'fixture.detectChanges();' %> const compiled = fixture.nativeElement as HTMLElement; diff --git a/packages/schematics/angular/application/files/module-files/src/app/app__suffix__.ts.template b/packages/schematics/angular/application/files/module-files/src/app/app__suffix__.ts.template index 055586955b75..a939bd8d6cc9 100644 --- a/packages/schematics/angular/application/files/module-files/src/app/app__suffix__.ts.template +++ b/packages/schematics/angular/application/files/module-files/src/app/app__suffix__.ts.template @@ -1,7 +1,10 @@ import { Component, signal } from '@angular/core'; @Component({ - selector: '<%= selector %>',<% if(inlineTemplate) { %> + selector: '<%= selector %>', + standalone: false,<% if (inlineStyle) { %> + styles: []<% } else { %> + styleUrl: './app<%= suffix %>.<%= style %>'<% } %><% if (inlineTemplate) { %> template: `

Hello, {{ title() }}

Congratulations! Your app is running. 🎉

@@ -11,9 +14,6 @@ import { Component, signal } from '@angular/core'; } %> `,<% } else { %> templateUrl: './app<%= suffix %>.html',<% } %> - standalone: false,<% if(inlineStyle) { %> - styles: []<% } else { %> - styleUrl: './app<%= suffix %>.<%= style %>'<% } %> }) export class App { protected readonly title = signal('<%= name %>'); diff --git a/packages/schematics/angular/application/files/module-files/src/app/app__typeSeparator__module.ts.template b/packages/schematics/angular/application/files/module-files/src/app/app__typeSeparator__module.ts.template index f7ad6f2cb515..1efc27f522e6 100644 --- a/packages/schematics/angular/application/files/module-files/src/app/app__typeSeparator__module.ts.template +++ b/packages/schematics/angular/application/files/module-files/src/app/app__typeSeparator__module.ts.template @@ -1,6 +1,5 @@ -import { NgModule, provideBrowserGlobalErrorListeners<% if(!zoneless) { %>, provideZoneChangeDetection<% } %> } from '@angular/core'; -import { BrowserModule } from '@angular/platform-browser'; -<% if (routing) { %> +import { NgModule, provideBrowserGlobalErrorListeners<% if (!zoneless) { %>, provideZoneChangeDetection<% } %> } from '@angular/core'; +import { BrowserModule } from '@angular/platform-browser';<% if (routing) { %> import { AppRoutingModule } from './app-routing<%= typeSeparator %>module';<% } %> import { App } from './app<%= suffix %>'; @@ -13,7 +12,7 @@ import { App } from './app<%= suffix %>'; AppRoutingModule<% } %> ], providers: [ - provideBrowserGlobalErrorListeners(),<% if(!zoneless) { %> + provideBrowserGlobalErrorListeners(),<% if (!zoneless) { %> provideZoneChangeDetection({ eventCoalescing: true }),<% } %> ], bootstrap: [App] diff --git a/packages/schematics/angular/application/files/module-files/src/main.ts.template b/packages/schematics/angular/application/files/module-files/src/main.ts.template index f74887b16867..0fcb878b1e23 100644 --- a/packages/schematics/angular/application/files/module-files/src/main.ts.template +++ b/packages/schematics/angular/application/files/module-files/src/main.ts.template @@ -1,8 +1,8 @@ -<% if(!!viewEncapsulation) { %>import { ViewEncapsulation } from '@angular/core'; -<% }%>import { platformBrowser } from '@angular/platform-browser'; +<% if (!!viewEncapsulation) { %>import { ViewEncapsulation } from '@angular/core'; +<% } %>import { platformBrowser } from '@angular/platform-browser'; import { AppModule } from './app/app<%= typeSeparator %>module'; platformBrowser().bootstrapModule(AppModule, { - <% if(!!viewEncapsulation) { %> defaultEncapsulation: ViewEncapsulation.<%= viewEncapsulation %><% } %> + <% if (!!viewEncapsulation) { %> defaultEncapsulation: ViewEncapsulation.<%= viewEncapsulation %><% } %> }) .catch(err => console.error(err)); diff --git a/packages/schematics/angular/application/files/standalone-files/src/app/app.config.ts.template b/packages/schematics/angular/application/files/standalone-files/src/app/app.config.ts.template index 8f0e1b0dc23a..20201fdb80ca 100644 --- a/packages/schematics/angular/application/files/standalone-files/src/app/app.config.ts.template +++ b/packages/schematics/angular/application/files/standalone-files/src/app/app.config.ts.template @@ -1,12 +1,11 @@ -import { ApplicationConfig, provideBrowserGlobalErrorListeners<% if(!zoneless) { %>, provideZoneChangeDetection<% } %> } from '@angular/core';<% if (routing) { %> +import { ApplicationConfig, provideBrowserGlobalErrorListeners<% if (!zoneless) { %>, provideZoneChangeDetection<% } %> } from '@angular/core';<% if (routing) { %> import { provideRouter } from '@angular/router'; - import { routes } from './app.routes';<% } %> export const appConfig: ApplicationConfig = { providers: [ - provideBrowserGlobalErrorListeners(),<% if(!zoneless) { %> + provideBrowserGlobalErrorListeners(),<% if (!zoneless) { %> provideZoneChangeDetection({ eventCoalescing: true }),<% } %> - <% if (routing) {%>provideRouter(routes)<% } %> + <% if (routing) { %>provideRouter(routes)<% } %> ] }; diff --git a/packages/schematics/angular/application/files/standalone-files/src/app/app__suffix__.spec.ts.template b/packages/schematics/angular/application/files/standalone-files/src/app/app__suffix__.spec.ts.template index e6944dc73ccd..306911a0f500 100644 --- a/packages/schematics/angular/application/files/standalone-files/src/app/app__suffix__.spec.ts.template +++ b/packages/schematics/angular/application/files/standalone-files/src/app/app__suffix__.spec.ts.template @@ -5,7 +5,8 @@ describe('App', () => { beforeEach(async () => { await TestBed.configureTestingModule({ imports: [App], - }).compileComponents(); + }) + .compileComponents(); }); it('should create the app', () => { @@ -14,7 +15,7 @@ describe('App', () => { expect(app).toBeTruthy(); }); - it('should render title', <% if(zoneless) { %>async <% } %>() => { + it('should render title', <% if (zoneless) { %>async <% } %>() => { const fixture = TestBed.createComponent(App); <%= zoneless ? 'await fixture.whenStable();' : 'fixture.detectChanges();' %> const compiled = fixture.nativeElement as HTMLElement; diff --git a/packages/schematics/angular/application/files/standalone-files/src/app/app__suffix__.ts.template b/packages/schematics/angular/application/files/standalone-files/src/app/app__suffix__.ts.template index ce8010ecfbce..dfdb04abcb76 100644 --- a/packages/schematics/angular/application/files/standalone-files/src/app/app__suffix__.ts.template +++ b/packages/schematics/angular/application/files/standalone-files/src/app/app__suffix__.ts.template @@ -1,9 +1,11 @@ -import { Component, signal } from '@angular/core';<% if(routing) { %> +import { Component, signal } from '@angular/core';<% if (routing) { %> import { RouterOutlet } from '@angular/router';<% } %> @Component({ - selector: '<%= selector %>', - imports: [<% if(routing) { %>RouterOutlet<% } %>],<% if(inlineTemplate) { %> + imports: [<% if (routing) { %>RouterOutlet<% } %>], + selector: '<%= selector %>',<% if (inlineStyle) { %> + styles: [],<% } else { %> + styleUrl: './app<%= suffix %>.<%= style %>',<% } %><% if (inlineTemplate) { %> template: `

Hello, {{ title() }}

@@ -11,9 +13,7 @@ import { RouterOutlet } from '@angular/router';<% } %> %><% } %> `,<% } else { %> - templateUrl: './app<%= suffix %>.html',<% } if(inlineStyle) { %> - styles: [],<% } else { %> - styleUrl: './app<%= suffix %>.<%= style %>'<% } %> + templateUrl: './app<%= suffix %>.html',<% } %> }) export class App { protected readonly title = signal('<%= name %>'); diff --git a/packages/schematics/angular/component/files/__name@dasherize@if-flat__/__name@dasherize__.__type@dasherize__.__style__.template b/packages/schematics/angular/component/files/__name@dasherize@if-flat__/__name@dasherize__.__type@dasherize__.__style__.template index 2ccecd1220b9..4f8512fa3752 100644 --- a/packages/schematics/angular/component/files/__name@dasherize@if-flat__/__name@dasherize__.__type@dasherize__.__style__.template +++ b/packages/schematics/angular/component/files/__name@dasherize@if-flat__/__name@dasherize__.__type@dasherize__.__style__.template @@ -1,4 +1,4 @@ -<% if(displayBlock){ if(style != 'sass') { %>:host { +<% if (displayBlock) { if (style != 'sass') { %>:host { display: block; } <% } else { %>\:host diff --git a/packages/schematics/angular/component/files/__name@dasherize@if-flat__/__name@dasherize__.__type@dasherize__.spec.ts.template b/packages/schematics/angular/component/files/__name@dasherize@if-flat__/__name@dasherize__.__type@dasherize__.spec.ts.template index 74d858ea1e64..13be0cdf9856 100644 --- a/packages/schematics/angular/component/files/__name@dasherize@if-flat__/__name@dasherize__.__type@dasherize__.spec.ts.template +++ b/packages/schematics/angular/component/files/__name@dasherize@if-flat__/__name@dasherize__.__type@dasherize__.spec.ts.template @@ -1,6 +1,5 @@ import { ComponentFixture, TestBed } from '@angular/core/testing'; - -import <% if(!exportDefault) { %>{ <% }%><%= classifiedName %> <% if(!exportDefault) {%>} <% }%>from './<%= dasherize(name) %><%= type ? '.' + dasherize(type): '' %>'; +import <% if (!exportDefault) { %>{ <% } %><%= classifiedName %> <% if (!exportDefault) { %>} <% } %>from './<%= dasherize(name) %><%= type ? '.' + dasherize(type): '' %>'; describe('<%= classifiedName %>', () => { let component: <%= classifiedName %>; @@ -10,7 +9,7 @@ describe('<%= classifiedName %>', () => { await TestBed.configureTestingModule({ <%= standalone ? 'imports' : 'declarations' %>: [<%= classifiedName %>] }) - .compileComponents(); + .compileComponents(); fixture = TestBed.createComponent(<%= classifiedName %>); component = fixture.componentInstance; diff --git a/packages/schematics/angular/component/files/__name@dasherize@if-flat__/__name@dasherize__.__type@dasherize__.ts.template b/packages/schematics/angular/component/files/__name@dasherize@if-flat__/__name@dasherize__.__type@dasherize__.ts.template index d46cd8233862..7b3424c5be17 100644 --- a/packages/schematics/angular/component/files/__name@dasherize@if-flat__/__name@dasherize__.__type@dasherize__.ts.template +++ b/packages/schematics/angular/component/files/__name@dasherize@if-flat__/__name@dasherize__.__type@dasherize__.ts.template @@ -1,24 +1,23 @@ -import { <% if(changeDetection !== 'OnPush') { %>ChangeDetectionStrategy, <% }%>Component<% if(!!viewEncapsulation) { %>, ViewEncapsulation<% }%> } from '@angular/core'; +import { <% if (changeDetection !== 'OnPush') { %>ChangeDetectionStrategy, <% } %>Component<% if (!!viewEncapsulation) { %>, ViewEncapsulation<% } %> } from '@angular/core'; -@Component({<% if(!skipSelector) {%> - selector: '<%= selector %>',<%}%><% if(standalone) {%> - imports: [],<%} else { %> - standalone: false,<% }%><% if(inlineTemplate) { %> +@Component({<% if (changeDetection !== 'OnPush') { %> + changeDetection: ChangeDetectionStrategy.<%= changeDetection %>,<% } %><% if (!!viewEncapsulation) { %> + encapsulation: ViewEncapsulation.<%= viewEncapsulation %>,<% } %><% if (standalone) { %> + imports: [],<% } %><% if (!skipSelector) { %> + selector: '<%= selector %>',<% } %><% if (!standalone) { %> + standalone: false,<% } %><% if (inlineStyle) { %> + styles: `<% if (displayBlock) { %> + :host { + display: block; + } + <% } %>`,<% } else if (style !== 'none') { %> + styleUrl: './<%= dasherize(name) %><%= type ? '.' + dasherize(type): '' %>.<%= style %>',<% } %><% if (inlineTemplate) { %> template: `

<%= dasherize(name) %> works!

`,<% } else { %> - templateUrl: './<%= dasherize(name) %><%= type ? '.' + dasherize(type): '' %><%= ngext %>.html',<% } if(inlineStyle) { %> - styles: `<% if(displayBlock){ %> - :host { - display: block; - } - <% } %>`,<% } else if (style !== 'none') { %> - styleUrl: './<%= dasherize(name) %><%= type ? '.' + dasherize(type): '' %>.<%= style %>',<% } %><% if(!!viewEncapsulation) { %> - encapsulation: ViewEncapsulation.<%= viewEncapsulation %>,<% } if (changeDetection !== 'OnPush') { %> - changeDetection: ChangeDetectionStrategy.<%= changeDetection %>,<% } %> + templateUrl: './<%= dasherize(name) %><%= type ? '.' + dasherize(type): '' %><%= ngext %>.html',<% } %> }) -export <% if(exportDefault) {%>default <%}%>class <%= classifiedName %> { - +export <% if (exportDefault) { %>default <% } %>class <%= classifiedName %> { } diff --git a/packages/schematics/angular/directive/files/__name@dasherize__.__type@dasherize__.ts.template b/packages/schematics/angular/directive/files/__name@dasherize__.__type@dasherize__.ts.template index eff23c7e350a..d932838b1f8e 100644 --- a/packages/schematics/angular/directive/files/__name@dasherize__.__type@dasherize__.ts.template +++ b/packages/schematics/angular/directive/files/__name@dasherize__.__type@dasherize__.ts.template @@ -1,8 +1,8 @@ import { Directive } from '@angular/core'; @Directive({ - selector: '[<%= selector %>]',<% if(!standalone) {%> - standalone: false,<%}%> + selector: '[<%= selector %>]',<% if (!standalone) { %> + standalone: false,<% } %> }) export class <%= classifiedName %> { } diff --git a/packages/schematics/angular/guard/implements-files/__name@dasherize____typeSeparator__guard.spec.ts.template b/packages/schematics/angular/guard/implements-files/__name@dasherize____typeSeparator__guard.spec.ts.template index fefa3afee2b0..0bea60fdd710 100644 --- a/packages/schematics/angular/guard/implements-files/__name@dasherize____typeSeparator__guard.spec.ts.template +++ b/packages/schematics/angular/guard/implements-files/__name@dasherize____typeSeparator__guard.spec.ts.template @@ -1,5 +1,4 @@ import { TestBed } from '@angular/core/testing'; - import { <%= classify(name) %>Guard } from './<%= dasherize(name) %><%= typeSeparator %>guard'; describe('<%= classify(name) %>Guard', () => { diff --git a/packages/schematics/angular/guard/type-files/__name@dasherize____typeSeparator__guard.spec.ts.template b/packages/schematics/angular/guard/type-files/__name@dasherize____typeSeparator__guard.spec.ts.template index 9bad0a553eb4..a9420dc90d56 100644 --- a/packages/schematics/angular/guard/type-files/__name@dasherize____typeSeparator__guard.spec.ts.template +++ b/packages/schematics/angular/guard/type-files/__name@dasherize____typeSeparator__guard.spec.ts.template @@ -1,6 +1,5 @@ import { TestBed } from '@angular/core/testing'; import { <%= guardType %> } from '@angular/router'; - import { <%= camelize(name) %>Guard } from './<%= dasherize(name) %><%= typeSeparator %>guard'; describe('<%= camelize(name) %>Guard', () => { diff --git a/packages/schematics/angular/interceptor/class-files/__name@dasherize____typeSeparator__interceptor.spec.ts.template b/packages/schematics/angular/interceptor/class-files/__name@dasherize____typeSeparator__interceptor.spec.ts.template index 9af595489571..b836eb209e36 100755 --- a/packages/schematics/angular/interceptor/class-files/__name@dasherize____typeSeparator__interceptor.spec.ts.template +++ b/packages/schematics/angular/interceptor/class-files/__name@dasherize____typeSeparator__interceptor.spec.ts.template @@ -1,5 +1,4 @@ import { TestBed } from '@angular/core/testing'; - import { <%= classify(name) %>Interceptor } from './<%= dasherize(name) %><%= typeSeparator %>interceptor'; describe('<%= classify(name) %>Interceptor', () => { diff --git a/packages/schematics/angular/interceptor/class-files/__name@dasherize____typeSeparator__interceptor.ts.template b/packages/schematics/angular/interceptor/class-files/__name@dasherize____typeSeparator__interceptor.ts.template index fffab4ddf988..427ddd774765 100755 --- a/packages/schematics/angular/interceptor/class-files/__name@dasherize____typeSeparator__interceptor.ts.template +++ b/packages/schematics/angular/interceptor/class-files/__name@dasherize____typeSeparator__interceptor.ts.template @@ -9,9 +9,6 @@ import { Observable } from 'rxjs'; @Injectable() export class <%= classify(name) %>Interceptor implements HttpInterceptor { - - constructor() {} - intercept(request: HttpRequest, next: HttpHandler): Observable> { return next.handle(request); } diff --git a/packages/schematics/angular/interceptor/functional-files/__name@dasherize____typeSeparator__interceptor.spec.ts.template b/packages/schematics/angular/interceptor/functional-files/__name@dasherize____typeSeparator__interceptor.spec.ts.template index ee1662c6530f..a01d79325e01 100755 --- a/packages/schematics/angular/interceptor/functional-files/__name@dasherize____typeSeparator__interceptor.spec.ts.template +++ b/packages/schematics/angular/interceptor/functional-files/__name@dasherize____typeSeparator__interceptor.spec.ts.template @@ -1,6 +1,5 @@ import { TestBed } from '@angular/core/testing'; import { HttpInterceptorFn } from '@angular/common/http'; - import { <%= camelize(name) %>Interceptor } from './<%= dasherize(name) %><%= typeSeparator %>interceptor'; describe('<%= camelize(name) %>Interceptor', () => { diff --git a/packages/schematics/angular/pipe/files/__name@dasherize____typeSeparator__pipe.ts.template b/packages/schematics/angular/pipe/files/__name@dasherize____typeSeparator__pipe.ts.template index 57765121531e..3348a8225ee9 100644 --- a/packages/schematics/angular/pipe/files/__name@dasherize____typeSeparator__pipe.ts.template +++ b/packages/schematics/angular/pipe/files/__name@dasherize____typeSeparator__pipe.ts.template @@ -1,13 +1,11 @@ import { Pipe, PipeTransform } from '@angular/core'; @Pipe({ - name: '<%= camelize(name) %>',<% if(!standalone) {%> - standalone: false,<%}%> + name: '<%= camelize(name) %>',<% if (!standalone) { %> + standalone: false,<% } %> }) export class <%= classify(name) %>Pipe implements PipeTransform { - transform(value: unknown, ...args: unknown[]): unknown { return null; } - } diff --git a/packages/schematics/angular/resolver/class-files/__name@dasherize____typeSeparator__resolver.spec.ts.template b/packages/schematics/angular/resolver/class-files/__name@dasherize____typeSeparator__resolver.spec.ts.template index af27433460e5..42e600625d0b 100644 --- a/packages/schematics/angular/resolver/class-files/__name@dasherize____typeSeparator__resolver.spec.ts.template +++ b/packages/schematics/angular/resolver/class-files/__name@dasherize____typeSeparator__resolver.spec.ts.template @@ -1,5 +1,4 @@ import { TestBed } from '@angular/core/testing'; - import { <%= classify(name) %>Resolver } from './<%= dasherize(name) %><%= typeSeparator %>resolver'; describe('<%= classify(name) %>Resolver', () => { diff --git a/packages/schematics/angular/resolver/functional-files/__name@dasherize____typeSeparator__resolver.spec.ts.template b/packages/schematics/angular/resolver/functional-files/__name@dasherize____typeSeparator__resolver.spec.ts.template index c9f42a1a0bd5..c5a62b14b577 100644 --- a/packages/schematics/angular/resolver/functional-files/__name@dasherize____typeSeparator__resolver.spec.ts.template +++ b/packages/schematics/angular/resolver/functional-files/__name@dasherize____typeSeparator__resolver.spec.ts.template @@ -1,6 +1,5 @@ import { TestBed } from '@angular/core/testing'; import { ResolveFn } from '@angular/router'; - import { <%= camelize(name) %>Resolver } from './<%= dasherize(name) %><%= typeSeparator %>resolver'; describe('<%= camelize(name) %>Resolver', () => { diff --git a/packages/schematics/angular/server/files/server-builder/ngmodule-src/app/app.module.server.ts.template b/packages/schematics/angular/server/files/server-builder/ngmodule-src/app/app.module.server.ts.template index eeffba7f902b..5e79f7aa57ad 100644 --- a/packages/schematics/angular/server/files/server-builder/ngmodule-src/app/app.module.server.ts.template +++ b/packages/schematics/angular/server/files/server-builder/ngmodule-src/app/app.module.server.ts.template @@ -1,6 +1,5 @@ import { NgModule } from '@angular/core'; import { ServerModule } from '@angular/platform-server'; - import { <%= appModuleName %> } from '<%= appModulePath %>'; import { <%= appComponentName %> } from '<%= appComponentPath %>'; diff --git a/packages/schematics/angular/service/files/__name@dasherize__.__type@dasherize__.spec.ts.template b/packages/schematics/angular/service/files/__name@dasherize__.__type@dasherize__.spec.ts.template index 168bb9ef23f2..0a85fae12489 100644 --- a/packages/schematics/angular/service/files/__name@dasherize__.__type@dasherize__.spec.ts.template +++ b/packages/schematics/angular/service/files/__name@dasherize__.__type@dasherize__.spec.ts.template @@ -1,5 +1,4 @@ import { TestBed } from '@angular/core/testing'; - import { <%= classifiedName %> } from './<%= dasherize(name) %><%= type ? '.' + dasherize(type) : '' %>'; describe('<%= classifiedName %>', () => { diff --git a/packages/schematics/angular/service/files/__name@dasherize__.__type@dasherize__.ts.template b/packages/schematics/angular/service/files/__name@dasherize__.__type@dasherize__.ts.template index 3b9a10da6ce4..0c9620cb0bcd 100644 --- a/packages/schematics/angular/service/files/__name@dasherize__.__type@dasherize__.ts.template +++ b/packages/schematics/angular/service/files/__name@dasherize__.__type@dasherize__.ts.template @@ -4,5 +4,4 @@ import { <%= injectable ? 'Injectable' : 'Service' %> } from '@angular/core'; providedIn: 'root', })<% } else { %>@Service()<% } %> export class <%= classifiedName %> { - } From 0d7d6e3dcda63bf420682ecee794c51f658fe706 Mon Sep 17 00:00:00 2001 From: Russel Porosky Date: Fri, 29 May 2026 16:24:20 -0600 Subject: [PATCH 314/787] refactor(@angular-devkit/schematics): add missing comma to reordered component properties --- .../files/module-files/src/app/app__suffix__.ts.template | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/schematics/angular/application/files/module-files/src/app/app__suffix__.ts.template b/packages/schematics/angular/application/files/module-files/src/app/app__suffix__.ts.template index a939bd8d6cc9..ef9aebaa0e14 100644 --- a/packages/schematics/angular/application/files/module-files/src/app/app__suffix__.ts.template +++ b/packages/schematics/angular/application/files/module-files/src/app/app__suffix__.ts.template @@ -3,8 +3,8 @@ import { Component, signal } from '@angular/core'; @Component({ selector: '<%= selector %>', standalone: false,<% if (inlineStyle) { %> - styles: []<% } else { %> - styleUrl: './app<%= suffix %>.<%= style %>'<% } %><% if (inlineTemplate) { %> + styles: [],<% } else { %> + styleUrl: './app<%= suffix %>.<%= style %>',<% } %><% if (inlineTemplate) { %> template: `

Hello, {{ title() }}

Congratulations! Your app is running. 🎉

From 5b789a0dced41f23aa268c10bf92e111217e4c84 Mon Sep 17 00:00:00 2001 From: Angular Robot Date: Tue, 18 Aug 2026 19:30:31 +0000 Subject: [PATCH 315/787] build: update cross-repo angular dependencies See associated pull request for more information. --- tests/e2e/ng-snapshot/package.json | 32 +++++++++++++++--------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/tests/e2e/ng-snapshot/package.json b/tests/e2e/ng-snapshot/package.json index a8f75125d9ab..1b410674fd5a 100644 --- a/tests/e2e/ng-snapshot/package.json +++ b/tests/e2e/ng-snapshot/package.json @@ -2,21 +2,21 @@ "description": "snapshot versions of Angular for e2e testing", "private": true, "dependencies": { - "@angular/animations": "github:angular/animations-builds#316c84ff609bd60bd8e68a7a568d2ef9721fe0b6", - "@angular/cdk": "github:angular/cdk-builds#445a5a7b0b463a3bfda71c36f3631c60d8789791", - "@angular/common": "github:angular/common-builds#88897d953d1536c9b21f63683e4c64f7cc3de95c", - "@angular/compiler": "github:angular/compiler-builds#68079220681fccae119518abb118282e9edd442e", - "@angular/compiler-cli": "github:angular/compiler-cli-builds#cbdb69028d5bf1c216ef879ebda156d714a87798", - "@angular/core": "github:angular/core-builds#e761242e59fc7c15762d22a65d0d735919a46955", - "@angular/forms": "github:angular/forms-builds#acd664701770abb63878d3f412be116fbd005fa4", - "@angular/language-service": "github:angular/language-service-builds#71c927e4dc87023b7e719e11d6198f3557c46808", - "@angular/localize": "github:angular/localize-builds#947193a6e8a45616d742681ec418cd45990fb6a2", - "@angular/material": "github:angular/material-builds#6b4a1bcbdfac14a16386130370451993771162b5", - "@angular/material-moment-adapter": "github:angular/material-moment-adapter-builds#2aeb092a67a59fa0e8a3efdceec165166803811a", - "@angular/platform-browser": "github:angular/platform-browser-builds#47eb4cd3c3716344928a4190fa002e0a25c22bea", - "@angular/platform-browser-dynamic": "github:angular/platform-browser-dynamic-builds#a4c26f0799c893d59f0428a3d0ca9cb3b969e6eb", - "@angular/platform-server": "github:angular/platform-server-builds#9274f986a698d71233251744f88953ebba9cca72", - "@angular/router": "github:angular/router-builds#25a09cd2bd3ded54edba3371870df4f9fe72bcba", - "@angular/service-worker": "github:angular/service-worker-builds#29d297bddd794b1a457d97859feba871d3b7ead9" + "@angular/animations": "github:angular/animations-builds#678e20bdf29e8d892a878ab8d42552a512c11692", + "@angular/cdk": "github:angular/cdk-builds#4b4949e62c156a3b2530372ebe6a56a3e813b2d0", + "@angular/common": "github:angular/common-builds#215a13b7f977d1f75b4d01ca798c8f9cc44f830b", + "@angular/compiler": "github:angular/compiler-builds#81eef66a3e5d30b6a46e0fea62fa9d360c27adb7", + "@angular/compiler-cli": "github:angular/compiler-cli-builds#c6f76875c4a522726916c9682d87183e13e932e5", + "@angular/core": "github:angular/core-builds#6706323d706dcf6d639b8712976646e3e99e91e2", + "@angular/forms": "github:angular/forms-builds#9f6690da73275be22fdc7eba08d78b4909a7b6e4", + "@angular/language-service": "github:angular/language-service-builds#03a95f77d0f44c4b6f194cc6cf56850fd11a2691", + "@angular/localize": "github:angular/localize-builds#7de5c236d7852c00e713d256f03f03b77997671f", + "@angular/material": "github:angular/material-builds#bbe56c79c782500f0183a0c84adf017cdb7ccd15", + "@angular/material-moment-adapter": "github:angular/material-moment-adapter-builds#c26efa5523014d6ce9652cd6eb8125d1c60e0e0b", + "@angular/platform-browser": "github:angular/platform-browser-builds#a92de76171ed92a60aaae93f6fa9a3d15a82d092", + "@angular/platform-browser-dynamic": "github:angular/platform-browser-dynamic-builds#9ad24d91d95a25b57b854dc04d6aba660558ad8a", + "@angular/platform-server": "github:angular/platform-server-builds#d4ca9b253bfc472b0866fa37857e5716dc804887", + "@angular/router": "github:angular/router-builds#91098a665f813b3d9157b830411e1a48fda38c17", + "@angular/service-worker": "github:angular/service-worker-builds#eb60209150df4fa83342930e7ec2571a01703f44" } } From dcd65c3d6158c957a212af71b8fcc2a5b1cb183d Mon Sep 17 00:00:00 2001 From: Angular Robot Date: Tue, 18 Aug 2026 05:02:41 +0000 Subject: [PATCH 316/787] build: lock file maintenance See associated pull request for more information. --- MODULE.bazel.lock | 2 +- pnpm-lock.yaml | 621 +++++++++++++++++++++++----------------------- 2 files changed, 308 insertions(+), 315 deletions(-) diff --git a/MODULE.bazel.lock b/MODULE.bazel.lock index c78713d22533..e957c9cda7de 100644 --- a/MODULE.bazel.lock +++ b/MODULE.bazel.lock @@ -452,7 +452,7 @@ "aspect_rules_jasmine": "2.0.4", "aspect_tools_telemetry": "0.4.2" }, - "last_notice": 1 + "last_notice": 0 } } }, diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 7f1641ea068d..d578d33bc711 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -1581,8 +1581,8 @@ packages: conventional-commits-parser: optional: true - '@csstools/color-helpers@6.1.0': - resolution: {integrity: sha512-064IFJdjTfUqnjpCVpMOdbr8FLQBhinbZj6yRv2An2E41O/pLEXqfFRWqGq/SxlE5PEUYTlvWsG2r8MswAVvkg==} + '@csstools/color-helpers@6.1.1': + resolution: {integrity: sha512-gLNsunvwf3mCi5u5o46/Z/JcJMnhbHSaZ69rkgPzNM3J4s8hWwpPUQB6/tt0EDFyCiWzxANlx+2LJwpYj4zS1w==} engines: {node: '>=20.19.0'} '@csstools/css-calc@3.3.0': @@ -1592,8 +1592,8 @@ packages: '@csstools/css-parser-algorithms': ^4.0.0 '@csstools/css-tokenizer': ^4.0.0 - '@csstools/css-color-parser@4.1.10': - resolution: {integrity: sha512-UZhQLIUyJaaMepqehrCODwCg2KW25vFvLWBmqYFaPclYvvxzj/sG8LBOhBFCp11i9uE7t1EyS+RAoV9tztPFyw==} + '@csstools/css-color-parser@4.2.0': + resolution: {integrity: sha512-5+5LEmFuY1AjXdYhmgjTJogtQnP1evJ1zrBZGUNZ0thkpwnnmKxcHdAMn/OtFjAb25zA+jKDVYVRl+5G7rjv1A==} engines: {node: '>=20.19.0'} peerDependencies: '@csstools/css-parser-algorithms': ^4.0.0 @@ -1605,8 +1605,8 @@ packages: peerDependencies: '@csstools/css-tokenizer': ^4.0.0 - '@csstools/css-syntax-patches-for-csstree@1.1.7': - resolution: {integrity: sha512-fQ+05118eQS1cofO3aJpB5efgpBZMvIzwr/sbC8kDLVA5XLG8q1kJV5yzrUAI1f7lvhPnm8fgIjzFB8/O/5Dig==} + '@csstools/css-syntax-patches-for-csstree@1.1.8': + resolution: {integrity: sha512-CpMLjAvwQg3BL5S0IeqsZNMH7EQrEWi0kLKOC13ZBF0ZwERiLWlibNPJr8G1kdU3Ms/r2KiNrF81pUh2HwAHdg==} peerDependencies: css-tree: ^3.2.1 peerDependenciesMeta: @@ -2293,8 +2293,8 @@ packages: resolution: {integrity: sha512-+Sg6GCR/wy1oSmQDFq4LQDAhm3ETKnorxN+y5nbLULOR3P0c14f2Wurzj3/xqPXtasLFfHd5iRFQ7AJt4KH2cw==} engines: {node: '>=8'} - '@jasminejs/reporters@1.0.0': - resolution: {integrity: sha512-rM3GG4vx2H1Gp5kYCTr9aKlOEJFd43pzpiMAiy5b1+FUc2ub4e6bS6yCi/WQNDzAa5MVp9++dwcoEtcIfoEnhA==} + '@jasminejs/reporters@1.1.0': + resolution: {integrity: sha512-JIrlfaf9c6m0+GtBAgZdcFB6RIRbFBbXxZDZ0WOewq4cLIEcVKEe0RgI1FA77M39FNzeSMTAm+LK/kcQVIkfGQ==} '@jridgewell/gen-mapping@0.3.13': resolution: {integrity: sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==} @@ -2354,50 +2354,50 @@ packages: peerDependencies: tslib: '2' - '@jsonjoy.com/fs-core@4.68.0': - resolution: {integrity: sha512-OAioDU3UGV34ECVTB4pt641OfUzuyDuyUmgrlVM+Fp9g4YyavZrB4xxWuupYrU66+81+um9D0DAzYhjXto5ysQ==} + '@jsonjoy.com/fs-core@4.68.1': + resolution: {integrity: sha512-V5oZ4Gt9WJKyQef0n9cAd0N9qjSkIBm3E4MYsgNIWBk5aINCDPKxMPo1i29rBxqiT4Ixf1epklqV9VJMKIxwlw==} engines: {node: '>=10.0'} peerDependencies: tslib: '2' - '@jsonjoy.com/fs-fsa@4.68.0': - resolution: {integrity: sha512-dC6VeW8uqXMF9Hkqb7qYST/t165XCHG+bNwwMzRetoNZRxJC8anr5XCJSAk5B+YLHGn6SP+noNltU6OFg/oa7A==} + '@jsonjoy.com/fs-fsa@4.68.1': + resolution: {integrity: sha512-HCG72UioncuO7Gw09XNVG+S85e3cq2hrUC/mexBrsWsa3mI7eePkkqWie3uVYbtsb64OR9YGQs5SqaufDRYBcg==} engines: {node: '>=10.0'} peerDependencies: tslib: '2' - '@jsonjoy.com/fs-node-builtins@4.68.0': - resolution: {integrity: sha512-j3bb+k4NuqpqXQzinCLeagS7LGLCUvPqA6TnpaBkBqhnPjbzETYiQFpD7pWaV8cGOhhZcAv9dmpzk5mxNb1qsg==} + '@jsonjoy.com/fs-node-builtins@4.68.1': + resolution: {integrity: sha512-HK1BTksysokNZxNspqDH0yPaqN9YgR/AYIlYiIaU2Ys4BOk5CdybI7r6BgiZuiiPiV8n4sK/kZdice7Znpy2Kw==} engines: {node: '>=10.0'} peerDependencies: tslib: '2' - '@jsonjoy.com/fs-node-to-fsa@4.68.0': - resolution: {integrity: sha512-dtLpmLQxw3IBcGxoK9tVvftwmQLl9qmQyivt8DZpeEwDUcQkxk2CLMZERXtmOlF1mWXfT9CqtjjMiswkb03rKw==} + '@jsonjoy.com/fs-node-to-fsa@4.68.1': + resolution: {integrity: sha512-lpKmU4X9e/oh8GIuAI7EXaS5QiLNM3KD15CkdhfS6PYmrGvoJqKQcyEfnLgnnaGslh/PFUMYSIZBCf2ejJGw8g==} engines: {node: '>=10.0'} peerDependencies: tslib: '2' - '@jsonjoy.com/fs-node-utils@4.68.0': - resolution: {integrity: sha512-Q84pogSfRaz0WNrBBy+HzBmhNu4m6tWoM0po8bLwW4pKvrwrSadOgFpm1sku08sfg0QAtUubkWuZEBDpNI3toQ==} + '@jsonjoy.com/fs-node-utils@4.68.1': + resolution: {integrity: sha512-/GxfW1DWm9SCdkfbvqevLO/P5duobQfmKkHXxdMIDbcZMQeAgooAstIfZhkXpATzq9QbCQsnoWFM/dGHdZfndw==} engines: {node: '>=10.0'} peerDependencies: tslib: '2' - '@jsonjoy.com/fs-node@4.68.0': - resolution: {integrity: sha512-xYDlpSk3UDHjcI0kiz6kNJ/oVTEzlS7kUzAoAsgJh2/+yOtYV/eZW7M8O9Fj+ED3BDONYKt7+8OiPlWl6xpFeA==} + '@jsonjoy.com/fs-node@4.68.1': + resolution: {integrity: sha512-R5D9mWtqdURzcOWj1vdXr3APCwX0xchtFT+kmW7fXLNDifWdDrnh26jSID8pdnUfFBxTyfHtFtTL/NWKzIH7kQ==} engines: {node: '>=10.0'} peerDependencies: tslib: '2' - '@jsonjoy.com/fs-print@4.68.0': - resolution: {integrity: sha512-sdy9F6N9QEcyAcU8OxEQmB91mlgiyuMphTFeijQ+qFgigCOeT16lW3X1dCWNzD7wwKLOKXnnYqsFyeq4LWSlYQ==} + '@jsonjoy.com/fs-print@4.68.1': + resolution: {integrity: sha512-oGeZOGPYKK9v1CgeVeEDsLomH1lCnslSpqUN5GmPzrmAVGQlsmsdcXNA2O4lV8Y4xkuSuynx2ITBkUHJVaTbow==} engines: {node: '>=10.0'} peerDependencies: tslib: '2' - '@jsonjoy.com/fs-snapshot@4.68.0': - resolution: {integrity: sha512-eV44t9KY9LH47aPR1a4Nv4xYxM1vQ+OKEw9Mx/3zkuxGOILwmtFddlh5HakdMFpFHwuFNPw1s+NGq2eVYFpQRA==} + '@jsonjoy.com/fs-snapshot@4.68.1': + resolution: {integrity: sha512-XZfP0FDZN32bbc4t2bZN2qRrYHg5AktJnzk22HRoKGK4BprrbNRH2k5ceSNS/kupKYcofCs+O841+xaAbjnxwQ==} engines: {node: '>=10.0'} peerDependencies: tslib: '2' @@ -2997,35 +2997,35 @@ packages: resolution: {integrity: sha512-7FNeNl8NCE7aINx7WXiKQrPYZWC/hvrTsmk6zmxbI7LTXE7hVek/n8AfVgpe2y82zl3w0HvCHN0bVKMBoJcC0w==} engines: {node: '>= 10.0.0'} - '@peculiar/asn1-cms@2.8.0': - resolution: {integrity: sha512-NgekZOrSJFSBFLFoLfwePguAWAx7z1+f2TEsWFUMyiqqfntZ4+S/S5hzqME3q4pCA0iOsFKdwiQ35dwY24eVqA==} + '@peculiar/asn1-cms@2.9.0': + resolution: {integrity: sha512-VKQz6sJYgSxtGaK6UdnNBUx7hmSdg0K331qrEWh5qxpQsyZGWBjxbq05AJ2bTWWjd7d+nJIxFzwvsR5T7DWC/A==} - '@peculiar/asn1-csr@2.8.0': - resolution: {integrity: sha512-akbF8+uvleHs8sejNPQxwmVFuInAg6FMNHOwMILXfP518YfFJwdR3jr6oNUPOaEJfuEhn/vkNOCIT6ASUd4mbg==} + '@peculiar/asn1-csr@2.9.0': + resolution: {integrity: sha512-SbxRzHiWnRdiDuiiji/RLsJxu2au4hmSZSKK7GQOgNr2BVvheAlFQST9qqzRchUcZ6wvcyRuPXIfYXVzLoZ/5g==} - '@peculiar/asn1-ecc@2.8.0': - resolution: {integrity: sha512-ohwlk+u9Rv2NOAY1c6MfHj45ATVF8R1DUN/WCgABiRtLi2ZftlZWZX7KvpAbU8v9xPcmoILfELeEABj/rn18AQ==} + '@peculiar/asn1-ecc@2.9.0': + resolution: {integrity: sha512-vNspHtTd9h6e8c2lMW+B/VHEUD+HRFV0fj/Gvz7SaJbwiecA8dxd96UTFPYI1PR8k7qwjjW9AFEyI+LuyVi4Kw==} - '@peculiar/asn1-pfx@2.8.0': - resolution: {integrity: sha512-5yof1ytoB++RQtaFbqSUJ8pxDJtZT6vbVqZ8XoJ61ph7UjNVvfFwAilnCodqkNsAodpy13gDhoxZXw00pghnyg==} + '@peculiar/asn1-pfx@2.9.0': + resolution: {integrity: sha512-A6bX+gZr69U38Pg1mWvPrM1eRba6L6kLR8iVG+bJtKj3qSv2rSNmlXLtej7ZOkEWt6xL6PiJD73uFEdQI3BXCg==} - '@peculiar/asn1-pkcs8@2.8.0': - resolution: {integrity: sha512-qAKXtLpBEw9LqhKpjw3ajZSXlBur+ipW+y2ivVBQAG6F6qRx94yO+1ZR4mvw+YaCfKSaOzLeYEzsPaBp4SJELA==} + '@peculiar/asn1-pkcs8@2.9.0': + resolution: {integrity: sha512-1JH4FliKQ3trkMD17X+bKGsph5TsiM+AiiqnVKr1wxA/GoUSDHiWG/zROzLAbDIA7eclBCjQsp8hrBEJk7LRUQ==} - '@peculiar/asn1-pkcs9@2.8.0': - resolution: {integrity: sha512-b5nDWCnkV60+cQ141D6sVVwK9nz64R5n3zSVnklGd+ECdkW2Ol3U1a6yYFlalpSOaD557yuJB64A+q42jG7lUQ==} + '@peculiar/asn1-pkcs9@2.9.0': + resolution: {integrity: sha512-igArY6bpCI6tOPm2EU9QPrXuKq2s1iraLCTym4UlooYdzcRDIPCRUN9TAEcqZ5rZhA+HiPdFKTbDP9vneN/tsg==} - '@peculiar/asn1-rsa@2.8.0': - resolution: {integrity: sha512-zHEUlCqB2mk7x2lxDwHHJy7hWZOPdGHVlsmITWKB5/PbQo61atbu9PJ/0r9dQNMwFzbKPXZ8uK8/91eUhRznSg==} + '@peculiar/asn1-rsa@2.9.0': + resolution: {integrity: sha512-vOD7Q4UmQWhlMYuWJawS2sD+/JcPKJNtyQuFZx09r+KFhm5/HxfGak63y/m56cpBjmb5k6PeRlQf1fvLQAieUA==} - '@peculiar/asn1-schema@2.8.0': - resolution: {integrity: sha512-7YT0U/ze0tF2QOBbE15gKZwy5tvgGyLRiRHLzhlbOpf7BT032oBSd0haZqXn5W6l26WLlu3dyxzjM+2638/z2Q==} + '@peculiar/asn1-schema@2.9.0': + resolution: {integrity: sha512-AKvPMOM7LfK0uFe1m7o7+veOa8xQGPqsqOrKi3QKgCElzwjGp39mbhr2g7mt/v/mXQHiIvJmDj5cJS173x8Q9Q==} - '@peculiar/asn1-x509-attr@2.8.0': - resolution: {integrity: sha512-tHjkfS/qhMnmrlB2J9NhflQlQ7In3khO3CfmVrriOlpTeErY9ZIKOso1hQ5JQiyrJ7ShvqVPk7E5fQmbclkSKA==} + '@peculiar/asn1-x509-attr@2.9.0': + resolution: {integrity: sha512-f+u+EyGjfPvPzvr0+rlh/TFEO7LWt84mEwQynCUYr4F6urf/8s6+ESJ23qfSn1aamkZR6AuBNaC62iEsGvp0+w==} - '@peculiar/asn1-x509@2.8.0': - resolution: {integrity: sha512-N0CMuhWUzsWEVq6F1q9X6+VKUnWzSW+cSVg+aPaGGwDdbFoFWTYgin5MHwXgpWd6y9COMBxnfy/Qc+Xc7F0Zwg==} + '@peculiar/asn1-x509@2.9.0': + resolution: {integrity: sha512-b9Na83rhRFQBd5CuMmuEqokYhmyWUbG7mNZl/thGhBwLpCdiZ85TZ3WFhF7OVgOekC5uKhLk4C3HKtdiScCMdQ==} '@peculiar/utils@2.0.3': resolution: {integrity: sha512-+oL3HPFRIZ1St2K50lWCXiioIgSoxzz7R1J3uF6neO2yl1sgmpgY6XXJH4BdpoDkMWznQTeYF6oWNDZLCdQ4eQ==} @@ -3635,10 +3635,6 @@ packages: eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 typescript: '>=4.8.4 <6.1.0' - '@typescript-eslint/types@8.66.0': - resolution: {integrity: sha512-H6gcYaSDOyvL3AD/jHUtUFo2jqGgn/F6nuyuZSu0QTesxL+cP4dQoIMrODRofuJC09g64+WgZ6tE19Y1N2YIFQ==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@typescript-eslint/types@8.67.0': resolution: {integrity: sha512-sBtgslww8nsMYUjhdPBiSyUqSzT8uR6g93A2QXnQC8+cGdjz0CyaOdqHDRJb1AtORbZCNUJBBeFA/tNR2uQmww==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} @@ -3824,10 +3820,9 @@ packages: '@webassemblyjs/wast-printer@1.14.1': resolution: {integrity: sha512-kPSSXE6De1XOR820C90RIo2ogvZG+c3KiHzqUoO/F34Y2shGzesfqv7o57xrxovZJH/MetF5UjroJ/R/3isoiw==} - '@xmldom/xmldom@0.8.13': - resolution: {integrity: sha512-KRYzxepc14G/CEpEGc3Yn+JKaAeT63smlDr+vjB8jRfgTBBI9wRj/nkQEO+ucV8p8I9bfKLWp37uHgFrbntPvw==} + '@xmldom/xmldom@0.8.14': + resolution: {integrity: sha512-T4EDRUBVZYRldYApjEJiU0e1stYWaRAX7CuSnKzrpwdZKo53zGV8/pqfzV6FfwNl9YThD2OumQYvqtvjvgG7aQ==} engines: {node: '>=10.0.0'} - deprecated: this version has critical issues, please update to the latest version '@xtuc/ieee754@1.2.0': resolution: {integrity: sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA==} @@ -3838,140 +3833,140 @@ packages: '@yarnpkg/lockfile@1.1.0': resolution: {integrity: sha512-GpSwvyXOcOOlV70vbnzjj4fW5xW/FdUF6nQEt1ENy7m4ZCczi1+/buVUPAqmGfqznsORNFzUMjctTIp8a9tuCQ==} - '@yuku-codegen/binding-android-arm64@0.8.4': - resolution: {integrity: sha512-rsYkGl2kOkDRsh1mxriYnk1qBS78vjlBJ3+T2XwtwKwqOliy2n+2Ae0EDxJ/uX1DZLm3KkBZarGO5isEnmHchA==} + '@yuku-codegen/binding-android-arm64@0.8.7': + resolution: {integrity: sha512-C/0zV5IhgVdYhGJTwrY0v8dknxlhiKwtVJkMUaexu9/QvRmzlV4vfU3hZlUSgqc2BxQHntL1mCVbDq8j0FRFDw==} cpu: [arm64] os: [android] - '@yuku-codegen/binding-darwin-arm64@0.8.4': - resolution: {integrity: sha512-tNLKzPF3FYmEcHSYvWp/LEpjHHAtDR13hwo6/gdCkYMi9x59CWn2obczKzWNe7kDor4/1AMZuJDEVRpFkTSefw==} + '@yuku-codegen/binding-darwin-arm64@0.8.7': + resolution: {integrity: sha512-/u+REDMI4a0/lsJXTM4c53/w31OGZLOReZIyg62uhgLs0kc8NHsj/nOcxTdlQjq5gi0zhdkccD9LaLTXcdzPvw==} cpu: [arm64] os: [darwin] - '@yuku-codegen/binding-darwin-x64@0.8.4': - resolution: {integrity: sha512-tK7LWzXNb5JbZpnoCNHB0nEhPFss/LwwehM6m/f0oYDan+iZgFZXzdoy80JdE7dVxjTZDIhUNPx8X8xbIdaoxA==} + '@yuku-codegen/binding-darwin-x64@0.8.7': + resolution: {integrity: sha512-sMMzFOwCo4WXR+/6zIBThOocSC50iIIZZdfiIDbaLvj0Ax/rWt/iavyfEAqajyvzydLyCqR/ZItdLWSRlu1umw==} cpu: [x64] os: [darwin] - '@yuku-codegen/binding-freebsd-x64@0.8.4': - resolution: {integrity: sha512-5MUV4d7g2p5Hd8GiXW6ynTRgYjm4Dw4eM2gaWRZ4crkGetzNx+HlPxcEfGtVNPqH5Qaa4Z2REtzdsdgvaE6/Ng==} + '@yuku-codegen/binding-freebsd-x64@0.8.7': + resolution: {integrity: sha512-MpdpKXix9P+Y1rKgjvcNeNtGjXeL1CmttNhYINrWls8kRpm4xM/oBGTmn6w7to8lAlwj5jm8q03dQPl5mRv4Qw==} cpu: [x64] os: [freebsd] - '@yuku-codegen/binding-linux-arm-gnu@0.8.4': - resolution: {integrity: sha512-g6LnHrR0Rfqq5cXs7olwR2+LlVDc876pw7Hh7YXbukVSiBxQkaxqsEO/trO25z2g99zWzgXwoYvQZ1TnwA2wEw==} + '@yuku-codegen/binding-linux-arm-gnu@0.8.7': + resolution: {integrity: sha512-rr1srFLlPAmC1vtxfc9C1YLDe3iH09YjfSeeIidBqKhzx1MATjOAq4mjlRUOnhr/L27MotWIYOFKwVsd5JZFOg==} cpu: [arm] os: [linux] libc: [glibc] - '@yuku-codegen/binding-linux-arm-musl@0.8.4': - resolution: {integrity: sha512-7XAPHrROPEFuJWXEGZeLZQN4xR8ENQ65+HSCtCHjSzCwGgnX53GUjM9ExVcHopV0a5g4vu57v2wwtyWIM5iNOQ==} + '@yuku-codegen/binding-linux-arm-musl@0.8.7': + resolution: {integrity: sha512-eAufXh8qBRpiSO6ueaMDL+yyoXIGLhpUce72YbcACtZU2qhExwBIJyEtQf5kH2Ki0X2aqkSjSfog4OPtKXan3Q==} cpu: [arm] os: [linux] libc: [musl] - '@yuku-codegen/binding-linux-arm64-gnu@0.8.4': - resolution: {integrity: sha512-fnBm7NLuuwFXy7F1vRIuyOc+RW9ADUjuCKVGY87Dj8jtr9XgESNrwb+B9VLSFY7nZ0rCdK/Sm1fBqJpI7eLdKQ==} + '@yuku-codegen/binding-linux-arm64-gnu@0.8.7': + resolution: {integrity: sha512-gw4w6wPoHObBrdIC4duVWLmJOvpdE25j5D7yrM5mACNlK4klRz/lv8hK+ssQk9EJHBgZjSaqZIJVFgqNYbfv7A==} cpu: [arm64] os: [linux] libc: [glibc] - '@yuku-codegen/binding-linux-arm64-musl@0.8.4': - resolution: {integrity: sha512-6vTw4ZHO9nm4SUkw36uG+UE6/qifZ0E8HIef7Mx/U/c2Zxu3JLBfXtU7U/NN2GMkDmcJkgwjXfpQoYw4Ch5Y1w==} + '@yuku-codegen/binding-linux-arm64-musl@0.8.7': + resolution: {integrity: sha512-L68N6Y4XkqcIaKo3Ra88JEvBEH4AHff44A4INcrxeVWZ8CZtu2tCpfVxe3hR8qQQMcvBSQlDn24KpkCKEhVvfA==} cpu: [arm64] os: [linux] libc: [musl] - '@yuku-codegen/binding-linux-x64-gnu@0.8.4': - resolution: {integrity: sha512-+vuC3V3Lw+DB4oJgHV9pVDfQZlsZJnxmbdods7HzxgEALU3P5+czwdAcw3wfh7Ebabt0Ny8eLUb1k9RV5OB/+w==} + '@yuku-codegen/binding-linux-x64-gnu@0.8.7': + resolution: {integrity: sha512-dzyAbltJmf3Cqlb8HcFuYIf5Yn0fl1vTr3XJ9HiVNNvOlhqPSArOqtw9vI1p6/VTXTjrMLXlU+s+/kNHiIy/Cw==} cpu: [x64] os: [linux] libc: [glibc] - '@yuku-codegen/binding-linux-x64-musl@0.8.4': - resolution: {integrity: sha512-QH60PE4eZecmgNGa1/T1cKPhrfxt6ANtu4lrQ1FZ50F9b0GS9WjGmIjrfdSUeQa+f2Iqk3oEFSJdgVHBg1KPNg==} + '@yuku-codegen/binding-linux-x64-musl@0.8.7': + resolution: {integrity: sha512-Otw4MH3404q0Bbvl+YTdW9aoUV5vXmUw8260bWvt1XlaoIX/ceSgI4ygheRDMfBPoHt6FDayQaO9OLVUZAgkFA==} cpu: [x64] os: [linux] libc: [musl] - '@yuku-codegen/binding-win32-arm64@0.8.4': - resolution: {integrity: sha512-6r68c0nKZPIBRXZIBiD7zjlEukBR+xRxpTOVj4n1Fsjcdh4YbbJfjFfmIzdbo9jXR1xL+dPueDVdsRGOUH5MoQ==} + '@yuku-codegen/binding-win32-arm64@0.8.7': + resolution: {integrity: sha512-qo/jyrzryiBuKEsFiuWaBCBe3tRMynQ0qFWFgOEjcCMQeZfBm+wKiVEUEFXXLc7bh8YezguAWp0Mtnhq4ARNyA==} cpu: [arm64] os: [win32] - '@yuku-codegen/binding-win32-x64@0.8.4': - resolution: {integrity: sha512-i+BW77LPjNqe7Apq50J3OeEaVfga3G+eT2bKjb6bj4yO99fil/jnKb4ZDH4JLvby/Q7hRa6VicL2EZ7iS+ifzA==} + '@yuku-codegen/binding-win32-x64@0.8.7': + resolution: {integrity: sha512-D5lDsVDx6m00E6bWySlWdH72Ca4TPSaphDqB6QjU6MpuNLIJqoGoatYyq2rOmBE8Zv/kunot/o58KGL03P3eiA==} cpu: [x64] os: [win32] - '@yuku-parser/binding-android-arm64@0.8.4': - resolution: {integrity: sha512-+HIMmv08Zrh9ugIAEMnKBMMePOl7CDxrjc8Vui1+GG2TJHM1yI1+3wo1pnXB6Nj2IiHugDkQw8ycUI6SA2EUkQ==} + '@yuku-parser/binding-android-arm64@0.8.7': + resolution: {integrity: sha512-eGKYiUDX7Y0V7tDTmg+JTVnXnjMqfXXsorZ+EDf5kxwchQ3Or1HS14MzI2fw+jFhHR85fCWt+mtX33Yao73hIQ==} cpu: [arm64] os: [android] - '@yuku-parser/binding-darwin-arm64@0.8.4': - resolution: {integrity: sha512-Elf/B/2m3OsyvxoQnBk8Dtu+9csHkzBNs5Yv9GbHjT3x0kVKNWjFusyZgm41VwxcPDqdpRi8tWxNX7OqXkmf/A==} + '@yuku-parser/binding-darwin-arm64@0.8.7': + resolution: {integrity: sha512-Re0RHelKLnjEURulY2/KxW+Ngb8zuNA4BRZuMwgGQNzVumT6u4U2N2hc01oeYVNVof0i7GrXE4UCNBgbpRRnjQ==} cpu: [arm64] os: [darwin] - '@yuku-parser/binding-darwin-x64@0.8.4': - resolution: {integrity: sha512-CjZuMoXnL5XUkVpDqh4WDPwpAw8CwmtHHnTerGkS45So/sNuwkXdyIAEqqIZfaLopi5W/V9NApAT2md9XizjsQ==} + '@yuku-parser/binding-darwin-x64@0.8.7': + resolution: {integrity: sha512-Hn8DROtQkjlA1ACbPgj4a7eP9IuVOI504oiTwpkWPbpaDWD9KdmnVYCqW+1LfenNK/g7O9NhWGpXEdaCNX7lIA==} cpu: [x64] os: [darwin] - '@yuku-parser/binding-freebsd-x64@0.8.4': - resolution: {integrity: sha512-ibLKORdz71iI4Vs+fyFgvwQ51P5XcxJIyQLa8cSEWqwptRdo+BTcZHIQEcZnFDPUuvmJ19RRH9CoiJdfhr7pZw==} + '@yuku-parser/binding-freebsd-x64@0.8.7': + resolution: {integrity: sha512-bAP2OV8wRuzplX/jYxv9+vvqQT8JxyNphI8fLfXGL054Xs+4/J5u33cIm3y4rxY8rdoLmmdiJs2Tq7r7lrDRfA==} cpu: [x64] os: [freebsd] - '@yuku-parser/binding-linux-arm-gnu@0.8.4': - resolution: {integrity: sha512-Fo3r5fYhGDcFnl+KN+L9PgtiQPS4AIE1n1mG1o5jZ11p7g5yZ/1EjLFmSHAUsoXreun8KjTsFjEL7P1Sb93PZQ==} + '@yuku-parser/binding-linux-arm-gnu@0.8.7': + resolution: {integrity: sha512-kTYwJQQgmZeAWdDIWabiReIZMpmfLueIj1tCmjStUtFGhR1Z0qwxonKVfUC4N7h/VhGGzLZ//7O1kgt1QKqgCg==} cpu: [arm] os: [linux] libc: [glibc] - '@yuku-parser/binding-linux-arm-musl@0.8.4': - resolution: {integrity: sha512-BEB31vUEgXPWf7WkoMPSzzJhpC/wWCBXyysRCCPsw47BJ/OtbQsvJbxX9fFDuSRLy3kbyIV/WbdUTgbQ9COxiw==} + '@yuku-parser/binding-linux-arm-musl@0.8.7': + resolution: {integrity: sha512-uL4jE8HPT2BLlxAXyD10LqgPuXa9eDa0BKpCdSANmzIJghq/2eZo3/gQNtaxPZMupWoxjYzSad9IXrwu7aYPXQ==} cpu: [arm] os: [linux] libc: [musl] - '@yuku-parser/binding-linux-arm64-gnu@0.8.4': - resolution: {integrity: sha512-xGLCRcHn9xVz7JVNyyKtiNJSf503qtUmih9XVSsghgzOmiKUMnHObs69OMMwXN3788tg1jsl11fNjjQlB8idMA==} + '@yuku-parser/binding-linux-arm64-gnu@0.8.7': + resolution: {integrity: sha512-3gVN4pWSKZmXiNX7cU164dR9MPvesCHnlH6nPfpK+yQsCuYphjKKplcb4SnZBrhiqmXbgb2HR0c2TS0IZUPhgA==} cpu: [arm64] os: [linux] libc: [glibc] - '@yuku-parser/binding-linux-arm64-musl@0.8.4': - resolution: {integrity: sha512-3kNRi8NJT2q6FQRVCUFHIQ99+kXdi8cVJEEUi6+xtFqpMgNrZNnbgAj28ILsDC7zmclaU+v47eUCeJoKLSCbww==} + '@yuku-parser/binding-linux-arm64-musl@0.8.7': + resolution: {integrity: sha512-S0mwfEjoLpxzXeZw802Wa4RaELsQiPtWqG6INcy8j4GtvNFtl4LCX3eGO1XLn9pyLAISLzTRyU3zUCBUPin8lg==} cpu: [arm64] os: [linux] libc: [musl] - '@yuku-parser/binding-linux-x64-gnu@0.8.4': - resolution: {integrity: sha512-isi62oMy94Z3OXwGs2l2rkqRiRyqLmfHeTRHpA/uWZbsNhnm7IdVvkF7e7wHNKAtd5jwGzOqYSroxKv2fOm7Cw==} + '@yuku-parser/binding-linux-x64-gnu@0.8.7': + resolution: {integrity: sha512-lnbWdPmerE5D1uH1G4IEZKnPzCrWCStRGrtgpSIe1RibAo5bZIjDbbbPYXmMHCEh4F+x/JaJpElh26a3r+BPbg==} cpu: [x64] os: [linux] libc: [glibc] - '@yuku-parser/binding-linux-x64-musl@0.8.4': - resolution: {integrity: sha512-9RsEw2xYHqU/pjSRBTOupWN3sF8uz9stjJdARfz6o0llvF+yfrj5QHmTiocGGBeAI80fvKmDtr2RIQClUzAPcA==} + '@yuku-parser/binding-linux-x64-musl@0.8.7': + resolution: {integrity: sha512-769uwndMvMzUvATWbAcEvyLHKA+DzhHSCl/obBUrRdYfRo26yxui6S8y3z7uJ+Naup7UKrDxrpK7OnQkxkl9KQ==} cpu: [x64] os: [linux] libc: [musl] - '@yuku-parser/binding-win32-arm64@0.8.4': - resolution: {integrity: sha512-VEZHo9rEGOBKR20sA3vCO00aQvwWND5aLu7YxeX+YupMZJh9hd1f17AbClJN37Q2iL1PCHht+wDTOKX6tZYqXg==} + '@yuku-parser/binding-win32-arm64@0.8.7': + resolution: {integrity: sha512-mEB/9PlaAkisJ6KWGz0zvywXoU6+80dTlR2LwS7s/jcXXoU6fm2+sitBZXtqu3+Q4DcDgPxM45uWMCzPs0TSRw==} cpu: [arm64] os: [win32] - '@yuku-parser/binding-win32-x64@0.8.4': - resolution: {integrity: sha512-PeH3VzN1feGjPtDpVEAqf000fPT+nxtw/696LKp/5Z9RJi/MaXpB636QC+5QtrAPSoEnIkyEe+c+mq2QLZPWBA==} + '@yuku-parser/binding-win32-x64@0.8.7': + resolution: {integrity: sha512-8vNB2DP0ou61nGb8tc/qfi41gfyDXz1MHr2zqL3nR+cJ6CEbiuWV/l/a/vv151gCgiZLLAyGkQGENpozdg716w==} cpu: [x64] os: [win32] - '@yuku-toolchain/types@0.8.4': - resolution: {integrity: sha512-p7JE8flrj7ijZ/qLjHi4UwKqMarMD6zumbKXhrjp2I2iLJOuTYiQyci2U36VlXcUlNyzsY7E/mLnKCHotbzJVw==} + '@yuku-toolchain/types@0.8.7': + resolution: {integrity: sha512-2Z53dNxAJL6UvFoIrDZvYf3zlO8s4VJK4O2hhaB4mXVwwpX/7ajtss3cmfqKvamlNLWyt9FSWs4eoYdlbxpnHA==} JSONStream@1.3.5: resolution: {integrity: sha512-E+iruNOY8VV9s4JEbe1aNEm6MiszPRr/UfcHMz0TQh1BXSxHK+ASV1R6W4HpjBhSeS+54PIsAMCBmwD06LLsqQ==} @@ -4054,8 +4049,8 @@ packages: resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==} engines: {node: '>=8'} - ansi-regex@6.2.2: - resolution: {integrity: sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg==} + ansi-regex@6.3.0: + resolution: {integrity: sha512-WpDfL7NO6j7tH88IDBNVdUJxDh9nmCteAVW9dsep846XdwF4naCBK+/tGLX3KJgcpgMRXCFlTM2hKGoK9FsdrQ==} engines: {node: '>=12'} ansi-styles@4.3.0: @@ -4248,8 +4243,8 @@ packages: bare-events: optional: true - bare-url@2.5.1: - resolution: {integrity: sha512-cD5ciQuKlx+eumTCfqbfiL+fhQm+dHbVNB/cX4+d+I/nx4JsVop9VoFEPAs5RJ6I84QR6bZIBjpd2kjDOYeWcg==} + bare-url@2.5.2: + resolution: {integrity: sha512-L13PCJzKG8RGvx8V1/DdMi12ERhC3tprr7/8a94BxpmnRsFqxh5XZNdhtMxu5HPkRshYOOWRGY8lDP7ZhpG9Cg==} base64-js@1.5.1: resolution: {integrity: sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==} @@ -4258,8 +4253,8 @@ packages: resolution: {integrity: sha512-lGe34o6EHj9y3Kts9R4ZYs/Gr+6N7MCaMlIFA3F1R2O5/m7K06AxfSeO5530PEERE6/WyEg3lsuyw4GHlPZHog==} engines: {node: ^4.5.0 || >= 5.9} - baseline-browser-mapping@2.11.13: - resolution: {integrity: sha512-k9HNuUVMlqVjQ9UHzfPjIqiDbWw7WqT1AoT7GL8VwvF3r0ZfArtgiSPAlmupyNquNgOJHTuH4CKYf8ttMTWBTQ==} + baseline-browser-mapping@2.11.14: + resolution: {integrity: sha512-JyJ954WzuIR8/FFzX0o5krdSTrBAkcCSRfWSleRsIHSWV+cZe2FI1PKggVkFke1hBldRs+LRxUczzE9iPmgZww==} engines: {node: '>=6.0.0'} hasBin: true @@ -4563,8 +4558,8 @@ packages: resolution: {integrity: sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==} engines: {node: '>= 0.6'} - content-type@2.0.0: - resolution: {integrity: sha512-j/O/d7GcZCyNl7/hwZAb606rzqkyvaDctLmckbxLzHvFBzTJHuGEdodATcP3yIRoDrLHkIATJuvzbFlp/ki2cQ==} + content-type@2.1.0: + resolution: {integrity: sha512-mj7UPXE0jaqaOsukNZRUEfEi2AcL7C/vwmwcHV0O97eO1E1pxBZuyjlZrx5seTaNBg1U6+o35wpa35Qfcc+7ag==} engines: {node: '>=18'} conventional-commits-filter@6.0.1: @@ -4744,8 +4739,8 @@ packages: resolution: {integrity: sha512-x1VCxdX4t+8wVfd1so/9w+vQ4vx7lKd2Qp5tDRutErwmR85OgmfX7RlLRMWafRMY7hbEiXIbudNrjOAPa/hL8Q==} engines: {node: '>=18'} - default-browser@5.5.0: - resolution: {integrity: sha512-H9LMLr5zwIbSxrmvikGuI/5KGhZ8E2zH3stkMgM5LpOWDutGM2JZaj460Udnf1a+946zc7YBgrqEWwbk7zHvGw==} + default-browser@5.5.1: + resolution: {integrity: sha512-m1pAzaJgZ/gssEqlOhJkPJp8Xly7QyW6xcrkUa2KKcDeDSEMP7X8xipU3snUcfisTQx0w1AGae+9UtJSfVnXGw==} engines: {node: '>=18'} define-data-property@1.1.4: @@ -4870,8 +4865,8 @@ packages: engines: {node: '>=0.12.18'} hasBin: true - electron-to-chromium@1.5.403: - resolution: {integrity: sha512-MQsYmdaLzvaCX5j+ZZBr5Fm6uCCnPQcRtlvmvRlWqrXy+BH2O4ffXIAScF+JQznQWB9brWp4lSD9Z4yNmaf2BA==} + electron-to-chromium@1.5.408: + resolution: {integrity: sha512-SLoprcYpJ/OH2v2ps0+N5biv9H4/KBT3+YmmDew64TwK5y9j2wv7pMOFY7IorVkyMtEyLSCRlXKLsNlakeAlPw==} emoji-regex@10.6.0: resolution: {integrity: sha512-toUI84YS5YmxW219erniWD0CIVOo46xGKColeNQRgOzDorgBi1v4D71/OFzgD9GO2UGKIv1C3Sp8DAn0+j5w7A==} @@ -4971,8 +4966,8 @@ packages: resolution: {integrity: sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==} engines: {node: '>= 0.4'} - es-module-lexer@2.3.1: - resolution: {integrity: sha512-shc1dbU90Yl/xq1QrC7QRtfcwURZuVRfPhZbDoldJ1cn1gzDvBaBWlv0eFolj5+0znnPJz5TXLxsN77X/12KTA==} + es-module-lexer@2.3.2: + resolution: {integrity: sha512-poHGpORABojJJucnV9KbOavETW8lBVnphkW77ER5/BQ5Fz7oXSoCNek7IH3vR5nRjdsEz926ibFYX8KtLQmdyw==} es-object-atoms@1.1.2: resolution: {integrity: sha512-HWcBoN6NileqtSydK2FqHbS/LoDd2pqrnQHLyJzBj4kOp/ky2MWMN694xOfkK8/SnUsW2DH7EfyVlydKCsm1Zw==} @@ -5337,8 +5332,8 @@ packages: resolution: {integrity: sha512-YGGyuEdVIjqxkxVH1pUTMY/XtmmsApXrCVv5EU25iX6inEPbV+VakJfLealkBtJN69AQmh1eGOdCl9Sm1UP6XQ==} engines: {node: '>=18'} - gaxios@7.3.0: - resolution: {integrity: sha512-RB5vLV+vvQeoFPCX4QMK6/hjVkbIamPp1QSUD0CiZcnj12qbpiL+pLbYtgD+oZkWl0tl9z+o2Utp+MpM3QRhBA==} + gaxios@7.3.1: + resolution: {integrity: sha512-kB3rzJV7d9juLZh8/56QTXCwQfxyhdOMdyYk1HdQKFtF8TJTDTZQJtixWIwXdE9Jji91mC41DUNpjleo4L4eAQ==} engines: {node: '>=18'} gcp-metadata@8.1.2: @@ -5626,8 +5621,8 @@ packages: resolution: {integrity: sha512-BAg6QkE8W+TuQLrrw0Ugr7HegXduRuuj8/ti2kSOc+jz1dmx8/WNcjr6XGnq5YpDWxFwwaavqD0+jIUOKelTsw==} engines: {node: '>= 4'} - immutable@3.8.3: - resolution: {integrity: sha512-AUY/VyX0E5XlibOmWt10uabJzam1zlYjwiEgQSDc5+UIkFNaF9WM0JxXKaNMGf+F/ffUF+7kRKXM9A7C0xXqMg==} + immutable@3.8.4: + resolution: {integrity: sha512-ZQv17KolYrYmsDoDB8N67zhIKsNi9mGYlk96y/yuxyAqJB2hLzSGSM7k/sB0/ZvO4kx27U9+fBeD/XlLGh/uXQ==} engines: {node: '>=0.10.0'} immutable@5.1.9: @@ -6006,8 +6001,8 @@ packages: json-stringify-safe@5.0.1: resolution: {integrity: sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA==} - json-with-bigint@3.5.10: - resolution: {integrity: sha512-Vcx+JVNEBts/xfcoCS69sKrOhOk/3TVlvlT+XzUOefVKnnrbYSCKpDCm10pohsJFtsJVYnwa/cXRZ4eElzaM6w==} + json-with-bigint@3.5.12: + resolution: {integrity: sha512-uwbF/wSSuOgC7qqlq27Xp5B6a2MHVug3t0idZdTqu0JnlFvgJuH7ju+KAk/J06C7GfhoYy2gnb9wz2INqcne7w==} json5@1.0.2: resolution: {integrity: sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==} @@ -6335,8 +6330,8 @@ packages: resolution: {integrity: sha512-yz3xRaG20c6/BOzvYoDaGtPmGscs7YivItZEEqe6GbwNfHuxu9YNmvnEkMzKldAGY4/80pRcQRZSEnhquk9XuQ==} engines: {node: '>= 0.8'} - memfs@4.68.0: - resolution: {integrity: sha512-qlU8XrIfXUuZcmXk/GODL47KXXnhSbbaWtW5z+L7cLFfIQbgAOWzL5lqUYn39kfJh+BHLaD/siaM94/UTweGow==} + memfs@4.68.1: + resolution: {integrity: sha512-OD+IDRUvIxu3QHL+nFm9gdyugInD27FDJ+sl4B5QgomPHXMlbw+GP918P8VNKu2FkNlVeqBkpzkwROpamVifRw==} merge-descriptors@1.0.3: resolution: {integrity: sha512-gaNvAS7TZ897/rVaZ0nMtAyxNyi/pdbjbAwUpFQpN70GqnVfOiXpeUUMKRBmzXaSQ8DdTX4/0ms62r2K+hE6mQ==} @@ -6949,8 +6944,8 @@ packages: engines: {node: '>=14'} hasBin: true - probe-image-size@7.3.0: - resolution: {integrity: sha512-7CaDeBwiAbh6ohXsvLbAZhO7wzsZAmaevfxe39qvCwRh8LyaZfDlBGGLU1CCTgrTLtCOdwBBhjOrIHaIIimHfQ==} + probe-image-size@7.4.0: + resolution: {integrity: sha512-cdEprVtZxV+awMde9X+4jILBFYh4CARxVrQaMl4wY4YcPWbul9jntXrIW95NInBDyJwcVUP3U0T6yukN8rMBaQ==} proc-log@7.0.0: resolution: {integrity: sha512-FYgfaA69XZ93zaXLoMNQ+ViDXGGBgR8aLh03txzcFhV+9xOXx7+8DLCULrKKpR9+GsH9ZfHm82aSUPpozX0Ztg==} @@ -7917,8 +7912,8 @@ packages: resolution: {integrity: sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==} engines: {node: '>= 0.8'} - update-browserslist-db@1.3.0: - resolution: {integrity: sha512-x/M6q3w4Ybp91CNaS4S69UnliqR3BzRpOT6LWbksjth0S/+jhfaPJsWjt/TewpT8j9eLIojUf5jr29WextHroA==} + update-browserslist-db@1.3.1: + resolution: {integrity: sha512-ZZ61DsRsOnakl74HAmp3oSN4aXUmEWXf+i/yv0h7tIBfICc3VdrFErQKUUKPgu3AMsTUMbcongALEN4l6GSUrQ==} hasBin: true peerDependencies: browserslist: '>= 4.21.0' @@ -8310,14 +8305,14 @@ packages: resolution: {integrity: sha512-xYqdZFUK/VYazNl/oCDYN+3WloWQwMfZxBoiNt6qNyk+xfOdi598muWE42rNZFp1kNOiqW936q5RhUdnpqElSg==} engines: {node: '>=18'} - yuku-ast@0.8.4: - resolution: {integrity: sha512-s7EWfWIQkaGmsGnyr/BU0jli9YTN5TvrKIsSmALyRD9elumDQInuhv0BrVObENKVCxr9W3Ikmnx5u02KvfuUmw==} + yuku-ast@0.8.7: + resolution: {integrity: sha512-h6+4bDfyootiMB9vckk5uKo5r5j0GHrkr17FQTDNfEsFT3DWlN9uu1HJwQwc64pgmLCI945fWM3lbTIqxjT3GQ==} - yuku-codegen@0.8.4: - resolution: {integrity: sha512-1Rw+NYcmB1xkHAWlsIpbwIv/Fr50idtEbLf7OjDA+90dny6PM4Krz7Fs0TT+w2PBdjaldZpN4ye5wR4Dhlm8vA==} + yuku-codegen@0.8.7: + resolution: {integrity: sha512-adwDZSh8oVDzhE6Du9PwVWxcOxeV0e2EVhUuMKWfhSY4wkrDq9eqixlxFF3l/XGUV1E7UFzhpz9393MUumkyNw==} - yuku-parser@0.8.4: - resolution: {integrity: sha512-sw41wouvT5rUmLIp87hmvm5vtF+MRSI3x6yjq6xqpYmtkQj+Ht6N7xRQ8lMhLv8N7JAzughGj0Rfi0jQRSu9HQ==} + yuku-parser@0.8.7: + resolution: {integrity: sha512-vRD9nwt4L3aYpxNqeSC4WqLv58xrXef0Ong1Mc45CTXTIpvLafx7JO05sczmQZwdLEZvywrLOGdNC5+Rp5N1BQ==} zod@3.25.76: resolution: {integrity: sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ==} @@ -8520,7 +8515,7 @@ snapshots: '@asamuzakjp/css-color@6.0.7': dependencies: '@csstools/css-calc': 3.3.0(@csstools/css-parser-algorithms@4.0.0(@csstools/css-tokenizer@4.0.0))(@csstools/css-tokenizer@4.0.0) - '@csstools/css-color-parser': 4.1.10(@csstools/css-parser-algorithms@4.0.0(@csstools/css-tokenizer@4.0.0))(@csstools/css-tokenizer@4.0.0) + '@csstools/css-color-parser': 4.2.0(@csstools/css-parser-algorithms@4.0.0(@csstools/css-tokenizer@4.0.0))(@csstools/css-tokenizer@4.0.0) '@csstools/css-parser-algorithms': 4.0.0(@csstools/css-tokenizer@4.0.0) '@csstools/css-tokenizer': 4.0.0 lru-cache: 11.5.2 @@ -9228,16 +9223,16 @@ snapshots: conventional-commits-filter: 6.0.1 conventional-commits-parser: 7.1.2 - '@csstools/color-helpers@6.1.0': {} + '@csstools/color-helpers@6.1.1': {} '@csstools/css-calc@3.3.0(@csstools/css-parser-algorithms@4.0.0(@csstools/css-tokenizer@4.0.0))(@csstools/css-tokenizer@4.0.0)': dependencies: '@csstools/css-parser-algorithms': 4.0.0(@csstools/css-tokenizer@4.0.0) '@csstools/css-tokenizer': 4.0.0 - '@csstools/css-color-parser@4.1.10(@csstools/css-parser-algorithms@4.0.0(@csstools/css-tokenizer@4.0.0))(@csstools/css-tokenizer@4.0.0)': + '@csstools/css-color-parser@4.2.0(@csstools/css-parser-algorithms@4.0.0(@csstools/css-tokenizer@4.0.0))(@csstools/css-tokenizer@4.0.0)': dependencies: - '@csstools/color-helpers': 6.1.0 + '@csstools/color-helpers': 6.1.1 '@csstools/css-calc': 3.3.0(@csstools/css-parser-algorithms@4.0.0(@csstools/css-tokenizer@4.0.0))(@csstools/css-tokenizer@4.0.0) '@csstools/css-parser-algorithms': 4.0.0(@csstools/css-tokenizer@4.0.0) '@csstools/css-tokenizer': 4.0.0 @@ -9246,7 +9241,7 @@ snapshots: dependencies: '@csstools/css-tokenizer': 4.0.0 - '@csstools/css-syntax-patches-for-csstree@1.1.7(css-tree@3.2.1)': + '@csstools/css-syntax-patches-for-csstree@1.1.8(css-tree@3.2.1)': optionalDependencies: css-tree: 3.2.1 @@ -10086,7 +10081,7 @@ snapshots: '@istanbuljs/schema@0.1.6': {} - '@jasminejs/reporters@1.0.0': {} + '@jasminejs/reporters@1.1.0': {} '@jridgewell/gen-mapping@0.3.13': dependencies: @@ -10138,59 +10133,59 @@ snapshots: dependencies: tslib: 2.8.1 - '@jsonjoy.com/fs-core@4.68.0(tslib@2.8.1)': + '@jsonjoy.com/fs-core@4.68.1(tslib@2.8.1)': dependencies: - '@jsonjoy.com/fs-node-builtins': 4.68.0(tslib@2.8.1) - '@jsonjoy.com/fs-node-utils': 4.68.0(tslib@2.8.1) + '@jsonjoy.com/fs-node-builtins': 4.68.1(tslib@2.8.1) + '@jsonjoy.com/fs-node-utils': 4.68.1(tslib@2.8.1) thingies: 2.6.1(tslib@2.8.1) tslib: 2.8.1 - '@jsonjoy.com/fs-fsa@4.68.0(tslib@2.8.1)': + '@jsonjoy.com/fs-fsa@4.68.1(tslib@2.8.1)': dependencies: - '@jsonjoy.com/fs-core': 4.68.0(tslib@2.8.1) - '@jsonjoy.com/fs-node-builtins': 4.68.0(tslib@2.8.1) - '@jsonjoy.com/fs-node-utils': 4.68.0(tslib@2.8.1) + '@jsonjoy.com/fs-core': 4.68.1(tslib@2.8.1) + '@jsonjoy.com/fs-node-builtins': 4.68.1(tslib@2.8.1) + '@jsonjoy.com/fs-node-utils': 4.68.1(tslib@2.8.1) thingies: 2.6.1(tslib@2.8.1) tslib: 2.8.1 - '@jsonjoy.com/fs-node-builtins@4.68.0(tslib@2.8.1)': + '@jsonjoy.com/fs-node-builtins@4.68.1(tslib@2.8.1)': dependencies: tslib: 2.8.1 - '@jsonjoy.com/fs-node-to-fsa@4.68.0(tslib@2.8.1)': + '@jsonjoy.com/fs-node-to-fsa@4.68.1(tslib@2.8.1)': dependencies: - '@jsonjoy.com/fs-fsa': 4.68.0(tslib@2.8.1) - '@jsonjoy.com/fs-node-builtins': 4.68.0(tslib@2.8.1) - '@jsonjoy.com/fs-node-utils': 4.68.0(tslib@2.8.1) + '@jsonjoy.com/fs-fsa': 4.68.1(tslib@2.8.1) + '@jsonjoy.com/fs-node-builtins': 4.68.1(tslib@2.8.1) + '@jsonjoy.com/fs-node-utils': 4.68.1(tslib@2.8.1) tslib: 2.8.1 - '@jsonjoy.com/fs-node-utils@4.68.0(tslib@2.8.1)': + '@jsonjoy.com/fs-node-utils@4.68.1(tslib@2.8.1)': dependencies: - '@jsonjoy.com/fs-node-builtins': 4.68.0(tslib@2.8.1) + '@jsonjoy.com/fs-node-builtins': 4.68.1(tslib@2.8.1) glob-to-regex.js: 1.2.0(tslib@2.8.1) tslib: 2.8.1 - '@jsonjoy.com/fs-node@4.68.0(tslib@2.8.1)': + '@jsonjoy.com/fs-node@4.68.1(tslib@2.8.1)': dependencies: - '@jsonjoy.com/fs-core': 4.68.0(tslib@2.8.1) - '@jsonjoy.com/fs-node-builtins': 4.68.0(tslib@2.8.1) - '@jsonjoy.com/fs-node-utils': 4.68.0(tslib@2.8.1) - '@jsonjoy.com/fs-print': 4.68.0(tslib@2.8.1) - '@jsonjoy.com/fs-snapshot': 4.68.0(tslib@2.8.1) + '@jsonjoy.com/fs-core': 4.68.1(tslib@2.8.1) + '@jsonjoy.com/fs-node-builtins': 4.68.1(tslib@2.8.1) + '@jsonjoy.com/fs-node-utils': 4.68.1(tslib@2.8.1) + '@jsonjoy.com/fs-print': 4.68.1(tslib@2.8.1) + '@jsonjoy.com/fs-snapshot': 4.68.1(tslib@2.8.1) glob-to-regex.js: 1.2.0(tslib@2.8.1) thingies: 2.6.1(tslib@2.8.1) tslib: 2.8.1 - '@jsonjoy.com/fs-print@4.68.0(tslib@2.8.1)': + '@jsonjoy.com/fs-print@4.68.1(tslib@2.8.1)': dependencies: - '@jsonjoy.com/fs-node-utils': 4.68.0(tslib@2.8.1) + '@jsonjoy.com/fs-node-utils': 4.68.1(tslib@2.8.1) tree-dump: 1.1.0(tslib@2.8.1) tslib: 2.8.1 - '@jsonjoy.com/fs-snapshot@4.68.0(tslib@2.8.1)': + '@jsonjoy.com/fs-snapshot@4.68.1(tslib@2.8.1)': dependencies: '@jsonjoy.com/buffers': 17.67.0(tslib@2.8.1) - '@jsonjoy.com/fs-node-utils': 4.68.0(tslib@2.8.1) + '@jsonjoy.com/fs-node-utils': 4.68.1(tslib@2.8.1) '@jsonjoy.com/json-pack': 17.67.0(tslib@2.8.1) '@jsonjoy.com/util': 17.67.0(tslib@2.8.1) tslib: 2.8.1 @@ -10508,8 +10503,8 @@ snapshots: '@octokit/endpoint': 11.0.4 '@octokit/request-error': 7.1.1 '@octokit/types': 17.0.0 - content-type: 2.0.0 - json-with-bigint: 3.5.10 + content-type: 2.1.0 + json-with-bigint: 3.5.12 universal-user-agent: 7.0.3 '@octokit/rest@22.0.1': @@ -10664,78 +10659,78 @@ snapshots: '@parcel/watcher-win32-arm64': 2.6.0 '@parcel/watcher-win32-x64': 2.6.0 - '@peculiar/asn1-cms@2.8.0': + '@peculiar/asn1-cms@2.9.0': dependencies: - '@peculiar/asn1-schema': 2.8.0 - '@peculiar/asn1-x509': 2.8.0 - '@peculiar/asn1-x509-attr': 2.8.0 + '@peculiar/asn1-schema': 2.9.0 + '@peculiar/asn1-x509': 2.9.0 + '@peculiar/asn1-x509-attr': 2.9.0 asn1js: 3.0.10 tslib: 2.8.1 - '@peculiar/asn1-csr@2.8.0': + '@peculiar/asn1-csr@2.9.0': dependencies: - '@peculiar/asn1-schema': 2.8.0 - '@peculiar/asn1-x509': 2.8.0 + '@peculiar/asn1-schema': 2.9.0 + '@peculiar/asn1-x509': 2.9.0 asn1js: 3.0.10 tslib: 2.8.1 - '@peculiar/asn1-ecc@2.8.0': + '@peculiar/asn1-ecc@2.9.0': dependencies: - '@peculiar/asn1-schema': 2.8.0 - '@peculiar/asn1-x509': 2.8.0 + '@peculiar/asn1-schema': 2.9.0 + '@peculiar/asn1-x509': 2.9.0 asn1js: 3.0.10 tslib: 2.8.1 - '@peculiar/asn1-pfx@2.8.0': + '@peculiar/asn1-pfx@2.9.0': dependencies: - '@peculiar/asn1-cms': 2.8.0 - '@peculiar/asn1-pkcs8': 2.8.0 - '@peculiar/asn1-rsa': 2.8.0 - '@peculiar/asn1-schema': 2.8.0 + '@peculiar/asn1-cms': 2.9.0 + '@peculiar/asn1-pkcs8': 2.9.0 + '@peculiar/asn1-rsa': 2.9.0 + '@peculiar/asn1-schema': 2.9.0 asn1js: 3.0.10 tslib: 2.8.1 - '@peculiar/asn1-pkcs8@2.8.0': + '@peculiar/asn1-pkcs8@2.9.0': dependencies: - '@peculiar/asn1-schema': 2.8.0 - '@peculiar/asn1-x509': 2.8.0 + '@peculiar/asn1-schema': 2.9.0 + '@peculiar/asn1-x509': 2.9.0 asn1js: 3.0.10 tslib: 2.8.1 - '@peculiar/asn1-pkcs9@2.8.0': + '@peculiar/asn1-pkcs9@2.9.0': dependencies: - '@peculiar/asn1-cms': 2.8.0 - '@peculiar/asn1-pfx': 2.8.0 - '@peculiar/asn1-pkcs8': 2.8.0 - '@peculiar/asn1-schema': 2.8.0 - '@peculiar/asn1-x509': 2.8.0 - '@peculiar/asn1-x509-attr': 2.8.0 + '@peculiar/asn1-cms': 2.9.0 + '@peculiar/asn1-pfx': 2.9.0 + '@peculiar/asn1-pkcs8': 2.9.0 + '@peculiar/asn1-schema': 2.9.0 + '@peculiar/asn1-x509': 2.9.0 + '@peculiar/asn1-x509-attr': 2.9.0 asn1js: 3.0.10 tslib: 2.8.1 - '@peculiar/asn1-rsa@2.8.0': + '@peculiar/asn1-rsa@2.9.0': dependencies: - '@peculiar/asn1-schema': 2.8.0 - '@peculiar/asn1-x509': 2.8.0 + '@peculiar/asn1-schema': 2.9.0 + '@peculiar/asn1-x509': 2.9.0 asn1js: 3.0.10 tslib: 2.8.1 - '@peculiar/asn1-schema@2.8.0': + '@peculiar/asn1-schema@2.9.0': dependencies: '@peculiar/utils': 2.0.3 asn1js: 3.0.10 tslib: 2.8.1 - '@peculiar/asn1-x509-attr@2.8.0': + '@peculiar/asn1-x509-attr@2.9.0': dependencies: - '@peculiar/asn1-schema': 2.8.0 - '@peculiar/asn1-x509': 2.8.0 + '@peculiar/asn1-schema': 2.9.0 + '@peculiar/asn1-x509': 2.9.0 asn1js: 3.0.10 tslib: 2.8.1 - '@peculiar/asn1-x509@2.8.0': + '@peculiar/asn1-x509@2.9.0': dependencies: - '@peculiar/asn1-schema': 2.8.0 + '@peculiar/asn1-schema': 2.9.0 '@peculiar/utils': 2.0.3 asn1js: 3.0.10 tslib: 2.8.1 @@ -10746,13 +10741,13 @@ snapshots: '@peculiar/x509@1.14.3': dependencies: - '@peculiar/asn1-cms': 2.8.0 - '@peculiar/asn1-csr': 2.8.0 - '@peculiar/asn1-ecc': 2.8.0 - '@peculiar/asn1-pkcs9': 2.8.0 - '@peculiar/asn1-rsa': 2.8.0 - '@peculiar/asn1-schema': 2.8.0 - '@peculiar/asn1-x509': 2.8.0 + '@peculiar/asn1-cms': 2.9.0 + '@peculiar/asn1-csr': 2.9.0 + '@peculiar/asn1-ecc': 2.9.0 + '@peculiar/asn1-pkcs9': 2.9.0 + '@peculiar/asn1-rsa': 2.9.0 + '@peculiar/asn1-schema': 2.9.0 + '@peculiar/asn1-x509': 2.9.0 pvtsutils: 1.3.6 reflect-metadata: 0.2.2 tslib: 2.8.1 @@ -10993,7 +10988,7 @@ snapshots: '@stylistic/eslint-plugin@5.10.0(eslint@10.8.1(jiti@2.7.0)(supports-color@11.0.0))': dependencies: '@eslint-community/eslint-utils': 4.10.1(eslint@10.8.1(jiti@2.7.0)(supports-color@11.0.0)) - '@typescript-eslint/types': 8.66.0 + '@typescript-eslint/types': 8.67.0 eslint: 10.8.1(jiti@2.7.0)(supports-color@11.0.0) eslint-visitor-keys: 4.2.1 espree: 10.4.0 @@ -11281,8 +11276,6 @@ snapshots: transitivePeerDependencies: - supports-color - '@typescript-eslint/types@8.66.0': {} - '@typescript-eslint/types@8.67.0': {} '@typescript-eslint/typescript-estree@8.67.0(supports-color@11.0.0)(typescript@6.0.3)': @@ -11614,7 +11607,7 @@ snapshots: '@webassemblyjs/ast': 1.14.1 '@xtuc/long': 4.2.2 - '@xmldom/xmldom@0.8.13': {} + '@xmldom/xmldom@0.8.14': {} '@xtuc/ieee754@1.2.0': {} @@ -11622,79 +11615,79 @@ snapshots: '@yarnpkg/lockfile@1.1.0': {} - '@yuku-codegen/binding-android-arm64@0.8.4': + '@yuku-codegen/binding-android-arm64@0.8.7': optional: true - '@yuku-codegen/binding-darwin-arm64@0.8.4': + '@yuku-codegen/binding-darwin-arm64@0.8.7': optional: true - '@yuku-codegen/binding-darwin-x64@0.8.4': + '@yuku-codegen/binding-darwin-x64@0.8.7': optional: true - '@yuku-codegen/binding-freebsd-x64@0.8.4': + '@yuku-codegen/binding-freebsd-x64@0.8.7': optional: true - '@yuku-codegen/binding-linux-arm-gnu@0.8.4': + '@yuku-codegen/binding-linux-arm-gnu@0.8.7': optional: true - '@yuku-codegen/binding-linux-arm-musl@0.8.4': + '@yuku-codegen/binding-linux-arm-musl@0.8.7': optional: true - '@yuku-codegen/binding-linux-arm64-gnu@0.8.4': + '@yuku-codegen/binding-linux-arm64-gnu@0.8.7': optional: true - '@yuku-codegen/binding-linux-arm64-musl@0.8.4': + '@yuku-codegen/binding-linux-arm64-musl@0.8.7': optional: true - '@yuku-codegen/binding-linux-x64-gnu@0.8.4': + '@yuku-codegen/binding-linux-x64-gnu@0.8.7': optional: true - '@yuku-codegen/binding-linux-x64-musl@0.8.4': + '@yuku-codegen/binding-linux-x64-musl@0.8.7': optional: true - '@yuku-codegen/binding-win32-arm64@0.8.4': + '@yuku-codegen/binding-win32-arm64@0.8.7': optional: true - '@yuku-codegen/binding-win32-x64@0.8.4': + '@yuku-codegen/binding-win32-x64@0.8.7': optional: true - '@yuku-parser/binding-android-arm64@0.8.4': + '@yuku-parser/binding-android-arm64@0.8.7': optional: true - '@yuku-parser/binding-darwin-arm64@0.8.4': + '@yuku-parser/binding-darwin-arm64@0.8.7': optional: true - '@yuku-parser/binding-darwin-x64@0.8.4': + '@yuku-parser/binding-darwin-x64@0.8.7': optional: true - '@yuku-parser/binding-freebsd-x64@0.8.4': + '@yuku-parser/binding-freebsd-x64@0.8.7': optional: true - '@yuku-parser/binding-linux-arm-gnu@0.8.4': + '@yuku-parser/binding-linux-arm-gnu@0.8.7': optional: true - '@yuku-parser/binding-linux-arm-musl@0.8.4': + '@yuku-parser/binding-linux-arm-musl@0.8.7': optional: true - '@yuku-parser/binding-linux-arm64-gnu@0.8.4': + '@yuku-parser/binding-linux-arm64-gnu@0.8.7': optional: true - '@yuku-parser/binding-linux-arm64-musl@0.8.4': + '@yuku-parser/binding-linux-arm64-musl@0.8.7': optional: true - '@yuku-parser/binding-linux-x64-gnu@0.8.4': + '@yuku-parser/binding-linux-x64-gnu@0.8.7': optional: true - '@yuku-parser/binding-linux-x64-musl@0.8.4': + '@yuku-parser/binding-linux-x64-musl@0.8.7': optional: true - '@yuku-parser/binding-win32-arm64@0.8.4': + '@yuku-parser/binding-win32-arm64@0.8.7': optional: true - '@yuku-parser/binding-win32-x64@0.8.4': + '@yuku-parser/binding-win32-x64@0.8.7': optional: true - '@yuku-toolchain/types@0.8.4': {} + '@yuku-toolchain/types@0.8.7': {} JSONStream@1.3.5: dependencies: @@ -11773,7 +11766,7 @@ snapshots: ansi-regex@5.0.1: {} - ansi-regex@6.2.2: {} + ansi-regex@6.3.0: {} ansi-styles@4.3.0: dependencies: @@ -11929,7 +11922,7 @@ snapshots: bare-events: 2.9.1 bare-path: 3.1.1 bare-stream: 2.13.3(bare-events@2.9.1) - bare-url: 2.5.1 + bare-url: 2.5.2 fast-fifo: 1.3.2 transitivePeerDependencies: - bare-abort-controller @@ -11947,7 +11940,7 @@ snapshots: transitivePeerDependencies: - react-native-b4a - bare-url@2.5.1: + bare-url@2.5.2: dependencies: bare-path: 3.1.1 @@ -11955,7 +11948,7 @@ snapshots: base64id@2.0.0: {} - baseline-browser-mapping@2.11.13: {} + baseline-browser-mapping@2.11.14: {} batch@0.6.1: {} @@ -12011,7 +12004,7 @@ snapshots: body-parser@2.3.0(supports-color@11.0.0): dependencies: bytes: 3.1.2 - content-type: 2.0.0 + content-type: 2.1.0 debug: 4.4.3(supports-color@11.0.0) http-errors: 2.0.1 iconv-lite: 0.7.3 @@ -12059,7 +12052,7 @@ snapshots: async-each-series: 0.1.1 chalk: 4.1.2 connect-history-api-fallback: 1.6.0 - immutable: 3.8.3 + immutable: 3.8.4 server-destroy: 1.0.1 socket.io-client: 4.8.3(bufferutil@4.1.0)(supports-color@11.0.0)(utf-8-validate@6.0.6) stream-throttle: 0.1.3 @@ -12084,7 +12077,7 @@ snapshots: fresh: 0.5.2 fs-extra: 3.0.1 http-proxy: 1.18.1(debug@4.4.3(supports-color@11.0.0)) - immutable: 3.8.3 + immutable: 3.8.4 micromatch: 4.0.8 opn: 5.3.0 portscanner: 2.2.0 @@ -12110,11 +12103,11 @@ snapshots: browserslist@4.28.8: dependencies: - baseline-browser-mapping: 2.11.13 + baseline-browser-mapping: 2.11.14 caniuse-lite: 1.0.30001809 - electron-to-chromium: 1.5.403 + electron-to-chromium: 1.5.408 node-releases: 2.0.53 - update-browserslist-db: 1.3.0(browserslist@4.28.8) + update-browserslist-db: 1.3.1(browserslist@4.28.8) bs-recipes@1.3.4: {} @@ -12340,7 +12333,7 @@ snapshots: content-type@1.0.5: {} - content-type@2.0.0: {} + content-type@2.1.0: {} conventional-commits-filter@6.0.1: {} @@ -12503,7 +12496,7 @@ snapshots: default-browser-id@5.0.1: {} - default-browser@5.5.0: + default-browser@5.5.1: dependencies: bundle-name: 4.1.0 default-browser-id: 5.0.1 @@ -12624,7 +12617,7 @@ snapshots: ejs@6.0.1: {} - electron-to-chromium@1.5.403: {} + electron-to-chromium@1.5.408: {} emoji-regex@10.6.0: {} @@ -12780,7 +12773,7 @@ snapshots: es-errors@1.3.0: {} - es-module-lexer@2.3.1: {} + es-module-lexer@2.3.2: {} es-object-atoms@1.1.2: dependencies: @@ -13314,7 +13307,7 @@ snapshots: transitivePeerDependencies: - supports-color - gaxios@7.3.0(supports-color@11.0.0): + gaxios@7.3.1(supports-color@11.0.0): dependencies: extend: 3.0.2 https-proxy-agent: 7.0.6(supports-color@11.0.0) @@ -13324,7 +13317,7 @@ snapshots: gcp-metadata@8.1.2(supports-color@11.0.0): dependencies: - gaxios: 7.3.0(supports-color@11.0.0) + gaxios: 7.3.1(supports-color@11.0.0) google-logging-utils: 1.1.3 json-bigint: 1.0.0 transitivePeerDependencies: @@ -13443,7 +13436,7 @@ snapshots: dependencies: base64-js: 1.5.1 ecdsa-sig-formatter: 1.0.11 - gaxios: 7.3.0(supports-color@11.0.0) + gaxios: 7.3.1(supports-color@11.0.0) gcp-metadata: 8.1.4(supports-color@11.0.0) google-logging-utils: 1.1.3 gtoken: 8.0.0(supports-color@11.0.0) @@ -13455,7 +13448,7 @@ snapshots: dependencies: base64-js: 1.5.1 ecdsa-sig-formatter: 1.0.11 - gaxios: 7.3.0(supports-color@11.0.0) + gaxios: 7.3.1(supports-color@11.0.0) gcp-metadata: 8.1.2(supports-color@11.0.0) google-logging-utils: 1.1.3 jws: 4.0.1 @@ -13513,7 +13506,7 @@ snapshots: gtoken@8.0.0(supports-color@11.0.0): dependencies: - gaxios: 7.3.0(supports-color@11.0.0) + gaxios: 7.3.1(supports-color@11.0.0) jws: 4.0.1 transitivePeerDependencies: - supports-color @@ -13690,7 +13683,7 @@ snapshots: ignore@7.0.6: {} - immutable@3.8.3: {} + immutable@3.8.4: {} immutable@5.1.9: {} @@ -13975,7 +13968,7 @@ snapshots: jasmine-reporters@2.5.2: dependencies: - '@xmldom/xmldom': 0.8.13 + '@xmldom/xmldom': 0.8.14 mkdirp: 1.0.4 jasmine-spec-reporter@7.0.0: @@ -13984,7 +13977,7 @@ snapshots: jasmine@6.3.0: dependencies: - '@jasminejs/reporters': 1.0.0 + '@jasminejs/reporters': 1.1.0 glob: 13.0.6 jasmine-core: 6.3.0 @@ -14015,7 +14008,7 @@ snapshots: '@asamuzakjp/css-color': 6.0.7 '@asamuzakjp/dom-selector': 8.3.2 '@bramus/specificity': 2.4.2 - '@csstools/css-syntax-patches-for-csstree': 1.1.7(css-tree@3.2.1) + '@csstools/css-syntax-patches-for-csstree': 1.1.8(css-tree@3.2.1) '@exodus/bytes': 1.15.1 css-tree: 3.2.1 data-urls: 7.0.0 @@ -14056,7 +14049,7 @@ snapshots: json-stringify-safe@5.0.1: {} - json-with-bigint@3.5.10: {} + json-with-bigint@3.5.12: {} json5@1.0.2: dependencies: @@ -14201,7 +14194,7 @@ snapshots: make-dir: 5.1.0 mime: 1.6.0 needle: 3.5.0 - probe-image-size: 7.3.0(supports-color@11.0.0) + probe-image-size: 7.4.0(supports-color@11.0.0) source-map: 0.6.1 transitivePeerDependencies: - supports-color @@ -14416,16 +14409,16 @@ snapshots: media-typer@1.1.1: {} - memfs@4.68.0: + memfs@4.68.1: dependencies: - '@jsonjoy.com/fs-core': 4.68.0(tslib@2.8.1) - '@jsonjoy.com/fs-fsa': 4.68.0(tslib@2.8.1) - '@jsonjoy.com/fs-node': 4.68.0(tslib@2.8.1) - '@jsonjoy.com/fs-node-builtins': 4.68.0(tslib@2.8.1) - '@jsonjoy.com/fs-node-to-fsa': 4.68.0(tslib@2.8.1) - '@jsonjoy.com/fs-node-utils': 4.68.0(tslib@2.8.1) - '@jsonjoy.com/fs-print': 4.68.0(tslib@2.8.1) - '@jsonjoy.com/fs-snapshot': 4.68.0(tslib@2.8.1) + '@jsonjoy.com/fs-core': 4.68.1(tslib@2.8.1) + '@jsonjoy.com/fs-fsa': 4.68.1(tslib@2.8.1) + '@jsonjoy.com/fs-node': 4.68.1(tslib@2.8.1) + '@jsonjoy.com/fs-node-builtins': 4.68.1(tslib@2.8.1) + '@jsonjoy.com/fs-node-to-fsa': 4.68.1(tslib@2.8.1) + '@jsonjoy.com/fs-node-utils': 4.68.1(tslib@2.8.1) + '@jsonjoy.com/fs-print': 4.68.1(tslib@2.8.1) + '@jsonjoy.com/fs-snapshot': 4.68.1(tslib@2.8.1) '@jsonjoy.com/json-pack': 1.21.0(tslib@2.8.1) '@jsonjoy.com/util': 1.9.0(tslib@2.8.1) glob-to-regex.js: 1.2.0(tslib@2.8.1) @@ -14755,7 +14748,7 @@ snapshots: open@11.0.0: dependencies: - default-browser: 5.5.0 + default-browser: 5.5.1 define-lazy-prop: 3.0.0 is-in-ssh: 1.0.0 is-inside-container: 1.0.0 @@ -15035,7 +15028,7 @@ snapshots: prettier@3.9.6: {} - probe-image-size@7.3.0(supports-color@11.0.0): + probe-image-size@7.4.0(supports-color@11.0.0): dependencies: lodash.merge: 4.6.2 needle: 2.9.1(supports-color@11.0.0) @@ -15346,9 +15339,9 @@ snapshots: get-tsconfig: 5.0.0-beta.5 obug: 2.1.4 rolldown: 1.2.4 - yuku-ast: 0.8.4 - yuku-codegen: 0.8.4 - yuku-parser: 0.8.4 + yuku-ast: 0.8.7 + yuku-codegen: 0.8.7 + yuku-parser: 0.8.7 optionalDependencies: typescript: 6.0.3 transitivePeerDependencies: @@ -15892,7 +15885,7 @@ snapshots: strip-ansi@7.2.0: dependencies: - ansi-regex: 6.2.2 + ansi-regex: 6.3.0 strip-bom@3.0.0: {} @@ -16086,7 +16079,7 @@ snapshots: type-is@2.1.0: dependencies: - content-type: 2.0.0 + content-type: 2.1.0 media-typer: 1.1.1 mime-types: 3.0.2 @@ -16194,7 +16187,7 @@ snapshots: unpipe@1.0.0: {} - update-browserslist-db@1.3.0(browserslist@4.28.8): + update-browserslist-db@1.3.1(browserslist@4.28.8): dependencies: browserslist: 4.28.8 escalade: 3.2.0 @@ -16325,7 +16318,7 @@ snapshots: '@vitest/snapshot': 4.1.10 '@vitest/spy': 4.1.10 '@vitest/utils': 4.1.10 - es-module-lexer: 2.3.1 + es-module-lexer: 2.3.2 expect-type: 1.4.0 magic-string: 0.30.21 obug: 2.1.4 @@ -16382,7 +16375,7 @@ snapshots: webpack-dev-middleware@8.1.1(webpack@5.109.2(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.26)(uglify-js@3.19.3)): dependencies: - memfs: 4.68.0 + memfs: 4.68.1 mime-types: 3.0.2 range-parser: 1.3.0 schema-utils: 4.3.3 @@ -16447,7 +16440,7 @@ snapshots: browserslist: 4.28.8 chrome-trace-event: 1.0.4 enhanced-resolve: 5.24.5 - es-module-lexer: 2.3.1 + es-module-lexer: 2.3.2 eslint-scope: 5.1.1 events: 3.3.0 graceful-fs: 4.2.11 @@ -16483,7 +16476,7 @@ snapshots: browserslist: 4.28.8 chrome-trace-event: 1.0.4 enhanced-resolve: 5.24.5 - es-module-lexer: 2.3.1 + es-module-lexer: 2.3.2 eslint-scope: 5.1.1 events: 3.3.0 graceful-fs: 4.2.11 @@ -16696,44 +16689,44 @@ snapshots: yoctocolors@2.2.0: {} - yuku-ast@0.8.4: + yuku-ast@0.8.7: dependencies: - '@yuku-toolchain/types': 0.8.4 + '@yuku-toolchain/types': 0.8.7 - yuku-codegen@0.8.4: + yuku-codegen@0.8.7: dependencies: - '@yuku-toolchain/types': 0.8.4 + '@yuku-toolchain/types': 0.8.7 optionalDependencies: - '@yuku-codegen/binding-android-arm64': 0.8.4 - '@yuku-codegen/binding-darwin-arm64': 0.8.4 - '@yuku-codegen/binding-darwin-x64': 0.8.4 - '@yuku-codegen/binding-freebsd-x64': 0.8.4 - '@yuku-codegen/binding-linux-arm-gnu': 0.8.4 - '@yuku-codegen/binding-linux-arm-musl': 0.8.4 - '@yuku-codegen/binding-linux-arm64-gnu': 0.8.4 - '@yuku-codegen/binding-linux-arm64-musl': 0.8.4 - '@yuku-codegen/binding-linux-x64-gnu': 0.8.4 - '@yuku-codegen/binding-linux-x64-musl': 0.8.4 - '@yuku-codegen/binding-win32-arm64': 0.8.4 - '@yuku-codegen/binding-win32-x64': 0.8.4 - - yuku-parser@0.8.4: - dependencies: - '@yuku-toolchain/types': 0.8.4 - yuku-ast: 0.8.4 + '@yuku-codegen/binding-android-arm64': 0.8.7 + '@yuku-codegen/binding-darwin-arm64': 0.8.7 + '@yuku-codegen/binding-darwin-x64': 0.8.7 + '@yuku-codegen/binding-freebsd-x64': 0.8.7 + '@yuku-codegen/binding-linux-arm-gnu': 0.8.7 + '@yuku-codegen/binding-linux-arm-musl': 0.8.7 + '@yuku-codegen/binding-linux-arm64-gnu': 0.8.7 + '@yuku-codegen/binding-linux-arm64-musl': 0.8.7 + '@yuku-codegen/binding-linux-x64-gnu': 0.8.7 + '@yuku-codegen/binding-linux-x64-musl': 0.8.7 + '@yuku-codegen/binding-win32-arm64': 0.8.7 + '@yuku-codegen/binding-win32-x64': 0.8.7 + + yuku-parser@0.8.7: + dependencies: + '@yuku-toolchain/types': 0.8.7 + yuku-ast: 0.8.7 optionalDependencies: - '@yuku-parser/binding-android-arm64': 0.8.4 - '@yuku-parser/binding-darwin-arm64': 0.8.4 - '@yuku-parser/binding-darwin-x64': 0.8.4 - '@yuku-parser/binding-freebsd-x64': 0.8.4 - '@yuku-parser/binding-linux-arm-gnu': 0.8.4 - '@yuku-parser/binding-linux-arm-musl': 0.8.4 - '@yuku-parser/binding-linux-arm64-gnu': 0.8.4 - '@yuku-parser/binding-linux-arm64-musl': 0.8.4 - '@yuku-parser/binding-linux-x64-gnu': 0.8.4 - '@yuku-parser/binding-linux-x64-musl': 0.8.4 - '@yuku-parser/binding-win32-arm64': 0.8.4 - '@yuku-parser/binding-win32-x64': 0.8.4 + '@yuku-parser/binding-android-arm64': 0.8.7 + '@yuku-parser/binding-darwin-arm64': 0.8.7 + '@yuku-parser/binding-darwin-x64': 0.8.7 + '@yuku-parser/binding-freebsd-x64': 0.8.7 + '@yuku-parser/binding-linux-arm-gnu': 0.8.7 + '@yuku-parser/binding-linux-arm-musl': 0.8.7 + '@yuku-parser/binding-linux-arm64-gnu': 0.8.7 + '@yuku-parser/binding-linux-arm64-musl': 0.8.7 + '@yuku-parser/binding-linux-x64-gnu': 0.8.7 + '@yuku-parser/binding-linux-x64-musl': 0.8.7 + '@yuku-parser/binding-win32-arm64': 0.8.7 + '@yuku-parser/binding-win32-x64': 0.8.7 zod@3.25.76: {} From 175273931ebb0cf08bf62dd1694dbde5ff5229b6 Mon Sep 17 00:00:00 2001 From: Troy Steuwer Date: Sun, 17 May 2026 08:42:50 -0400 Subject: [PATCH 317/787] feat(@angular/build): Support splitting browser and server stats jsonfiles for easier consumption This feature supports splitting out the browser and server stats json files so it's easier to inspect the bundle in various analyzers and addresses #28185 #28671. Today, everything gets dumped into a single file and it's nearly impossible to use without hours of `fix -> remove unused browser/server chunks -> analyze` and starting the loop all over again. This feature implements the feature request I made in #28185, along with another developers request to see a stats json file for just the initial page bundle. I've tested this out in my own repository and it's already helped an incredible amount. This will be required to be in the next Major version as it will break any existing build pipeline that relies on a single stats.json file. --- .../builders/application/chunk-optimizer.ts | 20 +++ .../src/builders/application/execute-build.ts | 61 ++++++- .../tests/options/stats-json_spec.ts | 165 ++++++++++++++++++ .../esbuild/angular/component-stylesheets.ts | 4 +- .../src/tools/esbuild/bundler-context.ts | 15 +- 5 files changed, 259 insertions(+), 6 deletions(-) create mode 100644 packages/angular/build/src/builders/application/tests/options/stats-json_spec.ts diff --git a/packages/angular/build/src/builders/application/chunk-optimizer.ts b/packages/angular/build/src/builders/application/chunk-optimizer.ts index 2241a4204999..7859355f8a84 100644 --- a/packages/angular/build/src/builders/application/chunk-optimizer.ts +++ b/packages/angular/build/src/builders/application/chunk-optimizer.ts @@ -423,5 +423,25 @@ export async function optimizeChunks( } } + // Rebuild browserMetafile from the updated combined metafile and output files. + // Chunk optimization only affects browser chunks, so serverMetafile is unchanged. + const browserOutputPaths = new Set( + original.outputFiles.filter((f) => f.type === BuildOutputFileType.Browser).map((f) => f.path), + ); + const newBrowserMetafile: Metafile = { inputs: {}, outputs: {} }; + for (const [path, output] of Object.entries(original.metafile.outputs)) { + if (!browserOutputPaths.has(path)) { + continue; + } + newBrowserMetafile.outputs[path] = output; + for (const inputPath of Object.keys(output.inputs)) { + const input = original.metafile.inputs[inputPath]; + if (input) { + newBrowserMetafile.inputs[inputPath] ??= input; + } + } + } + original.browserMetafile = newBrowserMetafile; + return original; } diff --git a/packages/angular/build/src/builders/application/execute-build.ts b/packages/angular/build/src/builders/application/execute-build.ts index d0213a9b8a79..f12f0d6ff11b 100644 --- a/packages/angular/build/src/builders/application/execute-build.ts +++ b/packages/angular/build/src/builders/application/execute-build.ts @@ -7,13 +7,14 @@ */ import { BuilderContext } from '@angular-devkit/architect'; +import type { Metafile } from 'esbuild'; import { createAngularCompilation } from '../../tools/angular/compilation'; import { AngularCompilationContext } from '../../tools/esbuild/angular/compilation-state'; import { SourceFileCache } from '../../tools/esbuild/angular/source-file-cache'; import { generateBudgetStats } from '../../tools/esbuild/budget-stats'; import { BundleContextResult, BundlerContext } from '../../tools/esbuild/bundler-context'; import { ExecutionResult, RebuildState } from '../../tools/esbuild/bundler-execution-result'; -import { BuildOutputFileType } from '../../tools/esbuild/bundler-files'; +import { BuildOutputFileType, type InitialFileRecord } from '../../tools/esbuild/bundler-files'; import { checkCommonJSModules } from '../../tools/esbuild/commonjs-checker'; import { LOCALE_DATA_BASE_MODULE } from '../../tools/esbuild/i18n-locale-plugin'; import { extractLicenses } from '../../tools/esbuild/license-extractor'; @@ -41,6 +42,38 @@ import { createComponentStyleBundler, setupBundlerContexts } from './setup-bundl const TOP_LEVEL_AWAIT_ERROR_TEXT = 'Top-level await is not available in the configured target environment'; +/** + * Returns a copy of the given metafile containing only outputs that appear in the + * provided initial-files map, with inputs filtered to those referenced by those outputs. + */ +function createInitialMetafile( + metafile: Metafile, + initialFiles: Map, +): Metafile { + const filteredOutputs: Metafile['outputs'] = {}; + const referencedInputs = new Set(); + + for (const [path, output] of Object.entries(metafile.outputs)) { + if (!initialFiles.has(path)) { + continue; + } + filteredOutputs[path] = output; + for (const inputPath of Object.keys(output.inputs)) { + referencedInputs.add(inputPath); + } + } + + const filteredInputs: Metafile['inputs'] = {}; + for (const path of referencedInputs) { + const input = metafile.inputs[path]; + if (input) { + filteredInputs[path] = input; + } + } + + return { inputs: filteredInputs, outputs: filteredOutputs }; +} + // eslint-disable-next-line max-lines-per-function export async function executeBuild( options: NormalizedApplicationBuildOptions, @@ -378,13 +411,33 @@ export async function executeBuild( BuildOutputFileType.Root, ); - // Write metafile if stats option is enabled + // Write metafiles if stats option is enabled if (options.stats) { + const { browserMetafile, serverMetafile } = bundlingResult; + + executionResult.addOutputFile( + 'browser-stats.json', + JSON.stringify(browserMetafile, null, 2), + BuildOutputFileType.Root, + ); executionResult.addOutputFile( - 'stats.json', - JSON.stringify(metafile, null, 2), + 'browser-initial-stats.json', + JSON.stringify(createInitialMetafile(browserMetafile, initialFiles), null, 2), BuildOutputFileType.Root, ); + + if (ssrOptions) { + executionResult.addOutputFile( + 'server-stats.json', + JSON.stringify(serverMetafile, null, 2), + BuildOutputFileType.Root, + ); + executionResult.addOutputFile( + 'server-initial-stats.json', + JSON.stringify(createInitialMetafile(serverMetafile, initialFiles), null, 2), + BuildOutputFileType.Root, + ); + } } if (!jsonLogs && !options.quiet) { diff --git a/packages/angular/build/src/builders/application/tests/options/stats-json_spec.ts b/packages/angular/build/src/builders/application/tests/options/stats-json_spec.ts new file mode 100644 index 000000000000..8ed22a52d8b3 --- /dev/null +++ b/packages/angular/build/src/builders/application/tests/options/stats-json_spec.ts @@ -0,0 +1,165 @@ +/** + * @license + * Copyright Google LLC All Rights Reserved. + * + * Use of this source code is governed by an MIT-style license that can be + * found in the LICENSE file at https://angular.dev/license + */ + +import { buildApplication } from '../../index'; +import { APPLICATION_BUILDER_INFO, BASE_OPTIONS, describeBuilder } from '../setup'; + +describeBuilder(buildApplication, APPLICATION_BUILDER_INFO, (harness) => { + describe('Option: "statsJson"', () => { + describe('browser-only build', () => { + it('generates only browser stats files when statsJson is true', async () => { + harness.useTarget('build', { + ...BASE_OPTIONS, + statsJson: true, + }); + + const { result } = await harness.executeOnce(); + expect(result?.success).toBeTrue(); + harness.expectFile('dist/browser-stats.json').toExist(); + harness.expectFile('dist/browser-initial-stats.json').toExist(); + harness.expectFile('dist/server-stats.json').toNotExist(); + harness.expectFile('dist/server-initial-stats.json').toNotExist(); + }); + + it('does not generate any stats files when statsJson is false', async () => { + harness.useTarget('build', { + ...BASE_OPTIONS, + statsJson: false, + }); + + const { result } = await harness.executeOnce(); + expect(result?.success).toBeTrue(); + harness.expectFile('dist/browser-stats.json').toNotExist(); + harness.expectFile('dist/browser-initial-stats.json').toNotExist(); + harness.expectFile('dist/server-stats.json').toNotExist(); + harness.expectFile('dist/server-initial-stats.json').toNotExist(); + }); + + it('does not generate legacy stats.json when statsJson is true', async () => { + harness.useTarget('build', { + ...BASE_OPTIONS, + statsJson: true, + }); + + const { result } = await harness.executeOnce(); + expect(result?.success).toBeTrue(); + harness.expectFile('dist/stats.json').toNotExist(); + }); + + it('browser-stats.json contains valid esbuild metafile with inputs and outputs', async () => { + harness.useTarget('build', { + ...BASE_OPTIONS, + statsJson: true, + }); + + const { result } = await harness.executeOnce(); + expect(result?.success).toBeTrue(); + + const content = harness.readFile('dist/browser-stats.json'); + const parsed = JSON.parse(content) as { inputs: unknown; outputs: unknown }; + expect(parsed.inputs).toBeDefined(); + expect(parsed.outputs).toBeDefined(); + }); + + it('browser-initial-stats.json contains only a subset of browser-stats.json outputs', async () => { + harness.useTarget('build', { + ...BASE_OPTIONS, + statsJson: true, + }); + + const { result } = await harness.executeOnce(); + expect(result?.success).toBeTrue(); + + const allStats = JSON.parse(harness.readFile('dist/browser-stats.json')) as { + outputs: Record; + }; + const initialStats = JSON.parse(harness.readFile('dist/browser-initial-stats.json')) as { + outputs: Record; + }; + + const allOutputCount = Object.keys(allStats.outputs).length; + const initialOutputCount = Object.keys(initialStats.outputs).length; + + expect(allOutputCount).toBeGreaterThanOrEqual(initialOutputCount); + for (const path of Object.keys(initialStats.outputs)) { + expect(allStats.outputs[path]).toBeDefined(); + } + }); + }); + + describe('SSR build', () => { + beforeEach(async () => { + await harness.modifyFile('src/tsconfig.app.json', (content) => { + const tsConfig = JSON.parse(content) as { files?: string[] }; + tsConfig.files ??= []; + tsConfig.files.push('main.server.ts'); + + return JSON.stringify(tsConfig); + }); + }); + + it('generates all four stats files for an SSR build', async () => { + harness.useTarget('build', { + ...BASE_OPTIONS, + server: 'src/main.server.ts', + ssr: true, + statsJson: true, + }); + + const { result } = await harness.executeOnce(); + expect(result?.success).toBeTrue(); + harness.expectFile('dist/browser-stats.json').toExist(); + harness.expectFile('dist/browser-initial-stats.json').toExist(); + harness.expectFile('dist/server-stats.json').toExist(); + harness.expectFile('dist/server-initial-stats.json').toExist(); + }); + + it('server-stats.json has non-empty outputs for an SSR build', async () => { + harness.useTarget('build', { + ...BASE_OPTIONS, + server: 'src/main.server.ts', + ssr: true, + statsJson: true, + }); + + const { result } = await harness.executeOnce(); + expect(result?.success).toBeTrue(); + + const content = harness.readFile('dist/server-stats.json'); + const parsed = JSON.parse(content) as { outputs: Record }; + expect(Object.keys(parsed.outputs).length).toBeGreaterThan(0); + }); + + it('browser-stats.json does not contain server output paths for an SSR build', async () => { + harness.useTarget('build', { + ...BASE_OPTIONS, + server: 'src/main.server.ts', + ssr: true, + statsJson: true, + }); + + const { result } = await harness.executeOnce(); + expect(result?.success).toBeTrue(); + + const browserStats = JSON.parse(harness.readFile('dist/browser-stats.json')) as { + outputs: Record; + }; + const serverStats = JSON.parse(harness.readFile('dist/server-stats.json')) as { + outputs: Record; + }; + + const browserPaths = new Set(Object.keys(browserStats.outputs)); + for (const path of Object.keys(serverStats.outputs)) { + expect(browserPaths.has(path)) + .withContext(`Server output '${path}' should not appear in browser-stats.json`) + .toBeFalse(); + } + }); + }); + }); +}); diff --git a/packages/angular/build/src/tools/esbuild/angular/component-stylesheets.ts b/packages/angular/build/src/tools/esbuild/angular/component-stylesheets.ts index 60c80ce057c6..121c25e530dd 100644 --- a/packages/angular/build/src/tools/esbuild/angular/component-stylesheets.ts +++ b/packages/angular/build/src/tools/esbuild/angular/component-stylesheets.ts @@ -258,7 +258,7 @@ export class ComponentStylesheetBundler { } } - const metafile = result.metafile; + const { metafile, browserMetafile, serverMetafile } = result; // Remove entryPoint fields from outputs to prevent the internal component styles from being // treated as initial files. Also mark the entry as a component resource for stat reporting. Object.values(metafile.outputs).forEach((output) => { @@ -273,6 +273,8 @@ export class ComponentStylesheetBundler { contents, outputFiles, metafile, + browserMetafile, + serverMetafile, referencedFiles, externalImports: result.externalImports, initialFiles: new Map(), diff --git a/packages/angular/build/src/tools/esbuild/bundler-context.ts b/packages/angular/build/src/tools/esbuild/bundler-context.ts index d3f3ca567a0f..26de48b021dc 100644 --- a/packages/angular/build/src/tools/esbuild/bundler-context.ts +++ b/packages/angular/build/src/tools/esbuild/bundler-context.ts @@ -33,6 +33,8 @@ export type BundleContextResult = errors: undefined; warnings: Message[]; metafile: Metafile; + browserMetafile: Metafile; + serverMetafile: Metafile; outputFiles: BuildOutputFile[]; initialFiles: Map; externalImports: { @@ -112,6 +114,8 @@ export class BundlerContext { let errors: Message[] | undefined; const warnings: Message[] = []; const metafile: Metafile = { inputs: {}, outputs: {} }; + const browserMetafile: Metafile = { inputs: {}, outputs: {} }; + const serverMetafile: Metafile = { inputs: {}, outputs: {} }; const initialFiles = new Map(); const externalImportsBrowser = new Set(); const externalImportsServer = new Set(); @@ -126,12 +130,17 @@ export class BundlerContext { continue; } - // Combine metafiles used for the stats option as well as bundle budgets and console output + // Combine metafiles used for the bundle budgets and console output if (result.metafile) { Object.assign(metafile.inputs, result.metafile.inputs); Object.assign(metafile.outputs, result.metafile.outputs); } + Object.assign(browserMetafile.inputs, result.browserMetafile.inputs); + Object.assign(browserMetafile.outputs, result.browserMetafile.outputs); + Object.assign(serverMetafile.inputs, result.serverMetafile.inputs); + Object.assign(serverMetafile.outputs, result.serverMetafile.outputs); + result.initialFiles.forEach((value, key) => initialFiles.set(key, value)); outputFiles.push(...result.outputFiles); @@ -154,6 +163,8 @@ export class BundlerContext { errors, warnings, metafile, + browserMetafile, + serverMetafile, initialFiles, outputFiles, externalImports: { @@ -416,6 +427,8 @@ export class BundlerContext { ...result, outputFiles, initialFiles, + browserMetafile: isPlatformServer ? { inputs: {}, outputs: {} } : result.metafile, + serverMetafile: isPlatformServer ? result.metafile : { inputs: {}, outputs: {} }, externalImports: { [isPlatformServer ? 'server' : 'browser']: externalImports, }, From fcb06aa4e663a254979f4e0d4c0b58f3fb3780dd Mon Sep 17 00:00:00 2001 From: Alan Agius <17563226+alan-agius4@users.noreply.github.com> Date: Mon, 17 Aug 2026 16:59:08 +0000 Subject: [PATCH 318/787] refactor(@angular/build): track and separate platform metafiles in bundler context Track the target platform (`browser` or `server`) on individual bundler context results and introduce `BundleMergedContextResult` to maintain separate `browser` and `server` metafiles when merging. This simplifies downstream consumers: - Enables direct usage of `metafiles.browser` for browser-specific steps (budgets, i18n, chunk optimization, CommonJS checks, and post-bundle processing). - Allows `extractLicenses` and `logBuildStats` to process all platform metafiles directly without merging them into a single structure. - Removes redundant filtering of server bundles in budget calculations. - Streamlines the `statsJson` file emission for browser and server targets. --- .../builders/application/chunk-optimizer.ts | 36 +--- .../src/builders/application/execute-build.ts | 98 +++------ .../application/execute-post-bundle.ts | 8 +- .../tests/options/stats-json_spec.ts | 154 ++++--------- .../esbuild/angular/component-stylesheets.ts | 5 +- .../build/src/tools/esbuild/budget-stats.ts | 6 +- .../src/tools/esbuild/bundler-context.ts | 64 +++--- .../src/tools/esbuild/license-extractor.ts | 202 +++++++++--------- .../angular/build/src/tools/esbuild/utils.ts | 18 +- 9 files changed, 244 insertions(+), 347 deletions(-) diff --git a/packages/angular/build/src/builders/application/chunk-optimizer.ts b/packages/angular/build/src/builders/application/chunk-optimizer.ts index 7859355f8a84..ea4c2f8076f9 100644 --- a/packages/angular/build/src/builders/application/chunk-optimizer.ts +++ b/packages/angular/build/src/builders/application/chunk-optimizer.ts @@ -20,7 +20,7 @@ import type { Message, Metafile } from 'esbuild'; import assert from 'node:assert'; import type { Plugin } from 'rollup'; -import { BundleContextResult } from '../../tools/esbuild/bundler-context'; +import { BundleMergedContextResult } from '../../tools/esbuild/bundler-context'; import { type BuildOutputFile, BuildOutputFileType, @@ -212,9 +212,9 @@ function createChunkOptimizationFailureMessage(message: string): Message { */ // eslint-disable-next-line max-lines-per-function export async function optimizeChunks( - original: BundleContextResult, + original: BundleMergedContextResult, sourcemap: boolean | 'hidden', -): Promise { +): Promise { // Failed builds cannot be optimized if (original.errors) { return original; @@ -235,7 +235,7 @@ export async function optimizeChunks( } // No action required if no browser main entrypoint or metafile for stats - if (!mainFile || !original.metafile) { + if (!mainFile || !original.metafiles.browser) { return original; } @@ -340,9 +340,9 @@ export async function optimizeChunks( } // Update metafile - const newMetafile = bundleOutputToEsbuildMetafile(optimizedOutput, original.metafile); + const newMetafile = bundleOutputToEsbuildMetafile(optimizedOutput, original.metafiles.browser); // Add back the outputs that were not part of the optimization - for (const [path, output] of Object.entries(original.metafile.outputs)) { + for (const [path, output] of Object.entries(original.metafiles.browser.outputs)) { if (usedChunks.has(path)) { continue; } @@ -350,11 +350,11 @@ export async function optimizeChunks( newMetafile.outputs[path] = output; for (const inputPath of Object.keys(output.inputs)) { if (!newMetafile.inputs[inputPath]) { - newMetafile.inputs[inputPath] = original.metafile.inputs[inputPath]; + newMetafile.inputs[inputPath] = original.metafiles.browser.inputs[inputPath]; } } } - original.metafile = newMetafile; + original.metafiles.browser = newMetafile; // Remove used chunks and associated sourcemaps from the original result original.outputFiles = original.outputFiles.filter( @@ -423,25 +423,5 @@ export async function optimizeChunks( } } - // Rebuild browserMetafile from the updated combined metafile and output files. - // Chunk optimization only affects browser chunks, so serverMetafile is unchanged. - const browserOutputPaths = new Set( - original.outputFiles.filter((f) => f.type === BuildOutputFileType.Browser).map((f) => f.path), - ); - const newBrowserMetafile: Metafile = { inputs: {}, outputs: {} }; - for (const [path, output] of Object.entries(original.metafile.outputs)) { - if (!browserOutputPaths.has(path)) { - continue; - } - newBrowserMetafile.outputs[path] = output; - for (const inputPath of Object.keys(output.inputs)) { - const input = original.metafile.inputs[inputPath]; - if (input) { - newBrowserMetafile.inputs[inputPath] ??= input; - } - } - } - original.browserMetafile = newBrowserMetafile; - return original; } diff --git a/packages/angular/build/src/builders/application/execute-build.ts b/packages/angular/build/src/builders/application/execute-build.ts index f12f0d6ff11b..8fe488a8ff76 100644 --- a/packages/angular/build/src/builders/application/execute-build.ts +++ b/packages/angular/build/src/builders/application/execute-build.ts @@ -7,14 +7,13 @@ */ import { BuilderContext } from '@angular-devkit/architect'; -import type { Metafile } from 'esbuild'; import { createAngularCompilation } from '../../tools/angular/compilation'; import { AngularCompilationContext } from '../../tools/esbuild/angular/compilation-state'; import { SourceFileCache } from '../../tools/esbuild/angular/source-file-cache'; import { generateBudgetStats } from '../../tools/esbuild/budget-stats'; import { BundleContextResult, BundlerContext } from '../../tools/esbuild/bundler-context'; import { ExecutionResult, RebuildState } from '../../tools/esbuild/bundler-execution-result'; -import { BuildOutputFileType, type InitialFileRecord } from '../../tools/esbuild/bundler-files'; +import { BuildOutputFileType } from '../../tools/esbuild/bundler-files'; import { checkCommonJSModules } from '../../tools/esbuild/commonjs-checker'; import { LOCALE_DATA_BASE_MODULE } from '../../tools/esbuild/i18n-locale-plugin'; import { extractLicenses } from '../../tools/esbuild/license-extractor'; @@ -41,39 +40,6 @@ import { createComponentStyleBundler, setupBundlerContexts } from './setup-bundl /** The esbuild error text prefix used to detect top-level await errors. */ const TOP_LEVEL_AWAIT_ERROR_TEXT = 'Top-level await is not available in the configured target environment'; - -/** - * Returns a copy of the given metafile containing only outputs that appear in the - * provided initial-files map, with inputs filtered to those referenced by those outputs. - */ -function createInitialMetafile( - metafile: Metafile, - initialFiles: Map, -): Metafile { - const filteredOutputs: Metafile['outputs'] = {}; - const referencedInputs = new Set(); - - for (const [path, output] of Object.entries(metafile.outputs)) { - if (!initialFiles.has(path)) { - continue; - } - filteredOutputs[path] = output; - for (const inputPath of Object.keys(output.inputs)) { - referencedInputs.add(inputPath); - } - } - - const filteredInputs: Metafile['inputs'] = {}; - for (const path of referencedInputs) { - const input = metafile.inputs[path]; - if (input) { - filteredInputs[path] = input; - } - } - - return { inputs: filteredInputs, outputs: filteredOutputs }; -} - // eslint-disable-next-line max-lines-per-function export async function executeBuild( options: NormalizedApplicationBuildOptions, @@ -109,7 +75,7 @@ export async function executeBuild( let bundlerContexts; let componentStyleBundler; let codeBundleCache; - let bundlingResult: BundleContextResult; + let bundlingIndividualResults: BundleContextResult[]; let templateUpdates: Map | undefined; let angularCompilationContext: AngularCompilationContext | undefined; let executionResult: ExecutionResult | undefined; @@ -132,7 +98,7 @@ export async function executeBuild( // Bundle all contexts that do not require TypeScript changed file checks. // These will automatically use cached results based on the changed files. - bundlingResult = await BundlerContext.bundleAll( + bundlingIndividualResults = await BundlerContext.bundleAll( bundlerContexts.otherContexts, allFileChanges, ); @@ -146,7 +112,8 @@ export async function executeBuild( const result = await typescriptContext.bundle(forceTypeScriptRebuild); typescriptResults.push(result); } - bundlingResult = BundlerContext.mergeResults([bundlingResult, ...typescriptResults]); + + bundlingIndividualResults.push(...typescriptResults); } else { const target = transformSupportedBrowsersToTargets(browsers); codeBundleCache = new SourceFileCache(cacheOptions.enabled ? cacheOptions.path : undefined); @@ -175,7 +142,7 @@ export async function executeBuild( ); // Bundle everything on initial build - bundlingResult = await BundlerContext.bundleAll([ + bundlingIndividualResults = await BundlerContext.bundleAll([ ...bundlerContexts.typescriptContexts, ...bundlerContexts.otherContexts, ]); @@ -187,9 +154,11 @@ export async function executeBuild( componentStyleBundler.invalidate(rebuildState.fileChanges.all); const componentResults = await componentStyleBundler.bundleAllFiles(true, true); - bundlingResult = BundlerContext.mergeResults([bundlingResult, ...componentResults]); + bundlingIndividualResults.push(...componentResults); } + let bundlingResult = BundlerContext.mergeResults(bundlingIndividualResults); + executionResult.addWarnings(bundlingResult.warnings); // Add used external component style referenced files to be watched @@ -239,8 +208,8 @@ export async function executeBuild( if (options.optimizationOptions.scripts) { // Count lazy chunks (files not needed for initial load). // Advanced chunk optimization is most beneficial when there are multiple lazy chunks. - const { metafile, initialFiles } = bundlingResult; - const lazyChunksCount = Object.keys(metafile.outputs).filter( + const { metafiles, initialFiles } = bundlingResult; + const lazyChunksCount = Object.keys(metafiles.browser.outputs || {}).filter( (path) => path.endsWith('.js') && !initialFiles.has(path), ).length; @@ -319,14 +288,19 @@ export async function executeBuild( executionResult.setExternalMetadata(implicitBrowser, implicitServer, [...explicitExternal]); } - const { metafile, initialFiles, outputFiles } = bundlingResult; + const { + metafiles: { browser: browserMetafile, server: serverMetafile }, + initialFiles, + outputFiles, + } = bundlingResult; + const metafiles = [browserMetafile, serverMetafile]; executionResult.outputFiles.push(...outputFiles); // Analyze files for bundle budget failures if present let budgetFailures: BudgetCalculatorResult[] | undefined; if (options.budgets) { - const compatStats = generateBudgetStats(metafile, outputFiles, initialFiles); + const compatStats = generateBudgetStats(browserMetafile, outputFiles, initialFiles); budgetFailures = [...checkBudgets(options.budgets, compatStats, true)]; for (const { message, severity } of budgetFailures) { if (severity === 'error') { @@ -345,7 +319,7 @@ export async function executeBuild( // Check metafile for CommonJS module usage if optimizing scripts if (optimizationOptions.scripts) { - const messages = checkCommonJSModules(metafile, options.allowedCommonJsDependencies); + const messages = checkCommonJSModules(browserMetafile, options.allowedCommonJsDependencies); executionResult.addWarnings(messages); } @@ -358,7 +332,7 @@ export async function executeBuild( if (options.extractLicenses) { executionResult.addOutputFile( '3rdpartylicenses.txt', - await extractLicenses(metafile, workspaceRoot), + await extractLicenses(metafiles, workspaceRoot), BuildOutputFileType.Root, ); } @@ -381,13 +355,13 @@ export async function executeBuild( // Perform i18n translation inlining if enabled if (i18nOptions.shouldInline) { - const result = await inlineI18n(metafile, options, executionResult, initialFiles); + const result = await inlineI18n(browserMetafile, options, executionResult, initialFiles); executionResult.addErrors(result.errors); executionResult.addWarnings(result.warnings); executionResult.addPrerenderedRoutes(result.prerenderedRoutes); } else { const result = await executePostBundleSteps( - metafile, + browserMetafile, options, executionResult.outputFiles, executionResult.assetFiles, @@ -405,38 +379,28 @@ export async function executeBuild( executionResult.assetFiles.push(...result.additionalAssets); } - executionResult.addOutputFile( - 'prerendered-routes.json', - JSON.stringify({ routes: executionResult.prerenderedRoutes }, null, 2), - BuildOutputFileType.Root, - ); + if (serverEntryPoint) { + executionResult.addOutputFile( + 'prerendered-routes.json', + JSON.stringify({ routes: executionResult.prerenderedRoutes }, null, 2), + BuildOutputFileType.Root, + ); + } // Write metafiles if stats option is enabled if (options.stats) { - const { browserMetafile, serverMetafile } = bundlingResult; - executionResult.addOutputFile( 'browser-stats.json', JSON.stringify(browserMetafile, null, 2), BuildOutputFileType.Root, ); - executionResult.addOutputFile( - 'browser-initial-stats.json', - JSON.stringify(createInitialMetafile(browserMetafile, initialFiles), null, 2), - BuildOutputFileType.Root, - ); - if (ssrOptions) { + if (serverEntryPoint) { executionResult.addOutputFile( 'server-stats.json', JSON.stringify(serverMetafile, null, 2), BuildOutputFileType.Root, ); - executionResult.addOutputFile( - 'server-initial-stats.json', - JSON.stringify(createInitialMetafile(serverMetafile, initialFiles), null, 2), - BuildOutputFileType.Root, - ); } } @@ -445,7 +409,7 @@ export async function executeBuild( rebuildState && executionResult.findChangedFiles(rebuildState.previousOutputInfo); executionResult.addLog( logBuildStats( - metafile, + metafiles, outputFiles, initialFiles, budgetFailures, diff --git a/packages/angular/build/src/builders/application/execute-post-bundle.ts b/packages/angular/build/src/builders/application/execute-post-bundle.ts index 198071c5a280..cf76a14d9030 100644 --- a/packages/angular/build/src/builders/application/execute-post-bundle.ts +++ b/packages/angular/build/src/builders/application/execute-post-bundle.ts @@ -36,7 +36,7 @@ import { OutputMode } from './schema'; /** * Run additional builds steps including SSG, AppShell, Index HTML file and Service worker generation. - * @param metafile An esbuild metafile object. + * @param browserMetafile An esbuild metafile object. * @param options The normalized application builder options used to create the build. * @param outputFiles The output files of an executed build. * @param assetFiles The assets of an executed build. @@ -45,7 +45,7 @@ import { OutputMode } from './schema'; */ // eslint-disable-next-line max-lines-per-function export async function executePostBundleSteps( - metafile: Metafile, + browserMetafile: Metafile, options: NormalizedApplicationBuildOptions, outputFiles: BuildOutputFile[], assetFiles: BuildOutputAsset[], @@ -131,7 +131,7 @@ export async function executePostBundleSteps( locale, baseHref, initialFilesPaths, - metafile, + browserMetafile, publicPath, ); @@ -214,7 +214,7 @@ export async function executePostBundleSteps( locale, baseHref, initialFilesPaths, - metafile, + browserMetafile, publicPath, ); diff --git a/packages/angular/build/src/builders/application/tests/options/stats-json_spec.ts b/packages/angular/build/src/builders/application/tests/options/stats-json_spec.ts index 8ed22a52d8b3..f38ae4996d16 100644 --- a/packages/angular/build/src/builders/application/tests/options/stats-json_spec.ts +++ b/packages/angular/build/src/builders/application/tests/options/stats-json_spec.ts @@ -11,91 +11,51 @@ import { APPLICATION_BUILDER_INFO, BASE_OPTIONS, describeBuilder } from '../setu describeBuilder(buildApplication, APPLICATION_BUILDER_INFO, (harness) => { describe('Option: "statsJson"', () => { - describe('browser-only build', () => { - it('generates only browser stats files when statsJson is true', async () => { - harness.useTarget('build', { - ...BASE_OPTIONS, - statsJson: true, - }); - - const { result } = await harness.executeOnce(); - expect(result?.success).toBeTrue(); - harness.expectFile('dist/browser-stats.json').toExist(); - harness.expectFile('dist/browser-initial-stats.json').toExist(); - harness.expectFile('dist/server-stats.json').toNotExist(); - harness.expectFile('dist/server-initial-stats.json').toNotExist(); + it('generates only browser stats file containing valid metafile data when true', async () => { + harness.useTarget('build', { + ...BASE_OPTIONS, + statsJson: true, }); - it('does not generate any stats files when statsJson is false', async () => { - harness.useTarget('build', { - ...BASE_OPTIONS, - statsJson: false, - }); + const { result } = await harness.executeOnce(); + expect(result?.success).toBeTrue(); - const { result } = await harness.executeOnce(); - expect(result?.success).toBeTrue(); - harness.expectFile('dist/browser-stats.json').toNotExist(); - harness.expectFile('dist/browser-initial-stats.json').toNotExist(); - harness.expectFile('dist/server-stats.json').toNotExist(); - harness.expectFile('dist/server-initial-stats.json').toNotExist(); - }); + harness.expectFile('dist/browser-stats.json').toExist(); + harness.expectFile('dist/server-stats.json').toNotExist(); - it('does not generate legacy stats.json when statsJson is true', async () => { - harness.useTarget('build', { - ...BASE_OPTIONS, - statsJson: true, - }); + const browserStats = JSON.parse(harness.readFile('dist/browser-stats.json')); + expect(browserStats.inputs).toBeDefined(); + expect(browserStats.outputs).toBeDefined(); + expect(Object.keys(browserStats.outputs).length).toBeGreaterThan(0); + }); - const { result } = await harness.executeOnce(); - expect(result?.success).toBeTrue(); - harness.expectFile('dist/stats.json').toNotExist(); + it('does not generate stats files when false', async () => { + harness.useTarget('build', { + ...BASE_OPTIONS, + statsJson: false, }); - it('browser-stats.json contains valid esbuild metafile with inputs and outputs', async () => { - harness.useTarget('build', { - ...BASE_OPTIONS, - statsJson: true, - }); - - const { result } = await harness.executeOnce(); - expect(result?.success).toBeTrue(); + const { result } = await harness.executeOnce(); + expect(result?.success).toBeTrue(); + harness.expectFile('dist/browser-stats.json').toNotExist(); + harness.expectFile('dist/server-stats.json').toNotExist(); + }); - const content = harness.readFile('dist/browser-stats.json'); - const parsed = JSON.parse(content) as { inputs: unknown; outputs: unknown }; - expect(parsed.inputs).toBeDefined(); - expect(parsed.outputs).toBeDefined(); + it('does not generate stats files when not set', async () => { + harness.useTarget('build', { + ...BASE_OPTIONS, }); - it('browser-initial-stats.json contains only a subset of browser-stats.json outputs', async () => { - harness.useTarget('build', { - ...BASE_OPTIONS, - statsJson: true, - }); - - const { result } = await harness.executeOnce(); - expect(result?.success).toBeTrue(); - - const allStats = JSON.parse(harness.readFile('dist/browser-stats.json')) as { - outputs: Record; - }; - const initialStats = JSON.parse(harness.readFile('dist/browser-initial-stats.json')) as { - outputs: Record; - }; - - const allOutputCount = Object.keys(allStats.outputs).length; - const initialOutputCount = Object.keys(initialStats.outputs).length; - - expect(allOutputCount).toBeGreaterThanOrEqual(initialOutputCount); - for (const path of Object.keys(initialStats.outputs)) { - expect(allStats.outputs[path]).toBeDefined(); - } - }); + const { result } = await harness.executeOnce(); + expect(result?.success).toBeTrue(); + harness.expectFile('dist/browser-stats.json').toNotExist(); + harness.expectFile('dist/server-stats.json').toNotExist(); }); - describe('SSR build', () => { + describe('server build', () => { beforeEach(async () => { await harness.modifyFile('src/tsconfig.app.json', (content) => { - const tsConfig = JSON.parse(content) as { files?: string[] }; + const tsConfig = JSON.parse(content); tsConfig.files ??= []; tsConfig.files.push('main.server.ts'); @@ -103,7 +63,7 @@ describeBuilder(buildApplication, APPLICATION_BUILDER_INFO, (harness) => { }); }); - it('generates all four stats files for an SSR build', async () => { + it('generates separated browser and server stats files for an SSR build', async () => { harness.useTarget('build', { ...BASE_OPTIONS, server: 'src/main.server.ts', @@ -113,52 +73,30 @@ describeBuilder(buildApplication, APPLICATION_BUILDER_INFO, (harness) => { const { result } = await harness.executeOnce(); expect(result?.success).toBeTrue(); + harness.expectFile('dist/browser-stats.json').toExist(); - harness.expectFile('dist/browser-initial-stats.json').toExist(); harness.expectFile('dist/server-stats.json').toExist(); - harness.expectFile('dist/server-initial-stats.json').toExist(); - }); - - it('server-stats.json has non-empty outputs for an SSR build', async () => { - harness.useTarget('build', { - ...BASE_OPTIONS, - server: 'src/main.server.ts', - ssr: true, - statsJson: true, - }); - - const { result } = await harness.executeOnce(); - expect(result?.success).toBeTrue(); - const content = harness.readFile('dist/server-stats.json'); - const parsed = JSON.parse(content) as { outputs: Record }; - expect(Object.keys(parsed.outputs).length).toBeGreaterThan(0); - }); + const browserStats = JSON.parse(harness.readFile('dist/browser-stats.json')); + const serverStats = JSON.parse(harness.readFile('dist/server-stats.json')); - it('browser-stats.json does not contain server output paths for an SSR build', async () => { - harness.useTarget('build', { - ...BASE_OPTIONS, - server: 'src/main.server.ts', - ssr: true, - statsJson: true, - }); - - const { result } = await harness.executeOnce(); - expect(result?.success).toBeTrue(); + const browserPaths = new Set(Object.keys(browserStats.outputs)); + const serverPaths = new Set(Object.keys(serverStats.outputs)); - const browserStats = JSON.parse(harness.readFile('dist/browser-stats.json')) as { - outputs: Record; - }; - const serverStats = JSON.parse(harness.readFile('dist/server-stats.json')) as { - outputs: Record; - }; + expect(serverPaths.size).toBeGreaterThan(0); + expect(browserPaths.size).toBeGreaterThan(0); - const browserPaths = new Set(Object.keys(browserStats.outputs)); - for (const path of Object.keys(serverStats.outputs)) { + for (const path of serverPaths) { expect(browserPaths.has(path)) .withContext(`Server output '${path}' should not appear in browser-stats.json`) .toBeFalse(); } + + for (const path of browserPaths) { + expect(serverPaths.has(path)) + .withContext(`Browser output '${path}' should not appear in server-stats.json`) + .toBeFalse(); + } }); }); }); diff --git a/packages/angular/build/src/tools/esbuild/angular/component-stylesheets.ts b/packages/angular/build/src/tools/esbuild/angular/component-stylesheets.ts index 121c25e530dd..f636e91fce4b 100644 --- a/packages/angular/build/src/tools/esbuild/angular/component-stylesheets.ts +++ b/packages/angular/build/src/tools/esbuild/angular/component-stylesheets.ts @@ -258,7 +258,7 @@ export class ComponentStylesheetBundler { } } - const { metafile, browserMetafile, serverMetafile } = result; + const { metafile } = result; // Remove entryPoint fields from outputs to prevent the internal component styles from being // treated as initial files. Also mark the entry as a component resource for stat reporting. Object.values(metafile.outputs).forEach((output) => { @@ -273,10 +273,9 @@ export class ComponentStylesheetBundler { contents, outputFiles, metafile, - browserMetafile, - serverMetafile, referencedFiles, externalImports: result.externalImports, + platform: result.platform, initialFiles: new Map(), }; } diff --git a/packages/angular/build/src/tools/esbuild/budget-stats.ts b/packages/angular/build/src/tools/esbuild/budget-stats.ts index a9c32778b3db..a14d9a24f1b6 100644 --- a/packages/angular/build/src/tools/esbuild/budget-stats.ts +++ b/packages/angular/build/src/tools/esbuild/budget-stats.ts @@ -30,12 +30,12 @@ export function generateBudgetStats( }; for (const { path: file, size, type } of outputFiles) { - if (!file.endsWith('.js') && !file.endsWith('.css')) { + // Exclude server bundles + if (type === BuildOutputFileType.ServerApplication || type === BuildOutputFileType.ServerRoot) { continue; } - // Exclude server bundles - if (type === BuildOutputFileType.ServerApplication || type === BuildOutputFileType.ServerRoot) { + if (!file.endsWith('.js') && !file.endsWith('.css')) { continue; } diff --git a/packages/angular/build/src/tools/esbuild/bundler-context.ts b/packages/angular/build/src/tools/esbuild/bundler-context.ts index 26de48b021dc..38a82d944e32 100644 --- a/packages/angular/build/src/tools/esbuild/bundler-context.ts +++ b/packages/angular/build/src/tools/esbuild/bundler-context.ts @@ -33,13 +33,27 @@ export type BundleContextResult = errors: undefined; warnings: Message[]; metafile: Metafile; - browserMetafile: Metafile; - serverMetafile: Metafile; + platform: 'browser' | 'server'; + outputFiles: BuildOutputFile[]; + initialFiles: Map; + externalImports: Set; + externalConfiguration?: string[]; + }; + +export type BundleMergedContextResult = + | { errors: Message[]; warnings: Message[] } + | { + errors: undefined; + warnings: Message[]; + metafiles: { + browser: Metafile; + server: Metafile; + }; outputFiles: BuildOutputFile[]; initialFiles: Map; externalImports: { - server?: Set; - browser?: Set; + server: Set; + browser: Set; }; externalConfiguration?: string[]; }; @@ -88,11 +102,11 @@ export class BundlerContext { }; } - static async bundleAll( + static bundleAll( contexts: Iterable, changedFiles?: Iterable, - ): Promise { - const individualResults = await Promise.all( + ): Promise { + return Promise.all( [...contexts].map((context) => { if (changedFiles) { context.invalidate(changedFiles); @@ -101,19 +115,11 @@ export class BundlerContext { return context.bundle(); }), ); - - return BundlerContext.mergeResults(individualResults); } - static mergeResults(results: BundleContextResult[]): BundleContextResult { - // Return directly if only one result - if (results.length === 1) { - return results[0]; - } - + static mergeResults(results: BundleContextResult[]): BundleMergedContextResult { let errors: Message[] | undefined; const warnings: Message[] = []; - const metafile: Metafile = { inputs: {}, outputs: {} }; const browserMetafile: Metafile = { inputs: {}, outputs: {} }; const serverMetafile: Metafile = { inputs: {}, outputs: {} }; const initialFiles = new Map(); @@ -130,22 +136,20 @@ export class BundlerContext { continue; } + const platformIsBrowser = result.platform === 'browser'; + // Combine metafiles used for the bundle budgets and console output if (result.metafile) { + const metafile = platformIsBrowser ? browserMetafile : serverMetafile; Object.assign(metafile.inputs, result.metafile.inputs); Object.assign(metafile.outputs, result.metafile.outputs); } - Object.assign(browserMetafile.inputs, result.browserMetafile.inputs); - Object.assign(browserMetafile.outputs, result.browserMetafile.outputs); - Object.assign(serverMetafile.inputs, result.serverMetafile.inputs); - Object.assign(serverMetafile.outputs, result.serverMetafile.outputs); + const externalImports = platformIsBrowser ? externalImportsBrowser : externalImportsServer; + result.externalImports?.forEach((value) => externalImports.add(value)); result.initialFiles.forEach((value, key) => initialFiles.set(key, value)); - outputFiles.push(...result.outputFiles); - result.externalImports.browser?.forEach((value) => externalImportsBrowser.add(value)); - result.externalImports.server?.forEach((value) => externalImportsServer.add(value)); if (result.externalConfiguration) { externalConfiguration ??= new Set(); @@ -162,15 +166,16 @@ export class BundlerContext { return { errors, warnings, - metafile, - browserMetafile, - serverMetafile, initialFiles, outputFiles, externalImports: { browser: externalImportsBrowser, server: externalImportsServer, }, + metafiles: { + browser: browserMetafile, + server: serverMetafile, + }, externalConfiguration: externalConfiguration ? [...externalConfiguration] : undefined, }; } @@ -427,11 +432,8 @@ export class BundlerContext { ...result, outputFiles, initialFiles, - browserMetafile: isPlatformServer ? { inputs: {}, outputs: {} } : result.metafile, - serverMetafile: isPlatformServer ? result.metafile : { inputs: {}, outputs: {} }, - externalImports: { - [isPlatformServer ? 'server' : 'browser']: externalImports, - }, + externalImports, + platform: isPlatformServer ? 'server' : 'browser', externalConfiguration, errors: undefined, }; diff --git a/packages/angular/build/src/tools/esbuild/license-extractor.ts b/packages/angular/build/src/tools/esbuild/license-extractor.ts index 890ebdd9826f..4c73012033bb 100644 --- a/packages/angular/build/src/tools/esbuild/license-extractor.ts +++ b/packages/angular/build/src/tools/esbuild/license-extractor.ts @@ -60,124 +60,132 @@ const EXTRACTION_FILE_SEPARATOR = '-'.repeat(80) + '\n'; * @param rootDirectory The root directory of the workspace. * @returns A string containing the content of the output licenses file. */ -export async function extractLicenses(metafile: Metafile, rootDirectory: string) { +export async function extractLicenses( + metafiles: Metafile[], + rootDirectory: string, +): Promise { let extractedLicenseContent = `${EXTRACTION_FILE_HEADER}\n${EXTRACTION_FILE_SEPARATOR}`; const seenPaths = new Set(); const seenPackageDirectories = new Set(); const seenPackages = new Set(); - for (const entry of Object.values(metafile.outputs)) { - for (const [inputPath, { bytesInOutput }] of Object.entries(entry.inputs)) { - // Skip if not included in output - if (bytesInOutput <= 0) { - continue; - } - - // Skip already processed paths - if (seenPaths.has(inputPath)) { - continue; - } - seenPaths.add(inputPath); + for (const metafile of metafiles) { + for (const entry of Object.values(metafile.outputs)) { + for (const [inputPath, { bytesInOutput }] of Object.entries(entry.inputs)) { + // Skip if not included in output + if (bytesInOutput <= 0) { + continue; + } - // Skip non-package paths - if (!inputPath.includes(NODE_MODULE_SEGMENT)) { - continue; - } + // Skip already processed paths + if (seenPaths.has(inputPath)) { + continue; + } + seenPaths.add(inputPath); - // Extract the package name from the path - let baseDirectory = path.join(rootDirectory, inputPath); - let nameOrScope, nameOrFile; - let found = false; - while (baseDirectory !== path.dirname(baseDirectory)) { - const segment = path.basename(baseDirectory); - if (segment === NODE_MODULE_SEGMENT) { - found = true; - break; + // Skip non-package paths + if (!inputPath.includes(NODE_MODULE_SEGMENT)) { + continue; } - nameOrFile = nameOrScope; - nameOrScope = segment; - baseDirectory = path.dirname(baseDirectory); - } + // Extract the package name from the path + let baseDirectory = path.join(rootDirectory, inputPath); + let nameOrScope, nameOrFile; + let found = false; + while (baseDirectory !== path.dirname(baseDirectory)) { + const segment = path.basename(baseDirectory); + if (segment === NODE_MODULE_SEGMENT) { + found = true; + break; + } - // Skip non-package path edge cases that are not caught in the includes check above - if (!found || !nameOrScope) { - continue; - } + nameOrFile = nameOrScope; + nameOrScope = segment; + baseDirectory = path.dirname(baseDirectory); + } - const packageName = nameOrScope.startsWith('@') - ? `${nameOrScope}/${nameOrFile}` - : nameOrScope; - const packageDirectory = path.join(baseDirectory, packageName); + // Skip non-package path edge cases that are not caught in the includes check above + if (!found || !nameOrScope) { + continue; + } - if (seenPackageDirectories.has(packageDirectory)) { - continue; - } - seenPackageDirectories.add(packageDirectory); - - // Load the package's metadata to find the package's name, version, and license type - const packageJsonPath = path.join(packageDirectory, 'package.json'); - let packageJson; - try { - packageJson = JSON.parse(await readFile(packageJsonPath, 'utf-8')) as { - name: string; - version: string; - // The object form is deprecated and should only be present in old packages - license?: string | { type: string }; - }; - } catch { - // Invalid package - continue; - } + const packageName = nameOrScope.startsWith('@') + ? `${nameOrScope}/${nameOrFile}` + : nameOrScope; + const packageDirectory = path.join(baseDirectory, packageName); - // Skip already processed packages - const packageId = `${packageName}@${packageJson.version}`; - if (seenPackages.has(packageId)) { - continue; - } - seenPackages.add(packageId); - - // Attempt to find license text inside package - let licenseText = ''; - if ( - typeof packageJson.license === 'string' && - packageJson.license.toUpperCase().startsWith(CUSTOM_LICENSE_TEXT) - ) { - // Attempt to load the package's custom license - let customLicensePath; - const customLicenseFile = path.normalize( - packageJson.license.slice(CUSTOM_LICENSE_TEXT.length).trim(), - ); - if (customLicenseFile.startsWith('..') || path.isAbsolute(customLicenseFile)) { - // Path is attempting to access files outside of the package - // TODO: Issue warning? - } else { - customLicensePath = path.join(packageDirectory, customLicenseFile); - try { - licenseText = await readFile(customLicensePath, 'utf-8'); - } catch {} + if (seenPackageDirectories.has(packageDirectory)) { + continue; + } + seenPackageDirectories.add(packageDirectory); + + // Load the package's metadata to find the package's name, version, and license type + const packageJsonPath = path.join(packageDirectory, 'package.json'); + let packageJson; + try { + packageJson = JSON.parse(await readFile(packageJsonPath, 'utf-8')) as { + name: string; + version: string; + // The object form is deprecated and should only be present in old packages + license?: string | { type: string }; + }; + } catch { + // Invalid package + continue; } - } else { - // Search for a license file within the root of the package - const entries = await readdir(packageDirectory, { withFileTypes: true }).catch(() => []); - for (const entry of entries) { - if ((entry.isFile() || entry.isSymbolicLink()) && LICENSE_FILE_REGEXP.test(entry.name)) { - const packageLicensePath = path.join(packageDirectory, entry.name); + // Skip already processed packages + const packageId = `${packageName}@${packageJson.version}`; + if (seenPackages.has(packageId)) { + continue; + } + seenPackages.add(packageId); + + // Attempt to find license text inside package + let licenseText = ''; + if ( + typeof packageJson.license === 'string' && + packageJson.license.toUpperCase().startsWith(CUSTOM_LICENSE_TEXT) + ) { + // Attempt to load the package's custom license + let customLicensePath; + const customLicenseFile = path.normalize( + packageJson.license.slice(CUSTOM_LICENSE_TEXT.length).trim(), + ); + if (customLicenseFile.startsWith('..') || path.isAbsolute(customLicenseFile)) { + // Path is attempting to access files outside of the package + // TODO: Issue warning? + } else { + customLicensePath = path.join(packageDirectory, customLicenseFile); try { - licenseText = await readFile(packageLicensePath, 'utf-8'); - break; + licenseText = await readFile(customLicensePath, 'utf-8'); } catch {} } + } else { + // Search for a license file within the root of the package + const entries = await readdir(packageDirectory, { withFileTypes: true }).catch(() => []); + + for (const entry of entries) { + if ( + (entry.isFile() || entry.isSymbolicLink()) && + LICENSE_FILE_REGEXP.test(entry.name) + ) { + const packageLicensePath = path.join(packageDirectory, entry.name); + try { + licenseText = await readFile(packageLicensePath, 'utf-8'); + break; + } catch {} + } + } } - } - // Generate the package's license entry in the output content - extractedLicenseContent += `Package: ${packageJson.name}\n`; - extractedLicenseContent += `License: ${JSON.stringify(packageJson.license, null, 2)}\n`; - extractedLicenseContent += `\n${licenseText}\n`; - extractedLicenseContent += EXTRACTION_FILE_SEPARATOR; + // Generate the package's license entry in the output content + extractedLicenseContent += `Package: ${packageJson.name}\n`; + extractedLicenseContent += `License: ${JSON.stringify(packageJson.license, null, 2)}\n`; + extractedLicenseContent += `\n${licenseText}\n`; + extractedLicenseContent += EXTRACTION_FILE_SEPARATOR; + } } } diff --git a/packages/angular/build/src/tools/esbuild/utils.ts b/packages/angular/build/src/tools/esbuild/utils.ts index e4881e184862..7d9dce4a5522 100644 --- a/packages/angular/build/src/tools/esbuild/utils.ts +++ b/packages/angular/build/src/tools/esbuild/utils.ts @@ -25,7 +25,7 @@ import { import { type BuildOutputFile, BuildOutputFileType, type InitialFileRecord } from './bundler-files'; export function logBuildStats( - metafile: Metafile, + metafiles: Metafile[], outputFiles: BuildOutputFile[], initial: Map, budgetFailures: BudgetCalculatorResult[] | undefined, @@ -65,12 +65,12 @@ export function logBuildStats( } // Skip logging external component stylesheets used for HMR - if (metafile.outputs[file] && 'ng-component' in metafile.outputs[file]) { + if (metafiles.some((mf) => mf.outputs[file] && 'ng-component' in mf.outputs[file])) { componentStyleChange = true; continue; } - const name = initial.get(file)?.name ?? getChunkNameFromMetafile(metafile, file); + const name = initial.get(file)?.name ?? getChunkNameFromMetafile(metafiles, file); const stat: BundleStats = { initial: initial.has(file), stats: [file, name ?? '-', size, estimatedTransferSizes?.get(file) ?? '-'], @@ -108,9 +108,15 @@ export function logBuildStats( return ''; } -export function getChunkNameFromMetafile(metafile: Metafile, file: string): string | undefined { - if (metafile.outputs[file]?.entryPoint) { - return getEntryPointName(metafile.outputs[file].entryPoint); +export function getChunkNameFromMetafile( + metafiles: Metafile[] | Metafile, + file: string, +): string | undefined { + const metafileArray = Array.isArray(metafiles) ? metafiles : [metafiles]; + for (const metafile of metafileArray) { + if (metafile.outputs[file]?.entryPoint) { + return getEntryPointName(metafile.outputs[file].entryPoint); + } } } From a0a2ebded55a256828534a40012068541f50a244 Mon Sep 17 00:00:00 2001 From: Guilherme Almeida <45276342+guisalmeida@users.noreply.github.com> Date: Wed, 15 Jul 2026 16:12:16 +0100 Subject: [PATCH 319/787] docs: mention Vitest instead of Karma in README template of schematic library files --- packages/schematics/angular/library/files/README.md.template | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/schematics/angular/library/files/README.md.template b/packages/schematics/angular/library/files/README.md.template index 661e8958b9f6..d0c32c07f678 100644 --- a/packages/schematics/angular/library/files/README.md.template +++ b/packages/schematics/angular/library/files/README.md.template @@ -43,7 +43,7 @@ Once the project is built, you can publish your library by following these steps ## Running unit tests -To execute unit tests with the [Karma](https://karma-runner.github.io) test runner, use the following command: +To execute unit tests with the [Vitest](https://vitest.dev/) test runner, use the following command: ```bash ng test From cce8c75e92992ada23f658873a4efda74f7b1341 Mon Sep 17 00:00:00 2001 From: Angular Robot Date: Wed, 19 Aug 2026 16:00:33 +0000 Subject: [PATCH 320/787] build: update cross-repo angular dependencies See associated pull request for more information. --- tests/e2e/ng-snapshot/package.json | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/tests/e2e/ng-snapshot/package.json b/tests/e2e/ng-snapshot/package.json index 1b410674fd5a..b90a52884ca2 100644 --- a/tests/e2e/ng-snapshot/package.json +++ b/tests/e2e/ng-snapshot/package.json @@ -2,21 +2,21 @@ "description": "snapshot versions of Angular for e2e testing", "private": true, "dependencies": { - "@angular/animations": "github:angular/animations-builds#678e20bdf29e8d892a878ab8d42552a512c11692", + "@angular/animations": "github:angular/animations-builds#8c7ebc8b22ec0a6dc67c4d2900e034eb96300fb7", "@angular/cdk": "github:angular/cdk-builds#4b4949e62c156a3b2530372ebe6a56a3e813b2d0", - "@angular/common": "github:angular/common-builds#215a13b7f977d1f75b4d01ca798c8f9cc44f830b", - "@angular/compiler": "github:angular/compiler-builds#81eef66a3e5d30b6a46e0fea62fa9d360c27adb7", - "@angular/compiler-cli": "github:angular/compiler-cli-builds#c6f76875c4a522726916c9682d87183e13e932e5", - "@angular/core": "github:angular/core-builds#6706323d706dcf6d639b8712976646e3e99e91e2", - "@angular/forms": "github:angular/forms-builds#9f6690da73275be22fdc7eba08d78b4909a7b6e4", - "@angular/language-service": "github:angular/language-service-builds#03a95f77d0f44c4b6f194cc6cf56850fd11a2691", - "@angular/localize": "github:angular/localize-builds#7de5c236d7852c00e713d256f03f03b77997671f", + "@angular/common": "github:angular/common-builds#6a1e68f4e997310f018ffbb74c230e1bbe2cf0fc", + "@angular/compiler": "github:angular/compiler-builds#7b2a69f7286aaf5ff617fb8e7ae38e48481c317a", + "@angular/compiler-cli": "github:angular/compiler-cli-builds#2abac2b6619918b4ed6b8a43079182d2f2757357", + "@angular/core": "github:angular/core-builds#a575d55a94dccfbc76fd101aa2db53a3f3de3f1f", + "@angular/forms": "github:angular/forms-builds#0d9e44f98591f56cfd3b2edea4683fe0f00e8ce2", + "@angular/language-service": "github:angular/language-service-builds#b2ad13ba654fd6310ffdfd4181d6d41c307e3043", + "@angular/localize": "github:angular/localize-builds#28d4c50d1001466a481d78962dba4744d23a31d5", "@angular/material": "github:angular/material-builds#bbe56c79c782500f0183a0c84adf017cdb7ccd15", "@angular/material-moment-adapter": "github:angular/material-moment-adapter-builds#c26efa5523014d6ce9652cd6eb8125d1c60e0e0b", - "@angular/platform-browser": "github:angular/platform-browser-builds#a92de76171ed92a60aaae93f6fa9a3d15a82d092", - "@angular/platform-browser-dynamic": "github:angular/platform-browser-dynamic-builds#9ad24d91d95a25b57b854dc04d6aba660558ad8a", - "@angular/platform-server": "github:angular/platform-server-builds#d4ca9b253bfc472b0866fa37857e5716dc804887", - "@angular/router": "github:angular/router-builds#91098a665f813b3d9157b830411e1a48fda38c17", - "@angular/service-worker": "github:angular/service-worker-builds#eb60209150df4fa83342930e7ec2571a01703f44" + "@angular/platform-browser": "github:angular/platform-browser-builds#0714800cb3afa7c30402d4477f7079caa64874c2", + "@angular/platform-browser-dynamic": "github:angular/platform-browser-dynamic-builds#dbaff82250087fe6f09ee81d5a06a5f8e0e4cd13", + "@angular/platform-server": "github:angular/platform-server-builds#b7631948a2ebac08642410067d7a28f8e29f10c4", + "@angular/router": "github:angular/router-builds#dff46dd0722569aac7b136c6f4877493d591be94", + "@angular/service-worker": "github:angular/service-worker-builds#abf5a9f3547cb85b6d90412690abadcfbaec0e51" } } From 04f1da717bf72efb1a635bec1d338ce9471159f9 Mon Sep 17 00:00:00 2001 From: Doug Parker Date: Wed, 19 Aug 2026 12:38:28 -0700 Subject: [PATCH 321/787] docs: release notes for the v22.1.5 release --- CHANGELOG.md | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index fca9a3af30cf..4009c2ab529d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,32 @@ + + +# 22.1.5 (2026-08-19) + +### @angular/cli + +| Commit | Type | Description | +| --------------------------------------------------------------------------------------------------- | ---- | ---------------------------------------------------------------- | +| [e672271f8](https://github.com/angular/angular-cli/commit/e672271f81e7b8b422b98c17fca5b67896d40844) | fix | enforce MCP roots in get_best_practices tool | +| [a14916cc4](https://github.com/angular/angular-cli/commit/a14916cc4b13412205d3e4a1c32d7e40be52f0e1) | fix | handle errors from isAllowedWorkspacePath in best-practices tool | +| [d6e1cddff](https://github.com/angular/angular-cli/commit/d6e1cddff92842f6889585ae7899efc028decc78) | fix | throw on out-of-roots workspace in best-practices tool | + +### @schematics/angular + +| Commit | Type | Description | +| --------------------------------------------------------------------------------------------------- | ---- | ------------------------------------------------------------ | +| [ba2b0e4c2](https://github.com/angular/angular-cli/commit/ba2b0e4c291842c699fdbeaaddec1531dbdd7952) | fix | transform fail() to expect.fail() in refactor-jasmine-vitest | + +### @angular/build + +| Commit | Type | Description | +| --------------------------------------------------------------------------------------------------- | ---- | ------------------------------------------------------------- | +| [cba72902d](https://github.com/angular/angular-cli/commit/cba72902d42022bd5a1bd17b23d65cacc0013e35) | fix | correct misleading error message for top-level await | +| [b4679998c](https://github.com/angular/angular-cli/commit/b4679998c205b6cce01d40fad24c4ee7954aa48d) | fix | disable code splitting for unit test builds | +| [ff1d3565e](https://github.com/angular/angular-cli/commit/ff1d3565e87749a8347c3be98cd4a7ebccb69fc0) | fix | preserve integrity and crossorigin in autoCsp loader | +| [1fc1fb05c](https://github.com/angular/angular-cli/commit/1fc1fb05cfe2c69ee7b9345b582d3c2177b923fd) | perf | traverse AST with iterative post-order walker in i18n inliner | + + + # 22.2.0-next.3 (2026-08-13) From d8e3baf39841f8a9b6f801006cb721c6f6585289 Mon Sep 17 00:00:00 2001 From: Doug Parker Date: Wed, 19 Aug 2026 12:45:40 -0700 Subject: [PATCH 322/787] release: cut the v22.2.0-next.4 release --- CHANGELOG.md | 30 ++++++++++++++++++++++++++++++ package.json | 2 +- 2 files changed, 31 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4009c2ab529d..f3077ffb76bc 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,33 @@ + + +# 22.2.0-next.4 (2026-08-19) + +### @angular/cli + +| Commit | Type | Description | +| --------------------------------------------------------------------------------------------------- | ---- | ---------------------------------------------------------------- | +| [34e1e0bb5](https://github.com/angular/angular-cli/commit/34e1e0bb5d5ccf374f51a1b241158f6f2ea0dd42) | fix | enforce MCP roots in get_best_practices tool | +| [2b060630c](https://github.com/angular/angular-cli/commit/2b060630c66ce688b7ecbe51d282955869e5d4b0) | fix | handle errors from isAllowedWorkspacePath in best-practices tool | +| [24fd8fce2](https://github.com/angular/angular-cli/commit/24fd8fce2a3ff035acdc5f3e036eb4ba21f71a76) | fix | throw on out-of-roots workspace in best-practices tool | + +### @schematics/angular + +| Commit | Type | Description | +| --------------------------------------------------------------------------------------------------- | ---- | ------------------------------------------------------------ | +| [ce1b60f89](https://github.com/angular/angular-cli/commit/ce1b60f89699c3a76496a0489e5f2b9e4fe62429) | fix | transform fail() to expect.fail() in refactor-jasmine-vitest | + +### @angular/build + +| Commit | Type | Description | +| --------------------------------------------------------------------------------------------------- | ---- | --------------------------------------------------------------------------- | +| [175273931](https://github.com/angular/angular-cli/commit/175273931ebb0cf08bf62dd1694dbde5ff5229b6) | feat | Support splitting browser and server stats jsonfiles for easier consumption | +| [1ee0beca7](https://github.com/angular/angular-cli/commit/1ee0beca7b243cc4c06eb42b25d216d7b256b097) | fix | correct misleading error message for top-level await | +| [0ffe2d27f](https://github.com/angular/angular-cli/commit/0ffe2d27f256a5755809fa4788e4adb97c65b806) | fix | disable code splitting for unit test builds | +| [50994d76e](https://github.com/angular/angular-cli/commit/50994d76e59a4b632f1782c51cd60f80c9cd50fb) | fix | preserve integrity and crossorigin in autoCsp loader | +| [d6fd24320](https://github.com/angular/angular-cli/commit/d6fd243207ad1c3e242b8592698afa986320cc6c) | perf | traverse AST with iterative post-order walker in i18n inliner | + + + # 22.1.5 (2026-08-19) diff --git a/package.json b/package.json index 0884c412256f..3d498f454317 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@angular/devkit-repo", - "version": "22.2.0-next.3", + "version": "22.2.0-next.4", "private": true, "description": "Software Development Kit for Angular", "keywords": [ From f8576e3c8bfe3490b1b0b85832b489593a4e43ac Mon Sep 17 00:00:00 2001 From: Alan Agius Date: Thu, 20 Aug 2026 10:28:29 +0200 Subject: [PATCH 323/787] fix(@angular/ssr): abort web request signal when node request is aborted --- packages/angular/ssr/node/src/request.ts | 9 +++++ .../ssr/node/test/request_http1_spec.ts | 38 +++++++++++++++++++ .../ssr/node/test/request_http2_spec.ts | 38 +++++++++++++++++++ 3 files changed, 85 insertions(+) diff --git a/packages/angular/ssr/node/src/request.ts b/packages/angular/ssr/node/src/request.ts index 4bd754b268cc..4f604b6a9d0e 100644 --- a/packages/angular/ssr/node/src/request.ts +++ b/packages/angular/ssr/node/src/request.ts @@ -55,9 +55,18 @@ export function createWebRequestFromNodeRequest( const { headers, method = 'GET' } = nodeRequest; const withBody = method !== 'GET' && method !== 'HEAD'; const referrer = headers.referer && URL.canParse(headers.referer) ? headers.referer : undefined; + const controller = new AbortController(); + if (nodeRequest.aborted) { + controller.abort(); + } else { + const onAbort = () => controller.abort(); + nodeRequest.once('aborted', onAbort); + nodeRequest.once('close', () => nodeRequest.off('aborted', onAbort)); + } return new Request(createRequestUrl(nodeRequest, trustProxyHeadersNormalized), { method, + signal: controller.signal, headers: createRequestHeaders(headers), body: withBody ? nodeRequest : undefined, duplex: withBody ? 'half' : undefined, diff --git a/packages/angular/ssr/node/test/request_http1_spec.ts b/packages/angular/ssr/node/test/request_http1_spec.ts index 87f25f918ef7..9f11fe390ed4 100644 --- a/packages/angular/ssr/node/test/request_http1_spec.ts +++ b/packages/angular/ssr/node/test/request_http1_spec.ts @@ -189,4 +189,42 @@ describe('createWebRequestFromNodeRequest (HTTP/1.1)', () => { expect(await webRequest.text()).toBe(''); }); }); + + describe('abort handling', () => { + it('should abort the web request signal when the node request is aborted', async () => { + const nodeRequest = await extractNodeRequest(() => { + request({ + hostname: 'localhost', + port, + path: '/abort', + method: 'GET', + }).end(); + }); + + const webRequest = createWebRequestFromNodeRequest(nodeRequest); + expect(webRequest.signal.aborted).toBeFalse(); + + nodeRequest.emit('aborted'); + + expect(webRequest.signal.aborted).toBeTrue(); + }); + + it('should create an aborted web request signal when the node request is already aborted', async () => { + const nodeRequest = await extractNodeRequest(() => { + request({ + hostname: 'localhost', + port, + path: '/already-aborted', + method: 'GET', + }).end(); + }); + + Object.defineProperty(nodeRequest, 'aborted', { get: () => true, configurable: true }); + + const webRequest = createWebRequestFromNodeRequest(nodeRequest); + expect(webRequest.signal.aborted).toBeTrue(); + + delete (nodeRequest as { aborted?: boolean }).aborted; + }); + }); }); diff --git a/packages/angular/ssr/node/test/request_http2_spec.ts b/packages/angular/ssr/node/test/request_http2_spec.ts index 7079a385daaf..e652c59f6461 100644 --- a/packages/angular/ssr/node/test/request_http2_spec.ts +++ b/packages/angular/ssr/node/test/request_http2_spec.ts @@ -188,4 +188,42 @@ describe('createWebRequestFromNodeRequest (HTTP/2)', () => { expect(await webRequest.text()).toBe(''); }); }); + + describe('abort handling', () => { + it('should abort the web request signal when the node request is aborted', async () => { + const nodeRequest = await extractNodeRequest(() => { + client + .request({ + ':path': '/abort', + ':method': 'GET', + }) + .end(); + }); + + const webRequest = createWebRequestFromNodeRequest(nodeRequest); + expect(webRequest.signal.aborted).toBeFalse(); + + nodeRequest.emit('aborted'); + + expect(webRequest.signal.aborted).toBeTrue(); + }); + + it('should create an aborted web request signal when the node request is already aborted', async () => { + const nodeRequest = await extractNodeRequest(() => { + client + .request({ + ':path': '/already-aborted', + ':method': 'GET', + }) + .end(); + }); + + Object.defineProperty(nodeRequest, 'aborted', { get: () => true, configurable: true }); + + const webRequest = createWebRequestFromNodeRequest(nodeRequest); + expect(webRequest.signal.aborted).toBeTrue(); + + delete (nodeRequest as { aborted?: boolean }).aborted; + }); + }); }); From f4dad31cce41bc3e8ed8767256d9e50a712c3a72 Mon Sep 17 00:00:00 2001 From: Alan Agius Date: Thu, 20 Aug 2026 10:28:51 +0200 Subject: [PATCH 324/787] perf(@angular/build): unify Oxc linking and optimization AST traversal passes Combine partial declaration linking and advanced optimizations into a single AST traversal pass over one Oxc parseSync AST in oxc-transform. This eliminates duplicate AST parses and MagicString sourcemap remapping chains when transforming Angular packages. --- .../src/tools/angular/linker/oxc-linker.ts | 163 +++++------------- .../tools/angular/linker/oxc-linker_spec.ts | 16 +- .../esbuild/javascript-transformer-worker.ts | 81 ++++----- .../build/src/tools/oxc/oxc-transform.ts | 93 ++++++---- .../build/src/tools/oxc/oxc-transform_spec.ts | 77 ++++++++- 5 files changed, 216 insertions(+), 214 deletions(-) diff --git a/packages/angular/build/src/tools/angular/linker/oxc-linker.ts b/packages/angular/build/src/tools/angular/linker/oxc-linker.ts index 7d085502978b..26133a6b5611 100644 --- a/packages/angular/build/src/tools/angular/linker/oxc-linker.ts +++ b/packages/angular/build/src/tools/angular/linker/oxc-linker.ts @@ -6,17 +6,13 @@ * found in the LICENSE file at https://angular.dev/license */ -import type { DecodedSourceMap } from '@ampproject/remapping'; import { ConsoleLogger, LogLevel } from '@angular/compiler-cli'; -import type { DeclarationScope } from '@angular/compiler-cli/linker'; -import { FileLinker, LinkerEnvironment, needsLinking } from '@angular/compiler-cli/linker'; +import { type DeclarationScope, FileLinker, LinkerEnvironment } from '@angular/compiler-cli/linker'; import type { AbsoluteFsPath, ReadonlyFileSystem, } from '@angular/compiler-cli/src/ngtsc/file_system'; -import type { CallExpression, Node } from '@oxc-project/types'; -import MagicString from 'magic-string'; -import { parseSync, visitorKeys } from 'oxc-parser'; +import type { CallExpression } from '@oxc-project/types'; import { OxcAstHost } from './oxc-ast-host'; import { StringAstFactory } from './string-ast-factory'; @@ -49,131 +45,52 @@ const noopFileSystem: ReadonlyFileSystem = { relative: (_from: string, to: string) => to, } as unknown as ReadonlyFileSystem; -const SHARED_LOGGER = new ConsoleLogger(LogLevel.info); - -const SHARED_AST_HOST = new OxcAstHost(); -const SHARED_DECLARATION_SCOPE = new InlineDeclarationScope(); +let SHARED_LOGGER: ConsoleLogger; +let SHARED_AST_HOST: OxcAstHost; +let SHARED_DECLARATION_SCOPE: InlineDeclarationScope; /** - * Recursively traverses ESTree AST nodes with subtree pruning. - * When `onCallExpression` returns `true` for a linked `CallExpression`, - * child traversal into `callee` and `arguments` is skipped. - * - * Why subtree pruning is safe for the linker: - * - Angular partial declarations (`ɵɵngDeclareComponent`, `ɵɵngDeclareDirective`, - * etc.) are never nested inside each other. - * - Once a declaration `CallExpression` is linked and replaced, there can never be - * another partial declaration within its metadata argument object. Pruning its - * subtree avoids traversing hundreds of unnecessary metadata argument nodes per - * component. + * Manages Angular partial declaration linking using Oxc AST nodes. */ -function visitNode( - node: Node | Node[] | null | undefined, - onCallExpression: (node: CallExpression) => boolean, -): void { - if (node === null || node === undefined || typeof node !== 'object') { - return; - } - - if (Array.isArray(node)) { - for (let i = 0; i < node.length; i++) { - visitNode(node[i], onCallExpression); - } - - return; - } - - const nodeType = node.type; - if (!nodeType) { - return; +export class OxcLinker { + readonly #fileLinker: FileLinker; + + constructor(filename: string, code: string, jit = false) { + SHARED_LOGGER ??= new ConsoleLogger(LogLevel.info); + SHARED_AST_HOST ??= new OxcAstHost(); + SHARED_DECLARATION_SCOPE ??= new InlineDeclarationScope(); + + const astFactory = new StringAstFactory(code); + const linkerEnvironment = LinkerEnvironment.create( + noopFileSystem, + SHARED_LOGGER, + SHARED_AST_HOST, + astFactory, + { linkerJitMode: jit, sourceMapping: false }, + ); + + this.#fileLinker = new FileLinker(linkerEnvironment, filename as AbsoluteFsPath, code); } - if (nodeType === 'CallExpression') { - if (onCallExpression(node)) { - // Subtree pruning: partial declarations cannot be nested, so skip child traversal. - return; - } - } - - const keys = visitorKeys[nodeType]; - if (keys) { - for (let i = 0; i < keys.length; i++) { - const child = (node as unknown as Record)[keys[i]]; - if (child !== undefined && child !== null) { - visitNode(child, onCallExpression); - } - } - } -} - -export interface OxcLinkerOptions { - sourcemap?: boolean; - jit?: boolean; - skipCheck?: boolean; -} - -/** - * Executes Angular partial declaration linking on the specified JavaScript file - * using `oxc-parser` and `magic-string`. - * - * @param filename The full path to the file. - * @param code The source code content. - * @param options Linker options (sourcemap, jit, skipCheck). - * @returns An object containing the transformed code and optional source map. - */ -export function linkWithOxc(filename: string, code: string, options: OxcLinkerOptions = {}) { - if (!options.skipCheck && !needsLinking(filename, code)) { - return { code, map: undefined }; - } - - const astFactory = new StringAstFactory(code); - - const linkerEnvironment = LinkerEnvironment.create( - noopFileSystem, - SHARED_LOGGER, - SHARED_AST_HOST, - astFactory, - { linkerJitMode: options.jit ?? false, sourceMapping: false }, - ); - - const fileLinker = new FileLinker(linkerEnvironment, filename as AbsoluteFsPath, code); - const { program } = parseSync(filename, code, { range: true }); - - let s: MagicString | undefined; - let hasLinked = false; - - visitNode(program, (node) => { + /** + * Attempts to link an Angular partial declaration CallExpression. + * + * @param node The CallExpression AST node to check and link. + * @returns The linked code string if the node is a partial declaration, or undefined otherwise. + */ + linkCallExpression(node: CallExpression): string | undefined { const calleeName = SHARED_AST_HOST.getSymbolName(node.callee); - if (calleeName && fileLinker.isPartialDeclaration(calleeName)) { - const args = SHARED_AST_HOST.parseArguments(node); - const linkedCode = fileLinker.linkPartialDeclaration( - calleeName, - args, - SHARED_DECLARATION_SCOPE, - ); - - s ??= new MagicString(code); - s.overwrite(node.start, node.end, linkedCode as string); - hasLinked = true; - - return true; + if (!calleeName || !this.#fileLinker.isPartialDeclaration(calleeName)) { + return undefined; } - return false; - }); + const args = SHARED_AST_HOST.parseArguments(node); + const linkedCode = this.#fileLinker.linkPartialDeclaration( + calleeName, + args, + SHARED_DECLARATION_SCOPE, + ); - if (!hasLinked || !s) { - return { code, map: undefined }; + return linkedCode as string; } - - let map: DecodedSourceMap | undefined; - if (options.sourcemap) { - const rawMap = s.generateDecodedMap({ hires: true, source: filename }); - map = { ...rawMap, version: 3 }; - } - - return { - code: s.toString(), - map, - }; } diff --git a/packages/angular/build/src/tools/angular/linker/oxc-linker_spec.ts b/packages/angular/build/src/tools/angular/linker/oxc-linker_spec.ts index 5f5cf6d84fe9..fa62c1c5ece1 100644 --- a/packages/angular/build/src/tools/angular/linker/oxc-linker_spec.ts +++ b/packages/angular/build/src/tools/angular/linker/oxc-linker_spec.ts @@ -6,12 +6,12 @@ * found in the LICENSE file at https://angular.dev/license */ -import { linkWithOxc } from './oxc-linker'; +import { transform } from '../../oxc/oxc-transform'; -describe('linkWithOxc', () => { +describe('oxc-linker', () => { it('should not modify code that does not need linking', () => { const input = 'const x = 1;'; - const result = linkWithOxc('test.js', input); + const result = transform('test.js', input, { link: true, advancedOptimizations: false }); expect(result.code).toBe(input); expect(result.map).toBeUndefined(); }); @@ -29,7 +29,7 @@ describe('linkWithOxc', () => { }); `; - const result = linkWithOxc('test.js', input); + const result = transform('test.js', input, { link: true, advancedOptimizations: false }); expect(result.code).toContain('i0.ɵɵdefineDirective'); expect(result.code).not.toContain('i0.ɵɵngDeclareDirective'); }); @@ -49,7 +49,7 @@ describe('linkWithOxc', () => { }); `; - const result = linkWithOxc('test.js', input); + const result = transform('test.js', input, { link: true, advancedOptimizations: false }); expect(result.code).toContain('i0.ɵɵdefineComponent'); expect(result.code).not.toContain('i0.ɵɵngDeclareComponent'); }); @@ -67,7 +67,11 @@ describe('linkWithOxc', () => { }); `; - const result = linkWithOxc('test.js', input, { sourcemap: true }); + const result = transform('test.js', input, { + link: true, + advancedOptimizations: false, + sourcemap: true, + }); expect(result.map).toBeDefined(); expect(result.map?.version).toBe(3); expect(result.map?.sources).toContain('test.js'); diff --git a/packages/angular/build/src/tools/esbuild/javascript-transformer-worker.ts b/packages/angular/build/src/tools/esbuild/javascript-transformer-worker.ts index 4d951ec8e963..f2ec7eccce6d 100644 --- a/packages/angular/build/src/tools/esbuild/javascript-transformer-worker.ts +++ b/packages/angular/build/src/tools/esbuild/javascript-transformer-worker.ts @@ -19,7 +19,6 @@ import { loadInputSourceMapFromUrl, removeSourceMappingURL, } from '../../utils/source-map'; -import { linkWithOxc } from '../angular/linker/oxc-linker.js'; import { transform as transformWithOxc } from '../oxc/oxc-transform.js'; import type { JavaScriptTransformerOptions } from './javascript-transformer'; @@ -170,61 +169,53 @@ async function transformJavaScriptImpl( coverageMap = result.map; } - if (shouldLink) { - if (useBabelLinker) { - const { createEs2015LinkerPlugin } = await import('@angular/compiler-cli/linker/babel'); - const { ConsoleLogger, LogLevel } = await import('@angular/compiler-cli'); + if (shouldLink && useBabelLinker) { + const { createEs2015LinkerPlugin } = await import('@angular/compiler-cli/linker/babel'); + const { ConsoleLogger, LogLevel } = await import('@angular/compiler-cli'); - const result = await transformAsync(code, { - filename, - inputSourceMap: false, - sourceMaps: !!useInputSourcemap, - compact: false, - configFile: false, - babelrc: false, - browserslistConfigFile: false, - plugins: [ - createEs2015LinkerPlugin({ - fileSystem: { - exists: () => false, - readFile: () => '', - resolve: (...paths: string[]) => paths.join('/'), - dirname: (path: string) => path.split('/').slice(0, -1).join('/'), - relative: (_from: string, to: string) => to, - } as never, - logger: new ConsoleLogger(LogLevel.info), - linkerJitMode: jit, - // This is a workaround until https://github.com/angular/angular/issues/42769 is fixed. - sourceMapping: false, - }) as PluginItem, - ], - }); + const result = await transformAsync(code, { + filename, + inputSourceMap: false, + sourceMaps: !!useInputSourcemap, + compact: false, + configFile: false, + babelrc: false, + browserslistConfigFile: false, + plugins: [ + createEs2015LinkerPlugin({ + fileSystem: { + exists: () => false, + readFile: () => '', + resolve: (...paths: string[]) => paths.join('/'), + dirname: (path: string) => path.split('/').slice(0, -1).join('/'), + relative: (_from: string, to: string) => to, + } as never, + logger: new ConsoleLogger(LogLevel.info), + linkerJitMode: jit, + // This is a workaround until https://github.com/angular/angular/issues/42769 is fixed. + sourceMapping: false, + }) as PluginItem, + ], + }); - code = result?.code ?? code; - if (result?.map) { - maps.push(result.map as EncodedSourceMap); - } - } else { - const result = linkWithOxc(filename, code, { - sourcemap: useInputSourcemap, - jit, - skipCheck: true, - }); - code = result.code; - if (result.map) { - maps.push(result.map); - } + code = result?.code ?? code; + if (result?.map) { + maps.push(result.map as EncodedSourceMap); } } - // Run advanced optimizations using our fast oxc-transform - if (advancedOptimizations) { + // Run Oxc linking and/or advanced optimizations in a single unified AST traversal pass + const oxcLink = shouldLink && !useBabelLinker; + if (oxcLink || advancedOptimizations) { const sideEffectFree = options.sideEffects === false; const safeAngularPackage = sideEffectFree && /[\\/]node_modules[\\/]@angular[\\/]/.test(filename); const topLevelSafeMode = !safeAngularPackage; const result = transformWithOxc(filename, code, { + link: oxcLink, + jit, + advancedOptimizations, sourcemap: useInputSourcemap, sideEffects: options.sideEffects, topLevelSafeMode, diff --git a/packages/angular/build/src/tools/oxc/oxc-transform.ts b/packages/angular/build/src/tools/oxc/oxc-transform.ts index bec14cd40385..c0389a9f75a4 100644 --- a/packages/angular/build/src/tools/oxc/oxc-transform.ts +++ b/packages/angular/build/src/tools/oxc/oxc-transform.ts @@ -7,15 +7,20 @@ */ import type { DecodedSourceMap } from '@ampproject/remapping'; +import { needsLinking } from '@angular/compiler-cli/linker'; import type { BindingIdentifier, Class, Node } from '@oxc-project/types'; import { MagicString } from 'magic-string'; import { Visitor, parseSync } from 'oxc-parser'; +import { OxcLinker } from '../angular/linker/oxc-linker'; export interface OxcTransformOptions { sourcemap?: boolean; sideEffects?: boolean; topLevelSafeMode?: boolean; pureAnnotate?: boolean; + link?: boolean; + jit?: boolean; + advancedOptimizations?: boolean; } /** @@ -256,8 +261,12 @@ function analyzeClassStaticProperties(classNode: Node, code: string): boolean { // eslint-disable-next-line max-lines-per-function export function transform(filename: string, code: string, options: OxcTransformOptions) { const { program } = parseSync(filename, code, { range: true }); - const s = new MagicString(code); + const source = new MagicString(code); + const shouldLink = options.link && needsLinking(filename, code); + const linker = shouldLink ? new OxcLinker(filename, code, options.jit) : undefined; + + const advancedOptimizations = options.advancedOptimizations ?? true; const sideEffectFree = options.sideEffects === false; const topLevelSafeMode = options.topLevelSafeMode ?? false; const wrapDecorators = sideEffectFree; @@ -412,12 +421,12 @@ export function transform(filename: string, code: string, options: OxcTransformO } // 1. Remove leading/trailing characters/parentheses of the expression statement - s.remove(nextStatement.start, nextExpr.start); - s.remove(nextExpr.end, nextStatement.end); + source.remove(nextStatement.start, nextExpr.start); + source.remove(nextExpr.end, nextStatement.end); markEdited(nextStatement.start, nextStatement.end); // 2. Add return statement inside IIFE body - s.appendRight(callee.body.end - 1, `; return ${paramName};`); + source.appendRight(callee.body.end - 1, `; return ${paramName};`); // 3. Remove `Name = ` assignment in arguments if it's a simple identifier if (rightCallArgument.left.type === 'Identifier') { @@ -428,13 +437,13 @@ export function transform(filename: string, code: string, options: OxcTransformO if (unwrapParentheses(rightCallArgument.right).type === 'AssignmentExpression') { replacement = `(${replacement})`; } - s.overwrite(arg.right.start, arg.right.end, replacement); + source.overwrite(arg.right.start, arg.right.end, replacement); markEdited(arg.right.start, arg.right.end); } // 4. Move IIFE to the var initializer - s.move(nextExpr.start, nextExpr.end, decl.id.end); - s.appendLeft(decl.id.end, ' = /*#__PURE__*/ '); + source.move(nextExpr.start, nextExpr.end, decl.id.end); + source.appendLeft(decl.id.end, ' = /*#__PURE__*/ '); } } @@ -562,7 +571,7 @@ export function transform(filename: string, code: string, options: OxcTransformO // Perform elisions immediately for (const item of wrapStatementPaths) { if (item.type === 'elide') { - s.remove(item.statement.start, item.statement.end); + source.remove(item.statement.start, item.statement.end); markEdited(item.statement.start, item.statement.end); } } @@ -582,27 +591,30 @@ export function transform(filename: string, code: string, options: OxcTransformO if (isExportDefault) { // 1. Remove `export default ` - s.overwrite(statement.start, classNode.start, ''); + source.overwrite(statement.start, classNode.start, ''); // 2. Wrap in IIFE - s.appendRight(classNode.start, `let ${classIdName} = /*#__PURE__*/ (() => {\n`); - s.appendLeft( + source.appendRight(classNode.start, `let ${classIdName} = /*#__PURE__*/ (() => {\n`); + source.appendLeft( lastStatement.end, `\nreturn ${classIdName};\n})();\nexport { ${classIdName} as default };`, ); } else if (isExportNamed) { // 1. Export is kept, turn `class` into `let ClassName = IIFE` - s.appendRight(classNode.start, `let ${classIdName} = /*#__PURE__*/ (() => {\n`); - s.appendLeft(lastStatement.end, `\nreturn ${classIdName};\n})();`); + source.appendRight(classNode.start, `let ${classIdName} = /*#__PURE__*/ (() => {\n`); + source.appendLeft(lastStatement.end, `\nreturn ${classIdName};\n})();`); } else if (isVariableClass) { // Wrap class inside init: `/*#__PURE__*/ (() => { let ClassName = class ClassName {}; return ClassName; })()` - s.appendRight(classNode.start, `/*#__PURE__*/ (() => {\nlet ${classIdName} = `); + source.appendRight(classNode.start, `/*#__PURE__*/ (() => {\nlet ${classIdName} = `); const terminator = activeWrapPaths.length === 0 ? ';' : ''; const iifeClosing = activeWrapPaths.length === 0 ? '})()' : '})();'; - s.appendLeft(lastStatement.end, `${terminator}\nreturn ${classIdName};\n${iifeClosing}`); + source.appendLeft( + lastStatement.end, + `${terminator}\nreturn ${classIdName};\n${iifeClosing}`, + ); } else { // Standard ClassDeclaration - s.appendRight(classNode.start, `let ${classIdName} = /*#__PURE__*/ (() => {\n`); - s.appendLeft(lastStatement.end, `\nreturn ${classIdName};\n})();`); + source.appendRight(classNode.start, `let ${classIdName} = /*#__PURE__*/ (() => {\n`); + source.appendLeft(lastStatement.end, `\nreturn ${classIdName};\n})();`); } markEdited(statement.start, lastStatement.end); @@ -611,8 +623,8 @@ export function transform(filename: string, code: string, options: OxcTransformO i += wrapStatementPaths.length; } else if (isExportDefault && !hasPotentialSideEffects) { // Splitting default export even when not wrapped - s.overwrite(statement.start, classNode.start, ''); - s.appendLeft(classNode.end, `\nexport { ${classIdName} as default };`); + source.overwrite(statement.start, classNode.start, ''); + source.appendLeft(classNode.end, `\nexport { ${classIdName} as default };`); markEdited(statement.start, classNode.end); } } @@ -655,19 +667,37 @@ export function transform(filename: string, code: string, options: OxcTransformO functionDepth--; functionStack.pop(); }, - Program(node) { - adjustTypeScriptEnumsInStatements(node.body); - adjustStaticMembersInStatements(node.body); + 'Program:exit'(node) { + if (advancedOptimizations) { + adjustTypeScriptEnumsInStatements(node.body); + adjustStaticMembersInStatements(node.body); + } }, - BlockStatement(node) { - adjustTypeScriptEnumsInStatements(node.body); - adjustStaticMembersInStatements(node.body); + 'BlockStatement:exit'(node) { + if (advancedOptimizations) { + adjustTypeScriptEnumsInStatements(node.body); + adjustStaticMembersInStatements(node.body); + } }, CallExpression(node) { if (isAlreadyEdited(node.start, node.end)) { return; } + if (linker) { + const linkedCode = linker.linkCallExpression(node); + if (linkedCode !== undefined) { + source.overwrite(node.start, node.end, linkedCode); + markEdited(node.start, node.end); + + return; + } + } + + if (!advancedOptimizations) { + return; + } + // 1. Elide Angular Metadata check let calleeName: string | undefined; if (node.callee.type === 'Identifier') { @@ -686,7 +716,7 @@ export function transform(filename: string, code: string, options: OxcTransformO (parentFunc.type === 'FunctionExpression' || parentFunc.type === 'ArrowFunctionExpression') ) { - s.overwrite(node.start, node.end, 'void 0'); + source.overwrite(node.start, node.end, 'void 0'); markEdited(node.start, node.end); return; @@ -714,11 +744,12 @@ export function transform(filename: string, code: string, options: OxcTransformO } if (!hasPureComment(node.start)) { - s.appendLeft(node.start, '/*#__PURE__*/ '); + source.appendLeft(node.start, '/*#__PURE__*/ '); } }, NewExpression(node) { if ( + !advancedOptimizations || !pureAnnotate || functionDepth > 0 || classDepth > 0 || @@ -729,7 +760,7 @@ export function transform(filename: string, code: string, options: OxcTransformO if (!topLevelSafeMode) { if (!hasPureComment(node.start)) { - s.appendLeft(node.start, '/*#__PURE__*/ '); + source.appendLeft(node.start, '/*#__PURE__*/ '); } return; @@ -738,7 +769,7 @@ export function transform(filename: string, code: string, options: OxcTransformO const callee = node.callee; if (callee.type === 'Identifier' && sideEffectFreeConstructors.has(callee.name)) { if (!hasPureComment(node.start)) { - s.appendLeft(node.start, '/*#__PURE__*/ '); + source.appendLeft(node.start, '/*#__PURE__*/ '); } } }, @@ -748,12 +779,12 @@ export function transform(filename: string, code: string, options: OxcTransformO let map: DecodedSourceMap | undefined; if (options.sourcemap) { - const rawMap = s.generateDecodedMap({ hires: true, source: filename }); + const rawMap = source.generateDecodedMap({ hires: true, source: filename }); map = { ...rawMap, version: 3 }; } return { - code: s.toString(), + code: source.toString(), map, }; } diff --git a/packages/angular/build/src/tools/oxc/oxc-transform_spec.ts b/packages/angular/build/src/tools/oxc/oxc-transform_spec.ts index daa4cf554634..d1b02f6a1bdc 100644 --- a/packages/angular/build/src/tools/oxc/oxc-transform_spec.ts +++ b/packages/angular/build/src/tools/oxc/oxc-transform_spec.ts @@ -8,14 +8,73 @@ import { transform } from './oxc-transform'; -describe('oxc-transform sourcemaps', () => { - it('should generate a decoded sourcemap when sourcemap option is enabled', () => { - const input = 'var result = new SomeClass();'; - const result = transform('test.js', input, { sourcemap: true }); - - expect(result.map).toBeDefined(); - expect(result.map?.version).toBe(3); - expect(result.map?.sources).toContain('test.js'); - expect(result.map?.mappings.length).toBeGreaterThan(0); +describe('oxc-transform', () => { + describe('sourcemaps', () => { + it('should generate a decoded sourcemap when sourcemap option is enabled', () => { + const input = 'var result = new SomeClass();'; + const result = transform('test.js', input, { sourcemap: true }); + + expect(result.map).toBeDefined(); + expect(result.map?.version).toBe(3); + expect(result.map?.sources).toContain('test.js'); + expect(result.map?.mappings.length).toBeGreaterThan(0); + }); + }); + + describe('linking and unified passes', () => { + const componentInput = ` + import * as i0 from "@angular/core"; + export class MyComponent {} + MyComponent.ɵcmp = i0.ɵɵngDeclareComponent({ + minVersion: "12.0.0", + version: "14.0.0", + ngImport: i0, + type: MyComponent, + isStandalone: true, + selector: "my-cmp", + template: "Hello" + }); + `; + + it('should link partial component declarations when link option is enabled', () => { + const result = transform('test.js', componentInput, { link: true }); + expect(result.code).toContain('i0.ɵɵdefineComponent'); + expect(result.code).not.toContain('i0.ɵɵngDeclareComponent'); + }); + + it('should not link partial component declarations when link option is disabled', () => { + const result = transform('test.js', componentInput, { link: false }); + expect(result.code).not.toContain('i0.ɵɵdefineComponent'); + expect(result.code).toContain('i0.ɵɵngDeclareComponent'); + }); + + it('should perform linking and advanced optimizations simultaneously in a single pass', () => { + const input = ` + import * as i0 from "@angular/core"; + export class MyComponent { + static create() { + return new MyComponent(); + } + } + MyComponent.ɵcmp = i0.ɵɵngDeclareComponent({ + minVersion: "12.0.0", + version: "14.0.0", + ngImport: i0, + type: MyComponent, + isStandalone: true, + selector: "my-cmp", + template: "Hello" + }); + `; + + const result = transform('test.js', input, { + link: true, + advancedOptimizations: true, + topLevelSafeMode: true, + }); + expect(result.code).toContain('i0.ɵɵdefineComponent'); + expect(result.code).not.toContain('i0.ɵɵngDeclareComponent'); + expect(result.code).toContain('let MyComponent = /*#__PURE__*/ (() => {'); + }); }); }); From e5a29cf86156c8d30ce151512423f43afcd62771 Mon Sep 17 00:00:00 2001 From: Angular Robot Date: Thu, 20 Aug 2026 06:01:19 +0000 Subject: [PATCH 325/787] build: update dependency karma-jasmine-html-reporter to ~2.3.0 See associated pull request for more information. --- .../schematics/angular/utility/latest-versions/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/schematics/angular/utility/latest-versions/package.json b/packages/schematics/angular/utility/latest-versions/package.json index 92aca6a12183..41ba63058ad4 100644 --- a/packages/schematics/angular/utility/latest-versions/package.json +++ b/packages/schematics/angular/utility/latest-versions/package.json @@ -13,7 +13,7 @@ "jasmine-spec-reporter": "~7.0.0", "karma-chrome-launcher": "~3.2.0", "karma-coverage": "~2.2.0", - "karma-jasmine-html-reporter": "~2.2.0", + "karma-jasmine-html-reporter": "~2.3.0", "karma-jasmine": "~5.1.0", "karma": "~6.4.0", "jsdom": "^30.0.0", From deac1b61193bbf6581e7cb1afd263a581cc28c6e Mon Sep 17 00:00:00 2001 From: Angular Robot Date: Thu, 20 Aug 2026 06:33:15 +0000 Subject: [PATCH 326/787] build: update all non-major dependencies See associated pull request for more information. --- modules/testing/builder/package.json | 4 +- package.json | 8 +- packages/angular/build/package.json | 10 +- .../angular_devkit/build_angular/package.json | 4 +- .../angular_devkit/schematics/package.json | 2 +- pnpm-lock.yaml | 634 +++++++++--------- 6 files changed, 343 insertions(+), 319 deletions(-) diff --git a/modules/testing/builder/package.json b/modules/testing/builder/package.json index bcbbd0c6de59..f2db890d966d 100644 --- a/modules/testing/builder/package.json +++ b/modules/testing/builder/package.json @@ -4,12 +4,12 @@ "@angular-devkit/build-angular": "workspace:*", "@angular-devkit/core": "workspace:*", "@angular/ssr": "workspace:*", - "@vitest/coverage-v8": "4.1.10", + "@vitest/coverage-v8": "4.1.11", "browser-sync": "3.0.4", "istanbul-lib-instrument": "6.0.3", "jsdom": "30.0.1", "ng-packagr": "22.2.0-next.3", "rxjs": "7.8.2", - "vitest": "4.1.10" + "vitest": "4.1.11" } } diff --git a/package.json b/package.json index 3d498f454317..604ee7863fe7 100644 --- a/package.json +++ b/package.json @@ -114,12 +114,12 @@ "karma-chrome-launcher": "~3.2.0", "karma-coverage": "~2.2.0", "karma-jasmine": "~5.1.0", - "karma-jasmine-html-reporter": "~2.2.0", + "karma-jasmine-html-reporter": "~2.3.0", "karma-source-map-support": "1.4.0", "lodash": "^4.17.21", - "magic-string": "1.1.1", + "magic-string": "1.2.1", "prettier": "^3.0.0", - "puppeteer": "25.6.0", + "puppeteer": "25.8.0", "quicktype-core": "26.0.0", "rollup": "4.62.4", "rollup-license-plugin": "~3.2.0", @@ -130,7 +130,7 @@ "tslib": "2.8.1", "undici": "8.10.0", "unenv": "^1.10.0", - "verdaccio": "6.9.2", + "verdaccio": "6.10.0", "verdaccio-auth-memory": "^13.0.0", "zone.js": "^0.16.0" }, diff --git a/packages/angular/build/package.json b/packages/angular/build/package.json index c0292af85e9c..490f2f4b474c 100644 --- a/packages/angular/build/package.json +++ b/packages/angular/build/package.json @@ -31,9 +31,9 @@ "https-proxy-agent": "9.1.0", "jsonc-parser": "3.3.1", "listr2": "11.0.0", - "magic-string": "1.1.1", + "magic-string": "1.2.1", "mrmime": "2.0.1", - "oxc-parser": "0.144.0", + "oxc-parser": "0.145.0", "parse5-html-rewriting-stream": "8.0.1", "picomatch": "4.0.5", "piscina": "5.3.0", @@ -51,15 +51,15 @@ "devDependencies": { "@angular-devkit/core": "workspace:*", "@angular/ssr": "workspace:*", - "@oxc-project/types": "0.144.0", + "@oxc-project/types": "0.145.0", "istanbul-lib-instrument": "6.0.3", "jsdom": "30.0.1", - "less": "4.8.1", + "less": "4.9.0", "ng-packagr": "22.2.0-next.3", "postcss": "8.5.26", "rollup": "4.62.4", "rxjs": "7.8.2", - "vitest": "4.1.10" + "vitest": "4.1.11" }, "peerDependencies": { "@angular/compiler": "0.0.0-ANGULAR-FW-PEER-DEP", diff --git a/packages/angular_devkit/build_angular/package.json b/packages/angular_devkit/build_angular/package.json index fd9718dd3986..865a0f807c2a 100644 --- a/packages/angular_devkit/build_angular/package.json +++ b/packages/angular_devkit/build_angular/package.json @@ -33,12 +33,12 @@ "istanbul-lib-instrument": "6.0.3", "jsonc-parser": "3.3.1", "karma-source-map-support": "1.4.0", - "less": "4.8.1", + "less": "4.9.0", "less-loader": "13.0.0", "license-webpack-plugin": "4.0.2", "loader-utils": "3.3.1", "mini-css-extract-plugin": "2.10.2", - "open": "11.0.0", + "open": "11.0.1", "ora": "9.4.1", "picomatch": "4.0.5", "piscina": "5.3.0", diff --git a/packages/angular_devkit/schematics/package.json b/packages/angular_devkit/schematics/package.json index 44d07e4739fc..708306b0e7b1 100644 --- a/packages/angular_devkit/schematics/package.json +++ b/packages/angular_devkit/schematics/package.json @@ -15,7 +15,7 @@ "dependencies": { "@angular-devkit/core": "workspace:0.0.0-PLACEHOLDER", "jsonc-parser": "3.3.1", - "magic-string": "1.1.1", + "magic-string": "1.2.1", "ora": "9.4.1", "rxjs": "7.8.2" } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index d578d33bc711..d9786f869c8c 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -230,8 +230,8 @@ importers: specifier: ~5.1.0 version: 5.1.0(karma@6.4.4(bufferutil@4.1.0)(debug@4.4.3(supports-color@11.0.0))(supports-color@11.0.0)(utf-8-validate@6.0.6)) karma-jasmine-html-reporter: - specifier: ~2.2.0 - version: 2.2.0(jasmine-core@6.3.0)(karma-jasmine@5.1.0(karma@6.4.4(bufferutil@4.1.0)(debug@4.4.3(supports-color@11.0.0))(supports-color@11.0.0)(utf-8-validate@6.0.6)))(karma@6.4.4(bufferutil@4.1.0)(debug@4.4.3(supports-color@11.0.0))(supports-color@11.0.0)(utf-8-validate@6.0.6)) + specifier: ~2.3.0 + version: 2.3.0(jasmine-core@6.3.0)(karma-jasmine@5.1.0(karma@6.4.4(bufferutil@4.1.0)(debug@4.4.3(supports-color@11.0.0))(supports-color@11.0.0)(utf-8-validate@6.0.6)))(karma@6.4.4(bufferutil@4.1.0)(debug@4.4.3(supports-color@11.0.0))(supports-color@11.0.0)(utf-8-validate@6.0.6)) karma-source-map-support: specifier: 1.4.0 version: 1.4.0 @@ -239,14 +239,14 @@ importers: specifier: ^4.17.21 version: 4.18.1 magic-string: - specifier: 1.1.1 - version: 1.1.1 + specifier: 1.2.1 + version: 1.2.1 prettier: specifier: ^3.0.0 version: 3.9.6 puppeteer: - specifier: 25.6.0 - version: 25.6.0(bufferutil@4.1.0)(utf-8-validate@6.0.6) + specifier: 25.8.0 + version: 25.8.0(bufferutil@4.1.0)(utf-8-validate@6.0.6) quicktype-core: specifier: 26.0.0 version: 26.0.0 @@ -278,8 +278,8 @@ importers: specifier: ^1.10.0 version: 1.10.0 verdaccio: - specifier: 6.9.2 - version: 6.9.2(encoding@0.1.13)(supports-color@11.0.0) + specifier: 6.10.0 + version: 6.10.0(encoding@0.1.13)(supports-color@11.0.0) verdaccio-auth-memory: specifier: ^13.0.0 version: 13.1.1(supports-color@11.0.0) @@ -302,8 +302,8 @@ importers: specifier: workspace:* version: link:../../../packages/angular/ssr '@vitest/coverage-v8': - specifier: 4.1.10 - version: 4.1.10(vitest@4.1.10) + specifier: 4.1.11 + version: 4.1.11(vitest@4.1.11) browser-sync: specifier: 3.0.4 version: 3.0.4(bufferutil@4.1.0)(debug@4.4.3(supports-color@11.0.0))(supports-color@11.0.0)(utf-8-validate@6.0.6) @@ -320,8 +320,8 @@ importers: specifier: 7.8.2 version: 7.8.2 vitest: - specifier: 4.1.10 - version: 4.1.10(@opentelemetry/api@1.9.1)(@types/node@22.20.1)(@vitest/coverage-v8@4.1.10)(esbuild@0.28.2)(jiti@2.7.0)(jsdom@30.0.1)(less@4.8.1(supports-color@11.0.0))(sass@1.102.0)(terser@5.50.0)(tsx@4.23.12)(yaml@2.9.0) + specifier: 4.1.11 + version: 4.1.11(@opentelemetry/api@1.9.1)(@types/node@22.20.1)(@vitest/coverage-v8@4.1.11)(esbuild@0.28.2)(jiti@2.7.0)(jsdom@30.0.1)(less@4.9.0(supports-color@11.0.0))(sass@1.102.0)(terser@5.50.0)(tsx@4.23.12)(yaml@2.9.0) packages/angular/build: dependencies: @@ -342,7 +342,7 @@ importers: version: 2.6.0 '@vitejs/plugin-basic-ssl': specifier: 2.3.0 - version: 2.3.0(vite@8.2.1(@types/node@22.20.1)(esbuild@0.28.2)(jiti@2.7.0)(less@4.8.1(supports-color@11.0.0))(sass@1.102.0)(terser@5.50.0)(tsx@4.23.12)(yaml@2.9.0)) + version: 2.3.0(vite@8.2.1(@types/node@22.20.1)(esbuild@0.28.2)(jiti@2.7.0)(less@4.9.0(supports-color@11.0.0))(sass@1.102.0)(terser@5.50.0)(tsx@4.23.12)(yaml@2.9.0)) beasties: specifier: 0.4.3 version: 0.4.3 @@ -365,14 +365,14 @@ importers: specifier: 11.0.0 version: 11.0.0 magic-string: - specifier: 1.1.1 - version: 1.1.1 + specifier: 1.2.1 + version: 1.2.1 mrmime: specifier: 2.0.1 version: 2.0.1 oxc-parser: - specifier: 0.144.0 - version: 0.144.0 + specifier: 0.145.0 + version: 0.145.0 parse5-html-rewriting-stream: specifier: 8.0.1 version: 8.0.1 @@ -399,7 +399,7 @@ importers: version: 0.2.17 vite: specifier: 8.2.1 - version: 8.2.1(@types/node@22.20.1)(esbuild@0.28.2)(jiti@2.7.0)(less@4.8.1(supports-color@11.0.0))(sass@1.102.0)(terser@5.50.0)(tsx@4.23.12)(yaml@2.9.0) + version: 8.2.1(@types/node@22.20.1)(esbuild@0.28.2)(jiti@2.7.0)(less@4.9.0(supports-color@11.0.0))(sass@1.102.0)(terser@5.50.0)(tsx@4.23.12)(yaml@2.9.0) xxhash-wasm: specifier: 1.1.0 version: 1.1.0 @@ -411,8 +411,8 @@ importers: specifier: workspace:* version: link:../ssr '@oxc-project/types': - specifier: 0.144.0 - version: 0.144.0 + specifier: 0.145.0 + version: 0.145.0 istanbul-lib-instrument: specifier: 6.0.3 version: 6.0.3(supports-color@11.0.0) @@ -420,8 +420,8 @@ importers: specifier: 30.0.1 version: 30.0.1 less: - specifier: 4.8.1 - version: 4.8.1(supports-color@11.0.0) + specifier: 4.9.0 + version: 4.9.0(supports-color@11.0.0) ng-packagr: specifier: 22.2.0-next.3 version: 22.2.0-next.3(@angular/compiler-cli@22.2.0-next.2(@angular/compiler@22.2.0-next.2)(typescript@6.0.3))(supports-color@11.0.0)(tslib@2.8.1)(typescript@6.0.3) @@ -435,8 +435,8 @@ importers: specifier: 7.8.2 version: 7.8.2 vitest: - specifier: 4.1.10 - version: 4.1.10(@opentelemetry/api@1.9.1)(@types/node@22.20.1)(@vitest/coverage-v8@4.1.10)(esbuild@0.28.2)(jiti@2.7.0)(jsdom@30.0.1)(less@4.8.1(supports-color@11.0.0))(sass@1.102.0)(terser@5.50.0)(tsx@4.23.12)(yaml@2.9.0) + specifier: 4.1.11 + version: 4.1.11(@opentelemetry/api@1.9.1)(@types/node@22.20.1)(@vitest/coverage-v8@4.1.11)(esbuild@0.28.2)(jiti@2.7.0)(jsdom@30.0.1)(less@4.9.0(supports-color@11.0.0))(sass@1.102.0)(terser@5.50.0)(tsx@4.23.12)(yaml@2.9.0) optionalDependencies: lmdb: specifier: 3.5.6 @@ -626,11 +626,11 @@ importers: specifier: 1.4.0 version: 1.4.0 less: - specifier: 4.8.1 - version: 4.8.1(supports-color@11.0.0) + specifier: 4.9.0 + version: 4.9.0(supports-color@11.0.0) less-loader: specifier: 13.0.0 - version: 13.0.0(less@4.8.1(supports-color@11.0.0))(webpack@5.109.2(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.26)(uglify-js@3.19.3)) + version: 13.0.0(less@4.9.0(supports-color@11.0.0))(webpack@5.109.2(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.26)(uglify-js@3.19.3)) license-webpack-plugin: specifier: 4.0.2 version: 4.0.2(webpack@5.109.2(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.26)(uglify-js@3.19.3)) @@ -641,8 +641,8 @@ importers: specifier: 2.10.2 version: 2.10.2(webpack@5.109.2(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.26)(uglify-js@3.19.3)) open: - specifier: 11.0.0 - version: 11.0.0 + specifier: 11.0.1 + version: 11.0.1 ora: specifier: 9.4.1 version: 9.4.1 @@ -777,8 +777,8 @@ importers: specifier: 3.3.1 version: 3.3.1 magic-string: - specifier: 1.1.1 - version: 1.1.1 + specifier: 1.2.1 + version: 1.2.1 ora: specifier: 9.4.1 version: 9.4.1 @@ -2790,124 +2790,124 @@ packages: resolution: {integrity: sha512-eSYWTm620tTk45EKSedaUL8MFYI8hW164hIXsgIHyxu3VobUB3fFCu5t0hQby6OoWRPsG1KkKUG2M5UadiLiVg==} engines: {node: '>=14'} - '@oxc-parser/binding-android-arm-eabi@0.144.0': - resolution: {integrity: sha512-IaoGBEp/huvja99PxI/b72TbKFzA/UzxxAka7f233dc/Tg/rRTX9Qn8IquFLWwWf4IddN/5TaJ8S4Subbjq7wQ==} + '@oxc-parser/binding-android-arm-eabi@0.145.0': + resolution: {integrity: sha512-3CBAqOv61gR/n/t13hr681uFHYm0dQu3bbsEJtsMWYtLCQ8lSYjuJCIlroD4fbI0wz44jpjw3N+L7CwBCzYHyg==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm] os: [android] - '@oxc-parser/binding-android-arm64@0.144.0': - resolution: {integrity: sha512-u6fJu8XQXP99+9pYO3jq7F1D7V9fyFuDBShYFlr+gY+GcJzhveeN/zoMfuXxX6XBquJO0kjqKd7BjhJ7pClWXQ==} + '@oxc-parser/binding-android-arm64@0.145.0': + resolution: {integrity: sha512-VOinEGxVMIWI+67MJw+MKmaLDC6X3D4dNDLKJX4fidJ7sO0hsevYHaKBCqLozbg9Ny+1yb25yagJMQAw1U/jQA==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [android] - '@oxc-parser/binding-darwin-arm64@0.144.0': - resolution: {integrity: sha512-o9xGSmMQcboJLjwI+acFf6xa7nYdp0/nRFE8ry4Xrt8OviQ9ITFDBUkAXVJMOLchSV9Pu981GxJuW0mt4i6vQQ==} + '@oxc-parser/binding-darwin-arm64@0.145.0': + resolution: {integrity: sha512-es9sOpZM3cdbXqqLHZ+5PF+6AyKnd2Z6gVJGvmXraX9jGz249Sb1V/Lf42UEuQPZsjp5iXMntxO4fWqHMJ2nRg==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [darwin] - '@oxc-parser/binding-darwin-x64@0.144.0': - resolution: {integrity: sha512-2yNm4tX++W3KLbyziVhs5alSb74a3C1uNDu/1P/AQj1ux8yZYuvbCAeJCCrGkr8J18ZmnBAzDthdTZBEAEb71w==} + '@oxc-parser/binding-darwin-x64@0.145.0': + resolution: {integrity: sha512-grIPJYT5aTB3IUp7iZz2grzzUQaTnnwIrb81tMWdFTzkCQQcnz0mWrXXEMWxSWidYp4a+DzI7ApLBEDuw2Xyhw==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [darwin] - '@oxc-parser/binding-freebsd-x64@0.144.0': - resolution: {integrity: sha512-TG4CjY1OjynplkF9nAQ9m9zboPJksnbAF+U/9xQGSXyIt+5sQRitwfQrUgjrG17/up9G8k/boNjLD2zp4xq1Kw==} + '@oxc-parser/binding-freebsd-x64@0.145.0': + resolution: {integrity: sha512-NimvYhXzF5QNIN42C1W339UNHYr5ESub4Th362q2u9NkSiGZ2X9exUshdmyRbIVIlZzo+29HIivhebkWY5g0SQ==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [freebsd] - '@oxc-parser/binding-linux-arm-gnueabihf@0.144.0': - resolution: {integrity: sha512-i0T9NagVmqc+rbSyBr5mDKj7TCMIBRrSteQlQJt1WhWIH/sZeOP9GB09H9w98YdinuZkDIPmO7Fz0jDC7bMvSA==} + '@oxc-parser/binding-linux-arm-gnueabihf@0.145.0': + resolution: {integrity: sha512-697j9HvY/HwfhPESnNop7qUBjyoJKl8Q9YrHQgcGhFcoQbcelxAgVSRVv5b3a9lndvjQ6KcV0oFrKzXqLYA6xg==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm] os: [linux] - '@oxc-parser/binding-linux-arm-musleabihf@0.144.0': - resolution: {integrity: sha512-YUsEqM3WMS3mOON+TFf7RzS0QthzEifx7tpUQu0GSF2MsT+D6t154ZBs6WhWaCZNl0GuVDEvndCyEAUBHzSHGw==} + '@oxc-parser/binding-linux-arm-musleabihf@0.145.0': + resolution: {integrity: sha512-gnKpdjlnPet71TY18hLs29f0lQmt5dFig6w/hEhaUljGJSTri8n5In6CTgHnF2UFG9oiBXfqnf9pHUUrJpO5cQ==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm] os: [linux] - '@oxc-parser/binding-linux-arm64-gnu@0.144.0': - resolution: {integrity: sha512-LlWH4kt+IET3qIAe0e0IFLNlQ3CVUAfN//UFsA6N0/FghMh/FBk1e+wzvgG+t8WSnXkvf8B1TovquS2EJras9g==} + '@oxc-parser/binding-linux-arm64-gnu@0.145.0': + resolution: {integrity: sha512-2NCBH6l3J2k4YQIYZzcGNZq7J0+/kub//5+cXWTdhtc6UW47mGHpogVm7fwPhHU+Bw7iw9SBm5V0qlGFj6ZY7w==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [linux] libc: [glibc] - '@oxc-parser/binding-linux-arm64-musl@0.144.0': - resolution: {integrity: sha512-ajXbXIWBWUD4U3IQxr2p6DiXwD7GPHEBLa+JteKhIfvLmBEBdTjO28lP+5r3AF2qal8cxLERfTnGs64Z22ZuXw==} + '@oxc-parser/binding-linux-arm64-musl@0.145.0': + resolution: {integrity: sha512-ih5NUVKrWOZN54DLGhP0YyCF2NjXl7stGiK73+xI4baFv2fL7n3K5BrUAjVDi/w73kCnwS3pJ/V/X8n027n/Yw==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [linux] libc: [musl] - '@oxc-parser/binding-linux-ppc64-gnu@0.144.0': - resolution: {integrity: sha512-/+sDzL/4cWEwdqenKo/DX3gkkxu7H7ytFAtealDey/Gd59yPWn64obVk6wXKVjVfXMciUUUTySxZG9AIMX3RNQ==} + '@oxc-parser/binding-linux-ppc64-gnu@0.145.0': + resolution: {integrity: sha512-pLOsK77bB2T0Qu+slW/kRI3zLfBAnbbfubGlzN5GROMbrzt8axAtx+0MZcGRuRX7LNDYzqM+ZeBLQbfYUg4rzQ==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [ppc64] os: [linux] libc: [glibc] - '@oxc-parser/binding-linux-riscv64-gnu@0.144.0': - resolution: {integrity: sha512-dMVhPBbrd8y6aeLd7Ihn9OZhKO8QgCQVtLBTRgbmf4lKrcR61SpaQRJPJuocTc/Cn5SJMm+alHYPnzkbOGM7Dg==} + '@oxc-parser/binding-linux-riscv64-gnu@0.145.0': + resolution: {integrity: sha512-dbS9FC4ziuyNNyFErVM6+bREi2+CbqUA7/xrOajcgnNUeX9QTsleQbOUJ2P6lCoT483H0ikg+gND4unNrygS9g==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [riscv64] os: [linux] libc: [glibc] - '@oxc-parser/binding-linux-riscv64-musl@0.144.0': - resolution: {integrity: sha512-jQ8O0+b6J2IhJgm0DnqEJq8hG9OocmF1b4TBWCk08CRWqTmLZj/+lYs7w3OA60nb2SiqOmthQyJPacrCi7y+oQ==} + '@oxc-parser/binding-linux-riscv64-musl@0.145.0': + resolution: {integrity: sha512-GtmdBGsNi+yCvxiJ4Bnrpo8+azePTedFqghDRtvKucyAGXZhqmuPRbqTHacfTGo1ukgFFqrzNlFxtXUnYjUjPA==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [riscv64] os: [linux] libc: [musl] - '@oxc-parser/binding-linux-s390x-gnu@0.144.0': - resolution: {integrity: sha512-/mZxZtcGrzuvqPLPV7gjavbROYs/dHy6+yQ2Sl/2to/+qoC/v6CcruGFnfQPzQbXXTYReXJzLb5QY9KmgCbJOg==} + '@oxc-parser/binding-linux-s390x-gnu@0.145.0': + resolution: {integrity: sha512-U5uJHvwWbDV+DvVugJRA/JkKTmikONTBDtDLFNFQTfEQOBVMs6itFiBGM3IxFIJr0/uVlIKMTDQSireOQLXvpg==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [s390x] os: [linux] libc: [glibc] - '@oxc-parser/binding-linux-x64-gnu@0.144.0': - resolution: {integrity: sha512-/caRGFHcarHZlBrucBwQwBbzqhD+UfZZ/r7soocS0/mp6/5KTq+1Zl/OQx5lFLcN+GpUPYszbrvQU9MCFLEzJg==} + '@oxc-parser/binding-linux-x64-gnu@0.145.0': + resolution: {integrity: sha512-hz3a08R2fWvj/oGmNeQ9Us9AUfyYLagbNMh7nwdBbL/JAK88gu8i3hZg/Zv5xU4EdrFjiFXGmadLOFcZk/AlvA==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [linux] libc: [glibc] - '@oxc-parser/binding-linux-x64-musl@0.144.0': - resolution: {integrity: sha512-qFtwAo6BWuWDjh57QDdZdYi746GW0mIeoZSGK2jJqlxIjo389Y/7lrriTOI+ou7tTvusOrSYGQZ+e+nDswt2vQ==} + '@oxc-parser/binding-linux-x64-musl@0.145.0': + resolution: {integrity: sha512-im2ckBQcAnIN0qiGUOPuftIqmehwXSRx9q8Bb8gaFvjxoLI1lmW7bUABcr0YixVUae0j23+qiy/3g8DYr0Iqpg==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [linux] libc: [musl] - '@oxc-parser/binding-openharmony-arm64@0.144.0': - resolution: {integrity: sha512-n+NgMGWWEYpH+rlkMhDvLR2k8vJDHQp3j8SoS86IS6J0hc4kuDaiYAAvu9dF86xjeGYy+h9WLj12sylmBJV9sg==} + '@oxc-parser/binding-openharmony-arm64@0.145.0': + resolution: {integrity: sha512-Ban4OInSMDkvzkaoROeg3AJVrYrlqjDA/GfJuLg0QL0MCVixj1WBy5lELiBxvHSTHR9KDo/0MzKZeHWeZ9cW0w==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [openharmony] - '@oxc-parser/binding-win32-arm64-msvc@0.144.0': - resolution: {integrity: sha512-fShxpJiCBOdG4+jBAvahTTFUDI5djXc/+IPC1ldeC8LbyCW0h9m/7oP8DRZWI7WT2Ahv8sHtZz4ugECylCFpTA==} + '@oxc-parser/binding-win32-arm64-msvc@0.145.0': + resolution: {integrity: sha512-mbTsMQKGpbdhjtaJUwhLyjoWRb0iIyIWuaguYQbS7IYsSo6KeRJQ3pb2P/9ZYYoQB9pV1oY/nD0SXTGFcfgIOA==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [win32] - '@oxc-parser/binding-win32-ia32-msvc@0.144.0': - resolution: {integrity: sha512-vFrYV+C3lJhIiSdNhdkZHnZ0YIClgTSluXaPMYjlGslVPD+uJg6K1s2xNL/X/gdBcy9IIbjbp0vNBwQhdMMdkw==} + '@oxc-parser/binding-win32-ia32-msvc@0.145.0': + resolution: {integrity: sha512-syaw++GhlFT4aJ9yaYgNKxUVAfE4cnP5Wk3iy9d3lLNwzWmmgXTb6sqQrcwVUq3Tv4RXAOZvr33bVe7C28G2Vg==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [ia32] os: [win32] - '@oxc-parser/binding-win32-x64-msvc@0.144.0': - resolution: {integrity: sha512-0ASbKSwdeihMekyy7y4jC0CwW3XBDZk5Sw64m/W7IReVQHaduqLYssF9KCJA2oHG9oldnl/1CMxqCoImXfqQkA==} + '@oxc-parser/binding-win32-x64-msvc@0.145.0': + resolution: {integrity: sha512-dIZyXCxsOLILtDYeUGtiHN8GqgaT3J5FsuGI57YqWJg7EDZWBT+oFH2N+AjYMasupru3zy5K3ttCxxAF2Cscjg==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [win32] @@ -2915,6 +2915,9 @@ packages: '@oxc-project/types@0.144.0': resolution: {integrity: sha512-nuhZIOLuI6TFQ32I/WnUx+SCPY7SdSKwgnFHydAuoS1+Z4BRcaP+RRJmGzl9lw+0OFF7UmaESf7KQRXaNLHypg==} + '@oxc-project/types@0.145.0': + resolution: {integrity: sha512-/UDI/xghp0wUJfvBu0fXIkn5nrDZCdesXo++ElC8UpDjzdFhB13k8XPXyMaSihaWPwgvdQXiJjRshVkaPEtaIQ==} + '@parcel/watcher-android-arm64@2.6.0': resolution: {integrity: sha512-trgpLSCKRC/huFjXX/Smh+0sWe4+YtKfktIToiMl59ghz7z+qkH6kMvNnUbLyRs9N11t8l4svSCs1+5B3rOAhA==} engines: {node: '>= 10.0.0'} @@ -3088,8 +3091,8 @@ packages: '@protobufjs/utf8@1.1.2': resolution: {integrity: sha512-b1UQwcEZ4yCnMCD8DAL1VlbvBJE9/IX4FTIp7BG1xYpf29SLazLSrqUkj4w7Y5y7cCVP6E5tcqqcI0xemPkHug==} - '@puppeteer/browsers@3.2.0': - resolution: {integrity: sha512-LlBrE8oqGfU7b1Nk2d5Q1SbuPhZxTj0cJEMDPEws28OjNMELlflekmPPuf4FnK03x0ZRjKaYwJElUcKK4kyqJA==} + '@puppeteer/browsers@3.2.1': + resolution: {integrity: sha512-KDz+3qDRdBAlRlMjmKyj6dEs33YHTk/xRHEENSXq6TNnhgoU15ruSHtEBeVF6OZ9tBDY55Se4P0nFMNsipzU9A==} engines: {node: '>=22.12.0'} hasBin: true peerDependencies: @@ -3656,79 +3659,83 @@ packages: resolution: {integrity: sha512-fkv8dHRDqfGtTHuJeebdrQ7cX6Ad4WAS00rgHh9UGvMycF1mjBfsxry1XsLIFhWZ6Judlh6UdzK+TYlbpCXgnA==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@verdaccio/auth@8.1.1': - resolution: {integrity: sha512-mIhE2uFWrUhknk1/bdBcZJGHcRrV13lrIBk0n8Hosdh5A+Cbqh3ctdmSyTske93eahBZFHzEnwSo0Zcg3mnK+A==} + '@verdaccio/auth@8.1.2': + resolution: {integrity: sha512-ts5k0Z7kkxOKTVg9U8gVIFxmvytqIEl/eU2zTD/w0CrBT3vkEzvwQ9K0kHDV4VR1dCWhX1nqJtIlqtWewZQr8A==} engines: {node: '>=22'} - '@verdaccio/config@8.2.1': - resolution: {integrity: sha512-6mT3OY0uS0FQ6QuxBZagm+iomj2M7/cN2GveN/V4AvigmSwDLcoVl7xjYzaW35E6jmYY+7SRUaJTjWO9XQmK9A==} + '@verdaccio/config@8.2.2': + resolution: {integrity: sha512-1rLGFg/qTRgHVq1llx5fW+FtYijV4MeXBRc82aSy2TUQ4fy+4yEckI1+GCAm7fIvl5+YOzW9PcABtZOeEkeu7Q==} engines: {node: '>=22'} '@verdaccio/core@8.2.1': resolution: {integrity: sha512-fcK9lGTXSxrNncbShtt5sCfFPiP2GdsQmhXdeu4HDIH9GU8cLF5Jj/QBpLjMuz+lB+qHg6QBFlUKS0pnio20jA==} engines: {node: '>=22'} + '@verdaccio/core@8.2.2': + resolution: {integrity: sha512-BSCCR5cFkepjL3HnosKUi6aRezwgHu1FihFtes63yxIiDXkMclVi5IekTH6SCeW/7MO1Uyp58kh1updbB6VW4w==} + engines: {node: '>=22'} + '@verdaccio/file-locking@13.1.0': resolution: {integrity: sha512-rGFfdyCZdgpbkROJJfjOA01R5BFtzrnDAhNIkxxc/yWZ6Cir+MRHpEbN2weOEPAwYDke9Wms4JKhpsStu+iV8Q==} engines: {node: '>=22'} - '@verdaccio/hooks@8.1.2': - resolution: {integrity: sha512-i8Ppd1ZycpT72aZ/FwrHXHvDFVv/rZ4jQeru7p0MNRZoaEqZX9yt6nuwMiYAOOyS0N32RIH8R0zlpqet7oMXFA==} + '@verdaccio/hooks@8.1.3': + resolution: {integrity: sha512-aCdLrzZAZB2zLmqImZQsQOK+7gIJsPv0cy4O34SenOJJ2kWESbacQVwcDGjv+EWIjbQy0EPCjgjqwryIkvdy8g==} engines: {node: '>=22'} - '@verdaccio/loaders@8.1.1': - resolution: {integrity: sha512-lj1RUBzmrQL0vOIADPXw6dnrHohJljI6w6hJCzWOGrc8vP8j1InQS9QhTEewtfOoruP44fjVNEkWe97nK/IGnQ==} + '@verdaccio/loaders@8.1.2': + resolution: {integrity: sha512-3NrHUaspgJUmTbKF4jQeHOo22zfa7XsYL5MD+PbviLg42OxERHXiuLBIBf2FE9KU3dhcuB+5WZqOLfS2U7WRSA==} engines: {node: '>=22'} - '@verdaccio/local-storage-legacy@11.4.1': - resolution: {integrity: sha512-DZzUIpFbYa10WMKm05eQb4KKReoyMsQknKjaP7O9T9UfmhWMQ9qOBEwkHdUpNe0z3Bq9je4MoLL5yrTs1420TA==} + '@verdaccio/local-storage-legacy@11.4.2': + resolution: {integrity: sha512-ay/Hs6itET+8YKHDUds7UWlyTpLMDmsmtKCKF67obF2fwPd9RRoiLFWiVyY0H5gsqSiEGOpOMw5JlFRYnf+row==} engines: {node: '>=22'} - '@verdaccio/logger-commons@8.1.1': - resolution: {integrity: sha512-TCf+R3WOVxFKqvCmaxcZNchmz8GyFrIoIeO3nWL0gpTbmrKhWvCWXI+iYZkAJQhqBE6CMzisQZ5/UDzl+HQHnQ==} + '@verdaccio/logger-commons@8.1.2': + resolution: {integrity: sha512-vw6QuRS2c6NmsJvjfZjHik8bTyqj9i2kAlJHSoDwPAlQ/njyfjmI9Sa+yoz5fKJX4aGA/LoIqHSYEW2Sf+5rjw==} engines: {node: '>=22'} '@verdaccio/logger-prettify@8.1.0': resolution: {integrity: sha512-Mriivx1LPx8/8ux0MlNoj/FtxQiQmf5BG2casfWEf9R7jzBDAUCqQJUR4s0PaV2Mlc9cdHcETOucx3RGPuWHeQ==} engines: {node: '>=22'} - '@verdaccio/logger@8.1.1': - resolution: {integrity: sha512-YOcM1niOSlnlCN7XuO2kLN4WE7hlONsuCUWGvQsld/niDFar24JaZ/+hR+WntERu5g39iPLBAzYMeXmIOIP0sg==} + '@verdaccio/logger@8.1.2': + resolution: {integrity: sha512-9FDPtTNH4b1ZBW2jXGk+5ud+omkKZiBRAUGumDX99R3+vW6HGqVjo0DjwmBP0sGxseLdh/q2S7A2Z91EvUpgYw==} engines: {node: '>=22'} - '@verdaccio/middleware@8.1.1': - resolution: {integrity: sha512-S2gK6F2h4KWJUpGWd7pyxkrbTuTWSSTqtXI55wPl5JIPzvlcS2Yls8ye3upmGb9eJuMzWkkwAG+61Vo6fdwLzA==} + '@verdaccio/middleware@8.1.2': + resolution: {integrity: sha512-JIMDFIkEVP7py9QxW7vBy1N2/PUMESE0SJ3tZGHtEVzUCCsUmpby7vuEDJ3STk6yzkqtqk2lTWYAcUbqwI/7sQ==} engines: {node: '>=22'} - '@verdaccio/package-filter@13.1.1': - resolution: {integrity: sha512-bFOlWOnTbi7/6p0mpqLLrceNoi+4XCNpgWtnhYDMbh9i5aenxRxE4jKl+bGIbrNzOzQSNJy3zVnOGdoxYMvpjg==} + '@verdaccio/package-filter@13.2.0': + resolution: {integrity: sha512-RrauvQMklcJMiV9iuklhBj7+K+R8w99nzlQbLoY/GqAvGdLZ3VRDWR3e/81Fcdy0fyL7E5NI7i8aA9iNZsm/LA==} engines: {node: '>=22'} '@verdaccio/search-indexer@8.1.0': resolution: {integrity: sha512-N0vHWnSCZVEU3ffvbH/g4cRvGkXO+FJQcNggdY1wxT8LP7K6NJ0F6aq7jSF3ebW5IokdQMJuqWTNx18h8dgrsg==} engines: {node: '>=22'} - '@verdaccio/signature@8.1.1': - resolution: {integrity: sha512-N7WpRriTzXjlWKNX9FpcHMEi+vysRXV8r02ymKfR95yVLaFiWyl8mu7X78qCulKjmAba2C51MZLrlRosED7rEw==} + '@verdaccio/signature@8.1.2': + resolution: {integrity: sha512-aa4FUz7f4Bj241PFZnI69ofZIcgJg1AHfkB4D8GG49rgwahpuEO9E81I0m46bqpe2gWAGib57KYkb9NOYCg/ig==} engines: {node: '>=22'} '@verdaccio/streams@10.3.0': resolution: {integrity: sha512-MARQAzAgS42GIawkrBVMTV81vRf2yqZmwonnQb9FWeGj+tsMcgpT/f2fWMQm/UubLpWxBBH6oCkmhFd29R2xGA==} engines: {node: '>=22', npm: '>=5'} - '@verdaccio/tarball@13.1.1': - resolution: {integrity: sha512-p8S7HcS7z8jq5+7eKW5y0mD3M1dcyhi86f+23mA0Re91ursyggrU7l5/5dFdKQfN3LNdQGaj/FC5UKmRtU6dlw==} + '@verdaccio/tarball@13.1.2': + resolution: {integrity: sha512-0xk52gcW776safIt+FLUTuv2wDb0zd4f4DxOYMMW4+5CRwa6QiiolLz4ImBWrC4O4WnZpbQ0mzLDyFaLd48LkQ==} engines: {node: '>=22'} - '@verdaccio/ui-theme@9.0.0-next-9.23': - resolution: {integrity: sha512-l4tUIT+uZ+t/YTG5Tqm7h/WF+J0KeE7duL9VHc7kjrax4TV4PdoBwlTEKWgo8MbGLLijtpwV52MIMmzZQhGhGg==} + '@verdaccio/ui-theme@9.0.0-next-9.26': + resolution: {integrity: sha512-qF5q16SOhmQhYWZoq+q5QW3yxzEQ7knSXW6N7hJKjFf/5FD+RcTHMALXH08iGxk6fHuuNKUq6KR9uRkHUNF9Yg==} - '@verdaccio/url@13.1.1': - resolution: {integrity: sha512-Vlq6ilfrraBzRIcfrgYHveKIi5j6Rpi33D6eTYVHMMXaEBqo3cId+hfOa+S1WH2eLSAIBt4tKiPcwi5Z4HEM/Q==} + '@verdaccio/url@13.1.2': + resolution: {integrity: sha512-AvaMN3BJnHk9zDDL5oT+VOAIoUoXqoOEWVe3hsfa8T/IDLcl6nyYJd75Gt4U0huOXLdCpOwjVUl4zpxOvvThZg==} engines: {node: '>=22'} - '@verdaccio/utils@8.2.1': - resolution: {integrity: sha512-Yen0yN7iraA3AGyAEPonC4k7pMWQuFYAhjMW+DXa57Q1zoYXq5Lk1cXwdNl6irF7EgKP+5Sz6bMUxQIWQELngQ==} + '@verdaccio/utils@8.2.2': + resolution: {integrity: sha512-RWS2h1yXeaF7txXD7jK/v1aecMrTCGFGRMDH3qjcvM0FMXYs5rleGo/MooiXHuOGFC4D7xNqt3hERXQweNlf2Q==} engines: {node: '>=22'} '@vitejs/plugin-basic-ssl@2.3.0': @@ -3737,20 +3744,20 @@ packages: peerDependencies: vite: ^6.0.0 || ^7.0.0 || ^8.0.0 - '@vitest/coverage-v8@4.1.10': - resolution: {integrity: sha512-IM49HmthevbgAO4anp1hwtoT9wYe59w0LR00gr+eagHE+ZJ5lK4sLPeO0ubgoJcwLk6dehU3R24N+FbEEKDc8g==} + '@vitest/coverage-v8@4.1.11': + resolution: {integrity: sha512-8MVGEFnJIcdGjcbfKmeq8z0pZHH0JlVtoVZH9Q/qwUp6wyFnEJUBMrw9DCaj+ra3vShGmhavjalMIhPNxZAUcw==} peerDependencies: - '@vitest/browser': 4.1.10 - vitest: 4.1.10 + '@vitest/browser': 4.1.11 + vitest: 4.1.11 peerDependenciesMeta: '@vitest/browser': optional: true - '@vitest/expect@4.1.10': - resolution: {integrity: sha512-YsCn+qAk1GWjQOWFEsEcL2gNQ0zmVmQu3T03qP6UyjhtmdtwtbuI+DASn/7iQB3HGTXkdBwGddzxPlmiql5vlA==} + '@vitest/expect@4.1.11': + resolution: {integrity: sha512-VX2x5vNJXET47KAFzwERI+KRMtTTCSWTfSMKsW7JsUsXV4psq++e3DvZpuTDOpHcxytiDs6p2nhVb2tVDiiUYw==} - '@vitest/mocker@4.1.10': - resolution: {integrity: sha512-v0xaezt+DKEmKfaxg133ldzADrwLGd7Ze1MfQQTYfvs8OqZIwbxyxaYURivwV7sWy5fqn3rH5uOrSp07bp44Ow==} + '@vitest/mocker@4.1.11': + resolution: {integrity: sha512-2XJVD55d1o5AZous5CCGKS74g/riOj9odEt2bQpCVZeblHyHdnMeFl4jl0XjU21stf4mbjUkew2eXQZt65g5CQ==} peerDependencies: msw: ^2.4.9 vite: ^6.0.0 || ^7.0.0 || ^8.0.0 @@ -3760,20 +3767,20 @@ packages: vite: optional: true - '@vitest/pretty-format@4.1.10': - resolution: {integrity: sha512-W1HsjSH4MXQ9YfmmhLAoIYf1HRfekQCGngeIgcei6MP5QQGWUe0gkopdZQaVCFO+JDJMrAJGwa5pRpNpvy4P8Q==} + '@vitest/pretty-format@4.1.11': + resolution: {integrity: sha512-yiZzPbGTS9Sr/JpFl8zHrcIkAofNbFV6k21vIgQN/cY/oxZeXhJv5sc/MBJ5jFKWmWs+oJHw0UXLZjmf931+Vw==} - '@vitest/runner@4.1.10': - resolution: {integrity: sha512-IKI6kpIH+LmpROplyLwBBaCfMgOZOMsygVa6BARD6ahA04VRuJSa6OaVG7kRvSEMD870Vd91rSSw0eegtWyLGg==} + '@vitest/runner@4.1.11': + resolution: {integrity: sha512-LztvUgdwMNJMIkj3hQnnxiC2Xy1zNxq928W/xhjCLaNCzqTZOudjwbQf6v9IntZGPw132i2Lq2rgTRZHD3JHNw==} - '@vitest/snapshot@4.1.10': - resolution: {integrity: sha512-xRkfOT1qpTAi/Ti4Y1LtfRc3kEuqxGw59eN2jN9pRWMtS/XDevekhcFSqvQqjUNGksfjMJu3Y+oJ+4Ypn2OaJw==} + '@vitest/snapshot@4.1.11': + resolution: {integrity: sha512-pN7ikn1ON7h8ee4gIAp4AzyK+zBtJPzVbqOgu5LCEh4VaJVbPQcgYQYJIMGQPXVeJJq1fnfazis7a5pFNPahog==} - '@vitest/spy@4.1.10': - resolution: {integrity: sha512-PLf/Ugvoq5wO/b4rwYCR1h2PSIdXz7wnkQFMiUpLdtM7l6pqVFcQIBEHyT1+l+cj7mNwAfZHzqXqDyjvOuwbDw==} + '@vitest/spy@4.1.11': + resolution: {integrity: sha512-apNa/prQy2qCeywhnixOHPRCgGNhvg7T4Dapfl1GahLp/R+uhBm5cPyFoNVyqsNd2h1nJxL6BqqdIjiABL60YA==} - '@vitest/utils@4.1.10': - resolution: {integrity: sha512-fy9am/HWxbaGt/Sawrp90vt6Y6jQwf1RX77cz3uwoJwJVMli/e1IEwRPnMNJ7vKfPTwo0diXifkpPvwH9v7nGA==} + '@vitest/utils@4.1.11': + resolution: {integrity: sha512-zTCVGpyFsGWBhllOyKlTw/vnr6D9qxsfSDyfbyZmTyjHw5N/VuvzHpHoQjm2ZJzn4RJgx5w4r7V0er69CmLgPQ==} '@webassemblyjs/ast@1.14.1': resolution: {integrity: sha512-nuBEDgQfm1ccRp/8bCQrx1frohyufl4JlbMMZ4P1wpeOfDhF6FQkxZJ1b/e+PLwr6X1Nhw6OLme5usuBWYBvuQ==} @@ -4787,8 +4794,8 @@ packages: engines: {node: '>= 0.8.0'} hasBin: true - devtools-protocol@0.0.1653615: - resolution: {integrity: sha512-pGVkY3T/qXxAp2nFPodwYqOevk6ncNMSmvL8QfRCx5ZWGd6Vor7AFNmyaA8Zs6uJyP1QAfjuLandCgvSix1BNA==} + devtools-protocol@0.0.1666840: + resolution: {integrity: sha512-gCcO42XCHKEs7Ag0S7aGYsnJ7hlgrO3qderYqeiY0Eqk+0GFfuvT13IA0hHreJTa2KCdDVyGMeOhdMNmrrTjVg==} di@0.0.1: resolution: {integrity: sha512-uJaamHkagcZtHPqCIHZxnFrXlunQXgBOsZSUOWwFw31QJCAbyTBoHMW75YOTur5ZNx8pIeAKgf6GWIgaqqiLhA==} @@ -6047,10 +6054,10 @@ packages: resolution: {integrity: sha512-yj7hbequkQP2qOSb20GuNSIyE//PgJWHwC2IydLE6XRtsnaflv+/OSGNssPjobYUlhVVagy99TQpqUt3vAUG7A==} engines: {node: '>=10.0.0'} - karma-jasmine-html-reporter@2.2.0: - resolution: {integrity: sha512-J0laEC43Oy2RdR5V5R3bqmdo7yRIYySq6XHKbA+e5iSAgLjhR1oICLGeSREPlJXpeyNcdJf3J17YcdhD0mRssQ==} + karma-jasmine-html-reporter@2.3.0: + resolution: {integrity: sha512-iFDjVpcWHnupRoJfnjuAeNF68sAGk+7RfceCzm33HHYNV6OgBa6EC1nPgJUFM+tVDHLlQ5NhgcTKz7AbdrV3AQ==} peerDependencies: - jasmine-core: ^4.0.0 || ^5.0.0 || ^6.0.0 + jasmine-core: ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 karma: ^6.0.0 karma-jasmine: ^5.0.0 @@ -6094,8 +6101,8 @@ packages: webpack: optional: true - less@4.8.1: - resolution: {integrity: sha512-jQ3lRIo1aUtiWVYXZ7mk4+V4BjCGswF3IxTLJ+4RUta8ZiHh8lhkig2G8dya2eCcyR1dYUvzuV46EkJN8PSwww==} + less@4.9.0: + resolution: {integrity: sha512-umRhrCH7fCi8Uj2RcwKjJdvUORTjeWqkdKx0LbcZvjIwsAVsnIAGcxHaqowPeBFBjQuWOeC/bve0AlpFzF/+SQ==} engines: {node: '>=18'} hasBin: true @@ -6301,8 +6308,8 @@ packages: magic-string@0.30.21: resolution: {integrity: sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==} - magic-string@1.1.1: - resolution: {integrity: sha512-qFemKPzc3ttrYVaMmnSkGtGc5nE6Ncl4bj7c9IE6C9OUIRXjf6PzJ+UZ1xhVIjYc7dolHq3qKzpAJPZUbvNj+A==} + magic-string@1.2.1: + resolution: {integrity: sha512-vCfXkt3lIJha02CjPT1igeysyHVfCsEpIeD20O+X9aJ2hML3/kKx8E9Iv1FB+aMSAlDOEAtpRWzuooQCrYwdUg==} magicast@0.5.4: resolution: {integrity: sha512-llBEhWm1SacoRwgHUoQJYtwp4PBLF4faQi5TCpIGyGs9n4y5+juI0tDgyKIfpqxckRHaHzouUEph3THklWh03w==} @@ -6688,8 +6695,8 @@ packages: resolution: {integrity: sha512-VXJjc87FScF88uafS3JllDgvAm+c/Slfz06lorj2uAY34rlUu0Nt+v8wreiImcrgAjjIHp1rXpTDlLOGw29WwQ==} engines: {node: '>=18'} - open@11.0.0: - resolution: {integrity: sha512-smsWv2LzFjP03xmvFoJ331ss6h+jixfA4UUV/Bsiyuu4YJPfN+FIQGOIiv4w9/+MoHkfkJ22UIaQWRVFRfH6Vw==} + open@11.0.1: + resolution: {integrity: sha512-NzwMUB6C1D0+Kd+9iMS/H4k+Ck3cTX6Ckyfr/gAGlmvSE1LUQZnEZvWBi4PYmMwH/S5SMeTXnE+9uAz8uF+pWw==} engines: {node: '>=20'} opn@5.3.0: @@ -6714,8 +6721,8 @@ packages: resolution: {integrity: sha512-19YVAg7T+WTrxggPukVq7DjTv6+PJ867TmhCvBsYwmbFCsZd344rq2Ld1p0wo8f8Qrrhgp82c6FJRqdXWtSEhg==} engines: {node: '>= 0.4'} - oxc-parser@0.144.0: - resolution: {integrity: sha512-eacM4wMgGWXctHubY262yo+50E76qtQBqe+uK73YEV1IT3qP12Acbnf9Nc8t+agIAdnko9iVT4KF83/d0EjY5w==} + oxc-parser@0.145.0: + resolution: {integrity: sha512-zLMOUMlzFPqpgiQPTdSYBpJF1pQX1Ym2h+qb/BIT3KoMYf+cn87LDD0ifjcGcikUwKS2uQKH/y4n2t3dHS9bFQ==} engines: {node: ^20.19.0 || >=22.12.0} p-finally@1.0.0: @@ -6935,6 +6942,10 @@ packages: resolution: {integrity: sha512-dM0jVuXJPsDN6DvRpea484tCUaMiXWjuCn++HGTqUWzGDjv5tZkEZldAJ/UMlqRYGFrD/etByo4/xOuC/snX2A==} engines: {node: '>=20'} + powershell-utils@0.2.0: + resolution: {integrity: sha512-ZlsFlG7MtSFCoc5xreOvBAozCJ6Pf06opgJjh9ONEv418xpZSAzNjstD36C6+JwOnfSqOW/9uDkqKjezTdxZhw==} + engines: {node: '>=20'} + prelude-ls@1.2.1: resolution: {integrity: sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==} engines: {node: '>= 0.8.0'} @@ -7005,12 +7016,12 @@ packages: resolution: {integrity: sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==} engines: {node: '>=6'} - puppeteer-core@25.6.0: - resolution: {integrity: sha512-GJ67rjZdVQzZmD2Ab0cgttfQN9j387QYMv3t6MN3/4nmjursNt6M5Utj4/T/4y0AwNrSwJzjw6Q/zuWFEIizOg==} + puppeteer-core@25.8.0: + resolution: {integrity: sha512-LDOrawV8vfCVk+yLj2ozvajNP4Sv3OV9y3Tpiyy2g2Z+aQlbcozP6KJfI4iSBq7YQER+86ihEtPa5ioiZyWxMQ==} engines: {node: '>=22.12.0'} - puppeteer@25.6.0: - resolution: {integrity: sha512-TXUolDddU4AwISjOOrGk2AhJDpbM/ZDt2KvGIqz74EOk+8bKwXFo+acUvP1sQx3hUda7owOeNuuT1UnJT1o0qA==} + puppeteer@25.8.0: + resolution: {integrity: sha512-3gcUJ+Jfodb5zNa/lWLZukBUwYiRIwAc8WRICoqfi+ZYmNWqpsPFyanTU3Gw/lhgII9aotVbAmhT6/NKHWgyUA==} engines: {node: '>=22.12.0'} hasBin: true @@ -7950,20 +7961,20 @@ packages: resolution: {integrity: sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==} engines: {node: '>= 0.8'} - verdaccio-audit@13.1.1: - resolution: {integrity: sha512-6RNvJ9sIvG4Zkqp4EAn/h2Q/XhaUJ2Hi4MSl8lKiZBdIzU4r/KBhuoYZ1xF/PBuSiih5z3OP47r0JwOu0qDwOw==} + verdaccio-audit@13.1.2: + resolution: {integrity: sha512-2nHSt8qRQcCCUQX6QO72eC1D1RoqCBZVPTotVdS/CGpMtE+jUHIDnOSWWMQxtN53PHa6wjjheySJCcuEpmtJsQ==} engines: {node: '>=22'} verdaccio-auth-memory@13.1.1: resolution: {integrity: sha512-Oo3CsyIGaM2S0qCXMN0Coi1uVyvIplT5DAEqwYK22z9XTHAZQf3oUgiVPxEwpFGcqxYsIAq1kxH5COST3xxR6g==} engines: {node: '>=22'} - verdaccio-htpasswd@13.1.1: - resolution: {integrity: sha512-cLzVGQyj2iYkUCZyqV+ACU82Nod9ThKzmDMCV+8fp4c7QmrHAsl6oUaSEW1ZBAtB2hIP/Gv2vAfiTzrXrAX7NA==} + verdaccio-htpasswd@13.1.2: + resolution: {integrity: sha512-37/V2zidmJWpJp78PFMAHEpDPMAdFiIRevV/CshJydyiglIJd0CJi0W4LGsbgXy2pSqYbu22dVzq6JV/MR5xYw==} engines: {node: '>=22'} - verdaccio@6.9.2: - resolution: {integrity: sha512-HwFvPB/LMfDZlfZdVo6zZX05rOWlVReRDMWqE7rihE0crlw4brNFNO4HTXxEVrjz/bV9iurJyRSANWOTaAOtAQ==} + verdaccio@6.10.0: + resolution: {integrity: sha512-kY/wz65nE5P3aJkVvIsM/5XqyuQgLjQ9vBKlnGSsgetT4d3nkPI/NAKkI02aSm00D0Ene1SOPNJ/oITELPrM/g==} engines: {node: '>=22'} hasBin: true @@ -8014,20 +8025,20 @@ packages: yaml: optional: true - vitest@4.1.10: - resolution: {integrity: sha512-R9jUTe5S4Qb0HCd4TNqpC7oGcrMssMRGXLW80ubjWsW9VH5GF8y1Y0SFLY9AbqSk6nt0PnOx4H4WNJYZ13GUPw==} + vitest@4.1.11: + resolution: {integrity: sha512-fhACrNXUidIbGSBr5FlbuBkO7VWC1ZyLl0DO4CU2DrQoAPxX84Ysxs+HeGQpii5lZWV1Q4gBZTTu49mF+A6Edw==} engines: {node: ^20.0.0 || ^22.0.0 || >=24.0.0} hasBin: true peerDependencies: '@edge-runtime/vm': '*' '@opentelemetry/api': ^1.9.0 '@types/node': ^20.0.0 || ^22.0.0 || >=24.0.0 - '@vitest/browser-playwright': 4.1.10 - '@vitest/browser-preview': 4.1.10 - '@vitest/browser-webdriverio': 4.1.10 - '@vitest/coverage-istanbul': 4.1.10 - '@vitest/coverage-v8': 4.1.10 - '@vitest/ui': 4.1.10 + '@vitest/browser-playwright': 4.1.11 + '@vitest/browser-preview': 4.1.11 + '@vitest/browser-webdriverio': 4.1.11 + '@vitest/coverage-istanbul': 4.1.11 + '@vitest/coverage-v8': 4.1.11 + '@vitest/ui': 4.1.11 happy-dom: '*' jsdom: '*' peerDependenciesMeta: @@ -8235,8 +8246,8 @@ packages: utf-8-validate: optional: true - wsl-utils@0.3.1: - resolution: {integrity: sha512-g/eziiSUNBSsdDJtCLB8bdYEUMj4jR7AGeUo96p/3dTafgjHhpF4RiCFPiRILwjQoDXx5MqkBr4fwWtR3Ky4Wg==} + wsl-utils@1.0.0: + resolution: {integrity: sha512-Hl0ZOAs672vg+06kfujwRhoS6/jehvULrlFkuF2dRu6pHgA8U06h3xqNIqNNU1LTXPcedxByAR4GS6pwQK0mgA==} engines: {node: '>=20'} xhr2@0.2.1: @@ -10544,65 +10555,67 @@ snapshots: '@opentelemetry/semantic-conventions@1.43.0': {} - '@oxc-parser/binding-android-arm-eabi@0.144.0': + '@oxc-parser/binding-android-arm-eabi@0.145.0': optional: true - '@oxc-parser/binding-android-arm64@0.144.0': + '@oxc-parser/binding-android-arm64@0.145.0': optional: true - '@oxc-parser/binding-darwin-arm64@0.144.0': + '@oxc-parser/binding-darwin-arm64@0.145.0': optional: true - '@oxc-parser/binding-darwin-x64@0.144.0': + '@oxc-parser/binding-darwin-x64@0.145.0': optional: true - '@oxc-parser/binding-freebsd-x64@0.144.0': + '@oxc-parser/binding-freebsd-x64@0.145.0': optional: true - '@oxc-parser/binding-linux-arm-gnueabihf@0.144.0': + '@oxc-parser/binding-linux-arm-gnueabihf@0.145.0': optional: true - '@oxc-parser/binding-linux-arm-musleabihf@0.144.0': + '@oxc-parser/binding-linux-arm-musleabihf@0.145.0': optional: true - '@oxc-parser/binding-linux-arm64-gnu@0.144.0': + '@oxc-parser/binding-linux-arm64-gnu@0.145.0': optional: true - '@oxc-parser/binding-linux-arm64-musl@0.144.0': + '@oxc-parser/binding-linux-arm64-musl@0.145.0': optional: true - '@oxc-parser/binding-linux-ppc64-gnu@0.144.0': + '@oxc-parser/binding-linux-ppc64-gnu@0.145.0': optional: true - '@oxc-parser/binding-linux-riscv64-gnu@0.144.0': + '@oxc-parser/binding-linux-riscv64-gnu@0.145.0': optional: true - '@oxc-parser/binding-linux-riscv64-musl@0.144.0': + '@oxc-parser/binding-linux-riscv64-musl@0.145.0': optional: true - '@oxc-parser/binding-linux-s390x-gnu@0.144.0': + '@oxc-parser/binding-linux-s390x-gnu@0.145.0': optional: true - '@oxc-parser/binding-linux-x64-gnu@0.144.0': + '@oxc-parser/binding-linux-x64-gnu@0.145.0': optional: true - '@oxc-parser/binding-linux-x64-musl@0.144.0': + '@oxc-parser/binding-linux-x64-musl@0.145.0': optional: true - '@oxc-parser/binding-openharmony-arm64@0.144.0': + '@oxc-parser/binding-openharmony-arm64@0.145.0': optional: true - '@oxc-parser/binding-win32-arm64-msvc@0.144.0': + '@oxc-parser/binding-win32-arm64-msvc@0.145.0': optional: true - '@oxc-parser/binding-win32-ia32-msvc@0.144.0': + '@oxc-parser/binding-win32-ia32-msvc@0.145.0': optional: true - '@oxc-parser/binding-win32-x64-msvc@0.144.0': + '@oxc-parser/binding-win32-x64-msvc@0.145.0': optional: true '@oxc-project/types@0.144.0': {} + '@oxc-project/types@0.145.0': {} + '@parcel/watcher-android-arm64@2.6.0': optional: true @@ -10798,7 +10811,7 @@ snapshots: '@protobufjs/utf8@1.1.2': {} - '@puppeteer/browsers@3.2.0': + '@puppeteer/browsers@3.2.1': dependencies: modern-tar: 0.8.4 yargs: 18.1.0 @@ -11309,21 +11322,21 @@ snapshots: '@typescript-eslint/types': 8.67.0 eslint-visitor-keys: 5.0.1 - '@verdaccio/auth@8.1.1(supports-color@11.0.0)': + '@verdaccio/auth@8.1.2(supports-color@11.0.0)': dependencies: - '@verdaccio/config': 8.2.1(supports-color@11.0.0) - '@verdaccio/core': 8.2.1 - '@verdaccio/loaders': 8.1.1(supports-color@11.0.0) - '@verdaccio/signature': 8.1.1(supports-color@11.0.0) + '@verdaccio/config': 8.2.2(supports-color@11.0.0) + '@verdaccio/core': 8.2.2 + '@verdaccio/loaders': 8.1.2(supports-color@11.0.0) + '@verdaccio/signature': 8.1.2(supports-color@11.0.0) debug: 4.4.3(supports-color@11.0.0) lodash: 4.18.1 - verdaccio-htpasswd: 13.1.1(supports-color@11.0.0) + verdaccio-htpasswd: 13.1.2(supports-color@11.0.0) transitivePeerDependencies: - supports-color - '@verdaccio/config@8.2.1(supports-color@11.0.0)': + '@verdaccio/config@8.2.2(supports-color@11.0.0)': dependencies: - '@verdaccio/core': 8.2.1 + '@verdaccio/core': 8.2.2 debug: 4.4.3(supports-color@11.0.0) js-yaml: 5.2.2 lodash: 4.18.1 @@ -11339,31 +11352,40 @@ snapshots: process-warning: 1.0.0 semver: 7.8.5 + '@verdaccio/core@8.2.2': + dependencies: + ajv: 8.20.0 + http-errors: 2.0.1 + http-status-codes: 2.3.0 + minimatch: 10.2.6 + process-warning: 1.0.0 + semver: 7.8.5 + '@verdaccio/file-locking@13.1.0': dependencies: lockfile: 1.0.4 - '@verdaccio/hooks@8.1.2(supports-color@11.0.0)': + '@verdaccio/hooks@8.1.3(supports-color@11.0.0)': dependencies: - '@verdaccio/core': 8.2.1 - '@verdaccio/logger': 8.1.1(supports-color@11.0.0) + '@verdaccio/core': 8.2.2 + '@verdaccio/logger': 8.1.2(supports-color@11.0.0) debug: 4.4.3(supports-color@11.0.0) got: 15.1.0 handlebars: 4.7.9 transitivePeerDependencies: - supports-color - '@verdaccio/loaders@8.1.1(supports-color@11.0.0)': + '@verdaccio/loaders@8.1.2(supports-color@11.0.0)': dependencies: - '@verdaccio/core': 8.2.1 + '@verdaccio/core': 8.2.2 debug: 4.4.3(supports-color@11.0.0) lodash: 4.18.1 transitivePeerDependencies: - supports-color - '@verdaccio/local-storage-legacy@11.4.1(supports-color@11.0.0)': + '@verdaccio/local-storage-legacy@11.4.2(supports-color@11.0.0)': dependencies: - '@verdaccio/core': 8.2.1 + '@verdaccio/core': 8.2.2 '@verdaccio/file-locking': 13.1.0 '@verdaccio/streams': 10.3.0 debug: 4.4.3(supports-color@11.0.0) @@ -11375,9 +11397,9 @@ snapshots: transitivePeerDependencies: - supports-color - '@verdaccio/logger-commons@8.1.1(supports-color@11.0.0)': + '@verdaccio/logger-commons@8.1.2(supports-color@11.0.0)': dependencies: - '@verdaccio/core': 8.2.1 + '@verdaccio/core': 8.2.2 '@verdaccio/logger-prettify': 8.1.0 colorette: 2.0.20 debug: 4.4.3(supports-color@11.0.0) @@ -11393,18 +11415,18 @@ snapshots: pino-abstract-transport: 1.2.0 sonic-boom: 3.8.1 - '@verdaccio/logger@8.1.1(supports-color@11.0.0)': + '@verdaccio/logger@8.1.2(supports-color@11.0.0)': dependencies: - '@verdaccio/logger-commons': 8.1.1(supports-color@11.0.0) + '@verdaccio/logger-commons': 8.1.2(supports-color@11.0.0) pino: 9.14.0 transitivePeerDependencies: - supports-color - '@verdaccio/middleware@8.1.1(supports-color@11.0.0)': + '@verdaccio/middleware@8.1.2(supports-color@11.0.0)': dependencies: - '@verdaccio/config': 8.2.1(supports-color@11.0.0) - '@verdaccio/core': 8.2.1 - '@verdaccio/url': 13.1.1(supports-color@11.0.0) + '@verdaccio/config': 8.2.2(supports-color@11.0.0) + '@verdaccio/core': 8.2.2 + '@verdaccio/url': 13.1.2(supports-color@11.0.0) debug: 4.4.3(supports-color@11.0.0) express: 4.22.2(supports-color@11.0.0) express-rate-limit: 5.5.1 @@ -11413,9 +11435,9 @@ snapshots: transitivePeerDependencies: - supports-color - '@verdaccio/package-filter@13.1.1(supports-color@11.0.0)': + '@verdaccio/package-filter@13.2.0(supports-color@11.0.0)': dependencies: - '@verdaccio/core': 8.2.1 + '@verdaccio/core': 8.2.2 debug: 4.4.3(supports-color@11.0.0) semver: 7.8.5 transitivePeerDependencies: @@ -11428,10 +11450,10 @@ snapshots: transitivePeerDependencies: - supports-color - '@verdaccio/signature@8.1.1(supports-color@11.0.0)': + '@verdaccio/signature@8.1.2(supports-color@11.0.0)': dependencies: - '@verdaccio/config': 8.2.1(supports-color@11.0.0) - '@verdaccio/core': 8.2.1 + '@verdaccio/config': 8.2.2(supports-color@11.0.0) + '@verdaccio/core': 8.2.2 debug: 4.4.3(supports-color@11.0.0) jsonwebtoken: 9.0.3 transitivePeerDependencies: @@ -11439,10 +11461,10 @@ snapshots: '@verdaccio/streams@10.3.0': {} - '@verdaccio/tarball@13.1.1(supports-color@11.0.0)': + '@verdaccio/tarball@13.1.2(supports-color@11.0.0)': dependencies: - '@verdaccio/core': 8.2.1 - '@verdaccio/url': 13.1.1(supports-color@11.0.0) + '@verdaccio/core': 8.2.2 + '@verdaccio/url': 13.1.2(supports-color@11.0.0) debug: 4.4.3(supports-color@11.0.0) gunzip-maybe: 1.4.2 tar-stream: 3.2.0 @@ -11452,34 +11474,34 @@ snapshots: - react-native-b4a - supports-color - '@verdaccio/ui-theme@9.0.0-next-9.23(supports-color@11.0.0)': + '@verdaccio/ui-theme@9.0.0-next-9.26(supports-color@11.0.0)': dependencies: debug: 4.4.3(supports-color@11.0.0) transitivePeerDependencies: - supports-color - '@verdaccio/url@13.1.1(supports-color@11.0.0)': + '@verdaccio/url@13.1.2(supports-color@11.0.0)': dependencies: - '@verdaccio/core': 8.2.1 + '@verdaccio/core': 8.2.2 debug: 4.4.3(supports-color@11.0.0) validator: 13.15.26 transitivePeerDependencies: - supports-color - '@verdaccio/utils@8.2.1': + '@verdaccio/utils@8.2.2': dependencies: - '@verdaccio/core': 8.2.1 + '@verdaccio/core': 8.2.2 lodash: 4.18.1 - minimatch: 10.2.5 + minimatch: 10.2.6 - '@vitejs/plugin-basic-ssl@2.3.0(vite@8.2.1(@types/node@22.20.1)(esbuild@0.28.2)(jiti@2.7.0)(less@4.8.1(supports-color@11.0.0))(sass@1.102.0)(terser@5.50.0)(tsx@4.23.12)(yaml@2.9.0))': + '@vitejs/plugin-basic-ssl@2.3.0(vite@8.2.1(@types/node@22.20.1)(esbuild@0.28.2)(jiti@2.7.0)(less@4.9.0(supports-color@11.0.0))(sass@1.102.0)(terser@5.50.0)(tsx@4.23.12)(yaml@2.9.0))': dependencies: - vite: 8.2.1(@types/node@22.20.1)(esbuild@0.28.2)(jiti@2.7.0)(less@4.8.1(supports-color@11.0.0))(sass@1.102.0)(terser@5.50.0)(tsx@4.23.12)(yaml@2.9.0) + vite: 8.2.1(@types/node@22.20.1)(esbuild@0.28.2)(jiti@2.7.0)(less@4.9.0(supports-color@11.0.0))(sass@1.102.0)(terser@5.50.0)(tsx@4.23.12)(yaml@2.9.0) - '@vitest/coverage-v8@4.1.10(vitest@4.1.10)': + '@vitest/coverage-v8@4.1.11(vitest@4.1.11)': dependencies: '@bcoe/v8-coverage': 1.0.2 - '@vitest/utils': 4.1.10 + '@vitest/utils': 4.1.11 ast-v8-to-istanbul: 1.0.5 istanbul-lib-coverage: 3.2.2 istanbul-lib-report: 3.0.1 @@ -11488,46 +11510,46 @@ snapshots: obug: 2.1.4 std-env: 4.2.0 tinyrainbow: 3.1.1 - vitest: 4.1.10(@opentelemetry/api@1.9.1)(@types/node@22.20.1)(@vitest/coverage-v8@4.1.10)(esbuild@0.28.2)(jiti@2.7.0)(jsdom@30.0.1)(less@4.8.1(supports-color@11.0.0))(sass@1.102.0)(terser@5.50.0)(tsx@4.23.12)(yaml@2.9.0) + vitest: 4.1.11(@opentelemetry/api@1.9.1)(@types/node@22.20.1)(@vitest/coverage-v8@4.1.11)(esbuild@0.28.2)(jiti@2.7.0)(jsdom@30.0.1)(less@4.9.0(supports-color@11.0.0))(sass@1.102.0)(terser@5.50.0)(tsx@4.23.12)(yaml@2.9.0) - '@vitest/expect@4.1.10': + '@vitest/expect@4.1.11': dependencies: '@standard-schema/spec': 1.1.0 '@types/chai': 5.2.3 - '@vitest/spy': 4.1.10 - '@vitest/utils': 4.1.10 + '@vitest/spy': 4.1.11 + '@vitest/utils': 4.1.11 chai: 6.2.2 tinyrainbow: 3.1.1 - '@vitest/mocker@4.1.10(vite@8.2.1(@types/node@22.20.1)(esbuild@0.28.2)(jiti@2.7.0)(less@4.8.1(supports-color@11.0.0))(sass@1.102.0)(terser@5.50.0)(tsx@4.23.12)(yaml@2.9.0))': + '@vitest/mocker@4.1.11(vite@8.2.1(@types/node@22.20.1)(esbuild@0.28.2)(jiti@2.7.0)(less@4.9.0(supports-color@11.0.0))(sass@1.102.0)(terser@5.50.0)(tsx@4.23.12)(yaml@2.9.0))': dependencies: - '@vitest/spy': 4.1.10 + '@vitest/spy': 4.1.11 estree-walker: 3.0.3 magic-string: 0.30.21 optionalDependencies: - vite: 8.2.1(@types/node@22.20.1)(esbuild@0.28.2)(jiti@2.7.0)(less@4.8.1(supports-color@11.0.0))(sass@1.102.0)(terser@5.50.0)(tsx@4.23.12)(yaml@2.9.0) + vite: 8.2.1(@types/node@22.20.1)(esbuild@0.28.2)(jiti@2.7.0)(less@4.9.0(supports-color@11.0.0))(sass@1.102.0)(terser@5.50.0)(tsx@4.23.12)(yaml@2.9.0) - '@vitest/pretty-format@4.1.10': + '@vitest/pretty-format@4.1.11': dependencies: tinyrainbow: 3.1.1 - '@vitest/runner@4.1.10': + '@vitest/runner@4.1.11': dependencies: - '@vitest/utils': 4.1.10 + '@vitest/utils': 4.1.11 pathe: 2.0.3 - '@vitest/snapshot@4.1.10': + '@vitest/snapshot@4.1.11': dependencies: - '@vitest/pretty-format': 4.1.10 - '@vitest/utils': 4.1.10 + '@vitest/pretty-format': 4.1.11 + '@vitest/utils': 4.1.11 magic-string: 0.30.21 pathe: 2.0.3 - '@vitest/spy@4.1.10': {} + '@vitest/spy@4.1.11': {} - '@vitest/utils@4.1.10': + '@vitest/utils@4.1.11': dependencies: - '@vitest/pretty-format': 4.1.10 + '@vitest/pretty-format': 4.1.11 convert-source-map: 2.0.0 tinyrainbow: 3.1.1 @@ -12206,9 +12228,9 @@ snapshots: chrome-trace-event@1.0.4: {} - chromium-bidi@17.0.2(devtools-protocol@0.0.1653615): + chromium-bidi@17.0.2(devtools-protocol@0.0.1666840): dependencies: - devtools-protocol: 0.0.1653615 + devtools-protocol: 0.0.1666840 mitt: 3.0.1 zod: 3.25.76 @@ -12531,7 +12553,7 @@ snapshots: dev-ip@1.0.1: {} - devtools-protocol@0.0.1653615: {} + devtools-protocol@0.0.1666840: {} di@0.0.1: {} @@ -14115,7 +14137,7 @@ snapshots: transitivePeerDependencies: - supports-color - karma-jasmine-html-reporter@2.2.0(jasmine-core@6.3.0)(karma-jasmine@5.1.0(karma@6.4.4(bufferutil@4.1.0)(debug@4.4.3(supports-color@11.0.0))(supports-color@11.0.0)(utf-8-validate@6.0.6)))(karma@6.4.4(bufferutil@4.1.0)(debug@4.4.3(supports-color@11.0.0))(supports-color@11.0.0)(utf-8-validate@6.0.6)): + karma-jasmine-html-reporter@2.3.0(jasmine-core@6.3.0)(karma-jasmine@5.1.0(karma@6.4.4(bufferutil@4.1.0)(debug@4.4.3(supports-color@11.0.0))(supports-color@11.0.0)(utf-8-validate@6.0.6)))(karma@6.4.4(bufferutil@4.1.0)(debug@4.4.3(supports-color@11.0.0))(supports-color@11.0.0)(utf-8-validate@6.0.6)): dependencies: jasmine-core: 6.3.0 karma: 6.4.4(bufferutil@4.1.0)(debug@4.4.3(supports-color@11.0.0))(supports-color@11.0.0)(utf-8-validate@6.0.6) @@ -14177,14 +14199,14 @@ snapshots: picocolors: 1.1.1 shell-quote: 1.10.0 - less-loader@13.0.0(less@4.8.1(supports-color@11.0.0))(webpack@5.109.2(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.26)(uglify-js@3.19.3)): + less-loader@13.0.0(less@4.9.0(supports-color@11.0.0))(webpack@5.109.2(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.26)(uglify-js@3.19.3)): dependencies: '@types/less': 3.0.8 - less: 4.8.1(supports-color@11.0.0) + less: 4.9.0(supports-color@11.0.0) optionalDependencies: webpack: 5.109.2(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.26)(uglify-js@3.19.3) - less@4.8.1(supports-color@11.0.0): + less@4.9.0(supports-color@11.0.0): dependencies: copy-anything: 3.0.5 parse-node-version: 1.0.1 @@ -14384,7 +14406,7 @@ snapshots: dependencies: '@jridgewell/sourcemap-codec': 1.5.5 - magic-string@1.1.1: + magic-string@1.2.1: dependencies: '@jridgewell/sourcemap-codec': 1.5.5 @@ -14604,7 +14626,7 @@ snapshots: find-cache-directory: 6.0.0 injection-js: 2.6.1 jsonc-parser: 3.3.1 - less: 4.8.1(supports-color@11.0.0) + less: 4.9.0(supports-color@11.0.0) ora: 9.4.1 piscina: 5.3.0 postcss: 8.5.26 @@ -14746,14 +14768,14 @@ snapshots: dependencies: mimic-function: 5.0.1 - open@11.0.0: + open@11.0.1: dependencies: default-browser: 5.5.1 define-lazy-prop: 3.0.0 is-in-ssh: 1.0.0 is-inside-container: 1.0.0 - powershell-utils: 0.1.0 - wsl-utils: 0.3.1 + powershell-utils: 0.2.0 + wsl-utils: 1.0.0 opn@5.3.0: dependencies: @@ -14791,29 +14813,29 @@ snapshots: object-keys: 1.1.1 safe-push-apply: 1.0.0 - oxc-parser@0.144.0: + oxc-parser@0.145.0: dependencies: - '@oxc-project/types': 0.144.0 + '@oxc-project/types': 0.145.0 optionalDependencies: - '@oxc-parser/binding-android-arm-eabi': 0.144.0 - '@oxc-parser/binding-android-arm64': 0.144.0 - '@oxc-parser/binding-darwin-arm64': 0.144.0 - '@oxc-parser/binding-darwin-x64': 0.144.0 - '@oxc-parser/binding-freebsd-x64': 0.144.0 - '@oxc-parser/binding-linux-arm-gnueabihf': 0.144.0 - '@oxc-parser/binding-linux-arm-musleabihf': 0.144.0 - '@oxc-parser/binding-linux-arm64-gnu': 0.144.0 - '@oxc-parser/binding-linux-arm64-musl': 0.144.0 - '@oxc-parser/binding-linux-ppc64-gnu': 0.144.0 - '@oxc-parser/binding-linux-riscv64-gnu': 0.144.0 - '@oxc-parser/binding-linux-riscv64-musl': 0.144.0 - '@oxc-parser/binding-linux-s390x-gnu': 0.144.0 - '@oxc-parser/binding-linux-x64-gnu': 0.144.0 - '@oxc-parser/binding-linux-x64-musl': 0.144.0 - '@oxc-parser/binding-openharmony-arm64': 0.144.0 - '@oxc-parser/binding-win32-arm64-msvc': 0.144.0 - '@oxc-parser/binding-win32-ia32-msvc': 0.144.0 - '@oxc-parser/binding-win32-x64-msvc': 0.144.0 + '@oxc-parser/binding-android-arm-eabi': 0.145.0 + '@oxc-parser/binding-android-arm64': 0.145.0 + '@oxc-parser/binding-darwin-arm64': 0.145.0 + '@oxc-parser/binding-darwin-x64': 0.145.0 + '@oxc-parser/binding-freebsd-x64': 0.145.0 + '@oxc-parser/binding-linux-arm-gnueabihf': 0.145.0 + '@oxc-parser/binding-linux-arm-musleabihf': 0.145.0 + '@oxc-parser/binding-linux-arm64-gnu': 0.145.0 + '@oxc-parser/binding-linux-arm64-musl': 0.145.0 + '@oxc-parser/binding-linux-ppc64-gnu': 0.145.0 + '@oxc-parser/binding-linux-riscv64-gnu': 0.145.0 + '@oxc-parser/binding-linux-riscv64-musl': 0.145.0 + '@oxc-parser/binding-linux-s390x-gnu': 0.145.0 + '@oxc-parser/binding-linux-x64-gnu': 0.145.0 + '@oxc-parser/binding-linux-x64-musl': 0.145.0 + '@oxc-parser/binding-openharmony-arm64': 0.145.0 + '@oxc-parser/binding-win32-arm64-msvc': 0.145.0 + '@oxc-parser/binding-win32-ia32-msvc': 0.145.0 + '@oxc-parser/binding-win32-x64-msvc': 0.145.0 p-finally@1.0.0: {} @@ -15024,6 +15046,8 @@ snapshots: powershell-utils@0.1.0: {} + powershell-utils@0.2.0: {} + prelude-ls@1.2.1: {} prettier@3.9.6: {} @@ -15092,11 +15116,11 @@ snapshots: punycode@2.3.1: {} - puppeteer-core@25.6.0(bufferutil@4.1.0)(utf-8-validate@6.0.6): + puppeteer-core@25.8.0(bufferutil@4.1.0)(utf-8-validate@6.0.6): dependencies: - '@puppeteer/browsers': 3.2.0 - chromium-bidi: 17.0.2(devtools-protocol@0.0.1653615) - devtools-protocol: 0.0.1653615 + '@puppeteer/browsers': 3.2.1 + chromium-bidi: 17.0.2(devtools-protocol@0.0.1666840) + devtools-protocol: 0.0.1666840 typed-query-selector: 2.12.2 webdriver-bidi-protocol: 0.4.2 ws: 8.21.3(bufferutil@4.1.0)(utf-8-validate@6.0.6) @@ -15106,13 +15130,13 @@ snapshots: - utf-8-validate - yauzl - puppeteer@25.6.0(bufferutil@4.1.0)(utf-8-validate@6.0.6): + puppeteer@25.8.0(bufferutil@4.1.0)(utf-8-validate@6.0.6): dependencies: - '@puppeteer/browsers': 3.2.0 - chromium-bidi: 17.0.2(devtools-protocol@0.0.1653615) - devtools-protocol: 0.0.1653615 + '@puppeteer/browsers': 3.2.1 + chromium-bidi: 17.0.2(devtools-protocol@0.0.1666840) + devtools-protocol: 0.0.1666840 lilconfig: 3.1.3 - puppeteer-core: 25.6.0(bufferutil@4.1.0)(utf-8-validate@6.0.6) + puppeteer-core: 25.8.0(bufferutil@4.1.0)(utf-8-validate@6.0.6) typed-query-selector: 2.12.2 transitivePeerDependencies: - bufferutil @@ -16215,10 +16239,10 @@ snapshots: vary@1.1.2: {} - verdaccio-audit@13.1.1(encoding@0.1.13)(supports-color@11.0.0): + verdaccio-audit@13.1.2(encoding@0.1.13)(supports-color@11.0.0): dependencies: - '@verdaccio/config': 8.2.1(supports-color@11.0.0) - '@verdaccio/core': 8.2.1 + '@verdaccio/config': 8.2.2(supports-color@11.0.0) + '@verdaccio/core': 8.2.2 express: 4.22.2(supports-color@11.0.0) https-proxy-agent: 5.0.1(supports-color@11.0.0) node-fetch: 2.6.7(encoding@0.1.13) @@ -16233,9 +16257,9 @@ snapshots: transitivePeerDependencies: - supports-color - verdaccio-htpasswd@13.1.1(supports-color@11.0.0): + verdaccio-htpasswd@13.1.2(supports-color@11.0.0): dependencies: - '@verdaccio/core': 8.2.1 + '@verdaccio/core': 8.2.2 '@verdaccio/file-locking': 13.1.0 apache-md5: 1.1.8 bcryptjs: 2.4.3 @@ -16245,25 +16269,25 @@ snapshots: transitivePeerDependencies: - supports-color - verdaccio@6.9.2(encoding@0.1.13)(supports-color@11.0.0): + verdaccio@6.10.0(encoding@0.1.13)(supports-color@11.0.0): dependencies: '@cypress/request': 4.0.1 - '@verdaccio/auth': 8.1.1(supports-color@11.0.0) - '@verdaccio/config': 8.2.1(supports-color@11.0.0) - '@verdaccio/core': 8.2.1 - '@verdaccio/hooks': 8.1.2(supports-color@11.0.0) - '@verdaccio/loaders': 8.1.1(supports-color@11.0.0) - '@verdaccio/local-storage-legacy': 11.4.1(supports-color@11.0.0) - '@verdaccio/logger': 8.1.1(supports-color@11.0.0) - '@verdaccio/middleware': 8.1.1(supports-color@11.0.0) - '@verdaccio/package-filter': 13.1.1(supports-color@11.0.0) + '@verdaccio/auth': 8.1.2(supports-color@11.0.0) + '@verdaccio/config': 8.2.2(supports-color@11.0.0) + '@verdaccio/core': 8.2.2 + '@verdaccio/hooks': 8.1.3(supports-color@11.0.0) + '@verdaccio/loaders': 8.1.2(supports-color@11.0.0) + '@verdaccio/local-storage-legacy': 11.4.2(supports-color@11.0.0) + '@verdaccio/logger': 8.1.2(supports-color@11.0.0) + '@verdaccio/middleware': 8.1.2(supports-color@11.0.0) + '@verdaccio/package-filter': 13.2.0(supports-color@11.0.0) '@verdaccio/search-indexer': 8.1.0(supports-color@11.0.0) - '@verdaccio/signature': 8.1.1(supports-color@11.0.0) + '@verdaccio/signature': 8.1.2(supports-color@11.0.0) '@verdaccio/streams': 10.3.0 - '@verdaccio/tarball': 13.1.1(supports-color@11.0.0) - '@verdaccio/ui-theme': 9.0.0-next-9.23(supports-color@11.0.0) - '@verdaccio/url': 13.1.1(supports-color@11.0.0) - '@verdaccio/utils': 8.2.1 + '@verdaccio/tarball': 13.1.2(supports-color@11.0.0) + '@verdaccio/ui-theme': 9.0.0-next-9.26(supports-color@11.0.0) + '@verdaccio/url': 13.1.2(supports-color@11.0.0) + '@verdaccio/utils': 8.2.2 JSONStream: 1.3.5 async: 3.2.6 clipanion: 4.0.0-rc.4 @@ -16276,8 +16300,8 @@ snapshots: lru-cache: 7.18.3 mime: 3.0.0 semver: 7.8.5 - verdaccio-audit: 13.1.1(encoding@0.1.13)(supports-color@11.0.0) - verdaccio-htpasswd: 13.1.1(supports-color@11.0.0) + verdaccio-audit: 13.1.2(encoding@0.1.13)(supports-color@11.0.0) + verdaccio-htpasswd: 13.1.2(supports-color@11.0.0) transitivePeerDependencies: - bare-abort-controller - bare-buffer @@ -16291,7 +16315,7 @@ snapshots: core-util-is: 1.0.2 extsprintf: 1.3.0 - vite@8.2.1(@types/node@22.20.1)(esbuild@0.28.2)(jiti@2.7.0)(less@4.8.1(supports-color@11.0.0))(sass@1.102.0)(terser@5.50.0)(tsx@4.23.12)(yaml@2.9.0): + vite@8.2.1(@types/node@22.20.1)(esbuild@0.28.2)(jiti@2.7.0)(less@4.9.0(supports-color@11.0.0))(sass@1.102.0)(terser@5.50.0)(tsx@4.23.12)(yaml@2.9.0): dependencies: lightningcss: 1.33.0 picomatch: 4.0.5 @@ -16303,21 +16327,21 @@ snapshots: esbuild: 0.28.2 fsevents: 2.3.3 jiti: 2.7.0 - less: 4.8.1(supports-color@11.0.0) + less: 4.9.0(supports-color@11.0.0) sass: 1.102.0 terser: 5.50.0 tsx: 4.23.12 yaml: 2.9.0 - vitest@4.1.10(@opentelemetry/api@1.9.1)(@types/node@22.20.1)(@vitest/coverage-v8@4.1.10)(esbuild@0.28.2)(jiti@2.7.0)(jsdom@30.0.1)(less@4.8.1(supports-color@11.0.0))(sass@1.102.0)(terser@5.50.0)(tsx@4.23.12)(yaml@2.9.0): + vitest@4.1.11(@opentelemetry/api@1.9.1)(@types/node@22.20.1)(@vitest/coverage-v8@4.1.11)(esbuild@0.28.2)(jiti@2.7.0)(jsdom@30.0.1)(less@4.9.0(supports-color@11.0.0))(sass@1.102.0)(terser@5.50.0)(tsx@4.23.12)(yaml@2.9.0): dependencies: - '@vitest/expect': 4.1.10 - '@vitest/mocker': 4.1.10(vite@8.2.1(@types/node@22.20.1)(esbuild@0.28.2)(jiti@2.7.0)(less@4.8.1(supports-color@11.0.0))(sass@1.102.0)(terser@5.50.0)(tsx@4.23.12)(yaml@2.9.0)) - '@vitest/pretty-format': 4.1.10 - '@vitest/runner': 4.1.10 - '@vitest/snapshot': 4.1.10 - '@vitest/spy': 4.1.10 - '@vitest/utils': 4.1.10 + '@vitest/expect': 4.1.11 + '@vitest/mocker': 4.1.11(vite@8.2.1(@types/node@22.20.1)(esbuild@0.28.2)(jiti@2.7.0)(less@4.9.0(supports-color@11.0.0))(sass@1.102.0)(terser@5.50.0)(tsx@4.23.12)(yaml@2.9.0)) + '@vitest/pretty-format': 4.1.11 + '@vitest/runner': 4.1.11 + '@vitest/snapshot': 4.1.11 + '@vitest/spy': 4.1.11 + '@vitest/utils': 4.1.11 es-module-lexer: 2.3.2 expect-type: 1.4.0 magic-string: 0.30.21 @@ -16329,12 +16353,12 @@ snapshots: tinyexec: 1.3.0 tinyglobby: 0.2.17 tinyrainbow: 3.1.1 - vite: 8.2.1(@types/node@22.20.1)(esbuild@0.28.2)(jiti@2.7.0)(less@4.8.1(supports-color@11.0.0))(sass@1.102.0)(terser@5.50.0)(tsx@4.23.12)(yaml@2.9.0) + vite: 8.2.1(@types/node@22.20.1)(esbuild@0.28.2)(jiti@2.7.0)(less@4.9.0(supports-color@11.0.0))(sass@1.102.0)(terser@5.50.0)(tsx@4.23.12)(yaml@2.9.0) why-is-node-running: 2.3.0 optionalDependencies: '@opentelemetry/api': 1.9.1 '@types/node': 22.20.1 - '@vitest/coverage-v8': 4.1.10(vitest@4.1.10) + '@vitest/coverage-v8': 4.1.11(vitest@4.1.11) jsdom: 30.0.1 transitivePeerDependencies: - '@vitejs/devtools' @@ -16401,7 +16425,7 @@ snapshots: http-proxy-middleware: 4.2.0(supports-color@11.0.0) ipaddr.js: 2.5.0 launch-editor: 2.14.1 - open: 11.0.0 + open: 11.0.1 p-retry: 8.0.0 schema-utils: 4.3.3 selfsigned: 5.5.0 @@ -16627,7 +16651,7 @@ snapshots: bufferutil: 4.1.0 utf-8-validate: 6.0.6 - wsl-utils@0.3.1: + wsl-utils@1.0.0: dependencies: is-wsl: 3.1.1 powershell-utils: 0.1.0 From 0b59dc63262c4e01f98cb788b42bea677f14f18c Mon Sep 17 00:00:00 2001 From: Angular Robot Date: Thu, 20 Aug 2026 13:37:13 +0000 Subject: [PATCH 327/787] build: update cross-repo angular dependencies See associated pull request for more information. --- .../assistant-to-the-branch-manager.yml | 2 +- .github/workflows/ci.yml | 52 ++-- .github/workflows/dev-infra.yml | 6 +- .github/workflows/perf.yml | 6 +- .github/workflows/pr.yml | 44 +-- MODULE.bazel | 6 +- MODULE.bazel.lock | 50 +-- package.json | 28 +- packages/angular/ssr/package.json | 12 +- packages/ngtools/webpack/package.json | 4 +- pnpm-lock.yaml | 291 +++++++++--------- tests/e2e/ng-snapshot/package.json | 32 +- 12 files changed, 266 insertions(+), 267 deletions(-) diff --git a/.github/workflows/assistant-to-the-branch-manager.yml b/.github/workflows/assistant-to-the-branch-manager.yml index 5466bf10b602..7bcd8eaa270d 100644 --- a/.github/workflows/assistant-to-the-branch-manager.yml +++ b/.github/workflows/assistant-to-the-branch-manager.yml @@ -18,6 +18,6 @@ jobs: - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: persist-credentials: false - - uses: angular/dev-infra/github-actions/branch-manager@630fa0aa7ce9b7127b1ec4464b6af02d34f8154b # main + - uses: angular/dev-infra/github-actions/branch-manager@6d918a6dd670e28afd4ba54d00b805d4aba43dca # main with: angular-robot-key: ${{ secrets.ANGULAR_ROBOT_PRIVATE_KEY }} diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index d8ccecaa8a26..8395ac196c14 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -21,9 +21,9 @@ jobs: runs-on: ubuntu-latest steps: - name: Initialize environment - uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@630fa0aa7ce9b7127b1ec4464b6af02d34f8154b # main + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@6d918a6dd670e28afd4ba54d00b805d4aba43dca # main - name: Setup Bazel - uses: angular/dev-infra/github-actions/bazel/setup@630fa0aa7ce9b7127b1ec4464b6af02d34f8154b # main + uses: angular/dev-infra/github-actions/bazel/setup@6d918a6dd670e28afd4ba54d00b805d4aba43dca # main - name: Install node modules run: pnpm install --frozen-lockfile - name: Generate JSON schema types @@ -44,11 +44,11 @@ jobs: runs-on: ubuntu-latest steps: - name: Initialize environment - uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@630fa0aa7ce9b7127b1ec4464b6af02d34f8154b # main + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@6d918a6dd670e28afd4ba54d00b805d4aba43dca # main - name: Setup Bazel - uses: angular/dev-infra/github-actions/bazel/setup@630fa0aa7ce9b7127b1ec4464b6af02d34f8154b # main + uses: angular/dev-infra/github-actions/bazel/setup@6d918a6dd670e28afd4ba54d00b805d4aba43dca # main - name: Setup Bazel RBE - uses: angular/dev-infra/github-actions/bazel/configure-remote@630fa0aa7ce9b7127b1ec4464b6af02d34f8154b # main + uses: angular/dev-infra/github-actions/bazel/configure-remote@6d918a6dd670e28afd4ba54d00b805d4aba43dca # main with: google_credential: ${{ secrets.RBE_TRUSTED_BUILDS_USER }} - name: Install node modules @@ -61,11 +61,11 @@ jobs: runs-on: ubuntu-latest steps: - name: Initialize environment - uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@630fa0aa7ce9b7127b1ec4464b6af02d34f8154b # main + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@6d918a6dd670e28afd4ba54d00b805d4aba43dca # main - name: Setup Bazel - uses: angular/dev-infra/github-actions/bazel/setup@630fa0aa7ce9b7127b1ec4464b6af02d34f8154b # main + uses: angular/dev-infra/github-actions/bazel/setup@6d918a6dd670e28afd4ba54d00b805d4aba43dca # main - name: Setup Bazel RBE - uses: angular/dev-infra/github-actions/bazel/configure-remote@630fa0aa7ce9b7127b1ec4464b6af02d34f8154b # main + uses: angular/dev-infra/github-actions/bazel/configure-remote@6d918a6dd670e28afd4ba54d00b805d4aba43dca # main with: google_credential: ${{ secrets.RBE_TRUSTED_BUILDS_USER }} - name: Install node modules @@ -84,13 +84,13 @@ jobs: runs-on: ubuntu-latest steps: - name: Initialize environment - uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@630fa0aa7ce9b7127b1ec4464b6af02d34f8154b # main + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@6d918a6dd670e28afd4ba54d00b805d4aba43dca # main - name: Install node modules run: pnpm install --frozen-lockfile - name: Setup Bazel - uses: angular/dev-infra/github-actions/bazel/setup@630fa0aa7ce9b7127b1ec4464b6af02d34f8154b # main + uses: angular/dev-infra/github-actions/bazel/setup@6d918a6dd670e28afd4ba54d00b805d4aba43dca # main - name: Setup Bazel RBE - uses: angular/dev-infra/github-actions/bazel/configure-remote@630fa0aa7ce9b7127b1ec4464b6af02d34f8154b # main + uses: angular/dev-infra/github-actions/bazel/configure-remote@6d918a6dd670e28afd4ba54d00b805d4aba43dca # main with: google_credential: ${{ secrets.RBE_TRUSTED_BUILDS_USER }} - name: Run CLI E2E tests @@ -100,11 +100,11 @@ jobs: runs-on: ubuntu-latest steps: - name: Initialize environment - uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@630fa0aa7ce9b7127b1ec4464b6af02d34f8154b # main + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@6d918a6dd670e28afd4ba54d00b805d4aba43dca # main - name: Setup Bazel - uses: angular/dev-infra/github-actions/bazel/setup@630fa0aa7ce9b7127b1ec4464b6af02d34f8154b # main + uses: angular/dev-infra/github-actions/bazel/setup@6d918a6dd670e28afd4ba54d00b805d4aba43dca # main - name: Setup Bazel RBE - uses: angular/dev-infra/github-actions/bazel/configure-remote@630fa0aa7ce9b7127b1ec4464b6af02d34f8154b # main + uses: angular/dev-infra/github-actions/bazel/configure-remote@6d918a6dd670e28afd4ba54d00b805d4aba43dca # main with: google_credential: ${{ secrets.RBE_TRUSTED_BUILDS_USER }} - name: Install node modules @@ -137,7 +137,7 @@ jobs: runs-on: windows-2025 steps: - name: Initialize environment - uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@630fa0aa7ce9b7127b1ec4464b6af02d34f8154b # main + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@6d918a6dd670e28afd4ba54d00b805d4aba43dca # main - name: Install node modules run: pnpm install --frozen-lockfile - name: Download built Windows E2E tests @@ -164,13 +164,13 @@ jobs: runs-on: ubuntu-latest steps: - name: Initialize environment - uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@630fa0aa7ce9b7127b1ec4464b6af02d34f8154b # main + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@6d918a6dd670e28afd4ba54d00b805d4aba43dca # main - name: Install node modules run: pnpm install --frozen-lockfile - name: Setup Bazel - uses: angular/dev-infra/github-actions/bazel/setup@630fa0aa7ce9b7127b1ec4464b6af02d34f8154b # main + uses: angular/dev-infra/github-actions/bazel/setup@6d918a6dd670e28afd4ba54d00b805d4aba43dca # main - name: Setup Bazel RBE - uses: angular/dev-infra/github-actions/bazel/configure-remote@630fa0aa7ce9b7127b1ec4464b6af02d34f8154b # main + uses: angular/dev-infra/github-actions/bazel/configure-remote@6d918a6dd670e28afd4ba54d00b805d4aba43dca # main with: google_credential: ${{ secrets.RBE_TRUSTED_BUILDS_USER }} - name: Run CLI E2E tests @@ -188,13 +188,13 @@ jobs: runs-on: ubuntu-latest steps: - name: Initialize environment - uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@630fa0aa7ce9b7127b1ec4464b6af02d34f8154b # main + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@6d918a6dd670e28afd4ba54d00b805d4aba43dca # main - name: Install node modules run: pnpm install --frozen-lockfile - name: Setup Bazel - uses: angular/dev-infra/github-actions/bazel/setup@630fa0aa7ce9b7127b1ec4464b6af02d34f8154b # main + uses: angular/dev-infra/github-actions/bazel/setup@6d918a6dd670e28afd4ba54d00b805d4aba43dca # main - name: Setup Bazel RBE - uses: angular/dev-infra/github-actions/bazel/configure-remote@630fa0aa7ce9b7127b1ec4464b6af02d34f8154b # main + uses: angular/dev-infra/github-actions/bazel/configure-remote@6d918a6dd670e28afd4ba54d00b805d4aba43dca # main with: google_credential: ${{ secrets.RBE_TRUSTED_BUILDS_USER }} - name: Run CLI E2E tests @@ -208,13 +208,13 @@ jobs: SAUCE_TUNNEL_IDENTIFIER: angular-cli-${{ github.workflow }}-${{ github.run_number }} steps: - name: Initialize environment - uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@630fa0aa7ce9b7127b1ec4464b6af02d34f8154b # main + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@6d918a6dd670e28afd4ba54d00b805d4aba43dca # main - name: Install node modules run: pnpm install --frozen-lockfile - name: Setup Bazel - uses: angular/dev-infra/github-actions/bazel/setup@630fa0aa7ce9b7127b1ec4464b6af02d34f8154b # main + uses: angular/dev-infra/github-actions/bazel/setup@6d918a6dd670e28afd4ba54d00b805d4aba43dca # main - name: Setup Bazel RBE - uses: angular/dev-infra/github-actions/bazel/configure-remote@630fa0aa7ce9b7127b1ec4464b6af02d34f8154b # main + uses: angular/dev-infra/github-actions/bazel/configure-remote@6d918a6dd670e28afd4ba54d00b805d4aba43dca # main with: google_credential: ${{ secrets.RBE_TRUSTED_BUILDS_USER }} - name: Start Sauce Connect @@ -245,11 +245,11 @@ jobs: CIRCLE_BRANCH: ${{ github.ref_name }} steps: - name: Initialize environment - uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@630fa0aa7ce9b7127b1ec4464b6af02d34f8154b # main + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@6d918a6dd670e28afd4ba54d00b805d4aba43dca # main - name: Install node modules run: pnpm install --frozen-lockfile - name: Setup Bazel - uses: angular/dev-infra/github-actions/bazel/setup@630fa0aa7ce9b7127b1ec4464b6af02d34f8154b # main + uses: angular/dev-infra/github-actions/bazel/setup@6d918a6dd670e28afd4ba54d00b805d4aba43dca # main - run: pnpm admin snapshots --verbose env: SNAPSHOT_BUILDS_GITHUB_TOKEN: ${{ secrets.SNAPSHOT_BUILDS_GITHUB_TOKEN }} diff --git a/.github/workflows/dev-infra.yml b/.github/workflows/dev-infra.yml index a5f9bc649f1d..3ff292ec3ff9 100644 --- a/.github/workflows/dev-infra.yml +++ b/.github/workflows/dev-infra.yml @@ -16,21 +16,21 @@ jobs: if: github.event_name == 'pull_request_target' runs-on: ubuntu-latest steps: - - uses: angular/dev-infra/github-actions/labeling/pull-request@630fa0aa7ce9b7127b1ec4464b6af02d34f8154b # main + - uses: angular/dev-infra/github-actions/labeling/pull-request@6d918a6dd670e28afd4ba54d00b805d4aba43dca # main with: angular-robot-key: ${{ secrets.ANGULAR_ROBOT_PRIVATE_KEY }} post_approval_changes: if: github.event_name == 'pull_request_target' runs-on: ubuntu-latest steps: - - uses: angular/dev-infra/github-actions/post-approval-changes@630fa0aa7ce9b7127b1ec4464b6af02d34f8154b # main + - uses: angular/dev-infra/github-actions/post-approval-changes@6d918a6dd670e28afd4ba54d00b805d4aba43dca # main with: angular-robot-key: ${{ secrets.ANGULAR_ROBOT_PRIVATE_KEY }} issue_labels: if: github.event_name == 'issues' runs-on: ubuntu-latest steps: - - uses: angular/dev-infra/github-actions/labeling/issue@630fa0aa7ce9b7127b1ec4464b6af02d34f8154b # main + - uses: angular/dev-infra/github-actions/labeling/issue@6d918a6dd670e28afd4ba54d00b805d4aba43dca # main with: angular-robot-key: ${{ secrets.ANGULAR_ROBOT_PRIVATE_KEY }} google-generative-ai-key: ${{ secrets.GOOGLE_GENERATIVE_AI_KEY }} diff --git a/.github/workflows/perf.yml b/.github/workflows/perf.yml index a941fa92e40d..8b7edf35f34b 100644 --- a/.github/workflows/perf.yml +++ b/.github/workflows/perf.yml @@ -22,7 +22,7 @@ jobs: workflows: ${{ steps.workflows.outputs.workflows }} steps: - name: Initialize environment - uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@630fa0aa7ce9b7127b1ec4464b6af02d34f8154b # main + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@6d918a6dd670e28afd4ba54d00b805d4aba43dca # main - name: Install node modules run: pnpm install --frozen-lockfile - id: workflows @@ -40,9 +40,9 @@ jobs: workflow: ${{ fromJSON(needs.list.outputs.workflows) }} steps: - name: Initialize environment - uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@630fa0aa7ce9b7127b1ec4464b6af02d34f8154b # main + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@6d918a6dd670e28afd4ba54d00b805d4aba43dca # main - name: Setup Bazel - uses: angular/dev-infra/github-actions/bazel/setup@630fa0aa7ce9b7127b1ec4464b6af02d34f8154b # main + uses: angular/dev-infra/github-actions/bazel/setup@6d918a6dd670e28afd4ba54d00b805d4aba43dca # main - name: Install node modules run: pnpm install --frozen-lockfile # We utilize the google-github-actions/auth action to allow us to get an active credential using workflow diff --git a/.github/workflows/pr.yml b/.github/workflows/pr.yml index 6cfb86456745..44071b0478ef 100644 --- a/.github/workflows/pr.yml +++ b/.github/workflows/pr.yml @@ -34,9 +34,9 @@ jobs: runs-on: ubuntu-latest steps: - name: Initialize environment - uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@630fa0aa7ce9b7127b1ec4464b6af02d34f8154b # main + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@6d918a6dd670e28afd4ba54d00b805d4aba43dca # main - name: Setup Bazel - uses: angular/dev-infra/github-actions/bazel/setup@630fa0aa7ce9b7127b1ec4464b6af02d34f8154b # main + uses: angular/dev-infra/github-actions/bazel/setup@6d918a6dd670e28afd4ba54d00b805d4aba43dca # main - name: Setup ESLint Caching uses: actions/cache@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0 with: @@ -66,17 +66,17 @@ jobs: # it has been merged. run: pnpm ng-dev format changed --check ${{ github.event.pull_request.base.sha }} - name: Check Package Licenses - uses: angular/dev-infra/github-actions/linting/licenses@630fa0aa7ce9b7127b1ec4464b6af02d34f8154b # main + uses: angular/dev-infra/github-actions/linting/licenses@6d918a6dd670e28afd4ba54d00b805d4aba43dca # main build: runs-on: ubuntu-latest steps: - name: Initialize environment - uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@630fa0aa7ce9b7127b1ec4464b6af02d34f8154b # main + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@6d918a6dd670e28afd4ba54d00b805d4aba43dca # main - name: Setup Bazel - uses: angular/dev-infra/github-actions/bazel/setup@630fa0aa7ce9b7127b1ec4464b6af02d34f8154b # main + uses: angular/dev-infra/github-actions/bazel/setup@6d918a6dd670e28afd4ba54d00b805d4aba43dca # main - name: Setup Bazel RBE - uses: angular/dev-infra/github-actions/bazel/configure-remote@630fa0aa7ce9b7127b1ec4464b6af02d34f8154b # main + uses: angular/dev-infra/github-actions/bazel/configure-remote@6d918a6dd670e28afd4ba54d00b805d4aba43dca # main - name: Install node modules run: pnpm install --frozen-lockfile - name: Build release targets @@ -93,11 +93,11 @@ jobs: runs-on: ubuntu-latest steps: - name: Initialize environment - uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@630fa0aa7ce9b7127b1ec4464b6af02d34f8154b # main + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@6d918a6dd670e28afd4ba54d00b805d4aba43dca # main - name: Setup Bazel - uses: angular/dev-infra/github-actions/bazel/setup@630fa0aa7ce9b7127b1ec4464b6af02d34f8154b # main + uses: angular/dev-infra/github-actions/bazel/setup@6d918a6dd670e28afd4ba54d00b805d4aba43dca # main - name: Setup Bazel RBE - uses: angular/dev-infra/github-actions/bazel/configure-remote@630fa0aa7ce9b7127b1ec4464b6af02d34f8154b # main + uses: angular/dev-infra/github-actions/bazel/configure-remote@6d918a6dd670e28afd4ba54d00b805d4aba43dca # main - name: Install node modules run: pnpm install --frozen-lockfile - name: Run module and package tests @@ -114,13 +114,13 @@ jobs: runs-on: ubuntu-latest steps: - name: Initialize environment - uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@630fa0aa7ce9b7127b1ec4464b6af02d34f8154b # main + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@6d918a6dd670e28afd4ba54d00b805d4aba43dca # main - name: Install node modules run: pnpm install --frozen-lockfile - name: Setup Bazel - uses: angular/dev-infra/github-actions/bazel/setup@630fa0aa7ce9b7127b1ec4464b6af02d34f8154b # main + uses: angular/dev-infra/github-actions/bazel/setup@6d918a6dd670e28afd4ba54d00b805d4aba43dca # main - name: Setup Bazel RBE - uses: angular/dev-infra/github-actions/bazel/configure-remote@630fa0aa7ce9b7127b1ec4464b6af02d34f8154b # main + uses: angular/dev-infra/github-actions/bazel/configure-remote@6d918a6dd670e28afd4ba54d00b805d4aba43dca # main - name: Run CLI E2E tests run: pnpm bazel test --test_env=E2E_SHARD_TOTAL=6 --test_env=E2E_SHARD_INDEX=${{ matrix.shard }} --config=e2e //tests:e2e.${{ matrix.subset }}_node${{ matrix.node }} @@ -128,11 +128,11 @@ jobs: runs-on: ubuntu-latest steps: - name: Initialize environment - uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@630fa0aa7ce9b7127b1ec4464b6af02d34f8154b # main + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@6d918a6dd670e28afd4ba54d00b805d4aba43dca # main - name: Setup Bazel - uses: angular/dev-infra/github-actions/bazel/setup@630fa0aa7ce9b7127b1ec4464b6af02d34f8154b # main + uses: angular/dev-infra/github-actions/bazel/setup@6d918a6dd670e28afd4ba54d00b805d4aba43dca # main - name: Setup Bazel RBE - uses: angular/dev-infra/github-actions/bazel/configure-remote@630fa0aa7ce9b7127b1ec4464b6af02d34f8154b # main + uses: angular/dev-infra/github-actions/bazel/configure-remote@6d918a6dd670e28afd4ba54d00b805d4aba43dca # main - name: Install node modules run: pnpm install --frozen-lockfile - name: Build E2E tests for Windows on Linux @@ -156,7 +156,7 @@ jobs: runs-on: windows-2025 steps: - name: Initialize environment - uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@630fa0aa7ce9b7127b1ec4464b6af02d34f8154b # main + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@6d918a6dd670e28afd4ba54d00b805d4aba43dca # main - name: Install node modules run: pnpm install --frozen-lockfile - name: Download built Windows E2E tests @@ -183,13 +183,13 @@ jobs: runs-on: ubuntu-latest steps: - name: Initialize environment - uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@630fa0aa7ce9b7127b1ec4464b6af02d34f8154b # main + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@6d918a6dd670e28afd4ba54d00b805d4aba43dca # main - name: Install node modules run: pnpm install --frozen-lockfile - name: Setup Bazel - uses: angular/dev-infra/github-actions/bazel/setup@630fa0aa7ce9b7127b1ec4464b6af02d34f8154b # main + uses: angular/dev-infra/github-actions/bazel/setup@6d918a6dd670e28afd4ba54d00b805d4aba43dca # main - name: Setup Bazel RBE - uses: angular/dev-infra/github-actions/bazel/configure-remote@630fa0aa7ce9b7127b1ec4464b6af02d34f8154b # main + uses: angular/dev-infra/github-actions/bazel/configure-remote@6d918a6dd670e28afd4ba54d00b805d4aba43dca # main - name: Run CLI E2E tests run: pnpm bazel test --test_env=E2E_SHARD_TOTAL=3 --test_env=E2E_SHARD_INDEX=${{ matrix.shard }} --config=e2e //tests:e2e.${{ matrix.subset }}_node${{ matrix.node }} @@ -205,12 +205,12 @@ jobs: runs-on: ubuntu-latest steps: - name: Initialize environment - uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@630fa0aa7ce9b7127b1ec4464b6af02d34f8154b # main + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@6d918a6dd670e28afd4ba54d00b805d4aba43dca # main - name: Install node modules run: pnpm install --frozen-lockfile - name: Setup Bazel - uses: angular/dev-infra/github-actions/bazel/setup@630fa0aa7ce9b7127b1ec4464b6af02d34f8154b # main + uses: angular/dev-infra/github-actions/bazel/setup@6d918a6dd670e28afd4ba54d00b805d4aba43dca # main - name: Setup Bazel RBE - uses: angular/dev-infra/github-actions/bazel/configure-remote@630fa0aa7ce9b7127b1ec4464b6af02d34f8154b # main + uses: angular/dev-infra/github-actions/bazel/configure-remote@6d918a6dd670e28afd4ba54d00b805d4aba43dca # main - name: Run CLI E2E tests run: pnpm bazel test --test_env=E2E_SHARD_TOTAL=6 --test_env=E2E_SHARD_INDEX=${{ matrix.shard }} --config=e2e //tests:e2e.snapshots.${{ matrix.subset }}_node${{ matrix.node }} diff --git a/MODULE.bazel b/MODULE.bazel index cb1a08fd5963..9bfc8c1b806d 100644 --- a/MODULE.bazel +++ b/MODULE.bazel @@ -19,21 +19,21 @@ bazel_dep(name = "aspect_rules_jasmine", version = "2.0.4") bazel_dep(name = "rules_angular") git_override( module_name = "rules_angular", - commit = "c1d74dbcda5f0ee9529dc78c485f34628c3985d5", + commit = "334ed4f0bf82cfcf21b1d8bd501d2294b186061e", remote = "https://github.com/angular/rules_angular.git", ) bazel_dep(name = "devinfra") git_override( module_name = "devinfra", - commit = "630fa0aa7ce9b7127b1ec4464b6af02d34f8154b", + commit = "6d918a6dd670e28afd4ba54d00b805d4aba43dca", remote = "https://github.com/angular/dev-infra.git", ) bazel_dep(name = "rules_browsers") git_override( module_name = "rules_browsers", - commit = "5836240755b286b6224ecccb7045c318b1279def", + commit = "dd75910a556e309d6f475d54214551be919a21d1", remote = "https://github.com/angular/rules_browsers.git", ) diff --git a/MODULE.bazel.lock b/MODULE.bazel.lock index e957c9cda7de..b1c759780a9a 100644 --- a/MODULE.bazel.lock +++ b/MODULE.bazel.lock @@ -536,7 +536,7 @@ }, "@@rules_browsers+//browsers:extensions.bzl%browsers": { "general": { - "bzlTransitiveDigest": "4TUvIB8juKCShOmy6m77drIdimJqOTEPwfzMxkWD5a4=", + "bzlTransitiveDigest": "85AglD+Q1+ncEIApuW5Ng/2cY4OkSMPrOZ05Jp4CTmk=", "usagesDigest": "FmXYJVoVJlnfUU8x8gObSvu4qWcco/9Faw61aC/wBF0=", "recordedFileInputs": {}, "recordedDirentsInputs": {}, @@ -545,9 +545,9 @@ "rules_browsers_chrome_linux": { "repoRuleId": "@@rules_browsers+//browsers/private:browser_repo.bzl%browser_repo", "attributes": { - "sha256": "5b132ebe0be5c0c15cb5222c33e04e37ae21ed3e00d84c68e905f80f29221c50", + "sha256": "1a20882bf1a4f9d1167171b6905efe359bb229be1ce636ae9c931f3d285fbabe", "urls": [ - "https://storage.googleapis.com/chrome-for-testing-public/153.0.7993.0/linux64/chrome-headless-shell-linux64.zip" + "https://storage.googleapis.com/chrome-for-testing-public/154.0.8013.0/linux64/chrome-headless-shell-linux64.zip" ], "named_files": { "CHROME-HEADLESS-SHELL": "chrome-headless-shell-linux64/chrome-headless-shell" @@ -563,9 +563,9 @@ "rules_browsers_chrome_mac": { "repoRuleId": "@@rules_browsers+//browsers/private:browser_repo.bzl%browser_repo", "attributes": { - "sha256": "522e62dbfce61fddd413fb76a65e699b6f5bdce4045e4398d1e2fb1ef73ff6f3", + "sha256": "1b0e0a078fc62c2b9f8cf837d41461084bd4064cf50cfc15ff84447a1f1b8dab", "urls": [ - "https://storage.googleapis.com/chrome-for-testing-public/153.0.7993.0/mac-x64/chrome-headless-shell-mac-x64.zip" + "https://storage.googleapis.com/chrome-for-testing-public/154.0.8013.0/mac-x64/chrome-headless-shell-mac-x64.zip" ], "named_files": { "CHROME-HEADLESS-SHELL": "chrome-headless-shell-mac-x64/chrome-headless-shell" @@ -581,9 +581,9 @@ "rules_browsers_chrome_mac_arm": { "repoRuleId": "@@rules_browsers+//browsers/private:browser_repo.bzl%browser_repo", "attributes": { - "sha256": "b68d54b63ab30042874a87ad81a135360fa87e1d4763df2431b30b4d59878b4e", + "sha256": "7438714da3696778b697b277a2df1d9701b99819ae58f5ab809b1009933677ec", "urls": [ - "https://storage.googleapis.com/chrome-for-testing-public/153.0.7993.0/mac-arm64/chrome-headless-shell-mac-arm64.zip" + "https://storage.googleapis.com/chrome-for-testing-public/154.0.8013.0/mac-arm64/chrome-headless-shell-mac-arm64.zip" ], "named_files": { "CHROME-HEADLESS-SHELL": "chrome-headless-shell-mac-arm64/chrome-headless-shell" @@ -599,9 +599,9 @@ "rules_browsers_chrome_win64": { "repoRuleId": "@@rules_browsers+//browsers/private:browser_repo.bzl%browser_repo", "attributes": { - "sha256": "0fd5b488d41686cb7cb0be1feb861f1e4cb44d9c5e67a4c5328a385742aa6a8e", + "sha256": "4349c800be1f063adc0f1a7e820d024b43ea73917a6893a3f6b3797a5200d49b", "urls": [ - "https://storage.googleapis.com/chrome-for-testing-public/153.0.7993.0/win64/chrome-headless-shell-win64.zip" + "https://storage.googleapis.com/chrome-for-testing-public/154.0.8013.0/win64/chrome-headless-shell-win64.zip" ], "named_files": { "CHROME-HEADLESS-SHELL": "chrome-headless-shell-win64/chrome-headless-shell.exe" @@ -617,9 +617,9 @@ "rules_browsers_chromedriver_linux": { "repoRuleId": "@@rules_browsers+//browsers/private:browser_repo.bzl%browser_repo", "attributes": { - "sha256": "69139f654d93c12d04209713c725b33ea7074a1e35c47aaf98f419c4a00b4e9b", + "sha256": "d275f01236831bd44c6b6712ba5bec0a028b1ce9473a6182aceae6657740a3d3", "urls": [ - "https://storage.googleapis.com/chrome-for-testing-public/153.0.7993.0/linux64/chromedriver-linux64.zip" + "https://storage.googleapis.com/chrome-for-testing-public/154.0.8013.0/linux64/chromedriver-linux64.zip" ], "named_files": { "CHROMEDRIVER": "chromedriver-linux64/chromedriver" @@ -633,9 +633,9 @@ "rules_browsers_chromedriver_mac": { "repoRuleId": "@@rules_browsers+//browsers/private:browser_repo.bzl%browser_repo", "attributes": { - "sha256": "b56b49cb41658c25405757b3c01a5412403e3744ee6935c5f9f59bf2b907bcf6", + "sha256": "cb331889191aa8ab11be6d5a3cc4de760f8cf63dbea5d1f22c80cf16ae68e46f", "urls": [ - "https://storage.googleapis.com/chrome-for-testing-public/153.0.7993.0/mac-x64/chromedriver-mac-x64.zip" + "https://storage.googleapis.com/chrome-for-testing-public/154.0.8013.0/mac-x64/chromedriver-mac-x64.zip" ], "named_files": { "CHROMEDRIVER": "chromedriver-mac-x64/chromedriver" @@ -649,9 +649,9 @@ "rules_browsers_chromedriver_mac_arm": { "repoRuleId": "@@rules_browsers+//browsers/private:browser_repo.bzl%browser_repo", "attributes": { - "sha256": "e2bd843b45ba197632d29eeef188940488779684207eb3118a5a78c26aef9659", + "sha256": "1584dc9ae35f4a22c4ba4b142335d91d6d3096813395d3acaf135fb6e716ce8e", "urls": [ - "https://storage.googleapis.com/chrome-for-testing-public/153.0.7993.0/mac-arm64/chromedriver-mac-arm64.zip" + "https://storage.googleapis.com/chrome-for-testing-public/154.0.8013.0/mac-arm64/chromedriver-mac-arm64.zip" ], "named_files": { "CHROMEDRIVER": "chromedriver-mac-arm64/chromedriver" @@ -665,9 +665,9 @@ "rules_browsers_chromedriver_win64": { "repoRuleId": "@@rules_browsers+//browsers/private:browser_repo.bzl%browser_repo", "attributes": { - "sha256": "2f56f10ba3989d8b5c44c22cff080c2cc436314f8f8babbcc151bb95b34de841", + "sha256": "061b4d1be9eb2a11ed036b3e562b565ebfd257fcd7cda3681a58e63bff5dd6d0", "urls": [ - "https://storage.googleapis.com/chrome-for-testing-public/153.0.7993.0/win64/chromedriver-win64.zip" + "https://storage.googleapis.com/chrome-for-testing-public/154.0.8013.0/win64/chromedriver-win64.zip" ], "named_files": { "CHROMEDRIVER": "chromedriver-win64/chromedriver.exe" @@ -681,9 +681,9 @@ "rules_browsers_firefox_linux": { "repoRuleId": "@@rules_browsers+//browsers/private:browser_repo.bzl%browser_repo", "attributes": { - "sha256": "bfc57e7b6b4e6204b11e7e03c4b93cff708e9fb37f6b9948be243455311d82ee", + "sha256": "7665cd49ab13417270748325838e565136adbc76d41bbd76fb24d15a0cc7792b", "urls": [ - "https://archive.mozilla.org/pub/firefox/releases/153.0/linux-x86_64/en-US/firefox-153.0.tar.xz" + "https://archive.mozilla.org/pub/firefox/releases/154.0/linux-x86_64/en-US/firefox-154.0.tar.xz" ], "named_files": { "FIREFOX": "firefox/firefox" @@ -697,9 +697,9 @@ "rules_browsers_firefox_mac": { "repoRuleId": "@@rules_browsers+//browsers/private:browser_repo.bzl%browser_repo", "attributes": { - "sha256": "2f9b5a20e546e7e79e4182f8fe10353a3e251635963ab3f6d399a3f290adeb96", + "sha256": "b0295d3b77ec632a60282cf2b9770e1dada085879d00e43d8d23fddf5015e06a", "urls": [ - "https://archive.mozilla.org/pub/firefox/releases/153.0/mac/en-US/Firefox%20153.0.dmg" + "https://archive.mozilla.org/pub/firefox/releases/154.0/mac/en-US/Firefox%20154.0.dmg" ], "named_files": { "FIREFOX": "Firefox.app/Contents/MacOS/firefox" @@ -713,9 +713,9 @@ "rules_browsers_firefox_mac_arm": { "repoRuleId": "@@rules_browsers+//browsers/private:browser_repo.bzl%browser_repo", "attributes": { - "sha256": "2f9b5a20e546e7e79e4182f8fe10353a3e251635963ab3f6d399a3f290adeb96", + "sha256": "b0295d3b77ec632a60282cf2b9770e1dada085879d00e43d8d23fddf5015e06a", "urls": [ - "https://archive.mozilla.org/pub/firefox/releases/153.0/mac/en-US/Firefox%20153.0.dmg" + "https://archive.mozilla.org/pub/firefox/releases/154.0/mac/en-US/Firefox%20154.0.dmg" ], "named_files": { "FIREFOX": "Firefox.app/Contents/MacOS/firefox" @@ -729,9 +729,9 @@ "rules_browsers_firefox_win64": { "repoRuleId": "@@rules_browsers+//browsers/private:browser_repo.bzl%browser_repo", "attributes": { - "sha256": "b409ff5af3419214f11f928e67b1f44c1ad0f8a46f7db7e697caedefa02a6d2a", + "sha256": "6b3c996d27b50dca8e5b6dd2956233cc6bf4720cea3f0847a9423c2cd6759e73", "urls": [ - "https://archive.mozilla.org/pub/firefox/releases/153.0/win64/en-US/Firefox%20Setup%20153.0.exe" + "https://archive.mozilla.org/pub/firefox/releases/154.0/win64/en-US/Firefox%20Setup%20154.0.exe" ], "named_files": { "FIREFOX": "core/firefox.exe" diff --git a/package.json b/package.json index 604ee7863fe7..967ecf1229c4 100644 --- a/package.json +++ b/package.json @@ -42,23 +42,23 @@ }, "homepage": "https://github.com/angular/angular-cli", "dependencies": { - "@angular/compiler-cli": "22.2.0-next.2", + "@angular/compiler-cli": "22.2.0-next.3", "typescript": "6.0.3" }, "devDependencies": { - "@angular/animations": "22.2.0-next.2", - "@angular/cdk": "22.2.0-next.1", - "@angular/common": "22.2.0-next.2", - "@angular/compiler": "22.2.0-next.2", - "@angular/core": "22.2.0-next.2", - "@angular/forms": "22.2.0-next.2", - "@angular/localize": "22.2.0-next.2", - "@angular/material": "22.2.0-next.1", - "@angular/ng-dev": "https://github.com/angular/dev-infra-private-ng-dev-builds.git#fe8d168ef720af0b12276b21f820b2c93e3d342e", - "@angular/platform-browser": "22.2.0-next.2", - "@angular/platform-server": "22.2.0-next.2", - "@angular/router": "22.2.0-next.2", - "@angular/service-worker": "22.2.0-next.2", + "@angular/animations": "22.2.0-next.3", + "@angular/cdk": "22.2.0-next.2", + "@angular/common": "22.2.0-next.3", + "@angular/compiler": "22.2.0-next.3", + "@angular/core": "22.2.0-next.3", + "@angular/forms": "22.2.0-next.3", + "@angular/localize": "22.2.0-next.3", + "@angular/material": "22.2.0-next.2", + "@angular/ng-dev": "https://github.com/angular/dev-infra-private-ng-dev-builds.git#bcad06e14cb29b52b0856020af5e2ab868075602", + "@angular/platform-browser": "22.2.0-next.3", + "@angular/platform-server": "22.2.0-next.3", + "@angular/router": "22.2.0-next.3", + "@angular/service-worker": "22.2.0-next.3", "@babel/core": "8.0.1", "@bazel/bazelisk": "1.28.1", "@bazel/buildifier": "8.2.1", diff --git a/packages/angular/ssr/package.json b/packages/angular/ssr/package.json index dcfe379438ff..96800a3e72e4 100644 --- a/packages/angular/ssr/package.json +++ b/packages/angular/ssr/package.json @@ -37,12 +37,12 @@ }, "devDependencies": { "@angular-devkit/schematics": "workspace:*", - "@angular/common": "22.2.0-next.2", - "@angular/compiler": "22.2.0-next.2", - "@angular/core": "22.2.0-next.2", - "@angular/platform-browser": "22.2.0-next.2", - "@angular/platform-server": "22.2.0-next.2", - "@angular/router": "22.2.0-next.2", + "@angular/common": "22.2.0-next.3", + "@angular/compiler": "22.2.0-next.3", + "@angular/core": "22.2.0-next.3", + "@angular/platform-browser": "22.2.0-next.3", + "@angular/platform-server": "22.2.0-next.3", + "@angular/router": "22.2.0-next.3", "@schematics/angular": "workspace:*", "beasties": "0.4.3" }, diff --git a/packages/ngtools/webpack/package.json b/packages/ngtools/webpack/package.json index 911a2dca9d50..7713b54577bb 100644 --- a/packages/ngtools/webpack/package.json +++ b/packages/ngtools/webpack/package.json @@ -17,8 +17,8 @@ }, "devDependencies": { "@angular-devkit/core": "workspace:0.0.0-PLACEHOLDER", - "@angular/compiler": "22.2.0-next.2", - "@angular/compiler-cli": "22.2.0-next.2", + "@angular/compiler": "22.2.0-next.3", + "@angular/compiler-cli": "22.2.0-next.3", "typescript": "6.0.3", "webpack": "5.109.2" } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index d9786f869c8c..cb19bf3d6971 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -14,8 +14,8 @@ importers: .: dependencies: '@angular/compiler-cli': - specifier: 22.2.0-next.2 - version: 22.2.0-next.2(@angular/compiler@22.2.0-next.2)(typescript@6.0.3) + specifier: 22.2.0-next.3 + version: 22.2.0-next.3(@angular/compiler@22.2.0-next.3)(typescript@6.0.3) typescript: specifier: 6.0.3 version: 6.0.3 @@ -26,44 +26,44 @@ importers: built: true devDependencies: '@angular/animations': - specifier: 22.2.0-next.2 - version: 22.2.0-next.2(@angular/core@22.2.0-next.2(@angular/compiler@22.2.0-next.2)(rxjs@7.8.2)(zone.js@0.16.2)) + specifier: 22.2.0-next.3 + version: 22.2.0-next.3(@angular/core@22.2.0-next.3(@angular/compiler@22.2.0-next.3)(rxjs@7.8.2)(zone.js@0.16.2)) '@angular/cdk': - specifier: 22.2.0-next.1 - version: 22.2.0-next.1(@angular/common@22.2.0-next.2(@angular/core@22.2.0-next.2(@angular/compiler@22.2.0-next.2)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2))(@angular/core@22.2.0-next.2(@angular/compiler@22.2.0-next.2)(rxjs@7.8.2)(zone.js@0.16.2))(@angular/platform-browser@22.2.0-next.2(@angular/animations@22.2.0-next.2(@angular/core@22.2.0-next.2(@angular/compiler@22.2.0-next.2)(rxjs@7.8.2)(zone.js@0.16.2)))(@angular/common@22.2.0-next.2(@angular/core@22.2.0-next.2(@angular/compiler@22.2.0-next.2)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2))(@angular/core@22.2.0-next.2(@angular/compiler@22.2.0-next.2)(rxjs@7.8.2)(zone.js@0.16.2)))(rxjs@7.8.2) - '@angular/common': specifier: 22.2.0-next.2 - version: 22.2.0-next.2(@angular/core@22.2.0-next.2(@angular/compiler@22.2.0-next.2)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2) + version: 22.2.0-next.2(@angular/common@22.2.0-next.3(@angular/core@22.2.0-next.3(@angular/compiler@22.2.0-next.3)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2))(@angular/core@22.2.0-next.3(@angular/compiler@22.2.0-next.3)(rxjs@7.8.2)(zone.js@0.16.2))(@angular/platform-browser@22.2.0-next.3(@angular/animations@22.2.0-next.3(@angular/core@22.2.0-next.3(@angular/compiler@22.2.0-next.3)(rxjs@7.8.2)(zone.js@0.16.2)))(@angular/common@22.2.0-next.3(@angular/core@22.2.0-next.3(@angular/compiler@22.2.0-next.3)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2))(@angular/core@22.2.0-next.3(@angular/compiler@22.2.0-next.3)(rxjs@7.8.2)(zone.js@0.16.2)))(rxjs@7.8.2) + '@angular/common': + specifier: 22.2.0-next.3 + version: 22.2.0-next.3(@angular/core@22.2.0-next.3(@angular/compiler@22.2.0-next.3)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2) '@angular/compiler': - specifier: 22.2.0-next.2 - version: 22.2.0-next.2 + specifier: 22.2.0-next.3 + version: 22.2.0-next.3 '@angular/core': - specifier: 22.2.0-next.2 - version: 22.2.0-next.2(@angular/compiler@22.2.0-next.2)(rxjs@7.8.2)(zone.js@0.16.2) + specifier: 22.2.0-next.3 + version: 22.2.0-next.3(@angular/compiler@22.2.0-next.3)(rxjs@7.8.2)(zone.js@0.16.2) '@angular/forms': - specifier: 22.2.0-next.2 - version: 22.2.0-next.2(@angular/common@22.2.0-next.2(@angular/core@22.2.0-next.2(@angular/compiler@22.2.0-next.2)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2))(@angular/core@22.2.0-next.2(@angular/compiler@22.2.0-next.2)(rxjs@7.8.2)(zone.js@0.16.2))(@angular/platform-browser@22.2.0-next.2(@angular/animations@22.2.0-next.2(@angular/core@22.2.0-next.2(@angular/compiler@22.2.0-next.2)(rxjs@7.8.2)(zone.js@0.16.2)))(@angular/common@22.2.0-next.2(@angular/core@22.2.0-next.2(@angular/compiler@22.2.0-next.2)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2))(@angular/core@22.2.0-next.2(@angular/compiler@22.2.0-next.2)(rxjs@7.8.2)(zone.js@0.16.2)))(rxjs@7.8.2) + specifier: 22.2.0-next.3 + version: 22.2.0-next.3(@angular/common@22.2.0-next.3(@angular/core@22.2.0-next.3(@angular/compiler@22.2.0-next.3)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2))(@angular/core@22.2.0-next.3(@angular/compiler@22.2.0-next.3)(rxjs@7.8.2)(zone.js@0.16.2))(@angular/platform-browser@22.2.0-next.3(@angular/animations@22.2.0-next.3(@angular/core@22.2.0-next.3(@angular/compiler@22.2.0-next.3)(rxjs@7.8.2)(zone.js@0.16.2)))(@angular/common@22.2.0-next.3(@angular/core@22.2.0-next.3(@angular/compiler@22.2.0-next.3)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2))(@angular/core@22.2.0-next.3(@angular/compiler@22.2.0-next.3)(rxjs@7.8.2)(zone.js@0.16.2)))(rxjs@7.8.2) '@angular/localize': - specifier: 22.2.0-next.2 - version: 22.2.0-next.2(@angular/compiler-cli@22.2.0-next.2(@angular/compiler@22.2.0-next.2)(typescript@6.0.3))(@angular/compiler@22.2.0-next.2) + specifier: 22.2.0-next.3 + version: 22.2.0-next.3(@angular/compiler-cli@22.2.0-next.3(@angular/compiler@22.2.0-next.3)(typescript@6.0.3))(@angular/compiler@22.2.0-next.3) '@angular/material': - specifier: 22.2.0-next.1 - version: 22.2.0-next.1(7f44ad9ccd852341470f4234c3737d66) + specifier: 22.2.0-next.2 + version: 22.2.0-next.2(d4251d47b7bf7d31284dc64d049d8a95) '@angular/ng-dev': - specifier: https://github.com/angular/dev-infra-private-ng-dev-builds.git#fe8d168ef720af0b12276b21f820b2c93e3d342e - version: https://codeload.github.com/angular/dev-infra-private-ng-dev-builds/tar.gz/fe8d168ef720af0b12276b21f820b2c93e3d342e + specifier: https://github.com/angular/dev-infra-private-ng-dev-builds.git#bcad06e14cb29b52b0856020af5e2ab868075602 + version: https://codeload.github.com/angular/dev-infra-private-ng-dev-builds/tar.gz/bcad06e14cb29b52b0856020af5e2ab868075602 '@angular/platform-browser': - specifier: 22.2.0-next.2 - version: 22.2.0-next.2(@angular/animations@22.2.0-next.2(@angular/core@22.2.0-next.2(@angular/compiler@22.2.0-next.2)(rxjs@7.8.2)(zone.js@0.16.2)))(@angular/common@22.2.0-next.2(@angular/core@22.2.0-next.2(@angular/compiler@22.2.0-next.2)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2))(@angular/core@22.2.0-next.2(@angular/compiler@22.2.0-next.2)(rxjs@7.8.2)(zone.js@0.16.2)) + specifier: 22.2.0-next.3 + version: 22.2.0-next.3(@angular/animations@22.2.0-next.3(@angular/core@22.2.0-next.3(@angular/compiler@22.2.0-next.3)(rxjs@7.8.2)(zone.js@0.16.2)))(@angular/common@22.2.0-next.3(@angular/core@22.2.0-next.3(@angular/compiler@22.2.0-next.3)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2))(@angular/core@22.2.0-next.3(@angular/compiler@22.2.0-next.3)(rxjs@7.8.2)(zone.js@0.16.2)) '@angular/platform-server': - specifier: 22.2.0-next.2 - version: 22.2.0-next.2(@angular/common@22.2.0-next.2(@angular/core@22.2.0-next.2(@angular/compiler@22.2.0-next.2)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2))(@angular/compiler@22.2.0-next.2)(@angular/core@22.2.0-next.2(@angular/compiler@22.2.0-next.2)(rxjs@7.8.2)(zone.js@0.16.2))(@angular/platform-browser@22.2.0-next.2(@angular/animations@22.2.0-next.2(@angular/core@22.2.0-next.2(@angular/compiler@22.2.0-next.2)(rxjs@7.8.2)(zone.js@0.16.2)))(@angular/common@22.2.0-next.2(@angular/core@22.2.0-next.2(@angular/compiler@22.2.0-next.2)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2))(@angular/core@22.2.0-next.2(@angular/compiler@22.2.0-next.2)(rxjs@7.8.2)(zone.js@0.16.2)))(rxjs@7.8.2) + specifier: 22.2.0-next.3 + version: 22.2.0-next.3(@angular/common@22.2.0-next.3(@angular/core@22.2.0-next.3(@angular/compiler@22.2.0-next.3)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2))(@angular/compiler@22.2.0-next.3)(@angular/core@22.2.0-next.3(@angular/compiler@22.2.0-next.3)(rxjs@7.8.2)(zone.js@0.16.2))(@angular/platform-browser@22.2.0-next.3(@angular/animations@22.2.0-next.3(@angular/core@22.2.0-next.3(@angular/compiler@22.2.0-next.3)(rxjs@7.8.2)(zone.js@0.16.2)))(@angular/common@22.2.0-next.3(@angular/core@22.2.0-next.3(@angular/compiler@22.2.0-next.3)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2))(@angular/core@22.2.0-next.3(@angular/compiler@22.2.0-next.3)(rxjs@7.8.2)(zone.js@0.16.2)))(rxjs@7.8.2) '@angular/router': - specifier: 22.2.0-next.2 - version: 22.2.0-next.2(@angular/common@22.2.0-next.2(@angular/core@22.2.0-next.2(@angular/compiler@22.2.0-next.2)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2))(@angular/core@22.2.0-next.2(@angular/compiler@22.2.0-next.2)(rxjs@7.8.2)(zone.js@0.16.2))(@angular/platform-browser@22.2.0-next.2(@angular/animations@22.2.0-next.2(@angular/core@22.2.0-next.2(@angular/compiler@22.2.0-next.2)(rxjs@7.8.2)(zone.js@0.16.2)))(@angular/common@22.2.0-next.2(@angular/core@22.2.0-next.2(@angular/compiler@22.2.0-next.2)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2))(@angular/core@22.2.0-next.2(@angular/compiler@22.2.0-next.2)(rxjs@7.8.2)(zone.js@0.16.2)))(rxjs@7.8.2) + specifier: 22.2.0-next.3 + version: 22.2.0-next.3(@angular/common@22.2.0-next.3(@angular/core@22.2.0-next.3(@angular/compiler@22.2.0-next.3)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2))(@angular/core@22.2.0-next.3(@angular/compiler@22.2.0-next.3)(rxjs@7.8.2)(zone.js@0.16.2))(@angular/platform-browser@22.2.0-next.3(@angular/animations@22.2.0-next.3(@angular/core@22.2.0-next.3(@angular/compiler@22.2.0-next.3)(rxjs@7.8.2)(zone.js@0.16.2)))(@angular/common@22.2.0-next.3(@angular/core@22.2.0-next.3(@angular/compiler@22.2.0-next.3)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2))(@angular/core@22.2.0-next.3(@angular/compiler@22.2.0-next.3)(rxjs@7.8.2)(zone.js@0.16.2)))(rxjs@7.8.2) '@angular/service-worker': - specifier: 22.2.0-next.2 - version: 22.2.0-next.2(@angular/core@22.2.0-next.2(@angular/compiler@22.2.0-next.2)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2) + specifier: 22.2.0-next.3 + version: 22.2.0-next.3(@angular/core@22.2.0-next.3(@angular/compiler@22.2.0-next.3)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2) '@babel/core': specifier: 8.0.1 version: 8.0.1 @@ -315,7 +315,7 @@ importers: version: 30.0.1 ng-packagr: specifier: 22.2.0-next.3 - version: 22.2.0-next.3(@angular/compiler-cli@22.2.0-next.2(@angular/compiler@22.2.0-next.2)(typescript@6.0.3))(supports-color@11.0.0)(tslib@2.8.1)(typescript@6.0.3) + version: 22.2.0-next.3(@angular/compiler-cli@22.2.0-next.3(@angular/compiler@22.2.0-next.3)(typescript@6.0.3))(supports-color@11.0.0)(tslib@2.8.1)(typescript@6.0.3) rxjs: specifier: 7.8.2 version: 7.8.2 @@ -424,7 +424,7 @@ importers: version: 4.9.0(supports-color@11.0.0) ng-packagr: specifier: 22.2.0-next.3 - version: 22.2.0-next.3(@angular/compiler-cli@22.2.0-next.2(@angular/compiler@22.2.0-next.2)(typescript@6.0.3))(supports-color@11.0.0)(tslib@2.8.1)(typescript@6.0.3) + version: 22.2.0-next.3(@angular/compiler-cli@22.2.0-next.3(@angular/compiler@22.2.0-next.3)(typescript@6.0.3))(supports-color@11.0.0)(tslib@2.8.1)(typescript@6.0.3) postcss: specifier: 8.5.26 version: 8.5.26 @@ -509,23 +509,23 @@ importers: specifier: workspace:* version: link:../../angular_devkit/schematics '@angular/common': - specifier: 22.2.0-next.2 - version: 22.2.0-next.2(@angular/core@22.2.0-next.2(@angular/compiler@22.2.0-next.2)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2) + specifier: 22.2.0-next.3 + version: 22.2.0-next.3(@angular/core@22.2.0-next.3(@angular/compiler@22.2.0-next.3)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2) '@angular/compiler': - specifier: 22.2.0-next.2 - version: 22.2.0-next.2 + specifier: 22.2.0-next.3 + version: 22.2.0-next.3 '@angular/core': - specifier: 22.2.0-next.2 - version: 22.2.0-next.2(@angular/compiler@22.2.0-next.2)(rxjs@7.8.2)(zone.js@0.16.2) + specifier: 22.2.0-next.3 + version: 22.2.0-next.3(@angular/compiler@22.2.0-next.3)(rxjs@7.8.2)(zone.js@0.16.2) '@angular/platform-browser': - specifier: 22.2.0-next.2 - version: 22.2.0-next.2(@angular/animations@22.2.0-next.2(@angular/core@22.2.0-next.2(@angular/compiler@22.2.0-next.2)(rxjs@7.8.2)(zone.js@0.16.2)))(@angular/common@22.2.0-next.2(@angular/core@22.2.0-next.2(@angular/compiler@22.2.0-next.2)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2))(@angular/core@22.2.0-next.2(@angular/compiler@22.2.0-next.2)(rxjs@7.8.2)(zone.js@0.16.2)) + specifier: 22.2.0-next.3 + version: 22.2.0-next.3(@angular/animations@22.2.0-next.3(@angular/core@22.2.0-next.3(@angular/compiler@22.2.0-next.3)(rxjs@7.8.2)(zone.js@0.16.2)))(@angular/common@22.2.0-next.3(@angular/core@22.2.0-next.3(@angular/compiler@22.2.0-next.3)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2))(@angular/core@22.2.0-next.3(@angular/compiler@22.2.0-next.3)(rxjs@7.8.2)(zone.js@0.16.2)) '@angular/platform-server': - specifier: 22.2.0-next.2 - version: 22.2.0-next.2(@angular/common@22.2.0-next.2(@angular/core@22.2.0-next.2(@angular/compiler@22.2.0-next.2)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2))(@angular/compiler@22.2.0-next.2)(@angular/core@22.2.0-next.2(@angular/compiler@22.2.0-next.2)(rxjs@7.8.2)(zone.js@0.16.2))(@angular/platform-browser@22.2.0-next.2(@angular/animations@22.2.0-next.2(@angular/core@22.2.0-next.2(@angular/compiler@22.2.0-next.2)(rxjs@7.8.2)(zone.js@0.16.2)))(@angular/common@22.2.0-next.2(@angular/core@22.2.0-next.2(@angular/compiler@22.2.0-next.2)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2))(@angular/core@22.2.0-next.2(@angular/compiler@22.2.0-next.2)(rxjs@7.8.2)(zone.js@0.16.2)))(rxjs@7.8.2) + specifier: 22.2.0-next.3 + version: 22.2.0-next.3(@angular/common@22.2.0-next.3(@angular/core@22.2.0-next.3(@angular/compiler@22.2.0-next.3)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2))(@angular/compiler@22.2.0-next.3)(@angular/core@22.2.0-next.3(@angular/compiler@22.2.0-next.3)(rxjs@7.8.2)(zone.js@0.16.2))(@angular/platform-browser@22.2.0-next.3(@angular/animations@22.2.0-next.3(@angular/core@22.2.0-next.3(@angular/compiler@22.2.0-next.3)(rxjs@7.8.2)(zone.js@0.16.2)))(@angular/common@22.2.0-next.3(@angular/core@22.2.0-next.3(@angular/compiler@22.2.0-next.3)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2))(@angular/core@22.2.0-next.3(@angular/compiler@22.2.0-next.3)(rxjs@7.8.2)(zone.js@0.16.2)))(rxjs@7.8.2) '@angular/router': - specifier: 22.2.0-next.2 - version: 22.2.0-next.2(@angular/common@22.2.0-next.2(@angular/core@22.2.0-next.2(@angular/compiler@22.2.0-next.2)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2))(@angular/core@22.2.0-next.2(@angular/compiler@22.2.0-next.2)(rxjs@7.8.2)(zone.js@0.16.2))(@angular/platform-browser@22.2.0-next.2(@angular/animations@22.2.0-next.2(@angular/core@22.2.0-next.2(@angular/compiler@22.2.0-next.2)(rxjs@7.8.2)(zone.js@0.16.2)))(@angular/common@22.2.0-next.2(@angular/core@22.2.0-next.2(@angular/compiler@22.2.0-next.2)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2))(@angular/core@22.2.0-next.2(@angular/compiler@22.2.0-next.2)(rxjs@7.8.2)(zone.js@0.16.2)))(rxjs@7.8.2) + specifier: 22.2.0-next.3 + version: 22.2.0-next.3(@angular/common@22.2.0-next.3(@angular/core@22.2.0-next.3(@angular/compiler@22.2.0-next.3)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2))(@angular/core@22.2.0-next.3(@angular/compiler@22.2.0-next.3)(rxjs@7.8.2)(zone.js@0.16.2))(@angular/platform-browser@22.2.0-next.3(@angular/animations@22.2.0-next.3(@angular/core@22.2.0-next.3(@angular/compiler@22.2.0-next.3)(rxjs@7.8.2)(zone.js@0.16.2)))(@angular/common@22.2.0-next.3(@angular/core@22.2.0-next.3(@angular/compiler@22.2.0-next.3)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2))(@angular/core@22.2.0-next.3(@angular/compiler@22.2.0-next.3)(rxjs@7.8.2)(zone.js@0.16.2)))(rxjs@7.8.2) '@schematics/angular': specifier: workspace:* version: link:../../schematics/angular @@ -712,7 +712,7 @@ importers: version: 3.0.4(bufferutil@4.1.0)(debug@4.4.3(supports-color@11.0.0))(supports-color@11.0.0)(utf-8-validate@6.0.6) ng-packagr: specifier: 22.2.0-next.3 - version: 22.2.0-next.3(@angular/compiler-cli@22.2.0-next.2(@angular/compiler@22.2.0-next.2)(typescript@6.0.3))(supports-color@11.0.0)(tslib@2.8.1)(typescript@6.0.3) + version: 22.2.0-next.3(@angular/compiler-cli@22.2.0-next.3(@angular/compiler@22.2.0-next.3)(typescript@6.0.3))(supports-color@11.0.0)(tslib@2.8.1)(typescript@6.0.3) undici: specifier: 8.10.0 version: 8.10.0 @@ -804,11 +804,11 @@ importers: specifier: workspace:0.0.0-PLACEHOLDER version: link:../../angular_devkit/core '@angular/compiler': - specifier: 22.2.0-next.2 - version: 22.2.0-next.2 + specifier: 22.2.0-next.3 + version: 22.2.0-next.3 '@angular/compiler-cli': - specifier: 22.2.0-next.2 - version: 22.2.0-next.2(@angular/compiler@22.2.0-next.2)(typescript@6.0.3) + specifier: 22.2.0-next.3 + version: 22.2.0-next.3(@angular/compiler@22.2.0-next.3)(typescript@6.0.3) typescript: specifier: 6.0.3 version: 6.0.3 @@ -861,48 +861,47 @@ packages: resolution: {integrity: sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==} engines: {node: '>=6.0.0'} - '@angular/animations@22.2.0-next.2': - resolution: {integrity: sha512-3ULxhRd4PKVNHa4b0EFDY5N0UTyh9BT0QZ3T51AVZvHEzrZh9yXzY6UxZnLZl9Vaw6gA9a3sfV4j+nlVlU8T4A==} + '@angular/animations@22.2.0-next.3': + resolution: {integrity: sha512-6NvI3B8d8d9XbZi2gMRwY+eBthu62uW8Gi5CHBSShlDmJc8KfYItPgVOXYYNL9im0jN1tReFiwHV4sds5vlgZA==} engines: {node: ^22.22.3 || ^24.15.0 || >=26.0.0} - deprecated: '@angular/animations is deprecated. Use `animate.enter` and `animate.leave` instead. For more information see: https://v22.angular.dev/guide/animations.' peerDependencies: - '@angular/core': 22.2.0-next.2 + '@angular/core': 22.2.0-next.3 - '@angular/cdk@22.2.0-next.1': - resolution: {integrity: sha512-4oiNpIiv89+0OPVmNKo17tmRUGumvT9+saaS+V2knTDSGmPEkvGo1APXP2dnzOQR5xuScdqsfXM0QXrkMH6otg==} + '@angular/cdk@22.2.0-next.2': + resolution: {integrity: sha512-oe+Hf5h527tGQvjZMA6REkV9tuRW4WWNC9KM03AdQxHo8Kz19a4UqIExmFLKuFDjJqtZ45QA4AfeegD0mLeNOA==} peerDependencies: '@angular/common': ^22.0.0-0 || ^22.1.0-0 || ^22.2.0-0 || ^22.3.0-0 || ^23.0.0-0 '@angular/core': ^22.0.0-0 || ^22.1.0-0 || ^22.2.0-0 || ^22.3.0-0 || ^23.0.0-0 '@angular/platform-browser': ^22.0.0-0 || ^22.1.0-0 || ^22.2.0-0 || ^22.3.0-0 || ^23.0.0-0 rxjs: ^6.5.3 || ^7.4.0 - '@angular/common@22.2.0-next.2': - resolution: {integrity: sha512-CPpjyvGwoSrZPbBACNJ+Ij5V2fXQ4GQLnJHBKLFHlMukNDRVOEBORnvde7zQDLW6b2p1/c8TQUEENS+2rPmJMQ==} + '@angular/common@22.2.0-next.3': + resolution: {integrity: sha512-nX8hky9OuLeL7ar3OOCWaSmlWiBcDHfGvc8idsFohLNwjc5y/0KrGvR5zP6Z9HCUoxEQUeTJOaUGxY6U4209BQ==} engines: {node: ^22.22.3 || ^24.15.0 || >=26.0.0} peerDependencies: - '@angular/core': 22.2.0-next.2 + '@angular/core': 22.2.0-next.3 rxjs: ^6.5.3 || ^7.4.0 - '@angular/compiler-cli@22.2.0-next.2': - resolution: {integrity: sha512-6OhigdUH65DlTmeEWHr6xosDl61tFPdSYwKf4IFAExWrko2MV48OL1tyjCoqgCxVwU+j989DgPCv7AMbcdBYuw==} + '@angular/compiler-cli@22.2.0-next.3': + resolution: {integrity: sha512-CuguonGetrbI5Ru1A/kCWJH9d4kHIo1vaMRh9mrfgO9qsS9q3MqgEcyPCYuNqKmi+oJQloD7tyK+oaFHgnWcCQ==} engines: {node: ^22.22.3 || ^24.15.0 || >=26.0.0} hasBin: true peerDependencies: - '@angular/compiler': 22.2.0-next.2 + '@angular/compiler': 22.2.0-next.3 typescript: '>=6.0 <6.1' peerDependenciesMeta: typescript: optional: true - '@angular/compiler@22.2.0-next.2': - resolution: {integrity: sha512-aU7mOSLoZ3PiEhVMWvBbBN3/8BYHa12tbznnd6AGNWeid3I+IoRaGGP1S56D0nkg5jqS2UMQvwcdCT+Xft/0jA==} + '@angular/compiler@22.2.0-next.3': + resolution: {integrity: sha512-RdgU10sRXVPMGwEWVcmRcZbmlKXUwtFhc3yqEJwT1ZCCP9MQFQjz8YWy0l+yc8SMYfxVH77gQgiHaWyvtvvEdw==} engines: {node: ^22.22.3 || ^24.15.0 || >=26.0.0} - '@angular/core@22.2.0-next.2': - resolution: {integrity: sha512-2vMX+uqYtwDwXGgKCUkm+6nBfKlLtTjTm3ojWuf2PJx0jKD5BFOW+RruzCN7bDy7a1Q2vt3lp6gcsdYGSJbHDg==} + '@angular/core@22.2.0-next.3': + resolution: {integrity: sha512-C8IkKl58XblpONZwZoSkOkmX1c1sM9xLZSthpKzFiVnyA0ua2Ci7sVRSxPAAPaU9fKxYMUJ24w1Z+iJB7rU0yw==} engines: {node: ^22.22.3 || ^24.15.0 || >=26.0.0} peerDependencies: - '@angular/compiler': 22.2.0-next.2 + '@angular/compiler': 22.2.0-next.3 rxjs: ^6.5.3 || ^7.4.0 zone.js: ~0.15.0 || ~0.16.0 peerDependenciesMeta: @@ -911,74 +910,74 @@ packages: zone.js: optional: true - '@angular/forms@22.2.0-next.2': - resolution: {integrity: sha512-X/ZAf1TNiA/iwB9HCLEQ4U1rnb+rRtD3NJChKsArPa8eV1OIAJLFFzGLD6xWxwfIwOkdjRHnVKvalmymE3hfHg==} + '@angular/forms@22.2.0-next.3': + resolution: {integrity: sha512-2ap4X3Ym89YflGgCR20ULFFI93zOOydUeCAP8ng0wxO7l0rjLjP+iDHP5RnD2izCphDdmHeQ6JSnOm4YA06gJQ==} engines: {node: ^22.22.3 || ^24.15.0 || >=26.0.0} peerDependencies: - '@angular/common': 22.2.0-next.2 - '@angular/core': 22.2.0-next.2 - '@angular/platform-browser': 22.2.0-next.2 + '@angular/common': 22.2.0-next.3 + '@angular/core': 22.2.0-next.3 + '@angular/platform-browser': 22.2.0-next.3 rxjs: ^6.5.3 || ^7.4.0 - '@angular/localize@22.2.0-next.2': - resolution: {integrity: sha512-l3QmUKbpJ+E1P1ewj2oxSnXp1wgqBfUSqwMtxCNd/+f14gJKRPiKh2hCchGDz4Jo3qxivp/CBXNkKA7BLP3LUw==} + '@angular/localize@22.2.0-next.3': + resolution: {integrity: sha512-avaS0gRjyOXYppPqZcmQCaN82rGH/8dLIdA8bCyUsn6uGX3kCYuHCZHzyozwUiQErbkb4oQpygk6hDp9+sKubw==} engines: {node: ^22.22.3 || ^24.15.0 || >=26.0.0} hasBin: true peerDependencies: - '@angular/compiler': 22.2.0-next.2 - '@angular/compiler-cli': 22.2.0-next.2 + '@angular/compiler': 22.2.0-next.3 + '@angular/compiler-cli': 22.2.0-next.3 - '@angular/material@22.2.0-next.1': - resolution: {integrity: sha512-qHtAzMC1wtxqIuXvY40PvNgaG4qVCe6GwoljfbqQpTYGKq7w+0fhXz6orw1oRNZU7sXPv1jP+M25YLJIaJoCiQ==} + '@angular/material@22.2.0-next.2': + resolution: {integrity: sha512-3OVQerQD4nQN6CyFepTAXOKMCTI5WOXwmvewMOV+VTkVLlGqFWEAMW4XG0bnaVdYWYtDD5mv4PT17mNfhhElFA==} peerDependencies: - '@angular/cdk': 22.2.0-next.1 + '@angular/cdk': 22.2.0-next.2 '@angular/common': ^22.0.0-0 || ^22.1.0-0 || ^22.2.0-0 || ^22.3.0-0 || ^23.0.0-0 '@angular/core': ^22.0.0-0 || ^22.1.0-0 || ^22.2.0-0 || ^22.3.0-0 || ^23.0.0-0 '@angular/forms': ^22.0.0-0 || ^22.1.0-0 || ^22.2.0-0 || ^22.3.0-0 || ^23.0.0-0 '@angular/platform-browser': ^22.0.0-0 || ^22.1.0-0 || ^22.2.0-0 || ^22.3.0-0 || ^23.0.0-0 rxjs: ^6.5.3 || ^7.4.0 - '@angular/ng-dev@https://codeload.github.com/angular/dev-infra-private-ng-dev-builds/tar.gz/fe8d168ef720af0b12276b21f820b2c93e3d342e': - resolution: {gitHosted: true, integrity: sha512-6sQRCd29gx7lREERjAupLXS6orZKqCwNssMKW2YQYBYwulyLTK4G31M2yu5+m2Izly7VsfVQyeOVk+ZmD9j2jA==, tarball: https://codeload.github.com/angular/dev-infra-private-ng-dev-builds/tar.gz/fe8d168ef720af0b12276b21f820b2c93e3d342e} - version: 0.0.0-630fa0aa7ce9b7127b1ec4464b6af02d34f8154b + '@angular/ng-dev@https://codeload.github.com/angular/dev-infra-private-ng-dev-builds/tar.gz/bcad06e14cb29b52b0856020af5e2ab868075602': + resolution: {gitHosted: true, integrity: sha512-fs92JkAu6Y2CXh1HEUDSTzgdVp12emRA/jEfoJG1d9V1t60tBZTsbnYyi3Zd8XkDy1Tu0l9Ne8xcHjQqwdhy8Q==, tarball: https://codeload.github.com/angular/dev-infra-private-ng-dev-builds/tar.gz/bcad06e14cb29b52b0856020af5e2ab868075602} + version: 0.0.0-6d918a6dd670e28afd4ba54d00b805d4aba43dca hasBin: true - '@angular/platform-browser@22.2.0-next.2': - resolution: {integrity: sha512-/ivDdcWiGCktx/vpcOV7mZ2/GxJ6cx1oL+phCw/2OPZay9zAoPfTkWSZxrad+XPlEx838OhhE3Ezafos1yq7UQ==} + '@angular/platform-browser@22.2.0-next.3': + resolution: {integrity: sha512-oNIJ/MJehV86A/u+I6J1czCS4gLYOpnys2uujfXAalJHMjUViBoqjw8WnrFapV73XINbucA3B34x/pZlDWrg5A==} engines: {node: ^22.22.3 || ^24.15.0 || >=26.0.0} peerDependencies: - '@angular/animations': 22.2.0-next.2 - '@angular/common': 22.2.0-next.2 - '@angular/core': 22.2.0-next.2 + '@angular/animations': 22.2.0-next.3 + '@angular/common': 22.2.0-next.3 + '@angular/core': 22.2.0-next.3 peerDependenciesMeta: '@angular/animations': optional: true - '@angular/platform-server@22.2.0-next.2': - resolution: {integrity: sha512-RDkHud6HSYg5jPpkHzUAj6v1Vo7h/9UlcDOFIwNmBLSbejw0GCZHcrK+OJwo/mJKMbSuTT9zMhMypxbZUKU6TA==} + '@angular/platform-server@22.2.0-next.3': + resolution: {integrity: sha512-dkwIyC+U2MfYDkgUiFYFiUCwrO0d4jxwCZF5PoBSHF2SGMoS1Q+ciWB+Jm8GPPRbWX0FaRyEfugqHoFq/XMSkw==} engines: {node: ^22.22.3 || ^24.15.0 || >=26.0.0} peerDependencies: - '@angular/common': 22.2.0-next.2 - '@angular/compiler': 22.2.0-next.2 - '@angular/core': 22.2.0-next.2 - '@angular/platform-browser': 22.2.0-next.2 + '@angular/common': 22.2.0-next.3 + '@angular/compiler': 22.2.0-next.3 + '@angular/core': 22.2.0-next.3 + '@angular/platform-browser': 22.2.0-next.3 rxjs: ^6.5.3 || ^7.4.0 - '@angular/router@22.2.0-next.2': - resolution: {integrity: sha512-p9tpL7zLEVciOpO8BHcCJaRIM66tIBe+7FqdqCkssA/hBpZKiFkhGRD6N+KaN7lxIe77tnXgYGxKZpXkr9KJOw==} + '@angular/router@22.2.0-next.3': + resolution: {integrity: sha512-zmcJW9Z83FGWaEuOx9fJkdLWC5vaHropzZT1nFRu54LRXpj4/9+VZsoW5bTosxhP9wrgOGJWH+oqX/UkjFY0Wg==} engines: {node: ^22.22.3 || ^24.15.0 || >=26.0.0} peerDependencies: - '@angular/common': 22.2.0-next.2 - '@angular/core': 22.2.0-next.2 - '@angular/platform-browser': 22.2.0-next.2 + '@angular/common': 22.2.0-next.3 + '@angular/core': 22.2.0-next.3 + '@angular/platform-browser': 22.2.0-next.3 rxjs: ^6.5.3 || ^7.4.0 - '@angular/service-worker@22.2.0-next.2': - resolution: {integrity: sha512-B+P/w2+V6TAWegrxYNZ7Qs/6fPd8/xfqtL2MKW+tYg1VsMT0rzspl9zCyPwTZy4kZTqS/w/Rj6NCYO1JSnlvKQ==} + '@angular/service-worker@22.2.0-next.3': + resolution: {integrity: sha512-TsVVyrV/uzsLE1espkFKQVqLubWuW1MDDmKBl567/ayGhs7ry8rLt19MvHubPbVRzDo0h3Pbx7/ddBf0i8apeg==} engines: {node: ^22.22.3 || ^24.15.0 || >=26.0.0} hasBin: true peerDependencies: - '@angular/core': 22.2.0-next.2 + '@angular/core': 22.2.0-next.3 rxjs: ^6.5.3 || ^7.4.0 '@asamuzakjp/css-color@6.0.7': @@ -2101,8 +2100,8 @@ packages: resolution: {integrity: sha512-IJn+8A3QZJfe7FUtWqHVNo3xJs7KFpurCWGWCiCz3oEh+BkRymKZ1QxfAbU2yGMDzTytLGQ2IV6T2r3cuo75/w==} engines: {node: '>=18'} - '@google/genai@2.17.0': - resolution: {integrity: sha512-Cnw71bRtYXnGkN/K1YLb4Wz3yPwIe/7c5kw4VkbXAX508A9HHZCTMsBUhaAjTHDfD9Tn2veHxyJXK1Dxxtcx4g==} + '@google/genai@2.17.1': + resolution: {integrity: sha512-CdZ3M/titoH81hXXkvOikrOW26bC9IXh9iYT7u+r+5p7wi1LnMEnB0AbJfDeWAkjuneP4oJ299BtCt6twmORWg==} engines: {node: '>=20.0.0'} peerDependencies: '@modelcontextprotocol/sdk': ^1.25.2 @@ -8357,29 +8356,29 @@ snapshots: '@jridgewell/gen-mapping': 0.3.13 '@jridgewell/trace-mapping': 0.3.31 - '@angular/animations@22.2.0-next.2(@angular/core@22.2.0-next.2(@angular/compiler@22.2.0-next.2)(rxjs@7.8.2)(zone.js@0.16.2))': + '@angular/animations@22.2.0-next.3(@angular/core@22.2.0-next.3(@angular/compiler@22.2.0-next.3)(rxjs@7.8.2)(zone.js@0.16.2))': dependencies: - '@angular/core': 22.2.0-next.2(@angular/compiler@22.2.0-next.2)(rxjs@7.8.2)(zone.js@0.16.2) + '@angular/core': 22.2.0-next.3(@angular/compiler@22.2.0-next.3)(rxjs@7.8.2)(zone.js@0.16.2) tslib: 2.8.1 - '@angular/cdk@22.2.0-next.1(@angular/common@22.2.0-next.2(@angular/core@22.2.0-next.2(@angular/compiler@22.2.0-next.2)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2))(@angular/core@22.2.0-next.2(@angular/compiler@22.2.0-next.2)(rxjs@7.8.2)(zone.js@0.16.2))(@angular/platform-browser@22.2.0-next.2(@angular/animations@22.2.0-next.2(@angular/core@22.2.0-next.2(@angular/compiler@22.2.0-next.2)(rxjs@7.8.2)(zone.js@0.16.2)))(@angular/common@22.2.0-next.2(@angular/core@22.2.0-next.2(@angular/compiler@22.2.0-next.2)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2))(@angular/core@22.2.0-next.2(@angular/compiler@22.2.0-next.2)(rxjs@7.8.2)(zone.js@0.16.2)))(rxjs@7.8.2)': + '@angular/cdk@22.2.0-next.2(@angular/common@22.2.0-next.3(@angular/core@22.2.0-next.3(@angular/compiler@22.2.0-next.3)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2))(@angular/core@22.2.0-next.3(@angular/compiler@22.2.0-next.3)(rxjs@7.8.2)(zone.js@0.16.2))(@angular/platform-browser@22.2.0-next.3(@angular/animations@22.2.0-next.3(@angular/core@22.2.0-next.3(@angular/compiler@22.2.0-next.3)(rxjs@7.8.2)(zone.js@0.16.2)))(@angular/common@22.2.0-next.3(@angular/core@22.2.0-next.3(@angular/compiler@22.2.0-next.3)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2))(@angular/core@22.2.0-next.3(@angular/compiler@22.2.0-next.3)(rxjs@7.8.2)(zone.js@0.16.2)))(rxjs@7.8.2)': dependencies: - '@angular/common': 22.2.0-next.2(@angular/core@22.2.0-next.2(@angular/compiler@22.2.0-next.2)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2) - '@angular/core': 22.2.0-next.2(@angular/compiler@22.2.0-next.2)(rxjs@7.8.2)(zone.js@0.16.2) - '@angular/platform-browser': 22.2.0-next.2(@angular/animations@22.2.0-next.2(@angular/core@22.2.0-next.2(@angular/compiler@22.2.0-next.2)(rxjs@7.8.2)(zone.js@0.16.2)))(@angular/common@22.2.0-next.2(@angular/core@22.2.0-next.2(@angular/compiler@22.2.0-next.2)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2))(@angular/core@22.2.0-next.2(@angular/compiler@22.2.0-next.2)(rxjs@7.8.2)(zone.js@0.16.2)) + '@angular/common': 22.2.0-next.3(@angular/core@22.2.0-next.3(@angular/compiler@22.2.0-next.3)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2) + '@angular/core': 22.2.0-next.3(@angular/compiler@22.2.0-next.3)(rxjs@7.8.2)(zone.js@0.16.2) + '@angular/platform-browser': 22.2.0-next.3(@angular/animations@22.2.0-next.3(@angular/core@22.2.0-next.3(@angular/compiler@22.2.0-next.3)(rxjs@7.8.2)(zone.js@0.16.2)))(@angular/common@22.2.0-next.3(@angular/core@22.2.0-next.3(@angular/compiler@22.2.0-next.3)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2))(@angular/core@22.2.0-next.3(@angular/compiler@22.2.0-next.3)(rxjs@7.8.2)(zone.js@0.16.2)) parse5: 8.0.1 rxjs: 7.8.2 tslib: 2.8.1 - '@angular/common@22.2.0-next.2(@angular/core@22.2.0-next.2(@angular/compiler@22.2.0-next.2)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2)': + '@angular/common@22.2.0-next.3(@angular/core@22.2.0-next.3(@angular/compiler@22.2.0-next.3)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2)': dependencies: - '@angular/core': 22.2.0-next.2(@angular/compiler@22.2.0-next.2)(rxjs@7.8.2)(zone.js@0.16.2) + '@angular/core': 22.2.0-next.3(@angular/compiler@22.2.0-next.3)(rxjs@7.8.2)(zone.js@0.16.2) rxjs: 7.8.2 tslib: 2.8.1 - '@angular/compiler-cli@22.2.0-next.2(@angular/compiler@22.2.0-next.2)(typescript@6.0.3)': + '@angular/compiler-cli@22.2.0-next.3(@angular/compiler@22.2.0-next.3)(typescript@6.0.3)': dependencies: - '@angular/compiler': 22.2.0-next.2 + '@angular/compiler': 22.2.0-next.3 '@babel/core': 8.0.1 '@jridgewell/sourcemap-codec': 1.5.5 chokidar: 5.0.0 @@ -8391,52 +8390,52 @@ snapshots: optionalDependencies: typescript: 6.0.3 - '@angular/compiler@22.2.0-next.2': + '@angular/compiler@22.2.0-next.3': dependencies: tslib: 2.8.1 - '@angular/core@22.2.0-next.2(@angular/compiler@22.2.0-next.2)(rxjs@7.8.2)(zone.js@0.16.2)': + '@angular/core@22.2.0-next.3(@angular/compiler@22.2.0-next.3)(rxjs@7.8.2)(zone.js@0.16.2)': dependencies: rxjs: 7.8.2 tslib: 2.8.1 optionalDependencies: - '@angular/compiler': 22.2.0-next.2 + '@angular/compiler': 22.2.0-next.3 zone.js: 0.16.2 - '@angular/forms@22.2.0-next.2(@angular/common@22.2.0-next.2(@angular/core@22.2.0-next.2(@angular/compiler@22.2.0-next.2)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2))(@angular/core@22.2.0-next.2(@angular/compiler@22.2.0-next.2)(rxjs@7.8.2)(zone.js@0.16.2))(@angular/platform-browser@22.2.0-next.2(@angular/animations@22.2.0-next.2(@angular/core@22.2.0-next.2(@angular/compiler@22.2.0-next.2)(rxjs@7.8.2)(zone.js@0.16.2)))(@angular/common@22.2.0-next.2(@angular/core@22.2.0-next.2(@angular/compiler@22.2.0-next.2)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2))(@angular/core@22.2.0-next.2(@angular/compiler@22.2.0-next.2)(rxjs@7.8.2)(zone.js@0.16.2)))(rxjs@7.8.2)': + '@angular/forms@22.2.0-next.3(@angular/common@22.2.0-next.3(@angular/core@22.2.0-next.3(@angular/compiler@22.2.0-next.3)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2))(@angular/core@22.2.0-next.3(@angular/compiler@22.2.0-next.3)(rxjs@7.8.2)(zone.js@0.16.2))(@angular/platform-browser@22.2.0-next.3(@angular/animations@22.2.0-next.3(@angular/core@22.2.0-next.3(@angular/compiler@22.2.0-next.3)(rxjs@7.8.2)(zone.js@0.16.2)))(@angular/common@22.2.0-next.3(@angular/core@22.2.0-next.3(@angular/compiler@22.2.0-next.3)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2))(@angular/core@22.2.0-next.3(@angular/compiler@22.2.0-next.3)(rxjs@7.8.2)(zone.js@0.16.2)))(rxjs@7.8.2)': dependencies: - '@angular/common': 22.2.0-next.2(@angular/core@22.2.0-next.2(@angular/compiler@22.2.0-next.2)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2) - '@angular/core': 22.2.0-next.2(@angular/compiler@22.2.0-next.2)(rxjs@7.8.2)(zone.js@0.16.2) - '@angular/platform-browser': 22.2.0-next.2(@angular/animations@22.2.0-next.2(@angular/core@22.2.0-next.2(@angular/compiler@22.2.0-next.2)(rxjs@7.8.2)(zone.js@0.16.2)))(@angular/common@22.2.0-next.2(@angular/core@22.2.0-next.2(@angular/compiler@22.2.0-next.2)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2))(@angular/core@22.2.0-next.2(@angular/compiler@22.2.0-next.2)(rxjs@7.8.2)(zone.js@0.16.2)) + '@angular/common': 22.2.0-next.3(@angular/core@22.2.0-next.3(@angular/compiler@22.2.0-next.3)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2) + '@angular/core': 22.2.0-next.3(@angular/compiler@22.2.0-next.3)(rxjs@7.8.2)(zone.js@0.16.2) + '@angular/platform-browser': 22.2.0-next.3(@angular/animations@22.2.0-next.3(@angular/core@22.2.0-next.3(@angular/compiler@22.2.0-next.3)(rxjs@7.8.2)(zone.js@0.16.2)))(@angular/common@22.2.0-next.3(@angular/core@22.2.0-next.3(@angular/compiler@22.2.0-next.3)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2))(@angular/core@22.2.0-next.3(@angular/compiler@22.2.0-next.3)(rxjs@7.8.2)(zone.js@0.16.2)) '@standard-schema/spec': 1.1.0 rxjs: 7.8.2 tslib: 2.8.1 zod: 4.4.3 - '@angular/localize@22.2.0-next.2(@angular/compiler-cli@22.2.0-next.2(@angular/compiler@22.2.0-next.2)(typescript@6.0.3))(@angular/compiler@22.2.0-next.2)': + '@angular/localize@22.2.0-next.3(@angular/compiler-cli@22.2.0-next.3(@angular/compiler@22.2.0-next.3)(typescript@6.0.3))(@angular/compiler@22.2.0-next.3)': dependencies: - '@angular/compiler': 22.2.0-next.2 - '@angular/compiler-cli': 22.2.0-next.2(@angular/compiler@22.2.0-next.2)(typescript@6.0.3) + '@angular/compiler': 22.2.0-next.3 + '@angular/compiler-cli': 22.2.0-next.3(@angular/compiler@22.2.0-next.3)(typescript@6.0.3) '@babel/core': 8.0.1 tinyglobby: 0.2.17 yargs: 18.1.0 - '@angular/material@22.2.0-next.1(7f44ad9ccd852341470f4234c3737d66)': + '@angular/material@22.2.0-next.2(d4251d47b7bf7d31284dc64d049d8a95)': dependencies: - '@angular/cdk': 22.2.0-next.1(@angular/common@22.2.0-next.2(@angular/core@22.2.0-next.2(@angular/compiler@22.2.0-next.2)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2))(@angular/core@22.2.0-next.2(@angular/compiler@22.2.0-next.2)(rxjs@7.8.2)(zone.js@0.16.2))(@angular/platform-browser@22.2.0-next.2(@angular/animations@22.2.0-next.2(@angular/core@22.2.0-next.2(@angular/compiler@22.2.0-next.2)(rxjs@7.8.2)(zone.js@0.16.2)))(@angular/common@22.2.0-next.2(@angular/core@22.2.0-next.2(@angular/compiler@22.2.0-next.2)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2))(@angular/core@22.2.0-next.2(@angular/compiler@22.2.0-next.2)(rxjs@7.8.2)(zone.js@0.16.2)))(rxjs@7.8.2) - '@angular/common': 22.2.0-next.2(@angular/core@22.2.0-next.2(@angular/compiler@22.2.0-next.2)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2) - '@angular/core': 22.2.0-next.2(@angular/compiler@22.2.0-next.2)(rxjs@7.8.2)(zone.js@0.16.2) - '@angular/forms': 22.2.0-next.2(@angular/common@22.2.0-next.2(@angular/core@22.2.0-next.2(@angular/compiler@22.2.0-next.2)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2))(@angular/core@22.2.0-next.2(@angular/compiler@22.2.0-next.2)(rxjs@7.8.2)(zone.js@0.16.2))(@angular/platform-browser@22.2.0-next.2(@angular/animations@22.2.0-next.2(@angular/core@22.2.0-next.2(@angular/compiler@22.2.0-next.2)(rxjs@7.8.2)(zone.js@0.16.2)))(@angular/common@22.2.0-next.2(@angular/core@22.2.0-next.2(@angular/compiler@22.2.0-next.2)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2))(@angular/core@22.2.0-next.2(@angular/compiler@22.2.0-next.2)(rxjs@7.8.2)(zone.js@0.16.2)))(rxjs@7.8.2) - '@angular/platform-browser': 22.2.0-next.2(@angular/animations@22.2.0-next.2(@angular/core@22.2.0-next.2(@angular/compiler@22.2.0-next.2)(rxjs@7.8.2)(zone.js@0.16.2)))(@angular/common@22.2.0-next.2(@angular/core@22.2.0-next.2(@angular/compiler@22.2.0-next.2)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2))(@angular/core@22.2.0-next.2(@angular/compiler@22.2.0-next.2)(rxjs@7.8.2)(zone.js@0.16.2)) + '@angular/cdk': 22.2.0-next.2(@angular/common@22.2.0-next.3(@angular/core@22.2.0-next.3(@angular/compiler@22.2.0-next.3)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2))(@angular/core@22.2.0-next.3(@angular/compiler@22.2.0-next.3)(rxjs@7.8.2)(zone.js@0.16.2))(@angular/platform-browser@22.2.0-next.3(@angular/animations@22.2.0-next.3(@angular/core@22.2.0-next.3(@angular/compiler@22.2.0-next.3)(rxjs@7.8.2)(zone.js@0.16.2)))(@angular/common@22.2.0-next.3(@angular/core@22.2.0-next.3(@angular/compiler@22.2.0-next.3)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2))(@angular/core@22.2.0-next.3(@angular/compiler@22.2.0-next.3)(rxjs@7.8.2)(zone.js@0.16.2)))(rxjs@7.8.2) + '@angular/common': 22.2.0-next.3(@angular/core@22.2.0-next.3(@angular/compiler@22.2.0-next.3)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2) + '@angular/core': 22.2.0-next.3(@angular/compiler@22.2.0-next.3)(rxjs@7.8.2)(zone.js@0.16.2) + '@angular/forms': 22.2.0-next.3(@angular/common@22.2.0-next.3(@angular/core@22.2.0-next.3(@angular/compiler@22.2.0-next.3)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2))(@angular/core@22.2.0-next.3(@angular/compiler@22.2.0-next.3)(rxjs@7.8.2)(zone.js@0.16.2))(@angular/platform-browser@22.2.0-next.3(@angular/animations@22.2.0-next.3(@angular/core@22.2.0-next.3(@angular/compiler@22.2.0-next.3)(rxjs@7.8.2)(zone.js@0.16.2)))(@angular/common@22.2.0-next.3(@angular/core@22.2.0-next.3(@angular/compiler@22.2.0-next.3)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2))(@angular/core@22.2.0-next.3(@angular/compiler@22.2.0-next.3)(rxjs@7.8.2)(zone.js@0.16.2)))(rxjs@7.8.2) + '@angular/platform-browser': 22.2.0-next.3(@angular/animations@22.2.0-next.3(@angular/core@22.2.0-next.3(@angular/compiler@22.2.0-next.3)(rxjs@7.8.2)(zone.js@0.16.2)))(@angular/common@22.2.0-next.3(@angular/core@22.2.0-next.3(@angular/compiler@22.2.0-next.3)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2))(@angular/core@22.2.0-next.3(@angular/compiler@22.2.0-next.3)(rxjs@7.8.2)(zone.js@0.16.2)) rxjs: 7.8.2 tslib: 2.8.1 - '@angular/ng-dev@https://codeload.github.com/angular/dev-infra-private-ng-dev-builds/tar.gz/fe8d168ef720af0b12276b21f820b2c93e3d342e': + '@angular/ng-dev@https://codeload.github.com/angular/dev-infra-private-ng-dev-builds/tar.gz/bcad06e14cb29b52b0856020af5e2ab868075602': dependencies: '@actions/core': 3.0.1 '@conventional-changelog/git-client': 3.1.2(conventional-commits-filter@6.0.1)(conventional-commits-parser@7.1.2) '@google-cloud/spanner': 8.0.0(supports-color@11.0.0) - '@google/genai': 2.17.0(bufferutil@4.1.0)(supports-color@11.0.0)(utf-8-validate@6.0.6) + '@google/genai': 2.17.1(bufferutil@4.1.0)(supports-color@11.0.0)(utf-8-validate@6.0.6) '@inquirer/prompts': 8.5.2(@types/node@24.13.3) '@inquirer/type': 4.0.7(@types/node@24.13.3) '@octokit/auth-app': 8.3.0 @@ -8491,35 +8490,35 @@ snapshots: - '@modelcontextprotocol/sdk' - '@react-native-async-storage/async-storage' - '@angular/platform-browser@22.2.0-next.2(@angular/animations@22.2.0-next.2(@angular/core@22.2.0-next.2(@angular/compiler@22.2.0-next.2)(rxjs@7.8.2)(zone.js@0.16.2)))(@angular/common@22.2.0-next.2(@angular/core@22.2.0-next.2(@angular/compiler@22.2.0-next.2)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2))(@angular/core@22.2.0-next.2(@angular/compiler@22.2.0-next.2)(rxjs@7.8.2)(zone.js@0.16.2))': + '@angular/platform-browser@22.2.0-next.3(@angular/animations@22.2.0-next.3(@angular/core@22.2.0-next.3(@angular/compiler@22.2.0-next.3)(rxjs@7.8.2)(zone.js@0.16.2)))(@angular/common@22.2.0-next.3(@angular/core@22.2.0-next.3(@angular/compiler@22.2.0-next.3)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2))(@angular/core@22.2.0-next.3(@angular/compiler@22.2.0-next.3)(rxjs@7.8.2)(zone.js@0.16.2))': dependencies: - '@angular/common': 22.2.0-next.2(@angular/core@22.2.0-next.2(@angular/compiler@22.2.0-next.2)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2) - '@angular/core': 22.2.0-next.2(@angular/compiler@22.2.0-next.2)(rxjs@7.8.2)(zone.js@0.16.2) + '@angular/common': 22.2.0-next.3(@angular/core@22.2.0-next.3(@angular/compiler@22.2.0-next.3)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2) + '@angular/core': 22.2.0-next.3(@angular/compiler@22.2.0-next.3)(rxjs@7.8.2)(zone.js@0.16.2) tslib: 2.8.1 optionalDependencies: - '@angular/animations': 22.2.0-next.2(@angular/core@22.2.0-next.2(@angular/compiler@22.2.0-next.2)(rxjs@7.8.2)(zone.js@0.16.2)) + '@angular/animations': 22.2.0-next.3(@angular/core@22.2.0-next.3(@angular/compiler@22.2.0-next.3)(rxjs@7.8.2)(zone.js@0.16.2)) - '@angular/platform-server@22.2.0-next.2(@angular/common@22.2.0-next.2(@angular/core@22.2.0-next.2(@angular/compiler@22.2.0-next.2)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2))(@angular/compiler@22.2.0-next.2)(@angular/core@22.2.0-next.2(@angular/compiler@22.2.0-next.2)(rxjs@7.8.2)(zone.js@0.16.2))(@angular/platform-browser@22.2.0-next.2(@angular/animations@22.2.0-next.2(@angular/core@22.2.0-next.2(@angular/compiler@22.2.0-next.2)(rxjs@7.8.2)(zone.js@0.16.2)))(@angular/common@22.2.0-next.2(@angular/core@22.2.0-next.2(@angular/compiler@22.2.0-next.2)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2))(@angular/core@22.2.0-next.2(@angular/compiler@22.2.0-next.2)(rxjs@7.8.2)(zone.js@0.16.2)))(rxjs@7.8.2)': + '@angular/platform-server@22.2.0-next.3(@angular/common@22.2.0-next.3(@angular/core@22.2.0-next.3(@angular/compiler@22.2.0-next.3)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2))(@angular/compiler@22.2.0-next.3)(@angular/core@22.2.0-next.3(@angular/compiler@22.2.0-next.3)(rxjs@7.8.2)(zone.js@0.16.2))(@angular/platform-browser@22.2.0-next.3(@angular/animations@22.2.0-next.3(@angular/core@22.2.0-next.3(@angular/compiler@22.2.0-next.3)(rxjs@7.8.2)(zone.js@0.16.2)))(@angular/common@22.2.0-next.3(@angular/core@22.2.0-next.3(@angular/compiler@22.2.0-next.3)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2))(@angular/core@22.2.0-next.3(@angular/compiler@22.2.0-next.3)(rxjs@7.8.2)(zone.js@0.16.2)))(rxjs@7.8.2)': dependencies: - '@angular/common': 22.2.0-next.2(@angular/core@22.2.0-next.2(@angular/compiler@22.2.0-next.2)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2) - '@angular/compiler': 22.2.0-next.2 - '@angular/core': 22.2.0-next.2(@angular/compiler@22.2.0-next.2)(rxjs@7.8.2)(zone.js@0.16.2) - '@angular/platform-browser': 22.2.0-next.2(@angular/animations@22.2.0-next.2(@angular/core@22.2.0-next.2(@angular/compiler@22.2.0-next.2)(rxjs@7.8.2)(zone.js@0.16.2)))(@angular/common@22.2.0-next.2(@angular/core@22.2.0-next.2(@angular/compiler@22.2.0-next.2)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2))(@angular/core@22.2.0-next.2(@angular/compiler@22.2.0-next.2)(rxjs@7.8.2)(zone.js@0.16.2)) + '@angular/common': 22.2.0-next.3(@angular/core@22.2.0-next.3(@angular/compiler@22.2.0-next.3)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2) + '@angular/compiler': 22.2.0-next.3 + '@angular/core': 22.2.0-next.3(@angular/compiler@22.2.0-next.3)(rxjs@7.8.2)(zone.js@0.16.2) + '@angular/platform-browser': 22.2.0-next.3(@angular/animations@22.2.0-next.3(@angular/core@22.2.0-next.3(@angular/compiler@22.2.0-next.3)(rxjs@7.8.2)(zone.js@0.16.2)))(@angular/common@22.2.0-next.3(@angular/core@22.2.0-next.3(@angular/compiler@22.2.0-next.3)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2))(@angular/core@22.2.0-next.3(@angular/compiler@22.2.0-next.3)(rxjs@7.8.2)(zone.js@0.16.2)) rxjs: 7.8.2 tslib: 2.8.1 xhr2: 0.2.1 - '@angular/router@22.2.0-next.2(@angular/common@22.2.0-next.2(@angular/core@22.2.0-next.2(@angular/compiler@22.2.0-next.2)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2))(@angular/core@22.2.0-next.2(@angular/compiler@22.2.0-next.2)(rxjs@7.8.2)(zone.js@0.16.2))(@angular/platform-browser@22.2.0-next.2(@angular/animations@22.2.0-next.2(@angular/core@22.2.0-next.2(@angular/compiler@22.2.0-next.2)(rxjs@7.8.2)(zone.js@0.16.2)))(@angular/common@22.2.0-next.2(@angular/core@22.2.0-next.2(@angular/compiler@22.2.0-next.2)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2))(@angular/core@22.2.0-next.2(@angular/compiler@22.2.0-next.2)(rxjs@7.8.2)(zone.js@0.16.2)))(rxjs@7.8.2)': + '@angular/router@22.2.0-next.3(@angular/common@22.2.0-next.3(@angular/core@22.2.0-next.3(@angular/compiler@22.2.0-next.3)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2))(@angular/core@22.2.0-next.3(@angular/compiler@22.2.0-next.3)(rxjs@7.8.2)(zone.js@0.16.2))(@angular/platform-browser@22.2.0-next.3(@angular/animations@22.2.0-next.3(@angular/core@22.2.0-next.3(@angular/compiler@22.2.0-next.3)(rxjs@7.8.2)(zone.js@0.16.2)))(@angular/common@22.2.0-next.3(@angular/core@22.2.0-next.3(@angular/compiler@22.2.0-next.3)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2))(@angular/core@22.2.0-next.3(@angular/compiler@22.2.0-next.3)(rxjs@7.8.2)(zone.js@0.16.2)))(rxjs@7.8.2)': dependencies: - '@angular/common': 22.2.0-next.2(@angular/core@22.2.0-next.2(@angular/compiler@22.2.0-next.2)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2) - '@angular/core': 22.2.0-next.2(@angular/compiler@22.2.0-next.2)(rxjs@7.8.2)(zone.js@0.16.2) - '@angular/platform-browser': 22.2.0-next.2(@angular/animations@22.2.0-next.2(@angular/core@22.2.0-next.2(@angular/compiler@22.2.0-next.2)(rxjs@7.8.2)(zone.js@0.16.2)))(@angular/common@22.2.0-next.2(@angular/core@22.2.0-next.2(@angular/compiler@22.2.0-next.2)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2))(@angular/core@22.2.0-next.2(@angular/compiler@22.2.0-next.2)(rxjs@7.8.2)(zone.js@0.16.2)) + '@angular/common': 22.2.0-next.3(@angular/core@22.2.0-next.3(@angular/compiler@22.2.0-next.3)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2) + '@angular/core': 22.2.0-next.3(@angular/compiler@22.2.0-next.3)(rxjs@7.8.2)(zone.js@0.16.2) + '@angular/platform-browser': 22.2.0-next.3(@angular/animations@22.2.0-next.3(@angular/core@22.2.0-next.3(@angular/compiler@22.2.0-next.3)(rxjs@7.8.2)(zone.js@0.16.2)))(@angular/common@22.2.0-next.3(@angular/core@22.2.0-next.3(@angular/compiler@22.2.0-next.3)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2))(@angular/core@22.2.0-next.3(@angular/compiler@22.2.0-next.3)(rxjs@7.8.2)(zone.js@0.16.2)) rxjs: 7.8.2 tslib: 2.8.1 - '@angular/service-worker@22.2.0-next.2(@angular/core@22.2.0-next.2(@angular/compiler@22.2.0-next.2)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2)': + '@angular/service-worker@22.2.0-next.3(@angular/core@22.2.0-next.3(@angular/compiler@22.2.0-next.3)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2)': dependencies: - '@angular/core': 22.2.0-next.2(@angular/compiler@22.2.0-next.2)(rxjs@7.8.2)(zone.js@0.16.2) + '@angular/core': 22.2.0-next.3(@angular/compiler@22.2.0-next.3)(rxjs@7.8.2)(zone.js@0.16.2) rxjs: 7.8.2 tslib: 2.8.1 @@ -9793,7 +9792,7 @@ snapshots: transitivePeerDependencies: - supports-color - '@google/genai@2.17.0(bufferutil@4.1.0)(supports-color@11.0.0)(utf-8-validate@6.0.6)': + '@google/genai@2.17.1(bufferutil@4.1.0)(supports-color@11.0.0)(utf-8-validate@6.0.6)': dependencies: google-auth-library: 10.9.1(supports-color@11.0.0) p-retry: 4.6.2 @@ -14613,10 +14612,10 @@ snapshots: neo-async@2.6.2: {} - ng-packagr@22.2.0-next.3(@angular/compiler-cli@22.2.0-next.2(@angular/compiler@22.2.0-next.2)(typescript@6.0.3))(supports-color@11.0.0)(tslib@2.8.1)(typescript@6.0.3): + ng-packagr@22.2.0-next.3(@angular/compiler-cli@22.2.0-next.3(@angular/compiler@22.2.0-next.3)(typescript@6.0.3))(supports-color@11.0.0)(tslib@2.8.1)(typescript@6.0.3): dependencies: '@ampproject/remapping': 2.3.0 - '@angular/compiler-cli': 22.2.0-next.2(@angular/compiler@22.2.0-next.2)(typescript@6.0.3) + '@angular/compiler-cli': 22.2.0-next.3(@angular/compiler@22.2.0-next.3)(typescript@6.0.3) ajv: 8.20.0 browserslist: 4.28.8 chokidar: 5.0.0 diff --git a/tests/e2e/ng-snapshot/package.json b/tests/e2e/ng-snapshot/package.json index b90a52884ca2..efab529ee805 100644 --- a/tests/e2e/ng-snapshot/package.json +++ b/tests/e2e/ng-snapshot/package.json @@ -2,21 +2,21 @@ "description": "snapshot versions of Angular for e2e testing", "private": true, "dependencies": { - "@angular/animations": "github:angular/animations-builds#8c7ebc8b22ec0a6dc67c4d2900e034eb96300fb7", - "@angular/cdk": "github:angular/cdk-builds#4b4949e62c156a3b2530372ebe6a56a3e813b2d0", - "@angular/common": "github:angular/common-builds#6a1e68f4e997310f018ffbb74c230e1bbe2cf0fc", - "@angular/compiler": "github:angular/compiler-builds#7b2a69f7286aaf5ff617fb8e7ae38e48481c317a", - "@angular/compiler-cli": "github:angular/compiler-cli-builds#2abac2b6619918b4ed6b8a43079182d2f2757357", - "@angular/core": "github:angular/core-builds#a575d55a94dccfbc76fd101aa2db53a3f3de3f1f", - "@angular/forms": "github:angular/forms-builds#0d9e44f98591f56cfd3b2edea4683fe0f00e8ce2", - "@angular/language-service": "github:angular/language-service-builds#b2ad13ba654fd6310ffdfd4181d6d41c307e3043", - "@angular/localize": "github:angular/localize-builds#28d4c50d1001466a481d78962dba4744d23a31d5", - "@angular/material": "github:angular/material-builds#bbe56c79c782500f0183a0c84adf017cdb7ccd15", - "@angular/material-moment-adapter": "github:angular/material-moment-adapter-builds#c26efa5523014d6ce9652cd6eb8125d1c60e0e0b", - "@angular/platform-browser": "github:angular/platform-browser-builds#0714800cb3afa7c30402d4477f7079caa64874c2", - "@angular/platform-browser-dynamic": "github:angular/platform-browser-dynamic-builds#dbaff82250087fe6f09ee81d5a06a5f8e0e4cd13", - "@angular/platform-server": "github:angular/platform-server-builds#b7631948a2ebac08642410067d7a28f8e29f10c4", - "@angular/router": "github:angular/router-builds#dff46dd0722569aac7b136c6f4877493d591be94", - "@angular/service-worker": "github:angular/service-worker-builds#abf5a9f3547cb85b6d90412690abadcfbaec0e51" + "@angular/animations": "github:angular/animations-builds#ebf341ae0035dbacee781ab987f8c8336c62a6ba", + "@angular/cdk": "github:angular/cdk-builds#f764328652e240521a38d818a3f2a3b8e8c33f4a", + "@angular/common": "github:angular/common-builds#b8fd07bfdc97d3570f90e368b60ddf3c337c8c43", + "@angular/compiler": "github:angular/compiler-builds#4d1d1548fc38bd7e04330dedb782fccb8e1fb141", + "@angular/compiler-cli": "github:angular/compiler-cli-builds#1d3fe381f981ce77ea6884a57359386baa2e3e64", + "@angular/core": "github:angular/core-builds#26979caac965dc0d479a25b5d05a5fcf14d0ad9e", + "@angular/forms": "github:angular/forms-builds#a6874141905517d6a388112b57753a285aa7888f", + "@angular/language-service": "github:angular/language-service-builds#b41c6925fa8537c63678960486bf2e5363510bfb", + "@angular/localize": "github:angular/localize-builds#427a45e50ab8cbb563b736b46985fce98d6de21e", + "@angular/material": "github:angular/material-builds#7ed21d84d11c896cfc26cf493fc512b28dd9dead", + "@angular/material-moment-adapter": "github:angular/material-moment-adapter-builds#e41d169012c512aea113cad42e16671fe92a6b22", + "@angular/platform-browser": "github:angular/platform-browser-builds#1dac78e7b5785a885df765f02b08acab0c9b8bb4", + "@angular/platform-browser-dynamic": "github:angular/platform-browser-dynamic-builds#170de259e7e98c7065da3e4d6ca4c795cd09dbf8", + "@angular/platform-server": "github:angular/platform-server-builds#55db150433a54d9f83ac190e2437f1f464815632", + "@angular/router": "github:angular/router-builds#a58b82a40376882a54591ee2c2e91dcc626e712f", + "@angular/service-worker": "github:angular/service-worker-builds#d5eef8ef96e0a24617c4871444babe6566ee811c" } } From 43476391939d881106a875a59d28b5fc66a2f8fc Mon Sep 17 00:00:00 2001 From: Angular Robot Date: Thu, 20 Aug 2026 06:00:07 +0000 Subject: [PATCH 328/787] build: update github/codeql-action action to v4.37.7 See associated pull request for more information. --- .github/workflows/codeql.yml | 4 ++-- .github/workflows/scorecard.yml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml index 15fc3e9c9ba5..36a2c904452e 100644 --- a/.github/workflows/codeql.yml +++ b/.github/workflows/codeql.yml @@ -23,12 +23,12 @@ jobs: with: persist-credentials: false - name: Initialize CodeQL - uses: github/codeql-action/init@5595ccaf912efad79be6eef63a5619ff05969be3 # v4.37.6 + uses: github/codeql-action/init@ff2f1c621b7f889edc0d3c761ac2e6a3f8cdb0dd # v4.37.7 with: languages: javascript-typescript build-mode: none config-file: .github/codeql/config.yml - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@5595ccaf912efad79be6eef63a5619ff05969be3 # v4.37.6 + uses: github/codeql-action/analyze@ff2f1c621b7f889edc0d3c761ac2e6a3f8cdb0dd # v4.37.7 with: category: '/language:javascript-typescript' diff --git a/.github/workflows/scorecard.yml b/.github/workflows/scorecard.yml index 862ead79f856..666a9b20049c 100644 --- a/.github/workflows/scorecard.yml +++ b/.github/workflows/scorecard.yml @@ -46,6 +46,6 @@ jobs: # Upload the results to GitHub's code scanning dashboard. - name: 'Upload to code-scanning' - uses: github/codeql-action/upload-sarif@5595ccaf912efad79be6eef63a5619ff05969be3 # v4.37.6 + uses: github/codeql-action/upload-sarif@ff2f1c621b7f889edc0d3c761ac2e6a3f8cdb0dd # v4.37.7 with: sarif_file: results.sarif From a9e507adddea275045dfa4553f70aacc41eba774 Mon Sep 17 00:00:00 2001 From: Kristiyan Kostadinov Date: Fri, 21 Aug 2026 09:23:36 +0200 Subject: [PATCH 329/787] build: remove scorecard workflow The scorecard workflow has been replaced at the org level so these changes remove it from our workflows. --- .github/codeql/config.yml | 8 ------ .github/workflows/codeql.yml | 34 ---------------------- .github/workflows/scorecard.yml | 51 --------------------------------- 3 files changed, 93 deletions(-) delete mode 100644 .github/codeql/config.yml delete mode 100644 .github/workflows/codeql.yml delete mode 100644 .github/workflows/scorecard.yml diff --git a/.github/codeql/config.yml b/.github/codeql/config.yml deleted file mode 100644 index ad81a268eda4..000000000000 --- a/.github/codeql/config.yml +++ /dev/null @@ -1,8 +0,0 @@ -name: 'Angular CLI CodeQL config' - -query-filters: - # TODO(josephperrott): reevaluate if these can be reenabled. - - exclude: - id: js/bad-code-sanitization - - exclude: - id: js/regex-injection diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml deleted file mode 100644 index 36a2c904452e..000000000000 --- a/.github/workflows/codeql.yml +++ /dev/null @@ -1,34 +0,0 @@ -name: 'CodeQL' - -on: - push: - branches: ['main', '*.*.x'] - schedule: - - cron: '39 9 * * 1' - -permissions: {} - -jobs: - analyze: - name: Analyze - runs-on: 'ubuntu-latest' - permissions: - security-events: write - packages: read - strategy: - fail-fast: false - steps: - - name: Checkout repository - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 - with: - persist-credentials: false - - name: Initialize CodeQL - uses: github/codeql-action/init@ff2f1c621b7f889edc0d3c761ac2e6a3f8cdb0dd # v4.37.7 - with: - languages: javascript-typescript - build-mode: none - config-file: .github/codeql/config.yml - - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@ff2f1c621b7f889edc0d3c761ac2e6a3f8cdb0dd # v4.37.7 - with: - category: '/language:javascript-typescript' diff --git a/.github/workflows/scorecard.yml b/.github/workflows/scorecard.yml deleted file mode 100644 index 666a9b20049c..000000000000 --- a/.github/workflows/scorecard.yml +++ /dev/null @@ -1,51 +0,0 @@ -name: OpenSSF Scorecard -on: - branch_protection_rule: - schedule: - - cron: '0 2 * * 0' - push: - branches: [main] - workflow_dispatch: - -# Declare default permissions as read only. -permissions: - contents: read - -jobs: - analysis: - name: Scorecards analysis - runs-on: ubuntu-latest - permissions: - actions: read - contents: read - # Needed to upload the results to code-scanning dashboard. - security-events: write - # Needed to publish results - id-token: write - - steps: - - name: 'Checkout code' - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 - with: - persist-credentials: false - - - name: 'Run analysis' - uses: ossf/scorecard-action@2d1146689b8cda280b9bc96326124645441f03bc # v2.4.4 - with: - results_file: results.sarif - results_format: sarif - publish_results: true - - # Upload the results as artifacts. - - name: 'Upload artifact' - uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 - with: - name: SARIF file - path: results.sarif - retention-days: 5 - - # Upload the results to GitHub's code scanning dashboard. - - name: 'Upload to code-scanning' - uses: github/codeql-action/upload-sarif@ff2f1c621b7f889edc0d3c761ac2e6a3f8cdb0dd # v4.37.7 - with: - sarif_file: results.sarif From 9a1b250bbd3617ce66ff67730075dcda054b5e79 Mon Sep 17 00:00:00 2001 From: Angular Robot Date: Fri, 21 Aug 2026 10:01:24 +0000 Subject: [PATCH 330/787] build: update cross-repo angular dependencies See associated pull request for more information. --- tests/e2e/ng-snapshot/package.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/e2e/ng-snapshot/package.json b/tests/e2e/ng-snapshot/package.json index efab529ee805..29037946b4e6 100644 --- a/tests/e2e/ng-snapshot/package.json +++ b/tests/e2e/ng-snapshot/package.json @@ -3,7 +3,7 @@ "private": true, "dependencies": { "@angular/animations": "github:angular/animations-builds#ebf341ae0035dbacee781ab987f8c8336c62a6ba", - "@angular/cdk": "github:angular/cdk-builds#f764328652e240521a38d818a3f2a3b8e8c33f4a", + "@angular/cdk": "github:angular/cdk-builds#8c5c4e194a0fec929ddc81b53938866fc7359c03", "@angular/common": "github:angular/common-builds#b8fd07bfdc97d3570f90e368b60ddf3c337c8c43", "@angular/compiler": "github:angular/compiler-builds#4d1d1548fc38bd7e04330dedb782fccb8e1fb141", "@angular/compiler-cli": "github:angular/compiler-cli-builds#1d3fe381f981ce77ea6884a57359386baa2e3e64", @@ -11,8 +11,8 @@ "@angular/forms": "github:angular/forms-builds#a6874141905517d6a388112b57753a285aa7888f", "@angular/language-service": "github:angular/language-service-builds#b41c6925fa8537c63678960486bf2e5363510bfb", "@angular/localize": "github:angular/localize-builds#427a45e50ab8cbb563b736b46985fce98d6de21e", - "@angular/material": "github:angular/material-builds#7ed21d84d11c896cfc26cf493fc512b28dd9dead", - "@angular/material-moment-adapter": "github:angular/material-moment-adapter-builds#e41d169012c512aea113cad42e16671fe92a6b22", + "@angular/material": "github:angular/material-builds#59ff7da13227dac6276ba5b6dec298327c3e11ac", + "@angular/material-moment-adapter": "github:angular/material-moment-adapter-builds#ab87a2ea5a15a8dc2f5afc723211bf4d0e7c9777", "@angular/platform-browser": "github:angular/platform-browser-builds#1dac78e7b5785a885df765f02b08acab0c9b8bb4", "@angular/platform-browser-dynamic": "github:angular/platform-browser-dynamic-builds#170de259e7e98c7065da3e4d6ca4c795cd09dbf8", "@angular/platform-server": "github:angular/platform-server-builds#55db150433a54d9f83ac190e2437f1f464815632", From 204eafc0a670566a1a9c76b6ede46b9cbdcad131 Mon Sep 17 00:00:00 2001 From: Angular Robot Date: Sat, 22 Aug 2026 13:31:49 +0000 Subject: [PATCH 331/787] build: update all non-major dependencies See associated pull request for more information. --- package.json | 8 +- packages/angular/build/package.json | 18 +- packages/angular/cli/package.json | 2 +- .../angular_devkit/build_angular/package.json | 4 +- .../angular_devkit/schematics/package.json | 2 +- .../schematics_cli/package.json | 2 +- pnpm-lock.yaml | 1086 +++++++++++------ 7 files changed, 708 insertions(+), 414 deletions(-) diff --git a/package.json b/package.json index 967ecf1229c4..df3a9c868816 100644 --- a/package.json +++ b/package.json @@ -70,7 +70,7 @@ "@rollup/plugin-commonjs": "^29.0.0", "@rollup/plugin-json": "^6.1.0", "@rollup/plugin-node-resolve": "16.0.3", - "@rollup/wasm-node": "4.62.4", + "@rollup/wasm-node": "4.62.5", "@stylistic/eslint-plugin": "^5.0.0", "@tony.ganchev/eslint-plugin-header": "~3.4.0", "@types/babel__core": "7.20.5", @@ -97,7 +97,7 @@ "buffer": "6.0.3", "esbuild": "0.28.2", "esbuild-wasm": "0.28.2", - "eslint": "10.8.1", + "eslint": "10.9.0", "eslint-config-prettier": "10.1.8", "eslint-plugin-import": "2.32.0", "express": "5.2.1", @@ -117,11 +117,11 @@ "karma-jasmine-html-reporter": "~2.3.0", "karma-source-map-support": "1.4.0", "lodash": "^4.17.21", - "magic-string": "1.2.1", + "magic-string": "1.2.2", "prettier": "^3.0.0", "puppeteer": "25.8.0", "quicktype-core": "26.0.0", - "rollup": "4.62.4", + "rollup": "4.62.5", "rollup-license-plugin": "~3.2.0", "rollup-plugin-dts": "6.5.1", "rollup-plugin-sourcemaps2": "0.5.8", diff --git a/packages/angular/build/package.json b/packages/angular/build/package.json index 490f2f4b474c..0a998207cf27 100644 --- a/packages/angular/build/package.json +++ b/packages/angular/build/package.json @@ -21,7 +21,7 @@ "@ampproject/remapping": "2.3.0", "@angular-devkit/architect": "workspace:0.0.0-EXPERIMENTAL-PLACEHOLDER", "@babel/core": "8.0.1", - "@inquirer/confirm": "6.1.1", + "@inquirer/confirm": "6.2.0", "@parcel/watcher": "2.6.0", "@vitejs/plugin-basic-ssl": "2.3.0", "beasties": "0.4.3", @@ -31,18 +31,18 @@ "https-proxy-agent": "9.1.0", "jsonc-parser": "3.3.1", "listr2": "11.0.0", - "magic-string": "1.2.1", + "magic-string": "1.2.2", "mrmime": "2.0.1", - "oxc-parser": "0.145.0", + "oxc-parser": "0.146.0", "parse5-html-rewriting-stream": "8.0.1", "picomatch": "4.0.5", - "piscina": "5.3.0", - "rolldown": "1.2.4", - "sass": "1.102.0", + "piscina": "5.3.1", + "rolldown": "1.2.5", + "sass": "1.103.1", "semver": "7.8.5", "source-map-support": "0.5.21", "tinyglobby": "0.2.17", - "vite": "8.2.1", + "vite": "8.2.2", "xxhash-wasm": "1.1.0" }, "optionalDependencies": { @@ -51,13 +51,13 @@ "devDependencies": { "@angular-devkit/core": "workspace:*", "@angular/ssr": "workspace:*", - "@oxc-project/types": "0.145.0", + "@oxc-project/types": "0.146.0", "istanbul-lib-instrument": "6.0.3", "jsdom": "30.0.1", "less": "4.9.0", "ng-packagr": "22.2.0-next.3", "postcss": "8.5.26", - "rollup": "4.62.4", + "rollup": "4.62.5", "rxjs": "7.8.2", "vitest": "4.1.11" }, diff --git a/packages/angular/cli/package.json b/packages/angular/cli/package.json index 4840834b4bed..8af94acdb2f7 100644 --- a/packages/angular/cli/package.json +++ b/packages/angular/cli/package.json @@ -15,7 +15,7 @@ "@angular-devkit/architect": "workspace:0.0.0-EXPERIMENTAL-PLACEHOLDER", "@angular-devkit/core": "workspace:0.0.0-PLACEHOLDER", "@angular-devkit/schematics": "workspace:0.0.0-PLACEHOLDER", - "@inquirer/prompts": "8.5.2", + "@inquirer/prompts": "8.6.0", "@listr2/prompt-adapter-inquirer": "4.2.5", "@modelcontextprotocol/server": "2.0.0", "@schematics/angular": "workspace:0.0.0-PLACEHOLDER", diff --git a/packages/angular_devkit/build_angular/package.json b/packages/angular_devkit/build_angular/package.json index 865a0f807c2a..4b9531956a86 100644 --- a/packages/angular_devkit/build_angular/package.json +++ b/packages/angular_devkit/build_angular/package.json @@ -41,12 +41,12 @@ "open": "11.0.1", "ora": "9.4.1", "picomatch": "4.0.5", - "piscina": "5.3.0", + "piscina": "5.3.1", "postcss": "8.5.26", "postcss-loader": "8.2.1", "resolve-url-loader": "5.0.0", "rxjs": "7.8.2", - "sass": "1.102.0", + "sass": "1.103.1", "sass-loader": "17.0.0", "semver": "7.8.5", "source-map-loader": "5.0.0", diff --git a/packages/angular_devkit/schematics/package.json b/packages/angular_devkit/schematics/package.json index 708306b0e7b1..b42434d7994f 100644 --- a/packages/angular_devkit/schematics/package.json +++ b/packages/angular_devkit/schematics/package.json @@ -15,7 +15,7 @@ "dependencies": { "@angular-devkit/core": "workspace:0.0.0-PLACEHOLDER", "jsonc-parser": "3.3.1", - "magic-string": "1.2.1", + "magic-string": "1.2.2", "ora": "9.4.1", "rxjs": "7.8.2" } diff --git a/packages/angular_devkit/schematics_cli/package.json b/packages/angular_devkit/schematics_cli/package.json index 97ab57c4fce7..93c7f0b014e3 100644 --- a/packages/angular_devkit/schematics_cli/package.json +++ b/packages/angular_devkit/schematics_cli/package.json @@ -18,6 +18,6 @@ "dependencies": { "@angular-devkit/core": "workspace:0.0.0-PLACEHOLDER", "@angular-devkit/schematics": "workspace:0.0.0-PLACEHOLDER", - "@inquirer/prompts": "8.5.2" + "@inquirer/prompts": "8.6.0" } } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index cb19bf3d6971..d396ec5afaf6 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -78,34 +78,34 @@ importers: version: 0.28.0 '@eslint/compat': specifier: 2.1.0 - version: 2.1.0(eslint@10.8.1(jiti@2.7.0)(supports-color@11.0.0)) + version: 2.1.0(eslint@10.9.0(jiti@2.7.0)(supports-color@11.0.0)) '@eslint/eslintrc': specifier: 3.3.6 version: 3.3.6(supports-color@11.0.0) '@eslint/js': specifier: 10.0.1 - version: 10.0.1(eslint@10.8.1(jiti@2.7.0)(supports-color@11.0.0)) + version: 10.0.1(eslint@10.9.0(jiti@2.7.0)(supports-color@11.0.0)) '@rollup/plugin-alias': specifier: ^6.0.0 - version: 6.0.0(rollup@4.62.4) + version: 6.0.0(rollup@4.62.5) '@rollup/plugin-commonjs': specifier: ^29.0.0 - version: 29.0.3(rollup@4.62.4) + version: 29.0.3(rollup@4.62.5) '@rollup/plugin-json': specifier: ^6.1.0 - version: 6.1.0(rollup@4.62.4) + version: 6.1.0(rollup@4.62.5) '@rollup/plugin-node-resolve': specifier: 16.0.3 - version: 16.0.3(rollup@4.62.4) + version: 16.0.3(rollup@4.62.5) '@rollup/wasm-node': - specifier: 4.62.4 - version: 4.62.4 + specifier: 4.62.5 + version: 4.62.5 '@stylistic/eslint-plugin': specifier: ^5.0.0 - version: 5.10.0(eslint@10.8.1(jiti@2.7.0)(supports-color@11.0.0)) + version: 5.10.0(eslint@10.9.0(jiti@2.7.0)(supports-color@11.0.0)) '@tony.ganchev/eslint-plugin-header': specifier: ~3.4.0 - version: 3.4.4(eslint@10.8.1(jiti@2.7.0)(supports-color@11.0.0)) + version: 3.4.4(eslint@10.9.0(jiti@2.7.0)(supports-color@11.0.0)) '@types/babel__core': specifier: 7.20.5 version: 7.20.5 @@ -162,10 +162,10 @@ importers: version: 21.0.3 '@typescript-eslint/eslint-plugin': specifier: 8.67.0 - version: 8.67.0(@typescript-eslint/parser@8.67.0(eslint@10.8.1(jiti@2.7.0)(supports-color@11.0.0))(supports-color@11.0.0)(typescript@6.0.3))(eslint@10.8.1(jiti@2.7.0)(supports-color@11.0.0))(supports-color@11.0.0)(typescript@6.0.3) + version: 8.67.0(@typescript-eslint/parser@8.67.0(eslint@10.9.0(jiti@2.7.0)(supports-color@11.0.0))(supports-color@11.0.0)(typescript@6.0.3))(eslint@10.9.0(jiti@2.7.0)(supports-color@11.0.0))(supports-color@11.0.0)(typescript@6.0.3) '@typescript-eslint/parser': specifier: 8.67.0 - version: 8.67.0(eslint@10.8.1(jiti@2.7.0)(supports-color@11.0.0))(supports-color@11.0.0)(typescript@6.0.3) + version: 8.67.0(eslint@10.9.0(jiti@2.7.0)(supports-color@11.0.0))(supports-color@11.0.0)(typescript@6.0.3) ajv: specifier: 8.20.0 version: 8.20.0 @@ -179,14 +179,14 @@ importers: specifier: 0.28.2 version: 0.28.2 eslint: - specifier: 10.8.1 - version: 10.8.1(jiti@2.7.0)(supports-color@11.0.0) + specifier: 10.9.0 + version: 10.9.0(jiti@2.7.0)(supports-color@11.0.0) eslint-config-prettier: specifier: 10.1.8 - version: 10.1.8(eslint@10.8.1(jiti@2.7.0)(supports-color@11.0.0)) + version: 10.1.8(eslint@10.9.0(jiti@2.7.0)(supports-color@11.0.0)) eslint-plugin-import: specifier: 2.32.0 - version: 2.32.0(@typescript-eslint/parser@8.67.0(eslint@10.8.1(jiti@2.7.0)(supports-color@11.0.0))(supports-color@11.0.0)(typescript@6.0.3))(eslint@10.8.1(jiti@2.7.0)(supports-color@11.0.0))(supports-color@11.0.0) + version: 2.32.0(@typescript-eslint/parser@8.67.0(eslint@10.9.0(jiti@2.7.0)(supports-color@11.0.0))(supports-color@11.0.0)(typescript@6.0.3))(eslint@10.9.0(jiti@2.7.0)(supports-color@11.0.0))(supports-color@11.0.0) express: specifier: 5.2.1 version: 5.2.1(supports-color@11.0.0) @@ -239,8 +239,8 @@ importers: specifier: ^4.17.21 version: 4.18.1 magic-string: - specifier: 1.2.1 - version: 1.2.1 + specifier: 1.2.2 + version: 1.2.2 prettier: specifier: ^3.0.0 version: 3.9.6 @@ -251,17 +251,17 @@ importers: specifier: 26.0.0 version: 26.0.0 rollup: - specifier: 4.62.4 - version: 4.62.4 + specifier: 4.62.5 + version: 4.62.5 rollup-license-plugin: specifier: ~3.2.0 version: 3.2.1 rollup-plugin-dts: specifier: 6.5.1 - version: 6.5.1(rollup@4.62.4)(typescript@6.0.3) + version: 6.5.1(rollup@4.62.5)(typescript@6.0.3) rollup-plugin-sourcemaps2: specifier: 0.5.8 - version: 0.5.8(@types/node@22.20.1)(rollup@4.62.4) + version: 0.5.8(@types/node@22.20.1)(rollup@4.62.5) semver: specifier: 7.8.5 version: 7.8.5 @@ -321,7 +321,7 @@ importers: version: 7.8.2 vitest: specifier: 4.1.11 - version: 4.1.11(@opentelemetry/api@1.9.1)(@types/node@22.20.1)(@vitest/coverage-v8@4.1.11)(esbuild@0.28.2)(jiti@2.7.0)(jsdom@30.0.1)(less@4.9.0(supports-color@11.0.0))(sass@1.102.0)(terser@5.50.0)(tsx@4.23.12)(yaml@2.9.0) + version: 4.1.11(@opentelemetry/api@1.9.1)(@types/node@22.20.1)(@vitest/coverage-v8@4.1.11)(esbuild@0.28.2)(jiti@2.7.0)(jsdom@30.0.1)(less@4.9.0(supports-color@11.0.0))(sass@1.103.1)(terser@5.50.0)(tsx@4.23.12)(yaml@2.9.0) packages/angular/build: dependencies: @@ -335,14 +335,14 @@ importers: specifier: 8.0.1 version: 8.0.1 '@inquirer/confirm': - specifier: 6.1.1 - version: 6.1.1(@types/node@22.20.1) + specifier: 6.2.0 + version: 6.2.0(@types/node@22.20.1) '@parcel/watcher': specifier: 2.6.0 version: 2.6.0 '@vitejs/plugin-basic-ssl': specifier: 2.3.0 - version: 2.3.0(vite@8.2.1(@types/node@22.20.1)(esbuild@0.28.2)(jiti@2.7.0)(less@4.9.0(supports-color@11.0.0))(sass@1.102.0)(terser@5.50.0)(tsx@4.23.12)(yaml@2.9.0)) + version: 2.3.0(vite@8.2.2(@types/node@22.20.1)(esbuild@0.28.2)(jiti@2.7.0)(less@4.9.0(supports-color@11.0.0))(sass@1.103.1)(terser@5.50.0)(tsx@4.23.12)(yaml@2.9.0)) beasties: specifier: 0.4.3 version: 0.4.3 @@ -365,14 +365,14 @@ importers: specifier: 11.0.0 version: 11.0.0 magic-string: - specifier: 1.2.1 - version: 1.2.1 + specifier: 1.2.2 + version: 1.2.2 mrmime: specifier: 2.0.1 version: 2.0.1 oxc-parser: - specifier: 0.145.0 - version: 0.145.0 + specifier: 0.146.0 + version: 0.146.0 parse5-html-rewriting-stream: specifier: 8.0.1 version: 8.0.1 @@ -380,14 +380,14 @@ importers: specifier: 4.0.5 version: 4.0.5 piscina: - specifier: 5.3.0 - version: 5.3.0 + specifier: 5.3.1 + version: 5.3.1 rolldown: - specifier: 1.2.4 - version: 1.2.4 + specifier: 1.2.5 + version: 1.2.5 sass: - specifier: 1.102.0 - version: 1.102.0 + specifier: 1.103.1 + version: 1.103.1 semver: specifier: 7.8.5 version: 7.8.5 @@ -398,8 +398,8 @@ importers: specifier: 0.2.17 version: 0.2.17 vite: - specifier: 8.2.1 - version: 8.2.1(@types/node@22.20.1)(esbuild@0.28.2)(jiti@2.7.0)(less@4.9.0(supports-color@11.0.0))(sass@1.102.0)(terser@5.50.0)(tsx@4.23.12)(yaml@2.9.0) + specifier: 8.2.2 + version: 8.2.2(@types/node@22.20.1)(esbuild@0.28.2)(jiti@2.7.0)(less@4.9.0(supports-color@11.0.0))(sass@1.103.1)(terser@5.50.0)(tsx@4.23.12)(yaml@2.9.0) xxhash-wasm: specifier: 1.1.0 version: 1.1.0 @@ -411,8 +411,8 @@ importers: specifier: workspace:* version: link:../ssr '@oxc-project/types': - specifier: 0.145.0 - version: 0.145.0 + specifier: 0.146.0 + version: 0.146.0 istanbul-lib-instrument: specifier: 6.0.3 version: 6.0.3(supports-color@11.0.0) @@ -429,14 +429,14 @@ importers: specifier: 8.5.26 version: 8.5.26 rollup: - specifier: 4.62.4 - version: 4.62.4 + specifier: 4.62.5 + version: 4.62.5 rxjs: specifier: 7.8.2 version: 7.8.2 vitest: specifier: 4.1.11 - version: 4.1.11(@opentelemetry/api@1.9.1)(@types/node@22.20.1)(@vitest/coverage-v8@4.1.11)(esbuild@0.28.2)(jiti@2.7.0)(jsdom@30.0.1)(less@4.9.0(supports-color@11.0.0))(sass@1.102.0)(terser@5.50.0)(tsx@4.23.12)(yaml@2.9.0) + version: 4.1.11(@opentelemetry/api@1.9.1)(@types/node@22.20.1)(@vitest/coverage-v8@4.1.11)(esbuild@0.28.2)(jiti@2.7.0)(jsdom@30.0.1)(less@4.9.0(supports-color@11.0.0))(sass@1.103.1)(terser@5.50.0)(tsx@4.23.12)(yaml@2.9.0) optionalDependencies: lmdb: specifier: 3.5.6 @@ -454,11 +454,11 @@ importers: specifier: workspace:0.0.0-PLACEHOLDER version: link:../../angular_devkit/schematics '@inquirer/prompts': - specifier: 8.5.2 - version: 8.5.2(@types/node@22.20.1) + specifier: 8.6.0 + version: 8.6.0(@types/node@22.20.1) '@listr2/prompt-adapter-inquirer': specifier: 4.2.5 - version: 4.2.5(@inquirer/prompts@8.5.2(@types/node@22.20.1))(@types/node@22.20.1)(listr2@11.0.0) + version: 4.2.5(@inquirer/prompts@8.6.0(@types/node@22.20.1))(@types/node@22.20.1)(listr2@11.0.0) '@modelcontextprotocol/server': specifier: 2.0.0 version: 2.0.0 @@ -650,8 +650,8 @@ importers: specifier: 4.0.5 version: 4.0.5 piscina: - specifier: 5.3.0 - version: 5.3.0 + specifier: 5.3.1 + version: 5.3.1 postcss: specifier: 8.5.26 version: 8.5.26 @@ -665,11 +665,11 @@ importers: specifier: 7.8.2 version: 7.8.2 sass: - specifier: 1.102.0 - version: 1.102.0 + specifier: 1.103.1 + version: 1.103.1 sass-loader: specifier: 17.0.0 - version: 17.0.0(sass@1.102.0)(webpack@5.109.2(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.26)(uglify-js@3.19.3)) + version: 17.0.0(sass@1.103.1)(webpack@5.109.2(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.26)(uglify-js@3.19.3)) semver: specifier: 7.8.5 version: 7.8.5 @@ -777,8 +777,8 @@ importers: specifier: 3.3.1 version: 3.3.1 magic-string: - specifier: 1.2.1 - version: 1.2.1 + specifier: 1.2.2 + version: 1.2.2 ora: specifier: 9.4.1 version: 9.4.1 @@ -795,8 +795,8 @@ importers: specifier: workspace:0.0.0-PLACEHOLDER version: link:../schematics '@inquirer/prompts': - specifier: 8.5.2 - version: 8.5.2(@types/node@22.20.1) + specifier: 8.6.0 + version: 8.6.0(@types/node@22.20.1) packages/ngtools/webpack: devDependencies: @@ -2163,8 +2163,17 @@ packages: '@types/node': optional: true - '@inquirer/confirm@6.1.1': - resolution: {integrity: sha512-eb8DBZcz/2qHWQda4rk2JiQk5h9QV/cVHi1yjt0f69WFZMRFn0sJTye3EAP8icut8UDMjQPsaH5KbcOogefrFQ==} + '@inquirer/checkbox@5.2.2': + resolution: {integrity: sha512-Y5/bAScMy5Y+9isCx0SKbyJebMCaXXX5em0kxkj115eZNscgV9srOHrgyfS0e5xAVymIfOh9piYBKDILktsMMg==} + engines: {node: '>=23.5.0 || ^22.13.0 || ^20.17.0'} + peerDependencies: + '@types/node': '>=18' + peerDependenciesMeta: + '@types/node': + optional: true + + '@inquirer/confirm@6.2.0': + resolution: {integrity: sha512-SKXarWrYhtpqOEctf9XGCGy29QjsvJAM0Aq9ZR9z4Ns94OmpqudOly+aSEfNqUf9SwsQaUgY9+Z8hyzG0xX8fw==} engines: {node: '>=23.5.0 || ^22.13.0 || ^20.17.0'} peerDependencies: '@types/node': '>=18' @@ -2181,6 +2190,15 @@ packages: '@types/node': optional: true + '@inquirer/core@12.0.0': + resolution: {integrity: sha512-+nnvFEXIB08CZNVXpvW3B+zHW96QXvGUjNKJ8NJIPqAZi5Kd4WhYt2S3C234ReepG1qw2HOlEUbjYVHBowXObA==} + engines: {node: '>=23.5.0 || ^22.13.0 || ^20.17.0'} + peerDependencies: + '@types/node': '>=18' + peerDependenciesMeta: + '@types/node': + optional: true + '@inquirer/editor@5.2.2': resolution: {integrity: sha512-ZRVd/oD+sYsUd5zVm0NflqEzlqfYCyHNsqkHl2oWXEUHs12tCbcSFi+wVFEvD8+LGRaMUsVrE7qeo6lSG/S1Vg==} engines: {node: '>=23.5.0 || ^22.13.0 || ^20.17.0'} @@ -2190,6 +2208,15 @@ packages: '@types/node': optional: true + '@inquirer/editor@5.3.0': + resolution: {integrity: sha512-nnsP/IdJ8s83q7ZuObmgn12QM+uLCkab9E0Oordojbn62WUg1c+v9Ou/F/057pgh0ppX0W+Hj5bO/Dp5hsxQtA==} + engines: {node: '>=23.5.0 || ^22.13.0 || ^20.17.0'} + peerDependencies: + '@types/node': '>=18' + peerDependenciesMeta: + '@types/node': + optional: true + '@inquirer/expand@5.1.1': resolution: {integrity: sha512-YmQpenjbFSHAK3sOd44puHh3V1KXXr+JiNpUztoSQ4drLh2rTVzTap/YtlAVu/5xavifIlBfNEzJ/neZJ1a/1g==} engines: {node: '>=23.5.0 || ^22.13.0 || ^20.17.0'} @@ -2199,6 +2226,15 @@ packages: '@types/node': optional: true + '@inquirer/expand@5.1.2': + resolution: {integrity: sha512-OWIH1IyyWqEKIyqC9Xy+Bnga7NkGMovFdo4atYZMUOTRqf6rO2WCv9E/1MyzvOErDBCxs+9UFliRUDc50xs/jw==} + engines: {node: '>=23.5.0 || ^22.13.0 || ^20.17.0'} + peerDependencies: + '@types/node': '>=18' + peerDependenciesMeta: + '@types/node': + optional: true + '@inquirer/external-editor@3.0.3': resolution: {integrity: sha512-6thf5I8q7lZwzGLAxPaaGEREEkZ3nyePPDQ1oyobblxmEE8mqTLguScP7pDjUTAibiyb4hfXl+qjUEJ+di/aNA==} engines: {node: '>=23.5.0 || ^22.13.0 || ^20.17.0'} @@ -2208,10 +2244,23 @@ packages: '@types/node': optional: true + '@inquirer/external-editor@3.0.4': + resolution: {integrity: sha512-tZbbaK2ovq6vlrRBNQvjrypmrED/p5x2ncIHQ79cD55tei3dD96v5glMMA+6tiq7K104i/25DVYKWVPJuV6ptA==} + engines: {node: '>=23.5.0 || ^22.13.0 || ^20.17.0'} + peerDependencies: + '@types/node': '>=18' + peerDependenciesMeta: + '@types/node': + optional: true + '@inquirer/figures@2.0.7': resolution: {integrity: sha512-aJ8TBPOGB6f/2qziPfElISTCEd5XOYTFckA2SGjhNmiKzfK/u4ot3v0DUzGVdUnKjN10EqnnEPck36BkyfLnJw==} engines: {node: '>=23.5.0 || ^22.13.0 || ^20.17.0'} + '@inquirer/figures@2.0.8': + resolution: {integrity: sha512-tApbon79GM9ry56ja/Ud3SY2CL4TQsao9fIwDQbgTeNY55025GdMzQ2+UdegV/lx51VNGUB59M0v0nMpybYY4Q==} + engines: {node: '>=23.5.0 || ^22.13.0 || ^20.17.0'} + '@inquirer/input@5.1.2': resolution: {integrity: sha512-9K/DDBSQpOyZSkt6sOVP9Vo0TR7atX2kuILsUu0x3wVcVbe97lJwIJKMLdMw25tDYuXl/qp6erT0Xs1rfmcfZg==} engines: {node: '>=23.5.0 || ^22.13.0 || ^20.17.0'} @@ -2221,6 +2270,15 @@ packages: '@types/node': optional: true + '@inquirer/input@5.1.3': + resolution: {integrity: sha512-F/BZHtyEzP+HO+IGVd4AjBRgvX/ywm42bx8S0+dENk2YclzE9tJ3X/15THwtT6ehApmKvdYDMsVTuyyDod0gOQ==} + engines: {node: '>=23.5.0 || ^22.13.0 || ^20.17.0'} + peerDependencies: + '@types/node': '>=18' + peerDependenciesMeta: + '@types/node': + optional: true + '@inquirer/number@4.1.1': resolution: {integrity: sha512-XF4IXAbPnGPgw0wsbC/i2tPcyfdZgDpUlhsqU0SfT4IRIGWha6Xm9VRgN5yYxJq+jnyXlfXI/nQ3ulfk0iEICA==} engines: {node: '>=23.5.0 || ^22.13.0 || ^20.17.0'} @@ -2230,6 +2288,15 @@ packages: '@types/node': optional: true + '@inquirer/number@4.2.0': + resolution: {integrity: sha512-ew+fSDijsQ/WhD4TV3XLb+if400cDuzTzHfGR8sTNBXkK9CYDWoGE8fhaO8GbT312pNv1AJEOsDxy/z/HVettA==} + engines: {node: '>=23.5.0 || ^22.13.0 || ^20.17.0'} + peerDependencies: + '@types/node': '>=18' + peerDependenciesMeta: + '@types/node': + optional: true + '@inquirer/password@5.1.1': resolution: {integrity: sha512-3XBfF7DAsp5qeDsvN5Rd1HmbNokVvEQoUM0QLrRcybC9nX96w3Pbmu7qUsb3IT3J3jBvs2+mTXaKHOUsgHMLzg==} engines: {node: '>=23.5.0 || ^22.13.0 || ^20.17.0'} @@ -2239,6 +2306,15 @@ packages: '@types/node': optional: true + '@inquirer/password@5.1.2': + resolution: {integrity: sha512-nSdufycW8xynEVssFkNQEYIzTySilog0UlfOVRwh3pXzPSk4frXUT2jZWjHnKae6RU9PaoF9wfy1pGwewQuqGw==} + engines: {node: '>=23.5.0 || ^22.13.0 || ^20.17.0'} + peerDependencies: + '@types/node': '>=18' + peerDependenciesMeta: + '@types/node': + optional: true + '@inquirer/prompts@8.5.2': resolution: {integrity: sha512-IYR/3C/paEVVQYQvdDlFZVjRCJVYHHON0XXMH91KO9GSxs0TdKYWlUdvfQl2EfAHDxUaN3IBffkE/BDTh5nJ6g==} engines: {node: '>=23.5.0 || ^22.13.0 || ^20.17.0'} @@ -2248,6 +2324,15 @@ packages: '@types/node': optional: true + '@inquirer/prompts@8.6.0': + resolution: {integrity: sha512-WgBVDRy3IQ4v9XMCpQ1YDGpso2PcMUxYJzZdH4Nt4t0eoXhEPmOCh5iZbXbR4GTbdUB9VPWBbJB12rkjbaGDCw==} + engines: {node: '>=23.5.0 || ^22.13.0 || ^20.17.0'} + peerDependencies: + '@types/node': '>=18' + peerDependenciesMeta: + '@types/node': + optional: true + '@inquirer/rawlist@5.3.1': resolution: {integrity: sha512-QqdTqQddL3qPX/PPrjobpsO25NZ4dWXgTLenrR445L2ptLEYE6Z+PD5c5CNDJNx4ugRgELAIpSIJxZaO2jJ2Og==} engines: {node: '>=23.5.0 || ^22.13.0 || ^20.17.0'} @@ -2257,6 +2342,15 @@ packages: '@types/node': optional: true + '@inquirer/rawlist@5.3.2': + resolution: {integrity: sha512-oPSKrYK1X1bMkjXDzIKHUkJp195LFSfgbnVtXnjSKGFjrCbS6I+wyvfAZTwKE9BSt3HwWgfD7JfsXALBgCogzQ==} + engines: {node: '>=23.5.0 || ^22.13.0 || ^20.17.0'} + peerDependencies: + '@types/node': '>=18' + peerDependenciesMeta: + '@types/node': + optional: true + '@inquirer/search@4.2.1': resolution: {integrity: sha512-xJj8QWKRSrfKoBIITLZK61dD3zwo0Rz11fgDImku30/Oe81zMdIdGgrLY2h6RkJ+KZ/GhNYIRMKnH/62qBTA5g==} engines: {node: '>=23.5.0 || ^22.13.0 || ^20.17.0'} @@ -2266,6 +2360,15 @@ packages: '@types/node': optional: true + '@inquirer/search@4.3.0': + resolution: {integrity: sha512-HFxXE5w727ctSUcAwrDquftJGjMgu36OeV5SHEXMlr2j/ahzmRX9xSEeVolV8tzYnTf45cg6vGkdMMRdm3RPhQ==} + engines: {node: '>=23.5.0 || ^22.13.0 || ^20.17.0'} + peerDependencies: + '@types/node': '>=18' + peerDependenciesMeta: + '@types/node': + optional: true + '@inquirer/select@5.2.1': resolution: {integrity: sha512-FlDndEUww8m7BfukO2nJa25vhD+H5jxxCv4oGioKqzyWz3nPHhhw4LKdYRSlXuAx7DsdWia7iyaBPKKS95Evfw==} engines: {node: '>=23.5.0 || ^22.13.0 || ^20.17.0'} @@ -2275,6 +2378,15 @@ packages: '@types/node': optional: true + '@inquirer/select@5.2.2': + resolution: {integrity: sha512-RkI8dRHWt+bh04oLixvF1kFzKC7e5rqJoHKkzcqSHATebBXFC6GmrT8ddbVkgSzLV0HnHs2cPFuBINr8otij8Q==} + engines: {node: '>=23.5.0 || ^22.13.0 || ^20.17.0'} + peerDependencies: + '@types/node': '>=18' + peerDependenciesMeta: + '@types/node': + optional: true + '@inquirer/type@4.0.7': resolution: {integrity: sha512-t28inv14nMQ1PhKpsJPY+kEs/c00qzeCOS2gTNRyTjG5d6qsVA2fItxW4hkvGZ5lvanGLdtCzVIx5dwdRpN1+g==} engines: {node: '>=23.5.0 || ^22.13.0 || ^20.17.0'} @@ -2789,124 +2901,124 @@ packages: resolution: {integrity: sha512-eSYWTm620tTk45EKSedaUL8MFYI8hW164hIXsgIHyxu3VobUB3fFCu5t0hQby6OoWRPsG1KkKUG2M5UadiLiVg==} engines: {node: '>=14'} - '@oxc-parser/binding-android-arm-eabi@0.145.0': - resolution: {integrity: sha512-3CBAqOv61gR/n/t13hr681uFHYm0dQu3bbsEJtsMWYtLCQ8lSYjuJCIlroD4fbI0wz44jpjw3N+L7CwBCzYHyg==} + '@oxc-parser/binding-android-arm-eabi@0.146.0': + resolution: {integrity: sha512-jBCZIsff/9J/zdK1KSKZREScXOtRE4wYO+MUjrE+5NHGdsslrP4biJA9QJyKwErwS8lkwxH6Z537HaL4CQr0ow==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm] os: [android] - '@oxc-parser/binding-android-arm64@0.145.0': - resolution: {integrity: sha512-VOinEGxVMIWI+67MJw+MKmaLDC6X3D4dNDLKJX4fidJ7sO0hsevYHaKBCqLozbg9Ny+1yb25yagJMQAw1U/jQA==} + '@oxc-parser/binding-android-arm64@0.146.0': + resolution: {integrity: sha512-BVwj6sVmgD9j5F+R5B+13pYQKOCmew+3myS19wcG5e+AeZu5ybBLEfcaKueC8MhvjtwL2Suh2tQE/Ywop2Z8rA==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [android] - '@oxc-parser/binding-darwin-arm64@0.145.0': - resolution: {integrity: sha512-es9sOpZM3cdbXqqLHZ+5PF+6AyKnd2Z6gVJGvmXraX9jGz249Sb1V/Lf42UEuQPZsjp5iXMntxO4fWqHMJ2nRg==} + '@oxc-parser/binding-darwin-arm64@0.146.0': + resolution: {integrity: sha512-jQGIM4zEEvvuypbBcoeoWuigRfP6R8Ow/9gfDzVoYkv5mFyVPbIePNQnV752jUynfty0nDxarIpML+7Q/MyMPg==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [darwin] - '@oxc-parser/binding-darwin-x64@0.145.0': - resolution: {integrity: sha512-grIPJYT5aTB3IUp7iZz2grzzUQaTnnwIrb81tMWdFTzkCQQcnz0mWrXXEMWxSWidYp4a+DzI7ApLBEDuw2Xyhw==} + '@oxc-parser/binding-darwin-x64@0.146.0': + resolution: {integrity: sha512-quDy3cvW1712l6W+qe1/xWRym6STOuGJmFzRIg5StXVJglsbqrCpHfw9PyqPs0hQeOAjAEO1USrjPaIvHiRKQw==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [darwin] - '@oxc-parser/binding-freebsd-x64@0.145.0': - resolution: {integrity: sha512-NimvYhXzF5QNIN42C1W339UNHYr5ESub4Th362q2u9NkSiGZ2X9exUshdmyRbIVIlZzo+29HIivhebkWY5g0SQ==} + '@oxc-parser/binding-freebsd-x64@0.146.0': + resolution: {integrity: sha512-wx/p/9phlX4VbYk671G4WewST3pysXNQfZRx4gx69QIz0/uW2O3MCnnEQh4il6l2lYr0EDAq3kFYovIw68CXHw==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [freebsd] - '@oxc-parser/binding-linux-arm-gnueabihf@0.145.0': - resolution: {integrity: sha512-697j9HvY/HwfhPESnNop7qUBjyoJKl8Q9YrHQgcGhFcoQbcelxAgVSRVv5b3a9lndvjQ6KcV0oFrKzXqLYA6xg==} + '@oxc-parser/binding-linux-arm-gnueabihf@0.146.0': + resolution: {integrity: sha512-W9nzfbWH8Z6cIaBj6Rh/eVgymFkZ2MaOV0rQruKTLYKLAZADo9JlOmBml6Dq2QbChtmuc3DKDL42KDHaQFX8yQ==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm] os: [linux] - '@oxc-parser/binding-linux-arm-musleabihf@0.145.0': - resolution: {integrity: sha512-gnKpdjlnPet71TY18hLs29f0lQmt5dFig6w/hEhaUljGJSTri8n5In6CTgHnF2UFG9oiBXfqnf9pHUUrJpO5cQ==} + '@oxc-parser/binding-linux-arm-musleabihf@0.146.0': + resolution: {integrity: sha512-S5X1mEvTLBTl+xt7bRlr1n6qI+OTy1EaRkYyd4EQgEZqV7i53fQa1I72OqR0IwSQKVwh6TZPkzDcsN7fS9MynQ==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm] os: [linux] - '@oxc-parser/binding-linux-arm64-gnu@0.145.0': - resolution: {integrity: sha512-2NCBH6l3J2k4YQIYZzcGNZq7J0+/kub//5+cXWTdhtc6UW47mGHpogVm7fwPhHU+Bw7iw9SBm5V0qlGFj6ZY7w==} + '@oxc-parser/binding-linux-arm64-gnu@0.146.0': + resolution: {integrity: sha512-Br9UB4nnecVfj/Vp+JiJnJo2wIJtwaOm+uN7MwWKF5cx10P816urucmksG/iG2OeL7hfZ4h5fCmePrLU6TocfQ==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [linux] libc: [glibc] - '@oxc-parser/binding-linux-arm64-musl@0.145.0': - resolution: {integrity: sha512-ih5NUVKrWOZN54DLGhP0YyCF2NjXl7stGiK73+xI4baFv2fL7n3K5BrUAjVDi/w73kCnwS3pJ/V/X8n027n/Yw==} + '@oxc-parser/binding-linux-arm64-musl@0.146.0': + resolution: {integrity: sha512-5AP+od9VGhRyCwswTfuD0jSDfIcWptEBC+K0LWmXsUJ9BPVF3KbhsjeoV+9tijX6g5is0w4H8DUV7NkOJoOVVA==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [linux] libc: [musl] - '@oxc-parser/binding-linux-ppc64-gnu@0.145.0': - resolution: {integrity: sha512-pLOsK77bB2T0Qu+slW/kRI3zLfBAnbbfubGlzN5GROMbrzt8axAtx+0MZcGRuRX7LNDYzqM+ZeBLQbfYUg4rzQ==} + '@oxc-parser/binding-linux-ppc64-gnu@0.146.0': + resolution: {integrity: sha512-Qz3jc1qgvU9B9vQu3jAJcxKlGX7zYRtKs8LPYtQi8cmirhtYcX6XvXseESaDFbi1L+SorXhjRQ/2npEX85kKBw==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [ppc64] os: [linux] libc: [glibc] - '@oxc-parser/binding-linux-riscv64-gnu@0.145.0': - resolution: {integrity: sha512-dbS9FC4ziuyNNyFErVM6+bREi2+CbqUA7/xrOajcgnNUeX9QTsleQbOUJ2P6lCoT483H0ikg+gND4unNrygS9g==} + '@oxc-parser/binding-linux-riscv64-gnu@0.146.0': + resolution: {integrity: sha512-Mfmg18lOZ1IWJJJuHi1ZsMLunqNVeLEh3Byuw+Aa8dYo7qOrZOMZQz1gFgAeNga5/Z5jjRuIKuIdo9aO7HYMdg==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [riscv64] os: [linux] libc: [glibc] - '@oxc-parser/binding-linux-riscv64-musl@0.145.0': - resolution: {integrity: sha512-GtmdBGsNi+yCvxiJ4Bnrpo8+azePTedFqghDRtvKucyAGXZhqmuPRbqTHacfTGo1ukgFFqrzNlFxtXUnYjUjPA==} + '@oxc-parser/binding-linux-riscv64-musl@0.146.0': + resolution: {integrity: sha512-6OdXwYnzbwYcnUH8f0LYauLNitjIcgDR/CDA/wcZ2whwJwVflGtCLF3+3HOXgs/SESnpQCWXr7Q/z9muLJ5bmQ==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [riscv64] os: [linux] libc: [musl] - '@oxc-parser/binding-linux-s390x-gnu@0.145.0': - resolution: {integrity: sha512-U5uJHvwWbDV+DvVugJRA/JkKTmikONTBDtDLFNFQTfEQOBVMs6itFiBGM3IxFIJr0/uVlIKMTDQSireOQLXvpg==} + '@oxc-parser/binding-linux-s390x-gnu@0.146.0': + resolution: {integrity: sha512-BilV4Ei84A0m6r1v+LmgVrfUMbAz33IXRooVw/BQNDExUvGGNLrk6NWeot+ve99bRidTZdwWuzBHgxWCnSSa9Q==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [s390x] os: [linux] libc: [glibc] - '@oxc-parser/binding-linux-x64-gnu@0.145.0': - resolution: {integrity: sha512-hz3a08R2fWvj/oGmNeQ9Us9AUfyYLagbNMh7nwdBbL/JAK88gu8i3hZg/Zv5xU4EdrFjiFXGmadLOFcZk/AlvA==} + '@oxc-parser/binding-linux-x64-gnu@0.146.0': + resolution: {integrity: sha512-RaMfGIpWOa87u3aD87drbPgisy7Nv6gIdjRFw6msIDKO+3FmcOTw+vpp4hVANhUIzpQta2EAsmYQRrqeprZTmQ==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [linux] libc: [glibc] - '@oxc-parser/binding-linux-x64-musl@0.145.0': - resolution: {integrity: sha512-im2ckBQcAnIN0qiGUOPuftIqmehwXSRx9q8Bb8gaFvjxoLI1lmW7bUABcr0YixVUae0j23+qiy/3g8DYr0Iqpg==} + '@oxc-parser/binding-linux-x64-musl@0.146.0': + resolution: {integrity: sha512-0bzF60jfQRsJ9TJOIHK+wSUirenJAyWCdP9z3P6LMS0znD4Gf7WYOiv7niONVOpRnlGjzMPd4kqgOJfCDLQAQg==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [linux] libc: [musl] - '@oxc-parser/binding-openharmony-arm64@0.145.0': - resolution: {integrity: sha512-Ban4OInSMDkvzkaoROeg3AJVrYrlqjDA/GfJuLg0QL0MCVixj1WBy5lELiBxvHSTHR9KDo/0MzKZeHWeZ9cW0w==} + '@oxc-parser/binding-openharmony-arm64@0.146.0': + resolution: {integrity: sha512-O1gxUFt5FUgyFVUQK2BhZNwv7jLsqLR8uBANOhpYE5D5q+eCvcry7RvQT3DgKpWP1XRYB5UsbQGHHcwchEKb+w==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [openharmony] - '@oxc-parser/binding-win32-arm64-msvc@0.145.0': - resolution: {integrity: sha512-mbTsMQKGpbdhjtaJUwhLyjoWRb0iIyIWuaguYQbS7IYsSo6KeRJQ3pb2P/9ZYYoQB9pV1oY/nD0SXTGFcfgIOA==} + '@oxc-parser/binding-win32-arm64-msvc@0.146.0': + resolution: {integrity: sha512-i46zYS0TTCt+oaXaDx4mKxuXo+h8OBWI12XFatRm5I9/l2WKhp4TQ6VAjw0r1NMRiQQZ9dwQlRyQNhyTkOaINg==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [win32] - '@oxc-parser/binding-win32-ia32-msvc@0.145.0': - resolution: {integrity: sha512-syaw++GhlFT4aJ9yaYgNKxUVAfE4cnP5Wk3iy9d3lLNwzWmmgXTb6sqQrcwVUq3Tv4RXAOZvr33bVe7C28G2Vg==} + '@oxc-parser/binding-win32-ia32-msvc@0.146.0': + resolution: {integrity: sha512-v1bb+ma2oKXwh4NHAg2NQwe9ORXFBDSCEkuO1qC4Rzm8EXcQdNhiJHpTNfulZ2P+1QpYUB6QYupW4mgMVom/tA==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [ia32] os: [win32] - '@oxc-parser/binding-win32-x64-msvc@0.145.0': - resolution: {integrity: sha512-dIZyXCxsOLILtDYeUGtiHN8GqgaT3J5FsuGI57YqWJg7EDZWBT+oFH2N+AjYMasupru3zy5K3ttCxxAF2Cscjg==} + '@oxc-parser/binding-win32-x64-msvc@0.146.0': + resolution: {integrity: sha512-uT8N1/qdNSGonvW1O2kZYNczqb/VYfnj5dpUy1FmedOPodj3MNFNWhAJkMZlI5u8xuTRtrpTccnr0U5HAMVRjQ==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [win32] @@ -2914,8 +3026,8 @@ packages: '@oxc-project/types@0.144.0': resolution: {integrity: sha512-nuhZIOLuI6TFQ32I/WnUx+SCPY7SdSKwgnFHydAuoS1+Z4BRcaP+RRJmGzl9lw+0OFF7UmaESf7KQRXaNLHypg==} - '@oxc-project/types@0.145.0': - resolution: {integrity: sha512-/UDI/xghp0wUJfvBu0fXIkn5nrDZCdesXo++ElC8UpDjzdFhB13k8XPXyMaSihaWPwgvdQXiJjRshVkaPEtaIQ==} + '@oxc-project/types@0.146.0': + resolution: {integrity: sha512-XC0QsnnhVe7sLIWmYmdPw7x5P0h4W8vUU3Nv1ySgWXtvCz8NizoAEpGXA0sOYoJQV2Rl13LgURAHQ5cI5ILCSA==} '@parcel/watcher-android-arm64@2.6.0': resolution: {integrity: sha512-trgpLSCKRC/huFjXX/Smh+0sWe4+YtKfktIToiMl59ghz7z+qkH6kMvNnUbLyRs9N11t8l4svSCs1+5B3rOAhA==} @@ -3103,36 +3215,72 @@ packages: yauzl: optional: true + '@rolldown/binding-android-arm-eabi@1.2.5': + resolution: {integrity: sha512-DLe/i+l8ynIBY7XEQ191TeZvCoowIGa18R+dIV30GW7DiOtp74i/xX8hs8GUjW5ARV7VZuie3d6AumSmCwbeRA==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm] + os: [android] + '@rolldown/binding-android-arm64@1.2.4': resolution: {integrity: sha512-jHC2cnyKz5xU2fhECtFl8OZ83cYNt13GZQD+0uMJ/X3o+ijmd56okHhTUwxVSHPx1IRVIJEZ1/1pPzeLCU6XKA==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [android] + '@rolldown/binding-android-arm64@1.2.5': + resolution: {integrity: sha512-zXcwKlQApYAOELHd8PwKDFkagYF9Wy4e0RJ+0qnzl9Pjnpj75TEG8ufv40p2J7kCEfwZAsNiuzRIyNNMWT38ig==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [android] + '@rolldown/binding-darwin-arm64@1.2.4': resolution: {integrity: sha512-Dc5mPD8F5F/FS8i01syd7FTF6yB2fVthH/TRkjwJkzUK6EpoxHtqvZQP5Zwq80/5z19TWYHIg1KOHboCgVx/aQ==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [darwin] + '@rolldown/binding-darwin-arm64@1.2.5': + resolution: {integrity: sha512-dK4QakI42nzWgJT5sm4y4y/O//D4OxM75/cH28RLV+nzIN9AY+YsbuUVrUTjlLjXR6vpyxFbSsbmNuJ6BP9sww==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [darwin] + '@rolldown/binding-darwin-x64@1.2.4': resolution: {integrity: sha512-fpDm4oBo6SqLvWUYCmFhdde3U9KH2fRNNMeAnAPAIwxRL345xutL0EtEUcuoxsoazdJGv/MuDBQHlCDrtbvqOg==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [darwin] + '@rolldown/binding-darwin-x64@1.2.5': + resolution: {integrity: sha512-fqSALaUu1Wjd1nK2uW2kJDWdLCc8lx1IcY+MTY26Aurfdx19anlzhqXOgCFbBFQnlFDTn4TC1/7Nz4Bl2mLP3A==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [x64] + os: [darwin] + '@rolldown/binding-freebsd-x64@1.2.4': resolution: {integrity: sha512-rSJoreDE/HoIzoaib6MTp5jQtCTdMHKIvItAKT/ImS6Y6Ww76oUaeMyp4Vc/fAgd/ehji068IxetHXAnqUwN9A==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [freebsd] + '@rolldown/binding-freebsd-x64@1.2.5': + resolution: {integrity: sha512-/vCnNxlkxs9tKxNDcyWUePpJ/PgTzxIaVhoM5SmG8UV+GR/IcPam4VYxi7GIMo7PSDuNqlJqvprqii9NqqVCMw==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [x64] + os: [freebsd] + '@rolldown/binding-linux-arm-gnueabihf@1.2.4': resolution: {integrity: sha512-/jm8OGHgn7oGaJu3i/qZI9spUGcJ+y/lk43ttQ/iO1tOd9NissG6o97bighBCiL+BKRngmcDuR6ikfwYdJmVuQ==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm] os: [linux] + '@rolldown/binding-linux-arm-gnueabihf@1.2.5': + resolution: {integrity: sha512-abk0NLA519LxRCszmbE0jYKuQ9YPocOXTiOXOo6Yr+YAT95VH+PtqYAjOJvGKt3viEd/x4qzabAlwd5bHOOARg==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm] + os: [linux] + '@rolldown/binding-linux-arm64-gnu@1.2.4': resolution: {integrity: sha512-tIP06BeD9EqvECBrPZ+sqdPlYrT+aYaAiu1wYziVx5elRK/ftm33JxVDy2bXGbr6J0CrtirCkR87/X5a2euEng==} engines: {node: ^20.19.0 || >=22.12.0} @@ -3140,6 +3288,13 @@ packages: os: [linux] libc: [glibc] + '@rolldown/binding-linux-arm64-gnu@1.2.5': + resolution: {integrity: sha512-Y7eALiJ8lr0M2HH103Js+g7V34wf6snlpZLAsHI90uLhr3PVlNsbFVAXJC9d/V6BnPyKtpSwI+NcB/RLxsQxuA==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [linux] + libc: [glibc] + '@rolldown/binding-linux-arm64-musl@1.2.4': resolution: {integrity: sha512-Ql1Q0EQqVThvn9VAVlwNzsUvbSFtCMGjLpRRi4pk5i7NZZ4n5ISiLMjHYtus4VQ2PvkSw24zyaCVsiS+sXPj1w==} engines: {node: ^20.19.0 || >=22.12.0} @@ -3147,6 +3302,13 @@ packages: os: [linux] libc: [musl] + '@rolldown/binding-linux-arm64-musl@1.2.5': + resolution: {integrity: sha512-xMvZgnbZg4YVnR/AX2b3oOPDTFYJvUVaJg5FedA/LuvexAtXibZQej4cnTkw3rjsJ/ggUROB64TdtETiim+FYA==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [linux] + libc: [musl] + '@rolldown/binding-linux-ppc64-gnu@1.2.4': resolution: {integrity: sha512-GjbjXD4XXfN19D0LZNbmiCBUoDiRACsYHr0yaIbbn8aFsXjHZifcYqu/W5Er5X2X990WjHXFrxarn5chzItorQ==} engines: {node: ^20.19.0 || >=22.12.0} @@ -3154,6 +3316,13 @@ packages: os: [linux] libc: [glibc] + '@rolldown/binding-linux-ppc64-gnu@1.2.5': + resolution: {integrity: sha512-GRjeqTUDHTo5GwntsLaAMcBahG3nlpjftXWZLN73HiYQlhwEowvarFgQnRnQZtIp4keXX7quXFbG38uPZBa2EA==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [ppc64] + os: [linux] + libc: [glibc] + '@rolldown/binding-linux-s390x-gnu@1.2.4': resolution: {integrity: sha512-p5WR0NOwaRmJ/B1b6IjEFLLivwEsf3PrdBIhRbhTCQisbo2SvHHpG4ELB/+FgQNnB88LTOF86upmJmbvZdQ2lw==} engines: {node: ^20.19.0 || >=22.12.0} @@ -3161,6 +3330,13 @@ packages: os: [linux] libc: [glibc] + '@rolldown/binding-linux-s390x-gnu@1.2.5': + resolution: {integrity: sha512-vLNTR45F2Uwc8AufkNXPmB4VliaXs+FvcheEogIzOXzO4l+LzieXF5A/TWxLy5HtqpsRCHUfd0lPVrrdgXdLHQ==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [s390x] + os: [linux] + libc: [glibc] + '@rolldown/binding-linux-x64-gnu@1.2.4': resolution: {integrity: sha512-4/GyVjmhR+Tc6HLJvwc1sOhPqAZtySiSMesOZyX6JQ5XBxoTDEMKQzvo07NIK6nTon/SivlZqvhzvuVBNQhObQ==} engines: {node: ^20.19.0 || >=22.12.0} @@ -3168,6 +3344,13 @@ packages: os: [linux] libc: [glibc] + '@rolldown/binding-linux-x64-gnu@1.2.5': + resolution: {integrity: sha512-Mgj59/HTuYeK9Gz2MA+mBWKnHsAgkBSec15ZMb1st3oIfFbX7gCjOae7GydHhzcyQi9Z/7M1QuN9bR3oFqF0jQ==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [x64] + os: [linux] + libc: [glibc] + '@rolldown/binding-linux-x64-musl@1.2.4': resolution: {integrity: sha512-l9eeLsCNvPpmSXUej0etw/J1eqV0Jj1D5G/xG6YTijmE6dkv6E2QezgWbTfQk63v952DPqrjOCoiqxq7Bw0YUQ==} engines: {node: ^20.19.0 || >=22.12.0} @@ -3175,24 +3358,49 @@ packages: os: [linux] libc: [musl] + '@rolldown/binding-linux-x64-musl@1.2.5': + resolution: {integrity: sha512-mY8AP0/ichsbhAxGnLa3d3+MwV0EfgrPND2bplI3Ym8T6R2pJ0N87bvrKVwNXmdy3jnr6eQBecdqx/HMknBmpA==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [x64] + os: [linux] + libc: [musl] + '@rolldown/binding-openharmony-arm64@1.2.4': resolution: {integrity: sha512-e0F355MSTMm3+UOqtV3L24gFUp2N5m1f8L/7d56deik6va+AXdrt9F8LbzGpeWGWRbZEDq4m8NVnJDeBtf9DZg==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [openharmony] + '@rolldown/binding-openharmony-arm64@1.2.5': + resolution: {integrity: sha512-8SLssA2oweAxyRgDp789ACfRb/3P+zNRJpzZxSizxF9m8NUDQ4+3xjo8ttjhVGGw6Qxb70oZiEtIjaKikCO7Yw==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [openharmony] + '@rolldown/binding-win32-arm64-msvc@1.2.4': resolution: {integrity: sha512-AWLi0uBRYh6QlE7OKhiz+phZC0qwtij2QZmhmOdsLdFn64m7oMpooE9ICE3lhm9xMb4SpDo2WbHcxX1iFLFtqw==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [win32] + '@rolldown/binding-win32-arm64-msvc@1.2.5': + resolution: {integrity: sha512-vGbruD5zquhoc8D9SViXgN2FBJtNdTyQ4DtG+SWiEGlJiAzoKcZ2xp+xuXCffhubVdt0NJlTZqkeRuERy7g8Cw==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [win32] + '@rolldown/binding-win32-x64-msvc@1.2.4': resolution: {integrity: sha512-UwSDJOg3dqCAejWdxclJjCsh3Qq4vLYMDxmyHqo1btz3stK2VqgwNd3mm5tuIwzSlGIQ/1H9Hr+Zn09mrezNqQ==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [win32] + '@rolldown/binding-win32-x64-msvc@1.2.5': + resolution: {integrity: sha512-e/SXpgISz+IoqVcSSI0rx/d/he8zqLex+/rCWpnHpmVfmPIUjag9H6P7zotf0gJHwPUhQxZ/mF8tr6acebT9yw==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [x64] + os: [win32] + '@rolldown/pluginutils@1.0.1': resolution: {integrity: sha512-2j9bGt5Jh8hj+vPtgzPtl72j0yRxHAyumoo6TNfAjsLB04UtpSvPbPcDcBMxz7n+9CYB0c1GxQFxYRg2jimqGw==} @@ -3241,146 +3449,146 @@ packages: rollup: optional: true - '@rollup/rollup-android-arm-eabi@4.62.4': - resolution: {integrity: sha512-RrPokAb7dmbxFoeO3TloqHyOjgye8RkBhSqmp4aJMIex4c9r46ZstPnleDQOq1t46VOVjwIuwNogIqbodV1Vvg==} + '@rollup/rollup-android-arm-eabi@4.62.5': + resolution: {integrity: sha512-jfkGfTwhQpsiSckPF8r9bU3pn3vyd72NlWaO+TgEO6WPSDnUhXzrNYCHBMOYj0ACaUgjm6eERLF+XV9a6RstoA==} cpu: [arm] os: [android] - '@rollup/rollup-android-arm64@4.62.4': - resolution: {integrity: sha512-JKuJc+pnpks2pjy7L/N3v/cAkZxYlnmuZoD840ldbMI5KDbC4iO9NKwPKYdjYFCMAIIlBzYSFHxIJVYzRo2/8A==} + '@rollup/rollup-android-arm64@4.62.5': + resolution: {integrity: sha512-oGVqyQlxnrz9/ty89oHpU857VUHEl5/Xu4R2lS+aivCTrNnSsbiENzTnNaBsjxH0CNWGPhzHArOLFwo+oKXveA==} cpu: [arm64] os: [android] - '@rollup/rollup-darwin-arm64@4.62.4': - resolution: {integrity: sha512-krw5uS2STmvJ02x0uTXHbqQNuz+9eZ1iw+qXk9dmW2gvV4jV7O2hEoOnuhFrpOPiel1mBFtqbxYZZtC46hXLOw==} + '@rollup/rollup-darwin-arm64@4.62.5': + resolution: {integrity: sha512-bW7B8xMEq8n99Q3ieEcPRGuphurdZAaFzQc9Efyyw3FL6DZO6pMy9xhdN+kBoD7Sy05xNXSr4OyPPnpkYriS/A==} cpu: [arm64] os: [darwin] - '@rollup/rollup-darwin-x64@4.62.4': - resolution: {integrity: sha512-wsTxtgApb4PrOsNJIm0FZ1h3WvCC+k9uxLJ4ad75hgoS4NiRes2SoJFlDAyMwiUY8IssDqGcHbXuN0sx1tfF1A==} + '@rollup/rollup-darwin-x64@4.62.5': + resolution: {integrity: sha512-YSwBS86QeHOGlrxJ1PSOIZSkzRL/JmKeunhc+lV6M1a6En8QuVCD/T/qIA0J4Gd2Y86RIOBYrLcOUtqGh9+/1w==} cpu: [x64] os: [darwin] - '@rollup/rollup-freebsd-arm64@4.62.4': - resolution: {integrity: sha512-GUOnQlyZe3yAXhWOtOMsn5Qkrv5E5mZXa0thbARWi5Ei2szlVXJFQhddZ4HbAzh8q92w5twp+CQvs/eFanz9YQ==} + '@rollup/rollup-freebsd-arm64@4.62.5': + resolution: {integrity: sha512-2fST8lILgl7cKbme/1KDdPCmbXbG+gqoV3bHp19L0ypX/3akYMBVdOunPleRCwonoLnXOZ/0F+Mt/v8POFmfcQ==} cpu: [arm64] os: [freebsd] - '@rollup/rollup-freebsd-x64@4.62.4': - resolution: {integrity: sha512-/Y7f3QuxjzPKsjA/rfEDa3+0vXqyjmJ50Ln8dPpCmWkKTrUoWHG1cWhTqaAMLob2m2nESWuC7yGrREz019Ztqg==} + '@rollup/rollup-freebsd-x64@4.62.5': + resolution: {integrity: sha512-cpIxQCP9J+EVad0a6LO1kY3ZGODlk80VlI+2I96B8xMcdHZ4pLVhfQ49JFpYqjPF91FFkQWftf57YlDcTiw9yQ==} cpu: [x64] os: [freebsd] - '@rollup/rollup-linux-arm-gnueabihf@4.62.4': - resolution: {integrity: sha512-81wiiX3v7aqy+T+bT61TJ78yJjRquqFFTTbAPt08imfQQzkPIW8t6aJbkTagtCCrXMNc9D66+geqlK7ydLPNqA==} + '@rollup/rollup-linux-arm-gnueabihf@4.62.5': + resolution: {integrity: sha512-r9fGh3eFs3e/udWh5ZjXQtxiYK/xoFxQaYR/cELxac/Udkl5Th+IsFm0CX3Kl9hmUH/we7EoMpjJgeQNnE0+IA==} cpu: [arm] os: [linux] libc: [glibc] - '@rollup/rollup-linux-arm-musleabihf@4.62.4': - resolution: {integrity: sha512-9kmDIvNZqdoHOBZgNtpTBeLWYO/LVipM3H/j62P8848/l/VPEQL6N3uxU9pvP1oZAsXyC2MEnFP3ovRjo7WYNQ==} + '@rollup/rollup-linux-arm-musleabihf@4.62.5': + resolution: {integrity: sha512-xdvFdp7OM6KLJviJT2g/YuRSUjnZgGHk4RNgwIbN7X6cPugOucV60DdHXWzsBVCUdrGb6qSXnJQrrAKMmQuj3Q==} cpu: [arm] os: [linux] libc: [musl] - '@rollup/rollup-linux-arm64-gnu@4.62.4': - resolution: {integrity: sha512-CcnXHWnXg69g+DX5VWL3FHts3qMRN2uVEHX+BZvGLdd07/gXkn3ePjYtO1LDJvxkGKVHMclKBRa1QUTH+6toYQ==} + '@rollup/rollup-linux-arm64-gnu@4.62.5': + resolution: {integrity: sha512-rRqILAndyzHzP7T9NFQrq+4HFWNhqkqkKur7eiBpfLmz01PO0JKx5Vchu3YllE4YXI/Ftgq/szrDWg5GJ0mI8g==} cpu: [arm64] os: [linux] libc: [glibc] - '@rollup/rollup-linux-arm64-musl@4.62.4': - resolution: {integrity: sha512-iFOibiHnTRuhrWLlRsOQFdZJJIa7S8OwkneJr4ocALP16u5yk6lWLINFwhHaEqBFMsKDUZofLkGos7+CPzGB3g==} + '@rollup/rollup-linux-arm64-musl@4.62.5': + resolution: {integrity: sha512-Gf4X3qVMucayUvux6aXXPgXovocSFUC0rrffDuPI/S2nHhNMhjcZxsrAFYCOF350PRreW1XwzFj3CT/3bKsWCw==} cpu: [arm64] os: [linux] libc: [musl] - '@rollup/rollup-linux-loong64-gnu@4.62.4': - resolution: {integrity: sha512-XnWYMI7euHlb5a871xPja+Gm7DRCFU+FGRrtS2sMq9N8FvqtpagUy6gD4YOemC5MRk9xbh8+jYMEJbigFQwsgA==} + '@rollup/rollup-linux-loong64-gnu@4.62.5': + resolution: {integrity: sha512-+s5qA0TNM0qm8PK/a5gt/1Hpx+NV08uSuCncvhziIlQzT6AEV2fnUQo7eBtFTFO0nA9scauvoR2HusfXmQnO4w==} cpu: [loong64] os: [linux] libc: [glibc] - '@rollup/rollup-linux-loong64-musl@4.62.4': - resolution: {integrity: sha512-qGDAlO0U8xedCcsdRm9oaoQY8DAx/QT7uIxJWhCdx0ceIWX783UC9QSYkdpzAe29wNiVfp24+bZdQmn49o45SQ==} + '@rollup/rollup-linux-loong64-musl@4.62.5': + resolution: {integrity: sha512-ybb6QvWwWJCbBWqERpc8K3pYVGIrXlG8MEQ8IIuJY6Y9KdHQxoFoNyfkAOtKn1VHu3KuLidXvwrvGR1mEjeWCw==} cpu: [loong64] os: [linux] libc: [musl] - '@rollup/rollup-linux-ppc64-gnu@4.62.4': - resolution: {integrity: sha512-ru4H6ezD7ysA5EiEK6qkkaEb4modH8CTej6kUy/gQi20u3kB3G7Zn8snXXkeJSCOFKG/rbPPtM/+9Wgas1961w==} + '@rollup/rollup-linux-ppc64-gnu@4.62.5': + resolution: {integrity: sha512-nZb1DtnOyhCmYvsC8A2CwOkopVg+IS1+fPUa7rMOAXtNw5+lLCLLPqd6XAiNrGtoQKsbvIBOwsHnBH/3wnb4HQ==} cpu: [ppc64] os: [linux] libc: [glibc] - '@rollup/rollup-linux-ppc64-musl@4.62.4': - resolution: {integrity: sha512-2W4MO5WQVJnbJaZdvDb9rhBDuFU1nKIepPFpJUBsTh2k1YY2g+ODViaWuyOAjQ5cOP7NvrvLzt3wvHOoiAvc7w==} + '@rollup/rollup-linux-ppc64-musl@4.62.5': + resolution: {integrity: sha512-yMbj63Sp89ryrXLWyz+sy+fYD2HpOnMCLGbe4Oa1smclFSUukdtD/BgdiHaAetJNb74URD8U4hM+qG5KVzMEkg==} cpu: [ppc64] os: [linux] libc: [musl] - '@rollup/rollup-linux-riscv64-gnu@4.62.4': - resolution: {integrity: sha512-+fxjfuoAmVMCYV5QyjoIpu0cp5DOiOTeqYFk1AVaxGr+/ravWLX89XfQmptsoWcaVy/TGf2hexzbUOrCQIL1CQ==} + '@rollup/rollup-linux-riscv64-gnu@4.62.5': + resolution: {integrity: sha512-mhoan3OJw2kYV/e1jtIdmvUZgyBFeA6zGWsOswmR0Tg19TQbowZuR+JMLID6spbbBN7Zee2ejrgmy3+FxGrIdA==} cpu: [riscv64] os: [linux] libc: [glibc] - '@rollup/rollup-linux-riscv64-musl@4.62.4': - resolution: {integrity: sha512-jTn8JfHGL4djjFxPuM06LmNUJDsst2jeVlsd9OmIH6zc5sC9K6rIuO4YajXatLUpBmBKl6b35ro1QZocLi+tcA==} + '@rollup/rollup-linux-riscv64-musl@4.62.5': + resolution: {integrity: sha512-5ZTLmjWbb1VZdjuyhe83K/8QO0/h11midQCBP+X5OYn32ra7eOBoM0ZqtaY4nkgNsYgmdVhMYPoyVPTjUpHf3w==} cpu: [riscv64] os: [linux] libc: [musl] - '@rollup/rollup-linux-s390x-gnu@4.62.4': - resolution: {integrity: sha512-oCJCJL4pXsoDcP2QZ+JVlPTIRc6266zsIaeJJsWImmF7HO0W8nb6HuSgZlMWxJwaPf8ehbSw8yo0EUw925hKsA==} + '@rollup/rollup-linux-s390x-gnu@4.62.5': + resolution: {integrity: sha512-m53kG+br6PGxOTmgBEM2DHSDs9RVjsyEbUwjJPJGTFm1grWOG8EKJggDCTb60unD4Tjby8fi7/m9XfkEWasVWg==} cpu: [s390x] os: [linux] libc: [glibc] - '@rollup/rollup-linux-x64-gnu@4.62.4': - resolution: {integrity: sha512-W69hukhZ3KKNRCaMIEzKvcFye42hh0FE1+YoYaf5+Ikacuftoco6yO/xouz0hc5d5W/s3yBro5jRiuEE/Q5vUw==} + '@rollup/rollup-linux-x64-gnu@4.62.5': + resolution: {integrity: sha512-6RHPJR1g/uvdYU8uXBnfq3nlqyZCP82Fr6NHgfGoaIeSh0YEqnX/x6uA9MmJJbnSH7swqX4F+CkGdUF+6doiQA==} cpu: [x64] os: [linux] libc: [glibc] - '@rollup/rollup-linux-x64-musl@4.62.4': - resolution: {integrity: sha512-qiXbGG2jkjXhzXpsFZSR2Xpb8DN/UaxYsbb/STbuR/6fpaDgRmmaq1B/LmtF2wQFOFOSsK2jdE0RZ3a0zHn4QA==} + '@rollup/rollup-linux-x64-musl@4.62.5': + resolution: {integrity: sha512-xs+OXQtEXgpXT0DmA5+U3qnRZHdCST/5HRQxS8wSPZTUZN/EMWeHuSIod32LQklTBZBV9DyfncKBQ8n5V3eFdw==} cpu: [x64] os: [linux] libc: [musl] - '@rollup/rollup-openbsd-x64@4.62.4': - resolution: {integrity: sha512-nWeM//hxv8mIo6jD7Hu4o48DVmV9pbV6gsKaWU+4NFyqHoPKwrkRiZGLKUhOBk8qNmDmpwFtPKg80Bo/Tn4xiQ==} + '@rollup/rollup-openbsd-x64@4.62.5': + resolution: {integrity: sha512-e7hD+sl3s+mcLQDZ8pbudBVsdG6r5yN4w3LqG2TJ8sQHDpblWj5lrJs/3m01Cvlxbt4x13zu5thLjgypgtkYzw==} cpu: [x64] os: [openbsd] - '@rollup/rollup-openharmony-arm64@4.62.4': - resolution: {integrity: sha512-s62SQ/vgsRSvMwDkOEfTqfgASF0f26ZNaQuTA6Aok5lrikf89yI2W0gFHvZb2Jpgc6N8JnOKZgCK2iciO3CsxQ==} + '@rollup/rollup-openharmony-arm64@4.62.5': + resolution: {integrity: sha512-GiyJaCf+WpMub/17aPcKk27QMl5W6f+KhdPTjlFOn5akH5Wa/DCM9Stdx5cDfmasyKB08MqpVQ1uJE2RkkpbXg==} cpu: [arm64] os: [openharmony] - '@rollup/rollup-win32-arm64-msvc@4.62.4': - resolution: {integrity: sha512-J6wGf8TVGbXJq+HH+ttTvrcfNKPbuZecV6KT1B8I18BC5IURUh5kl4Yl5OEP5eFIUoI5BWxCsyYMhFsDx8kekw==} + '@rollup/rollup-win32-arm64-msvc@4.62.5': + resolution: {integrity: sha512-+OQ8U2DdoEfXl8T4Fb18AjmEwbXMerKDKCL8yCPAYhKCEEKoul7rkbeGCBFCbAlaGaa7pmtRTpkAJM2LE/i5FA==} cpu: [arm64] os: [win32] - '@rollup/rollup-win32-ia32-msvc@4.62.4': - resolution: {integrity: sha512-zmfrQd/0wu6oJs8Vq8KwY/YtsKSsLtKe/HwAP4Wqy8LhWjeT55fHRAkOhYQ12wI3ayS4Tt12d5CDRD7N96SAYQ==} + '@rollup/rollup-win32-ia32-msvc@4.62.5': + resolution: {integrity: sha512-KanvAZrPKbDBFwrgiU9yEVpQoox9QPV1WZOXX7HudJQY+eSlu82CtWxDU8WtuRRvtN5EGkLczkd6Y6DTcvm9wA==} cpu: [ia32] os: [win32] - '@rollup/rollup-win32-x64-gnu@4.62.4': - resolution: {integrity: sha512-qPzHqdj9rfUD+w79dtE07zi/kFwKyCJqplp5K5ygeLTp7jLpAoc16OAH39HSmRC9UpozaecsleI8uAdEj6v2yw==} + '@rollup/rollup-win32-x64-gnu@4.62.5': + resolution: {integrity: sha512-1aC3UEWTtRl3RK3VpDJ/Tqk1XI4SLTmXIthAq6wRWo8XiSXJNd+VprJM4/1P4+i6HIaFEFlVi9sTTziniD2tOQ==} cpu: [x64] os: [win32] - '@rollup/rollup-win32-x64-msvc@4.62.4': - resolution: {integrity: sha512-zD6NdeWEByGE9QF9vCrlJ5YQB4oq9q91kPZS37Jwj5hOkvR1lTBSpsKhKDw4IJtbQ35LsTS1HD9DZYGKIshU1Q==} + '@rollup/rollup-win32-x64-msvc@4.62.5': + resolution: {integrity: sha512-/gDJaRs4gl0NPIwqCz+6PkpmhhjRAD2j6P4rSNHBzUkO3naEx2mIU0pRle1vUNRQ7mE/+8OOeXLTv/J56FKiQg==} cpu: [x64] os: [win32] - '@rollup/wasm-node@4.62.4': - resolution: {integrity: sha512-GJFM5d4k5dSoY/oyILsKArplGvkss1DOURyXsl6IEM/X9RV3bQwqu9GY6tYfA97ZwIejfAguHa9fo1pGOQcyDg==} + '@rollup/wasm-node@4.62.5': + resolution: {integrity: sha512-NSyG08F0m74qhvWDyFeYaZapAmieh3bEiQzCzql3N9ErlYoyt+V3xpDX8dBdKiZu1UXUpGNbBEblKaW5zcpqaw==} engines: {node: '>=18.0.0', npm: '>=8.0.0'} hasBin: true @@ -3829,6 +4037,7 @@ packages: '@xmldom/xmldom@0.8.14': resolution: {integrity: sha512-T4EDRUBVZYRldYApjEJiU0e1stYWaRAX7CuSnKzrpwdZKo53zGV8/pqfzV6FfwNl9YThD2OumQYvqtvjvgG7aQ==} engines: {node: '>=10.0.0'} + deprecated: this version has critical issues, please update to the latest version '@xtuc/ieee754@1.2.0': resolution: {integrity: sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA==} @@ -5072,8 +5281,8 @@ packages: resolution: {integrity: sha512-tD40eHxA35h0PEIZNeIjkHoDR4YjjJp34biM0mDvplBe//mB+IHCqHDGV7pxF+7MklTvighcCPPZC7ynWyjdTA==} engines: {node: ^20.19.0 || ^22.13.0 || >=24} - eslint@10.8.1: - resolution: {integrity: sha512-wqA7W2jbsC/BnV9Iv1UZpKVFkO1AdNoSmYW8NWG4HNOBbkAMvIqDZ27pI2f07dqn583NcIC44ckjAcOXDL1QbQ==} + eslint@10.9.0: + resolution: {integrity: sha512-5KeEOJZBfEVA47boFiBsf+6MmmJpffM7qEBg4pLla2e4nlKgdKlqCW0oSLOGsT8Wl5uCGJptLV1bkaiShj90Gw==} engines: {node: ^20.19.0 || ^22.13.0 || >=24} hasBin: true peerDependencies: @@ -6307,8 +6516,8 @@ packages: magic-string@0.30.21: resolution: {integrity: sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==} - magic-string@1.2.1: - resolution: {integrity: sha512-vCfXkt3lIJha02CjPT1igeysyHVfCsEpIeD20O+X9aJ2hML3/kKx8E9Iv1FB+aMSAlDOEAtpRWzuooQCrYwdUg==} + magic-string@1.2.2: + resolution: {integrity: sha512-veT/+7iXrXzT39XnEN4lOxtNl72dMgJ8Lp+5Bd6YcMSWpb0n0MjBM8Uuooi6jgJr8dhUW2swQgBmoZVMni5SVg==} magicast@0.5.4: resolution: {integrity: sha512-llBEhWm1SacoRwgHUoQJYtwp4PBLF4faQi5TCpIGyGs9n4y5+juI0tDgyKIfpqxckRHaHzouUEph3THklWh03w==} @@ -6720,8 +6929,8 @@ packages: resolution: {integrity: sha512-19YVAg7T+WTrxggPukVq7DjTv6+PJ867TmhCvBsYwmbFCsZd344rq2Ld1p0wo8f8Qrrhgp82c6FJRqdXWtSEhg==} engines: {node: '>= 0.4'} - oxc-parser@0.145.0: - resolution: {integrity: sha512-zLMOUMlzFPqpgiQPTdSYBpJF1pQX1Ym2h+qb/BIT3KoMYf+cn87LDD0ifjcGcikUwKS2uQKH/y4n2t3dHS9bFQ==} + oxc-parser@0.146.0: + resolution: {integrity: sha512-hrt0Ou2mCL8dLuvfvKWFjRlWaJKt0Xs7CfacAgb9mha0gKW1lSisUzNRyALgItMPIfThxkl8jH2ONP6ZbQXpaA==} engines: {node: ^20.19.0 || >=22.12.0} p-finally@1.0.0: @@ -6856,8 +7065,8 @@ packages: resolution: {integrity: sha512-8OEwKp5juEvb/MjpIc4hjqfgCNysrS94RIOMXYvpYCdm/jglrKEiAYmiumbmGhCvs+IcInsphYDFwqrjr7398w==} hasBin: true - piscina@5.3.0: - resolution: {integrity: sha512-9D3tPBayfoal6l9l4Y8NrMn1jkV718qJoYrla6P51+hh9h0Q+9/1c8KgEnoBQqhguyfgjay4biADI8HJG3pkoA==} + piscina@5.3.1: + resolution: {integrity: sha512-LYbVUyHb5CzavqNgs64Uv+gHkrCdEt73kfPazdsJnndDSJiaEDIzMUIAHbtV3plzaoBUphZfXZCQKF01LHMgXw==} engines: {node: '>=20.x'} pkg-dir@8.0.0: @@ -7227,6 +7436,11 @@ packages: engines: {node: ^20.19.0 || >=22.12.0} hasBin: true + rolldown@1.2.5: + resolution: {integrity: sha512-VD2IE5PUG4Oj8zz2VGykiYd5wbnjdIiSsNQb8Qu5B+noEp+A78mu2iVvpp27g8es14Tk9rofNs5Tku9iQCS4fA==} + engines: {node: ^20.19.0 || >=22.12.0} + hasBin: true + rollup-license-plugin@3.2.1: resolution: {integrity: sha512-66iiym49fU6YDJW4DPEYbmUwm4emHXP048lJM9YkecADYGO4cKf0gQZ13U/IqRN00DXbKz0g7O3yOt8m4BNFew==} engines: {node: '>=18.0.0'} @@ -7252,8 +7466,8 @@ packages: '@types/node': optional: true - rollup@4.62.4: - resolution: {integrity: sha512-RXOqwaPsBGjMNMa4sQjDjHieHEZDFoj/Rdr46l2MU5DfEs16wHJPC2RPTPHWhNl+M3aI472LLqFkFKut4SblOg==} + rollup@4.62.5: + resolution: {integrity: sha512-/tqMfgP7GPA3PHhCmuiS4vIjrSVhHLgY++i+dhbG462euyAj7FpM4D9uq1X3BgjlqRdpcOrYhcQtfiQLNc8tqw==} engines: {node: '>=18.0.0', npm: '>=8.0.0'} hasBin: true @@ -7320,8 +7534,8 @@ packages: webpack: optional: true - sass@1.102.0: - resolution: {integrity: sha512-NSOyTnaQF7rTAEOtI2fwb386vL+akyiQLBZu8Na7hXCb+umJy0GAqlcMIaqACZ6Z1VgTBS4K9PG6B3IdjHGJsw==} + sass@1.103.1: + resolution: {integrity: sha512-9icZURbP51S6S0QGoyaeqk9uB06GNWxsFYWfH5RgpFgqK5FA8tJcM3AdVxrZEVJ7dz+L87nG95gBKf4VuaMHGw==} engines: {node: '>=20.19.0'} hasBin: true @@ -7981,13 +8195,13 @@ packages: resolution: {integrity: sha512-ZZKSmDAEFOijERBLkmYfJ+vmk3w+7hOLYDNkRCuRuMJGEmqYNCNLyBBFwWKVMhfwaEF3WOd0Zlw86U/WC/+nYw==} engines: {'0': node >=0.6.0} - vite@8.2.1: - resolution: {integrity: sha512-EU/eS7BH3XROHh2YnBefjM6DBKA6ZeMZEYQbj7NLWg5wHYlhB8B/Mayd5XsgWq+NFYccDOTemRpdETWR6Ka/lw==} + vite@8.2.2: + resolution: {integrity: sha512-cFKLV/PRgAUlIRm5WjMjJ86jrftzpqcgH+Us+DS8mI3CDNiH30Whrz8uHL3+MOLPAgqbMBAqWdAHAphOAM+z/Q==} engines: {node: ^20.19.0 || >=22.12.0} hasBin: true peerDependencies: '@types/node': ^20.19.0 || >=22.12.0 - '@vitejs/devtools': ^0.4.0 + '@vitejs/devtools': ^0.4.0 || ^0.5.0 esbuild: ^0.27.0 || ^0.28.0 jiti: '>=1.21.0' less: ^4.0.0 @@ -9357,18 +9571,18 @@ snapshots: '@esbuild/win32-x64@0.28.2': optional: true - '@eslint-community/eslint-utils@4.10.1(eslint@10.8.1(jiti@2.7.0)(supports-color@11.0.0))': + '@eslint-community/eslint-utils@4.10.1(eslint@10.9.0(jiti@2.7.0)(supports-color@11.0.0))': dependencies: - eslint: 10.8.1(jiti@2.7.0)(supports-color@11.0.0) + eslint: 10.9.0(jiti@2.7.0)(supports-color@11.0.0) eslint-visitor-keys: 3.4.3 '@eslint-community/regexpp@4.12.2': {} - '@eslint/compat@2.1.0(eslint@10.8.1(jiti@2.7.0)(supports-color@11.0.0))': + '@eslint/compat@2.1.0(eslint@10.9.0(jiti@2.7.0)(supports-color@11.0.0))': dependencies: '@eslint/core': 1.2.1 optionalDependencies: - eslint: 10.8.1(jiti@2.7.0)(supports-color@11.0.0) + eslint: 10.9.0(jiti@2.7.0)(supports-color@11.0.0) '@eslint/config-array@0.23.5(supports-color@11.0.0)': dependencies: @@ -9400,9 +9614,9 @@ snapshots: transitivePeerDependencies: - supports-color - '@eslint/js@10.0.1(eslint@10.8.1(jiti@2.7.0)(supports-color@11.0.0))': + '@eslint/js@10.0.1(eslint@10.9.0(jiti@2.7.0)(supports-color@11.0.0))': optionalDependencies: - eslint: 10.8.1(jiti@2.7.0)(supports-color@11.0.0) + eslint: 10.9.0(jiti@2.7.0)(supports-color@11.0.0) '@eslint/object-schema@3.0.5': {} @@ -9848,15 +10062,6 @@ snapshots: '@inquirer/ansi@2.0.7': {} - '@inquirer/checkbox@5.2.1(@types/node@22.20.1)': - dependencies: - '@inquirer/ansi': 2.0.7 - '@inquirer/core': 11.2.1(@types/node@22.20.1) - '@inquirer/figures': 2.0.7 - '@inquirer/type': 4.0.7(@types/node@22.20.1) - optionalDependencies: - '@types/node': 22.20.1 - '@inquirer/checkbox@5.2.1(@types/node@24.13.3)': dependencies: '@inquirer/ansi': 2.0.7 @@ -9866,24 +10071,45 @@ snapshots: optionalDependencies: '@types/node': 24.13.3 - '@inquirer/confirm@6.1.1(@types/node@22.20.1)': + '@inquirer/checkbox@5.2.2(@types/node@22.20.1)': dependencies: - '@inquirer/core': 11.2.1(@types/node@22.20.1) + '@inquirer/ansi': 2.0.7 + '@inquirer/core': 12.0.0(@types/node@22.20.1) + '@inquirer/figures': 2.0.8 '@inquirer/type': 4.0.7(@types/node@22.20.1) optionalDependencies: '@types/node': 22.20.1 - '@inquirer/confirm@6.1.1(@types/node@24.13.3)': + '@inquirer/confirm@6.2.0(@types/node@22.20.1)': dependencies: - '@inquirer/core': 11.2.1(@types/node@24.13.3) + '@inquirer/core': 12.0.0(@types/node@22.20.1) + '@inquirer/type': 4.0.7(@types/node@22.20.1) + optionalDependencies: + '@types/node': 22.20.1 + + '@inquirer/confirm@6.2.0(@types/node@24.13.3)': + dependencies: + '@inquirer/core': 12.0.0(@types/node@24.13.3) '@inquirer/type': 4.0.7(@types/node@24.13.3) optionalDependencies: '@types/node': 24.13.3 - '@inquirer/core@11.2.1(@types/node@22.20.1)': + '@inquirer/core@11.2.1(@types/node@24.13.3)': dependencies: '@inquirer/ansi': 2.0.7 '@inquirer/figures': 2.0.7 + '@inquirer/type': 4.0.7(@types/node@24.13.3) + cli-width: 4.1.0 + fast-wrap-ansi: 0.2.2 + mute-stream: 3.0.0 + signal-exit: 4.1.0 + optionalDependencies: + '@types/node': 24.13.3 + + '@inquirer/core@12.0.0(@types/node@22.20.1)': + dependencies: + '@inquirer/ansi': 2.0.7 + '@inquirer/figures': 2.0.8 '@inquirer/type': 4.0.7(@types/node@22.20.1) cli-width: 4.1.0 fast-wrap-ansi: 0.2.2 @@ -9892,10 +10118,10 @@ snapshots: optionalDependencies: '@types/node': 22.20.1 - '@inquirer/core@11.2.1(@types/node@24.13.3)': + '@inquirer/core@12.0.0(@types/node@24.13.3)': dependencies: '@inquirer/ansi': 2.0.7 - '@inquirer/figures': 2.0.7 + '@inquirer/figures': 2.0.8 '@inquirer/type': 4.0.7(@types/node@24.13.3) cli-width: 4.1.0 fast-wrap-ansi: 0.2.2 @@ -9904,14 +10130,6 @@ snapshots: optionalDependencies: '@types/node': 24.13.3 - '@inquirer/editor@5.2.2(@types/node@22.20.1)': - dependencies: - '@inquirer/core': 11.2.1(@types/node@22.20.1) - '@inquirer/external-editor': 3.0.3(@types/node@22.20.1) - '@inquirer/type': 4.0.7(@types/node@22.20.1) - optionalDependencies: - '@types/node': 22.20.1 - '@inquirer/editor@5.2.2(@types/node@24.13.3)': dependencies: '@inquirer/core': 11.2.1(@types/node@24.13.3) @@ -9920,9 +10138,10 @@ snapshots: optionalDependencies: '@types/node': 24.13.3 - '@inquirer/expand@5.1.1(@types/node@22.20.1)': + '@inquirer/editor@5.3.0(@types/node@22.20.1)': dependencies: - '@inquirer/core': 11.2.1(@types/node@22.20.1) + '@inquirer/core': 12.0.0(@types/node@22.20.1) + '@inquirer/external-editor': 3.0.4(@types/node@22.20.1) '@inquirer/type': 4.0.7(@types/node@22.20.1) optionalDependencies: '@types/node': 22.20.1 @@ -9934,10 +10153,10 @@ snapshots: optionalDependencies: '@types/node': 24.13.3 - '@inquirer/external-editor@3.0.3(@types/node@22.20.1)': + '@inquirer/expand@5.1.2(@types/node@22.20.1)': dependencies: - chardet: 2.2.0 - iconv-lite: 0.7.3 + '@inquirer/core': 12.0.0(@types/node@22.20.1) + '@inquirer/type': 4.0.7(@types/node@22.20.1) optionalDependencies: '@types/node': 22.20.1 @@ -9948,15 +10167,17 @@ snapshots: optionalDependencies: '@types/node': 24.13.3 - '@inquirer/figures@2.0.7': {} - - '@inquirer/input@5.1.2(@types/node@22.20.1)': + '@inquirer/external-editor@3.0.4(@types/node@22.20.1)': dependencies: - '@inquirer/core': 11.2.1(@types/node@22.20.1) - '@inquirer/type': 4.0.7(@types/node@22.20.1) + chardet: 2.2.0 + iconv-lite: 0.7.3 optionalDependencies: '@types/node': 22.20.1 + '@inquirer/figures@2.0.7': {} + + '@inquirer/figures@2.0.8': {} + '@inquirer/input@5.1.2(@types/node@24.13.3)': dependencies: '@inquirer/core': 11.2.1(@types/node@24.13.3) @@ -9964,9 +10185,9 @@ snapshots: optionalDependencies: '@types/node': 24.13.3 - '@inquirer/number@4.1.1(@types/node@22.20.1)': + '@inquirer/input@5.1.3(@types/node@22.20.1)': dependencies: - '@inquirer/core': 11.2.1(@types/node@22.20.1) + '@inquirer/core': 12.0.0(@types/node@22.20.1) '@inquirer/type': 4.0.7(@types/node@22.20.1) optionalDependencies: '@types/node': 22.20.1 @@ -9978,10 +10199,9 @@ snapshots: optionalDependencies: '@types/node': 24.13.3 - '@inquirer/password@5.1.1(@types/node@22.20.1)': + '@inquirer/number@4.2.0(@types/node@22.20.1)': dependencies: - '@inquirer/ansi': 2.0.7 - '@inquirer/core': 11.2.1(@types/node@22.20.1) + '@inquirer/core': 12.0.0(@types/node@22.20.1) '@inquirer/type': 4.0.7(@types/node@22.20.1) optionalDependencies: '@types/node': 22.20.1 @@ -9994,25 +10214,18 @@ snapshots: optionalDependencies: '@types/node': 24.13.3 - '@inquirer/prompts@8.5.2(@types/node@22.20.1)': - dependencies: - '@inquirer/checkbox': 5.2.1(@types/node@22.20.1) - '@inquirer/confirm': 6.1.1(@types/node@22.20.1) - '@inquirer/editor': 5.2.2(@types/node@22.20.1) - '@inquirer/expand': 5.1.1(@types/node@22.20.1) - '@inquirer/input': 5.1.2(@types/node@22.20.1) - '@inquirer/number': 4.1.1(@types/node@22.20.1) - '@inquirer/password': 5.1.1(@types/node@22.20.1) - '@inquirer/rawlist': 5.3.1(@types/node@22.20.1) - '@inquirer/search': 4.2.1(@types/node@22.20.1) - '@inquirer/select': 5.2.1(@types/node@22.20.1) + '@inquirer/password@5.1.2(@types/node@22.20.1)': + dependencies: + '@inquirer/ansi': 2.0.7 + '@inquirer/core': 12.0.0(@types/node@22.20.1) + '@inquirer/type': 4.0.7(@types/node@22.20.1) optionalDependencies: '@types/node': 22.20.1 '@inquirer/prompts@8.5.2(@types/node@24.13.3)': dependencies: '@inquirer/checkbox': 5.2.1(@types/node@24.13.3) - '@inquirer/confirm': 6.1.1(@types/node@24.13.3) + '@inquirer/confirm': 6.2.0(@types/node@24.13.3) '@inquirer/editor': 5.2.2(@types/node@24.13.3) '@inquirer/expand': 5.1.1(@types/node@24.13.3) '@inquirer/input': 5.1.2(@types/node@24.13.3) @@ -10024,10 +10237,18 @@ snapshots: optionalDependencies: '@types/node': 24.13.3 - '@inquirer/rawlist@5.3.1(@types/node@22.20.1)': - dependencies: - '@inquirer/core': 11.2.1(@types/node@22.20.1) - '@inquirer/type': 4.0.7(@types/node@22.20.1) + '@inquirer/prompts@8.6.0(@types/node@22.20.1)': + dependencies: + '@inquirer/checkbox': 5.2.2(@types/node@22.20.1) + '@inquirer/confirm': 6.2.0(@types/node@22.20.1) + '@inquirer/editor': 5.3.0(@types/node@22.20.1) + '@inquirer/expand': 5.1.2(@types/node@22.20.1) + '@inquirer/input': 5.1.3(@types/node@22.20.1) + '@inquirer/number': 4.2.0(@types/node@22.20.1) + '@inquirer/password': 5.1.2(@types/node@22.20.1) + '@inquirer/rawlist': 5.3.2(@types/node@22.20.1) + '@inquirer/search': 4.3.0(@types/node@22.20.1) + '@inquirer/select': 5.2.2(@types/node@22.20.1) optionalDependencies: '@types/node': 22.20.1 @@ -10038,10 +10259,9 @@ snapshots: optionalDependencies: '@types/node': 24.13.3 - '@inquirer/search@4.2.1(@types/node@22.20.1)': + '@inquirer/rawlist@5.3.2(@types/node@22.20.1)': dependencies: - '@inquirer/core': 11.2.1(@types/node@22.20.1) - '@inquirer/figures': 2.0.7 + '@inquirer/core': 12.0.0(@types/node@22.20.1) '@inquirer/type': 4.0.7(@types/node@22.20.1) optionalDependencies: '@types/node': 22.20.1 @@ -10054,11 +10274,10 @@ snapshots: optionalDependencies: '@types/node': 24.13.3 - '@inquirer/select@5.2.1(@types/node@22.20.1)': + '@inquirer/search@4.3.0(@types/node@22.20.1)': dependencies: - '@inquirer/ansi': 2.0.7 - '@inquirer/core': 11.2.1(@types/node@22.20.1) - '@inquirer/figures': 2.0.7 + '@inquirer/core': 12.0.0(@types/node@22.20.1) + '@inquirer/figures': 2.0.8 '@inquirer/type': 4.0.7(@types/node@22.20.1) optionalDependencies: '@types/node': 22.20.1 @@ -10072,6 +10291,15 @@ snapshots: optionalDependencies: '@types/node': 24.13.3 + '@inquirer/select@5.2.2(@types/node@22.20.1)': + dependencies: + '@inquirer/ansi': 2.0.7 + '@inquirer/core': 12.0.0(@types/node@22.20.1) + '@inquirer/figures': 2.0.8 + '@inquirer/type': 4.0.7(@types/node@22.20.1) + optionalDependencies: + '@types/node': 22.20.1 + '@inquirer/type@4.0.7(@types/node@22.20.1)': optionalDependencies: '@types/node': 22.20.1 @@ -10251,9 +10479,9 @@ snapshots: '@leichtgewicht/ip-codec@2.0.5': {} - '@listr2/prompt-adapter-inquirer@4.2.5(@inquirer/prompts@8.5.2(@types/node@22.20.1))(@types/node@22.20.1)(listr2@11.0.0)': + '@listr2/prompt-adapter-inquirer@4.2.5(@inquirer/prompts@8.6.0(@types/node@22.20.1))(@types/node@22.20.1)(listr2@11.0.0)': dependencies: - '@inquirer/prompts': 8.5.2(@types/node@22.20.1) + '@inquirer/prompts': 8.6.0(@types/node@22.20.1) '@inquirer/type': 4.0.7(@types/node@22.20.1) listr2: 11.0.0 transitivePeerDependencies: @@ -10554,66 +10782,66 @@ snapshots: '@opentelemetry/semantic-conventions@1.43.0': {} - '@oxc-parser/binding-android-arm-eabi@0.145.0': + '@oxc-parser/binding-android-arm-eabi@0.146.0': optional: true - '@oxc-parser/binding-android-arm64@0.145.0': + '@oxc-parser/binding-android-arm64@0.146.0': optional: true - '@oxc-parser/binding-darwin-arm64@0.145.0': + '@oxc-parser/binding-darwin-arm64@0.146.0': optional: true - '@oxc-parser/binding-darwin-x64@0.145.0': + '@oxc-parser/binding-darwin-x64@0.146.0': optional: true - '@oxc-parser/binding-freebsd-x64@0.145.0': + '@oxc-parser/binding-freebsd-x64@0.146.0': optional: true - '@oxc-parser/binding-linux-arm-gnueabihf@0.145.0': + '@oxc-parser/binding-linux-arm-gnueabihf@0.146.0': optional: true - '@oxc-parser/binding-linux-arm-musleabihf@0.145.0': + '@oxc-parser/binding-linux-arm-musleabihf@0.146.0': optional: true - '@oxc-parser/binding-linux-arm64-gnu@0.145.0': + '@oxc-parser/binding-linux-arm64-gnu@0.146.0': optional: true - '@oxc-parser/binding-linux-arm64-musl@0.145.0': + '@oxc-parser/binding-linux-arm64-musl@0.146.0': optional: true - '@oxc-parser/binding-linux-ppc64-gnu@0.145.0': + '@oxc-parser/binding-linux-ppc64-gnu@0.146.0': optional: true - '@oxc-parser/binding-linux-riscv64-gnu@0.145.0': + '@oxc-parser/binding-linux-riscv64-gnu@0.146.0': optional: true - '@oxc-parser/binding-linux-riscv64-musl@0.145.0': + '@oxc-parser/binding-linux-riscv64-musl@0.146.0': optional: true - '@oxc-parser/binding-linux-s390x-gnu@0.145.0': + '@oxc-parser/binding-linux-s390x-gnu@0.146.0': optional: true - '@oxc-parser/binding-linux-x64-gnu@0.145.0': + '@oxc-parser/binding-linux-x64-gnu@0.146.0': optional: true - '@oxc-parser/binding-linux-x64-musl@0.145.0': + '@oxc-parser/binding-linux-x64-musl@0.146.0': optional: true - '@oxc-parser/binding-openharmony-arm64@0.145.0': + '@oxc-parser/binding-openharmony-arm64@0.146.0': optional: true - '@oxc-parser/binding-win32-arm64-msvc@0.145.0': + '@oxc-parser/binding-win32-arm64-msvc@0.146.0': optional: true - '@oxc-parser/binding-win32-ia32-msvc@0.145.0': + '@oxc-parser/binding-win32-ia32-msvc@0.146.0': optional: true - '@oxc-parser/binding-win32-x64-msvc@0.145.0': + '@oxc-parser/binding-win32-x64-msvc@0.146.0': optional: true '@oxc-project/types@0.144.0': {} - '@oxc-project/types@0.145.0': {} + '@oxc-project/types@0.146.0': {} '@parcel/watcher-android-arm64@2.6.0': optional: true @@ -10815,57 +11043,102 @@ snapshots: modern-tar: 0.8.4 yargs: 18.1.0 + '@rolldown/binding-android-arm-eabi@1.2.5': + optional: true + '@rolldown/binding-android-arm64@1.2.4': optional: true + '@rolldown/binding-android-arm64@1.2.5': + optional: true + '@rolldown/binding-darwin-arm64@1.2.4': optional: true + '@rolldown/binding-darwin-arm64@1.2.5': + optional: true + '@rolldown/binding-darwin-x64@1.2.4': optional: true + '@rolldown/binding-darwin-x64@1.2.5': + optional: true + '@rolldown/binding-freebsd-x64@1.2.4': optional: true + '@rolldown/binding-freebsd-x64@1.2.5': + optional: true + '@rolldown/binding-linux-arm-gnueabihf@1.2.4': optional: true + '@rolldown/binding-linux-arm-gnueabihf@1.2.5': + optional: true + '@rolldown/binding-linux-arm64-gnu@1.2.4': optional: true + '@rolldown/binding-linux-arm64-gnu@1.2.5': + optional: true + '@rolldown/binding-linux-arm64-musl@1.2.4': optional: true + '@rolldown/binding-linux-arm64-musl@1.2.5': + optional: true + '@rolldown/binding-linux-ppc64-gnu@1.2.4': optional: true + '@rolldown/binding-linux-ppc64-gnu@1.2.5': + optional: true + '@rolldown/binding-linux-s390x-gnu@1.2.4': optional: true + '@rolldown/binding-linux-s390x-gnu@1.2.5': + optional: true + '@rolldown/binding-linux-x64-gnu@1.2.4': optional: true + '@rolldown/binding-linux-x64-gnu@1.2.5': + optional: true + '@rolldown/binding-linux-x64-musl@1.2.4': optional: true + '@rolldown/binding-linux-x64-musl@1.2.5': + optional: true + '@rolldown/binding-openharmony-arm64@1.2.4': optional: true + '@rolldown/binding-openharmony-arm64@1.2.5': + optional: true + '@rolldown/binding-win32-arm64-msvc@1.2.4': optional: true + '@rolldown/binding-win32-arm64-msvc@1.2.5': + optional: true + '@rolldown/binding-win32-x64-msvc@1.2.4': optional: true + '@rolldown/binding-win32-x64-msvc@1.2.5': + optional: true + '@rolldown/pluginutils@1.0.1': {} - '@rollup/plugin-alias@6.0.0(rollup@4.62.4)': + '@rollup/plugin-alias@6.0.0(rollup@4.62.5)': optionalDependencies: - rollup: 4.62.4 + rollup: 4.62.5 - '@rollup/plugin-commonjs@29.0.3(rollup@4.62.4)': + '@rollup/plugin-commonjs@29.0.3(rollup@4.62.5)': dependencies: - '@rollup/pluginutils': 5.4.0(rollup@4.62.4) + '@rollup/pluginutils': 5.4.0(rollup@4.62.5) commondir: 1.0.1 estree-walker: 2.0.2 fdir: 6.5.0(picomatch@4.0.5) @@ -10873,108 +11146,108 @@ snapshots: magic-string: 0.30.21 picomatch: 4.0.5 optionalDependencies: - rollup: 4.62.4 + rollup: 4.62.5 - '@rollup/plugin-json@6.1.0(rollup@4.62.4)': + '@rollup/plugin-json@6.1.0(rollup@4.62.5)': dependencies: - '@rollup/pluginutils': 5.4.0(rollup@4.62.4) + '@rollup/pluginutils': 5.4.0(rollup@4.62.5) optionalDependencies: - rollup: 4.62.4 + rollup: 4.62.5 - '@rollup/plugin-node-resolve@16.0.3(rollup@4.62.4)': + '@rollup/plugin-node-resolve@16.0.3(rollup@4.62.5)': dependencies: - '@rollup/pluginutils': 5.4.0(rollup@4.62.4) + '@rollup/pluginutils': 5.4.0(rollup@4.62.5) '@types/resolve': 1.20.2 deepmerge: 4.3.1 is-module: 1.0.0 resolve: 1.22.12 optionalDependencies: - rollup: 4.62.4 + rollup: 4.62.5 - '@rollup/pluginutils@5.4.0(rollup@4.62.4)': + '@rollup/pluginutils@5.4.0(rollup@4.62.5)': dependencies: '@types/estree': 1.0.9 estree-walker: 2.0.2 picomatch: 4.0.5 optionalDependencies: - rollup: 4.62.4 + rollup: 4.62.5 - '@rollup/rollup-android-arm-eabi@4.62.4': + '@rollup/rollup-android-arm-eabi@4.62.5': optional: true - '@rollup/rollup-android-arm64@4.62.4': + '@rollup/rollup-android-arm64@4.62.5': optional: true - '@rollup/rollup-darwin-arm64@4.62.4': + '@rollup/rollup-darwin-arm64@4.62.5': optional: true - '@rollup/rollup-darwin-x64@4.62.4': + '@rollup/rollup-darwin-x64@4.62.5': optional: true - '@rollup/rollup-freebsd-arm64@4.62.4': + '@rollup/rollup-freebsd-arm64@4.62.5': optional: true - '@rollup/rollup-freebsd-x64@4.62.4': + '@rollup/rollup-freebsd-x64@4.62.5': optional: true - '@rollup/rollup-linux-arm-gnueabihf@4.62.4': + '@rollup/rollup-linux-arm-gnueabihf@4.62.5': optional: true - '@rollup/rollup-linux-arm-musleabihf@4.62.4': + '@rollup/rollup-linux-arm-musleabihf@4.62.5': optional: true - '@rollup/rollup-linux-arm64-gnu@4.62.4': + '@rollup/rollup-linux-arm64-gnu@4.62.5': optional: true - '@rollup/rollup-linux-arm64-musl@4.62.4': + '@rollup/rollup-linux-arm64-musl@4.62.5': optional: true - '@rollup/rollup-linux-loong64-gnu@4.62.4': + '@rollup/rollup-linux-loong64-gnu@4.62.5': optional: true - '@rollup/rollup-linux-loong64-musl@4.62.4': + '@rollup/rollup-linux-loong64-musl@4.62.5': optional: true - '@rollup/rollup-linux-ppc64-gnu@4.62.4': + '@rollup/rollup-linux-ppc64-gnu@4.62.5': optional: true - '@rollup/rollup-linux-ppc64-musl@4.62.4': + '@rollup/rollup-linux-ppc64-musl@4.62.5': optional: true - '@rollup/rollup-linux-riscv64-gnu@4.62.4': + '@rollup/rollup-linux-riscv64-gnu@4.62.5': optional: true - '@rollup/rollup-linux-riscv64-musl@4.62.4': + '@rollup/rollup-linux-riscv64-musl@4.62.5': optional: true - '@rollup/rollup-linux-s390x-gnu@4.62.4': + '@rollup/rollup-linux-s390x-gnu@4.62.5': optional: true - '@rollup/rollup-linux-x64-gnu@4.62.4': + '@rollup/rollup-linux-x64-gnu@4.62.5': optional: true - '@rollup/rollup-linux-x64-musl@4.62.4': + '@rollup/rollup-linux-x64-musl@4.62.5': optional: true - '@rollup/rollup-openbsd-x64@4.62.4': + '@rollup/rollup-openbsd-x64@4.62.5': optional: true - '@rollup/rollup-openharmony-arm64@4.62.4': + '@rollup/rollup-openharmony-arm64@4.62.5': optional: true - '@rollup/rollup-win32-arm64-msvc@4.62.4': + '@rollup/rollup-win32-arm64-msvc@4.62.5': optional: true - '@rollup/rollup-win32-ia32-msvc@4.62.4': + '@rollup/rollup-win32-ia32-msvc@4.62.5': optional: true - '@rollup/rollup-win32-x64-gnu@4.62.4': + '@rollup/rollup-win32-x64-gnu@4.62.5': optional: true - '@rollup/rollup-win32-x64-msvc@4.62.4': + '@rollup/rollup-win32-x64-msvc@4.62.5': optional: true - '@rollup/wasm-node@4.62.4': + '@rollup/wasm-node@4.62.5': dependencies: '@types/estree': 1.0.9 optionalDependencies: @@ -10997,19 +11270,19 @@ snapshots: '@standard-schema/spec@1.1.0': {} - '@stylistic/eslint-plugin@5.10.0(eslint@10.8.1(jiti@2.7.0)(supports-color@11.0.0))': + '@stylistic/eslint-plugin@5.10.0(eslint@10.9.0(jiti@2.7.0)(supports-color@11.0.0))': dependencies: - '@eslint-community/eslint-utils': 4.10.1(eslint@10.8.1(jiti@2.7.0)(supports-color@11.0.0)) + '@eslint-community/eslint-utils': 4.10.1(eslint@10.9.0(jiti@2.7.0)(supports-color@11.0.0)) '@typescript-eslint/types': 8.67.0 - eslint: 10.8.1(jiti@2.7.0)(supports-color@11.0.0) + eslint: 10.9.0(jiti@2.7.0)(supports-color@11.0.0) eslint-visitor-keys: 4.2.1 espree: 10.4.0 estraverse: 5.3.0 picomatch: 4.0.5 - '@tony.ganchev/eslint-plugin-header@3.4.4(eslint@10.8.1(jiti@2.7.0)(supports-color@11.0.0))': + '@tony.ganchev/eslint-plugin-header@3.4.4(eslint@10.9.0(jiti@2.7.0)(supports-color@11.0.0))': dependencies: - eslint: 10.8.1(jiti@2.7.0)(supports-color@11.0.0) + eslint: 10.9.0(jiti@2.7.0)(supports-color@11.0.0) '@types/babel__core@7.20.5': dependencies: @@ -11230,15 +11503,15 @@ snapshots: '@types/yarnpkg__lockfile@1.1.9': {} - '@typescript-eslint/eslint-plugin@8.67.0(@typescript-eslint/parser@8.67.0(eslint@10.8.1(jiti@2.7.0)(supports-color@11.0.0))(supports-color@11.0.0)(typescript@6.0.3))(eslint@10.8.1(jiti@2.7.0)(supports-color@11.0.0))(supports-color@11.0.0)(typescript@6.0.3)': + '@typescript-eslint/eslint-plugin@8.67.0(@typescript-eslint/parser@8.67.0(eslint@10.9.0(jiti@2.7.0)(supports-color@11.0.0))(supports-color@11.0.0)(typescript@6.0.3))(eslint@10.9.0(jiti@2.7.0)(supports-color@11.0.0))(supports-color@11.0.0)(typescript@6.0.3)': dependencies: '@eslint-community/regexpp': 4.12.2 - '@typescript-eslint/parser': 8.67.0(eslint@10.8.1(jiti@2.7.0)(supports-color@11.0.0))(supports-color@11.0.0)(typescript@6.0.3) + '@typescript-eslint/parser': 8.67.0(eslint@10.9.0(jiti@2.7.0)(supports-color@11.0.0))(supports-color@11.0.0)(typescript@6.0.3) '@typescript-eslint/scope-manager': 8.67.0 - '@typescript-eslint/type-utils': 8.67.0(eslint@10.8.1(jiti@2.7.0)(supports-color@11.0.0))(supports-color@11.0.0)(typescript@6.0.3) - '@typescript-eslint/utils': 8.67.0(eslint@10.8.1(jiti@2.7.0)(supports-color@11.0.0))(supports-color@11.0.0)(typescript@6.0.3) + '@typescript-eslint/type-utils': 8.67.0(eslint@10.9.0(jiti@2.7.0)(supports-color@11.0.0))(supports-color@11.0.0)(typescript@6.0.3) + '@typescript-eslint/utils': 8.67.0(eslint@10.9.0(jiti@2.7.0)(supports-color@11.0.0))(supports-color@11.0.0)(typescript@6.0.3) '@typescript-eslint/visitor-keys': 8.67.0 - eslint: 10.8.1(jiti@2.7.0)(supports-color@11.0.0) + eslint: 10.9.0(jiti@2.7.0)(supports-color@11.0.0) ignore: 7.0.6 natural-compare: 1.4.0 ts-api-utils: 2.5.0(typescript@6.0.3) @@ -11246,14 +11519,14 @@ snapshots: transitivePeerDependencies: - supports-color - '@typescript-eslint/parser@8.67.0(eslint@10.8.1(jiti@2.7.0)(supports-color@11.0.0))(supports-color@11.0.0)(typescript@6.0.3)': + '@typescript-eslint/parser@8.67.0(eslint@10.9.0(jiti@2.7.0)(supports-color@11.0.0))(supports-color@11.0.0)(typescript@6.0.3)': dependencies: '@typescript-eslint/scope-manager': 8.67.0 '@typescript-eslint/types': 8.67.0 '@typescript-eslint/typescript-estree': 8.67.0(supports-color@11.0.0)(typescript@6.0.3) '@typescript-eslint/visitor-keys': 8.67.0 debug: 4.4.3(supports-color@11.0.0) - eslint: 10.8.1(jiti@2.7.0)(supports-color@11.0.0) + eslint: 10.9.0(jiti@2.7.0)(supports-color@11.0.0) typescript: 6.0.3 transitivePeerDependencies: - supports-color @@ -11276,13 +11549,13 @@ snapshots: dependencies: typescript: 6.0.3 - '@typescript-eslint/type-utils@8.67.0(eslint@10.8.1(jiti@2.7.0)(supports-color@11.0.0))(supports-color@11.0.0)(typescript@6.0.3)': + '@typescript-eslint/type-utils@8.67.0(eslint@10.9.0(jiti@2.7.0)(supports-color@11.0.0))(supports-color@11.0.0)(typescript@6.0.3)': dependencies: '@typescript-eslint/types': 8.67.0 '@typescript-eslint/typescript-estree': 8.67.0(supports-color@11.0.0)(typescript@6.0.3) - '@typescript-eslint/utils': 8.67.0(eslint@10.8.1(jiti@2.7.0)(supports-color@11.0.0))(supports-color@11.0.0)(typescript@6.0.3) + '@typescript-eslint/utils': 8.67.0(eslint@10.9.0(jiti@2.7.0)(supports-color@11.0.0))(supports-color@11.0.0)(typescript@6.0.3) debug: 4.4.3(supports-color@11.0.0) - eslint: 10.8.1(jiti@2.7.0)(supports-color@11.0.0) + eslint: 10.9.0(jiti@2.7.0)(supports-color@11.0.0) ts-api-utils: 2.5.0(typescript@6.0.3) typescript: 6.0.3 transitivePeerDependencies: @@ -11305,13 +11578,13 @@ snapshots: transitivePeerDependencies: - supports-color - '@typescript-eslint/utils@8.67.0(eslint@10.8.1(jiti@2.7.0)(supports-color@11.0.0))(supports-color@11.0.0)(typescript@6.0.3)': + '@typescript-eslint/utils@8.67.0(eslint@10.9.0(jiti@2.7.0)(supports-color@11.0.0))(supports-color@11.0.0)(typescript@6.0.3)': dependencies: - '@eslint-community/eslint-utils': 4.10.1(eslint@10.8.1(jiti@2.7.0)(supports-color@11.0.0)) + '@eslint-community/eslint-utils': 4.10.1(eslint@10.9.0(jiti@2.7.0)(supports-color@11.0.0)) '@typescript-eslint/scope-manager': 8.67.0 '@typescript-eslint/types': 8.67.0 '@typescript-eslint/typescript-estree': 8.67.0(supports-color@11.0.0)(typescript@6.0.3) - eslint: 10.8.1(jiti@2.7.0)(supports-color@11.0.0) + eslint: 10.9.0(jiti@2.7.0)(supports-color@11.0.0) typescript: 6.0.3 transitivePeerDependencies: - supports-color @@ -11493,9 +11766,9 @@ snapshots: lodash: 4.18.1 minimatch: 10.2.6 - '@vitejs/plugin-basic-ssl@2.3.0(vite@8.2.1(@types/node@22.20.1)(esbuild@0.28.2)(jiti@2.7.0)(less@4.9.0(supports-color@11.0.0))(sass@1.102.0)(terser@5.50.0)(tsx@4.23.12)(yaml@2.9.0))': + '@vitejs/plugin-basic-ssl@2.3.0(vite@8.2.2(@types/node@22.20.1)(esbuild@0.28.2)(jiti@2.7.0)(less@4.9.0(supports-color@11.0.0))(sass@1.103.1)(terser@5.50.0)(tsx@4.23.12)(yaml@2.9.0))': dependencies: - vite: 8.2.1(@types/node@22.20.1)(esbuild@0.28.2)(jiti@2.7.0)(less@4.9.0(supports-color@11.0.0))(sass@1.102.0)(terser@5.50.0)(tsx@4.23.12)(yaml@2.9.0) + vite: 8.2.2(@types/node@22.20.1)(esbuild@0.28.2)(jiti@2.7.0)(less@4.9.0(supports-color@11.0.0))(sass@1.103.1)(terser@5.50.0)(tsx@4.23.12)(yaml@2.9.0) '@vitest/coverage-v8@4.1.11(vitest@4.1.11)': dependencies: @@ -11509,7 +11782,7 @@ snapshots: obug: 2.1.4 std-env: 4.2.0 tinyrainbow: 3.1.1 - vitest: 4.1.11(@opentelemetry/api@1.9.1)(@types/node@22.20.1)(@vitest/coverage-v8@4.1.11)(esbuild@0.28.2)(jiti@2.7.0)(jsdom@30.0.1)(less@4.9.0(supports-color@11.0.0))(sass@1.102.0)(terser@5.50.0)(tsx@4.23.12)(yaml@2.9.0) + vitest: 4.1.11(@opentelemetry/api@1.9.1)(@types/node@22.20.1)(@vitest/coverage-v8@4.1.11)(esbuild@0.28.2)(jiti@2.7.0)(jsdom@30.0.1)(less@4.9.0(supports-color@11.0.0))(sass@1.103.1)(terser@5.50.0)(tsx@4.23.12)(yaml@2.9.0) '@vitest/expect@4.1.11': dependencies: @@ -11520,13 +11793,13 @@ snapshots: chai: 6.2.2 tinyrainbow: 3.1.1 - '@vitest/mocker@4.1.11(vite@8.2.1(@types/node@22.20.1)(esbuild@0.28.2)(jiti@2.7.0)(less@4.9.0(supports-color@11.0.0))(sass@1.102.0)(terser@5.50.0)(tsx@4.23.12)(yaml@2.9.0))': + '@vitest/mocker@4.1.11(vite@8.2.2(@types/node@22.20.1)(esbuild@0.28.2)(jiti@2.7.0)(less@4.9.0(supports-color@11.0.0))(sass@1.103.1)(terser@5.50.0)(tsx@4.23.12)(yaml@2.9.0))': dependencies: '@vitest/spy': 4.1.11 estree-walker: 3.0.3 magic-string: 0.30.21 optionalDependencies: - vite: 8.2.1(@types/node@22.20.1)(esbuild@0.28.2)(jiti@2.7.0)(less@4.9.0(supports-color@11.0.0))(sass@1.102.0)(terser@5.50.0)(tsx@4.23.12)(yaml@2.9.0) + vite: 8.2.2(@types/node@22.20.1)(esbuild@0.28.2)(jiti@2.7.0)(less@4.9.0(supports-color@11.0.0))(sass@1.103.1)(terser@5.50.0)(tsx@4.23.12)(yaml@2.9.0) '@vitest/pretty-format@4.1.11': dependencies: @@ -12857,9 +13130,9 @@ snapshots: escape-string-regexp@4.0.0: {} - eslint-config-prettier@10.1.8(eslint@10.8.1(jiti@2.7.0)(supports-color@11.0.0)): + eslint-config-prettier@10.1.8(eslint@10.9.0(jiti@2.7.0)(supports-color@11.0.0)): dependencies: - eslint: 10.8.1(jiti@2.7.0)(supports-color@11.0.0) + eslint: 10.9.0(jiti@2.7.0)(supports-color@11.0.0) eslint-import-resolver-node@0.3.10(supports-color@11.0.0): dependencies: @@ -12869,17 +13142,17 @@ snapshots: transitivePeerDependencies: - supports-color - eslint-module-utils@2.14.0(@typescript-eslint/parser@8.67.0(eslint@10.8.1(jiti@2.7.0)(supports-color@11.0.0))(supports-color@11.0.0)(typescript@6.0.3))(eslint-import-resolver-node@0.3.10(supports-color@11.0.0))(eslint@10.8.1(jiti@2.7.0)(supports-color@11.0.0))(supports-color@11.0.0): + eslint-module-utils@2.14.0(@typescript-eslint/parser@8.67.0(eslint@10.9.0(jiti@2.7.0)(supports-color@11.0.0))(supports-color@11.0.0)(typescript@6.0.3))(eslint-import-resolver-node@0.3.10(supports-color@11.0.0))(eslint@10.9.0(jiti@2.7.0)(supports-color@11.0.0))(supports-color@11.0.0): dependencies: debug: 3.2.7(supports-color@11.0.0) optionalDependencies: - '@typescript-eslint/parser': 8.67.0(eslint@10.8.1(jiti@2.7.0)(supports-color@11.0.0))(supports-color@11.0.0)(typescript@6.0.3) - eslint: 10.8.1(jiti@2.7.0)(supports-color@11.0.0) + '@typescript-eslint/parser': 8.67.0(eslint@10.9.0(jiti@2.7.0)(supports-color@11.0.0))(supports-color@11.0.0)(typescript@6.0.3) + eslint: 10.9.0(jiti@2.7.0)(supports-color@11.0.0) eslint-import-resolver-node: 0.3.10(supports-color@11.0.0) transitivePeerDependencies: - supports-color - eslint-plugin-import@2.32.0(@typescript-eslint/parser@8.67.0(eslint@10.8.1(jiti@2.7.0)(supports-color@11.0.0))(supports-color@11.0.0)(typescript@6.0.3))(eslint@10.8.1(jiti@2.7.0)(supports-color@11.0.0))(supports-color@11.0.0): + eslint-plugin-import@2.32.0(@typescript-eslint/parser@8.67.0(eslint@10.9.0(jiti@2.7.0)(supports-color@11.0.0))(supports-color@11.0.0)(typescript@6.0.3))(eslint@10.9.0(jiti@2.7.0)(supports-color@11.0.0))(supports-color@11.0.0): dependencies: '@rtsao/scc': 1.1.0 array-includes: 3.1.9 @@ -12888,9 +13161,9 @@ snapshots: array.prototype.flatmap: 1.3.3 debug: 3.2.7(supports-color@11.0.0) doctrine: 2.1.0 - eslint: 10.8.1(jiti@2.7.0)(supports-color@11.0.0) + eslint: 10.9.0(jiti@2.7.0)(supports-color@11.0.0) eslint-import-resolver-node: 0.3.10(supports-color@11.0.0) - eslint-module-utils: 2.14.0(@typescript-eslint/parser@8.67.0(eslint@10.8.1(jiti@2.7.0)(supports-color@11.0.0))(supports-color@11.0.0)(typescript@6.0.3))(eslint-import-resolver-node@0.3.10(supports-color@11.0.0))(eslint@10.8.1(jiti@2.7.0)(supports-color@11.0.0))(supports-color@11.0.0) + eslint-module-utils: 2.14.0(@typescript-eslint/parser@8.67.0(eslint@10.9.0(jiti@2.7.0)(supports-color@11.0.0))(supports-color@11.0.0)(typescript@6.0.3))(eslint-import-resolver-node@0.3.10(supports-color@11.0.0))(eslint@10.9.0(jiti@2.7.0)(supports-color@11.0.0))(supports-color@11.0.0) hasown: 2.0.4 is-core-module: 2.16.2 is-glob: 4.0.3 @@ -12902,7 +13175,7 @@ snapshots: string.prototype.trimend: 1.0.10 tsconfig-paths: 3.15.0 optionalDependencies: - '@typescript-eslint/parser': 8.67.0(eslint@10.8.1(jiti@2.7.0)(supports-color@11.0.0))(supports-color@11.0.0)(typescript@6.0.3) + '@typescript-eslint/parser': 8.67.0(eslint@10.9.0(jiti@2.7.0)(supports-color@11.0.0))(supports-color@11.0.0)(typescript@6.0.3) transitivePeerDependencies: - eslint-import-resolver-typescript - eslint-import-resolver-webpack @@ -12926,9 +13199,9 @@ snapshots: eslint-visitor-keys@5.0.1: {} - eslint@10.8.1(jiti@2.7.0)(supports-color@11.0.0): + eslint@10.9.0(jiti@2.7.0)(supports-color@11.0.0): dependencies: - '@eslint-community/eslint-utils': 4.10.1(eslint@10.8.1(jiti@2.7.0)(supports-color@11.0.0)) + '@eslint-community/eslint-utils': 4.10.1(eslint@10.9.0(jiti@2.7.0)(supports-color@11.0.0)) '@eslint-community/regexpp': 4.12.2 '@eslint/config-array': 0.23.5(supports-color@11.0.0) '@eslint/config-helpers': 0.7.0 @@ -14405,7 +14678,7 @@ snapshots: dependencies: '@jridgewell/sourcemap-codec': 1.5.5 - magic-string@1.2.1: + magic-string@1.2.2: dependencies: '@jridgewell/sourcemap-codec': 1.5.5 @@ -14627,12 +14900,12 @@ snapshots: jsonc-parser: 3.3.1 less: 4.9.0(supports-color@11.0.0) ora: 9.4.1 - piscina: 5.3.0 + piscina: 5.3.1 postcss: 8.5.26 - rolldown: 1.2.4 - rolldown-plugin-dts: 0.28.2(rolldown@1.2.4)(typescript@6.0.3) + rolldown: 1.2.5 + rolldown-plugin-dts: 0.28.2(rolldown@1.2.5)(typescript@6.0.3) rxjs: 7.8.2 - sass: 1.102.0 + sass: 1.103.1 tinyglobby: 0.2.17 tslib: 2.8.1 typescript: 6.0.3 @@ -14812,29 +15085,29 @@ snapshots: object-keys: 1.1.1 safe-push-apply: 1.0.0 - oxc-parser@0.145.0: + oxc-parser@0.146.0: dependencies: - '@oxc-project/types': 0.145.0 + '@oxc-project/types': 0.146.0 optionalDependencies: - '@oxc-parser/binding-android-arm-eabi': 0.145.0 - '@oxc-parser/binding-android-arm64': 0.145.0 - '@oxc-parser/binding-darwin-arm64': 0.145.0 - '@oxc-parser/binding-darwin-x64': 0.145.0 - '@oxc-parser/binding-freebsd-x64': 0.145.0 - '@oxc-parser/binding-linux-arm-gnueabihf': 0.145.0 - '@oxc-parser/binding-linux-arm-musleabihf': 0.145.0 - '@oxc-parser/binding-linux-arm64-gnu': 0.145.0 - '@oxc-parser/binding-linux-arm64-musl': 0.145.0 - '@oxc-parser/binding-linux-ppc64-gnu': 0.145.0 - '@oxc-parser/binding-linux-riscv64-gnu': 0.145.0 - '@oxc-parser/binding-linux-riscv64-musl': 0.145.0 - '@oxc-parser/binding-linux-s390x-gnu': 0.145.0 - '@oxc-parser/binding-linux-x64-gnu': 0.145.0 - '@oxc-parser/binding-linux-x64-musl': 0.145.0 - '@oxc-parser/binding-openharmony-arm64': 0.145.0 - '@oxc-parser/binding-win32-arm64-msvc': 0.145.0 - '@oxc-parser/binding-win32-ia32-msvc': 0.145.0 - '@oxc-parser/binding-win32-x64-msvc': 0.145.0 + '@oxc-parser/binding-android-arm-eabi': 0.146.0 + '@oxc-parser/binding-android-arm64': 0.146.0 + '@oxc-parser/binding-darwin-arm64': 0.146.0 + '@oxc-parser/binding-darwin-x64': 0.146.0 + '@oxc-parser/binding-freebsd-x64': 0.146.0 + '@oxc-parser/binding-linux-arm-gnueabihf': 0.146.0 + '@oxc-parser/binding-linux-arm-musleabihf': 0.146.0 + '@oxc-parser/binding-linux-arm64-gnu': 0.146.0 + '@oxc-parser/binding-linux-arm64-musl': 0.146.0 + '@oxc-parser/binding-linux-ppc64-gnu': 0.146.0 + '@oxc-parser/binding-linux-riscv64-gnu': 0.146.0 + '@oxc-parser/binding-linux-riscv64-musl': 0.146.0 + '@oxc-parser/binding-linux-s390x-gnu': 0.146.0 + '@oxc-parser/binding-linux-x64-gnu': 0.146.0 + '@oxc-parser/binding-linux-x64-musl': 0.146.0 + '@oxc-parser/binding-openharmony-arm64': 0.146.0 + '@oxc-parser/binding-win32-arm64-msvc': 0.146.0 + '@oxc-parser/binding-win32-ia32-msvc': 0.146.0 + '@oxc-parser/binding-win32-x64-msvc': 0.146.0 p-finally@1.0.0: {} @@ -14966,7 +15239,7 @@ snapshots: sonic-boom: 4.2.1 thread-stream: 3.2.0 - piscina@5.3.0: + piscina@5.3.1: optionalDependencies: '@napi-rs/nice': 1.1.1 @@ -15356,12 +15629,12 @@ snapshots: dependencies: glob: 10.5.0 - rolldown-plugin-dts@0.28.2(rolldown@1.2.4)(typescript@6.0.3): + rolldown-plugin-dts@0.28.2(rolldown@1.2.5)(typescript@6.0.3): dependencies: dts-resolver: 3.0.0 get-tsconfig: 5.0.0-beta.5 obug: 2.1.4 - rolldown: 1.2.4 + rolldown: 1.2.5 yuku-ast: 0.8.7 yuku-codegen: 0.8.7 yuku-parser: 0.8.7 @@ -15390,6 +15663,27 @@ snapshots: '@rolldown/binding-win32-arm64-msvc': 1.2.4 '@rolldown/binding-win32-x64-msvc': 1.2.4 + rolldown@1.2.5: + dependencies: + '@oxc-project/types': 0.146.0 + '@rolldown/pluginutils': 1.0.1 + optionalDependencies: + '@rolldown/binding-android-arm-eabi': 1.2.5 + '@rolldown/binding-android-arm64': 1.2.5 + '@rolldown/binding-darwin-arm64': 1.2.5 + '@rolldown/binding-darwin-x64': 1.2.5 + '@rolldown/binding-freebsd-x64': 1.2.5 + '@rolldown/binding-linux-arm-gnueabihf': 1.2.5 + '@rolldown/binding-linux-arm64-gnu': 1.2.5 + '@rolldown/binding-linux-arm64-musl': 1.2.5 + '@rolldown/binding-linux-ppc64-gnu': 1.2.5 + '@rolldown/binding-linux-s390x-gnu': 1.2.5 + '@rolldown/binding-linux-x64-gnu': 1.2.5 + '@rolldown/binding-linux-x64-musl': 1.2.5 + '@rolldown/binding-openharmony-arm64': 1.2.5 + '@rolldown/binding-win32-arm64-msvc': 1.2.5 + '@rolldown/binding-win32-x64-msvc': 1.2.5 + rollup-license-plugin@3.2.1: dependencies: get-npm-tarball-url: 2.1.0 @@ -15397,54 +15691,54 @@ snapshots: semver: 7.8.5 spdx-expression-validate: 2.0.0 - rollup-plugin-dts@6.5.1(rollup@4.62.4)(typescript@6.0.3): + rollup-plugin-dts@6.5.1(rollup@4.62.5)(typescript@6.0.3): dependencies: '@jridgewell/remapping': 2.3.5 '@jridgewell/sourcemap-codec': 1.5.5 convert-source-map: 2.0.0 magic-string: 0.30.21 - rollup: 4.62.4 + rollup: 4.62.5 typescript: 6.0.3 optionalDependencies: '@babel/code-frame': 8.0.0 - rollup-plugin-sourcemaps2@0.5.8(@types/node@22.20.1)(rollup@4.62.4): + rollup-plugin-sourcemaps2@0.5.8(@types/node@22.20.1)(rollup@4.62.5): dependencies: - '@rollup/pluginutils': 5.4.0(rollup@4.62.4) - rollup: 4.62.4 + '@rollup/pluginutils': 5.4.0(rollup@4.62.5) + rollup: 4.62.5 optionalDependencies: '@types/node': 22.20.1 - rollup@4.62.4: + rollup@4.62.5: dependencies: '@types/estree': 1.0.9 optionalDependencies: '@napi-rs/lzma-linux-x64-gnu': 1.5.1 - '@rollup/rollup-android-arm-eabi': 4.62.4 - '@rollup/rollup-android-arm64': 4.62.4 - '@rollup/rollup-darwin-arm64': 4.62.4 - '@rollup/rollup-darwin-x64': 4.62.4 - '@rollup/rollup-freebsd-arm64': 4.62.4 - '@rollup/rollup-freebsd-x64': 4.62.4 - '@rollup/rollup-linux-arm-gnueabihf': 4.62.4 - '@rollup/rollup-linux-arm-musleabihf': 4.62.4 - '@rollup/rollup-linux-arm64-gnu': 4.62.4 - '@rollup/rollup-linux-arm64-musl': 4.62.4 - '@rollup/rollup-linux-loong64-gnu': 4.62.4 - '@rollup/rollup-linux-loong64-musl': 4.62.4 - '@rollup/rollup-linux-ppc64-gnu': 4.62.4 - '@rollup/rollup-linux-ppc64-musl': 4.62.4 - '@rollup/rollup-linux-riscv64-gnu': 4.62.4 - '@rollup/rollup-linux-riscv64-musl': 4.62.4 - '@rollup/rollup-linux-s390x-gnu': 4.62.4 - '@rollup/rollup-linux-x64-gnu': 4.62.4 - '@rollup/rollup-linux-x64-musl': 4.62.4 - '@rollup/rollup-openbsd-x64': 4.62.4 - '@rollup/rollup-openharmony-arm64': 4.62.4 - '@rollup/rollup-win32-arm64-msvc': 4.62.4 - '@rollup/rollup-win32-ia32-msvc': 4.62.4 - '@rollup/rollup-win32-x64-gnu': 4.62.4 - '@rollup/rollup-win32-x64-msvc': 4.62.4 + '@rollup/rollup-android-arm-eabi': 4.62.5 + '@rollup/rollup-android-arm64': 4.62.5 + '@rollup/rollup-darwin-arm64': 4.62.5 + '@rollup/rollup-darwin-x64': 4.62.5 + '@rollup/rollup-freebsd-arm64': 4.62.5 + '@rollup/rollup-freebsd-x64': 4.62.5 + '@rollup/rollup-linux-arm-gnueabihf': 4.62.5 + '@rollup/rollup-linux-arm-musleabihf': 4.62.5 + '@rollup/rollup-linux-arm64-gnu': 4.62.5 + '@rollup/rollup-linux-arm64-musl': 4.62.5 + '@rollup/rollup-linux-loong64-gnu': 4.62.5 + '@rollup/rollup-linux-loong64-musl': 4.62.5 + '@rollup/rollup-linux-ppc64-gnu': 4.62.5 + '@rollup/rollup-linux-ppc64-musl': 4.62.5 + '@rollup/rollup-linux-riscv64-gnu': 4.62.5 + '@rollup/rollup-linux-riscv64-musl': 4.62.5 + '@rollup/rollup-linux-s390x-gnu': 4.62.5 + '@rollup/rollup-linux-x64-gnu': 4.62.5 + '@rollup/rollup-linux-x64-musl': 4.62.5 + '@rollup/rollup-openbsd-x64': 4.62.5 + '@rollup/rollup-openharmony-arm64': 4.62.5 + '@rollup/rollup-win32-arm64-msvc': 4.62.5 + '@rollup/rollup-win32-ia32-msvc': 4.62.5 + '@rollup/rollup-win32-x64-gnu': 4.62.5 + '@rollup/rollup-win32-x64-msvc': 4.62.5 fsevents: 2.3.3 router@2.2.0(supports-color@11.0.0): @@ -15500,12 +15794,12 @@ snapshots: dependencies: truncate-utf8-bytes: 1.0.2 - sass-loader@17.0.0(sass@1.102.0)(webpack@5.109.2(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.26)(uglify-js@3.19.3)): + sass-loader@17.0.0(sass@1.103.1)(webpack@5.109.2(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.26)(uglify-js@3.19.3)): optionalDependencies: - sass: 1.102.0 + sass: 1.103.1 webpack: 5.109.2(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.26)(uglify-js@3.19.3) - sass@1.102.0: + sass@1.103.1: dependencies: chokidar: 5.0.0 immutable: 5.1.9 @@ -16314,7 +16608,7 @@ snapshots: core-util-is: 1.0.2 extsprintf: 1.3.0 - vite@8.2.1(@types/node@22.20.1)(esbuild@0.28.2)(jiti@2.7.0)(less@4.9.0(supports-color@11.0.0))(sass@1.102.0)(terser@5.50.0)(tsx@4.23.12)(yaml@2.9.0): + vite@8.2.2(@types/node@22.20.1)(esbuild@0.28.2)(jiti@2.7.0)(less@4.9.0(supports-color@11.0.0))(sass@1.103.1)(terser@5.50.0)(tsx@4.23.12)(yaml@2.9.0): dependencies: lightningcss: 1.33.0 picomatch: 4.0.5 @@ -16327,15 +16621,15 @@ snapshots: fsevents: 2.3.3 jiti: 2.7.0 less: 4.9.0(supports-color@11.0.0) - sass: 1.102.0 + sass: 1.103.1 terser: 5.50.0 tsx: 4.23.12 yaml: 2.9.0 - vitest@4.1.11(@opentelemetry/api@1.9.1)(@types/node@22.20.1)(@vitest/coverage-v8@4.1.11)(esbuild@0.28.2)(jiti@2.7.0)(jsdom@30.0.1)(less@4.9.0(supports-color@11.0.0))(sass@1.102.0)(terser@5.50.0)(tsx@4.23.12)(yaml@2.9.0): + vitest@4.1.11(@opentelemetry/api@1.9.1)(@types/node@22.20.1)(@vitest/coverage-v8@4.1.11)(esbuild@0.28.2)(jiti@2.7.0)(jsdom@30.0.1)(less@4.9.0(supports-color@11.0.0))(sass@1.103.1)(terser@5.50.0)(tsx@4.23.12)(yaml@2.9.0): dependencies: '@vitest/expect': 4.1.11 - '@vitest/mocker': 4.1.11(vite@8.2.1(@types/node@22.20.1)(esbuild@0.28.2)(jiti@2.7.0)(less@4.9.0(supports-color@11.0.0))(sass@1.102.0)(terser@5.50.0)(tsx@4.23.12)(yaml@2.9.0)) + '@vitest/mocker': 4.1.11(vite@8.2.2(@types/node@22.20.1)(esbuild@0.28.2)(jiti@2.7.0)(less@4.9.0(supports-color@11.0.0))(sass@1.103.1)(terser@5.50.0)(tsx@4.23.12)(yaml@2.9.0)) '@vitest/pretty-format': 4.1.11 '@vitest/runner': 4.1.11 '@vitest/snapshot': 4.1.11 @@ -16352,7 +16646,7 @@ snapshots: tinyexec: 1.3.0 tinyglobby: 0.2.17 tinyrainbow: 3.1.1 - vite: 8.2.1(@types/node@22.20.1)(esbuild@0.28.2)(jiti@2.7.0)(less@4.9.0(supports-color@11.0.0))(sass@1.102.0)(terser@5.50.0)(tsx@4.23.12)(yaml@2.9.0) + vite: 8.2.2(@types/node@22.20.1)(esbuild@0.28.2)(jiti@2.7.0)(less@4.9.0(supports-color@11.0.0))(sass@1.103.1)(terser@5.50.0)(tsx@4.23.12)(yaml@2.9.0) why-is-node-running: 2.3.0 optionalDependencies: '@opentelemetry/api': 1.9.1 From 6acadf214c6435596c92168f472000d5728daa3d Mon Sep 17 00:00:00 2001 From: Charles Lyding <19598772+clydin@users.noreply.github.com> Date: Mon, 24 Aug 2026 10:51:46 -0400 Subject: [PATCH 332/787] refactor(@angular/build): parallelize multi-locale inlining with 2D task sharding The new `inlineFileBatch` worker action processes multiple locales per file in memory while parsing sourcemaps and extracting AST metadata once per batch. `I18nInliner` now provides `inlineAll` with adaptive 2D task partitioning across files and locales to maximize worker thread utilization across any project topology. The application builder's `inlineI18n` step now dispatches all locales in parallel prior to executing per-locale post-bundle actions. --- .../build/src/builders/application/i18n.ts | 17 +- .../src/tools/esbuild/i18n-inliner-worker.ts | 107 ++++- .../build/src/tools/esbuild/i18n-inliner.ts | 379 ++++++++++++++---- .../src/tools/esbuild/i18n-inliner_spec.ts | 171 ++++++++ 4 files changed, 570 insertions(+), 104 deletions(-) diff --git a/packages/angular/build/src/builders/application/i18n.ts b/packages/angular/build/src/builders/application/i18n.ts index 137336497885..f212659a14be 100644 --- a/packages/angular/build/src/builders/application/i18n.ts +++ b/packages/angular/build/src/builders/application/i18n.ts @@ -8,6 +8,7 @@ import { BuilderContext } from '@angular-devkit/architect'; import type { Metafile } from 'esbuild'; +import assert from 'node:assert'; import { readFile } from 'node:fs/promises'; import { join } from 'node:path'; import { @@ -74,7 +75,7 @@ export async function inlineI18n( ); try { - for (const locale of i18nOptions.inlineLocales) { + const localesToInline = Array.from(i18nOptions.inlineLocales, (locale) => { const localeDescription = i18nOptions.locales[locale]; let translationIntegrity: string | undefined = ''; for (const file of localeDescription.files) { @@ -85,12 +86,18 @@ export async function inlineI18n( translationIntegrity += (translationIntegrity ? '|' : '') + file.integrity; } - // A locale specific set of files is returned from the inliner. - const localeInlineResult = await inliner.inlineForLocale( + return { locale, - localeDescription.translation, + translation: localeDescription.translation, translationIntegrity, - ); + }; + }); + + const inlinedLocales = await inliner.inlineAll(localesToInline); + + for (const locale of i18nOptions.inlineLocales) { + const localeInlineResult = inlinedLocales.get(locale); + assert(localeInlineResult !== undefined, 'Inlined result must exist for locale: ' + locale); const localeOutputFiles = localeInlineResult.outputFiles; inlineResult.errors.push(...localeInlineResult.errors); inlineResult.warnings.push(...localeInlineResult.warnings); diff --git a/packages/angular/build/src/tools/esbuild/i18n-inliner-worker.ts b/packages/angular/build/src/tools/esbuild/i18n-inliner-worker.ts index b95f4eae53a9..379368088ad0 100644 --- a/packages/angular/build/src/tools/esbuild/i18n-inliner-worker.ts +++ b/packages/angular/build/src/tools/esbuild/i18n-inliner-worker.ts @@ -64,10 +64,45 @@ interface InlineCodeRequest { translation?: Blob; } +/** + * The options passed to the inliner for a batch file request + */ +interface InlineFileBatchRequest { + /** + * The filename that should be processed. The data for the file is provided to the Worker + * during Worker initialization. + */ + filename: string; + + /** + * The locale specifiers or locale objects that should be used during the inlining process of the file. + */ + locales: (string | { locale: string; translation?: Blob })[]; +} + +/** + * The result for a single locale within a batch file request. + */ +interface InlineLocaleResult { + locale: string; + code: string; + map?: string; + messages: { type: 'error' | 'warning'; message: string }[]; +} + +/** + * The response returned from a batch file request. + */ +interface InlineFileBatchResult { + file: string; + results: InlineLocaleResult[]; +} + // Extract the application files and common options used for inline requests from the Worker context -const { files, missingTranslation } = (workerData || {}) as { +const { files, missingTranslation, translations } = (workerData || {}) as { files: ReadonlyMap; missingTranslation: 'error' | 'warning' | 'ignore'; + translations?: ReadonlyMap; }; /** @@ -113,24 +148,30 @@ function getFileData(filename: string): Promise { } /** - * Deserializes the translation messages for an inline request, reusing the result for any + * Deserializes the translation messages for a locale, reusing the result for any * subsequent request that targets the same locale. - * @param request An inline request containing the locale and its serialized messages. + * @param locale The locale identifier. + * @param translation Optional serialized translation messages. If omitted, workerData.translations is used. * @returns The translation messages, or undefined if the locale has no translations. */ function loadTranslation( - request: InlineFileRequest | InlineCodeRequest, + locale: string, + translation?: Blob, ): Promise> | undefined { - const { locale, translation } = request; - if (!translation) { + const translationBlob = translation ?? translations?.get(locale); + if (!translationBlob) { return undefined; } let messagesPromise = deserializedTranslations.get(locale); if (!messagesPromise) { - messagesPromise = translation + messagesPromise = translationBlob .arrayBuffer() - .then((buffer) => deserialize(new Uint8Array(buffer)) as Record); + .then((buffer) => deserialize(new Uint8Array(buffer)) as Record) + .catch((error) => { + deserializedTranslations.delete(locale); + throw error; + }); deserializedTranslations.set(locale, messagesPromise); } @@ -149,8 +190,6 @@ export default async function inlineFile(request: InlineFileRequest) { // Sourcemaps are parsed on demand per request rather than cached long-term to prevent // monotonic memory growth as a worker processes multiple files across the build. - // When multi-locale batching is implemented, the sourcemap can be parsed once per batch and released - // upon batch completion. const rawMap = await files.get(request.filename + '.map')?.text(); const map = rawMap ? (JSON.parse(rawMap) as SourceMapInput) : undefined; @@ -159,7 +198,7 @@ export default async function inlineFile(request: InlineFileRequest) { map, metadata, request.locale, - await loadTranslation(request), + await loadTranslation(request.locale, request.translation), request.filename, ); @@ -171,6 +210,50 @@ export default async function inlineFile(request: InlineFileRequest) { }; } +/** + * Inlines multiple locales and translations into a JavaScript file that contains `$localize` usage. + * + * @param request An InlineFileBatchRequest object representing the options for inlining. + * @returns An object containing the inlined results for each requested locale. + */ +export async function inlineFileBatch( + request: InlineFileBatchRequest, +): Promise { + const { code, metadata } = await getFileData(request.filename); + + // Parse the sourcemap once for the entire batch. + // It will naturally be garbage-collected after this batch action returns. + const rawMap = await files.get(request.filename + '.map')?.text(); + const map = rawMap ? (JSON.parse(rawMap) as SourceMapInput) : undefined; + + const results = await Promise.all( + request.locales.map(async (entry) => { + const locale = typeof entry === 'string' ? entry : entry.locale; + const translation = typeof entry === 'string' ? undefined : entry.translation; + const result = await inlineLocalize( + code, + map, + metadata, + locale, + await loadTranslation(locale, translation), + request.filename, + ); + + return { + locale, + code: result.code, + map: result.map, + messages: result.diagnostics.messages, + }; + }), + ); + + return { + file: request.filename, + results, + }; +} + /** * Inlines the provided locale and translation into JavaScript code that contains `$localize` usage. * This function is a secondary entry primarily for use with component HMR update modules. @@ -185,7 +268,7 @@ export async function inlineCode(request: InlineCodeRequest) { undefined, metadata, request.locale, - await loadTranslation(request), + await loadTranslation(request.locale, request.translation), request.filename, ); diff --git a/packages/angular/build/src/tools/esbuild/i18n-inliner.ts b/packages/angular/build/src/tools/esbuild/i18n-inliner.ts index a65d28516cce..535aae960b34 100644 --- a/packages/angular/build/src/tools/esbuild/i18n-inliner.ts +++ b/packages/angular/build/src/tools/esbuild/i18n-inliner.ts @@ -43,6 +43,71 @@ export interface I18nInlinerOptions { shouldOptimize?: boolean; persistentCachePath?: string; localizeVersion?: string; + translations?: ReadonlyMap; +} + +/** + * Options for inlining a specific locale. + */ +export interface LocaleInlineOptions { + /** + * The locale specifier string. + */ + locale: string; + + /** + * The translation messages for the locale, or undefined for the source/untranslated locale. + */ + translation?: Record; + + /** + * An optional content integrity hash of the translation file(s) for fast cache key calculation. + */ + translationIntegrity?: string; +} + +/** + * Result of inlining for a specific locale. + */ +export interface LocaleInlineResult { + outputFiles: BuildOutputFile[]; + errors: string[]; + warnings: string[]; +} + +/** + * Transformation result for a single file and locale combination. + */ +interface TransformedFileResult { + file: string; + code: string; + map?: string; + messages: { type: 'error' | 'warning'; message: string }[]; +} + +/** + * Represents an in-flight asynchronous cache lookup for a single (file x locale) transformation. + */ +interface CacheCheckItem { + /** + * The relative file path of the JavaScript file to transform. + */ + filename: string; + + /** + * The locale specifier being targeted for translation. + */ + locale: string; + + /** + * The computed cache key hash, or undefined if persistent caching is not configured. + */ + cacheKey: string | undefined; + + /** + * A promise that resolves to the cached transform result, or null if uncached or on lookup failure. + */ + cachedResult: Promise; } /** @@ -63,7 +128,7 @@ export class I18nInliner { maxThreads?: number, ) { this.#unmodifiedFiles = []; - const { outputFiles, shouldOptimize, missingTranslation } = options; + const { outputFiles, shouldOptimize, missingTranslation, translations } = options; const files = new Map(); const pendingMaps = []; @@ -115,6 +180,7 @@ export class I18nInliner { workerData: { missingTranslation, shouldOptimize, + translations, // A Blob is an immutable data structure that allows sharing the data between workers // without copying until the data is actually used within a Worker. This is useful here // since each file may not actually be processed in each Worker and the Blob avoids @@ -127,120 +193,259 @@ export class I18nInliner { } /** - * Performs inlining of translations for the provided locale and translations. The files that - * are processed originate from the files passed to the class constructor and filter by presence - * of the localize function keyword. - * @param locale The string representing the locale to inline. - * @param translation The translation messages to use when inlining. - * @param translationIntegrity An optional integrity value for the translation messages to use for caching. - * @returns A promise that resolves to an array of OutputFiles representing a translated result. + * Performs inlining of translations across multiple locales in parallel. + * + * An adaptive 2D task-partitioning algorithm distributes (files x locales) work units + * across all worker threads while caching AST metadata and sourcemaps in worker memory. + * + * @param locales The locales and translations to inline. + * @returns A map of locale names to their inlined output files and diagnostics. */ - async inlineForLocale( - locale: string, - translation: Record | undefined, - translationIntegrity?: string, - ): Promise<{ outputFiles: BuildOutputFile[]; errors: string[]; warnings: string[] }> { + async inlineAll( + locales: Iterable, + ): Promise> { await this.initCache(); - const { shouldOptimize, missingTranslation } = this.options; + const { shouldOptimize, missingTranslation, localizeVersion } = this.options; + const localeList = Array.from(locales); - // Serialized once here and then shared by the request for every file of this locale - const translationBlob = serializeTranslation(translation); + if (localeList.length === 0) { + return new Map(); + } - // Request inlining for each file that contains localize calls - const requests = []; + const fileResultsByLocale = new Map>(); + for (const { locale } of localeList) { + fileResultsByLocale.set(locale, new Map()); + } - let fileCacheKeyBase: string | undefined; + // Pre-calculate cache key bases and serialized Blobs for each requested locale + const localeCacheBases = new Map(); + const localeBlobs = new Map(); - for (const [filename, file] of this.#localizeFiles) { - let cacheKey: string | undefined; - if (filename.endsWith('.map')) { - continue; - } + for (const { locale, translation, translationIntegrity } of localeList) { + localeBlobs.set(locale, serializeTranslation(translation)); - let cacheResultPromise = Promise.resolve(null); if (this.#cache) { - // The options are digested here so that each file's key is derived from a fixed number - // of bytes. Hashing the options directly would re-hash the full set of messages, which - // can be several megabytes, once for every file. - fileCacheKeyBase ??= calculateHash( - JSON.stringify({ - locale, - translation: translationIntegrity ?? translation, - missingTranslation, - shouldOptimize, - localizeVersion: this.options.localizeVersion, - }), + localeCacheBases.set( + locale, + calculateHash( + JSON.stringify({ + locale, + translation: translationIntegrity || translation, + missingTranslation, + shouldOptimize, + localizeVersion, + }), + ), ); + } + } - // NOTE: If additional options are added, this may need to be updated. - const hasher = createContentHash(); - hasher.update(file.hash); - hasher.update(filename); - hasher.update(fileCacheKeyBase); - cacheKey = hasher.digest(); + const filenames = Array.from(this.#localizeFiles.keys()).filter( + (name) => !name.endsWith('.map'), + ); - // Failure to get the value should not fail the transform - cacheResultPromise = this.#cache.get(cacheKey).catch(() => null); - } + const cacheChecks: CacheCheckItem[] = []; - const fileResult = cacheResultPromise.then(async (cachedResult) => { - if (cachedResult) { - return cachedResult; + for (const filename of filenames) { + const file = this.#localizeFiles.get(filename); + assert(file !== undefined, 'Localize file must exist: ' + filename); + + for (const { locale } of localeList) { + let cacheKey: string | undefined; + let cachedResultPromise: Promise = Promise.resolve(null); + + if (this.#cache) { + const fileCacheKeyBase = localeCacheBases.get(locale); + assert(fileCacheKeyBase !== undefined, 'Cache base must exist for locale: ' + locale); + + const hasher = createContentHash(); + hasher.update(file.hash); + hasher.update(filename); + hasher.update(fileCacheKeyBase); + cacheKey = hasher.digest(); + + cachedResultPromise = this.#cache.get(cacheKey).catch(() => null); } - const result = await this.#workerPool.run({ + cacheChecks.push({ filename, locale, - translation: translationBlob, + cacheKey, + cachedResult: cachedResultPromise, }); - if (this.#cache && cacheKey) { - try { - // Failure to set the value should not fail the transform - await this.#cache.set(cacheKey, result); - } catch {} - } + } + } - return result; - }); + // Await all cache checks + const resolvedChecks = await Promise.all( + cacheChecks.map(async (item) => ({ + ...item, + result: await item.cachedResult, + })), + ); + + // Group uncached items by filename + const uncachedByFile = new Map< + string, + Array<{ locale: string; cacheKey?: string; translation?: Blob }> + >(); - requests.push(fileResult); + for (const item of resolvedChecks) { + if (item.result) { + // Cache hit: store directly in locale file results + fileResultsByLocale.get(item.locale)?.set(item.filename, item.result); + } else { + // Cache miss: needs worker processing + let fileEntries = uncachedByFile.get(item.filename); + if (!fileEntries) { + fileEntries = []; + uncachedByFile.set(item.filename, fileEntries); + } + fileEntries.push({ + locale: item.locale, + cacheKey: item.cacheKey, + translation: localeBlobs.get(item.locale), + }); + } } - // Wait for all file requests to complete - const rawResults = await Promise.all(requests); + // Adaptive 2D Sharding for uncached tasks + if (uncachedByFile.size > 0) { + await this.#processUncachedBatches(uncachedByFile, localeList.length, fileResultsByLocale); + } - // Convert raw results to output file objects and include all unmodified files - const errors: string[] = []; - const warnings: string[] = []; - const outputFiles = [ - ...rawResults.flatMap(({ file, code, map, messages }) => { - const type = this.#localizeFiles.get(file)?.type; - assert(type !== undefined, 'localized file should always have a type' + file); - - const resultFiles = [createOutputFile(file, code, type)]; - if (map) { - resultFiles.push(createOutputFile(file + '.map', map, type)); - } + // Assemble final results in deterministic order per locale + const resultsByLocale = new Map(); + + for (const { locale } of localeList) { + const fileResults = fileResultsByLocale.get(locale); + const outputFiles: BuildOutputFile[] = []; + const errors: string[] = []; + const warnings: string[] = []; + + if (fileResults) { + for (const filename of filenames) { + const fileResult = fileResults.get(filename); + if (!fileResult) { + continue; + } + + const type = this.#localizeFiles.get(filename)?.type; + assert(type !== undefined, 'localized file should always have a type: ' + filename); - for (const message of messages) { - if (message.type === 'error') { - errors.push(message.message); - } else { - warnings.push(message.message); + outputFiles.push(createOutputFile(filename, fileResult.code, type)); + if (fileResult.map) { + outputFiles.push(createOutputFile(filename + '.map', fileResult.map, type)); + } + + for (const message of fileResult.messages) { + if (message.type === 'error') { + errors.push(message.message); + } else { + warnings.push(message.message); + } } } + } - return resultFiles; - }), - ...this.#unmodifiedFiles.map((file) => file.clone()), - ]; + // Include cloned unmodified files for every locale + outputFiles.push(...this.#unmodifiedFiles.map((file) => file.clone())); - return { - outputFiles, - errors, - warnings, - }; + resultsByLocale.set(locale, { + outputFiles, + errors, + warnings, + }); + } + + return resultsByLocale; + } + + async #processUncachedBatches( + uncachedByFile: Map>, + localeCount: number, + fileResultsByLocale: Map>, + ): Promise { + const workerCount = this.#workerPool.maxThreads || 1; + const targetTaskCount = Math.max(uncachedByFile.size, workerCount * 2); + const localesPerBatch = Math.max( + 1, + Math.ceil(localeCount / (targetTaskCount / (uncachedByFile.size || 1))), + ); + + const workerTasks: Promise[] = []; + + for (const [filename, entries] of uncachedByFile) { + for (let i = 0; i < entries.length; i += localesPerBatch) { + const batchEntries = entries.slice(i, i + localesPerBatch); + const task = (async () => { + const batchResult = (await this.#workerPool.run( + { + filename, + locales: batchEntries.map((e) => ({ + locale: e.locale, + translation: e.translation, + })), + }, + { name: 'inlineFileBatch' }, + )) as { + file: string; + results: Array; + }; + + const cachePromises: Promise[] = []; + for (const res of batchResult.results) { + const matchingEntry = batchEntries.find((e) => e.locale === res.locale); + const cacheKey = matchingEntry?.cacheKey; + + if (this.#cache && cacheKey) { + // `CacheStore.set` may return `this` synchronously or a `Promise`. + // `Promise.resolve` normalizes both return values into a Promise so `Promise.allSettled` + // can safely handle any synchronous or asynchronous cache store errors. + cachePromises.push( + Promise.resolve( + this.#cache.set(cacheKey, { + file: filename, + code: res.code, + map: res.map, + messages: res.messages, + }), + ), + ); + } + + fileResultsByLocale.get(res.locale)?.set(filename, res); + } + await Promise.allSettled(cachePromises); + })(); + + workerTasks.push(task); + } + } + + await Promise.all(workerTasks); + } + + /** + * Performs inlining of translations for the provided locale and translations. The files that + * are processed originate from the files passed to the class constructor and filter by presence + * of the localize function keyword. + * @param locale The string representing the locale to inline. + * @param translation The translation messages to use when inlining. + * @param translationIntegrity An optional integrity value for the translation messages to use for caching. + * @returns A promise that resolves to an array of OutputFiles representing a translated result. + */ + async inlineForLocale( + locale: string, + translation: Record | undefined, + translationIntegrity?: string, + ): Promise { + const results = await this.inlineAll([{ locale, translation, translationIntegrity }]); + const result = results.get(locale); + assert(result !== undefined, `Result for locale '${locale}' should be present.`); + + return result; } async inlineTemplateUpdate( diff --git a/packages/angular/build/src/tools/esbuild/i18n-inliner_spec.ts b/packages/angular/build/src/tools/esbuild/i18n-inliner_spec.ts index 94f390e2334c..d71f9c0a8830 100644 --- a/packages/angular/build/src/tools/esbuild/i18n-inliner_spec.ts +++ b/packages/angular/build/src/tools/esbuild/i18n-inliner_spec.ts @@ -7,6 +7,9 @@ */ import { transform } from 'esbuild'; +import fs from 'node:fs/promises'; +import os from 'node:os'; +import path from 'node:path'; import { type BuildOutputFile, BuildOutputFileType, createOutputFile } from './bundler-files'; import { I18nInliner } from './i18n-inliner'; @@ -340,4 +343,172 @@ describe('I18nInliner', () => { expect(findFile(outputFiles, 'main.js').text).toContain('"Bonjour"'); expect(findFile(outputFiles, 'main.js').text).not.toContain('$localize'); }); + + it('inlines multiple locales in parallel via inlineAll', async () => { + const localeInliner = createInliner([ + browserFile('main.js', GREETING_SOURCE), + browserFile('chunk.js', GREETING_SOURCE), + browserFile('other.js', 'export const answer = 42;\n'), + ]); + + const results = await localeInliner.inlineAll([ + { locale: 'fr', translation: { greeting: translationFor('Bonjour') } }, + { locale: 'de', translation: { greeting: translationFor('Hallo') } }, + { locale: 'es', translation: { greeting: translationFor('Hola') } }, + { locale: 'en-US', translation: undefined }, + ]); + + expect(results.size).toBe(4); + + const fr = results.get('fr'); + expect(fr).toBeDefined(); + expect(fr?.errors).toEqual([]); + expect(fr?.warnings).toEqual([]); + expect(findFile(fr?.outputFiles ?? [], 'main.js').text).toContain('"Bonjour"'); + expect(findFile(fr?.outputFiles ?? [], 'chunk.js').text).toContain('"Bonjour"'); + expect(findFile(fr?.outputFiles ?? [], 'other.js').text).toBe('export const answer = 42;\n'); + + const de = results.get('de'); + expect(de).toBeDefined(); + expect(de?.errors).toEqual([]); + expect(findFile(de?.outputFiles ?? [], 'main.js').text).toContain('"Hallo"'); + + const es = results.get('es'); + expect(es).toBeDefined(); + expect(es?.errors).toEqual([]); + expect(findFile(es?.outputFiles ?? [], 'main.js').text).toContain('"Hola"'); + + const en = results.get('en-US'); + expect(en).toBeDefined(); + expect(en?.errors).toEqual([]); + expect(findFile(en?.outputFiles ?? [], 'main.js').text).toContain('"Hello"'); + }); + + it('inlines multiple locales with sourcemaps in parallel via inlineAll', async () => { + const { code, map } = await transform(GREETING_SOURCE, { + sourcefile: 'greeting.ts', + loader: 'ts', + sourcemap: 'external', + }); + + const localeInliner = createInliner([ + browserFile('main.js', code), + browserFile('main.js.map', map), + browserFile('other.js', 'export const answer = 42;\n'), + ]); + + const results = await localeInliner.inlineAll([ + { locale: 'fr', translation: { greeting: translationFor('Bonjour') } }, + { locale: 'de', translation: { greeting: translationFor('Hallo') } }, + { locale: 'en-US', translation: undefined }, + ]); + + expect(results.size).toBe(3); + + for (const [locale, greeting] of [ + ['fr', 'Bonjour'], + ['de', 'Hallo'], + ['en-US', 'Hello'], + ] as const) { + const localeResult = results.get(locale); + expect(localeResult).toBeDefined(); + expect(localeResult?.errors).toEqual([]); + expect(localeResult?.warnings).toEqual([]); + + const mainJs = findFile(localeResult?.outputFiles ?? [], 'main.js'); + expect(mainJs.text).toContain(`"${greeting}"`); + + const mainMap = findFile(localeResult?.outputFiles ?? [], 'main.js.map'); + const outputMap = JSON.parse(mainMap.text) as { + version: number; + sources: string[]; + mappings: string; + }; + expect(outputMap.version).toBe(3); + expect(outputMap.sources).toContain('greeting.ts'); + expect(outputMap.mappings.length).toBeGreaterThan(0); + + const otherJs = findFile(localeResult?.outputFiles ?? [], 'other.js'); + expect(otherJs.text).toBe('export const answer = 42;\n'); + } + }); + + it('inlines multiple locales with partial cache hits and misses via inlineAll', async () => { + const cacheDir = await fs.mkdtemp(path.join(os.tmpdir(), 'i18n-cache-test-')); + + try { + const initialInliner = new I18nInliner( + { + missingTranslation: 'warning', + outputFiles: [ + browserFile('main.js', GREETING_SOURCE), + browserFile('other.js', 'export const answer = 42;\n'), + ], + persistentCachePath: cacheDir, + }, + 2, + ); + + // Pre-populate cache for 'fr' + await initialInliner.inlineForLocale( + 'fr', + { greeting: translationFor('Bonjour') }, + 'integrity-fr-1', + ); + await initialInliner.close(); + + // Create new inliner with same cache path, inlining cached 'fr' alongside uncached 'de' and 'es' + inliner = new I18nInliner( + { + missingTranslation: 'warning', + outputFiles: [ + browserFile('main.js', GREETING_SOURCE), + browserFile('other.js', 'export const answer = 42;\n'), + ], + persistentCachePath: cacheDir, + }, + 2, + ); + + const results = await inliner.inlineAll([ + { + locale: 'fr', + translation: { greeting: translationFor('Bonjour') }, + translationIntegrity: 'integrity-fr-1', + }, + { + locale: 'de', + translation: { greeting: translationFor('Hallo') }, + translationIntegrity: 'integrity-de-1', + }, + { + locale: 'es', + translation: { greeting: translationFor('Hola') }, + translationIntegrity: 'integrity-es-1', + }, + ]); + + expect(results.size).toBe(3); + + const fr = results.get('fr'); + expect(fr?.errors).toEqual([]); + expect(findFile(fr?.outputFiles ?? [], 'main.js').text).toContain('"Bonjour"'); + expect(findFile(fr?.outputFiles ?? [], 'other.js').text).toBe('export const answer = 42;\n'); + + const de = results.get('de'); + expect(de?.errors).toEqual([]); + expect(findFile(de?.outputFiles ?? [], 'main.js').text).toContain('"Hallo"'); + + const es = results.get('es'); + expect(es?.errors).toEqual([]); + expect(findFile(es?.outputFiles ?? [], 'main.js').text).toContain('"Hola"'); + + // Verify deterministic file order matching input order + for (const localeResult of results.values()) { + expect(localeResult.outputFiles.map((f) => f.path)).toEqual(['main.js', 'other.js']); + } + } finally { + await fs.rm(cacheDir, { recursive: true, force: true }); + } + }); }); From e4111ae8180f3cd5800f248c23010844aa1730ad Mon Sep 17 00:00:00 2001 From: Alan Agius <17563226+alan-agius4@users.noreply.github.com> Date: Mon, 24 Aug 2026 09:30:50 +0000 Subject: [PATCH 333/787] fix(@angular/build): prevent memory leaks in parallel compilation and caches Deletes resolved stylesheetRequests in parallel worker, closes IPC channels in finally blocks, removes invalidated files from TypeScript source cache, and prunes stale watch files in load result cache. --- .../compilation/parallel-compilation.ts | 69 +++++-- .../angular/compilation/parallel-worker.ts | 188 ++++++++++-------- .../esbuild/angular/component-stylesheets.ts | 14 +- .../esbuild/angular/source-file-cache_spec.ts | 34 ++++ .../angular/build/src/tools/esbuild/cache.ts | 21 ++ .../build/src/tools/esbuild/cache_spec.ts | 17 ++ .../src/tools/esbuild/load-result-cache.ts | 25 ++- .../tools/esbuild/load-result-cache_spec.ts | 31 +++ 8 files changed, 293 insertions(+), 106 deletions(-) create mode 100644 packages/angular/build/src/tools/esbuild/angular/source-file-cache_spec.ts diff --git a/packages/angular/build/src/tools/angular/compilation/parallel-compilation.ts b/packages/angular/build/src/tools/angular/compilation/parallel-compilation.ts index af7602d72630..f9a504ee6fc0 100644 --- a/packages/angular/build/src/tools/angular/compilation/parallel-compilation.ts +++ b/packages/angular/build/src/tools/angular/compilation/parallel-compilation.ts @@ -30,6 +30,7 @@ import { */ export class ParallelCompilation extends AngularCompilation { readonly #worker: WorkerPool; + #webWorkerChannel?: MessageChannel; constructor( private readonly jit: boolean, @@ -47,7 +48,7 @@ export class ParallelCompilation extends AngularCompilation { }); } - override initialize( + override async initialize( tsconfig: string, hostOptions: AngularHostOptions, compilerOptionsTransformer?: (compilerOptions: CompilerOptions) => CompilerOptions, @@ -64,9 +65,12 @@ export class ParallelCompilation extends AngularCompilation { }, ); + this.#webWorkerChannel?.port1.close(); + // The web worker processing is a synchronous operation and uses shared memory combined with // the Atomics API to block execution here until a response is received. const webWorkerChannel = new MessageChannel(); + this.#webWorkerChannel = webWorkerChannel; const webWorkerSignal = new Int32Array(new SharedArrayBuffer(4)); webWorkerChannel.port1.on('message', ({ workerFile, containingFile }) => { try { @@ -89,31 +93,44 @@ export class ParallelCompilation extends AngularCompilation { const transformedOptions = compilerOptionsTransformer?.(compilerOptions) ?? compilerOptions; optionsChannel.port1.postMessage({ transformedOptions }); } catch (error) { - webWorkerChannel.port1.postMessage({ error }); + optionsChannel.port1.postMessage({ error }); } finally { Atomics.store(optionsSignal, 0, 1); Atomics.notify(optionsSignal, 0); } }); - // Execute the initialize function in the worker thread - return this.#worker.run( - { - fileReplacements: hostOptions.fileReplacements, - tsconfig, - jit: this.jit, - browserOnlyBuild: this.browserOnlyBuild, - stylesheetPort: stylesheetChannel.port2, - optionsPort: optionsChannel.port2, - optionsSignal, - webWorkerPort: webWorkerChannel.port2, - webWorkerSignal, - }, - { - name: 'initialize', - transferList: [stylesheetChannel.port2, optionsChannel.port2, webWorkerChannel.port2], - }, - ); + let success = false; + try { + // Execute the initialize function in the worker thread + const result = await this.#worker.run( + { + fileReplacements: hostOptions.fileReplacements, + tsconfig, + jit: this.jit, + browserOnlyBuild: this.browserOnlyBuild, + stylesheetPort: stylesheetChannel.port2, + optionsPort: optionsChannel.port2, + optionsSignal, + webWorkerPort: webWorkerChannel.port2, + webWorkerSignal, + }, + { + name: 'initialize', + transferList: [stylesheetChannel.port2, optionsChannel.port2, webWorkerChannel.port2], + }, + ); + success = true; + + return result; + } finally { + stylesheetChannel.port1.close(); + optionsChannel.port1.close(); + if (!success) { + this.#webWorkerChannel?.port1.close(); + this.#webWorkerChannel = undefined; + } + } } /** @@ -135,8 +152,13 @@ export class ParallelCompilation extends AngularCompilation { return result; } - override emitAffectedFiles(): Promise> { - return this.#worker.run(undefined, { name: 'emit' }); + override async emitAffectedFiles(): Promise> { + try { + return await this.#worker.run(undefined, { name: 'emit' }); + } finally { + this.#webWorkerChannel?.port1.close(); + this.#webWorkerChannel = undefined; + } } override update(files: Set): Promise { @@ -144,6 +166,9 @@ export class ParallelCompilation extends AngularCompilation { } override close() { + this.#webWorkerChannel?.port1.close(); + this.#webWorkerChannel = undefined; + return this.#worker.destroy(); } } diff --git a/packages/angular/build/src/tools/angular/compilation/parallel-worker.ts b/packages/angular/build/src/tools/angular/compilation/parallel-worker.ts index d592b5fb4777..b736e710fa7d 100644 --- a/packages/angular/build/src/tools/angular/compilation/parallel-worker.ts +++ b/packages/angular/build/src/tools/angular/compilation/parallel-worker.ts @@ -33,99 +33,122 @@ export interface InitRequest { } let compilation: AngularCompilation | undefined; +let activeWebWorkerPort: MessagePort | undefined; const modifiedFiles = new Set(); export async function initialize(request: InitRequest): Promise { + activeWebWorkerPort?.close(); + activeWebWorkerPort = request.webWorkerPort; + const currentModifiedFiles = new Set(modifiedFiles); modifiedFiles.clear(); - await initializeHash(); - compilation ??= request.jit - ? new JitCompilation(request.browserOnlyBuild) - : new AotCompilation(request.browserOnlyBuild); - - const stylesheetRequests = new Map void, (reason: Error) => void]>(); - request.stylesheetPort.on('message', ({ requestId, value, error }) => { - if (error) { - stylesheetRequests.get(requestId)?.[1](error); - } else { - stylesheetRequests.get(requestId)?.[0](value); - } - }); - - const { - compilerOptions, - referencedFiles, - externalStylesheets, - templateUpdates, - componentResourcesDependencies, - } = await compilation.initialize( - request.tsconfig, - { - fileReplacements: request.fileReplacements, - modifiedFiles: currentModifiedFiles, - transformStylesheet(data, containingFile, stylesheetFile, order, className) { - const requestId = randomUUID(); - const resultPromise = new Promise((resolve, reject) => - stylesheetRequests.set(requestId, [resolve, reject]), - ); - - request.stylesheetPort.postMessage({ - requestId, - data, - containingFile, - stylesheetFile, - order, - className, - }); - - return resultPromise; + let success = false; + try { + await initializeHash(); + compilation ??= request.jit + ? new JitCompilation(request.browserOnlyBuild) + : new AotCompilation(request.browserOnlyBuild); + + const stylesheetRequests = new Map< + string, + [(value: string) => void, (reason: Error) => void] + >(); + request.stylesheetPort.on('message', ({ requestId, value, error }) => { + const handlers = stylesheetRequests.get(requestId); + if (handlers) { + stylesheetRequests.delete(requestId); + if (error) { + handlers[1](error); + } else { + handlers[0](value); + } + } + }); + + const { + compilerOptions, + referencedFiles, + externalStylesheets, + templateUpdates, + componentResourcesDependencies, + } = await compilation.initialize( + request.tsconfig, + { + fileReplacements: request.fileReplacements, + modifiedFiles: currentModifiedFiles, + transformStylesheet(data, containingFile, stylesheetFile, order, className) { + const requestId = randomUUID(); + const resultPromise = new Promise((resolve, reject) => + stylesheetRequests.set(requestId, [resolve, reject]), + ); + + request.stylesheetPort.postMessage({ + requestId, + data, + containingFile, + stylesheetFile, + order, + className, + }); + + return resultPromise; + }, + processWebWorker(workerFile, containingFile) { + Atomics.store(request.webWorkerSignal, 0, 0); + request.webWorkerPort.postMessage({ workerFile, containingFile }); + + Atomics.wait(request.webWorkerSignal, 0, 0); + const result = receiveMessageOnPort(request.webWorkerPort)?.message; + + if (result?.error) { + throw result.error; + } + + return result?.workerCodeFile ?? workerFile; + }, }, - processWebWorker(workerFile, containingFile) { - Atomics.store(request.webWorkerSignal, 0, 0); - request.webWorkerPort.postMessage({ workerFile, containingFile }); + (compilerOptions) => { + Atomics.store(request.optionsSignal, 0, 0); + request.optionsPort.postMessage(compilerOptions); - Atomics.wait(request.webWorkerSignal, 0, 0); - const result = receiveMessageOnPort(request.webWorkerPort)?.message; + Atomics.wait(request.optionsSignal, 0, 0); + const result = receiveMessageOnPort(request.optionsPort)?.message; if (result?.error) { throw result.error; } - return result?.workerCodeFile ?? workerFile; + return result?.transformedOptions ?? compilerOptions; }, - }, - (compilerOptions) => { - Atomics.store(request.optionsSignal, 0, 0); - request.optionsPort.postMessage(compilerOptions); - - Atomics.wait(request.optionsSignal, 0, 0); - const result = receiveMessageOnPort(request.optionsPort)?.message; - - if (result?.error) { - throw result.error; - } - - return result?.transformedOptions ?? compilerOptions; - }, - ); - - return { - externalStylesheets, - templateUpdates, - referencedFiles, - // TODO: Expand? `allowJs`, `isolatedModules`, `sourceMap`, `inlineSourceMap` are the only fields needed currently. - compilerOptions: { - allowJs: compilerOptions.allowJs, - isolatedModules: compilerOptions.isolatedModules, - sourceMap: compilerOptions.sourceMap, - inlineSourceMap: compilerOptions.inlineSourceMap, - _useTypeScriptTranspilation: compilerOptions['_useTypeScriptTranspilation'] as - boolean | undefined, - }, - componentResourcesDependencies, - }; + ); + + success = true; + + return { + externalStylesheets, + templateUpdates, + referencedFiles, + // TODO: Expand? `allowJs`, `isolatedModules`, `sourceMap`, `inlineSourceMap` are the only fields needed currently. + compilerOptions: { + allowJs: compilerOptions.allowJs, + isolatedModules: compilerOptions.isolatedModules, + sourceMap: compilerOptions.sourceMap, + inlineSourceMap: compilerOptions.inlineSourceMap, + _useTypeScriptTranspilation: compilerOptions['_useTypeScriptTranspilation'] as + boolean | undefined, + }, + componentResourcesDependencies, + }; + } finally { + request.stylesheetPort.close(); + request.optionsPort.close(); + if (!success) { + activeWebWorkerPort?.close(); + activeWebWorkerPort = undefined; + } + } } export async function diagnose(modes: DiagnosticModes): Promise<{ @@ -147,9 +170,14 @@ export async function diagnose(modes: DiagnosticModes): Promise<{ export async function emit() { assert(compilation); - const files = await compilation.emitAffectedFiles(); + try { + const files = await compilation.emitAffectedFiles(); - return [...files]; + return [...files]; + } finally { + activeWebWorkerPort?.close(); + activeWebWorkerPort = undefined; + } } export async function update(files: Set): Promise { diff --git a/packages/angular/build/src/tools/esbuild/angular/component-stylesheets.ts b/packages/angular/build/src/tools/esbuild/angular/component-stylesheets.ts index f636e91fce4b..7cfc6e91e9f2 100644 --- a/packages/angular/build/src/tools/esbuild/angular/component-stylesheets.ts +++ b/packages/angular/build/src/tools/esbuild/angular/component-stylesheets.ts @@ -176,6 +176,7 @@ export class ComponentStylesheetBundler { } const normalizedFiles = [...files].map(path.normalize); + const normalizedFilesSet = new Set(normalizedFiles); let entries: string[] | undefined; for (const [entry, bundler] of this.#fileContexts.entries()) { @@ -184,8 +185,17 @@ export class ComponentStylesheetBundler { entries.push(entry); } } - for (const bundler of this.#inlineContexts.values()) { - bundler.invalidate(normalizedFiles); + for (const [entry, bundler] of this.#inlineContexts.entries()) { + // Entry is format: [language, id, filename].join(';') + const firstSemi = entry.indexOf(';'); + const secondSemi = firstSemi !== -1 ? entry.indexOf(';', firstSemi + 1) : -1; + const filename = secondSemi !== -1 ? entry.slice(secondSemi + 1) : ''; + if (filename && normalizedFilesSet.has(path.normalize(filename))) { + this.#inlineContexts.delete(entry); + void bundler.dispose(); + } else { + bundler.invalidate(normalizedFiles); + } } return entries; diff --git a/packages/angular/build/src/tools/esbuild/angular/source-file-cache_spec.ts b/packages/angular/build/src/tools/esbuild/angular/source-file-cache_spec.ts new file mode 100644 index 000000000000..1a3b2c402618 --- /dev/null +++ b/packages/angular/build/src/tools/esbuild/angular/source-file-cache_spec.ts @@ -0,0 +1,34 @@ +/** + * @license + * Copyright Google LLC All Rights Reserved. + * + * Use of this source code is governed by an MIT-style license that can be + * found in the LICENSE file at https://angular.dev/license + */ + +import { SourceFileCache } from './source-file-cache'; + +describe('SourceFileCache', () => { + let cache: SourceFileCache; + + beforeEach(() => { + cache = new SourceFileCache(); + }); + + it('should clean up all caches on clear()', async () => { + cache.typeScriptFileCache.set('/test/app.component.ts', 'console.log("test");'); + cache.modifiedFiles.add('/test/app.component.ts'); + cache.referencedFiles = ['/test/app.component.ts']; + await cache.loadResultCache.put('file:/test/app.component.ts', { + contents: 'test', + loader: 'js', + }); + + cache.clear(); + + expect(cache.typeScriptFileCache.size).toBe(0); + expect(cache.modifiedFiles.size).toBe(0); + expect(cache.referencedFiles).toBeUndefined(); + expect(cache.loadResultCache.get('file:/test/app.component.ts')).toBeUndefined(); + }); +}); diff --git a/packages/angular/build/src/tools/esbuild/cache.ts b/packages/angular/build/src/tools/esbuild/cache.ts index 2bb6afcb725f..5f1cd0d2927b 100644 --- a/packages/angular/build/src/tools/esbuild/cache.ts +++ b/packages/angular/build/src/tools/esbuild/cache.ts @@ -195,6 +195,15 @@ export class Cache = CacheStore> { await this.store.set(namespacedKey, value); } + /** + * Clears internal state for a specific namespaced key (requests, write counts, and pending gets). + */ + protected deleteInternal(namespacedKey: string): void { + this.#requests.delete(namespacedKey); + this.#writeCounts.delete(namespacedKey); + this.#pendingGets.delete(namespacedKey); + } + /** * Clears the base class internal state (requests, write counts, and pending gets). */ @@ -213,6 +222,18 @@ export class MemoryCache extends Cache> { super(new Map()); } + /** + * Removes the specified key from the cache instance. + * @param key The key to remove. + * @returns True if an element in the Map existed and has been removed, or false if the element does not exist. + */ + delete(key: string): boolean { + const namespacedKey = this.withNamespace(key); + this.deleteInternal(namespacedKey); + + return this.store.delete(namespacedKey); + } + /** * Removes all entries from the cache instance. */ diff --git a/packages/angular/build/src/tools/esbuild/cache_spec.ts b/packages/angular/build/src/tools/esbuild/cache_spec.ts index a30852836eff..a81bfbd25acd 100644 --- a/packages/angular/build/src/tools/esbuild/cache_spec.ts +++ b/packages/angular/build/src/tools/esbuild/cache_spec.ts @@ -141,4 +141,21 @@ describe('MemoryCache', () => { const val2 = await cache.getOrCreate('key', () => 'should-not-run'); expect(val2).toBe('override-value'); }); + + it('should delete a cached key and allow creating a new value', async () => { + await cache.put('key', 'value-1'); + expect(await cache.get('key')).toBe('value-1'); + + const deleted = cache.delete('key'); + expect(deleted).toBeTrue(); + expect(await cache.get('key')).toBeUndefined(); + + // Subsequent getOrCreate should call creator + const newValue = await cache.getOrCreate('key', () => 'value-2'); + expect(newValue).toBe('value-2'); + }); + + it('should return false when deleting a non-existent key', () => { + expect(cache.delete('non-existent')).toBeFalse(); + }); }); diff --git a/packages/angular/build/src/tools/esbuild/load-result-cache.ts b/packages/angular/build/src/tools/esbuild/load-result-cache.ts index 00f803f2fdc7..a0e8d1139310 100644 --- a/packages/angular/build/src/tools/esbuild/load-result-cache.ts +++ b/packages/angular/build/src/tools/esbuild/load-result-cache.ts @@ -57,14 +57,35 @@ export class MemoryLoadResultCache implements LoadResultCache { } async put(path: string, result: OnLoadResult): Promise { + const previousWatchFiles = this.#watchFilesPerKey.get(path); + if (result.errors && result.errors.length > 0) { - const previousWatchFiles = this.#watchFilesPerKey.get(path); if (previousWatchFiles) { result.watchFiles = Array.from( new Set([...(result.watchFiles ?? []), ...previousWatchFiles]), ); } - } else if (result.watchFiles && result.watchFiles.length > 0) { + } + + const currentNormalizedWatchFiles = new Set(result.watchFiles?.map(normalize) ?? []); + + // Clean up any previous file dependencies that are no longer referenced + if (previousWatchFiles) { + for (const watchFile of previousWatchFiles) { + const normalizedWatchFile = normalize(watchFile); + if (!currentNormalizedWatchFiles.has(normalizedWatchFile)) { + const affected = this.#fileDependencies.get(normalizedWatchFile); + if (affected) { + affected.delete(path); + if (affected.size === 0) { + this.#fileDependencies.delete(normalizedWatchFile); + } + } + } + } + } + + if (result.watchFiles && result.watchFiles.length > 0) { this.#watchFilesPerKey.set(path, [...result.watchFiles]); } else { this.#watchFilesPerKey.delete(path); diff --git a/packages/angular/build/src/tools/esbuild/load-result-cache_spec.ts b/packages/angular/build/src/tools/esbuild/load-result-cache_spec.ts index fb0396aea829..a44256676653 100644 --- a/packages/angular/build/src/tools/esbuild/load-result-cache_spec.ts +++ b/packages/angular/build/src/tools/esbuild/load-result-cache_spec.ts @@ -82,4 +82,35 @@ describe('MemoryLoadResultCache', () => { expect(invalidated).toBeTrue(); expect(cache.get('file:/test/styles.css')).toBeUndefined(); }); + + it('should clean up previous file dependencies when put updates watchFiles', async () => { + const initialResult = { + contents: 'body { color: red; }', + loader: 'css' as const, + watchFiles: ['/test/styles.css', '/test/old-dep.json'], + }; + + await cache.put('file:/test/styles.css', initialResult); + expect(cache.watchFiles).toContain('/test/old-dep.json'); + + // Update with new watch files (not containing old-dep.json) + const updatedResult = { + contents: 'body { color: blue; }', + loader: 'css' as const, + watchFiles: ['/test/styles.css', '/test/new-dep.json'], + }; + + await cache.put('file:/test/styles.css', updatedResult); + expect(cache.watchFiles).not.toContain('/test/old-dep.json'); + expect(cache.watchFiles).toContain('/test/new-dep.json'); + + // Invalidating old dependency should not affect the cache + expect(cache.invalidate('/test/old-dep.json')).toBeFalse(); + expect(cache.get('file:/test/styles.css')).toBe(updatedResult); + + // Invalidating new dependency should invalidate the cache + expect(cache.invalidate('/test/new-dep.json')).toBeTrue(); + expect(cache.get('file:/test/styles.css')).toBeUndefined(); + expect(cache.watchFiles).not.toContain('/test/new-dep.json'); + }); }); From 62999cabf4d65cf1060598150a77494e147fcc2a Mon Sep 17 00:00:00 2001 From: Alan Agius <17563226+alan-agius4@users.noreply.github.com> Date: Mon, 24 Aug 2026 10:53:04 +0000 Subject: [PATCH 334/787] perf(@angular/build): batch prerender routes and share in-memory server bundles Back in-memory server bundles with SharedArrayBuffer to eliminate V8 structuredClone memory duplication across worker threads and loader hooks. Batch routes dynamically during prerendering to amortize IPC messaging and event loop scheduling overhead. --- .../esm-in-memory-loader/loader-hooks.ts | 28 +- .../esm-in-memory-loader/loader-hooks_spec.ts | 246 ++++++++++++++++++ .../esm-in-memory-loader/utils.ts | 38 +++ .../esm-in-memory-loader/utils_spec.ts | 147 +++++++++++ .../src/utils/server-rendering/prerender.ts | 145 +++++++---- .../utils/server-rendering/render-worker.ts | 52 +++- 6 files changed, 588 insertions(+), 68 deletions(-) create mode 100644 packages/angular/build/src/utils/server-rendering/esm-in-memory-loader/loader-hooks_spec.ts create mode 100644 packages/angular/build/src/utils/server-rendering/esm-in-memory-loader/utils_spec.ts diff --git a/packages/angular/build/src/utils/server-rendering/esm-in-memory-loader/loader-hooks.ts b/packages/angular/build/src/utils/server-rendering/esm-in-memory-loader/loader-hooks.ts index 1d0d9df32d30..6f21bfbc739b 100644 --- a/packages/angular/build/src/utils/server-rendering/esm-in-memory-loader/loader-hooks.ts +++ b/packages/angular/build/src/utils/server-rendering/esm-in-memory-loader/loader-hooks.ts @@ -16,6 +16,7 @@ import { fileURLToPath, pathToFileURL } from 'node:url'; * @note For some unknown reason, setting `globalThis.ngServerMode = true` does not work when using ESM loader hooks. */ const NG_SERVER_MODE_INIT_BYTES = new TextEncoder().encode('var ngServerMode=true;'); +const UTF8_DECODER = new TextDecoder(); /** * Node.js ESM loader to redirect imports to in memory files. @@ -25,12 +26,12 @@ const NG_SERVER_MODE_INIT_BYTES = new TextEncoder().encode('var ngServerMode=tru const MEMORY_URL_SCHEME = 'memory://'; export interface ESMInMemoryFileLoaderWorkerData { - outputFiles: Record; + outputFiles: Record; workspaceRoot: string; } let memoryVirtualRootUrl: string; -let outputFiles: Record; +let outputFiles: Record; export function initialize(data: ESMInMemoryFileLoaderWorkerData) { // This path does not actually exist but is used to overlay the in memory files with the @@ -84,7 +85,7 @@ export function resolve( } catch {} if ( - specifierUrl?.pathname && + specifierUrl?.href.startsWith(memoryVirtualRootUrl) && Object.hasOwn(outputFiles, specifierUrl.href.slice(memoryVirtualRootUrl.length)) ) { return { @@ -114,12 +115,14 @@ export async function load(url: string, context: { format?: string | null }, nex // Load the file from memory if the URL is based in the virtual root if (url.startsWith(memoryVirtualRootUrl)) { - const source = outputFiles[url.slice(memoryVirtualRootUrl.length)]; - assert(source !== undefined, 'Resolved in-memory ESM file should always exist: ' + url); + const rawSource = outputFiles[url.slice(memoryVirtualRootUrl.length)]; + assert(rawSource !== undefined, 'Resolved in-memory ESM file should always exist: ' + url); + + const source = typeof rawSource === 'string' ? rawSource : UTF8_DECODER.decode(rawSource); // In-memory files have already been transformer during bundling and can be returned directly return { - format, + format: format ?? 'module', shortCircuit: true, source, }; @@ -128,14 +131,15 @@ export async function load(url: string, context: { format?: string | null }, nex // Only module files potentially require transformation. Angular libraries that would // need linking are ESM only. if (format === 'module' && isFileProtocol(url)) { - const filePath = fileURLToPath(url); - let source = await readFile(filePath); - - if (filePath.includes('@angular/')) { - // Prepend 'var ngServerMode=true;' to the source. - source = Buffer.concat([NG_SERVER_MODE_INIT_BYTES, source]); + // Check url instead of filePath so the check is robust across Windows and POSIX path separators. + if (!url.includes('/@angular/')) { + return nextLoad(url, context); } + const filePath = fileURLToPath(url); + const fileBytes = await readFile(filePath); + const source = Buffer.concat([NG_SERVER_MODE_INIT_BYTES, fileBytes]); + return { format, shortCircuit: true, diff --git a/packages/angular/build/src/utils/server-rendering/esm-in-memory-loader/loader-hooks_spec.ts b/packages/angular/build/src/utils/server-rendering/esm-in-memory-loader/loader-hooks_spec.ts new file mode 100644 index 000000000000..2b7622145378 --- /dev/null +++ b/packages/angular/build/src/utils/server-rendering/esm-in-memory-loader/loader-hooks_spec.ts @@ -0,0 +1,246 @@ +/** + * @license + * Copyright Google LLC All Rights Reserved. + * + * Use of this source code is governed by an MIT-style license that can be + * found in the LICENSE file at https://angular.dev/license + */ + +import { initialize, load, resolve } from './loader-hooks'; +import { createSharedServerFiles } from './utils'; + +describe('esm-in-memory-loader loader-hooks', () => { + const workspaceRoot = '/mock/workspace/root'; + const sharedFiles = createSharedServerFiles({ + 'main.server.mjs': 'export const main = true;', + 'chunk-abc.mjs': 'export const chunk = "abc";', + 'nested/chunk-sub.mjs': 'export const sub = "sub";', + 'utf8.mjs': 'export const text = "🔥 UTF-8 🚀";', + 'empty.mjs': '', + }); + + beforeEach(() => { + initialize({ + workspaceRoot, + outputFiles: sharedFiles, + }); + }); + + describe('resolve', () => { + it('should resolve memory:// URLs into virtual filesystem URLs', () => { + const nextResolve = jasmine.createSpy('nextResolve'); + const memoryUrl = new URL('./main.server.mjs', 'memory://').href; + const result = resolve(memoryUrl, { parentURL: undefined }, nextResolve); + + expect(nextResolve).not.toHaveBeenCalled(); + expect(result.format).toBe('module'); + expect(result.shortCircuit).toBeTrue(); + expect(result.url).toContain('/.angular/prerender-root/'); + expect(result.url).toContain('/main.server.mjs'); + }); + + it('should fail when memory:// URL is malformed', () => { + const nextResolve = jasmine.createSpy('nextResolve'); + expect(() => { + resolve('memory://::invalid', { parentURL: undefined }, nextResolve); + }).toThrowMatching((err: Error) => + err.message.includes('External code attempted to use malformed memory scheme'), + ); + expect(nextResolve).not.toHaveBeenCalled(); + }); + + it('should resolve relative specifiers within in-memory files', () => { + const memoryUrl = new URL('./main.server.mjs', 'memory://').href; + const rootResolve = resolve(memoryUrl, { parentURL: undefined }, () => {}); + const parentURL = rootResolve.url; + + const nextResolve = jasmine.createSpy('nextResolve'); + const result = resolve('./chunk-abc.mjs', { parentURL }, nextResolve); + + expect(nextResolve).not.toHaveBeenCalled(); + expect(result.format).toBe('module'); + expect(result.shortCircuit).toBeTrue(); + expect(result.url).toContain('/chunk-abc.mjs'); + }); + + it('should resolve relative specifiers navigating parent directories within in-memory files', () => { + const memoryUrl = new URL('./nested/chunk-sub.mjs', 'memory://').href; + const rootResolve = resolve(memoryUrl, { parentURL: undefined }, () => {}); + const parentURL = rootResolve.url; + + const nextResolve = jasmine.createSpy('nextResolve'); + const result = resolve('../chunk-abc.mjs', { parentURL }, nextResolve); + + expect(nextResolve).not.toHaveBeenCalled(); + expect(result.format).toBe('module'); + expect(result.shortCircuit).toBeTrue(); + expect(result.url).toContain('/chunk-abc.mjs'); + }); + + it('should fail when relative specifier from in-memory file does not exist', () => { + const memoryUrl = new URL('./main.server.mjs', 'memory://').href; + const rootResolve = resolve(memoryUrl, { parentURL: undefined }, () => {}); + const parentURL = rootResolve.url; + + const nextResolve = jasmine.createSpy('nextResolve'); + expect(() => { + resolve('./non-existent.mjs', { parentURL }, nextResolve); + }).toThrowMatching((err: Error) => + err.message.includes('In-memory ESM relative file should always exist'), + ); + expect(nextResolve).not.toHaveBeenCalled(); + }); + + it('should rewrite parentURL to index.js in virtual root for bare package specifiers', () => { + const memoryUrl = new URL('./main.server.mjs', 'memory://').href; + const rootResolve = resolve(memoryUrl, { parentURL: undefined }, () => {}); + const parentURL = rootResolve.url; + + const nextResolve = jasmine + .createSpy('nextResolve') + .and.returnValue({ url: 'file:///some/node_modules/@angular/core/index.js' }); + const result = resolve('@angular/core', { parentURL }, nextResolve); + + expect(nextResolve).toHaveBeenCalledWith( + '@angular/core', + jasmine.objectContaining({ + parentURL: jasmine.stringMatching(/\/\.angular\/prerender-root\/[^/]+\/index\.js$/), + }), + ); + expect(result.url).toBe('file:///some/node_modules/@angular/core/index.js'); + }); + + it('should delegate to nextResolve for external non-memory URLs', () => { + const nextResolve = jasmine + .createSpy('nextResolve') + .and.returnValue({ url: 'file:///some/ext/pkg' }); + const result = resolve('some-pkg', { parentURL: 'file:///some/ext/file.js' }, nextResolve); + + expect(nextResolve).toHaveBeenCalledWith('some-pkg', { + parentURL: 'file:///some/ext/file.js', + }); + expect(result.url).toBe('file:///some/ext/pkg'); + }); + }); + + describe('load', () => { + it('should load in-memory file source from SharedArrayBuffer backed Uint8Array', async () => { + const memoryUrl = new URL('./main.server.mjs', 'memory://').href; + const rootResolve = resolve(memoryUrl, { parentURL: undefined }, () => {}); + const nextLoad = jasmine.createSpy('nextLoad'); + + const result = await load(rootResolve.url, { format: 'module' }, nextLoad); + + expect(nextLoad).not.toHaveBeenCalled(); + expect(result.format).toBe('module'); + expect(result.shortCircuit).toBeTrue(); + expect(result.source).toBe('export const main = true;'); + }); + + it('should load in-memory file with multi-byte UTF-8 characters', async () => { + const memoryUrl = new URL('./utf8.mjs', 'memory://').href; + const rootResolve = resolve(memoryUrl, { parentURL: undefined }, () => {}); + const nextLoad = jasmine.createSpy('nextLoad'); + + const result = await load(rootResolve.url, { format: 'module' }, nextLoad); + + expect(nextLoad).not.toHaveBeenCalled(); + expect(result.format).toBe('module'); + expect(result.shortCircuit).toBeTrue(); + expect(result.source).toBe('export const text = "🔥 UTF-8 🚀";'); + }); + + it('should load in-memory file with empty content', async () => { + const memoryUrl = new URL('./empty.mjs', 'memory://').href; + const rootResolve = resolve(memoryUrl, { parentURL: undefined }, () => {}); + const nextLoad = jasmine.createSpy('nextLoad'); + + const result = await load(rootResolve.url, { format: 'module' }, nextLoad); + + expect(nextLoad).not.toHaveBeenCalled(); + expect(result.format).toBe('module'); + expect(result.shortCircuit).toBeTrue(); + expect(result.source).toBe(''); + }); + + it('should load in-memory file source with non-zero byteOffset in Uint8Array', async () => { + const target = 'export const sliced = 42;'; + const fullBuffer = Buffer.from(`__PADDING__${target}__MORE__`); + const offset = Buffer.byteLength('__PADDING__', 'utf-8'); + const length = Buffer.byteLength(target, 'utf-8'); + const subView = new Uint8Array(fullBuffer.buffer, fullBuffer.byteOffset + offset, length); + + initialize({ + workspaceRoot, + outputFiles: { + 'sliced.mjs': subView, + }, + }); + + const memoryUrl = new URL('./sliced.mjs', 'memory://').href; + const rootResolve = resolve(memoryUrl, { parentURL: undefined }, () => {}); + const nextLoad = jasmine.createSpy('nextLoad'); + + const result = await load(rootResolve.url, { format: 'module' }, nextLoad); + + expect(nextLoad).not.toHaveBeenCalled(); + expect(result.format).toBe('module'); + expect(result.shortCircuit).toBeTrue(); + expect(result.source).toBe(target); + }); + + it('should load in-memory file source when outputFiles contain string values', async () => { + initialize({ + workspaceRoot, + outputFiles: { + 'string-file.mjs': 'export const fromString = 1;', + }, + }); + + const memoryUrl = new URL('./string-file.mjs', 'memory://').href; + const rootResolve = resolve(memoryUrl, { parentURL: undefined }, () => {}); + const nextLoad = jasmine.createSpy('nextLoad'); + + const result = await load(rootResolve.url, { format: 'module' }, nextLoad); + + expect(nextLoad).not.toHaveBeenCalled(); + expect(result.format).toBe('module'); + expect(result.shortCircuit).toBeTrue(); + expect(result.source).toBe('export const fromString = 1;'); + }); + + it('should reject when in-memory file does not exist in outputFiles', async () => { + const memoryUrl = new URL('./main.server.mjs', 'memory://').href; + const rootResolve = resolve(memoryUrl, { parentURL: undefined }, () => {}); + const nonExistentVirtualUrl = rootResolve.url.replace('main.server.mjs', 'missing.mjs'); + const nextLoad = jasmine.createSpy('nextLoad'); + + await expectAsync( + load(nonExistentVirtualUrl, { format: 'module' }, nextLoad), + ).toBeRejectedWithError(/Resolved in-memory ESM file should always exist/); + expect(nextLoad).not.toHaveBeenCalled(); + }); + + it('should delegate to nextLoad for non-angular file URLs', async () => { + const nextLoad = jasmine.createSpy('nextLoad').and.resolveTo({ format: 'module' }); + const result = await load( + 'file:///workspace/node_modules/rxjs/index.js', + { format: 'module' }, + nextLoad, + ); + + expect(nextLoad).toHaveBeenCalledWith('file:///workspace/node_modules/rxjs/index.js', { + format: 'module', + }); + expect(result.format).toBe('module'); + }); + + it('should delegate to nextLoad for non-memory non-file URLs', async () => { + const nextLoad = jasmine.createSpy('nextLoad').and.resolveTo({ format: 'builtin' }); + const result = await load('node:fs', { format: 'builtin' }, nextLoad); + + expect(nextLoad).toHaveBeenCalledWith('node:fs'); + expect(result.format).toBe('builtin'); + }); + }); +}); diff --git a/packages/angular/build/src/utils/server-rendering/esm-in-memory-loader/utils.ts b/packages/angular/build/src/utils/server-rendering/esm-in-memory-loader/utils.ts index 3af354f6ba0f..7eb2bd1f5c49 100644 --- a/packages/angular/build/src/utils/server-rendering/esm-in-memory-loader/utils.ts +++ b/packages/angular/build/src/utils/server-rendering/esm-in-memory-loader/utils.ts @@ -11,3 +11,41 @@ import { pathToFileURL } from 'node:url'; export const IMPORT_EXEC_ARGV = '--import=' + pathToFileURL(join(__dirname, 'register-hooks.js')).href; + +/** + * Creates a shared zero-copy `Uint8Array` backed by a `SharedArrayBuffer` for the given file content. + */ +export function createSharedFile(content: string | Uint8Array): Uint8Array { + if (typeof content === 'string') { + const byteLength = Buffer.byteLength(content, 'utf-8'); + const sab = new SharedArrayBuffer(byteLength); + Buffer.from(sab).write(content, 'utf-8'); + + return new Uint8Array(sab); + } + + if (content.buffer instanceof SharedArrayBuffer) { + return content; + } + + const sab = new SharedArrayBuffer(content.byteLength); + const view = new Uint8Array(sab); + view.set(content); + + return view; +} + +/** + * Creates shared zero-copy `Uint8Array` views backed by `SharedArrayBuffer` for all output files. + */ +export function createSharedServerFiles( + outputFiles: Record, +): Record { + const sharedFiles: Record = {}; + + for (const [key, value] of Object.entries(outputFiles)) { + sharedFiles[key] = createSharedFile(value); + } + + return sharedFiles; +} diff --git a/packages/angular/build/src/utils/server-rendering/esm-in-memory-loader/utils_spec.ts b/packages/angular/build/src/utils/server-rendering/esm-in-memory-loader/utils_spec.ts new file mode 100644 index 000000000000..b7bb2844b66e --- /dev/null +++ b/packages/angular/build/src/utils/server-rendering/esm-in-memory-loader/utils_spec.ts @@ -0,0 +1,147 @@ +/** + * @license + * Copyright Google LLC All Rights Reserved. + * + * Use of this source code is governed by an MIT-style license that can be + * found in the LICENSE file at https://angular.dev/license + */ + +import { createSharedFile, createSharedServerFiles } from './utils'; + +describe('server-rendering shared file utilities', () => { + describe('createSharedFile', () => { + it('should create a Uint8Array backed by SharedArrayBuffer from string', () => { + const text = 'console.log("hello world");'; + const shared = createSharedFile(text); + + expect(shared instanceof Uint8Array).toBeTrue(); + expect(shared.buffer instanceof SharedArrayBuffer).toBeTrue(); + expect(shared.byteLength).toBe(Buffer.byteLength(text, 'utf-8')); + + const decoded = Buffer.from(shared.buffer, shared.byteOffset, shared.byteLength).toString( + 'utf-8', + ); + expect(decoded).toBe(text); + }); + + it('should correctly handle multi-byte UTF-8 characters', () => { + const text = 'export const greeting = "🚀 Привет, мир! 🌍";'; + const shared = createSharedFile(text); + + expect(shared.buffer instanceof SharedArrayBuffer).toBeTrue(); + const decoded = Buffer.from(shared.buffer, shared.byteOffset, shared.byteLength).toString( + 'utf-8', + ); + expect(decoded).toBe(text); + }); + + it('should handle empty string', () => { + const shared = createSharedFile(''); + + expect(shared.buffer instanceof SharedArrayBuffer).toBeTrue(); + expect(shared.byteLength).toBe(0); + const decoded = Buffer.from(shared.buffer, shared.byteOffset, shared.byteLength).toString( + 'utf-8', + ); + expect(decoded).toBe(''); + }); + + it('should handle empty Uint8Array', () => { + const shared = createSharedFile(new Uint8Array(0)); + + expect(shared.buffer instanceof SharedArrayBuffer).toBeTrue(); + expect(shared.byteLength).toBe(0); + }); + + it('should return the same Uint8Array if already backed by SharedArrayBuffer', () => { + const text = 'export default 42;'; + const shared1 = createSharedFile(text); + const shared2 = createSharedFile(shared1); + + expect(shared2).toBe(shared1); + expect(shared2.buffer).toBe(shared1.buffer); + }); + + it('should return existing Uint8Array view if already backed by SharedArrayBuffer with non-zero byteOffset', () => { + const text = '0123456789abcdef'; + const shared1 = createSharedFile(text); + const subView = new Uint8Array(shared1.buffer, 4, 8); + const shared2 = createSharedFile(subView); + + expect(shared2).toBe(subView); + expect(shared2.byteOffset).toBe(4); + expect(shared2.byteLength).toBe(8); + + const decoded = Buffer.from(shared2.buffer, shared2.byteOffset, shared2.byteLength).toString( + 'utf-8', + ); + expect(decoded).toBe('456789ab'); + }); + + it('should convert standard Uint8Array to SharedArrayBuffer backed Uint8Array', () => { + const regularBuffer = Buffer.from('export const test = true;'); + expect(regularBuffer.buffer instanceof SharedArrayBuffer).toBeFalse(); + + const shared = createSharedFile(regularBuffer); + expect(shared.buffer instanceof SharedArrayBuffer).toBeTrue(); + + const decoded = Buffer.from(shared.buffer, shared.byteOffset, shared.byteLength).toString( + 'utf-8', + ); + expect(decoded).toBe('export const test = true;'); + }); + + it('should handle Uint8Array slice with non-zero byteOffset from standard ArrayBuffer', () => { + const target = 'export const data = 123;'; + const fullBuffer = Buffer.from(`__PREFIX__${target}__SUFFIX__`); + const offset = Buffer.byteLength('__PREFIX__', 'utf-8'); + const length = Buffer.byteLength(target, 'utf-8'); + const subView = new Uint8Array(fullBuffer.buffer, fullBuffer.byteOffset + offset, length); + + const shared = createSharedFile(subView); + expect(shared.buffer instanceof SharedArrayBuffer).toBeTrue(); + expect(shared.byteLength).toBe(length); + + const decoded = Buffer.from(shared.buffer, shared.byteOffset, shared.byteLength).toString( + 'utf-8', + ); + expect(decoded).toBe(target); + }); + }); + + describe('createSharedServerFiles', () => { + it('should convert all entries in a record to SharedArrayBuffer backed Uint8Arrays', () => { + const files: Record = { + 'main.server.mjs': 'export default function() {}', + 'chunk-1.mjs': 'export const x = 1;', + 'render-utils.mjs': Buffer.from('export const helper = () => true;'), + }; + + const sharedFiles = createSharedServerFiles(files); + + expect(Object.keys(sharedFiles)).toEqual([ + 'main.server.mjs', + 'chunk-1.mjs', + 'render-utils.mjs', + ]); + + for (const [key, shared] of Object.entries(sharedFiles)) { + expect(shared instanceof Uint8Array).toBeTrue(); + expect(shared.buffer instanceof SharedArrayBuffer).toBeTrue(); + + const expectedText = + typeof files[key] === 'string' ? files[key] : (files[key] as Buffer).toString('utf-8'); + + const decoded = Buffer.from(shared.buffer, shared.byteOffset, shared.byteLength).toString( + 'utf-8', + ); + expect(decoded).toBe(expectedText); + } + }); + + it('should handle empty file map', () => { + const sharedFiles = createSharedServerFiles({}); + expect(Object.keys(sharedFiles).length).toBe(0); + }); + }); +}); diff --git a/packages/angular/build/src/utils/server-rendering/prerender.ts b/packages/angular/build/src/utils/server-rendering/prerender.ts index b4f81f03a800..37e29f02385b 100644 --- a/packages/angular/build/src/utils/server-rendering/prerender.ts +++ b/packages/angular/build/src/utils/server-rendering/prerender.ts @@ -16,7 +16,11 @@ import { assertIsError } from '../error'; import { toPosixPath } from '../path'; import { addLeadingSlash, addTrailingSlash, joinUrlParts, stripLeadingSlash } from '../url'; import { WorkerPool } from '../worker-pool'; -import { IMPORT_EXEC_ARGV } from './esm-in-memory-loader/utils'; +import { + IMPORT_EXEC_ARGV, + createSharedFile, + createSharedServerFiles, +} from './esm-in-memory-loader/utils'; import { SERVER_APP_MANIFEST_FILENAME } from './manifest'; import { RouteRenderMode, @@ -25,7 +29,7 @@ import { SerializableRouteTreeNode, WritableSerializableRouteTreeNode, } from './models'; -import type { RenderWorkerData } from './render-worker'; +import type { RenderResult, RenderWorkerData } from './render-worker'; import { generateRedirectStaticPage } from './utils'; type PrerenderOptions = NormalizedApplicationBuildOptions['prerenderOptions']; @@ -63,7 +67,7 @@ export async function prerenderPages( errors: string[]; serializableRouteTreeNode: SerializableRouteTreeNode; }> { - const outputFilesForWorker: Record = {}; + const rawOutputFiles: Record = {}; const serverBundlesSourceMaps = new Map(); const warnings: string[] = []; const errors: string[] = []; @@ -77,23 +81,25 @@ export async function prerenderPages( if (extname(path) === '.map') { serverBundlesSourceMaps.set(path.slice(0, -4), text); } else { - outputFilesForWorker[path] = text; + rawOutputFiles[path] = text; } } // Inline sourcemap into JS file. This is needed to make Node.js resolve sourcemaps // when using `--enable-source-maps` when using in memory files. for (const [filePath, map] of serverBundlesSourceMaps) { - const jsContent = outputFilesForWorker[filePath]; + const jsContent = rawOutputFiles[filePath]; if (jsContent) { - outputFilesForWorker[filePath] = + rawOutputFiles[filePath] = jsContent + - `\n//# sourceMappingURL=` + + '\n//# sourceMappingURL=' + `data:application/json;base64,${Buffer.from(map).toString('base64')}`; } } serverBundlesSourceMaps.clear(); + const outputFilesForWorker = createSharedServerFiles(rawOutputFiles); + const assetsReversed: Record = {}; for (const { source, destination } of assets) { // Assets are not stored with baseHref when using i18n, @@ -169,9 +175,13 @@ export async function prerenderPages( // We could re-generate it from the start, but that would require a number of options to be passed down. const manifest = outputFilesForWorker[SERVER_APP_MANIFEST_FILENAME]; if (manifest) { - outputFilesForWorker[SERVER_APP_MANIFEST_FILENAME] = manifest.replace( - 'routes: undefined,', - `routes: ${JSON.stringify(serializableRouteTreeNodeForPrerender, undefined, 2)},`, + const manifestText = new TextDecoder().decode(manifest); + + outputFilesForWorker[SERVER_APP_MANIFEST_FILENAME] = createSharedFile( + manifestText.replace( + 'routes: undefined,', + `routes: ${JSON.stringify(serializableRouteTreeNodeForPrerender, undefined, 2)},`, + ), ); } @@ -204,7 +214,7 @@ async function renderPages( serializableRouteTreeNode: SerializableRouteTreeNode, maxThreads: number, workspaceRoot: string, - outputFilesForWorker: Record, + outputFilesForWorker: Record, assetFilesForWorker: Record, outputMode: OutputMode | undefined, appShellRoute: string | undefined, @@ -214,15 +224,59 @@ async function renderPages( }> { const output: PrerenderOutput = {}; const errors: string[] = []; - const workerExecArgv = [IMPORT_EXEC_ARGV]; + const baseHrefPathnameWithLeadingSlash = new URL(baseHref, 'http://localhost').pathname; + const appShellRouteWithoutBaseHref = appShellRoute + ? addTrailingSlash(appShellRoute).startsWith(baseHrefPathnameWithLeadingSlash) + ? addLeadingSlash(appShellRoute.slice(baseHrefPathnameWithLeadingSlash.length)) + : addLeadingSlash(appShellRoute) + : undefined; + + const routesToRender: { route: string; outPath: string; isAppShell: boolean }[] = []; + + for (const { route, redirectTo } of serializableRouteTreeNode) { + // Remove the base href from the file output path. + const routeWithoutBaseHref = addTrailingSlash(route).startsWith( + baseHrefPathnameWithLeadingSlash, + ) + ? addLeadingSlash(route.slice(baseHrefPathnameWithLeadingSlash.length)) + : route; + + const outPath = stripLeadingSlash(posix.join(routeWithoutBaseHref, 'index.html')); + + if (typeof redirectTo === 'string') { + output[outPath] = { content: generateRedirectStaticPage(redirectTo), appShellRoute: false }; + + continue; + } + + routesToRender.push({ + route, + outPath, + isAppShell: appShellRouteWithoutBaseHref === routeWithoutBaseHref, + }); + } + + if (routesToRender.length === 0) { + return { + errors, + output, + }; + } + + // Batch routes to reduce IPC overhead while ensuring enough batches exist for load balancing across worker threads. + const batchSize = Math.max(1, Math.min(50, Math.ceil(routesToRender.length / (maxThreads * 4)))); + const numBatches = Math.ceil(routesToRender.length / batchSize); + const effectiveMaxThreads = Math.min(numBatches, maxThreads); + + const workerExecArgv = [IMPORT_EXEC_ARGV]; if (sourcemap) { workerExecArgv.push('--enable-source-maps'); } const renderWorker = new WorkerPool({ filename: require.resolve('./render-worker'), - maxThreads: Math.min(serializableRouteTreeNode.length, maxThreads), + maxThreads: effectiveMaxThreads, workerData: { workspaceRoot, outputFiles: outputFilesForWorker, @@ -238,45 +292,46 @@ async function renderPages( }); try { - const renderingPromises: Promise[] = []; - const appShellRouteWithLeadingSlash = appShellRoute && addLeadingSlash(appShellRoute); - const baseHrefPathnameWithLeadingSlash = new URL(baseHref, 'http://localhost').pathname; - - for (const { route, redirectTo } of serializableRouteTreeNode) { - // Remove the base href from the file output path. - const routeWithoutBaseHref = addTrailingSlash(route).startsWith( - baseHrefPathnameWithLeadingSlash, - ) - ? addLeadingSlash(route.slice(baseHrefPathnameWithLeadingSlash.length)) - : route; - - const outPath = stripLeadingSlash(posix.join(routeWithoutBaseHref, 'index.html')); - - if (typeof redirectTo === 'string') { - output[outPath] = { content: generateRedirectStaticPage(redirectTo), appShellRoute: false }; + const routeOutPathMap = new Map(); + for (const item of routesToRender) { + routeOutPathMap.set(item.route, item); + } - continue; - } + const renderingPromises: Promise[] = []; - const render: Promise = renderWorker.run({ url: route }); - const renderResult: Promise = render - .then((content) => { - if (content !== null) { - output[outPath] = { - content, - appShellRoute: appShellRouteWithLeadingSlash === routeWithoutBaseHref, - }; + for (let i = 0; i < routesToRender.length; i += batchSize) { + const batch = routesToRender.slice(i, i + batchSize); + const urls = batch.map((item) => item.route); + const renderBatchPromise: Promise = renderWorker.run(urls); + const batchResultPromise = renderBatchPromise + .then((results) => { + for (const { url, content, error } of results) { + if (error) { + errors.push(`An error occurred while prerendering route '${url}'.\n\n${error}`); + continue; + } + + if (content !== null) { + const routeInfo = routeOutPathMap.get(url); + if (routeInfo) { + output[routeInfo.outPath] = { + content, + appShellRoute: routeInfo.isAppShell, + }; + } + } } }) .catch((err) => { assertIsError(err); - errors.push( - `An error occurred while prerendering route '${route}'.\n\n${err.stack ?? err.message ?? err.code ?? err}`, - ); - void renderWorker.destroy(); + for (const url of urls) { + errors.push( + `An error occurred while prerendering route '${url}'.\n\n${err.stack ?? err.message ?? err.code ?? err}`, + ); + } }); - renderingPromises.push(renderResult); + renderingPromises.push(batchResultPromise); } await Promise.all(renderingPromises); @@ -293,7 +348,7 @@ async function renderPages( async function getAllRoutes( workspaceRoot: string, baseHref: string, - outputFilesForWorker: Record, + outputFilesForWorker: Record, assetFilesForWorker: Record, appShellOptions: AppShellOptions | undefined, prerenderOptions: PrerenderOptions | undefined, diff --git a/packages/angular/build/src/utils/server-rendering/render-worker.ts b/packages/angular/build/src/utils/server-rendering/render-worker.ts index 7ded0550b826..b8f01c440c4b 100644 --- a/packages/angular/build/src/utils/server-rendering/render-worker.ts +++ b/packages/angular/build/src/utils/server-rendering/render-worker.ts @@ -8,6 +8,7 @@ import { workerData } from 'node:worker_threads'; import type { OutputMode } from '../../builders/application/schema'; +import { assertIsError } from '../error'; import type { ESMInMemoryFileLoaderWorkerData } from './esm-in-memory-loader/loader-hooks'; import { patchFetchToLoadInMemoryAssets } from './fetch-patch'; import { DEFAULT_URL, launchServer } from './launch-server'; @@ -20,10 +21,14 @@ export interface RenderWorkerData extends ESMInMemoryFileLoaderWorkerData { hasSsrEntry: boolean; } -export interface RenderOptions { +export interface RenderResultItem { url: string; + content: string | null; + error?: string; } +export type RenderResult = RenderResultItem[]; + /** * This is passed as workerData when setting up the worker via the `piscina` package. */ @@ -35,16 +40,12 @@ const { outputMode, hasSsrEntry } = workerData as { let serverURL = DEFAULT_URL; /** - * Renders each route in routes and writes them to //index.html. + * Renders a single route URL. */ -async function renderPage({ url }: RenderOptions): Promise { - const { ɵgetOrCreateAngularServerApp: getOrCreateAngularServerApp } = - await loadEsmModuleFromMemory('./main.server.mjs'); - - const angularServerApp = getOrCreateAngularServerApp({ - allowStaticRouteRender: true, - }); - +async function renderPage( + url: string, + angularServerApp: { handle: (request: Request) => Promise }, +): Promise { const response = await angularServerApp.handle( new Request(new URL(url, serverURL), { signal: AbortSignal.timeout(30_000) }), ); @@ -58,6 +59,35 @@ async function renderPage({ url }: RenderOptions): Promise { return location ? generateRedirectStaticPage(location) : response.text(); } +/** + * Renders routes in batch or individual URL. + */ +async function renderPages(urls: string[]): Promise { + const { ɵgetOrCreateAngularServerApp: getOrCreateAngularServerApp } = + await loadEsmModuleFromMemory('./main.server.mjs'); + + const angularServerApp = getOrCreateAngularServerApp({ + allowStaticRouteRender: true, + }); + + const results: RenderResult = []; + for (const currentUrl of urls) { + try { + const content = await renderPage(currentUrl, angularServerApp); + results.push({ url: currentUrl, content }); + } catch (err) { + assertIsError(err); + results.push({ + url: currentUrl, + content: null, + error: err.stack ?? err.message ?? err.code ?? `${err}`, + }); + } + } + + return results; +} + async function initialize() { // Load the compiler because `@angular/ssr/node` depends on `@angular/` packages, // which must be processed by the runtime linker, even if they are not used. @@ -69,7 +99,7 @@ async function initialize() { patchFetchToLoadInMemoryAssets(serverURL); - return renderPage; + return renderPages; } export default initialize(); From e463c6ed9b9b80e7d46bbd594ba1da93ec86f11d Mon Sep 17 00:00:00 2001 From: Charles Lyding <19598772+clydin@users.noreply.github.com> Date: Mon, 24 Aug 2026 19:41:35 -0400 Subject: [PATCH 335/787] refactor(@angular/build): support direct builds and shared load cache in BundlerContext Enhance BundlerContext to allow incremental result caching without requiring a persistent esbuild context instance. The useContext constructor parameter defaults to incremental for backward compatibility while allowing callers to disable persistent contexts. Also support passing an external LoadResultCache instance to share load caches across contexts, and add an optional invalidate method to the LoadResultCache interface. --- .../src/tools/esbuild/bundler-context.ts | 74 ++++++++++++------- .../src/tools/esbuild/load-result-cache.ts | 16 ++-- .../tools/esbuild/load-result-cache_spec.ts | 5 +- 3 files changed, 60 insertions(+), 35 deletions(-) diff --git a/packages/angular/build/src/tools/esbuild/bundler-context.ts b/packages/angular/build/src/tools/esbuild/bundler-context.ts index 38a82d944e32..ae87e08d3524 100644 --- a/packages/angular/build/src/tools/esbuild/bundler-context.ts +++ b/packages/angular/build/src/tools/esbuild/bundler-context.ts @@ -17,7 +17,7 @@ import { context, } from 'esbuild'; import assert from 'node:assert'; -import { basename, extname, join, relative } from 'node:path'; +import { basename, extname, isAbsolute, join, normalize, relative } from 'node:path'; import { SERVER_GENERATED_EXTERNALS } from '../../utils/server-rendering/manifest'; import { type BuildOutputFile, @@ -79,16 +79,18 @@ export class BundlerContext { #disposed = false; #optionsFactory: BundlerOptionsFactory; #shouldCacheResult: boolean; - #loadCache?: MemoryLoadResultCache; + #loadCache?: LoadResultCache; readonly watchFiles = new Set(); constructor( private workspaceRoot: string, private incremental: boolean, options: BuildOptions | BundlerOptionsFactory, - private alwaysUseContext = false, + private useContext = incremental, private initialFilter?: (initial: Readonly) => boolean, + sharedLoadCache?: LoadResultCache, ) { + this.#loadCache = sharedLoadCache; // To cache the results an option factory is needed to capture the full set of dependencies this.#shouldCacheResult = incremental && typeof options === 'function'; this.#optionsFactory = (...args) => { @@ -219,7 +221,7 @@ export class BundlerContext { async #performBundle(): Promise { // Create esbuild options if not present if (this.#esbuildOptions === undefined) { - if (this.incremental) { + if (this.incremental && !this.#loadCache) { this.#loadCache = new MemoryLoadResultCache(); } this.#esbuildOptions = this.#optionsFactory(this.#loadCache); @@ -234,7 +236,7 @@ export class BundlerContext { if (this.#esbuildContext) { // Rebuild using the existing incremental build context result = await this.#esbuildContext.rebuild(); - } else if (this.incremental || this.alwaysUseContext) { + } else if (this.useContext) { // Create a build context and perform the build. // Context creation does not perform a build. const esbuildContext = await context(this.#esbuildOptions); @@ -258,23 +260,12 @@ export class BundlerContext { // Build failures will throw an exception which contains errors/warnings if (isEsBuildFailure(failure)) { this.#addErrorsToWatch(failure); + this.#addLoadCacheFilesToWatch(); return failure; } else { throw failure; } - } finally { - if (this.incremental) { - // When incremental always add any files from the load result cache - if (this.#loadCache) { - for (const file of this.#loadCache.watchFiles) { - if (!isInternalAngularFile(file)) { - // watch files are fully resolved paths - this.watchFiles.add(file); - } - } - } - } } // Update files that should be watched. @@ -283,18 +274,36 @@ export class BundlerContext { if (this.incremental) { // Add input files except virtual angular files which do not exist on disk for (const input of Object.keys(result.metafile.inputs)) { - if (isInternalAngularFile(input) || isInternalBundlerFile(input)) { - continue; + const isInternal = isInternalAngularFile(input) || isInternalBundlerFile(input); + + // Input file paths are always relative to the workspace root unless already absolute + const absoluteInput = isAbsolute(input) ? input : join(this.workspaceRoot, input); + const normalizedAbsoluteInput = normalize(absoluteInput); + + if (!isInternal) { + this.watchFiles.add(normalizedAbsoluteInput); } - // Input file paths are always relative to the workspace root - this.watchFiles.add(join(this.workspaceRoot, input)); + if (this.#loadCache) { + const cachedLoad = await (this.#loadCache.get(input) ?? + this.#loadCache.get(input.replace(';', ':')) ?? + this.#loadCache.get('file:' + absoluteInput) ?? + this.#loadCache.get('file:' + normalizedAbsoluteInput)); + if (cachedLoad?.watchFiles) { + for (const file of cachedLoad.watchFiles) { + if (!isInternalAngularFile(file)) { + this.watchFiles.add(isAbsolute(file) ? file : join(this.workspaceRoot, file)); + } + } + } + } } } // Return if the build encountered any errors if (result.errors.length) { this.#addErrorsToWatch(result); + this.#addLoadCacheFilesToWatch(); return { errors: result.errors, @@ -443,12 +452,24 @@ export class BundlerContext { for (const error of result.errors) { let file = error.location?.file; if (file && !isInternalAngularFile(file)) { - this.watchFiles.add(join(this.workspaceRoot, file)); + const absoluteFile = isAbsolute(file) ? file : join(this.workspaceRoot, file); + this.watchFiles.add(normalize(absoluteFile)); } for (const note of error.notes) { file = note.location?.file; if (file && !isInternalAngularFile(file)) { - this.watchFiles.add(join(this.workspaceRoot, file)); + const absoluteFile = isAbsolute(file) ? file : join(this.workspaceRoot, file); + this.watchFiles.add(normalize(absoluteFile)); + } + } + } + } + + #addLoadCacheFilesToWatch(): void { + if (this.incremental && this.#loadCache) { + for (const file of this.#loadCache.watchFiles) { + if (!isInternalAngularFile(file)) { + this.watchFiles.add(isAbsolute(file) ? file : join(this.workspaceRoot, file)); } } } @@ -468,12 +489,15 @@ export class BundlerContext { let invalid = false; for (const file of files) { - if (this.#loadCache?.invalidate(file)) { + const absoluteFile = isAbsolute(file) ? file : join(this.workspaceRoot, file); + const normalizedFile = normalize(absoluteFile); + + if (this.#loadCache?.invalidate(normalizedFile)) { invalid = true; continue; } - invalid ||= this.watchFiles.has(file); + invalid ||= this.watchFiles.has(normalizedFile); } if (invalid) { diff --git a/packages/angular/build/src/tools/esbuild/load-result-cache.ts b/packages/angular/build/src/tools/esbuild/load-result-cache.ts index a0e8d1139310..402069cff1a5 100644 --- a/packages/angular/build/src/tools/esbuild/load-result-cache.ts +++ b/packages/angular/build/src/tools/esbuild/load-result-cache.ts @@ -12,6 +12,7 @@ import { normalize } from 'node:path'; export interface LoadResultCache { get(path: string): OnLoadResult | Promise | undefined; put(path: string, result: OnLoadResult): Promise; + invalidate(path: string): boolean; readonly watchFiles: ReadonlyArray; } @@ -108,18 +109,15 @@ export class MemoryLoadResultCache implements LoadResultCache { invalidate(path: string): boolean { const affectedPaths = this.#fileDependencies.get(path); - let found = false; + if (!affectedPaths) { + return false; + } - if (affectedPaths) { - for (const affected of affectedPaths) { - if (this.#loadResults.delete(affected)) { - found = true; - } - } - this.#fileDependencies.delete(path); + for (const affected of affectedPaths) { + this.#loadResults.delete(affected); } - return found; + return true; } get watchFiles(): string[] { diff --git a/packages/angular/build/src/tools/esbuild/load-result-cache_spec.ts b/packages/angular/build/src/tools/esbuild/load-result-cache_spec.ts index a44256676653..8a8682beed61 100644 --- a/packages/angular/build/src/tools/esbuild/load-result-cache_spec.ts +++ b/packages/angular/build/src/tools/esbuild/load-result-cache_spec.ts @@ -111,6 +111,9 @@ describe('MemoryLoadResultCache', () => { // Invalidating new dependency should invalidate the cache expect(cache.invalidate('/test/new-dep.json')).toBeTrue(); expect(cache.get('file:/test/styles.css')).toBeUndefined(); - expect(cache.watchFiles).not.toContain('/test/new-dep.json'); + // Invalidating a file marks its cached results stale, but preserves watch file tracking + // so the file watcher continues monitoring the dependency for subsequent changes until + // a new build pass (via put) updates the active dependencies. + expect(cache.watchFiles).toContain('/test/new-dep.json'); }); }); From 643942b8a5fc78779fe0324a2a647532804b150a Mon Sep 17 00:00:00 2001 From: Charles Lyding <19598772+clydin@users.noreply.github.com> Date: Mon, 24 Aug 2026 21:14:06 -0400 Subject: [PATCH 336/787] refactor(@angular/build): share load cache across global stylesheet bundler contexts Update setupBundlerContexts to instantiate a single MemoryLoadResultCache and share it across initial and non-initial global stylesheet BundlerContext instances. This allows global stylesheet contexts to share load cache state without instantiating multiple separate cache instances. --- .../builders/application/setup-bundling.ts | 11 +++++++- .../src/tools/esbuild/bundler-context.ts | 26 ++++++++----------- 2 files changed, 21 insertions(+), 16 deletions(-) diff --git a/packages/angular/build/src/builders/application/setup-bundling.ts b/packages/angular/build/src/builders/application/setup-bundling.ts index 79209ba0eaf9..4380db080e87 100644 --- a/packages/angular/build/src/builders/application/setup-bundling.ts +++ b/packages/angular/build/src/builders/application/setup-bundling.ts @@ -19,6 +19,7 @@ import { import { BundlerContext } from '../../tools/esbuild/bundler-context'; import { createGlobalScriptsBundleOptions } from '../../tools/esbuild/global-scripts'; import { createGlobalStylesBundleOptions } from '../../tools/esbuild/global-styles'; +import { MemoryLoadResultCache } from '../../tools/esbuild/load-result-cache'; import { getSupportedNodeTargets } from '../../tools/esbuild/target'; import type { NormalizedApplicationBuildOptions } from './options'; @@ -94,11 +95,19 @@ export function setupBundlerContexts( // Global Stylesheets if (options.globalStyles.length > 0) { + const globalStylesCache = new MemoryLoadResultCache(); for (const initial of [true, false]) { const bundleOptions = createGlobalStylesBundleOptions(options, target, initial); if (bundleOptions) { otherContexts.push( - new BundlerContext(workspaceRoot, watch, bundleOptions, true, () => initial), + new BundlerContext( + workspaceRoot, + watch, + bundleOptions, + true, + () => initial, + globalStylesCache, + ), ); } } diff --git a/packages/angular/build/src/tools/esbuild/bundler-context.ts b/packages/angular/build/src/tools/esbuild/bundler-context.ts index ae87e08d3524..865ff301a214 100644 --- a/packages/angular/build/src/tools/esbuild/bundler-context.ts +++ b/packages/angular/build/src/tools/esbuild/bundler-context.ts @@ -277,8 +277,9 @@ export class BundlerContext { const isInternal = isInternalAngularFile(input) || isInternalBundlerFile(input); // Input file paths are always relative to the workspace root unless already absolute - const absoluteInput = isAbsolute(input) ? input : join(this.workspaceRoot, input); - const normalizedAbsoluteInput = normalize(absoluteInput); + const normalizedAbsoluteInput = isAbsolute(input) + ? normalize(input) + : join(this.workspaceRoot, input); if (!isInternal) { this.watchFiles.add(normalizedAbsoluteInput); @@ -287,12 +288,13 @@ export class BundlerContext { if (this.#loadCache) { const cachedLoad = await (this.#loadCache.get(input) ?? this.#loadCache.get(input.replace(';', ':')) ?? - this.#loadCache.get('file:' + absoluteInput) ?? this.#loadCache.get('file:' + normalizedAbsoluteInput)); if (cachedLoad?.watchFiles) { for (const file of cachedLoad.watchFiles) { if (!isInternalAngularFile(file)) { - this.watchFiles.add(isAbsolute(file) ? file : join(this.workspaceRoot, file)); + this.watchFiles.add( + isAbsolute(file) ? normalize(file) : join(this.workspaceRoot, file), + ); } } } @@ -452,14 +454,12 @@ export class BundlerContext { for (const error of result.errors) { let file = error.location?.file; if (file && !isInternalAngularFile(file)) { - const absoluteFile = isAbsolute(file) ? file : join(this.workspaceRoot, file); - this.watchFiles.add(normalize(absoluteFile)); + this.watchFiles.add(isAbsolute(file) ? normalize(file) : join(this.workspaceRoot, file)); } for (const note of error.notes) { file = note.location?.file; if (file && !isInternalAngularFile(file)) { - const absoluteFile = isAbsolute(file) ? file : join(this.workspaceRoot, file); - this.watchFiles.add(normalize(absoluteFile)); + this.watchFiles.add(isAbsolute(file) ? normalize(file) : join(this.workspaceRoot, file)); } } } @@ -469,7 +469,7 @@ export class BundlerContext { if (this.incremental && this.#loadCache) { for (const file of this.#loadCache.watchFiles) { if (!isInternalAngularFile(file)) { - this.watchFiles.add(isAbsolute(file) ? file : join(this.workspaceRoot, file)); + this.watchFiles.add(isAbsolute(file) ? normalize(file) : join(this.workspaceRoot, file)); } } } @@ -489,13 +489,9 @@ export class BundlerContext { let invalid = false; for (const file of files) { - const absoluteFile = isAbsolute(file) ? file : join(this.workspaceRoot, file); - const normalizedFile = normalize(absoluteFile); + const normalizedFile = isAbsolute(file) ? normalize(file) : join(this.workspaceRoot, file); - if (this.#loadCache?.invalidate(normalizedFile)) { - invalid = true; - continue; - } + this.#loadCache?.invalidate(normalizedFile); invalid ||= this.watchFiles.has(normalizedFile); } From bac09a56493749c56594c4ac19f0bab35991298b Mon Sep 17 00:00:00 2001 From: Angular Robot Date: Tue, 25 Aug 2026 05:03:29 +0000 Subject: [PATCH 337/787] build: lock file maintenance See associated pull request for more information. --- MODULE.bazel.lock | 2 +- pnpm-lock.yaml | 638 +++++++++++++--------------------------------- 2 files changed, 178 insertions(+), 462 deletions(-) diff --git a/MODULE.bazel.lock b/MODULE.bazel.lock index b1c759780a9a..ee16930eae77 100644 --- a/MODULE.bazel.lock +++ b/MODULE.bazel.lock @@ -452,7 +452,7 @@ "aspect_rules_jasmine": "2.0.4", "aspect_tools_telemetry": "0.4.2" }, - "last_notice": 0 + "last_notice": 1 } } }, diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index d396ec5afaf6..ad8a28e1ca05 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -282,7 +282,7 @@ importers: version: 6.10.0(encoding@0.1.13)(supports-color@11.0.0) verdaccio-auth-memory: specifier: ^13.0.0 - version: 13.1.1(supports-color@11.0.0) + version: 13.1.2(supports-color@11.0.0) zone.js: specifier: ^0.16.0 version: 0.16.2 @@ -2154,15 +2154,6 @@ packages: resolution: {integrity: sha512-3eTuUO1vH2cZm2ZKHeQxnOqlTi9EfZDGgIe3BL3I4u+rJHocr9Fz86M4fjYABPvFnQG/gGK551HqDiIcETwU6Q==} engines: {node: '>=23.5.0 || ^22.13.0 || ^20.17.0'} - '@inquirer/checkbox@5.2.1': - resolution: {integrity: sha512-b6xmA/VlTe0ZgDQHDui+Nav470u7u49nRd8/iuhOcQPO9Ch7lGuogydhi2VOmNlZ+zXcM8IcPuNSwQcdJaF/kw==} - engines: {node: '>=23.5.0 || ^22.13.0 || ^20.17.0'} - peerDependencies: - '@types/node': '>=18' - peerDependenciesMeta: - '@types/node': - optional: true - '@inquirer/checkbox@5.2.2': resolution: {integrity: sha512-Y5/bAScMy5Y+9isCx0SKbyJebMCaXXX5em0kxkj115eZNscgV9srOHrgyfS0e5xAVymIfOh9piYBKDILktsMMg==} engines: {node: '>=23.5.0 || ^22.13.0 || ^20.17.0'} @@ -2181,15 +2172,6 @@ packages: '@types/node': optional: true - '@inquirer/core@11.2.1': - resolution: {integrity: sha512-Qd6GJT1yVyrZZCfN8W2qKF5ApmqryXRhRKCuip8h01x2w/esJQ2XIYc6f9abMIHgKQdBfFTSOdbHRLAhuM09UA==} - engines: {node: '>=23.5.0 || ^22.13.0 || ^20.17.0'} - peerDependencies: - '@types/node': '>=18' - peerDependenciesMeta: - '@types/node': - optional: true - '@inquirer/core@12.0.0': resolution: {integrity: sha512-+nnvFEXIB08CZNVXpvW3B+zHW96QXvGUjNKJ8NJIPqAZi5Kd4WhYt2S3C234ReepG1qw2HOlEUbjYVHBowXObA==} engines: {node: '>=23.5.0 || ^22.13.0 || ^20.17.0'} @@ -2199,15 +2181,6 @@ packages: '@types/node': optional: true - '@inquirer/editor@5.2.2': - resolution: {integrity: sha512-ZRVd/oD+sYsUd5zVm0NflqEzlqfYCyHNsqkHl2oWXEUHs12tCbcSFi+wVFEvD8+LGRaMUsVrE7qeo6lSG/S1Vg==} - engines: {node: '>=23.5.0 || ^22.13.0 || ^20.17.0'} - peerDependencies: - '@types/node': '>=18' - peerDependenciesMeta: - '@types/node': - optional: true - '@inquirer/editor@5.3.0': resolution: {integrity: sha512-nnsP/IdJ8s83q7ZuObmgn12QM+uLCkab9E0Oordojbn62WUg1c+v9Ou/F/057pgh0ppX0W+Hj5bO/Dp5hsxQtA==} engines: {node: '>=23.5.0 || ^22.13.0 || ^20.17.0'} @@ -2217,15 +2190,6 @@ packages: '@types/node': optional: true - '@inquirer/expand@5.1.1': - resolution: {integrity: sha512-YmQpenjbFSHAK3sOd44puHh3V1KXXr+JiNpUztoSQ4drLh2rTVzTap/YtlAVu/5xavifIlBfNEzJ/neZJ1a/1g==} - engines: {node: '>=23.5.0 || ^22.13.0 || ^20.17.0'} - peerDependencies: - '@types/node': '>=18' - peerDependenciesMeta: - '@types/node': - optional: true - '@inquirer/expand@5.1.2': resolution: {integrity: sha512-OWIH1IyyWqEKIyqC9Xy+Bnga7NkGMovFdo4atYZMUOTRqf6rO2WCv9E/1MyzvOErDBCxs+9UFliRUDc50xs/jw==} engines: {node: '>=23.5.0 || ^22.13.0 || ^20.17.0'} @@ -2235,15 +2199,6 @@ packages: '@types/node': optional: true - '@inquirer/external-editor@3.0.3': - resolution: {integrity: sha512-6thf5I8q7lZwzGLAxPaaGEREEkZ3nyePPDQ1oyobblxmEE8mqTLguScP7pDjUTAibiyb4hfXl+qjUEJ+di/aNA==} - engines: {node: '>=23.5.0 || ^22.13.0 || ^20.17.0'} - peerDependencies: - '@types/node': '>=18' - peerDependenciesMeta: - '@types/node': - optional: true - '@inquirer/external-editor@3.0.4': resolution: {integrity: sha512-tZbbaK2ovq6vlrRBNQvjrypmrED/p5x2ncIHQ79cD55tei3dD96v5glMMA+6tiq7K104i/25DVYKWVPJuV6ptA==} engines: {node: '>=23.5.0 || ^22.13.0 || ^20.17.0'} @@ -2253,23 +2208,10 @@ packages: '@types/node': optional: true - '@inquirer/figures@2.0.7': - resolution: {integrity: sha512-aJ8TBPOGB6f/2qziPfElISTCEd5XOYTFckA2SGjhNmiKzfK/u4ot3v0DUzGVdUnKjN10EqnnEPck36BkyfLnJw==} - engines: {node: '>=23.5.0 || ^22.13.0 || ^20.17.0'} - '@inquirer/figures@2.0.8': resolution: {integrity: sha512-tApbon79GM9ry56ja/Ud3SY2CL4TQsao9fIwDQbgTeNY55025GdMzQ2+UdegV/lx51VNGUB59M0v0nMpybYY4Q==} engines: {node: '>=23.5.0 || ^22.13.0 || ^20.17.0'} - '@inquirer/input@5.1.2': - resolution: {integrity: sha512-9K/DDBSQpOyZSkt6sOVP9Vo0TR7atX2kuILsUu0x3wVcVbe97lJwIJKMLdMw25tDYuXl/qp6erT0Xs1rfmcfZg==} - engines: {node: '>=23.5.0 || ^22.13.0 || ^20.17.0'} - peerDependencies: - '@types/node': '>=18' - peerDependenciesMeta: - '@types/node': - optional: true - '@inquirer/input@5.1.3': resolution: {integrity: sha512-F/BZHtyEzP+HO+IGVd4AjBRgvX/ywm42bx8S0+dENk2YclzE9tJ3X/15THwtT6ehApmKvdYDMsVTuyyDod0gOQ==} engines: {node: '>=23.5.0 || ^22.13.0 || ^20.17.0'} @@ -2279,15 +2221,6 @@ packages: '@types/node': optional: true - '@inquirer/number@4.1.1': - resolution: {integrity: sha512-XF4IXAbPnGPgw0wsbC/i2tPcyfdZgDpUlhsqU0SfT4IRIGWha6Xm9VRgN5yYxJq+jnyXlfXI/nQ3ulfk0iEICA==} - engines: {node: '>=23.5.0 || ^22.13.0 || ^20.17.0'} - peerDependencies: - '@types/node': '>=18' - peerDependenciesMeta: - '@types/node': - optional: true - '@inquirer/number@4.2.0': resolution: {integrity: sha512-ew+fSDijsQ/WhD4TV3XLb+if400cDuzTzHfGR8sTNBXkK9CYDWoGE8fhaO8GbT312pNv1AJEOsDxy/z/HVettA==} engines: {node: '>=23.5.0 || ^22.13.0 || ^20.17.0'} @@ -2297,15 +2230,6 @@ packages: '@types/node': optional: true - '@inquirer/password@5.1.1': - resolution: {integrity: sha512-3XBfF7DAsp5qeDsvN5Rd1HmbNokVvEQoUM0QLrRcybC9nX96w3Pbmu7qUsb3IT3J3jBvs2+mTXaKHOUsgHMLzg==} - engines: {node: '>=23.5.0 || ^22.13.0 || ^20.17.0'} - peerDependencies: - '@types/node': '>=18' - peerDependenciesMeta: - '@types/node': - optional: true - '@inquirer/password@5.1.2': resolution: {integrity: sha512-nSdufycW8xynEVssFkNQEYIzTySilog0UlfOVRwh3pXzPSk4frXUT2jZWjHnKae6RU9PaoF9wfy1pGwewQuqGw==} engines: {node: '>=23.5.0 || ^22.13.0 || ^20.17.0'} @@ -2333,15 +2257,6 @@ packages: '@types/node': optional: true - '@inquirer/rawlist@5.3.1': - resolution: {integrity: sha512-QqdTqQddL3qPX/PPrjobpsO25NZ4dWXgTLenrR445L2ptLEYE6Z+PD5c5CNDJNx4ugRgELAIpSIJxZaO2jJ2Og==} - engines: {node: '>=23.5.0 || ^22.13.0 || ^20.17.0'} - peerDependencies: - '@types/node': '>=18' - peerDependenciesMeta: - '@types/node': - optional: true - '@inquirer/rawlist@5.3.2': resolution: {integrity: sha512-oPSKrYK1X1bMkjXDzIKHUkJp195LFSfgbnVtXnjSKGFjrCbS6I+wyvfAZTwKE9BSt3HwWgfD7JfsXALBgCogzQ==} engines: {node: '>=23.5.0 || ^22.13.0 || ^20.17.0'} @@ -2351,15 +2266,6 @@ packages: '@types/node': optional: true - '@inquirer/search@4.2.1': - resolution: {integrity: sha512-xJj8QWKRSrfKoBIITLZK61dD3zwo0Rz11fgDImku30/Oe81zMdIdGgrLY2h6RkJ+KZ/GhNYIRMKnH/62qBTA5g==} - engines: {node: '>=23.5.0 || ^22.13.0 || ^20.17.0'} - peerDependencies: - '@types/node': '>=18' - peerDependenciesMeta: - '@types/node': - optional: true - '@inquirer/search@4.3.0': resolution: {integrity: sha512-HFxXE5w727ctSUcAwrDquftJGjMgu36OeV5SHEXMlr2j/ahzmRX9xSEeVolV8tzYnTf45cg6vGkdMMRdm3RPhQ==} engines: {node: '>=23.5.0 || ^22.13.0 || ^20.17.0'} @@ -2369,15 +2275,6 @@ packages: '@types/node': optional: true - '@inquirer/select@5.2.1': - resolution: {integrity: sha512-FlDndEUww8m7BfukO2nJa25vhD+H5jxxCv4oGioKqzyWz3nPHhhw4LKdYRSlXuAx7DsdWia7iyaBPKKS95Evfw==} - engines: {node: '>=23.5.0 || ^22.13.0 || ^20.17.0'} - peerDependencies: - '@types/node': '>=18' - peerDependenciesMeta: - '@types/node': - optional: true - '@inquirer/select@5.2.2': resolution: {integrity: sha512-RkI8dRHWt+bh04oLixvF1kFzKC7e5rqJoHKkzcqSHATebBXFC6GmrT8ddbVkgSzLV0HnHs2cPFuBINr8otij8Q==} engines: {node: '>=23.5.0 || ^22.13.0 || ^20.17.0'} @@ -2858,8 +2755,8 @@ packages: resolution: {integrity: sha512-+eaY7G2VVpSf2pc5Gn1+mph837V/d/TYTJAgWL9Tb0ogGYcpN3IlAVFgjL+Vv93F/sevrxkvsYCedtpLdcFLzA==} engines: {node: '>= 20'} - '@octokit/request@10.0.13': - resolution: {integrity: sha512-v2269YxL9Yf+x3d+gRI63FP0vFQEiWgLyBzxe/Y+0yFDg2B/Tzf5dhh9VNfccVAQnfcfwQWyk/y6Bn7rUXXs7A==} + '@octokit/request@10.0.15': + resolution: {integrity: sha512-3CBg9aJ0hO9Pjyij8LbK/xYtEaPws9SW7xKz67daPNxQB1q5Y9OMA7DDOG0A6Hwf9ygGu3tvzusg0LXQ8/wAjA==} engines: {node: '>= 20'} '@octokit/rest@22.0.1': @@ -3023,9 +2920,6 @@ packages: cpu: [x64] os: [win32] - '@oxc-project/types@0.144.0': - resolution: {integrity: sha512-nuhZIOLuI6TFQ32I/WnUx+SCPY7SdSKwgnFHydAuoS1+Z4BRcaP+RRJmGzl9lw+0OFF7UmaESf7KQRXaNLHypg==} - '@oxc-project/types@0.146.0': resolution: {integrity: sha512-XC0QsnnhVe7sLIWmYmdPw7x5P0h4W8vUU3Nv1ySgWXtvCz8NizoAEpGXA0sOYoJQV2Rl13LgURAHQ5cI5ILCSA==} @@ -3111,35 +3005,45 @@ packages: resolution: {integrity: sha512-7FNeNl8NCE7aINx7WXiKQrPYZWC/hvrTsmk6zmxbI7LTXE7hVek/n8AfVgpe2y82zl3w0HvCHN0bVKMBoJcC0w==} engines: {node: '>= 10.0.0'} - '@peculiar/asn1-cms@2.9.0': - resolution: {integrity: sha512-VKQz6sJYgSxtGaK6UdnNBUx7hmSdg0K331qrEWh5qxpQsyZGWBjxbq05AJ2bTWWjd7d+nJIxFzwvsR5T7DWC/A==} + '@peculiar/asn1-cms@2.9.4': + resolution: {integrity: sha512-cben7oxmQsUGZqotus7yt0srYdncOT6RNWcTQ77T2RFOXejYVYkXadrfePdRcrVpO9K95IRLKKglG2k38jKXuw==} + engines: {node: '>=14'} - '@peculiar/asn1-csr@2.9.0': - resolution: {integrity: sha512-SbxRzHiWnRdiDuiiji/RLsJxu2au4hmSZSKK7GQOgNr2BVvheAlFQST9qqzRchUcZ6wvcyRuPXIfYXVzLoZ/5g==} + '@peculiar/asn1-csr@2.9.4': + resolution: {integrity: sha512-xd4YN4vpRjkDAQWVfZZkeu12IEND7DOpkqaHSIHxZl1uggUNa9Ju0QxY2jHvDAS9pP0zhRBytg8ifsnGo3V0jw==} + engines: {node: '>=14'} - '@peculiar/asn1-ecc@2.9.0': - resolution: {integrity: sha512-vNspHtTd9h6e8c2lMW+B/VHEUD+HRFV0fj/Gvz7SaJbwiecA8dxd96UTFPYI1PR8k7qwjjW9AFEyI+LuyVi4Kw==} + '@peculiar/asn1-ecc@2.9.4': + resolution: {integrity: sha512-JJXefFshRAuVAjWQo/39bkg1ywc1VaiO44S8RRC+Ykvf/u2KDmYffoDb0ZBPCR5uJy4AGKQhl8mX+Q8ShcWaXQ==} + engines: {node: '>=14'} - '@peculiar/asn1-pfx@2.9.0': - resolution: {integrity: sha512-A6bX+gZr69U38Pg1mWvPrM1eRba6L6kLR8iVG+bJtKj3qSv2rSNmlXLtej7ZOkEWt6xL6PiJD73uFEdQI3BXCg==} + '@peculiar/asn1-pfx@2.9.4': + resolution: {integrity: sha512-khuGzHTzNzk4GDlIBEILyIs6Lce0yn0ZBdoI9v93kmNncfZRhD+AQ5ODFqdhvoE8cMJF/JMTQ8yA+t1D14kqCw==} + engines: {node: '>=14'} - '@peculiar/asn1-pkcs8@2.9.0': - resolution: {integrity: sha512-1JH4FliKQ3trkMD17X+bKGsph5TsiM+AiiqnVKr1wxA/GoUSDHiWG/zROzLAbDIA7eclBCjQsp8hrBEJk7LRUQ==} + '@peculiar/asn1-pkcs8@2.9.4': + resolution: {integrity: sha512-duRdotlUx9eDZe6QrQpQKl61RbWykCHBCkKayP8V8XdEFwlKHZ8qGGDMyS6Pye7OX7nLFttTTpRkJeet78ckwQ==} + engines: {node: '>=14'} - '@peculiar/asn1-pkcs9@2.9.0': - resolution: {integrity: sha512-igArY6bpCI6tOPm2EU9QPrXuKq2s1iraLCTym4UlooYdzcRDIPCRUN9TAEcqZ5rZhA+HiPdFKTbDP9vneN/tsg==} + '@peculiar/asn1-pkcs9@2.9.4': + resolution: {integrity: sha512-kaL4cNxBpdQE2dKlyZBqz4ygCrwffO+8wfoxTEqM1Z8RadvCeELBRzcv0dzM8aY9azHMwODO5nxU65zXmhToOQ==} + engines: {node: '>=14'} - '@peculiar/asn1-rsa@2.9.0': - resolution: {integrity: sha512-vOD7Q4UmQWhlMYuWJawS2sD+/JcPKJNtyQuFZx09r+KFhm5/HxfGak63y/m56cpBjmb5k6PeRlQf1fvLQAieUA==} + '@peculiar/asn1-rsa@2.9.4': + resolution: {integrity: sha512-pZ96eD1PptovcWQ/GSmuNFXd/7EQJNlKfDaNCyE2rx3W0v6QFelkzquVqRSRyyDXXCYD69ZXJDzZ8GhIiQzKoA==} + engines: {node: '>=14'} - '@peculiar/asn1-schema@2.9.0': - resolution: {integrity: sha512-AKvPMOM7LfK0uFe1m7o7+veOa8xQGPqsqOrKi3QKgCElzwjGp39mbhr2g7mt/v/mXQHiIvJmDj5cJS173x8Q9Q==} + '@peculiar/asn1-schema@2.9.4': + resolution: {integrity: sha512-GjzePcT9Iw8NzeOPf73iNS9xM+TBhd/FilAfP+RQGkTMQJTVWtytN3JHJACCjf/ABNau5S7mS3g+DcuxmRgYEg==} + engines: {node: '>=14'} - '@peculiar/asn1-x509-attr@2.9.0': - resolution: {integrity: sha512-f+u+EyGjfPvPzvr0+rlh/TFEO7LWt84mEwQynCUYr4F6urf/8s6+ESJ23qfSn1aamkZR6AuBNaC62iEsGvp0+w==} + '@peculiar/asn1-x509-attr@2.9.4': + resolution: {integrity: sha512-ehQXbpQaQYycgu8OrvigwSPTFfVRcu0ECNYCWw+yzBp02Lw5paRqzzhUpfOgO2K38+WfFZuEz/0RPtam5g0OMg==} + engines: {node: '>=14'} - '@peculiar/asn1-x509@2.9.0': - resolution: {integrity: sha512-b9Na83rhRFQBd5CuMmuEqokYhmyWUbG7mNZl/thGhBwLpCdiZ85TZ3WFhF7OVgOekC5uKhLk4C3HKtdiScCMdQ==} + '@peculiar/asn1-x509@2.9.4': + resolution: {integrity: sha512-CxhBo/RdEbMMob7T31ZdQjGuoyRFLVwrDzTn25bihzBasRg9kRm/0IxIPvhgQtcK/9dNcO1XQL2fuPugwELL0Q==} + engines: {node: '>=14'} '@peculiar/utils@2.0.3': resolution: {integrity: sha512-+oL3HPFRIZ1St2K50lWCXiioIgSoxzz7R1J3uF6neO2yl1sgmpgY6XXJH4BdpoDkMWznQTeYF6oWNDZLCdQ4eQ==} @@ -3221,73 +3125,36 @@ packages: cpu: [arm] os: [android] - '@rolldown/binding-android-arm64@1.2.4': - resolution: {integrity: sha512-jHC2cnyKz5xU2fhECtFl8OZ83cYNt13GZQD+0uMJ/X3o+ijmd56okHhTUwxVSHPx1IRVIJEZ1/1pPzeLCU6XKA==} - engines: {node: ^20.19.0 || >=22.12.0} - cpu: [arm64] - os: [android] - '@rolldown/binding-android-arm64@1.2.5': resolution: {integrity: sha512-zXcwKlQApYAOELHd8PwKDFkagYF9Wy4e0RJ+0qnzl9Pjnpj75TEG8ufv40p2J7kCEfwZAsNiuzRIyNNMWT38ig==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [android] - '@rolldown/binding-darwin-arm64@1.2.4': - resolution: {integrity: sha512-Dc5mPD8F5F/FS8i01syd7FTF6yB2fVthH/TRkjwJkzUK6EpoxHtqvZQP5Zwq80/5z19TWYHIg1KOHboCgVx/aQ==} - engines: {node: ^20.19.0 || >=22.12.0} - cpu: [arm64] - os: [darwin] - '@rolldown/binding-darwin-arm64@1.2.5': resolution: {integrity: sha512-dK4QakI42nzWgJT5sm4y4y/O//D4OxM75/cH28RLV+nzIN9AY+YsbuUVrUTjlLjXR6vpyxFbSsbmNuJ6BP9sww==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [darwin] - '@rolldown/binding-darwin-x64@1.2.4': - resolution: {integrity: sha512-fpDm4oBo6SqLvWUYCmFhdde3U9KH2fRNNMeAnAPAIwxRL345xutL0EtEUcuoxsoazdJGv/MuDBQHlCDrtbvqOg==} - engines: {node: ^20.19.0 || >=22.12.0} - cpu: [x64] - os: [darwin] - '@rolldown/binding-darwin-x64@1.2.5': resolution: {integrity: sha512-fqSALaUu1Wjd1nK2uW2kJDWdLCc8lx1IcY+MTY26Aurfdx19anlzhqXOgCFbBFQnlFDTn4TC1/7Nz4Bl2mLP3A==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [darwin] - '@rolldown/binding-freebsd-x64@1.2.4': - resolution: {integrity: sha512-rSJoreDE/HoIzoaib6MTp5jQtCTdMHKIvItAKT/ImS6Y6Ww76oUaeMyp4Vc/fAgd/ehji068IxetHXAnqUwN9A==} - engines: {node: ^20.19.0 || >=22.12.0} - cpu: [x64] - os: [freebsd] - '@rolldown/binding-freebsd-x64@1.2.5': resolution: {integrity: sha512-/vCnNxlkxs9tKxNDcyWUePpJ/PgTzxIaVhoM5SmG8UV+GR/IcPam4VYxi7GIMo7PSDuNqlJqvprqii9NqqVCMw==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [freebsd] - '@rolldown/binding-linux-arm-gnueabihf@1.2.4': - resolution: {integrity: sha512-/jm8OGHgn7oGaJu3i/qZI9spUGcJ+y/lk43ttQ/iO1tOd9NissG6o97bighBCiL+BKRngmcDuR6ikfwYdJmVuQ==} - engines: {node: ^20.19.0 || >=22.12.0} - cpu: [arm] - os: [linux] - '@rolldown/binding-linux-arm-gnueabihf@1.2.5': resolution: {integrity: sha512-abk0NLA519LxRCszmbE0jYKuQ9YPocOXTiOXOo6Yr+YAT95VH+PtqYAjOJvGKt3viEd/x4qzabAlwd5bHOOARg==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm] os: [linux] - '@rolldown/binding-linux-arm64-gnu@1.2.4': - resolution: {integrity: sha512-tIP06BeD9EqvECBrPZ+sqdPlYrT+aYaAiu1wYziVx5elRK/ftm33JxVDy2bXGbr6J0CrtirCkR87/X5a2euEng==} - engines: {node: ^20.19.0 || >=22.12.0} - cpu: [arm64] - os: [linux] - libc: [glibc] - '@rolldown/binding-linux-arm64-gnu@1.2.5': resolution: {integrity: sha512-Y7eALiJ8lr0M2HH103Js+g7V34wf6snlpZLAsHI90uLhr3PVlNsbFVAXJC9d/V6BnPyKtpSwI+NcB/RLxsQxuA==} engines: {node: ^20.19.0 || >=22.12.0} @@ -3295,13 +3162,6 @@ packages: os: [linux] libc: [glibc] - '@rolldown/binding-linux-arm64-musl@1.2.4': - resolution: {integrity: sha512-Ql1Q0EQqVThvn9VAVlwNzsUvbSFtCMGjLpRRi4pk5i7NZZ4n5ISiLMjHYtus4VQ2PvkSw24zyaCVsiS+sXPj1w==} - engines: {node: ^20.19.0 || >=22.12.0} - cpu: [arm64] - os: [linux] - libc: [musl] - '@rolldown/binding-linux-arm64-musl@1.2.5': resolution: {integrity: sha512-xMvZgnbZg4YVnR/AX2b3oOPDTFYJvUVaJg5FedA/LuvexAtXibZQej4cnTkw3rjsJ/ggUROB64TdtETiim+FYA==} engines: {node: ^20.19.0 || >=22.12.0} @@ -3309,13 +3169,6 @@ packages: os: [linux] libc: [musl] - '@rolldown/binding-linux-ppc64-gnu@1.2.4': - resolution: {integrity: sha512-GjbjXD4XXfN19D0LZNbmiCBUoDiRACsYHr0yaIbbn8aFsXjHZifcYqu/W5Er5X2X990WjHXFrxarn5chzItorQ==} - engines: {node: ^20.19.0 || >=22.12.0} - cpu: [ppc64] - os: [linux] - libc: [glibc] - '@rolldown/binding-linux-ppc64-gnu@1.2.5': resolution: {integrity: sha512-GRjeqTUDHTo5GwntsLaAMcBahG3nlpjftXWZLN73HiYQlhwEowvarFgQnRnQZtIp4keXX7quXFbG38uPZBa2EA==} engines: {node: ^20.19.0 || >=22.12.0} @@ -3323,13 +3176,6 @@ packages: os: [linux] libc: [glibc] - '@rolldown/binding-linux-s390x-gnu@1.2.4': - resolution: {integrity: sha512-p5WR0NOwaRmJ/B1b6IjEFLLivwEsf3PrdBIhRbhTCQisbo2SvHHpG4ELB/+FgQNnB88LTOF86upmJmbvZdQ2lw==} - engines: {node: ^20.19.0 || >=22.12.0} - cpu: [s390x] - os: [linux] - libc: [glibc] - '@rolldown/binding-linux-s390x-gnu@1.2.5': resolution: {integrity: sha512-vLNTR45F2Uwc8AufkNXPmB4VliaXs+FvcheEogIzOXzO4l+LzieXF5A/TWxLy5HtqpsRCHUfd0lPVrrdgXdLHQ==} engines: {node: ^20.19.0 || >=22.12.0} @@ -3337,13 +3183,6 @@ packages: os: [linux] libc: [glibc] - '@rolldown/binding-linux-x64-gnu@1.2.4': - resolution: {integrity: sha512-4/GyVjmhR+Tc6HLJvwc1sOhPqAZtySiSMesOZyX6JQ5XBxoTDEMKQzvo07NIK6nTon/SivlZqvhzvuVBNQhObQ==} - engines: {node: ^20.19.0 || >=22.12.0} - cpu: [x64] - os: [linux] - libc: [glibc] - '@rolldown/binding-linux-x64-gnu@1.2.5': resolution: {integrity: sha512-Mgj59/HTuYeK9Gz2MA+mBWKnHsAgkBSec15ZMb1st3oIfFbX7gCjOae7GydHhzcyQi9Z/7M1QuN9bR3oFqF0jQ==} engines: {node: ^20.19.0 || >=22.12.0} @@ -3351,13 +3190,6 @@ packages: os: [linux] libc: [glibc] - '@rolldown/binding-linux-x64-musl@1.2.4': - resolution: {integrity: sha512-l9eeLsCNvPpmSXUej0etw/J1eqV0Jj1D5G/xG6YTijmE6dkv6E2QezgWbTfQk63v952DPqrjOCoiqxq7Bw0YUQ==} - engines: {node: ^20.19.0 || >=22.12.0} - cpu: [x64] - os: [linux] - libc: [musl] - '@rolldown/binding-linux-x64-musl@1.2.5': resolution: {integrity: sha512-mY8AP0/ichsbhAxGnLa3d3+MwV0EfgrPND2bplI3Ym8T6R2pJ0N87bvrKVwNXmdy3jnr6eQBecdqx/HMknBmpA==} engines: {node: ^20.19.0 || >=22.12.0} @@ -3365,36 +3197,18 @@ packages: os: [linux] libc: [musl] - '@rolldown/binding-openharmony-arm64@1.2.4': - resolution: {integrity: sha512-e0F355MSTMm3+UOqtV3L24gFUp2N5m1f8L/7d56deik6va+AXdrt9F8LbzGpeWGWRbZEDq4m8NVnJDeBtf9DZg==} - engines: {node: ^20.19.0 || >=22.12.0} - cpu: [arm64] - os: [openharmony] - '@rolldown/binding-openharmony-arm64@1.2.5': resolution: {integrity: sha512-8SLssA2oweAxyRgDp789ACfRb/3P+zNRJpzZxSizxF9m8NUDQ4+3xjo8ttjhVGGw6Qxb70oZiEtIjaKikCO7Yw==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [openharmony] - '@rolldown/binding-win32-arm64-msvc@1.2.4': - resolution: {integrity: sha512-AWLi0uBRYh6QlE7OKhiz+phZC0qwtij2QZmhmOdsLdFn64m7oMpooE9ICE3lhm9xMb4SpDo2WbHcxX1iFLFtqw==} - engines: {node: ^20.19.0 || >=22.12.0} - cpu: [arm64] - os: [win32] - '@rolldown/binding-win32-arm64-msvc@1.2.5': resolution: {integrity: sha512-vGbruD5zquhoc8D9SViXgN2FBJtNdTyQ4DtG+SWiEGlJiAzoKcZ2xp+xuXCffhubVdt0NJlTZqkeRuERy7g8Cw==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [win32] - '@rolldown/binding-win32-x64-msvc@1.2.4': - resolution: {integrity: sha512-UwSDJOg3dqCAejWdxclJjCsh3Qq4vLYMDxmyHqo1btz3stK2VqgwNd3mm5tuIwzSlGIQ/1H9Hr+Zn09mrezNqQ==} - engines: {node: ^20.19.0 || >=22.12.0} - cpu: [x64] - os: [win32] - '@rolldown/binding-win32-x64-msvc@1.2.5': resolution: {integrity: sha512-e/SXpgISz+IoqVcSSI0rx/d/he8zqLex+/rCWpnHpmVfmPIUjag9H6P7zotf0gJHwPUhQxZ/mF8tr6acebT9yw==} engines: {node: ^20.19.0 || >=22.12.0} @@ -3874,10 +3688,6 @@ packages: resolution: {integrity: sha512-1rLGFg/qTRgHVq1llx5fW+FtYijV4MeXBRc82aSy2TUQ4fy+4yEckI1+GCAm7fIvl5+YOzW9PcABtZOeEkeu7Q==} engines: {node: '>=22'} - '@verdaccio/core@8.2.1': - resolution: {integrity: sha512-fcK9lGTXSxrNncbShtt5sCfFPiP2GdsQmhXdeu4HDIH9GU8cLF5Jj/QBpLjMuz+lB+qHg6QBFlUKS0pnio20jA==} - engines: {node: '>=22'} - '@verdaccio/core@8.2.2': resolution: {integrity: sha512-BSCCR5cFkepjL3HnosKUi6aRezwgHu1FihFtes63yxIiDXkMclVi5IekTH6SCeW/7MO1Uyp58kh1updbB6VW4w==} engines: {node: '>=22'} @@ -4034,10 +3844,9 @@ packages: '@webassemblyjs/wast-printer@1.14.1': resolution: {integrity: sha512-kPSSXE6De1XOR820C90RIo2ogvZG+c3KiHzqUoO/F34Y2shGzesfqv7o57xrxovZJH/MetF5UjroJ/R/3isoiw==} - '@xmldom/xmldom@0.8.14': - resolution: {integrity: sha512-T4EDRUBVZYRldYApjEJiU0e1stYWaRAX7CuSnKzrpwdZKo53zGV8/pqfzV6FfwNl9YThD2OumQYvqtvjvgG7aQ==} + '@xmldom/xmldom@0.8.15': + resolution: {integrity: sha512-/5NV/vDALVFDXgLmfsy9TRCBlKwO2LNBFzpzvb9iIj+jR+eSc6DLYYvVOdivT/jm7MtU6TebYuRmzEOI7w40UA==} engines: {node: '>=10.0.0'} - deprecated: this version has critical issues, please update to the latest version '@xtuc/ieee754@1.2.0': resolution: {integrity: sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA==} @@ -4468,8 +4277,8 @@ packages: resolution: {integrity: sha512-lGe34o6EHj9y3Kts9R4ZYs/Gr+6N7MCaMlIFA3F1R2O5/m7K06AxfSeO5530PEERE6/WyEg3lsuyw4GHlPZHog==} engines: {node: ^4.5.0 || >= 5.9} - baseline-browser-mapping@2.11.14: - resolution: {integrity: sha512-JyJ954WzuIR8/FFzX0o5krdSTrBAkcCSRfWSleRsIHSWV+cZe2FI1PKggVkFke1hBldRs+LRxUczzE9iPmgZww==} + baseline-browser-mapping@2.11.18: + resolution: {integrity: sha512-1iEmLEYSiE1SeBoAfPo/Mnx3PzfzHUkDK61ASkCpuk3YXugYLH5DYK1SzqV55F8FMI6s0F+/tCP7Polz1QRjxw==} engines: {node: '>=6.0.0'} hasBin: true @@ -4777,6 +4586,10 @@ packages: resolution: {integrity: sha512-mj7UPXE0jaqaOsukNZRUEfEi2AcL7C/vwmwcHV0O97eO1E1pxBZuyjlZrx5seTaNBg1U6+o35wpa35Qfcc+7ag==} engines: {node: '>=18'} + content-type@3.0.0: + resolution: {integrity: sha512-AIi5H6p0xk5uknXcN3/rmhP8jgp69OfSe/JuKiQAFprJ7UGw7mwj7m4XcmDzlrnJDG+cGpphAINGdU3g3g7kDw==} + engines: {node: '>=22'} + conventional-commits-filter@6.0.1: resolution: {integrity: sha512-cs+LadpH7Kpw0M3k8wurk+sOVVDAENA0iK4OBOrkL94j5lEVYRJ4j3zd2bhY9qgzyrPqthdcYT3axzRN7AliMg==} engines: {node: '>=22'} @@ -5080,8 +4893,8 @@ packages: engines: {node: '>=0.12.18'} hasBin: true - electron-to-chromium@1.5.408: - resolution: {integrity: sha512-SLoprcYpJ/OH2v2ps0+N5biv9H4/KBT3+YmmDew64TwK5y9j2wv7pMOFY7IorVkyMtEyLSCRlXKLsNlakeAlPw==} + electron-to-chromium@1.5.412: + resolution: {integrity: sha512-z4rMe3esBzlzovKHj4gxJnsCGZRK5l4baUvm+gCGJBPE+gsyUMKsuU9tnEUtI1dOebXz1ytAPGjvXhmQ7rIPwA==} emoji-regex@10.6.0: resolution: {integrity: sha512-toUI84YS5YmxW219erniWD0CIVOo46xGKColeNQRgOzDorgBi1v4D71/OFzgD9GO2UGKIv1C3Sp8DAn0+j5w7A==} @@ -5390,8 +5203,8 @@ packages: fast-string-width@3.0.2: resolution: {integrity: sha512-gX8LrtNEI5hq8DVUfRQMbr5lpaS4nMIWV+7XEbXk2b8kiQIizgnlr12B4dA3ZEx3308ze0O4Q1R+cHts8kyUJg==} - fast-uri@3.1.5: - resolution: {integrity: sha512-gHwA1O9LDIcKunMKhObS/HimwtehO1nPUECKAu5TpKgaO19fcWEl4bliWe1jWxVFvIXztJjjQ4L8XQ1EU9f7Jw==} + fast-uri@3.1.6: + resolution: {integrity: sha512-7Ical1vFEMr0onbVzEDIreM22I4khW+fzyQPwvAFWBp1iwdshSZRsL4jjRvPG9JP1uiqMHRto+YU6R2/CzDz5Q==} fast-wrap-ansi@0.2.2: resolution: {integrity: sha512-7F2Fl+TjRSenLqlU3UjSH0iyqopqoZIu7eZVpEirP2g1GtWa2G/ecEmBdgz31+Mxr+ELclgg6sokpSFIQiZ02Q==} @@ -6615,10 +6428,6 @@ packages: peerDependencies: webpack: ^5.0.0 - minimatch@10.2.5: - resolution: {integrity: sha512-MULkVLfKGYDFYejP07QOurDLLQpcjk7Fw+7jXS2R2czRQzR56yHRveU5NDJEOviH+hETZKSkIk5c+T23GjFUMg==} - engines: {node: 18 || 20 || >=22} - minimatch@10.2.6: resolution: {integrity: sha512-vpLQEs+VLCr1nU0BXS07maYoFwlDAH0gngQuuttxIwutDFEMHq2blX+8vpgxDdK3J1PwjCJiep77OitTZ4Ll1A==} engines: {node: 18 || 20 || >=22} @@ -6758,9 +6567,9 @@ packages: resolution: {integrity: sha512-myRT3DiWPHqho5PrJaIRyaMv2kgYf0mUVgBNOYMuCH5Ki1yEiQaf/ZJuQ62nvpc44wL5WDbTX7yGJi1Neevw8w==} engines: {node: '>= 0.6'} - negotiator@1.0.0: - resolution: {integrity: sha512-8Ofs/AUQh8MaEcrlq5xOX0CQ9ypTF5dl78mjlMNfOK08fzpgTHQRQPBxcPlEtIw0yRpws+Zo/3r+5WRby7u3Gg==} - engines: {node: '>= 0.6'} + negotiator@1.1.0: + resolution: {integrity: sha512-NMPBRMJgiQHjbd8phG3Vebdx4kZ1H121rbl5IkMqeOsahptB9BKo/d7oJ3zTXqTgagn2bWlNSXkh0QUGM31RYg==} + engines: {node: '>=18'} neo-async@2.6.2: resolution: {integrity: sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==} @@ -7431,11 +7240,6 @@ packages: vue-tsc: optional: true - rolldown@1.2.4: - resolution: {integrity: sha512-rSr7irW0K7QRWzjdJXqZowkcRdDtjRduh43rBltnVKd0VFq839l1lJoDvGJb6gl7+4rTTCrPWu+YfujUL8Ug7w==} - engines: {node: ^20.19.0 || >=22.12.0} - hasBin: true - rolldown@1.2.5: resolution: {integrity: sha512-VD2IE5PUG4Oj8zz2VGykiYd5wbnjdIiSsNQb8Qu5B+noEp+A78mu2iVvpp27g8es14Tk9rofNs5Tku9iQCS4fA==} engines: {node: ^20.19.0 || >=22.12.0} @@ -8178,8 +7982,8 @@ packages: resolution: {integrity: sha512-2nHSt8qRQcCCUQX6QO72eC1D1RoqCBZVPTotVdS/CGpMtE+jUHIDnOSWWMQxtN53PHa6wjjheySJCcuEpmtJsQ==} engines: {node: '>=22'} - verdaccio-auth-memory@13.1.1: - resolution: {integrity: sha512-Oo3CsyIGaM2S0qCXMN0Coi1uVyvIplT5DAEqwYK22z9XTHAZQf3oUgiVPxEwpFGcqxYsIAq1kxH5COST3xxR6g==} + verdaccio-auth-memory@13.1.2: + resolution: {integrity: sha512-Z5CH/iUa37QmaNt+nbgvyjojyQ6WZA0r06ymsGjor8xCqFBzGtIlLsM8Es0Njh/fU06r928RcsfEjha7zFqv1w==} engines: {node: '>=22'} verdaccio-htpasswd@13.1.2: @@ -8428,8 +8232,8 @@ packages: wordwrap@1.0.0: resolution: {integrity: sha512-gvVzJFlPycKc5dZN4yPkP8w7Dc37BtP1yczEneOb4uq34pXZcvrtRTmWV8W+Ume+XCxKgbjM+nevkyFPMybd4Q==} - wrap-ansi@10.0.0: - resolution: {integrity: sha512-SGcvg80f0wUy2/fXES19feHMz8E0JoXv2uNgHOu4Dgi2OrCy1lqwFYEJz1BLbDI0exjPMe/ZdzZ/YpGECBG/aQ==} + wrap-ansi@10.0.1: + resolution: {integrity: sha512-M0N4xzyzosiIok3svYlEo1sdLZts/8FPgYH/GPC3wvlmPoRvnoManGMrE54waYj3tISA8w6lsdesfVv67qSr8Q==} engines: {node: '>=20'} wrap-ansi@7.0.0: @@ -10062,15 +9866,6 @@ snapshots: '@inquirer/ansi@2.0.7': {} - '@inquirer/checkbox@5.2.1(@types/node@24.13.3)': - dependencies: - '@inquirer/ansi': 2.0.7 - '@inquirer/core': 11.2.1(@types/node@24.13.3) - '@inquirer/figures': 2.0.7 - '@inquirer/type': 4.0.7(@types/node@24.13.3) - optionalDependencies: - '@types/node': 24.13.3 - '@inquirer/checkbox@5.2.2(@types/node@22.20.1)': dependencies: '@inquirer/ansi': 2.0.7 @@ -10080,6 +9875,15 @@ snapshots: optionalDependencies: '@types/node': 22.20.1 + '@inquirer/checkbox@5.2.2(@types/node@24.13.3)': + dependencies: + '@inquirer/ansi': 2.0.7 + '@inquirer/core': 12.0.0(@types/node@24.13.3) + '@inquirer/figures': 2.0.8 + '@inquirer/type': 4.0.7(@types/node@24.13.3) + optionalDependencies: + '@types/node': 24.13.3 + '@inquirer/confirm@6.2.0(@types/node@22.20.1)': dependencies: '@inquirer/core': 12.0.0(@types/node@22.20.1) @@ -10094,18 +9898,6 @@ snapshots: optionalDependencies: '@types/node': 24.13.3 - '@inquirer/core@11.2.1(@types/node@24.13.3)': - dependencies: - '@inquirer/ansi': 2.0.7 - '@inquirer/figures': 2.0.7 - '@inquirer/type': 4.0.7(@types/node@24.13.3) - cli-width: 4.1.0 - fast-wrap-ansi: 0.2.2 - mute-stream: 3.0.0 - signal-exit: 4.1.0 - optionalDependencies: - '@types/node': 24.13.3 - '@inquirer/core@12.0.0(@types/node@22.20.1)': dependencies: '@inquirer/ansi': 2.0.7 @@ -10130,14 +9922,6 @@ snapshots: optionalDependencies: '@types/node': 24.13.3 - '@inquirer/editor@5.2.2(@types/node@24.13.3)': - dependencies: - '@inquirer/core': 11.2.1(@types/node@24.13.3) - '@inquirer/external-editor': 3.0.3(@types/node@24.13.3) - '@inquirer/type': 4.0.7(@types/node@24.13.3) - optionalDependencies: - '@types/node': 24.13.3 - '@inquirer/editor@5.3.0(@types/node@22.20.1)': dependencies: '@inquirer/core': 12.0.0(@types/node@22.20.1) @@ -10146,9 +9930,10 @@ snapshots: optionalDependencies: '@types/node': 22.20.1 - '@inquirer/expand@5.1.1(@types/node@24.13.3)': + '@inquirer/editor@5.3.0(@types/node@24.13.3)': dependencies: - '@inquirer/core': 11.2.1(@types/node@24.13.3) + '@inquirer/core': 12.0.0(@types/node@24.13.3) + '@inquirer/external-editor': 3.0.4(@types/node@24.13.3) '@inquirer/type': 4.0.7(@types/node@24.13.3) optionalDependencies: '@types/node': 24.13.3 @@ -10160,10 +9945,10 @@ snapshots: optionalDependencies: '@types/node': 22.20.1 - '@inquirer/external-editor@3.0.3(@types/node@24.13.3)': + '@inquirer/expand@5.1.2(@types/node@24.13.3)': dependencies: - chardet: 2.2.0 - iconv-lite: 0.7.3 + '@inquirer/core': 12.0.0(@types/node@24.13.3) + '@inquirer/type': 4.0.7(@types/node@24.13.3) optionalDependencies: '@types/node': 24.13.3 @@ -10174,17 +9959,15 @@ snapshots: optionalDependencies: '@types/node': 22.20.1 - '@inquirer/figures@2.0.7': {} - - '@inquirer/figures@2.0.8': {} - - '@inquirer/input@5.1.2(@types/node@24.13.3)': + '@inquirer/external-editor@3.0.4(@types/node@24.13.3)': dependencies: - '@inquirer/core': 11.2.1(@types/node@24.13.3) - '@inquirer/type': 4.0.7(@types/node@24.13.3) + chardet: 2.2.0 + iconv-lite: 0.7.3 optionalDependencies: '@types/node': 24.13.3 + '@inquirer/figures@2.0.8': {} + '@inquirer/input@5.1.3(@types/node@22.20.1)': dependencies: '@inquirer/core': 12.0.0(@types/node@22.20.1) @@ -10192,9 +9975,9 @@ snapshots: optionalDependencies: '@types/node': 22.20.1 - '@inquirer/number@4.1.1(@types/node@24.13.3)': + '@inquirer/input@5.1.3(@types/node@24.13.3)': dependencies: - '@inquirer/core': 11.2.1(@types/node@24.13.3) + '@inquirer/core': 12.0.0(@types/node@24.13.3) '@inquirer/type': 4.0.7(@types/node@24.13.3) optionalDependencies: '@types/node': 24.13.3 @@ -10206,10 +9989,9 @@ snapshots: optionalDependencies: '@types/node': 22.20.1 - '@inquirer/password@5.1.1(@types/node@24.13.3)': + '@inquirer/number@4.2.0(@types/node@24.13.3)': dependencies: - '@inquirer/ansi': 2.0.7 - '@inquirer/core': 11.2.1(@types/node@24.13.3) + '@inquirer/core': 12.0.0(@types/node@24.13.3) '@inquirer/type': 4.0.7(@types/node@24.13.3) optionalDependencies: '@types/node': 24.13.3 @@ -10222,18 +10004,26 @@ snapshots: optionalDependencies: '@types/node': 22.20.1 + '@inquirer/password@5.1.2(@types/node@24.13.3)': + dependencies: + '@inquirer/ansi': 2.0.7 + '@inquirer/core': 12.0.0(@types/node@24.13.3) + '@inquirer/type': 4.0.7(@types/node@24.13.3) + optionalDependencies: + '@types/node': 24.13.3 + '@inquirer/prompts@8.5.2(@types/node@24.13.3)': dependencies: - '@inquirer/checkbox': 5.2.1(@types/node@24.13.3) + '@inquirer/checkbox': 5.2.2(@types/node@24.13.3) '@inquirer/confirm': 6.2.0(@types/node@24.13.3) - '@inquirer/editor': 5.2.2(@types/node@24.13.3) - '@inquirer/expand': 5.1.1(@types/node@24.13.3) - '@inquirer/input': 5.1.2(@types/node@24.13.3) - '@inquirer/number': 4.1.1(@types/node@24.13.3) - '@inquirer/password': 5.1.1(@types/node@24.13.3) - '@inquirer/rawlist': 5.3.1(@types/node@24.13.3) - '@inquirer/search': 4.2.1(@types/node@24.13.3) - '@inquirer/select': 5.2.1(@types/node@24.13.3) + '@inquirer/editor': 5.3.0(@types/node@24.13.3) + '@inquirer/expand': 5.1.2(@types/node@24.13.3) + '@inquirer/input': 5.1.3(@types/node@24.13.3) + '@inquirer/number': 4.2.0(@types/node@24.13.3) + '@inquirer/password': 5.1.2(@types/node@24.13.3) + '@inquirer/rawlist': 5.3.2(@types/node@24.13.3) + '@inquirer/search': 4.3.0(@types/node@24.13.3) + '@inquirer/select': 5.2.2(@types/node@24.13.3) optionalDependencies: '@types/node': 24.13.3 @@ -10252,13 +10042,6 @@ snapshots: optionalDependencies: '@types/node': 22.20.1 - '@inquirer/rawlist@5.3.1(@types/node@24.13.3)': - dependencies: - '@inquirer/core': 11.2.1(@types/node@24.13.3) - '@inquirer/type': 4.0.7(@types/node@24.13.3) - optionalDependencies: - '@types/node': 24.13.3 - '@inquirer/rawlist@5.3.2(@types/node@22.20.1)': dependencies: '@inquirer/core': 12.0.0(@types/node@22.20.1) @@ -10266,10 +10049,9 @@ snapshots: optionalDependencies: '@types/node': 22.20.1 - '@inquirer/search@4.2.1(@types/node@24.13.3)': + '@inquirer/rawlist@5.3.2(@types/node@24.13.3)': dependencies: - '@inquirer/core': 11.2.1(@types/node@24.13.3) - '@inquirer/figures': 2.0.7 + '@inquirer/core': 12.0.0(@types/node@24.13.3) '@inquirer/type': 4.0.7(@types/node@24.13.3) optionalDependencies: '@types/node': 24.13.3 @@ -10282,11 +10064,10 @@ snapshots: optionalDependencies: '@types/node': 22.20.1 - '@inquirer/select@5.2.1(@types/node@24.13.3)': + '@inquirer/search@4.3.0(@types/node@24.13.3)': dependencies: - '@inquirer/ansi': 2.0.7 - '@inquirer/core': 11.2.1(@types/node@24.13.3) - '@inquirer/figures': 2.0.7 + '@inquirer/core': 12.0.0(@types/node@24.13.3) + '@inquirer/figures': 2.0.8 '@inquirer/type': 4.0.7(@types/node@24.13.3) optionalDependencies: '@types/node': 24.13.3 @@ -10300,6 +10081,15 @@ snapshots: optionalDependencies: '@types/node': 22.20.1 + '@inquirer/select@5.2.2(@types/node@24.13.3)': + dependencies: + '@inquirer/ansi': 2.0.7 + '@inquirer/core': 12.0.0(@types/node@24.13.3) + '@inquirer/figures': 2.0.8 + '@inquirer/type': 4.0.7(@types/node@24.13.3) + optionalDependencies: + '@types/node': 24.13.3 + '@inquirer/type@4.0.7(@types/node@22.20.1)': optionalDependencies: '@types/node': 22.20.1 @@ -10637,7 +10427,7 @@ snapshots: dependencies: '@octokit/auth-oauth-app': 9.0.4 '@octokit/auth-oauth-user': 6.0.3 - '@octokit/request': 10.0.13 + '@octokit/request': 10.0.15 '@octokit/request-error': 7.1.1 '@octokit/types': 17.0.0 toad-cache: 3.7.4 @@ -10648,14 +10438,14 @@ snapshots: dependencies: '@octokit/auth-oauth-device': 8.0.4 '@octokit/auth-oauth-user': 6.0.3 - '@octokit/request': 10.0.13 + '@octokit/request': 10.0.15 '@octokit/types': 17.0.0 universal-user-agent: 7.0.3 '@octokit/auth-oauth-device@8.0.4': dependencies: '@octokit/oauth-methods': 6.0.4 - '@octokit/request': 10.0.13 + '@octokit/request': 10.0.15 '@octokit/types': 17.0.0 universal-user-agent: 7.0.3 @@ -10663,7 +10453,7 @@ snapshots: dependencies: '@octokit/auth-oauth-device': 8.0.4 '@octokit/oauth-methods': 6.0.4 - '@octokit/request': 10.0.13 + '@octokit/request': 10.0.15 '@octokit/types': 17.0.0 universal-user-agent: 7.0.3 @@ -10673,7 +10463,7 @@ snapshots: dependencies: '@octokit/auth-token': 6.0.0 '@octokit/graphql': 9.0.4 - '@octokit/request': 10.0.13 + '@octokit/request': 10.0.15 '@octokit/request-error': 7.1.1 '@octokit/types': 17.0.0 before-after-hook: 4.0.0 @@ -10691,7 +10481,7 @@ snapshots: '@octokit/graphql@9.0.4': dependencies: - '@octokit/request': 10.0.13 + '@octokit/request': 10.0.15 '@octokit/types': 17.0.0 universal-user-agent: 7.0.3 @@ -10700,7 +10490,7 @@ snapshots: '@octokit/oauth-methods@6.0.4': dependencies: '@octokit/oauth-authorization-url': 8.0.0 - '@octokit/request': 10.0.13 + '@octokit/request': 10.0.15 '@octokit/request-error': 7.1.1 '@octokit/types': 17.0.0 @@ -10736,12 +10526,12 @@ snapshots: dependencies: '@octokit/types': 17.0.0 - '@octokit/request@10.0.13': + '@octokit/request@10.0.15': dependencies: '@octokit/endpoint': 11.0.4 '@octokit/request-error': 7.1.1 '@octokit/types': 17.0.0 - content-type: 2.1.0 + content-type: 3.0.0 json-with-bigint: 3.5.12 universal-user-agent: 7.0.3 @@ -10839,8 +10629,6 @@ snapshots: '@oxc-parser/binding-win32-x64-msvc@0.146.0': optional: true - '@oxc-project/types@0.144.0': {} - '@oxc-project/types@0.146.0': {} '@parcel/watcher-android-arm64@2.6.0': @@ -10899,78 +10687,78 @@ snapshots: '@parcel/watcher-win32-arm64': 2.6.0 '@parcel/watcher-win32-x64': 2.6.0 - '@peculiar/asn1-cms@2.9.0': + '@peculiar/asn1-cms@2.9.4': dependencies: - '@peculiar/asn1-schema': 2.9.0 - '@peculiar/asn1-x509': 2.9.0 - '@peculiar/asn1-x509-attr': 2.9.0 + '@peculiar/asn1-schema': 2.9.4 + '@peculiar/asn1-x509': 2.9.4 + '@peculiar/asn1-x509-attr': 2.9.4 asn1js: 3.0.10 tslib: 2.8.1 - '@peculiar/asn1-csr@2.9.0': + '@peculiar/asn1-csr@2.9.4': dependencies: - '@peculiar/asn1-schema': 2.9.0 - '@peculiar/asn1-x509': 2.9.0 + '@peculiar/asn1-schema': 2.9.4 + '@peculiar/asn1-x509': 2.9.4 asn1js: 3.0.10 tslib: 2.8.1 - '@peculiar/asn1-ecc@2.9.0': + '@peculiar/asn1-ecc@2.9.4': dependencies: - '@peculiar/asn1-schema': 2.9.0 - '@peculiar/asn1-x509': 2.9.0 + '@peculiar/asn1-schema': 2.9.4 + '@peculiar/asn1-x509': 2.9.4 asn1js: 3.0.10 tslib: 2.8.1 - '@peculiar/asn1-pfx@2.9.0': + '@peculiar/asn1-pfx@2.9.4': dependencies: - '@peculiar/asn1-cms': 2.9.0 - '@peculiar/asn1-pkcs8': 2.9.0 - '@peculiar/asn1-rsa': 2.9.0 - '@peculiar/asn1-schema': 2.9.0 + '@peculiar/asn1-cms': 2.9.4 + '@peculiar/asn1-pkcs8': 2.9.4 + '@peculiar/asn1-rsa': 2.9.4 + '@peculiar/asn1-schema': 2.9.4 asn1js: 3.0.10 tslib: 2.8.1 - '@peculiar/asn1-pkcs8@2.9.0': + '@peculiar/asn1-pkcs8@2.9.4': dependencies: - '@peculiar/asn1-schema': 2.9.0 - '@peculiar/asn1-x509': 2.9.0 + '@peculiar/asn1-schema': 2.9.4 + '@peculiar/asn1-x509': 2.9.4 asn1js: 3.0.10 tslib: 2.8.1 - '@peculiar/asn1-pkcs9@2.9.0': + '@peculiar/asn1-pkcs9@2.9.4': dependencies: - '@peculiar/asn1-cms': 2.9.0 - '@peculiar/asn1-pfx': 2.9.0 - '@peculiar/asn1-pkcs8': 2.9.0 - '@peculiar/asn1-schema': 2.9.0 - '@peculiar/asn1-x509': 2.9.0 - '@peculiar/asn1-x509-attr': 2.9.0 + '@peculiar/asn1-cms': 2.9.4 + '@peculiar/asn1-pfx': 2.9.4 + '@peculiar/asn1-pkcs8': 2.9.4 + '@peculiar/asn1-schema': 2.9.4 + '@peculiar/asn1-x509': 2.9.4 + '@peculiar/asn1-x509-attr': 2.9.4 asn1js: 3.0.10 tslib: 2.8.1 - '@peculiar/asn1-rsa@2.9.0': + '@peculiar/asn1-rsa@2.9.4': dependencies: - '@peculiar/asn1-schema': 2.9.0 - '@peculiar/asn1-x509': 2.9.0 + '@peculiar/asn1-schema': 2.9.4 + '@peculiar/asn1-x509': 2.9.4 asn1js: 3.0.10 tslib: 2.8.1 - '@peculiar/asn1-schema@2.9.0': + '@peculiar/asn1-schema@2.9.4': dependencies: '@peculiar/utils': 2.0.3 asn1js: 3.0.10 tslib: 2.8.1 - '@peculiar/asn1-x509-attr@2.9.0': + '@peculiar/asn1-x509-attr@2.9.4': dependencies: - '@peculiar/asn1-schema': 2.9.0 - '@peculiar/asn1-x509': 2.9.0 + '@peculiar/asn1-schema': 2.9.4 + '@peculiar/asn1-x509': 2.9.4 asn1js: 3.0.10 tslib: 2.8.1 - '@peculiar/asn1-x509@2.9.0': + '@peculiar/asn1-x509@2.9.4': dependencies: - '@peculiar/asn1-schema': 2.9.0 + '@peculiar/asn1-schema': 2.9.4 '@peculiar/utils': 2.0.3 asn1js: 3.0.10 tslib: 2.8.1 @@ -10981,13 +10769,13 @@ snapshots: '@peculiar/x509@1.14.3': dependencies: - '@peculiar/asn1-cms': 2.9.0 - '@peculiar/asn1-csr': 2.9.0 - '@peculiar/asn1-ecc': 2.9.0 - '@peculiar/asn1-pkcs9': 2.9.0 - '@peculiar/asn1-rsa': 2.9.0 - '@peculiar/asn1-schema': 2.9.0 - '@peculiar/asn1-x509': 2.9.0 + '@peculiar/asn1-cms': 2.9.4 + '@peculiar/asn1-csr': 2.9.4 + '@peculiar/asn1-ecc': 2.9.4 + '@peculiar/asn1-pkcs9': 2.9.4 + '@peculiar/asn1-rsa': 2.9.4 + '@peculiar/asn1-schema': 2.9.4 + '@peculiar/asn1-x509': 2.9.4 pvtsutils: 1.3.6 reflect-metadata: 0.2.2 tslib: 2.8.1 @@ -11046,87 +10834,45 @@ snapshots: '@rolldown/binding-android-arm-eabi@1.2.5': optional: true - '@rolldown/binding-android-arm64@1.2.4': - optional: true - '@rolldown/binding-android-arm64@1.2.5': optional: true - '@rolldown/binding-darwin-arm64@1.2.4': - optional: true - '@rolldown/binding-darwin-arm64@1.2.5': optional: true - '@rolldown/binding-darwin-x64@1.2.4': - optional: true - '@rolldown/binding-darwin-x64@1.2.5': optional: true - '@rolldown/binding-freebsd-x64@1.2.4': - optional: true - '@rolldown/binding-freebsd-x64@1.2.5': optional: true - '@rolldown/binding-linux-arm-gnueabihf@1.2.4': - optional: true - '@rolldown/binding-linux-arm-gnueabihf@1.2.5': optional: true - '@rolldown/binding-linux-arm64-gnu@1.2.4': - optional: true - '@rolldown/binding-linux-arm64-gnu@1.2.5': optional: true - '@rolldown/binding-linux-arm64-musl@1.2.4': - optional: true - '@rolldown/binding-linux-arm64-musl@1.2.5': optional: true - '@rolldown/binding-linux-ppc64-gnu@1.2.4': - optional: true - '@rolldown/binding-linux-ppc64-gnu@1.2.5': optional: true - '@rolldown/binding-linux-s390x-gnu@1.2.4': - optional: true - '@rolldown/binding-linux-s390x-gnu@1.2.5': optional: true - '@rolldown/binding-linux-x64-gnu@1.2.4': - optional: true - '@rolldown/binding-linux-x64-gnu@1.2.5': optional: true - '@rolldown/binding-linux-x64-musl@1.2.4': - optional: true - '@rolldown/binding-linux-x64-musl@1.2.5': optional: true - '@rolldown/binding-openharmony-arm64@1.2.4': - optional: true - '@rolldown/binding-openharmony-arm64@1.2.5': optional: true - '@rolldown/binding-win32-arm64-msvc@1.2.4': - optional: true - '@rolldown/binding-win32-arm64-msvc@1.2.5': optional: true - '@rolldown/binding-win32-x64-msvc@1.2.4': - optional: true - '@rolldown/binding-win32-x64-msvc@1.2.5': optional: true @@ -11615,15 +11361,6 @@ snapshots: transitivePeerDependencies: - supports-color - '@verdaccio/core@8.2.1': - dependencies: - ajv: 8.20.0 - http-errors: 2.0.1 - http-status-codes: 2.3.0 - minimatch: 10.2.5 - process-warning: 1.0.0 - semver: 7.8.5 - '@verdaccio/core@8.2.2': dependencies: ajv: 8.20.0 @@ -11901,7 +11638,7 @@ snapshots: '@webassemblyjs/ast': 1.14.1 '@xtuc/long': 4.2.2 - '@xmldom/xmldom@0.8.14': {} + '@xmldom/xmldom@0.8.15': {} '@xtuc/ieee754@1.2.0': {} @@ -12000,7 +11737,7 @@ snapshots: accepts@2.0.0: dependencies: mime-types: 3.0.2 - negotiator: 1.0.0 + negotiator: 1.1.0 acorn-jsx@5.3.2(acorn@8.18.0): dependencies: @@ -12046,7 +11783,7 @@ snapshots: ajv@8.20.0: dependencies: fast-deep-equal: 3.1.3 - fast-uri: 3.1.5 + fast-uri: 3.1.6 json-schema-traverse: 1.0.0 require-from-string: 2.0.2 @@ -12242,7 +11979,7 @@ snapshots: base64id@2.0.0: {} - baseline-browser-mapping@2.11.14: {} + baseline-browser-mapping@2.11.18: {} batch@0.6.1: {} @@ -12397,9 +12134,9 @@ snapshots: browserslist@4.28.8: dependencies: - baseline-browser-mapping: 2.11.14 + baseline-browser-mapping: 2.11.18 caniuse-lite: 1.0.30001809 - electron-to-chromium: 1.5.408 + electron-to-chromium: 1.5.412 node-releases: 2.0.53 update-browserslist-db: 1.3.1(browserslist@4.28.8) @@ -12629,6 +12366,8 @@ snapshots: content-type@2.1.0: {} + content-type@3.0.0: {} + conventional-commits-filter@6.0.1: {} conventional-commits-parser@7.1.2: @@ -12911,7 +12650,7 @@ snapshots: ejs@6.0.1: {} - electron-to-chromium@1.5.408: {} + electron-to-chromium@1.5.412: {} emoji-regex@10.6.0: {} @@ -13383,7 +13122,7 @@ snapshots: dependencies: fast-string-truncated-width: 3.0.3 - fast-uri@3.1.5: {} + fast-uri@3.1.6: {} fast-wrap-ansi@0.2.2: dependencies: @@ -14262,7 +14001,7 @@ snapshots: jasmine-reporters@2.5.2: dependencies: - '@xmldom/xmldom': 0.8.14 + '@xmldom/xmldom': 0.8.15 mkdirp: 1.0.4 jasmine-spec-reporter@7.0.0: @@ -14563,7 +14302,7 @@ snapshots: dependencies: cli-truncate: 6.1.1 log-update: 8.0.0 - wrap-ansi: 10.0.0 + wrap-ansi: 10.0.1 lmdb@3.5.6: dependencies: @@ -14638,7 +14377,7 @@ snapshots: slice-ansi: 9.0.0 string-width: 8.2.2 strip-ansi: 7.2.0 - wrap-ansi: 10.0.0 + wrap-ansi: 10.0.1 log4js@6.9.1(supports-color@11.0.0): dependencies: @@ -14763,10 +14502,6 @@ snapshots: tapable: 2.3.3 webpack: 5.109.2(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.26)(uglify-js@3.19.3) - minimatch@10.2.5: - dependencies: - brace-expansion: 5.0.9 - minimatch@10.2.6: dependencies: brace-expansion: 5.0.9 @@ -14881,7 +14616,9 @@ snapshots: negotiator@0.6.4: {} - negotiator@1.0.0: {} + negotiator@1.1.0: + dependencies: + content-type: 2.1.0 neo-async@2.6.2: {} @@ -15643,26 +15380,6 @@ snapshots: transitivePeerDependencies: - oxc-resolver - rolldown@1.2.4: - dependencies: - '@oxc-project/types': 0.144.0 - '@rolldown/pluginutils': 1.0.1 - optionalDependencies: - '@rolldown/binding-android-arm64': 1.2.4 - '@rolldown/binding-darwin-arm64': 1.2.4 - '@rolldown/binding-darwin-x64': 1.2.4 - '@rolldown/binding-freebsd-x64': 1.2.4 - '@rolldown/binding-linux-arm-gnueabihf': 1.2.4 - '@rolldown/binding-linux-arm64-gnu': 1.2.4 - '@rolldown/binding-linux-arm64-musl': 1.2.4 - '@rolldown/binding-linux-ppc64-gnu': 1.2.4 - '@rolldown/binding-linux-s390x-gnu': 1.2.4 - '@rolldown/binding-linux-x64-gnu': 1.2.4 - '@rolldown/binding-linux-x64-musl': 1.2.4 - '@rolldown/binding-openharmony-arm64': 1.2.4 - '@rolldown/binding-win32-arm64-msvc': 1.2.4 - '@rolldown/binding-win32-x64-msvc': 1.2.4 - rolldown@1.2.5: dependencies: '@oxc-project/types': 0.146.0 @@ -16543,9 +16260,9 @@ snapshots: - encoding - supports-color - verdaccio-auth-memory@13.1.1(supports-color@11.0.0): + verdaccio-auth-memory@13.1.2(supports-color@11.0.0): dependencies: - '@verdaccio/core': 8.2.1 + '@verdaccio/core': 8.2.2 debug: 4.4.3(supports-color@11.0.0) transitivePeerDependencies: - supports-color @@ -16613,7 +16330,7 @@ snapshots: lightningcss: 1.33.0 picomatch: 4.0.5 postcss: 8.5.26 - rolldown: 1.2.4 + rolldown: 1.2.5 tinyglobby: 0.2.17 optionalDependencies: '@types/node': 22.20.1 @@ -16913,11 +16630,10 @@ snapshots: wordwrap@1.0.0: {} - wrap-ansi@10.0.0: + wrap-ansi@10.0.1: dependencies: ansi-styles: 6.2.3 string-width: 8.2.2 - strip-ansi: 7.2.0 wrap-ansi@7.0.0: dependencies: From 4d0be683b780a9a1629dc8f9cddad49153bddabf Mon Sep 17 00:00:00 2001 From: Alan Agius <17563226+alan-agius4@users.noreply.github.com> Date: Tue, 25 Aug 2026 13:34:01 +0000 Subject: [PATCH 338/787] fix(@angular/build): ignore side-effect annotations in unit test builds MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit In libraries built with ng-packagr, `package.json` typically specifies `"sideEffects": false` so consumer applications can tree-shake unused code. However, when executing unit tests through `@angular/build:unit-test`, the test builder bundles workspace library source directly (via tsconfig paths). Because esbuild tree-shaking respects `"sideEffects": false` annotations in the enclosing `package.json`, bundling multiple spec entry points without splitting can cause esbuild to prune module bodies (such as component definitions) from multi-level `export *` barrel graphs while retaining namespace re-export accessors. At runtime, accessing the exported symbols evaluates to `undefined`, causing failures such as `TypeError: Cannot read properties of undefined (reading 'ɵcmp')`. Test bundles are executed locally in memory and never distributed over the wire, so side-effect annotations and pure call pruning are not required. Setting `ignoreAnnotations: true` when `disableCodeSplitting` is enabled ensures that statically reachable barrel exports in workspace code are retained without affecting production application or package builds. Closes #33910 --- .../vitest-barrel-side-effects_spec.ts | 134 ++++++++++++++++++ .../tools/esbuild/application-code-bundle.ts | 3 + 2 files changed, 137 insertions(+) create mode 100644 packages/angular/build/src/builders/unit-test/tests/behavior/vitest-barrel-side-effects_spec.ts diff --git a/packages/angular/build/src/builders/unit-test/tests/behavior/vitest-barrel-side-effects_spec.ts b/packages/angular/build/src/builders/unit-test/tests/behavior/vitest-barrel-side-effects_spec.ts new file mode 100644 index 000000000000..7a59f09eeaa0 --- /dev/null +++ b/packages/angular/build/src/builders/unit-test/tests/behavior/vitest-barrel-side-effects_spec.ts @@ -0,0 +1,134 @@ +/** + * @license + * Copyright Google LLC All Rights Reserved. + * + * Use of this source code is governed by an MIT-style license that can be + * found in the LICENSE file at https://angular.dev/license + */ + +import { execute } from '../../index'; +import { BASE_OPTIONS, describeBuilder, UNIT_TEST_BUILDER_INFO } from '../setup'; + +describeBuilder(execute, UNIT_TEST_BUILDER_INFO, (harness) => { + describe('Behavior: "Vitest barrel sideEffects"', () => { + // Regression test for https://github.com/angular/angular-cli/issues/33910. + it('should retain barrel-exported components when package.json has sideEffects: false', async () => { + harness.withBuilderTarget( + 'build', + async () => ({ success: true }), + { + project: 'src/lib/ng-package.json', + }, + { + builderName: '@angular/build:ng-packagr', + }, + ); + + await harness.modifyFile('tsconfig.json', (content) => { + const tsconfig = JSON.parse(content); + tsconfig.compilerOptions ??= {}; + tsconfig.compilerOptions.paths = { + '@lib': ['./src/lib/public-api.ts'], + '@lib/sub': ['./src/lib/sub/public-api.ts'], + }; + + return JSON.stringify(tsconfig); + }); + + await harness.writeFiles({ + 'src/lib/package.json': JSON.stringify({ + name: '@lib', + version: '0.0.1', + sideEffects: false, + }), + 'src/lib/ng-package.json': JSON.stringify({ + lib: { + entryFile: 'public-api.ts', + }, + }), + 'src/lib/public-api.ts': ` + export * from './components/public-api-components'; + export * from './other/other.component'; + `, + 'src/lib/components/public-api-components.ts': `export * from './foo/foo.component';`, + 'src/lib/components/foo/foo.component.ts': ` + import { Component } from '@angular/core'; + + @Component({ + selector: 'lib-foo', + standalone: true, + template: '

foo

', + }) + export class FooComponent {} + `, + 'src/lib/other/other.component.ts': ` + import { Component } from '@angular/core'; + + @Component({ + selector: 'lib-other', + standalone: true, + template: '

other

', + }) + export class OtherComponent {} + `, + 'src/lib/other/other.component.spec.ts': ` + import { TestBed } from '@angular/core/testing'; + import { describe, it, expect } from 'vitest'; + import { OtherComponent } from '@lib'; + + describe('OtherComponent', () => { + it('creates', () => { + TestBed.configureTestingModule({ + imports: [OtherComponent], + }); + const fixture = TestBed.createComponent(OtherComponent); + expect(fixture).toBeTruthy(); + }); + }); + `, + 'src/lib/sub/ng-package.json': JSON.stringify({ + lib: { + entryFile: 'public-api.ts', + }, + }), + 'src/lib/sub/public-api.ts': `export * from './bar/bar.component';`, + 'src/lib/sub/bar/bar.component.ts': ` + import { Component } from '@angular/core'; + import { FooComponent } from '@lib'; + + @Component({ + selector: 'lib-bar', + standalone: true, + imports: [FooComponent], + template: '', + }) + export class BarComponent {} + `, + 'src/lib/sub/bar/bar.component.spec.ts': ` + import { TestBed } from '@angular/core/testing'; + import { describe, it, expect } from 'vitest'; + import { BarComponent } from './bar.component'; + + describe('BarComponent', () => { + it('creates', () => { + TestBed.configureTestingModule({ + imports: [BarComponent], + }); + const fixture = TestBed.createComponent(BarComponent); + expect(fixture).toBeTruthy(); + }); + }); + `, + }); + + harness.useTarget('test', { + ...BASE_OPTIONS, + include: ['lib/**/*.spec.ts'], + }); + + const { result } = await harness.executeOnce(); + + expect(result?.success).toBeTrue(); + }); + }); +}); diff --git a/packages/angular/build/src/tools/esbuild/application-code-bundle.ts b/packages/angular/build/src/tools/esbuild/application-code-bundle.ts index ba1c6e1c69f7..775475f3e0c8 100644 --- a/packages/angular/build/src/tools/esbuild/application-code-bundle.ts +++ b/packages/angular/build/src/tools/esbuild/application-code-bundle.ts @@ -75,6 +75,9 @@ export function createBrowserCodeBundleOptions( // Splitting emits shared chunks that are read across chunk boundaries as live ESM bindings, // which the unit-test runners' module loading does not reliably preserve. buildOptions.splitting = false; + // In unit test builds, package.json "sideEffects": false annotations can cause esbuild + // to incorrectly elide statically-referenced barrel module bodies across multiple entry points. + buildOptions.ignoreAnnotations = true; } buildOptions.plugins ??= []; From 4a26c2f62246f2da3fbbc0360484f36d05279ed6 Mon Sep 17 00:00:00 2001 From: Charles Lyding <19598772+clydin@users.noreply.github.com> Date: Mon, 24 Aug 2026 13:27:19 -0400 Subject: [PATCH 339/787] refactor(@angular/build): avoid retaining worker file data for single-batch inlining When processing files where all remaining locales fit into a single batch, the file will only be transformed once across all worker threads. Retaining the parsed AST and source code in the worker's long-term `fileDataCache` leads to monotonic memory growth across multi-file builds without providing any cache reuse. This change marks single-batch requests as `ephemeral`, allowing the worker to extract localization metadata and perform inlining within the execution frame without caching the file data long-term. The parsed AST and code are then naturally garbage-collected when the batch action completes. --- .../src/tools/esbuild/i18n-inliner-worker.ts | 50 +++++++++++++------ .../build/src/tools/esbuild/i18n-inliner.ts | 10 +++- .../src/tools/esbuild/i18n-inliner_spec.ts | 5 ++ 3 files changed, 47 insertions(+), 18 deletions(-) diff --git a/packages/angular/build/src/tools/esbuild/i18n-inliner-worker.ts b/packages/angular/build/src/tools/esbuild/i18n-inliner-worker.ts index 379368088ad0..13b14d9623e7 100644 --- a/packages/angular/build/src/tools/esbuild/i18n-inliner-worker.ts +++ b/packages/angular/build/src/tools/esbuild/i18n-inliner-worker.ts @@ -78,6 +78,12 @@ interface InlineFileBatchRequest { * The locale specifiers or locale objects that should be used during the inlining process of the file. */ locales: (string | { locale: string; translation?: Blob })[]; + + /** + * Whether the file data should be treated as ephemeral and not cached long-term in the Worker. + * Typically true when all remaining locales for the file are processed in a single batch. + */ + ephemeral?: boolean; } /** @@ -124,23 +130,35 @@ const fileDataCache = new Map>(); const deserializedTranslations = new Map>>(); /** - * Retrieves the cached file data for a filename, loading and extracting it on the first request. + * Retrieves the file data for a filename, loading and extracting localization metadata. + * If `cache` is true, the result is cached in `fileDataCache` across requests in this Worker. + * If `cache` is false (ephemeral), the result is not retained in `fileDataCache`, allowing it + * to be garbage-collected once the batch request finishes. * * @param filename The name of the file to load. - * @returns The cached code and localization metadata. + * @param cache Whether to cache the loaded file data in the Worker's long-term cache. + * @returns The cached or newly extracted code and localization metadata. */ -function getFileData(filename: string): Promise { - let fileDataPromise = fileDataCache.get(filename); - if (!fileDataPromise) { - fileDataPromise = (async () => { - const data = files.get(filename); - assert(data !== undefined, `Invalid inline request for file '${filename}'.`); - - const code = await data.text(); - const metadata = extractLocalizeMetadata(filename, code); - - return { code, metadata }; - })(); +function loadFileData(filename: string, cache = true): Promise { + const existing = fileDataCache.get(filename); + if (existing) { + return existing; + } + + const fileDataPromise = (async () => { + const data = files.get(filename); + assert(data !== undefined, `Invalid inline request for file '${filename}'.`); + + const code = await data.text(); + const metadata = extractLocalizeMetadata(filename, code); + + return { code, metadata }; + })(); + + if (cache) { + fileDataPromise.catch(() => { + fileDataCache.delete(filename); + }); fileDataCache.set(filename, fileDataPromise); } @@ -186,7 +204,7 @@ function loadTranslation( * @returns An object containing the inlined file and optional map content. */ export default async function inlineFile(request: InlineFileRequest) { - const { code, metadata } = await getFileData(request.filename); + const { code, metadata } = await loadFileData(request.filename, true); // Sourcemaps are parsed on demand per request rather than cached long-term to prevent // monotonic memory growth as a worker processes multiple files across the build. @@ -219,7 +237,7 @@ export default async function inlineFile(request: InlineFileRequest) { export async function inlineFileBatch( request: InlineFileBatchRequest, ): Promise { - const { code, metadata } = await getFileData(request.filename); + const { code, metadata } = await loadFileData(request.filename, !request.ephemeral); // Parse the sourcemap once for the entire batch. // It will naturally be garbage-collected after this batch action returns. diff --git a/packages/angular/build/src/tools/esbuild/i18n-inliner.ts b/packages/angular/build/src/tools/esbuild/i18n-inliner.ts index 535aae960b34..983f17956b31 100644 --- a/packages/angular/build/src/tools/esbuild/i18n-inliner.ts +++ b/packages/angular/build/src/tools/esbuild/i18n-inliner.ts @@ -9,7 +9,7 @@ import assert from 'node:assert'; import { extname, join } from 'node:path'; import { serialize } from 'node:v8'; -import { calculateHash, createContentHash } from '../../utils/hash'; +import { calculateHash, createContentHash, initializeHash } from '../../utils/hash'; import { WorkerPool } from '../../utils/worker-pool'; import { type BuildOutputFile, BuildOutputFileType, createOutputFile } from './bundler-files'; import { type PersistentCacheStore, createPersistentCacheStore } from './cache'; @@ -377,6 +377,7 @@ export class I18nInliner { const workerTasks: Promise[] = []; for (const [filename, entries] of uncachedByFile) { + const ephemeral = entries.length <= localesPerBatch; for (let i = 0; i < entries.length; i += localesPerBatch) { const batchEntries = entries.slice(i, i + localesPerBatch); const task = (async () => { @@ -387,6 +388,7 @@ export class I18nInliner { locale: e.locale, translation: e.translation, })), + ephemeral, }, { name: 'inlineFileBatch' }, )) as { @@ -518,7 +520,11 @@ export class I18nInliner { // Initialize a persistent cache for i18n transformations. try { - this.#cache = await createPersistentCacheStore(join(persistentCachePath, 'angular-i18n')); + const [, cache] = await Promise.all([ + initializeHash(), + createPersistentCacheStore(join(persistentCachePath, 'angular-i18n')), + ]); + this.#cache = cache; } catch { this.#cacheInitFailed = true; diff --git a/packages/angular/build/src/tools/esbuild/i18n-inliner_spec.ts b/packages/angular/build/src/tools/esbuild/i18n-inliner_spec.ts index d71f9c0a8830..e8fefeb3a14f 100644 --- a/packages/angular/build/src/tools/esbuild/i18n-inliner_spec.ts +++ b/packages/angular/build/src/tools/esbuild/i18n-inliner_spec.ts @@ -10,6 +10,7 @@ import { transform } from 'esbuild'; import fs from 'node:fs/promises'; import os from 'node:os'; import path from 'node:path'; +import { initializeHash } from '../../utils/hash'; import { type BuildOutputFile, BuildOutputFileType, createOutputFile } from './bundler-files'; import { I18nInliner } from './i18n-inliner'; @@ -43,6 +44,10 @@ function findFile(outputFiles: BuildOutputFile[], path: string): BuildOutputFile describe('I18nInliner', () => { let inliner: I18nInliner | undefined; + beforeAll(async () => { + await initializeHash(); + }); + // A single thread is used throughout so that every file of every locale is inlined by the same // Worker. Any translation state that a Worker retains between requests is then observable. function createInliner(outputFiles: BuildOutputFile[]): I18nInliner { From f1cc959439d8ca11a45d693520c34dd94e0b6548 Mon Sep 17 00:00:00 2001 From: Charles Lyding <19598772+clydin@users.noreply.github.com> Date: Mon, 24 Aug 2026 15:57:11 -0400 Subject: [PATCH 340/787] perf(@angular/build): implement sliding-window batching and worker translation eviction MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit In enterprise Angular applications with a high number of locales (e.g. 20–50+), deserializing translation dictionaries into native JavaScript objects across all worker threads simultaneously can lead to multi-gigabyte resident memory footprints in V8 worker heaps. This change introduces sliding-window locale batching and lock-free translation eviction: - `I18nInliner.inlineAll` processes locales in sliding windows of up to 8 locales each (`DEFAULT_LOCALE_WINDOW_SIZE`), capping peak memory while retaining maximum multi-locale batching throughput. - Worker tasks receive an `activeLocales` array on each batch request. Workers automatically purge any cached translation dictionaries in `deserializedTranslations` that are not part of the active window when transitioning across window boundaries. --- .../src/tools/esbuild/i18n-inliner-worker.ts | 15 ++ .../build/src/tools/esbuild/i18n-inliner.ts | 180 ++++++++++-------- .../src/tools/esbuild/i18n-inliner_spec.ts | 24 +++ 3 files changed, 140 insertions(+), 79 deletions(-) diff --git a/packages/angular/build/src/tools/esbuild/i18n-inliner-worker.ts b/packages/angular/build/src/tools/esbuild/i18n-inliner-worker.ts index 13b14d9623e7..a0ca9e25e6f2 100644 --- a/packages/angular/build/src/tools/esbuild/i18n-inliner-worker.ts +++ b/packages/angular/build/src/tools/esbuild/i18n-inliner-worker.ts @@ -84,6 +84,12 @@ interface InlineFileBatchRequest { * Typically true when all remaining locales for the file are processed in a single batch. */ ephemeral?: boolean; + + /** + * The list of active locales in the current inlining window. Any cached translation dictionaries + * not present in this list will be evicted from the Worker's memory cache. + */ + activeLocales?: string[]; } /** @@ -237,6 +243,15 @@ export default async function inlineFile(request: InlineFileRequest) { export async function inlineFileBatch( request: InlineFileBatchRequest, ): Promise { + if (request.activeLocales) { + const activeSet = new Set(request.activeLocales); + for (const locale of deserializedTranslations.keys()) { + if (!activeSet.has(locale)) { + deserializedTranslations.delete(locale); + } + } + } + const { code, metadata } = await loadFileData(request.filename, !request.ephemeral); // Parse the sourcemap once for the entire batch. diff --git a/packages/angular/build/src/tools/esbuild/i18n-inliner.ts b/packages/angular/build/src/tools/esbuild/i18n-inliner.ts index 983f17956b31..61ff460579c1 100644 --- a/packages/angular/build/src/tools/esbuild/i18n-inliner.ts +++ b/packages/angular/build/src/tools/esbuild/i18n-inliner.ts @@ -20,6 +20,12 @@ import { type PersistentCacheStore, createPersistentCacheStore } from './cache'; */ const LOCALIZE_KEYWORD = '$localize'; +/** + * The maximum number of locales to process concurrently in a single sliding window. + * This caps peak worker memory while maintaining multi-locale batching throughput. + */ +const DEFAULT_LOCALE_WINDOW_SIZE = 8; + /** * Serializes the translation messages for a locale for transfer to an inliner Worker. * @@ -218,101 +224,114 @@ export class I18nInliner { fileResultsByLocale.set(locale, new Map()); } - // Pre-calculate cache key bases and serialized Blobs for each requested locale - const localeCacheBases = new Map(); - const localeBlobs = new Map(); - - for (const { locale, translation, translationIntegrity } of localeList) { - localeBlobs.set(locale, serializeTranslation(translation)); - - if (this.#cache) { - localeCacheBases.set( - locale, - calculateHash( - JSON.stringify({ - locale, - translation: translationIntegrity || translation, - missingTranslation, - shouldOptimize, - localizeVersion, - }), - ), - ); - } - } - const filenames = Array.from(this.#localizeFiles.keys()).filter( (name) => !name.endsWith('.map'), ); - const cacheChecks: CacheCheckItem[] = []; + // Process locales in sliding windows to cap peak worker memory + for (let i = 0; i < localeList.length; i += DEFAULT_LOCALE_WINDOW_SIZE) { + const windowLocales = localeList.slice(i, i + DEFAULT_LOCALE_WINDOW_SIZE); + const activeLocales = windowLocales.map((item) => item.locale); + const isLastWindow = i + DEFAULT_LOCALE_WINDOW_SIZE >= localeList.length; - for (const filename of filenames) { - const file = this.#localizeFiles.get(filename); - assert(file !== undefined, 'Localize file must exist: ' + filename); + // Pre-calculate cache key bases and serialized Blobs for each locale in this window + const localeCacheBases = new Map(); + const localeBlobs = new Map(); - for (const { locale } of localeList) { - let cacheKey: string | undefined; - let cachedResultPromise: Promise = Promise.resolve(null); + for (const { locale, translation, translationIntegrity } of windowLocales) { + localeBlobs.set(locale, serializeTranslation(translation)); if (this.#cache) { - const fileCacheKeyBase = localeCacheBases.get(locale); - assert(fileCacheKeyBase !== undefined, 'Cache base must exist for locale: ' + locale); + localeCacheBases.set( + locale, + calculateHash( + JSON.stringify({ + locale, + translation: translationIntegrity || translation, + missingTranslation, + shouldOptimize, + localizeVersion, + }), + ), + ); + } + } - const hasher = createContentHash(); - hasher.update(file.hash); - hasher.update(filename); - hasher.update(fileCacheKeyBase); - cacheKey = hasher.digest(); + const cacheChecks: CacheCheckItem[] = []; - cachedResultPromise = this.#cache.get(cacheKey).catch(() => null); - } + for (const filename of filenames) { + const file = this.#localizeFiles.get(filename); + assert(file !== undefined, 'Localize file must exist: ' + filename); - cacheChecks.push({ - filename, - locale, - cacheKey, - cachedResult: cachedResultPromise, - }); - } - } + for (const { locale } of windowLocales) { + let cacheKey: string | undefined; + let cachedResultPromise: Promise = Promise.resolve(null); - // Await all cache checks - const resolvedChecks = await Promise.all( - cacheChecks.map(async (item) => ({ - ...item, - result: await item.cachedResult, - })), - ); + if (this.#cache) { + const fileCacheKeyBase = localeCacheBases.get(locale); + assert(fileCacheKeyBase !== undefined, 'Cache base must exist for locale: ' + locale); - // Group uncached items by filename - const uncachedByFile = new Map< - string, - Array<{ locale: string; cacheKey?: string; translation?: Blob }> - >(); + const hasher = createContentHash(); + hasher.update(file.hash); + hasher.update(filename); + hasher.update(fileCacheKeyBase); + cacheKey = hasher.digest(); - for (const item of resolvedChecks) { - if (item.result) { - // Cache hit: store directly in locale file results - fileResultsByLocale.get(item.locale)?.set(item.filename, item.result); - } else { - // Cache miss: needs worker processing - let fileEntries = uncachedByFile.get(item.filename); - if (!fileEntries) { - fileEntries = []; - uncachedByFile.set(item.filename, fileEntries); + cachedResultPromise = this.#cache.get(cacheKey).catch(() => null); + } + + cacheChecks.push({ + filename, + locale, + cacheKey, + cachedResult: cachedResultPromise, + }); } - fileEntries.push({ - locale: item.locale, - cacheKey: item.cacheKey, - translation: localeBlobs.get(item.locale), - }); } - } - // Adaptive 2D Sharding for uncached tasks - if (uncachedByFile.size > 0) { - await this.#processUncachedBatches(uncachedByFile, localeList.length, fileResultsByLocale); + // Await all cache checks for this window + const resolvedChecks = await Promise.all( + cacheChecks.map(async (item) => ({ + ...item, + result: await item.cachedResult, + })), + ); + + // Group uncached items by filename for this window + const uncachedByFile = new Map< + string, + Array<{ locale: string; cacheKey?: string; translation?: Blob }> + >(); + + for (const item of resolvedChecks) { + if (item.result) { + // Cache hit: store directly in locale file results + fileResultsByLocale.get(item.locale)?.set(item.filename, item.result); + } else { + // Cache miss: needs worker processing + let fileEntries = uncachedByFile.get(item.filename); + if (!fileEntries) { + fileEntries = []; + uncachedByFile.set(item.filename, fileEntries); + } + fileEntries.push({ + locale: item.locale, + cacheKey: item.cacheKey, + translation: localeBlobs.get(item.locale), + }); + } + } + + // Adaptive 2D Sharding for uncached tasks in this window + if (uncachedByFile.size > 0) { + await this.#processUncachedBatches( + uncachedByFile, + windowLocales.length, + fileResultsByLocale, + activeLocales, + isLastWindow, + ); + } } // Assemble final results in deterministic order per locale @@ -366,6 +385,8 @@ export class I18nInliner { uncachedByFile: Map>, localeCount: number, fileResultsByLocale: Map>, + activeLocales?: string[], + isLastWindow = true, ): Promise { const workerCount = this.#workerPool.maxThreads || 1; const targetTaskCount = Math.max(uncachedByFile.size, workerCount * 2); @@ -377,7 +398,7 @@ export class I18nInliner { const workerTasks: Promise[] = []; for (const [filename, entries] of uncachedByFile) { - const ephemeral = entries.length <= localesPerBatch; + const ephemeral = isLastWindow && entries.length <= localesPerBatch; for (let i = 0; i < entries.length; i += localesPerBatch) { const batchEntries = entries.slice(i, i + localesPerBatch); const task = (async () => { @@ -389,6 +410,7 @@ export class I18nInliner { translation: e.translation, })), ephemeral, + activeLocales, }, { name: 'inlineFileBatch' }, )) as { diff --git a/packages/angular/build/src/tools/esbuild/i18n-inliner_spec.ts b/packages/angular/build/src/tools/esbuild/i18n-inliner_spec.ts index e8fefeb3a14f..90b9a9779a6d 100644 --- a/packages/angular/build/src/tools/esbuild/i18n-inliner_spec.ts +++ b/packages/angular/build/src/tools/esbuild/i18n-inliner_spec.ts @@ -516,4 +516,28 @@ describe('I18nInliner', () => { await fs.rm(cacheDir, { recursive: true, force: true }); } }); + + it('inlines across sliding windows when locale count exceeds window size', async () => { + const locales = Array.from({ length: 20 }, (_, i) => ({ + locale: `locale-${i}`, + translation: { greeting: translationFor(`Hello ${i}`) }, + })); + + const inliner = new I18nInliner( + { + missingTranslation: 'warning', + outputFiles: [browserFile('main.js', GREETING_SOURCE)], + }, + 2, + ); + + const results = await inliner.inlineAll(locales); + + expect(results.size).toBe(20); + for (let i = 0; i < 20; i++) { + const localeResult = results.get(`locale-${i}`); + expect(localeResult?.errors).toEqual([]); + expect(findFile(localeResult?.outputFiles ?? [], 'main.js').text).toContain(`"Hello ${i}"`); + } + }); }); From c0d872bd183f90f2f295f519a0d246d25ff0f746 Mon Sep 17 00:00:00 2001 From: Charles Lyding <19598772+clydin@users.noreply.github.com> Date: Mon, 24 Aug 2026 18:36:34 -0400 Subject: [PATCH 341/787] refactor(@angular/build): use namespaced Cache abstraction in i18n inliner Updates I18nInliner to instantiate and use a namespaced Cache instance (cacheStore.createCache('transforms')) instead of directly invoking lower-level CacheStore methods (get/set). Using the Cache abstraction ensures standard namespace partitioning within the angular-i18n persistent cache store, automatic in-flight promise management, and proper get/put promise semantics. --- .../build/src/tools/esbuild/i18n-inliner.ts | 38 +++++++++---------- 1 file changed, 19 insertions(+), 19 deletions(-) diff --git a/packages/angular/build/src/tools/esbuild/i18n-inliner.ts b/packages/angular/build/src/tools/esbuild/i18n-inliner.ts index 61ff460579c1..b8ad6cdedcab 100644 --- a/packages/angular/build/src/tools/esbuild/i18n-inliner.ts +++ b/packages/angular/build/src/tools/esbuild/i18n-inliner.ts @@ -12,7 +12,7 @@ import { serialize } from 'node:v8'; import { calculateHash, createContentHash, initializeHash } from '../../utils/hash'; import { WorkerPool } from '../../utils/worker-pool'; import { type BuildOutputFile, BuildOutputFileType, createOutputFile } from './bundler-files'; -import { type PersistentCacheStore, createPersistentCacheStore } from './cache'; +import { type Cache, type PersistentCacheStore, createPersistentCacheStore } from './cache'; /** * A keyword used to indicate if a JavaScript file may require inlining of translations. @@ -125,7 +125,8 @@ interface CacheCheckItem { export class I18nInliner { #cacheInitFailed = false; #workerPool: WorkerPool; - #cache: PersistentCacheStore | undefined; + #cacheStore: PersistentCacheStore | undefined; + #cache: Cache | undefined; readonly #localizeFiles: ReadonlyMap; readonly #unmodifiedFiles: Array; @@ -241,7 +242,7 @@ export class I18nInliner { for (const { locale, translation, translationIntegrity } of windowLocales) { localeBlobs.set(locale, serializeTranslation(translation)); - if (this.#cache) { + if (this.#cacheStore) { localeCacheBases.set( locale, calculateHash( @@ -277,7 +278,10 @@ export class I18nInliner { hasher.update(fileCacheKeyBase); cacheKey = hasher.digest(); - cachedResultPromise = this.#cache.get(cacheKey).catch(() => null); + cachedResultPromise = this.#cache + .get(cacheKey) + .then((val) => val ?? null) + .catch(() => null); } cacheChecks.push({ @@ -424,18 +428,13 @@ export class I18nInliner { const cacheKey = matchingEntry?.cacheKey; if (this.#cache && cacheKey) { - // `CacheStore.set` may return `this` synchronously or a `Promise`. - // `Promise.resolve` normalizes both return values into a Promise so `Promise.allSettled` - // can safely handle any synchronous or asynchronous cache store errors. cachePromises.push( - Promise.resolve( - this.#cache.set(cacheKey, { - file: filename, - code: res.code, - map: res.map, - messages: res.messages, - }), - ), + this.#cache.put(cacheKey, { + file: filename, + code: res.code, + map: res.map, + messages: res.messages, + }), ); } @@ -520,7 +519,7 @@ export class I18nInliner { * @returns A void promise that resolves when closing is complete. */ async close(): Promise { - await Promise.allSettled([this.#cache?.close(), this.#workerPool.destroy()]); + await Promise.allSettled([this.#cacheStore?.close(), this.#workerPool.destroy()]); } /** @@ -530,7 +529,7 @@ export class I18nInliner { * @returns A promise that resolves once the cache initialization process is complete. */ private async initCache(): Promise { - if (this.#cache || this.#cacheInitFailed) { + if (this.#cacheStore || this.#cacheInitFailed) { return; } @@ -542,11 +541,12 @@ export class I18nInliner { // Initialize a persistent cache for i18n transformations. try { - const [, cache] = await Promise.all([ + const [, cacheStore] = await Promise.all([ initializeHash(), createPersistentCacheStore(join(persistentCachePath, 'angular-i18n')), ]); - this.#cache = cache; + this.#cacheStore = cacheStore; + this.#cache = cacheStore.createCache('transforms'); } catch { this.#cacheInitFailed = true; From 0589edd9cdc493ecf34a160cc7b8491618b59f72 Mon Sep 17 00:00:00 2001 From: Alan Agius Date: Tue, 25 Aug 2026 16:44:23 +0200 Subject: [PATCH 342/787] perf(@angular/build): consolidate component stylesheet bundling with shared load result cache Replaces per-stylesheet `esbuild.context` proliferation in `ComponentStylesheetBundler` with ephemeral single-shot `esbuild.build()` invocations and a shared, persistent `MemoryLoadResultCache`. --- .../esbuild/angular/component-stylesheets.ts | 184 ++++++++++-------- .../src/tools/esbuild/bundler-context.ts | 68 ++++++- .../src/tools/esbuild/bundler-context_spec.ts | 113 +++++++++++ 3 files changed, 282 insertions(+), 83 deletions(-) create mode 100644 packages/angular/build/src/tools/esbuild/bundler-context_spec.ts diff --git a/packages/angular/build/src/tools/esbuild/angular/component-stylesheets.ts b/packages/angular/build/src/tools/esbuild/angular/component-stylesheets.ts index 7cfc6e91e9f2..dd1b3b704150 100644 --- a/packages/angular/build/src/tools/esbuild/angular/component-stylesheets.ts +++ b/packages/angular/build/src/tools/esbuild/angular/component-stylesheets.ts @@ -12,6 +12,7 @@ import { createContentHash } from '../../../utils/hash'; import { BundleContextResult, BundlerContext } from '../bundler-context'; import { type BuildOutputFile, BuildOutputFileType } from '../bundler-files'; import { MemoryCache } from '../cache'; +import { MemoryLoadResultCache } from '../load-result-cache'; import { BundleStylesheetOptions, createStylesheetBundleOptions, @@ -30,11 +31,12 @@ export type ComponentStylesheetResult = BundleContextResult & { export class ComponentStylesheetBundler { readonly #fileContexts = new MemoryCache(); readonly #inlineContexts = new MemoryCache(); + readonly #loadCache = new MemoryLoadResultCache(); /** - * * @param options An object containing the stylesheet bundling options. - * @param cache A load result cache to use when bundling. + * @param defaultInlineLanguage The default language to use for inline component styles. + * @param incremental True if incremental watch mode is enabled. */ constructor( private readonly options: BundleStylesheetOptions, @@ -54,29 +56,38 @@ export class ComponentStylesheetBundler { externalId?: string | boolean, direct?: boolean, ): Promise { - const bundlerContext = await this.#fileContexts.getOrCreate(entry, () => { - return new BundlerContext(this.options.workspaceRoot, this.incremental, (loadCache) => { - const buildOptions = createStylesheetBundleOptions(this.options, loadCache); - if (externalId) { - assert( - typeof externalId === 'string', - 'Initial external component stylesheets must have a string identifier', - ); - - buildOptions.entryPoints = { [externalId]: entry }; - buildOptions.entryNames = '[name]'; - delete buildOptions.publicPath; - } else { - buildOptions.entryPoints = [entry]; - } + entry = path.normalize(entry); - // Angular encapsulation does not support nesting - // See: https://github.com/angular/angular/issues/58996 - buildOptions.supported ??= {}; - buildOptions.supported['nesting'] = false; + const bundlerContext = await this.#fileContexts.getOrCreate(entry, () => { + return new BundlerContext( + this.options.workspaceRoot, + this.incremental, + (loadCache) => { + const buildOptions = createStylesheetBundleOptions(this.options, loadCache); + if (externalId) { + assert( + typeof externalId === 'string', + 'Initial external component stylesheets must have a string identifier', + ); + + buildOptions.entryPoints = { [externalId]: entry }; + buildOptions.entryNames = '[name]'; + delete buildOptions.publicPath; + } else { + buildOptions.entryPoints = [entry]; + } - return buildOptions; - }); + // Angular encapsulation does not support nesting + // See: https://github.com/angular/angular/issues/58996 + buildOptions.supported ??= {}; + buildOptions.supported['nesting'] = false; + + return buildOptions; + }, + /* useContext */ false, + /* initialFilter */ undefined, + this.#loadCache, + ); }); return this.extractResult( @@ -101,6 +112,8 @@ export class ComponentStylesheetBundler { language = this.defaultInlineLanguage, externalId?: string, ): Promise { + filename = path.normalize(filename); + // Use a hash of the inline stylesheet content to ensure a consistent identifier. External stylesheets will resolve // to the actual stylesheet file path. const hasher = createContentHash(); @@ -112,48 +125,55 @@ export class ComponentStylesheetBundler { const bundlerContext = await this.#inlineContexts.getOrCreate(entry, () => { const namespace = 'angular:styles/component'; - return new BundlerContext(this.options.workspaceRoot, this.incremental, (loadCache) => { - const buildOptions = createStylesheetBundleOptions(this.options, loadCache, { - [entry]: data, - }); - if (externalId) { - buildOptions.entryPoints = { [externalId]: `${namespace};${entry}` }; - buildOptions.entryNames = '[name]'; - delete buildOptions.publicPath; - } else { - buildOptions.entryPoints = [`${namespace};${entry}`]; - } + return new BundlerContext( + this.options.workspaceRoot, + this.incremental, + (loadCache) => { + const buildOptions = createStylesheetBundleOptions(this.options, loadCache, { + [entry]: data, + }); + if (externalId) { + buildOptions.entryPoints = { [externalId]: `${namespace};${entry}` }; + buildOptions.entryNames = '[name]'; + delete buildOptions.publicPath; + } else { + buildOptions.entryPoints = [`${namespace};${entry}`]; + } - // Angular encapsulation does not support nesting - // See: https://github.com/angular/angular/issues/58996 - buildOptions.supported ??= {}; - buildOptions.supported['nesting'] = false; - - buildOptions.plugins.push({ - name: 'angular-component-styles', - setup(build) { - build.onResolve({ filter: /^angular:styles\/component;/ }, (args) => { - if (args.kind !== 'entry-point') { - return null; - } - - return { - path: entry, - namespace, - }; - }); - build.onLoad({ filter: /^css;/, namespace }, () => { - return { - contents: data, - loader: 'css', - resolveDir: path.dirname(filename), - }; - }); - }, - }); - - return buildOptions; - }); + // Angular encapsulation does not support nesting + // See: https://github.com/angular/angular/issues/58996 + buildOptions.supported ??= {}; + buildOptions.supported['nesting'] = false; + + buildOptions.plugins.push({ + name: 'angular-component-styles', + setup(build) { + build.onResolve({ filter: /^angular:styles\/component;/ }, (args) => { + if (args.kind !== 'entry-point') { + return null; + } + + return { + path: entry, + namespace, + }; + }); + build.onLoad({ filter: /^css;/, namespace }, () => { + return { + contents: data, + loader: 'css', + resolveDir: path.dirname(filename), + }; + }); + }, + }); + + return buildOptions; + }, + /* useContext */ false, + /* initialFilter */ undefined, + this.#loadCache, + ); }); // Extract the result of the bundling from the output files @@ -170,13 +190,20 @@ export class ComponentStylesheetBundler { * @param files The group of files that have been modified * @returns An array of file based stylesheet entries if any were invalidated; otherwise, undefined. */ - invalidate(files: Iterable): string[] | undefined { + invalidate(files: Iterable | ReadonlySet): string[] | undefined { if (!this.incremental) { return; } - const normalizedFiles = [...files].map(path.normalize); - const normalizedFilesSet = new Set(normalizedFiles); + const normalizedFiles = new Set(); + for (const file of files) { + const normalized = path.normalize(file); + normalizedFiles.add(normalized); + if (!path.isAbsolute(normalized)) { + normalizedFiles.add(path.normalize(path.join(this.options.workspaceRoot, normalized))); + } + } + let entries: string[] | undefined; for (const [entry, bundler] of this.#fileContexts.entries()) { @@ -190,7 +217,7 @@ export class ComponentStylesheetBundler { const firstSemi = entry.indexOf(';'); const secondSemi = firstSemi !== -1 ? entry.indexOf(';', firstSemi + 1) : -1; const filename = secondSemi !== -1 ? entry.slice(secondSemi + 1) : ''; - if (filename && normalizedFilesSet.has(path.normalize(filename))) { + if (filename && normalizedFiles.has(path.normalize(filename))) { this.#inlineContexts.delete(entry); void bundler.dispose(); } else { @@ -214,6 +241,7 @@ export class ComponentStylesheetBundler { const contexts = [...this.#fileContexts.values(), ...this.#inlineContexts.values()]; this.#fileContexts.clear(); this.#inlineContexts.clear(); + this.#loadCache.clear(); await Promise.allSettled(contexts.map((context) => context.dispose())); } @@ -268,14 +296,18 @@ export class ComponentStylesheetBundler { } } - const { metafile } = result; - // Remove entryPoint fields from outputs to prevent the internal component styles from being - // treated as initial files. Also mark the entry as a component resource for stat reporting. - Object.values(metafile.outputs).forEach((output) => { - delete output.entryPoint; - // eslint-disable-next-line @typescript-eslint/no-explicit-any - (output as any)['ng-component'] = true; - }); + // Clone metafile to prevent mutation of the cached result by downstream plugins + const metafile = { + inputs: { ...result.metafile.inputs }, + outputs: Object.fromEntries( + Object.entries(result.metafile.outputs).map(([key, output]) => { + const cloned = { ...output, ['ng-component']: true }; + delete cloned.entryPoint; + + return [key, cloned]; + }), + ), + }; return { errors, diff --git a/packages/angular/build/src/tools/esbuild/bundler-context.ts b/packages/angular/build/src/tools/esbuild/bundler-context.ts index 865ff301a214..b335a1160ba6 100644 --- a/packages/angular/build/src/tools/esbuild/bundler-context.ts +++ b/packages/angular/build/src/tools/esbuild/bundler-context.ts @@ -106,7 +106,7 @@ export class BundlerContext { static bundleAll( contexts: Iterable, - changedFiles?: Iterable, + changedFiles?: Iterable | ReadonlySet, ): Promise { return Promise.all( [...contexts].map((context) => { @@ -482,18 +482,72 @@ export class BundlerContext { * to be stored. * @returns True, if the result was invalidated; False, otherwise. */ - invalidate(files: Iterable): boolean { + invalidate(files: Iterable | ReadonlySet): boolean { if (!this.incremental) { return false; } - let invalid = false; - for (const file of files) { - const normalizedFile = isAbsolute(file) ? normalize(file) : join(this.workspaceRoot, file); + let candidateFiles: ReadonlySet; + if (files instanceof Set) { + let isCandidateReady = true; + for (const file of files) { + if ( + file !== normalize(file) || + (!isAbsolute(file) && !files.has(normalize(join(this.workspaceRoot, file)))) + ) { + isCandidateReady = false; + break; + } + } + + if (isCandidateReady) { + candidateFiles = files; + } else { + const normalizedFiles = new Set(); + for (const file of files) { + const normalized = normalize(file); + normalizedFiles.add(normalized); + if (!isAbsolute(normalized)) { + normalizedFiles.add(normalize(join(this.workspaceRoot, normalized))); + } + } + candidateFiles = normalizedFiles; + } + } else { + const normalizedFiles = new Set(); + for (const file of files) { + const normalized = normalize(file); + normalizedFiles.add(normalized); + if (!isAbsolute(normalized)) { + normalizedFiles.add(normalize(join(this.workspaceRoot, normalized))); + } + } + candidateFiles = normalizedFiles; + } - this.#loadCache?.invalidate(normalizedFile); + let invalid = false; + for (const file of candidateFiles) { + if (this.#loadCache?.invalidate(file)) { + invalid = true; + } + } - invalid ||= this.watchFiles.has(normalizedFile); + if (!invalid) { + if (this.watchFiles.size < candidateFiles.size) { + for (const file of this.watchFiles) { + if (candidateFiles.has(file)) { + invalid = true; + break; + } + } + } else { + for (const file of candidateFiles) { + if (this.watchFiles.has(file)) { + invalid = true; + break; + } + } + } } if (invalid) { diff --git a/packages/angular/build/src/tools/esbuild/bundler-context_spec.ts b/packages/angular/build/src/tools/esbuild/bundler-context_spec.ts new file mode 100644 index 000000000000..213354389122 --- /dev/null +++ b/packages/angular/build/src/tools/esbuild/bundler-context_spec.ts @@ -0,0 +1,113 @@ +/** + * @license + * Copyright Google LLC All Rights Reserved. + * + * Use of this source code is governed by an MIT-style license that can be + * found in the LICENSE file at https://angular.dev/license + */ + +import { BundlerContext } from './bundler-context'; +import { MemoryLoadResultCache } from './load-result-cache'; + +describe('BundlerContext', () => { + describe('invalidate', () => { + it('should return false when incremental is disabled', () => { + const context = new BundlerContext('/workspace', /* incremental */ false, () => ({ + entryPoints: ['main.js'], + })); + context.watchFiles.add('/workspace/src/app.css'); + + expect(context.invalidate(['/workspace/src/app.css'])).toBeFalse(); + }); + + it('should return true when a watch file matches changed files as an array', () => { + const context = new BundlerContext('/workspace', /* incremental */ true, () => ({ + entryPoints: ['main.js'], + })); + context.watchFiles.add('/workspace/src/app.css'); + + expect(context.invalidate(['/workspace/src/app.css'])).toBeTrue(); + }); + + it('should return true when a watch file matches changed files as a ReadonlySet', () => { + const context = new BundlerContext('/workspace', /* incremental */ true, () => ({ + entryPoints: ['main.js'], + })); + context.watchFiles.add('/workspace/src/app.css'); + + const changedSet: ReadonlySet = new Set(['/workspace/src/app.css']); + expect(context.invalidate(changedSet)).toBeTrue(); + }); + + it('should return false when changed files do not intersect with watchFiles', () => { + const context = new BundlerContext('/workspace', /* incremental */ true, () => ({ + entryPoints: ['main.js'], + })); + context.watchFiles.add('/workspace/src/app.css'); + + expect(context.invalidate(['/workspace/src/other.css'])).toBeFalse(); + }); + + it('should correctly handle relative changed file paths', () => { + const context = new BundlerContext('/workspace', /* incremental */ true, () => ({ + entryPoints: ['main.js'], + })); + context.watchFiles.add('/workspace/src/app.css'); + + expect(context.invalidate(['src/app.css'])).toBeTrue(); + }); + + it('should correctly handle relative paths inside a ReadonlySet', () => { + const context = new BundlerContext('/workspace', /* incremental */ true, () => ({ + entryPoints: ['main.js'], + })); + context.watchFiles.add('/workspace/src/app.css'); + + const set: ReadonlySet = new Set(['src/app.css']); + expect(context.invalidate(set)).toBeTrue(); + }); + + it('should invalidate shared load cache when files change', async () => { + const loadCache = new MemoryLoadResultCache(); + await loadCache.put('file:/workspace/src/app.css', { + contents: 'body {}', + loader: 'css', + watchFiles: ['/workspace/src/app.css'], + }); + + const context = new BundlerContext( + '/workspace', + /* incremental */ true, + () => ({ entryPoints: ['main.js'] }), + /* useContext */ false, + /* initialFilter */ undefined, + loadCache, + ); + + expect(loadCache.get('file:/workspace/src/app.css')).toBeDefined(); + expect(context.invalidate(['/workspace/src/app.css'])).toBeTrue(); + expect(loadCache.get('file:/workspace/src/app.css')).toBeUndefined(); + }); + + it('should work when watchFiles is smaller than changed files', () => { + const context = new BundlerContext('/workspace', /* incremental */ true, () => ({ + entryPoints: ['main.js'], + })); + context.watchFiles.add('/workspace/src/file10.css'); + + const changedFiles = Array.from({ length: 100 }, (_, i) => `/workspace/src/file${i}.css`); + expect(context.invalidate(new Set(changedFiles))).toBeTrue(); + }); + + it('should work when changed files is smaller than watchFiles', () => { + const context = new BundlerContext('/workspace', /* incremental */ true, () => ({ + entryPoints: ['main.js'], + })); + for (let i = 0; i < 100; i++) { + context.watchFiles.add(`/workspace/src/file${i}.css`); + } + + expect(context.invalidate(new Set(['/workspace/src/file50.css']))).toBeTrue(); + }); + }); +}); From 11ab5eb79132c699f39b107fb7686c3b0f575542 Mon Sep 17 00:00:00 2001 From: Alan Agius <17563226+alan-agius4@users.noreply.github.com> Date: Tue, 25 Aug 2026 14:28:24 +0000 Subject: [PATCH 343/787] test(@angular/build): ensure hash init in i18n inliner tests The i18n inliner hashes output files which requires the hash utility to be initialized prior to execution. This adds `initializeHash()` to `beforeAll` in `i18n-inliner_spec.ts`. Also removes an unused import in `application-code-bundle.ts`. --- .../build/src/tools/esbuild/application-code-bundle.ts | 1 - packages/angular/build/src/tools/esbuild/i18n-inliner_spec.ts | 4 ++++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/packages/angular/build/src/tools/esbuild/application-code-bundle.ts b/packages/angular/build/src/tools/esbuild/application-code-bundle.ts index 775475f3e0c8..1896ddf2dce3 100644 --- a/packages/angular/build/src/tools/esbuild/application-code-bundle.ts +++ b/packages/angular/build/src/tools/esbuild/application-code-bundle.ts @@ -19,7 +19,6 @@ import { SERVER_APP_MANIFEST_FILENAME, SERVER_GENERATED_EXTERNALS, } from '../../utils/server-rendering/manifest'; -import { AngularCompilation, NoopCompilation } from '../angular/compilation'; import { AngularCompilationContext } from './angular/compilation-state'; import { createCompilerPlugin } from './angular/compiler-plugin'; import { ComponentStylesheetBundler } from './angular/component-stylesheets'; diff --git a/packages/angular/build/src/tools/esbuild/i18n-inliner_spec.ts b/packages/angular/build/src/tools/esbuild/i18n-inliner_spec.ts index 90b9a9779a6d..26baeb592796 100644 --- a/packages/angular/build/src/tools/esbuild/i18n-inliner_spec.ts +++ b/packages/angular/build/src/tools/esbuild/i18n-inliner_spec.ts @@ -56,6 +56,10 @@ describe('I18nInliner', () => { return inliner; } + beforeAll(async () => { + await initializeHash(); + }); + afterEach(async () => { await inliner?.close(); inliner = undefined; From a877aa7ebdbf919d6bc17e6ec0920ca702db0db4 Mon Sep 17 00:00:00 2001 From: Charles Lyding <19598772+clydin@users.noreply.github.com> Date: Mon, 24 Aug 2026 17:17:54 -0400 Subject: [PATCH 344/787] perf(@angular/build): implement SharedArrayBuffer translation dictionaries for zero-copy worker access Translation catalogs are encoded into a contiguous SharedArrayBuffer containing a binary header, sorted index table with lexicographical string keys, and UTF-8 string pool via encodeTranslationToBuffer. Lookups perform zero-copy binary search over shared memory pages with on-demand string decoding through a Proxy wrapper compatible with @angular/localize. I18nInliner and worker tasks prefer SharedArrayBuffer over V8 serialized Blobs for windowed locale translation passing, eliminating Structured Clone heap duplication across worker threads. Serialized Blobs are retained as a fallback for environments such as WebContainers that do not support SharedArrayBuffer. --- .../src/tools/esbuild/i18n-inliner-worker.ts | 45 ++-- .../build/src/tools/esbuild/i18n-inliner.ts | 43 ++-- .../tools/esbuild/i18n-translation-encoder.ts | 109 ++++++++++ .../esbuild/i18n-translation-encoder_spec.ts | 168 +++++++++++++++ .../tools/esbuild/i18n-translation-reader.ts | 193 ++++++++++++++++++ 5 files changed, 525 insertions(+), 33 deletions(-) create mode 100644 packages/angular/build/src/tools/esbuild/i18n-translation-encoder.ts create mode 100644 packages/angular/build/src/tools/esbuild/i18n-translation-encoder_spec.ts create mode 100644 packages/angular/build/src/tools/esbuild/i18n-translation-reader.ts diff --git a/packages/angular/build/src/tools/esbuild/i18n-inliner-worker.ts b/packages/angular/build/src/tools/esbuild/i18n-inliner-worker.ts index a0ca9e25e6f2..0ad9262da354 100644 --- a/packages/angular/build/src/tools/esbuild/i18n-inliner-worker.ts +++ b/packages/angular/build/src/tools/esbuild/i18n-inliner-worker.ts @@ -13,6 +13,7 @@ import assert from 'node:assert'; import { deserialize } from 'node:v8'; import { workerData } from 'node:worker_threads'; import { parseSync, visitorKeys } from 'oxc-parser'; +import { createSharedTranslationProxy } from './i18n-translation-reader'; /** * The options passed to the inliner for each file request @@ -31,10 +32,10 @@ interface InlineFileRequest { /** * The serialized translation messages for the locale that should be used during the inlining - * process of the file. A Blob is used so that the messages are shared with the Worker by - * reference instead of being copied into it for every request. + * process of the file. A SharedArrayBuffer or Blob is used so that the messages are shared with + * the Worker by reference instead of being copied into it for every request. */ - translation?: Blob; + translation?: Blob | SharedArrayBuffer; } /** @@ -58,10 +59,10 @@ interface InlineCodeRequest { /** * The serialized translation messages for the locale that should be used during the inlining - * process of the file. A Blob is used so that the messages are shared with the Worker by - * reference instead of being copied into it for every request. + * process of the file. A SharedArrayBuffer or Blob is used so that the messages are shared with + * the Worker by reference instead of being copied into it for every request. */ - translation?: Blob; + translation?: Blob | SharedArrayBuffer; } /** @@ -77,7 +78,7 @@ interface InlineFileBatchRequest { /** * The locale specifiers or locale objects that should be used during the inlining process of the file. */ - locales: (string | { locale: string; translation?: Blob })[]; + locales: (string | { locale: string; translation?: Blob | SharedArrayBuffer })[]; /** * Whether the file data should be treated as ephemeral and not cached long-term in the Worker. @@ -114,7 +115,7 @@ interface InlineFileBatchResult { const { files, missingTranslation, translations } = (workerData || {}) as { files: ReadonlyMap; missingTranslation: 'error' | 'warning' | 'ignore'; - translations?: ReadonlyMap; + translations?: ReadonlyMap; }; /** @@ -172,30 +173,34 @@ function loadFileData(filename: string, cache = true): Promise { } /** - * Deserializes the translation messages for a locale, reusing the result for any + * Deserializes or wraps the translation messages for a locale, reusing the result for any * subsequent request that targets the same locale. * @param locale The locale identifier. - * @param translation Optional serialized translation messages. If omitted, workerData.translations is used. + * @param translation Optional serialized translation messages (SharedArrayBuffer or Blob). * @returns The translation messages, or undefined if the locale has no translations. */ function loadTranslation( locale: string, - translation?: Blob, + translation?: Blob | SharedArrayBuffer, ): Promise> | undefined { - const translationBlob = translation ?? translations?.get(locale); - if (!translationBlob) { + const translationData = translation ?? translations?.get(locale); + if (!translationData) { return undefined; } let messagesPromise = deserializedTranslations.get(locale); if (!messagesPromise) { - messagesPromise = translationBlob - .arrayBuffer() - .then((buffer) => deserialize(new Uint8Array(buffer)) as Record) - .catch((error) => { - deserializedTranslations.delete(locale); - throw error; - }); + if (translationData instanceof Blob) { + messagesPromise = translationData + .arrayBuffer() + .then((buffer) => deserialize(new Uint8Array(buffer)) as Record) + .catch((error) => { + deserializedTranslations.delete(locale); + throw error; + }); + } else { + messagesPromise = Promise.resolve(createSharedTranslationProxy(translationData)); + } deserializedTranslations.set(locale, messagesPromise); } diff --git a/packages/angular/build/src/tools/esbuild/i18n-inliner.ts b/packages/angular/build/src/tools/esbuild/i18n-inliner.ts index b8ad6cdedcab..41de55de666f 100644 --- a/packages/angular/build/src/tools/esbuild/i18n-inliner.ts +++ b/packages/angular/build/src/tools/esbuild/i18n-inliner.ts @@ -13,6 +13,7 @@ import { calculateHash, createContentHash, initializeHash } from '../../utils/ha import { WorkerPool } from '../../utils/worker-pool'; import { type BuildOutputFile, BuildOutputFileType, createOutputFile } from './bundler-files'; import { type Cache, type PersistentCacheStore, createPersistentCacheStore } from './cache'; +import { encodeTranslationToBuffer } from './i18n-translation-encoder'; /** * A keyword used to indicate if a JavaScript file may require inlining of translations. @@ -29,15 +30,25 @@ const DEFAULT_LOCALE_WINDOW_SIZE = 8; /** * Serializes the translation messages for a locale for transfer to an inliner Worker. * - * A Blob is used because cloning one shares its data by reference, whereas sending the messages - * themselves copies them into a Worker for every request that carries them. A locale can contain - * tens of thousands of messages, which makes that copy the dominant cost of inlining a locale. + * A SharedArrayBuffer is preferred because it enables zero-copy shared memory access + * and on-demand string decoding across all worker threads. Falls back to a Blob when + * SharedArrayBuffer is unavailable. * * @param translation The translation messages for a locale, if the locale has any. - * @returns A Blob containing the serialized messages, or undefined if the locale has none. + * @returns A SharedArrayBuffer or Blob containing the serialized messages, or undefined if none. */ -function serializeTranslation(translation: Record | undefined): Blob | undefined { - return translation && new Blob([serialize(translation)]); +function serializeTranslation( + translation: Record | undefined, +): SharedArrayBuffer | Blob | undefined { + if (!translation) { + return undefined; + } + + if (typeof SharedArrayBuffer !== 'undefined') { + return encodeTranslationToBuffer(translation); + } + + return new Blob([serialize(translation)]); } /** @@ -49,7 +60,7 @@ export interface I18nInlinerOptions { shouldOptimize?: boolean; persistentCachePath?: string; localizeVersion?: string; - translations?: ReadonlyMap; + translations?: ReadonlyMap; } /** @@ -116,6 +127,15 @@ interface CacheCheckItem { cachedResult: Promise; } +/** + * An uncached transformation request entry for a file within a specific locale. + */ +interface UncachedLocaleEntry { + locale: string; + cacheKey?: string; + translation?: Blob | SharedArrayBuffer; +} + /** * A class that performs i18n translation inlining of JavaScript code. * A worker pool is used to distribute the transformation actions and allow @@ -237,7 +257,7 @@ export class I18nInliner { // Pre-calculate cache key bases and serialized Blobs for each locale in this window const localeCacheBases = new Map(); - const localeBlobs = new Map(); + const localeBlobs = new Map(); for (const { locale, translation, translationIntegrity } of windowLocales) { localeBlobs.set(locale, serializeTranslation(translation)); @@ -302,10 +322,7 @@ export class I18nInliner { ); // Group uncached items by filename for this window - const uncachedByFile = new Map< - string, - Array<{ locale: string; cacheKey?: string; translation?: Blob }> - >(); + const uncachedByFile = new Map(); for (const item of resolvedChecks) { if (item.result) { @@ -386,7 +403,7 @@ export class I18nInliner { } async #processUncachedBatches( - uncachedByFile: Map>, + uncachedByFile: Map, localeCount: number, fileResultsByLocale: Map>, activeLocales?: string[], diff --git a/packages/angular/build/src/tools/esbuild/i18n-translation-encoder.ts b/packages/angular/build/src/tools/esbuild/i18n-translation-encoder.ts new file mode 100644 index 000000000000..091d9ba0ff26 --- /dev/null +++ b/packages/angular/build/src/tools/esbuild/i18n-translation-encoder.ts @@ -0,0 +1,109 @@ +/** + * @license + * Copyright Google LLC All Rights Reserved. + * + * Use of this source code is governed by an MIT-style license that can be + * found in the LICENSE file at https://angular.dev/license + */ + +/** + * Magic header identifier for i18n SharedArrayBuffer translation tables ('I18N'). + */ +export const I18N_MAGIC_ID = 0x4931384e; + +/** + * Encodes a JavaScript translation dictionary into a contiguous SharedArrayBuffer. + * The buffer contains a header, a sorted index table (by key for fast O(log N) binary search), + * and a UTF-8 string pool. + * + * @param translation The translation dictionary object. + * @returns A SharedArrayBuffer containing the binary encoded translation catalog. + */ +export function encodeTranslationToBuffer(translation: Record): SharedArrayBuffer { + const encoder = new TextEncoder(); + const entries = Object.entries(translation); + const entryCount = entries.length; + + // Pre-encode string keys and JSON-serialized string values + const encodedEntries: { + keyBytes: Uint8Array; + valBytes: Uint8Array; + }[] = new Array(entryCount); + + let stringPoolByteSize = 0; + + for (let i = 0; i < entryCount; i++) { + const [key, val] = entries[i]; + const keyBytes = encoder.encode(key); + const valBytes = encoder.encode(JSON.stringify(val)); + + encodedEntries[i] = { keyBytes, valBytes }; + stringPoolByteSize += keyBytes.byteLength + valBytes.byteLength; + } + + // Sort entries lexicographically by UTF-8 byte comparison. + // Lexicographical byte comparison matches the binary search reader's byte comparison, + // ensuring deterministic and zero-allocation lookups across all runtimes regardless of UTF-16 surrogate pairs. + encodedEntries.sort((a, b) => { + const aBytes = a.keyBytes; + const bBytes = b.keyBytes; + const minLen = Math.min(aBytes.length, bBytes.length); + + for (let i = 0; i < minLen; i++) { + const diff = aBytes[i] - bBytes[i]; + if (diff !== 0) { + return diff; + } + } + + return aBytes.length - bBytes.length; + }); + + const indexByteSize = entryCount * 16; + const headerByteSize = 16; + const stringPoolOffset = headerByteSize + indexByteSize; + + const totalByteSize = stringPoolOffset + stringPoolByteSize; + const buffer = new SharedArrayBuffer(totalByteSize); + + // Set up views over the SharedArrayBuffer + const uint32Header = new Uint32Array(buffer, 0, 4); + const uint32Index = new Uint32Array(buffer, headerByteSize, entryCount * 4); + const uint8Pool = new Uint8Array(buffer, stringPoolOffset); + + // Write Header: Magic, EntryCount, IndexOffset, StringPoolOffset + uint32Header[0] = I18N_MAGIC_ID; + uint32Header[1] = entryCount; + uint32Header[2] = headerByteSize; + uint32Header[3] = stringPoolOffset; + + // Write Index Table and String Pool entries + let currentPoolOffset = 0; + + for (let i = 0; i < entryCount; i++) { + const { keyBytes, valBytes } = encodedEntries[i]; + + const keyOffset = currentPoolOffset; + const keyLen = keyBytes.byteLength; + uint8Pool.set(keyBytes, keyOffset); + currentPoolOffset += keyLen; + + const valOffset = currentPoolOffset; + const valLen = valBytes.byteLength; + uint8Pool.set(valBytes, valOffset); + currentPoolOffset += valLen; + + // Index entry format (4 uint32 words / 16 bytes): + // [0]: keyOffset (uint32) + // [1]: keyLength (uint32) + // [2]: valOffset (uint32) + // [3]: valLength (uint32) + const idx = i * 4; + uint32Index[idx] = keyOffset; + uint32Index[idx + 1] = keyLen; + uint32Index[idx + 2] = valOffset; + uint32Index[idx + 3] = valLen; + } + + return buffer; +} diff --git a/packages/angular/build/src/tools/esbuild/i18n-translation-encoder_spec.ts b/packages/angular/build/src/tools/esbuild/i18n-translation-encoder_spec.ts new file mode 100644 index 000000000000..c3b6409d40b5 --- /dev/null +++ b/packages/angular/build/src/tools/esbuild/i18n-translation-encoder_spec.ts @@ -0,0 +1,168 @@ +/** + * @license + * Copyright Google LLC All Rights Reserved. + * + * Use of this source code is governed by an MIT-style license that can be + * found in the LICENSE file at https://angular.dev/license + */ + +import { encodeTranslationToBuffer } from './i18n-translation-encoder'; +import { + SharedTranslationDictionary, + createSharedTranslationProxy, +} from './i18n-translation-reader'; + +describe('SharedArrayBuffer Translation Encoder & Reader', () => { + it('encodes and reads simple key-value translations', () => { + const translation = { + greeting: 'Hello', + farewell: 'Goodbye', + numberKey: 42, + arrayKey: ['part1', 'part2'], + }; + + const buffer = encodeTranslationToBuffer(translation); + const dictionary = new SharedTranslationDictionary(buffer); + + expect(dictionary.get('greeting')).toEqual('Hello'); + expect(dictionary.get('farewell')).toEqual('Goodbye'); + expect(dictionary.get('numberKey')).toEqual(42); + expect(dictionary.get('arrayKey')).toEqual(['part1', 'part2']); + expect(dictionary.get('nonexistent')).toBeUndefined(); + }); + + it('works with Proxy wrapper and "in" operator', () => { + const translation = { + msg1: 'Message 1', + msg2: 'Message 2', + }; + + const buffer = encodeTranslationToBuffer(translation); + const proxy = createSharedTranslationProxy(buffer); + + expect(proxy['msg1']).toEqual('Message 1'); + expect(proxy['msg2']).toEqual('Message 2'); + expect(proxy['unknown']).toBeUndefined(); + expect('msg1' in proxy).toBeTrue(); + expect('msg2' in proxy).toBeTrue(); + expect('unknown' in proxy).toBeFalse(); + }); + + it('supports Object.prototype.hasOwnProperty and Object.getOwnPropertyDescriptor on Proxy', () => { + const translation = { + msg1: 'Message 1', + }; + + const buffer = encodeTranslationToBuffer(translation); + const proxy = createSharedTranslationProxy(buffer); + + expect(Object.prototype.hasOwnProperty.call(proxy, 'msg1')).toBeTrue(); + expect(Object.prototype.hasOwnProperty.call(proxy, 'unknown')).toBeFalse(); + + const desc = Object.getOwnPropertyDescriptor(proxy, 'msg1'); + expect(desc).toBeDefined(); + expect(desc?.value).toEqual('Message 1'); + expect(desc?.enumerable).toBeTrue(); + + const missingDesc = Object.getOwnPropertyDescriptor(proxy, 'unknown'); + expect(missingDesc).toBeUndefined(); + + // Verify standard Object.prototype methods work and don't throw + expect(typeof proxy.toString).toBe('function'); + expect(proxy.toString()).toEqual('[object Object]'); + expect(typeof proxy.valueOf).toBe('function'); + expect('toString' in proxy).toBeTrue(); + expect(String(proxy)).toEqual('[object Object]'); + }); + + it('handles non-BMP Unicode surrogate pairs and high BMP keys correctly', () => { + const translation = { + '😀': 'emoji message', + '\uE000': 'uE000 message', + 'abc': 'abc message', + }; + + const buffer = encodeTranslationToBuffer(translation); + const dictionary = new SharedTranslationDictionary(buffer); + + expect(dictionary.get('😀')).toEqual('emoji message'); + expect(dictionary.get('\uE000')).toEqual('uE000 message'); + expect(dictionary.get('abc')).toEqual('abc message'); + }); + + it('handles empty translation dictionaries', () => { + const buffer = encodeTranslationToBuffer({}); + const dictionary = new SharedTranslationDictionary(buffer); + + expect(dictionary.get('anyKey')).toBeUndefined(); + }); + + it('caches missing translation lookups efficiently', () => { + const translation = { + msg1: 'Message 1', + }; + + const buffer = encodeTranslationToBuffer(translation); + const dictionary = new SharedTranslationDictionary(buffer); + + // First lookup for missing key + expect(dictionary.get('missingKey')).toBeUndefined(); + // Second lookup for missing key (should hit lazyCache NOT_FOUND sentinel) + expect(dictionary.get('missingKey')).toBeUndefined(); + }); + + it('validates header size and offsets on initialization', () => { + // Buffer too small + const smallSab = new SharedArrayBuffer(8); + expect(() => new SharedTranslationDictionary(smallSab)).toThrowError( + 'Invalid SharedArrayBuffer translation header: buffer too small.', + ); + + // Invalid magic header + const badMagicSab = new SharedArrayBuffer(16); + expect(() => new SharedTranslationDictionary(badMagicSab)).toThrowError( + 'Invalid SharedArrayBuffer translation header magic identifier.', + ); + + // Out-of-bounds offset values + const invalidOffsetsSab = new SharedArrayBuffer(16); + const view = new Uint32Array(invalidOffsetsSab); + view[0] = 0x4931384e; // I18N_MAGIC_ID + view[1] = 100; // entryCount = 100 entries requiring 1600 bytes + view[2] = 16; + view[3] = 16; + expect(() => new SharedTranslationDictionary(invalidOffsetsSab)).toThrowError( + 'Invalid SharedArrayBuffer translation header offsets.', + ); + + // Unaligned header size + const unalignedHeaderSab = new SharedArrayBuffer(32); + const unalignedView = new Uint32Array(unalignedHeaderSab); + unalignedView[0] = 0x4931384e; + unalignedView[1] = 0; + unalignedView[2] = 17; // unaligned header byte size + unalignedView[3] = 17; + expect(() => new SharedTranslationDictionary(unalignedHeaderSab)).toThrowError( + 'Invalid SharedArrayBuffer translation header offsets.', + ); + }); + + it('safely handles corrupted index offsets within a valid header', () => { + // 1 entry: header (16 bytes) + index (16 bytes) + pool (10 bytes) = 42 bytes + const buffer = new SharedArrayBuffer(48); + const uint32 = new Uint32Array(buffer); + uint32[0] = 0x4931384e; // Magic + uint32[1] = 1; // 1 entry + uint32[2] = 16; // header size + uint32[3] = 32; // string pool offset + + // Corrupted entry: keyOffset points past pool length + uint32[4] = 100; // keyOffset = 100 + uint32[5] = 5; // keyLen = 5 + uint32[6] = 0; // valOffset = 0 + uint32[7] = 5; // valLen = 5 + + const dictionary = new SharedTranslationDictionary(buffer); + expect(dictionary.get('testKey')).toBeUndefined(); + }); +}); diff --git a/packages/angular/build/src/tools/esbuild/i18n-translation-reader.ts b/packages/angular/build/src/tools/esbuild/i18n-translation-reader.ts new file mode 100644 index 000000000000..bc87633da5dc --- /dev/null +++ b/packages/angular/build/src/tools/esbuild/i18n-translation-reader.ts @@ -0,0 +1,193 @@ +/** + * @license + * Copyright Google LLC All Rights Reserved. + * + * Use of this source code is governed by an MIT-style license that can be + * found in the LICENSE file at https://angular.dev/license + */ + +import { I18N_MAGIC_ID } from './i18n-translation-encoder'; + +/** + * Sentinel value used to cache non-existent message key lookups in lazyCache. + */ +const NOT_FOUND = Symbol('NOT_FOUND'); + +/** + * Compares a target key's UTF-8 byte array against a byte sequence in the string pool. + * Lexicographical byte comparison of UTF-8 sequences matches UTF-16 code-unit string comparison + * used when encoding the sorted index table. + */ +function compareBytes( + target: Uint8Array, + pool: Uint8Array, + poolOffset: number, + keyLen: number, +): number { + if (poolOffset < 0 || poolOffset + keyLen > pool.length) { + return 1; + } + + const minLen = Math.min(target.length, keyLen); + for (let i = 0; i < minLen; i++) { + const diff = target[i] - pool[poolOffset + i]; + if (diff !== 0) { + return diff; + } + } + + return target.length - keyLen; +} + +/** + * A zero-copy reader that queries translation messages directly from a SharedArrayBuffer + * using binary search over a sorted key index. + */ +export class SharedTranslationDictionary { + private readonly entryCount: number; + private readonly uint32Index: Uint32Array; + private readonly uint8Pool: Uint8Array; + private readonly decoder = new TextDecoder(); + private readonly encoder = new TextEncoder(); + private readonly lazyCache = new Map(); + + constructor(buffer: SharedArrayBuffer) { + if (buffer.byteLength < 16) { + throw new Error('Invalid SharedArrayBuffer translation header: buffer too small.'); + } + + const uint32Header = new Uint32Array(buffer, 0, 4); + if (uint32Header[0] !== I18N_MAGIC_ID) { + throw new Error('Invalid SharedArrayBuffer translation header magic identifier.'); + } + + this.entryCount = uint32Header[1]; + const headerByteSize = uint32Header[2]; + const stringPoolOffset = uint32Header[3]; + + if ( + headerByteSize < 16 || + headerByteSize % 4 !== 0 || + headerByteSize + this.entryCount * 16 > buffer.byteLength || + stringPoolOffset < headerByteSize + this.entryCount * 16 || + stringPoolOffset > buffer.byteLength + ) { + throw new Error('Invalid SharedArrayBuffer translation header offsets.'); + } + + this.uint32Index = new Uint32Array(buffer, headerByteSize, this.entryCount * 4); + this.uint8Pool = new Uint8Array(buffer, stringPoolOffset); + } + + /** + * Looks up a translation message by key. + * Performs a binary search over the index table if not previously cached in the lazy cache. + * + * @param targetKey The message key ID to search for. + * @returns The parsed translation message, or undefined if not found. + */ + get(targetKey: string): unknown | undefined { + const cached = this.lazyCache.get(targetKey); + if (cached !== undefined) { + return cached === NOT_FOUND ? undefined : cached; + } + + const targetBytes = this.encoder.encode(targetKey); + let low = 0; + let high = this.entryCount - 1; + + while (low <= high) { + const mid = (low + high) >>> 1; + const idx = mid * 4; + + const keyOffset = this.uint32Index[idx]; + const keyLen = this.uint32Index[idx + 1]; + + const cmp = compareBytes(targetBytes, this.uint8Pool, keyOffset, keyLen); + if (cmp === 0) { + const valOffset = this.uint32Index[idx + 2]; + const valLen = this.uint32Index[idx + 3]; + if (valOffset < 0 || valOffset + valLen > this.uint8Pool.length) { + this.lazyCache.set(targetKey, NOT_FOUND); + + return undefined; + } + + const valBytes = this.uint8Pool.subarray(valOffset, valOffset + valLen); + const valJson = this.decoder.decode(valBytes); + + try { + const val = JSON.parse(valJson); + this.lazyCache.set(targetKey, val); + + return val; + } catch { + this.lazyCache.set(targetKey, NOT_FOUND); + + return undefined; + } + } else if (cmp < 0) { + high = mid - 1; + } else { + low = mid + 1; + } + } + + this.lazyCache.set(targetKey, NOT_FOUND); + + return undefined; + } +} + +/** + * Creates a JavaScript object Proxy wrapping a SharedTranslationDictionary so it can be passed + * directly to `@angular/localize` inliner functions as a standard translation Record. + * + * Traps `get`, `has`, and `getOwnPropertyDescriptor` to fulfill all `@angular/localize` `translate()` + * lookup requirements (`translations[id]`, `translations[legacyId]`, `Object.hasOwn(translations, id)`). + * The `ownKeys` trap is intentionally omitted so keys are not eagerly decoded upfront upon reflection. + * + * @param buffer The SharedArrayBuffer containing binary encoded translation catalog. + * @returns A Proxy object that intercepts property reads and queries the SharedTranslationDictionary. + */ +export function createSharedTranslationProxy(buffer: SharedArrayBuffer): Record { + const dictionary = new SharedTranslationDictionary(buffer); + + return new Proxy( + {}, + { + get(target, prop: string | symbol) { + if (typeof prop === 'string') { + const value = dictionary.get(prop); + if (value !== undefined) { + return value; + } + } + + return Reflect.get(target, prop); + }, + has(target, prop: string | symbol) { + if (typeof prop === 'string' && dictionary.get(prop) !== undefined) { + return true; + } + + return Reflect.has(target, prop); + }, + getOwnPropertyDescriptor(target, prop: string | symbol) { + if (typeof prop === 'string') { + const val = dictionary.get(prop); + if (val !== undefined) { + return { + enumerable: true, + configurable: true, + writable: false, + value: val, + }; + } + } + + return Reflect.getOwnPropertyDescriptor(target, prop); + }, + }, + ); +} From 89cc6b3ab80e009d746397a2d3c1fc63d236f8db Mon Sep 17 00:00:00 2001 From: Charles Lyding <19598772+clydin@users.noreply.github.com> Date: Tue, 25 Aug 2026 15:09:31 -0400 Subject: [PATCH 345/787] refactor(@angular/build): optimize i18n locale polyfill data bundling per locale Inject global Angular locale data scripts on-demand into each locale's polyfill bundle during inlining instead of bundling all active locale datasets into a single shared polyfill output file. The `loadLocaleData` utility resolves and caches `@angular/common/locales/global` data per locale. During inlining, `i18n-inliner-worker` injects the specific locale data script alongside `___NG_LOCALE_INSERT___` in the polyfill bundle. This eliminates cross-locale bundle bloat so users download only the exact locale data needed for their targeted locale. --- .../tools/esbuild/application-code-bundle.ts | 12 +- .../src/tools/esbuild/i18n-inliner-worker.ts | 19 +- .../src/tools/esbuild/i18n-inliner_spec.ts | 92 +++++++ .../src/tools/esbuild/i18n-locale-plugin.ts | 249 ++++++++++-------- 4 files changed, 255 insertions(+), 117 deletions(-) diff --git a/packages/angular/build/src/tools/esbuild/application-code-bundle.ts b/packages/angular/build/src/tools/esbuild/application-code-bundle.ts index 1896ddf2dce3..afb03d436d29 100644 --- a/packages/angular/build/src/tools/esbuild/application-code-bundle.ts +++ b/packages/angular/build/src/tools/esbuild/application-code-bundle.ts @@ -697,20 +697,12 @@ function getEsBuildCommonPolyfillsOptions( } // Add Angular's global locale data if i18n options are present. - // Locale data should go first so that project provided polyfill code can augment if needed. let needLocaleDataPlugin = false; if (i18nOptions.shouldInline) { // Remove localize polyfill when i18n inline transformation have been applied to all the packages. polyfills = polyfills.filter((path) => !path.startsWith('@angular/localize')); - - // Add locale data for all active locales - // TODO: Inject each individually within the inlining process itself - for (const locale of i18nOptions.inlineLocales) { - polyfills.unshift(`angular:locale/data:${locale}`); - } - needLocaleDataPlugin = true; } else if (i18nOptions.hasDefinedSourceLocale) { - // When not inlining and a source local is present, use the source locale data directly + // When not inlining and a source locale is present, use the source locale data directly polyfills.unshift(`angular:locale/data:${i18nOptions.sourceLocale}`); needLocaleDataPlugin = true; } @@ -718,7 +710,7 @@ function getEsBuildCommonPolyfillsOptions( buildOptions.plugins.unshift(createAngularLocaleDataPlugin()); } - if (polyfills.length === 0) { + if (polyfills.length === 0 && !i18nOptions.shouldInline && !i18nOptions.hasDefinedSourceLocale) { return; } diff --git a/packages/angular/build/src/tools/esbuild/i18n-inliner-worker.ts b/packages/angular/build/src/tools/esbuild/i18n-inliner-worker.ts index 0ad9262da354..af9d9dce134b 100644 --- a/packages/angular/build/src/tools/esbuild/i18n-inliner-worker.ts +++ b/packages/angular/build/src/tools/esbuild/i18n-inliner-worker.ts @@ -13,6 +13,7 @@ import assert from 'node:assert'; import { deserialize } from 'node:v8'; import { workerData } from 'node:worker_threads'; import { parseSync, visitorKeys } from 'oxc-parser'; +import { loadLocaleData } from './i18n-locale-plugin'; import { createSharedTranslationProxy } from './i18n-translation-reader'; /** @@ -502,8 +503,22 @@ async function inlineLocalize( } } - for (const site of metadata.localeInsertSites) { - magicString.overwrite(site.start, site.end, JSON.stringify(locale)); + if (metadata.localeInsertSites.length > 0) { + const localeData = await loadLocaleData(locale); + if (localeData.error) { + diagnostics.error(localeData.error); + } else if (localeData.warning) { + diagnostics.warn(localeData.warning); + } + let injected = false; + for (const site of metadata.localeInsertSites) { + magicString.overwrite( + site.start, + site.end, + JSON.stringify(locale) + (localeData.code && !injected ? `;\n${localeData.code}\n;` : ''), + ); + injected = true; + } } for (const callSite of metadata.callSites) { diff --git a/packages/angular/build/src/tools/esbuild/i18n-inliner_spec.ts b/packages/angular/build/src/tools/esbuild/i18n-inliner_spec.ts index 26baeb592796..46d1cb4145d4 100644 --- a/packages/angular/build/src/tools/esbuild/i18n-inliner_spec.ts +++ b/packages/angular/build/src/tools/esbuild/i18n-inliner_spec.ts @@ -544,4 +544,96 @@ describe('I18nInliner', () => { expect(findFile(localeResult?.outputFiles ?? [], 'main.js').text).toContain(`"Hello ${i}"`); } }); + + it('injects locale data alongside ___NG_LOCALE_INSERT___ for non-English locales', async () => { + const source = `(globalThis.$localize ??= {}).locale = "___NG_LOCALE_INSERT___";\n${GREETING_SOURCE}`; + const localeInliner = createInliner([browserFile('polyfills.js', source)]); + + const results = await localeInliner.inlineAll([ + { locale: 'fr', translation: { greeting: translationFor('Bonjour') } }, + { locale: 'en-US', translation: undefined }, + ]); + + const fr = results.get('fr'); + expect(fr?.errors).toEqual([]); + const frPolyfills = findFile(fr?.outputFiles ?? [], 'polyfills.js').text; + expect(frPolyfills).toContain('(globalThis.$localize ??= {}).locale = "fr";'); + expect(frPolyfills).toContain('ng.common.locales'); + + const en = results.get('en-US'); + expect(en?.errors).toEqual([]); + const enPolyfills = findFile(en?.outputFiles ?? [], 'polyfills.js').text; + expect(enPolyfills).toContain('(globalThis.$localize ??= {}).locale = "en-US";'); + expect(enPolyfills).not.toContain('ng.common.locales'); + }); + + it('warns and uses parent locale data when a subtag locale is not directly available', async () => { + const source = `(globalThis.$localize ??= {}).locale = "___NG_LOCALE_INSERT___";\n${GREETING_SOURCE}`; + const localeInliner = createInliner([browserFile('polyfills.js', source)]); + + const results = await localeInliner.inlineAll([ + { locale: 'fr-ZZ', translation: { greeting: translationFor('Bonjour') } }, + ]); + + const frZZ = results.get('fr-ZZ'); + expect(frZZ?.errors).toEqual([]); + expect(frZZ?.warnings).toEqual([ + "Locale data for 'fr-ZZ' cannot be found. Using locale data for 'fr'.", + ]); + const polyfills = findFile(frZZ?.outputFiles ?? [], 'polyfills.js').text; + expect(polyfills).toContain('(globalThis.$localize ??= {}).locale = "fr-ZZ";'); + expect(polyfills).toContain('ng.common.locales'); + }); + + it('warns and includes no locale data when locale data cannot be found', async () => { + const source = `(globalThis.$localize ??= {}).locale = "___NG_LOCALE_INSERT___";\n${GREETING_SOURCE}`; + const localeInliner = createInliner([browserFile('polyfills.js', source)]); + + const results = await localeInliner.inlineAll([ + { locale: 'xx-YY', translation: { greeting: translationFor('Test') } }, + ]); + + const xxYY = results.get('xx-YY'); + expect(xxYY?.errors).toEqual([]); + expect(xxYY?.warnings).toEqual([ + "Locale data for 'xx-YY' cannot be found. No locale data will be included for this locale.", + ]); + const polyfills = findFile(xxYY?.outputFiles ?? [], 'polyfills.js').text; + expect(polyfills).toContain('(globalThis.$localize ??= {}).locale = "xx-YY";'); + expect(polyfills).not.toContain('ng.common.locales'); + }); + + it('reports an error diagnostic when an invalid or unsupported locale is provided', async () => { + const source = `(globalThis.$localize ??= {}).locale = "___NG_LOCALE_INSERT___";\n${GREETING_SOURCE}`; + const localeInliner = createInliner([browserFile('polyfills.js', source)]); + + const results = await localeInliner.inlineAll([ + { locale: 'invalid locale tag', translation: { greeting: translationFor('Test') } }, + ]); + + const invalid = results.get('invalid locale tag'); + expect(invalid?.errors).toEqual([ + 'Invalid or unsupported locale provided in configuration: "invalid locale tag"', + ]); + }); + + it('injects locale data script only once when multiple ___NG_LOCALE_INSERT___ sites are present', async () => { + const source = + `(globalThis.$localize ??= {}).locale = "___NG_LOCALE_INSERT___";\n` + + `const secondary = "___NG_LOCALE_INSERT___";\n${GREETING_SOURCE}`; + const localeInliner = createInliner([browserFile('polyfills.js', source)]); + + const results = await localeInliner.inlineAll([ + { locale: 'fr', translation: { greeting: translationFor('Bonjour') } }, + ]); + + const fr = results.get('fr'); + expect(fr?.errors).toEqual([]); + const frPolyfills = findFile(fr?.outputFiles ?? [], 'polyfills.js').text; + expect(frPolyfills).toContain('(globalThis.$localize ??= {}).locale = "fr";'); + expect(frPolyfills).toContain('const secondary = "fr";'); + + const iifeMatches = frPolyfills.match(/function\s*\(global/g); + expect(iifeMatches?.length).toBe(1); + }); }); diff --git a/packages/angular/build/src/tools/esbuild/i18n-locale-plugin.ts b/packages/angular/build/src/tools/esbuild/i18n-locale-plugin.ts index 603c65677b00..8ffddf19adb7 100644 --- a/packages/angular/build/src/tools/esbuild/i18n-locale-plugin.ts +++ b/packages/angular/build/src/tools/esbuild/i18n-locale-plugin.ts @@ -6,7 +6,8 @@ * found in the LICENSE file at https://angular.dev/license */ -import type { Plugin, ResolveResult } from 'esbuild'; +import type { Plugin } from 'esbuild'; +import { readFile } from 'node:fs/promises'; import { createProjectResolver } from '../../utils/resolve-project'; /** @@ -19,6 +20,124 @@ export const LOCALE_DATA_NAMESPACE = 'angular:locale/data'; */ export const LOCALE_DATA_BASE_MODULE = '@angular/common/locales/global'; +/** + * Result of resolving locale data for a given locale tag. + */ +export interface LocaleDataResolution { + path?: string; + warning?: string; + error?: string; +} + +/** + * Result of loading locale data for a given locale tag. + */ +export interface LoadedLocaleData { + code?: string; + warning?: string; + error?: string; +} + +const localeDataCache = new Map>(); + +/** + * Resolves the path to the Angular locale data file for a given locale tag. + * + * @param rawLocaleTag The raw locale identifier (e.g. "fr-CA", "de", "en-US"). + * @param projectResolve A function that attempts to resolve a path string to an absolute file path. + * @returns Resolution result with file path, or warning/error diagnostics if applicable. + */ +export function resolveLocaleDataPath( + rawLocaleTag: string, + projectResolve: (potentialPath: string) => string | undefined, +): LocaleDataResolution { + let partialLocaleTag: string; + try { + const locale = new Intl.Locale(rawLocaleTag); + partialLocaleTag = locale.baseName; + } catch { + return { + error: `Invalid or unsupported locale provided in configuration: "${rawLocaleTag}"`, + }; + } + + let exact = true; + while (partialLocaleTag) { + // Angular embeds the `en`/`en-US` locale into the framework and it does not need to be included again here. + if (partialLocaleTag === 'en' || partialLocaleTag === 'en-US') { + return {}; + } + + const potentialPath = `${LOCALE_DATA_BASE_MODULE}/${partialLocaleTag}`; + try { + const resolvedPath = projectResolve(potentialPath); + if (resolvedPath) { + return { + path: resolvedPath, + warning: exact + ? undefined + : `Locale data for '${rawLocaleTag}' cannot be found. Using locale data for '${partialLocaleTag}'.`, + }; + } + } catch {} + + // Remove the last subtag and try again with a less specific locale. + const parts = partialLocaleTag.split('-'); + partialLocaleTag = parts.slice(0, -1).join('-'); + exact = false; + } + + return { + warning: `Locale data for '${rawLocaleTag}' cannot be found. No locale data will be included for this locale.`, + }; +} + +/** + * Loads the Angular global locale data script for a specified locale tag. + * + * @param rawLocaleTag The raw locale identifier (e.g. "fr-CA", "de", "en-US"). + * @param projectRoot Optional project root for module resolution. + * @returns A promise resolving to the loaded locale data script code and any diagnostic warnings. + */ +export function loadLocaleData( + rawLocaleTag: string, + projectRoot?: string, +): Promise { + let cached = localeDataCache.get(rawLocaleTag); + if (!cached) { + cached = (async () => { + const projectResolve = createProjectResolver(projectRoot ?? process.cwd()); + const resolution = resolveLocaleDataPath(rawLocaleTag, (potentialPath) => { + try { + return projectResolve(potentialPath); + } catch { + return undefined; + } + }); + + if (resolution.error) { + return { error: resolution.error }; + } + + if (resolution.path) { + try { + const code = await readFile(resolution.path, 'utf8'); + + return { code, warning: resolution.warning }; + } catch (e) { + return { error: `Failed to read locale data file: ${(e as Error).message}` }; + } + } + + return { warning: resolution.warning }; + })(); + + localeDataCache.set(rawLocaleTag, cached); + } + + return cached; +} + /** * Creates an esbuild plugin that resolves Angular locale data files from `@angular/common`. * @@ -29,124 +148,44 @@ export function createAngularLocaleDataPlugin(): Plugin { name: 'angular-locale-data', setup(build): void { build.onResolve({ filter: /^angular:locale\/data:/ }, async ({ path }) => { - // Extract the locale from the path const rawLocaleTag = path.split(':', 3)[2]; + const { absWorkingDir } = build.initialOptions; + let projectResolve: ((packageName: string) => string) | undefined; - // Extract and normalize the base name of the raw locale tag - let partialLocaleTag: string; - try { - const locale = new Intl.Locale(rawLocaleTag); - partialLocaleTag = locale.baseName; - } catch { + const resolution = resolveLocaleDataPath(rawLocaleTag, (potentialPath) => { + projectResolve ??= createProjectResolver(absWorkingDir ?? process.cwd()); + try { + return projectResolve(potentialPath); + } catch { + return undefined; + } + }); + + if (resolution.error) { return { path: rawLocaleTag, namespace: LOCALE_DATA_NAMESPACE, - errors: [ - { - text: `Invalid or unsupported locale provided in configuration: "${rawLocaleTag}"`, - }, - ], + errors: [{ text: resolution.error }], }; } - let exact = true; - let projectResolve: ((packageName: string) => string) | undefined; - while (partialLocaleTag) { - // Angular embeds the `en`/`en-US` locale into the framework and it does not need to be included again here. - // The onLoad hook below for the locale data namespace has an `empty` loader that will prevent inclusion. - // Angular does not contain exact locale data for `en-US` but `en` is equivalent. - if (partialLocaleTag === 'en' || partialLocaleTag === 'en-US') { - return { - path: rawLocaleTag, - namespace: LOCALE_DATA_NAMESPACE, - }; - } - - // Attempt to resolve the locale tag data within the Angular base module location - const potentialPath = `${LOCALE_DATA_BASE_MODULE}/${partialLocaleTag}`; - - // If packages are configured to be external then leave the original angular locale import path. - // This happens when using the development server with caching enabled to allow Vite prebundling to work. - // There currently is no option on the esbuild resolve function to resolve while disabling the option. - // NOTE: If esbuild eventually allows controlling the external package options in a build.resolve call, this - // workaround can be removed. - let result: ResolveResult | undefined; - const { packages, absWorkingDir } = build.initialOptions; - if (packages === 'external' && absWorkingDir) { - projectResolve ??= createProjectResolver(absWorkingDir); - - try { - projectResolve(potentialPath); - - result = { - errors: [], - warnings: [], - external: true, - sideEffects: true, - namespace: '', - suffix: '', - pluginData: undefined, - path: potentialPath, - }; - } catch {} - } else { - result = await build.resolve(potentialPath, { - kind: 'import-statement', - resolveDir: absWorkingDir, - }); - if (result && result.external && absWorkingDir) { - projectResolve ??= createProjectResolver(absWorkingDir); - try { - const resolvedPath = projectResolve(potentialPath); - result = { - ...result, - external: false, - path: resolvedPath, - }; - } catch {} - } - } - - if (result?.path) { - if (exact) { - return result; - } else { - return { - ...result, - warnings: [ - ...result.warnings, - { - location: null, - text: `Locale data for '${rawLocaleTag}' cannot be found. Using locale data for '${partialLocaleTag}'.`, - }, - ], - }; - } - } - - // Remove the last subtag and try again with a less specific locale. - // Usually the match is exact so the string splitting here is not done until actually needed after the exact - // match fails to resolve. - const parts = partialLocaleTag.split('-'); - partialLocaleTag = parts.slice(0, -1).join('-'); - exact = false; + if (!resolution.path) { + return { + path: rawLocaleTag, + namespace: LOCALE_DATA_NAMESPACE, + warnings: resolution.warning + ? [{ location: null, text: resolution.warning }] + : undefined, + }; } - // Not found so issue a warning and use an empty loader. Framework built-in `en-US` data will be used. - // This retains existing behavior as in the Webpack-based builder. return { - path: rawLocaleTag, - namespace: LOCALE_DATA_NAMESPACE, - warnings: [ - { - location: null, - text: `Locale data for '${rawLocaleTag}' cannot be found. No locale data will be included for this locale.`, - }, - ], + path: resolution.path, + warnings: resolution.warning ? [{ location: null, text: resolution.warning }] : undefined, }; }); - // Locales that cannot be found will be loaded as empty content with a warning from the resolve step + // Locales that cannot be found or are en/en-US will be loaded as empty content build.onLoad({ filter: /./, namespace: LOCALE_DATA_NAMESPACE }, () => ({ contents: '', loader: 'empty', From ca982a255d894395ed1d834a03d56ed9d2a2c4ef Mon Sep 17 00:00:00 2001 From: Angular Robot Date: Wed, 26 Aug 2026 06:01:48 +0000 Subject: [PATCH 346/787] build: update pnpm to v11.24.0 See associated pull request for more information. --- MODULE.bazel | 4 ++-- package.json | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/MODULE.bazel b/MODULE.bazel index 9bfc8c1b806d..df0fc81009a6 100644 --- a/MODULE.bazel +++ b/MODULE.bazel @@ -131,8 +131,8 @@ use_repo( pnpm = use_extension("@aspect_rules_js//npm:extensions.bzl", "pnpm") pnpm.pnpm( name = "pnpm", - pnpm_version = "11.22.0", - pnpm_version_integrity = "sha512-H/hwxMYTPf2I+yr8Rt0T1H8JyXlLQ4xv20fKmMrzvBY4HuC+k6CRuOOCTPAfiJ9G19niCRD7C+GrD7W6qA3WIQ==", + pnpm_version = "11.24.0", + pnpm_version_integrity = "sha512-vSfjRel23LC+C3oSKCF7BJqBfiGx81XJDb59xGZxiVqLwebQbCRVRQXqk+oLRfSJon7Bv7yN5qlln8oPFvoAAA==", ) use_repo(pnpm, "pnpm") diff --git a/package.json b/package.json index df3a9c868816..a33875337f4b 100644 --- a/package.json +++ b/package.json @@ -28,12 +28,12 @@ "type": "git", "url": "git+https://github.com/angular/angular-cli.git" }, - "packageManager": "pnpm@11.22.0", + "packageManager": "pnpm@11.24.0", "engines": { "node": "^22.22.3 || ^24.15.0 || >=26.0.0", "npm": "Please use pnpm instead of NPM to install dependencies", "yarn": "Please use pnpm instead of Yarn to install dependencies", - "pnpm": "11.22.0" + "pnpm": "11.24.0" }, "author": "Angular Authors", "license": "MIT", From cf4cd2e25b1fe3cc3e4384e0f4db1d9c73ec42ee Mon Sep 17 00:00:00 2001 From: Angular Robot Date: Wed, 26 Aug 2026 06:33:13 +0000 Subject: [PATCH 347/787] build: update cross-repo angular dependencies See associated pull request for more information. --- .../assistant-to-the-branch-manager.yml | 2 +- .github/workflows/ci.yml | 52 +++++++++---------- .github/workflows/dev-infra.yml | 6 +-- .github/workflows/perf.yml | 6 +-- .github/workflows/pr.yml | 44 ++++++++-------- MODULE.bazel | 6 +-- tests/e2e/ng-snapshot/package.json | 32 ++++++------ 7 files changed, 74 insertions(+), 74 deletions(-) diff --git a/.github/workflows/assistant-to-the-branch-manager.yml b/.github/workflows/assistant-to-the-branch-manager.yml index 7bcd8eaa270d..9147cb3a65b8 100644 --- a/.github/workflows/assistant-to-the-branch-manager.yml +++ b/.github/workflows/assistant-to-the-branch-manager.yml @@ -18,6 +18,6 @@ jobs: - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: persist-credentials: false - - uses: angular/dev-infra/github-actions/branch-manager@6d918a6dd670e28afd4ba54d00b805d4aba43dca # main + - uses: angular/dev-infra/github-actions/branch-manager@e713eca55b2813448af42f2e0e752258e4edfeea # main with: angular-robot-key: ${{ secrets.ANGULAR_ROBOT_PRIVATE_KEY }} diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 8395ac196c14..b7d66e4aafc5 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -21,9 +21,9 @@ jobs: runs-on: ubuntu-latest steps: - name: Initialize environment - uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@6d918a6dd670e28afd4ba54d00b805d4aba43dca # main + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@e713eca55b2813448af42f2e0e752258e4edfeea # main - name: Setup Bazel - uses: angular/dev-infra/github-actions/bazel/setup@6d918a6dd670e28afd4ba54d00b805d4aba43dca # main + uses: angular/dev-infra/github-actions/bazel/setup@e713eca55b2813448af42f2e0e752258e4edfeea # main - name: Install node modules run: pnpm install --frozen-lockfile - name: Generate JSON schema types @@ -44,11 +44,11 @@ jobs: runs-on: ubuntu-latest steps: - name: Initialize environment - uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@6d918a6dd670e28afd4ba54d00b805d4aba43dca # main + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@e713eca55b2813448af42f2e0e752258e4edfeea # main - name: Setup Bazel - uses: angular/dev-infra/github-actions/bazel/setup@6d918a6dd670e28afd4ba54d00b805d4aba43dca # main + uses: angular/dev-infra/github-actions/bazel/setup@e713eca55b2813448af42f2e0e752258e4edfeea # main - name: Setup Bazel RBE - uses: angular/dev-infra/github-actions/bazel/configure-remote@6d918a6dd670e28afd4ba54d00b805d4aba43dca # main + uses: angular/dev-infra/github-actions/bazel/configure-remote@e713eca55b2813448af42f2e0e752258e4edfeea # main with: google_credential: ${{ secrets.RBE_TRUSTED_BUILDS_USER }} - name: Install node modules @@ -61,11 +61,11 @@ jobs: runs-on: ubuntu-latest steps: - name: Initialize environment - uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@6d918a6dd670e28afd4ba54d00b805d4aba43dca # main + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@e713eca55b2813448af42f2e0e752258e4edfeea # main - name: Setup Bazel - uses: angular/dev-infra/github-actions/bazel/setup@6d918a6dd670e28afd4ba54d00b805d4aba43dca # main + uses: angular/dev-infra/github-actions/bazel/setup@e713eca55b2813448af42f2e0e752258e4edfeea # main - name: Setup Bazel RBE - uses: angular/dev-infra/github-actions/bazel/configure-remote@6d918a6dd670e28afd4ba54d00b805d4aba43dca # main + uses: angular/dev-infra/github-actions/bazel/configure-remote@e713eca55b2813448af42f2e0e752258e4edfeea # main with: google_credential: ${{ secrets.RBE_TRUSTED_BUILDS_USER }} - name: Install node modules @@ -84,13 +84,13 @@ jobs: runs-on: ubuntu-latest steps: - name: Initialize environment - uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@6d918a6dd670e28afd4ba54d00b805d4aba43dca # main + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@e713eca55b2813448af42f2e0e752258e4edfeea # main - name: Install node modules run: pnpm install --frozen-lockfile - name: Setup Bazel - uses: angular/dev-infra/github-actions/bazel/setup@6d918a6dd670e28afd4ba54d00b805d4aba43dca # main + uses: angular/dev-infra/github-actions/bazel/setup@e713eca55b2813448af42f2e0e752258e4edfeea # main - name: Setup Bazel RBE - uses: angular/dev-infra/github-actions/bazel/configure-remote@6d918a6dd670e28afd4ba54d00b805d4aba43dca # main + uses: angular/dev-infra/github-actions/bazel/configure-remote@e713eca55b2813448af42f2e0e752258e4edfeea # main with: google_credential: ${{ secrets.RBE_TRUSTED_BUILDS_USER }} - name: Run CLI E2E tests @@ -100,11 +100,11 @@ jobs: runs-on: ubuntu-latest steps: - name: Initialize environment - uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@6d918a6dd670e28afd4ba54d00b805d4aba43dca # main + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@e713eca55b2813448af42f2e0e752258e4edfeea # main - name: Setup Bazel - uses: angular/dev-infra/github-actions/bazel/setup@6d918a6dd670e28afd4ba54d00b805d4aba43dca # main + uses: angular/dev-infra/github-actions/bazel/setup@e713eca55b2813448af42f2e0e752258e4edfeea # main - name: Setup Bazel RBE - uses: angular/dev-infra/github-actions/bazel/configure-remote@6d918a6dd670e28afd4ba54d00b805d4aba43dca # main + uses: angular/dev-infra/github-actions/bazel/configure-remote@e713eca55b2813448af42f2e0e752258e4edfeea # main with: google_credential: ${{ secrets.RBE_TRUSTED_BUILDS_USER }} - name: Install node modules @@ -137,7 +137,7 @@ jobs: runs-on: windows-2025 steps: - name: Initialize environment - uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@6d918a6dd670e28afd4ba54d00b805d4aba43dca # main + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@e713eca55b2813448af42f2e0e752258e4edfeea # main - name: Install node modules run: pnpm install --frozen-lockfile - name: Download built Windows E2E tests @@ -164,13 +164,13 @@ jobs: runs-on: ubuntu-latest steps: - name: Initialize environment - uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@6d918a6dd670e28afd4ba54d00b805d4aba43dca # main + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@e713eca55b2813448af42f2e0e752258e4edfeea # main - name: Install node modules run: pnpm install --frozen-lockfile - name: Setup Bazel - uses: angular/dev-infra/github-actions/bazel/setup@6d918a6dd670e28afd4ba54d00b805d4aba43dca # main + uses: angular/dev-infra/github-actions/bazel/setup@e713eca55b2813448af42f2e0e752258e4edfeea # main - name: Setup Bazel RBE - uses: angular/dev-infra/github-actions/bazel/configure-remote@6d918a6dd670e28afd4ba54d00b805d4aba43dca # main + uses: angular/dev-infra/github-actions/bazel/configure-remote@e713eca55b2813448af42f2e0e752258e4edfeea # main with: google_credential: ${{ secrets.RBE_TRUSTED_BUILDS_USER }} - name: Run CLI E2E tests @@ -188,13 +188,13 @@ jobs: runs-on: ubuntu-latest steps: - name: Initialize environment - uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@6d918a6dd670e28afd4ba54d00b805d4aba43dca # main + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@e713eca55b2813448af42f2e0e752258e4edfeea # main - name: Install node modules run: pnpm install --frozen-lockfile - name: Setup Bazel - uses: angular/dev-infra/github-actions/bazel/setup@6d918a6dd670e28afd4ba54d00b805d4aba43dca # main + uses: angular/dev-infra/github-actions/bazel/setup@e713eca55b2813448af42f2e0e752258e4edfeea # main - name: Setup Bazel RBE - uses: angular/dev-infra/github-actions/bazel/configure-remote@6d918a6dd670e28afd4ba54d00b805d4aba43dca # main + uses: angular/dev-infra/github-actions/bazel/configure-remote@e713eca55b2813448af42f2e0e752258e4edfeea # main with: google_credential: ${{ secrets.RBE_TRUSTED_BUILDS_USER }} - name: Run CLI E2E tests @@ -208,13 +208,13 @@ jobs: SAUCE_TUNNEL_IDENTIFIER: angular-cli-${{ github.workflow }}-${{ github.run_number }} steps: - name: Initialize environment - uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@6d918a6dd670e28afd4ba54d00b805d4aba43dca # main + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@e713eca55b2813448af42f2e0e752258e4edfeea # main - name: Install node modules run: pnpm install --frozen-lockfile - name: Setup Bazel - uses: angular/dev-infra/github-actions/bazel/setup@6d918a6dd670e28afd4ba54d00b805d4aba43dca # main + uses: angular/dev-infra/github-actions/bazel/setup@e713eca55b2813448af42f2e0e752258e4edfeea # main - name: Setup Bazel RBE - uses: angular/dev-infra/github-actions/bazel/configure-remote@6d918a6dd670e28afd4ba54d00b805d4aba43dca # main + uses: angular/dev-infra/github-actions/bazel/configure-remote@e713eca55b2813448af42f2e0e752258e4edfeea # main with: google_credential: ${{ secrets.RBE_TRUSTED_BUILDS_USER }} - name: Start Sauce Connect @@ -245,11 +245,11 @@ jobs: CIRCLE_BRANCH: ${{ github.ref_name }} steps: - name: Initialize environment - uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@6d918a6dd670e28afd4ba54d00b805d4aba43dca # main + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@e713eca55b2813448af42f2e0e752258e4edfeea # main - name: Install node modules run: pnpm install --frozen-lockfile - name: Setup Bazel - uses: angular/dev-infra/github-actions/bazel/setup@6d918a6dd670e28afd4ba54d00b805d4aba43dca # main + uses: angular/dev-infra/github-actions/bazel/setup@e713eca55b2813448af42f2e0e752258e4edfeea # main - run: pnpm admin snapshots --verbose env: SNAPSHOT_BUILDS_GITHUB_TOKEN: ${{ secrets.SNAPSHOT_BUILDS_GITHUB_TOKEN }} diff --git a/.github/workflows/dev-infra.yml b/.github/workflows/dev-infra.yml index 3ff292ec3ff9..f0b468e675ea 100644 --- a/.github/workflows/dev-infra.yml +++ b/.github/workflows/dev-infra.yml @@ -16,21 +16,21 @@ jobs: if: github.event_name == 'pull_request_target' runs-on: ubuntu-latest steps: - - uses: angular/dev-infra/github-actions/labeling/pull-request@6d918a6dd670e28afd4ba54d00b805d4aba43dca # main + - uses: angular/dev-infra/github-actions/labeling/pull-request@e713eca55b2813448af42f2e0e752258e4edfeea # main with: angular-robot-key: ${{ secrets.ANGULAR_ROBOT_PRIVATE_KEY }} post_approval_changes: if: github.event_name == 'pull_request_target' runs-on: ubuntu-latest steps: - - uses: angular/dev-infra/github-actions/post-approval-changes@6d918a6dd670e28afd4ba54d00b805d4aba43dca # main + - uses: angular/dev-infra/github-actions/post-approval-changes@e713eca55b2813448af42f2e0e752258e4edfeea # main with: angular-robot-key: ${{ secrets.ANGULAR_ROBOT_PRIVATE_KEY }} issue_labels: if: github.event_name == 'issues' runs-on: ubuntu-latest steps: - - uses: angular/dev-infra/github-actions/labeling/issue@6d918a6dd670e28afd4ba54d00b805d4aba43dca # main + - uses: angular/dev-infra/github-actions/labeling/issue@e713eca55b2813448af42f2e0e752258e4edfeea # main with: angular-robot-key: ${{ secrets.ANGULAR_ROBOT_PRIVATE_KEY }} google-generative-ai-key: ${{ secrets.GOOGLE_GENERATIVE_AI_KEY }} diff --git a/.github/workflows/perf.yml b/.github/workflows/perf.yml index 8b7edf35f34b..392fbd4cc108 100644 --- a/.github/workflows/perf.yml +++ b/.github/workflows/perf.yml @@ -22,7 +22,7 @@ jobs: workflows: ${{ steps.workflows.outputs.workflows }} steps: - name: Initialize environment - uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@6d918a6dd670e28afd4ba54d00b805d4aba43dca # main + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@e713eca55b2813448af42f2e0e752258e4edfeea # main - name: Install node modules run: pnpm install --frozen-lockfile - id: workflows @@ -40,9 +40,9 @@ jobs: workflow: ${{ fromJSON(needs.list.outputs.workflows) }} steps: - name: Initialize environment - uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@6d918a6dd670e28afd4ba54d00b805d4aba43dca # main + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@e713eca55b2813448af42f2e0e752258e4edfeea # main - name: Setup Bazel - uses: angular/dev-infra/github-actions/bazel/setup@6d918a6dd670e28afd4ba54d00b805d4aba43dca # main + uses: angular/dev-infra/github-actions/bazel/setup@e713eca55b2813448af42f2e0e752258e4edfeea # main - name: Install node modules run: pnpm install --frozen-lockfile # We utilize the google-github-actions/auth action to allow us to get an active credential using workflow diff --git a/.github/workflows/pr.yml b/.github/workflows/pr.yml index 44071b0478ef..0837c2b0fa67 100644 --- a/.github/workflows/pr.yml +++ b/.github/workflows/pr.yml @@ -34,9 +34,9 @@ jobs: runs-on: ubuntu-latest steps: - name: Initialize environment - uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@6d918a6dd670e28afd4ba54d00b805d4aba43dca # main + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@e713eca55b2813448af42f2e0e752258e4edfeea # main - name: Setup Bazel - uses: angular/dev-infra/github-actions/bazel/setup@6d918a6dd670e28afd4ba54d00b805d4aba43dca # main + uses: angular/dev-infra/github-actions/bazel/setup@e713eca55b2813448af42f2e0e752258e4edfeea # main - name: Setup ESLint Caching uses: actions/cache@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0 with: @@ -66,17 +66,17 @@ jobs: # it has been merged. run: pnpm ng-dev format changed --check ${{ github.event.pull_request.base.sha }} - name: Check Package Licenses - uses: angular/dev-infra/github-actions/linting/licenses@6d918a6dd670e28afd4ba54d00b805d4aba43dca # main + uses: angular/dev-infra/github-actions/linting/licenses@e713eca55b2813448af42f2e0e752258e4edfeea # main build: runs-on: ubuntu-latest steps: - name: Initialize environment - uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@6d918a6dd670e28afd4ba54d00b805d4aba43dca # main + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@e713eca55b2813448af42f2e0e752258e4edfeea # main - name: Setup Bazel - uses: angular/dev-infra/github-actions/bazel/setup@6d918a6dd670e28afd4ba54d00b805d4aba43dca # main + uses: angular/dev-infra/github-actions/bazel/setup@e713eca55b2813448af42f2e0e752258e4edfeea # main - name: Setup Bazel RBE - uses: angular/dev-infra/github-actions/bazel/configure-remote@6d918a6dd670e28afd4ba54d00b805d4aba43dca # main + uses: angular/dev-infra/github-actions/bazel/configure-remote@e713eca55b2813448af42f2e0e752258e4edfeea # main - name: Install node modules run: pnpm install --frozen-lockfile - name: Build release targets @@ -93,11 +93,11 @@ jobs: runs-on: ubuntu-latest steps: - name: Initialize environment - uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@6d918a6dd670e28afd4ba54d00b805d4aba43dca # main + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@e713eca55b2813448af42f2e0e752258e4edfeea # main - name: Setup Bazel - uses: angular/dev-infra/github-actions/bazel/setup@6d918a6dd670e28afd4ba54d00b805d4aba43dca # main + uses: angular/dev-infra/github-actions/bazel/setup@e713eca55b2813448af42f2e0e752258e4edfeea # main - name: Setup Bazel RBE - uses: angular/dev-infra/github-actions/bazel/configure-remote@6d918a6dd670e28afd4ba54d00b805d4aba43dca # main + uses: angular/dev-infra/github-actions/bazel/configure-remote@e713eca55b2813448af42f2e0e752258e4edfeea # main - name: Install node modules run: pnpm install --frozen-lockfile - name: Run module and package tests @@ -114,13 +114,13 @@ jobs: runs-on: ubuntu-latest steps: - name: Initialize environment - uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@6d918a6dd670e28afd4ba54d00b805d4aba43dca # main + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@e713eca55b2813448af42f2e0e752258e4edfeea # main - name: Install node modules run: pnpm install --frozen-lockfile - name: Setup Bazel - uses: angular/dev-infra/github-actions/bazel/setup@6d918a6dd670e28afd4ba54d00b805d4aba43dca # main + uses: angular/dev-infra/github-actions/bazel/setup@e713eca55b2813448af42f2e0e752258e4edfeea # main - name: Setup Bazel RBE - uses: angular/dev-infra/github-actions/bazel/configure-remote@6d918a6dd670e28afd4ba54d00b805d4aba43dca # main + uses: angular/dev-infra/github-actions/bazel/configure-remote@e713eca55b2813448af42f2e0e752258e4edfeea # main - name: Run CLI E2E tests run: pnpm bazel test --test_env=E2E_SHARD_TOTAL=6 --test_env=E2E_SHARD_INDEX=${{ matrix.shard }} --config=e2e //tests:e2e.${{ matrix.subset }}_node${{ matrix.node }} @@ -128,11 +128,11 @@ jobs: runs-on: ubuntu-latest steps: - name: Initialize environment - uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@6d918a6dd670e28afd4ba54d00b805d4aba43dca # main + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@e713eca55b2813448af42f2e0e752258e4edfeea # main - name: Setup Bazel - uses: angular/dev-infra/github-actions/bazel/setup@6d918a6dd670e28afd4ba54d00b805d4aba43dca # main + uses: angular/dev-infra/github-actions/bazel/setup@e713eca55b2813448af42f2e0e752258e4edfeea # main - name: Setup Bazel RBE - uses: angular/dev-infra/github-actions/bazel/configure-remote@6d918a6dd670e28afd4ba54d00b805d4aba43dca # main + uses: angular/dev-infra/github-actions/bazel/configure-remote@e713eca55b2813448af42f2e0e752258e4edfeea # main - name: Install node modules run: pnpm install --frozen-lockfile - name: Build E2E tests for Windows on Linux @@ -156,7 +156,7 @@ jobs: runs-on: windows-2025 steps: - name: Initialize environment - uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@6d918a6dd670e28afd4ba54d00b805d4aba43dca # main + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@e713eca55b2813448af42f2e0e752258e4edfeea # main - name: Install node modules run: pnpm install --frozen-lockfile - name: Download built Windows E2E tests @@ -183,13 +183,13 @@ jobs: runs-on: ubuntu-latest steps: - name: Initialize environment - uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@6d918a6dd670e28afd4ba54d00b805d4aba43dca # main + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@e713eca55b2813448af42f2e0e752258e4edfeea # main - name: Install node modules run: pnpm install --frozen-lockfile - name: Setup Bazel - uses: angular/dev-infra/github-actions/bazel/setup@6d918a6dd670e28afd4ba54d00b805d4aba43dca # main + uses: angular/dev-infra/github-actions/bazel/setup@e713eca55b2813448af42f2e0e752258e4edfeea # main - name: Setup Bazel RBE - uses: angular/dev-infra/github-actions/bazel/configure-remote@6d918a6dd670e28afd4ba54d00b805d4aba43dca # main + uses: angular/dev-infra/github-actions/bazel/configure-remote@e713eca55b2813448af42f2e0e752258e4edfeea # main - name: Run CLI E2E tests run: pnpm bazel test --test_env=E2E_SHARD_TOTAL=3 --test_env=E2E_SHARD_INDEX=${{ matrix.shard }} --config=e2e //tests:e2e.${{ matrix.subset }}_node${{ matrix.node }} @@ -205,12 +205,12 @@ jobs: runs-on: ubuntu-latest steps: - name: Initialize environment - uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@6d918a6dd670e28afd4ba54d00b805d4aba43dca # main + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@e713eca55b2813448af42f2e0e752258e4edfeea # main - name: Install node modules run: pnpm install --frozen-lockfile - name: Setup Bazel - uses: angular/dev-infra/github-actions/bazel/setup@6d918a6dd670e28afd4ba54d00b805d4aba43dca # main + uses: angular/dev-infra/github-actions/bazel/setup@e713eca55b2813448af42f2e0e752258e4edfeea # main - name: Setup Bazel RBE - uses: angular/dev-infra/github-actions/bazel/configure-remote@6d918a6dd670e28afd4ba54d00b805d4aba43dca # main + uses: angular/dev-infra/github-actions/bazel/configure-remote@e713eca55b2813448af42f2e0e752258e4edfeea # main - name: Run CLI E2E tests run: pnpm bazel test --test_env=E2E_SHARD_TOTAL=6 --test_env=E2E_SHARD_INDEX=${{ matrix.shard }} --config=e2e //tests:e2e.snapshots.${{ matrix.subset }}_node${{ matrix.node }} diff --git a/MODULE.bazel b/MODULE.bazel index df0fc81009a6..3015308e9d38 100644 --- a/MODULE.bazel +++ b/MODULE.bazel @@ -19,21 +19,21 @@ bazel_dep(name = "aspect_rules_jasmine", version = "2.0.4") bazel_dep(name = "rules_angular") git_override( module_name = "rules_angular", - commit = "334ed4f0bf82cfcf21b1d8bd501d2294b186061e", + commit = "a30fc96ae7cbf6738d37d9d7d3e1c6e6cb7744f5", remote = "https://github.com/angular/rules_angular.git", ) bazel_dep(name = "devinfra") git_override( module_name = "devinfra", - commit = "6d918a6dd670e28afd4ba54d00b805d4aba43dca", + commit = "e713eca55b2813448af42f2e0e752258e4edfeea", remote = "https://github.com/angular/dev-infra.git", ) bazel_dep(name = "rules_browsers") git_override( module_name = "rules_browsers", - commit = "dd75910a556e309d6f475d54214551be919a21d1", + commit = "c6cb5590120af8ae8125343f9fc522b7b66eb0e8", remote = "https://github.com/angular/rules_browsers.git", ) diff --git a/tests/e2e/ng-snapshot/package.json b/tests/e2e/ng-snapshot/package.json index 29037946b4e6..aa97dcca2190 100644 --- a/tests/e2e/ng-snapshot/package.json +++ b/tests/e2e/ng-snapshot/package.json @@ -2,21 +2,21 @@ "description": "snapshot versions of Angular for e2e testing", "private": true, "dependencies": { - "@angular/animations": "github:angular/animations-builds#ebf341ae0035dbacee781ab987f8c8336c62a6ba", - "@angular/cdk": "github:angular/cdk-builds#8c5c4e194a0fec929ddc81b53938866fc7359c03", - "@angular/common": "github:angular/common-builds#b8fd07bfdc97d3570f90e368b60ddf3c337c8c43", - "@angular/compiler": "github:angular/compiler-builds#4d1d1548fc38bd7e04330dedb782fccb8e1fb141", - "@angular/compiler-cli": "github:angular/compiler-cli-builds#1d3fe381f981ce77ea6884a57359386baa2e3e64", - "@angular/core": "github:angular/core-builds#26979caac965dc0d479a25b5d05a5fcf14d0ad9e", - "@angular/forms": "github:angular/forms-builds#a6874141905517d6a388112b57753a285aa7888f", - "@angular/language-service": "github:angular/language-service-builds#b41c6925fa8537c63678960486bf2e5363510bfb", - "@angular/localize": "github:angular/localize-builds#427a45e50ab8cbb563b736b46985fce98d6de21e", - "@angular/material": "github:angular/material-builds#59ff7da13227dac6276ba5b6dec298327c3e11ac", - "@angular/material-moment-adapter": "github:angular/material-moment-adapter-builds#ab87a2ea5a15a8dc2f5afc723211bf4d0e7c9777", - "@angular/platform-browser": "github:angular/platform-browser-builds#1dac78e7b5785a885df765f02b08acab0c9b8bb4", - "@angular/platform-browser-dynamic": "github:angular/platform-browser-dynamic-builds#170de259e7e98c7065da3e4d6ca4c795cd09dbf8", - "@angular/platform-server": "github:angular/platform-server-builds#55db150433a54d9f83ac190e2437f1f464815632", - "@angular/router": "github:angular/router-builds#a58b82a40376882a54591ee2c2e91dcc626e712f", - "@angular/service-worker": "github:angular/service-worker-builds#d5eef8ef96e0a24617c4871444babe6566ee811c" + "@angular/animations": "github:angular/animations-builds#383cdb66a8b166172c60c6247b8f62433fc036ce", + "@angular/cdk": "github:angular/cdk-builds#7e9e3a08b985ff5f6b1c28c84732f67043c750cc", + "@angular/common": "github:angular/common-builds#a2042413ef60c154437ed8395276b75cc928a4af", + "@angular/compiler": "github:angular/compiler-builds#7aad56f2fe4720c93804a7fcfb0797e9327db4c0", + "@angular/compiler-cli": "github:angular/compiler-cli-builds#49e31924991ee9186a9aea250d101820e79bb4a6", + "@angular/core": "github:angular/core-builds#6deca1aa4567d280ec97e66b0d70970f6b506332", + "@angular/forms": "github:angular/forms-builds#6d9eb4089cb8795077db81049e7702bc688c2d58", + "@angular/language-service": "github:angular/language-service-builds#8e758b0550fb522155bd24a58b291e6e7344d327", + "@angular/localize": "github:angular/localize-builds#d627d4f27929f8f5a27d1f6a349543cdaf3bfb42", + "@angular/material": "github:angular/material-builds#972986b028de9bb40e498551ff034e115d961e8b", + "@angular/material-moment-adapter": "github:angular/material-moment-adapter-builds#55d307862a1da6877154314fadf554b18da0a811", + "@angular/platform-browser": "github:angular/platform-browser-builds#8dcc3b87feb7b4479a3debf34989feb8a7dd9f16", + "@angular/platform-browser-dynamic": "github:angular/platform-browser-dynamic-builds#91e2b4643158129289707721bb72b58910efda5f", + "@angular/platform-server": "github:angular/platform-server-builds#d1e8965023f08bbe4e166749eb0e4149ab3af9dd", + "@angular/router": "github:angular/router-builds#8a1452377452f1c53f9fe37f360f5dc6ca575213", + "@angular/service-worker": "github:angular/service-worker-builds#3222e80c93a80abf873e16ad50b7b731a5878dad" } } From feb050082564a335b07c8d90248414df5fcd8761 Mon Sep 17 00:00:00 2001 From: Alan Agius <17563226+alan-agius4@users.noreply.github.com> Date: Wed, 26 Aug 2026 07:40:30 +0000 Subject: [PATCH 348/787] docs: release notes for the v20.3.35 release --- CHANGELOG.md | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index f3077ffb76bc..017571ba1d02 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,15 @@ + + +# 20.3.35 (2026-08-26) + +### @angular-devkit/build-angular + +| Commit | Type | Description | +| ---------------------------------------------------------------------------------------------------- | ---- | ---------------------------------- | +| [94b620acd7](https://github.com/angular/angular-cli/commit/94b620acd76e39c7d5cc8527dfc6fe9096855cbd) | fix | update webpack-dev-server to 5.2.6 | + + + # 22.2.0-next.4 (2026-08-19) From c44060d43e16551eae9661a8526e667ded811596 Mon Sep 17 00:00:00 2001 From: Alan Agius <17563226+alan-agius4@users.noreply.github.com> Date: Wed, 26 Aug 2026 07:45:49 +0000 Subject: [PATCH 349/787] docs: release notes for the v21.2.22 release --- CHANGELOG.md | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 017571ba1d02..9145b7880610 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,15 @@ + + +# 21.2.22 (2026-08-26) + +### @angular-devkit/build-angular + +| Commit | Type | Description | +| ---------------------------------------------------------------------------------------------------- | ---- | ---------------------------------- | +| [b0047b04f5](https://github.com/angular/angular-cli/commit/b0047b04f56f5cb3fb8e4465ba0fad777497144a) | fix | update webpack-dev-server to 5.2.6 | + + + # 20.3.35 (2026-08-26) From 8098402a9dde17f27a72bdf0e5d3d64cb1522d50 Mon Sep 17 00:00:00 2001 From: Alan Agius <17563226+alan-agius4@users.noreply.github.com> Date: Wed, 26 Aug 2026 07:50:17 +0000 Subject: [PATCH 350/787] docs: release notes for the v22.1.6 release --- CHANGELOG.md | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9145b7880610..d00c4258aa1b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,22 @@ + + +# 22.1.6 (2026-08-26) + +### @angular/build + +| Commit | Type | Description | +| ---------------------------------------------------------------------------------------------------- | ---- | --------------------------------------------------------- | +| [3f132eaa97](https://github.com/angular/angular-cli/commit/3f132eaa97b95e16c58b8095c2566e3c78190446) | fix | ignore side-effect annotations in unit test builds | +| [5b1028936f](https://github.com/angular/angular-cli/commit/5b1028936f6e9582917f95ac37942dca0ee2c659) | perf | batch prerender routes and share in-memory server bundles | + +### @angular/ssr + +| Commit | Type | Description | +| ---------------------------------------------------------------------------------------------------- | ---- | ----------------------------------------------------- | +| [76818cb811](https://github.com/angular/angular-cli/commit/76818cb811a8fe669575f988fec2e4528dca8c73) | fix | abort web request signal when node request is aborted | + + + # 21.2.22 (2026-08-26) From 07f9122ff3a0781a486f86c7d77e0f5fe71cebdb Mon Sep 17 00:00:00 2001 From: Alan Agius <17563226+alan-agius4@users.noreply.github.com> Date: Wed, 26 Aug 2026 07:51:21 +0000 Subject: [PATCH 351/787] release: cut the v22.2.0-next.5 release --- CHANGELOG.md | 24 ++++++++++++++++++++++++ package.json | 2 +- 2 files changed, 25 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index d00c4258aa1b..e1fcb5a988ac 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,27 @@ + + +# 22.2.0-next.5 (2026-08-26) + +### @angular/build + +| Commit | Type | Description | +| ---------------------------------------------------------------------------------------------------- | ---- | -------------------------------------------------------------------------------- | +| [4d0be683b7](https://github.com/angular/angular-cli/commit/4d0be683b780a9a1629dc8f9cddad49153bddabf) | fix | ignore side-effect annotations in unit test builds | +| [e4111ae818](https://github.com/angular/angular-cli/commit/e4111ae8180f3cd5800f248c23010844aa1730ad) | fix | prevent memory leaks in parallel compilation and caches | +| [62999cabf4](https://github.com/angular/angular-cli/commit/62999cabf4d65cf1060598150a77494e147fcc2a) | perf | batch prerender routes and share in-memory server bundles | +| [0589edd9cd](https://github.com/angular/angular-cli/commit/0589edd9cdc493ecf34a160cc7b8491618b59f72) | perf | consolidate component stylesheet bundling with shared load result cache | +| [a877aa7ebd](https://github.com/angular/angular-cli/commit/a877aa7ebdbf919d6bc17e6ec0920ca702db0db4) | perf | implement SharedArrayBuffer translation dictionaries for zero-copy worker access | +| [f1cc959439](https://github.com/angular/angular-cli/commit/f1cc959439d8ca11a45d693520c34dd94e0b6548) | perf | implement sliding-window batching and worker translation eviction | +| [f4dad31cce](https://github.com/angular/angular-cli/commit/f4dad31cce41bc3e8ed8767256d9e50a712c3a72) | perf | unify Oxc linking and optimization AST traversal passes | + +### @angular/ssr + +| Commit | Type | Description | +| ---------------------------------------------------------------------------------------------------- | ---- | ----------------------------------------------------- | +| [f8576e3c8b](https://github.com/angular/angular-cli/commit/f8576e3c8bfe3490b1b0b85832b489593a4e43ac) | fix | abort web request signal when node request is aborted | + + + # 22.1.6 (2026-08-26) diff --git a/package.json b/package.json index a33875337f4b..b4a082868bcb 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@angular/devkit-repo", - "version": "22.2.0-next.4", + "version": "22.2.0-next.5", "private": true, "description": "Software Development Kit for Angular", "keywords": [ From ecbcd87b8857225e4df3df7896b3236d63553f23 Mon Sep 17 00:00:00 2001 From: Alan Agius <17563226+alan-agius4@users.noreply.github.com> Date: Wed, 26 Aug 2026 16:18:03 +0000 Subject: [PATCH 352/787] perf(@angular/build): use native sass-embedded compiler daemon Replaces the Piscina-based worker thread pool executing pure-JS Dart Sass (`sass` compiled via `dart2js`) with a native Dart Sass asynchronous compiler daemon (`sass-embedded`). The build system previously relied on multi-threaded worker pools with synchronous compilation to bypass performance overheads inherent to pure-JS asynchronous Dart Sass. However, this approach incurred significant V8 heap and isolate duplication across worker threads, as well as thread contention and blocking due to `Atomics.wait()` synchronization loops during custom URL and module rebasing. With `sass-embedded`, Sass compilation is delegated to a long-lived native Dart AOT binary communicating asynchronously via Protocol Buffers over stdio pipes. This eliminates duplicate V8 isolates, replaces synchronous `Atomics.wait()` with event-driven asynchronous message handling, and dramatically reduces memory pressure on the Node.js process. The compiler infrastructure is structured around a shared `SassServiceImplementation` interface with two isolated implementations dynamically loaded on demand: - `SassAsyncCompilerImplementation`: Manages the native `sass-embedded` daemon lifecycle and asynchronous URL rebasing importers (`AsyncModuleUrlRebasingImporter`). - `SassWorkerImplementation`: Retained as an isolated worker pool fallback. Environment Variable & Fallbacks: - `NG_BUILD_SASS_WORKER=1` (or `true`): Forces the build system to fall back to the pure-JS `SassWorkerImplementation` using worker threads. - In restricted environments where native platform binaries cannot be spawned (such as WebContainers detected via `process.versions.webcontainer`), the build system automatically falls back to `SassWorkerImplementation` without requiring manual configuration. ### Benchmarks: Sass Service in Isolation #### 10 Small Files (Angular Components) | Metric | Worker Pool (`main`) | Native Async (`this change`) | Delta | Speedup / Improvement | | :--- | :---: | :---: | :---: | :---: | | Cold Start | 369.04 ms | 229.89 ms | -139.15 ms | 1.61x faster (-37.7%) | | Warm Median | 22.46 ms | 5.27 ms | -17.19 ms | 4.26x faster (-76.5%) | | Warm Mean | 25.82 ms | 7.25 ms | -18.57 ms | 3.56x faster (-71.9%) | | Warm P95 | 37.30 ms | 14.55 ms | -22.75 ms | 2.56x faster (-61.0%) | | Warm Throughput | 445.2 files/s | 1,899.3 files/s | +1,454.1 files/s | 4.27x throughput (+326.6%) | | Incremental Median | 6.54 ms | 2.08 ms | -4.46 ms | 3.14x faster (-68.2%) | | Incremental Throughput | 153.0 files/s | 480.5 files/s | +327.5 files/s | 3.14x throughput (+214.0%) | | Peak Memory RSS | 281.16 MB | 78.73 MB | -202.43 MB | -72.0% memory saved | #### 10 Large Files (Design System Tokens & Themes) | Metric | Worker Pool (`main`) | Native Async (`this change`) | Delta | Speedup / Improvement | | :--- | :---: | :---: | :---: | :---: | | Cold Start | 823.95 ms | 386.25 ms | -437.70 ms | 2.13x faster (-53.1%) | | Warm Median | 231.85 ms | 175.64 ms | -56.21 ms | 1.32x faster (-24.2%) | | Warm Mean | 241.50 ms | 172.22 ms | -69.28 ms | 1.40x faster (-28.7%) | | Warm P95 | 293.09 ms | 215.48 ms | -77.61 ms | 1.36x faster (-26.5%) | | Warm Throughput | 43.1 files/s | 56.9 files/s | +13.8 files/s | 1.32x throughput (+32.0%) | | Incremental Median | 72.63 ms | 35.34 ms | -37.29 ms | 2.06x faster (-51.3%) | | Incremental Throughput | 13.8 files/s | 28.3 files/s | +14.5 files/s | 2.05x throughput (+105.4%) | | Peak Memory RSS | 986.47 MB | 112.34 MB | -874.13 MB | -88.6% memory saved | ### Benchmarks: Real Angular CLI Application Scenarios (ng build) #### Small App (5 small files) | Phase / Metric | Main (`NG_BUILD_SASS_WORKER=1`) | This Change (Native Async) | Delta | Improvement | | :--- | :---: | :---: | :---: | :---: | | Cold Wall Time | 3,201.3 ms | 2,950.2 ms | -251.1 ms | -7.8% | | Cold CLI Time | 2,456.0 ms | 2,302.0 ms | -154.0 ms | -6.3% | | Cold Peak RSS | 1,227.3 MB | 1,058.9 MB | -168.4 MB | -13.7% | | Warm (Avg) Wall Time | 2,762.0 ms | 2,475.3 ms | -286.7 ms | -10.4% | | Warm (Avg) CLI Time | 2,071.3 ms | 1,820.3 ms | -251.0 ms | -12.1% | | Warm (Avg) Peak RSS | 1,102.3 MB | 894.8 MB | -207.5 MB | -18.8% | #### Small App (5 large files) | Phase / Metric | Main (`NG_BUILD_SASS_WORKER=1`) | This Change (Native Async) | Delta | Improvement | | :--- | :---: | :---: | :---: | :---: | | Cold Wall Time | 3,605.9 ms | 3,175.8 ms | -430.1 ms | -11.9% | | Cold CLI Time | 2,874.0 ms | 2,482.0 ms | -392.0 ms | -13.6% | | Cold Peak RSS | 1,420.2 MB | 1,072.3 MB | -347.9 MB | -24.5% | | Warm (Avg) Wall Time | 3,123.7 ms | 2,682.5 ms | -441.2 ms | -14.1% | | Warm (Avg) CLI Time | 2,435.7 ms | 2,028.7 ms | -407.0 ms | -16.7% | | Warm (Avg) Peak RSS | 1,278.2 MB | 911.3 MB | -366.9 MB | -28.7% | #### Large App (500 files: 250 large + 250 small) | Phase / Metric | Main (`NG_BUILD_SASS_WORKER=1`) | This Change (Native Async) | Delta | Improvement | | :--- | :---: | :---: | :---: | :---: | | Cold Wall Time | 15,259.7 ms | 15,348.6 ms | +88.9 ms | +0.6% (Parity) | | Cold CLI Time | 14,425.0 ms | 14,373.0 ms | -52.0 ms | -0.4% (Parity) | | Cold Peak RSS | 2,305.1 MB | 1,582.7 MB | -722.4 MB | -31.3% memory saved | | Warm Run 1 Wall Time | 14,673.1 ms | 14,277.1 ms | -396.0 ms | -2.7% | | Warm Run 1 CLI Time | 13,812.0 ms | 13,375.0 ms | -437.0 ms | -3.2% | | Warm Run 1 Peak RSS | 2,180.5 MB | 1,485.6 MB | -694.9 MB | -31.9% memory saved | | Warm Run 2 Wall Time | 14,771.2 ms | 14,502.7 ms | -268.5 ms | -1.8% | | Warm Run 2 CLI Time | 13,943.0 ms | 13,527.0 ms | -416.0 ms | -3.0% | | Warm Run 2 Peak RSS | 2,220.8 MB | 1,493.3 MB | -727.5 MB | -32.8% memory saved | | Warm (Avg) Peak RSS | 2,200.7 MB | 1,489.5 MB | -711.2 MB | -32.3% memory saved | Closes #29319 --- packages/angular/build/BUILD.bazel | 1 + packages/angular/build/package.json | 1 + packages/angular/build/src/private.ts | 2 +- .../esbuild/stylesheets/sass-language.ts | 45 +-- .../stylesheets/stylesheet-plugin-factory.ts | 2 +- .../build/src/tools/sass/rebasing-importer.ts | 40 ++- .../sass-async-compiler-implementation.ts | 182 ++++++++++++ .../build/src/tools/sass/sass-service.ts | 248 +--------------- .../tools/sass/sass-worker-implementation.ts | 245 ++++++++++++++++ .../angular/build/src/tools/sass/worker.ts | 5 +- .../build/src/utils/environment-options.ts | 7 + pnpm-lock.yaml | 268 +++++++++++++++++- 12 files changed, 771 insertions(+), 275 deletions(-) create mode 100644 packages/angular/build/src/tools/sass/sass-async-compiler-implementation.ts create mode 100644 packages/angular/build/src/tools/sass/sass-worker-implementation.ts diff --git a/packages/angular/build/BUILD.bazel b/packages/angular/build/BUILD.bazel index 75eedd6a7f5f..e63b084ec458 100644 --- a/packages/angular/build/BUILD.bazel +++ b/packages/angular/build/BUILD.bazel @@ -106,6 +106,7 @@ ts_project( ":node_modules/rolldown", ":node_modules/rollup", ":node_modules/sass", + ":node_modules/sass-embedded", ":node_modules/source-map-support", ":node_modules/tinyglobby", ":node_modules/vite", diff --git a/packages/angular/build/package.json b/packages/angular/build/package.json index 0a998207cf27..609cf3132ce0 100644 --- a/packages/angular/build/package.json +++ b/packages/angular/build/package.json @@ -39,6 +39,7 @@ "piscina": "5.3.1", "rolldown": "1.2.5", "sass": "1.103.1", + "sass-embedded": "1.103.1", "semver": "7.8.5", "source-map-support": "0.5.21", "tinyglobby": "0.2.17", diff --git a/packages/angular/build/src/private.ts b/packages/angular/build/src/private.ts index 1e99d84c9832..315636decae2 100644 --- a/packages/angular/build/src/private.ts +++ b/packages/angular/build/src/private.ts @@ -35,7 +35,7 @@ export { export type { ExternalResultMetadata } from './tools/esbuild/bundler-execution-result'; export { emitFilesToDisk } from './tools/esbuild/utils'; export { transformSupportedBrowsersToTargets } from './tools/esbuild/target'; -export { SassWorkerImplementation } from './tools/sass/sass-service'; +export { SassWorkerImplementation } from './tools/sass/sass-worker-implementation'; export { SourceFileCache } from './tools/esbuild/angular/source-file-cache'; export { Cache } from './tools/esbuild/cache'; diff --git a/packages/angular/build/src/tools/esbuild/stylesheets/sass-language.ts b/packages/angular/build/src/tools/esbuild/stylesheets/sass-language.ts index 4bccfb3adba4..92c75d76d7ec 100644 --- a/packages/angular/build/src/tools/esbuild/stylesheets/sass-language.ts +++ b/packages/angular/build/src/tools/esbuild/stylesheets/sass-language.ts @@ -9,26 +9,27 @@ import type { OnLoadResult, PartialMessage, PartialNote, ResolveResult } from 'esbuild'; import { dirname, join } from 'node:path'; import { fileURLToPath, pathToFileURL } from 'node:url'; -import type { CanonicalizeContext, CompileResult, Exception, Syntax } from 'sass'; -import type { SassWorkerImplementation } from '../../sass/sass-service'; +import type { CanonicalizeContext, CompileResult, Exception, Syntax } from 'sass-embedded'; +import { useSassWorker } from '../../../utils/environment-options'; +import type { SassServiceImplementation } from '../../sass/sass-service'; import { MemoryCache } from '../cache'; import { StylesheetLanguage, StylesheetPluginOptions } from './stylesheet-plugin-factory'; -let sassWorkerPool: SassWorkerImplementation | undefined; -let sassWorkerPoolPromise: Promise | undefined; +let sassService: SassServiceImplementation | undefined; +let sassServicePromise: Promise | undefined; function isSassException(error: unknown): error is Exception { return !!error && typeof error === 'object' && 'sassMessage' in error; } export function shutdownSassWorkerPool(): void { - if (sassWorkerPool) { - void sassWorkerPool.close(); - sassWorkerPool = undefined; - } else if (sassWorkerPoolPromise) { - void sassWorkerPoolPromise.then(shutdownSassWorkerPool); + if (sassService) { + void sassService.close(); + sassService = undefined; + } else if (sassServicePromise) { + void sassServicePromise.then(shutdownSassWorkerPool); } - sassWorkerPoolPromise = undefined; + sassServicePromise = undefined; } export const SassStylesheetLanguage = Object.freeze({ @@ -78,13 +79,21 @@ async function compileString( resolveUrl: (url: string, options: CanonicalizeContext) => Promise, ): Promise { // Lazily load Sass when a Sass file is found - if (sassWorkerPool === undefined) { - if (sassWorkerPoolPromise === undefined) { - sassWorkerPoolPromise = import('../../sass/sass-service').then( - (sassService) => new sassService.SassWorkerImplementation(true), - ); + if (sassService === undefined) { + if (sassServicePromise === undefined) { + sassServicePromise = useSassWorker + ? import('../../sass/sass-worker-implementation').then( + (sassService) => new sassService.SassWorkerImplementation(true), + ) + : import('../../sass/sass-async-compiler-implementation').then( + (sassService) => new sassService.SassAsyncCompilerImplementation(), + ); + } + try { + sassService = await sassServicePromise; + } finally { + sassServicePromise = undefined; } - sassWorkerPool = await sassWorkerPoolPromise; } // Cache is currently local to individual compile requests. @@ -99,7 +108,7 @@ async function compileString( const { silenceDeprecations, futureDeprecations, fatalDeprecations } = options.sass ?? {}; try { - const { css, sourceMap, loadedUrls } = await sassWorkerPool.compileStringAsync(data, { + const { css, sourceMap, loadedUrls } = await sassService.compileStringAsync(data, { url: pathToFileURL(filePath), style: 'expanded', syntax, @@ -226,7 +235,7 @@ function* extractFilesFromStack(stack: string): Iterable { } if (path) { - // Stack paths from dart-sass are relative to the current working directory (not input file or workspace root) + // Stack paths from sass are relative to the current working directory (not input file or workspace root) yield join(cwd, path); } } diff --git a/packages/angular/build/src/tools/esbuild/stylesheets/stylesheet-plugin-factory.ts b/packages/angular/build/src/tools/esbuild/stylesheets/stylesheet-plugin-factory.ts index 2c40e007350e..79337fe1652e 100644 --- a/packages/angular/build/src/tools/esbuild/stylesheets/stylesheet-plugin-factory.ts +++ b/packages/angular/build/src/tools/esbuild/stylesheets/stylesheet-plugin-factory.ts @@ -11,7 +11,7 @@ import assert from 'node:assert'; import { readFile } from 'node:fs/promises'; import { createRequire } from 'node:module'; import { dirname, extname } from 'node:path'; -import type { Options } from 'sass'; +import type { Options } from 'sass-embedded'; import { glob } from 'tinyglobby'; import { assertIsError } from '../../../utils/error'; import type { PostcssConfiguration } from '../../../utils/postcss-configuration'; diff --git a/packages/angular/build/src/tools/sass/rebasing-importer.ts b/packages/angular/build/src/tools/sass/rebasing-importer.ts index 5d2a4ddc2267..e9509574f455 100644 --- a/packages/angular/build/src/tools/sass/rebasing-importer.ts +++ b/packages/angular/build/src/tools/sass/rebasing-importer.ts @@ -11,7 +11,7 @@ import { MagicString } from 'magic-string'; import { readFileSync, readdirSync, statSync } from 'node:fs'; import { basename, dirname, extname, join, relative } from 'node:path'; import { fileURLToPath, pathToFileURL } from 'node:url'; -import type { CanonicalizeContext, Importer, ImporterResult, Syntax } from 'sass'; +import type { CanonicalizeContext, Importer, ImporterResult, Syntax } from 'sass-embedded'; import { assertIsError } from '../../utils/error'; import { toPosixPath } from '../../utils/path'; import { findUrls } from './lexer'; @@ -343,6 +343,44 @@ export class ModuleUrlRebasingImporter extends RelativeUrlRebasingImporter { } } +/** + * Provides the Sass importer logic to resolve module (npm package) stylesheet imports asynchronously + * and also rebase any `url()` function usage within those stylesheets. + */ +export class AsyncModuleUrlRebasingImporter implements Importer<'async'> { + private relativeImporter: RelativeUrlRebasingImporter; + + constructor( + entryDirectory: string, + directoryCache: Map, + rebaseSourceMaps: Map | undefined, + private finder: ( + specifier: string, + options: CanonicalizeContext, + ) => Promise | URL | null, + ) { + this.relativeImporter = new RelativeUrlRebasingImporter( + entryDirectory, + directoryCache, + rebaseSourceMaps, + ); + } + + async canonicalize(url: string, options: CanonicalizeContext): Promise { + if (url.startsWith('file://')) { + return this.relativeImporter.canonicalize(url, options); + } + + const result = await this.finder(url, options); + + return result ? this.relativeImporter.canonicalize(result.href, options) : null; + } + + load(canonicalUrl: URL): ImporterResult | null { + return this.relativeImporter.load(canonicalUrl); + } +} + /** * Provides the Sass importer logic to resolve load paths located stylesheet imports via both import and * use rules and also rebase any `url()` function usage within those stylesheets. The rebasing will ensure that diff --git a/packages/angular/build/src/tools/sass/sass-async-compiler-implementation.ts b/packages/angular/build/src/tools/sass/sass-async-compiler-implementation.ts new file mode 100644 index 000000000000..cdf483994f12 --- /dev/null +++ b/packages/angular/build/src/tools/sass/sass-async-compiler-implementation.ts @@ -0,0 +1,182 @@ +/** + * @license + * Copyright Google LLC All Rights Reserved. + * + * Use of this source code is governed by an MIT-style license that can be + * found in the LICENSE file at https://angular.dev/license + */ + +import mergeSourceMaps, { type DecodedSourceMap, type RawSourceMap } from '@ampproject/remapping'; +import { dirname } from 'node:path'; +import { fileURLToPath } from 'node:url'; +import type { + AsyncCompiler, + CanonicalizeContext, + CompileResult, + FileImporter, + Importer, + NodePackageImporter, + StringOptions, +} from 'sass-embedded'; +import { + AsyncModuleUrlRebasingImporter, + DirectoryEntry, + LoadPathsUrlRebasingImporter, + RelativeUrlRebasingImporter, +} from './rebasing-importer'; +import { type SassServiceImplementation, isFileImporter } from './sass-service'; + +/** + * A Sass renderer implementation that uses the persistent Dart Sass embedded compiler + * daemon (`sass-embedded`) communicating over standard input/output with protocol buffers. + */ +export class SassAsyncCompilerImplementation implements SassServiceImplementation { + #asyncCompiler: AsyncCompiler | undefined; + #asyncCompilerPromise: Promise | undefined; + + async #ensureAsyncCompiler(): Promise { + if (this.#asyncCompiler) { + return this.#asyncCompiler; + } + + // Import and initialize the async compiler on the main thread. + this.#asyncCompilerPromise ??= import('sass-embedded').then(({ initAsyncCompiler }) => + initAsyncCompiler(), + ); + + try { + this.#asyncCompiler = await this.#asyncCompilerPromise; + } finally { + this.#asyncCompilerPromise = undefined; + } + + return this.#asyncCompiler; + } + + /** + * Provides information about the Sass implementation. + * This mimics enough of the `sass-embedded` value to be used with the `sass-loader`. + */ + get info(): string { + return 'sass-embedded\tasync-compiler'; + } + + /** + * The synchronous render function is not used by the `sass-loader`. + */ + compileString(): never { + throw new Error('Sass compileString is not supported.'); + } + + /** + * Asynchronously request a Sass stylesheet to be rendered using the native embedded compiler. + * + * @param source The contents to compile. + * @param options The `sass-embedded` options to use when rendering the stylesheet. + */ + async compileStringAsync( + source: string, + options: StringOptions<'async'>, + ): Promise { + // The CLI's configuration does not use or expose the ability to define custom Sass functions + if (options.functions && Object.keys(options.functions).length > 0) { + throw new Error('Sass custom functions are not supported.'); + } + + const { functions, importers, importer, url, logger, ...serializableOptions } = options; + + let finalImporters: + (Importer<'async'> | FileImporter<'async'> | NodePackageImporter)[] | undefined; + let loadPaths = options.loadPaths; + const entryDirectory = url ? dirname(fileURLToPath(url)) : process.cwd(); + const directoryCache = new Map(); + const rebaseSourceMaps = options.sourceMap ? new Map() : undefined; + + if (importers?.length) { + for (const importer of importers) { + if (!isFileImporter(importer)) { + throw new Error('Only File Importers are supported.'); + } + } + + finalImporters = [ + new AsyncModuleUrlRebasingImporter( + entryDirectory, + directoryCache, + rebaseSourceMaps, + async (specifier: string, options: CanonicalizeContext): Promise => { + for (const importer of importers) { + const result = await (importer as FileImporter<'async'>).findFileUrl( + specifier, + options, + ); + if (result) { + return result; + } + } + + return null; + }, + ), + ]; + } + + if (loadPaths?.length) { + finalImporters ??= []; + finalImporters.push( + new LoadPathsUrlRebasingImporter( + entryDirectory, + directoryCache, + rebaseSourceMaps, + loadPaths, + ), + ); + loadPaths = undefined; + } + + const relativeImporter = new RelativeUrlRebasingImporter( + entryDirectory, + directoryCache, + rebaseSourceMaps, + ); + + const compiler = await this.#ensureAsyncCompiler(); + const result = await compiler.compileStringAsync(source, { + ...serializableOptions, + url, + loadPaths, + importers: finalImporters, + importer: relativeImporter, + logger, + }); + + if (result.sourceMap && rebaseSourceMaps?.size) { + result.sourceMap = mergeSourceMaps( + result.sourceMap as unknown as RawSourceMap, + (file, context) => (file !== context.importer ? rebaseSourceMaps.get(file) : null), + ) as unknown as typeof result.sourceMap; + } + + return result; + } + + /** + * Shutdown the native embedded Sass compiler daemon. + * @returns A void promise that resolves when closing is complete. + */ + async close(): Promise { + if (this.#asyncCompilerPromise) { + try { + await this.#ensureAsyncCompiler(); + } catch { + // Ignore compiler initialization failures on shutdown + } + } + + if (this.#asyncCompiler) { + const compiler = this.#asyncCompiler; + this.#asyncCompiler = undefined; + await compiler.dispose(); + } + } +} diff --git a/packages/angular/build/src/tools/sass/sass-service.ts b/packages/angular/build/src/tools/sass/sass-service.ts index 2df6f85f7a52..1a7c3b7866d8 100644 --- a/packages/angular/build/src/tools/sass/sass-service.ts +++ b/packages/angular/build/src/tools/sass/sass-service.ts @@ -6,261 +6,33 @@ * found in the LICENSE file at https://angular.dev/license */ -import assert from 'node:assert'; -import { fileURLToPath, pathToFileURL } from 'node:url'; -import { MessageChannel } from 'node:worker_threads'; import type { - CanonicalizeContext, CompileResult, - Deprecation, - Exception, FileImporter, Importer, NodePackageImporter, - SourceSpan, StringOptions, -} from 'sass'; -import { maxWorkers } from '../../utils/environment-options'; -import { WorkerPool } from '../../utils/worker-pool'; - -// Polyfill Symbol.dispose if not present -// eslint-disable-next-line @typescript-eslint/no-explicit-any -(Symbol as any).dispose ??= Symbol('Symbol Dispose'); +} from 'sass-embedded'; /** - * The maximum number of Workers that will be created to execute render requests. + * Common interface for Sass service implementations. */ -const MAX_RENDER_WORKERS = maxWorkers; +export interface SassServiceImplementation { + readonly info: string; + compileStringAsync(source: string, options: StringOptions<'async'>): Promise; + close(): Promise; +} /** * All available importer types. */ -type Importers = +export type Importers = | Importer<'sync'> | Importer<'async'> | FileImporter<'sync'> | FileImporter<'async'> | NodePackageImporter; -export interface SerializableVersion { - major: number; - minor: number; - patch: number; -} - -export interface SerializableDeprecation extends Omit { - /** The version this deprecation first became active in. */ - deprecatedIn: SerializableVersion | null; - - /** The version this deprecation became obsolete in. */ - obsoleteIn: SerializableVersion | null; -} - -export type SerializableWarningMessage = ( - | { - deprecation: true; - deprecationType: SerializableDeprecation; - } - | { deprecation: false } -) & { - message: string; - span?: Omit & { url?: string }; - stack?: string; -}; - -/** - * A response from the Sass render Worker containing the result of the operation. - */ -interface RenderResponseMessage { - error?: Exception; - result?: Omit & { loadedUrls: string[] }; - warnings?: SerializableWarningMessage[]; -} - -/** - * A Sass renderer implementation that provides an interface that can be used by Webpack's - * `sass-loader`. The implementation uses a Worker thread to perform the Sass rendering - * with the `dart-sass` package. The `dart-sass` synchronous render function is used within - * the worker which can be up to two times faster than the asynchronous variant. - */ -export class SassWorkerImplementation { - #workerPool: WorkerPool | undefined; - - constructor( - private readonly rebase = false, - readonly maxThreads = MAX_RENDER_WORKERS, - ) {} - - #ensureWorkerPool(): WorkerPool { - this.#workerPool ??= new WorkerPool({ - filename: require.resolve('./worker'), - maxThreads: this.maxThreads, - }); - - return this.#workerPool; - } - - /** - * Provides information about the Sass implementation. - * This mimics enough of the `dart-sass` value to be used with the `sass-loader`. - */ - get info(): string { - return 'dart-sass\tworker'; - } - - /** - * The synchronous render function is not used by the `sass-loader`. - */ - compileString(): never { - throw new Error('Sass compileString is not supported.'); - } - - /** - * Asynchronously request a Sass stylesheet to be renderered. - * - * @param source The contents to compile. - * @param options The `dart-sass` options to use when rendering the stylesheet. - */ - async compileStringAsync( - source: string, - options: StringOptions<'async'>, - ): Promise { - // The `functions`, `logger` and `importer` options are JavaScript functions that cannot be transferred. - // If any additional function options are added in the future, they must be excluded as well. - const { functions, importers, url, logger, ...serializableOptions } = options; - - // The CLI's configuration does not use or expose the ability to define custom Sass functions - if (functions && Object.keys(functions).length > 0) { - throw new Error('Sass custom functions are not supported.'); - } - - using importerChannel = importers?.length ? this.#createImporterChannel(importers) : undefined; - - const response = (await this.#ensureWorkerPool().run( - { - source, - importerChannel, - hasLogger: !!logger, - rebase: this.rebase, - options: { - ...serializableOptions, - // URL is not serializable so to convert to string here and back to URL in the worker. - url: url ? fileURLToPath(url) : undefined, - }, - }, - { - transferList: importerChannel ? [importerChannel.port] : undefined, - }, - )) as RenderResponseMessage; - - const { result, error, warnings } = response; - - if (warnings && logger?.warn) { - for (const { message, span, ...options } of warnings) { - logger.warn(message, { - ...options, - span: span && { - ...span, - url: span.url ? pathToFileURL(span.url) : undefined, - }, - }); - } - } - - if (error) { - // Convert stringified url value required for cloning back to a URL object - const url = error.span?.url as string | undefined; - if (url) { - error.span.url = pathToFileURL(url); - } - - throw error; - } - - assert(result, 'Sass render worker should always return a result or an error'); - - return { - ...result, - // URL is not serializable so in the worker we convert to string and here back to URL. - loadedUrls: result.loadedUrls.map((p) => pathToFileURL(p)), - }; - } - - /** - * Shutdown the Sass render worker. - * Executing this method will stop any pending render requests. - * @returns A void promise that resolves when closing is complete. - */ - async close(): Promise { - if (this.#workerPool) { - try { - await this.#workerPool.destroy(); - } finally { - this.#workerPool = undefined; - } - } - } - - #createImporterChannel(importers: Iterable) { - const { port1: mainImporterPort, port2: workerImporterPort } = new MessageChannel(); - const importerSignal = new Int32Array(new SharedArrayBuffer(4)); - - mainImporterPort.on( - 'message', - ({ url, options }: { url: string; options: CanonicalizeContext }) => { - this.processImporters(importers, url, { - ...options, - // URL is not serializable so in the worker we convert to string and here back to URL. - containingUrl: options.containingUrl - ? pathToFileURL(options.containingUrl as unknown as string) - : null, - }) - .then((result) => { - mainImporterPort.postMessage(result); - }) - .catch((error) => { - mainImporterPort.postMessage(error); - }) - .finally(() => { - Atomics.store(importerSignal, 0, 1); - Atomics.notify(importerSignal, 0); - }); - }, - ); - - mainImporterPort.unref(); - - return { - port: workerImporterPort, - signal: importerSignal, - [Symbol.dispose]() { - mainImporterPort.close(); - }, - }; - } - - private async processImporters( - importers: Iterable, - url: string, - options: CanonicalizeContext, - ): Promise { - for (const importer of importers) { - if (!this.isFileImporter(importer)) { - // Importer - throw new Error('Only File Importers are supported.'); - } - - // File importer (Can be sync or aync). - const result = await importer.findFileUrl(url, options); - if (result) { - return fileURLToPath(result); - } - } - - return null; - } - - private isFileImporter(value: Importers): value is FileImporter { - return 'findFileUrl' in value; - } +export function isFileImporter(value: Importers): value is FileImporter { + return 'findFileUrl' in value; } diff --git a/packages/angular/build/src/tools/sass/sass-worker-implementation.ts b/packages/angular/build/src/tools/sass/sass-worker-implementation.ts new file mode 100644 index 000000000000..9208bef3a803 --- /dev/null +++ b/packages/angular/build/src/tools/sass/sass-worker-implementation.ts @@ -0,0 +1,245 @@ +/** + * @license + * Copyright Google LLC All Rights Reserved. + * + * Use of this source code is governed by an MIT-style license that can be + * found in the LICENSE file at https://angular.dev/license + */ + +import assert from 'node:assert'; +import { fileURLToPath, pathToFileURL } from 'node:url'; +import { MessageChannel } from 'node:worker_threads'; +import type { + CanonicalizeContext, + CompileResult, + Deprecation, + Exception, + SourceSpan, + StringOptions, +} from 'sass-embedded'; +import { maxWorkers } from '../../utils/environment-options'; +import { WorkerPool } from '../../utils/worker-pool'; +import { type Importers, type SassServiceImplementation, isFileImporter } from './sass-service'; + +// Polyfill Symbol.dispose if not present +// eslint-disable-next-line @typescript-eslint/no-explicit-any +(Symbol as any).dispose ??= Symbol('Symbol Dispose'); + +/** + * The maximum number of Workers that will be created to execute render requests. + */ +const MAX_RENDER_WORKERS = maxWorkers; + +export interface SerializableVersion { + major: number; + minor: number; + patch: number; +} + +export interface SerializableDeprecation extends Omit { + /** The version this deprecation first became active in. */ + deprecatedIn: SerializableVersion | null; + + /** The version this deprecation became obsolete in. */ + obsoleteIn: SerializableVersion | null; +} + +export type SerializableWarningMessage = ( + | { + deprecation: true; + deprecationType: SerializableDeprecation; + } + | { deprecation: false } +) & { + message: string; + span?: Omit & { url?: string }; + stack?: string; +}; + +/** + * A response from the Sass render Worker containing the result of the operation. + */ +export interface RenderResponseMessage { + error?: Exception; + result?: Omit & { loadedUrls: string[] }; + warnings?: SerializableWarningMessage[]; +} + +/** + * A Sass renderer implementation that provides an interface that can be used by Webpack's + * `sass-loader` or as a fallback in environments that do not support native binaries. + * The implementation uses a Worker thread pool to perform Sass rendering with the pure-JS + * `sass` package. + */ +export class SassWorkerImplementation implements SassServiceImplementation { + #workerPool: WorkerPool | undefined; + + constructor( + private readonly rebase = false, + readonly maxThreads = MAX_RENDER_WORKERS, + ) {} + + #ensureWorkerPool(): WorkerPool { + this.#workerPool ??= new WorkerPool({ + filename: require.resolve('./worker'), + maxThreads: this.maxThreads, + }); + + return this.#workerPool; + } + + /** + * Provides information about the Sass implementation. + * This mimics enough of the `sass` value to be used with the `sass-loader`. + */ + get info(): string { + return 'dart-sass\tworker'; + } + + /** + * The synchronous render function is not used by the `sass-loader`. + */ + compileString(): never { + throw new Error('Sass compileString is not supported.'); + } + + /** + * Asynchronously request a Sass stylesheet to be rendered using worker threads. + * + * @param source The contents to compile. + * @param options The Sass options to use when rendering the stylesheet. + */ + async compileStringAsync( + source: string, + options: StringOptions<'async'>, + ): Promise { + // The CLI's configuration does not use or expose the ability to define custom Sass functions + if (options.functions && Object.keys(options.functions).length > 0) { + throw new Error('Sass custom functions are not supported.'); + } + + const { functions, importers, importer, url, logger, ...serializableOptions } = options; + using importerChannel = importers?.length ? this.#createImporterChannel(importers) : undefined; + + const response = (await this.#ensureWorkerPool().run( + { + source, + importerChannel, + hasLogger: !!logger, + rebase: this.rebase, + options: { + ...serializableOptions, + // URL is not serializable so to convert to string here and back to URL in the worker. + url: url ? fileURLToPath(url) : undefined, + }, + }, + { + transferList: importerChannel ? [importerChannel.port] : undefined, + }, + )) as RenderResponseMessage; + + const { result, error, warnings } = response; + + if (warnings && logger?.warn) { + for (const { message, span, ...options } of warnings) { + logger.warn(message, { + ...options, + span: span && { + ...span, + url: span.url ? pathToFileURL(span.url) : undefined, + }, + }); + } + } + + if (error) { + // Convert stringified url value required for cloning back to a URL object + const url = error.span?.url as string | undefined; + if (url) { + error.span.url = pathToFileURL(url); + } + + throw error; + } + + assert(result, 'Sass render worker should always return a result or an error'); + + return { + ...result, + // URL is not serializable so in the worker we convert to string and here back to URL. + loadedUrls: result.loadedUrls.map((p) => pathToFileURL(p)), + }; + } + + /** + * Shutdown the Sass render worker. + * Executing this method will stop any pending render requests. + * @returns A void promise that resolves when closing is complete. + */ + async close(): Promise { + if (this.#workerPool) { + const pool = this.#workerPool; + this.#workerPool = undefined; + await pool.destroy(); + } + } + + #createImporterChannel(importers: Iterable) { + const { port1: mainImporterPort, port2: workerImporterPort } = new MessageChannel(); + const importerSignal = new Int32Array(new SharedArrayBuffer(4)); + + mainImporterPort.on( + 'message', + ({ url, options }: { url: string; options: CanonicalizeContext }) => { + this.processImporters(importers, url, { + ...options, + // URL is not serializable so in the worker we convert to string and here back to URL. + containingUrl: options.containingUrl + ? pathToFileURL(options.containingUrl as unknown as string) + : null, + }) + .then((result) => { + mainImporterPort.postMessage(result); + }) + .catch((error) => { + mainImporterPort.postMessage(error); + }) + .finally(() => { + Atomics.store(importerSignal, 0, 1); + Atomics.notify(importerSignal, 0); + }); + }, + ); + + mainImporterPort.unref(); + + return { + port: workerImporterPort, + signal: importerSignal, + [Symbol.dispose]() { + mainImporterPort.close(); + }, + }; + } + + private async processImporters( + importers: Iterable, + url: string, + options: CanonicalizeContext, + ): Promise { + for (const importer of importers) { + if (!isFileImporter(importer)) { + // Importer + throw new Error('Only File Importers are supported.'); + } + + // File importer (Can be sync or aync). + const result = await importer.findFileUrl(url, options); + if (result) { + return fileURLToPath(result); + } + } + + return null; + } +} diff --git a/packages/angular/build/src/tools/sass/worker.ts b/packages/angular/build/src/tools/sass/worker.ts index e4167a3d1c69..2416fe21e5cd 100644 --- a/packages/angular/build/src/tools/sass/worker.ts +++ b/packages/angular/build/src/tools/sass/worker.ts @@ -25,7 +25,10 @@ import { RelativeUrlRebasingImporter, sassBindWorkaround, } from './rebasing-importer'; -import type { SerializableDeprecation, SerializableWarningMessage } from './sass-service'; +import type { + SerializableDeprecation, + SerializableWarningMessage, +} from './sass-worker-implementation'; /** * A request to render a Sass stylesheet using the supplied options. diff --git a/packages/angular/build/src/utils/environment-options.ts b/packages/angular/build/src/utils/environment-options.ts index 206467e929a0..c9ac132e7887 100644 --- a/packages/angular/build/src/utils/environment-options.ts +++ b/packages/angular/build/src/utils/environment-options.ts @@ -201,6 +201,13 @@ export const usePartialSsrBuild = parseTristate(process.env['NG_BUILD_PARTIAL_SS */ export const useBabelLinker = parseTristate(process.env['NG_BUILD_BABEL_LINKER']) === true; +/** + * When `NG_BUILD_SASS_WORKER` is enabled (`1` or `true`), the worker-based + * Sass implementation will be used instead of the native asynchronous compiler. + */ +export const useSassWorker = + !!process.versions.webcontainer || parseTristate(process.env['NG_BUILD_SASS_WORKER']) === true; + const bazelBinDirectory = process.env['BAZEL_BINDIR']; const bazelExecRoot = process.env['JS_BINARY__EXECROOT']; diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index ad8a28e1ca05..6bab452d7092 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -321,7 +321,7 @@ importers: version: 7.8.2 vitest: specifier: 4.1.11 - version: 4.1.11(@opentelemetry/api@1.9.1)(@types/node@22.20.1)(@vitest/coverage-v8@4.1.11)(esbuild@0.28.2)(jiti@2.7.0)(jsdom@30.0.1)(less@4.9.0(supports-color@11.0.0))(sass@1.103.1)(terser@5.50.0)(tsx@4.23.12)(yaml@2.9.0) + version: 4.1.11(@opentelemetry/api@1.9.1)(@types/node@22.20.1)(@vitest/coverage-v8@4.1.11)(esbuild@0.28.2)(jiti@2.7.0)(jsdom@30.0.1)(less@4.9.0(supports-color@11.0.0))(sass-embedded@1.103.1)(sass@1.103.1)(terser@5.50.0)(tsx@4.23.12)(yaml@2.9.0) packages/angular/build: dependencies: @@ -342,7 +342,7 @@ importers: version: 2.6.0 '@vitejs/plugin-basic-ssl': specifier: 2.3.0 - version: 2.3.0(vite@8.2.2(@types/node@22.20.1)(esbuild@0.28.2)(jiti@2.7.0)(less@4.9.0(supports-color@11.0.0))(sass@1.103.1)(terser@5.50.0)(tsx@4.23.12)(yaml@2.9.0)) + version: 2.3.0(vite@8.2.2(@types/node@22.20.1)(esbuild@0.28.2)(jiti@2.7.0)(less@4.9.0(supports-color@11.0.0))(sass-embedded@1.103.1)(sass@1.103.1)(terser@5.50.0)(tsx@4.23.12)(yaml@2.9.0)) beasties: specifier: 0.4.3 version: 0.4.3 @@ -388,6 +388,9 @@ importers: sass: specifier: 1.103.1 version: 1.103.1 + sass-embedded: + specifier: 1.103.1 + version: 1.103.1 semver: specifier: 7.8.5 version: 7.8.5 @@ -399,7 +402,7 @@ importers: version: 0.2.17 vite: specifier: 8.2.2 - version: 8.2.2(@types/node@22.20.1)(esbuild@0.28.2)(jiti@2.7.0)(less@4.9.0(supports-color@11.0.0))(sass@1.103.1)(terser@5.50.0)(tsx@4.23.12)(yaml@2.9.0) + version: 8.2.2(@types/node@22.20.1)(esbuild@0.28.2)(jiti@2.7.0)(less@4.9.0(supports-color@11.0.0))(sass-embedded@1.103.1)(sass@1.103.1)(terser@5.50.0)(tsx@4.23.12)(yaml@2.9.0) xxhash-wasm: specifier: 1.1.0 version: 1.1.0 @@ -436,7 +439,7 @@ importers: version: 7.8.2 vitest: specifier: 4.1.11 - version: 4.1.11(@opentelemetry/api@1.9.1)(@types/node@22.20.1)(@vitest/coverage-v8@4.1.11)(esbuild@0.28.2)(jiti@2.7.0)(jsdom@30.0.1)(less@4.9.0(supports-color@11.0.0))(sass@1.103.1)(terser@5.50.0)(tsx@4.23.12)(yaml@2.9.0) + version: 4.1.11(@opentelemetry/api@1.9.1)(@types/node@22.20.1)(@vitest/coverage-v8@4.1.11)(esbuild@0.28.2)(jiti@2.7.0)(jsdom@30.0.1)(less@4.9.0(supports-color@11.0.0))(sass-embedded@1.103.1)(sass@1.103.1)(terser@5.50.0)(tsx@4.23.12)(yaml@2.9.0) optionalDependencies: lmdb: specifier: 3.5.6 @@ -669,7 +672,7 @@ importers: version: 1.103.1 sass-loader: specifier: 17.0.0 - version: 17.0.0(sass@1.103.1)(webpack@5.109.2(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.26)(uglify-js@3.19.3)) + version: 17.0.0(sass-embedded@1.103.1)(sass@1.103.1)(webpack@5.109.2(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.26)(uglify-js@3.19.3)) semver: specifier: 7.8.5 version: 7.8.5 @@ -1564,6 +1567,9 @@ packages: resolution: {integrity: sha512-ctxtJ/eA+t+6q2++vj5j7FYX3nRu311q1wfYH3xjlLOsczhlhxAg2FWNUXhpGvAw3BWo1xBcvOV6/YLc2r5FJw==} hasBin: true + '@bufbuild/protobuf@2.14.0': + resolution: {integrity: sha512-C3UGsiCwSprE2NKIIFA3hCDlpXTMCAXRZuEVp88L1GY36Y41+rYL5fryE+nOFhp4p4JPQvdV8PQ4DWgHgeTE+w==} + '@colors/colors@1.5.0': resolution: {integrity: sha512-ooWCrlZP11i8GImSjTHYHLkvFDP48nS4+204nGb1RiX/WXYHmJA2III9/e2DWVabCESdW7hBAEzHRqUn9OUVvQ==} engines: {node: '>=0.1.90'} @@ -4518,6 +4524,9 @@ packages: colorette@2.0.20: resolution: {integrity: sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w==} + colorjs.io@0.7.1: + resolution: {integrity: sha512-LY7OHnJZxHwT5UlzNa9bbhHHDbzB6yE5+3MIPwJEQKRvSCt/T4G7epsj+9j2BExUIIfXFIJGsIXUKdfrK9Q5tA==} + colors@1.4.0: resolution: {integrity: sha512-a+UqTh4kgZg/SlGvfbzDHpgRu7AAQOmmqRHJnxhRZICKFUT91brVhNNt58CMWU9PsBbv3PDCZUHbVxuDiH2mtA==} engines: {node: '>=0.1.90'} @@ -7320,6 +7329,123 @@ packages: sanitize-filename@1.6.4: resolution: {integrity: sha512-9ZyI08PsvdQl2r/bBIGubpVdR3RR9sY6RDiWFPreA21C/EFlQhmgo20UZlNjZMMZNubusLhAQozkA0Od5J21Eg==} + sass-embedded-all-unknown@1.103.1: + resolution: {integrity: sha512-MwX2ap06TbImAqlbnH6EndgBBejk6Eq2QB6Ae2hukCn9wmXf9cRu27um3mz3tyB4oJOOku0xfHqFH/+ckYj6YA==} + cpu: ['!arm', '!arm64', '!riscv64', '!x64'] + + sass-embedded-android-arm64@1.103.1: + resolution: {integrity: sha512-jBXWMksyz55XeLOWvQs64BqiG5DcqflmMxcvMoA2oHtQT/7XZ02hBn502qpcF/q8Qd+qqG/hU5ccM+hGXrbQZw==} + engines: {node: '>=14.0.0'} + cpu: [arm64] + os: [android] + + sass-embedded-android-arm@1.103.1: + resolution: {integrity: sha512-p36WHpsu5HEo2+NVNbI2Nmb8VgVH0xwOQyzghvZhF7ikGCzEVYI5BP28vHUZlCcgj2TUvMEJKI2lV336a+F/sg==} + engines: {node: '>=14.0.0'} + cpu: [arm] + os: [android] + + sass-embedded-android-riscv64@1.103.1: + resolution: {integrity: sha512-rzrH7RNntk0rx+zCE9xOiAIUt37D1cQKvFfcoX0xiePdGbNHBN8DWKaWN9vaCRfbgKCmxPjevzaqFNI/G/8E1A==} + engines: {node: '>=14.0.0'} + cpu: [riscv64] + os: [android] + + sass-embedded-android-x64@1.103.1: + resolution: {integrity: sha512-EQglAJXJutuIcqgZf7YOwzao2ND6ow/OgqN+cM48/Qaeb6AimYmZiUJmM9FFcmS3Q2n1k6/2OU3l3Hlin7bFpw==} + engines: {node: '>=14.0.0'} + cpu: [x64] + os: [android] + + sass-embedded-darwin-arm64@1.103.1: + resolution: {integrity: sha512-rlaBeCul8pLbDRKdBAxdDxSBwFU5fbX42ci6CxW2Vbs34jWTMQ72+nE2v2KkGGce+JnYbb7UV6xDP/4uDWWi+w==} + engines: {node: '>=14.0.0'} + cpu: [arm64] + os: [darwin] + + sass-embedded-darwin-x64@1.103.1: + resolution: {integrity: sha512-VSKFfhI//AOct6ppFmAaSH7tlW2LOFECMGs77jIoWf0ZjvGch/3sc9lUTTdIaYIOnTS4qpZck+8OcI2D0G92QA==} + engines: {node: '>=14.0.0'} + cpu: [x64] + os: [darwin] + + sass-embedded-linux-arm64@1.103.1: + resolution: {integrity: sha512-rC+80/Xr9svo0ka2Zr/sjD+N1zEHTw2Urm/nsEjaVp5HSH2i22jwhTKTIqie2OLl6ti+qdYnbI0sSfxOYRtgrg==} + engines: {node: '>=14.0.0'} + cpu: [arm64] + os: [linux] + libc: glibc + + sass-embedded-linux-arm@1.103.1: + resolution: {integrity: sha512-tJRLPUtBwXHTnBnG7I39gQvCLreuOHLLCMyKHPR1hQ7aFNwiZjADYzKMRQPNMUqti/Os9z+6I7V13FqgQHfuzg==} + engines: {node: '>=14.0.0'} + cpu: [arm] + os: [linux] + libc: glibc + + sass-embedded-linux-musl-arm64@1.103.1: + resolution: {integrity: sha512-jMgG/C/VMo7+ShMFdk0xjJmQmYkj1PbJu/yrQiaQHpuo5pE2G+vnkEgsuM5EM3lTQ4MbMfnf715qy1fkbNPiUQ==} + engines: {node: '>=14.0.0'} + cpu: [arm64] + os: [linux] + libc: musl + + sass-embedded-linux-musl-arm@1.103.1: + resolution: {integrity: sha512-N8L/kgVzXpnH+8d6ErIzqvb0l8kHODR3OfPaf0Azw6DOLGtEjwDRUbHno+G7iogGzyPOjKsM8OdyqHJj/bpTdw==} + engines: {node: '>=14.0.0'} + cpu: [arm] + os: [linux] + libc: musl + + sass-embedded-linux-musl-riscv64@1.103.1: + resolution: {integrity: sha512-LZm8rEvI6sKU87qPOlODsYeAs7CmWy0B4ShYkjG4OMcGCcV4Ffxn25XW4TFqmruThITQvJ8WT+WGblzdoxYgbA==} + engines: {node: '>=14.0.0'} + cpu: [riscv64] + os: [linux] + libc: musl + + sass-embedded-linux-musl-x64@1.103.1: + resolution: {integrity: sha512-rmKzgk4t6RpaDhSefbbnk5yrA4pk1nHlVhJECGay8yMfzK8eglATeY9fzPgt89xCuQk6rkOiy11e+m8tLYOW5Q==} + engines: {node: '>=14.0.0'} + cpu: [x64] + os: [linux] + libc: musl + + sass-embedded-linux-riscv64@1.103.1: + resolution: {integrity: sha512-xydQmtxla31uMrmN6z+mAogVGdEMDmkUElVq2+udomX/TPZDYJBkApEyJl237M2VLWVv29v1N4U4i2Z4xa7SDA==} + engines: {node: '>=14.0.0'} + cpu: [riscv64] + os: [linux] + libc: glibc + + sass-embedded-linux-x64@1.103.1: + resolution: {integrity: sha512-Rln1oWm0MWKzzemOgQWrRFzfVBARwS9qxAidZPpCQHSohzPnWizFkmY1CUJad/YJNsA7sscueMdX63OEvxoM8w==} + engines: {node: '>=14.0.0'} + cpu: [x64] + os: [linux] + libc: glibc + + sass-embedded-unknown-all@1.103.1: + resolution: {integrity: sha512-p7kI4US8+n+YguKczXh+4KcodJnk+8cwv+QFdvMaz3OfPrdHV0EnhPsaVDWD9qXb1XXCEdUhpp6vQwGk3eKc3A==} + os: ['!android', '!darwin', '!linux', '!win32'] + + sass-embedded-win32-arm64@1.103.1: + resolution: {integrity: sha512-/0renOj3SpZGu4TA8CZJ6qZbTxGZk1khkPfiBTmV1uFB40ESYM5VsdXNj76P07bsAjIj9X2fCjTafLQFLSd9Nw==} + engines: {node: '>=14.0.0'} + cpu: [arm64] + os: [win32] + + sass-embedded-win32-x64@1.103.1: + resolution: {integrity: sha512-fIg60j9u5YlLUU3W8FvySMR4HHIo9R12HHFQTW7njyQ8nXqgR+t+XfCzGJloQka8g583BlAfu31Q76Ljr5o+9g==} + engines: {node: '>=14.0.0'} + cpu: [x64] + os: [win32] + + sass-embedded@1.103.1: + resolution: {integrity: sha512-UVIuFZPzz+4DXYbHzQ5gKaKkyP2IH3Sc/WoF63N2V7QIfnC2E9UpQAtiKlCVJTfBe43HRgHDBLnXpZkYAEBsNQ==} + engines: {node: '>=20.19.0'} + hasBin: true + sass-loader@17.0.0: resolution: {integrity: sha512-0Ybm8ohBQ9LcrycVrFQp/KQBNX5a3Wda9/smS0mE/xLffzEnwvV8nykOzrbiSWNzTE3IB/jiXx8O4QmDPG2+Gw==} engines: {node: '>= 22.11.0'} @@ -7661,6 +7787,14 @@ packages: symbol-tree@3.2.4: resolution: {integrity: sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==} + sync-child-process@1.0.2: + resolution: {integrity: sha512-8lD+t2KrrScJ/7KXCSyfhT3/hRq78rC0wBFqNJXv3mZyn6hW2ypM05JmlSvtqRbeq6jqA94oHbxAr2vYsJ8vDA==} + engines: {node: '>=16.0.0'} + + sync-message-port@1.2.0: + resolution: {integrity: sha512-gAQ9qrUN/UCypHtGFbbe7Rc/f9bzO88IwrG8TDo/aMKAApKyD6E3W4Cm0EfhfBb6Z6SKt59tTCTfD+n1xmAvMg==} + engines: {node: '>=16.0.0'} + tagged-tag@1.0.0: resolution: {integrity: sha512-yEFYrVhod+hdNyx7g5Bnkkb0G6si8HJurOoOEgC8B/O0uXLHlaey/65KRv6cuWBNhBgHKAROVpc7QyYqE5gFng==} engines: {node: '>=20'} @@ -7974,6 +8108,9 @@ packages: resolution: {integrity: sha512-spH26xU080ydGggxRyR1Yhcbgx+j3y5jbNXk/8L+iRvdIEQ4uTRH2Sgf2dokud6Q4oAtsbNvJ1Ft+9xmm6IZcA==} engines: {node: '>= 0.10'} + varint@6.0.0: + resolution: {integrity: sha512-cXEIW6cfr15lFv563k4GuVuW/fiwjknytD37jIOLSdSWuOI6WnO/oKwmP2FQTU2l01LP8/M5TSAJpzUaGe3uWg==} + vary@1.1.2: resolution: {integrity: sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==} engines: {node: '>= 0.8'} @@ -9240,6 +9377,8 @@ snapshots: dependencies: css-tree: 3.2.1 + '@bufbuild/protobuf@2.14.0': {} + '@colors/colors@1.5.0': {} '@conventional-changelog/git-client@3.1.2(conventional-commits-filter@6.0.1)(conventional-commits-parser@7.1.2)': @@ -11503,9 +11642,9 @@ snapshots: lodash: 4.18.1 minimatch: 10.2.6 - '@vitejs/plugin-basic-ssl@2.3.0(vite@8.2.2(@types/node@22.20.1)(esbuild@0.28.2)(jiti@2.7.0)(less@4.9.0(supports-color@11.0.0))(sass@1.103.1)(terser@5.50.0)(tsx@4.23.12)(yaml@2.9.0))': + '@vitejs/plugin-basic-ssl@2.3.0(vite@8.2.2(@types/node@22.20.1)(esbuild@0.28.2)(jiti@2.7.0)(less@4.9.0(supports-color@11.0.0))(sass-embedded@1.103.1)(sass@1.103.1)(terser@5.50.0)(tsx@4.23.12)(yaml@2.9.0))': dependencies: - vite: 8.2.2(@types/node@22.20.1)(esbuild@0.28.2)(jiti@2.7.0)(less@4.9.0(supports-color@11.0.0))(sass@1.103.1)(terser@5.50.0)(tsx@4.23.12)(yaml@2.9.0) + vite: 8.2.2(@types/node@22.20.1)(esbuild@0.28.2)(jiti@2.7.0)(less@4.9.0(supports-color@11.0.0))(sass-embedded@1.103.1)(sass@1.103.1)(terser@5.50.0)(tsx@4.23.12)(yaml@2.9.0) '@vitest/coverage-v8@4.1.11(vitest@4.1.11)': dependencies: @@ -11519,7 +11658,7 @@ snapshots: obug: 2.1.4 std-env: 4.2.0 tinyrainbow: 3.1.1 - vitest: 4.1.11(@opentelemetry/api@1.9.1)(@types/node@22.20.1)(@vitest/coverage-v8@4.1.11)(esbuild@0.28.2)(jiti@2.7.0)(jsdom@30.0.1)(less@4.9.0(supports-color@11.0.0))(sass@1.103.1)(terser@5.50.0)(tsx@4.23.12)(yaml@2.9.0) + vitest: 4.1.11(@opentelemetry/api@1.9.1)(@types/node@22.20.1)(@vitest/coverage-v8@4.1.11)(esbuild@0.28.2)(jiti@2.7.0)(jsdom@30.0.1)(less@4.9.0(supports-color@11.0.0))(sass-embedded@1.103.1)(sass@1.103.1)(terser@5.50.0)(tsx@4.23.12)(yaml@2.9.0) '@vitest/expect@4.1.11': dependencies: @@ -11530,13 +11669,13 @@ snapshots: chai: 6.2.2 tinyrainbow: 3.1.1 - '@vitest/mocker@4.1.11(vite@8.2.2(@types/node@22.20.1)(esbuild@0.28.2)(jiti@2.7.0)(less@4.9.0(supports-color@11.0.0))(sass@1.103.1)(terser@5.50.0)(tsx@4.23.12)(yaml@2.9.0))': + '@vitest/mocker@4.1.11(vite@8.2.2(@types/node@22.20.1)(esbuild@0.28.2)(jiti@2.7.0)(less@4.9.0(supports-color@11.0.0))(sass-embedded@1.103.1)(sass@1.103.1)(terser@5.50.0)(tsx@4.23.12)(yaml@2.9.0))': dependencies: '@vitest/spy': 4.1.11 estree-walker: 3.0.3 magic-string: 0.30.21 optionalDependencies: - vite: 8.2.2(@types/node@22.20.1)(esbuild@0.28.2)(jiti@2.7.0)(less@4.9.0(supports-color@11.0.0))(sass@1.103.1)(terser@5.50.0)(tsx@4.23.12)(yaml@2.9.0) + vite: 8.2.2(@types/node@22.20.1)(esbuild@0.28.2)(jiti@2.7.0)(less@4.9.0(supports-color@11.0.0))(sass-embedded@1.103.1)(sass@1.103.1)(terser@5.50.0)(tsx@4.23.12)(yaml@2.9.0) '@vitest/pretty-format@4.1.11': dependencies: @@ -12300,6 +12439,8 @@ snapshots: colorette@2.0.20: {} + colorjs.io@0.7.1: {} + colors@1.4.0: {} combined-stream@1.0.8: @@ -15511,9 +15652,97 @@ snapshots: dependencies: truncate-utf8-bytes: 1.0.2 - sass-loader@17.0.0(sass@1.103.1)(webpack@5.109.2(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.26)(uglify-js@3.19.3)): + sass-embedded-all-unknown@1.103.1: + dependencies: + sass: 1.103.1 + optional: true + + sass-embedded-android-arm64@1.103.1: + optional: true + + sass-embedded-android-arm@1.103.1: + optional: true + + sass-embedded-android-riscv64@1.103.1: + optional: true + + sass-embedded-android-x64@1.103.1: + optional: true + + sass-embedded-darwin-arm64@1.103.1: + optional: true + + sass-embedded-darwin-x64@1.103.1: + optional: true + + sass-embedded-linux-arm64@1.103.1: + optional: true + + sass-embedded-linux-arm@1.103.1: + optional: true + + sass-embedded-linux-musl-arm64@1.103.1: + optional: true + + sass-embedded-linux-musl-arm@1.103.1: + optional: true + + sass-embedded-linux-musl-riscv64@1.103.1: + optional: true + + sass-embedded-linux-musl-x64@1.103.1: + optional: true + + sass-embedded-linux-riscv64@1.103.1: + optional: true + + sass-embedded-linux-x64@1.103.1: + optional: true + + sass-embedded-unknown-all@1.103.1: + dependencies: + sass: 1.103.1 + optional: true + + sass-embedded-win32-arm64@1.103.1: + optional: true + + sass-embedded-win32-x64@1.103.1: + optional: true + + sass-embedded@1.103.1: + dependencies: + '@bufbuild/protobuf': 2.14.0 + colorjs.io: 0.7.1 + immutable: 5.1.9 + rxjs: 7.8.2 + supports-color: 8.1.1 + sync-child-process: 1.0.2 + varint: 6.0.0 + optionalDependencies: + sass-embedded-all-unknown: 1.103.1 + sass-embedded-android-arm: 1.103.1 + sass-embedded-android-arm64: 1.103.1 + sass-embedded-android-riscv64: 1.103.1 + sass-embedded-android-x64: 1.103.1 + sass-embedded-darwin-arm64: 1.103.1 + sass-embedded-darwin-x64: 1.103.1 + sass-embedded-linux-arm: 1.103.1 + sass-embedded-linux-arm64: 1.103.1 + sass-embedded-linux-musl-arm: 1.103.1 + sass-embedded-linux-musl-arm64: 1.103.1 + sass-embedded-linux-musl-riscv64: 1.103.1 + sass-embedded-linux-musl-x64: 1.103.1 + sass-embedded-linux-riscv64: 1.103.1 + sass-embedded-linux-x64: 1.103.1 + sass-embedded-unknown-all: 1.103.1 + sass-embedded-win32-arm64: 1.103.1 + sass-embedded-win32-x64: 1.103.1 + + sass-loader@17.0.0(sass-embedded@1.103.1)(sass@1.103.1)(webpack@5.109.2(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.26)(uglify-js@3.19.3)): optionalDependencies: sass: 1.103.1 + sass-embedded: 1.103.1 webpack: 5.109.2(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.26)(uglify-js@3.19.3) sass@1.103.1: @@ -15941,6 +16170,12 @@ snapshots: symbol-tree@3.2.4: {} + sync-child-process@1.0.2: + dependencies: + sync-message-port: 1.2.0 + + sync-message-port@1.2.0: {} + tagged-tag@1.0.0: {} tapable@2.3.3: {} @@ -16247,6 +16482,8 @@ snapshots: validator@13.15.26: {} + varint@6.0.0: {} + vary@1.1.2: {} verdaccio-audit@13.1.2(encoding@0.1.13)(supports-color@11.0.0): @@ -16325,7 +16562,7 @@ snapshots: core-util-is: 1.0.2 extsprintf: 1.3.0 - vite@8.2.2(@types/node@22.20.1)(esbuild@0.28.2)(jiti@2.7.0)(less@4.9.0(supports-color@11.0.0))(sass@1.103.1)(terser@5.50.0)(tsx@4.23.12)(yaml@2.9.0): + vite@8.2.2(@types/node@22.20.1)(esbuild@0.28.2)(jiti@2.7.0)(less@4.9.0(supports-color@11.0.0))(sass-embedded@1.103.1)(sass@1.103.1)(terser@5.50.0)(tsx@4.23.12)(yaml@2.9.0): dependencies: lightningcss: 1.33.0 picomatch: 4.0.5 @@ -16339,14 +16576,15 @@ snapshots: jiti: 2.7.0 less: 4.9.0(supports-color@11.0.0) sass: 1.103.1 + sass-embedded: 1.103.1 terser: 5.50.0 tsx: 4.23.12 yaml: 2.9.0 - vitest@4.1.11(@opentelemetry/api@1.9.1)(@types/node@22.20.1)(@vitest/coverage-v8@4.1.11)(esbuild@0.28.2)(jiti@2.7.0)(jsdom@30.0.1)(less@4.9.0(supports-color@11.0.0))(sass@1.103.1)(terser@5.50.0)(tsx@4.23.12)(yaml@2.9.0): + vitest@4.1.11(@opentelemetry/api@1.9.1)(@types/node@22.20.1)(@vitest/coverage-v8@4.1.11)(esbuild@0.28.2)(jiti@2.7.0)(jsdom@30.0.1)(less@4.9.0(supports-color@11.0.0))(sass-embedded@1.103.1)(sass@1.103.1)(terser@5.50.0)(tsx@4.23.12)(yaml@2.9.0): dependencies: '@vitest/expect': 4.1.11 - '@vitest/mocker': 4.1.11(vite@8.2.2(@types/node@22.20.1)(esbuild@0.28.2)(jiti@2.7.0)(less@4.9.0(supports-color@11.0.0))(sass@1.103.1)(terser@5.50.0)(tsx@4.23.12)(yaml@2.9.0)) + '@vitest/mocker': 4.1.11(vite@8.2.2(@types/node@22.20.1)(esbuild@0.28.2)(jiti@2.7.0)(less@4.9.0(supports-color@11.0.0))(sass-embedded@1.103.1)(sass@1.103.1)(terser@5.50.0)(tsx@4.23.12)(yaml@2.9.0)) '@vitest/pretty-format': 4.1.11 '@vitest/runner': 4.1.11 '@vitest/snapshot': 4.1.11 @@ -16363,7 +16601,7 @@ snapshots: tinyexec: 1.3.0 tinyglobby: 0.2.17 tinyrainbow: 3.1.1 - vite: 8.2.2(@types/node@22.20.1)(esbuild@0.28.2)(jiti@2.7.0)(less@4.9.0(supports-color@11.0.0))(sass@1.103.1)(terser@5.50.0)(tsx@4.23.12)(yaml@2.9.0) + vite: 8.2.2(@types/node@22.20.1)(esbuild@0.28.2)(jiti@2.7.0)(less@4.9.0(supports-color@11.0.0))(sass-embedded@1.103.1)(sass@1.103.1)(terser@5.50.0)(tsx@4.23.12)(yaml@2.9.0) why-is-node-running: 2.3.0 optionalDependencies: '@opentelemetry/api': 1.9.1 From 701bde4818439de0e49c99d57dc749b0dd22c4dd Mon Sep 17 00:00:00 2001 From: Charles Lyding <19598772+clydin@users.noreply.github.com> Date: Wed, 26 Aug 2026 19:24:20 -0400 Subject: [PATCH 353/787] fix(@angular/build): preserve duplicate bundle filenames across output file types When building applications with SSR and Service Worker enabled, bundle outputs (such as CSS chunks produced from JS imports) can share the same relative path name across different `BuildOutputFileType`s (e.g. `BuildOutputFileType.Browser` and `BuildOutputFileType.ServerApplication`). Previously, build results stored output files in a Record keyed by file path, which caused server files to overwrite browser files of the same name and prevented them from being emitted to the browser output directory. The build `Result` interface now maintains `files` as an array (`ResultFile[]`), and rebuild tracking keys output files using a compound type and path key, ensuring all files are preserved and emitted correctly regardless of type. Closes #33922 --- .../src/builders/application/build-action.ts | 108 +++++++++++------- .../build/src/builders/application/index.ts | 4 +- .../build/src/builders/application/results.ts | 5 +- .../tests/options/service-worker_spec.ts | 37 +++++- .../src/builders/dev-server/vite/index.ts | 20 +--- .../src/builders/dev-server/vite/utils.ts | 13 ++- .../extract-i18n/application-extraction.ts | 13 ++- .../src/builders/karma/application_builder.ts | 2 +- .../src/builders/karma/assets-middleware.ts | 11 +- .../src/builders/karma/progress-reporter.ts | 12 +- .../angular/build/src/builders/karma/utils.ts | 8 +- .../build/src/builders/unit-test/builder.ts | 2 +- .../unit-test/runners/vitest/executor.ts | 8 +- .../tools/esbuild/bundler-execution-result.ts | 9 +- .../angular/build/src/tools/esbuild/utils.ts | 2 +- .../angular/build/src/utils/test-files.ts | 11 +- .../extract-i18n/application-extraction.ts | 13 ++- 17 files changed, 167 insertions(+), 111 deletions(-) diff --git a/packages/angular/build/src/builders/application/build-action.ts b/packages/angular/build/src/builders/application/build-action.ts index e71663765274..3f8d24da6ecc 100644 --- a/packages/angular/build/src/builders/application/build-action.ts +++ b/packages/angular/build/src/builders/application/build-action.ts @@ -9,7 +9,11 @@ import { BuilderContext } from '@angular-devkit/architect'; import { existsSync } from 'node:fs'; import path from 'node:path'; -import { ExecutionResult, RebuildState } from '../../tools/esbuild/bundler-execution-result'; +import { + BuildOutputAsset, + ExecutionResult, + RebuildState, +} from '../../tools/esbuild/bundler-execution-result'; import { BuildOutputFile, BuildOutputFileType } from '../../tools/esbuild/bundler-files'; import { shutdownSassWorkerPool } from '../../tools/esbuild/stylesheets/sass-language'; import { logMessages, withNoProgress, withSpinner } from '../../tools/esbuild/utils'; @@ -279,34 +283,15 @@ function* emitOutputResults( // Use a full result if there is no rebuild state (no prior build result) if (!rebuildState || !changes) { - const result: FullResult = { - kind: ResultKind.Full, - warnings: warnings as ResultMessage[], - files: {}, - detail: { - externalMetadata, - htmlIndexPath, - htmlBaseHref, - outputOptions, - }, - }; - for (const file of assetFiles) { - result.files[file.destination] = { - type: BuildOutputFileType.Browser, - inputPath: file.source, - origin: 'disk', - }; - } - for (const file of outputFiles) { - result.files[file.path] = { - type: file.type, - contents: file.contents, - origin: 'memory', - hash: file.hash, - }; - } - - yield result; + yield createFullResult( + outputFiles, + assetFiles, + warnings, + outputOptions, + externalMetadata, + htmlIndexPath, + htmlBaseHref, + ); return; } @@ -326,7 +311,7 @@ function* emitOutputResults( added: [], removed: [], modified: [], - files: {}, + files: [], detail: { externalMetadata, htmlIndexPath, @@ -340,9 +325,10 @@ function* emitOutputResults( // Initially assume all previous output files have been removed const removedOutputFiles = new Map(previousOutputInfo); for (const file of outputFiles) { - removedOutputFiles.delete(file.path); + const key = `${file.type}:${file.path}`; + removedOutputFiles.delete(key); - const previousHash = previousOutputInfo.get(file.path)?.hash; + const previousHash = previousOutputInfo.get(key)?.hash; let needFile = false; if (previousHash === undefined) { needFile = true; @@ -359,12 +345,13 @@ function* emitOutputResults( incrementalResult.background = false; } - incrementalResult.files[file.path] = { + incrementalResult.files.push({ + path: file.path, type: file.type, contents: file.contents, origin: 'memory', hash: file.hash, - }; + }); } } @@ -385,11 +372,12 @@ function* emitOutputResults( hasCssUpdates ||= destination.endsWith('.css'); - incrementalResult.files[destination] = { + incrementalResult.files.push({ + path: destination, type: BuildOutputFileType.Browser, inputPath: source, origin: 'disk', - }; + }); } // Do not remove stale files yet if there are template updates. @@ -403,12 +391,12 @@ function* emitOutputResults( // Include the removed output and asset files incrementalResult.removed.push( - ...Array.from(removedOutputFiles, ([file, { type }]) => ({ - path: file, + ...Array.from(removedOutputFiles.values(), ({ type, path }) => ({ + path, type, })), - ...Array.from(removedAssetFiles.values(), (file) => ({ - path: file, + ...Array.from(removedAssetFiles.values(), (path) => ({ + path, type: BuildOutputFileType.Browser, })), ); @@ -425,9 +413,7 @@ function* emitOutputResults( added: incrementalResult.added.filter(isCssFilePath), removed: incrementalResult.removed.filter(({ path }) => isCssFilePath(path)), modified: incrementalResult.modified.filter(isCssFilePath), - files: Object.fromEntries( - Object.entries(incrementalResult.files).filter(([path]) => isCssFilePath(path)), - ), + files: incrementalResult.files.filter((file) => isCssFilePath(file.path)), }; yield styleResult; @@ -446,6 +432,42 @@ function* emitOutputResults( } } +function createFullResult( + outputFiles: readonly BuildOutputFile[], + assetFiles: readonly BuildOutputAsset[], + warnings: readonly unknown[], + outputOptions: NormalizedApplicationBuildOptions['outputOptions'], + externalMetadata: unknown, + htmlIndexPath: unknown, + htmlBaseHref: unknown, +): FullResult { + return { + kind: ResultKind.Full, + warnings: warnings as ResultMessage[], + files: [ + ...assetFiles.map(({ source, destination }) => ({ + path: destination, + type: BuildOutputFileType.Browser, + inputPath: source, + origin: 'disk' as const, + })), + ...outputFiles.map((file) => ({ + path: file.path, + type: file.type, + contents: file.contents, + origin: 'memory' as const, + hash: file.hash, + })), + ], + detail: { + externalMetadata, + htmlIndexPath, + htmlBaseHref, + outputOptions, + }, + }; +} + function isCssFilePath(filePath: string): boolean { return /\.css(?:\.map)?$/i.test(filePath); } diff --git a/packages/angular/build/src/builders/application/index.ts b/packages/angular/build/src/builders/application/index.ts index b31fc0a8f81b..59ded1cd8182 100644 --- a/packages/angular/build/src/builders/application/index.ts +++ b/packages/angular/build/src/builders/application/index.ts @@ -199,7 +199,7 @@ export async function* buildApplication( // Writes the output files to disk and ensures the containing directories are present const directoryExists = new Set(); try { - await emitFilesToDisk(Object.entries(result.files), async ([filePath, file]) => { + await emitFilesToDisk(result.files, async (file) => { if ( outputOptions.ignoreServer && (file.type === BuildOutputFileType.ServerApplication || @@ -208,7 +208,7 @@ export async function* buildApplication( return; } - const fullFilePath = generateFullPath(filePath, file.type, outputOptions); + const fullFilePath = generateFullPath(file.path, file.type, outputOptions); // Ensure output subdirectories exist const fileBasePath = path.dirname(fullFilePath); diff --git a/packages/angular/build/src/builders/application/results.ts b/packages/angular/build/src/builders/application/results.ts index 6fa23f9f19cd..8e95176639f5 100644 --- a/packages/angular/build/src/builders/application/results.ts +++ b/packages/angular/build/src/builders/application/results.ts @@ -31,7 +31,7 @@ export interface FailureResult extends BaseResult { export interface FullResult extends BaseResult { kind: ResultKind.Full; - files: Record; + files: ResultFile[]; } export interface IncrementalResult extends BaseResult { @@ -40,13 +40,14 @@ export interface IncrementalResult extends BaseResult { added: string[]; removed: { path: string; type: BuildOutputFileType }[]; modified: string[]; - files: Record; + files: ResultFile[]; } export type ResultFile = DiskFile | MemoryFile; export interface BaseResultFile { origin: 'memory' | 'disk'; + path: string; type: BuildOutputFileType; } diff --git a/packages/angular/build/src/builders/application/tests/options/service-worker_spec.ts b/packages/angular/build/src/builders/application/tests/options/service-worker_spec.ts index 958cd5007960..444babc37a02 100644 --- a/packages/angular/build/src/builders/application/tests/options/service-worker_spec.ts +++ b/packages/angular/build/src/builders/application/tests/options/service-worker_spec.ts @@ -19,7 +19,7 @@ describeBuilder(buildApplication, APPLICATION_BUILDER_INFO, (harness) => { name: 'app', installMode: 'prefetch', resources: { - files: ['/favicon.ico', '/index.html'], + files: ['/favicon.ico', '/index.html', '/*.css', '/*.js'], }, }, { @@ -88,5 +88,40 @@ describeBuilder(buildApplication, APPLICATION_BUILDER_INFO, (harness) => { const config = await harness.readFile('dist/browser/ngsw.json'); expect(JSON.parse(config)).toEqual(jasmine.objectContaining({ index: '/index.csr.html' })); }); + + it('should write JS-imported CSS chunk to browser dist when SSR is enabled', async () => { + await harness.modifyFile('src/tsconfig.app.json', (content) => { + const tsConfig = JSON.parse(content); + tsConfig.files ??= []; + tsConfig.files.push('main.server.ts', 'server.ts', 'extra.d.ts'); + + return JSON.stringify(tsConfig); + }); + + await harness.writeFile('src/extra.d.ts', `declare module '*.css';`); + await harness.writeFile('src/server.ts', `console.log('Server!');`); + await harness.writeFile('src/extra.css', `body { color: red; }`); + await harness.modifyFile('src/main.ts', (content) => `import './extra.css';\n${content}`); + + harness.useTarget('build', { + ...BASE_OPTIONS, + server: 'src/main.server.ts', + ssr: { entry: 'src/server.ts' }, + serviceWorker: true, + }); + + const { result } = await harness.executeOnce(); + expect(result?.success).toBeTrue(); + + const config = JSON.parse(harness.readFile('dist/browser/ngsw.json')); + const hashTable = config.hashTable as Record; + + const cssChunkUrls = Object.keys(hashTable).filter((url) => url.endsWith('.css')); + expect(cssChunkUrls.length).toBeGreaterThan(0); + + for (const url of Object.keys(hashTable)) { + harness.expectFile(`dist/browser${url}`).toExist(); + } + }); }); }); diff --git a/packages/angular/build/src/builders/dev-server/vite/index.ts b/packages/angular/build/src/builders/dev-server/vite/index.ts index 94192ec41b8c..8c8f23c3a339 100644 --- a/packages/angular/build/src/builders/dev-server/vite/index.ts +++ b/packages/angular/build/src/builders/dev-server/vite/index.ts @@ -262,9 +262,8 @@ export async function* serveWithVite( componentStyles.clear(); generatedFiles.clear(); - for (const [outputPath, file] of Object.entries(result.files)) { + for (const file of result.files) { updateResultRecord( - outputPath, file, normalizePath, htmlIndexPath, @@ -292,22 +291,9 @@ export async function* serveWithVite( assetFiles.delete(filePath); } - for (const modified of result.modified) { + for (const file of result.files) { updateResultRecord( - modified, - result.files[modified], - normalizePath, - htmlIndexPath, - generatedFiles, - assetFiles, - componentStyles, - ); - } - - for (const added of result.added) { - updateResultRecord( - added, - result.files[added], + file, normalizePath, htmlIndexPath, generatedFiles, diff --git a/packages/angular/build/src/builders/dev-server/vite/utils.ts b/packages/angular/build/src/builders/dev-server/vite/utils.ts index e1e6b4f96847..bc2d4a513b5a 100644 --- a/packages/angular/build/src/builders/dev-server/vite/utils.ts +++ b/packages/angular/build/src/builders/dev-server/vite/utils.ts @@ -30,7 +30,6 @@ export interface DevServerExternalResultMetadata extends Omit string, htmlIndexPath: string, @@ -40,7 +39,7 @@ export function updateResultRecord( initial = false, ): void { if (file.origin === 'disk') { - assetFiles.set('/' + normalizePath(outputPath), { + assetFiles.set('/' + normalizePath(file.path), { source: normalizePath(file.inputPath), updated: !initial, }); @@ -49,12 +48,12 @@ export function updateResultRecord( } let filePath; - if (outputPath === htmlIndexPath) { + if (file.path === htmlIndexPath) { // Convert custom index output path to standard index path for dev-server usage. // This mimics the Webpack dev-server behavior. filePath = '/index.html'; } else { - filePath = '/' + normalizePath(outputPath); + filePath = '/' + normalizePath(file.path); } const servable = @@ -74,6 +73,12 @@ export function updateResultRecord( return; } + // Avoid overwriting a servable browser file with a non-servable server file of the same path (e.g. CSS chunks) + const existing = generatedFiles.get(filePath); + if (existing?.servable && !servable) { + return; + } + // New or updated file generatedFiles.set(filePath, { contents: file.contents, diff --git a/packages/angular/build/src/builders/extract-i18n/application-extraction.ts b/packages/angular/build/src/builders/extract-i18n/application-extraction.ts index e7f8bee10c32..ff223ba0bd16 100644 --- a/packages/angular/build/src/builders/extract-i18n/application-extraction.ts +++ b/packages/angular/build/src/builders/extract-i18n/application-extraction.ts @@ -65,12 +65,12 @@ export async function extractMessages( // Extract messages from each output JavaScript file. // Output files are only present on a successful build. - for (const filePath of Object.keys(builderResult.files)) { - if (!filePath.endsWith('.js')) { + for (const file of builderResult.files) { + if (!file.path.endsWith('.js')) { continue; } - const fileMessages = extractor.extractMessages(filePath); + const fileMessages = extractor.extractMessages(file.path); messages.push(...fileMessages); } @@ -88,9 +88,10 @@ export async function extractMessages( function setupLocalizeExtractor( extractorConstructor: typeof MessageExtractor, - files: Record, + files: readonly ResultFile[], context: BuilderContext, ): MessageExtractor { + const fileMap = new Map(files.map((file) => [file.path, file])); const textDecoder = new TextDecoder(); // Setup a virtual file system instance for the extractor // * MessageExtractor itself uses readFile, relative and resolve @@ -100,7 +101,7 @@ function setupLocalizeExtractor( // Output files are stored as relative to the workspace root const requestedPath = nodePath.relative(context.workspaceRoot, path); - const file = files[requestedPath]; + const file = fileMap.get(requestedPath); let content; if (file?.origin === 'memory') { content = textDecoder.decode(file.contents); @@ -123,7 +124,7 @@ function setupLocalizeExtractor( // Output files are stored as relative to the workspace root const requestedPath = nodePath.relative(context.workspaceRoot, path); - return files[requestedPath] !== undefined; + return fileMap.has(requestedPath); }, dirname(path: string): string { return nodePath.dirname(path); diff --git a/packages/angular/build/src/builders/karma/application_builder.ts b/packages/angular/build/src/builders/karma/application_builder.ts index d0adb6c3cf0e..674a7db0e4be 100644 --- a/packages/angular/build/src/builders/karma/application_builder.ts +++ b/packages/angular/build/src/builders/karma/application_builder.ts @@ -386,7 +386,7 @@ async function configureKarma( ); } - parsedKarmaConfig.plugins.push(AngularAssetsMiddleware.createPlugin(buildOutput)); + parsedKarmaConfig.plugins.push(AngularAssetsMiddleware.createPlugin(buildOutput.files)); parsedKarmaConfig.middleware ??= []; parsedKarmaConfig.middleware.push(AngularAssetsMiddleware.NAME); diff --git a/packages/angular/build/src/builders/karma/assets-middleware.ts b/packages/angular/build/src/builders/karma/assets-middleware.ts index fd6ce489e583..45483cb4ec41 100644 --- a/packages/angular/build/src/builders/karma/assets-middleware.ts +++ b/packages/angular/build/src/builders/karma/assets-middleware.ts @@ -25,7 +25,7 @@ interface ServeFileFunction { } export interface LatestBuildFiles { - files: Record; + files: Map; } const LATEST_BUILD_FILES_TOKEN = 'angularLatestBuildFiles'; @@ -49,7 +49,7 @@ export class AngularAssetsMiddleware { pathname = pathname.replaceAll(path.posix.sep, path.win32.sep); } - const file = this.latestBuildFiles.files[pathname]; + const file = this.latestBuildFiles.files.get(pathname); if (!file) { next(); @@ -76,9 +76,12 @@ export class AngularAssetsMiddleware { } } - static createPlugin(initialFiles: LatestBuildFiles): InlinePluginDef { + static createPlugin(initialFiles: readonly ResultFile[]): InlinePluginDef { return { - [LATEST_BUILD_FILES_TOKEN]: ['value', { files: { ...initialFiles.files } }], + [LATEST_BUILD_FILES_TOKEN]: [ + 'value', + { files: new Map(initialFiles.map((file) => [file.path, file])) }, + ], [`middleware:${AngularAssetsMiddleware.NAME}`]: [ 'factory', diff --git a/packages/angular/build/src/builders/karma/progress-reporter.ts b/packages/angular/build/src/builders/karma/progress-reporter.ts index 6fc92b6c74c8..e7d40be15cfd 100644 --- a/packages/angular/build/src/builders/karma/progress-reporter.ts +++ b/packages/angular/build/src/builders/karma/progress-reporter.ts @@ -76,12 +76,14 @@ export function injectKarmaReporter( buildOutput.kind === ResultKind.Full ) { if (buildOutput.kind === ResultKind.Full) { - this.latestBuildFiles.files = buildOutput.files; + this.latestBuildFiles.files.clear(); } else { - this.latestBuildFiles.files = { - ...this.latestBuildFiles.files, - ...buildOutput.files, - }; + for (const { path } of buildOutput.removed) { + this.latestBuildFiles.files.delete(path); + } + } + for (const file of buildOutput.files) { + this.latestBuildFiles.files.set(file.path, file); } await writeTestFiles(buildOutput.files, buildOptions.outputPath); this.emitter.refreshFiles(); diff --git a/packages/angular/build/src/builders/karma/utils.ts b/packages/angular/build/src/builders/karma/utils.ts index 9a8aa749c269..ecdda5516cbd 100644 --- a/packages/angular/build/src/builders/karma/utils.ts +++ b/packages/angular/build/src/builders/karma/utils.ts @@ -8,8 +8,8 @@ import type { BuilderContext } from '@angular-devkit/architect'; import { createRequire } from 'node:module'; -import { BuildOutputFileType } from '../../tools/esbuild/bundler-files'; import { getProjectRootPaths } from '../../utils/project-metadata'; +import type { ResultFile } from '../application/results'; import { findTests, getTestEntrypoints } from './find-tests'; import type { NormalizedKarmaBuilderOptions } from './options'; @@ -62,9 +62,9 @@ export async function collectEntrypoints( return getTestEntrypoints(testFiles, { projectSourceRoot, workspaceRoot: context.workspaceRoot }); } -export function hasChunkOrWorkerFiles(files: Record): boolean { - return Object.keys(files).some((filename) => { - return /(?:^|\/)(?:worker|chunk)[^/]+\.js$/.test(filename); +export function hasChunkOrWorkerFiles(files: readonly ResultFile[]): boolean { + return files.some((file) => { + return /(?:^|\/)(?:worker|chunk)[^/]+\.js$/.test(file.path); }); } diff --git a/packages/angular/build/src/builders/unit-test/builder.ts b/packages/angular/build/src/builders/unit-test/builder.ts index 146ce6654bd0..755b91c40544 100644 --- a/packages/angular/build/src/builders/unit-test/builder.ts +++ b/packages/angular/build/src/builders/unit-test/builder.ts @@ -227,7 +227,7 @@ export async function* execute( await using executor = await runner.createExecutor(context, normalizedOptions, undefined); yield* executor.execute({ kind: ResultKind.Full, - files: {}, + files: [], }); } catch (e) { assertIsError(e); diff --git a/packages/angular/build/src/builders/unit-test/runners/vitest/executor.ts b/packages/angular/build/src/builders/unit-test/runners/vitest/executor.ts index ac2bfe20fa38..fc64e432e19f 100644 --- a/packages/angular/build/src/builders/unit-test/runners/vitest/executor.ts +++ b/packages/angular/build/src/builders/unit-test/runners/vitest/executor.ts @@ -104,8 +104,8 @@ export class VitestExecutor implements TestExecutor { if (buildResult.kind === ResultKind.Full) { this.buildResultFiles.clear(); - for (const [path, file] of Object.entries(buildResult.files)) { - this.buildResultFiles.set(this.normalizePath(path), file); + for (const file of buildResult.files) { + this.buildResultFiles.set(this.normalizePath(file.path), file); } this.debugLog( DebugLogLevel.Info, @@ -124,8 +124,8 @@ export class VitestExecutor implements TestExecutor { for (const file of buildResult.removed) { this.buildResultFiles.delete(this.normalizePath(file.path)); } - for (const [path, file] of Object.entries(buildResult.files)) { - this.buildResultFiles.set(this.normalizePath(path), file); + for (const file of buildResult.files) { + this.buildResultFiles.set(this.normalizePath(file.path), file); } } diff --git a/packages/angular/build/src/tools/esbuild/bundler-execution-result.ts b/packages/angular/build/src/tools/esbuild/bundler-execution-result.ts index 53e17e7e427c..eeb7045dfb61 100644 --- a/packages/angular/build/src/tools/esbuild/bundler-execution-result.ts +++ b/packages/angular/build/src/tools/esbuild/bundler-execution-result.ts @@ -27,7 +27,10 @@ export interface RebuildState { componentStyleBundler: ComponentStylesheetBundler; codeBundleCache?: SourceFileCache; fileChanges: ChangedFiles; - previousOutputInfo: ReadonlyMap; + previousOutputInfo: ReadonlyMap< + string, + { hash: string; type: BuildOutputFileType; path: string } + >; previousAssetsInfo: ReadonlyMap; templateUpdates?: Map; } @@ -171,7 +174,7 @@ export class ExecutionResult { componentStyleBundler: this.componentStyleBundler, fileChanges, previousOutputInfo: new Map( - this.outputFiles.map(({ path, hash, type }) => [path, { hash, type }]), + this.outputFiles.map(({ path, hash, type }) => [`${type}:${path}`, { hash, type, path }]), ), previousAssetsInfo: new Map( this.assetFiles.map(({ source, destination }) => [source, destination]), @@ -185,7 +188,7 @@ export class ExecutionResult { ): Set { const changed = new Set(); for (const file of this.outputFiles) { - const previousHash = previousOutputHashes.get(file.path)?.hash; + const previousHash = previousOutputHashes.get(`${file.type}:${file.path}`)?.hash; if (previousHash === undefined || previousHash !== file.hash) { changed.add(file.path); } diff --git a/packages/angular/build/src/tools/esbuild/utils.ts b/packages/angular/build/src/tools/esbuild/utils.ts index 7d9dce4a5522..3bbaabdd2400 100644 --- a/packages/angular/build/src/tools/esbuild/utils.ts +++ b/packages/angular/build/src/tools/esbuild/utils.ts @@ -214,7 +214,7 @@ export function getFeatureSupport(nativeAsyncAwait: boolean): BuildOptions['supp const MAX_CONCURRENT_WRITES = 64; export async function emitFilesToDisk( - files: T[], + files: readonly T[], writeFileCallback: (file: T) => Promise, ): Promise { // Write files in groups of MAX_CONCURRENT_WRITES to avoid too many open files diff --git a/packages/angular/build/src/utils/test-files.ts b/packages/angular/build/src/utils/test-files.ts index d5f0edb2815d..6790d007e220 100644 --- a/packages/angular/build/src/utils/test-files.ts +++ b/packages/angular/build/src/utils/test-files.ts @@ -17,21 +17,18 @@ import { emitFilesToDisk } from '../tools/esbuild/utils'; * This function handles both in-memory and on-disk files, creating subdirectories * as needed. * - * @param files A map of file paths to `ResultFile` objects, representing the build output. + * @param files A collection of `ResultFile` objects, representing the build output. * @param testDir The absolute path to the directory where the files should be written. */ -export async function writeTestFiles( - files: Record, - testDir: string, -): Promise { +export async function writeTestFiles(files: readonly ResultFile[], testDir: string): Promise { const directoryExists = new Set(); // Writes the test related output files to disk and ensures the containing directories are present - await emitFilesToDisk(Object.entries(files), async ([filePath, file]) => { + await emitFilesToDisk(files, async (file) => { if (file.type !== BuildOutputFileType.Browser && file.type !== BuildOutputFileType.Media) { return; } - const fullFilePath = path.join(testDir, filePath); + const fullFilePath = path.join(testDir, file.path); // Ensure output subdirectories exist const fileBasePath = path.dirname(fullFilePath); diff --git a/packages/angular_devkit/build_angular/src/builders/extract-i18n/application-extraction.ts b/packages/angular_devkit/build_angular/src/builders/extract-i18n/application-extraction.ts index fb6e9138982e..8de8b6863aaf 100644 --- a/packages/angular_devkit/build_angular/src/builders/extract-i18n/application-extraction.ts +++ b/packages/angular_devkit/build_angular/src/builders/extract-i18n/application-extraction.ts @@ -70,12 +70,12 @@ export async function extractMessages( // Extract messages from each output JavaScript file. // Output files are only present on a successful build. - for (const filePath of Object.keys(builderResult.files)) { - if (!filePath.endsWith('.js')) { + for (const file of builderResult.files) { + if (!file.path.endsWith('.js')) { continue; } - const fileMessages = extractor.extractMessages(filePath); + const fileMessages = extractor.extractMessages(file.path); messages.push(...fileMessages); } @@ -93,9 +93,10 @@ export async function extractMessages( function setupLocalizeExtractor( extractorConstructor: typeof MessageExtractor, - files: Record, + files: readonly ResultFile[], context: BuilderContext, ): MessageExtractor { + const fileMap = new Map(files.map((file) => [file.path, file])); const textDecoder = new TextDecoder(); // Setup a virtual file system instance for the extractor // * MessageExtractor itself uses readFile, relative and resolve @@ -105,7 +106,7 @@ function setupLocalizeExtractor( // Output files are stored as relative to the workspace root const requestedPath = nodePath.relative(context.workspaceRoot, path); - const file = files[requestedPath]; + const file = fileMap.get(requestedPath); let content; if (file?.origin === 'memory') { content = textDecoder.decode(file.contents); @@ -128,7 +129,7 @@ function setupLocalizeExtractor( // Output files are stored as relative to the workspace root const requestedPath = nodePath.relative(context.workspaceRoot, path); - return files[requestedPath] !== undefined; + return fileMap.has(requestedPath); }, dirname(path: string): string { return nodePath.dirname(path); From a4cc979c2c1ef039f9ce84aebb2955d9b8454498 Mon Sep 17 00:00:00 2001 From: Charles Lyding <19598772+clydin@users.noreply.github.com> Date: Tue, 25 Aug 2026 22:53:06 -0400 Subject: [PATCH 354/787] refactor(@angular/build): remove unused options and dead code from i18n inliner Remove obsolete and unused options from the I18nInliner options and workerData. The `shouldOptimize` option is removed from `I18nInlinerOptions`, `workerData`, and cache base key calculation since inliner AST transformations do not perform code optimization. The `translations` option is also removed from `I18nInlinerOptions` and `workerData` because translations are provided per batch request. In addition, the unused single-file `inlineFile` worker action and interface are removed, and `InlineFileBatchRequest` is updated to model `locales` as a `ReadonlyMap` to enforce locale key uniqueness. --- .../build/src/builders/application/i18n.ts | 3 +- .../src/tools/esbuild/i18n-inliner-worker.ts | 75 ++----------------- .../build/src/tools/esbuild/i18n-inliner.ts | 14 +--- 3 files changed, 12 insertions(+), 80 deletions(-) diff --git a/packages/angular/build/src/builders/application/i18n.ts b/packages/angular/build/src/builders/application/i18n.ts index f212659a14be..058a2fa3d6a4 100644 --- a/packages/angular/build/src/builders/application/i18n.ts +++ b/packages/angular/build/src/builders/application/i18n.ts @@ -42,14 +42,13 @@ export async function inlineI18n( warnings: string[]; prerenderedRoutes: PrerenderedRoutesRecord; }> { - const { i18nOptions, optimizationOptions, baseHref, cacheOptions } = options; + const { i18nOptions, baseHref, cacheOptions } = options; // Create the multi-threaded inliner with common options and the files generated from the build. const inliner = new I18nInliner( { missingTranslation: i18nOptions.missingTranslationBehavior ?? 'warning', outputFiles: executionResult.outputFiles, - shouldOptimize: optimizationOptions.scripts, persistentCachePath: cacheOptions.enabled ? cacheOptions.path : undefined, localizeVersion: i18nOptions.localizeVersion, }, diff --git a/packages/angular/build/src/tools/esbuild/i18n-inliner-worker.ts b/packages/angular/build/src/tools/esbuild/i18n-inliner-worker.ts index af9d9dce134b..0b22c7412ba1 100644 --- a/packages/angular/build/src/tools/esbuild/i18n-inliner-worker.ts +++ b/packages/angular/build/src/tools/esbuild/i18n-inliner-worker.ts @@ -16,29 +16,6 @@ import { parseSync, visitorKeys } from 'oxc-parser'; import { loadLocaleData } from './i18n-locale-plugin'; import { createSharedTranslationProxy } from './i18n-translation-reader'; -/** - * The options passed to the inliner for each file request - */ -interface InlineFileRequest { - /** - * The filename that should be processed. The data for the file is provided to the Worker - * during Worker initialization. - */ - filename: string; - - /** - * The locale specifier that should be used during the inlining process of the file. - */ - locale: string; - - /** - * The serialized translation messages for the locale that should be used during the inlining - * process of the file. A SharedArrayBuffer or Blob is used so that the messages are shared with - * the Worker by reference instead of being copied into it for every request. - */ - translation?: Blob | SharedArrayBuffer; -} - /** * The options passed to the inliner for each code request */ @@ -77,9 +54,9 @@ interface InlineFileBatchRequest { filename: string; /** - * The locale specifiers or locale objects that should be used during the inlining process of the file. + * The locale specifiers and optional translations to use during the inlining process of the file. */ - locales: (string | { locale: string; translation?: Blob | SharedArrayBuffer })[]; + locales: ReadonlyMap; /** * Whether the file data should be treated as ephemeral and not cached long-term in the Worker. @@ -113,10 +90,9 @@ interface InlineFileBatchResult { } // Extract the application files and common options used for inline requests from the Worker context -const { files, missingTranslation, translations } = (workerData || {}) as { +const { files, missingTranslation } = (workerData || {}) as { files: ReadonlyMap; missingTranslation: 'error' | 'warning' | 'ignore'; - translations?: ReadonlyMap; }; /** @@ -184,15 +160,14 @@ function loadTranslation( locale: string, translation?: Blob | SharedArrayBuffer, ): Promise> | undefined { - const translationData = translation ?? translations?.get(locale); - if (!translationData) { + if (!translation) { return undefined; } let messagesPromise = deserializedTranslations.get(locale); if (!messagesPromise) { - if (translationData instanceof Blob) { - messagesPromise = translationData + if (translation instanceof Blob) { + messagesPromise = translation .arrayBuffer() .then((buffer) => deserialize(new Uint8Array(buffer)) as Record) .catch((error) => { @@ -200,7 +175,7 @@ function loadTranslation( throw error; }); } else { - messagesPromise = Promise.resolve(createSharedTranslationProxy(translationData)); + messagesPromise = Promise.resolve(createSharedTranslationProxy(translation)); } deserializedTranslations.set(locale, messagesPromise); } @@ -208,38 +183,6 @@ function loadTranslation( return messagesPromise; } -/** - * Inlines the provided locale and translation into a JavaScript file that contains `$localize` usage. - * This function is the main entry for the Worker's action that is called by the worker pool. - * - * @param request An InlineRequest object representing the options for inlining - * @returns An object containing the inlined file and optional map content. - */ -export default async function inlineFile(request: InlineFileRequest) { - const { code, metadata } = await loadFileData(request.filename, true); - - // Sourcemaps are parsed on demand per request rather than cached long-term to prevent - // monotonic memory growth as a worker processes multiple files across the build. - const rawMap = await files.get(request.filename + '.map')?.text(); - const map = rawMap ? (JSON.parse(rawMap) as SourceMapInput) : undefined; - - const result = await inlineLocalize( - code, - map, - metadata, - request.locale, - await loadTranslation(request.locale, request.translation), - request.filename, - ); - - return { - file: request.filename, - code: result.code, - map: result.map, - messages: result.diagnostics.messages, - }; -} - /** * Inlines multiple locales and translations into a JavaScript file that contains `$localize` usage. * @@ -266,9 +209,7 @@ export async function inlineFileBatch( const map = rawMap ? (JSON.parse(rawMap) as SourceMapInput) : undefined; const results = await Promise.all( - request.locales.map(async (entry) => { - const locale = typeof entry === 'string' ? entry : entry.locale; - const translation = typeof entry === 'string' ? undefined : entry.translation; + Array.from(request.locales, async ([locale, translation]) => { const result = await inlineLocalize( code, map, diff --git a/packages/angular/build/src/tools/esbuild/i18n-inliner.ts b/packages/angular/build/src/tools/esbuild/i18n-inliner.ts index 41de55de666f..689fc7736995 100644 --- a/packages/angular/build/src/tools/esbuild/i18n-inliner.ts +++ b/packages/angular/build/src/tools/esbuild/i18n-inliner.ts @@ -57,10 +57,8 @@ function serializeTranslation( export interface I18nInlinerOptions { missingTranslation: 'error' | 'warning' | 'ignore'; outputFiles: BuildOutputFile[]; - shouldOptimize?: boolean; persistentCachePath?: string; localizeVersion?: string; - translations?: ReadonlyMap; } /** @@ -155,7 +153,7 @@ export class I18nInliner { maxThreads?: number, ) { this.#unmodifiedFiles = []; - const { outputFiles, shouldOptimize, missingTranslation, translations } = options; + const { outputFiles, missingTranslation } = options; const files = new Map(); const pendingMaps = []; @@ -206,8 +204,6 @@ export class I18nInliner { // Extract options to ensure only the named options are serialized and sent to the worker workerData: { missingTranslation, - shouldOptimize, - translations, // A Blob is an immutable data structure that allows sharing the data between workers // without copying until the data is actually used within a Worker. This is useful here // since each file may not actually be processed in each Worker and the Blob avoids @@ -233,7 +229,7 @@ export class I18nInliner { ): Promise> { await this.initCache(); - const { shouldOptimize, missingTranslation, localizeVersion } = this.options; + const { missingTranslation, localizeVersion } = this.options; const localeList = Array.from(locales); if (localeList.length === 0) { @@ -270,7 +266,6 @@ export class I18nInliner { locale, translation: translationIntegrity || translation, missingTranslation, - shouldOptimize, localizeVersion, }), ), @@ -426,10 +421,7 @@ export class I18nInliner { const batchResult = (await this.#workerPool.run( { filename, - locales: batchEntries.map((e) => ({ - locale: e.locale, - translation: e.translation, - })), + locales: new Map(batchEntries.map((e) => [e.locale, e.translation])), ephemeral, activeLocales, }, From e3d55b2ddf319683b575a02ba911c676119d91e4 Mon Sep 17 00:00:00 2001 From: Charles Lyding <19598772+clydin@users.noreply.github.com> Date: Wed, 26 Aug 2026 09:50:48 -0400 Subject: [PATCH 355/787] =?UTF-8?q?refactor(@angular/build):=20use=20?= =?UTF-8?q?=C9=B5ParsedTranslation=20in=20i18n=20inliner?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Replace untyped Record translation dictionaries with Record throughout the i18n inliner and related utilities. The SharedTranslationDictionary and createSharedTranslationProxy utilities now default to ɵParsedTranslation with generic support for custom value types in unit tests. --- .../src/tools/esbuild/i18n-inliner-worker.ts | 9 ++--- .../build/src/tools/esbuild/i18n-inliner.ts | 9 ++--- .../src/tools/esbuild/i18n-inliner_spec.ts | 36 +++++++++++-------- .../tools/esbuild/i18n-translation-encoder.ts | 6 +++- .../esbuild/i18n-translation-encoder_spec.ts | 12 +++---- .../tools/esbuild/i18n-translation-reader.ts | 15 ++++---- .../angular/build/src/utils/i18n-options.ts | 5 +-- 7 files changed, 55 insertions(+), 37 deletions(-) diff --git a/packages/angular/build/src/tools/esbuild/i18n-inliner-worker.ts b/packages/angular/build/src/tools/esbuild/i18n-inliner-worker.ts index 0b22c7412ba1..d6a56ad10d74 100644 --- a/packages/angular/build/src/tools/esbuild/i18n-inliner-worker.ts +++ b/packages/angular/build/src/tools/esbuild/i18n-inliner-worker.ts @@ -7,6 +7,7 @@ */ import remapping, { type DecodedSourceMap, type SourceMapInput } from '@ampproject/remapping'; +import type { ɵParsedTranslation } from '@angular/localize'; import type { Node } from '@oxc-project/types'; import { MagicString } from 'magic-string'; import assert from 'node:assert'; @@ -111,7 +112,7 @@ const fileDataCache = new Map>(); /** * Cache of deserialized translation messages keyed by locale. */ -const deserializedTranslations = new Map>>(); +const deserializedTranslations = new Map>>(); /** * Retrieves the file data for a filename, loading and extracting localization metadata. @@ -159,7 +160,7 @@ function loadFileData(filename: string, cache = true): Promise { function loadTranslation( locale: string, translation?: Blob | SharedArrayBuffer, -): Promise> | undefined { +): Promise> | undefined { if (!translation) { return undefined; } @@ -169,7 +170,7 @@ function loadTranslation( if (translation instanceof Blob) { messagesPromise = translation .arrayBuffer() - .then((buffer) => deserialize(new Uint8Array(buffer)) as Record) + .then((buffer) => deserialize(new Uint8Array(buffer)) as Record) .catch((error) => { deserializedTranslations.delete(locale); throw error; @@ -431,7 +432,7 @@ async function inlineLocalize( map: SourceMapInput | undefined, metadata: FileLocalizeMetadata, locale: string, - translation: Record | undefined, + translation: Record | undefined, filename: string, ) { const magicString = new MagicString(code); diff --git a/packages/angular/build/src/tools/esbuild/i18n-inliner.ts b/packages/angular/build/src/tools/esbuild/i18n-inliner.ts index 689fc7736995..33b570a46017 100644 --- a/packages/angular/build/src/tools/esbuild/i18n-inliner.ts +++ b/packages/angular/build/src/tools/esbuild/i18n-inliner.ts @@ -6,6 +6,7 @@ * found in the LICENSE file at https://angular.dev/license */ +import type { ɵParsedTranslation } from '@angular/localize'; import assert from 'node:assert'; import { extname, join } from 'node:path'; import { serialize } from 'node:v8'; @@ -38,7 +39,7 @@ const DEFAULT_LOCALE_WINDOW_SIZE = 8; * @returns A SharedArrayBuffer or Blob containing the serialized messages, or undefined if none. */ function serializeTranslation( - translation: Record | undefined, + translation: Record | undefined, ): SharedArrayBuffer | Blob | undefined { if (!translation) { return undefined; @@ -73,7 +74,7 @@ export interface LocaleInlineOptions { /** * The translation messages for the locale, or undefined for the source/untranslated locale. */ - translation?: Record; + translation?: Record; /** * An optional content integrity hash of the translation file(s) for fast cache key calculation. @@ -470,7 +471,7 @@ export class I18nInliner { */ async inlineForLocale( locale: string, - translation: Record | undefined, + translation: Record | undefined, translationIntegrity?: string, ): Promise { const results = await this.inlineAll([{ locale, translation, translationIntegrity }]); @@ -482,7 +483,7 @@ export class I18nInliner { async inlineTemplateUpdate( locale: string, - translation: Record | undefined, + translation: Record | undefined, templateCode: string, templateId: string, ): Promise<{ code: string; errors: string[]; warnings: string[] }> { diff --git a/packages/angular/build/src/tools/esbuild/i18n-inliner_spec.ts b/packages/angular/build/src/tools/esbuild/i18n-inliner_spec.ts index 46d1cb4145d4..acceab7513b5 100644 --- a/packages/angular/build/src/tools/esbuild/i18n-inliner_spec.ts +++ b/packages/angular/build/src/tools/esbuild/i18n-inliner_spec.ts @@ -6,6 +6,7 @@ * found in the LICENSE file at https://angular.dev/license */ +import type { ɵParsedTranslation } from '@angular/localize'; import { transform } from 'esbuild'; import fs from 'node:fs/promises'; import os from 'node:os'; @@ -21,11 +22,22 @@ import { I18nInliner } from './i18n-inliner'; const GREETING_SOURCE = 'export const greeting = $localize`:@@greeting:Hello`;\n'; /** - * Creates the parsed translation form that `@angular/localize` expects for a message without - * placeholders. + * Creates the parsed translation form that `@angular/localize` expects. */ -function translationFor(message: string): Record { - return { messageParts: [message], placeholderNames: [], text: message }; +function parsedTranslation( + parts: string[], + placeholderNames: string[] = [], + text?: string, +): ɵParsedTranslation { + return { + messageParts: Object.assign([...parts], { raw: [...parts] }), + placeholderNames, + text: text ?? parts.join(''), + }; +} + +function translationFor(message: string): ɵParsedTranslation { + return parsedTranslation([message], [], message); } function browserFile(path: string, contents: string): BuildOutputFile { @@ -222,11 +234,7 @@ describe('I18nInliner', () => { const { outputFiles, errors, warnings } = await createInliner([ browserFile('main.js', source), ]).inlineForLocale('fr', { - welcome: { - messageParts: ['Bonjour ', ' !'], - placeholderNames: ['PH'], - text: 'Bonjour {$PH} !', - }, + welcome: parsedTranslation(['Bonjour ', ' !'], ['PH'], 'Bonjour {$PH} !'), }); expect(errors).toEqual([]); @@ -294,11 +302,11 @@ describe('I18nInliner', () => { browserFile('main.js', source), ]).inlineForLocale('fr', { inner: translationFor('Pomme'), - outer: { - messageParts: ['Vous avez sélectionné ', ' pour la livraison.'], - placeholderNames: ['PH'], - text: 'Vous avez sélectionné {$PH} pour la livraison.', - }, + outer: parsedTranslation( + ['Vous avez sélectionné ', ' pour la livraison.'], + ['PH'], + 'Vous avez sélectionné {$PH} pour la livraison.', + ), }); expect(errors).toEqual([]); diff --git a/packages/angular/build/src/tools/esbuild/i18n-translation-encoder.ts b/packages/angular/build/src/tools/esbuild/i18n-translation-encoder.ts index 091d9ba0ff26..cc8f1ae50f31 100644 --- a/packages/angular/build/src/tools/esbuild/i18n-translation-encoder.ts +++ b/packages/angular/build/src/tools/esbuild/i18n-translation-encoder.ts @@ -6,6 +6,8 @@ * found in the LICENSE file at https://angular.dev/license */ +import type { ɵParsedTranslation } from '@angular/localize'; + /** * Magic header identifier for i18n SharedArrayBuffer translation tables ('I18N'). */ @@ -19,7 +21,9 @@ export const I18N_MAGIC_ID = 0x4931384e; * @param translation The translation dictionary object. * @returns A SharedArrayBuffer containing the binary encoded translation catalog. */ -export function encodeTranslationToBuffer(translation: Record): SharedArrayBuffer { +export function encodeTranslationToBuffer( + translation: Record, +): SharedArrayBuffer { const encoder = new TextEncoder(); const entries = Object.entries(translation); const entryCount = entries.length; diff --git a/packages/angular/build/src/tools/esbuild/i18n-translation-encoder_spec.ts b/packages/angular/build/src/tools/esbuild/i18n-translation-encoder_spec.ts index c3b6409d40b5..dd660f9a4059 100644 --- a/packages/angular/build/src/tools/esbuild/i18n-translation-encoder_spec.ts +++ b/packages/angular/build/src/tools/esbuild/i18n-translation-encoder_spec.ts @@ -22,7 +22,7 @@ describe('SharedArrayBuffer Translation Encoder & Reader', () => { }; const buffer = encodeTranslationToBuffer(translation); - const dictionary = new SharedTranslationDictionary(buffer); + const dictionary = new SharedTranslationDictionary(buffer); expect(dictionary.get('greeting')).toEqual('Hello'); expect(dictionary.get('farewell')).toEqual('Goodbye'); @@ -38,7 +38,7 @@ describe('SharedArrayBuffer Translation Encoder & Reader', () => { }; const buffer = encodeTranslationToBuffer(translation); - const proxy = createSharedTranslationProxy(buffer); + const proxy = createSharedTranslationProxy(buffer); expect(proxy['msg1']).toEqual('Message 1'); expect(proxy['msg2']).toEqual('Message 2'); @@ -54,7 +54,7 @@ describe('SharedArrayBuffer Translation Encoder & Reader', () => { }; const buffer = encodeTranslationToBuffer(translation); - const proxy = createSharedTranslationProxy(buffer); + const proxy = createSharedTranslationProxy(buffer); expect(Object.prototype.hasOwnProperty.call(proxy, 'msg1')).toBeTrue(); expect(Object.prototype.hasOwnProperty.call(proxy, 'unknown')).toBeFalse(); @@ -83,7 +83,7 @@ describe('SharedArrayBuffer Translation Encoder & Reader', () => { }; const buffer = encodeTranslationToBuffer(translation); - const dictionary = new SharedTranslationDictionary(buffer); + const dictionary = new SharedTranslationDictionary(buffer); expect(dictionary.get('😀')).toEqual('emoji message'); expect(dictionary.get('\uE000')).toEqual('uE000 message'); @@ -102,8 +102,8 @@ describe('SharedArrayBuffer Translation Encoder & Reader', () => { msg1: 'Message 1', }; - const buffer = encodeTranslationToBuffer(translation); - const dictionary = new SharedTranslationDictionary(buffer); + const buffer = encodeTranslationToBuffer(translation); + const dictionary = new SharedTranslationDictionary(buffer); // First lookup for missing key expect(dictionary.get('missingKey')).toBeUndefined(); diff --git a/packages/angular/build/src/tools/esbuild/i18n-translation-reader.ts b/packages/angular/build/src/tools/esbuild/i18n-translation-reader.ts index bc87633da5dc..c332b47f1941 100644 --- a/packages/angular/build/src/tools/esbuild/i18n-translation-reader.ts +++ b/packages/angular/build/src/tools/esbuild/i18n-translation-reader.ts @@ -6,6 +6,7 @@ * found in the LICENSE file at https://angular.dev/license */ +import type { ɵParsedTranslation } from '@angular/localize'; import { I18N_MAGIC_ID } from './i18n-translation-encoder'; /** @@ -43,13 +44,13 @@ function compareBytes( * A zero-copy reader that queries translation messages directly from a SharedArrayBuffer * using binary search over a sorted key index. */ -export class SharedTranslationDictionary { +export class SharedTranslationDictionary { private readonly entryCount: number; private readonly uint32Index: Uint32Array; private readonly uint8Pool: Uint8Array; private readonly decoder = new TextDecoder(); private readonly encoder = new TextEncoder(); - private readonly lazyCache = new Map(); + private readonly lazyCache = new Map(); constructor(buffer: SharedArrayBuffer) { if (buffer.byteLength < 16) { @@ -86,7 +87,7 @@ export class SharedTranslationDictionary { * @param targetKey The message key ID to search for. * @returns The parsed translation message, or undefined if not found. */ - get(targetKey: string): unknown | undefined { + get(targetKey: string): T | undefined { const cached = this.lazyCache.get(targetKey); if (cached !== undefined) { return cached === NOT_FOUND ? undefined : cached; @@ -117,7 +118,7 @@ export class SharedTranslationDictionary { const valJson = this.decoder.decode(valBytes); try { - const val = JSON.parse(valJson); + const val = JSON.parse(valJson) as T; this.lazyCache.set(targetKey, val); return val; @@ -150,8 +151,10 @@ export class SharedTranslationDictionary { * @param buffer The SharedArrayBuffer containing binary encoded translation catalog. * @returns A Proxy object that intercepts property reads and queries the SharedTranslationDictionary. */ -export function createSharedTranslationProxy(buffer: SharedArrayBuffer): Record { - const dictionary = new SharedTranslationDictionary(buffer); +export function createSharedTranslationProxy( + buffer: SharedArrayBuffer, +): Record { + const dictionary = new SharedTranslationDictionary(buffer); return new Proxy( {}, diff --git a/packages/angular/build/src/utils/i18n-options.ts b/packages/angular/build/src/utils/i18n-options.ts index 6a288622d053..9a55656e6798 100644 --- a/packages/angular/build/src/utils/i18n-options.ts +++ b/packages/angular/build/src/utils/i18n-options.ts @@ -6,6 +6,7 @@ * found in the LICENSE file at https://angular.dev/license */ +import type { ɵParsedTranslation } from '@angular/localize'; import path from 'node:path'; import type { TranslationLoader } from './load-translations'; @@ -15,7 +16,7 @@ export interface LocaleDescription { integrity?: string; format?: string; }[]; - translation?: Record; + translation?: Record; dataPath?: string; baseHref?: string; subPath: string; @@ -244,7 +245,7 @@ export function loadTranslations( usedFormats?: Set, duplicateTranslation?: 'ignore' | 'error' | 'warning', ) { - let translations: Record | undefined = undefined; + let translations: Record | undefined = undefined; for (const file of desc.files) { const loadResult = loader(path.join(workspaceRoot, file.path)); From 135662d9a1de85b42292b26b547160eaca71e5da Mon Sep 17 00:00:00 2001 From: "d.bronnikov" Date: Thu, 27 Aug 2026 17:00:47 +0800 Subject: [PATCH 356/787] fix(@angular/build): preserve binary values in the SQLite cache store The SQLite cache store serialized values with `JSON.stringify` and read them back with `JSON.parse`. Several cached values contain binary data: the JavaScript transformer stores its worker output as a `Uint8Array` (`Cache`), and `CachedLoadResultEntry.contents` is typed as `string | Uint8Array`. A JSON round trip cannot represent typed arrays, so those values came back from disk as plain objects (`{"0":105,"1":109,...}`) and were handed to esbuild as load result contents, failing the build with `"contents" must be a string or a Uint8Array`. The failure only appeared from the second build onwards, because the first build serves the value from the in-memory cache layer and the value is only corrupted once it is read back from disk. Values are now persisted using the V8 structured clone serialization API (`node:v8`), which supports typed arrays natively and matches the behavior of the LMDB store. The `value` column is declared as `BLOB` accordingly. SQLite column types are dynamic, so a stored value is checked at runtime before it is deserialized; values that are not binary, or whose payload is corrupt, are treated as a cache miss and recreated. The store is only reached when LMDB fails to load, which is why this went unnoticed on most systems. A common trigger is a prebuilt `@lmdb/lmdb-linux-x64` binary requiring a newer glibc than the host provides, for example on Ubuntu 20.04, Debian 11, or RHEL/CentOS 8. The fallback can also be selected explicitly with `NG_BUILD_CACHE_STORE=sqlite`. Closes #33841 --- .../src/tools/esbuild/sqlite-cache-store.ts | 26 ++++-- .../tools/esbuild/sqlite-cache-store_spec.ts | 79 ++++++++++++++++++- 2 files changed, 96 insertions(+), 9 deletions(-) diff --git a/packages/angular/build/src/tools/esbuild/sqlite-cache-store.ts b/packages/angular/build/src/tools/esbuild/sqlite-cache-store.ts index 4f50515749df..cbd51d345ddd 100644 --- a/packages/angular/build/src/tools/esbuild/sqlite-cache-store.ts +++ b/packages/angular/build/src/tools/esbuild/sqlite-cache-store.ts @@ -7,8 +7,17 @@ */ import { DatabaseSync, StatementSync } from 'node:sqlite'; +import { deserialize, serialize } from 'node:v8'; import { Cache, PersistentCacheStore } from './cache'; +/** + * A persistent cache store backed by SQLite. + * + * Values are persisted with the V8 structured clone serialization API instead of JSON. Cached + * values include binary data such as the `Uint8Array` output of the JavaScript transformer and + * the `contents` of an esbuild load result. A JSON round-trip converts those into plain objects + * (`{"0":105,"1":109,...}`), which breaks consumers on any build that reads them back from disk. + */ export class SqliteCacheStore implements PersistentCacheStore { #db: DatabaseSync | undefined; #getStmt: StatementSync | undefined; @@ -35,7 +44,7 @@ export class SqliteCacheStore implements PersistentCacheStore { this.#db.exec('PRAGMA temp_store = MEMORY;'); this.#db.exec('PRAGMA mmap_size = 268435456;'); this.#db.exec( - 'CREATE TABLE IF NOT EXISTS cache (key TEXT PRIMARY KEY, value TEXT, last_accessed INTEGER NOT NULL) WITHOUT ROWID;', + 'CREATE TABLE IF NOT EXISTS cache (key TEXT PRIMARY KEY, value BLOB, last_accessed INTEGER NOT NULL) WITHOUT ROWID;', ); this.#getStmt = this.#db.prepare('SELECT value FROM cache WHERE key = ?'); @@ -92,15 +101,18 @@ export class SqliteCacheStore implements PersistentCacheStore { // eslint-disable-next-line @typescript-eslint/no-explicit-any async get(key: string): Promise { this.#ensureDb(); - const row = this.#getStmt?.get(key) as { value: string } | undefined; + // SQLite column types are dynamic, so the stored value is only known at runtime. + const row = this.#getStmt?.get(key) as { value: unknown } | undefined; if (row) { this.#queueAccessUpdate(key); - try { - return JSON.parse(row.value); - } catch { - return undefined; + if (row.value instanceof Uint8Array) { + try { + return deserialize(row.value); + } catch { + // Treat corrupt or unparseable cached payloads as a cache miss. + } } } @@ -116,7 +128,7 @@ export class SqliteCacheStore implements PersistentCacheStore { async set(key: string, value: unknown): Promise { this.#ensureDb(); this.#pendingAccessedKeys.delete(key); - this.#setStmt?.run(key, JSON.stringify(value)); + this.#setStmt?.run(key, serialize(value)); return this; } diff --git a/packages/angular/build/src/tools/esbuild/sqlite-cache-store_spec.ts b/packages/angular/build/src/tools/esbuild/sqlite-cache-store_spec.ts index 679bff21de20..75ab1a358573 100644 --- a/packages/angular/build/src/tools/esbuild/sqlite-cache-store_spec.ts +++ b/packages/angular/build/src/tools/esbuild/sqlite-cache-store_spec.ts @@ -36,6 +36,81 @@ describe('SqliteCacheStore', () => { expect(result).toEqual(data); }); + it('should preserve binary values', async () => { + const data = new TextEncoder().encode('export const value = 1;\n'); + await store.set('binary-key', data); + + const result = await store.get('binary-key'); + expect(result).toBeInstanceOf(Uint8Array); + expect(result).toEqual(data); + }); + + it('should preserve binary values nested within an object', async () => { + const data = { + contents: new TextEncoder().encode('export const value = 1;\n'), + loader: 'js', + watchFiles: ['/some/file.js'], + }; + await store.set('nested-binary-key', data); + + const result = await store.get('nested-binary-key'); + expect(result.contents).toBeInstanceOf(Uint8Array); + expect(result).toEqual(data); + }); + + it('should preserve binary values across store instances', async () => { + const data = new TextEncoder().encode('export const value = 1;\n'); + await store.set('persisted-binary-key', data); + store.close(); + + const reopenedStore = new SqliteCacheStore(cachePath); + try { + const result = await reopenedStore.get('persisted-binary-key'); + expect(result).toBeInstanceOf(Uint8Array); + expect(result).toEqual(data); + } finally { + reopenedStore.close(); + } + }); + + it('should treat a corrupt payload as a cache miss', async () => { + await store.set('corrupt-key', 'value'); + store.close(); + + // Simulate an entry with an invalid/corrupt payload that fails deserialization. + const { DatabaseSync } = await import('node:sqlite'); + const directDb = new DatabaseSync(cachePath); + directDb + .prepare('UPDATE cache SET value = ? WHERE key = ?') + .run(new Uint8Array([0x00, 0x01, 0x02]), 'corrupt-key'); + directDb.close(); + + const reopenedStore = new SqliteCacheStore(cachePath); + try { + expect(await reopenedStore.get('corrupt-key')).toBeUndefined(); + } finally { + reopenedStore.close(); + } + }); + + it('should treat a non-binary payload as a cache miss', async () => { + await store.set('text-key', 'value'); + store.close(); + + // SQLite column types are dynamic, so a stored value is not guaranteed to be binary. + const { DatabaseSync } = await import('node:sqlite'); + const directDb = new DatabaseSync(cachePath); + directDb.prepare('UPDATE cache SET value = ? WHERE key = ?').run('"value"', 'text-key'); + directDb.close(); + + const reopenedStore = new SqliteCacheStore(cachePath); + try { + expect(await reopenedStore.get('text-key')).toBeUndefined(); + } finally { + reopenedStore.close(); + } + }); + it('should return undefined for non-existent key', async () => { const result = await store.get('missing-key'); expect(result).toBeUndefined(); @@ -89,8 +164,8 @@ describe('SqliteCacheStore', () => { store.close(); // Create a store with a tiny size limit (e.g. 25 bytes) - // Keys 'k1', 'k2', 'k3' are small (each is 10 bytes: key + JSON.stringify(value)). - // Total size of k1 + k2 + k3 is 30 bytes, which exceeds the 25 bytes limit. + // Keys 'k1', 'k2', 'k3' are small (each is 12 bytes: 2 byte key + 10 byte serialized value). + // Total size of k1 + k2 + k3 is 36 bytes, which exceeds the 25 bytes limit. const sizeStore = new SqliteCacheStore(cachePath, 25); // Set k1, then k2, then k3. From 51565d4bcbd4667c23c607d878f08301afc4c5e3 Mon Sep 17 00:00:00 2001 From: Alan Agius <17563226+alan-agius4@users.noreply.github.com> Date: Thu, 27 Aug 2026 13:09:16 +0000 Subject: [PATCH 357/787] fix(@angular/build): enable code splitting for vitest browser tests Enables code splitting for Vitest browser tests while keeping it disabled for Node-based tests (JSDOM/Happy-DOM). Vitest's Node-based module loading emulation (vite-node) is not fully spec compliant and lacks live ESM bindings across chunk boundaries, which can cause uninitialized exports and break mocking. In browser tests, however, the real browser adheres to the ECMAScript spec, so code splitting can be safely enabled there. --- .../unit-test/runners/vitest/build-options.ts | 12 ++++++------ .../src/tools/esbuild/angular/compiler-plugin.ts | 4 +--- 2 files changed, 7 insertions(+), 9 deletions(-) diff --git a/packages/angular/build/src/builders/unit-test/runners/vitest/build-options.ts b/packages/angular/build/src/builders/unit-test/runners/vitest/build-options.ts index 3936f44b09fd..c522d51c2272 100644 --- a/packages/angular/build/src/builders/unit-test/runners/vitest/build-options.ts +++ b/packages/angular/build/src/builders/unit-test/runners/vitest/build-options.ts @@ -256,13 +256,13 @@ export async function getVitestBuildOptions( sourceMap: { scripts: true, vendor: false, styles: false }, outputHashing: adjustOutputHashing(baseBuildOptions.outputHashing), optimization: false, + namedChunks: false, entryPoints, - // Every spec file is its own entry point, so splitting hoists any module shared between two - // specs into a chunk whose exports are then read across a chunk boundary. Those reads rely on - // live ESM bindings, and a module placed in a shared chunk is only assigned its exported value - // when that chunk's lazy initializer runs, so an importing chunk can read `undefined`. Nothing - // downloads these bundles, so there is no benefit to weigh against that. - disableCodeSplitting: true, + // Vitest's Node-based module loading emulation (vite-node) is not fully spec compliant and lacks + // live ESM bindings across chunk boundaries. This can cause uninitialized exports or break mocking. + // In browser tests, however, the real browser adheres to the ECMAScript spec, so code splitting can + // be safely enabled. + disableCodeSplitting: options.browsers?.length ? false : true, // Enable support for vitest browser prebundling. Excludes can be controlled with a runnerConfig // and the `optimizeDeps.exclude` option. externalPackages: true, diff --git a/packages/angular/build/src/tools/esbuild/angular/compiler-plugin.ts b/packages/angular/build/src/tools/esbuild/angular/compiler-plugin.ts index b0ff0593cecc..0cc9d1f499f8 100644 --- a/packages/angular/build/src/tools/esbuild/angular/compiler-plugin.ts +++ b/packages/angular/build/src/tools/esbuild/angular/compiler-plugin.ts @@ -576,9 +576,7 @@ export function createCompilerPlugin( const replacement = pluginOptions.fileReplacements?.[path.normalize(args.path)]; if (replacement) { return { - contents: await import('node:fs/promises').then(({ readFile }) => - readFile(path.normalize(replacement)), - ), + contents: await readFile(path.normalize(replacement)), loader: 'json' as const, watchFiles: [replacement], }; From bbaa07b75a6565c83257aa965d82de59f0c1dd7f Mon Sep 17 00:00:00 2001 From: Alan Agius <17563226+alan-agius4@users.noreply.github.com> Date: Thu, 27 Aug 2026 08:23:08 +0000 Subject: [PATCH 358/787] build: update all non-major dependencies See associated pull request for more information. Closes #33939 as a pr takeover --- package.json | 12 +- packages/angular/build/package.json | 10 +- packages/angular/cli/package.json | 4 +- .../angular_devkit/build_angular/package.json | 2 +- packages/angular_devkit/core/package.json | 2 +- pnpm-lock.yaml | 742 +++++++++--------- tests/e2e/utils/tar.ts | 11 +- tests/package.json | 2 +- 8 files changed, 409 insertions(+), 376 deletions(-) diff --git a/package.json b/package.json index b4a082868bcb..fbf396e21a0e 100644 --- a/package.json +++ b/package.json @@ -70,7 +70,7 @@ "@rollup/plugin-commonjs": "^29.0.0", "@rollup/plugin-json": "^6.1.0", "@rollup/plugin-node-resolve": "16.0.3", - "@rollup/wasm-node": "4.62.5", + "@rollup/wasm-node": "4.63.0", "@stylistic/eslint-plugin": "^5.0.0", "@tony.ganchev/eslint-plugin-header": "~3.4.0", "@types/babel__core": "7.20.5", @@ -91,13 +91,13 @@ "@types/semver": "^7.3.12", "@types/yargs": "^17.0.20", "@types/yargs-parser": "^21.0.0", - "@typescript-eslint/eslint-plugin": "8.67.0", - "@typescript-eslint/parser": "8.67.0", + "@typescript-eslint/eslint-plugin": "8.68.0", + "@typescript-eslint/parser": "8.68.0", "ajv": "8.20.0", "buffer": "6.0.3", "esbuild": "0.28.2", "esbuild-wasm": "0.28.2", - "eslint": "10.9.0", + "eslint": "10.9.1", "eslint-config-prettier": "10.1.8", "eslint-plugin-import": "2.32.0", "express": "5.2.1", @@ -119,9 +119,9 @@ "lodash": "^4.17.21", "magic-string": "1.2.2", "prettier": "^3.0.0", - "puppeteer": "25.8.0", + "puppeteer": "25.9.0", "quicktype-core": "26.0.0", - "rollup": "4.62.5", + "rollup": "4.63.0", "rollup-license-plugin": "~3.2.0", "rollup-plugin-dts": "6.5.1", "rollup-plugin-sourcemaps2": "0.5.8", diff --git a/packages/angular/build/package.json b/packages/angular/build/package.json index 609cf3132ce0..906505b51f86 100644 --- a/packages/angular/build/package.json +++ b/packages/angular/build/package.json @@ -30,12 +30,12 @@ "esbuild": "0.28.2", "https-proxy-agent": "9.1.0", "jsonc-parser": "3.3.1", - "listr2": "11.0.0", + "listr2": "11.0.1", "magic-string": "1.2.2", "mrmime": "2.0.1", - "oxc-parser": "0.146.0", + "oxc-parser": "0.147.0", "parse5-html-rewriting-stream": "8.0.1", - "picomatch": "4.0.5", + "picomatch": "4.0.7", "piscina": "5.3.1", "rolldown": "1.2.5", "sass": "1.103.1", @@ -52,13 +52,13 @@ "devDependencies": { "@angular-devkit/core": "workspace:*", "@angular/ssr": "workspace:*", - "@oxc-project/types": "0.146.0", + "@oxc-project/types": "0.147.0", "istanbul-lib-instrument": "6.0.3", "jsdom": "30.0.1", "less": "4.9.0", "ng-packagr": "22.2.0-next.3", "postcss": "8.5.26", - "rollup": "4.62.5", + "rollup": "4.63.0", "rxjs": "7.8.2", "vitest": "4.1.11" }, diff --git a/packages/angular/cli/package.json b/packages/angular/cli/package.json index 8af94acdb2f7..7510daba2329 100644 --- a/packages/angular/cli/package.json +++ b/packages/angular/cli/package.json @@ -16,11 +16,11 @@ "@angular-devkit/core": "workspace:0.0.0-PLACEHOLDER", "@angular-devkit/schematics": "workspace:0.0.0-PLACEHOLDER", "@inquirer/prompts": "8.6.0", - "@listr2/prompt-adapter-inquirer": "4.2.5", + "@listr2/prompt-adapter-inquirer": "4.2.6", "@modelcontextprotocol/server": "2.0.0", "@schematics/angular": "workspace:0.0.0-PLACEHOLDER", "jsonc-parser": "3.3.1", - "listr2": "11.0.0", + "listr2": "11.0.1", "npm-package-arg": "14.0.0", "parse5-html-rewriting-stream": "8.0.1", "semver": "7.8.5", diff --git a/packages/angular_devkit/build_angular/package.json b/packages/angular_devkit/build_angular/package.json index 4b9531956a86..bdd784c01bf1 100644 --- a/packages/angular_devkit/build_angular/package.json +++ b/packages/angular_devkit/build_angular/package.json @@ -40,7 +40,7 @@ "mini-css-extract-plugin": "2.10.2", "open": "11.0.1", "ora": "9.4.1", - "picomatch": "4.0.5", + "picomatch": "4.0.7", "piscina": "5.3.1", "postcss": "8.5.26", "postcss-loader": "8.2.1", diff --git a/packages/angular_devkit/core/package.json b/packages/angular_devkit/core/package.json index 0834f96afba0..8145dfe036b6 100644 --- a/packages/angular_devkit/core/package.json +++ b/packages/angular_devkit/core/package.json @@ -28,7 +28,7 @@ "ajv": "8.20.0", "ajv-formats": "3.0.1", "jsonc-parser": "3.3.1", - "picomatch": "4.0.5", + "picomatch": "4.0.7", "rxjs": "7.8.2", "source-map": "0.8.0" }, diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 6bab452d7092..f3b55cb8ec6e 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -78,34 +78,34 @@ importers: version: 0.28.0 '@eslint/compat': specifier: 2.1.0 - version: 2.1.0(eslint@10.9.0(jiti@2.7.0)(supports-color@11.0.0)) + version: 2.1.0(eslint@10.9.1(jiti@2.7.0)(supports-color@11.0.0)) '@eslint/eslintrc': specifier: 3.3.6 version: 3.3.6(supports-color@11.0.0) '@eslint/js': specifier: 10.0.1 - version: 10.0.1(eslint@10.9.0(jiti@2.7.0)(supports-color@11.0.0)) + version: 10.0.1(eslint@10.9.1(jiti@2.7.0)(supports-color@11.0.0)) '@rollup/plugin-alias': specifier: ^6.0.0 - version: 6.0.0(rollup@4.62.5) + version: 6.0.0(rollup@4.63.0) '@rollup/plugin-commonjs': specifier: ^29.0.0 - version: 29.0.3(rollup@4.62.5) + version: 29.0.3(rollup@4.63.0) '@rollup/plugin-json': specifier: ^6.1.0 - version: 6.1.0(rollup@4.62.5) + version: 6.1.0(rollup@4.63.0) '@rollup/plugin-node-resolve': specifier: 16.0.3 - version: 16.0.3(rollup@4.62.5) + version: 16.0.3(rollup@4.63.0) '@rollup/wasm-node': - specifier: 4.62.5 - version: 4.62.5 + specifier: 4.63.0 + version: 4.63.0 '@stylistic/eslint-plugin': specifier: ^5.0.0 - version: 5.10.0(eslint@10.9.0(jiti@2.7.0)(supports-color@11.0.0)) + version: 5.10.0(eslint@10.9.1(jiti@2.7.0)(supports-color@11.0.0)) '@tony.ganchev/eslint-plugin-header': specifier: ~3.4.0 - version: 3.4.4(eslint@10.9.0(jiti@2.7.0)(supports-color@11.0.0)) + version: 3.4.4(eslint@10.9.1(jiti@2.7.0)(supports-color@11.0.0)) '@types/babel__core': specifier: 7.20.5 version: 7.20.5 @@ -161,11 +161,11 @@ importers: specifier: ^21.0.0 version: 21.0.3 '@typescript-eslint/eslint-plugin': - specifier: 8.67.0 - version: 8.67.0(@typescript-eslint/parser@8.67.0(eslint@10.9.0(jiti@2.7.0)(supports-color@11.0.0))(supports-color@11.0.0)(typescript@6.0.3))(eslint@10.9.0(jiti@2.7.0)(supports-color@11.0.0))(supports-color@11.0.0)(typescript@6.0.3) + specifier: 8.68.0 + version: 8.68.0(@typescript-eslint/parser@8.68.0(eslint@10.9.1(jiti@2.7.0)(supports-color@11.0.0))(supports-color@11.0.0)(typescript@6.0.3))(eslint@10.9.1(jiti@2.7.0)(supports-color@11.0.0))(supports-color@11.0.0)(typescript@6.0.3) '@typescript-eslint/parser': - specifier: 8.67.0 - version: 8.67.0(eslint@10.9.0(jiti@2.7.0)(supports-color@11.0.0))(supports-color@11.0.0)(typescript@6.0.3) + specifier: 8.68.0 + version: 8.68.0(eslint@10.9.1(jiti@2.7.0)(supports-color@11.0.0))(supports-color@11.0.0)(typescript@6.0.3) ajv: specifier: 8.20.0 version: 8.20.0 @@ -179,14 +179,14 @@ importers: specifier: 0.28.2 version: 0.28.2 eslint: - specifier: 10.9.0 - version: 10.9.0(jiti@2.7.0)(supports-color@11.0.0) + specifier: 10.9.1 + version: 10.9.1(jiti@2.7.0)(supports-color@11.0.0) eslint-config-prettier: specifier: 10.1.8 - version: 10.1.8(eslint@10.9.0(jiti@2.7.0)(supports-color@11.0.0)) + version: 10.1.8(eslint@10.9.1(jiti@2.7.0)(supports-color@11.0.0)) eslint-plugin-import: specifier: 2.32.0 - version: 2.32.0(@typescript-eslint/parser@8.67.0(eslint@10.9.0(jiti@2.7.0)(supports-color@11.0.0))(supports-color@11.0.0)(typescript@6.0.3))(eslint@10.9.0(jiti@2.7.0)(supports-color@11.0.0))(supports-color@11.0.0) + version: 2.32.0(@typescript-eslint/parser@8.68.0(eslint@10.9.1(jiti@2.7.0)(supports-color@11.0.0))(supports-color@11.0.0)(typescript@6.0.3))(eslint@10.9.1(jiti@2.7.0)(supports-color@11.0.0))(supports-color@11.0.0) express: specifier: 5.2.1 version: 5.2.1(supports-color@11.0.0) @@ -245,23 +245,23 @@ importers: specifier: ^3.0.0 version: 3.9.6 puppeteer: - specifier: 25.8.0 - version: 25.8.0(bufferutil@4.1.0)(utf-8-validate@6.0.6) + specifier: 25.9.0 + version: 25.9.0(bufferutil@4.1.0)(utf-8-validate@6.0.6) quicktype-core: specifier: 26.0.0 version: 26.0.0 rollup: - specifier: 4.62.5 - version: 4.62.5 + specifier: 4.63.0 + version: 4.63.0 rollup-license-plugin: specifier: ~3.2.0 version: 3.2.1 rollup-plugin-dts: specifier: 6.5.1 - version: 6.5.1(rollup@4.62.5)(typescript@6.0.3) + version: 6.5.1(rollup@4.63.0)(typescript@6.0.3) rollup-plugin-sourcemaps2: specifier: 0.5.8 - version: 0.5.8(@types/node@22.20.1)(rollup@4.62.5) + version: 0.5.8(@types/node@22.20.1)(rollup@4.63.0) semver: specifier: 7.8.5 version: 7.8.5 @@ -362,8 +362,8 @@ importers: specifier: 3.3.1 version: 3.3.1 listr2: - specifier: 11.0.0 - version: 11.0.0 + specifier: 11.0.1 + version: 11.0.1 magic-string: specifier: 1.2.2 version: 1.2.2 @@ -371,14 +371,14 @@ importers: specifier: 2.0.1 version: 2.0.1 oxc-parser: - specifier: 0.146.0 - version: 0.146.0 + specifier: 0.147.0 + version: 0.147.0 parse5-html-rewriting-stream: specifier: 8.0.1 version: 8.0.1 picomatch: - specifier: 4.0.5 - version: 4.0.5 + specifier: 4.0.7 + version: 4.0.7 piscina: specifier: 5.3.1 version: 5.3.1 @@ -414,8 +414,8 @@ importers: specifier: workspace:* version: link:../ssr '@oxc-project/types': - specifier: 0.146.0 - version: 0.146.0 + specifier: 0.147.0 + version: 0.147.0 istanbul-lib-instrument: specifier: 6.0.3 version: 6.0.3(supports-color@11.0.0) @@ -432,8 +432,8 @@ importers: specifier: 8.5.26 version: 8.5.26 rollup: - specifier: 4.62.5 - version: 4.62.5 + specifier: 4.63.0 + version: 4.63.0 rxjs: specifier: 7.8.2 version: 7.8.2 @@ -460,8 +460,8 @@ importers: specifier: 8.6.0 version: 8.6.0(@types/node@22.20.1) '@listr2/prompt-adapter-inquirer': - specifier: 4.2.5 - version: 4.2.5(@inquirer/prompts@8.6.0(@types/node@22.20.1))(@types/node@22.20.1)(listr2@11.0.0) + specifier: 4.2.6 + version: 4.2.6(@inquirer/prompts@8.6.0(@types/node@22.20.1))(@types/node@22.20.1)(listr2@11.0.1) '@modelcontextprotocol/server': specifier: 2.0.0 version: 2.0.0 @@ -472,8 +472,8 @@ importers: specifier: 3.3.1 version: 3.3.1 listr2: - specifier: 11.0.0 - version: 11.0.0 + specifier: 11.0.1 + version: 11.0.1 npm-package-arg: specifier: 14.0.0 version: 14.0.0 @@ -650,8 +650,8 @@ importers: specifier: 9.4.1 version: 9.4.1 picomatch: - specifier: 4.0.5 - version: 4.0.5 + specifier: 4.0.7 + version: 4.0.7 piscina: specifier: 5.3.1 version: 5.3.1 @@ -758,8 +758,8 @@ importers: specifier: 3.3.1 version: 3.3.1 picomatch: - specifier: 4.0.5 - version: 4.0.5 + specifier: 4.0.7 + version: 4.0.7 rxjs: specifier: 7.8.2 version: 7.8.2 @@ -843,8 +843,8 @@ importers: specifier: 3.1.4 version: 3.1.4 tar-stream: - specifier: 3.2.0 - version: 3.2.0 + specifier: 3.2.1 + version: 3.2.1 packages: @@ -867,6 +867,7 @@ packages: '@angular/animations@22.2.0-next.3': resolution: {integrity: sha512-6NvI3B8d8d9XbZi2gMRwY+eBthu62uW8Gi5CHBSShlDmJc8KfYItPgVOXYYNL9im0jN1tReFiwHV4sds5vlgZA==} engines: {node: ^22.22.3 || ^24.15.0 || >=26.0.0} + deprecated: '@angular/animations is deprecated. Use `animate.enter` and `animate.leave` instead. For more information see: https://v22.angular.dev/guide/animations.' peerDependencies: '@angular/core': 22.2.0-next.3 @@ -2458,12 +2459,12 @@ packages: '@leichtgewicht/ip-codec@2.0.5': resolution: {integrity: sha512-Vo+PSpZG2/fmgmiNzYK9qWRh8h/CHrwD0mo1h1DzL4yzHNSfWYujGTYsWGreD000gcgmZ7K4Ys6Tx9TxtsKdDw==} - '@listr2/prompt-adapter-inquirer@4.2.5': - resolution: {integrity: sha512-pYGy9dTdTwXdasPgyohkr0HoQ4FrkAzFnsUZl/gcnadDArbpZ8e+fgr+F9WBdNEl2y00mb9bCM4WgmoBkZJ27A==} + '@listr2/prompt-adapter-inquirer@4.2.6': + resolution: {integrity: sha512-eQSUUwTpKIXOgbJ4Fx2vEzV0h6ofWknhgtaTSab0C5xG/kWZRg9n3hx5+lE9Z5Z+cXZ2efpVpWT0tNueWRP71w==} engines: {node: '>=22.13.0'} peerDependencies: '@inquirer/prompts': '>= 3 < 9' - listr2: 11.0.0 + listr2: 11.0.1 '@lmdb/lmdb-darwin-arm64@3.5.6': resolution: {integrity: sha512-mY5FG4TjPAkY4P0w+OhHaUka5mDh2TX2WKYIwuKzJ1zeW3VvRgxdam/lGJTquI+bthTx5CSHDW+BAQCnNAzkEA==} @@ -2804,124 +2805,124 @@ packages: resolution: {integrity: sha512-eSYWTm620tTk45EKSedaUL8MFYI8hW164hIXsgIHyxu3VobUB3fFCu5t0hQby6OoWRPsG1KkKUG2M5UadiLiVg==} engines: {node: '>=14'} - '@oxc-parser/binding-android-arm-eabi@0.146.0': - resolution: {integrity: sha512-jBCZIsff/9J/zdK1KSKZREScXOtRE4wYO+MUjrE+5NHGdsslrP4biJA9QJyKwErwS8lkwxH6Z537HaL4CQr0ow==} + '@oxc-parser/binding-android-arm-eabi@0.147.0': + resolution: {integrity: sha512-fOtoGvIoirkvxQVw9J1WJPxz571XPgLsPf9uhRD+PJteUnvrJHMDmK9pw2yZEGGyismtRoEsp+JcXUdF/JDMDw==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm] os: [android] - '@oxc-parser/binding-android-arm64@0.146.0': - resolution: {integrity: sha512-BVwj6sVmgD9j5F+R5B+13pYQKOCmew+3myS19wcG5e+AeZu5ybBLEfcaKueC8MhvjtwL2Suh2tQE/Ywop2Z8rA==} + '@oxc-parser/binding-android-arm64@0.147.0': + resolution: {integrity: sha512-emjQHOYJaomo4ykaXQ1EItunr/I94Nk01oqBmU4dSkKSTupIDx6OysVDf2e8Eytm77rb+4ZxzgElyWP7rcEX7A==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [android] - '@oxc-parser/binding-darwin-arm64@0.146.0': - resolution: {integrity: sha512-jQGIM4zEEvvuypbBcoeoWuigRfP6R8Ow/9gfDzVoYkv5mFyVPbIePNQnV752jUynfty0nDxarIpML+7Q/MyMPg==} + '@oxc-parser/binding-darwin-arm64@0.147.0': + resolution: {integrity: sha512-kXvBPJL7RmDPJ2mze/vXPPVQimCDtFr9OFLjf7dyhV5Dx64cgcXh9KKrA1sMWvCObvJll9CZZUO0FBlFwD0l6A==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [darwin] - '@oxc-parser/binding-darwin-x64@0.146.0': - resolution: {integrity: sha512-quDy3cvW1712l6W+qe1/xWRym6STOuGJmFzRIg5StXVJglsbqrCpHfw9PyqPs0hQeOAjAEO1USrjPaIvHiRKQw==} + '@oxc-parser/binding-darwin-x64@0.147.0': + resolution: {integrity: sha512-mgFF8pLU6R64LbT27lSrtVRspVC/3IcZ0qyIikzmi78Y3Ik2OPnlAHHI0UEBRcC3qmNgtjaef7zkFt7/uPxIcw==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [darwin] - '@oxc-parser/binding-freebsd-x64@0.146.0': - resolution: {integrity: sha512-wx/p/9phlX4VbYk671G4WewST3pysXNQfZRx4gx69QIz0/uW2O3MCnnEQh4il6l2lYr0EDAq3kFYovIw68CXHw==} + '@oxc-parser/binding-freebsd-x64@0.147.0': + resolution: {integrity: sha512-v38aiF11qufOTBcCAKL4skgQf0zJ4NEvRlivq7B5kHrlyvjCLjvNrMtNWDTz1SDUL6/xVsJRmLDxv2e+Cp4oWw==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [freebsd] - '@oxc-parser/binding-linux-arm-gnueabihf@0.146.0': - resolution: {integrity: sha512-W9nzfbWH8Z6cIaBj6Rh/eVgymFkZ2MaOV0rQruKTLYKLAZADo9JlOmBml6Dq2QbChtmuc3DKDL42KDHaQFX8yQ==} + '@oxc-parser/binding-linux-arm-gnueabihf@0.147.0': + resolution: {integrity: sha512-AeIiBbwUaP0H1+4/qGW9l5qHecS/+XA5iMuieVcGb1T+tyc2dVGspFW13BWk/XrLsiGP/CiDJTJqAPLLCzZHkw==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm] os: [linux] - '@oxc-parser/binding-linux-arm-musleabihf@0.146.0': - resolution: {integrity: sha512-S5X1mEvTLBTl+xt7bRlr1n6qI+OTy1EaRkYyd4EQgEZqV7i53fQa1I72OqR0IwSQKVwh6TZPkzDcsN7fS9MynQ==} + '@oxc-parser/binding-linux-arm-musleabihf@0.147.0': + resolution: {integrity: sha512-/41MKPW4RgPY4DJco0NCF0RYX3IMZaVlRNMNzvhaxRavc7tN3Txm+qllZbh0aMRs0VHdgUlbI8TcAOiTai4TKg==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm] os: [linux] - '@oxc-parser/binding-linux-arm64-gnu@0.146.0': - resolution: {integrity: sha512-Br9UB4nnecVfj/Vp+JiJnJo2wIJtwaOm+uN7MwWKF5cx10P816urucmksG/iG2OeL7hfZ4h5fCmePrLU6TocfQ==} + '@oxc-parser/binding-linux-arm64-gnu@0.147.0': + resolution: {integrity: sha512-bmpw/RPhVXgZbtb3xBDuwW5s8+LvZYdqcDSX/sP2ltL77aTio3DP/B5ZTwwgoJ6Mr9vJs4RrmgEKW9XkLNUU1g==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [linux] libc: [glibc] - '@oxc-parser/binding-linux-arm64-musl@0.146.0': - resolution: {integrity: sha512-5AP+od9VGhRyCwswTfuD0jSDfIcWptEBC+K0LWmXsUJ9BPVF3KbhsjeoV+9tijX6g5is0w4H8DUV7NkOJoOVVA==} + '@oxc-parser/binding-linux-arm64-musl@0.147.0': + resolution: {integrity: sha512-gd7VX/FDVOw6mjQcu45iIcp4QkgybgJwh3a0OFG2NxmPCj628mQWD96QGu1kK8+mZF9qK4b/gIEyC63vQoB7+Q==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [linux] libc: [musl] - '@oxc-parser/binding-linux-ppc64-gnu@0.146.0': - resolution: {integrity: sha512-Qz3jc1qgvU9B9vQu3jAJcxKlGX7zYRtKs8LPYtQi8cmirhtYcX6XvXseESaDFbi1L+SorXhjRQ/2npEX85kKBw==} + '@oxc-parser/binding-linux-ppc64-gnu@0.147.0': + resolution: {integrity: sha512-HnAzcfki7dSUNHf510Q2NmbJlz8Ys7rn8l9l588Pkx0tYe1BHLZnmELIgqizJ4WPhHGSwN8Ce+B/menVxS3odA==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [ppc64] os: [linux] libc: [glibc] - '@oxc-parser/binding-linux-riscv64-gnu@0.146.0': - resolution: {integrity: sha512-Mfmg18lOZ1IWJJJuHi1ZsMLunqNVeLEh3Byuw+Aa8dYo7qOrZOMZQz1gFgAeNga5/Z5jjRuIKuIdo9aO7HYMdg==} + '@oxc-parser/binding-linux-riscv64-gnu@0.147.0': + resolution: {integrity: sha512-qlkOL6wT44U+fT5s/+sR6Shx0OdwvQF83JyIPZUxG/ovqZF5/7atOtjH+JPZ5/7ATQLbFBBSmghcy/+2NVB/ew==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [riscv64] os: [linux] libc: [glibc] - '@oxc-parser/binding-linux-riscv64-musl@0.146.0': - resolution: {integrity: sha512-6OdXwYnzbwYcnUH8f0LYauLNitjIcgDR/CDA/wcZ2whwJwVflGtCLF3+3HOXgs/SESnpQCWXr7Q/z9muLJ5bmQ==} + '@oxc-parser/binding-linux-riscv64-musl@0.147.0': + resolution: {integrity: sha512-DlefD7L7sMXs/3hIBH23Egk0phj8kG0SA81dVGOQ3S1ekjOlmTLH2E+F2Thwfh1slKx6aH+lNc5fQYAw0GU7/g==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [riscv64] os: [linux] libc: [musl] - '@oxc-parser/binding-linux-s390x-gnu@0.146.0': - resolution: {integrity: sha512-BilV4Ei84A0m6r1v+LmgVrfUMbAz33IXRooVw/BQNDExUvGGNLrk6NWeot+ve99bRidTZdwWuzBHgxWCnSSa9Q==} + '@oxc-parser/binding-linux-s390x-gnu@0.147.0': + resolution: {integrity: sha512-Xqpagk/031IvZ4svrk2FF01YEqM/iN3MJV3SVZadKg/CsGlDCGoREqKHXYnoV5+8SfGe/m6RM1szXFLusTu/Uw==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [s390x] os: [linux] libc: [glibc] - '@oxc-parser/binding-linux-x64-gnu@0.146.0': - resolution: {integrity: sha512-RaMfGIpWOa87u3aD87drbPgisy7Nv6gIdjRFw6msIDKO+3FmcOTw+vpp4hVANhUIzpQta2EAsmYQRrqeprZTmQ==} + '@oxc-parser/binding-linux-x64-gnu@0.147.0': + resolution: {integrity: sha512-QioQOeUbI4ATUr0S2z88uA3Cds2R3Mm5Ge7U8XNYtlTb2GJF3rWlcj70z0AJhhOlbdm0YgVjqPBldUNbFylDIg==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [linux] libc: [glibc] - '@oxc-parser/binding-linux-x64-musl@0.146.0': - resolution: {integrity: sha512-0bzF60jfQRsJ9TJOIHK+wSUirenJAyWCdP9z3P6LMS0znD4Gf7WYOiv7niONVOpRnlGjzMPd4kqgOJfCDLQAQg==} + '@oxc-parser/binding-linux-x64-musl@0.147.0': + resolution: {integrity: sha512-NXy1tv/OdC+pPTwf9RiCZWPK53V/Xq/2cjSnjOSyKopajdaDqMIkgtDY+jXZemp2e8px5FeWfY2L2LwhKZQovg==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [linux] libc: [musl] - '@oxc-parser/binding-openharmony-arm64@0.146.0': - resolution: {integrity: sha512-O1gxUFt5FUgyFVUQK2BhZNwv7jLsqLR8uBANOhpYE5D5q+eCvcry7RvQT3DgKpWP1XRYB5UsbQGHHcwchEKb+w==} + '@oxc-parser/binding-openharmony-arm64@0.147.0': + resolution: {integrity: sha512-GpGWZ6oKz4bjCWW9Mz5pCaGPyk2Aaze6zEoaslIQqpSLtpx5pXj/ap5gUNb5Jn2LIbqWyjkGLX9yv3NMuNcBVQ==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [openharmony] - '@oxc-parser/binding-win32-arm64-msvc@0.146.0': - resolution: {integrity: sha512-i46zYS0TTCt+oaXaDx4mKxuXo+h8OBWI12XFatRm5I9/l2WKhp4TQ6VAjw0r1NMRiQQZ9dwQlRyQNhyTkOaINg==} + '@oxc-parser/binding-win32-arm64-msvc@0.147.0': + resolution: {integrity: sha512-a8mlt7CC8z7LUdCfaxhff4kCd+vSjE+NEFL0cxA8ukfuSnvAto/pWTjytW4BuVLnQGcCVdHJwcRKOfs++H+tjw==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [win32] - '@oxc-parser/binding-win32-ia32-msvc@0.146.0': - resolution: {integrity: sha512-v1bb+ma2oKXwh4NHAg2NQwe9ORXFBDSCEkuO1qC4Rzm8EXcQdNhiJHpTNfulZ2P+1QpYUB6QYupW4mgMVom/tA==} + '@oxc-parser/binding-win32-ia32-msvc@0.147.0': + resolution: {integrity: sha512-M5ViVDBcFLnl2632AuuWuP35zEL5oikK1jTx8r3+902VEDeSNHxFZAB6RZyfZ7MU6Oi5QTOG8MmMkIeHsudSaw==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [ia32] os: [win32] - '@oxc-parser/binding-win32-x64-msvc@0.146.0': - resolution: {integrity: sha512-uT8N1/qdNSGonvW1O2kZYNczqb/VYfnj5dpUy1FmedOPodj3MNFNWhAJkMZlI5u8xuTRtrpTccnr0U5HAMVRjQ==} + '@oxc-parser/binding-win32-x64-msvc@0.147.0': + resolution: {integrity: sha512-DUaE13OwnUSlHpLZNcC/nuT10ivlWqc5EZgsfgXuAmWYw0r3nDxGeLD1zlGwYwIgVk1/ZMAxoXpV+05stvbHaA==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [win32] @@ -2929,6 +2930,9 @@ packages: '@oxc-project/types@0.146.0': resolution: {integrity: sha512-XC0QsnnhVe7sLIWmYmdPw7x5P0h4W8vUU3Nv1ySgWXtvCz8NizoAEpGXA0sOYoJQV2Rl13LgURAHQ5cI5ILCSA==} + '@oxc-project/types@0.147.0': + resolution: {integrity: sha512-IJ3s6ltHLp45S0bh7phkX+gJO7A1Wuz2EaqpAhb8WjqDwbzMiWKHhyyT42tskaWjEYXtHtVCPpnBJVT9+dcRLg==} + '@parcel/watcher-android-arm64@2.6.0': resolution: {integrity: sha512-trgpLSCKRC/huFjXX/Smh+0sWe4+YtKfktIToiMl59ghz7z+qkH6kMvNnUbLyRs9N11t8l4svSCs1+5B3rOAhA==} engines: {node: '>= 10.0.0'} @@ -3269,146 +3273,146 @@ packages: rollup: optional: true - '@rollup/rollup-android-arm-eabi@4.62.5': - resolution: {integrity: sha512-jfkGfTwhQpsiSckPF8r9bU3pn3vyd72NlWaO+TgEO6WPSDnUhXzrNYCHBMOYj0ACaUgjm6eERLF+XV9a6RstoA==} + '@rollup/rollup-android-arm-eabi@4.63.0': + resolution: {integrity: sha512-70TeIFezKKy65LgAVyQh+w94/gjWhvPWaLaGGeMEgVrPkQhuj/M5bAYYZzIFUj9Y69oHyTm5Um/R6gcLh4A8JA==} cpu: [arm] os: [android] - '@rollup/rollup-android-arm64@4.62.5': - resolution: {integrity: sha512-oGVqyQlxnrz9/ty89oHpU857VUHEl5/Xu4R2lS+aivCTrNnSsbiENzTnNaBsjxH0CNWGPhzHArOLFwo+oKXveA==} + '@rollup/rollup-android-arm64@4.63.0': + resolution: {integrity: sha512-YC86tYIHK6M1IV+wbzO+Bxk8RCBr6ZyWYgWxUCzaZD8mc8rrFoIJDNzDrkHBYRc/wKdrsIXmm6/F7NzrAO+OrA==} cpu: [arm64] os: [android] - '@rollup/rollup-darwin-arm64@4.62.5': - resolution: {integrity: sha512-bW7B8xMEq8n99Q3ieEcPRGuphurdZAaFzQc9Efyyw3FL6DZO6pMy9xhdN+kBoD7Sy05xNXSr4OyPPnpkYriS/A==} + '@rollup/rollup-darwin-arm64@4.63.0': + resolution: {integrity: sha512-oI+ECtUcli0y0fi4xpW82GdPIXdTkI8G8DSjG2LRuw09fPAGykaWYH/hXxiKuTxiAjiPSTIIuYUqof5Z2hShWw==} cpu: [arm64] os: [darwin] - '@rollup/rollup-darwin-x64@4.62.5': - resolution: {integrity: sha512-YSwBS86QeHOGlrxJ1PSOIZSkzRL/JmKeunhc+lV6M1a6En8QuVCD/T/qIA0J4Gd2Y86RIOBYrLcOUtqGh9+/1w==} + '@rollup/rollup-darwin-x64@4.63.0': + resolution: {integrity: sha512-NwV+1s7TiKrMe4owHyKB/dTLD7ZJD0YEBEhIz+hvav1Cu1GReJjF+rsdNwjzENQeIAbE/CoNiaAc5Vz2h5DPAA==} cpu: [x64] os: [darwin] - '@rollup/rollup-freebsd-arm64@4.62.5': - resolution: {integrity: sha512-2fST8lILgl7cKbme/1KDdPCmbXbG+gqoV3bHp19L0ypX/3akYMBVdOunPleRCwonoLnXOZ/0F+Mt/v8POFmfcQ==} + '@rollup/rollup-freebsd-arm64@4.63.0': + resolution: {integrity: sha512-tWtHBTu5gOPK4u4Urtk4qAHW3zZ9rQAmbssO8gp7ELvGTGI3aCiq6NqyTQ0PCIg7KbHJF2UkGDDs77YZGxfjCA==} cpu: [arm64] os: [freebsd] - '@rollup/rollup-freebsd-x64@4.62.5': - resolution: {integrity: sha512-cpIxQCP9J+EVad0a6LO1kY3ZGODlk80VlI+2I96B8xMcdHZ4pLVhfQ49JFpYqjPF91FFkQWftf57YlDcTiw9yQ==} + '@rollup/rollup-freebsd-x64@4.63.0': + resolution: {integrity: sha512-2qPoJiwTvtHQ27NnYvTnsgk8laXWYuVmNESG8WFZBcEPKLfZ3I27qBJarjVRQtwGeYyRfq5ZowHXih9lm2BItw==} cpu: [x64] os: [freebsd] - '@rollup/rollup-linux-arm-gnueabihf@4.62.5': - resolution: {integrity: sha512-r9fGh3eFs3e/udWh5ZjXQtxiYK/xoFxQaYR/cELxac/Udkl5Th+IsFm0CX3Kl9hmUH/we7EoMpjJgeQNnE0+IA==} + '@rollup/rollup-linux-arm-gnueabihf@4.63.0': + resolution: {integrity: sha512-FQwsTRvLNuHoTdICABJQfbPUSEueISGmnpT06tXTMpfprf5NiKLSXKA0A+w45wJnCmZAnzgqBwbt6ARFuyOi5w==} cpu: [arm] os: [linux] libc: [glibc] - '@rollup/rollup-linux-arm-musleabihf@4.62.5': - resolution: {integrity: sha512-xdvFdp7OM6KLJviJT2g/YuRSUjnZgGHk4RNgwIbN7X6cPugOucV60DdHXWzsBVCUdrGb6qSXnJQrrAKMmQuj3Q==} + '@rollup/rollup-linux-arm-musleabihf@4.63.0': + resolution: {integrity: sha512-BBVTXziw8mY1a4ZbWME9tZyfzqXCDPqaC7Z3heQ29p5dkvXzwL0NwelO8zLa8c3RBKvl3YTuSnBgsBhYBtwjIw==} cpu: [arm] os: [linux] libc: [musl] - '@rollup/rollup-linux-arm64-gnu@4.62.5': - resolution: {integrity: sha512-rRqILAndyzHzP7T9NFQrq+4HFWNhqkqkKur7eiBpfLmz01PO0JKx5Vchu3YllE4YXI/Ftgq/szrDWg5GJ0mI8g==} + '@rollup/rollup-linux-arm64-gnu@4.63.0': + resolution: {integrity: sha512-w2Iyy9+RqKwx3d9qWMKsJg0FfRBsY0/pXNv0mCQ3ueRvJI6+QAScfD4nrMlzFLs2HNVW6Ew+mtZfDl9b7Ew5/Q==} cpu: [arm64] os: [linux] libc: [glibc] - '@rollup/rollup-linux-arm64-musl@4.62.5': - resolution: {integrity: sha512-Gf4X3qVMucayUvux6aXXPgXovocSFUC0rrffDuPI/S2nHhNMhjcZxsrAFYCOF350PRreW1XwzFj3CT/3bKsWCw==} + '@rollup/rollup-linux-arm64-musl@4.63.0': + resolution: {integrity: sha512-YK++KtrFRHYE0P6/RtYEAy9t8F37znP+K03RrIuLPYOL6SVlObRumf/0OE4V/h63xL9DwkWbNssZfmA9hawuDA==} cpu: [arm64] os: [linux] libc: [musl] - '@rollup/rollup-linux-loong64-gnu@4.62.5': - resolution: {integrity: sha512-+s5qA0TNM0qm8PK/a5gt/1Hpx+NV08uSuCncvhziIlQzT6AEV2fnUQo7eBtFTFO0nA9scauvoR2HusfXmQnO4w==} + '@rollup/rollup-linux-loong64-gnu@4.63.0': + resolution: {integrity: sha512-aBfOG6fP7YkkPmTqPwufRJeFyz7WPpECv9XNbnsk9+vg7rxdih0lbtEel7jcRng4LZrrmU3FfitCFyEj4BWDWg==} cpu: [loong64] os: [linux] libc: [glibc] - '@rollup/rollup-linux-loong64-musl@4.62.5': - resolution: {integrity: sha512-ybb6QvWwWJCbBWqERpc8K3pYVGIrXlG8MEQ8IIuJY6Y9KdHQxoFoNyfkAOtKn1VHu3KuLidXvwrvGR1mEjeWCw==} + '@rollup/rollup-linux-loong64-musl@4.63.0': + resolution: {integrity: sha512-LGaHEOeHNAag9VuS1Crs5DFg4RrU9MPi2nVnNJk9DTePx/B6RRYKVmrIXt2h7YOJlwjaFJ6lwtFDliZxScTLrQ==} cpu: [loong64] os: [linux] libc: [musl] - '@rollup/rollup-linux-ppc64-gnu@4.62.5': - resolution: {integrity: sha512-nZb1DtnOyhCmYvsC8A2CwOkopVg+IS1+fPUa7rMOAXtNw5+lLCLLPqd6XAiNrGtoQKsbvIBOwsHnBH/3wnb4HQ==} + '@rollup/rollup-linux-ppc64-gnu@4.63.0': + resolution: {integrity: sha512-jClvk+J0FC3b7Udvegiw5/4hErbHtmsNsQgENnKXDWtNCJXsJYZH5WURvu7imDOO38xYml24eeh5x3A04ppwCw==} cpu: [ppc64] os: [linux] libc: [glibc] - '@rollup/rollup-linux-ppc64-musl@4.62.5': - resolution: {integrity: sha512-yMbj63Sp89ryrXLWyz+sy+fYD2HpOnMCLGbe4Oa1smclFSUukdtD/BgdiHaAetJNb74URD8U4hM+qG5KVzMEkg==} + '@rollup/rollup-linux-ppc64-musl@4.63.0': + resolution: {integrity: sha512-0OJlaGK+8+B777Ql5okIpD7ua5Ro9+VB9Ve0OKa28OQJZ1RbuUBVNHK/e3pr4BROqsyPl1JrPO1ZxJseCNffcA==} cpu: [ppc64] os: [linux] libc: [musl] - '@rollup/rollup-linux-riscv64-gnu@4.62.5': - resolution: {integrity: sha512-mhoan3OJw2kYV/e1jtIdmvUZgyBFeA6zGWsOswmR0Tg19TQbowZuR+JMLID6spbbBN7Zee2ejrgmy3+FxGrIdA==} + '@rollup/rollup-linux-riscv64-gnu@4.63.0': + resolution: {integrity: sha512-Ygsx+HoNH7afwi1bTIXbnTvVnsO+zurPLSYxybV1hHFVU72OWOCl6v05ql/z0hkpAPx+DK7Kn9Bi7MayCcjLTA==} cpu: [riscv64] os: [linux] libc: [glibc] - '@rollup/rollup-linux-riscv64-musl@4.62.5': - resolution: {integrity: sha512-5ZTLmjWbb1VZdjuyhe83K/8QO0/h11midQCBP+X5OYn32ra7eOBoM0ZqtaY4nkgNsYgmdVhMYPoyVPTjUpHf3w==} + '@rollup/rollup-linux-riscv64-musl@4.63.0': + resolution: {integrity: sha512-pDQxtMGb+OvG3fLwR2OkZlSd47hW+kWg4BYMG/++sR6RqorQccwPTDsxda5hPwiIeIErAnCF9ma3SAU06bdQtQ==} cpu: [riscv64] os: [linux] libc: [musl] - '@rollup/rollup-linux-s390x-gnu@4.62.5': - resolution: {integrity: sha512-m53kG+br6PGxOTmgBEM2DHSDs9RVjsyEbUwjJPJGTFm1grWOG8EKJggDCTb60unD4Tjby8fi7/m9XfkEWasVWg==} + '@rollup/rollup-linux-s390x-gnu@4.63.0': + resolution: {integrity: sha512-0BnUG9mS8I4SSHr3XsxVhuCMEiu+rX61xxZF5vujso4LaiAGFZFxvDjg6Xn6tLPNTUAfuCvQYas4LMQMVsKRSQ==} cpu: [s390x] os: [linux] libc: [glibc] - '@rollup/rollup-linux-x64-gnu@4.62.5': - resolution: {integrity: sha512-6RHPJR1g/uvdYU8uXBnfq3nlqyZCP82Fr6NHgfGoaIeSh0YEqnX/x6uA9MmJJbnSH7swqX4F+CkGdUF+6doiQA==} + '@rollup/rollup-linux-x64-gnu@4.63.0': + resolution: {integrity: sha512-Adu/VttB1dpPNW+FEacrZ+xVm9tFty84+RrFzsqlFaPxoJB+9XXyDGtp5dCOoBwGBIEVH0To7lExFXEx0BIF4A==} cpu: [x64] os: [linux] libc: [glibc] - '@rollup/rollup-linux-x64-musl@4.62.5': - resolution: {integrity: sha512-xs+OXQtEXgpXT0DmA5+U3qnRZHdCST/5HRQxS8wSPZTUZN/EMWeHuSIod32LQklTBZBV9DyfncKBQ8n5V3eFdw==} + '@rollup/rollup-linux-x64-musl@4.63.0': + resolution: {integrity: sha512-NQ3bDvjUbFKmP23671xUlXtKmqVsUBd6M4PQCvbmNtOy06hnQIdKHy8oG/6S3R/S6He1JgPk6A5VT+prAJMYEw==} cpu: [x64] os: [linux] libc: [musl] - '@rollup/rollup-openbsd-x64@4.62.5': - resolution: {integrity: sha512-e7hD+sl3s+mcLQDZ8pbudBVsdG6r5yN4w3LqG2TJ8sQHDpblWj5lrJs/3m01Cvlxbt4x13zu5thLjgypgtkYzw==} + '@rollup/rollup-openbsd-x64@4.63.0': + resolution: {integrity: sha512-u2eDAl4+0aFvA13GxlGBtTI3SS3sdgwgtV0HyjZ0QaQVCgNE+jqNGey+GtxWiq+wxr/UycAx/OnfJzApCFamvA==} cpu: [x64] os: [openbsd] - '@rollup/rollup-openharmony-arm64@4.62.5': - resolution: {integrity: sha512-GiyJaCf+WpMub/17aPcKk27QMl5W6f+KhdPTjlFOn5akH5Wa/DCM9Stdx5cDfmasyKB08MqpVQ1uJE2RkkpbXg==} + '@rollup/rollup-openharmony-arm64@4.63.0': + resolution: {integrity: sha512-XvRb5vfW3wAZQ+ZUG21AnHHDKtNcw99eigzEhjr//NZ3u7SoBaPP0seSc7FgP7p1epAEdAoZckMW9WY/+4w70w==} cpu: [arm64] os: [openharmony] - '@rollup/rollup-win32-arm64-msvc@4.62.5': - resolution: {integrity: sha512-+OQ8U2DdoEfXl8T4Fb18AjmEwbXMerKDKCL8yCPAYhKCEEKoul7rkbeGCBFCbAlaGaa7pmtRTpkAJM2LE/i5FA==} + '@rollup/rollup-win32-arm64-msvc@4.63.0': + resolution: {integrity: sha512-iZPmniy4kNBf5yo2RezbkYNNK5HPbXE9+g+twnbqSng7dtLEJy1SKoxiE/ni4FDacjyuZpEeb9U054N4EoKHYw==} cpu: [arm64] os: [win32] - '@rollup/rollup-win32-ia32-msvc@4.62.5': - resolution: {integrity: sha512-KanvAZrPKbDBFwrgiU9yEVpQoox9QPV1WZOXX7HudJQY+eSlu82CtWxDU8WtuRRvtN5EGkLczkd6Y6DTcvm9wA==} + '@rollup/rollup-win32-ia32-msvc@4.63.0': + resolution: {integrity: sha512-mFBBd+LF37fnE8JnYUOH+imj0aPFPK30vpar4ehJkgnLj9sZn8ZxiRENmLtgIwxK7TC8klF6N57fxdNBwQoqOA==} cpu: [ia32] os: [win32] - '@rollup/rollup-win32-x64-gnu@4.62.5': - resolution: {integrity: sha512-1aC3UEWTtRl3RK3VpDJ/Tqk1XI4SLTmXIthAq6wRWo8XiSXJNd+VprJM4/1P4+i6HIaFEFlVi9sTTziniD2tOQ==} + '@rollup/rollup-win32-x64-gnu@4.63.0': + resolution: {integrity: sha512-ujeqEY3B+zbGn3Z4Q03cUBG/LGWnBJncVT36WER31LcOsQk9+1dmINKKtvmmfChUvRbK1G0R8OhMWFgHgaZtAw==} cpu: [x64] os: [win32] - '@rollup/rollup-win32-x64-msvc@4.62.5': - resolution: {integrity: sha512-/gDJaRs4gl0NPIwqCz+6PkpmhhjRAD2j6P4rSNHBzUkO3naEx2mIU0pRle1vUNRQ7mE/+8OOeXLTv/J56FKiQg==} + '@rollup/rollup-win32-x64-msvc@4.63.0': + resolution: {integrity: sha512-hncn90N4sOky0L2LKE5oESKLbxCPeVo4eLA2LSMoDzM+879ml4WSr+Rr4DWknNIVVvS1Hirkc9hx02W6YxS8rQ==} cpu: [x64] os: [win32] - '@rollup/wasm-node@4.62.5': - resolution: {integrity: sha512-NSyG08F0m74qhvWDyFeYaZapAmieh3bEiQzCzql3N9ErlYoyt+V3xpDX8dBdKiZu1UXUpGNbBEblKaW5zcpqaw==} + '@rollup/wasm-node@4.63.0': + resolution: {integrity: sha512-xYOZhVB5bo0sv80toQNC5doOzaKt9bJtdPobqY1IKHm/Ro0pBq6NoRP/ZuHmoDixR4btK+JepYAtjFNrSK/mgA==} engines: {node: '>=18.0.0', npm: '>=8.0.0'} hasBin: true @@ -3627,39 +3631,39 @@ packages: '@types/yarnpkg__lockfile@1.1.9': resolution: {integrity: sha512-GD4Fk15UoP5NLCNor51YdfL9MSdldKCqOC9EssrRw3HVfar9wUZ5y8Lfnp+qVD6hIinLr8ygklDYnmlnlQo12Q==} - '@typescript-eslint/eslint-plugin@8.67.0': - resolution: {integrity: sha512-Un7Heoyj65NREbKAyIrFxeM143NZpExWmy1Nep4DLeQOeLlTeumPjoNKnBrU5D5moWXbPJgRa5Uwcdu0faVNGQ==} + '@typescript-eslint/eslint-plugin@8.68.0': + resolution: {integrity: sha512-WASHDpCm6qO5jj9g1a+8NiW5+GCkAyLReR56/4VruYmNgfUmqpxOfZ2Yfb8xGfJPWv5Qi6LSD8sXdces3vbp/Q==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: - '@typescript-eslint/parser': ^8.67.0 + '@typescript-eslint/parser': ^8.68.0 eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 typescript: '>=4.8.4 <6.1.0' - '@typescript-eslint/parser@8.67.0': - resolution: {integrity: sha512-fUBfTuuEulWqX6V8+O3PtScV01tzYYRUDTAirHFKoRAt7nOzoGiPt0M/bB47wWNy0coOOcgEwAMUtBpykMxl6w==} + '@typescript-eslint/parser@8.68.0': + resolution: {integrity: sha512-fHq2VC1kpyYfvEcbiMjOpySY4WS7voEp89yAThrHRX5sm9j2lzYppCb2umFMEed4fWcyeLjHxrz0mpjNBaBxMQ==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 typescript: '>=4.8.4 <6.1.0' - '@typescript-eslint/project-service@8.67.0': - resolution: {integrity: sha512-cvE8c7ulYeXN9fYuszhCeCsbzyVEXuhrRCybnBre7TUmqb5nRmBfQAwCj0O3WJFDeyAZt4VYv51vMCC9LHSdYw==} + '@typescript-eslint/project-service@8.68.0': + resolution: {integrity: sha512-5GQtWZCXFcFYux955pvoS02WLc49pXNlvIxocKjS0clvwo3in1RdlzVKyiqQH9vE5AKWFLTaUgeQkOrTS+0Qxw==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: typescript: '>=4.8.4 <6.1.0' - '@typescript-eslint/scope-manager@8.67.0': - resolution: {integrity: sha512-EgvsleTwS4E+WzzSvem8fAUubLwatMNF1B5hHSLQxcvs7q2dtRhGyujHwLJSYlG41niJ7GP24Aha2+0mb1b2kg==} + '@typescript-eslint/scope-manager@8.68.0': + resolution: {integrity: sha512-T5eXpcaJNg8bhjHJ8Rjp68Vq/QBteYtTKY8TZqVNPaUbuz0f6jI9t6aDkylwvalpAB9XTTFeFOjrjXAZ3YvmVA==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@typescript-eslint/tsconfig-utils@8.67.0': - resolution: {integrity: sha512-vV+LUSv5njUWsknE71fqKTlXUva+R76SaeORd6Zojcunk/6DvKFXONU3BrAs2H49mbygUXt6gbYunzwqNwlhdg==} + '@typescript-eslint/tsconfig-utils@8.68.0': + resolution: {integrity: sha512-F7zrGQfiJHojPwi8vhxZQC1tWtJzvL74cK/nqri2lk8YUXvYaYwl263xOJ69jDWPUk1hmcdoayFwk9lX09npVw==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: typescript: '>=4.8.4 <6.1.0' - '@typescript-eslint/type-utils@8.67.0': - resolution: {integrity: sha512-aVWDXbRmdXO9siTfX4ditQI1T9+zVcNazT48EJCD0v40/9RIFoUgZ05CmGEq9H2gixRpjUn/iplwvlcvutJW/Q==} + '@typescript-eslint/type-utils@8.68.0': + resolution: {integrity: sha512-X77zqoY1EjeWGs/0JNxeaMfp5C5lIz4Tw8y66F1Ne8Faq6g424sBNYM6xBAqElfGZPLpWS+CZAp0DXyKDzWiHg==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 @@ -3669,21 +3673,25 @@ packages: resolution: {integrity: sha512-sBtgslww8nsMYUjhdPBiSyUqSzT8uR6g93A2QXnQC8+cGdjz0CyaOdqHDRJb1AtORbZCNUJBBeFA/tNR2uQmww==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@typescript-eslint/typescript-estree@8.67.0': - resolution: {integrity: sha512-EKQBCE9yNlRJYm7jdTW5AhDacDUmSwQb0FAJAmK2EKYrNXIsa2vxcSZx6PvJ/dEdI6lS+Y9W+EXckLj0iPFGcw==} + '@typescript-eslint/types@8.68.0': + resolution: {integrity: sha512-9RnpsGJjrAllCMefGVVsImJM24YurhC0Q1h4UbvivtvOqXmR/vEJge2OoE++z9m6hyg8T1Q8t5SNT6tHSbrxcg==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@typescript-eslint/typescript-estree@8.68.0': + resolution: {integrity: sha512-OKKsD0tYmoNiU5PW2zehO1yO56jYOm1ShYlxon/Z0SJNidAkdVg86eg9ruRuoXf8xfnuWZGbwDsStkoXbZtIIA==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: typescript: '>=4.8.4 <6.1.0' - '@typescript-eslint/utils@8.67.0': - resolution: {integrity: sha512-U9D1FdwEWBwok3hxxSdhclMb0twvt9QnjIQ0VfQ1AiX2epnpSgv2ubVDsayOFyY8K6FX+AQ7E0FKWVG3iKsj1A==} + '@typescript-eslint/utils@8.68.0': + resolution: {integrity: sha512-PB5gJMMOg0Q5P1tsgWtEAqQacJXq0qEqRHDX/YJ4FaTMLfZPpHB3gjl2EJuiZyPABxmj4ZQYiY9m1bdAJ5y7tQ==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 typescript: '>=4.8.4 <6.1.0' - '@typescript-eslint/visitor-keys@8.67.0': - resolution: {integrity: sha512-fkv8dHRDqfGtTHuJeebdrQ7cX6Ad4WAS00rgHh9UGvMycF1mjBfsxry1XsLIFhWZ6Judlh6UdzK+TYlbpCXgnA==} + '@typescript-eslint/visitor-keys@8.68.0': + resolution: {integrity: sha512-YR65gGdGvTUAWLldC3xLOvOzamdGzB4A5/N8rehEaHs3Zvoe39BhgY+u0SPch1OvrVTfLcc55wsSgK2NcnTS/A==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} '@verdaccio/auth@8.1.2': @@ -5103,8 +5111,8 @@ packages: resolution: {integrity: sha512-tD40eHxA35h0PEIZNeIjkHoDR4YjjJp34biM0mDvplBe//mB+IHCqHDGV7pxF+7MklTvighcCPPZC7ynWyjdTA==} engines: {node: ^20.19.0 || ^22.13.0 || >=24} - eslint@10.9.0: - resolution: {integrity: sha512-5KeEOJZBfEVA47boFiBsf+6MmmJpffM7qEBg4pLla2e4nlKgdKlqCW0oSLOGsT8Wl5uCGJptLV1bkaiShj90Gw==} + eslint@10.9.1: + resolution: {integrity: sha512-9VaAkDURekixUQJy0oJYl2DcN6oKMfxay7XzaGYAWQwsb6qfKf+x76R2k1L8kb1boc+FyCAaTA9GmiKaaiaF+A==} engines: {node: ^20.19.0 || ^22.13.0 || >=24} hasBin: true peerDependencies: @@ -6232,8 +6240,8 @@ packages: lines-and-columns@1.2.4: resolution: {integrity: sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==} - listr2@11.0.0: - resolution: {integrity: sha512-8K88S0aSrcSXdJfiZtEy5BQMnR+TyjrCGLcgAvQs6ta0NEnIm0RJ72/Pv67Jvg07cfBhDbuN74V81lSSVYEFEw==} + listr2@11.0.1: + resolution: {integrity: sha512-TzOB/8yb2KIW/hb7DCLfloZi0j01xhIqqvvHuXhPVEprbebjPtxWzBmUC4jZoQv6imUfxYk6tbAudCb/m//DPQ==} engines: {node: '>=22.13.0'} lmdb@3.5.6: @@ -6747,8 +6755,8 @@ packages: resolution: {integrity: sha512-19YVAg7T+WTrxggPukVq7DjTv6+PJ867TmhCvBsYwmbFCsZd344rq2Ld1p0wo8f8Qrrhgp82c6FJRqdXWtSEhg==} engines: {node: '>= 0.4'} - oxc-parser@0.146.0: - resolution: {integrity: sha512-hrt0Ou2mCL8dLuvfvKWFjRlWaJKt0Xs7CfacAgb9mha0gKW1lSisUzNRyALgItMPIfThxkl8jH2ONP6ZbQXpaA==} + oxc-parser@0.147.0: + resolution: {integrity: sha512-5xaug6t7GfV3BO5Iv+xHW1rmQkDEQ3BEu3L8g3InsvWO5i8CYGc4tCZ2X985QcwWNycFJam+aOns6Nr2XAThTA==} engines: {node: ^20.19.0 || >=22.12.0} p-finally@1.0.0: @@ -6862,8 +6870,8 @@ packages: resolution: {integrity: sha512-V7+vQEJ06Z+c5tSye8S+nHUfI51xoXIXjHQ99cQtKUkQqqO1kO/KCJUfZXuB47h/YBlDhah2H3hdUGXn8ie0oA==} engines: {node: '>=8.6'} - picomatch@4.0.5: - resolution: {integrity: sha512-RvwwcruNjI1ncT5xRakeyS9Lf8lcItv34KD+aif+VH9kduAyfYBipGh12274xtenIPZ119/R9BdTBa8gAwSh0A==} + picomatch@4.0.7: + resolution: {integrity: sha512-qcJu88Q2IWqJsDD529JKMdwGm/dvInW4HvQnRwiH9JtihJvzGOscDtHE3x1pBKeUOTysQ8kVmLnJ2kJu7yhcGA==} engines: {node: '>=12'} pify@3.0.0: @@ -7042,12 +7050,12 @@ packages: resolution: {integrity: sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==} engines: {node: '>=6'} - puppeteer-core@25.8.0: - resolution: {integrity: sha512-LDOrawV8vfCVk+yLj2ozvajNP4Sv3OV9y3Tpiyy2g2Z+aQlbcozP6KJfI4iSBq7YQER+86ihEtPa5ioiZyWxMQ==} + puppeteer-core@25.9.0: + resolution: {integrity: sha512-U61rCwSMha62CA/Opy6tCx2Fx+ck7ouiKnbpEApzSoLYMoEu9F71nuFpHL55vmIt33/GYm6eKZVhH2ev0nAIeg==} engines: {node: '>=22.12.0'} - puppeteer@25.8.0: - resolution: {integrity: sha512-3gcUJ+Jfodb5zNa/lWLZukBUwYiRIwAc8WRICoqfi+ZYmNWqpsPFyanTU3Gw/lhgII9aotVbAmhT6/NKHWgyUA==} + puppeteer@25.9.0: + resolution: {integrity: sha512-2JqQszD2pyDTpIvBH1ZCXdrHgENVNdJIeOM6asbwHRgWknFiaLd1gNB91w/B/0hQHNpafkpxa90lPpBaJM87Hw==} engines: {node: '>=22.12.0'} hasBin: true @@ -7279,8 +7287,8 @@ packages: '@types/node': optional: true - rollup@4.62.5: - resolution: {integrity: sha512-/tqMfgP7GPA3PHhCmuiS4vIjrSVhHLgY++i+dhbG462euyAj7FpM4D9uq1X3BgjlqRdpcOrYhcQtfiQLNc8tqw==} + rollup@4.63.0: + resolution: {integrity: sha512-T5vnZ2y4QqC3/4P+w2+JO+Q/OVdnPsv4XcSYJYMEn0R9/jjl5AgLwO9LAZMzP2lN71O6pypn91rB7lDstUkfrQ==} engines: {node: '>=18.0.0', npm: '>=8.0.0'} hasBin: true @@ -7806,6 +7814,9 @@ packages: tar-stream@3.2.0: resolution: {integrity: sha512-ojzvCvVaNp6aOTFmG7jaRD0meowIAuPc3cMMhSgKiVWws1GyHbGd/xvnyuRKcKlMpt3qvxx6r0hreCNITP9hIg==} + tar-stream@3.2.1: + resolution: {integrity: sha512-nqsEO8zLZJvrOMdEwkA0QdCLFbetHMn95Zqu4fKwX+hkaTWJPZZOrxx/PwtxoK0MMGQmBQNRW3CPs8IFYQz4cQ==} + teeny-request@10.1.4: resolution: {integrity: sha512-R1Cg4Vu0UULeDfHL/kjABLaTW++9yD/B6n2g48y5dJ04hsEaxcfmAqbNDzNsbqAYJyIpZafjklLG9YxRu9uzOg==} engines: {node: '>=18'} @@ -9514,18 +9525,18 @@ snapshots: '@esbuild/win32-x64@0.28.2': optional: true - '@eslint-community/eslint-utils@4.10.1(eslint@10.9.0(jiti@2.7.0)(supports-color@11.0.0))': + '@eslint-community/eslint-utils@4.10.1(eslint@10.9.1(jiti@2.7.0)(supports-color@11.0.0))': dependencies: - eslint: 10.9.0(jiti@2.7.0)(supports-color@11.0.0) + eslint: 10.9.1(jiti@2.7.0)(supports-color@11.0.0) eslint-visitor-keys: 3.4.3 '@eslint-community/regexpp@4.12.2': {} - '@eslint/compat@2.1.0(eslint@10.9.0(jiti@2.7.0)(supports-color@11.0.0))': + '@eslint/compat@2.1.0(eslint@10.9.1(jiti@2.7.0)(supports-color@11.0.0))': dependencies: '@eslint/core': 1.2.1 optionalDependencies: - eslint: 10.9.0(jiti@2.7.0)(supports-color@11.0.0) + eslint: 10.9.1(jiti@2.7.0)(supports-color@11.0.0) '@eslint/config-array@0.23.5(supports-color@11.0.0)': dependencies: @@ -9557,9 +9568,9 @@ snapshots: transitivePeerDependencies: - supports-color - '@eslint/js@10.0.1(eslint@10.9.0(jiti@2.7.0)(supports-color@11.0.0))': + '@eslint/js@10.0.1(eslint@10.9.1(jiti@2.7.0)(supports-color@11.0.0))': optionalDependencies: - eslint: 10.9.0(jiti@2.7.0)(supports-color@11.0.0) + eslint: 10.9.1(jiti@2.7.0)(supports-color@11.0.0) '@eslint/object-schema@3.0.5': {} @@ -10408,11 +10419,11 @@ snapshots: '@leichtgewicht/ip-codec@2.0.5': {} - '@listr2/prompt-adapter-inquirer@4.2.5(@inquirer/prompts@8.6.0(@types/node@22.20.1))(@types/node@22.20.1)(listr2@11.0.0)': + '@listr2/prompt-adapter-inquirer@4.2.6(@inquirer/prompts@8.6.0(@types/node@22.20.1))(@types/node@22.20.1)(listr2@11.0.1)': dependencies: '@inquirer/prompts': 8.6.0(@types/node@22.20.1) '@inquirer/type': 4.0.7(@types/node@22.20.1) - listr2: 11.0.0 + listr2: 11.0.1 transitivePeerDependencies: - '@types/node' @@ -10711,65 +10722,67 @@ snapshots: '@opentelemetry/semantic-conventions@1.43.0': {} - '@oxc-parser/binding-android-arm-eabi@0.146.0': + '@oxc-parser/binding-android-arm-eabi@0.147.0': optional: true - '@oxc-parser/binding-android-arm64@0.146.0': + '@oxc-parser/binding-android-arm64@0.147.0': optional: true - '@oxc-parser/binding-darwin-arm64@0.146.0': + '@oxc-parser/binding-darwin-arm64@0.147.0': optional: true - '@oxc-parser/binding-darwin-x64@0.146.0': + '@oxc-parser/binding-darwin-x64@0.147.0': optional: true - '@oxc-parser/binding-freebsd-x64@0.146.0': + '@oxc-parser/binding-freebsd-x64@0.147.0': optional: true - '@oxc-parser/binding-linux-arm-gnueabihf@0.146.0': + '@oxc-parser/binding-linux-arm-gnueabihf@0.147.0': optional: true - '@oxc-parser/binding-linux-arm-musleabihf@0.146.0': + '@oxc-parser/binding-linux-arm-musleabihf@0.147.0': optional: true - '@oxc-parser/binding-linux-arm64-gnu@0.146.0': + '@oxc-parser/binding-linux-arm64-gnu@0.147.0': optional: true - '@oxc-parser/binding-linux-arm64-musl@0.146.0': + '@oxc-parser/binding-linux-arm64-musl@0.147.0': optional: true - '@oxc-parser/binding-linux-ppc64-gnu@0.146.0': + '@oxc-parser/binding-linux-ppc64-gnu@0.147.0': optional: true - '@oxc-parser/binding-linux-riscv64-gnu@0.146.0': + '@oxc-parser/binding-linux-riscv64-gnu@0.147.0': optional: true - '@oxc-parser/binding-linux-riscv64-musl@0.146.0': + '@oxc-parser/binding-linux-riscv64-musl@0.147.0': optional: true - '@oxc-parser/binding-linux-s390x-gnu@0.146.0': + '@oxc-parser/binding-linux-s390x-gnu@0.147.0': optional: true - '@oxc-parser/binding-linux-x64-gnu@0.146.0': + '@oxc-parser/binding-linux-x64-gnu@0.147.0': optional: true - '@oxc-parser/binding-linux-x64-musl@0.146.0': + '@oxc-parser/binding-linux-x64-musl@0.147.0': optional: true - '@oxc-parser/binding-openharmony-arm64@0.146.0': + '@oxc-parser/binding-openharmony-arm64@0.147.0': optional: true - '@oxc-parser/binding-win32-arm64-msvc@0.146.0': + '@oxc-parser/binding-win32-arm64-msvc@0.147.0': optional: true - '@oxc-parser/binding-win32-ia32-msvc@0.146.0': + '@oxc-parser/binding-win32-ia32-msvc@0.147.0': optional: true - '@oxc-parser/binding-win32-x64-msvc@0.146.0': + '@oxc-parser/binding-win32-x64-msvc@0.147.0': optional: true '@oxc-project/types@0.146.0': {} + '@oxc-project/types@0.147.0': {} + '@parcel/watcher-android-arm64@2.6.0': optional: true @@ -10811,7 +10824,7 @@ snapshots: detect-libc: 2.1.2 is-glob: 4.0.3 node-addon-api: 7.1.1 - picomatch: 4.0.5 + picomatch: 4.0.7 optionalDependencies: '@parcel/watcher-android-arm64': 2.6.0 '@parcel/watcher-darwin-arm64': 2.6.0 @@ -11017,122 +11030,122 @@ snapshots: '@rolldown/pluginutils@1.0.1': {} - '@rollup/plugin-alias@6.0.0(rollup@4.62.5)': + '@rollup/plugin-alias@6.0.0(rollup@4.63.0)': optionalDependencies: - rollup: 4.62.5 + rollup: 4.63.0 - '@rollup/plugin-commonjs@29.0.3(rollup@4.62.5)': + '@rollup/plugin-commonjs@29.0.3(rollup@4.63.0)': dependencies: - '@rollup/pluginutils': 5.4.0(rollup@4.62.5) + '@rollup/pluginutils': 5.4.0(rollup@4.63.0) commondir: 1.0.1 estree-walker: 2.0.2 - fdir: 6.5.0(picomatch@4.0.5) + fdir: 6.5.0(picomatch@4.0.7) is-reference: 1.2.1 magic-string: 0.30.21 - picomatch: 4.0.5 + picomatch: 4.0.7 optionalDependencies: - rollup: 4.62.5 + rollup: 4.63.0 - '@rollup/plugin-json@6.1.0(rollup@4.62.5)': + '@rollup/plugin-json@6.1.0(rollup@4.63.0)': dependencies: - '@rollup/pluginutils': 5.4.0(rollup@4.62.5) + '@rollup/pluginutils': 5.4.0(rollup@4.63.0) optionalDependencies: - rollup: 4.62.5 + rollup: 4.63.0 - '@rollup/plugin-node-resolve@16.0.3(rollup@4.62.5)': + '@rollup/plugin-node-resolve@16.0.3(rollup@4.63.0)': dependencies: - '@rollup/pluginutils': 5.4.0(rollup@4.62.5) + '@rollup/pluginutils': 5.4.0(rollup@4.63.0) '@types/resolve': 1.20.2 deepmerge: 4.3.1 is-module: 1.0.0 resolve: 1.22.12 optionalDependencies: - rollup: 4.62.5 + rollup: 4.63.0 - '@rollup/pluginutils@5.4.0(rollup@4.62.5)': + '@rollup/pluginutils@5.4.0(rollup@4.63.0)': dependencies: '@types/estree': 1.0.9 estree-walker: 2.0.2 - picomatch: 4.0.5 + picomatch: 4.0.7 optionalDependencies: - rollup: 4.62.5 + rollup: 4.63.0 - '@rollup/rollup-android-arm-eabi@4.62.5': + '@rollup/rollup-android-arm-eabi@4.63.0': optional: true - '@rollup/rollup-android-arm64@4.62.5': + '@rollup/rollup-android-arm64@4.63.0': optional: true - '@rollup/rollup-darwin-arm64@4.62.5': + '@rollup/rollup-darwin-arm64@4.63.0': optional: true - '@rollup/rollup-darwin-x64@4.62.5': + '@rollup/rollup-darwin-x64@4.63.0': optional: true - '@rollup/rollup-freebsd-arm64@4.62.5': + '@rollup/rollup-freebsd-arm64@4.63.0': optional: true - '@rollup/rollup-freebsd-x64@4.62.5': + '@rollup/rollup-freebsd-x64@4.63.0': optional: true - '@rollup/rollup-linux-arm-gnueabihf@4.62.5': + '@rollup/rollup-linux-arm-gnueabihf@4.63.0': optional: true - '@rollup/rollup-linux-arm-musleabihf@4.62.5': + '@rollup/rollup-linux-arm-musleabihf@4.63.0': optional: true - '@rollup/rollup-linux-arm64-gnu@4.62.5': + '@rollup/rollup-linux-arm64-gnu@4.63.0': optional: true - '@rollup/rollup-linux-arm64-musl@4.62.5': + '@rollup/rollup-linux-arm64-musl@4.63.0': optional: true - '@rollup/rollup-linux-loong64-gnu@4.62.5': + '@rollup/rollup-linux-loong64-gnu@4.63.0': optional: true - '@rollup/rollup-linux-loong64-musl@4.62.5': + '@rollup/rollup-linux-loong64-musl@4.63.0': optional: true - '@rollup/rollup-linux-ppc64-gnu@4.62.5': + '@rollup/rollup-linux-ppc64-gnu@4.63.0': optional: true - '@rollup/rollup-linux-ppc64-musl@4.62.5': + '@rollup/rollup-linux-ppc64-musl@4.63.0': optional: true - '@rollup/rollup-linux-riscv64-gnu@4.62.5': + '@rollup/rollup-linux-riscv64-gnu@4.63.0': optional: true - '@rollup/rollup-linux-riscv64-musl@4.62.5': + '@rollup/rollup-linux-riscv64-musl@4.63.0': optional: true - '@rollup/rollup-linux-s390x-gnu@4.62.5': + '@rollup/rollup-linux-s390x-gnu@4.63.0': optional: true - '@rollup/rollup-linux-x64-gnu@4.62.5': + '@rollup/rollup-linux-x64-gnu@4.63.0': optional: true - '@rollup/rollup-linux-x64-musl@4.62.5': + '@rollup/rollup-linux-x64-musl@4.63.0': optional: true - '@rollup/rollup-openbsd-x64@4.62.5': + '@rollup/rollup-openbsd-x64@4.63.0': optional: true - '@rollup/rollup-openharmony-arm64@4.62.5': + '@rollup/rollup-openharmony-arm64@4.63.0': optional: true - '@rollup/rollup-win32-arm64-msvc@4.62.5': + '@rollup/rollup-win32-arm64-msvc@4.63.0': optional: true - '@rollup/rollup-win32-ia32-msvc@4.62.5': + '@rollup/rollup-win32-ia32-msvc@4.63.0': optional: true - '@rollup/rollup-win32-x64-gnu@4.62.5': + '@rollup/rollup-win32-x64-gnu@4.63.0': optional: true - '@rollup/rollup-win32-x64-msvc@4.62.5': + '@rollup/rollup-win32-x64-msvc@4.63.0': optional: true - '@rollup/wasm-node@4.62.5': + '@rollup/wasm-node@4.63.0': dependencies: '@types/estree': 1.0.9 optionalDependencies: @@ -11155,19 +11168,19 @@ snapshots: '@standard-schema/spec@1.1.0': {} - '@stylistic/eslint-plugin@5.10.0(eslint@10.9.0(jiti@2.7.0)(supports-color@11.0.0))': + '@stylistic/eslint-plugin@5.10.0(eslint@10.9.1(jiti@2.7.0)(supports-color@11.0.0))': dependencies: - '@eslint-community/eslint-utils': 4.10.1(eslint@10.9.0(jiti@2.7.0)(supports-color@11.0.0)) + '@eslint-community/eslint-utils': 4.10.1(eslint@10.9.1(jiti@2.7.0)(supports-color@11.0.0)) '@typescript-eslint/types': 8.67.0 - eslint: 10.9.0(jiti@2.7.0)(supports-color@11.0.0) + eslint: 10.9.1(jiti@2.7.0)(supports-color@11.0.0) eslint-visitor-keys: 4.2.1 espree: 10.4.0 estraverse: 5.3.0 - picomatch: 4.0.5 + picomatch: 4.0.7 - '@tony.ganchev/eslint-plugin-header@3.4.4(eslint@10.9.0(jiti@2.7.0)(supports-color@11.0.0))': + '@tony.ganchev/eslint-plugin-header@3.4.4(eslint@10.9.1(jiti@2.7.0)(supports-color@11.0.0))': dependencies: - eslint: 10.9.0(jiti@2.7.0)(supports-color@11.0.0) + eslint: 10.9.1(jiti@2.7.0)(supports-color@11.0.0) '@types/babel__core@7.20.5': dependencies: @@ -11388,15 +11401,15 @@ snapshots: '@types/yarnpkg__lockfile@1.1.9': {} - '@typescript-eslint/eslint-plugin@8.67.0(@typescript-eslint/parser@8.67.0(eslint@10.9.0(jiti@2.7.0)(supports-color@11.0.0))(supports-color@11.0.0)(typescript@6.0.3))(eslint@10.9.0(jiti@2.7.0)(supports-color@11.0.0))(supports-color@11.0.0)(typescript@6.0.3)': + '@typescript-eslint/eslint-plugin@8.68.0(@typescript-eslint/parser@8.68.0(eslint@10.9.1(jiti@2.7.0)(supports-color@11.0.0))(supports-color@11.0.0)(typescript@6.0.3))(eslint@10.9.1(jiti@2.7.0)(supports-color@11.0.0))(supports-color@11.0.0)(typescript@6.0.3)': dependencies: '@eslint-community/regexpp': 4.12.2 - '@typescript-eslint/parser': 8.67.0(eslint@10.9.0(jiti@2.7.0)(supports-color@11.0.0))(supports-color@11.0.0)(typescript@6.0.3) - '@typescript-eslint/scope-manager': 8.67.0 - '@typescript-eslint/type-utils': 8.67.0(eslint@10.9.0(jiti@2.7.0)(supports-color@11.0.0))(supports-color@11.0.0)(typescript@6.0.3) - '@typescript-eslint/utils': 8.67.0(eslint@10.9.0(jiti@2.7.0)(supports-color@11.0.0))(supports-color@11.0.0)(typescript@6.0.3) - '@typescript-eslint/visitor-keys': 8.67.0 - eslint: 10.9.0(jiti@2.7.0)(supports-color@11.0.0) + '@typescript-eslint/parser': 8.68.0(eslint@10.9.1(jiti@2.7.0)(supports-color@11.0.0))(supports-color@11.0.0)(typescript@6.0.3) + '@typescript-eslint/scope-manager': 8.68.0 + '@typescript-eslint/type-utils': 8.68.0(eslint@10.9.1(jiti@2.7.0)(supports-color@11.0.0))(supports-color@11.0.0)(typescript@6.0.3) + '@typescript-eslint/utils': 8.68.0(eslint@10.9.1(jiti@2.7.0)(supports-color@11.0.0))(supports-color@11.0.0)(typescript@6.0.3) + '@typescript-eslint/visitor-keys': 8.68.0 + eslint: 10.9.1(jiti@2.7.0)(supports-color@11.0.0) ignore: 7.0.6 natural-compare: 1.4.0 ts-api-utils: 2.5.0(typescript@6.0.3) @@ -11404,43 +11417,43 @@ snapshots: transitivePeerDependencies: - supports-color - '@typescript-eslint/parser@8.67.0(eslint@10.9.0(jiti@2.7.0)(supports-color@11.0.0))(supports-color@11.0.0)(typescript@6.0.3)': + '@typescript-eslint/parser@8.68.0(eslint@10.9.1(jiti@2.7.0)(supports-color@11.0.0))(supports-color@11.0.0)(typescript@6.0.3)': dependencies: - '@typescript-eslint/scope-manager': 8.67.0 - '@typescript-eslint/types': 8.67.0 - '@typescript-eslint/typescript-estree': 8.67.0(supports-color@11.0.0)(typescript@6.0.3) - '@typescript-eslint/visitor-keys': 8.67.0 + '@typescript-eslint/scope-manager': 8.68.0 + '@typescript-eslint/types': 8.68.0 + '@typescript-eslint/typescript-estree': 8.68.0(supports-color@11.0.0)(typescript@6.0.3) + '@typescript-eslint/visitor-keys': 8.68.0 debug: 4.4.3(supports-color@11.0.0) - eslint: 10.9.0(jiti@2.7.0)(supports-color@11.0.0) + eslint: 10.9.1(jiti@2.7.0)(supports-color@11.0.0) typescript: 6.0.3 transitivePeerDependencies: - supports-color - '@typescript-eslint/project-service@8.67.0(supports-color@11.0.0)(typescript@6.0.3)': + '@typescript-eslint/project-service@8.68.0(supports-color@11.0.0)(typescript@6.0.3)': dependencies: - '@typescript-eslint/tsconfig-utils': 8.67.0(typescript@6.0.3) - '@typescript-eslint/types': 8.67.0 + '@typescript-eslint/tsconfig-utils': 8.68.0(typescript@6.0.3) + '@typescript-eslint/types': 8.68.0 debug: 4.4.3(supports-color@11.0.0) typescript: 6.0.3 transitivePeerDependencies: - supports-color - '@typescript-eslint/scope-manager@8.67.0': + '@typescript-eslint/scope-manager@8.68.0': dependencies: - '@typescript-eslint/types': 8.67.0 - '@typescript-eslint/visitor-keys': 8.67.0 + '@typescript-eslint/types': 8.68.0 + '@typescript-eslint/visitor-keys': 8.68.0 - '@typescript-eslint/tsconfig-utils@8.67.0(typescript@6.0.3)': + '@typescript-eslint/tsconfig-utils@8.68.0(typescript@6.0.3)': dependencies: typescript: 6.0.3 - '@typescript-eslint/type-utils@8.67.0(eslint@10.9.0(jiti@2.7.0)(supports-color@11.0.0))(supports-color@11.0.0)(typescript@6.0.3)': + '@typescript-eslint/type-utils@8.68.0(eslint@10.9.1(jiti@2.7.0)(supports-color@11.0.0))(supports-color@11.0.0)(typescript@6.0.3)': dependencies: - '@typescript-eslint/types': 8.67.0 - '@typescript-eslint/typescript-estree': 8.67.0(supports-color@11.0.0)(typescript@6.0.3) - '@typescript-eslint/utils': 8.67.0(eslint@10.9.0(jiti@2.7.0)(supports-color@11.0.0))(supports-color@11.0.0)(typescript@6.0.3) + '@typescript-eslint/types': 8.68.0 + '@typescript-eslint/typescript-estree': 8.68.0(supports-color@11.0.0)(typescript@6.0.3) + '@typescript-eslint/utils': 8.68.0(eslint@10.9.1(jiti@2.7.0)(supports-color@11.0.0))(supports-color@11.0.0)(typescript@6.0.3) debug: 4.4.3(supports-color@11.0.0) - eslint: 10.9.0(jiti@2.7.0)(supports-color@11.0.0) + eslint: 10.9.1(jiti@2.7.0)(supports-color@11.0.0) ts-api-utils: 2.5.0(typescript@6.0.3) typescript: 6.0.3 transitivePeerDependencies: @@ -11448,12 +11461,14 @@ snapshots: '@typescript-eslint/types@8.67.0': {} - '@typescript-eslint/typescript-estree@8.67.0(supports-color@11.0.0)(typescript@6.0.3)': + '@typescript-eslint/types@8.68.0': {} + + '@typescript-eslint/typescript-estree@8.68.0(supports-color@11.0.0)(typescript@6.0.3)': dependencies: - '@typescript-eslint/project-service': 8.67.0(supports-color@11.0.0)(typescript@6.0.3) - '@typescript-eslint/tsconfig-utils': 8.67.0(typescript@6.0.3) - '@typescript-eslint/types': 8.67.0 - '@typescript-eslint/visitor-keys': 8.67.0 + '@typescript-eslint/project-service': 8.68.0(supports-color@11.0.0)(typescript@6.0.3) + '@typescript-eslint/tsconfig-utils': 8.68.0(typescript@6.0.3) + '@typescript-eslint/types': 8.68.0 + '@typescript-eslint/visitor-keys': 8.68.0 debug: 4.4.3(supports-color@11.0.0) minimatch: 10.2.6 semver: 7.8.5 @@ -11463,20 +11478,20 @@ snapshots: transitivePeerDependencies: - supports-color - '@typescript-eslint/utils@8.67.0(eslint@10.9.0(jiti@2.7.0)(supports-color@11.0.0))(supports-color@11.0.0)(typescript@6.0.3)': + '@typescript-eslint/utils@8.68.0(eslint@10.9.1(jiti@2.7.0)(supports-color@11.0.0))(supports-color@11.0.0)(typescript@6.0.3)': dependencies: - '@eslint-community/eslint-utils': 4.10.1(eslint@10.9.0(jiti@2.7.0)(supports-color@11.0.0)) - '@typescript-eslint/scope-manager': 8.67.0 - '@typescript-eslint/types': 8.67.0 - '@typescript-eslint/typescript-estree': 8.67.0(supports-color@11.0.0)(typescript@6.0.3) - eslint: 10.9.0(jiti@2.7.0)(supports-color@11.0.0) + '@eslint-community/eslint-utils': 4.10.1(eslint@10.9.1(jiti@2.7.0)(supports-color@11.0.0)) + '@typescript-eslint/scope-manager': 8.68.0 + '@typescript-eslint/types': 8.68.0 + '@typescript-eslint/typescript-estree': 8.68.0(supports-color@11.0.0)(typescript@6.0.3) + eslint: 10.9.1(jiti@2.7.0)(supports-color@11.0.0) typescript: 6.0.3 transitivePeerDependencies: - supports-color - '@typescript-eslint/visitor-keys@8.67.0': + '@typescript-eslint/visitor-keys@8.68.0': dependencies: - '@typescript-eslint/types': 8.67.0 + '@typescript-eslint/types': 8.68.0 eslint-visitor-keys: 5.0.1 '@verdaccio/auth@8.1.2(supports-color@11.0.0)': @@ -13010,9 +13025,9 @@ snapshots: escape-string-regexp@4.0.0: {} - eslint-config-prettier@10.1.8(eslint@10.9.0(jiti@2.7.0)(supports-color@11.0.0)): + eslint-config-prettier@10.1.8(eslint@10.9.1(jiti@2.7.0)(supports-color@11.0.0)): dependencies: - eslint: 10.9.0(jiti@2.7.0)(supports-color@11.0.0) + eslint: 10.9.1(jiti@2.7.0)(supports-color@11.0.0) eslint-import-resolver-node@0.3.10(supports-color@11.0.0): dependencies: @@ -13022,17 +13037,17 @@ snapshots: transitivePeerDependencies: - supports-color - eslint-module-utils@2.14.0(@typescript-eslint/parser@8.67.0(eslint@10.9.0(jiti@2.7.0)(supports-color@11.0.0))(supports-color@11.0.0)(typescript@6.0.3))(eslint-import-resolver-node@0.3.10(supports-color@11.0.0))(eslint@10.9.0(jiti@2.7.0)(supports-color@11.0.0))(supports-color@11.0.0): + eslint-module-utils@2.14.0(@typescript-eslint/parser@8.68.0(eslint@10.9.1(jiti@2.7.0)(supports-color@11.0.0))(supports-color@11.0.0)(typescript@6.0.3))(eslint-import-resolver-node@0.3.10(supports-color@11.0.0))(eslint@10.9.1(jiti@2.7.0)(supports-color@11.0.0))(supports-color@11.0.0): dependencies: debug: 3.2.7(supports-color@11.0.0) optionalDependencies: - '@typescript-eslint/parser': 8.67.0(eslint@10.9.0(jiti@2.7.0)(supports-color@11.0.0))(supports-color@11.0.0)(typescript@6.0.3) - eslint: 10.9.0(jiti@2.7.0)(supports-color@11.0.0) + '@typescript-eslint/parser': 8.68.0(eslint@10.9.1(jiti@2.7.0)(supports-color@11.0.0))(supports-color@11.0.0)(typescript@6.0.3) + eslint: 10.9.1(jiti@2.7.0)(supports-color@11.0.0) eslint-import-resolver-node: 0.3.10(supports-color@11.0.0) transitivePeerDependencies: - supports-color - eslint-plugin-import@2.32.0(@typescript-eslint/parser@8.67.0(eslint@10.9.0(jiti@2.7.0)(supports-color@11.0.0))(supports-color@11.0.0)(typescript@6.0.3))(eslint@10.9.0(jiti@2.7.0)(supports-color@11.0.0))(supports-color@11.0.0): + eslint-plugin-import@2.32.0(@typescript-eslint/parser@8.68.0(eslint@10.9.1(jiti@2.7.0)(supports-color@11.0.0))(supports-color@11.0.0)(typescript@6.0.3))(eslint@10.9.1(jiti@2.7.0)(supports-color@11.0.0))(supports-color@11.0.0): dependencies: '@rtsao/scc': 1.1.0 array-includes: 3.1.9 @@ -13041,9 +13056,9 @@ snapshots: array.prototype.flatmap: 1.3.3 debug: 3.2.7(supports-color@11.0.0) doctrine: 2.1.0 - eslint: 10.9.0(jiti@2.7.0)(supports-color@11.0.0) + eslint: 10.9.1(jiti@2.7.0)(supports-color@11.0.0) eslint-import-resolver-node: 0.3.10(supports-color@11.0.0) - eslint-module-utils: 2.14.0(@typescript-eslint/parser@8.67.0(eslint@10.9.0(jiti@2.7.0)(supports-color@11.0.0))(supports-color@11.0.0)(typescript@6.0.3))(eslint-import-resolver-node@0.3.10(supports-color@11.0.0))(eslint@10.9.0(jiti@2.7.0)(supports-color@11.0.0))(supports-color@11.0.0) + eslint-module-utils: 2.14.0(@typescript-eslint/parser@8.68.0(eslint@10.9.1(jiti@2.7.0)(supports-color@11.0.0))(supports-color@11.0.0)(typescript@6.0.3))(eslint-import-resolver-node@0.3.10(supports-color@11.0.0))(eslint@10.9.1(jiti@2.7.0)(supports-color@11.0.0))(supports-color@11.0.0) hasown: 2.0.4 is-core-module: 2.16.2 is-glob: 4.0.3 @@ -13055,7 +13070,7 @@ snapshots: string.prototype.trimend: 1.0.10 tsconfig-paths: 3.15.0 optionalDependencies: - '@typescript-eslint/parser': 8.67.0(eslint@10.9.0(jiti@2.7.0)(supports-color@11.0.0))(supports-color@11.0.0)(typescript@6.0.3) + '@typescript-eslint/parser': 8.68.0(eslint@10.9.1(jiti@2.7.0)(supports-color@11.0.0))(supports-color@11.0.0)(typescript@6.0.3) transitivePeerDependencies: - eslint-import-resolver-typescript - eslint-import-resolver-webpack @@ -13079,9 +13094,9 @@ snapshots: eslint-visitor-keys@5.0.1: {} - eslint@10.9.0(jiti@2.7.0)(supports-color@11.0.0): + eslint@10.9.1(jiti@2.7.0)(supports-color@11.0.0): dependencies: - '@eslint-community/eslint-utils': 4.10.1(eslint@10.9.0(jiti@2.7.0)(supports-color@11.0.0)) + '@eslint-community/eslint-utils': 4.10.1(eslint@10.9.1(jiti@2.7.0)(supports-color@11.0.0)) '@eslint-community/regexpp': 4.12.2 '@eslint/config-array': 0.23.5(supports-color@11.0.0) '@eslint/config-helpers': 0.7.0 @@ -13277,9 +13292,9 @@ snapshots: dependencies: websocket-driver: 0.7.5 - fdir@6.5.0(picomatch@4.0.5): + fdir@6.5.0(picomatch@4.0.7): optionalDependencies: - picomatch: 4.0.5 + picomatch: 4.0.7 fetch-blob@3.2.0: dependencies: @@ -14439,7 +14454,7 @@ snapshots: lines-and-columns@1.2.4: {} - listr2@11.0.0: + listr2@11.0.1: dependencies: cli-truncate: 6.1.1 log-update: 8.0.0 @@ -14963,29 +14978,29 @@ snapshots: object-keys: 1.1.1 safe-push-apply: 1.0.0 - oxc-parser@0.146.0: + oxc-parser@0.147.0: dependencies: - '@oxc-project/types': 0.146.0 + '@oxc-project/types': 0.147.0 optionalDependencies: - '@oxc-parser/binding-android-arm-eabi': 0.146.0 - '@oxc-parser/binding-android-arm64': 0.146.0 - '@oxc-parser/binding-darwin-arm64': 0.146.0 - '@oxc-parser/binding-darwin-x64': 0.146.0 - '@oxc-parser/binding-freebsd-x64': 0.146.0 - '@oxc-parser/binding-linux-arm-gnueabihf': 0.146.0 - '@oxc-parser/binding-linux-arm-musleabihf': 0.146.0 - '@oxc-parser/binding-linux-arm64-gnu': 0.146.0 - '@oxc-parser/binding-linux-arm64-musl': 0.146.0 - '@oxc-parser/binding-linux-ppc64-gnu': 0.146.0 - '@oxc-parser/binding-linux-riscv64-gnu': 0.146.0 - '@oxc-parser/binding-linux-riscv64-musl': 0.146.0 - '@oxc-parser/binding-linux-s390x-gnu': 0.146.0 - '@oxc-parser/binding-linux-x64-gnu': 0.146.0 - '@oxc-parser/binding-linux-x64-musl': 0.146.0 - '@oxc-parser/binding-openharmony-arm64': 0.146.0 - '@oxc-parser/binding-win32-arm64-msvc': 0.146.0 - '@oxc-parser/binding-win32-ia32-msvc': 0.146.0 - '@oxc-parser/binding-win32-x64-msvc': 0.146.0 + '@oxc-parser/binding-android-arm-eabi': 0.147.0 + '@oxc-parser/binding-android-arm64': 0.147.0 + '@oxc-parser/binding-darwin-arm64': 0.147.0 + '@oxc-parser/binding-darwin-x64': 0.147.0 + '@oxc-parser/binding-freebsd-x64': 0.147.0 + '@oxc-parser/binding-linux-arm-gnueabihf': 0.147.0 + '@oxc-parser/binding-linux-arm-musleabihf': 0.147.0 + '@oxc-parser/binding-linux-arm64-gnu': 0.147.0 + '@oxc-parser/binding-linux-arm64-musl': 0.147.0 + '@oxc-parser/binding-linux-ppc64-gnu': 0.147.0 + '@oxc-parser/binding-linux-riscv64-gnu': 0.147.0 + '@oxc-parser/binding-linux-riscv64-musl': 0.147.0 + '@oxc-parser/binding-linux-s390x-gnu': 0.147.0 + '@oxc-parser/binding-linux-x64-gnu': 0.147.0 + '@oxc-parser/binding-linux-x64-musl': 0.147.0 + '@oxc-parser/binding-openharmony-arm64': 0.147.0 + '@oxc-parser/binding-win32-arm64-msvc': 0.147.0 + '@oxc-parser/binding-win32-ia32-msvc': 0.147.0 + '@oxc-parser/binding-win32-x64-msvc': 0.147.0 p-finally@1.0.0: {} @@ -15088,7 +15103,7 @@ snapshots: picomatch@2.3.2: {} - picomatch@4.0.5: {} + picomatch@4.0.7: {} pify@3.0.0: {} @@ -15266,7 +15281,7 @@ snapshots: punycode@2.3.1: {} - puppeteer-core@25.8.0(bufferutil@4.1.0)(utf-8-validate@6.0.6): + puppeteer-core@25.9.0(bufferutil@4.1.0)(utf-8-validate@6.0.6): dependencies: '@puppeteer/browsers': 3.2.1 chromium-bidi: 17.0.2(devtools-protocol@0.0.1666840) @@ -15280,13 +15295,13 @@ snapshots: - utf-8-validate - yauzl - puppeteer@25.8.0(bufferutil@4.1.0)(utf-8-validate@6.0.6): + puppeteer@25.9.0(bufferutil@4.1.0)(utf-8-validate@6.0.6): dependencies: '@puppeteer/browsers': 3.2.1 chromium-bidi: 17.0.2(devtools-protocol@0.0.1666840) devtools-protocol: 0.0.1666840 lilconfig: 3.1.3 - puppeteer-core: 25.8.0(bufferutil@4.1.0)(utf-8-validate@6.0.6) + puppeteer-core: 25.9.0(bufferutil@4.1.0)(utf-8-validate@6.0.6) typed-query-selector: 2.12.2 transitivePeerDependencies: - bufferutil @@ -15549,54 +15564,54 @@ snapshots: semver: 7.8.5 spdx-expression-validate: 2.0.0 - rollup-plugin-dts@6.5.1(rollup@4.62.5)(typescript@6.0.3): + rollup-plugin-dts@6.5.1(rollup@4.63.0)(typescript@6.0.3): dependencies: '@jridgewell/remapping': 2.3.5 '@jridgewell/sourcemap-codec': 1.5.5 convert-source-map: 2.0.0 magic-string: 0.30.21 - rollup: 4.62.5 + rollup: 4.63.0 typescript: 6.0.3 optionalDependencies: '@babel/code-frame': 8.0.0 - rollup-plugin-sourcemaps2@0.5.8(@types/node@22.20.1)(rollup@4.62.5): + rollup-plugin-sourcemaps2@0.5.8(@types/node@22.20.1)(rollup@4.63.0): dependencies: - '@rollup/pluginutils': 5.4.0(rollup@4.62.5) - rollup: 4.62.5 + '@rollup/pluginutils': 5.4.0(rollup@4.63.0) + rollup: 4.63.0 optionalDependencies: '@types/node': 22.20.1 - rollup@4.62.5: + rollup@4.63.0: dependencies: '@types/estree': 1.0.9 optionalDependencies: '@napi-rs/lzma-linux-x64-gnu': 1.5.1 - '@rollup/rollup-android-arm-eabi': 4.62.5 - '@rollup/rollup-android-arm64': 4.62.5 - '@rollup/rollup-darwin-arm64': 4.62.5 - '@rollup/rollup-darwin-x64': 4.62.5 - '@rollup/rollup-freebsd-arm64': 4.62.5 - '@rollup/rollup-freebsd-x64': 4.62.5 - '@rollup/rollup-linux-arm-gnueabihf': 4.62.5 - '@rollup/rollup-linux-arm-musleabihf': 4.62.5 - '@rollup/rollup-linux-arm64-gnu': 4.62.5 - '@rollup/rollup-linux-arm64-musl': 4.62.5 - '@rollup/rollup-linux-loong64-gnu': 4.62.5 - '@rollup/rollup-linux-loong64-musl': 4.62.5 - '@rollup/rollup-linux-ppc64-gnu': 4.62.5 - '@rollup/rollup-linux-ppc64-musl': 4.62.5 - '@rollup/rollup-linux-riscv64-gnu': 4.62.5 - '@rollup/rollup-linux-riscv64-musl': 4.62.5 - '@rollup/rollup-linux-s390x-gnu': 4.62.5 - '@rollup/rollup-linux-x64-gnu': 4.62.5 - '@rollup/rollup-linux-x64-musl': 4.62.5 - '@rollup/rollup-openbsd-x64': 4.62.5 - '@rollup/rollup-openharmony-arm64': 4.62.5 - '@rollup/rollup-win32-arm64-msvc': 4.62.5 - '@rollup/rollup-win32-ia32-msvc': 4.62.5 - '@rollup/rollup-win32-x64-gnu': 4.62.5 - '@rollup/rollup-win32-x64-msvc': 4.62.5 + '@rollup/rollup-android-arm-eabi': 4.63.0 + '@rollup/rollup-android-arm64': 4.63.0 + '@rollup/rollup-darwin-arm64': 4.63.0 + '@rollup/rollup-darwin-x64': 4.63.0 + '@rollup/rollup-freebsd-arm64': 4.63.0 + '@rollup/rollup-freebsd-x64': 4.63.0 + '@rollup/rollup-linux-arm-gnueabihf': 4.63.0 + '@rollup/rollup-linux-arm-musleabihf': 4.63.0 + '@rollup/rollup-linux-arm64-gnu': 4.63.0 + '@rollup/rollup-linux-arm64-musl': 4.63.0 + '@rollup/rollup-linux-loong64-gnu': 4.63.0 + '@rollup/rollup-linux-loong64-musl': 4.63.0 + '@rollup/rollup-linux-ppc64-gnu': 4.63.0 + '@rollup/rollup-linux-ppc64-musl': 4.63.0 + '@rollup/rollup-linux-riscv64-gnu': 4.63.0 + '@rollup/rollup-linux-riscv64-musl': 4.63.0 + '@rollup/rollup-linux-s390x-gnu': 4.63.0 + '@rollup/rollup-linux-x64-gnu': 4.63.0 + '@rollup/rollup-linux-x64-musl': 4.63.0 + '@rollup/rollup-openbsd-x64': 4.63.0 + '@rollup/rollup-openharmony-arm64': 4.63.0 + '@rollup/rollup-win32-arm64-msvc': 4.63.0 + '@rollup/rollup-win32-ia32-msvc': 4.63.0 + '@rollup/rollup-win32-x64-gnu': 4.63.0 + '@rollup/rollup-win32-x64-msvc': 4.63.0 fsevents: 2.3.3 router@2.2.0(supports-color@11.0.0): @@ -16191,6 +16206,17 @@ snapshots: - bare-buffer - react-native-b4a + tar-stream@3.2.1: + dependencies: + b4a: 1.8.1 + bare-fs: 4.8.0 + fast-fifo: 1.3.2 + streamx: 2.28.0 + transitivePeerDependencies: + - bare-abort-controller + - bare-buffer + - react-native-b4a + teeny-request@10.1.4(supports-color@11.0.0): dependencies: http-proxy-agent: 7.0.2(supports-color@11.0.0) @@ -16249,8 +16275,8 @@ snapshots: tinyglobby@0.2.17: dependencies: - fdir: 6.5.0(picomatch@4.0.5) - picomatch: 4.0.5 + fdir: 6.5.0(picomatch@4.0.7) + picomatch: 4.0.7 tinyrainbow@3.1.1: {} @@ -16565,7 +16591,7 @@ snapshots: vite@8.2.2(@types/node@22.20.1)(esbuild@0.28.2)(jiti@2.7.0)(less@4.9.0(supports-color@11.0.0))(sass-embedded@1.103.1)(sass@1.103.1)(terser@5.50.0)(tsx@4.23.12)(yaml@2.9.0): dependencies: lightningcss: 1.33.0 - picomatch: 4.0.5 + picomatch: 4.0.7 postcss: 8.5.26 rolldown: 1.2.5 tinyglobby: 0.2.17 @@ -16595,7 +16621,7 @@ snapshots: magic-string: 0.30.21 obug: 2.1.4 pathe: 2.0.3 - picomatch: 4.0.5 + picomatch: 4.0.7 std-env: 4.2.0 tinybench: 2.9.0 tinyexec: 1.3.0 diff --git a/tests/e2e/utils/tar.ts b/tests/e2e/utils/tar.ts index d78f47762337..016e88f25024 100644 --- a/tests/e2e/utils/tar.ts +++ b/tests/e2e/utils/tar.ts @@ -33,7 +33,7 @@ export function extractFile(tarball: string, filePath: string): Promise } const chunks: Buffer[] = []; - stream.on('data', (chunk) => chunks.push(chunk)); + stream.on('data', (chunk) => chunks.push(chunk as Buffer)); stream.on('error', reject); stream.on('end', () => { resolve(Buffer.concat(chunks)); @@ -43,6 +43,13 @@ export function extractFile(tarball: string, filePath: string): Promise extractor.on('finish', () => reject(new Error(`'${filePath}' not found in '${tarball}'.`))); - createReadStream(tarball).pipe(createGunzip()).pipe(extractor).on('error', reject); + const readStream = createReadStream(tarball); + const gunzip = createGunzip(); + + readStream.on('error', reject); + gunzip.on('error', reject); + extractor.on('error', reject); + + readStream.pipe(gunzip).pipe(extractor as unknown as NodeJS.WritableStream); }); } diff --git a/tests/package.json b/tests/package.json index 7ab64c3d5212..4c46f7f75f44 100644 --- a/tests/package.json +++ b/tests/package.json @@ -2,6 +2,6 @@ "devDependencies": { "@types/tar-stream": "3.1.4", "@angular-devkit/schematics": "workspace:*", - "tar-stream": "3.2.0" + "tar-stream": "3.2.1" } } From 7634b27e3c377aa007423f89d085a17514b0a6b4 Mon Sep 17 00:00:00 2001 From: Charles Lyding <19598772+clydin@users.noreply.github.com> Date: Wed, 26 Aug 2026 10:35:53 -0400 Subject: [PATCH 359/787] refactor(@angular/build): optimize unmodified file and locale handling in i18n inliner When AST analysis determines that a file has zero $localize call sites and zero locale insert sites, the worker returns a lightweight unmodified batch result immediately, skipping per-locale loops, translation dictionary queries, and sourcemap parsing. For files where transformations occur but a specific locale produces no text modifications, code and sourcemap strings are omitted from the worker result, avoiding redundant serialization over worker IPC. The main thread falls back directly to the existing BuildOutputFile contents and cloned sourcemaps. --- .../src/tools/esbuild/i18n-inliner-worker.ts | 41 +++++++-- .../build/src/tools/esbuild/i18n-inliner.ts | 87 +++++++++++++------ .../src/tools/esbuild/i18n-inliner_spec.ts | 79 +++++++++++++++++ 3 files changed, 173 insertions(+), 34 deletions(-) diff --git a/packages/angular/build/src/tools/esbuild/i18n-inliner-worker.ts b/packages/angular/build/src/tools/esbuild/i18n-inliner-worker.ts index d6a56ad10d74..e7b11cc53225 100644 --- a/packages/angular/build/src/tools/esbuild/i18n-inliner-worker.ts +++ b/packages/angular/build/src/tools/esbuild/i18n-inliner-worker.ts @@ -77,7 +77,7 @@ interface InlineFileBatchRequest { */ interface InlineLocaleResult { locale: string; - code: string; + code?: string; map?: string; messages: { type: 'error' | 'warning'; message: string }[]; } @@ -85,10 +85,17 @@ interface InlineLocaleResult { /** * The response returned from a batch file request. */ -interface InlineFileBatchResult { - file: string; - results: InlineLocaleResult[]; -} +type InlineFileBatchResult = + | { + file: string; + unmodified: true; + messages: { type: 'error' | 'warning'; message: string }[]; + } + | { + file: string; + unmodified?: false; + results: InlineLocaleResult[]; + }; // Extract the application files and common options used for inline requests from the Worker context const { files, missingTranslation } = (workerData || {}) as { @@ -204,6 +211,18 @@ export async function inlineFileBatch( const { code, metadata } = await loadFileData(request.filename, !request.ephemeral); + // Fast path: file has no $localize call sites or locale insert sites + if (metadata.callSites.length === 0 && metadata.localeInsertSites.length === 0) { + return { + file: request.filename, + unmodified: true, + messages: (metadata.diagnostics ?? []).map((message) => ({ + type: 'error' as const, + message, + })), + }; + } + // Parse the sourcemap once for the entire batch. // It will naturally be garbage-collected after this batch action returns. const rawMap = await files.get(request.filename + '.map')?.text(); @@ -254,7 +273,7 @@ export async function inlineCode(request: InlineCodeRequest) { ); return { - output: result.code, + output: result.code ?? request.code, messages: result.diagnostics.messages, }; } @@ -499,9 +518,17 @@ async function inlineLocalize( magicString.overwrite(callSite.start, callSite.end, replacement); } + if (!magicString.hasChanged()) { + return { + code: undefined, + map: undefined, + diagnostics, + }; + } + const outputCode = magicString.toString(); let outputMap; - if (map && magicString.hasChanged()) { + if (map) { // A decoded map is generated here rather than an encoded one because remapping decodes its // inputs. Encoding the mappings only for remapping to immediately decode them again doubles // the peak memory of the largest structure involved in inlining a file. diff --git a/packages/angular/build/src/tools/esbuild/i18n-inliner.ts b/packages/angular/build/src/tools/esbuild/i18n-inliner.ts index 33b570a46017..5cca10c534c9 100644 --- a/packages/angular/build/src/tools/esbuild/i18n-inliner.ts +++ b/packages/angular/build/src/tools/esbuild/i18n-inliner.ts @@ -96,7 +96,7 @@ export interface LocaleInlineResult { */ interface TransformedFileResult { file: string; - code: string; + code?: string; map?: string; messages: { type: 'error' | 'warning'; message: string }[]; } @@ -362,17 +362,26 @@ export class I18nInliner { if (fileResults) { for (const filename of filenames) { + const originalFile = this.#localizeFiles.get(filename); + assert(originalFile !== undefined, 'Localize file must exist: ' + filename); + const fileResult = fileResults.get(filename); if (!fileResult) { continue; } - const type = this.#localizeFiles.get(filename)?.type; - assert(type !== undefined, 'localized file should always have a type: ' + filename); + const type = originalFile.type; + if (fileResult.code != undefined) { + outputFiles.push(createOutputFile(filename, fileResult.code, type)); + } else { + outputFiles.push(originalFile.clone()); + } - outputFiles.push(createOutputFile(filename, fileResult.code, type)); - if (fileResult.map) { + const originalMap = this.#localizeFiles.get(filename + '.map'); + if (fileResult.map !== undefined) { outputFiles.push(createOutputFile(filename + '.map', fileResult.map, type)); + } else if (originalMap !== undefined) { + outputFiles.push(originalMap.clone()); } for (const message of fileResult.messages) { @@ -427,30 +436,54 @@ export class I18nInliner { activeLocales, }, { name: 'inlineFileBatch' }, - )) as { - file: string; - results: Array; - }; - - const cachePromises: Promise[] = []; - for (const res of batchResult.results) { - const matchingEntry = batchEntries.find((e) => e.locale === res.locale); - const cacheKey = matchingEntry?.cacheKey; - - if (this.#cache && cacheKey) { - cachePromises.push( - this.#cache.put(cacheKey, { - file: filename, - code: res.code, - map: res.map, - messages: res.messages, - }), - ); + )) as + | { + file: string; + unmodified: true; + messages: { type: 'error' | 'warning'; message: string }[]; + } + | { + file: string; + unmodified?: false; + results: Array; + }; + + if (batchResult.unmodified) { + const unmodifiedResult: TransformedFileResult = { + file: filename, + messages: batchResult.messages, + }; + + const cachePromises: Promise[] = []; + for (const { locale, cacheKey } of batchEntries) { + fileResultsByLocale.get(locale)?.set(filename, unmodifiedResult); + + if (this.#cache && cacheKey) { + cachePromises.push(this.#cache.put(cacheKey, unmodifiedResult)); + } } - - fileResultsByLocale.get(res.locale)?.set(filename, res); + await Promise.allSettled(cachePromises); + } else { + const cachePromises: Promise[] = []; + for (const res of batchResult.results) { + const matchingEntry = batchEntries.find((e) => e.locale === res.locale); + const cacheKey = matchingEntry?.cacheKey; + + if (this.#cache && cacheKey) { + cachePromises.push( + this.#cache.put(cacheKey, { + file: filename, + code: res.code, + map: res.map, + messages: res.messages, + }), + ); + } + + fileResultsByLocale.get(res.locale)?.set(filename, res); + } + await Promise.allSettled(cachePromises); } - await Promise.allSettled(cachePromises); })(); workerTasks.push(task); diff --git a/packages/angular/build/src/tools/esbuild/i18n-inliner_spec.ts b/packages/angular/build/src/tools/esbuild/i18n-inliner_spec.ts index acceab7513b5..d2f5559f5bb2 100644 --- a/packages/angular/build/src/tools/esbuild/i18n-inliner_spec.ts +++ b/packages/angular/build/src/tools/esbuild/i18n-inliner_spec.ts @@ -644,4 +644,83 @@ describe('I18nInliner', () => { const iifeMatches = frPolyfills.match(/function\s*\(global/g); expect(iifeMatches?.length).toBe(1); }); + + it('preserves code and sourcemaps when a file contains the $localize keyword only in comments', async () => { + const source = '// $localize keyword in comment\nexport const message = "hello world";\n'; + const { code, map } = await transform(source, { + sourcefile: 'comment-only.ts', + loader: 'ts', + sourcemap: 'external', + }); + + const localeInliner = createInliner([ + browserFile('main.js', code), + browserFile('main.js.map', map), + ]); + + const results = await localeInliner.inlineAll([ + { locale: 'fr', translation: { greeting: translationFor('Bonjour') } }, + { locale: 'de', translation: { greeting: translationFor('Hallo') } }, + ]); + + expect(results.size).toBe(2); + + for (const locale of ['fr', 'de'] as const) { + const localeResult = results.get(locale); + expect(localeResult).toBeDefined(); + expect(localeResult?.errors).toEqual([]); + expect(localeResult?.warnings).toEqual([]); + + const mainJs = findFile(localeResult?.outputFiles ?? [], 'main.js'); + expect(mainJs.text).toBe(code); + + const mainMap = findFile(localeResult?.outputFiles ?? [], 'main.js.map'); + expect(mainMap.text).toBe(map); + } + }); + + it('correctly handles persistent caching for unmodified files', async () => { + const cacheDir = await fs.mkdtemp(path.join(os.tmpdir(), 'i18n-unmodified-cache-test-')); + const source = '// $localize comment only\nexport const value = 123;\n'; + + try { + const inliner1 = new I18nInliner({ + missingTranslation: 'error', + outputFiles: [browserFile('main.js', source)], + persistentCachePath: cacheDir, + }); + + const results1 = await inliner1.inlineAll([ + { + locale: 'fr', + translation: { greeting: translationFor('Bonjour') }, + translationIntegrity: 'fr-1', + }, + ]); + + expect(results1.get('fr')?.errors).toEqual([]); + expect(findFile(results1.get('fr')?.outputFiles ?? [], 'main.js').text).toBe(source); + await inliner1.close(); + + const inliner2 = new I18nInliner({ + missingTranslation: 'error', + outputFiles: [browserFile('main.js', source)], + persistentCachePath: cacheDir, + }); + + const results2 = await inliner2.inlineAll([ + { + locale: 'fr', + translation: { greeting: translationFor('Bonjour') }, + translationIntegrity: 'fr-1', + }, + ]); + + expect(results2.get('fr')?.errors).toEqual([]); + expect(findFile(results2.get('fr')?.outputFiles ?? [], 'main.js').text).toBe(source); + await inliner2.close(); + } finally { + await fs.rm(cacheDir, { recursive: true, force: true }); + } + }); }); From 224dd87f683cda4554ffcd3f90e191d29d6c138d Mon Sep 17 00:00:00 2001 From: Angular Robot Date: Thu, 27 Aug 2026 06:33:01 +0000 Subject: [PATCH 360/787] build: update bazel dependencies See associated pull request for more information. --- MODULE.bazel | 4 ++-- MODULE.bazel.lock | 25 ++++++++++++++----------- 2 files changed, 16 insertions(+), 13 deletions(-) diff --git a/MODULE.bazel b/MODULE.bazel index 3015308e9d38..ecdb8e826ee2 100644 --- a/MODULE.bazel +++ b/MODULE.bazel @@ -7,8 +7,8 @@ module( bazel_dep(name = "platforms", version = "1.1.0") bazel_dep(name = "yq.bzl", version = "0.3.6") bazel_dep(name = "rules_nodejs", version = "6.7.5") -bazel_dep(name = "aspect_rules_js", version = "3.4.0") -bazel_dep(name = "aspect_rules_ts", version = "3.10.0") +bazel_dep(name = "aspect_rules_js", version = "3.4.1") +bazel_dep(name = "aspect_rules_ts", version = "3.10.1") bazel_dep(name = "rules_pkg", version = "1.3.0") bazel_dep(name = "rules_cc", version = "0.2.22") bazel_dep(name = "jq.bzl", version = "0.6.1") diff --git a/MODULE.bazel.lock b/MODULE.bazel.lock index ee16930eae77..780cef563755 100644 --- a/MODULE.bazel.lock +++ b/MODULE.bazel.lock @@ -24,13 +24,16 @@ "https://bcr.bazel.build/modules/aspect_rules_jasmine/2.0.4/source.json": "81ffb708333cd98ec3c0b4cc004f4d5cf92a16914b5196a2892c45141bba7cff", "https://bcr.bazel.build/modules/aspect_rules_js/2.0.0/MODULE.bazel": "b45b507574aa60a92796e3e13c195cd5744b3b8aff516a9c0cb5ae6a048161c5", "https://bcr.bazel.build/modules/aspect_rules_js/3.4.0/MODULE.bazel": "88844ac411e1961f4574a92f3c5be5b20d1c6997778c6b88316c5c3b4b60e284", - "https://bcr.bazel.build/modules/aspect_rules_js/3.4.0/source.json": "85e5822f00dcbe64a1eda1324119e289c8c03cacb5c3695dffee16397b529078", + "https://bcr.bazel.build/modules/aspect_rules_js/3.4.1/MODULE.bazel": "e46853c134b48bc84c9bb5c4a4c8ae792dcfd5277acac9d90c444d65fa43dd19", + "https://bcr.bazel.build/modules/aspect_rules_js/3.4.1/source.json": "b11f550b53d451800ebd0b4f38a048aea33fbfbd78fb5c77dca847f6b9b47a3b", "https://bcr.bazel.build/modules/aspect_rules_ts/3.10.0/MODULE.bazel": "69d06f57f30f4a2b6e53471584a9559d3b7cd7f891e1699876991230c7cabb95", - "https://bcr.bazel.build/modules/aspect_rules_ts/3.10.0/source.json": "56f28a3ddb55ceaaf57a1ef8d7195136789ca1d72d0c8a6a9eeaad313be4099d", + "https://bcr.bazel.build/modules/aspect_rules_ts/3.10.1/MODULE.bazel": "035205a7834b0ed9724ed3c4790e12d1c779ef2520d72496ab234e6307715e6c", + "https://bcr.bazel.build/modules/aspect_rules_ts/3.10.1/source.json": "d42b6560206adb5524caad2abc40ae0b5b34478dd38184a9f6ea4a5fed848cd6", "https://bcr.bazel.build/modules/aspect_tools_telemetry/0.2.8/MODULE.bazel": "aa975a83e72bcaac62ee61ab12b788ea324a1d05c4aab28aadb202f647881679", "https://bcr.bazel.build/modules/aspect_tools_telemetry/0.3.3/MODULE.bazel": "37c764292861c2f70314efa9846bb6dbb44fc0308903b3285da6528305450183", "https://bcr.bazel.build/modules/aspect_tools_telemetry/0.4.2/MODULE.bazel": "f31aa84151d31e98cffd43eb7217ccff5ec52bdd5f2d10db8f053aeb23342eca", - "https://bcr.bazel.build/modules/aspect_tools_telemetry/0.4.2/source.json": "d027d264e6b6e7fc421e38189f4374fcd14a67e0bd6e0e705de8c2185c3787e1", + "https://bcr.bazel.build/modules/aspect_tools_telemetry/0.5.1/MODULE.bazel": "9d94e5c22c0019995c0a3216a6abb1717dc3f35acccf4e6267a55d6df38367aa", + "https://bcr.bazel.build/modules/aspect_tools_telemetry/0.5.1/source.json": "dbe0a75bf1f741b18c7b72dd4d205fa5a45c8c135fee15f7fdd1a2b50ba0fdde", "https://bcr.bazel.build/modules/bazel_features/1.1.1/MODULE.bazel": "27b8c79ef57efe08efccbd9dd6ef70d61b4798320b8d3c134fd571f78963dbcd", "https://bcr.bazel.build/modules/bazel_features/1.11.0/MODULE.bazel": "f9382337dd5a474c3b7d334c2f83e50b6eaedc284253334cf823044a26de03e8", "https://bcr.bazel.build/modules/bazel_features/1.15.0/MODULE.bazel": "d38ff6e517149dc509406aca0db3ad1efdd890a85e049585b7234d04238e2a4d", @@ -219,7 +222,7 @@ "moduleExtensions": { "@@aspect_rules_esbuild+//esbuild:extensions.bzl%esbuild": { "general": { - "bzlTransitiveDigest": "eGsGosHZTHOEZx11j7nDLNMHxCkESoe1oypcL3+G6GI=", + "bzlTransitiveDigest": "yziqvbws9noFTds23HE5koMAI5QqGgQ7qmxOQkVtiw4=", "usagesDigest": "LZ71sshnfqI8R/HeWwBTwawxIa7KnitayBl2hYrqPo4=", "recordedFileInputs": {}, "recordedDirentsInputs": {}, @@ -434,8 +437,8 @@ }, "@@aspect_tools_telemetry+//:extension.bzl%telemetry": { "general": { - "bzlTransitiveDigest": "4w9RM0xjdKo1crk5zL20a/TuhqO0P1z1LsuXDneBXD4=", - "usagesDigest": "VoGyqZ+r/3juGZUfSXD4FAe965Z3XS4WANRrYH79+1Q=", + "bzlTransitiveDigest": "zFgbaCUuPzH6bIE7CBHBVCqjWSJ78/WNXisdzXaKSnU=", + "usagesDigest": "2cLMn8ZcqY/6j/zH70TrPob+ENshTw9h48kUHxn1cUM=", "recordedFileInputs": {}, "recordedDirentsInputs": {}, "envVariables": { @@ -446,11 +449,11 @@ "repoRuleId": "@@aspect_tools_telemetry+//:extension.bzl%tel_repository", "attributes": { "deps": { - "aspect_rules_js": "3.4.0", - "aspect_rules_ts": "3.10.0", + "aspect_rules_js": "3.4.1", + "aspect_rules_ts": "3.10.1", "aspect_rules_esbuild": "0.27.0", "aspect_rules_jasmine": "2.0.4", - "aspect_tools_telemetry": "0.4.2" + "aspect_tools_telemetry": "0.5.1" }, "last_notice": 1 } @@ -1172,7 +1175,7 @@ "@@yq.bzl+//yq:extensions.bzl%yq": { "general": { "bzlTransitiveDigest": "UfFMy8CWK4/dVo/tfaSAIYUiDGNAPes5eRllx9O9Q9Q=", - "usagesDigest": "9kbJ6OfvQpAM3otgkGgS5xpOHOoVgV5ZJ9jSgMgUG2g=", + "usagesDigest": "eEOK0cJsj9/GBF2ShPyWYqgDUBnB4T9UVZlCprAY7Iw=", "recordedFileInputs": {}, "recordedDirentsInputs": {}, "envVariables": {}, @@ -1253,7 +1256,7 @@ }, "facts": { "@@aspect_tools_telemetry+//:extension.bzl%telemetry": { - "notice_version": "1" + "notice_version": "2" } } } From 9cebe228c532877cb984506159deb2c3331bdedc Mon Sep 17 00:00:00 2001 From: Angular Robot Date: Thu, 27 Aug 2026 15:44:08 +0000 Subject: [PATCH 361/787] build: update cross-repo angular dependencies See associated pull request for more information. --- .../assistant-to-the-branch-manager.yml | 2 +- .github/workflows/ci.yml | 52 ++-- .github/workflows/dev-infra.yml | 6 +- .github/workflows/perf.yml | 6 +- .github/workflows/pr.yml | 44 +-- MODULE.bazel | 4 +- modules/testing/builder/package.json | 2 +- package.json | 28 +- packages/angular/build/package.json | 2 +- packages/angular/ssr/package.json | 12 +- .../angular_devkit/build_angular/package.json | 2 +- packages/ngtools/webpack/package.json | 4 +- pnpm-lock.yaml | 293 +++++++++--------- tests/e2e/ng-snapshot/package.json | 32 +- 14 files changed, 244 insertions(+), 245 deletions(-) diff --git a/.github/workflows/assistant-to-the-branch-manager.yml b/.github/workflows/assistant-to-the-branch-manager.yml index 9147cb3a65b8..adb1937840ae 100644 --- a/.github/workflows/assistant-to-the-branch-manager.yml +++ b/.github/workflows/assistant-to-the-branch-manager.yml @@ -18,6 +18,6 @@ jobs: - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: persist-credentials: false - - uses: angular/dev-infra/github-actions/branch-manager@e713eca55b2813448af42f2e0e752258e4edfeea # main + - uses: angular/dev-infra/github-actions/branch-manager@fa43fd2864c3bec677cd47f4e095370850cdf8bc # main with: angular-robot-key: ${{ secrets.ANGULAR_ROBOT_PRIVATE_KEY }} diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index b7d66e4aafc5..9ca3788bd8d5 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -21,9 +21,9 @@ jobs: runs-on: ubuntu-latest steps: - name: Initialize environment - uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@e713eca55b2813448af42f2e0e752258e4edfeea # main + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@fa43fd2864c3bec677cd47f4e095370850cdf8bc # main - name: Setup Bazel - uses: angular/dev-infra/github-actions/bazel/setup@e713eca55b2813448af42f2e0e752258e4edfeea # main + uses: angular/dev-infra/github-actions/bazel/setup@fa43fd2864c3bec677cd47f4e095370850cdf8bc # main - name: Install node modules run: pnpm install --frozen-lockfile - name: Generate JSON schema types @@ -44,11 +44,11 @@ jobs: runs-on: ubuntu-latest steps: - name: Initialize environment - uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@e713eca55b2813448af42f2e0e752258e4edfeea # main + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@fa43fd2864c3bec677cd47f4e095370850cdf8bc # main - name: Setup Bazel - uses: angular/dev-infra/github-actions/bazel/setup@e713eca55b2813448af42f2e0e752258e4edfeea # main + uses: angular/dev-infra/github-actions/bazel/setup@fa43fd2864c3bec677cd47f4e095370850cdf8bc # main - name: Setup Bazel RBE - uses: angular/dev-infra/github-actions/bazel/configure-remote@e713eca55b2813448af42f2e0e752258e4edfeea # main + uses: angular/dev-infra/github-actions/bazel/configure-remote@fa43fd2864c3bec677cd47f4e095370850cdf8bc # main with: google_credential: ${{ secrets.RBE_TRUSTED_BUILDS_USER }} - name: Install node modules @@ -61,11 +61,11 @@ jobs: runs-on: ubuntu-latest steps: - name: Initialize environment - uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@e713eca55b2813448af42f2e0e752258e4edfeea # main + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@fa43fd2864c3bec677cd47f4e095370850cdf8bc # main - name: Setup Bazel - uses: angular/dev-infra/github-actions/bazel/setup@e713eca55b2813448af42f2e0e752258e4edfeea # main + uses: angular/dev-infra/github-actions/bazel/setup@fa43fd2864c3bec677cd47f4e095370850cdf8bc # main - name: Setup Bazel RBE - uses: angular/dev-infra/github-actions/bazel/configure-remote@e713eca55b2813448af42f2e0e752258e4edfeea # main + uses: angular/dev-infra/github-actions/bazel/configure-remote@fa43fd2864c3bec677cd47f4e095370850cdf8bc # main with: google_credential: ${{ secrets.RBE_TRUSTED_BUILDS_USER }} - name: Install node modules @@ -84,13 +84,13 @@ jobs: runs-on: ubuntu-latest steps: - name: Initialize environment - uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@e713eca55b2813448af42f2e0e752258e4edfeea # main + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@fa43fd2864c3bec677cd47f4e095370850cdf8bc # main - name: Install node modules run: pnpm install --frozen-lockfile - name: Setup Bazel - uses: angular/dev-infra/github-actions/bazel/setup@e713eca55b2813448af42f2e0e752258e4edfeea # main + uses: angular/dev-infra/github-actions/bazel/setup@fa43fd2864c3bec677cd47f4e095370850cdf8bc # main - name: Setup Bazel RBE - uses: angular/dev-infra/github-actions/bazel/configure-remote@e713eca55b2813448af42f2e0e752258e4edfeea # main + uses: angular/dev-infra/github-actions/bazel/configure-remote@fa43fd2864c3bec677cd47f4e095370850cdf8bc # main with: google_credential: ${{ secrets.RBE_TRUSTED_BUILDS_USER }} - name: Run CLI E2E tests @@ -100,11 +100,11 @@ jobs: runs-on: ubuntu-latest steps: - name: Initialize environment - uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@e713eca55b2813448af42f2e0e752258e4edfeea # main + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@fa43fd2864c3bec677cd47f4e095370850cdf8bc # main - name: Setup Bazel - uses: angular/dev-infra/github-actions/bazel/setup@e713eca55b2813448af42f2e0e752258e4edfeea # main + uses: angular/dev-infra/github-actions/bazel/setup@fa43fd2864c3bec677cd47f4e095370850cdf8bc # main - name: Setup Bazel RBE - uses: angular/dev-infra/github-actions/bazel/configure-remote@e713eca55b2813448af42f2e0e752258e4edfeea # main + uses: angular/dev-infra/github-actions/bazel/configure-remote@fa43fd2864c3bec677cd47f4e095370850cdf8bc # main with: google_credential: ${{ secrets.RBE_TRUSTED_BUILDS_USER }} - name: Install node modules @@ -137,7 +137,7 @@ jobs: runs-on: windows-2025 steps: - name: Initialize environment - uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@e713eca55b2813448af42f2e0e752258e4edfeea # main + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@fa43fd2864c3bec677cd47f4e095370850cdf8bc # main - name: Install node modules run: pnpm install --frozen-lockfile - name: Download built Windows E2E tests @@ -164,13 +164,13 @@ jobs: runs-on: ubuntu-latest steps: - name: Initialize environment - uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@e713eca55b2813448af42f2e0e752258e4edfeea # main + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@fa43fd2864c3bec677cd47f4e095370850cdf8bc # main - name: Install node modules run: pnpm install --frozen-lockfile - name: Setup Bazel - uses: angular/dev-infra/github-actions/bazel/setup@e713eca55b2813448af42f2e0e752258e4edfeea # main + uses: angular/dev-infra/github-actions/bazel/setup@fa43fd2864c3bec677cd47f4e095370850cdf8bc # main - name: Setup Bazel RBE - uses: angular/dev-infra/github-actions/bazel/configure-remote@e713eca55b2813448af42f2e0e752258e4edfeea # main + uses: angular/dev-infra/github-actions/bazel/configure-remote@fa43fd2864c3bec677cd47f4e095370850cdf8bc # main with: google_credential: ${{ secrets.RBE_TRUSTED_BUILDS_USER }} - name: Run CLI E2E tests @@ -188,13 +188,13 @@ jobs: runs-on: ubuntu-latest steps: - name: Initialize environment - uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@e713eca55b2813448af42f2e0e752258e4edfeea # main + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@fa43fd2864c3bec677cd47f4e095370850cdf8bc # main - name: Install node modules run: pnpm install --frozen-lockfile - name: Setup Bazel - uses: angular/dev-infra/github-actions/bazel/setup@e713eca55b2813448af42f2e0e752258e4edfeea # main + uses: angular/dev-infra/github-actions/bazel/setup@fa43fd2864c3bec677cd47f4e095370850cdf8bc # main - name: Setup Bazel RBE - uses: angular/dev-infra/github-actions/bazel/configure-remote@e713eca55b2813448af42f2e0e752258e4edfeea # main + uses: angular/dev-infra/github-actions/bazel/configure-remote@fa43fd2864c3bec677cd47f4e095370850cdf8bc # main with: google_credential: ${{ secrets.RBE_TRUSTED_BUILDS_USER }} - name: Run CLI E2E tests @@ -208,13 +208,13 @@ jobs: SAUCE_TUNNEL_IDENTIFIER: angular-cli-${{ github.workflow }}-${{ github.run_number }} steps: - name: Initialize environment - uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@e713eca55b2813448af42f2e0e752258e4edfeea # main + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@fa43fd2864c3bec677cd47f4e095370850cdf8bc # main - name: Install node modules run: pnpm install --frozen-lockfile - name: Setup Bazel - uses: angular/dev-infra/github-actions/bazel/setup@e713eca55b2813448af42f2e0e752258e4edfeea # main + uses: angular/dev-infra/github-actions/bazel/setup@fa43fd2864c3bec677cd47f4e095370850cdf8bc # main - name: Setup Bazel RBE - uses: angular/dev-infra/github-actions/bazel/configure-remote@e713eca55b2813448af42f2e0e752258e4edfeea # main + uses: angular/dev-infra/github-actions/bazel/configure-remote@fa43fd2864c3bec677cd47f4e095370850cdf8bc # main with: google_credential: ${{ secrets.RBE_TRUSTED_BUILDS_USER }} - name: Start Sauce Connect @@ -245,11 +245,11 @@ jobs: CIRCLE_BRANCH: ${{ github.ref_name }} steps: - name: Initialize environment - uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@e713eca55b2813448af42f2e0e752258e4edfeea # main + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@fa43fd2864c3bec677cd47f4e095370850cdf8bc # main - name: Install node modules run: pnpm install --frozen-lockfile - name: Setup Bazel - uses: angular/dev-infra/github-actions/bazel/setup@e713eca55b2813448af42f2e0e752258e4edfeea # main + uses: angular/dev-infra/github-actions/bazel/setup@fa43fd2864c3bec677cd47f4e095370850cdf8bc # main - run: pnpm admin snapshots --verbose env: SNAPSHOT_BUILDS_GITHUB_TOKEN: ${{ secrets.SNAPSHOT_BUILDS_GITHUB_TOKEN }} diff --git a/.github/workflows/dev-infra.yml b/.github/workflows/dev-infra.yml index f0b468e675ea..3de13736b60d 100644 --- a/.github/workflows/dev-infra.yml +++ b/.github/workflows/dev-infra.yml @@ -16,21 +16,21 @@ jobs: if: github.event_name == 'pull_request_target' runs-on: ubuntu-latest steps: - - uses: angular/dev-infra/github-actions/labeling/pull-request@e713eca55b2813448af42f2e0e752258e4edfeea # main + - uses: angular/dev-infra/github-actions/labeling/pull-request@fa43fd2864c3bec677cd47f4e095370850cdf8bc # main with: angular-robot-key: ${{ secrets.ANGULAR_ROBOT_PRIVATE_KEY }} post_approval_changes: if: github.event_name == 'pull_request_target' runs-on: ubuntu-latest steps: - - uses: angular/dev-infra/github-actions/post-approval-changes@e713eca55b2813448af42f2e0e752258e4edfeea # main + - uses: angular/dev-infra/github-actions/post-approval-changes@fa43fd2864c3bec677cd47f4e095370850cdf8bc # main with: angular-robot-key: ${{ secrets.ANGULAR_ROBOT_PRIVATE_KEY }} issue_labels: if: github.event_name == 'issues' runs-on: ubuntu-latest steps: - - uses: angular/dev-infra/github-actions/labeling/issue@e713eca55b2813448af42f2e0e752258e4edfeea # main + - uses: angular/dev-infra/github-actions/labeling/issue@fa43fd2864c3bec677cd47f4e095370850cdf8bc # main with: angular-robot-key: ${{ secrets.ANGULAR_ROBOT_PRIVATE_KEY }} google-generative-ai-key: ${{ secrets.GOOGLE_GENERATIVE_AI_KEY }} diff --git a/.github/workflows/perf.yml b/.github/workflows/perf.yml index 392fbd4cc108..83dfe2812a83 100644 --- a/.github/workflows/perf.yml +++ b/.github/workflows/perf.yml @@ -22,7 +22,7 @@ jobs: workflows: ${{ steps.workflows.outputs.workflows }} steps: - name: Initialize environment - uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@e713eca55b2813448af42f2e0e752258e4edfeea # main + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@fa43fd2864c3bec677cd47f4e095370850cdf8bc # main - name: Install node modules run: pnpm install --frozen-lockfile - id: workflows @@ -40,9 +40,9 @@ jobs: workflow: ${{ fromJSON(needs.list.outputs.workflows) }} steps: - name: Initialize environment - uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@e713eca55b2813448af42f2e0e752258e4edfeea # main + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@fa43fd2864c3bec677cd47f4e095370850cdf8bc # main - name: Setup Bazel - uses: angular/dev-infra/github-actions/bazel/setup@e713eca55b2813448af42f2e0e752258e4edfeea # main + uses: angular/dev-infra/github-actions/bazel/setup@fa43fd2864c3bec677cd47f4e095370850cdf8bc # main - name: Install node modules run: pnpm install --frozen-lockfile # We utilize the google-github-actions/auth action to allow us to get an active credential using workflow diff --git a/.github/workflows/pr.yml b/.github/workflows/pr.yml index 0837c2b0fa67..453a75f453ae 100644 --- a/.github/workflows/pr.yml +++ b/.github/workflows/pr.yml @@ -34,9 +34,9 @@ jobs: runs-on: ubuntu-latest steps: - name: Initialize environment - uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@e713eca55b2813448af42f2e0e752258e4edfeea # main + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@fa43fd2864c3bec677cd47f4e095370850cdf8bc # main - name: Setup Bazel - uses: angular/dev-infra/github-actions/bazel/setup@e713eca55b2813448af42f2e0e752258e4edfeea # main + uses: angular/dev-infra/github-actions/bazel/setup@fa43fd2864c3bec677cd47f4e095370850cdf8bc # main - name: Setup ESLint Caching uses: actions/cache@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0 with: @@ -66,17 +66,17 @@ jobs: # it has been merged. run: pnpm ng-dev format changed --check ${{ github.event.pull_request.base.sha }} - name: Check Package Licenses - uses: angular/dev-infra/github-actions/linting/licenses@e713eca55b2813448af42f2e0e752258e4edfeea # main + uses: angular/dev-infra/github-actions/linting/licenses@fa43fd2864c3bec677cd47f4e095370850cdf8bc # main build: runs-on: ubuntu-latest steps: - name: Initialize environment - uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@e713eca55b2813448af42f2e0e752258e4edfeea # main + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@fa43fd2864c3bec677cd47f4e095370850cdf8bc # main - name: Setup Bazel - uses: angular/dev-infra/github-actions/bazel/setup@e713eca55b2813448af42f2e0e752258e4edfeea # main + uses: angular/dev-infra/github-actions/bazel/setup@fa43fd2864c3bec677cd47f4e095370850cdf8bc # main - name: Setup Bazel RBE - uses: angular/dev-infra/github-actions/bazel/configure-remote@e713eca55b2813448af42f2e0e752258e4edfeea # main + uses: angular/dev-infra/github-actions/bazel/configure-remote@fa43fd2864c3bec677cd47f4e095370850cdf8bc # main - name: Install node modules run: pnpm install --frozen-lockfile - name: Build release targets @@ -93,11 +93,11 @@ jobs: runs-on: ubuntu-latest steps: - name: Initialize environment - uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@e713eca55b2813448af42f2e0e752258e4edfeea # main + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@fa43fd2864c3bec677cd47f4e095370850cdf8bc # main - name: Setup Bazel - uses: angular/dev-infra/github-actions/bazel/setup@e713eca55b2813448af42f2e0e752258e4edfeea # main + uses: angular/dev-infra/github-actions/bazel/setup@fa43fd2864c3bec677cd47f4e095370850cdf8bc # main - name: Setup Bazel RBE - uses: angular/dev-infra/github-actions/bazel/configure-remote@e713eca55b2813448af42f2e0e752258e4edfeea # main + uses: angular/dev-infra/github-actions/bazel/configure-remote@fa43fd2864c3bec677cd47f4e095370850cdf8bc # main - name: Install node modules run: pnpm install --frozen-lockfile - name: Run module and package tests @@ -114,13 +114,13 @@ jobs: runs-on: ubuntu-latest steps: - name: Initialize environment - uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@e713eca55b2813448af42f2e0e752258e4edfeea # main + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@fa43fd2864c3bec677cd47f4e095370850cdf8bc # main - name: Install node modules run: pnpm install --frozen-lockfile - name: Setup Bazel - uses: angular/dev-infra/github-actions/bazel/setup@e713eca55b2813448af42f2e0e752258e4edfeea # main + uses: angular/dev-infra/github-actions/bazel/setup@fa43fd2864c3bec677cd47f4e095370850cdf8bc # main - name: Setup Bazel RBE - uses: angular/dev-infra/github-actions/bazel/configure-remote@e713eca55b2813448af42f2e0e752258e4edfeea # main + uses: angular/dev-infra/github-actions/bazel/configure-remote@fa43fd2864c3bec677cd47f4e095370850cdf8bc # main - name: Run CLI E2E tests run: pnpm bazel test --test_env=E2E_SHARD_TOTAL=6 --test_env=E2E_SHARD_INDEX=${{ matrix.shard }} --config=e2e //tests:e2e.${{ matrix.subset }}_node${{ matrix.node }} @@ -128,11 +128,11 @@ jobs: runs-on: ubuntu-latest steps: - name: Initialize environment - uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@e713eca55b2813448af42f2e0e752258e4edfeea # main + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@fa43fd2864c3bec677cd47f4e095370850cdf8bc # main - name: Setup Bazel - uses: angular/dev-infra/github-actions/bazel/setup@e713eca55b2813448af42f2e0e752258e4edfeea # main + uses: angular/dev-infra/github-actions/bazel/setup@fa43fd2864c3bec677cd47f4e095370850cdf8bc # main - name: Setup Bazel RBE - uses: angular/dev-infra/github-actions/bazel/configure-remote@e713eca55b2813448af42f2e0e752258e4edfeea # main + uses: angular/dev-infra/github-actions/bazel/configure-remote@fa43fd2864c3bec677cd47f4e095370850cdf8bc # main - name: Install node modules run: pnpm install --frozen-lockfile - name: Build E2E tests for Windows on Linux @@ -156,7 +156,7 @@ jobs: runs-on: windows-2025 steps: - name: Initialize environment - uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@e713eca55b2813448af42f2e0e752258e4edfeea # main + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@fa43fd2864c3bec677cd47f4e095370850cdf8bc # main - name: Install node modules run: pnpm install --frozen-lockfile - name: Download built Windows E2E tests @@ -183,13 +183,13 @@ jobs: runs-on: ubuntu-latest steps: - name: Initialize environment - uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@e713eca55b2813448af42f2e0e752258e4edfeea # main + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@fa43fd2864c3bec677cd47f4e095370850cdf8bc # main - name: Install node modules run: pnpm install --frozen-lockfile - name: Setup Bazel - uses: angular/dev-infra/github-actions/bazel/setup@e713eca55b2813448af42f2e0e752258e4edfeea # main + uses: angular/dev-infra/github-actions/bazel/setup@fa43fd2864c3bec677cd47f4e095370850cdf8bc # main - name: Setup Bazel RBE - uses: angular/dev-infra/github-actions/bazel/configure-remote@e713eca55b2813448af42f2e0e752258e4edfeea # main + uses: angular/dev-infra/github-actions/bazel/configure-remote@fa43fd2864c3bec677cd47f4e095370850cdf8bc # main - name: Run CLI E2E tests run: pnpm bazel test --test_env=E2E_SHARD_TOTAL=3 --test_env=E2E_SHARD_INDEX=${{ matrix.shard }} --config=e2e //tests:e2e.${{ matrix.subset }}_node${{ matrix.node }} @@ -205,12 +205,12 @@ jobs: runs-on: ubuntu-latest steps: - name: Initialize environment - uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@e713eca55b2813448af42f2e0e752258e4edfeea # main + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@fa43fd2864c3bec677cd47f4e095370850cdf8bc # main - name: Install node modules run: pnpm install --frozen-lockfile - name: Setup Bazel - uses: angular/dev-infra/github-actions/bazel/setup@e713eca55b2813448af42f2e0e752258e4edfeea # main + uses: angular/dev-infra/github-actions/bazel/setup@fa43fd2864c3bec677cd47f4e095370850cdf8bc # main - name: Setup Bazel RBE - uses: angular/dev-infra/github-actions/bazel/configure-remote@e713eca55b2813448af42f2e0e752258e4edfeea # main + uses: angular/dev-infra/github-actions/bazel/configure-remote@fa43fd2864c3bec677cd47f4e095370850cdf8bc # main - name: Run CLI E2E tests run: pnpm bazel test --test_env=E2E_SHARD_TOTAL=6 --test_env=E2E_SHARD_INDEX=${{ matrix.shard }} --config=e2e //tests:e2e.snapshots.${{ matrix.subset }}_node${{ matrix.node }} diff --git a/MODULE.bazel b/MODULE.bazel index ecdb8e826ee2..1c0127473365 100644 --- a/MODULE.bazel +++ b/MODULE.bazel @@ -19,14 +19,14 @@ bazel_dep(name = "aspect_rules_jasmine", version = "2.0.4") bazel_dep(name = "rules_angular") git_override( module_name = "rules_angular", - commit = "a30fc96ae7cbf6738d37d9d7d3e1c6e6cb7744f5", + commit = "ed98d720477b10c13f3d0ccee72f929c777f6ccd", remote = "https://github.com/angular/rules_angular.git", ) bazel_dep(name = "devinfra") git_override( module_name = "devinfra", - commit = "e713eca55b2813448af42f2e0e752258e4edfeea", + commit = "fa43fd2864c3bec677cd47f4e095370850cdf8bc", remote = "https://github.com/angular/dev-infra.git", ) diff --git a/modules/testing/builder/package.json b/modules/testing/builder/package.json index f2db890d966d..42b38d3a02ab 100644 --- a/modules/testing/builder/package.json +++ b/modules/testing/builder/package.json @@ -8,7 +8,7 @@ "browser-sync": "3.0.4", "istanbul-lib-instrument": "6.0.3", "jsdom": "30.0.1", - "ng-packagr": "22.2.0-next.3", + "ng-packagr": "22.2.0-next.4", "rxjs": "7.8.2", "vitest": "4.1.11" } diff --git a/package.json b/package.json index fbf396e21a0e..7806b3b929ed 100644 --- a/package.json +++ b/package.json @@ -42,23 +42,23 @@ }, "homepage": "https://github.com/angular/angular-cli", "dependencies": { - "@angular/compiler-cli": "22.2.0-next.3", + "@angular/compiler-cli": "22.2.0-next.4", "typescript": "6.0.3" }, "devDependencies": { - "@angular/animations": "22.2.0-next.3", - "@angular/cdk": "22.2.0-next.2", - "@angular/common": "22.2.0-next.3", - "@angular/compiler": "22.2.0-next.3", - "@angular/core": "22.2.0-next.3", - "@angular/forms": "22.2.0-next.3", - "@angular/localize": "22.2.0-next.3", - "@angular/material": "22.2.0-next.2", - "@angular/ng-dev": "https://github.com/angular/dev-infra-private-ng-dev-builds.git#bcad06e14cb29b52b0856020af5e2ab868075602", - "@angular/platform-browser": "22.2.0-next.3", - "@angular/platform-server": "22.2.0-next.3", - "@angular/router": "22.2.0-next.3", - "@angular/service-worker": "22.2.0-next.3", + "@angular/animations": "22.2.0-next.4", + "@angular/cdk": "22.2.0-next.3", + "@angular/common": "22.2.0-next.4", + "@angular/compiler": "22.2.0-next.4", + "@angular/core": "22.2.0-next.4", + "@angular/forms": "22.2.0-next.4", + "@angular/localize": "22.2.0-next.4", + "@angular/material": "22.2.0-next.3", + "@angular/ng-dev": "https://github.com/angular/dev-infra-private-ng-dev-builds.git#beec8fe17573a33c9934487ce99ce9cce3e3f6bf", + "@angular/platform-browser": "22.2.0-next.4", + "@angular/platform-server": "22.2.0-next.4", + "@angular/router": "22.2.0-next.4", + "@angular/service-worker": "22.2.0-next.4", "@babel/core": "8.0.1", "@bazel/bazelisk": "1.28.1", "@bazel/buildifier": "8.2.1", diff --git a/packages/angular/build/package.json b/packages/angular/build/package.json index 906505b51f86..54268c4c7df5 100644 --- a/packages/angular/build/package.json +++ b/packages/angular/build/package.json @@ -56,7 +56,7 @@ "istanbul-lib-instrument": "6.0.3", "jsdom": "30.0.1", "less": "4.9.0", - "ng-packagr": "22.2.0-next.3", + "ng-packagr": "22.2.0-next.4", "postcss": "8.5.26", "rollup": "4.63.0", "rxjs": "7.8.2", diff --git a/packages/angular/ssr/package.json b/packages/angular/ssr/package.json index 96800a3e72e4..e832d63a1883 100644 --- a/packages/angular/ssr/package.json +++ b/packages/angular/ssr/package.json @@ -37,12 +37,12 @@ }, "devDependencies": { "@angular-devkit/schematics": "workspace:*", - "@angular/common": "22.2.0-next.3", - "@angular/compiler": "22.2.0-next.3", - "@angular/core": "22.2.0-next.3", - "@angular/platform-browser": "22.2.0-next.3", - "@angular/platform-server": "22.2.0-next.3", - "@angular/router": "22.2.0-next.3", + "@angular/common": "22.2.0-next.4", + "@angular/compiler": "22.2.0-next.4", + "@angular/core": "22.2.0-next.4", + "@angular/platform-browser": "22.2.0-next.4", + "@angular/platform-server": "22.2.0-next.4", + "@angular/router": "22.2.0-next.4", "@schematics/angular": "workspace:*", "beasties": "0.4.3" }, diff --git a/packages/angular_devkit/build_angular/package.json b/packages/angular_devkit/build_angular/package.json index bdd784c01bf1..ba718f28cd5e 100644 --- a/packages/angular_devkit/build_angular/package.json +++ b/packages/angular_devkit/build_angular/package.json @@ -66,7 +66,7 @@ "devDependencies": { "@angular/ssr": "workspace:*", "browser-sync": "3.0.4", - "ng-packagr": "22.2.0-next.3", + "ng-packagr": "22.2.0-next.4", "undici": "8.10.0" }, "peerDependencies": { diff --git a/packages/ngtools/webpack/package.json b/packages/ngtools/webpack/package.json index 7713b54577bb..b9268a8b4fbb 100644 --- a/packages/ngtools/webpack/package.json +++ b/packages/ngtools/webpack/package.json @@ -17,8 +17,8 @@ }, "devDependencies": { "@angular-devkit/core": "workspace:0.0.0-PLACEHOLDER", - "@angular/compiler": "22.2.0-next.3", - "@angular/compiler-cli": "22.2.0-next.3", + "@angular/compiler": "22.2.0-next.4", + "@angular/compiler-cli": "22.2.0-next.4", "typescript": "6.0.3", "webpack": "5.109.2" } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index f3b55cb8ec6e..6a0dd2e5c007 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -14,8 +14,8 @@ importers: .: dependencies: '@angular/compiler-cli': - specifier: 22.2.0-next.3 - version: 22.2.0-next.3(@angular/compiler@22.2.0-next.3)(typescript@6.0.3) + specifier: 22.2.0-next.4 + version: 22.2.0-next.4(@angular/compiler@22.2.0-next.4)(typescript@6.0.3) typescript: specifier: 6.0.3 version: 6.0.3 @@ -26,44 +26,44 @@ importers: built: true devDependencies: '@angular/animations': - specifier: 22.2.0-next.3 - version: 22.2.0-next.3(@angular/core@22.2.0-next.3(@angular/compiler@22.2.0-next.3)(rxjs@7.8.2)(zone.js@0.16.2)) + specifier: 22.2.0-next.4 + version: 22.2.0-next.4(@angular/core@22.2.0-next.4(@angular/compiler@22.2.0-next.4)(rxjs@7.8.2)(zone.js@0.16.2)) '@angular/cdk': - specifier: 22.2.0-next.2 - version: 22.2.0-next.2(@angular/common@22.2.0-next.3(@angular/core@22.2.0-next.3(@angular/compiler@22.2.0-next.3)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2))(@angular/core@22.2.0-next.3(@angular/compiler@22.2.0-next.3)(rxjs@7.8.2)(zone.js@0.16.2))(@angular/platform-browser@22.2.0-next.3(@angular/animations@22.2.0-next.3(@angular/core@22.2.0-next.3(@angular/compiler@22.2.0-next.3)(rxjs@7.8.2)(zone.js@0.16.2)))(@angular/common@22.2.0-next.3(@angular/core@22.2.0-next.3(@angular/compiler@22.2.0-next.3)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2))(@angular/core@22.2.0-next.3(@angular/compiler@22.2.0-next.3)(rxjs@7.8.2)(zone.js@0.16.2)))(rxjs@7.8.2) - '@angular/common': specifier: 22.2.0-next.3 - version: 22.2.0-next.3(@angular/core@22.2.0-next.3(@angular/compiler@22.2.0-next.3)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2) + version: 22.2.0-next.3(@angular/common@22.2.0-next.4(@angular/core@22.2.0-next.4(@angular/compiler@22.2.0-next.4)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2))(@angular/core@22.2.0-next.4(@angular/compiler@22.2.0-next.4)(rxjs@7.8.2)(zone.js@0.16.2))(@angular/platform-browser@22.2.0-next.4(@angular/animations@22.2.0-next.4(@angular/core@22.2.0-next.4(@angular/compiler@22.2.0-next.4)(rxjs@7.8.2)(zone.js@0.16.2)))(@angular/common@22.2.0-next.4(@angular/core@22.2.0-next.4(@angular/compiler@22.2.0-next.4)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2))(@angular/core@22.2.0-next.4(@angular/compiler@22.2.0-next.4)(rxjs@7.8.2)(zone.js@0.16.2)))(rxjs@7.8.2) + '@angular/common': + specifier: 22.2.0-next.4 + version: 22.2.0-next.4(@angular/core@22.2.0-next.4(@angular/compiler@22.2.0-next.4)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2) '@angular/compiler': - specifier: 22.2.0-next.3 - version: 22.2.0-next.3 + specifier: 22.2.0-next.4 + version: 22.2.0-next.4 '@angular/core': - specifier: 22.2.0-next.3 - version: 22.2.0-next.3(@angular/compiler@22.2.0-next.3)(rxjs@7.8.2)(zone.js@0.16.2) + specifier: 22.2.0-next.4 + version: 22.2.0-next.4(@angular/compiler@22.2.0-next.4)(rxjs@7.8.2)(zone.js@0.16.2) '@angular/forms': - specifier: 22.2.0-next.3 - version: 22.2.0-next.3(@angular/common@22.2.0-next.3(@angular/core@22.2.0-next.3(@angular/compiler@22.2.0-next.3)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2))(@angular/core@22.2.0-next.3(@angular/compiler@22.2.0-next.3)(rxjs@7.8.2)(zone.js@0.16.2))(@angular/platform-browser@22.2.0-next.3(@angular/animations@22.2.0-next.3(@angular/core@22.2.0-next.3(@angular/compiler@22.2.0-next.3)(rxjs@7.8.2)(zone.js@0.16.2)))(@angular/common@22.2.0-next.3(@angular/core@22.2.0-next.3(@angular/compiler@22.2.0-next.3)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2))(@angular/core@22.2.0-next.3(@angular/compiler@22.2.0-next.3)(rxjs@7.8.2)(zone.js@0.16.2)))(rxjs@7.8.2) + specifier: 22.2.0-next.4 + version: 22.2.0-next.4(@angular/common@22.2.0-next.4(@angular/core@22.2.0-next.4(@angular/compiler@22.2.0-next.4)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2))(@angular/core@22.2.0-next.4(@angular/compiler@22.2.0-next.4)(rxjs@7.8.2)(zone.js@0.16.2))(@angular/platform-browser@22.2.0-next.4(@angular/animations@22.2.0-next.4(@angular/core@22.2.0-next.4(@angular/compiler@22.2.0-next.4)(rxjs@7.8.2)(zone.js@0.16.2)))(@angular/common@22.2.0-next.4(@angular/core@22.2.0-next.4(@angular/compiler@22.2.0-next.4)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2))(@angular/core@22.2.0-next.4(@angular/compiler@22.2.0-next.4)(rxjs@7.8.2)(zone.js@0.16.2)))(rxjs@7.8.2) '@angular/localize': - specifier: 22.2.0-next.3 - version: 22.2.0-next.3(@angular/compiler-cli@22.2.0-next.3(@angular/compiler@22.2.0-next.3)(typescript@6.0.3))(@angular/compiler@22.2.0-next.3) + specifier: 22.2.0-next.4 + version: 22.2.0-next.4(@angular/compiler-cli@22.2.0-next.4(@angular/compiler@22.2.0-next.4)(typescript@6.0.3))(@angular/compiler@22.2.0-next.4) '@angular/material': - specifier: 22.2.0-next.2 - version: 22.2.0-next.2(d4251d47b7bf7d31284dc64d049d8a95) + specifier: 22.2.0-next.3 + version: 22.2.0-next.3(2d3d12f5adbcb81bda5dafdebadbbaef) '@angular/ng-dev': - specifier: https://github.com/angular/dev-infra-private-ng-dev-builds.git#bcad06e14cb29b52b0856020af5e2ab868075602 - version: https://codeload.github.com/angular/dev-infra-private-ng-dev-builds/tar.gz/bcad06e14cb29b52b0856020af5e2ab868075602 + specifier: https://github.com/angular/dev-infra-private-ng-dev-builds.git#beec8fe17573a33c9934487ce99ce9cce3e3f6bf + version: https://codeload.github.com/angular/dev-infra-private-ng-dev-builds/tar.gz/beec8fe17573a33c9934487ce99ce9cce3e3f6bf '@angular/platform-browser': - specifier: 22.2.0-next.3 - version: 22.2.0-next.3(@angular/animations@22.2.0-next.3(@angular/core@22.2.0-next.3(@angular/compiler@22.2.0-next.3)(rxjs@7.8.2)(zone.js@0.16.2)))(@angular/common@22.2.0-next.3(@angular/core@22.2.0-next.3(@angular/compiler@22.2.0-next.3)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2))(@angular/core@22.2.0-next.3(@angular/compiler@22.2.0-next.3)(rxjs@7.8.2)(zone.js@0.16.2)) + specifier: 22.2.0-next.4 + version: 22.2.0-next.4(@angular/animations@22.2.0-next.4(@angular/core@22.2.0-next.4(@angular/compiler@22.2.0-next.4)(rxjs@7.8.2)(zone.js@0.16.2)))(@angular/common@22.2.0-next.4(@angular/core@22.2.0-next.4(@angular/compiler@22.2.0-next.4)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2))(@angular/core@22.2.0-next.4(@angular/compiler@22.2.0-next.4)(rxjs@7.8.2)(zone.js@0.16.2)) '@angular/platform-server': - specifier: 22.2.0-next.3 - version: 22.2.0-next.3(@angular/common@22.2.0-next.3(@angular/core@22.2.0-next.3(@angular/compiler@22.2.0-next.3)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2))(@angular/compiler@22.2.0-next.3)(@angular/core@22.2.0-next.3(@angular/compiler@22.2.0-next.3)(rxjs@7.8.2)(zone.js@0.16.2))(@angular/platform-browser@22.2.0-next.3(@angular/animations@22.2.0-next.3(@angular/core@22.2.0-next.3(@angular/compiler@22.2.0-next.3)(rxjs@7.8.2)(zone.js@0.16.2)))(@angular/common@22.2.0-next.3(@angular/core@22.2.0-next.3(@angular/compiler@22.2.0-next.3)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2))(@angular/core@22.2.0-next.3(@angular/compiler@22.2.0-next.3)(rxjs@7.8.2)(zone.js@0.16.2)))(rxjs@7.8.2) + specifier: 22.2.0-next.4 + version: 22.2.0-next.4(@angular/common@22.2.0-next.4(@angular/core@22.2.0-next.4(@angular/compiler@22.2.0-next.4)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2))(@angular/compiler@22.2.0-next.4)(@angular/core@22.2.0-next.4(@angular/compiler@22.2.0-next.4)(rxjs@7.8.2)(zone.js@0.16.2))(@angular/platform-browser@22.2.0-next.4(@angular/animations@22.2.0-next.4(@angular/core@22.2.0-next.4(@angular/compiler@22.2.0-next.4)(rxjs@7.8.2)(zone.js@0.16.2)))(@angular/common@22.2.0-next.4(@angular/core@22.2.0-next.4(@angular/compiler@22.2.0-next.4)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2))(@angular/core@22.2.0-next.4(@angular/compiler@22.2.0-next.4)(rxjs@7.8.2)(zone.js@0.16.2)))(rxjs@7.8.2) '@angular/router': - specifier: 22.2.0-next.3 - version: 22.2.0-next.3(@angular/common@22.2.0-next.3(@angular/core@22.2.0-next.3(@angular/compiler@22.2.0-next.3)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2))(@angular/core@22.2.0-next.3(@angular/compiler@22.2.0-next.3)(rxjs@7.8.2)(zone.js@0.16.2))(@angular/platform-browser@22.2.0-next.3(@angular/animations@22.2.0-next.3(@angular/core@22.2.0-next.3(@angular/compiler@22.2.0-next.3)(rxjs@7.8.2)(zone.js@0.16.2)))(@angular/common@22.2.0-next.3(@angular/core@22.2.0-next.3(@angular/compiler@22.2.0-next.3)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2))(@angular/core@22.2.0-next.3(@angular/compiler@22.2.0-next.3)(rxjs@7.8.2)(zone.js@0.16.2)))(rxjs@7.8.2) + specifier: 22.2.0-next.4 + version: 22.2.0-next.4(@angular/common@22.2.0-next.4(@angular/core@22.2.0-next.4(@angular/compiler@22.2.0-next.4)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2))(@angular/core@22.2.0-next.4(@angular/compiler@22.2.0-next.4)(rxjs@7.8.2)(zone.js@0.16.2))(@angular/platform-browser@22.2.0-next.4(@angular/animations@22.2.0-next.4(@angular/core@22.2.0-next.4(@angular/compiler@22.2.0-next.4)(rxjs@7.8.2)(zone.js@0.16.2)))(@angular/common@22.2.0-next.4(@angular/core@22.2.0-next.4(@angular/compiler@22.2.0-next.4)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2))(@angular/core@22.2.0-next.4(@angular/compiler@22.2.0-next.4)(rxjs@7.8.2)(zone.js@0.16.2)))(rxjs@7.8.2) '@angular/service-worker': - specifier: 22.2.0-next.3 - version: 22.2.0-next.3(@angular/core@22.2.0-next.3(@angular/compiler@22.2.0-next.3)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2) + specifier: 22.2.0-next.4 + version: 22.2.0-next.4(@angular/core@22.2.0-next.4(@angular/compiler@22.2.0-next.4)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2) '@babel/core': specifier: 8.0.1 version: 8.0.1 @@ -314,8 +314,8 @@ importers: specifier: 30.0.1 version: 30.0.1 ng-packagr: - specifier: 22.2.0-next.3 - version: 22.2.0-next.3(@angular/compiler-cli@22.2.0-next.3(@angular/compiler@22.2.0-next.3)(typescript@6.0.3))(supports-color@11.0.0)(tslib@2.8.1)(typescript@6.0.3) + specifier: 22.2.0-next.4 + version: 22.2.0-next.4(@angular/compiler-cli@22.2.0-next.4(@angular/compiler@22.2.0-next.4)(typescript@6.0.3))(supports-color@11.0.0)(tslib@2.8.1)(typescript@6.0.3) rxjs: specifier: 7.8.2 version: 7.8.2 @@ -426,8 +426,8 @@ importers: specifier: 4.9.0 version: 4.9.0(supports-color@11.0.0) ng-packagr: - specifier: 22.2.0-next.3 - version: 22.2.0-next.3(@angular/compiler-cli@22.2.0-next.3(@angular/compiler@22.2.0-next.3)(typescript@6.0.3))(supports-color@11.0.0)(tslib@2.8.1)(typescript@6.0.3) + specifier: 22.2.0-next.4 + version: 22.2.0-next.4(@angular/compiler-cli@22.2.0-next.4(@angular/compiler@22.2.0-next.4)(typescript@6.0.3))(supports-color@11.0.0)(tslib@2.8.1)(typescript@6.0.3) postcss: specifier: 8.5.26 version: 8.5.26 @@ -512,23 +512,23 @@ importers: specifier: workspace:* version: link:../../angular_devkit/schematics '@angular/common': - specifier: 22.2.0-next.3 - version: 22.2.0-next.3(@angular/core@22.2.0-next.3(@angular/compiler@22.2.0-next.3)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2) + specifier: 22.2.0-next.4 + version: 22.2.0-next.4(@angular/core@22.2.0-next.4(@angular/compiler@22.2.0-next.4)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2) '@angular/compiler': - specifier: 22.2.0-next.3 - version: 22.2.0-next.3 + specifier: 22.2.0-next.4 + version: 22.2.0-next.4 '@angular/core': - specifier: 22.2.0-next.3 - version: 22.2.0-next.3(@angular/compiler@22.2.0-next.3)(rxjs@7.8.2)(zone.js@0.16.2) + specifier: 22.2.0-next.4 + version: 22.2.0-next.4(@angular/compiler@22.2.0-next.4)(rxjs@7.8.2)(zone.js@0.16.2) '@angular/platform-browser': - specifier: 22.2.0-next.3 - version: 22.2.0-next.3(@angular/animations@22.2.0-next.3(@angular/core@22.2.0-next.3(@angular/compiler@22.2.0-next.3)(rxjs@7.8.2)(zone.js@0.16.2)))(@angular/common@22.2.0-next.3(@angular/core@22.2.0-next.3(@angular/compiler@22.2.0-next.3)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2))(@angular/core@22.2.0-next.3(@angular/compiler@22.2.0-next.3)(rxjs@7.8.2)(zone.js@0.16.2)) + specifier: 22.2.0-next.4 + version: 22.2.0-next.4(@angular/animations@22.2.0-next.4(@angular/core@22.2.0-next.4(@angular/compiler@22.2.0-next.4)(rxjs@7.8.2)(zone.js@0.16.2)))(@angular/common@22.2.0-next.4(@angular/core@22.2.0-next.4(@angular/compiler@22.2.0-next.4)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2))(@angular/core@22.2.0-next.4(@angular/compiler@22.2.0-next.4)(rxjs@7.8.2)(zone.js@0.16.2)) '@angular/platform-server': - specifier: 22.2.0-next.3 - version: 22.2.0-next.3(@angular/common@22.2.0-next.3(@angular/core@22.2.0-next.3(@angular/compiler@22.2.0-next.3)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2))(@angular/compiler@22.2.0-next.3)(@angular/core@22.2.0-next.3(@angular/compiler@22.2.0-next.3)(rxjs@7.8.2)(zone.js@0.16.2))(@angular/platform-browser@22.2.0-next.3(@angular/animations@22.2.0-next.3(@angular/core@22.2.0-next.3(@angular/compiler@22.2.0-next.3)(rxjs@7.8.2)(zone.js@0.16.2)))(@angular/common@22.2.0-next.3(@angular/core@22.2.0-next.3(@angular/compiler@22.2.0-next.3)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2))(@angular/core@22.2.0-next.3(@angular/compiler@22.2.0-next.3)(rxjs@7.8.2)(zone.js@0.16.2)))(rxjs@7.8.2) + specifier: 22.2.0-next.4 + version: 22.2.0-next.4(@angular/common@22.2.0-next.4(@angular/core@22.2.0-next.4(@angular/compiler@22.2.0-next.4)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2))(@angular/compiler@22.2.0-next.4)(@angular/core@22.2.0-next.4(@angular/compiler@22.2.0-next.4)(rxjs@7.8.2)(zone.js@0.16.2))(@angular/platform-browser@22.2.0-next.4(@angular/animations@22.2.0-next.4(@angular/core@22.2.0-next.4(@angular/compiler@22.2.0-next.4)(rxjs@7.8.2)(zone.js@0.16.2)))(@angular/common@22.2.0-next.4(@angular/core@22.2.0-next.4(@angular/compiler@22.2.0-next.4)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2))(@angular/core@22.2.0-next.4(@angular/compiler@22.2.0-next.4)(rxjs@7.8.2)(zone.js@0.16.2)))(rxjs@7.8.2) '@angular/router': - specifier: 22.2.0-next.3 - version: 22.2.0-next.3(@angular/common@22.2.0-next.3(@angular/core@22.2.0-next.3(@angular/compiler@22.2.0-next.3)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2))(@angular/core@22.2.0-next.3(@angular/compiler@22.2.0-next.3)(rxjs@7.8.2)(zone.js@0.16.2))(@angular/platform-browser@22.2.0-next.3(@angular/animations@22.2.0-next.3(@angular/core@22.2.0-next.3(@angular/compiler@22.2.0-next.3)(rxjs@7.8.2)(zone.js@0.16.2)))(@angular/common@22.2.0-next.3(@angular/core@22.2.0-next.3(@angular/compiler@22.2.0-next.3)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2))(@angular/core@22.2.0-next.3(@angular/compiler@22.2.0-next.3)(rxjs@7.8.2)(zone.js@0.16.2)))(rxjs@7.8.2) + specifier: 22.2.0-next.4 + version: 22.2.0-next.4(@angular/common@22.2.0-next.4(@angular/core@22.2.0-next.4(@angular/compiler@22.2.0-next.4)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2))(@angular/core@22.2.0-next.4(@angular/compiler@22.2.0-next.4)(rxjs@7.8.2)(zone.js@0.16.2))(@angular/platform-browser@22.2.0-next.4(@angular/animations@22.2.0-next.4(@angular/core@22.2.0-next.4(@angular/compiler@22.2.0-next.4)(rxjs@7.8.2)(zone.js@0.16.2)))(@angular/common@22.2.0-next.4(@angular/core@22.2.0-next.4(@angular/compiler@22.2.0-next.4)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2))(@angular/core@22.2.0-next.4(@angular/compiler@22.2.0-next.4)(rxjs@7.8.2)(zone.js@0.16.2)))(rxjs@7.8.2) '@schematics/angular': specifier: workspace:* version: link:../../schematics/angular @@ -714,8 +714,8 @@ importers: specifier: 3.0.4 version: 3.0.4(bufferutil@4.1.0)(debug@4.4.3(supports-color@11.0.0))(supports-color@11.0.0)(utf-8-validate@6.0.6) ng-packagr: - specifier: 22.2.0-next.3 - version: 22.2.0-next.3(@angular/compiler-cli@22.2.0-next.3(@angular/compiler@22.2.0-next.3)(typescript@6.0.3))(supports-color@11.0.0)(tslib@2.8.1)(typescript@6.0.3) + specifier: 22.2.0-next.4 + version: 22.2.0-next.4(@angular/compiler-cli@22.2.0-next.4(@angular/compiler@22.2.0-next.4)(typescript@6.0.3))(supports-color@11.0.0)(tslib@2.8.1)(typescript@6.0.3) undici: specifier: 8.10.0 version: 8.10.0 @@ -807,11 +807,11 @@ importers: specifier: workspace:0.0.0-PLACEHOLDER version: link:../../angular_devkit/core '@angular/compiler': - specifier: 22.2.0-next.3 - version: 22.2.0-next.3 + specifier: 22.2.0-next.4 + version: 22.2.0-next.4 '@angular/compiler-cli': - specifier: 22.2.0-next.3 - version: 22.2.0-next.3(@angular/compiler@22.2.0-next.3)(typescript@6.0.3) + specifier: 22.2.0-next.4 + version: 22.2.0-next.4(@angular/compiler@22.2.0-next.4)(typescript@6.0.3) typescript: specifier: 6.0.3 version: 6.0.3 @@ -864,48 +864,47 @@ packages: resolution: {integrity: sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==} engines: {node: '>=6.0.0'} - '@angular/animations@22.2.0-next.3': - resolution: {integrity: sha512-6NvI3B8d8d9XbZi2gMRwY+eBthu62uW8Gi5CHBSShlDmJc8KfYItPgVOXYYNL9im0jN1tReFiwHV4sds5vlgZA==} + '@angular/animations@22.2.0-next.4': + resolution: {integrity: sha512-pNbEIjYL4v8uhHUhZX7MYLqFT/L6JChJN1QsWI6wpjgq92hu0TTAy7IdpzrQlB4R9yEjfiygfTEzmwQS+gfXBw==} engines: {node: ^22.22.3 || ^24.15.0 || >=26.0.0} - deprecated: '@angular/animations is deprecated. Use `animate.enter` and `animate.leave` instead. For more information see: https://v22.angular.dev/guide/animations.' peerDependencies: - '@angular/core': 22.2.0-next.3 + '@angular/core': 22.2.0-next.4 - '@angular/cdk@22.2.0-next.2': - resolution: {integrity: sha512-oe+Hf5h527tGQvjZMA6REkV9tuRW4WWNC9KM03AdQxHo8Kz19a4UqIExmFLKuFDjJqtZ45QA4AfeegD0mLeNOA==} + '@angular/cdk@22.2.0-next.3': + resolution: {integrity: sha512-rdba75nOYip4YLBjeocti4YMFQvvso87FEstH0qegQRuhaRo0KvTc+midQX2G73DFnhkyCR0H48TwqCSzl59Bw==} peerDependencies: '@angular/common': ^22.0.0-0 || ^22.1.0-0 || ^22.2.0-0 || ^22.3.0-0 || ^23.0.0-0 '@angular/core': ^22.0.0-0 || ^22.1.0-0 || ^22.2.0-0 || ^22.3.0-0 || ^23.0.0-0 '@angular/platform-browser': ^22.0.0-0 || ^22.1.0-0 || ^22.2.0-0 || ^22.3.0-0 || ^23.0.0-0 rxjs: ^6.5.3 || ^7.4.0 - '@angular/common@22.2.0-next.3': - resolution: {integrity: sha512-nX8hky9OuLeL7ar3OOCWaSmlWiBcDHfGvc8idsFohLNwjc5y/0KrGvR5zP6Z9HCUoxEQUeTJOaUGxY6U4209BQ==} + '@angular/common@22.2.0-next.4': + resolution: {integrity: sha512-dXSVRdeDf6ZoRkTpBcynDnhcqrZh+EpuxjeVFh/jwvaHVLuNhhrBefQScQKyWnjf5dZPoholwJVJpb7du4CCCw==} engines: {node: ^22.22.3 || ^24.15.0 || >=26.0.0} peerDependencies: - '@angular/core': 22.2.0-next.3 + '@angular/core': 22.2.0-next.4 rxjs: ^6.5.3 || ^7.4.0 - '@angular/compiler-cli@22.2.0-next.3': - resolution: {integrity: sha512-CuguonGetrbI5Ru1A/kCWJH9d4kHIo1vaMRh9mrfgO9qsS9q3MqgEcyPCYuNqKmi+oJQloD7tyK+oaFHgnWcCQ==} + '@angular/compiler-cli@22.2.0-next.4': + resolution: {integrity: sha512-0FiX8UXSRuKRl73XlDryOi7y2IETyIZfQ8+1O1oEpcut8BTRE8kLl42ZHZ7uSSBskh4i5wOMj6frNFRNooredw==} engines: {node: ^22.22.3 || ^24.15.0 || >=26.0.0} hasBin: true peerDependencies: - '@angular/compiler': 22.2.0-next.3 + '@angular/compiler': 22.2.0-next.4 typescript: '>=6.0 <6.1' peerDependenciesMeta: typescript: optional: true - '@angular/compiler@22.2.0-next.3': - resolution: {integrity: sha512-RdgU10sRXVPMGwEWVcmRcZbmlKXUwtFhc3yqEJwT1ZCCP9MQFQjz8YWy0l+yc8SMYfxVH77gQgiHaWyvtvvEdw==} + '@angular/compiler@22.2.0-next.4': + resolution: {integrity: sha512-vrXeT/lit44PoudhDFlw4qfYM2qlhMX/Db20EozxJACQrhK7RA6KFLfl4HgyPKopJ93b9/3uFT4O7VMsV8ngxg==} engines: {node: ^22.22.3 || ^24.15.0 || >=26.0.0} - '@angular/core@22.2.0-next.3': - resolution: {integrity: sha512-C8IkKl58XblpONZwZoSkOkmX1c1sM9xLZSthpKzFiVnyA0ua2Ci7sVRSxPAAPaU9fKxYMUJ24w1Z+iJB7rU0yw==} + '@angular/core@22.2.0-next.4': + resolution: {integrity: sha512-fkIhSgLg41rKMMBLiZ+jy3AA3jEPKE++LCqGZzXKy3nHRbLxhA9lHYWonVvZav4+/zT1Plxh5hFoeSuPBMcghw==} engines: {node: ^22.22.3 || ^24.15.0 || >=26.0.0} peerDependencies: - '@angular/compiler': 22.2.0-next.3 + '@angular/compiler': 22.2.0-next.4 rxjs: ^6.5.3 || ^7.4.0 zone.js: ~0.15.0 || ~0.16.0 peerDependenciesMeta: @@ -914,74 +913,74 @@ packages: zone.js: optional: true - '@angular/forms@22.2.0-next.3': - resolution: {integrity: sha512-2ap4X3Ym89YflGgCR20ULFFI93zOOydUeCAP8ng0wxO7l0rjLjP+iDHP5RnD2izCphDdmHeQ6JSnOm4YA06gJQ==} + '@angular/forms@22.2.0-next.4': + resolution: {integrity: sha512-IF2HZ93j0HyAABZ60hG0iKHc4pvb26sEnZUcy6yvxhz5otWFUAUFNVliWRZurgrJvAeAvRY7RrTC2iE5iVnZvA==} engines: {node: ^22.22.3 || ^24.15.0 || >=26.0.0} peerDependencies: - '@angular/common': 22.2.0-next.3 - '@angular/core': 22.2.0-next.3 - '@angular/platform-browser': 22.2.0-next.3 + '@angular/common': 22.2.0-next.4 + '@angular/core': 22.2.0-next.4 + '@angular/platform-browser': 22.2.0-next.4 rxjs: ^6.5.3 || ^7.4.0 - '@angular/localize@22.2.0-next.3': - resolution: {integrity: sha512-avaS0gRjyOXYppPqZcmQCaN82rGH/8dLIdA8bCyUsn6uGX3kCYuHCZHzyozwUiQErbkb4oQpygk6hDp9+sKubw==} + '@angular/localize@22.2.0-next.4': + resolution: {integrity: sha512-smom8errFhBOsTCzqPTB139DF0qHglJektQuUy8vnzOSayLPcsGFyCP7aivakKZfAL5+DnYbBeDxmrPr88tOjA==} engines: {node: ^22.22.3 || ^24.15.0 || >=26.0.0} hasBin: true peerDependencies: - '@angular/compiler': 22.2.0-next.3 - '@angular/compiler-cli': 22.2.0-next.3 + '@angular/compiler': 22.2.0-next.4 + '@angular/compiler-cli': 22.2.0-next.4 - '@angular/material@22.2.0-next.2': - resolution: {integrity: sha512-3OVQerQD4nQN6CyFepTAXOKMCTI5WOXwmvewMOV+VTkVLlGqFWEAMW4XG0bnaVdYWYtDD5mv4PT17mNfhhElFA==} + '@angular/material@22.2.0-next.3': + resolution: {integrity: sha512-IO0O1nbCH7tz2qViPkDcPG2UHEXuO8Wighfw/FCkMHSXJrcVaFFML55ZNNKMNjJBIZ88M3v5fjibu/3yX7jE2A==} peerDependencies: - '@angular/cdk': 22.2.0-next.2 + '@angular/cdk': 22.2.0-next.3 '@angular/common': ^22.0.0-0 || ^22.1.0-0 || ^22.2.0-0 || ^22.3.0-0 || ^23.0.0-0 '@angular/core': ^22.0.0-0 || ^22.1.0-0 || ^22.2.0-0 || ^22.3.0-0 || ^23.0.0-0 '@angular/forms': ^22.0.0-0 || ^22.1.0-0 || ^22.2.0-0 || ^22.3.0-0 || ^23.0.0-0 '@angular/platform-browser': ^22.0.0-0 || ^22.1.0-0 || ^22.2.0-0 || ^22.3.0-0 || ^23.0.0-0 rxjs: ^6.5.3 || ^7.4.0 - '@angular/ng-dev@https://codeload.github.com/angular/dev-infra-private-ng-dev-builds/tar.gz/bcad06e14cb29b52b0856020af5e2ab868075602': - resolution: {gitHosted: true, integrity: sha512-fs92JkAu6Y2CXh1HEUDSTzgdVp12emRA/jEfoJG1d9V1t60tBZTsbnYyi3Zd8XkDy1Tu0l9Ne8xcHjQqwdhy8Q==, tarball: https://codeload.github.com/angular/dev-infra-private-ng-dev-builds/tar.gz/bcad06e14cb29b52b0856020af5e2ab868075602} - version: 0.0.0-6d918a6dd670e28afd4ba54d00b805d4aba43dca + '@angular/ng-dev@https://codeload.github.com/angular/dev-infra-private-ng-dev-builds/tar.gz/beec8fe17573a33c9934487ce99ce9cce3e3f6bf': + resolution: {gitHosted: true, integrity: sha512-ELGv/rsp5iaQw1+viAhn5IlLrodz7g7rPm6Ea06sEsBpQ2kSamcpZnXWf+j4SPzGvK+td+DtFCrgbkX+ihFiZQ==, tarball: https://codeload.github.com/angular/dev-infra-private-ng-dev-builds/tar.gz/beec8fe17573a33c9934487ce99ce9cce3e3f6bf} + version: 0.0.0-8fb164f40c9776c41771785c6d9facbd9ea63b73 hasBin: true - '@angular/platform-browser@22.2.0-next.3': - resolution: {integrity: sha512-oNIJ/MJehV86A/u+I6J1czCS4gLYOpnys2uujfXAalJHMjUViBoqjw8WnrFapV73XINbucA3B34x/pZlDWrg5A==} + '@angular/platform-browser@22.2.0-next.4': + resolution: {integrity: sha512-rr85FO4b4xAesiHJe8sZaNmx29ZrZgwcgu42eccDiHzFYK4+hl0i09aL6rIxG7ibjcetu85q3jVPqyMo4yZUvg==} engines: {node: ^22.22.3 || ^24.15.0 || >=26.0.0} peerDependencies: - '@angular/animations': 22.2.0-next.3 - '@angular/common': 22.2.0-next.3 - '@angular/core': 22.2.0-next.3 + '@angular/animations': 22.2.0-next.4 + '@angular/common': 22.2.0-next.4 + '@angular/core': 22.2.0-next.4 peerDependenciesMeta: '@angular/animations': optional: true - '@angular/platform-server@22.2.0-next.3': - resolution: {integrity: sha512-dkwIyC+U2MfYDkgUiFYFiUCwrO0d4jxwCZF5PoBSHF2SGMoS1Q+ciWB+Jm8GPPRbWX0FaRyEfugqHoFq/XMSkw==} + '@angular/platform-server@22.2.0-next.4': + resolution: {integrity: sha512-y9VMStVESPgWWjMMaAaG6HAF5UeWJF1T1wbQxfWyFRV80NWUtOEJgaUwIACgad/wm8JMxmA06xEQ3qpBwUNIZw==} engines: {node: ^22.22.3 || ^24.15.0 || >=26.0.0} peerDependencies: - '@angular/common': 22.2.0-next.3 - '@angular/compiler': 22.2.0-next.3 - '@angular/core': 22.2.0-next.3 - '@angular/platform-browser': 22.2.0-next.3 + '@angular/common': 22.2.0-next.4 + '@angular/compiler': 22.2.0-next.4 + '@angular/core': 22.2.0-next.4 + '@angular/platform-browser': 22.2.0-next.4 rxjs: ^6.5.3 || ^7.4.0 - '@angular/router@22.2.0-next.3': - resolution: {integrity: sha512-zmcJW9Z83FGWaEuOx9fJkdLWC5vaHropzZT1nFRu54LRXpj4/9+VZsoW5bTosxhP9wrgOGJWH+oqX/UkjFY0Wg==} + '@angular/router@22.2.0-next.4': + resolution: {integrity: sha512-uRxpJa+ELc3SwiyO1qtXpQeS2R0N3Pg4MJTwWCDbhttqLtaSdq/eIWlQaH2j5LWa5b2lb1lbdg2FnzdlEgA9ng==} engines: {node: ^22.22.3 || ^24.15.0 || >=26.0.0} peerDependencies: - '@angular/common': 22.2.0-next.3 - '@angular/core': 22.2.0-next.3 - '@angular/platform-browser': 22.2.0-next.3 + '@angular/common': 22.2.0-next.4 + '@angular/core': 22.2.0-next.4 + '@angular/platform-browser': 22.2.0-next.4 rxjs: ^6.5.3 || ^7.4.0 - '@angular/service-worker@22.2.0-next.3': - resolution: {integrity: sha512-TsVVyrV/uzsLE1espkFKQVqLubWuW1MDDmKBl567/ayGhs7ry8rLt19MvHubPbVRzDo0h3Pbx7/ddBf0i8apeg==} + '@angular/service-worker@22.2.0-next.4': + resolution: {integrity: sha512-9FQfLH0FarrqkBiL92Yq9eXEM9nRz9DgcZdCuHWY3YZ5uk2eZZel4gBRILS2hUGeesPpQG4nDf7+DJq0x7HEMQ==} engines: {node: ^22.22.3 || ^24.15.0 || >=26.0.0} hasBin: true peerDependencies: - '@angular/core': 22.2.0-next.3 + '@angular/core': 22.2.0-next.4 rxjs: ^6.5.3 || ^7.4.0 '@asamuzakjp/css-color@6.0.7': @@ -6591,8 +6590,8 @@ packages: neo-async@2.6.2: resolution: {integrity: sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==} - ng-packagr@22.2.0-next.3: - resolution: {integrity: sha512-bWjugQxxaZt1yWN/TxDCPbHwfuqHaAjD7blIZd7YDLAd32424JHWLFKqQwzi93NYYCUadSg8CU+LGiczZkuFsA==} + ng-packagr@22.2.0-next.4: + resolution: {integrity: sha512-wV+9/vPHP4ZmNraPgo5hH6qilZny6YgEwUt7j6N/3MGAxjQQRmc+FRp7ilQhioQht9jsddOLgSZqj9DYaYzigg==} engines: {node: ^22.22.3 || ^24.15.0 || >=26.0.0} hasBin: true peerDependencies: @@ -8522,29 +8521,29 @@ snapshots: '@jridgewell/gen-mapping': 0.3.13 '@jridgewell/trace-mapping': 0.3.31 - '@angular/animations@22.2.0-next.3(@angular/core@22.2.0-next.3(@angular/compiler@22.2.0-next.3)(rxjs@7.8.2)(zone.js@0.16.2))': + '@angular/animations@22.2.0-next.4(@angular/core@22.2.0-next.4(@angular/compiler@22.2.0-next.4)(rxjs@7.8.2)(zone.js@0.16.2))': dependencies: - '@angular/core': 22.2.0-next.3(@angular/compiler@22.2.0-next.3)(rxjs@7.8.2)(zone.js@0.16.2) + '@angular/core': 22.2.0-next.4(@angular/compiler@22.2.0-next.4)(rxjs@7.8.2)(zone.js@0.16.2) tslib: 2.8.1 - '@angular/cdk@22.2.0-next.2(@angular/common@22.2.0-next.3(@angular/core@22.2.0-next.3(@angular/compiler@22.2.0-next.3)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2))(@angular/core@22.2.0-next.3(@angular/compiler@22.2.0-next.3)(rxjs@7.8.2)(zone.js@0.16.2))(@angular/platform-browser@22.2.0-next.3(@angular/animations@22.2.0-next.3(@angular/core@22.2.0-next.3(@angular/compiler@22.2.0-next.3)(rxjs@7.8.2)(zone.js@0.16.2)))(@angular/common@22.2.0-next.3(@angular/core@22.2.0-next.3(@angular/compiler@22.2.0-next.3)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2))(@angular/core@22.2.0-next.3(@angular/compiler@22.2.0-next.3)(rxjs@7.8.2)(zone.js@0.16.2)))(rxjs@7.8.2)': + '@angular/cdk@22.2.0-next.3(@angular/common@22.2.0-next.4(@angular/core@22.2.0-next.4(@angular/compiler@22.2.0-next.4)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2))(@angular/core@22.2.0-next.4(@angular/compiler@22.2.0-next.4)(rxjs@7.8.2)(zone.js@0.16.2))(@angular/platform-browser@22.2.0-next.4(@angular/animations@22.2.0-next.4(@angular/core@22.2.0-next.4(@angular/compiler@22.2.0-next.4)(rxjs@7.8.2)(zone.js@0.16.2)))(@angular/common@22.2.0-next.4(@angular/core@22.2.0-next.4(@angular/compiler@22.2.0-next.4)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2))(@angular/core@22.2.0-next.4(@angular/compiler@22.2.0-next.4)(rxjs@7.8.2)(zone.js@0.16.2)))(rxjs@7.8.2)': dependencies: - '@angular/common': 22.2.0-next.3(@angular/core@22.2.0-next.3(@angular/compiler@22.2.0-next.3)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2) - '@angular/core': 22.2.0-next.3(@angular/compiler@22.2.0-next.3)(rxjs@7.8.2)(zone.js@0.16.2) - '@angular/platform-browser': 22.2.0-next.3(@angular/animations@22.2.0-next.3(@angular/core@22.2.0-next.3(@angular/compiler@22.2.0-next.3)(rxjs@7.8.2)(zone.js@0.16.2)))(@angular/common@22.2.0-next.3(@angular/core@22.2.0-next.3(@angular/compiler@22.2.0-next.3)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2))(@angular/core@22.2.0-next.3(@angular/compiler@22.2.0-next.3)(rxjs@7.8.2)(zone.js@0.16.2)) + '@angular/common': 22.2.0-next.4(@angular/core@22.2.0-next.4(@angular/compiler@22.2.0-next.4)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2) + '@angular/core': 22.2.0-next.4(@angular/compiler@22.2.0-next.4)(rxjs@7.8.2)(zone.js@0.16.2) + '@angular/platform-browser': 22.2.0-next.4(@angular/animations@22.2.0-next.4(@angular/core@22.2.0-next.4(@angular/compiler@22.2.0-next.4)(rxjs@7.8.2)(zone.js@0.16.2)))(@angular/common@22.2.0-next.4(@angular/core@22.2.0-next.4(@angular/compiler@22.2.0-next.4)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2))(@angular/core@22.2.0-next.4(@angular/compiler@22.2.0-next.4)(rxjs@7.8.2)(zone.js@0.16.2)) parse5: 8.0.1 rxjs: 7.8.2 tslib: 2.8.1 - '@angular/common@22.2.0-next.3(@angular/core@22.2.0-next.3(@angular/compiler@22.2.0-next.3)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2)': + '@angular/common@22.2.0-next.4(@angular/core@22.2.0-next.4(@angular/compiler@22.2.0-next.4)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2)': dependencies: - '@angular/core': 22.2.0-next.3(@angular/compiler@22.2.0-next.3)(rxjs@7.8.2)(zone.js@0.16.2) + '@angular/core': 22.2.0-next.4(@angular/compiler@22.2.0-next.4)(rxjs@7.8.2)(zone.js@0.16.2) rxjs: 7.8.2 tslib: 2.8.1 - '@angular/compiler-cli@22.2.0-next.3(@angular/compiler@22.2.0-next.3)(typescript@6.0.3)': + '@angular/compiler-cli@22.2.0-next.4(@angular/compiler@22.2.0-next.4)(typescript@6.0.3)': dependencies: - '@angular/compiler': 22.2.0-next.3 + '@angular/compiler': 22.2.0-next.4 '@babel/core': 8.0.1 '@jridgewell/sourcemap-codec': 1.5.5 chokidar: 5.0.0 @@ -8556,47 +8555,47 @@ snapshots: optionalDependencies: typescript: 6.0.3 - '@angular/compiler@22.2.0-next.3': + '@angular/compiler@22.2.0-next.4': dependencies: tslib: 2.8.1 - '@angular/core@22.2.0-next.3(@angular/compiler@22.2.0-next.3)(rxjs@7.8.2)(zone.js@0.16.2)': + '@angular/core@22.2.0-next.4(@angular/compiler@22.2.0-next.4)(rxjs@7.8.2)(zone.js@0.16.2)': dependencies: rxjs: 7.8.2 tslib: 2.8.1 optionalDependencies: - '@angular/compiler': 22.2.0-next.3 + '@angular/compiler': 22.2.0-next.4 zone.js: 0.16.2 - '@angular/forms@22.2.0-next.3(@angular/common@22.2.0-next.3(@angular/core@22.2.0-next.3(@angular/compiler@22.2.0-next.3)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2))(@angular/core@22.2.0-next.3(@angular/compiler@22.2.0-next.3)(rxjs@7.8.2)(zone.js@0.16.2))(@angular/platform-browser@22.2.0-next.3(@angular/animations@22.2.0-next.3(@angular/core@22.2.0-next.3(@angular/compiler@22.2.0-next.3)(rxjs@7.8.2)(zone.js@0.16.2)))(@angular/common@22.2.0-next.3(@angular/core@22.2.0-next.3(@angular/compiler@22.2.0-next.3)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2))(@angular/core@22.2.0-next.3(@angular/compiler@22.2.0-next.3)(rxjs@7.8.2)(zone.js@0.16.2)))(rxjs@7.8.2)': + '@angular/forms@22.2.0-next.4(@angular/common@22.2.0-next.4(@angular/core@22.2.0-next.4(@angular/compiler@22.2.0-next.4)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2))(@angular/core@22.2.0-next.4(@angular/compiler@22.2.0-next.4)(rxjs@7.8.2)(zone.js@0.16.2))(@angular/platform-browser@22.2.0-next.4(@angular/animations@22.2.0-next.4(@angular/core@22.2.0-next.4(@angular/compiler@22.2.0-next.4)(rxjs@7.8.2)(zone.js@0.16.2)))(@angular/common@22.2.0-next.4(@angular/core@22.2.0-next.4(@angular/compiler@22.2.0-next.4)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2))(@angular/core@22.2.0-next.4(@angular/compiler@22.2.0-next.4)(rxjs@7.8.2)(zone.js@0.16.2)))(rxjs@7.8.2)': dependencies: - '@angular/common': 22.2.0-next.3(@angular/core@22.2.0-next.3(@angular/compiler@22.2.0-next.3)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2) - '@angular/core': 22.2.0-next.3(@angular/compiler@22.2.0-next.3)(rxjs@7.8.2)(zone.js@0.16.2) - '@angular/platform-browser': 22.2.0-next.3(@angular/animations@22.2.0-next.3(@angular/core@22.2.0-next.3(@angular/compiler@22.2.0-next.3)(rxjs@7.8.2)(zone.js@0.16.2)))(@angular/common@22.2.0-next.3(@angular/core@22.2.0-next.3(@angular/compiler@22.2.0-next.3)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2))(@angular/core@22.2.0-next.3(@angular/compiler@22.2.0-next.3)(rxjs@7.8.2)(zone.js@0.16.2)) + '@angular/common': 22.2.0-next.4(@angular/core@22.2.0-next.4(@angular/compiler@22.2.0-next.4)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2) + '@angular/core': 22.2.0-next.4(@angular/compiler@22.2.0-next.4)(rxjs@7.8.2)(zone.js@0.16.2) + '@angular/platform-browser': 22.2.0-next.4(@angular/animations@22.2.0-next.4(@angular/core@22.2.0-next.4(@angular/compiler@22.2.0-next.4)(rxjs@7.8.2)(zone.js@0.16.2)))(@angular/common@22.2.0-next.4(@angular/core@22.2.0-next.4(@angular/compiler@22.2.0-next.4)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2))(@angular/core@22.2.0-next.4(@angular/compiler@22.2.0-next.4)(rxjs@7.8.2)(zone.js@0.16.2)) '@standard-schema/spec': 1.1.0 rxjs: 7.8.2 tslib: 2.8.1 zod: 4.4.3 - '@angular/localize@22.2.0-next.3(@angular/compiler-cli@22.2.0-next.3(@angular/compiler@22.2.0-next.3)(typescript@6.0.3))(@angular/compiler@22.2.0-next.3)': + '@angular/localize@22.2.0-next.4(@angular/compiler-cli@22.2.0-next.4(@angular/compiler@22.2.0-next.4)(typescript@6.0.3))(@angular/compiler@22.2.0-next.4)': dependencies: - '@angular/compiler': 22.2.0-next.3 - '@angular/compiler-cli': 22.2.0-next.3(@angular/compiler@22.2.0-next.3)(typescript@6.0.3) + '@angular/compiler': 22.2.0-next.4 + '@angular/compiler-cli': 22.2.0-next.4(@angular/compiler@22.2.0-next.4)(typescript@6.0.3) '@babel/core': 8.0.1 tinyglobby: 0.2.17 yargs: 18.1.0 - '@angular/material@22.2.0-next.2(d4251d47b7bf7d31284dc64d049d8a95)': + '@angular/material@22.2.0-next.3(2d3d12f5adbcb81bda5dafdebadbbaef)': dependencies: - '@angular/cdk': 22.2.0-next.2(@angular/common@22.2.0-next.3(@angular/core@22.2.0-next.3(@angular/compiler@22.2.0-next.3)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2))(@angular/core@22.2.0-next.3(@angular/compiler@22.2.0-next.3)(rxjs@7.8.2)(zone.js@0.16.2))(@angular/platform-browser@22.2.0-next.3(@angular/animations@22.2.0-next.3(@angular/core@22.2.0-next.3(@angular/compiler@22.2.0-next.3)(rxjs@7.8.2)(zone.js@0.16.2)))(@angular/common@22.2.0-next.3(@angular/core@22.2.0-next.3(@angular/compiler@22.2.0-next.3)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2))(@angular/core@22.2.0-next.3(@angular/compiler@22.2.0-next.3)(rxjs@7.8.2)(zone.js@0.16.2)))(rxjs@7.8.2) - '@angular/common': 22.2.0-next.3(@angular/core@22.2.0-next.3(@angular/compiler@22.2.0-next.3)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2) - '@angular/core': 22.2.0-next.3(@angular/compiler@22.2.0-next.3)(rxjs@7.8.2)(zone.js@0.16.2) - '@angular/forms': 22.2.0-next.3(@angular/common@22.2.0-next.3(@angular/core@22.2.0-next.3(@angular/compiler@22.2.0-next.3)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2))(@angular/core@22.2.0-next.3(@angular/compiler@22.2.0-next.3)(rxjs@7.8.2)(zone.js@0.16.2))(@angular/platform-browser@22.2.0-next.3(@angular/animations@22.2.0-next.3(@angular/core@22.2.0-next.3(@angular/compiler@22.2.0-next.3)(rxjs@7.8.2)(zone.js@0.16.2)))(@angular/common@22.2.0-next.3(@angular/core@22.2.0-next.3(@angular/compiler@22.2.0-next.3)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2))(@angular/core@22.2.0-next.3(@angular/compiler@22.2.0-next.3)(rxjs@7.8.2)(zone.js@0.16.2)))(rxjs@7.8.2) - '@angular/platform-browser': 22.2.0-next.3(@angular/animations@22.2.0-next.3(@angular/core@22.2.0-next.3(@angular/compiler@22.2.0-next.3)(rxjs@7.8.2)(zone.js@0.16.2)))(@angular/common@22.2.0-next.3(@angular/core@22.2.0-next.3(@angular/compiler@22.2.0-next.3)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2))(@angular/core@22.2.0-next.3(@angular/compiler@22.2.0-next.3)(rxjs@7.8.2)(zone.js@0.16.2)) + '@angular/cdk': 22.2.0-next.3(@angular/common@22.2.0-next.4(@angular/core@22.2.0-next.4(@angular/compiler@22.2.0-next.4)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2))(@angular/core@22.2.0-next.4(@angular/compiler@22.2.0-next.4)(rxjs@7.8.2)(zone.js@0.16.2))(@angular/platform-browser@22.2.0-next.4(@angular/animations@22.2.0-next.4(@angular/core@22.2.0-next.4(@angular/compiler@22.2.0-next.4)(rxjs@7.8.2)(zone.js@0.16.2)))(@angular/common@22.2.0-next.4(@angular/core@22.2.0-next.4(@angular/compiler@22.2.0-next.4)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2))(@angular/core@22.2.0-next.4(@angular/compiler@22.2.0-next.4)(rxjs@7.8.2)(zone.js@0.16.2)))(rxjs@7.8.2) + '@angular/common': 22.2.0-next.4(@angular/core@22.2.0-next.4(@angular/compiler@22.2.0-next.4)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2) + '@angular/core': 22.2.0-next.4(@angular/compiler@22.2.0-next.4)(rxjs@7.8.2)(zone.js@0.16.2) + '@angular/forms': 22.2.0-next.4(@angular/common@22.2.0-next.4(@angular/core@22.2.0-next.4(@angular/compiler@22.2.0-next.4)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2))(@angular/core@22.2.0-next.4(@angular/compiler@22.2.0-next.4)(rxjs@7.8.2)(zone.js@0.16.2))(@angular/platform-browser@22.2.0-next.4(@angular/animations@22.2.0-next.4(@angular/core@22.2.0-next.4(@angular/compiler@22.2.0-next.4)(rxjs@7.8.2)(zone.js@0.16.2)))(@angular/common@22.2.0-next.4(@angular/core@22.2.0-next.4(@angular/compiler@22.2.0-next.4)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2))(@angular/core@22.2.0-next.4(@angular/compiler@22.2.0-next.4)(rxjs@7.8.2)(zone.js@0.16.2)))(rxjs@7.8.2) + '@angular/platform-browser': 22.2.0-next.4(@angular/animations@22.2.0-next.4(@angular/core@22.2.0-next.4(@angular/compiler@22.2.0-next.4)(rxjs@7.8.2)(zone.js@0.16.2)))(@angular/common@22.2.0-next.4(@angular/core@22.2.0-next.4(@angular/compiler@22.2.0-next.4)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2))(@angular/core@22.2.0-next.4(@angular/compiler@22.2.0-next.4)(rxjs@7.8.2)(zone.js@0.16.2)) rxjs: 7.8.2 tslib: 2.8.1 - '@angular/ng-dev@https://codeload.github.com/angular/dev-infra-private-ng-dev-builds/tar.gz/bcad06e14cb29b52b0856020af5e2ab868075602': + '@angular/ng-dev@https://codeload.github.com/angular/dev-infra-private-ng-dev-builds/tar.gz/beec8fe17573a33c9934487ce99ce9cce3e3f6bf': dependencies: '@actions/core': 3.0.1 '@conventional-changelog/git-client': 3.1.2(conventional-commits-filter@6.0.1)(conventional-commits-parser@7.1.2) @@ -8656,35 +8655,35 @@ snapshots: - '@modelcontextprotocol/sdk' - '@react-native-async-storage/async-storage' - '@angular/platform-browser@22.2.0-next.3(@angular/animations@22.2.0-next.3(@angular/core@22.2.0-next.3(@angular/compiler@22.2.0-next.3)(rxjs@7.8.2)(zone.js@0.16.2)))(@angular/common@22.2.0-next.3(@angular/core@22.2.0-next.3(@angular/compiler@22.2.0-next.3)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2))(@angular/core@22.2.0-next.3(@angular/compiler@22.2.0-next.3)(rxjs@7.8.2)(zone.js@0.16.2))': + '@angular/platform-browser@22.2.0-next.4(@angular/animations@22.2.0-next.4(@angular/core@22.2.0-next.4(@angular/compiler@22.2.0-next.4)(rxjs@7.8.2)(zone.js@0.16.2)))(@angular/common@22.2.0-next.4(@angular/core@22.2.0-next.4(@angular/compiler@22.2.0-next.4)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2))(@angular/core@22.2.0-next.4(@angular/compiler@22.2.0-next.4)(rxjs@7.8.2)(zone.js@0.16.2))': dependencies: - '@angular/common': 22.2.0-next.3(@angular/core@22.2.0-next.3(@angular/compiler@22.2.0-next.3)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2) - '@angular/core': 22.2.0-next.3(@angular/compiler@22.2.0-next.3)(rxjs@7.8.2)(zone.js@0.16.2) + '@angular/common': 22.2.0-next.4(@angular/core@22.2.0-next.4(@angular/compiler@22.2.0-next.4)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2) + '@angular/core': 22.2.0-next.4(@angular/compiler@22.2.0-next.4)(rxjs@7.8.2)(zone.js@0.16.2) tslib: 2.8.1 optionalDependencies: - '@angular/animations': 22.2.0-next.3(@angular/core@22.2.0-next.3(@angular/compiler@22.2.0-next.3)(rxjs@7.8.2)(zone.js@0.16.2)) + '@angular/animations': 22.2.0-next.4(@angular/core@22.2.0-next.4(@angular/compiler@22.2.0-next.4)(rxjs@7.8.2)(zone.js@0.16.2)) - '@angular/platform-server@22.2.0-next.3(@angular/common@22.2.0-next.3(@angular/core@22.2.0-next.3(@angular/compiler@22.2.0-next.3)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2))(@angular/compiler@22.2.0-next.3)(@angular/core@22.2.0-next.3(@angular/compiler@22.2.0-next.3)(rxjs@7.8.2)(zone.js@0.16.2))(@angular/platform-browser@22.2.0-next.3(@angular/animations@22.2.0-next.3(@angular/core@22.2.0-next.3(@angular/compiler@22.2.0-next.3)(rxjs@7.8.2)(zone.js@0.16.2)))(@angular/common@22.2.0-next.3(@angular/core@22.2.0-next.3(@angular/compiler@22.2.0-next.3)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2))(@angular/core@22.2.0-next.3(@angular/compiler@22.2.0-next.3)(rxjs@7.8.2)(zone.js@0.16.2)))(rxjs@7.8.2)': + '@angular/platform-server@22.2.0-next.4(@angular/common@22.2.0-next.4(@angular/core@22.2.0-next.4(@angular/compiler@22.2.0-next.4)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2))(@angular/compiler@22.2.0-next.4)(@angular/core@22.2.0-next.4(@angular/compiler@22.2.0-next.4)(rxjs@7.8.2)(zone.js@0.16.2))(@angular/platform-browser@22.2.0-next.4(@angular/animations@22.2.0-next.4(@angular/core@22.2.0-next.4(@angular/compiler@22.2.0-next.4)(rxjs@7.8.2)(zone.js@0.16.2)))(@angular/common@22.2.0-next.4(@angular/core@22.2.0-next.4(@angular/compiler@22.2.0-next.4)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2))(@angular/core@22.2.0-next.4(@angular/compiler@22.2.0-next.4)(rxjs@7.8.2)(zone.js@0.16.2)))(rxjs@7.8.2)': dependencies: - '@angular/common': 22.2.0-next.3(@angular/core@22.2.0-next.3(@angular/compiler@22.2.0-next.3)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2) - '@angular/compiler': 22.2.0-next.3 - '@angular/core': 22.2.0-next.3(@angular/compiler@22.2.0-next.3)(rxjs@7.8.2)(zone.js@0.16.2) - '@angular/platform-browser': 22.2.0-next.3(@angular/animations@22.2.0-next.3(@angular/core@22.2.0-next.3(@angular/compiler@22.2.0-next.3)(rxjs@7.8.2)(zone.js@0.16.2)))(@angular/common@22.2.0-next.3(@angular/core@22.2.0-next.3(@angular/compiler@22.2.0-next.3)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2))(@angular/core@22.2.0-next.3(@angular/compiler@22.2.0-next.3)(rxjs@7.8.2)(zone.js@0.16.2)) + '@angular/common': 22.2.0-next.4(@angular/core@22.2.0-next.4(@angular/compiler@22.2.0-next.4)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2) + '@angular/compiler': 22.2.0-next.4 + '@angular/core': 22.2.0-next.4(@angular/compiler@22.2.0-next.4)(rxjs@7.8.2)(zone.js@0.16.2) + '@angular/platform-browser': 22.2.0-next.4(@angular/animations@22.2.0-next.4(@angular/core@22.2.0-next.4(@angular/compiler@22.2.0-next.4)(rxjs@7.8.2)(zone.js@0.16.2)))(@angular/common@22.2.0-next.4(@angular/core@22.2.0-next.4(@angular/compiler@22.2.0-next.4)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2))(@angular/core@22.2.0-next.4(@angular/compiler@22.2.0-next.4)(rxjs@7.8.2)(zone.js@0.16.2)) rxjs: 7.8.2 tslib: 2.8.1 xhr2: 0.2.1 - '@angular/router@22.2.0-next.3(@angular/common@22.2.0-next.3(@angular/core@22.2.0-next.3(@angular/compiler@22.2.0-next.3)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2))(@angular/core@22.2.0-next.3(@angular/compiler@22.2.0-next.3)(rxjs@7.8.2)(zone.js@0.16.2))(@angular/platform-browser@22.2.0-next.3(@angular/animations@22.2.0-next.3(@angular/core@22.2.0-next.3(@angular/compiler@22.2.0-next.3)(rxjs@7.8.2)(zone.js@0.16.2)))(@angular/common@22.2.0-next.3(@angular/core@22.2.0-next.3(@angular/compiler@22.2.0-next.3)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2))(@angular/core@22.2.0-next.3(@angular/compiler@22.2.0-next.3)(rxjs@7.8.2)(zone.js@0.16.2)))(rxjs@7.8.2)': + '@angular/router@22.2.0-next.4(@angular/common@22.2.0-next.4(@angular/core@22.2.0-next.4(@angular/compiler@22.2.0-next.4)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2))(@angular/core@22.2.0-next.4(@angular/compiler@22.2.0-next.4)(rxjs@7.8.2)(zone.js@0.16.2))(@angular/platform-browser@22.2.0-next.4(@angular/animations@22.2.0-next.4(@angular/core@22.2.0-next.4(@angular/compiler@22.2.0-next.4)(rxjs@7.8.2)(zone.js@0.16.2)))(@angular/common@22.2.0-next.4(@angular/core@22.2.0-next.4(@angular/compiler@22.2.0-next.4)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2))(@angular/core@22.2.0-next.4(@angular/compiler@22.2.0-next.4)(rxjs@7.8.2)(zone.js@0.16.2)))(rxjs@7.8.2)': dependencies: - '@angular/common': 22.2.0-next.3(@angular/core@22.2.0-next.3(@angular/compiler@22.2.0-next.3)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2) - '@angular/core': 22.2.0-next.3(@angular/compiler@22.2.0-next.3)(rxjs@7.8.2)(zone.js@0.16.2) - '@angular/platform-browser': 22.2.0-next.3(@angular/animations@22.2.0-next.3(@angular/core@22.2.0-next.3(@angular/compiler@22.2.0-next.3)(rxjs@7.8.2)(zone.js@0.16.2)))(@angular/common@22.2.0-next.3(@angular/core@22.2.0-next.3(@angular/compiler@22.2.0-next.3)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2))(@angular/core@22.2.0-next.3(@angular/compiler@22.2.0-next.3)(rxjs@7.8.2)(zone.js@0.16.2)) + '@angular/common': 22.2.0-next.4(@angular/core@22.2.0-next.4(@angular/compiler@22.2.0-next.4)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2) + '@angular/core': 22.2.0-next.4(@angular/compiler@22.2.0-next.4)(rxjs@7.8.2)(zone.js@0.16.2) + '@angular/platform-browser': 22.2.0-next.4(@angular/animations@22.2.0-next.4(@angular/core@22.2.0-next.4(@angular/compiler@22.2.0-next.4)(rxjs@7.8.2)(zone.js@0.16.2)))(@angular/common@22.2.0-next.4(@angular/core@22.2.0-next.4(@angular/compiler@22.2.0-next.4)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2))(@angular/core@22.2.0-next.4(@angular/compiler@22.2.0-next.4)(rxjs@7.8.2)(zone.js@0.16.2)) rxjs: 7.8.2 tslib: 2.8.1 - '@angular/service-worker@22.2.0-next.3(@angular/core@22.2.0-next.3(@angular/compiler@22.2.0-next.3)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2)': + '@angular/service-worker@22.2.0-next.4(@angular/core@22.2.0-next.4(@angular/compiler@22.2.0-next.4)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2)': dependencies: - '@angular/core': 22.2.0-next.3(@angular/compiler@22.2.0-next.3)(rxjs@7.8.2)(zone.js@0.16.2) + '@angular/core': 22.2.0-next.4(@angular/compiler@22.2.0-next.4)(rxjs@7.8.2)(zone.js@0.16.2) rxjs: 7.8.2 tslib: 2.8.1 @@ -14778,10 +14777,10 @@ snapshots: neo-async@2.6.2: {} - ng-packagr@22.2.0-next.3(@angular/compiler-cli@22.2.0-next.3(@angular/compiler@22.2.0-next.3)(typescript@6.0.3))(supports-color@11.0.0)(tslib@2.8.1)(typescript@6.0.3): + ng-packagr@22.2.0-next.4(@angular/compiler-cli@22.2.0-next.4(@angular/compiler@22.2.0-next.4)(typescript@6.0.3))(supports-color@11.0.0)(tslib@2.8.1)(typescript@6.0.3): dependencies: '@ampproject/remapping': 2.3.0 - '@angular/compiler-cli': 22.2.0-next.3(@angular/compiler@22.2.0-next.3)(typescript@6.0.3) + '@angular/compiler-cli': 22.2.0-next.4(@angular/compiler@22.2.0-next.4)(typescript@6.0.3) ajv: 8.20.0 browserslist: 4.28.8 chokidar: 5.0.0 diff --git a/tests/e2e/ng-snapshot/package.json b/tests/e2e/ng-snapshot/package.json index aa97dcca2190..e9c94700043e 100644 --- a/tests/e2e/ng-snapshot/package.json +++ b/tests/e2e/ng-snapshot/package.json @@ -2,21 +2,21 @@ "description": "snapshot versions of Angular for e2e testing", "private": true, "dependencies": { - "@angular/animations": "github:angular/animations-builds#383cdb66a8b166172c60c6247b8f62433fc036ce", - "@angular/cdk": "github:angular/cdk-builds#7e9e3a08b985ff5f6b1c28c84732f67043c750cc", - "@angular/common": "github:angular/common-builds#a2042413ef60c154437ed8395276b75cc928a4af", - "@angular/compiler": "github:angular/compiler-builds#7aad56f2fe4720c93804a7fcfb0797e9327db4c0", - "@angular/compiler-cli": "github:angular/compiler-cli-builds#49e31924991ee9186a9aea250d101820e79bb4a6", - "@angular/core": "github:angular/core-builds#6deca1aa4567d280ec97e66b0d70970f6b506332", - "@angular/forms": "github:angular/forms-builds#6d9eb4089cb8795077db81049e7702bc688c2d58", - "@angular/language-service": "github:angular/language-service-builds#8e758b0550fb522155bd24a58b291e6e7344d327", - "@angular/localize": "github:angular/localize-builds#d627d4f27929f8f5a27d1f6a349543cdaf3bfb42", - "@angular/material": "github:angular/material-builds#972986b028de9bb40e498551ff034e115d961e8b", - "@angular/material-moment-adapter": "github:angular/material-moment-adapter-builds#55d307862a1da6877154314fadf554b18da0a811", - "@angular/platform-browser": "github:angular/platform-browser-builds#8dcc3b87feb7b4479a3debf34989feb8a7dd9f16", - "@angular/platform-browser-dynamic": "github:angular/platform-browser-dynamic-builds#91e2b4643158129289707721bb72b58910efda5f", - "@angular/platform-server": "github:angular/platform-server-builds#d1e8965023f08bbe4e166749eb0e4149ab3af9dd", - "@angular/router": "github:angular/router-builds#8a1452377452f1c53f9fe37f360f5dc6ca575213", - "@angular/service-worker": "github:angular/service-worker-builds#3222e80c93a80abf873e16ad50b7b731a5878dad" + "@angular/animations": "github:angular/animations-builds#c84632a6dbf96114295b3fe07649d8ac82b76d46", + "@angular/cdk": "github:angular/cdk-builds#b5726421e80460c8182e92b41c8d415dc5561faf", + "@angular/common": "github:angular/common-builds#4b526b121e3b74f29fe3b960352f2fe5260d1cdd", + "@angular/compiler": "github:angular/compiler-builds#a52ffe17b21ceeeaea156838fd5f932f6ac03817", + "@angular/compiler-cli": "github:angular/compiler-cli-builds#5a5fbb4a3987257567b2d610379ffb23a7755452", + "@angular/core": "github:angular/core-builds#d20a5cc634812ec5977c0ff319c786426be70512", + "@angular/forms": "github:angular/forms-builds#4690df90e6f4f033e05cde1b3422712e230d2d81", + "@angular/language-service": "github:angular/language-service-builds#6bb9311e04a8c4ae9f3567e0ae45cac6705ec632", + "@angular/localize": "github:angular/localize-builds#cf93c39daf39980bee67712b4bd859cdf4e0bd8b", + "@angular/material": "github:angular/material-builds#32f58c9763fdcf4e07e30bb3d9b2c81750eb24dc", + "@angular/material-moment-adapter": "github:angular/material-moment-adapter-builds#53ba33ada6974d5fa35f2bd9ef3d63b4c0955bf9", + "@angular/platform-browser": "github:angular/platform-browser-builds#cfdec573a8659c00b7c8b5d5547b8d5a8e87efb0", + "@angular/platform-browser-dynamic": "github:angular/platform-browser-dynamic-builds#69ece7bde70642dcb53f03a76283e0dade652a66", + "@angular/platform-server": "github:angular/platform-server-builds#ccee0b1b0e5a1b9830d02b30351e4dc68499e82c", + "@angular/router": "github:angular/router-builds#1d1ea6df7c02df172924446ef0890567c772069c", + "@angular/service-worker": "github:angular/service-worker-builds#1b630d7e0d7947a6fb3ac79ec1d5a632793e4a07" } } From fc5a2ecb147fefb8eeb4833dfcc09fcc5424ec35 Mon Sep 17 00:00:00 2001 From: Alan Agius <17563226+alan-agius4@users.noreply.github.com> Date: Thu, 27 Aug 2026 07:49:44 +0000 Subject: [PATCH 362/787] refactor(@angular/build): remove sass worker and fallback to pure-JS sass Removes the legacy Piscina-based Sass worker thread pool implementation (`sass-worker-implementation.ts` and `worker.ts`). When the native `sass-embedded` compiler cannot be used (such as inside WebContainers or when disabled), the build system now directly falls back to the in-process pure-JS Dart Sass asynchronous compiler (`sass.initAsyncCompiler()`). Consolidates the Sass compilation logic in `packages/angular/build/src/tools/sass` into a simplified `SassCompiler` class in `sass-service.ts` supporting both rebasing (esbuild) and non-rebasing (Webpack) usage. Environment Variable: - Replaces `NG_BUILD_SASS_WORKER` with `NG_BUILD_SASS_EMBEDDED`. - When `NG_BUILD_SASS_EMBEDDED` is set to `0` or `false`, or when running within a WebContainer environment, the native embedded Sass compiler is disabled and the pure-JS Sass compiler is used instead. --- packages/angular/build/src/private.ts | 2 +- .../esbuild/stylesheets/sass-language.ts | 17 +- .../build/src/tools/sass/rebasing-importer.ts | 47 +-- .../sass-async-compiler-implementation.ts | 182 ----------- .../build/src/tools/sass/sass-service.ts | 199 +++++++++++- .../tools/sass/sass-worker-implementation.ts | 245 -------------- .../angular/build/src/tools/sass/worker.ts | 305 ------------------ .../build/src/utils/environment-options.ts | 9 +- .../src/tools/webpack/configs/styles.ts | 8 +- 9 files changed, 207 insertions(+), 807 deletions(-) delete mode 100644 packages/angular/build/src/tools/sass/sass-async-compiler-implementation.ts delete mode 100644 packages/angular/build/src/tools/sass/sass-worker-implementation.ts delete mode 100644 packages/angular/build/src/tools/sass/worker.ts diff --git a/packages/angular/build/src/private.ts b/packages/angular/build/src/private.ts index 315636decae2..9225c2f9d686 100644 --- a/packages/angular/build/src/private.ts +++ b/packages/angular/build/src/private.ts @@ -35,7 +35,7 @@ export { export type { ExternalResultMetadata } from './tools/esbuild/bundler-execution-result'; export { emitFilesToDisk } from './tools/esbuild/utils'; export { transformSupportedBrowsersToTargets } from './tools/esbuild/target'; -export { SassWorkerImplementation } from './tools/sass/sass-worker-implementation'; +export { SassCompiler } from './tools/sass/sass-service'; export { SourceFileCache } from './tools/esbuild/angular/source-file-cache'; export { Cache } from './tools/esbuild/cache'; diff --git a/packages/angular/build/src/tools/esbuild/stylesheets/sass-language.ts b/packages/angular/build/src/tools/esbuild/stylesheets/sass-language.ts index 92c75d76d7ec..ad2961cc2b2e 100644 --- a/packages/angular/build/src/tools/esbuild/stylesheets/sass-language.ts +++ b/packages/angular/build/src/tools/esbuild/stylesheets/sass-language.ts @@ -10,13 +10,12 @@ import type { OnLoadResult, PartialMessage, PartialNote, ResolveResult } from 'e import { dirname, join } from 'node:path'; import { fileURLToPath, pathToFileURL } from 'node:url'; import type { CanonicalizeContext, CompileResult, Exception, Syntax } from 'sass-embedded'; -import { useSassWorker } from '../../../utils/environment-options'; -import type { SassServiceImplementation } from '../../sass/sass-service'; +import type { SassCompiler } from '../../sass/sass-service'; import { MemoryCache } from '../cache'; import { StylesheetLanguage, StylesheetPluginOptions } from './stylesheet-plugin-factory'; -let sassService: SassServiceImplementation | undefined; -let sassServicePromise: Promise | undefined; +let sassService: SassCompiler | undefined; +let sassServicePromise: Promise | undefined; function isSassException(error: unknown): error is Exception { return !!error && typeof error === 'object' && 'sassMessage' in error; @@ -81,13 +80,9 @@ async function compileString( // Lazily load Sass when a Sass file is found if (sassService === undefined) { if (sassServicePromise === undefined) { - sassServicePromise = useSassWorker - ? import('../../sass/sass-worker-implementation').then( - (sassService) => new sassService.SassWorkerImplementation(true), - ) - : import('../../sass/sass-async-compiler-implementation').then( - (sassService) => new sassService.SassAsyncCompilerImplementation(), - ); + sassServicePromise = import('../../sass/sass-service').then( + (sassService) => new sassService.SassCompiler(true), + ); } try { sassService = await sassServicePromise; diff --git a/packages/angular/build/src/tools/sass/rebasing-importer.ts b/packages/angular/build/src/tools/sass/rebasing-importer.ts index e9509574f455..7198d8b74f1e 100644 --- a/packages/angular/build/src/tools/sass/rebasing-importer.ts +++ b/packages/angular/build/src/tools/sass/rebasing-importer.ts @@ -45,7 +45,9 @@ abstract class UrlRebasingImporter implements Importer<'sync'> { constructor( private entryDirectory: string, private rebaseSourceMaps?: Map, - ) {} + ) { + this.load = this.load.bind(this); + } abstract canonicalize(url: string, options: { fromImport: boolean }): URL | null; @@ -140,6 +142,7 @@ export class RelativeUrlRebasingImporter extends UrlRebasingImporter { rebaseSourceMaps?: Map, ) { super(entryDirectory, rebaseSourceMaps); + this.canonicalize = this.canonicalize.bind(this); } canonicalize(url: string, options: { fromImport: boolean }): URL | null { @@ -316,33 +319,6 @@ export class RelativeUrlRebasingImporter extends UrlRebasingImporter { } } -/** - * Provides the Sass importer logic to resolve module (npm package) stylesheet imports via both import and - * use rules and also rebase any `url()` function usage within those stylesheets. The rebasing will ensure that - * the URLs in the output of the Sass compiler reflect the final filesystem location of the output CSS file. - */ -export class ModuleUrlRebasingImporter extends RelativeUrlRebasingImporter { - constructor( - entryDirectory: string, - directoryCache: Map, - rebaseSourceMaps: Map | undefined, - private finder: (specifier: string, options: CanonicalizeContext) => URL | null, - ) { - super(entryDirectory, directoryCache, rebaseSourceMaps); - } - - override canonicalize(url: string, options: CanonicalizeContext): URL | null { - if (url.startsWith('file://')) { - return super.canonicalize(url, options); - } - - let result = this.finder(url, options); - result &&= super.canonicalize(result.href, options); - - return result; - } -} - /** * Provides the Sass importer logic to resolve module (npm package) stylesheet imports asynchronously * and also rebase any `url()` function usage within those stylesheets. @@ -364,6 +340,8 @@ export class AsyncModuleUrlRebasingImporter implements Importer<'async'> { directoryCache, rebaseSourceMaps, ); + this.canonicalize = this.canonicalize.bind(this); + this.load = this.load.bind(this); } async canonicalize(url: string, options: CanonicalizeContext): Promise { @@ -412,16 +390,3 @@ export class LoadPathsUrlRebasingImporter extends RelativeUrlRebasingImporter { return result; } } - -/** - * Workaround for Sass not calling instance methods with `this`. - * The `canonicalize` and `load` methods will be bound to the class instance. - * @param importer A Sass importer to bind. - * @returns The bound Sass importer. - */ -export function sassBindWorkaround(importer: T): T { - importer.canonicalize = importer.canonicalize.bind(importer); - importer.load = importer.load.bind(importer); - - return importer; -} diff --git a/packages/angular/build/src/tools/sass/sass-async-compiler-implementation.ts b/packages/angular/build/src/tools/sass/sass-async-compiler-implementation.ts deleted file mode 100644 index cdf483994f12..000000000000 --- a/packages/angular/build/src/tools/sass/sass-async-compiler-implementation.ts +++ /dev/null @@ -1,182 +0,0 @@ -/** - * @license - * Copyright Google LLC All Rights Reserved. - * - * Use of this source code is governed by an MIT-style license that can be - * found in the LICENSE file at https://angular.dev/license - */ - -import mergeSourceMaps, { type DecodedSourceMap, type RawSourceMap } from '@ampproject/remapping'; -import { dirname } from 'node:path'; -import { fileURLToPath } from 'node:url'; -import type { - AsyncCompiler, - CanonicalizeContext, - CompileResult, - FileImporter, - Importer, - NodePackageImporter, - StringOptions, -} from 'sass-embedded'; -import { - AsyncModuleUrlRebasingImporter, - DirectoryEntry, - LoadPathsUrlRebasingImporter, - RelativeUrlRebasingImporter, -} from './rebasing-importer'; -import { type SassServiceImplementation, isFileImporter } from './sass-service'; - -/** - * A Sass renderer implementation that uses the persistent Dart Sass embedded compiler - * daemon (`sass-embedded`) communicating over standard input/output with protocol buffers. - */ -export class SassAsyncCompilerImplementation implements SassServiceImplementation { - #asyncCompiler: AsyncCompiler | undefined; - #asyncCompilerPromise: Promise | undefined; - - async #ensureAsyncCompiler(): Promise { - if (this.#asyncCompiler) { - return this.#asyncCompiler; - } - - // Import and initialize the async compiler on the main thread. - this.#asyncCompilerPromise ??= import('sass-embedded').then(({ initAsyncCompiler }) => - initAsyncCompiler(), - ); - - try { - this.#asyncCompiler = await this.#asyncCompilerPromise; - } finally { - this.#asyncCompilerPromise = undefined; - } - - return this.#asyncCompiler; - } - - /** - * Provides information about the Sass implementation. - * This mimics enough of the `sass-embedded` value to be used with the `sass-loader`. - */ - get info(): string { - return 'sass-embedded\tasync-compiler'; - } - - /** - * The synchronous render function is not used by the `sass-loader`. - */ - compileString(): never { - throw new Error('Sass compileString is not supported.'); - } - - /** - * Asynchronously request a Sass stylesheet to be rendered using the native embedded compiler. - * - * @param source The contents to compile. - * @param options The `sass-embedded` options to use when rendering the stylesheet. - */ - async compileStringAsync( - source: string, - options: StringOptions<'async'>, - ): Promise { - // The CLI's configuration does not use or expose the ability to define custom Sass functions - if (options.functions && Object.keys(options.functions).length > 0) { - throw new Error('Sass custom functions are not supported.'); - } - - const { functions, importers, importer, url, logger, ...serializableOptions } = options; - - let finalImporters: - (Importer<'async'> | FileImporter<'async'> | NodePackageImporter)[] | undefined; - let loadPaths = options.loadPaths; - const entryDirectory = url ? dirname(fileURLToPath(url)) : process.cwd(); - const directoryCache = new Map(); - const rebaseSourceMaps = options.sourceMap ? new Map() : undefined; - - if (importers?.length) { - for (const importer of importers) { - if (!isFileImporter(importer)) { - throw new Error('Only File Importers are supported.'); - } - } - - finalImporters = [ - new AsyncModuleUrlRebasingImporter( - entryDirectory, - directoryCache, - rebaseSourceMaps, - async (specifier: string, options: CanonicalizeContext): Promise => { - for (const importer of importers) { - const result = await (importer as FileImporter<'async'>).findFileUrl( - specifier, - options, - ); - if (result) { - return result; - } - } - - return null; - }, - ), - ]; - } - - if (loadPaths?.length) { - finalImporters ??= []; - finalImporters.push( - new LoadPathsUrlRebasingImporter( - entryDirectory, - directoryCache, - rebaseSourceMaps, - loadPaths, - ), - ); - loadPaths = undefined; - } - - const relativeImporter = new RelativeUrlRebasingImporter( - entryDirectory, - directoryCache, - rebaseSourceMaps, - ); - - const compiler = await this.#ensureAsyncCompiler(); - const result = await compiler.compileStringAsync(source, { - ...serializableOptions, - url, - loadPaths, - importers: finalImporters, - importer: relativeImporter, - logger, - }); - - if (result.sourceMap && rebaseSourceMaps?.size) { - result.sourceMap = mergeSourceMaps( - result.sourceMap as unknown as RawSourceMap, - (file, context) => (file !== context.importer ? rebaseSourceMaps.get(file) : null), - ) as unknown as typeof result.sourceMap; - } - - return result; - } - - /** - * Shutdown the native embedded Sass compiler daemon. - * @returns A void promise that resolves when closing is complete. - */ - async close(): Promise { - if (this.#asyncCompilerPromise) { - try { - await this.#ensureAsyncCompiler(); - } catch { - // Ignore compiler initialization failures on shutdown - } - } - - if (this.#asyncCompiler) { - const compiler = this.#asyncCompiler; - this.#asyncCompiler = undefined; - await compiler.dispose(); - } - } -} diff --git a/packages/angular/build/src/tools/sass/sass-service.ts b/packages/angular/build/src/tools/sass/sass-service.ts index 1a7c3b7866d8..c3d6cf991526 100644 --- a/packages/angular/build/src/tools/sass/sass-service.ts +++ b/packages/angular/build/src/tools/sass/sass-service.ts @@ -6,33 +6,204 @@ * found in the LICENSE file at https://angular.dev/license */ +import mergeSourceMaps, { type DecodedSourceMap, type RawSourceMap } from '@ampproject/remapping'; +import { dirname } from 'node:path'; +import { fileURLToPath } from 'node:url'; import type { + AsyncCompiler, + CanonicalizeContext, CompileResult, FileImporter, Importer, NodePackageImporter, StringOptions, } from 'sass-embedded'; +import { useSassEmbedded } from '../../utils/environment-options'; +import { + AsyncModuleUrlRebasingImporter, + DirectoryEntry, + LoadPathsUrlRebasingImporter, + RelativeUrlRebasingImporter, +} from './rebasing-importer'; -/** - * Common interface for Sass service implementations. - */ -export interface SassServiceImplementation { - readonly info: string; - compileStringAsync(source: string, options: StringOptions<'async'>): Promise; - close(): Promise; -} - -/** - * All available importer types. - */ -export type Importers = +type Importers = | Importer<'sync'> | Importer<'async'> | FileImporter<'sync'> | FileImporter<'async'> | NodePackageImporter; -export function isFileImporter(value: Importers): value is FileImporter { +function isFileImporter(value: Importers): value is FileImporter { return 'findFileUrl' in value; } + +/** + * A Sass renderer implementation that uses the persistent Dart Sass embedded compiler + * daemon (`sass-embedded`) communicating over standard input/output with protocol buffers, + * or falls back to the pure-JS Dart Sass async compiler (`sass.initAsyncCompiler()`). + */ +export class SassCompiler { + #asyncCompiler: AsyncCompiler | undefined; + #asyncCompilerPromise: Promise | undefined; + + constructor(private readonly rebase = false) {} + + async #createAsyncCompiler(): Promise { + if (useSassEmbedded) { + const { initAsyncCompiler } = await import('sass-embedded'); + + return initAsyncCompiler(); + } + + const { initAsyncCompiler } = await import('sass'); + + return initAsyncCompiler() as unknown as Promise; + } + + async #ensureAsyncCompiler(): Promise { + if (this.#asyncCompiler) { + return this.#asyncCompiler; + } + + this.#asyncCompilerPromise ??= this.#createAsyncCompiler(); + + try { + this.#asyncCompiler = await this.#asyncCompilerPromise; + } finally { + this.#asyncCompilerPromise = undefined; + } + + return this.#asyncCompiler; + } + + /** + * Provides information about the Sass implementation. + * This mimics enough of the `sass-embedded` or `sass` value to be used with the `sass-loader`. + */ + get info(): string { + return useSassEmbedded ? 'sass-embedded\tasync-compiler' : 'dart-sass\tasync-compiler'; + } + + /** + * The synchronous render function is not used by the `sass-loader`. + */ + compileString(): never { + throw new Error('Sass compileString is not supported.'); + } + + /** + * Asynchronously request a Sass stylesheet to be rendered using the native embedded compiler + * or the pure-JS async compiler fallback. + * + * @param source The contents to compile. + * @param options The `sass` / `sass-embedded` options to use when rendering the stylesheet. + */ + async compileStringAsync( + source: string, + options: StringOptions<'async'>, + ): Promise { + // The CLI's configuration does not use or expose the ability to define custom Sass functions + if (options.functions && Object.keys(options.functions).length > 0) { + throw new Error('Sass custom functions are not supported.'); + } + + const compiler = await this.#ensureAsyncCompiler(); + + if (!this.rebase) { + return compiler.compileStringAsync(source, options); + } + + const { functions, importers, importer, url, logger, ...serializableOptions } = options; + + let finalImporters: + (Importer<'async'> | FileImporter<'async'> | NodePackageImporter)[] | undefined; + let loadPaths = options.loadPaths; + const entryDirectory = url ? dirname(fileURLToPath(url)) : process.cwd(); + const directoryCache = new Map(); + const rebaseSourceMaps = options.sourceMap ? new Map() : undefined; + + if (importers?.length) { + if (importers.some((i) => !isFileImporter(i))) { + throw new Error('Only File Importers are supported.'); + } + + finalImporters = [ + new AsyncModuleUrlRebasingImporter( + entryDirectory, + directoryCache, + rebaseSourceMaps, + async (specifier: string, options: CanonicalizeContext): Promise => { + for (const importer of importers) { + const result = await (importer as FileImporter<'async'>).findFileUrl( + specifier, + options, + ); + if (result) { + return result; + } + } + + return null; + }, + ), + ]; + } + + if (loadPaths?.length) { + finalImporters ??= []; + finalImporters.push( + new LoadPathsUrlRebasingImporter( + entryDirectory, + directoryCache, + rebaseSourceMaps, + loadPaths, + ), + ); + loadPaths = undefined; + } + + const relativeImporter = new RelativeUrlRebasingImporter( + entryDirectory, + directoryCache, + rebaseSourceMaps, + ); + + const result = await compiler.compileStringAsync(source, { + ...serializableOptions, + url, + loadPaths, + importers: finalImporters, + importer: relativeImporter, + logger, + }); + + if (result.sourceMap && rebaseSourceMaps?.size) { + result.sourceMap = mergeSourceMaps( + result.sourceMap as unknown as RawSourceMap, + (file, context) => (file !== context.importer ? rebaseSourceMaps.get(file) : null), + ) as unknown as typeof result.sourceMap; + } + + return result; + } + + /** + * Shutdown the Sass compiler. + * @returns A void promise that resolves when closing is complete. + */ + async close(): Promise { + if (this.#asyncCompilerPromise) { + try { + await this.#ensureAsyncCompiler(); + } catch { + // Ignore compiler initialization failures on shutdown + } + } + + if (this.#asyncCompiler) { + const compiler = this.#asyncCompiler; + this.#asyncCompiler = undefined; + await compiler.dispose(); + } + } +} diff --git a/packages/angular/build/src/tools/sass/sass-worker-implementation.ts b/packages/angular/build/src/tools/sass/sass-worker-implementation.ts deleted file mode 100644 index 9208bef3a803..000000000000 --- a/packages/angular/build/src/tools/sass/sass-worker-implementation.ts +++ /dev/null @@ -1,245 +0,0 @@ -/** - * @license - * Copyright Google LLC All Rights Reserved. - * - * Use of this source code is governed by an MIT-style license that can be - * found in the LICENSE file at https://angular.dev/license - */ - -import assert from 'node:assert'; -import { fileURLToPath, pathToFileURL } from 'node:url'; -import { MessageChannel } from 'node:worker_threads'; -import type { - CanonicalizeContext, - CompileResult, - Deprecation, - Exception, - SourceSpan, - StringOptions, -} from 'sass-embedded'; -import { maxWorkers } from '../../utils/environment-options'; -import { WorkerPool } from '../../utils/worker-pool'; -import { type Importers, type SassServiceImplementation, isFileImporter } from './sass-service'; - -// Polyfill Symbol.dispose if not present -// eslint-disable-next-line @typescript-eslint/no-explicit-any -(Symbol as any).dispose ??= Symbol('Symbol Dispose'); - -/** - * The maximum number of Workers that will be created to execute render requests. - */ -const MAX_RENDER_WORKERS = maxWorkers; - -export interface SerializableVersion { - major: number; - minor: number; - patch: number; -} - -export interface SerializableDeprecation extends Omit { - /** The version this deprecation first became active in. */ - deprecatedIn: SerializableVersion | null; - - /** The version this deprecation became obsolete in. */ - obsoleteIn: SerializableVersion | null; -} - -export type SerializableWarningMessage = ( - | { - deprecation: true; - deprecationType: SerializableDeprecation; - } - | { deprecation: false } -) & { - message: string; - span?: Omit & { url?: string }; - stack?: string; -}; - -/** - * A response from the Sass render Worker containing the result of the operation. - */ -export interface RenderResponseMessage { - error?: Exception; - result?: Omit & { loadedUrls: string[] }; - warnings?: SerializableWarningMessage[]; -} - -/** - * A Sass renderer implementation that provides an interface that can be used by Webpack's - * `sass-loader` or as a fallback in environments that do not support native binaries. - * The implementation uses a Worker thread pool to perform Sass rendering with the pure-JS - * `sass` package. - */ -export class SassWorkerImplementation implements SassServiceImplementation { - #workerPool: WorkerPool | undefined; - - constructor( - private readonly rebase = false, - readonly maxThreads = MAX_RENDER_WORKERS, - ) {} - - #ensureWorkerPool(): WorkerPool { - this.#workerPool ??= new WorkerPool({ - filename: require.resolve('./worker'), - maxThreads: this.maxThreads, - }); - - return this.#workerPool; - } - - /** - * Provides information about the Sass implementation. - * This mimics enough of the `sass` value to be used with the `sass-loader`. - */ - get info(): string { - return 'dart-sass\tworker'; - } - - /** - * The synchronous render function is not used by the `sass-loader`. - */ - compileString(): never { - throw new Error('Sass compileString is not supported.'); - } - - /** - * Asynchronously request a Sass stylesheet to be rendered using worker threads. - * - * @param source The contents to compile. - * @param options The Sass options to use when rendering the stylesheet. - */ - async compileStringAsync( - source: string, - options: StringOptions<'async'>, - ): Promise { - // The CLI's configuration does not use or expose the ability to define custom Sass functions - if (options.functions && Object.keys(options.functions).length > 0) { - throw new Error('Sass custom functions are not supported.'); - } - - const { functions, importers, importer, url, logger, ...serializableOptions } = options; - using importerChannel = importers?.length ? this.#createImporterChannel(importers) : undefined; - - const response = (await this.#ensureWorkerPool().run( - { - source, - importerChannel, - hasLogger: !!logger, - rebase: this.rebase, - options: { - ...serializableOptions, - // URL is not serializable so to convert to string here and back to URL in the worker. - url: url ? fileURLToPath(url) : undefined, - }, - }, - { - transferList: importerChannel ? [importerChannel.port] : undefined, - }, - )) as RenderResponseMessage; - - const { result, error, warnings } = response; - - if (warnings && logger?.warn) { - for (const { message, span, ...options } of warnings) { - logger.warn(message, { - ...options, - span: span && { - ...span, - url: span.url ? pathToFileURL(span.url) : undefined, - }, - }); - } - } - - if (error) { - // Convert stringified url value required for cloning back to a URL object - const url = error.span?.url as string | undefined; - if (url) { - error.span.url = pathToFileURL(url); - } - - throw error; - } - - assert(result, 'Sass render worker should always return a result or an error'); - - return { - ...result, - // URL is not serializable so in the worker we convert to string and here back to URL. - loadedUrls: result.loadedUrls.map((p) => pathToFileURL(p)), - }; - } - - /** - * Shutdown the Sass render worker. - * Executing this method will stop any pending render requests. - * @returns A void promise that resolves when closing is complete. - */ - async close(): Promise { - if (this.#workerPool) { - const pool = this.#workerPool; - this.#workerPool = undefined; - await pool.destroy(); - } - } - - #createImporterChannel(importers: Iterable) { - const { port1: mainImporterPort, port2: workerImporterPort } = new MessageChannel(); - const importerSignal = new Int32Array(new SharedArrayBuffer(4)); - - mainImporterPort.on( - 'message', - ({ url, options }: { url: string; options: CanonicalizeContext }) => { - this.processImporters(importers, url, { - ...options, - // URL is not serializable so in the worker we convert to string and here back to URL. - containingUrl: options.containingUrl - ? pathToFileURL(options.containingUrl as unknown as string) - : null, - }) - .then((result) => { - mainImporterPort.postMessage(result); - }) - .catch((error) => { - mainImporterPort.postMessage(error); - }) - .finally(() => { - Atomics.store(importerSignal, 0, 1); - Atomics.notify(importerSignal, 0); - }); - }, - ); - - mainImporterPort.unref(); - - return { - port: workerImporterPort, - signal: importerSignal, - [Symbol.dispose]() { - mainImporterPort.close(); - }, - }; - } - - private async processImporters( - importers: Iterable, - url: string, - options: CanonicalizeContext, - ): Promise { - for (const importer of importers) { - if (!isFileImporter(importer)) { - // Importer - throw new Error('Only File Importers are supported.'); - } - - // File importer (Can be sync or aync). - const result = await importer.findFileUrl(url, options); - if (result) { - return fileURLToPath(result); - } - } - - return null; - } -} diff --git a/packages/angular/build/src/tools/sass/worker.ts b/packages/angular/build/src/tools/sass/worker.ts deleted file mode 100644 index 2416fe21e5cd..000000000000 --- a/packages/angular/build/src/tools/sass/worker.ts +++ /dev/null @@ -1,305 +0,0 @@ -/** - * @license - * Copyright Google LLC All Rights Reserved. - * - * Use of this source code is governed by an MIT-style license that can be - * found in the LICENSE file at https://angular.dev/license - */ - -import mergeSourceMaps, { type DecodedSourceMap, type RawSourceMap } from '@ampproject/remapping'; -import { dirname } from 'node:path'; -import { fileURLToPath, pathToFileURL } from 'node:url'; -import { MessagePort, receiveMessageOnPort } from 'node:worker_threads'; -import { - Deprecation, - Exception, - FileImporter, - SourceSpan, - StringOptions, - compileString, -} from 'sass'; -import { - DirectoryEntry, - LoadPathsUrlRebasingImporter, - ModuleUrlRebasingImporter, - RelativeUrlRebasingImporter, - sassBindWorkaround, -} from './rebasing-importer'; -import type { - SerializableDeprecation, - SerializableWarningMessage, -} from './sass-worker-implementation'; - -/** - * A request to render a Sass stylesheet using the supplied options. - */ -interface RenderRequestMessage { - /** - * The contents to compile. - */ - source: string; - - /** - * The Sass options to provide to the `dart-sass` compile function. - */ - options: Omit, 'url'> & { url: string }; - - /** - * Indicates the request has a custom importer function on the main thread. - */ - importerChannel?: { - port: MessagePort; - signal: Int32Array; - }; - - /** - * Indicates the request has a custom logger for warning messages. - */ - hasLogger: boolean; - - /** - * Indicates paths within url() CSS functions should be rebased. - */ - rebase: boolean; -} - -interface RenderResult { - warnings: SerializableWarningMessage[] | undefined; - result: { - css: string; - loadedUrls: string[]; - sourceMap?: RawSourceMap; - }; -} - -interface RenderError { - warnings: SerializableWarningMessage[] | undefined; - error: { - message: string; - stack?: string; - span?: Omit & { url?: string }; - sassMessage?: string; - sassStack?: string; - }; -} - -export default async function renderSassStylesheet( - request: RenderRequestMessage, -): Promise { - const { importerChannel, hasLogger, source, options, rebase } = request; - - const entryDirectory = dirname(options.url); - let warnings: SerializableWarningMessage[] | undefined; - try { - const directoryCache = new Map(); - const rebaseSourceMaps = options.sourceMap ? new Map() : undefined; - if (importerChannel) { - // When a custom importer function is present, the importer request must be proxied - // back to the main thread where it can be executed. - // This process must be synchronous from the perspective of dart-sass. The `Atomics` - // functions combined with the shared memory `importSignal` and the Node.js - // `receiveMessageOnPort` function are used to ensure synchronous behavior. - const proxyImporter: FileImporter<'sync'> = { - findFileUrl: (url, { fromImport, containingUrl }) => { - Atomics.store(importerChannel.signal, 0, 0); - importerChannel.port.postMessage({ - url, - options: { - fromImport, - containingUrl: containingUrl ? fileURLToPath(containingUrl) : null, - }, - }); - // Wait for the main thread to set the signal to 1 and notify, which tells - // us that a message can be received on the port. - // If the main thread is fast, the signal will already be set to 1, and no - // sleep/notify is necessary. - // However, there can be a race condition here: - // - the main thread sets the signal to 1, but does not get to the notify instruction yet - // - the worker does not pause because the signal is set to 1 - // - the worker very soon enters this method again - // - this method sets the signal to 0 and sends the message - // - the signal is 0 and so the `Atomics.wait` call blocks - // - only now the main thread runs the `notify` from the first invocation, so the - // worker continues. - // - but there is no message yet in the port, because the thread should not have been - // waken up yet. - // To combat this, wait for a non-0 value _twice_. - // Almost every time, this immediately continues with "not-equal", because - // the signal is still set to 1, except during the race condition, when the second - // wait will wait for the correct notify. - Atomics.wait(importerChannel.signal, 0, 0); - Atomics.wait(importerChannel.signal, 0, 0); - - const result = receiveMessageOnPort(importerChannel.port)?.message as string | null; - - return result ? pathToFileURL(result) : null; - }, - }; - options.importers = [ - rebase - ? sassBindWorkaround( - new ModuleUrlRebasingImporter( - entryDirectory, - directoryCache, - rebaseSourceMaps, - proxyImporter.findFileUrl, - ), - ) - : proxyImporter, - ]; - } - - if (rebase && options.loadPaths?.length) { - options.importers ??= []; - options.importers.push( - sassBindWorkaround( - new LoadPathsUrlRebasingImporter( - entryDirectory, - directoryCache, - rebaseSourceMaps, - options.loadPaths, - ), - ), - ); - options.loadPaths = undefined; - } - - let relativeImporter; - if (rebase) { - relativeImporter = sassBindWorkaround( - new RelativeUrlRebasingImporter(entryDirectory, directoryCache, rebaseSourceMaps), - ); - } - - // The synchronous Sass render function can be up to two times faster than the async variant - const result = compileString(source, { - ...options, - // URL is not serializable so to convert to string in the parent and back to URL here. - url: pathToFileURL(options.url), - // The `importer` option (singular) handles relative imports - importer: relativeImporter, - logger: hasLogger - ? { - warn(message, warnOptions) { - warnings ??= []; - warnings.push({ - ...warnOptions, - message, - span: warnOptions.span && convertSourceSpan(warnOptions.span), - ...convertDeprecation( - warnOptions.deprecation, - // eslint-disable-next-line @typescript-eslint/no-explicit-any - (warnOptions as any).deprecationType, - ), - }); - }, - } - : undefined, - }); - - if (result.sourceMap && rebaseSourceMaps?.size) { - // Merge the intermediate rebasing source maps into the final Sass generated source map. - // Casting is required due to small but compatible differences in typings between the packages. - result.sourceMap = mergeSourceMaps( - result.sourceMap as unknown as RawSourceMap, - // To prevent an infinite lookup loop, skip getting the source when the rebasing source map - // is referencing its original self. - (file, context) => (file !== context.importer ? rebaseSourceMaps.get(file) : null), - ) as unknown as typeof result.sourceMap; - } - - return { - warnings, - result: { - ...result, - sourceMap: result.sourceMap as unknown as RawSourceMap | undefined, - // URL is not serializable so to convert to string here and back to URL in the parent. - loadedUrls: result.loadedUrls.map((p) => fileURLToPath(p)), - }, - }; - } catch (error) { - // Needed because V8 will only serialize the message and stack properties of an Error instance. - if (error instanceof Exception) { - const { span, message, stack, sassMessage, sassStack } = error; - - return { - warnings, - error: { - span: convertSourceSpan(span), - message, - stack, - sassMessage, - sassStack, - }, - }; - } else if (error instanceof Error) { - const { message, stack } = error; - - return { warnings, error: { message, stack } }; - } else { - return { - warnings, - error: { message: 'An unknown error has occurred.' }, - }; - } - } -} - -/** - * Converts a Sass SourceSpan object into a serializable form. - * The SourceSpan object contains a URL property which must be converted into a string. - * Also, most of the interface's properties are get accessors and are not automatically - * serialized when sent back from the worker. - * - * @param span The Sass SourceSpan object to convert. - * @returns A serializable form of the SourceSpan object. - */ -function convertSourceSpan(span: SourceSpan): Omit & { url?: string } { - return { - text: span.text, - context: span.context, - end: { - column: span.end.column, - offset: span.end.offset, - line: span.end.line, - }, - start: { - column: span.start.column, - offset: span.start.offset, - line: span.start.line, - }, - url: span.url ? fileURLToPath(span.url) : undefined, - }; -} - -function convertDeprecation( - deprecation: boolean, - deprecationType: Deprecation | undefined, -): { deprecation: false } | { deprecation: true; deprecationType: SerializableDeprecation } { - if (!deprecation || !deprecationType) { - return { deprecation: false }; - } - - const { obsoleteIn, deprecatedIn, ...rest } = deprecationType; - - return { - deprecation: true, - deprecationType: { - ...rest, - obsoleteIn: obsoleteIn - ? { - major: obsoleteIn.major, - minor: obsoleteIn.minor, - patch: obsoleteIn.patch, - } - : null, - deprecatedIn: deprecatedIn - ? { - major: deprecatedIn.major, - minor: deprecatedIn.minor, - patch: deprecatedIn.patch, - } - : null, - }, - }; -} diff --git a/packages/angular/build/src/utils/environment-options.ts b/packages/angular/build/src/utils/environment-options.ts index c9ac132e7887..f008673a1552 100644 --- a/packages/angular/build/src/utils/environment-options.ts +++ b/packages/angular/build/src/utils/environment-options.ts @@ -202,11 +202,12 @@ export const usePartialSsrBuild = parseTristate(process.env['NG_BUILD_PARTIAL_SS export const useBabelLinker = parseTristate(process.env['NG_BUILD_BABEL_LINKER']) === true; /** - * When `NG_BUILD_SASS_WORKER` is enabled (`1` or `true`), the worker-based - * Sass implementation will be used instead of the native asynchronous compiler. + * When `NG_BUILD_SASS_EMBEDDED` is set to `0` or `false`, or when running within a + * WebContainer environment, the native embedded Sass compiler is disabled + * and the pure-JavaScript Sass compiler is used instead. */ -export const useSassWorker = - !!process.versions.webcontainer || parseTristate(process.env['NG_BUILD_SASS_WORKER']) === true; +export const useSassEmbedded = + !process.versions.webcontainer && parseTristate(process.env['NG_BUILD_SASS_EMBEDDED']) !== false; const bazelBinDirectory = process.env['BAZEL_BINDIR']; const bazelExecRoot = process.env['JS_BINARY__EXECROOT']; diff --git a/packages/angular_devkit/build_angular/src/tools/webpack/configs/styles.ts b/packages/angular_devkit/build_angular/src/tools/webpack/configs/styles.ts index e9d7be5cbef1..cd541faa9900 100644 --- a/packages/angular_devkit/build_angular/src/tools/webpack/configs/styles.ts +++ b/packages/angular_devkit/build_angular/src/tools/webpack/configs/styles.ts @@ -7,7 +7,7 @@ */ import { - SassWorkerImplementation, + SassCompiler, findTailwindConfiguration, generateSearchDirectories, loadPostcssConfiguration, @@ -66,11 +66,11 @@ export async function getStylesConfig(wco: WebpackConfigOptions): Promise { + compiler.hooks.shutdown.tap('sass-service', () => { void sassImplementation.close(); }); }, @@ -332,7 +332,7 @@ export async function getStylesConfig(wco: WebpackConfigOptions): Promise Date: Thu, 27 Aug 2026 08:31:06 +0000 Subject: [PATCH 363/787] build: move sass from dependencies to devDependencies in build-angular This `sass` version is only used for types, as the `sass` implementation is in `@angular/build`. --- packages/angular_devkit/build_angular/package.json | 2 +- pnpm-lock.yaml | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/packages/angular_devkit/build_angular/package.json b/packages/angular_devkit/build_angular/package.json index ba718f28cd5e..9038b43df99a 100644 --- a/packages/angular_devkit/build_angular/package.json +++ b/packages/angular_devkit/build_angular/package.json @@ -46,7 +46,6 @@ "postcss-loader": "8.2.1", "resolve-url-loader": "5.0.0", "rxjs": "7.8.2", - "sass": "1.103.1", "sass-loader": "17.0.0", "semver": "7.8.5", "source-map-loader": "5.0.0", @@ -67,6 +66,7 @@ "@angular/ssr": "workspace:*", "browser-sync": "3.0.4", "ng-packagr": "22.2.0-next.4", + "sass": "1.103.1", "undici": "8.10.0" }, "peerDependencies": { diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 6a0dd2e5c007..e5308f871e85 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -667,9 +667,6 @@ importers: rxjs: specifier: 7.8.2 version: 7.8.2 - sass: - specifier: 1.103.1 - version: 1.103.1 sass-loader: specifier: 17.0.0 version: 17.0.0(sass-embedded@1.103.1)(sass@1.103.1)(webpack@5.109.2(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.26)(uglify-js@3.19.3)) @@ -716,6 +713,9 @@ importers: ng-packagr: specifier: 22.2.0-next.4 version: 22.2.0-next.4(@angular/compiler-cli@22.2.0-next.4(@angular/compiler@22.2.0-next.4)(typescript@6.0.3))(supports-color@11.0.0)(tslib@2.8.1)(typescript@6.0.3) + sass: + specifier: 1.103.1 + version: 1.103.1 undici: specifier: 8.10.0 version: 8.10.0 From f0b045eba9a37bd509b5bea3a17e059c1e27433c Mon Sep 17 00:00:00 2001 From: Charles Lyding <19598772+clydin@users.noreply.github.com> Date: Thu, 27 Aug 2026 16:56:46 -0400 Subject: [PATCH 364/787] refactor(@angular/build): isolate TypeScript diagnostics and AST caching in TypeScriptCompilation Decouple the AngularCompilation base class from TypeScript diagnostic structures and types, and encapsulate TypeScript-specific compilation logic in an intermediate TypeScriptCompilation class. TypeScriptCompilation extends AngularCompilation to manage the ts.SourceFile AST cache, file invalidation, and TypeScript diagnostic collection and conversion. This allows AngularCompilation.diagnoseFiles to return an empty diagnostics result by default, removing collectDiagnostics, static loadTypescript, and typescript imports from AngularCompilation entirely. AotCompilation and JitCompilation now extend TypeScriptCompilation, sharing unified AST caching and file invalidation logic, while NoopCompilation and ParallelCompilation no longer require dummy collectDiagnostics stubs. In addition, diagnostics.ts is relocated from tools/esbuild/angular/ into tools/angular/compilation/ so TypeScript diagnostic formatting remains strictly encapsulated within the compilation subsystem. --- .../compilation/angular-compilation.ts | 45 +--------- .../compilation/angular-compilation_spec.ts | 86 ++++++++++++++++++- .../angular/compilation/aot-compilation.ts | 17 ++-- .../compilation}/diagnostics.ts | 0 .../src/tools/angular/compilation/index.ts | 1 + .../angular/compilation/jit-compilation.ts | 17 +--- .../angular/compilation/noop-compilation.ts | 4 - .../compilation/parallel-compilation.ts | 8 -- .../compilation/typescript-compilation.ts | 57 ++++++++++++ 9 files changed, 152 insertions(+), 83 deletions(-) rename packages/angular/build/src/tools/{esbuild/angular => angular/compilation}/diagnostics.ts (100%) create mode 100644 packages/angular/build/src/tools/angular/compilation/typescript-compilation.ts diff --git a/packages/angular/build/src/tools/angular/compilation/angular-compilation.ts b/packages/angular/build/src/tools/angular/compilation/angular-compilation.ts index 4c17bb6e60de..308b0d255df3 100644 --- a/packages/angular/build/src/tools/angular/compilation/angular-compilation.ts +++ b/packages/angular/build/src/tools/angular/compilation/angular-compilation.ts @@ -8,9 +8,7 @@ import type * as ng from '@angular/compiler-cli'; import type { PartialMessage } from 'esbuild'; -import type ts from 'typescript'; -import { convertTypeScriptDiagnostic } from '../../esbuild/angular/diagnostics'; -import { profileAsync, profileSync } from '../../esbuild/profiling'; +import { profileSync } from '../../esbuild/profiling'; import type { AngularHostOptions } from '../angular-host'; export interface EmitFileResult { @@ -51,7 +49,6 @@ export enum DiagnosticModes { export abstract class AngularCompilation { static #angularCompilerCliModule?: typeof ng; - static #typescriptModule?: typeof ts; static async loadCompilerCli(): Promise { AngularCompilation.#angularCompilerCliModule ??= await import('@angular/compiler-cli'); @@ -59,12 +56,6 @@ export abstract class AngularCompilation { return AngularCompilation.#angularCompilerCliModule; } - static async loadTypescript(): Promise { - AngularCompilation.#typescriptModule ??= await import('typescript'); - - return AngularCompilation.#typescriptModule; - } - protected async loadConfiguration(tsconfig: string): Promise { const { readConfiguration } = await AngularCompilation.loadCompilerCli(); @@ -100,40 +91,10 @@ export abstract class AngularCompilation { transformFile?(filename: string, content: string): Promise; - protected collectDiagnostics?( - modes: DiagnosticModes, - ): Iterable | Promise>; - async diagnoseFiles( - modes = DiagnosticModes.All, + modes?: DiagnosticModes, ): Promise<{ errors?: PartialMessage[]; warnings?: PartialMessage[] }> { - if (!this.collectDiagnostics) { - return {}; - } - - const result: { errors?: PartialMessage[]; warnings?: PartialMessage[] } = {}; - - // Avoid loading typescript until actually needed. - // This allows for avoiding the load of typescript in the main thread when using the parallel compilation. - const typescript = await AngularCompilation.loadTypescript(); - - await profileAsync('NG_DIAGNOSTICS_TOTAL', async () => { - const diagnostics = await this.collectDiagnostics?.(modes); - if (!diagnostics) { - return; - } - - for (const diagnostic of diagnostics) { - const message = convertTypeScriptDiagnostic(typescript, diagnostic); - if (diagnostic.category === typescript.DiagnosticCategory.Error) { - (result.errors ??= []).push(message); - } else { - (result.warnings ??= []).push(message); - } - } - }); - - return result; + return {}; } update?(files: Set): Promise; diff --git a/packages/angular/build/src/tools/angular/compilation/angular-compilation_spec.ts b/packages/angular/build/src/tools/angular/compilation/angular-compilation_spec.ts index a9e93b701e5f..66d21cb52f51 100644 --- a/packages/angular/build/src/tools/angular/compilation/angular-compilation_spec.ts +++ b/packages/angular/build/src/tools/angular/compilation/angular-compilation_spec.ts @@ -6,11 +6,14 @@ * found in the LICENSE file at https://angular.dev/license */ +import ts from 'typescript'; import type { AngularHostOptions } from '../angular-host'; import { AngularCompilation, AngularCompilationResult, + DiagnosticModes, NoopCompilation, + TypeScriptCompilation, createAngularCompilation, } from './index'; @@ -68,15 +71,90 @@ describe('AngularCompilation', () => { expect(result.compilerOptions['customOption']).toBe(true); }); - it('throws when calling collectDiagnostics or emitAffectedFiles', () => { + it('throws when calling emitAffectedFiles', () => { const compilation = new NoopCompilation(); - expect(() => - (compilation as unknown as { collectDiagnostics(): unknown }).collectDiagnostics(), - ).toThrowError('Not available when using noop compilation.'); expect(() => compilation.emitAffectedFiles()).toThrowError( 'Not available when using noop compilation.', ); }); + + it('returns empty diagnostics from diagnoseFiles', async () => { + const compilation = new NoopCompilation(); + const diagnostics = await compilation.diagnoseFiles(); + expect(diagnostics).toEqual({}); + }); + }); + + describe('TypeScriptCompilation', () => { + class MockTypeScriptCompilation extends TypeScriptCompilation { + async initialize(): Promise { + return { compilerOptions: {}, referencedFiles: [] }; + } + + protected override *collectDiagnostics(modes: DiagnosticModes): Iterable { + if (modes & DiagnosticModes.Option) { + yield { + category: ts.DiagnosticCategory.Error, + code: 1234, + messageText: 'Mock option error', + file: undefined, + start: undefined, + length: undefined, + }; + } + if (modes & DiagnosticModes.Semantic) { + yield { + category: ts.DiagnosticCategory.Warning, + code: 5678, + messageText: 'Mock semantic warning', + file: undefined, + start: undefined, + length: undefined, + }; + } + } + + public getCachedSourceFiles(): Map { + return this.sourceFiles; + } + } + + it('collects and converts diagnostics categorized by error and warning', async () => { + const compilation = new MockTypeScriptCompilation(); + const diagnostics = await compilation.diagnoseFiles(DiagnosticModes.All); + + expect(diagnostics.errors?.length).toBe(1); + expect(diagnostics.errors?.[0].text).toContain('Mock option error'); + expect(diagnostics.warnings?.length).toBe(1); + expect(diagnostics.warnings?.[0].text).toContain('Mock semantic warning'); + }); + + it('filters diagnostics according to requested DiagnosticModes', async () => { + const compilation = new MockTypeScriptCompilation(); + const diagnostics = await compilation.diagnoseFiles(DiagnosticModes.Option); + + expect(diagnostics.errors?.length).toBe(1); + expect(diagnostics.errors?.[0].text).toContain('Mock option error'); + expect(diagnostics.warnings).toBeUndefined(); + }); + + it('returns empty diagnostics immediately when mode is DiagnosticModes.None', async () => { + const compilation = new MockTypeScriptCompilation(); + const diagnostics = await compilation.diagnoseFiles(DiagnosticModes.None); + + expect(diagnostics).toEqual({}); + }); + + it('evicts files from AST cache on update and invalidateFiles', async () => { + const compilation = new MockTypeScriptCompilation(); + const mockSourceFile = ts.createSourceFile('test.ts', '', ts.ScriptTarget.Latest); + compilation.getCachedSourceFiles().set('/src/test.ts', mockSourceFile); + + expect(compilation.getCachedSourceFiles().has('/src/test.ts')).toBeTrue(); + + await compilation.update?.(new Set(['/src/test.ts'])); + expect(compilation.getCachedSourceFiles().has('/src/test.ts')).toBeFalse(); + }); }); describe('createAngularCompilation', () => { diff --git a/packages/angular/build/src/tools/angular/compilation/aot-compilation.ts b/packages/angular/build/src/tools/angular/compilation/aot-compilation.ts index 42df6a40e778..99f6da756930 100644 --- a/packages/angular/build/src/tools/angular/compilation/aot-compilation.ts +++ b/packages/angular/build/src/tools/angular/compilation/aot-compilation.ts @@ -11,7 +11,6 @@ import assert from 'node:assert'; import { relative } from 'node:path'; import ts from 'typescript'; import { useTypeChecking } from '../../../utils/environment-options'; -import { toPosixPath } from '../../../utils/path'; import { profileAsync, profileSync } from '../../esbuild/profiling'; import { AngularHostOptions, @@ -28,6 +27,7 @@ import { EmitFileResult, } from './angular-compilation'; import { collectHmrCandidates } from './hmr-candidates'; +import { TypeScriptCompilation } from './typescript-compilation'; import { printSourceFileWithMap } from './typescript-printer'; /** @@ -54,9 +54,8 @@ class AngularCompilationState { } } -export class AotCompilation extends AngularCompilation { +export class AotCompilation extends TypeScriptCompilation { #state?: AngularCompilationState; - readonly #sourceFiles = new Map(); constructor(private readonly browserOnlyBuild: boolean) { super(); @@ -100,9 +99,9 @@ export class AotCompilation extends AngularCompilation { let staleSourceFiles; let clearPackageJsonCache = false; if (hostOptions.modifiedFiles) { - for (const modifiedFile of hostOptions.modifiedFiles) { - this.#sourceFiles.delete(toPosixPath(modifiedFile)); + this.invalidateFiles(hostOptions.modifiedFiles); + for (const modifiedFile of hostOptions.modifiedFiles) { if (this.#state) { // Clear package.json cache if a node modules file was modified if (!clearPackageJsonCache && modifiedFile.includes('node_modules')) { @@ -128,7 +127,7 @@ export class AotCompilation extends AngularCompilation { compilerOptions, hostOptions, packageJsonCache, - this.#sourceFiles, + this.sourceFiles, ); // Create the Angular specific program that contains the Angular compiler @@ -463,12 +462,6 @@ export class AotCompilation extends AngularCompilation { return emittedFiles.values(); } - - override async update(files: Set): Promise { - for (const file of files) { - this.#sourceFiles.delete(toPosixPath(file)); - } - } } function findAffectedFiles( diff --git a/packages/angular/build/src/tools/esbuild/angular/diagnostics.ts b/packages/angular/build/src/tools/angular/compilation/diagnostics.ts similarity index 100% rename from packages/angular/build/src/tools/esbuild/angular/diagnostics.ts rename to packages/angular/build/src/tools/angular/compilation/diagnostics.ts diff --git a/packages/angular/build/src/tools/angular/compilation/index.ts b/packages/angular/build/src/tools/angular/compilation/index.ts index 213f55cac326..736adea60682 100644 --- a/packages/angular/build/src/tools/angular/compilation/index.ts +++ b/packages/angular/build/src/tools/angular/compilation/index.ts @@ -16,3 +16,4 @@ export { } from './angular-compilation'; export { createAngularCompilation, type AngularCompilationMode } from './factory'; export { NoopCompilation } from './noop-compilation'; +export { TypeScriptCompilation } from './typescript-compilation'; diff --git a/packages/angular/build/src/tools/angular/compilation/jit-compilation.ts b/packages/angular/build/src/tools/angular/compilation/jit-compilation.ts index 955c90502cb0..e4e371a05df8 100644 --- a/packages/angular/build/src/tools/angular/compilation/jit-compilation.ts +++ b/packages/angular/build/src/tools/angular/compilation/jit-compilation.ts @@ -9,7 +9,6 @@ import type * as ng from '@angular/compiler-cli'; import assert from 'node:assert'; import ts from 'typescript'; -import { toPosixPath } from '../../../utils/path'; import { profileSync } from '../../esbuild/profiling'; import { AngularHostOptions, createAngularCompilerHost } from '../angular-host'; import { createJitResourceTransformer } from '../transformers/jit-resource-transformer'; @@ -21,6 +20,7 @@ import { DiagnosticModes, EmitFileResult, } from './angular-compilation'; +import { TypeScriptCompilation } from './typescript-compilation'; class JitCompilationState { constructor( @@ -32,9 +32,8 @@ class JitCompilationState { ) {} } -export class JitCompilation extends AngularCompilation { +export class JitCompilation extends TypeScriptCompilation { #state?: JitCompilationState; - readonly #sourceFiles = new Map(); constructor(private readonly browserOnlyBuild: boolean) { super(); @@ -59,9 +58,7 @@ export class JitCompilation extends AngularCompilation { compilerOptionsTransformer?.(originalCompilerOptions) ?? originalCompilerOptions; if (hostOptions.modifiedFiles) { - for (const modifiedFile of hostOptions.modifiedFiles) { - this.#sourceFiles.delete(toPosixPath(modifiedFile)); - } + this.invalidateFiles(hostOptions.modifiedFiles); } // Create Angular compiler host @@ -70,7 +67,7 @@ export class JitCompilation extends AngularCompilation { compilerOptions, hostOptions, undefined, - this.#sourceFiles, + this.sourceFiles, ); // Create the TypeScript Program @@ -167,10 +164,4 @@ export class JitCompilation extends AngularCompilation { return emittedFiles; } - - override async update(files: Set): Promise { - for (const file of files) { - this.#sourceFiles.delete(toPosixPath(file)); - } - } } diff --git a/packages/angular/build/src/tools/angular/compilation/noop-compilation.ts b/packages/angular/build/src/tools/angular/compilation/noop-compilation.ts index a2bb722d10a8..55c5913dbad4 100644 --- a/packages/angular/build/src/tools/angular/compilation/noop-compilation.ts +++ b/packages/angular/build/src/tools/angular/compilation/noop-compilation.ts @@ -24,10 +24,6 @@ export class NoopCompilation extends AngularCompilation { return { compilerOptions, referencedFiles: [] }; } - protected override collectDiagnostics(): never { - throw new Error('Not available when using noop compilation.'); - } - override emitAffectedFiles(): never { throw new Error('Not available when using noop compilation.'); } diff --git a/packages/angular/build/src/tools/angular/compilation/parallel-compilation.ts b/packages/angular/build/src/tools/angular/compilation/parallel-compilation.ts index f9a504ee6fc0..7fc530161789 100644 --- a/packages/angular/build/src/tools/angular/compilation/parallel-compilation.ts +++ b/packages/angular/build/src/tools/angular/compilation/parallel-compilation.ts @@ -133,14 +133,6 @@ export class ParallelCompilation extends AngularCompilation { } } - /** - * This is not needed with this compilation type since the worker will already send a response - * with the serializable esbuild compatible diagnostics. - */ - protected override collectDiagnostics(): never { - throw new Error('Not implemented in ParallelCompilation.'); - } - override async diagnoseFiles( modes = DiagnosticModes.All, ): Promise<{ errors?: PartialMessage[]; warnings?: PartialMessage[] }> { diff --git a/packages/angular/build/src/tools/angular/compilation/typescript-compilation.ts b/packages/angular/build/src/tools/angular/compilation/typescript-compilation.ts new file mode 100644 index 000000000000..7591e2028c36 --- /dev/null +++ b/packages/angular/build/src/tools/angular/compilation/typescript-compilation.ts @@ -0,0 +1,57 @@ +/** + * @license + * Copyright Google LLC All Rights Reserved. + * + * Use of this source code is governed by an MIT-style license that can be + * found in the LICENSE file at https://angular.dev/license + */ + +import type { PartialMessage } from 'esbuild'; +import ts from 'typescript'; +import { toPosixPath } from '../../../utils/path'; +import { profileAsync } from '../../esbuild/profiling'; +import { AngularCompilation, DiagnosticModes } from './angular-compilation'; +import { convertTypeScriptDiagnostic } from './diagnostics'; + +export abstract class TypeScriptCompilation extends AngularCompilation { + protected readonly sourceFiles = new Map(); + + protected invalidateFiles(files: Iterable): void { + for (const file of files) { + this.sourceFiles.delete(toPosixPath(file)); + } + } + + override async update(files: Set): Promise { + this.invalidateFiles(files); + } + + protected abstract collectDiagnostics( + modes: DiagnosticModes, + ): Iterable | Promise>; + + override async diagnoseFiles( + modes = DiagnosticModes.All, + ): Promise<{ errors?: PartialMessage[]; warnings?: PartialMessage[] }> { + if (modes === DiagnosticModes.None) { + return {}; + } + + const result: { errors?: PartialMessage[]; warnings?: PartialMessage[] } = {}; + + await profileAsync('NG_DIAGNOSTICS_TOTAL', async () => { + const diagnostics = await this.collectDiagnostics(modes); + + for (const diagnostic of diagnostics) { + const message = convertTypeScriptDiagnostic(ts, diagnostic); + if (diagnostic.category === ts.DiagnosticCategory.Error) { + (result.errors ??= []).push(message); + } else { + (result.warnings ??= []).push(message); + } + } + }); + + return result; + } +} From eacbeb2c5da166876cc1340c4fefe7c092d5dc11 Mon Sep 17 00:00:00 2001 From: Angular Robot Date: Fri, 28 Aug 2026 06:24:10 +0000 Subject: [PATCH 365/787] build: update dependency node to v24.20.0 See associated pull request for more information. --- .nvmrc | 2 +- MODULE.bazel | 16 ++++++++-------- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/.nvmrc b/.nvmrc index 60ade1ae01e8..b7179aed06e8 100644 --- a/.nvmrc +++ b/.nvmrc @@ -1 +1 @@ -24.19.0 +24.20.0 diff --git a/MODULE.bazel b/MODULE.bazel index 1c0127473365..994210f39c91 100644 --- a/MODULE.bazel +++ b/MODULE.bazel @@ -40,15 +40,15 @@ git_override( node = use_extension("@rules_nodejs//nodejs:extensions.bzl", "node") node.toolchain( node_repositories = { - "24.19.0-darwin_arm64": ("node-v24.19.0-darwin-arm64.tar.gz", "node-v24.19.0-darwin-arm64", "8294b7aa9b03997481c06babf1e8b270c859358f27da57a11509afe537ac381d"), - "24.19.0-darwin_amd64": ("node-v24.19.0-darwin-x64.tar.gz", "node-v24.19.0-darwin-x64", "d1b5e999db158c62fe8f7267a4476b035d8bd93b1a605bac24a3f0dd166e3316"), - "24.19.0-linux_arm64": ("node-v24.19.0-linux-arm64.tar.xz", "node-v24.19.0-linux-arm64", "01443c1e1a29e531ccad5a46fefa6df490d2189c49f7955904aecdbb0fe86fdc"), - "24.19.0-linux_ppc64le": ("node-v24.19.0-linux-ppc64le.tar.xz", "node-v24.19.0-linux-ppc64le", "c510c6ce12f07010f771e6edb22a3fe23f4f2e6f40b1ffd4941aed0646a0d8b3"), - "24.19.0-linux_s390x": ("node-v24.19.0-linux-s390x.tar.xz", "node-v24.19.0-linux-s390x", "a4792e65962ffa0af42627aacf1122a60c3c88dbf4e4184f06820d66f9da8ba4"), - "24.19.0-linux_amd64": ("node-v24.19.0-linux-x64.tar.xz", "node-v24.19.0-linux-x64", "14b342e71204f811bde6153be8e04b62aef63c236fef92b55f9c83154b409647"), - "24.19.0-windows_amd64": ("node-v24.19.0-win-x64.zip", "node-v24.19.0-win-x64", "57f71ab3652e797d84acddc79c81cc9ff1c6ddb2a1974cdb83f00fee9bff4c73"), + "24.20.0-darwin_arm64": ("node-v24.20.0-darwin-arm64.tar.gz", "node-v24.20.0-darwin-arm64", "40e5607e5ecb3db9192723776da2d75d966260fc74a7a9e731c1bd67dda96bc8"), + "24.20.0-darwin_amd64": ("node-v24.20.0-darwin-x64.tar.gz", "node-v24.20.0-darwin-x64", "9e5b2644cf107befb6aefca676b96d3296bc10138096f022ed378d6233ed81f4"), + "24.20.0-linux_arm64": ("node-v24.20.0-linux-arm64.tar.xz", "node-v24.20.0-linux-arm64", "5f4ddab610c1ab2016b3c227cebdbf6d9495161487e4739c7b90090595f465f7"), + "24.20.0-linux_ppc64le": ("node-v24.20.0-linux-ppc64le.tar.xz", "node-v24.20.0-linux-ppc64le", "341307dcee20d88332307008f2a480450c54f42d5149e7c4c8a18d937e37b5c1"), + "24.20.0-linux_s390x": ("node-v24.20.0-linux-s390x.tar.xz", "node-v24.20.0-linux-s390x", "ca381121cb5a8d38c2954b6699cea09a83fba1b03141a71a8348f08df02de245"), + "24.20.0-linux_amd64": ("node-v24.20.0-linux-x64.tar.xz", "node-v24.20.0-linux-x64", "2f2c0da162318f0de47665410c7c8c2ed3d36c8f3105de4bbc61176c70a7cbf2"), + "24.20.0-windows_amd64": ("node-v24.20.0-win-x64.zip", "node-v24.20.0-win-x64", "6cac9ffbca8f6a47091e4b5c772e0606049c3871cb67d900c0cedde630e545ba"), }, - node_version = "24.19.0", + node_version = "24.20.0", ) use_repo( node, From a90512dbc43a8db1c4eae6ef02a291265915622d Mon Sep 17 00:00:00 2001 From: Charles Lyding <19598772+clydin@users.noreply.github.com> Date: Tue, 25 Aug 2026 17:10:25 -0400 Subject: [PATCH 366/787] refactor(@angular/build): cache persistent binary translation buffers in i18n inliner Persist binary SharedArrayBuffer translation layouts on disk in .angular/cache keyed by translation file integrity hash. The I18nInliner creates a dedicated #translationCache instance under namespace 'translations' alongside #transformedFileCache under namespace 'transforms'. During locale serialization, translationCache.getOrCreate deduplicates in-flight encoding and restores pre-built binary buffers directly from disk, skipping translation dictionary binary encoding on warm builds. --- .../build/src/builders/application/i18n.ts | 9 +- .../build/src/tools/esbuild/i18n-inliner.ts | 99 ++++++++++++----- .../src/tools/esbuild/i18n-inliner_spec.ts | 100 ++++++++++++++++++ 3 files changed, 177 insertions(+), 31 deletions(-) diff --git a/packages/angular/build/src/builders/application/i18n.ts b/packages/angular/build/src/builders/application/i18n.ts index 058a2fa3d6a4..5d7efd7548f9 100644 --- a/packages/angular/build/src/builders/application/i18n.ts +++ b/packages/angular/build/src/builders/application/i18n.ts @@ -161,19 +161,20 @@ export async function inlineI18n( if (executionResult.templateUpdates?.size) { // The development server only allows a single locale but issue a warning if used programmatically (experimental) // with multiple locales and template HMR. - if (i18nOptions.inlineLocales.size > 1) { + if (localesToInline.length > 1) { inlineResult.warnings.push( `Component HMR updates can only be inlined with a single locale. The first locale will be used.`, ); } - const firstLocale = [...i18nOptions.inlineLocales][0]; + const targetLocale = localesToInline[0]; for (const [id, content] of executionResult.templateUpdates) { const templateUpdateResult = await inliner.inlineTemplateUpdate( - firstLocale, - i18nOptions.locales[firstLocale].translation, + targetLocale.locale, + targetLocale.translation, content, id, + targetLocale.translationIntegrity, ); executionResult.templateUpdates.set(id, templateUpdateResult.code); inlineResult.errors.push(...templateUpdateResult.errors); diff --git a/packages/angular/build/src/tools/esbuild/i18n-inliner.ts b/packages/angular/build/src/tools/esbuild/i18n-inliner.ts index 5cca10c534c9..b09229737bf6 100644 --- a/packages/angular/build/src/tools/esbuild/i18n-inliner.ts +++ b/packages/angular/build/src/tools/esbuild/i18n-inliner.ts @@ -36,16 +36,46 @@ const DEFAULT_LOCALE_WINDOW_SIZE = 8; * SharedArrayBuffer is unavailable. * * @param translation The translation messages for a locale, if the locale has any. + * @param translationIntegrity Optional content hash of the translation file for cache lookup. + * @param translationCache Optional Cache instance for binary translation buffers. * @returns A SharedArrayBuffer or Blob containing the serialized messages, or undefined if none. */ -function serializeTranslation( +async function serializeTranslation( translation: Record | undefined, -): SharedArrayBuffer | Blob | undefined { + translationIntegrity?: string, + translationCache?: Cache, +): Promise { if (!translation) { return undefined; } if (typeof SharedArrayBuffer !== 'undefined') { + if (translationIntegrity && translationCache) { + // Look up or generate binary translation data in the persistent cache. + // A Uint8Array view is stored in the cache store to allow binary persistence. + const binaryData = await translationCache.getOrCreate(translationIntegrity, () => { + return new Uint8Array(encodeTranslationToBuffer(translation)); + }); + + // On a cache miss, getOrCreate returns the newly created Uint8Array backed by the + // original SharedArrayBuffer. Return it directly to avoid an unnecessary allocation and copy. + if ( + binaryData.buffer instanceof SharedArrayBuffer && + binaryData.byteOffset === 0 && + binaryData.byteLength === binaryData.buffer.byteLength + ) { + return binaryData.buffer; + } + + // On a warm cache hit, the restored data is backed by a standard ArrayBuffer from disk. + // Copy it into a SharedArrayBuffer so worker threads can access it via zero-copy shared memory. + const buffer = new SharedArrayBuffer(binaryData.byteLength); + new Uint8Array(buffer).set(binaryData); + + return buffer; + } + + // When persistent caching is not configured, encode directly into a SharedArrayBuffer. return encodeTranslationToBuffer(translation); } @@ -145,7 +175,8 @@ export class I18nInliner { #cacheInitFailed = false; #workerPool: WorkerPool; #cacheStore: PersistentCacheStore | undefined; - #cache: Cache | undefined; + #transformedFileCache: Cache | undefined; + #translationCache: Cache | undefined; readonly #localizeFiles: ReadonlyMap; readonly #unmodifiedFiles: Array; @@ -239,6 +270,7 @@ export class I18nInliner { const fileResultsByLocale = new Map>(); for (const { locale } of localeList) { + assert(!fileResultsByLocale.has(locale), 'Duplicate locale provided to inliner: ' + locale); fileResultsByLocale.set(locale, new Map()); } @@ -256,23 +288,30 @@ export class I18nInliner { const localeCacheBases = new Map(); const localeBlobs = new Map(); - for (const { locale, translation, translationIntegrity } of windowLocales) { - localeBlobs.set(locale, serializeTranslation(translation)); - - if (this.#cacheStore) { - localeCacheBases.set( - locale, - calculateHash( - JSON.stringify({ - locale, - translation: translationIntegrity || translation, - missingTranslation, - localizeVersion, - }), - ), + await Promise.all( + windowLocales.map(async ({ locale, translation, translationIntegrity }) => { + const serialized = await serializeTranslation( + translation, + translationIntegrity, + this.#translationCache, ); - } - } + localeBlobs.set(locale, serialized); + + if (this.#cacheStore) { + localeCacheBases.set( + locale, + calculateHash( + JSON.stringify({ + locale, + translation: translationIntegrity || translation, + missingTranslation, + localizeVersion, + }), + ), + ); + } + }), + ); const cacheChecks: CacheCheckItem[] = []; @@ -284,7 +323,7 @@ export class I18nInliner { let cacheKey: string | undefined; let cachedResultPromise: Promise = Promise.resolve(null); - if (this.#cache) { + if (this.#transformedFileCache) { const fileCacheKeyBase = localeCacheBases.get(locale); assert(fileCacheKeyBase !== undefined, 'Cache base must exist for locale: ' + locale); @@ -294,7 +333,7 @@ export class I18nInliner { hasher.update(fileCacheKeyBase); cacheKey = hasher.digest(); - cachedResultPromise = this.#cache + cachedResultPromise = this.#transformedFileCache .get(cacheKey) .then((val) => val ?? null) .catch(() => null); @@ -458,8 +497,8 @@ export class I18nInliner { for (const { locale, cacheKey } of batchEntries) { fileResultsByLocale.get(locale)?.set(filename, unmodifiedResult); - if (this.#cache && cacheKey) { - cachePromises.push(this.#cache.put(cacheKey, unmodifiedResult)); + if (this.#transformedFileCache && cacheKey) { + cachePromises.push(this.#transformedFileCache.put(cacheKey, unmodifiedResult)); } } await Promise.allSettled(cachePromises); @@ -469,9 +508,9 @@ export class I18nInliner { const matchingEntry = batchEntries.find((e) => e.locale === res.locale); const cacheKey = matchingEntry?.cacheKey; - if (this.#cache && cacheKey) { + if (this.#transformedFileCache && cacheKey) { cachePromises.push( - this.#cache.put(cacheKey, { + this.#transformedFileCache.put(cacheKey, { file: filename, code: res.code, map: res.map, @@ -519,6 +558,7 @@ export class I18nInliner { translation: Record | undefined, templateCode: string, templateId: string, + translationIntegrity?: string, ): Promise<{ code: string; errors: string[]; warnings: string[] }> { const hasLocalize = templateCode.includes(LOCALIZE_KEYWORD); @@ -535,7 +575,11 @@ export class I18nInliner { code: templateCode, filename: templateId, locale, - translation: serializeTranslation(translation), + translation: await serializeTranslation( + translation, + translationIntegrity, + this.#translationCache, + ), }, { name: 'inlineCode' }, ); @@ -589,7 +633,8 @@ export class I18nInliner { createPersistentCacheStore(join(persistentCachePath, 'angular-i18n')), ]); this.#cacheStore = cacheStore; - this.#cache = cacheStore.createCache('transforms'); + this.#transformedFileCache = cacheStore.createCache('transforms'); + this.#translationCache = cacheStore.createCache('translations'); } catch { this.#cacheInitFailed = true; diff --git a/packages/angular/build/src/tools/esbuild/i18n-inliner_spec.ts b/packages/angular/build/src/tools/esbuild/i18n-inliner_spec.ts index d2f5559f5bb2..00d5260fc591 100644 --- a/packages/angular/build/src/tools/esbuild/i18n-inliner_spec.ts +++ b/packages/angular/build/src/tools/esbuild/i18n-inliner_spec.ts @@ -13,6 +13,7 @@ import os from 'node:os'; import path from 'node:path'; import { initializeHash } from '../../utils/hash'; import { type BuildOutputFile, BuildOutputFileType, createOutputFile } from './bundler-files'; +import { createPersistentCacheStore } from './cache'; import { I18nInliner } from './i18n-inliner'; /** @@ -213,6 +214,34 @@ describe('I18nInliner', () => { expect(code).toBe(source); }); + + it('inlines translations with translationIntegrity and persistent caching', async () => { + const cacheDir = await fs.mkdtemp(path.join(os.tmpdir(), 'i18n-template-cache-test-')); + + try { + const inliner = new I18nInliner({ + missingTranslation: 'error', + outputFiles: [], + persistentCachePath: cacheDir, + }); + + const translationIntegrity = 'hash-template-integrity-123'; + const { code, errors, warnings } = await inliner.inlineTemplateUpdate( + 'fr', + { greeting: translationFor('Bonjour') }, + GREETING_SOURCE, + 'template-id', + translationIntegrity, + ); + + expect(errors).toEqual([]); + expect(warnings).toEqual([]); + expect(code).toContain('"Bonjour"'); + await inliner.close(); + } finally { + await fs.rm(cacheDir, { recursive: true, force: true }); + } + }); }); it('safely inlines translations containing special characters, quotes, and newlines', async () => { @@ -723,4 +752,75 @@ describe('I18nInliner', () => { await fs.rm(cacheDir, { recursive: true, force: true }); } }); + + it('caches binary translation buffer in persistent cache store when translationIntegrity is provided', async () => { + const cacheDir = await fs.mkdtemp(path.join(os.tmpdir(), 'i18n-inliner-trans-cache-test-')); + + try { + const inliner1 = new I18nInliner({ + missingTranslation: 'error', + outputFiles: [browserFile('main.js', GREETING_SOURCE)], + persistentCachePath: cacheDir, + }); + + const translationIntegrity = 'hash-test-integrity-12345'; + const results1 = await inliner1.inlineAll([ + { + locale: 'fr', + translation: { greeting: translationFor('Bonjour') }, + translationIntegrity, + }, + ]); + + expect(results1.get('fr')?.errors).toEqual([]); + expect(findFile(results1.get('fr')?.outputFiles ?? [], 'main.js').text).toContain( + '"Bonjour"', + ); + await inliner1.close(); + + // Verify directly that the binary translation buffer was persisted on disk + const store = await createPersistentCacheStore(path.join(cacheDir, 'angular-i18n')); + try { + const translationCache = store.createCache('translations'); + const cachedData = await translationCache.get(translationIntegrity); + expect(cachedData).toBeInstanceOf(Uint8Array); + expect(cachedData?.byteLength).toBeGreaterThan(0); + } finally { + await store.close(); + } + + const inliner2 = new I18nInliner({ + missingTranslation: 'error', + outputFiles: [browserFile('main.js', GREETING_SOURCE)], + persistentCachePath: cacheDir, + }); + + const results2 = await inliner2.inlineAll([ + { + locale: 'fr', + translation: { greeting: translationFor('Bonjour') }, + translationIntegrity, + }, + ]); + + expect(results2.get('fr')?.errors).toEqual([]); + expect(findFile(results2.get('fr')?.outputFiles ?? [], 'main.js').text).toContain( + '"Bonjour"', + ); + await inliner2.close(); + } finally { + await fs.rm(cacheDir, { recursive: true, force: true }); + } + }); + + it('throws an error when duplicate locales are provided to inlineAll', async () => { + const localeInliner = createInliner([browserFile('main.js', GREETING_SOURCE)]); + + await expectAsync( + localeInliner.inlineAll([ + { locale: 'fr', translation: { greeting: translationFor('Bonjour') } }, + { locale: 'fr', translation: { greeting: translationFor('Salut') } }, + ]), + ).toBeRejectedWithError(/Duplicate locale provided to inliner: fr/); + }); }); From fc80beb8831169c7066d4e2e1ab5e3a3a7c2373d Mon Sep 17 00:00:00 2001 From: Charles Lyding <19598772+clydin@users.noreply.github.com> Date: Thu, 27 Aug 2026 20:36:40 -0400 Subject: [PATCH 367/787] refactor(@angular/build): pass code and sourcemap Blobs on demand per batch request in i18n inliner Streamline WorkerPool initialization by removing global files Map from workerData. Instead of storing all file Blobs in workerData for the worker pool lifetime, pass code and sourcemap Blobs on demand per inlineFileBatch request. On the worker thread, loadFileData consumes the passed code Blob on initial cache misses and continues to cache pre-parsed OXC AST metadata in worker thread memory, preserving 100% of worker AST parsing speed while improving V8 Young Generation garbage collection. --- .../src/tools/esbuild/i18n-inliner-worker.ts | 37 ++++++++++++------- .../build/src/tools/esbuild/i18n-inliner.ts | 13 +++---- 2 files changed, 29 insertions(+), 21 deletions(-) diff --git a/packages/angular/build/src/tools/esbuild/i18n-inliner-worker.ts b/packages/angular/build/src/tools/esbuild/i18n-inliner-worker.ts index e7b11cc53225..430a174326e6 100644 --- a/packages/angular/build/src/tools/esbuild/i18n-inliner-worker.ts +++ b/packages/angular/build/src/tools/esbuild/i18n-inliner-worker.ts @@ -49,11 +49,20 @@ interface InlineCodeRequest { */ interface InlineFileBatchRequest { /** - * The filename that should be processed. The data for the file is provided to the Worker - * during Worker initialization. + * The filename that should be processed. */ filename: string; + /** + * The file content as a Blob. + */ + code: Blob; + + /** + * Optional sourcemap content as a Blob. + */ + map?: Blob; + /** * The locale specifiers and optional translations to use during the inlining process of the file. */ @@ -97,9 +106,8 @@ type InlineFileBatchResult = results: InlineLocaleResult[]; }; -// Extract the application files and common options used for inline requests from the Worker context -const { files, missingTranslation } = (workerData || {}) as { - files: ReadonlyMap; +// Extract common options used for inline requests from the Worker context +const { missingTranslation } = (workerData || {}) as { missingTranslation: 'error' | 'warning' | 'ignore'; }; @@ -128,20 +136,18 @@ const deserializedTranslations = new Map { +function loadFileData(filename: string, codeBlob: Blob, cache = true): Promise { const existing = fileDataCache.get(filename); if (existing) { return existing; } const fileDataPromise = (async () => { - const data = files.get(filename); - assert(data !== undefined, `Invalid inline request for file '${filename}'.`); - - const code = await data.text(); + const code = await codeBlob.text(); const metadata = extractLocalizeMetadata(filename, code); return { code, metadata }; @@ -209,7 +215,7 @@ export async function inlineFileBatch( } } - const { code, metadata } = await loadFileData(request.filename, !request.ephemeral); + const { code, metadata } = await loadFileData(request.filename, request.code, !request.ephemeral); // Fast path: file has no $localize call sites or locale insert sites if (metadata.callSites.length === 0 && metadata.localeInsertSites.length === 0) { @@ -223,10 +229,13 @@ export async function inlineFileBatch( }; } - // Parse the sourcemap once for the entire batch. + // Parse the sourcemap once for the entire batch if provided. // It will naturally be garbage-collected after this batch action returns. - const rawMap = await files.get(request.filename + '.map')?.text(); - const map = rawMap ? (JSON.parse(rawMap) as SourceMapInput) : undefined; + let map: SourceMapInput | undefined; + if (request.map) { + const rawMap = await request.map.text(); + map = rawMap ? (JSON.parse(rawMap) as SourceMapInput) : undefined; + } const results = await Promise.all( Array.from(request.locales, async ([locale, translation]) => { diff --git a/packages/angular/build/src/tools/esbuild/i18n-inliner.ts b/packages/angular/build/src/tools/esbuild/i18n-inliner.ts index b09229737bf6..e8f8e67462c2 100644 --- a/packages/angular/build/src/tools/esbuild/i18n-inliner.ts +++ b/packages/angular/build/src/tools/esbuild/i18n-inliner.ts @@ -236,13 +236,6 @@ export class I18nInliner { // Extract options to ensure only the named options are serialized and sent to the worker workerData: { missingTranslation, - // A Blob is an immutable data structure that allows sharing the data between workers - // without copying until the data is actually used within a Worker. This is useful here - // since each file may not actually be processed in each Worker and the Blob avoids - // unneeded repeat copying of potentially large JavaScript files. - files: new Map( - Array.from(files, ([name, file]) => [name, new Blob([file.contents])]), - ), }, }); } @@ -463,6 +456,10 @@ export class I18nInliner { const workerTasks: Promise[] = []; for (const [filename, entries] of uncachedByFile) { + const codeFile = this.#localizeFiles.get(filename); + assert(codeFile !== undefined, 'Localize file must exist: ' + filename); + const mapFile = this.#localizeFiles.get(filename + '.map'); + const ephemeral = isLastWindow && entries.length <= localesPerBatch; for (let i = 0; i < entries.length; i += localesPerBatch) { const batchEntries = entries.slice(i, i + localesPerBatch); @@ -470,6 +467,8 @@ export class I18nInliner { const batchResult = (await this.#workerPool.run( { filename, + code: new Blob([codeFile.contents]), + map: mapFile ? new Blob([mapFile.contents]) : undefined, locales: new Map(batchEntries.map((e) => [e.locale, e.translation])), ephemeral, activeLocales, From 2b85529e8290c8c916539b5a0336b4efdb68578c Mon Sep 17 00:00:00 2001 From: Charles Lyding <19598772+clydin@users.noreply.github.com> Date: Thu, 27 Aug 2026 12:41:15 -0400 Subject: [PATCH 368/787] perf(@angular/build): use iterative post-order AST traversal for OXC transforms Replace the recursive Visitor class from oxc-parser with a specialized iterative post-order AST traversal implementation. The new traversal implementation eliminates per-file visitor instantiation and internal cache overhead, prunes non-executable TypeScript type subtrees at the root, and uses monomorphic property access for high-frequency AST node types. It also provides stack safety with a single tree-depth array stack and is shared between the OXC transformer and the i18n inliner worker. --- .../src/tools/esbuild/i18n-inliner-worker.ts | 54 +-- .../build/src/tools/oxc/oxc-transform.ts | 218 +++++------ .../angular/build/src/tools/oxc/traversal.ts | 354 ++++++++++++++++++ 3 files changed, 445 insertions(+), 181 deletions(-) create mode 100644 packages/angular/build/src/tools/oxc/traversal.ts diff --git a/packages/angular/build/src/tools/esbuild/i18n-inliner-worker.ts b/packages/angular/build/src/tools/esbuild/i18n-inliner-worker.ts index 430a174326e6..269341c3df81 100644 --- a/packages/angular/build/src/tools/esbuild/i18n-inliner-worker.ts +++ b/packages/angular/build/src/tools/esbuild/i18n-inliner-worker.ts @@ -13,7 +13,8 @@ import { MagicString } from 'magic-string'; import assert from 'node:assert'; import { deserialize } from 'node:v8'; import { workerData } from 'node:worker_threads'; -import { parseSync, visitorKeys } from 'oxc-parser'; +import { parseSync } from 'oxc-parser'; +import { traversePostOrder } from '../oxc/traversal'; import { loadLocaleData } from './i18n-locale-plugin'; import { createSharedTranslationProxy } from './i18n-translation-reader'; @@ -312,55 +313,6 @@ async function loadLocalizeTools(): Promise { return localizeToolsModule; } -/** - * Traverses ESTree AST nodes in post-order (bottom-up) without recursion. - * Bottom-up traversal ensures that nested `$localize` expressions are transformed and - * written to MagicString before outer containing templates are evaluated. - * - * @param root The root AST node to traverse. - * @param onExit Callback invoked on each AST node in post-order. - */ -function walkAstPostOrder(root: Node, onExit: (node: Node) => void): void { - const traverseStack: Node[] = [root]; - const postOrderNodes: Node[] = []; - - while (traverseStack.length > 0) { - const current = traverseStack.pop(); - if (!current) { - continue; - } - - postOrderNodes.push(current); - - const keys = visitorKeys[current.type]; - if (!keys) { - continue; - } - - for (let i = 0; i < keys.length; i++) { - const child = (current as unknown as Record)[keys[i]]; - if (!child) { - continue; - } - - if (Array.isArray(child)) { - for (const item of child) { - if (item) { - traverseStack.push(item); - } - } - } else { - traverseStack.push(child); - } - } - } - - // Process collected nodes in reverse order to achieve bottom-up (post-order) traversal - for (let i = postOrderNodes.length - 1; i >= 0; i--) { - onExit(postOrderNodes[i]); - } -} - /** * Metadata for a `$localize` tagged template expression extracted from the AST. */ @@ -400,7 +352,7 @@ function extractLocalizeMetadata(filename: string, code: string): FileLocalizeMe const localeInsertSites: { start: number; end: number }[] = []; let diagnostics: string[] | undefined; - walkAstPostOrder(program, (node) => { + traversePostOrder(program, (node) => { if (node.type === 'Literal') { if (typeof node.value === 'string' && node.value === '___NG_LOCALE_INSERT___') { localeInsertSites.push({ start: node.start, end: node.end }); diff --git a/packages/angular/build/src/tools/oxc/oxc-transform.ts b/packages/angular/build/src/tools/oxc/oxc-transform.ts index c0389a9f75a4..0ebbc04ec1e5 100644 --- a/packages/angular/build/src/tools/oxc/oxc-transform.ts +++ b/packages/angular/build/src/tools/oxc/oxc-transform.ts @@ -10,8 +10,9 @@ import type { DecodedSourceMap } from '@ampproject/remapping'; import { needsLinking } from '@angular/compiler-cli/linker'; import type { BindingIdentifier, Class, Node } from '@oxc-project/types'; import { MagicString } from 'magic-string'; -import { Visitor, parseSync } from 'oxc-parser'; +import { parseSync } from 'oxc-parser'; import { OxcLinker } from '../angular/linker/oxc-linker'; +import { traversePostOrder } from './traversal'; export interface OxcTransformOptions { sourcemap?: boolean; @@ -320,11 +321,6 @@ export function transform(filename: string, code: string, options: OxcTransformO return editedRanges.some((r) => start >= r.start && end <= r.end); } - // Track function nesting depth and closest function expression wrapper - let functionDepth = 0; - let classDepth = 0; - const functionStack: Node[] = []; - /** * Scans and rewrites TypeScript emitted enum declarations in the statement block. * Wraps enum statements inside a pure IIFE assignable directly to the enum variable. @@ -630,153 +626,115 @@ export function transform(filename: string, code: string, options: OxcTransformO } } - const visitor = new Visitor({ - ClassDeclaration(node) { - classDepth++; - }, - 'ClassDeclaration:exit'() { - classDepth--; - }, - ClassExpression(node) { - classDepth++; - }, - 'ClassExpression:exit'() { - classDepth--; - }, - FunctionDeclaration(node) { - functionDepth++; - functionStack.push(node); - }, - 'FunctionDeclaration:exit'() { - functionDepth--; - functionStack.pop(); - }, - FunctionExpression(node) { - functionDepth++; - functionStack.push(node); - }, - 'FunctionExpression:exit'() { - functionDepth--; - functionStack.pop(); - }, - ArrowFunctionExpression(node) { - functionDepth++; - functionStack.push(node); - }, - 'ArrowFunctionExpression:exit'() { - functionDepth--; - functionStack.pop(); - }, - 'Program:exit'(node) { - if (advancedOptimizations) { - adjustTypeScriptEnumsInStatements(node.body); - adjustStaticMembersInStatements(node.body); - } - }, - 'BlockStatement:exit'(node) { - if (advancedOptimizations) { - adjustTypeScriptEnumsInStatements(node.body); - adjustStaticMembersInStatements(node.body); - } - }, - CallExpression(node) { - if (isAlreadyEdited(node.start, node.end)) { - return; - } + traversePostOrder(program, (node, { functionDepth, classDepth, parentFunc }) => { + switch (node.type) { + case 'Program': + case 'BlockStatement': + if (advancedOptimizations) { + adjustTypeScriptEnumsInStatements(node.body); + adjustStaticMembersInStatements(node.body); + } + break; + + case 'CallExpression': { + if (isAlreadyEdited(node.start, node.end)) { + return; + } + + if (linker) { + const linkedCode = linker.linkCallExpression(node); + if (linkedCode !== undefined) { + source.overwrite(node.start, node.end, linkedCode); + markEdited(node.start, node.end); - if (linker) { - const linkedCode = linker.linkCallExpression(node); - if (linkedCode !== undefined) { - source.overwrite(node.start, node.end, linkedCode); - markEdited(node.start, node.end); + return; + } + } + if (!advancedOptimizations) { return; } - } - if (!advancedOptimizations) { - return; - } + // 1. Elide Angular Metadata check + let calleeName: string | undefined; + if (node.callee.type === 'Identifier') { + calleeName = node.callee.name; + } else if ( + node.callee.type === 'MemberExpression' && + node.callee.property.type === 'Identifier' + ) { + calleeName = node.callee.property.name; + } - // 1. Elide Angular Metadata check - let calleeName: string | undefined; - if (node.callee.type === 'Identifier') { - calleeName = node.callee.name; - } else if ( - node.callee.type === 'MemberExpression' && - node.callee.property.type === 'Identifier' - ) { - calleeName = node.callee.property.name; - } + if (calleeName && angularMetadataFunctions.has(calleeName)) { + if ( + parentFunc && + (parentFunc.type === 'FunctionExpression' || + parentFunc.type === 'ArrowFunctionExpression') + ) { + source.overwrite(node.start, node.end, 'void 0'); + markEdited(node.start, node.end); + + return; + } + } - if (calleeName && angularMetadataFunctions.has(calleeName)) { - const parentFunc = functionStack[functionStack.length - 1]; + // 2. Mark Top-Level Pure Functions check + if (!pureAnnotate || functionDepth > 0 || classDepth > 0 || topLevelSafeMode) { + return; + } + + const callee = unwrapParentheses(node.callee); if ( - parentFunc && - (parentFunc.type === 'FunctionExpression' || - parentFunc.type === 'ArrowFunctionExpression') + (callee.type === 'FunctionExpression' || callee.type === 'ArrowFunctionExpression') && + node.arguments.length !== 0 ) { - source.overwrite(node.start, node.end, 'void 0'); - markEdited(node.start, node.end); - return; } - } - // 2. Mark Top-Level Pure Functions check - if (!pureAnnotate || functionDepth > 0 || classDepth > 0 || topLevelSafeMode) { - return; - } + if ( + callee.type === 'Identifier' && + (isTslibHelperName(callee.name) || isBabelHelperName(callee.name)) + ) { + return; + } - const callee = unwrapParentheses(node.callee); - if ( - (callee.type === 'FunctionExpression' || callee.type === 'ArrowFunctionExpression') && - node.arguments.length !== 0 - ) { - return; + if (!hasPureComment(node.start)) { + source.appendLeft(node.start, '/*#__PURE__*/ '); + } + break; } - if ( - callee.type === 'Identifier' && - (isTslibHelperName(callee.name) || isBabelHelperName(callee.name)) - ) { - return; - } + case 'NewExpression': { + if ( + !advancedOptimizations || + !pureAnnotate || + functionDepth > 0 || + classDepth > 0 || + isAlreadyEdited(node.start, node.end) + ) { + return; + } - if (!hasPureComment(node.start)) { - source.appendLeft(node.start, '/*#__PURE__*/ '); - } - }, - NewExpression(node) { - if ( - !advancedOptimizations || - !pureAnnotate || - functionDepth > 0 || - classDepth > 0 || - isAlreadyEdited(node.start, node.end) - ) { - return; - } + if (!topLevelSafeMode) { + if (!hasPureComment(node.start)) { + source.appendLeft(node.start, '/*#__PURE__*/ '); + } - if (!topLevelSafeMode) { - if (!hasPureComment(node.start)) { - source.appendLeft(node.start, '/*#__PURE__*/ '); + return; } - return; - } - - const callee = node.callee; - if (callee.type === 'Identifier' && sideEffectFreeConstructors.has(callee.name)) { - if (!hasPureComment(node.start)) { - source.appendLeft(node.start, '/*#__PURE__*/ '); + const newCallee = node.callee; + if (newCallee.type === 'Identifier' && sideEffectFreeConstructors.has(newCallee.name)) { + if (!hasPureComment(node.start)) { + source.appendLeft(node.start, '/*#__PURE__*/ '); + } } + break; } - }, + } }); - visitor.visit(program); - let map: DecodedSourceMap | undefined; if (options.sourcemap) { const rawMap = source.generateDecodedMap({ hires: true, source: filename }); diff --git a/packages/angular/build/src/tools/oxc/traversal.ts b/packages/angular/build/src/tools/oxc/traversal.ts new file mode 100644 index 000000000000..f25f4bc78664 --- /dev/null +++ b/packages/angular/build/src/tools/oxc/traversal.ts @@ -0,0 +1,354 @@ +/** + * @license + * Copyright Google LLC All Rights Reserved. + * + * Use of this source code is governed by an MIT-style license that can be + * found in the LICENSE file at https://angular.dev/license + */ + +import type { Node } from '@oxc-project/types'; +import { visitorKeys } from 'oxc-parser'; + +/** + * Contextual scope information provided to AST visitor callbacks during traversal. + */ +export interface TraversalContext { + /** + * The current function nesting depth. Top-level code has depth 0. + */ + functionDepth: number; + + /** + * The current class nesting depth. Top-level code has depth 0. + */ + classDepth: number; + + /** + * The immediate enclosing function AST node, if currently inside a function. + */ + parentFunc?: Node; +} + +/** + * A set of TypeScript AST node types that contain executable code or runtime declarations. + */ +const executableTypeScriptNodes = new Set([ + 'TSEnumDeclaration', + 'TSEnumBody', + 'TSEnumMember', + 'TSModuleDeclaration', + 'TSModuleBlock', + 'TSParameterProperty', + 'TSImportEqualsDeclaration', + 'TSExternalModuleReference', +]); + +/** + * Determines whether the given AST node type represents a function declaration or expression. + * + * @param type The AST node type to check. + * @returns True if the type is a function; otherwise, false. + */ +function isFunction(type: Node['type']): boolean { + return ( + type === 'FunctionDeclaration' || + type === 'FunctionExpression' || + type === 'ArrowFunctionExpression' + ); +} + +/** + * Determines whether the given AST node type represents a class declaration or expression. + * + * @param type The AST node type to check. + * @returns True if the type is a class; otherwise, false. + */ +function isClass(type: Node['type']): boolean { + return type === 'ClassDeclaration' || type === 'ClassExpression'; +} + +/** + * Determines whether the given AST node type represents a non-executable TypeScript type-only node. + * Executable TypeScript nodes (e.g. enums, namespaces, parameter properties) return false. + * + * @param type The AST node type to check. + * @returns True if the type is a TypeScript type construct that can be safely pruned; otherwise, false. + */ +function isTypeOnlyTypeScriptNode(type: Node['type']): boolean { + return type.startsWith('TS') && !executableTypeScriptNodes.has(type); +} + +/** + * Pushes an array of AST nodes onto the traversal stack in reverse order. + * + * @param nodes The array of child AST nodes to push. + * @param stack The traversal stack. + */ +function pushNodesReverse( + nodes: readonly (Node | null | undefined)[] | undefined, + stack: (Node | null)[], +): void { + if (nodes) { + for (let i = nodes.length - 1; i >= 0; i--) { + const item = nodes[i]; + if (item) { + stack.push(item); + } + } + } +} + +/** + * Pushes child AST nodes of the specified node onto the traversal stack in reverse order + * so they are visited in source order. + * + * Explicit cases are provided for the most common AST node types (~95%+ of AST nodes) to: + * 1. Fast-path leaf nodes and frequent expressions/statements by avoiding dynamic `visitorKeys` + * dictionary lookups, string indexing, and dynamic array iteration. + * 2. Prune non-executable TypeScript type subtrees (e.g. `typeAnnotation`, `typeParameters`, + * `returnType`, `implements`) so traversal only processes executable JavaScript expressions. + * + * All other less frequent node types fall back to the `visitorKeys` lookup in `default:`. + * + * @param node The parent AST node whose children to push. + * @param stack The traversal stack. + */ +function pushChildNodes(node: Node, stack: (Node | null)[]): void { + switch (node.type) { + // High-frequency leaf nodes (~50% of AST) + case 'Identifier': + case 'PrivateIdentifier': + case 'Literal': + case 'ThisExpression': + break; + + case 'Program': + case 'BlockStatement': + case 'ClassBody': + case 'StaticBlock': + pushNodesReverse(node.body, stack); + break; + + case 'ExpressionStatement': + case 'ParenthesizedExpression': + case 'ChainExpression': + case 'TSNonNullExpression': + case 'TSAsExpression': + case 'TSTypeAssertion': + case 'TSSatisfiesExpression': + case 'TSInstantiationExpression': + case 'TSExportAssignment': + if (node.expression) { + stack.push(node.expression); + } + break; + + case 'CallExpression': + case 'NewExpression': + pushNodesReverse(node.arguments, stack); + if (node.callee) { + stack.push(node.callee); + } + break; + + case 'MemberExpression': + if (node.property) { + stack.push(node.property); + } + if (node.object) { + stack.push(node.object); + } + break; + + case 'BinaryExpression': + case 'LogicalExpression': + case 'AssignmentExpression': + if (node.right) { + stack.push(node.right); + } + if (node.left) { + stack.push(node.left); + } + break; + + case 'UnaryExpression': + case 'UpdateExpression': + case 'AwaitExpression': + case 'YieldExpression': + case 'ReturnStatement': + case 'ThrowStatement': + if (node.argument) { + stack.push(node.argument); + } + break; + + case 'IfStatement': + case 'ConditionalExpression': + if (node.alternate) { + stack.push(node.alternate); + } + if (node.consequent) { + stack.push(node.consequent); + } + if (node.test) { + stack.push(node.test); + } + break; + + case 'VariableDeclaration': + pushNodesReverse(node.declarations, stack); + break; + + case 'VariableDeclarator': + if (node.init) { + stack.push(node.init); + } + if (node.id) { + stack.push(node.id); + } + break; + + case 'FunctionDeclaration': + case 'FunctionExpression': + case 'ArrowFunctionExpression': + if (node.body) { + stack.push(node.body); + } + pushNodesReverse(node.params, stack); + if (node.id) { + stack.push(node.id); + } + break; + + case 'ClassDeclaration': + case 'ClassExpression': + if (node.body) { + stack.push(node.body); + } + if (node.superClass) { + stack.push(node.superClass); + } + if (node.id) { + stack.push(node.id); + } + pushNodesReverse(node.decorators, stack); + break; + + case 'Property': + case 'PropertyDefinition': + case 'MethodDefinition': + if (node.value) { + stack.push(node.value); + } + if (node.key) { + stack.push(node.key); + } + if (node.type !== 'Property') { + pushNodesReverse(node.decorators, stack); + } + break; + + case 'ObjectExpression': + pushNodesReverse(node.properties, stack); + break; + + case 'ArrayExpression': + pushNodesReverse(node.elements, stack); + break; + + case 'TemplateLiteral': + pushNodesReverse(node.expressions, stack); + break; + + case 'TaggedTemplateExpression': + if (node.quasi) { + stack.push(node.quasi); + } + if (node.tag) { + stack.push(node.tag); + } + break; + + default: { + // Prune non-executable TypeScript type-only AST nodes (e.g. TSTypeAnnotation, TSTypeReference, etc.) + if (isTypeOnlyTypeScriptNode(node.type)) { + break; + } + + const keys = visitorKeys[node.type]; + if (!keys) { + break; + } + + for (let i = keys.length - 1; i >= 0; i--) { + const child = ( + node as unknown as Record + )[keys[i]]; + if (!child) { + continue; + } + + if (Array.isArray(child)) { + pushNodesReverse(child, stack); + } else { + stack.push(child); + } + } + break; + } + } +} + +/** + * Traverses ESTree AST nodes in post-order (bottom-up) without recursion. + * + * @param root The root AST node to traverse. + * @param visit Callback invoked on each AST node in post-order. + */ +export function traversePostOrder( + root: Node, + visit: (node: Node, context: TraversalContext) => void, +): void { + const stack: (Node | null)[] = [root]; + let functionDepth = 0; + let classDepth = 0; + const functionStack: Node[] = []; + + while (stack.length > 0) { + const current = stack.pop(); + if (current === undefined) { + break; + } + if (current === null) { + const node = stack.pop(); + if (!node) { + continue; + } + const type = node.type; + if (isFunction(type)) { + functionDepth--; + functionStack.pop(); + } else if (isClass(type)) { + classDepth--; + } + visit(node, { + functionDepth, + classDepth, + parentFunc: functionStack[functionStack.length - 1], + }); + continue; + } + + stack.push(current); + stack.push(null); + const type = current.type; + if (isFunction(type)) { + functionDepth++; + functionStack.push(current); + } else if (isClass(type)) { + classDepth++; + } + + pushChildNodes(current, stack); + } +} From 4b8c62a8f1a1d312ef2e1e0df6b7642bf1db5c5f Mon Sep 17 00:00:00 2001 From: Alan Agius <17563226+alan-agius4@users.noreply.github.com> Date: Fri, 28 Aug 2026 14:37:10 +0000 Subject: [PATCH 369/787] fix(@angular/build): add splitting option to unit-test builder Adds a `splitting` option to the unit-test builder to control code splitting for the test build with the Vitest runner. This option is enabled by default to optimize test bundling performance and memory consumption, avoiding issues during code coverage collection. For Node-based test environments where live ESM bindings across chunk boundaries cause issues (such as uninitialized exports or mocking failures), splitting can be disabled. Closes #33960 and closes #33948 --- goldens/public-api/angular/build/index.api.md | 1 + .../build/src/builders/unit-test/options.ts | 14 +- .../unit-test/runners/vitest/build-options.ts | 5 +- .../build/src/builders/unit-test/schema.json | 5 + .../behavior/vitest-shared-chunk-init_spec.ts | 1 + .../unit-test/tests/options/splitting_spec.ts | 132 ++++++++++++++++++ 6 files changed, 153 insertions(+), 5 deletions(-) create mode 100644 packages/angular/build/src/builders/unit-test/tests/options/splitting_spec.ts diff --git a/goldens/public-api/angular/build/index.api.md b/goldens/public-api/angular/build/index.api.md index 3c0b9bd67c53..c9d83bc6fd9b 100644 --- a/goldens/public-api/angular/build/index.api.md +++ b/goldens/public-api/angular/build/index.api.md @@ -243,6 +243,7 @@ export type UnitTestBuilderOptions = { runner?: Runner; runnerConfig?: RunnerConfig; setupFiles?: string[]; + splitting?: boolean; tsConfig?: string; ui?: boolean; watch?: boolean; diff --git a/packages/angular/build/src/builders/unit-test/options.ts b/packages/angular/build/src/builders/unit-test/options.ts index 7d57716214b1..44f6b6b9208b 100644 --- a/packages/angular/build/src/builders/unit-test/options.ts +++ b/packages/angular/build/src/builders/unit-test/options.ts @@ -67,8 +67,17 @@ export async function normalizeOptions( const cacheOptions = normalizeCacheOptions(projectMetadata, workspaceRoot); cacheOptions.path = path.join(cacheOptions.path, projectName); - const { runner, browsers, progress, filter, browserViewport, ui, runnerConfig, isolate } = - options; + const { + runner, + browsers, + progress, + filter, + browserViewport, + ui, + runnerConfig, + isolate, + splitting = true, + } = options; if (ui && runner !== Runner.Vitest) { throw new Error('The "ui" option is only available for the "vitest" runner.'); @@ -140,6 +149,7 @@ export async function normalizeOptions( debug: options.debug ?? false, ui: process.env['CI'] ? false : ui, isolate, + splitting, quiet: options.quiet ?? (process.env['CI'] ? false : true), providersFile: options.providersFile && path.join(workspaceRoot, options.providersFile), setupFiles: options.setupFiles diff --git a/packages/angular/build/src/builders/unit-test/runners/vitest/build-options.ts b/packages/angular/build/src/builders/unit-test/runners/vitest/build-options.ts index c522d51c2272..9c5abb9386bf 100644 --- a/packages/angular/build/src/builders/unit-test/runners/vitest/build-options.ts +++ b/packages/angular/build/src/builders/unit-test/runners/vitest/build-options.ts @@ -260,9 +260,8 @@ export async function getVitestBuildOptions( entryPoints, // Vitest's Node-based module loading emulation (vite-node) is not fully spec compliant and lacks // live ESM bindings across chunk boundaries. This can cause uninitialized exports or break mocking. - // In browser tests, however, the real browser adheres to the ECMAScript spec, so code splitting can - // be safely enabled. - disableCodeSplitting: options.browsers?.length ? false : true, + // Disabling code splitting avoids shared chunks, but increases build and coverage memory/time. + disableCodeSplitting: !options.splitting, // Enable support for vitest browser prebundling. Excludes can be controlled with a runnerConfig // and the `optimizeDeps.exclude` option. externalPackages: true, diff --git a/packages/angular/build/src/builders/unit-test/schema.json b/packages/angular/build/src/builders/unit-test/schema.json index 0c6c819392f3..5e9a62cf495d 100644 --- a/packages/angular/build/src/builders/unit-test/schema.json +++ b/packages/angular/build/src/builders/unit-test/schema.json @@ -77,6 +77,11 @@ "type": "boolean", "description": "Enables isolation for test execution. When true, Vitest runs tests in separate threads or processes. This option is only available for the Vitest runner. Defaults to false to align with the Karma/Jasmine experience." }, + "splitting": { + "type": "boolean", + "description": "Enables code splitting for test execution. When enabled, shared code between test files is split into separate chunks. Issues with live ESM bindings in Node.js environments (such as uninitialized exports or mocking failures) can be resolved by disabling splitting. This option is only available for the Vitest runner.", + "default": true + }, "quiet": { "type": "boolean", "description": "Suppresses the verbose build summary and stats table on each rebuild. Defaults to `true` locally and `false` in CI environments." diff --git a/packages/angular/build/src/builders/unit-test/tests/behavior/vitest-shared-chunk-init_spec.ts b/packages/angular/build/src/builders/unit-test/tests/behavior/vitest-shared-chunk-init_spec.ts index 13870ba36eba..afccfc2c06e1 100644 --- a/packages/angular/build/src/builders/unit-test/tests/behavior/vitest-shared-chunk-init_spec.ts +++ b/packages/angular/build/src/builders/unit-test/tests/behavior/vitest-shared-chunk-init_spec.ts @@ -37,6 +37,7 @@ describeBuilder(execute, UNIT_TEST_BUILDER_INFO, (harness) => { harness.useTarget('test', { ...BASE_OPTIONS, + splitting: false, }); // Keep the default project's spec deterministic; a third spec entry that does not touch diff --git a/packages/angular/build/src/builders/unit-test/tests/options/splitting_spec.ts b/packages/angular/build/src/builders/unit-test/tests/options/splitting_spec.ts new file mode 100644 index 000000000000..133c54ca21e9 --- /dev/null +++ b/packages/angular/build/src/builders/unit-test/tests/options/splitting_spec.ts @@ -0,0 +1,132 @@ +/** + * @license + * Copyright Google LLC All Rights Reserved. + * + * Use of this source code is governed by an MIT-style license that can be + * found in the LICENSE file at https://angular.dev/license + */ + +import { execute } from '../../index'; +import { + BASE_OPTIONS, + describeBuilder, + UNIT_TEST_BUILDER_INFO, + setupApplicationTarget, + expectLog, + expectNoLog, +} from '../setup'; + +describeBuilder(execute, UNIT_TEST_BUILDER_INFO, (harness) => { + describe('Option: "splitting"', () => { + beforeEach(async () => { + setupApplicationTarget(harness); + }); + + it('should default to true and run tests successfully', async () => { + harness.useTarget('test', { + ...BASE_OPTIONS, + }); + + const { result } = await harness.executeOnce(); + expect(result?.success).toBeTrue(); + }); + + it('should run tests successfully when splitting is true', async () => { + harness.useTarget('test', { + ...BASE_OPTIONS, + splitting: true, + }); + + const { result } = await harness.executeOnce(); + expect(result?.success).toBeTrue(); + }); + + it('should run tests successfully when splitting is false', async () => { + harness.useTarget('test', { + ...BASE_OPTIONS, + splitting: false, + }); + + const { result } = await harness.executeOnce(); + expect(result?.success).toBeTrue(); + }); + + it('should split shared code into a separate chunk when splitting is true', async () => { + await harness.writeFile( + 'src/app/shared.ts', + `export const SHARED_DATA = 'shared-data-value';`, + ); + + await harness.writeFile( + 'src/app/first.spec.ts', + ` + import { SHARED_DATA } from './shared'; + + it('tests first', () => { + expect(SHARED_DATA).toBe('shared-data-value'); + }); + `, + ); + + await harness.writeFile( + 'src/app/second.spec.ts', + ` + import { SHARED_DATA } from './shared'; + + it('tests second', () => { + expect(SHARED_DATA).toBe('shared-data-value'); + }); + `, + ); + + harness.useTarget('test', { + ...BASE_OPTIONS, + splitting: true, + quiet: false, + }); + + const { result, logs } = await harness.executeOnce(); + expect(result?.success).toBeTrue(); + expectLog(logs, /chunk-[a-z0-9]+\.js/i); + }); + + it('should not split shared code into a separate chunk when splitting is false', async () => { + await harness.writeFile( + 'src/app/shared.ts', + `export const SHARED_DATA = 'shared-data-value';`, + ); + + await harness.writeFile( + 'src/app/first.spec.ts', + ` + import { SHARED_DATA } from './shared'; + + it('tests first', () => { + expect(SHARED_DATA).toBe('shared-data-value'); + }); + `, + ); + + await harness.writeFile( + 'src/app/second.spec.ts', + ` + import { SHARED_DATA } from './shared'; + + it('tests second', () => { + expect(SHARED_DATA).toBe('shared-data-value'); + }); + `, + ); + + harness.useTarget('test', { + ...BASE_OPTIONS, + splitting: false, + quiet: false, + }); + + const { result, logs } = await harness.executeOnce(); + expect(result?.success).toBeTrue(); + expectNoLog(logs, /chunk-[a-z0-9]+\.js/i); + }); + }); +}); From bb72145f9ab45aee29f523236b3a25cd0813a841 Mon Sep 17 00:00:00 2001 From: Alan Agius <17563226+alan-agius4@users.noreply.github.com> Date: Fri, 28 Aug 2026 07:36:10 +0000 Subject: [PATCH 370/787] fix(@angular/ssr): ensure public directory containment in CommonEngine Ensure that paths resolved in `retrieveSSGPage` strictly remain within the configured `publicPath` by checking `relative()` containment before evaluating the static file. Previously, a string `startsWith()` check was used, which could match sibling directories that share the same name prefix as `publicPath`. --- .../ssr/node/src/common-engine/common-engine.ts | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/packages/angular/ssr/node/src/common-engine/common-engine.ts b/packages/angular/ssr/node/src/common-engine/common-engine.ts index 8db528f30f34..6af1c0f2727c 100644 --- a/packages/angular/ssr/node/src/common-engine/common-engine.ts +++ b/packages/angular/ssr/node/src/common-engine/common-engine.ts @@ -10,7 +10,7 @@ import { ApplicationRef, StaticProvider, Type } from '@angular/core'; import { BootstrapContext } from '@angular/platform-browser'; import { renderApplication, renderModule, ɵSERVER_CONTEXT } from '@angular/platform-server'; import * as fs from 'node:fs'; -import { dirname, join, normalize, resolve } from 'node:path'; +import { dirname, isAbsolute, join, relative, resolve } from 'node:path'; import { URL } from 'node:url'; import { validateUrl } from '../../../src/utils/validation'; import { getAllowedHostsFromEnv } from '../environment-options'; @@ -155,16 +155,18 @@ export class CommonEngine { // See: https://portswigger.net/web-security/file-path-traversal const pagePath = join(publicPath, pathname, 'index.html'); + const relativePath = relative(publicPath, pagePath); + const isOutside = + relativePath === '..' || relativePath.startsWith('../') || relativePath.startsWith('..\\'); + if (isOutside || isAbsolute(relativePath)) { + return undefined; + } + if (this.pageIsSSG.get(pagePath)) { // Serve pre-rendered page. return fs.promises.readFile(pagePath, 'utf-8'); } - if (!pagePath.startsWith(normalize(publicPath))) { - // Potential path traversal detected. - return undefined; - } - if (pagePath === resolve(documentFilePath) || !(await exists(pagePath))) { // View matches with prerender path or file does not exist. return undefined; From 0e632f101d328d5b88418924601fc8837005e14c Mon Sep 17 00:00:00 2001 From: Charles Lyding <19598772+clydin@users.noreply.github.com> Date: Fri, 28 Aug 2026 16:34:06 -0400 Subject: [PATCH 371/787] refactor(@angular/build): decouple compiler options transformation and remove worker options IPC Move the TypeScript compiler options transformation logic from compiler-plugin.ts into transformCompilerOptions in the compilation layer. This replaces numeric literal values with strongly-typed TypeScript enums and encapsulates options normalization within the compilation classes. Replace the optionsChannel, optionsSignal, and synchronous Atomics barrier between the main thread and the compilation worker thread with serializable CompilerOptionOverrides passed during initialization. Any compiler options transformation warnings are now returned directly in AngularCompilationResult.warnings rather than mutating a main-thread array. --- .../compilation/angular-compilation.ts | 4 +- .../compilation/angular-compilation_spec.ts | 180 +++++++++++++++++- .../angular/compilation/aot-compilation.ts | 14 +- .../angular/compilation/compiler-options.ts | 136 +++++++++++++ .../src/tools/angular/compilation/index.ts | 2 +- .../angular/compilation/jit-compilation.ts | 15 +- .../angular/compilation/noop-compilation.ts | 38 +++- .../compilation/parallel-compilation.ts | 26 +-- .../angular/compilation/parallel-worker.ts | 21 +- .../tools/esbuild/angular/compiler-plugin.ts | 128 ++----------- 10 files changed, 390 insertions(+), 174 deletions(-) create mode 100644 packages/angular/build/src/tools/angular/compilation/compiler-options.ts diff --git a/packages/angular/build/src/tools/angular/compilation/angular-compilation.ts b/packages/angular/build/src/tools/angular/compilation/angular-compilation.ts index 308b0d255df3..ea1fe00d04aa 100644 --- a/packages/angular/build/src/tools/angular/compilation/angular-compilation.ts +++ b/packages/angular/build/src/tools/angular/compilation/angular-compilation.ts @@ -10,6 +10,7 @@ import type * as ng from '@angular/compiler-cli'; import type { PartialMessage } from 'esbuild'; import { profileSync } from '../../esbuild/profiling'; import type { AngularHostOptions } from '../angular-host'; +import type { CompilerOptionOverrides } from './compiler-options'; export interface EmitFileResult { filename: string; @@ -37,6 +38,7 @@ export interface AngularCompilationResult { externalStylesheets?: ReadonlyMap; templateUpdates?: ReadonlyMap; componentResourcesDependencies?: ReadonlyMap; + warnings?: readonly PartialMessage[]; } export enum DiagnosticModes { @@ -82,7 +84,7 @@ export abstract class AngularCompilation { abstract initialize( tsconfig: string, hostOptions: AngularHostOptions, - compilerOptionsTransformer?: (compilerOptions: ng.CompilerOptions) => ng.CompilerOptions, + compilerOptionOverrides?: CompilerOptionOverrides, ): Promise; emitAffectedFiles(): Iterable | Promise> { diff --git a/packages/angular/build/src/tools/angular/compilation/angular-compilation_spec.ts b/packages/angular/build/src/tools/angular/compilation/angular-compilation_spec.ts index 66d21cb52f51..ad28c31bcce5 100644 --- a/packages/angular/build/src/tools/angular/compilation/angular-compilation_spec.ts +++ b/packages/angular/build/src/tools/angular/compilation/angular-compilation_spec.ts @@ -8,12 +8,13 @@ import ts from 'typescript'; import type { AngularHostOptions } from '../angular-host'; +import { transformCompilerOptions } from './compiler-options'; +import { TypeScriptCompilation } from './typescript-compilation'; import { AngularCompilation, AngularCompilationResult, DiagnosticModes, NoopCompilation, - TypeScriptCompilation, createAngularCompilation, } from './index'; @@ -62,13 +63,24 @@ describe('AngularCompilation', () => { it('initializes with empty referencedFiles and compiler options', async () => { const compilation = new NoopCompilation(); const mockHostOptions = {} as AngularHostOptions; - const result = await compilation.initialize('tsconfig.json', mockHostOptions, (opts) => ({ - ...opts, - customOption: true, - })); + const result = await compilation.initialize('tsconfig.json', mockHostOptions); expect(result.referencedFiles).toEqual([]); - expect(result.compilerOptions['customOption']).toBe(true); + expect(result.compilerOptions).toBeDefined(); + }); + + it('initializes with CompilerOptionOverrides object', async () => { + const compilation = new NoopCompilation(); + const mockHostOptions = {} as AngularHostOptions; + const result = await compilation.initialize('tsconfig.json', mockHostOptions, { + sourcemap: true, + enableHmr: true, + }); + + expect(result.referencedFiles).toEqual([]); + expect(result.compilerOptions.inlineSources).toBe(true); + expect(result.compilerOptions.inlineSourceMap).toBe(true); + expect(result.compilerOptions['_enableHmr']).toBe(true); }); it('throws when calling emitAffectedFiles', () => { @@ -184,4 +196,160 @@ describe('AngularCompilation', () => { ); }); }); + + describe('transformCompilerOptions', () => { + it('does not mutate the input compiler options object', () => { + const originalOptions: ts.CompilerOptions = { + target: ts.ScriptTarget.ES2020, + module: ts.ModuleKind.CommonJS, + }; + const originalCopy = { ...originalOptions }; + + transformCompilerOptions(ts, originalOptions); + + expect(originalOptions).toEqual(originalCopy); + }); + + it('sets target to ES2022 and useDefineForClassFields to false when target is undefined', () => { + const { compilerOptions, warnings } = transformCompilerOptions( + ts, + { module: ts.ModuleKind.ES2022 }, + undefined, + 'tsconfig.json', + ); + + expect(compilerOptions.target).toBe(ts.ScriptTarget.ES2022); + expect(compilerOptions.useDefineForClassFields).toBe(false); + expect(warnings.length).toBe(1); + expect(warnings[0].text).toContain( + "TypeScript compiler options 'target' and 'useDefineForClassFields'", + ); + expect(warnings[0].location?.file).toBe('tsconfig.json'); + }); + + it('preserves existing useDefineForClassFields if target < ES2022', () => { + const { compilerOptions, warnings } = transformCompilerOptions( + ts, + { + target: ts.ScriptTarget.ES2020, + useDefineForClassFields: true, + module: ts.ModuleKind.ES2022, + }, + undefined, + 'tsconfig.json', + ); + + expect(compilerOptions.target).toBe(ts.ScriptTarget.ES2022); + expect(compilerOptions.useDefineForClassFields).toBe(true); + expect(warnings.length).toBe(1); + }); + + it('sets compilationMode to full and warns when compilationMode is partial', () => { + const { compilerOptions, warnings } = transformCompilerOptions(ts, { + target: ts.ScriptTarget.ES2022, + module: ts.ModuleKind.ES2022, + compilationMode: 'partial', + }); + + expect(compilerOptions.compilationMode).toBe('full'); + expect(warnings.length).toBe(1); + expect(warnings[0].text).toContain('Angular partial compilation mode is not supported'); + }); + + it('configures incremental and tsBuildInfoFile when cachePath is provided', () => { + const { compilerOptions } = transformCompilerOptions( + ts, + { target: ts.ScriptTarget.ES2022 }, + { cachePath: '/tmp/cache' }, + ); + + expect(compilerOptions.incremental).toBe(true); + expect(compilerOptions.tsBuildInfoFile).toContain('.tsbuildinfo'); + }); + + it('sets incremental to false when cachePath is not provided or incremental is false', () => { + const { compilerOptions: opt1 } = transformCompilerOptions( + ts, + { target: ts.ScriptTarget.ES2022 }, + undefined, + ); + expect(opt1.incremental).toBe(false); + + const { compilerOptions: opt2 } = transformCompilerOptions( + ts, + { target: ts.ScriptTarget.ES2022, incremental: false }, + { cachePath: '/tmp/cache' }, + ); + expect(opt2.incremental).toBe(false); + }); + + it('sets module to ES2022 and warns when module < ES2015', () => { + const { compilerOptions, warnings } = transformCompilerOptions(ts, { + target: ts.ScriptTarget.ES2022, + module: ts.ModuleKind.CommonJS, + }); + + expect(compilerOptions.module).toBe(ts.ModuleKind.ES2022); + expect(warnings.length).toBe(1); + expect(warnings[0].text).toContain( + "TypeScript compiler options 'module' values 'CommonJS', 'UMD'", + ); + }); + + it('warns when isolatedModules is enabled with emitDecoratorMetadata', () => { + const { warnings } = transformCompilerOptions(ts, { + target: ts.ScriptTarget.ES2022, + module: ts.ModuleKind.ES2022, + isolatedModules: true, + emitDecoratorMetadata: true, + }); + + expect(warnings.length).toBe(1); + expect(warnings[0].text).toContain( + "TypeScript compiler option 'isolatedModules' may prevent", + ); + }); + + it('synchronizes customConditions when moduleResolution is Bundler or module is Preserve', () => { + const { compilerOptions: bundlerOptions } = transformCompilerOptions( + ts, + { target: ts.ScriptTarget.ES2022, moduleResolution: ts.ModuleResolutionKind.Bundler }, + { customConditions: ['development'] }, + ); + expect(bundlerOptions.customConditions).toEqual(['development']); + + const { compilerOptions: preserveOptions } = transformCompilerOptions( + ts, + { target: ts.ScriptTarget.ES2022, module: ts.ModuleKind.Preserve }, + { customConditions: ['development'] }, + ); + expect(preserveOptions.customConditions).toEqual(['development']); + }); + + it('applies override options correctly', () => { + const { compilerOptions } = transformCompilerOptions( + ts, + { target: ts.ScriptTarget.ES2022, isolatedModules: true }, + { + sourcemap: true, + preserveSymlinks: true, + externalRuntimeStyles: true, + enableHmr: true, + instrumentForCoverage: true, + includeTestMetadata: true, + }, + ); + + expect(compilerOptions.inlineSources).toBe(true); + expect(compilerOptions.inlineSourceMap).toBe(true); + expect(compilerOptions.preserveSymlinks).toBe(true); + expect(compilerOptions.externalRuntimeStyles).toBe(true); + expect(compilerOptions['_enableHmr']).toBe(true); + expect(compilerOptions['_useTypeScriptTranspilation']).toBe(true); + expect(compilerOptions.supportTestBed).toBe(true); + expect(compilerOptions.supportJitMode).toBe(true); + expect(compilerOptions.noEmitOnError).toBe(false); + expect(compilerOptions.composite).toBe(false); + }); + }); }); diff --git a/packages/angular/build/src/tools/angular/compilation/aot-compilation.ts b/packages/angular/build/src/tools/angular/compilation/aot-compilation.ts index 99f6da756930..ec68415e62fb 100644 --- a/packages/angular/build/src/tools/angular/compilation/aot-compilation.ts +++ b/packages/angular/build/src/tools/angular/compilation/aot-compilation.ts @@ -7,6 +7,7 @@ */ import type * as ng from '@angular/compiler-cli'; +import type { PartialMessage } from 'esbuild'; import assert from 'node:assert'; import { relative } from 'node:path'; import ts from 'typescript'; @@ -26,6 +27,7 @@ import { DiagnosticModes, EmitFileResult, } from './angular-compilation'; +import { CompilerOptionOverrides, transformCompilerOptions } from './compiler-options'; import { collectHmrCandidates } from './hmr-candidates'; import { TypeScriptCompilation } from './typescript-compilation'; import { printSourceFileWithMap } from './typescript-printer'; @@ -64,7 +66,7 @@ export class AotCompilation extends TypeScriptCompilation { async initialize( tsconfig: string, hostOptions: AngularHostOptions, - compilerOptionsTransformer?: (compilerOptions: ng.CompilerOptions) => ng.CompilerOptions, + compilerOptionOverrides?: CompilerOptionOverrides, ): Promise { // Dynamically load the Angular compiler CLI package const { NgtscProgram, OptimizeFor } = await AngularCompilation.loadCompilerCli(); @@ -75,8 +77,13 @@ export class AotCompilation extends TypeScriptCompilation { rootNames, errors: configurationDiagnostics, } = await this.loadConfiguration(tsconfig); - const compilerOptions = - compilerOptionsTransformer?.(originalCompilerOptions) ?? originalCompilerOptions; + + const { compilerOptions, warnings } = transformCompilerOptions( + ts, + originalCompilerOptions, + compilerOptionOverrides, + tsconfig, + ); const useTypeScriptTranspilation = (compilerOptions['_useTypeScriptTranspilation'] as boolean | undefined) ?? @@ -245,6 +252,7 @@ export class AotCompilation extends TypeScriptCompilation { externalStylesheets: hostOptions.externalStylesheets, templateUpdates, componentResourcesDependencies, + warnings, }; } diff --git a/packages/angular/build/src/tools/angular/compilation/compiler-options.ts b/packages/angular/build/src/tools/angular/compilation/compiler-options.ts new file mode 100644 index 000000000000..bb8c494f2213 --- /dev/null +++ b/packages/angular/build/src/tools/angular/compilation/compiler-options.ts @@ -0,0 +1,136 @@ +/** + * @license + * Copyright Google LLC All Rights Reserved. + * + * Use of this source code is governed by an MIT-style license that can be + * found in the LICENSE file at https://angular.dev/license + */ + +import type * as ng from '@angular/compiler-cli'; +import type { PartialMessage } from 'esbuild'; +import * as path from 'node:path'; +import type ts from 'typescript'; + +export interface CompilerOptionOverrides { + sourcemap?: boolean; + preserveSymlinks?: boolean; + cachePath?: string; + externalRuntimeStyles?: boolean; + enableHmr?: boolean; + instrumentForCoverage?: boolean; + includeTestMetadata?: boolean; + customConditions?: string[]; +} + +export function transformCompilerOptions( + typeScript: typeof ts, + baseCompilerOptions: ng.CompilerOptions, + overrides?: CompilerOptionOverrides, + tsconfig?: string, +): { compilerOptions: ng.CompilerOptions; warnings: PartialMessage[] } { + const compilerOptions = { ...baseCompilerOptions }; + const warnings: PartialMessage[] = []; + + if ( + compilerOptions.target === undefined || + compilerOptions.target < typeScript.ScriptTarget.ES2022 + ) { + // If 'useDefineForClassFields' is already defined in the users project leave the value as is. + // Otherwise fallback to false due to https://github.com/microsoft/TypeScript/issues/45995 + // which breaks the deprecated `@Effects` NGRX decorator and potentially other existing code as well. + compilerOptions.target = typeScript.ScriptTarget.ES2022; + compilerOptions.useDefineForClassFields ??= false; + + warnings.push({ + text: + `TypeScript compiler options 'target' and 'useDefineForClassFields' are set to 'ES2022' and ` + + `'false' respectively by the Angular CLI.`, + location: tsconfig ? { file: tsconfig } : null, + notes: [ + { + text: + 'To control ECMA version and features use the Browserslist configuration. ' + + 'For more information, see https://angular.dev/tools/cli/build#configuring-browser-compatibility', + }, + ], + }); + } + + if (compilerOptions.compilationMode === 'partial') { + warnings.push({ + text: 'Angular partial compilation mode is not supported when building applications.', + location: null, + notes: [{ text: 'Full compilation mode will be used instead.' }], + }); + compilerOptions.compilationMode = 'full'; + } + + // Enable incremental compilation by default if caching is enabled and incremental is not explicitly disabled + if (compilerOptions.incremental !== false && overrides?.cachePath) { + compilerOptions.incremental = true; + // Set the build info file location to the configured cache directory + compilerOptions.tsBuildInfoFile = path.join(overrides.cachePath, '.tsbuildinfo'); + } else { + compilerOptions.incremental = false; + } + + if ( + compilerOptions.module === undefined || + compilerOptions.module < typeScript.ModuleKind.ES2015 + ) { + compilerOptions.module = typeScript.ModuleKind.ES2022; + warnings.push({ + text: `TypeScript compiler options 'module' values 'CommonJS', 'UMD', 'System' and 'AMD' are not supported.`, + location: null, + notes: [{ text: `The 'module' option will be set to 'ES2022' instead.` }], + }); + } + + if (compilerOptions.isolatedModules && compilerOptions.emitDecoratorMetadata) { + warnings.push({ + text: `TypeScript compiler option 'isolatedModules' may prevent the 'emitDecoratorMetadata' option from emitting all metadata.`, + location: null, + notes: [ + { + text: + `The 'emitDecoratorMetadata' option is not required by Angular` + + 'and can be removed if not explictly required by the project.', + }, + ], + }); + } + + // Synchronize custom resolve conditions. + // Set if using the supported bundler resolution mode (bundler is the default in new projects) + if ( + compilerOptions.moduleResolution === typeScript.ModuleResolutionKind.Bundler || + compilerOptions.module === typeScript.ModuleKind.Preserve + ) { + compilerOptions.customConditions = overrides?.customConditions; + } + + return { + compilerOptions: { + ...compilerOptions, + noEmitOnError: false, + composite: false, + inlineSources: !!overrides?.sourcemap, + inlineSourceMap: !!overrides?.sourcemap, + sourceMap: undefined, + mapRoot: undefined, + sourceRoot: undefined, + preserveSymlinks: overrides?.preserveSymlinks, + externalRuntimeStyles: overrides?.externalRuntimeStyles, + _enableHmr: !!overrides?.enableHmr, + // TypeScript transpilation is forced if: + // - isolatedModules is disabled (TS needs full module types to emit JS). + // - Karma code coverage is active (the coverage instrumentation transformer is Babel-based + // and cannot parse raw TypeScript code; Vitest handles coverage instrumentation downstream). + _useTypeScriptTranspilation: + !compilerOptions.isolatedModules || !!overrides?.instrumentForCoverage, + supportTestBed: !!overrides?.includeTestMetadata, + supportJitMode: !!overrides?.includeTestMetadata, + }, + warnings, + }; +} diff --git a/packages/angular/build/src/tools/angular/compilation/index.ts b/packages/angular/build/src/tools/angular/compilation/index.ts index 736adea60682..39391bcfb562 100644 --- a/packages/angular/build/src/tools/angular/compilation/index.ts +++ b/packages/angular/build/src/tools/angular/compilation/index.ts @@ -14,6 +14,6 @@ export { type EmitFileResult, type FileTransformResult, } from './angular-compilation'; +export type { CompilerOptionOverrides } from './compiler-options'; export { createAngularCompilation, type AngularCompilationMode } from './factory'; export { NoopCompilation } from './noop-compilation'; -export { TypeScriptCompilation } from './typescript-compilation'; diff --git a/packages/angular/build/src/tools/angular/compilation/jit-compilation.ts b/packages/angular/build/src/tools/angular/compilation/jit-compilation.ts index e4e371a05df8..b54f66701c6c 100644 --- a/packages/angular/build/src/tools/angular/compilation/jit-compilation.ts +++ b/packages/angular/build/src/tools/angular/compilation/jit-compilation.ts @@ -7,6 +7,7 @@ */ import type * as ng from '@angular/compiler-cli'; +import type { PartialMessage } from 'esbuild'; import assert from 'node:assert'; import ts from 'typescript'; import { profileSync } from '../../esbuild/profiling'; @@ -20,6 +21,7 @@ import { DiagnosticModes, EmitFileResult, } from './angular-compilation'; +import { CompilerOptionOverrides, transformCompilerOptions } from './compiler-options'; import { TypeScriptCompilation } from './typescript-compilation'; class JitCompilationState { @@ -42,7 +44,7 @@ export class JitCompilation extends TypeScriptCompilation { async initialize( tsconfig: string, hostOptions: AngularHostOptions, - compilerOptionsTransformer?: (compilerOptions: ng.CompilerOptions) => ng.CompilerOptions, + compilerOptionOverrides?: CompilerOptionOverrides, ): Promise { // Dynamically load the Angular compiler CLI package const { constructorParametersDownlevelTransform } = @@ -54,8 +56,13 @@ export class JitCompilation extends TypeScriptCompilation { rootNames, errors: configurationDiagnostics, } = await this.loadConfiguration(tsconfig); - const compilerOptions = - compilerOptionsTransformer?.(originalCompilerOptions) ?? originalCompilerOptions; + + const { compilerOptions, warnings } = transformCompilerOptions( + ts, + originalCompilerOptions, + compilerOptionOverrides, + tsconfig, + ); if (hostOptions.modifiedFiles) { this.invalidateFiles(hostOptions.modifiedFiles); @@ -93,7 +100,7 @@ export class JitCompilation extends TypeScriptCompilation { .getSourceFiles() .map((sourceFile) => sourceFile.fileName); - return { compilerOptions, referencedFiles }; + return { compilerOptions, referencedFiles, warnings }; } protected override *collectDiagnostics(modes: DiagnosticModes): Iterable { diff --git a/packages/angular/build/src/tools/angular/compilation/noop-compilation.ts b/packages/angular/build/src/tools/angular/compilation/noop-compilation.ts index 55c5913dbad4..7ace166d90fd 100644 --- a/packages/angular/build/src/tools/angular/compilation/noop-compilation.ts +++ b/packages/angular/build/src/tools/angular/compilation/noop-compilation.ts @@ -6,20 +6,48 @@ * found in the LICENSE file at https://angular.dev/license */ -import type * as ng from '@angular/compiler-cli'; import { AngularHostOptions } from '../angular-host'; import { AngularCompilation, AngularCompilationResult } from './angular-compilation'; +import type { CompilerOptionOverrides } from './compiler-options'; +/** + * An Angular compilation that performs no actual compilation or code emission. + * Used for secondary compilation contexts where only the resolved compiler options + * and configuration state are needed. + */ export class NoopCompilation extends AngularCompilation { async initialize( tsconfig: string, hostOptions: AngularHostOptions, - compilerOptionsTransformer?: (compilerOptions: ng.CompilerOptions) => ng.CompilerOptions, + compilerOptionOverrides?: CompilerOptionOverrides, ): Promise { - // Load the compiler configuration and transform as needed + // Load the compiler configuration const { options: originalCompilerOptions } = await this.loadConfiguration(tsconfig); - const compilerOptions = - compilerOptionsTransformer?.(originalCompilerOptions) ?? originalCompilerOptions; + // Apply relevant overrides directly without invoking `transformCompilerOptions` + // to avoid loading the `typescript` package on the main thread. + const compilerOptions = { + ...originalCompilerOptions, + noEmitOnError: false, + composite: false, + inlineSources: !!compilerOptionOverrides?.sourcemap, + inlineSourceMap: !!compilerOptionOverrides?.sourcemap, + sourceMap: undefined, + mapRoot: undefined, + sourceRoot: undefined, + preserveSymlinks: compilerOptionOverrides?.preserveSymlinks, + externalRuntimeStyles: compilerOptionOverrides?.externalRuntimeStyles, + _enableHmr: !!compilerOptionOverrides?.enableHmr, + _useTypeScriptTranspilation: + !originalCompilerOptions.isolatedModules || + !!compilerOptionOverrides?.instrumentForCoverage, + supportTestBed: !!compilerOptionOverrides?.includeTestMetadata, + supportJitMode: !!compilerOptionOverrides?.includeTestMetadata, + customConditions: + originalCompilerOptions.moduleResolution === 100 /* Bundler */ || + originalCompilerOptions.module === 200 /* Preserve */ + ? compilerOptionOverrides?.customConditions + : originalCompilerOptions.customConditions, + }; return { compilerOptions, referencedFiles: [] }; } diff --git a/packages/angular/build/src/tools/angular/compilation/parallel-compilation.ts b/packages/angular/build/src/tools/angular/compilation/parallel-compilation.ts index 7fc530161789..4df13b3a500e 100644 --- a/packages/angular/build/src/tools/angular/compilation/parallel-compilation.ts +++ b/packages/angular/build/src/tools/angular/compilation/parallel-compilation.ts @@ -6,7 +6,6 @@ * found in the LICENSE file at https://angular.dev/license */ -import type { CompilerOptions } from '@angular/compiler-cli'; import type { PartialMessage } from 'esbuild'; import { createRequire } from 'node:module'; import { MessageChannel } from 'node:worker_threads'; @@ -19,6 +18,7 @@ import { DiagnosticModes, EmitFileResult, } from './angular-compilation'; +import type { CompilerOptionOverrides } from './compiler-options'; /** * An Angular compilation which uses a Node.js Worker thread to load and execute @@ -51,7 +51,7 @@ export class ParallelCompilation extends AngularCompilation { override async initialize( tsconfig: string, hostOptions: AngularHostOptions, - compilerOptionsTransformer?: (compilerOptions: CompilerOptions) => CompilerOptions, + compilerOptionOverrides?: CompilerOptionOverrides, ): Promise { const stylesheetChannel = new MessageChannel(); // The request identifier is required because Angular can issue multiple concurrent requests @@ -84,22 +84,6 @@ export class ParallelCompilation extends AngularCompilation { } }); - // The compiler options transformation is a synchronous operation and uses shared memory combined - // with the Atomics API to block execution here until a response is received. - const optionsChannel = new MessageChannel(); - const optionsSignal = new Int32Array(new SharedArrayBuffer(4)); - optionsChannel.port1.on('message', (compilerOptions) => { - try { - const transformedOptions = compilerOptionsTransformer?.(compilerOptions) ?? compilerOptions; - optionsChannel.port1.postMessage({ transformedOptions }); - } catch (error) { - optionsChannel.port1.postMessage({ error }); - } finally { - Atomics.store(optionsSignal, 0, 1); - Atomics.notify(optionsSignal, 0); - } - }); - let success = false; try { // Execute the initialize function in the worker thread @@ -109,15 +93,14 @@ export class ParallelCompilation extends AngularCompilation { tsconfig, jit: this.jit, browserOnlyBuild: this.browserOnlyBuild, + compilerOptionOverrides, stylesheetPort: stylesheetChannel.port2, - optionsPort: optionsChannel.port2, - optionsSignal, webWorkerPort: webWorkerChannel.port2, webWorkerSignal, }, { name: 'initialize', - transferList: [stylesheetChannel.port2, optionsChannel.port2, webWorkerChannel.port2], + transferList: [stylesheetChannel.port2, webWorkerChannel.port2], }, ); success = true; @@ -125,7 +108,6 @@ export class ParallelCompilation extends AngularCompilation { return result; } finally { stylesheetChannel.port1.close(); - optionsChannel.port1.close(); if (!success) { this.#webWorkerChannel?.port1.close(); this.#webWorkerChannel = undefined; diff --git a/packages/angular/build/src/tools/angular/compilation/parallel-worker.ts b/packages/angular/build/src/tools/angular/compilation/parallel-worker.ts index b736e710fa7d..71b4d34e2756 100644 --- a/packages/angular/build/src/tools/angular/compilation/parallel-worker.ts +++ b/packages/angular/build/src/tools/angular/compilation/parallel-worker.ts @@ -18,6 +18,7 @@ import type { DiagnosticModes, } from './angular-compilation'; import { AotCompilation } from './aot-compilation'; +import type { CompilerOptionOverrides } from './compiler-options'; import { JitCompilation } from './jit-compilation'; export interface InitRequest { @@ -25,9 +26,8 @@ export interface InitRequest { browserOnlyBuild: boolean; tsconfig: string; fileReplacements?: Record; + compilerOptionOverrides?: CompilerOptionOverrides; stylesheetPort: MessagePort; - optionsPort: MessagePort; - optionsSignal: Int32Array; webWorkerPort: MessagePort; webWorkerSignal: Int32Array; } @@ -73,6 +73,7 @@ export async function initialize(request: InitRequest): Promise { - Atomics.store(request.optionsSignal, 0, 0); - request.optionsPort.postMessage(compilerOptions); - - Atomics.wait(request.optionsSignal, 0, 0); - const result = receiveMessageOnPort(request.optionsPort)?.message; - - if (result?.error) { - throw result.error; - } - - return result?.transformedOptions ?? compilerOptions; - }, + request.compilerOptionOverrides, ); success = true; @@ -130,6 +119,7 @@ export async function initialize(request: InitRequest): Promise[2] { - return (compilerOptions) => { - // target of 9 is ES2022 (using the number avoids an expensive import of typescript just for an enum) - if (compilerOptions.target === undefined || compilerOptions.target < 9 /** ES2022 */) { - // If 'useDefineForClassFields' is already defined in the users project leave the value as is. - // Otherwise fallback to false due to https://github.com/microsoft/TypeScript/issues/45995 - // which breaks the deprecated `@Effects` NGRX decorator and potentially other existing code as well. - compilerOptions.target = 9; /** ES2022 */ - compilerOptions.useDefineForClassFields ??= false; - - // Only add the warning on the initial build - setupWarnings?.push({ - text: - `TypeScript compiler options 'target' and 'useDefineForClassFields' are set to 'ES2022' and ` + - `'false' respectively by the Angular CLI.`, - location: { file: pluginOptions.tsconfig }, - notes: [ - { - text: - 'To control ECMA version and features use the Browserslist configuration. ' + - 'For more information, see https://angular.dev/tools/cli/build#configuring-browser-compatibility', - }, - ], - }); - } - - if (compilerOptions.compilationMode === 'partial') { - setupWarnings?.push({ - text: 'Angular partial compilation mode is not supported when building applications.', - location: null, - notes: [{ text: 'Full compilation mode will be used instead.' }], - }); - compilerOptions.compilationMode = 'full'; - } - - // Enable incremental compilation by default if caching is enabled and incremental is not explicitly disabled - if ( - compilerOptions.incremental !== false && - pluginOptions.sourceFileCache?.persistentCachePath - ) { - compilerOptions.incremental = true; - // Set the build info file location to the configured cache directory - compilerOptions.tsBuildInfoFile = path.join( - pluginOptions.sourceFileCache?.persistentCachePath, - '.tsbuildinfo', - ); - } else { - compilerOptions.incremental = false; - } - - if (compilerOptions.module === undefined || compilerOptions.module < 5 /** ES2015 */) { - compilerOptions.module = 7; /** ES2022 */ - setupWarnings?.push({ - text: `TypeScript compiler options 'module' values 'CommonJS', 'UMD', 'System' and 'AMD' are not supported.`, - location: null, - notes: [{ text: `The 'module' option will be set to 'ES2022' instead.` }], - }); - } - - if (compilerOptions.isolatedModules && compilerOptions.emitDecoratorMetadata) { - setupWarnings?.push({ - text: `TypeScript compiler option 'isolatedModules' may prevent the 'emitDecoratorMetadata' option from emitting all metadata.`, - location: null, - notes: [ - { - text: - `The 'emitDecoratorMetadata' option is not required by Angular` + - 'and can be removed if not explictly required by the project.', - }, - ], - }); - } - - // Synchronize custom resolve conditions. - // Set if using the supported bundler resolution mode (bundler is the default in new projects) - if ( - compilerOptions.moduleResolution === 100 /* ModuleResolutionKind.Bundler */ || - compilerOptions.module === 200 /** ModuleKind.Preserve */ - ) { - compilerOptions.customConditions = customConditions; - } - - return { - ...compilerOptions, - noEmitOnError: false, - composite: false, - inlineSources: !!pluginOptions.sourcemap, - inlineSourceMap: !!pluginOptions.sourcemap, - sourceMap: undefined, - mapRoot: undefined, - sourceRoot: undefined, - preserveSymlinks, - externalRuntimeStyles: pluginOptions.externalRuntimeStyles, - _enableHmr: !!pluginOptions.templateUpdates, - // TypeScript transpilation is forced if: - // - isolatedModules is disabled (TS needs full module types to emit JS). - // - Karma code coverage is active (the coverage instrumentation transformer is Babel-based - // and cannot parse raw TypeScript code; Vitest handles coverage instrumentation downstream). - _useTypeScriptTranspilation: - !compilerOptions.isolatedModules || !!pluginOptions.instrumentForCoverage, - supportTestBed: !!pluginOptions.includeTestMetadata, - supportJitMode: !!pluginOptions.includeTestMetadata, - }; - }; -} - function bundleWebWorker( build: PluginBuild, pluginOptions: CompilerPluginOptions, From 4182b96abc0a33de380a3e15afd35179ea4ac98d Mon Sep 17 00:00:00 2001 From: Charles Lyding <19598772+clydin@users.noreply.github.com> Date: Fri, 28 Aug 2026 12:18:10 -0400 Subject: [PATCH 372/787] refactor(@angular/build): precompute expression indexes in i18n inliner worker Previously, callSite.expressions.map((_, index) => index) was evaluated on every $localize call site for every locale inside inlineLocalize. In bundles with hundreds of call sites processed across multiple locales in a batch, this resulted in thousands of redundant small array allocations. expressionIndexes is now precomputed once during AST extraction in extractLocalizeMetadata and stored on LocalizeCallSite, eliminating per-locale index array allocations in the worker transformation loop. --- .../angular/build/src/tools/esbuild/i18n-inliner-worker.ts | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/packages/angular/build/src/tools/esbuild/i18n-inliner-worker.ts b/packages/angular/build/src/tools/esbuild/i18n-inliner-worker.ts index 269341c3df81..d3f72808b90d 100644 --- a/packages/angular/build/src/tools/esbuild/i18n-inliner-worker.ts +++ b/packages/angular/build/src/tools/esbuild/i18n-inliner-worker.ts @@ -321,6 +321,7 @@ interface LocalizeCallSite { end: number; messageParts: TemplateStringsArray; expressions: { start: number; end: number }[]; + expressionIndexes: number[]; } /** @@ -381,12 +382,14 @@ function extractLocalizeMetadata(filename: string, code: string): FileLocalizeMe start: expr.start, end: expr.end, })); + const expressionIndexes = expressions.map((_, index) => index); callSites.push({ start: node.start, end: node.end, messageParts, expressions, + expressionIndexes, }); } } @@ -448,7 +451,7 @@ async function inlineLocalize( diagnostics, translation || {}, callSite.messageParts, - callSite.expressions.map((_, index) => index), + callSite.expressionIndexes, translation === undefined ? 'ignore' : missingTranslation, ); From 799f332c9680ce6dfff86720b85a1b8857d37f8a Mon Sep 17 00:00:00 2001 From: Charles Lyding <19598772+clydin@users.noreply.github.com> Date: Fri, 28 Aug 2026 12:20:58 -0400 Subject: [PATCH 373/787] refactor(@angular/build): hoist blob instantiation in i18n inliner batch loop Instantiate codeBlob and mapBlob once per file outside the batch loop instead of re-creating new Blob instances on each batch slice. Blobs are immutable, read-only binary handles and can be safely shared across multiple worker batch tasks concurrently. --- packages/angular/build/src/tools/esbuild/i18n-inliner.ts | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/packages/angular/build/src/tools/esbuild/i18n-inliner.ts b/packages/angular/build/src/tools/esbuild/i18n-inliner.ts index e8f8e67462c2..c1fc01455c73 100644 --- a/packages/angular/build/src/tools/esbuild/i18n-inliner.ts +++ b/packages/angular/build/src/tools/esbuild/i18n-inliner.ts @@ -459,6 +459,8 @@ export class I18nInliner { const codeFile = this.#localizeFiles.get(filename); assert(codeFile !== undefined, 'Localize file must exist: ' + filename); const mapFile = this.#localizeFiles.get(filename + '.map'); + const codeBlob = new Blob([codeFile.contents]); + const mapBlob = mapFile ? new Blob([mapFile.contents]) : undefined; const ephemeral = isLastWindow && entries.length <= localesPerBatch; for (let i = 0; i < entries.length; i += localesPerBatch) { @@ -467,8 +469,8 @@ export class I18nInliner { const batchResult = (await this.#workerPool.run( { filename, - code: new Blob([codeFile.contents]), - map: mapFile ? new Blob([mapFile.contents]) : undefined, + code: codeBlob, + map: mapBlob, locales: new Map(batchEntries.map((e) => [e.locale, e.translation])), ephemeral, activeLocales, From a2dcb23103ad9c42ca983ac4f4906ba40073d7e0 Mon Sep 17 00:00:00 2001 From: Charles Lyding <19598772+clydin@users.noreply.github.com> Date: Fri, 28 Aug 2026 12:31:46 -0400 Subject: [PATCH 374/787] refactor(@angular/build): streamline cache check resolution in i18n inliner Streamline the asynchronous cache resolution in inlineAll by removing the intermediate CacheCheckItem interface and array mapping allocations. Results are now assigned directly to fileResultsByLocale on hit or pushed to uncachedByFile on miss. When no persistent cache is configured, a fast path directly queues uncached files without promise or hash overhead. --- .../build/src/tools/esbuild/i18n-inliner.ts | 119 +++++++----------- 1 file changed, 48 insertions(+), 71 deletions(-) diff --git a/packages/angular/build/src/tools/esbuild/i18n-inliner.ts b/packages/angular/build/src/tools/esbuild/i18n-inliner.ts index c1fc01455c73..b2d32da7f8bd 100644 --- a/packages/angular/build/src/tools/esbuild/i18n-inliner.ts +++ b/packages/angular/build/src/tools/esbuild/i18n-inliner.ts @@ -131,31 +131,6 @@ interface TransformedFileResult { messages: { type: 'error' | 'warning'; message: string }[]; } -/** - * Represents an in-flight asynchronous cache lookup for a single (file x locale) transformation. - */ -interface CacheCheckItem { - /** - * The relative file path of the JavaScript file to transform. - */ - filename: string; - - /** - * The locale specifier being targeted for translation. - */ - locale: string; - - /** - * The computed cache key hash, or undefined if persistent caching is not configured. - */ - cacheKey: string | undefined; - - /** - * A promise that resolves to the cached transform result, or null if uncached or on lookup failure. - */ - cachedResult: Promise; -} - /** * An uncached transformation request entry for a file within a specific locale. */ @@ -306,17 +281,18 @@ export class I18nInliner { }), ); - const cacheChecks: CacheCheckItem[] = []; + const uncachedByFile = new Map(); - for (const filename of filenames) { - const file = this.#localizeFiles.get(filename); - assert(file !== undefined, 'Localize file must exist: ' + filename); + if (this.#transformedFileCache) { + const cacheChecks: Promise[] = []; - for (const { locale } of windowLocales) { - let cacheKey: string | undefined; - let cachedResultPromise: Promise = Promise.resolve(null); + for (const filename of filenames) { + const file = this.#localizeFiles.get(filename); + assert(file !== undefined, 'Localize file must exist: ' + filename); + + const fileEntries: UncachedLocaleEntry[] = []; - if (this.#transformedFileCache) { + for (const { locale } of windowLocales) { const fileCacheKeyBase = localeCacheBases.get(locale); assert(fileCacheKeyBase !== undefined, 'Cache base must exist for locale: ' + locale); @@ -324,50 +300,51 @@ export class I18nInliner { hasher.update(file.hash); hasher.update(filename); hasher.update(fileCacheKeyBase); - cacheKey = hasher.digest(); - - cachedResultPromise = this.#transformedFileCache - .get(cacheKey) - .then((val) => val ?? null) - .catch(() => null); + const cacheKey = hasher.digest(); + + cacheChecks.push( + this.#transformedFileCache + .get(cacheKey) + .then((result) => { + if (result) { + fileResultsByLocale.get(locale)?.set(filename, result); + } else { + fileEntries.push({ + locale, + cacheKey, + translation: localeBlobs.get(locale), + }); + } + }) + .catch(() => { + fileEntries.push({ + locale, + cacheKey, + translation: localeBlobs.get(locale), + }); + }), + ); } - cacheChecks.push({ - filename, - locale, - cacheKey, - cachedResult: cachedResultPromise, - }); + uncachedByFile.set(filename, fileEntries); } - } - - // Await all cache checks for this window - const resolvedChecks = await Promise.all( - cacheChecks.map(async (item) => ({ - ...item, - result: await item.cachedResult, - })), - ); - // Group uncached items by filename for this window - const uncachedByFile = new Map(); + await Promise.all(cacheChecks); - for (const item of resolvedChecks) { - if (item.result) { - // Cache hit: store directly in locale file results - fileResultsByLocale.get(item.locale)?.set(item.filename, item.result); - } else { - // Cache miss: needs worker processing - let fileEntries = uncachedByFile.get(item.filename); - if (!fileEntries) { - fileEntries = []; - uncachedByFile.set(item.filename, fileEntries); + for (const [filename, entries] of uncachedByFile) { + if (entries.length === 0) { + uncachedByFile.delete(filename); } - fileEntries.push({ - locale: item.locale, - cacheKey: item.cacheKey, - translation: localeBlobs.get(item.locale), - }); + } + } else { + for (const filename of filenames) { + uncachedByFile.set( + filename, + windowLocales.map(({ locale }) => ({ + locale, + translation: localeBlobs.get(locale), + })), + ); } } From d0324d3dde538096f958e0b4f92e2fa0cc490728 Mon Sep 17 00:00:00 2001 From: Charles Lyding <19598772+clydin@users.noreply.github.com> Date: Fri, 28 Aug 2026 12:55:11 -0400 Subject: [PATCH 375/787] refactor(@angular/build): support generation-based worker cache clearing in i18n inliner Introduce generation tracking in I18nInliner and worker batch tasks to guarantee long-term worker caches (fileDataCache and deserializedTranslations) are wiped whenever a new inlining pass or rebuild begins (e.g. watch mode or shared worker pools). --- .../src/tools/esbuild/i18n-inliner-worker.ts | 21 +++++++++++++ .../build/src/tools/esbuild/i18n-inliner.ts | 5 ++++ .../src/tools/esbuild/i18n-inliner_spec.ts | 30 +++++++++++++++++++ 3 files changed, 56 insertions(+) diff --git a/packages/angular/build/src/tools/esbuild/i18n-inliner-worker.ts b/packages/angular/build/src/tools/esbuild/i18n-inliner-worker.ts index d3f72808b90d..d19de3d6d4b7 100644 --- a/packages/angular/build/src/tools/esbuild/i18n-inliner-worker.ts +++ b/packages/angular/build/src/tools/esbuild/i18n-inliner-worker.ts @@ -80,6 +80,12 @@ interface InlineFileBatchRequest { * not present in this list will be evicted from the Worker's memory cache. */ activeLocales?: string[]; + + /** + * The current inlining generation counter. When a request with a new generation is received, + * all long-term worker caches are cleared. + */ + generation?: number; } /** @@ -130,6 +136,11 @@ const fileDataCache = new Map>(); */ const deserializedTranslations = new Map>>(); +/** + * The current inlining generation for this worker. + */ +let currentGeneration: number | undefined; + /** * Retrieves the file data for a filename, loading and extracting localization metadata. * If `cache` is true, the result is cached in `fileDataCache` across requests in this Worker. @@ -144,6 +155,10 @@ const deserializedTranslations = new Map { const existing = fileDataCache.get(filename); if (existing) { + if (!cache) { + fileDataCache.delete(filename); + } + return existing; } @@ -207,6 +222,12 @@ function loadTranslation( export async function inlineFileBatch( request: InlineFileBatchRequest, ): Promise { + if (request.generation !== undefined && request.generation !== currentGeneration) { + currentGeneration = request.generation; + fileDataCache.clear(); + deserializedTranslations.clear(); + } + if (request.activeLocales) { const activeSet = new Set(request.activeLocales); for (const locale of deserializedTranslations.keys()) { diff --git a/packages/angular/build/src/tools/esbuild/i18n-inliner.ts b/packages/angular/build/src/tools/esbuild/i18n-inliner.ts index b2d32da7f8bd..2a3c97f0aed0 100644 --- a/packages/angular/build/src/tools/esbuild/i18n-inliner.ts +++ b/packages/angular/build/src/tools/esbuild/i18n-inliner.ts @@ -152,6 +152,7 @@ export class I18nInliner { #cacheStore: PersistentCacheStore | undefined; #transformedFileCache: Cache | undefined; #translationCache: Cache | undefined; + #generation = 0; readonly #localizeFiles: ReadonlyMap; readonly #unmodifiedFiles: Array; @@ -229,6 +230,7 @@ export class I18nInliner { ): Promise> { await this.initCache(); + const generation = ++this.#generation; const { missingTranslation, localizeVersion } = this.options; const localeList = Array.from(locales); @@ -356,6 +358,7 @@ export class I18nInliner { fileResultsByLocale, activeLocales, isLastWindow, + generation, ); } } @@ -422,6 +425,7 @@ export class I18nInliner { fileResultsByLocale: Map>, activeLocales?: string[], isLastWindow = true, + generation?: number, ): Promise { const workerCount = this.#workerPool.maxThreads || 1; const targetTaskCount = Math.max(uncachedByFile.size, workerCount * 2); @@ -451,6 +455,7 @@ export class I18nInliner { locales: new Map(batchEntries.map((e) => [e.locale, e.translation])), ephemeral, activeLocales, + generation, }, { name: 'inlineFileBatch' }, )) as diff --git a/packages/angular/build/src/tools/esbuild/i18n-inliner_spec.ts b/packages/angular/build/src/tools/esbuild/i18n-inliner_spec.ts index 00d5260fc591..21c42d66777d 100644 --- a/packages/angular/build/src/tools/esbuild/i18n-inliner_spec.ts +++ b/packages/angular/build/src/tools/esbuild/i18n-inliner_spec.ts @@ -823,4 +823,34 @@ describe('I18nInliner', () => { ]), ).toBeRejectedWithError(/Duplicate locale provided to inliner: fr/); }); + + it('correctly transforms files across multiple inlineAll runs on the same inliner instance', async () => { + const localeInliner = new I18nInliner( + { + missingTranslation: 'warning', + outputFiles: [browserFile('main.js', GREETING_SOURCE)], + }, + 2, + ); + + try { + // First generation + const results1 = await localeInliner.inlineAll([ + { locale: 'fr', translation: { greeting: translationFor('Bonjour') } }, + ]); + expect(findFile(results1.get('fr')?.outputFiles ?? [], 'main.js').text).toContain( + '"Bonjour"', + ); + + // Second generation (e.g. watch mode rebuild with updated translation) + const results2 = await localeInliner.inlineAll([ + { locale: 'fr', translation: { greeting: translationFor('Salut') } }, + { locale: 'de', translation: { greeting: translationFor('Hallo') } }, + ]); + expect(findFile(results2.get('fr')?.outputFiles ?? [], 'main.js').text).toContain('"Salut"'); + expect(findFile(results2.get('de')?.outputFiles ?? [], 'main.js').text).toContain('"Hallo"'); + } finally { + await localeInliner.close(); + } + }); }); From 85794f0c9ad38c4f985a98a25d6080e8de876c76 Mon Sep 17 00:00:00 2001 From: Charles Lyding <19598772+clydin@users.noreply.github.com> Date: Fri, 28 Aug 2026 13:32:43 -0400 Subject: [PATCH 376/787] refactor(@angular/build): use single pass template literal escaping in i18n inliner worker Consolidate the 3 chained string replacement passes (unescaping double quotes, escaping backticks, and escaping ${ delimiters) into a single regex pass in escapeTemplatePart. This eliminates 3 intermediate string allocations and reduces 3 regex scans to 1 on every translated template literal part. --- .../src/tools/esbuild/i18n-inliner-worker.ts | 18 ++++++++++++------ .../src/tools/esbuild/i18n-inliner_spec.ts | 17 +++++++++++++++++ 2 files changed, 29 insertions(+), 6 deletions(-) diff --git a/packages/angular/build/src/tools/esbuild/i18n-inliner-worker.ts b/packages/angular/build/src/tools/esbuild/i18n-inliner-worker.ts index d19de3d6d4b7..2804e0ef8a9e 100644 --- a/packages/angular/build/src/tools/esbuild/i18n-inliner-worker.ts +++ b/packages/angular/build/src/tools/esbuild/i18n-inliner-worker.ts @@ -420,6 +420,17 @@ function extractLocalizeMetadata(filename: string, code: string): FileLocalizeMe return { callSites, localeInsertSites, diagnostics }; } +/** + * Escapes a template literal string part for insertion into an ES template literal (backticks). + * Uses JSON.stringify for base escaping of control characters and backslashes, then unescapes + * double quotes and escapes backticks and `${` expression delimiters in a single pass. + */ +function escapeTemplatePart(part: string): string { + return JSON.stringify(part) + .slice(1, -1) + .replace(/\\"|`|\$\{/g, (match) => (match === '\\"' ? '"' : '\\' + match)); +} + /** * Inlines translations into code using previously extracted localization metadata. * @@ -483,12 +494,7 @@ async function inlineLocalize( } else { replacement = '`'; for (let i = 0; i < translatedParts.length; i++) { - const escapedPart = JSON.stringify(translatedParts[i]) - .slice(1, -1) - .replace(/\\"/g, '"') - .replace(/`/g, '\\`') - .replace(/\$\{/g, '\\${'); - replacement += escapedPart; + replacement += escapeTemplatePart(translatedParts[i]); if (i < translatedSubstitutions.length) { const originalIndex = translatedSubstitutions[i]; diff --git a/packages/angular/build/src/tools/esbuild/i18n-inliner_spec.ts b/packages/angular/build/src/tools/esbuild/i18n-inliner_spec.ts index 21c42d66777d..ff86793cef9c 100644 --- a/packages/angular/build/src/tools/esbuild/i18n-inliner_spec.ts +++ b/packages/angular/build/src/tools/esbuild/i18n-inliner_spec.ts @@ -853,4 +853,21 @@ describe('I18nInliner', () => { await localeInliner.close(); } }); + + it('correctly escapes backticks, double quotes, and expression delimiters in translated template literals', async () => { + const source = 'export const msg = $localize`:@@msg:Hello ${name}:name:!`;\n'; + const inliner = createInliner([browserFile('main.js', source)]); + + const results = await inliner.inlineAll([ + { + locale: 'fr', + translation: { + msg: parsedTranslation(['Bonjour "', '` with ${injected} and \\backslash!'], ['name']), + }, + }, + ]); + + const outputText = findFile(results.get('fr')?.outputFiles ?? [], 'main.js').text; + expect(outputText).toContain('`Bonjour "${name}\\` with \\${injected} and \\\\backslash!`'); + }); }); From ab6d7dfb3a3b223540d5c9d857e76167590240e5 Mon Sep 17 00:00:00 2001 From: Charles Lyding <19598772+clydin@users.noreply.github.com> Date: Fri, 28 Aug 2026 14:19:36 -0400 Subject: [PATCH 377/787] refactor(@angular/build): ensure deterministic locale ordering in cache checks Resolve asynchronous cache checks on a per-file basis using Promise.all to ensure windowLocales ordering is preserved within uncachedByFile regardless of disk I/O resolution timing. Also avoids pre-populating and deleting empty arrays in uncachedByFile. --- .../build/src/tools/esbuild/i18n-inliner.ts | 78 +++++++++---------- 1 file changed, 36 insertions(+), 42 deletions(-) diff --git a/packages/angular/build/src/tools/esbuild/i18n-inliner.ts b/packages/angular/build/src/tools/esbuild/i18n-inliner.ts index 2a3c97f0aed0..7c4e19cb0268 100644 --- a/packages/angular/build/src/tools/esbuild/i18n-inliner.ts +++ b/packages/angular/build/src/tools/esbuild/i18n-inliner.ts @@ -286,58 +286,52 @@ export class I18nInliner { const uncachedByFile = new Map(); if (this.#transformedFileCache) { + const cache = this.#transformedFileCache; const cacheChecks: Promise[] = []; for (const filename of filenames) { const file = this.#localizeFiles.get(filename); assert(file !== undefined, 'Localize file must exist: ' + filename); - const fileEntries: UncachedLocaleEntry[] = []; - - for (const { locale } of windowLocales) { - const fileCacheKeyBase = localeCacheBases.get(locale); - assert(fileCacheKeyBase !== undefined, 'Cache base must exist for locale: ' + locale); - - const hasher = createContentHash(); - hasher.update(file.hash); - hasher.update(filename); - hasher.update(fileCacheKeyBase); - const cacheKey = hasher.digest(); - - cacheChecks.push( - this.#transformedFileCache - .get(cacheKey) - .then((result) => { - if (result) { - fileResultsByLocale.get(locale)?.set(filename, result); - } else { - fileEntries.push({ - locale, - cacheKey, - translation: localeBlobs.get(locale), - }); - } - }) - .catch(() => { - fileEntries.push({ - locale, - cacheKey, - translation: localeBlobs.get(locale), - }); - }), - ); - } + const fileEntriesPromises = windowLocales.map( + async ({ locale }): Promise => { + const fileCacheKeyBase = localeCacheBases.get(locale); + assert(fileCacheKeyBase !== undefined, 'Cache base must exist for locale: ' + locale); + + const hasher = createContentHash(); + hasher.update(file.hash); + hasher.update(filename); + hasher.update(fileCacheKeyBase); + const cacheKey = hasher.digest(); + + try { + const result = await cache.get(cacheKey); + if (result) { + fileResultsByLocale.get(locale)?.set(filename, result); + + return; + } + } catch {} + + return { + locale, + cacheKey, + translation: localeBlobs.get(locale), + }; + }, + ); - uncachedByFile.set(filename, fileEntries); + cacheChecks.push( + Promise.all(fileEntriesPromises).then((entries) => { + const filtered = entries.filter((e): e is UncachedLocaleEntry => e !== undefined); + if (filtered.length > 0) { + uncachedByFile.set(filename, filtered); + } + }), + ); } await Promise.all(cacheChecks); - - for (const [filename, entries] of uncachedByFile) { - if (entries.length === 0) { - uncachedByFile.delete(filename); - } - } } else { for (const filename of filenames) { uncachedByFile.set( From 4fa81d403c93a7480301e58630203cb028aebc69 Mon Sep 17 00:00:00 2001 From: Alan Agius <17563226+alan-agius4@users.noreply.github.com> Date: Mon, 31 Aug 2026 07:40:55 +0000 Subject: [PATCH 378/787] fix(@angular/ssr): decode pathname when constructing server asset path Ensure that the request pathname is decoded using `decodeURIComponent` when resolving server asset paths in `AngularServerApp`. Previously, `buildServerAssetPathFromRequest` used the raw percent-encoded `pathname` from `new URL(request.url)` while prerendered assets were registered in the manifest under decoded names. Consequently, prerendered routes with non-ASCII or percent-encoded characters failed asset lookup and fell through to server-side rendering or 404. Closes #33966 --- packages/angular/ssr/src/app.ts | 7 + packages/angular/ssr/test/app-engine_spec.ts | 25 +++ packages/angular/ssr/test/app_spec.ts | 169 +++++++++++++++---- 3 files changed, 164 insertions(+), 37 deletions(-) diff --git a/packages/angular/ssr/src/app.ts b/packages/angular/ssr/src/app.ts index 3e0f33be8ba7..af72ac9c44a2 100644 --- a/packages/angular/ssr/src/app.ts +++ b/packages/angular/ssr/src/app.ts @@ -455,12 +455,19 @@ export class AngularServerApp { */ private buildServerAssetPathFromRequest(request: Request): string { let { pathname: assetPath } = new URL(request.url); + try { + assetPath = decodeURIComponent(assetPath); + } catch { + // In case of malformed URI component, keep assetPath as is. + } + if (!assetPath.endsWith('/index.html')) { // Append "index.html" to build the default asset path. assetPath = joinUrlParts(assetPath, 'index.html'); } const { baseHref } = this.manifest; + // Check if the asset path starts with the base href and the base href is not (`/` or ``). if (baseHref.length > 1 && assetPath.startsWith(baseHref)) { // Remove the base href from the start of the asset path to align with server-asset expectations. diff --git a/packages/angular/ssr/test/app-engine_spec.ts b/packages/angular/ssr/test/app-engine_spec.ts index c4313be8a48c..eae063eec700 100644 --- a/packages/angular/ssr/test/app-engine_spec.ts +++ b/packages/angular/ssr/test/app-engine_spec.ts @@ -54,11 +54,13 @@ function createEntryPoint(locale: string) { setAngularAppTestingManifest( [ { path: 'ssg', component: SSGComponent }, + { path: 'ssg-non-ascii/دليل', component: SSGComponent }, { path: 'ssr', component: SSRComponent }, { path: '', component: HomeComponent }, ], [ { path: 'ssg', renderMode: RenderMode.Prerender }, + { path: 'ssg-non-ascii/دليل', renderMode: RenderMode.Prerender }, { path: '**', renderMode: RenderMode.Server }, ], '/' + locale, @@ -77,6 +79,20 @@ function createEntryPoint(locale: string) { `, }, + 'ssg-non-ascii/دليل/index.html': { + size: 35, + hash: 'a1b2c3d4e5f6', + text: async () => ` + + SSG non-ascii page + + + + SSG non-ascii works ${locale.toUpperCase()} + + + `, + }, }, locale, ); @@ -147,6 +163,15 @@ describe('AngularAppEngine', () => { expect(await response?.text()).toContain('SSG works IT'); }); + it('should return a served prerendered page for non-ASCII routes with correct locale', async () => { + const request = new Request( + 'https://example.com/it/ssg-non-ascii/%D8%AF%D9%84%D9%8A%D9%84', + ); + const response = await appEngine.handle(request); + expect(await response?.text()).toContain('SSG non-ascii works IT'); + expect(response?.headers?.get('Content-Language')).toBe('it'); + }); + it('should return null for requests to unknown pages in a locale', async () => { const request = new Request('https://example.com/it/unknown/page'); const response = await appEngine.handle(request); diff --git a/packages/angular/ssr/test/app_spec.ts b/packages/angular/ssr/test/app_spec.ts index 1e3d40d3ede8..f14c403106bd 100644 --- a/packages/angular/ssr/test/app_spec.ts +++ b/packages/angular/ssr/test/app_spec.ts @@ -22,58 +22,59 @@ import { setAngularAppTestingManifest } from './testing-utils'; describe('AngularServerApp', () => { let app: AngularServerApp; - beforeAll(() => { - @Component({ - selector: 'app-home', - template: `Home works`, - }) - class HomeComponent { - constructor() { - if (inject(ActivatedRoute).snapshot.data['destroyApp']) { - inject(PlatformRef).destroy(); - } + @Component({ + selector: 'app-home', + template: `Home works`, + }) + class HomeComponent { + constructor() { + if (inject(ActivatedRoute).snapshot.data['destroyApp']) { + inject(PlatformRef).destroy(); } } - - @Component({ - selector: 'app-redirect', - }) - class RedirectComponent { - constructor() { - const responseInit = inject(RESPONSE_INIT); - if (responseInit) { - responseInit.status = 308; - const headers = responseInit.headers; - if (headers) { - (headers as Headers).set('X-Redirect-Header', 'custom-value'); - } + } + + @Component({ + selector: 'app-redirect', + }) + class RedirectComponent { + constructor() { + const responseInit = inject(RESPONSE_INIT); + if (responseInit) { + responseInit.status = 308; + const headers = responseInit.headers; + if (headers) { + (headers as Headers).set('X-Redirect-Header', 'custom-value'); } - - void inject(Router).navigate([], { - queryParams: { filter: 'test' }, - }); } - } - const queryParamAdderGuard: CanActivateFn = (_route, state) => { - const urlTree = inject(Router).parseUrl(state.url); + void inject(Router).navigate([], { + queryParams: { filter: 'test' }, + }); + } + } - if (urlTree.queryParamMap.has('filter')) { - return true; - } + const queryParamAdderGuard: CanActivateFn = (_route, state) => { + const urlTree = inject(Router).parseUrl(state.url); - urlTree.queryParams = { - filter: 'test', - }; + if (urlTree.queryParamMap.has('filter')) { + return true; + } - return urlTree; + urlTree.queryParams = { + filter: 'test', }; + return urlTree; + }; + + function setupManifest(): void { setAngularAppTestingManifest( [ { path: 'home', component: HomeComponent }, { path: 'home-csr', component: HomeComponent }, { path: 'home-ssg', component: HomeComponent }, + { path: 'home-ssg-non-ascii/دليل', component: HomeComponent }, { path: 'page-with-headers', component: HomeComponent }, { path: 'page-with-status', component: HomeComponent }, { path: 'page-destroy-app', component: HomeComponent, data: { destroyApp: true } }, @@ -105,6 +106,10 @@ describe('AngularServerApp', () => { 'X-Some-Header': 'value', }, }, + { + path: 'home-ssg-non-ascii/دليل', + renderMode: RenderMode.Prerender, + }, { path: 'page-with-status', renderMode: RenderMode.Server, @@ -140,6 +145,21 @@ describe('AngularServerApp', () => { size: 28, hash: 'f799132d0a09e0fef93c68a12e443527700eb59e6f67fcb7854c3a60ff082fde', }, + 'home-ssg-non-ascii/دليل/index.html': { + text: async () => + ` + + SSG non-ascii page + + + + Home SSG non-ascii works + + + `, + size: 38, + hash: 'a1b2c3d4e5f6', + }, }, undefined, undefined, @@ -152,6 +172,10 @@ describe('AngularServerApp', () => { ); app = new AngularServerApp(); + } + + beforeAll(() => { + setupManifest(); }); describe('handle', () => { @@ -282,6 +306,77 @@ describe('AngularServerApp', () => { expect(await response?.text()).toContain('Home SSG works'); }); + it('should correctly serve prerendered page with non-ASCII path', async () => { + const response = await app.handle( + new Request('http://localhost/home-ssg-non-ascii/%D8%AF%D9%84%D9%8A%D9%84'), + ); + expect(await response?.text()).toContain('Home SSG non-ascii works'); + }); + + it(`should correctly serve prerendered page with non-ASCII path when the URL ends with 'index.html'`, async () => { + const response = await app.handle( + new Request('http://localhost/home-ssg-non-ascii/%D8%AF%D9%84%D9%8A%D9%84/index.html'), + ); + expect(await response?.text()).toContain('Home SSG non-ascii works'); + }); + + it('should correctly serve prerendered page when requested with decoded non-ASCII characters', async () => { + const response = await app.handle(new Request('http://localhost/home-ssg-non-ascii/دليل')); + expect(await response?.text()).toContain('Home SSG non-ascii works'); + }); + + it('should correctly serve prerendered page with non-ASCII path when baseHref is configured', async () => { + setAngularAppTestingManifest( + [{ path: 'home-ssg-non-ascii/دليل', component: HomeComponent }], + [ + { + path: 'home-ssg-non-ascii/دليل', + renderMode: RenderMode.Prerender, + }, + ], + '/ar/', + { + 'home-ssg-non-ascii/دليل/index.html': { + text: async () => 'SSG with baseHref works', + size: 47, + hash: '123456', + }, + }, + ); + + const customApp = new AngularServerApp(); + const response = await customApp.handle( + new Request('http://localhost/ar/home-ssg-non-ascii/%D8%AF%D9%84%D9%8A%D9%84'), + ); + expect(await response?.text()).toContain('SSG with baseHref works'); + }); + + it('should correctly serve prerendered page when baseHref contains non-ASCII characters', async () => { + setAngularAppTestingManifest( + [{ path: 'page', component: HomeComponent }], + [ + { + path: 'page', + renderMode: RenderMode.Prerender, + }, + ], + '/دليل/', + { + 'page/index.html': { + text: async () => 'SSG with non-ASCII baseHref works', + size: 57, + hash: 'abcdef', + }, + }, + ); + + const customApp = new AngularServerApp(); + const response = await customApp.handle( + new Request('http://localhost/%D8%AF%D9%84%D9%8A%D9%84/page'), + ); + expect(await response?.text()).toContain('SSG with non-ASCII baseHref works'); + }); + it('should return configured headers for pages with specific header settings', async () => { const response = await app.handle(new Request('http://localhost/home-ssg')); const headers = response?.headers.entries() ?? []; From 5b850fdfc7534d33db7ab4a7f1e32e143462eec7 Mon Sep 17 00:00:00 2001 From: Alan Agius <17563226+alan-agius4@users.noreply.github.com> Date: Mon, 31 Aug 2026 08:15:02 +0000 Subject: [PATCH 379/787] fix(@angular/build): fail build and exclude routes when prerendering fails When a prerendered route failed to render (such as when a component throws during route activation), the render worker returned null content which was silently skipped. Consequently, no HTML file was written, but the build still reported the route in prerender statistics, included it in prerendered-routes.json, and exited with code 0. Now: - The render worker throws an error if content is null ('The content returned was empty.'). - Prerendering records the error so the build fails with a non-zero exit code. - Prerendered routes recorded for manifest and statistics are derived strictly from routes that produced output files. Closes #33965 --- .../application/execute-post-bundle.ts | 13 ++-- .../src/utils/server-rendering/prerender.ts | 66 +++++++++++------ .../utils/server-rendering/render-worker.ts | 20 ++++-- .../build/prerender/error-component-render.ts | 72 +++++++++++++++++++ 4 files changed, 138 insertions(+), 33 deletions(-) create mode 100644 tests/e2e/tests/build/prerender/error-component-render.ts diff --git a/packages/angular/build/src/builders/application/execute-post-bundle.ts b/packages/angular/build/src/builders/application/execute-post-bundle.ts index cf76a14d9030..56098d9e2a38 100644 --- a/packages/angular/build/src/builders/application/execute-post-bundle.ts +++ b/packages/angular/build/src/builders/application/execute-post-bundle.ts @@ -157,7 +157,13 @@ export async function executePostBundleSteps( 'The "index" option is required when using the "ssg" or "appShell" options.', ); - const { output, warnings, errors, serializableRouteTreeNode } = await prerenderPages( + const { + output, + warnings, + errors, + serializableRouteTreeNode, + prerenderedRoutes: generatedPrerenderedRoutes, + } = await prerenderPages( workspaceRoot, baseHref, appShellOptions, @@ -171,6 +177,7 @@ export async function executePostBundleSteps( allErrors.push(...errors); allWarnings.push(...warnings); + Object.assign(prerenderedRoutes, generatedPrerenderedRoutes); const indexHasBeenPrerendered = output[indexHtmlOptions.output]; for (const [path, { content, appShellRoute }] of Object.entries(output)) { @@ -195,10 +202,6 @@ export async function executePostBundleSteps( const serializableRouteTreeNodeForManifest: WritableSerializableRouteTreeNode = []; for (const metadata of serializableRouteTreeNode) { serializableRouteTreeNodeForManifest.push(metadata); - - if (metadata.renderMode === RouteRenderMode.Prerender && !metadata.route.includes('*')) { - prerenderedRoutes[metadata.route] = { headers: metadata.headers }; - } } if (outputMode === OutputMode.Server) { diff --git a/packages/angular/build/src/utils/server-rendering/prerender.ts b/packages/angular/build/src/utils/server-rendering/prerender.ts index 37e29f02385b..98502c63587d 100644 --- a/packages/angular/build/src/utils/server-rendering/prerender.ts +++ b/packages/angular/build/src/utils/server-rendering/prerender.ts @@ -10,7 +10,10 @@ import { readFile } from 'node:fs/promises'; import { extname, posix } from 'node:path'; import { NormalizedApplicationBuildOptions } from '../../builders/application/options'; import { OutputMode } from '../../builders/application/schema'; -import { BuildOutputAsset } from '../../tools/esbuild/bundler-execution-result'; +import { + BuildOutputAsset, + PrerenderedRoutesRecord, +} from '../../tools/esbuild/bundler-execution-result'; import { BuildOutputFile, BuildOutputFileType } from '../../tools/esbuild/bundler-files'; import { assertIsError } from '../error'; import { toPosixPath } from '../path'; @@ -65,6 +68,7 @@ export async function prerenderPages( output: PrerenderOutput; warnings: string[]; errors: string[]; + prerenderedRoutes: PrerenderedRoutesRecord; serializableRouteTreeNode: SerializableRouteTreeNode; }> { const rawOutputFiles: Record = {}; @@ -167,6 +171,7 @@ export async function prerenderPages( errors, warnings, output: {}, + prerenderedRoutes: {}, serializableRouteTreeNode, }; } @@ -200,10 +205,22 @@ export async function prerenderPages( errors.push(...renderingErrors); + const prerenderedRoutes: PrerenderedRoutesRecord = {}; + const baseHrefPathnameWithLeadingSlash = new URL(baseHref, 'http://localhost').pathname; + + for (const metadata of serializableRouteTreeNodeForPrerender) { + const outPath = getRouteOutPath(metadata.route, baseHrefPathnameWithLeadingSlash); + + if (output[outPath]) { + prerenderedRoutes[metadata.route] = { headers: metadata.headers }; + } + } + return { errors, warnings, output, + prerenderedRoutes, serializableRouteTreeNode, }; } @@ -227,22 +244,15 @@ async function renderPages( const baseHrefPathnameWithLeadingSlash = new URL(baseHref, 'http://localhost').pathname; const appShellRouteWithoutBaseHref = appShellRoute - ? addTrailingSlash(appShellRoute).startsWith(baseHrefPathnameWithLeadingSlash) - ? addLeadingSlash(appShellRoute.slice(baseHrefPathnameWithLeadingSlash.length)) - : addLeadingSlash(appShellRoute) + ? addLeadingSlash(getRouteWithoutBaseHref(appShellRoute, baseHrefPathnameWithLeadingSlash)) : undefined; const routesToRender: { route: string; outPath: string; isAppShell: boolean }[] = []; for (const { route, redirectTo } of serializableRouteTreeNode) { // Remove the base href from the file output path. - const routeWithoutBaseHref = addTrailingSlash(route).startsWith( - baseHrefPathnameWithLeadingSlash, - ) - ? addLeadingSlash(route.slice(baseHrefPathnameWithLeadingSlash.length)) - : route; - - const outPath = stripLeadingSlash(posix.join(routeWithoutBaseHref, 'index.html')); + const routeWithoutBaseHref = getRouteWithoutBaseHref(route, baseHrefPathnameWithLeadingSlash); + const outPath = getRouteOutPath(route, baseHrefPathnameWithLeadingSlash); if (typeof redirectTo === 'string') { output[outPath] = { content: generateRedirectStaticPage(redirectTo), appShellRoute: false }; @@ -305,20 +315,20 @@ async function renderPages( const renderBatchPromise: Promise = renderWorker.run(urls); const batchResultPromise = renderBatchPromise .then((results) => { - for (const { url, content, error } of results) { - if (error) { - errors.push(`An error occurred while prerendering route '${url}'.\n\n${error}`); + for (const result of results) { + if ('error' in result) { + errors.push( + `An error occurred while prerendering route '${result.url}'.\n\n${result.error}`, + ); continue; } - if (content !== null) { - const routeInfo = routeOutPathMap.get(url); - if (routeInfo) { - output[routeInfo.outPath] = { - content, - appShellRoute: routeInfo.isAppShell, - }; - } + const routeInfo = routeOutPathMap.get(result.url); + if (routeInfo) { + output[routeInfo.outPath] = { + content: result.content, + appShellRoute: routeInfo.isAppShell, + }; } } }) @@ -439,3 +449,15 @@ async function getAllRoutes( void renderWorker.destroy(); } } + +function getRouteWithoutBaseHref(route: string, baseHrefPathname: string): string { + return addTrailingSlash(route).startsWith(baseHrefPathname) + ? addLeadingSlash(route.slice(baseHrefPathname.length)) + : route; +} + +function getRouteOutPath(route: string, baseHrefPathname: string): string { + const routeWithoutBaseHref = getRouteWithoutBaseHref(route, baseHrefPathname); + + return stripLeadingSlash(posix.join(routeWithoutBaseHref, 'index.html')); +} diff --git a/packages/angular/build/src/utils/server-rendering/render-worker.ts b/packages/angular/build/src/utils/server-rendering/render-worker.ts index b8f01c440c4b..df1fdb4ea103 100644 --- a/packages/angular/build/src/utils/server-rendering/render-worker.ts +++ b/packages/angular/build/src/utils/server-rendering/render-worker.ts @@ -21,11 +21,15 @@ export interface RenderWorkerData extends ESMInMemoryFileLoaderWorkerData { hasSsrEntry: boolean; } -export interface RenderResultItem { - url: string; - content: string | null; - error?: string; -} +export type RenderResultItem = + | { + url: string; + content: string; + } + | { + url: string; + error: string; + }; export type RenderResult = RenderResultItem[]; @@ -74,12 +78,16 @@ async function renderPages(urls: string[]): Promise { for (const currentUrl of urls) { try { const content = await renderPage(currentUrl, angularServerApp); + + if (content === null) { + throw new Error('The content returned was empty.'); + } + results.push({ url: currentUrl, content }); } catch (err) { assertIsError(err); results.push({ url: currentUrl, - content: null, error: err.stack ?? err.message ?? err.code ?? `${err}`, }); } diff --git a/tests/e2e/tests/build/prerender/error-component-render.ts b/tests/e2e/tests/build/prerender/error-component-render.ts new file mode 100644 index 000000000000..07c048c71c39 --- /dev/null +++ b/tests/e2e/tests/build/prerender/error-component-render.ts @@ -0,0 +1,72 @@ +import { existsSync } from 'node:fs'; +import assert, { match } from 'node:assert'; +import { getGlobalVariable } from '../../../utils/env'; +import { expectFileNotToExist, readFile, rimraf, writeMultipleFiles } from '../../../utils/fs'; +import { installWorkspacePackages } from '../../../utils/packages'; +import { ng } from '../../../utils/process'; +import { useSha } from '../../../utils/project'; +import { expectToFail } from '../../../utils/utils'; + +export default async function () { + const useWebpackBuilder = !getGlobalVariable('argv')['esbuild']; + if (useWebpackBuilder) { + return; + } + + // Forcibly remove in case another test doesn't clean itself up. + await rimraf('node_modules/@angular/ssr'); + await ng('add', '@angular/ssr', '--skip-confirmation'); + await useSha(); + await installWorkspacePackages(); + + await writeMultipleFiles({ + 'src/app/app.routes.ts': ` + import { Routes } from '@angular/router'; + import { Component } from '@angular/core'; + + @Component({ + selector: 'app-home', + standalone: true, + template: '

home works!

', + }) + export class HomeRoute {} + + @Component({ + selector: 'app-second', + standalone: true, + template: '

second works!

', + }) + export class SecondRoute { + constructor() { + throw new Error('render failure'); + } + } + + export const routes: Routes = [ + { path: '', component: HomeRoute }, + { path: 'second', component: SecondRoute }, + ]; + `, + 'src/app/app.routes.server.ts': ` + import { RenderMode, ServerRoute } from '@angular/ssr'; + + export const serverRoutes: ServerRoute[] = [ + { path: 'second', renderMode: RenderMode.Prerender }, + { path: '**', renderMode: RenderMode.Prerender }, + ]; + `, + }); + + const { message } = await expectToFail(() => ng('build', '--output-mode=server')); + + match(message, /An error occurred while prerendering route '\/second'\./); + + await expectFileNotToExist('dist/test-project/browser/second/index.html'); + + // prerendered-routes.json should only contain successfully prerendered routes if emitted + const statsPath = 'dist/test-project/prerendered-routes.json'; + if (existsSync(statsPath)) { + const stats = JSON.parse(await readFile(statsPath)); + assert.strictEqual(stats.routes['/second'], undefined); + } +} From ce83ac0e82981efd9408e07a35315e3cef9e1a36 Mon Sep 17 00:00:00 2001 From: Charles Lyding <19598772+clydin@users.noreply.github.com> Date: Fri, 28 Aug 2026 10:19:25 -0400 Subject: [PATCH 380/787] perf(@angular/build): use size-weighted task heuristics in i18n inliner Incorporate Longest Processing Time First (LPT) scheduling, hybrid relative sizing, and hardware-adaptive sliding windows for task dispatch in I18nInliner. Previously, files were dispatched in arbitrary insertion order, partitioned using a uniform locale batch size across all files regardless of byte size, and processed in fixed 8-locale sliding windows. This could result in large dominant files like main.js starting late in a window and causing single-worker straggler latency at the window barrier, while small chunks were unnecessarily fragmented into multiple IPC tasks and high-core machines (>8 cores) were throttled by the fixed 8-locale limit. --- .../build/src/tools/esbuild/i18n-inliner.ts | 70 ++++++++++++++----- .../src/tools/esbuild/i18n-inliner_spec.ts | 53 ++++++++++++++ 2 files changed, 107 insertions(+), 16 deletions(-) diff --git a/packages/angular/build/src/tools/esbuild/i18n-inliner.ts b/packages/angular/build/src/tools/esbuild/i18n-inliner.ts index 7c4e19cb0268..4350112d0cf9 100644 --- a/packages/angular/build/src/tools/esbuild/i18n-inliner.ts +++ b/packages/angular/build/src/tools/esbuild/i18n-inliner.ts @@ -23,11 +23,23 @@ import { encodeTranslationToBuffer } from './i18n-translation-encoder'; const LOCALIZE_KEYWORD = '$localize'; /** - * The maximum number of locales to process concurrently in a single sliding window. - * This caps peak worker memory while maintaining multi-locale batching throughput. + * The baseline number of locales to process concurrently in a single sliding window. + * This caps peak worker memory on low-core machines while maintaining multi-locale batching throughput. */ const DEFAULT_LOCALE_WINDOW_SIZE = 8; +/** + * Minimum byte size threshold for a file to be eligible for multi-batch sharding. + * Files below this threshold (< 100 KB) are processed in a single batch to minimize IPC overhead. + */ +const SMALL_FILE_FLOOR_BYTES = 100 * 1024; + +/** + * Ratio of the maximum file size in a window to consider a file "dominant". + * Files within 70% of the largest file are sharded across all workers for maximum concurrency. + */ +const DOMINANT_FILE_RATIO = 0.7; + /** * Serializes the translation messages for a locale for transfer to an inliner Worker. * @@ -248,11 +260,13 @@ export class I18nInliner { (name) => !name.endsWith('.map'), ); - // Process locales in sliding windows to cap peak worker memory - for (let i = 0; i < localeList.length; i += DEFAULT_LOCALE_WINDOW_SIZE) { - const windowLocales = localeList.slice(i, i + DEFAULT_LOCALE_WINDOW_SIZE); + // Process locales in sliding windows to cap peak worker memory. + // Ensure the window has at least enough locales to saturate all available workers on high-core machines. + const windowSize = Math.max(DEFAULT_LOCALE_WINDOW_SIZE, this.#workerPool.maxThreads || 1); + for (let i = 0; i < localeList.length; i += windowSize) { + const windowLocales = localeList.slice(i, i + windowSize); const activeLocales = windowLocales.map((item) => item.locale); - const isLastWindow = i + DEFAULT_LOCALE_WINDOW_SIZE >= localeList.length; + const isLastWindow = i + windowSize >= localeList.length; // Pre-calculate cache key bases and serialized Blobs for each locale in this window const localeCacheBases = new Map(); @@ -348,7 +362,6 @@ export class I18nInliner { if (uncachedByFile.size > 0) { await this.#processUncachedBatches( uncachedByFile, - windowLocales.length, fileResultsByLocale, activeLocales, isLastWindow, @@ -415,28 +428,53 @@ export class I18nInliner { async #processUncachedBatches( uncachedByFile: Map, - localeCount: number, fileResultsByLocale: Map>, activeLocales?: string[], isLastWindow = true, generation?: number, ): Promise { const workerCount = this.#workerPool.maxThreads || 1; - const targetTaskCount = Math.max(uncachedByFile.size, workerCount * 2); - const localesPerBatch = Math.max( - 1, - Math.ceil(localeCount / (targetTaskCount / (uncachedByFile.size || 1))), - ); - const workerTasks: Promise[] = []; - - for (const [filename, entries] of uncachedByFile) { + // Extract file data and identify the heaviest file size in a single pass + let maxFileSize = 0; + const sortedFiles = Array.from(uncachedByFile, ([filename, entries]) => { const codeFile = this.#localizeFiles.get(filename); assert(codeFile !== undefined, 'Localize file must exist: ' + filename); + const fileSize = codeFile.contents.byteLength; + if (fileSize > maxFileSize) { + maxFileSize = fileSize; + } + + return { filename, entries, codeFile, fileSize }; + }); + + // Sort files descending by byte size (Longest Processing Time First / LPT). + // Heavy files (e.g. main.js) are queued first to saturate all worker threads immediately, + // while small files act as gap fillers near the window barrier to prevent tail stragglers. + sortedFiles.sort((a, b) => b.fileSize - a.fileSize); + + const workerTasks: Promise[] = []; + + for (const { filename, entries, codeFile, fileSize } of sortedFiles) { const mapFile = this.#localizeFiles.get(filename + '.map'); const codeBlob = new Blob([codeFile.contents]); const mapBlob = mapFile ? new Blob([mapFile.contents]) : undefined; + let localesPerBatch: number; + if (uncachedByFile.size === 1) { + // Single file in window: shard across all workers to avoid idle threads + localesPerBatch = Math.max(1, Math.ceil(entries.length / workerCount)); + } else if (fileSize < SMALL_FILE_FLOOR_BYTES) { + // Small chunks (< 100 KB): process all locales in 1 batch to eliminate IPC overhead + localesPerBatch = entries.length; + } else if (fileSize >= maxFileSize * DOMINANT_FILE_RATIO) { + // Dominant file(s): shard across all workers for maximum multi-core parallelism + localesPerBatch = Math.max(1, Math.ceil(entries.length / workerCount)); + } else { + // Intermediate files: moderate sharding + localesPerBatch = Math.max(1, Math.ceil(entries.length / 2)); + } + const ephemeral = isLastWindow && entries.length <= localesPerBatch; for (let i = 0; i < entries.length; i += localesPerBatch) { const batchEntries = entries.slice(i, i + localesPerBatch); diff --git a/packages/angular/build/src/tools/esbuild/i18n-inliner_spec.ts b/packages/angular/build/src/tools/esbuild/i18n-inliner_spec.ts index ff86793cef9c..9cc560d038a1 100644 --- a/packages/angular/build/src/tools/esbuild/i18n-inliner_spec.ts +++ b/packages/angular/build/src/tools/esbuild/i18n-inliner_spec.ts @@ -870,4 +870,57 @@ describe('I18nInliner', () => { const outputText = findFile(results.get('fr')?.outputFiles ?? [], 'main.js').text; expect(outputText).toContain('`Bonjour "${name}\\` with \\${injected} and \\\\backslash!`'); }); + + it('correctly inlines when files have varying sizes across multiple workers', async () => { + // Create a large dominant bundle (> 120 KB) and a small chunk (< 10 KB) + const largePadding = '/* padding */ console.log(1);\n'.repeat(4000); + const largeSource = `${GREETING_SOURCE}\n${largePadding}`; + const smallSource = 'console.log($localize`:@@farewell:Goodbye`);'; + + const largeFile = browserFile('main.js', largeSource); + const smallFile = browserFile('chunk.js', smallSource); + + inliner = new I18nInliner( + { missingTranslation: 'error', outputFiles: [largeFile, smallFile] }, + 2, + ); + + const results = await inliner.inlineAll([ + { + locale: 'fr', + translation: { + greeting: translationFor('Bonjour'), + farewell: translationFor('Au revoir'), + }, + }, + { + locale: 'de', + translation: { + greeting: translationFor('Guten Tag'), + farewell: translationFor('Auf Wiedersehen'), + }, + }, + { + locale: 'es', + translation: { + greeting: translationFor('Hola'), + farewell: translationFor('Adios'), + }, + }, + ]); + + expect(results.size).toBe(3); + + const frFiles = results.get('fr')?.outputFiles ?? []; + expect(findFile(frFiles, 'main.js').text).toContain('"Bonjour"'); + expect(findFile(frFiles, 'chunk.js').text).toContain('"Au revoir"'); + + const deFiles = results.get('de')?.outputFiles ?? []; + expect(findFile(deFiles, 'main.js').text).toContain('"Guten Tag"'); + expect(findFile(deFiles, 'chunk.js').text).toContain('"Auf Wiedersehen"'); + + const esFiles = results.get('es')?.outputFiles ?? []; + expect(findFile(esFiles, 'main.js').text).toContain('"Hola"'); + expect(findFile(esFiles, 'chunk.js').text).toContain('"Adios"'); + }); }); From 2dc9aae681949642a9c0552de1253b1335ecb507 Mon Sep 17 00:00:00 2001 From: Angular Robot Date: Mon, 31 Aug 2026 20:53:59 +0000 Subject: [PATCH 381/787] build: update cross-repo angular dependencies See associated pull request for more information. --- .../assistant-to-the-branch-manager.yml | 2 +- .github/workflows/ci.yml | 52 +- .github/workflows/dev-infra.yml | 6 +- .github/workflows/perf.yml | 6 +- .github/workflows/pr.yml | 44 +- MODULE.bazel | 6 +- MODULE.bazel.lock | 1 - package.json | 2 +- pnpm-lock.yaml | 858 ++++++++++-------- tests/e2e/ng-snapshot/package.json | 32 +- 10 files changed, 558 insertions(+), 451 deletions(-) diff --git a/.github/workflows/assistant-to-the-branch-manager.yml b/.github/workflows/assistant-to-the-branch-manager.yml index adb1937840ae..27348ccb7eb7 100644 --- a/.github/workflows/assistant-to-the-branch-manager.yml +++ b/.github/workflows/assistant-to-the-branch-manager.yml @@ -18,6 +18,6 @@ jobs: - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: persist-credentials: false - - uses: angular/dev-infra/github-actions/branch-manager@fa43fd2864c3bec677cd47f4e095370850cdf8bc # main + - uses: angular/dev-infra/github-actions/branch-manager@6a54b1f6636c00be7b9c3fa5928da87df48ff9a0 # main with: angular-robot-key: ${{ secrets.ANGULAR_ROBOT_PRIVATE_KEY }} diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 9ca3788bd8d5..12f2214031d0 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -21,9 +21,9 @@ jobs: runs-on: ubuntu-latest steps: - name: Initialize environment - uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@fa43fd2864c3bec677cd47f4e095370850cdf8bc # main + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@6a54b1f6636c00be7b9c3fa5928da87df48ff9a0 # main - name: Setup Bazel - uses: angular/dev-infra/github-actions/bazel/setup@fa43fd2864c3bec677cd47f4e095370850cdf8bc # main + uses: angular/dev-infra/github-actions/bazel/setup@6a54b1f6636c00be7b9c3fa5928da87df48ff9a0 # main - name: Install node modules run: pnpm install --frozen-lockfile - name: Generate JSON schema types @@ -44,11 +44,11 @@ jobs: runs-on: ubuntu-latest steps: - name: Initialize environment - uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@fa43fd2864c3bec677cd47f4e095370850cdf8bc # main + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@6a54b1f6636c00be7b9c3fa5928da87df48ff9a0 # main - name: Setup Bazel - uses: angular/dev-infra/github-actions/bazel/setup@fa43fd2864c3bec677cd47f4e095370850cdf8bc # main + uses: angular/dev-infra/github-actions/bazel/setup@6a54b1f6636c00be7b9c3fa5928da87df48ff9a0 # main - name: Setup Bazel RBE - uses: angular/dev-infra/github-actions/bazel/configure-remote@fa43fd2864c3bec677cd47f4e095370850cdf8bc # main + uses: angular/dev-infra/github-actions/bazel/configure-remote@6a54b1f6636c00be7b9c3fa5928da87df48ff9a0 # main with: google_credential: ${{ secrets.RBE_TRUSTED_BUILDS_USER }} - name: Install node modules @@ -61,11 +61,11 @@ jobs: runs-on: ubuntu-latest steps: - name: Initialize environment - uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@fa43fd2864c3bec677cd47f4e095370850cdf8bc # main + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@6a54b1f6636c00be7b9c3fa5928da87df48ff9a0 # main - name: Setup Bazel - uses: angular/dev-infra/github-actions/bazel/setup@fa43fd2864c3bec677cd47f4e095370850cdf8bc # main + uses: angular/dev-infra/github-actions/bazel/setup@6a54b1f6636c00be7b9c3fa5928da87df48ff9a0 # main - name: Setup Bazel RBE - uses: angular/dev-infra/github-actions/bazel/configure-remote@fa43fd2864c3bec677cd47f4e095370850cdf8bc # main + uses: angular/dev-infra/github-actions/bazel/configure-remote@6a54b1f6636c00be7b9c3fa5928da87df48ff9a0 # main with: google_credential: ${{ secrets.RBE_TRUSTED_BUILDS_USER }} - name: Install node modules @@ -84,13 +84,13 @@ jobs: runs-on: ubuntu-latest steps: - name: Initialize environment - uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@fa43fd2864c3bec677cd47f4e095370850cdf8bc # main + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@6a54b1f6636c00be7b9c3fa5928da87df48ff9a0 # main - name: Install node modules run: pnpm install --frozen-lockfile - name: Setup Bazel - uses: angular/dev-infra/github-actions/bazel/setup@fa43fd2864c3bec677cd47f4e095370850cdf8bc # main + uses: angular/dev-infra/github-actions/bazel/setup@6a54b1f6636c00be7b9c3fa5928da87df48ff9a0 # main - name: Setup Bazel RBE - uses: angular/dev-infra/github-actions/bazel/configure-remote@fa43fd2864c3bec677cd47f4e095370850cdf8bc # main + uses: angular/dev-infra/github-actions/bazel/configure-remote@6a54b1f6636c00be7b9c3fa5928da87df48ff9a0 # main with: google_credential: ${{ secrets.RBE_TRUSTED_BUILDS_USER }} - name: Run CLI E2E tests @@ -100,11 +100,11 @@ jobs: runs-on: ubuntu-latest steps: - name: Initialize environment - uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@fa43fd2864c3bec677cd47f4e095370850cdf8bc # main + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@6a54b1f6636c00be7b9c3fa5928da87df48ff9a0 # main - name: Setup Bazel - uses: angular/dev-infra/github-actions/bazel/setup@fa43fd2864c3bec677cd47f4e095370850cdf8bc # main + uses: angular/dev-infra/github-actions/bazel/setup@6a54b1f6636c00be7b9c3fa5928da87df48ff9a0 # main - name: Setup Bazel RBE - uses: angular/dev-infra/github-actions/bazel/configure-remote@fa43fd2864c3bec677cd47f4e095370850cdf8bc # main + uses: angular/dev-infra/github-actions/bazel/configure-remote@6a54b1f6636c00be7b9c3fa5928da87df48ff9a0 # main with: google_credential: ${{ secrets.RBE_TRUSTED_BUILDS_USER }} - name: Install node modules @@ -137,7 +137,7 @@ jobs: runs-on: windows-2025 steps: - name: Initialize environment - uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@fa43fd2864c3bec677cd47f4e095370850cdf8bc # main + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@6a54b1f6636c00be7b9c3fa5928da87df48ff9a0 # main - name: Install node modules run: pnpm install --frozen-lockfile - name: Download built Windows E2E tests @@ -164,13 +164,13 @@ jobs: runs-on: ubuntu-latest steps: - name: Initialize environment - uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@fa43fd2864c3bec677cd47f4e095370850cdf8bc # main + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@6a54b1f6636c00be7b9c3fa5928da87df48ff9a0 # main - name: Install node modules run: pnpm install --frozen-lockfile - name: Setup Bazel - uses: angular/dev-infra/github-actions/bazel/setup@fa43fd2864c3bec677cd47f4e095370850cdf8bc # main + uses: angular/dev-infra/github-actions/bazel/setup@6a54b1f6636c00be7b9c3fa5928da87df48ff9a0 # main - name: Setup Bazel RBE - uses: angular/dev-infra/github-actions/bazel/configure-remote@fa43fd2864c3bec677cd47f4e095370850cdf8bc # main + uses: angular/dev-infra/github-actions/bazel/configure-remote@6a54b1f6636c00be7b9c3fa5928da87df48ff9a0 # main with: google_credential: ${{ secrets.RBE_TRUSTED_BUILDS_USER }} - name: Run CLI E2E tests @@ -188,13 +188,13 @@ jobs: runs-on: ubuntu-latest steps: - name: Initialize environment - uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@fa43fd2864c3bec677cd47f4e095370850cdf8bc # main + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@6a54b1f6636c00be7b9c3fa5928da87df48ff9a0 # main - name: Install node modules run: pnpm install --frozen-lockfile - name: Setup Bazel - uses: angular/dev-infra/github-actions/bazel/setup@fa43fd2864c3bec677cd47f4e095370850cdf8bc # main + uses: angular/dev-infra/github-actions/bazel/setup@6a54b1f6636c00be7b9c3fa5928da87df48ff9a0 # main - name: Setup Bazel RBE - uses: angular/dev-infra/github-actions/bazel/configure-remote@fa43fd2864c3bec677cd47f4e095370850cdf8bc # main + uses: angular/dev-infra/github-actions/bazel/configure-remote@6a54b1f6636c00be7b9c3fa5928da87df48ff9a0 # main with: google_credential: ${{ secrets.RBE_TRUSTED_BUILDS_USER }} - name: Run CLI E2E tests @@ -208,13 +208,13 @@ jobs: SAUCE_TUNNEL_IDENTIFIER: angular-cli-${{ github.workflow }}-${{ github.run_number }} steps: - name: Initialize environment - uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@fa43fd2864c3bec677cd47f4e095370850cdf8bc # main + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@6a54b1f6636c00be7b9c3fa5928da87df48ff9a0 # main - name: Install node modules run: pnpm install --frozen-lockfile - name: Setup Bazel - uses: angular/dev-infra/github-actions/bazel/setup@fa43fd2864c3bec677cd47f4e095370850cdf8bc # main + uses: angular/dev-infra/github-actions/bazel/setup@6a54b1f6636c00be7b9c3fa5928da87df48ff9a0 # main - name: Setup Bazel RBE - uses: angular/dev-infra/github-actions/bazel/configure-remote@fa43fd2864c3bec677cd47f4e095370850cdf8bc # main + uses: angular/dev-infra/github-actions/bazel/configure-remote@6a54b1f6636c00be7b9c3fa5928da87df48ff9a0 # main with: google_credential: ${{ secrets.RBE_TRUSTED_BUILDS_USER }} - name: Start Sauce Connect @@ -245,11 +245,11 @@ jobs: CIRCLE_BRANCH: ${{ github.ref_name }} steps: - name: Initialize environment - uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@fa43fd2864c3bec677cd47f4e095370850cdf8bc # main + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@6a54b1f6636c00be7b9c3fa5928da87df48ff9a0 # main - name: Install node modules run: pnpm install --frozen-lockfile - name: Setup Bazel - uses: angular/dev-infra/github-actions/bazel/setup@fa43fd2864c3bec677cd47f4e095370850cdf8bc # main + uses: angular/dev-infra/github-actions/bazel/setup@6a54b1f6636c00be7b9c3fa5928da87df48ff9a0 # main - run: pnpm admin snapshots --verbose env: SNAPSHOT_BUILDS_GITHUB_TOKEN: ${{ secrets.SNAPSHOT_BUILDS_GITHUB_TOKEN }} diff --git a/.github/workflows/dev-infra.yml b/.github/workflows/dev-infra.yml index 3de13736b60d..c26ca63f6fb9 100644 --- a/.github/workflows/dev-infra.yml +++ b/.github/workflows/dev-infra.yml @@ -16,21 +16,21 @@ jobs: if: github.event_name == 'pull_request_target' runs-on: ubuntu-latest steps: - - uses: angular/dev-infra/github-actions/labeling/pull-request@fa43fd2864c3bec677cd47f4e095370850cdf8bc # main + - uses: angular/dev-infra/github-actions/labeling/pull-request@6a54b1f6636c00be7b9c3fa5928da87df48ff9a0 # main with: angular-robot-key: ${{ secrets.ANGULAR_ROBOT_PRIVATE_KEY }} post_approval_changes: if: github.event_name == 'pull_request_target' runs-on: ubuntu-latest steps: - - uses: angular/dev-infra/github-actions/post-approval-changes@fa43fd2864c3bec677cd47f4e095370850cdf8bc # main + - uses: angular/dev-infra/github-actions/post-approval-changes@6a54b1f6636c00be7b9c3fa5928da87df48ff9a0 # main with: angular-robot-key: ${{ secrets.ANGULAR_ROBOT_PRIVATE_KEY }} issue_labels: if: github.event_name == 'issues' runs-on: ubuntu-latest steps: - - uses: angular/dev-infra/github-actions/labeling/issue@fa43fd2864c3bec677cd47f4e095370850cdf8bc # main + - uses: angular/dev-infra/github-actions/labeling/issue@6a54b1f6636c00be7b9c3fa5928da87df48ff9a0 # main with: angular-robot-key: ${{ secrets.ANGULAR_ROBOT_PRIVATE_KEY }} google-generative-ai-key: ${{ secrets.GOOGLE_GENERATIVE_AI_KEY }} diff --git a/.github/workflows/perf.yml b/.github/workflows/perf.yml index 83dfe2812a83..3f7797f93f73 100644 --- a/.github/workflows/perf.yml +++ b/.github/workflows/perf.yml @@ -22,7 +22,7 @@ jobs: workflows: ${{ steps.workflows.outputs.workflows }} steps: - name: Initialize environment - uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@fa43fd2864c3bec677cd47f4e095370850cdf8bc # main + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@6a54b1f6636c00be7b9c3fa5928da87df48ff9a0 # main - name: Install node modules run: pnpm install --frozen-lockfile - id: workflows @@ -40,9 +40,9 @@ jobs: workflow: ${{ fromJSON(needs.list.outputs.workflows) }} steps: - name: Initialize environment - uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@fa43fd2864c3bec677cd47f4e095370850cdf8bc # main + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@6a54b1f6636c00be7b9c3fa5928da87df48ff9a0 # main - name: Setup Bazel - uses: angular/dev-infra/github-actions/bazel/setup@fa43fd2864c3bec677cd47f4e095370850cdf8bc # main + uses: angular/dev-infra/github-actions/bazel/setup@6a54b1f6636c00be7b9c3fa5928da87df48ff9a0 # main - name: Install node modules run: pnpm install --frozen-lockfile # We utilize the google-github-actions/auth action to allow us to get an active credential using workflow diff --git a/.github/workflows/pr.yml b/.github/workflows/pr.yml index 453a75f453ae..c19c4cbacfa0 100644 --- a/.github/workflows/pr.yml +++ b/.github/workflows/pr.yml @@ -34,9 +34,9 @@ jobs: runs-on: ubuntu-latest steps: - name: Initialize environment - uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@fa43fd2864c3bec677cd47f4e095370850cdf8bc # main + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@6a54b1f6636c00be7b9c3fa5928da87df48ff9a0 # main - name: Setup Bazel - uses: angular/dev-infra/github-actions/bazel/setup@fa43fd2864c3bec677cd47f4e095370850cdf8bc # main + uses: angular/dev-infra/github-actions/bazel/setup@6a54b1f6636c00be7b9c3fa5928da87df48ff9a0 # main - name: Setup ESLint Caching uses: actions/cache@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0 with: @@ -66,17 +66,17 @@ jobs: # it has been merged. run: pnpm ng-dev format changed --check ${{ github.event.pull_request.base.sha }} - name: Check Package Licenses - uses: angular/dev-infra/github-actions/linting/licenses@fa43fd2864c3bec677cd47f4e095370850cdf8bc # main + uses: angular/dev-infra/github-actions/linting/licenses@6a54b1f6636c00be7b9c3fa5928da87df48ff9a0 # main build: runs-on: ubuntu-latest steps: - name: Initialize environment - uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@fa43fd2864c3bec677cd47f4e095370850cdf8bc # main + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@6a54b1f6636c00be7b9c3fa5928da87df48ff9a0 # main - name: Setup Bazel - uses: angular/dev-infra/github-actions/bazel/setup@fa43fd2864c3bec677cd47f4e095370850cdf8bc # main + uses: angular/dev-infra/github-actions/bazel/setup@6a54b1f6636c00be7b9c3fa5928da87df48ff9a0 # main - name: Setup Bazel RBE - uses: angular/dev-infra/github-actions/bazel/configure-remote@fa43fd2864c3bec677cd47f4e095370850cdf8bc # main + uses: angular/dev-infra/github-actions/bazel/configure-remote@6a54b1f6636c00be7b9c3fa5928da87df48ff9a0 # main - name: Install node modules run: pnpm install --frozen-lockfile - name: Build release targets @@ -93,11 +93,11 @@ jobs: runs-on: ubuntu-latest steps: - name: Initialize environment - uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@fa43fd2864c3bec677cd47f4e095370850cdf8bc # main + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@6a54b1f6636c00be7b9c3fa5928da87df48ff9a0 # main - name: Setup Bazel - uses: angular/dev-infra/github-actions/bazel/setup@fa43fd2864c3bec677cd47f4e095370850cdf8bc # main + uses: angular/dev-infra/github-actions/bazel/setup@6a54b1f6636c00be7b9c3fa5928da87df48ff9a0 # main - name: Setup Bazel RBE - uses: angular/dev-infra/github-actions/bazel/configure-remote@fa43fd2864c3bec677cd47f4e095370850cdf8bc # main + uses: angular/dev-infra/github-actions/bazel/configure-remote@6a54b1f6636c00be7b9c3fa5928da87df48ff9a0 # main - name: Install node modules run: pnpm install --frozen-lockfile - name: Run module and package tests @@ -114,13 +114,13 @@ jobs: runs-on: ubuntu-latest steps: - name: Initialize environment - uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@fa43fd2864c3bec677cd47f4e095370850cdf8bc # main + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@6a54b1f6636c00be7b9c3fa5928da87df48ff9a0 # main - name: Install node modules run: pnpm install --frozen-lockfile - name: Setup Bazel - uses: angular/dev-infra/github-actions/bazel/setup@fa43fd2864c3bec677cd47f4e095370850cdf8bc # main + uses: angular/dev-infra/github-actions/bazel/setup@6a54b1f6636c00be7b9c3fa5928da87df48ff9a0 # main - name: Setup Bazel RBE - uses: angular/dev-infra/github-actions/bazel/configure-remote@fa43fd2864c3bec677cd47f4e095370850cdf8bc # main + uses: angular/dev-infra/github-actions/bazel/configure-remote@6a54b1f6636c00be7b9c3fa5928da87df48ff9a0 # main - name: Run CLI E2E tests run: pnpm bazel test --test_env=E2E_SHARD_TOTAL=6 --test_env=E2E_SHARD_INDEX=${{ matrix.shard }} --config=e2e //tests:e2e.${{ matrix.subset }}_node${{ matrix.node }} @@ -128,11 +128,11 @@ jobs: runs-on: ubuntu-latest steps: - name: Initialize environment - uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@fa43fd2864c3bec677cd47f4e095370850cdf8bc # main + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@6a54b1f6636c00be7b9c3fa5928da87df48ff9a0 # main - name: Setup Bazel - uses: angular/dev-infra/github-actions/bazel/setup@fa43fd2864c3bec677cd47f4e095370850cdf8bc # main + uses: angular/dev-infra/github-actions/bazel/setup@6a54b1f6636c00be7b9c3fa5928da87df48ff9a0 # main - name: Setup Bazel RBE - uses: angular/dev-infra/github-actions/bazel/configure-remote@fa43fd2864c3bec677cd47f4e095370850cdf8bc # main + uses: angular/dev-infra/github-actions/bazel/configure-remote@6a54b1f6636c00be7b9c3fa5928da87df48ff9a0 # main - name: Install node modules run: pnpm install --frozen-lockfile - name: Build E2E tests for Windows on Linux @@ -156,7 +156,7 @@ jobs: runs-on: windows-2025 steps: - name: Initialize environment - uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@fa43fd2864c3bec677cd47f4e095370850cdf8bc # main + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@6a54b1f6636c00be7b9c3fa5928da87df48ff9a0 # main - name: Install node modules run: pnpm install --frozen-lockfile - name: Download built Windows E2E tests @@ -183,13 +183,13 @@ jobs: runs-on: ubuntu-latest steps: - name: Initialize environment - uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@fa43fd2864c3bec677cd47f4e095370850cdf8bc # main + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@6a54b1f6636c00be7b9c3fa5928da87df48ff9a0 # main - name: Install node modules run: pnpm install --frozen-lockfile - name: Setup Bazel - uses: angular/dev-infra/github-actions/bazel/setup@fa43fd2864c3bec677cd47f4e095370850cdf8bc # main + uses: angular/dev-infra/github-actions/bazel/setup@6a54b1f6636c00be7b9c3fa5928da87df48ff9a0 # main - name: Setup Bazel RBE - uses: angular/dev-infra/github-actions/bazel/configure-remote@fa43fd2864c3bec677cd47f4e095370850cdf8bc # main + uses: angular/dev-infra/github-actions/bazel/configure-remote@6a54b1f6636c00be7b9c3fa5928da87df48ff9a0 # main - name: Run CLI E2E tests run: pnpm bazel test --test_env=E2E_SHARD_TOTAL=3 --test_env=E2E_SHARD_INDEX=${{ matrix.shard }} --config=e2e //tests:e2e.${{ matrix.subset }}_node${{ matrix.node }} @@ -205,12 +205,12 @@ jobs: runs-on: ubuntu-latest steps: - name: Initialize environment - uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@fa43fd2864c3bec677cd47f4e095370850cdf8bc # main + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@6a54b1f6636c00be7b9c3fa5928da87df48ff9a0 # main - name: Install node modules run: pnpm install --frozen-lockfile - name: Setup Bazel - uses: angular/dev-infra/github-actions/bazel/setup@fa43fd2864c3bec677cd47f4e095370850cdf8bc # main + uses: angular/dev-infra/github-actions/bazel/setup@6a54b1f6636c00be7b9c3fa5928da87df48ff9a0 # main - name: Setup Bazel RBE - uses: angular/dev-infra/github-actions/bazel/configure-remote@fa43fd2864c3bec677cd47f4e095370850cdf8bc # main + uses: angular/dev-infra/github-actions/bazel/configure-remote@6a54b1f6636c00be7b9c3fa5928da87df48ff9a0 # main - name: Run CLI E2E tests run: pnpm bazel test --test_env=E2E_SHARD_TOTAL=6 --test_env=E2E_SHARD_INDEX=${{ matrix.shard }} --config=e2e //tests:e2e.snapshots.${{ matrix.subset }}_node${{ matrix.node }} diff --git a/MODULE.bazel b/MODULE.bazel index 994210f39c91..79c7997e4d26 100644 --- a/MODULE.bazel +++ b/MODULE.bazel @@ -19,21 +19,21 @@ bazel_dep(name = "aspect_rules_jasmine", version = "2.0.4") bazel_dep(name = "rules_angular") git_override( module_name = "rules_angular", - commit = "ed98d720477b10c13f3d0ccee72f929c777f6ccd", + commit = "0b3df623e1935b929f43a0981408a5cdc4fea953", remote = "https://github.com/angular/rules_angular.git", ) bazel_dep(name = "devinfra") git_override( module_name = "devinfra", - commit = "fa43fd2864c3bec677cd47f4e095370850cdf8bc", + commit = "6a54b1f6636c00be7b9c3fa5928da87df48ff9a0", remote = "https://github.com/angular/dev-infra.git", ) bazel_dep(name = "rules_browsers") git_override( module_name = "rules_browsers", - commit = "c6cb5590120af8ae8125343f9fc522b7b66eb0e8", + commit = "c00a3cb7a13840bbfa16fa6fa32ac190ae47c54f", remote = "https://github.com/angular/rules_browsers.git", ) diff --git a/MODULE.bazel.lock b/MODULE.bazel.lock index 780cef563755..a4a953ee498c 100644 --- a/MODULE.bazel.lock +++ b/MODULE.bazel.lock @@ -26,7 +26,6 @@ "https://bcr.bazel.build/modules/aspect_rules_js/3.4.0/MODULE.bazel": "88844ac411e1961f4574a92f3c5be5b20d1c6997778c6b88316c5c3b4b60e284", "https://bcr.bazel.build/modules/aspect_rules_js/3.4.1/MODULE.bazel": "e46853c134b48bc84c9bb5c4a4c8ae792dcfd5277acac9d90c444d65fa43dd19", "https://bcr.bazel.build/modules/aspect_rules_js/3.4.1/source.json": "b11f550b53d451800ebd0b4f38a048aea33fbfbd78fb5c77dca847f6b9b47a3b", - "https://bcr.bazel.build/modules/aspect_rules_ts/3.10.0/MODULE.bazel": "69d06f57f30f4a2b6e53471584a9559d3b7cd7f891e1699876991230c7cabb95", "https://bcr.bazel.build/modules/aspect_rules_ts/3.10.1/MODULE.bazel": "035205a7834b0ed9724ed3c4790e12d1c779ef2520d72496ab234e6307715e6c", "https://bcr.bazel.build/modules/aspect_rules_ts/3.10.1/source.json": "d42b6560206adb5524caad2abc40ae0b5b34478dd38184a9f6ea4a5fed848cd6", "https://bcr.bazel.build/modules/aspect_tools_telemetry/0.2.8/MODULE.bazel": "aa975a83e72bcaac62ee61ab12b788ea324a1d05c4aab28aadb202f647881679", diff --git a/package.json b/package.json index 7806b3b929ed..e5f7f3750512 100644 --- a/package.json +++ b/package.json @@ -54,7 +54,7 @@ "@angular/forms": "22.2.0-next.4", "@angular/localize": "22.2.0-next.4", "@angular/material": "22.2.0-next.3", - "@angular/ng-dev": "https://github.com/angular/dev-infra-private-ng-dev-builds.git#beec8fe17573a33c9934487ce99ce9cce3e3f6bf", + "@angular/ng-dev": "https://github.com/angular/dev-infra-private-ng-dev-builds.git#151e36ffa910f4a01aafe1c482ed8294e2050566", "@angular/platform-browser": "22.2.0-next.4", "@angular/platform-server": "22.2.0-next.4", "@angular/router": "22.2.0-next.4", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index e5308f871e85..2338e1b07beb 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -50,8 +50,8 @@ importers: specifier: 22.2.0-next.3 version: 22.2.0-next.3(2d3d12f5adbcb81bda5dafdebadbbaef) '@angular/ng-dev': - specifier: https://github.com/angular/dev-infra-private-ng-dev-builds.git#beec8fe17573a33c9934487ce99ce9cce3e3f6bf - version: https://codeload.github.com/angular/dev-infra-private-ng-dev-builds/tar.gz/beec8fe17573a33c9934487ce99ce9cce3e3f6bf + specifier: https://github.com/angular/dev-infra-private-ng-dev-builds.git#151e36ffa910f4a01aafe1c482ed8294e2050566 + version: https://codeload.github.com/angular/dev-infra-private-ng-dev-builds/tar.gz/151e36ffa910f4a01aafe1c482ed8294e2050566 '@angular/platform-browser': specifier: 22.2.0-next.4 version: 22.2.0-next.4(@angular/animations@22.2.0-next.4(@angular/core@22.2.0-next.4(@angular/compiler@22.2.0-next.4)(rxjs@7.8.2)(zone.js@0.16.2)))(@angular/common@22.2.0-next.4(@angular/core@22.2.0-next.4(@angular/compiler@22.2.0-next.4)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2))(@angular/core@22.2.0-next.4(@angular/compiler@22.2.0-next.4)(rxjs@7.8.2)(zone.js@0.16.2)) @@ -940,9 +940,9 @@ packages: '@angular/platform-browser': ^22.0.0-0 || ^22.1.0-0 || ^22.2.0-0 || ^22.3.0-0 || ^23.0.0-0 rxjs: ^6.5.3 || ^7.4.0 - '@angular/ng-dev@https://codeload.github.com/angular/dev-infra-private-ng-dev-builds/tar.gz/beec8fe17573a33c9934487ce99ce9cce3e3f6bf': - resolution: {gitHosted: true, integrity: sha512-ELGv/rsp5iaQw1+viAhn5IlLrodz7g7rPm6Ea06sEsBpQ2kSamcpZnXWf+j4SPzGvK+td+DtFCrgbkX+ihFiZQ==, tarball: https://codeload.github.com/angular/dev-infra-private-ng-dev-builds/tar.gz/beec8fe17573a33c9934487ce99ce9cce3e3f6bf} - version: 0.0.0-8fb164f40c9776c41771785c6d9facbd9ea63b73 + '@angular/ng-dev@https://codeload.github.com/angular/dev-infra-private-ng-dev-builds/tar.gz/151e36ffa910f4a01aafe1c482ed8294e2050566': + resolution: {gitHosted: true, integrity: sha512-Y1lrl+05m57WpiTLSB6CgdS0RxzG+uElOl97PtJhDhHCZSMyG0zmHsX2u1goa6uC1NSb0Zlr3erdqZhJ1a+3Ag==, tarball: https://codeload.github.com/angular/dev-infra-private-ng-dev-builds/tar.gz/151e36ffa910f4a01aafe1c482ed8294e2050566} + version: 0.0.0-6a54b1f6636c00be7b9c3fa5928da87df48ff9a0 hasBin: true '@angular/platform-browser@22.2.0-next.4': @@ -1847,75 +1847,75 @@ packages: '@noble/hashes': optional: true - '@firebase/ai@2.14.0': - resolution: {integrity: sha512-TYEQqCQUTyVHuG/HVi9vau6F9kvEaS49o/hmdn/yUuN6ZXQkwIml2nNJTIBfjNl/r9LOxwUNILgcOY16nxObug==} + '@firebase/ai@2.15.0': + resolution: {integrity: sha512-Aj7TbFdAIWZdkX8JfdDStERpR35g6WNs+7XhNPtFLFOizUotj6k4N/D8HJkR45165HhnMJBe4hjOeeaxnnn56Q==} engines: {node: '>=20.0.0'} peerDependencies: '@firebase/app': 0.x '@firebase/app-types': 0.x - '@firebase/analytics-compat@0.2.29': - resolution: {integrity: sha512-allztvCvCUlItZzD97TiRAtGoFJzR1FQFmLxbaLc6PvgscqD9cl5NdKPTtka6keShVYXvCZJpzWcRoH4TME8rw==} + '@firebase/analytics-compat@0.2.30': + resolution: {integrity: sha512-uVZEKlLaW4AHAhv8zoN9cTmveX6v86AVqcJ4LCaRCMTChTH8/NsjbisTq1lpBfWCLWS1spqwSHB4vol/YSCdMA==} peerDependencies: '@firebase/app': 0.x '@firebase/app-compat': 0.x - '@firebase/analytics-types@0.8.4': - resolution: {integrity: sha512-zQ+XTgkwH6CY/eUSHJRP7e4LxM30RCxlCmob5sy2axs25GE3Ny0XdgpDscMTHHQIGqWkxPXad4w2Mw9sCgT8zQ==} + '@firebase/analytics-types@0.8.5': + resolution: {integrity: sha512-kdnooE7Bis2jEnsqcerRwn/UQpH5D3uvHpku7OdUM9TJN3omlu6iYtbyAQ6XkAJRgJtO0aNf9OOkW8J6D59oCA==} - '@firebase/analytics@0.10.23': - resolution: {integrity: sha512-34ALWXzWA6PTRUA5hipZmsm1RKzeecw5J1+qTCXsiMzwLqONC+GuTIQSdmm91MmTAEA+wG1Q5t0IFahcYQOqAA==} + '@firebase/analytics@0.10.24': + resolution: {integrity: sha512-OfIAcIIwoqXjBzS+DnUQpOZ7i3ePaNFg83KPpDWjBZUKJmqMwzzAtLJqmKZOkQnW8im6vFR6f2I3M/9hxVd+QA==} peerDependencies: '@firebase/app': 0.x - '@firebase/app-check-compat@0.4.6': - resolution: {integrity: sha512-2pzNEZEkX84jSqy6TH6FI1HSLA1lc7kakRUybBbKjg9YhIttPlW/XX3N9CDtChji2PTTPWVPZiWhB10exHfA+A==} + '@firebase/app-check-compat@0.4.7': + resolution: {integrity: sha512-fBb/xSMyIKv1nDmccfzz3IAGBzx/cQOxmZai66rJzifb1hMMkztf824Xx7LhpTUe7HNUbXwY90IvJ66fi8q6yg==} engines: {node: '>=20.0.0'} peerDependencies: '@firebase/app': 0.x '@firebase/app-compat': 0.x - '@firebase/app-check-interop-types@0.3.4': - resolution: {integrity: sha512-zz3i6e13B8BfWiLy8MABtTh8aGIACgKbf9UVnyHcWs+yQzJXgQcl8A46b0zfaiJHdQ+niF0ouAfcpuf+3LMPQg==} + '@firebase/app-check-interop-types@0.3.5': + resolution: {integrity: sha512-qId34pVZ2CXTmtu4ofW5leiI93DvnOvIcr/5GT7MZPw5WXAi6nZoU+g9cNRgl7K90UJSbK0cXxten4meYMPyZg==} - '@firebase/app-check-types@0.5.4': - resolution: {integrity: sha512-xV7JsIyzVr15aA7f3Pi0rB9gdBuVubs89FGA8VkRYA4g0l78poADgdfrScgf7NndSg9mm7cR7PJyY0+t22KaGw==} + '@firebase/app-check-types@0.5.5': + resolution: {integrity: sha512-+DF4gzFrlwGFyky38o4T/YN/r51l70yCtJ2HTkwmRj8FCMwPjm4hLH4fQbj6BUvzkiFqliBkitFsRpf1/YZkWA==} - '@firebase/app-check@0.13.0': - resolution: {integrity: sha512-AbMttBKazQvGVXBZhQdVAdPzRhwHyJAY3Ghu5y2C7IZKIDIppzNYz0shTZ1mP4FBJa+28BuC4t+5h1Q6pT3Asg==} + '@firebase/app-check@0.13.1': + resolution: {integrity: sha512-l8y3dmnhodXks/APAwx4tWqRl3tk8b9874KF1FJyKg1DIU+kMD0l52iz7S9/MW+eK8k6cjJg0G0iJ5KQAsQpow==} engines: {node: '>=20.0.0'} peerDependencies: '@firebase/app': 0.x - '@firebase/app-compat@0.5.16': - resolution: {integrity: sha512-shQq37O8qELDzvsVwYPlDXwD1zlcrZ0m2bpBF5ov2HSbY8x+AHsnL5TtJ2e1JAfkQN05qHao1AfabS69PN6GiA==} + '@firebase/app-compat@0.5.17': + resolution: {integrity: sha512-5GdJWobqs6jbNYOnaQiSa4Ng8gnFerhqr7nY+v5jlnT7o9QbEeIZRLPQpnLe0TxYSWfRV2lAMbyR0kbXeIos9Q==} engines: {node: '>=20.0.0'} - '@firebase/app-types@0.9.5': - resolution: {integrity: sha512-YevqTjvo7Iujsa9Dwowmd6dSoElhzmD63ZSrq6bzjvQ6POjYgNjOFHLmNIgJs48eNO093NCERibuFnxbfOvU7A==} + '@firebase/app-types@0.9.6': + resolution: {integrity: sha512-yPLahy7Esfu2w/yme3msVK4xTkDXQqq6szfQn8yVOQpCKiT5GVFjqNpLbuz6NkX0WuTwUidkmPewW3r4xkvpeg==} - '@firebase/app@0.16.0': - resolution: {integrity: sha512-G+ZGEyVP8YTb3ay6A+XpcYgFH3sTESHcnHU/EyTktodqhz2BHkLq+QEP7IVwjiMX0cxYwpVKip0/wC0KZcn9vQ==} + '@firebase/app@0.16.1': + resolution: {integrity: sha512-tjUEorFyKrurH7PbLWv9zDHRuU4mLefgD/yY38D584ziorIRlQz/PVjx4c/SCGyCuUlmyzt72mK+Lh+COAywNQ==} engines: {node: '>=20.0.0'} - '@firebase/auth-compat@0.6.9': - resolution: {integrity: sha512-/hHeTBmQ61+N5J1RECls+WfskZTY78JXr7aO5EMOfUpqJvDqvoS+568k0rp6Ss/4UWwBjadILs+H+SGy1zCS3A==} + '@firebase/auth-compat@0.6.10': + resolution: {integrity: sha512-Bvklg2nL7BrBFCAqdsleW8fse9Jh0fARqJPlJmA40uermfWx1bJiO7dnKyZN3J39d2TFVd4VJXtg3i6Wg92/YQ==} engines: {node: '>=20.0.0'} peerDependencies: '@firebase/app': 0.x '@firebase/app-compat': 0.x - '@firebase/auth-interop-types@0.2.5': - resolution: {integrity: sha512-1Li/YuBDBAXcKv7BzY4U28gontUmAaw53sYiqbaVOMCFb2lFKK/c3CGMUWqtwe7+TXrl3poWnTCL5umYBg85Eg==} + '@firebase/auth-interop-types@0.2.6': + resolution: {integrity: sha512-FgwZqDrBqgK0BHI70QTv1v/5wmuDF9f8fsJFvKSxoRlK2PPfSQtZAk2jhXu4pe9BZzFi/e4UYusU/bEQHdf6Qg==} - '@firebase/auth-types@0.13.1': - resolution: {integrity: sha512-0c1Mnid0uMDfGJHeUS4zfvBa4/CedJXotGy/n/NZJnBjwiJawt0ZYU+wH2VAVLiRCEfG2ncCkAX3yd1/2nrB7g==} + '@firebase/auth-types@0.13.2': + resolution: {integrity: sha512-OU+miuoSxIWYN7GT291d2ylVJBL3k/OePo7/JDSoQtkFQoEiGBc4AHuMjj/seqFIsHrqnjrAfRCk4pfufoJolQ==} peerDependencies: '@firebase/app-types': 0.x '@firebase/util': 1.x - '@firebase/auth@1.13.4': - resolution: {integrity: sha512-s+NS1aV0DDyyfoIMeSz53HXnVTv7ufJjJfrP63XyaWHweJ5vOoxKWrTm5tO7S7PDqvyOa/Wi3oP0dgAo6JTMMA==} + '@firebase/auth@1.13.5': + resolution: {integrity: sha512-1AXoBJqBVD8WL8FZYo3S2GmJF9YUoom6Y6ngMxOSkzzhW5sT83pLchb6TGFgxes91dfXx8s/VYc5VrLDNqpLog==} engines: {node: '>=20.0.0'} peerDependencies: '@firebase/app': 0.x @@ -1924,17 +1924,17 @@ packages: '@react-native-async-storage/async-storage': optional: true - '@firebase/component@0.7.4': - resolution: {integrity: sha512-tLpOaaCol9ugUIYp2R3CbWPPA8Ajg/papX/XHEy8U52b/QXH3BbX8tTJX9aShDCjp+9sMAxMLD94i7lresdugQ==} + '@firebase/component@0.7.5': + resolution: {integrity: sha512-vuFDcL91Q+2ZuBJkyOh86T4q0B4ffNTDjc/A38tybO56odQABxRTFLTIowCWqAKeIcgo37GowWMVgFF73gD8Qw==} engines: {node: '>=20.0.0'} - '@firebase/data-connect@0.7.3': - resolution: {integrity: sha512-nHBFk3Ntl+NZCRIUG2d5j7I69P0otjyQ/duhVKLbw4+5cNke/F6RK1pdE5Jnf831/QOTs2Bd00LlxlZ+jNsb9w==} + '@firebase/data-connect@0.7.4': + resolution: {integrity: sha512-su1aGWlzhxb+xtggCUSsufJn1FDa06SBDK71y+fpQ+g2zMhMExik6FUv/odkKzOF/xfWVjabCbWBcjJY3MceDA==} peerDependencies: '@firebase/app': 0.x - '@firebase/database-compat@2.1.6': - resolution: {integrity: sha512-mu7S/75UIajB1A5M9Vfojk69LttW55uABp9nHEtWrV/mIaSEwvoaIe9GySsEzS2EKFK5/3f5okcAuUbihhYeJg==} + '@firebase/database-compat@2.1.7': + resolution: {integrity: sha512-lBq9sJm8MnJINKJnkAKSOj2MbC66xGoSVCcGkPtstl+lkoKEBtD46qHLbuDgW/WbLPoKVm17RIN8BxHj+Z2F2w==} engines: {node: '>=20.0.0'} peerDependencies: '@firebase/app': 0.x @@ -1945,135 +1945,135 @@ packages: '@firebase/app-compat': optional: true - '@firebase/database-types@1.0.21': - resolution: {integrity: sha512-SX1jUqhttKgg/m9dYRTvqU9QvucBooziWfA986r4cpsbi4zlsvewe424j3Vpduwd6DG1MSAMfBVT2VqA61FnkA==} + '@firebase/database-types@1.0.22': + resolution: {integrity: sha512-YAZNXsjY9EQQ+pKw/3ax8n5FgolHC7Qew7EY5RceYdl0R2ZP+kCv1O0DkKlcceue8uQCOreHCNN7PWVFpY1Nug==} - '@firebase/database@1.1.4': - resolution: {integrity: sha512-D+j4+8uhGtNd1tVD+X+c8JrC4ppStGJKyujSQt2NPwdN26QcCk0BeIxue+UqspHkHiFHyQOimwlzjLewGq6S+A==} + '@firebase/database@1.1.5': + resolution: {integrity: sha512-/JGpvszLoNXNgzilRXocigGfFF4hbcPA9wN1i1kjJx6oKkXgkHteZYl3lQs1lJX3ETDf6bv7zI15lPMVUp4sAQ==} engines: {node: '>=20.0.0'} - '@firebase/firestore-compat@0.4.12': - resolution: {integrity: sha512-k2uX81Ao/S0jnFcWGPOQpKK1cPlJHvD9WIqh/RE1XBDP2yg5zhE4rHhSg1rtB11k39q3nKon9XLNDDrPjGclag==} + '@firebase/firestore-compat@0.4.13': + resolution: {integrity: sha512-l9dCewxMzzLOIhcwTjERCKxrWOn1kZ9JvwOQq9zZNq4I/Nbvb/B9njT230V61uvQ9qZ3/qpUG758D8DDTEFXnw==} engines: {node: '>=20.0.0'} peerDependencies: '@firebase/app': 0.x '@firebase/app-compat': 0.x - '@firebase/firestore-types@3.0.4': - resolution: {integrity: sha512-jGn+JSS4X9zZsrfu7Yw66v5YRdOLD1oyQh4USR0xWl4CUqV/DA6bNIXRPpxH/cUl3iVTNiP6MN7g+EL42A4qfA==} + '@firebase/firestore-types@3.0.5': + resolution: {integrity: sha512-dbdMAQkMd5dwWc48eupz/Y6/E9ruat3+gY5lhVKscvvT/HnDBEEMzJW38zdKhgdnglZHGk2vUsJMOHAphMHGMA==} peerDependencies: '@firebase/app-types': 0.x '@firebase/util': 1.x - '@firebase/firestore@4.17.0': - resolution: {integrity: sha512-P9tof6pyO1bnLlMWbux+5O7WFJqlb7OTPMKxxOiXKYiQl7mxykAvxr1BFCgWeEXUU7DZxQncyJ040B0IhFVZCg==} + '@firebase/firestore@4.17.1': + resolution: {integrity: sha512-8lqPNf2w10CtYG+tayVjZO1pSyQpnhztQRudeD109VtXDzNbASTaYdO43sj5PMsDcWq0aOYY3RmJOUlXu9++jw==} engines: {node: '>=20.0.0'} peerDependencies: '@firebase/app': 0.x - '@firebase/functions-compat@0.4.6': - resolution: {integrity: sha512-dj9sOet+FIU91jeU4A3vGJoXHty7NqkSfjRLCwLgJXPDk1m72KFuxD3nlFgw/yXx/Fr7UjqzbxZ0LrIOdpx7+w==} + '@firebase/functions-compat@0.5.0': + resolution: {integrity: sha512-T3BDIToESZUHt7438wyKYMkRjKg3m1xAIux5fVpNvTRQlDOFLukWniQWBDhJ2znpU9kxMTR6+e31TVo8P15PZw==} engines: {node: '>=20.0.0'} peerDependencies: '@firebase/app': 0.x '@firebase/app-compat': 0.x - '@firebase/functions-types@0.6.4': - resolution: {integrity: sha512-zV6kgqtduR4rUAdC/ilS7kmb93XD7bEZoJDlVBZqlOw2uGGGCNBQBuleww2rr0Ulr3L9o2TDjumEt68/l1f9DQ==} + '@firebase/functions-types@0.6.5': + resolution: {integrity: sha512-Zc0pURjthHXzSj54ZivCkzKDSV1r/wIpnmHdhq82q2yFFPVoncG/ZJjnVMiANvQfeww/QnElhzODpfwUucVwdA==} - '@firebase/functions@0.13.6': - resolution: {integrity: sha512-9obLnzeQUivK5lmtGFOU2ucQ38BjTp+jpPtbfFp/mDsdVCvEpRqdWNvMMQ6aQwR4vcVc/utsvngm5BRkXbc7ZA==} + '@firebase/functions@0.14.0': + resolution: {integrity: sha512-DhuYFr0eMhp+s/PNEk6SiMsYkc00+XVOUeKbrl8MOzQNZI3SKQpqoDR1d+keNDAutwmHRWTUAdXBoVPD+xxVUw==} engines: {node: '>=20.0.0'} peerDependencies: '@firebase/app': 0.x - '@firebase/installations-compat@0.2.23': - resolution: {integrity: sha512-isaXmjb9roM83eVeXAe+ZRNKYNsSo2s0aNM+cy04AAGEyVL/d8Aa11GwEXovRFeYjl9+1yRAOxRDTOukZRwTxA==} + '@firebase/installations-compat@0.2.24': + resolution: {integrity: sha512-8M5nlcWwYt881x83COP2odq5vgf+NgwJh+RMd4LRSv8JI1pxwDfgrDJOERrjTgfC9J5Z0vnQX4b1pdN914e0Zw==} peerDependencies: '@firebase/app': 0.x '@firebase/app-compat': 0.x - '@firebase/installations-types@0.5.4': - resolution: {integrity: sha512-U2eFapdHwjb43Vx9o+Pmj4dFfvcHEK1IirEFLqMtWrTHvmdrS3gBpBD1kmJk/9HjsOtoHZxJ2Paoe79e+L1ZPg==} + '@firebase/installations-types@0.5.5': + resolution: {integrity: sha512-e9UYcju3puDl1vdrcKIi5dExzHLameOT/Tc61Q48PYwxtsM1NzZh/ikGbdBQTsbRgg0EMZqdPr0/m5ODUBobrg==} peerDependencies: '@firebase/app-types': 0.x - '@firebase/installations@0.6.23': - resolution: {integrity: sha512-MBkbcQfd+3qHjW+slsH4s7jH5qTdGlYpwqmxEZ7QcIpgDxu1SKyU0f+mCZhCt1BCacLNiOWF5L0R06N0LtlfMg==} + '@firebase/installations@0.6.24': + resolution: {integrity: sha512-Ui52ey8wHoWqkBbXRKJEKYWylI0JZogZmoLS+o8Anh1bxWtK27ZYjLla1UJAAdC5DCKLJ2qAp0VpJOjg8VOX1g==} peerDependencies: '@firebase/app': 0.x - '@firebase/logger@0.5.1': - resolution: {integrity: sha512-vZKLsqE1ABOy8OjQiE7cUTFn4gvaqlk88yp8N94Pk/sDpq61YqZGqmVFZTvOyflTwuYFcWirBdYGoJgbDaXKYQ==} + '@firebase/logger@0.5.2': + resolution: {integrity: sha512-J2VO4NFTc0xQFrxV1B/lm5balicm9cwuX2acR9Yn41fN8KgUeQFo+VJV222IqW2FPSXKDu9uo5WdQFWf9TPbYg==} engines: {node: '>=20.0.0'} - '@firebase/messaging-compat@0.2.28': - resolution: {integrity: sha512-/AmMqHRnSQhPsdeED3ocs+s30/tpFvZDiiwIYY2uXFRvLujo1fnbPOeCFoe4Y+dRy1LCSjpvJf+dy5ZTsxi1yg==} + '@firebase/messaging-compat@0.2.29': + resolution: {integrity: sha512-8Twe4CeYvAx8AzjBxyyQFKzinaMGGt13hPQBqaARQ2QZjagrEaqSVBe+Zy6F4L/vT8DV168yRgRu7W/RK7p+4w==} peerDependencies: '@firebase/app': 0.x '@firebase/app-compat': 0.x - '@firebase/messaging-interop-types@0.2.5': - resolution: {integrity: sha512-tUEKnaAP2Y/MNIqgnriPpV6e5l13Vs/+p2yrd6NGlncPJT9O3a8muYZtdnWe+IJ4fgKLHJVC79n/asxk/N5Msw==} + '@firebase/messaging-interop-types@0.2.6': + resolution: {integrity: sha512-MVzvkKe2V4H2dHu5oOxRfeKQcfTwWmCgnzsC4V1q3ixun5iiL8riCZ2qI35rDhCL4glPGiu0jHxDbpVNuTKfow==} - '@firebase/messaging@0.13.1': - resolution: {integrity: sha512-kL8fdjbNBI7hprlXJrUjktDWosrpT4JtfwXtVVevImPF/rBRAsC+LS/jIs+kgQVuotnvMhaBCgAFipBoY9YU9g==} + '@firebase/messaging@0.13.2': + resolution: {integrity: sha512-KcZoqUu2ih4sLH91dW9tmyHjCR0IQyNzSLZunX5uq7cLeImXb4uO2I0wq5FACduO2I+FoTeWa2BtUv7Jpowqdw==} peerDependencies: '@firebase/app': 0.x - '@firebase/performance-compat@0.2.26': - resolution: {integrity: sha512-jgoocXLN6ao26xWQ8pzosmzQ33uLzGBJQPNK0NTbVy1XvIHr5pfgBf9hWLOxsWe+R7sJq5bjD+8ybXprmt61mA==} + '@firebase/performance-compat@0.2.27': + resolution: {integrity: sha512-O/ozTf/EbChN94Pk7bd1eUC0PAC36726AwsaiJyC0bZzSBWfLGSWASGPH5pebUWXQPJtGxIJYRkkbX5l0Qa+Hw==} peerDependencies: '@firebase/app': 0.x '@firebase/app-compat': 0.x - '@firebase/performance-types@0.2.4': - resolution: {integrity: sha512-kJSEk7b0uhpcPRyL4SQ/GPujLqk52XNKcXlnsKDbWGAb9vugcLvOU3u6zfEdwd+d8hWJb5S5ZizV1JFFI0nkKg==} + '@firebase/performance-types@0.2.5': + resolution: {integrity: sha512-PRzOgB+/M+6AKlEkY8a9xy5Ff5SfZPIh4iShXhn2WAcL/euSbK7bdLqWysHduunNJhGFsXa22Ag3ixqL6rQtYg==} - '@firebase/performance@0.7.13': - resolution: {integrity: sha512-1u6fuXP9cj0s+lkTFAspr/ttfPebPbEdpx+5Wdr4mPZbp8qH2KCMxOddEAR1ZMRa5GI0E7hDYSnolEmbqOFOAg==} + '@firebase/performance@0.7.14': + resolution: {integrity: sha512-9PH1XEZVHErxGdbXluvGz4Uyjw4W955H8v7Mv9rHIybRrg5F2Ac2tvf5+mSf5EtnxWNmxrD2WLnvMFaZP4sMrQ==} peerDependencies: '@firebase/app': 0.x - '@firebase/remote-config-compat@0.2.28': - resolution: {integrity: sha512-kEO9Gn6fbmVj7eNUtZ6d59mLgUDUD0qo7aCicGOWNfuRWTaUv3CF9DMYychO61zaEQ3cfA+CEny4V1E8A1gRGA==} + '@firebase/remote-config-compat@0.2.29': + resolution: {integrity: sha512-mY7JtTISK6F4g4T0x3kVepr5cp0NXL7f5yjIUXXGaTrg4qUlFBWRbENaHaqZ78dwmNcLm24h/yPsOVRlDXEXhA==} peerDependencies: '@firebase/app': 0.x '@firebase/app-compat': 0.x - '@firebase/remote-config-types@0.5.1': - resolution: {integrity: sha512-cX/1LT6KQwkXzck2eSzeKnuvXZCyr8qaPpDcikoJs7jmI+oBOXixpDLeDtWj1U6GNMkIoXrEDNoyT2Ypcyp5/A==} + '@firebase/remote-config-types@0.5.2': + resolution: {integrity: sha512-i8k1omVfoAnaT1ZPv2FFjxMZrATYsO/GnFgHEj5+7fAJLzi8wLnGGv1WK06oEAD6ltrWXSO1HzeNyajn/NjMWw==} - '@firebase/remote-config@0.9.1': - resolution: {integrity: sha512-nzQUSJnk1zAZEl2Q5O3I7Z61cYLK5JI4H6wyyOiHkVZ+bmgy1YXNNMptNbVjixMQ/eCzgA6nZRaC+1eBcJGUFA==} + '@firebase/remote-config@0.9.2': + resolution: {integrity: sha512-Rii93DkXjM+RE/ytHdYa7EIiQLJbdBr+W8EEiqd/vbLCOC+1FdkDuRiumJBp6t3yewHGbdqbpjB3fk3z0cZ+8g==} peerDependencies: '@firebase/app': 0.x - '@firebase/storage-compat@0.4.4': - resolution: {integrity: sha512-qSRgCB9f2R/nCp8t/8OC101cIFBFeUazlRInOMdzbnLzvrQBzEfx19SrR4pvdj/0+M+P/y8AK/a2s+3EB+B1Pw==} + '@firebase/storage-compat@0.4.5': + resolution: {integrity: sha512-vO0tFPxXbKDKdlTu8tYT08S9t9ezUTJYEdLCULpWxWq2aq6zojwN1QmAB+1a50AI/g47GlWUJn1XPncm/PDZsw==} engines: {node: '>=20.0.0'} peerDependencies: '@firebase/app': 0.x '@firebase/app-compat': 0.x - '@firebase/storage-types@0.8.4': - resolution: {integrity: sha512-BT7cwxJOx8SWwlQfrlC+bD/Sk3Cw+1odCi8UZNFNWTVZoPsBnA5W+mqtZzVnvsdJpXCFGSGQ7R7vOR6dtM/BRA==} + '@firebase/storage-types@0.8.5': + resolution: {integrity: sha512-GEDs5P+rNUfNcS+wxIdOLAHficife2YXtvTJnyi3ssrX11AAtBg+nDUdbYh8vuBzWehVQZPmztGUUnud4L+4yg==} peerDependencies: '@firebase/app-types': 0.x '@firebase/util': 1.x - '@firebase/storage@0.14.4': - resolution: {integrity: sha512-jfzEWZb3Fpsq3FwAB2ifoc8mcSh935qXdDou3TpyjDWa45hhNcZUv8/w28/10njByhfK7snbakKN30nwnzQ3/w==} + '@firebase/storage@0.14.5': + resolution: {integrity: sha512-r2tozN/BlEewLi70tJNUQPzWwbex9GM7NgXZsamHKQrjKEfcR0i4jGgHBKAKA4hbwiPE9eNMb3hcxWnDpeJZwg==} engines: {node: '>=20.0.0'} peerDependencies: '@firebase/app': 0.x - '@firebase/util@1.15.2': - resolution: {integrity: sha512-974pWIZVLDMc5GW5YAsj8y0XxULxIy/sPUy7tsxmWbF93KRIyh9xpuHlh0zDL+shUcf5nHDjFOg9YLiQ763eiA==} + '@firebase/util@1.15.3': + resolution: {integrity: sha512-c/z/gaIlaaLZEuGbE6sLUuJ61tskg1JghvhcNQzW948ASBinbVBBRnZTC4b4yt4LaEtJQkYlyzqLHcutFwEIvA==} engines: {node: '>=20.0.0'} - '@firebase/webchannel-wrapper@1.0.6': - resolution: {integrity: sha512-Vr/Mqu79dMwGRAyGbJ4uN4+BtXB3/mRTdzetD1daWNeG8QaWuzhhbG77GltO5c0yYmYls8i250iX73624GJd7Q==} + '@firebase/webchannel-wrapper@1.0.7': + resolution: {integrity: sha512-phBFwieDLvkZGYN9CE9ZFNEIoBVksprzsnCzQejCmCHtgwCXReeuRpoEGN9C4EbhONztv8NRV1tau6Rb9pONwQ==} '@glideapps/ts-necessities@2.2.3': resolution: {integrity: sha512-gXi0awOZLHk3TbW55GZLCPP6O+y/b5X1pBXKBVckFONSwF1z1E5ND2BGJsghQFah+pW7pkkyFb2VhUQI2qhL5w==} @@ -2106,8 +2106,8 @@ packages: resolution: {integrity: sha512-IJn+8A3QZJfe7FUtWqHVNo3xJs7KFpurCWGWCiCz3oEh+BkRymKZ1QxfAbU2yGMDzTytLGQ2IV6T2r3cuo75/w==} engines: {node: '>=18'} - '@google/genai@2.17.1': - resolution: {integrity: sha512-CdZ3M/titoH81hXXkvOikrOW26bC9IXh9iYT7u+r+5p7wi1LnMEnB0AbJfDeWAkjuneP4oJ299BtCt6twmORWg==} + '@google/genai@2.19.0': + resolution: {integrity: sha512-IM3u1FjpOLyOPsPh0smGA6Ntj2olUWCPbTs/WQj7cA/2AKCGw/652W7IaySx0XtwuscFnMYBoraebQusSZ0zSQ==} engines: {node: '>=20.0.0'} peerDependencies: '@modelcontextprotocol/sdk': ^1.25.2 @@ -2169,6 +2169,15 @@ packages: '@types/node': optional: true + '@inquirer/checkbox@5.2.3': + resolution: {integrity: sha512-XEYX2WA8SBkLPczL6/yXPHLPCvDoptmh9v56Cy05BSV1Smk1vWy19bTC4qJBuIffw7+6l4CcaYYzGqG60RfW1g==} + engines: {node: '>=23.5.0 || ^22.13.0 || ^20.17.0'} + peerDependencies: + '@types/node': '>=18' + peerDependenciesMeta: + '@types/node': + optional: true + '@inquirer/confirm@6.2.0': resolution: {integrity: sha512-SKXarWrYhtpqOEctf9XGCGy29QjsvJAM0Aq9ZR9z4Ns94OmpqudOly+aSEfNqUf9SwsQaUgY9+Z8hyzG0xX8fw==} engines: {node: '>=23.5.0 || ^22.13.0 || ^20.17.0'} @@ -2178,6 +2187,15 @@ packages: '@types/node': optional: true + '@inquirer/confirm@6.3.0': + resolution: {integrity: sha512-pZHXJImFtERmSNMBHcjwuz8Ck5vEFEYNUZnwbb8aJpjHv/TwGuFErNxF2Hp8+V+pNJs2EYPMlyWscvFEqO9jOQ==} + engines: {node: '>=23.5.0 || ^22.13.0 || ^20.17.0'} + peerDependencies: + '@types/node': '>=18' + peerDependenciesMeta: + '@types/node': + optional: true + '@inquirer/core@12.0.0': resolution: {integrity: sha512-+nnvFEXIB08CZNVXpvW3B+zHW96QXvGUjNKJ8NJIPqAZi5Kd4WhYt2S3C234ReepG1qw2HOlEUbjYVHBowXObA==} engines: {node: '>=23.5.0 || ^22.13.0 || ^20.17.0'} @@ -2187,6 +2205,15 @@ packages: '@types/node': optional: true + '@inquirer/core@12.0.1': + resolution: {integrity: sha512-JMD5Jy/ScL5TZE18m83Nw25HjqGFLoWXwnEkW7IdwwAhZpB9Bus55/WU7zn3UqR1MOCjjTQOIYpiD4vjWA3LPw==} + engines: {node: '>=23.5.0 || ^22.13.0 || ^20.17.0'} + peerDependencies: + '@types/node': '>=18' + peerDependenciesMeta: + '@types/node': + optional: true + '@inquirer/editor@5.3.0': resolution: {integrity: sha512-nnsP/IdJ8s83q7ZuObmgn12QM+uLCkab9E0Oordojbn62WUg1c+v9Ou/F/057pgh0ppX0W+Hj5bO/Dp5hsxQtA==} engines: {node: '>=23.5.0 || ^22.13.0 || ^20.17.0'} @@ -2196,6 +2223,15 @@ packages: '@types/node': optional: true + '@inquirer/editor@5.3.1': + resolution: {integrity: sha512-y43COoyVUjPWIobn2Qep/uI1drPS78aaZZZ9kVi94Tyu/GuW2N8d8Q4rifJXGAXCEAXCPTTMjD8gC1HyvM5ukA==} + engines: {node: '>=23.5.0 || ^22.13.0 || ^20.17.0'} + peerDependencies: + '@types/node': '>=18' + peerDependenciesMeta: + '@types/node': + optional: true + '@inquirer/expand@5.1.2': resolution: {integrity: sha512-OWIH1IyyWqEKIyqC9Xy+Bnga7NkGMovFdo4atYZMUOTRqf6rO2WCv9E/1MyzvOErDBCxs+9UFliRUDc50xs/jw==} engines: {node: '>=23.5.0 || ^22.13.0 || ^20.17.0'} @@ -2205,6 +2241,15 @@ packages: '@types/node': optional: true + '@inquirer/expand@5.1.3': + resolution: {integrity: sha512-3NQJiXNJ/aj9wiAsr7pECdp5Qe9J0X9YUJCKsaFXS+ddOxfL6J4AIl3w3T4Gq3kK0WsQY5GMoDokK5X94m6lHw==} + engines: {node: '>=23.5.0 || ^22.13.0 || ^20.17.0'} + peerDependencies: + '@types/node': '>=18' + peerDependenciesMeta: + '@types/node': + optional: true + '@inquirer/external-editor@3.0.4': resolution: {integrity: sha512-tZbbaK2ovq6vlrRBNQvjrypmrED/p5x2ncIHQ79cD55tei3dD96v5glMMA+6tiq7K104i/25DVYKWVPJuV6ptA==} engines: {node: '>=23.5.0 || ^22.13.0 || ^20.17.0'} @@ -2227,6 +2272,15 @@ packages: '@types/node': optional: true + '@inquirer/input@5.1.4': + resolution: {integrity: sha512-3xQkQrOvgOzpSN2ciTVdRDlg1FWMCA8l+0KfB6SNlILoTCGzJTzO/gc0Rwjcb3usuGyKdaGtI6OiyMdeMeLWkg==} + engines: {node: '>=23.5.0 || ^22.13.0 || ^20.17.0'} + peerDependencies: + '@types/node': '>=18' + peerDependenciesMeta: + '@types/node': + optional: true + '@inquirer/number@4.2.0': resolution: {integrity: sha512-ew+fSDijsQ/WhD4TV3XLb+if400cDuzTzHfGR8sTNBXkK9CYDWoGE8fhaO8GbT312pNv1AJEOsDxy/z/HVettA==} engines: {node: '>=23.5.0 || ^22.13.0 || ^20.17.0'} @@ -2236,6 +2290,15 @@ packages: '@types/node': optional: true + '@inquirer/number@4.2.1': + resolution: {integrity: sha512-5KaqwZNLRpUuWcoCrYghPP9TMaXL5v2Sk4xqePM7RCVegcJStoXdWibio60YIC1bec+z1fCyb67N6XPJIkZtGA==} + engines: {node: '>=23.5.0 || ^22.13.0 || ^20.17.0'} + peerDependencies: + '@types/node': '>=18' + peerDependenciesMeta: + '@types/node': + optional: true + '@inquirer/password@5.1.2': resolution: {integrity: sha512-nSdufycW8xynEVssFkNQEYIzTySilog0UlfOVRwh3pXzPSk4frXUT2jZWjHnKae6RU9PaoF9wfy1pGwewQuqGw==} engines: {node: '>=23.5.0 || ^22.13.0 || ^20.17.0'} @@ -2245,8 +2308,8 @@ packages: '@types/node': optional: true - '@inquirer/prompts@8.5.2': - resolution: {integrity: sha512-IYR/3C/paEVVQYQvdDlFZVjRCJVYHHON0XXMH91KO9GSxs0TdKYWlUdvfQl2EfAHDxUaN3IBffkE/BDTh5nJ6g==} + '@inquirer/password@5.2.0': + resolution: {integrity: sha512-CvVcW09emkBESEOW+4R8CjLNkP3fB3XrjeL8CDvfpjgrJN+V9oerXmJAXXM3l+4xqYPD5Yaujzy/Ph0PLOdDuA==} engines: {node: '>=23.5.0 || ^22.13.0 || ^20.17.0'} peerDependencies: '@types/node': '>=18' @@ -2263,6 +2326,15 @@ packages: '@types/node': optional: true + '@inquirer/prompts@8.7.0': + resolution: {integrity: sha512-yQwBMYvpJ6jqrXtKiOwRD5XezjJoyt3VQvIyjsr5Arqb519nfIohOQymWVJ8/vEgg8xtZerrCsqlSaqt/LPC9A==} + engines: {node: '>=23.5.0 || ^22.13.0 || ^20.17.0'} + peerDependencies: + '@types/node': '>=18' + peerDependenciesMeta: + '@types/node': + optional: true + '@inquirer/rawlist@5.3.2': resolution: {integrity: sha512-oPSKrYK1X1bMkjXDzIKHUkJp195LFSfgbnVtXnjSKGFjrCbS6I+wyvfAZTwKE9BSt3HwWgfD7JfsXALBgCogzQ==} engines: {node: '>=23.5.0 || ^22.13.0 || ^20.17.0'} @@ -2272,6 +2344,15 @@ packages: '@types/node': optional: true + '@inquirer/rawlist@5.3.3': + resolution: {integrity: sha512-Mu7WrtmDLaXBDEyrRLS70SZgX9ZSm4Up1w0ZxiH8C1OOp9oaVCn2k8q3QGgmlnhsKYUhuaU3zFWhAP6wxkVIMA==} + engines: {node: '>=23.5.0 || ^22.13.0 || ^20.17.0'} + peerDependencies: + '@types/node': '>=18' + peerDependenciesMeta: + '@types/node': + optional: true + '@inquirer/search@4.3.0': resolution: {integrity: sha512-HFxXE5w727ctSUcAwrDquftJGjMgu36OeV5SHEXMlr2j/ahzmRX9xSEeVolV8tzYnTf45cg6vGkdMMRdm3RPhQ==} engines: {node: '>=23.5.0 || ^22.13.0 || ^20.17.0'} @@ -2281,6 +2362,15 @@ packages: '@types/node': optional: true + '@inquirer/search@4.3.1': + resolution: {integrity: sha512-0VWOvsHWI0rPj6CG70MoP4oXNCB6adcyN8bVFZXnh11eLDdPIK2f2XCmva78acPPDfJisfab7qNakwBh7hdBXw==} + engines: {node: '>=23.5.0 || ^22.13.0 || ^20.17.0'} + peerDependencies: + '@types/node': '>=18' + peerDependenciesMeta: + '@types/node': + optional: true + '@inquirer/select@5.2.2': resolution: {integrity: sha512-RkI8dRHWt+bh04oLixvF1kFzKC7e5rqJoHKkzcqSHATebBXFC6GmrT8ddbVkgSzLV0HnHs2cPFuBINr8otij8Q==} engines: {node: '>=23.5.0 || ^22.13.0 || ^20.17.0'} @@ -2290,6 +2380,15 @@ packages: '@types/node': optional: true + '@inquirer/select@5.2.3': + resolution: {integrity: sha512-KuRTodDa6xBXX2noIpjuitpX/QT7Sfav7dIZ/OfUY54Hxg95nrGoshSzxx6Ey7qqLbImKdiGkSDt7KjPXjQgmA==} + engines: {node: '>=23.5.0 || ^22.13.0 || ^20.17.0'} + peerDependencies: + '@types/node': '>=18' + peerDependenciesMeta: + '@types/node': + optional: true + '@inquirer/type@4.0.7': resolution: {integrity: sha512-t28inv14nMQ1PhKpsJPY+kEs/c00qzeCOS2gTNRyTjG5d6qsVA2fItxW4hkvGZ5lvanGLdtCzVIx5dwdRpN1+g==} engines: {node: '>=23.5.0 || ^22.13.0 || ^20.17.0'} @@ -2299,6 +2398,15 @@ packages: '@types/node': optional: true + '@inquirer/type@4.1.0': + resolution: {integrity: sha512-FMiJpuHUG3Dk0ex+UIXkre7i+i4OcwHWk9YdcVtZHFwb/r2rnrU2ipTCNAB7A+QOP0ryzIcqOfy76fRyyvOEAw==} + engines: {node: '>=23.5.0 || ^22.13.0 || ^20.17.0'} + peerDependencies: + '@types/node': '>=18' + peerDependenciesMeta: + '@types/node': + optional: true + '@isaacs/cliui@8.0.2': resolution: {integrity: sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==} engines: {node: '>=12'} @@ -5281,8 +5389,8 @@ packages: resolution: {integrity: sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==} engines: {node: '>=10'} - firebase@12.17.1: - resolution: {integrity: sha512-dhp41ye9jMQvhx5FwjMkf/hjDHJApl7gXmvzOZGvP0M7c/GZGUnQ4qvsvlOBkF0Pa7wAwHMdcpL0ON2pXCQ4Sw==} + firebase@12.18.0: + resolution: {integrity: sha512-XaL6tlE5Xd20ZDhckqOMIw+JJTET+wTdeZPxQ7ihc42oxRb7kWUyn/j1LO5V9dH1xq8Rv5R71Pv1fBCdIkt9Rw==} flat-cache@4.0.1: resolution: {integrity: sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw==} @@ -8595,14 +8703,14 @@ snapshots: rxjs: 7.8.2 tslib: 2.8.1 - '@angular/ng-dev@https://codeload.github.com/angular/dev-infra-private-ng-dev-builds/tar.gz/beec8fe17573a33c9934487ce99ce9cce3e3f6bf': + '@angular/ng-dev@https://codeload.github.com/angular/dev-infra-private-ng-dev-builds/tar.gz/151e36ffa910f4a01aafe1c482ed8294e2050566': dependencies: '@actions/core': 3.0.1 '@conventional-changelog/git-client': 3.1.2(conventional-commits-filter@6.0.1)(conventional-commits-parser@7.1.2) '@google-cloud/spanner': 8.0.0(supports-color@11.0.0) - '@google/genai': 2.17.1(bufferutil@4.1.0)(supports-color@11.0.0)(utf-8-validate@6.0.6) - '@inquirer/prompts': 8.5.2(@types/node@24.13.3) - '@inquirer/type': 4.0.7(@types/node@24.13.3) + '@google/genai': 2.19.0(bufferutil@4.1.0)(supports-color@11.0.0)(utf-8-validate@6.0.6) + '@inquirer/prompts': 8.7.0(@types/node@24.13.3) + '@inquirer/type': 4.1.0(@types/node@24.13.3) '@octokit/auth-app': 8.3.0 '@octokit/core': 7.0.7 '@octokit/graphql': 9.0.4 @@ -8632,7 +8740,7 @@ snapshots: ejs: 6.0.1 encoding: 0.1.13 fast-glob: 3.3.3 - firebase: 12.17.1 + firebase: 12.18.0 folder-hash: 4.1.3(supports-color@11.0.0) jasmine: 6.3.0 jasmine-core: 6.3.0 @@ -9580,323 +9688,323 @@ snapshots: '@exodus/bytes@1.15.1': {} - '@firebase/ai@2.14.0(@firebase/app-types@0.9.5)(@firebase/app@0.16.0)': + '@firebase/ai@2.15.0(@firebase/app-types@0.9.6)(@firebase/app@0.16.1)': dependencies: - '@firebase/app': 0.16.0 - '@firebase/app-check-interop-types': 0.3.4 - '@firebase/app-types': 0.9.5 - '@firebase/component': 0.7.4 - '@firebase/logger': 0.5.1 - '@firebase/util': 1.15.2 + '@firebase/app': 0.16.1 + '@firebase/app-check-interop-types': 0.3.5 + '@firebase/app-types': 0.9.6 + '@firebase/component': 0.7.5 + '@firebase/logger': 0.5.2 + '@firebase/util': 1.15.3 tslib: 2.8.1 - '@firebase/analytics-compat@0.2.29(@firebase/app-compat@0.5.16)(@firebase/app@0.16.0)': + '@firebase/analytics-compat@0.2.30(@firebase/app-compat@0.5.17)(@firebase/app@0.16.1)': dependencies: - '@firebase/analytics': 0.10.23(@firebase/app@0.16.0) - '@firebase/analytics-types': 0.8.4 - '@firebase/app': 0.16.0 - '@firebase/app-compat': 0.5.16 - '@firebase/component': 0.7.4 - '@firebase/util': 1.15.2 + '@firebase/analytics': 0.10.24(@firebase/app@0.16.1) + '@firebase/analytics-types': 0.8.5 + '@firebase/app': 0.16.1 + '@firebase/app-compat': 0.5.17 + '@firebase/component': 0.7.5 + '@firebase/util': 1.15.3 tslib: 2.8.1 - '@firebase/analytics-types@0.8.4': {} + '@firebase/analytics-types@0.8.5': {} - '@firebase/analytics@0.10.23(@firebase/app@0.16.0)': + '@firebase/analytics@0.10.24(@firebase/app@0.16.1)': dependencies: - '@firebase/app': 0.16.0 - '@firebase/component': 0.7.4 - '@firebase/installations': 0.6.23(@firebase/app@0.16.0) - '@firebase/logger': 0.5.1 - '@firebase/util': 1.15.2 + '@firebase/app': 0.16.1 + '@firebase/component': 0.7.5 + '@firebase/installations': 0.6.24(@firebase/app@0.16.1) + '@firebase/logger': 0.5.2 + '@firebase/util': 1.15.3 tslib: 2.8.1 - '@firebase/app-check-compat@0.4.6(@firebase/app-compat@0.5.16)(@firebase/app@0.16.0)': + '@firebase/app-check-compat@0.4.7(@firebase/app-compat@0.5.17)(@firebase/app@0.16.1)': dependencies: - '@firebase/app': 0.16.0 - '@firebase/app-check': 0.13.0(@firebase/app@0.16.0) - '@firebase/app-check-types': 0.5.4 - '@firebase/app-compat': 0.5.16 - '@firebase/component': 0.7.4 - '@firebase/logger': 0.5.1 - '@firebase/util': 1.15.2 + '@firebase/app': 0.16.1 + '@firebase/app-check': 0.13.1(@firebase/app@0.16.1) + '@firebase/app-check-types': 0.5.5 + '@firebase/app-compat': 0.5.17 + '@firebase/component': 0.7.5 + '@firebase/logger': 0.5.2 + '@firebase/util': 1.15.3 tslib: 2.8.1 - '@firebase/app-check-interop-types@0.3.4': {} + '@firebase/app-check-interop-types@0.3.5': {} - '@firebase/app-check-types@0.5.4': {} + '@firebase/app-check-types@0.5.5': {} - '@firebase/app-check@0.13.0(@firebase/app@0.16.0)': + '@firebase/app-check@0.13.1(@firebase/app@0.16.1)': dependencies: - '@firebase/app': 0.16.0 - '@firebase/component': 0.7.4 - '@firebase/logger': 0.5.1 - '@firebase/util': 1.15.2 + '@firebase/app': 0.16.1 + '@firebase/component': 0.7.5 + '@firebase/logger': 0.5.2 + '@firebase/util': 1.15.3 tslib: 2.8.1 - '@firebase/app-compat@0.5.16': + '@firebase/app-compat@0.5.17': dependencies: - '@firebase/app': 0.16.0 - '@firebase/component': 0.7.4 - '@firebase/logger': 0.5.1 - '@firebase/util': 1.15.2 + '@firebase/app': 0.16.1 + '@firebase/component': 0.7.5 + '@firebase/logger': 0.5.2 + '@firebase/util': 1.15.3 tslib: 2.8.1 - '@firebase/app-types@0.9.5': + '@firebase/app-types@0.9.6': dependencies: - '@firebase/logger': 0.5.1 + '@firebase/logger': 0.5.2 - '@firebase/app@0.16.0': + '@firebase/app@0.16.1': dependencies: - '@firebase/component': 0.7.4 - '@firebase/logger': 0.5.1 - '@firebase/util': 1.15.2 + '@firebase/component': 0.7.5 + '@firebase/logger': 0.5.2 + '@firebase/util': 1.15.3 idb: 7.1.1 tslib: 2.8.1 - '@firebase/auth-compat@0.6.9(@firebase/app-compat@0.5.16)(@firebase/app-types@0.9.5)(@firebase/app@0.16.0)': + '@firebase/auth-compat@0.6.10(@firebase/app-compat@0.5.17)(@firebase/app-types@0.9.6)(@firebase/app@0.16.1)': dependencies: - '@firebase/app': 0.16.0 - '@firebase/app-compat': 0.5.16 - '@firebase/auth': 1.13.4(@firebase/app@0.16.0) - '@firebase/auth-types': 0.13.1(@firebase/app-types@0.9.5)(@firebase/util@1.15.2) - '@firebase/component': 0.7.4 - '@firebase/util': 1.15.2 + '@firebase/app': 0.16.1 + '@firebase/app-compat': 0.5.17 + '@firebase/auth': 1.13.5(@firebase/app@0.16.1) + '@firebase/auth-types': 0.13.2(@firebase/app-types@0.9.6)(@firebase/util@1.15.3) + '@firebase/component': 0.7.5 + '@firebase/util': 1.15.3 tslib: 2.8.1 transitivePeerDependencies: - '@firebase/app-types' - '@react-native-async-storage/async-storage' - '@firebase/auth-interop-types@0.2.5': {} + '@firebase/auth-interop-types@0.2.6': {} - '@firebase/auth-types@0.13.1(@firebase/app-types@0.9.5)(@firebase/util@1.15.2)': + '@firebase/auth-types@0.13.2(@firebase/app-types@0.9.6)(@firebase/util@1.15.3)': dependencies: - '@firebase/app-types': 0.9.5 - '@firebase/util': 1.15.2 + '@firebase/app-types': 0.9.6 + '@firebase/util': 1.15.3 - '@firebase/auth@1.13.4(@firebase/app@0.16.0)': + '@firebase/auth@1.13.5(@firebase/app@0.16.1)': dependencies: - '@firebase/app': 0.16.0 - '@firebase/component': 0.7.4 - '@firebase/logger': 0.5.1 - '@firebase/util': 1.15.2 + '@firebase/app': 0.16.1 + '@firebase/component': 0.7.5 + '@firebase/logger': 0.5.2 + '@firebase/util': 1.15.3 tslib: 2.8.1 - '@firebase/component@0.7.4': + '@firebase/component@0.7.5': dependencies: - '@firebase/util': 1.15.2 + '@firebase/util': 1.15.3 tslib: 2.8.1 - '@firebase/data-connect@0.7.3(@firebase/app@0.16.0)': + '@firebase/data-connect@0.7.4(@firebase/app@0.16.1)': dependencies: - '@firebase/app': 0.16.0 - '@firebase/auth-interop-types': 0.2.5 - '@firebase/component': 0.7.4 - '@firebase/logger': 0.5.1 - '@firebase/util': 1.15.2 + '@firebase/app': 0.16.1 + '@firebase/auth-interop-types': 0.2.6 + '@firebase/component': 0.7.5 + '@firebase/logger': 0.5.2 + '@firebase/util': 1.15.3 tslib: 2.8.1 - '@firebase/database-compat@2.1.6(@firebase/app-compat@0.5.16)(@firebase/app@0.16.0)': + '@firebase/database-compat@2.1.7(@firebase/app-compat@0.5.17)(@firebase/app@0.16.1)': dependencies: - '@firebase/component': 0.7.4 - '@firebase/database': 1.1.4 - '@firebase/database-types': 1.0.21 - '@firebase/logger': 0.5.1 - '@firebase/util': 1.15.2 + '@firebase/component': 0.7.5 + '@firebase/database': 1.1.5 + '@firebase/database-types': 1.0.22 + '@firebase/logger': 0.5.2 + '@firebase/util': 1.15.3 tslib: 2.8.1 optionalDependencies: - '@firebase/app': 0.16.0 - '@firebase/app-compat': 0.5.16 + '@firebase/app': 0.16.1 + '@firebase/app-compat': 0.5.17 - '@firebase/database-types@1.0.21': + '@firebase/database-types@1.0.22': dependencies: - '@firebase/app-types': 0.9.5 - '@firebase/util': 1.15.2 + '@firebase/app-types': 0.9.6 + '@firebase/util': 1.15.3 - '@firebase/database@1.1.4': + '@firebase/database@1.1.5': dependencies: - '@firebase/app-check-interop-types': 0.3.4 - '@firebase/auth-interop-types': 0.2.5 - '@firebase/component': 0.7.4 - '@firebase/logger': 0.5.1 - '@firebase/util': 1.15.2 + '@firebase/app-check-interop-types': 0.3.5 + '@firebase/auth-interop-types': 0.2.6 + '@firebase/component': 0.7.5 + '@firebase/logger': 0.5.2 + '@firebase/util': 1.15.3 faye-websocket: 0.11.4 tslib: 2.8.1 - '@firebase/firestore-compat@0.4.12(@firebase/app-compat@0.5.16)(@firebase/app-types@0.9.5)(@firebase/app@0.16.0)': + '@firebase/firestore-compat@0.4.13(@firebase/app-compat@0.5.17)(@firebase/app-types@0.9.6)(@firebase/app@0.16.1)': dependencies: - '@firebase/app': 0.16.0 - '@firebase/app-compat': 0.5.16 - '@firebase/component': 0.7.4 - '@firebase/firestore': 4.17.0(@firebase/app@0.16.0) - '@firebase/firestore-types': 3.0.4(@firebase/app-types@0.9.5)(@firebase/util@1.15.2) - '@firebase/util': 1.15.2 + '@firebase/app': 0.16.1 + '@firebase/app-compat': 0.5.17 + '@firebase/component': 0.7.5 + '@firebase/firestore': 4.17.1(@firebase/app@0.16.1) + '@firebase/firestore-types': 3.0.5(@firebase/app-types@0.9.6)(@firebase/util@1.15.3) + '@firebase/util': 1.15.3 tslib: 2.8.1 transitivePeerDependencies: - '@firebase/app-types' - '@firebase/firestore-types@3.0.4(@firebase/app-types@0.9.5)(@firebase/util@1.15.2)': + '@firebase/firestore-types@3.0.5(@firebase/app-types@0.9.6)(@firebase/util@1.15.3)': dependencies: - '@firebase/app-types': 0.9.5 - '@firebase/util': 1.15.2 + '@firebase/app-types': 0.9.6 + '@firebase/util': 1.15.3 - '@firebase/firestore@4.17.0(@firebase/app@0.16.0)': + '@firebase/firestore@4.17.1(@firebase/app@0.16.1)': dependencies: - '@firebase/app': 0.16.0 - '@firebase/component': 0.7.4 - '@firebase/logger': 0.5.1 - '@firebase/util': 1.15.2 - '@firebase/webchannel-wrapper': 1.0.6 + '@firebase/app': 0.16.1 + '@firebase/component': 0.7.5 + '@firebase/logger': 0.5.2 + '@firebase/util': 1.15.3 + '@firebase/webchannel-wrapper': 1.0.7 '@grpc/grpc-js': 1.9.16 '@grpc/proto-loader': 0.7.15 re2js: 2.8.6 tslib: 2.8.1 - '@firebase/functions-compat@0.4.6(@firebase/app-compat@0.5.16)(@firebase/app@0.16.0)': + '@firebase/functions-compat@0.5.0(@firebase/app-compat@0.5.17)(@firebase/app@0.16.1)': dependencies: - '@firebase/app': 0.16.0 - '@firebase/app-compat': 0.5.16 - '@firebase/component': 0.7.4 - '@firebase/functions': 0.13.6(@firebase/app@0.16.0) - '@firebase/functions-types': 0.6.4 - '@firebase/util': 1.15.2 + '@firebase/app': 0.16.1 + '@firebase/app-compat': 0.5.17 + '@firebase/component': 0.7.5 + '@firebase/functions': 0.14.0(@firebase/app@0.16.1) + '@firebase/functions-types': 0.6.5 + '@firebase/util': 1.15.3 tslib: 2.8.1 - '@firebase/functions-types@0.6.4': {} + '@firebase/functions-types@0.6.5': {} - '@firebase/functions@0.13.6(@firebase/app@0.16.0)': + '@firebase/functions@0.14.0(@firebase/app@0.16.1)': dependencies: - '@firebase/app': 0.16.0 - '@firebase/app-check-interop-types': 0.3.4 - '@firebase/auth-interop-types': 0.2.5 - '@firebase/component': 0.7.4 - '@firebase/messaging-interop-types': 0.2.5 - '@firebase/util': 1.15.2 + '@firebase/app': 0.16.1 + '@firebase/app-check-interop-types': 0.3.5 + '@firebase/auth-interop-types': 0.2.6 + '@firebase/component': 0.7.5 + '@firebase/messaging-interop-types': 0.2.6 + '@firebase/util': 1.15.3 tslib: 2.8.1 - '@firebase/installations-compat@0.2.23(@firebase/app-compat@0.5.16)(@firebase/app-types@0.9.5)(@firebase/app@0.16.0)': + '@firebase/installations-compat@0.2.24(@firebase/app-compat@0.5.17)(@firebase/app-types@0.9.6)(@firebase/app@0.16.1)': dependencies: - '@firebase/app': 0.16.0 - '@firebase/app-compat': 0.5.16 - '@firebase/component': 0.7.4 - '@firebase/installations': 0.6.23(@firebase/app@0.16.0) - '@firebase/installations-types': 0.5.4(@firebase/app-types@0.9.5) - '@firebase/util': 1.15.2 + '@firebase/app': 0.16.1 + '@firebase/app-compat': 0.5.17 + '@firebase/component': 0.7.5 + '@firebase/installations': 0.6.24(@firebase/app@0.16.1) + '@firebase/installations-types': 0.5.5(@firebase/app-types@0.9.6) + '@firebase/util': 1.15.3 tslib: 2.8.1 transitivePeerDependencies: - '@firebase/app-types' - '@firebase/installations-types@0.5.4(@firebase/app-types@0.9.5)': + '@firebase/installations-types@0.5.5(@firebase/app-types@0.9.6)': dependencies: - '@firebase/app-types': 0.9.5 + '@firebase/app-types': 0.9.6 - '@firebase/installations@0.6.23(@firebase/app@0.16.0)': + '@firebase/installations@0.6.24(@firebase/app@0.16.1)': dependencies: - '@firebase/app': 0.16.0 - '@firebase/component': 0.7.4 - '@firebase/util': 1.15.2 + '@firebase/app': 0.16.1 + '@firebase/component': 0.7.5 + '@firebase/util': 1.15.3 idb: 7.1.1 tslib: 2.8.1 - '@firebase/logger@0.5.1': + '@firebase/logger@0.5.2': dependencies: tslib: 2.8.1 - '@firebase/messaging-compat@0.2.28(@firebase/app-compat@0.5.16)(@firebase/app@0.16.0)': + '@firebase/messaging-compat@0.2.29(@firebase/app-compat@0.5.17)(@firebase/app@0.16.1)': dependencies: - '@firebase/app': 0.16.0 - '@firebase/app-compat': 0.5.16 - '@firebase/component': 0.7.4 - '@firebase/messaging': 0.13.1(@firebase/app@0.16.0) - '@firebase/util': 1.15.2 + '@firebase/app': 0.16.1 + '@firebase/app-compat': 0.5.17 + '@firebase/component': 0.7.5 + '@firebase/messaging': 0.13.2(@firebase/app@0.16.1) + '@firebase/util': 1.15.3 tslib: 2.8.1 - '@firebase/messaging-interop-types@0.2.5': {} + '@firebase/messaging-interop-types@0.2.6': {} - '@firebase/messaging@0.13.1(@firebase/app@0.16.0)': + '@firebase/messaging@0.13.2(@firebase/app@0.16.1)': dependencies: - '@firebase/app': 0.16.0 - '@firebase/component': 0.7.4 - '@firebase/installations': 0.6.23(@firebase/app@0.16.0) - '@firebase/messaging-interop-types': 0.2.5 - '@firebase/util': 1.15.2 + '@firebase/app': 0.16.1 + '@firebase/component': 0.7.5 + '@firebase/installations': 0.6.24(@firebase/app@0.16.1) + '@firebase/messaging-interop-types': 0.2.6 + '@firebase/util': 1.15.3 idb: 7.1.1 tslib: 2.8.1 - '@firebase/performance-compat@0.2.26(@firebase/app-compat@0.5.16)(@firebase/app@0.16.0)': + '@firebase/performance-compat@0.2.27(@firebase/app-compat@0.5.17)(@firebase/app@0.16.1)': dependencies: - '@firebase/app': 0.16.0 - '@firebase/app-compat': 0.5.16 - '@firebase/component': 0.7.4 - '@firebase/logger': 0.5.1 - '@firebase/performance': 0.7.13(@firebase/app@0.16.0) - '@firebase/performance-types': 0.2.4 - '@firebase/util': 1.15.2 + '@firebase/app': 0.16.1 + '@firebase/app-compat': 0.5.17 + '@firebase/component': 0.7.5 + '@firebase/logger': 0.5.2 + '@firebase/performance': 0.7.14(@firebase/app@0.16.1) + '@firebase/performance-types': 0.2.5 + '@firebase/util': 1.15.3 tslib: 2.8.1 - '@firebase/performance-types@0.2.4': {} + '@firebase/performance-types@0.2.5': {} - '@firebase/performance@0.7.13(@firebase/app@0.16.0)': + '@firebase/performance@0.7.14(@firebase/app@0.16.1)': dependencies: - '@firebase/app': 0.16.0 - '@firebase/component': 0.7.4 - '@firebase/installations': 0.6.23(@firebase/app@0.16.0) - '@firebase/logger': 0.5.1 - '@firebase/util': 1.15.2 + '@firebase/app': 0.16.1 + '@firebase/component': 0.7.5 + '@firebase/installations': 0.6.24(@firebase/app@0.16.1) + '@firebase/logger': 0.5.2 + '@firebase/util': 1.15.3 tslib: 2.8.1 web-vitals: 4.2.4 - '@firebase/remote-config-compat@0.2.28(@firebase/app-compat@0.5.16)(@firebase/app@0.16.0)': + '@firebase/remote-config-compat@0.2.29(@firebase/app-compat@0.5.17)(@firebase/app@0.16.1)': dependencies: - '@firebase/app': 0.16.0 - '@firebase/app-compat': 0.5.16 - '@firebase/component': 0.7.4 - '@firebase/logger': 0.5.1 - '@firebase/remote-config': 0.9.1(@firebase/app@0.16.0) - '@firebase/remote-config-types': 0.5.1 - '@firebase/util': 1.15.2 + '@firebase/app': 0.16.1 + '@firebase/app-compat': 0.5.17 + '@firebase/component': 0.7.5 + '@firebase/logger': 0.5.2 + '@firebase/remote-config': 0.9.2(@firebase/app@0.16.1) + '@firebase/remote-config-types': 0.5.2 + '@firebase/util': 1.15.3 tslib: 2.8.1 - '@firebase/remote-config-types@0.5.1': {} + '@firebase/remote-config-types@0.5.2': {} - '@firebase/remote-config@0.9.1(@firebase/app@0.16.0)': + '@firebase/remote-config@0.9.2(@firebase/app@0.16.1)': dependencies: - '@firebase/app': 0.16.0 - '@firebase/component': 0.7.4 - '@firebase/installations': 0.6.23(@firebase/app@0.16.0) - '@firebase/logger': 0.5.1 - '@firebase/util': 1.15.2 + '@firebase/app': 0.16.1 + '@firebase/component': 0.7.5 + '@firebase/installations': 0.6.24(@firebase/app@0.16.1) + '@firebase/logger': 0.5.2 + '@firebase/util': 1.15.3 tslib: 2.8.1 - '@firebase/storage-compat@0.4.4(@firebase/app-compat@0.5.16)(@firebase/app-types@0.9.5)(@firebase/app@0.16.0)': + '@firebase/storage-compat@0.4.5(@firebase/app-compat@0.5.17)(@firebase/app-types@0.9.6)(@firebase/app@0.16.1)': dependencies: - '@firebase/app': 0.16.0 - '@firebase/app-compat': 0.5.16 - '@firebase/component': 0.7.4 - '@firebase/storage': 0.14.4(@firebase/app@0.16.0) - '@firebase/storage-types': 0.8.4(@firebase/app-types@0.9.5)(@firebase/util@1.15.2) - '@firebase/util': 1.15.2 + '@firebase/app': 0.16.1 + '@firebase/app-compat': 0.5.17 + '@firebase/component': 0.7.5 + '@firebase/storage': 0.14.5(@firebase/app@0.16.1) + '@firebase/storage-types': 0.8.5(@firebase/app-types@0.9.6)(@firebase/util@1.15.3) + '@firebase/util': 1.15.3 tslib: 2.8.1 transitivePeerDependencies: - '@firebase/app-types' - '@firebase/storage-types@0.8.4(@firebase/app-types@0.9.5)(@firebase/util@1.15.2)': + '@firebase/storage-types@0.8.5(@firebase/app-types@0.9.6)(@firebase/util@1.15.3)': dependencies: - '@firebase/app-types': 0.9.5 - '@firebase/util': 1.15.2 + '@firebase/app-types': 0.9.6 + '@firebase/util': 1.15.3 - '@firebase/storage@0.14.4(@firebase/app@0.16.0)': + '@firebase/storage@0.14.5(@firebase/app@0.16.1)': dependencies: - '@firebase/app': 0.16.0 - '@firebase/component': 0.7.4 - '@firebase/util': 1.15.2 + '@firebase/app': 0.16.1 + '@firebase/component': 0.7.5 + '@firebase/util': 1.15.3 tslib: 2.8.1 - '@firebase/util@1.15.2': + '@firebase/util@1.15.3': dependencies: tslib: 2.8.1 - '@firebase/webchannel-wrapper@1.0.6': {} + '@firebase/webchannel-wrapper@1.0.7': {} '@glideapps/ts-necessities@2.2.3': {} @@ -9959,7 +10067,7 @@ snapshots: transitivePeerDependencies: - supports-color - '@google/genai@2.17.1(bufferutil@4.1.0)(supports-color@11.0.0)(utf-8-validate@6.0.6)': + '@google/genai@2.19.0(bufferutil@4.1.0)(supports-color@11.0.0)(utf-8-validate@6.0.6)': dependencies: google-auth-library: 10.9.1(supports-color@11.0.0) p-retry: 4.6.2 @@ -10024,12 +10132,12 @@ snapshots: optionalDependencies: '@types/node': 22.20.1 - '@inquirer/checkbox@5.2.2(@types/node@24.13.3)': + '@inquirer/checkbox@5.2.3(@types/node@24.13.3)': dependencies: '@inquirer/ansi': 2.0.7 - '@inquirer/core': 12.0.0(@types/node@24.13.3) + '@inquirer/core': 12.0.1(@types/node@24.13.3) '@inquirer/figures': 2.0.8 - '@inquirer/type': 4.0.7(@types/node@24.13.3) + '@inquirer/type': 4.1.0(@types/node@24.13.3) optionalDependencies: '@types/node': 24.13.3 @@ -10040,10 +10148,10 @@ snapshots: optionalDependencies: '@types/node': 22.20.1 - '@inquirer/confirm@6.2.0(@types/node@24.13.3)': + '@inquirer/confirm@6.3.0(@types/node@24.13.3)': dependencies: - '@inquirer/core': 12.0.0(@types/node@24.13.3) - '@inquirer/type': 4.0.7(@types/node@24.13.3) + '@inquirer/core': 12.0.1(@types/node@24.13.3) + '@inquirer/type': 4.1.0(@types/node@24.13.3) optionalDependencies: '@types/node': 24.13.3 @@ -10059,11 +10167,11 @@ snapshots: optionalDependencies: '@types/node': 22.20.1 - '@inquirer/core@12.0.0(@types/node@24.13.3)': + '@inquirer/core@12.0.1(@types/node@24.13.3)': dependencies: '@inquirer/ansi': 2.0.7 '@inquirer/figures': 2.0.8 - '@inquirer/type': 4.0.7(@types/node@24.13.3) + '@inquirer/type': 4.1.0(@types/node@24.13.3) cli-width: 4.1.0 fast-wrap-ansi: 0.2.2 mute-stream: 3.0.0 @@ -10079,11 +10187,11 @@ snapshots: optionalDependencies: '@types/node': 22.20.1 - '@inquirer/editor@5.3.0(@types/node@24.13.3)': + '@inquirer/editor@5.3.1(@types/node@24.13.3)': dependencies: - '@inquirer/core': 12.0.0(@types/node@24.13.3) + '@inquirer/core': 12.0.1(@types/node@24.13.3) '@inquirer/external-editor': 3.0.4(@types/node@24.13.3) - '@inquirer/type': 4.0.7(@types/node@24.13.3) + '@inquirer/type': 4.1.0(@types/node@24.13.3) optionalDependencies: '@types/node': 24.13.3 @@ -10094,10 +10202,10 @@ snapshots: optionalDependencies: '@types/node': 22.20.1 - '@inquirer/expand@5.1.2(@types/node@24.13.3)': + '@inquirer/expand@5.1.3(@types/node@24.13.3)': dependencies: - '@inquirer/core': 12.0.0(@types/node@24.13.3) - '@inquirer/type': 4.0.7(@types/node@24.13.3) + '@inquirer/core': 12.0.1(@types/node@24.13.3) + '@inquirer/type': 4.1.0(@types/node@24.13.3) optionalDependencies: '@types/node': 24.13.3 @@ -10124,10 +10232,10 @@ snapshots: optionalDependencies: '@types/node': 22.20.1 - '@inquirer/input@5.1.3(@types/node@24.13.3)': + '@inquirer/input@5.1.4(@types/node@24.13.3)': dependencies: - '@inquirer/core': 12.0.0(@types/node@24.13.3) - '@inquirer/type': 4.0.7(@types/node@24.13.3) + '@inquirer/core': 12.0.1(@types/node@24.13.3) + '@inquirer/type': 4.1.0(@types/node@24.13.3) optionalDependencies: '@types/node': 24.13.3 @@ -10138,10 +10246,10 @@ snapshots: optionalDependencies: '@types/node': 22.20.1 - '@inquirer/number@4.2.0(@types/node@24.13.3)': + '@inquirer/number@4.2.1(@types/node@24.13.3)': dependencies: - '@inquirer/core': 12.0.0(@types/node@24.13.3) - '@inquirer/type': 4.0.7(@types/node@24.13.3) + '@inquirer/core': 12.0.1(@types/node@24.13.3) + '@inquirer/type': 4.1.0(@types/node@24.13.3) optionalDependencies: '@types/node': 24.13.3 @@ -10153,26 +10261,11 @@ snapshots: optionalDependencies: '@types/node': 22.20.1 - '@inquirer/password@5.1.2(@types/node@24.13.3)': + '@inquirer/password@5.2.0(@types/node@24.13.3)': dependencies: '@inquirer/ansi': 2.0.7 - '@inquirer/core': 12.0.0(@types/node@24.13.3) - '@inquirer/type': 4.0.7(@types/node@24.13.3) - optionalDependencies: - '@types/node': 24.13.3 - - '@inquirer/prompts@8.5.2(@types/node@24.13.3)': - dependencies: - '@inquirer/checkbox': 5.2.2(@types/node@24.13.3) - '@inquirer/confirm': 6.2.0(@types/node@24.13.3) - '@inquirer/editor': 5.3.0(@types/node@24.13.3) - '@inquirer/expand': 5.1.2(@types/node@24.13.3) - '@inquirer/input': 5.1.3(@types/node@24.13.3) - '@inquirer/number': 4.2.0(@types/node@24.13.3) - '@inquirer/password': 5.1.2(@types/node@24.13.3) - '@inquirer/rawlist': 5.3.2(@types/node@24.13.3) - '@inquirer/search': 4.3.0(@types/node@24.13.3) - '@inquirer/select': 5.2.2(@types/node@24.13.3) + '@inquirer/core': 12.0.1(@types/node@24.13.3) + '@inquirer/type': 4.1.0(@types/node@24.13.3) optionalDependencies: '@types/node': 24.13.3 @@ -10191,6 +10284,21 @@ snapshots: optionalDependencies: '@types/node': 22.20.1 + '@inquirer/prompts@8.7.0(@types/node@24.13.3)': + dependencies: + '@inquirer/checkbox': 5.2.3(@types/node@24.13.3) + '@inquirer/confirm': 6.3.0(@types/node@24.13.3) + '@inquirer/editor': 5.3.1(@types/node@24.13.3) + '@inquirer/expand': 5.1.3(@types/node@24.13.3) + '@inquirer/input': 5.1.4(@types/node@24.13.3) + '@inquirer/number': 4.2.1(@types/node@24.13.3) + '@inquirer/password': 5.2.0(@types/node@24.13.3) + '@inquirer/rawlist': 5.3.3(@types/node@24.13.3) + '@inquirer/search': 4.3.1(@types/node@24.13.3) + '@inquirer/select': 5.2.3(@types/node@24.13.3) + optionalDependencies: + '@types/node': 24.13.3 + '@inquirer/rawlist@5.3.2(@types/node@22.20.1)': dependencies: '@inquirer/core': 12.0.0(@types/node@22.20.1) @@ -10198,10 +10306,10 @@ snapshots: optionalDependencies: '@types/node': 22.20.1 - '@inquirer/rawlist@5.3.2(@types/node@24.13.3)': + '@inquirer/rawlist@5.3.3(@types/node@24.13.3)': dependencies: - '@inquirer/core': 12.0.0(@types/node@24.13.3) - '@inquirer/type': 4.0.7(@types/node@24.13.3) + '@inquirer/core': 12.0.1(@types/node@24.13.3) + '@inquirer/type': 4.1.0(@types/node@24.13.3) optionalDependencies: '@types/node': 24.13.3 @@ -10213,11 +10321,11 @@ snapshots: optionalDependencies: '@types/node': 22.20.1 - '@inquirer/search@4.3.0(@types/node@24.13.3)': + '@inquirer/search@4.3.1(@types/node@24.13.3)': dependencies: - '@inquirer/core': 12.0.0(@types/node@24.13.3) + '@inquirer/core': 12.0.1(@types/node@24.13.3) '@inquirer/figures': 2.0.8 - '@inquirer/type': 4.0.7(@types/node@24.13.3) + '@inquirer/type': 4.1.0(@types/node@24.13.3) optionalDependencies: '@types/node': 24.13.3 @@ -10230,12 +10338,12 @@ snapshots: optionalDependencies: '@types/node': 22.20.1 - '@inquirer/select@5.2.2(@types/node@24.13.3)': + '@inquirer/select@5.2.3(@types/node@24.13.3)': dependencies: '@inquirer/ansi': 2.0.7 - '@inquirer/core': 12.0.0(@types/node@24.13.3) + '@inquirer/core': 12.0.1(@types/node@24.13.3) '@inquirer/figures': 2.0.8 - '@inquirer/type': 4.0.7(@types/node@24.13.3) + '@inquirer/type': 4.1.0(@types/node@24.13.3) optionalDependencies: '@types/node': 24.13.3 @@ -10243,7 +10351,7 @@ snapshots: optionalDependencies: '@types/node': 22.20.1 - '@inquirer/type@4.0.7(@types/node@24.13.3)': + '@inquirer/type@4.1.0(@types/node@24.13.3)': optionalDependencies: '@types/node': 24.13.3 @@ -13367,36 +13475,36 @@ snapshots: locate-path: 6.0.0 path-exists: 4.0.0 - firebase@12.17.1: - dependencies: - '@firebase/ai': 2.14.0(@firebase/app-types@0.9.5)(@firebase/app@0.16.0) - '@firebase/analytics': 0.10.23(@firebase/app@0.16.0) - '@firebase/analytics-compat': 0.2.29(@firebase/app-compat@0.5.16)(@firebase/app@0.16.0) - '@firebase/app': 0.16.0 - '@firebase/app-check': 0.13.0(@firebase/app@0.16.0) - '@firebase/app-check-compat': 0.4.6(@firebase/app-compat@0.5.16)(@firebase/app@0.16.0) - '@firebase/app-compat': 0.5.16 - '@firebase/app-types': 0.9.5 - '@firebase/auth': 1.13.4(@firebase/app@0.16.0) - '@firebase/auth-compat': 0.6.9(@firebase/app-compat@0.5.16)(@firebase/app-types@0.9.5)(@firebase/app@0.16.0) - '@firebase/data-connect': 0.7.3(@firebase/app@0.16.0) - '@firebase/database': 1.1.4 - '@firebase/database-compat': 2.1.6(@firebase/app-compat@0.5.16)(@firebase/app@0.16.0) - '@firebase/firestore': 4.17.0(@firebase/app@0.16.0) - '@firebase/firestore-compat': 0.4.12(@firebase/app-compat@0.5.16)(@firebase/app-types@0.9.5)(@firebase/app@0.16.0) - '@firebase/functions': 0.13.6(@firebase/app@0.16.0) - '@firebase/functions-compat': 0.4.6(@firebase/app-compat@0.5.16)(@firebase/app@0.16.0) - '@firebase/installations': 0.6.23(@firebase/app@0.16.0) - '@firebase/installations-compat': 0.2.23(@firebase/app-compat@0.5.16)(@firebase/app-types@0.9.5)(@firebase/app@0.16.0) - '@firebase/messaging': 0.13.1(@firebase/app@0.16.0) - '@firebase/messaging-compat': 0.2.28(@firebase/app-compat@0.5.16)(@firebase/app@0.16.0) - '@firebase/performance': 0.7.13(@firebase/app@0.16.0) - '@firebase/performance-compat': 0.2.26(@firebase/app-compat@0.5.16)(@firebase/app@0.16.0) - '@firebase/remote-config': 0.9.1(@firebase/app@0.16.0) - '@firebase/remote-config-compat': 0.2.28(@firebase/app-compat@0.5.16)(@firebase/app@0.16.0) - '@firebase/storage': 0.14.4(@firebase/app@0.16.0) - '@firebase/storage-compat': 0.4.4(@firebase/app-compat@0.5.16)(@firebase/app-types@0.9.5)(@firebase/app@0.16.0) - '@firebase/util': 1.15.2 + firebase@12.18.0: + dependencies: + '@firebase/ai': 2.15.0(@firebase/app-types@0.9.6)(@firebase/app@0.16.1) + '@firebase/analytics': 0.10.24(@firebase/app@0.16.1) + '@firebase/analytics-compat': 0.2.30(@firebase/app-compat@0.5.17)(@firebase/app@0.16.1) + '@firebase/app': 0.16.1 + '@firebase/app-check': 0.13.1(@firebase/app@0.16.1) + '@firebase/app-check-compat': 0.4.7(@firebase/app-compat@0.5.17)(@firebase/app@0.16.1) + '@firebase/app-compat': 0.5.17 + '@firebase/app-types': 0.9.6 + '@firebase/auth': 1.13.5(@firebase/app@0.16.1) + '@firebase/auth-compat': 0.6.10(@firebase/app-compat@0.5.17)(@firebase/app-types@0.9.6)(@firebase/app@0.16.1) + '@firebase/data-connect': 0.7.4(@firebase/app@0.16.1) + '@firebase/database': 1.1.5 + '@firebase/database-compat': 2.1.7(@firebase/app-compat@0.5.17)(@firebase/app@0.16.1) + '@firebase/firestore': 4.17.1(@firebase/app@0.16.1) + '@firebase/firestore-compat': 0.4.13(@firebase/app-compat@0.5.17)(@firebase/app-types@0.9.6)(@firebase/app@0.16.1) + '@firebase/functions': 0.14.0(@firebase/app@0.16.1) + '@firebase/functions-compat': 0.5.0(@firebase/app-compat@0.5.17)(@firebase/app@0.16.1) + '@firebase/installations': 0.6.24(@firebase/app@0.16.1) + '@firebase/installations-compat': 0.2.24(@firebase/app-compat@0.5.17)(@firebase/app-types@0.9.6)(@firebase/app@0.16.1) + '@firebase/messaging': 0.13.2(@firebase/app@0.16.1) + '@firebase/messaging-compat': 0.2.29(@firebase/app-compat@0.5.17)(@firebase/app@0.16.1) + '@firebase/performance': 0.7.14(@firebase/app@0.16.1) + '@firebase/performance-compat': 0.2.27(@firebase/app-compat@0.5.17)(@firebase/app@0.16.1) + '@firebase/remote-config': 0.9.2(@firebase/app@0.16.1) + '@firebase/remote-config-compat': 0.2.29(@firebase/app-compat@0.5.17)(@firebase/app@0.16.1) + '@firebase/storage': 0.14.5(@firebase/app@0.16.1) + '@firebase/storage-compat': 0.4.5(@firebase/app-compat@0.5.17)(@firebase/app-types@0.9.6)(@firebase/app@0.16.1) + '@firebase/util': 1.15.3 transitivePeerDependencies: - '@react-native-async-storage/async-storage' diff --git a/tests/e2e/ng-snapshot/package.json b/tests/e2e/ng-snapshot/package.json index e9c94700043e..4cb1841981e4 100644 --- a/tests/e2e/ng-snapshot/package.json +++ b/tests/e2e/ng-snapshot/package.json @@ -2,21 +2,21 @@ "description": "snapshot versions of Angular for e2e testing", "private": true, "dependencies": { - "@angular/animations": "github:angular/animations-builds#c84632a6dbf96114295b3fe07649d8ac82b76d46", - "@angular/cdk": "github:angular/cdk-builds#b5726421e80460c8182e92b41c8d415dc5561faf", - "@angular/common": "github:angular/common-builds#4b526b121e3b74f29fe3b960352f2fe5260d1cdd", - "@angular/compiler": "github:angular/compiler-builds#a52ffe17b21ceeeaea156838fd5f932f6ac03817", - "@angular/compiler-cli": "github:angular/compiler-cli-builds#5a5fbb4a3987257567b2d610379ffb23a7755452", - "@angular/core": "github:angular/core-builds#d20a5cc634812ec5977c0ff319c786426be70512", - "@angular/forms": "github:angular/forms-builds#4690df90e6f4f033e05cde1b3422712e230d2d81", - "@angular/language-service": "github:angular/language-service-builds#6bb9311e04a8c4ae9f3567e0ae45cac6705ec632", - "@angular/localize": "github:angular/localize-builds#cf93c39daf39980bee67712b4bd859cdf4e0bd8b", - "@angular/material": "github:angular/material-builds#32f58c9763fdcf4e07e30bb3d9b2c81750eb24dc", - "@angular/material-moment-adapter": "github:angular/material-moment-adapter-builds#53ba33ada6974d5fa35f2bd9ef3d63b4c0955bf9", - "@angular/platform-browser": "github:angular/platform-browser-builds#cfdec573a8659c00b7c8b5d5547b8d5a8e87efb0", - "@angular/platform-browser-dynamic": "github:angular/platform-browser-dynamic-builds#69ece7bde70642dcb53f03a76283e0dade652a66", - "@angular/platform-server": "github:angular/platform-server-builds#ccee0b1b0e5a1b9830d02b30351e4dc68499e82c", - "@angular/router": "github:angular/router-builds#1d1ea6df7c02df172924446ef0890567c772069c", - "@angular/service-worker": "github:angular/service-worker-builds#1b630d7e0d7947a6fb3ac79ec1d5a632793e4a07" + "@angular/animations": "github:angular/animations-builds#5a17616799a04d2350bc04dbe75ae792f171ee88", + "@angular/cdk": "github:angular/cdk-builds#2e29d4c34e893b486a713f2cf6a08076f4cedcea", + "@angular/common": "github:angular/common-builds#9c9b546e71365ce9703f5dac3da1fd247ed04416", + "@angular/compiler": "github:angular/compiler-builds#8f6aa31135b34804f71ac9c5c8059d5f789be24c", + "@angular/compiler-cli": "github:angular/compiler-cli-builds#7f39ce1375237a8bc4c473a6ca1425c9183f2826", + "@angular/core": "github:angular/core-builds#3a3fcaf1499fc6050f29f75e4442dbcd2512cb43", + "@angular/forms": "github:angular/forms-builds#20542a5712b45bad559b1d32e61b85d3143532bb", + "@angular/language-service": "github:angular/language-service-builds#108c679c564ba9634779f2646de3ef291ca2fe83", + "@angular/localize": "github:angular/localize-builds#ae46c7df2563b7a9c1777fb49899645062251c4c", + "@angular/material": "github:angular/material-builds#f1ac90ea1312ab4b9fd6f9c5397700bbb5548da8", + "@angular/material-moment-adapter": "github:angular/material-moment-adapter-builds#129f7fe237ff52e6269585b363f18f282f5cfb59", + "@angular/platform-browser": "github:angular/platform-browser-builds#37d5b30e369848fea0431e55552b1724bc5da946", + "@angular/platform-browser-dynamic": "github:angular/platform-browser-dynamic-builds#47bb5f52770cc01a2f45745af5ec0f5fabf04d70", + "@angular/platform-server": "github:angular/platform-server-builds#eccecfd498b456758e98d27b5cd8210501003957", + "@angular/router": "github:angular/router-builds#0ef220c7125daf4880c6303e262a56be0b5fc361", + "@angular/service-worker": "github:angular/service-worker-builds#f62f2ab55d8eca69ddf55dc5efc55fb27c7ee35d" } } From f3291745b44712bbc91afcc27f428bff385cbcf6 Mon Sep 17 00:00:00 2001 From: Charles Lyding <19598772+clydin@users.noreply.github.com> Date: Mon, 31 Aug 2026 12:11:33 -0400 Subject: [PATCH 382/787] refactor(@angular/build): eliminate NoopCompilation and introduce primary and secondary compilation contexts NoopCompilation previously served as a AngularCompilation placeholder to satisfy the compilation requirement on AngularCompilationContext in secondary contexts (such as polyfills and server main code), leading to redundant compiler option extraction and tsconfig loading. AngularCompilationContext is now an abstract base class defining the shared contract. PrimaryCompilationContext encapsulates the active AngularCompilation, manages the lifecycle state, and holds the resolved compiler options. SecondaryCompilationContext omits the compilation entirely, delegates readiness and compiler option resolution to the primary context, and provides no-op lifecycle management. Secondary builds now await primary completion and retrieve compiler options without initializing or invoking a separate compilation. --- .../src/builders/application/execute-build.ts | 7 +- packages/angular/build/src/private.ts | 5 +- .../compilation/angular-compilation_spec.ts | 39 ---- .../src/tools/angular/compilation/index.ts | 1 - .../angular/compilation/noop-compilation.ts | 58 ------ .../esbuild/angular/compilation-state.ts | 89 +++++++-- .../esbuild/angular/compilation-state_spec.ts | 178 ++++++++++++++++++ .../tools/esbuild/angular/compiler-plugin.ts | 40 ++-- 8 files changed, 280 insertions(+), 137 deletions(-) delete mode 100644 packages/angular/build/src/tools/angular/compilation/noop-compilation.ts create mode 100644 packages/angular/build/src/tools/esbuild/angular/compilation-state_spec.ts diff --git a/packages/angular/build/src/builders/application/execute-build.ts b/packages/angular/build/src/builders/application/execute-build.ts index 8fe488a8ff76..379566e4de4d 100644 --- a/packages/angular/build/src/builders/application/execute-build.ts +++ b/packages/angular/build/src/builders/application/execute-build.ts @@ -8,7 +8,10 @@ import { BuilderContext } from '@angular-devkit/architect'; import { createAngularCompilation } from '../../tools/angular/compilation'; -import { AngularCompilationContext } from '../../tools/esbuild/angular/compilation-state'; +import { + AngularCompilationContext, + PrimaryCompilationContext, +} from '../../tools/esbuild/angular/compilation-state'; import { SourceFileCache } from '../../tools/esbuild/angular/source-file-cache'; import { generateBudgetStats } from '../../tools/esbuild/budget-stats'; import { BundleContextResult, BundlerContext } from '../../tools/esbuild/bundler-context'; @@ -125,7 +128,7 @@ export async function executeBuild( !!options.jit, !options.serverEntryPoint, ); - angularCompilationContext = new AngularCompilationContext(angularCompilation); + angularCompilationContext = new PrimaryCompilationContext(angularCompilation); bundlerContexts = setupBundlerContexts( options, target, diff --git a/packages/angular/build/src/private.ts b/packages/angular/build/src/private.ts index 9225c2f9d686..c4295aca88bb 100644 --- a/packages/angular/build/src/private.ts +++ b/packages/angular/build/src/private.ts @@ -13,7 +13,8 @@ * their existence may change in any future version. */ -import { NoopCompilation, createAngularCompilation } from './tools/angular/compilation'; +import { createAngularCompilation } from './tools/angular/compilation'; +import { SecondaryCompilationContext } from './tools/esbuild/angular/compilation-state'; import { CompilerPluginOptions, createCompilerPlugin as internalCreateCompilerPlugin, @@ -52,7 +53,7 @@ export function createCompilerPlugin( return internalCreateCompilerPlugin( pluginOptions, pluginOptions.noopTypeScriptCompilation - ? new NoopCompilation() + ? new SecondaryCompilationContext() : () => createAngularCompilation(!!pluginOptions.jit, !!pluginOptions.browserOnlyBuild), new ComponentStylesheetBundler( styleOptions, diff --git a/packages/angular/build/src/tools/angular/compilation/angular-compilation_spec.ts b/packages/angular/build/src/tools/angular/compilation/angular-compilation_spec.ts index ad28c31bcce5..5e520fbadef8 100644 --- a/packages/angular/build/src/tools/angular/compilation/angular-compilation_spec.ts +++ b/packages/angular/build/src/tools/angular/compilation/angular-compilation_spec.ts @@ -14,7 +14,6 @@ import { AngularCompilation, AngularCompilationResult, DiagnosticModes, - NoopCompilation, createAngularCompilation, } from './index'; @@ -59,44 +58,6 @@ describe('AngularCompilation', () => { expect(diagnostics).toEqual({}); }); - describe('NoopCompilation', () => { - it('initializes with empty referencedFiles and compiler options', async () => { - const compilation = new NoopCompilation(); - const mockHostOptions = {} as AngularHostOptions; - const result = await compilation.initialize('tsconfig.json', mockHostOptions); - - expect(result.referencedFiles).toEqual([]); - expect(result.compilerOptions).toBeDefined(); - }); - - it('initializes with CompilerOptionOverrides object', async () => { - const compilation = new NoopCompilation(); - const mockHostOptions = {} as AngularHostOptions; - const result = await compilation.initialize('tsconfig.json', mockHostOptions, { - sourcemap: true, - enableHmr: true, - }); - - expect(result.referencedFiles).toEqual([]); - expect(result.compilerOptions.inlineSources).toBe(true); - expect(result.compilerOptions.inlineSourceMap).toBe(true); - expect(result.compilerOptions['_enableHmr']).toBe(true); - }); - - it('throws when calling emitAffectedFiles', () => { - const compilation = new NoopCompilation(); - expect(() => compilation.emitAffectedFiles()).toThrowError( - 'Not available when using noop compilation.', - ); - }); - - it('returns empty diagnostics from diagnoseFiles', async () => { - const compilation = new NoopCompilation(); - const diagnostics = await compilation.diagnoseFiles(); - expect(diagnostics).toEqual({}); - }); - }); - describe('TypeScriptCompilation', () => { class MockTypeScriptCompilation extends TypeScriptCompilation { async initialize(): Promise { diff --git a/packages/angular/build/src/tools/angular/compilation/index.ts b/packages/angular/build/src/tools/angular/compilation/index.ts index 39391bcfb562..268abec678ca 100644 --- a/packages/angular/build/src/tools/angular/compilation/index.ts +++ b/packages/angular/build/src/tools/angular/compilation/index.ts @@ -16,4 +16,3 @@ export { } from './angular-compilation'; export type { CompilerOptionOverrides } from './compiler-options'; export { createAngularCompilation, type AngularCompilationMode } from './factory'; -export { NoopCompilation } from './noop-compilation'; diff --git a/packages/angular/build/src/tools/angular/compilation/noop-compilation.ts b/packages/angular/build/src/tools/angular/compilation/noop-compilation.ts deleted file mode 100644 index 7ace166d90fd..000000000000 --- a/packages/angular/build/src/tools/angular/compilation/noop-compilation.ts +++ /dev/null @@ -1,58 +0,0 @@ -/** - * @license - * Copyright Google LLC All Rights Reserved. - * - * Use of this source code is governed by an MIT-style license that can be - * found in the LICENSE file at https://angular.dev/license - */ - -import { AngularHostOptions } from '../angular-host'; -import { AngularCompilation, AngularCompilationResult } from './angular-compilation'; -import type { CompilerOptionOverrides } from './compiler-options'; - -/** - * An Angular compilation that performs no actual compilation or code emission. - * Used for secondary compilation contexts where only the resolved compiler options - * and configuration state are needed. - */ -export class NoopCompilation extends AngularCompilation { - async initialize( - tsconfig: string, - hostOptions: AngularHostOptions, - compilerOptionOverrides?: CompilerOptionOverrides, - ): Promise { - // Load the compiler configuration - const { options: originalCompilerOptions } = await this.loadConfiguration(tsconfig); - // Apply relevant overrides directly without invoking `transformCompilerOptions` - // to avoid loading the `typescript` package on the main thread. - const compilerOptions = { - ...originalCompilerOptions, - noEmitOnError: false, - composite: false, - inlineSources: !!compilerOptionOverrides?.sourcemap, - inlineSourceMap: !!compilerOptionOverrides?.sourcemap, - sourceMap: undefined, - mapRoot: undefined, - sourceRoot: undefined, - preserveSymlinks: compilerOptionOverrides?.preserveSymlinks, - externalRuntimeStyles: compilerOptionOverrides?.externalRuntimeStyles, - _enableHmr: !!compilerOptionOverrides?.enableHmr, - _useTypeScriptTranspilation: - !originalCompilerOptions.isolatedModules || - !!compilerOptionOverrides?.instrumentForCoverage, - supportTestBed: !!compilerOptionOverrides?.includeTestMetadata, - supportJitMode: !!compilerOptionOverrides?.includeTestMetadata, - customConditions: - originalCompilerOptions.moduleResolution === 100 /* Bundler */ || - originalCompilerOptions.module === 200 /* Preserve */ - ? compilerOptionOverrides?.customConditions - : originalCompilerOptions.customConditions, - }; - - return { compilerOptions, referencedFiles: [] }; - } - - override emitAffectedFiles(): never { - throw new Error('Not available when using noop compilation.'); - } -} diff --git a/packages/angular/build/src/tools/esbuild/angular/compilation-state.ts b/packages/angular/build/src/tools/esbuild/angular/compilation-state.ts index 286411a06057..541f52bbca76 100644 --- a/packages/angular/build/src/tools/esbuild/angular/compilation-state.ts +++ b/packages/angular/build/src/tools/esbuild/angular/compilation-state.ts @@ -6,24 +6,46 @@ * found in the LICENSE file at https://angular.dev/license */ -import { type AngularCompilation, NoopCompilation } from '../../angular/compilation'; +import type { CompilerOptions } from '@angular/compiler-cli'; +import type { AngularCompilation } from '../../angular/compilation'; -export class AngularCompilationContext { - #compilation: AngularCompilation; +export abstract class AngularCompilationContext { + abstract readonly compilation?: AngularCompilation; + abstract isPrimary(): this is PrimaryCompilationContext; + abstract readonly waitUntilReady: Promise; + abstract getCompilerOptions(): Promise; + abstract dispose(): Promise; + + createSecondaryContext(): AngularCompilationContext { + return new SecondaryCompilationContext(this); + } +} + +export class PrimaryCompilationContext extends AngularCompilationContext { + readonly #compilation: AngularCompilation; #pendingCompilation = true; #resolveCompilationReady: ((value: boolean) => void) | undefined; #compilationReadyPromise: Promise | undefined; #hasErrors = true; + #compilerOptions: CompilerOptions | undefined; + #resolveCompilerOptions: ((options: CompilerOptions) => void) | undefined; + #compilerOptionsPromise: Promise | undefined; + constructor(compilation: AngularCompilation) { + super(); this.#compilation = compilation; } - get compilation(): AngularCompilation { + override isPrimary(): this is PrimaryCompilationContext { + return true; + } + + override get compilation(): AngularCompilation { return this.#compilation; } - get waitUntilReady(): Promise { + override get waitUntilReady(): Promise { if (!this.#pendingCompilation) { return Promise.resolve(this.#hasErrors); } @@ -35,20 +57,51 @@ export class AngularCompilationContext { return this.#compilationReadyPromise; } + override getCompilerOptions(): Promise { + if (this.#compilerOptions) { + return Promise.resolve(this.#compilerOptions); + } + + if (!this.#pendingCompilation) { + return Promise.resolve({}); + } + + this.#compilerOptionsPromise ??= new Promise((resolve) => { + this.#resolveCompilerOptions = resolve; + }); + + return this.#compilerOptionsPromise; + } + + setCompilerOptions(options: CompilerOptions): void { + this.#compilerOptions = options; + this.#resolveCompilerOptions?.(options); + this.#resolveCompilerOptions = undefined; + this.#compilerOptionsPromise = undefined; + } + markAsReady(hasErrors: boolean): void { this.#hasErrors = hasErrors; this.#resolveCompilationReady?.(hasErrors); + this.#resolveCompilationReady = undefined; this.#compilationReadyPromise = undefined; this.#pendingCompilation = false; + + if (this.#resolveCompilerOptions) { + this.#resolveCompilerOptions(this.#compilerOptions ?? {}); + this.#resolveCompilerOptions = undefined; + this.#compilerOptionsPromise = undefined; + } } markAsInProgress(): void { this.#pendingCompilation = true; + this.#compilerOptions = undefined; } #disposal: Promise | undefined; - dispose(): Promise { + override dispose(): Promise { // Reuse any in progress disposal to ensure all callers can await completion return (this.#disposal ??= this.#close()); } @@ -61,27 +114,27 @@ export class AngularCompilationContext { // Suppress closure errors to avoid unhandled rejections during teardown. } } +} - createSecondaryContext(): AngularCompilationContext { - return new SecondaryCompilationContext(this); +export class SecondaryCompilationContext extends AngularCompilationContext { + constructor(private readonly primaryContext?: AngularCompilationContext) { + super(); } -} -class SecondaryCompilationContext extends AngularCompilationContext { - constructor(private primaryContext: AngularCompilationContext) { - super(new NoopCompilation()); + override isPrimary(): this is PrimaryCompilationContext { + return false; } - override get waitUntilReady(): Promise { - return this.primaryContext.waitUntilReady; + override get compilation(): undefined { + return undefined; } - override markAsReady(hasErrors: boolean): void { - // No-op: secondary contexts do not control compilation state + override get waitUntilReady(): Promise { + return this.primaryContext?.waitUntilReady ?? Promise.resolve(false); } - override markAsInProgress(): void { - // No-op: secondary contexts do not control compilation state + override getCompilerOptions(): Promise { + return this.primaryContext?.getCompilerOptions() ?? Promise.resolve({}); } override async dispose(): Promise { diff --git a/packages/angular/build/src/tools/esbuild/angular/compilation-state_spec.ts b/packages/angular/build/src/tools/esbuild/angular/compilation-state_spec.ts new file mode 100644 index 000000000000..8007427d497c --- /dev/null +++ b/packages/angular/build/src/tools/esbuild/angular/compilation-state_spec.ts @@ -0,0 +1,178 @@ +/** + * @license + * Copyright Google LLC All Rights Reserved. + * + * Use of this source code is governed by an MIT-style license that can be + * found in the LICENSE file at https://angular.dev/license + */ + +import type { CompilerOptions } from '@angular/compiler-cli'; +import type { AngularCompilation } from '../../angular/compilation'; +import { PrimaryCompilationContext, SecondaryCompilationContext } from './compilation-state'; + +describe('compilation-state', () => { + let mockCompilation: jasmine.SpyObj; + + beforeEach(() => { + mockCompilation = jasmine.createSpyObj('AngularCompilation', [ + 'initialize', + 'close', + ]); + }); + + describe('PrimaryCompilationContext', () => { + it('identifies as primary and provides the underlying compilation', () => { + const context = new PrimaryCompilationContext(mockCompilation); + + expect(context.isPrimary()).toBe(true); + expect(context.compilation).toBe(mockCompilation); + }); + + it('resolves getCompilerOptions after setCompilerOptions is called', async () => { + const context = new PrimaryCompilationContext(mockCompilation); + const options: CompilerOptions = { target: 9, allowJs: true }; + + context.setCompilerOptions(options); + + const resolved = await context.getCompilerOptions(); + expect(resolved).toEqual(options); + }); + + it('resolves pending getCompilerOptions when setCompilerOptions is called later', async () => { + const context = new PrimaryCompilationContext(mockCompilation); + const options: CompilerOptions = { target: 9, allowJs: true }; + + const optionsPromise = context.getCompilerOptions(); + context.setCompilerOptions(options); + + const resolved = await optionsPromise; + expect(resolved).toEqual(options); + }); + + it('manages ready state lifecycle correctly', async () => { + const context = new PrimaryCompilationContext(mockCompilation); + + // Initially in progress + const readyPromise = context.waitUntilReady; + context.markAsReady(false); + + const hasErrors = await readyPromise; + expect(hasErrors).toBe(false); + + // When already ready, immediately returns error state + expect(await context.waitUntilReady).toBe(false); + + // Mark in progress again + context.markAsInProgress(); + const secondReadyPromise = context.waitUntilReady; + context.markAsReady(true); + + expect(await secondReadyPromise).toBe(true); + }); + + it('closes compilation and marks ready with errors on dispose', async () => { + const context = new PrimaryCompilationContext(mockCompilation); + + const readyPromise = context.waitUntilReady; + await context.dispose(); + + expect(mockCompilation.close).toHaveBeenCalledTimes(1); + expect(await readyPromise).toBe(true); + }); + + it('unblocks pending getCompilerOptions on markAsReady error', async () => { + const context = new PrimaryCompilationContext(mockCompilation); + + const optionsPromise = context.getCompilerOptions(); + context.markAsReady(true); + + const options = await optionsPromise; + expect(options).toEqual({}); + }); + + it('returns empty options from getCompilerOptions when compilation is not pending and options are unset', async () => { + const context = new PrimaryCompilationContext(mockCompilation); + + context.markAsReady(false); + + const options = await context.getCompilerOptions(); + expect(options).toEqual({}); + }); + + it('clears cached compiler options on markAsInProgress to wait for fresh options on rebuild', async () => { + const context = new PrimaryCompilationContext(mockCompilation); + const initialOptions: CompilerOptions = { target: 9, allowJs: false }; + context.setCompilerOptions(initialOptions); + context.markAsReady(false); + + expect(await context.getCompilerOptions()).toEqual(initialOptions); + + // Rebuild starts + context.markAsInProgress(); + + // Pending call should wait for new options rather than returning stale ones + const nextOptionsPromise = context.getCompilerOptions(); + const updatedOptions: CompilerOptions = { target: 10, allowJs: true }; + context.setCompilerOptions(updatedOptions); + + expect(await nextOptionsPromise).toEqual(updatedOptions); + }); + + it('creates a linked SecondaryCompilationContext', () => { + const context = new PrimaryCompilationContext(mockCompilation); + const secondary = context.createSecondaryContext(); + + expect(secondary).toBeInstanceOf(SecondaryCompilationContext); + expect(secondary.isPrimary()).toBe(false); + expect(secondary.compilation).toBeUndefined(); + }); + }); + + describe('SecondaryCompilationContext', () => { + it('identifies as non-primary and has undefined compilation', () => { + const primary = new PrimaryCompilationContext(mockCompilation); + const secondary = primary.createSecondaryContext(); + + expect(secondary.isPrimary()).toBe(false); + expect(secondary.compilation).toBeUndefined(); + }); + + it('delegates waitUntilReady to primary context', async () => { + const primary = new PrimaryCompilationContext(mockCompilation); + const secondary = primary.createSecondaryContext(); + + const secondaryReadyPromise = secondary.waitUntilReady; + primary.markAsReady(false); + + expect(await secondaryReadyPromise).toBe(false); + }); + + it('delegates getCompilerOptions to primary context', async () => { + const primary = new PrimaryCompilationContext(mockCompilation); + const secondary = primary.createSecondaryContext(); + const options: CompilerOptions = { target: 9, allowJs: false }; + + primary.setCompilerOptions(options); + + expect(await secondary.getCompilerOptions()).toEqual(options); + }); + + it('does not dispose primary compilation when secondary is disposed', async () => { + const primary = new PrimaryCompilationContext(mockCompilation); + const secondary = primary.createSecondaryContext(); + + await secondary.dispose(); + + expect(mockCompilation.close).not.toHaveBeenCalled(); + }); + + it('handles standalone instantiation with sensible defaults', async () => { + const standalone = new SecondaryCompilationContext(); + + expect(standalone.isPrimary()).toBe(false); + expect(standalone.compilation).toBeUndefined(); + expect(await standalone.waitUntilReady).toBe(false); + expect(await standalone.getCompilerOptions()).toEqual({}); + }); + }); +}); diff --git a/packages/angular/build/src/tools/esbuild/angular/compiler-plugin.ts b/packages/angular/build/src/tools/esbuild/angular/compiler-plugin.ts index 05c49040b43c..5ce1130d093a 100644 --- a/packages/angular/build/src/tools/esbuild/angular/compiler-plugin.ts +++ b/packages/angular/build/src/tools/esbuild/angular/compiler-plugin.ts @@ -23,12 +23,12 @@ import * as path from 'node:path'; import { maxWorkers, useTypeChecking } from '../../../utils/environment-options'; import { calculateHash, initializeHash } from '../../../utils/hash'; import { AngularHostOptions } from '../../angular/angular-host'; -import { AngularCompilation, DiagnosticModes, NoopCompilation } from '../../angular/compilation'; +import { AngularCompilation, DiagnosticModes } from '../../angular/compilation'; import { type PersistentCacheStore, createPersistentCacheStore } from '../cache'; import { JavaScriptTransformer } from '../javascript-transformer'; import { LoadResultCache, createCachedLoad } from '../load-result-cache'; import { logCumulativeDurations, profileAsync, resetCumulativeDurations } from '../profiling'; -import { AngularCompilationContext } from './compilation-state'; +import { AngularCompilationContext, PrimaryCompilationContext } from './compilation-state'; import { ComponentStylesheetBundler } from './component-stylesheets'; import { FileReferenceTracker } from './file-reference-tracker'; import { setupJitPluginCallbacks } from './jit-plugin-callbacks'; @@ -117,12 +117,12 @@ export function createCompilerPlugin( const angularCompilationContext = compilationContextOrCompilation instanceof AngularCompilationContext ? compilationContextOrCompilation - : new AngularCompilationContext( + : new PrimaryCompilationContext( typeof compilationContextOrCompilation === 'function' ? await compilationContextOrCompilation() : compilationContextOrCompilation, ); - const compilation: AngularCompilation = angularCompilationContext.compilation; + const compilation: AngularCompilation | undefined = angularCompilationContext.compilation; // The in-memory cache of TypeScript file outputs will be used during the build in `onLoad` callbacks for TS files. // A string value indicates direct TS/NG output and a Uint8Array indicates fully transformed code. @@ -150,12 +150,23 @@ export function createCompilerPlugin( // eslint-disable-next-line max-lines-per-function build.onStart(async () => { await initializeHash(); - angularCompilationContext.markAsInProgress(); const result: OnStartResult = { warnings: setupWarnings, }; + if (!angularCompilationContext.isPrimary()) { + hasCompilationErrors = await angularCompilationContext.waitUntilReady; + const compilerOptions = await angularCompilationContext.getCompilerOptions(); + shouldTsIgnoreJs = !compilerOptions.allowJs; + useTypeScriptTranspilation = !!compilerOptions['_useTypeScriptTranspilation']; + + return result; + } + + angularCompilationContext.markAsInProgress(); + const compilation = angularCompilationContext.compilation; + // Reset debug performance tracking resetCumulativeDurations(); @@ -163,10 +174,7 @@ export function createCompilerPlugin( // Angular compiler which does not have direct knowledge of transitive resource // dependencies or web worker processing. let modifiedFiles; - if ( - !(compilation instanceof NoopCompilation) && - pluginOptions.sourceFileCache?.modifiedFiles.size - ) { + if (pluginOptions.sourceFileCache?.modifiedFiles.size) { // TODO: Differentiate between changed input files and stale output files modifiedFiles = referencedFileTracker.update(pluginOptions.sourceFileCache.modifiedFiles); pluginOptions.sourceFileCache.invalidate(modifiedFiles); @@ -320,6 +328,7 @@ export function createCompilerPlugin( if (initializationResult.warnings?.length) { setupWarnings?.push(...initializationResult.warnings); } + angularCompilationContext.setCompilerOptions(initializationResult.compilerOptions); shouldTsIgnoreJs = !initializationResult.compilerOptions.allowJs; useTypeScriptTranspilation = !!initializationResult.compilerOptions['_useTypeScriptTranspilation']; @@ -345,12 +354,7 @@ export function createCompilerPlugin( // Initialization failure prevents further compilation steps hasCompilationErrors = true; - - return result; - } - - if (compilation instanceof NoopCompilation) { - hasCompilationErrors = await angularCompilationContext.waitUntilReady; + angularCompilationContext.markAsReady(true); return result; } @@ -444,7 +448,7 @@ export function createCompilerPlugin( let contents = typeScriptFileCache.get(request); let directContents: string | undefined; - if (contents === undefined && compilation.transformFile) { + if (contents === undefined && compilation?.transformFile) { try { directContents = await readFile(request, 'utf-8'); const transformResult = await compilation.transformFile(request, directContents); @@ -607,7 +611,9 @@ export function createCompilerPlugin( build.onEnd((result) => { // Ensure other compilations are unblocked if the main compilation throws during start - angularCompilationContext.markAsReady(hasCompilationErrors); + if (angularCompilationContext.isPrimary()) { + angularCompilationContext.markAsReady(hasCompilationErrors); + } for (const { outputFiles, metafile } of additionalResults.values()) { // Add any additional output files to the main output files From 1d5377b632c4bb1482b73d25ee31ea3d48cba09a Mon Sep 17 00:00:00 2001 From: Charles Lyding <19598772+clydin@users.noreply.github.com> Date: Mon, 31 Aug 2026 15:16:09 -0400 Subject: [PATCH 383/787] refactor(@angular/build): pass files directly to inlineAll in i18n inliner Pass build files directly into inlineAll and inlineForLocale via the files parameter instead of requiring them in the I18nInliner constructor options. Because file data is passed on-demand to workers per batch request via Blobs, the WorkerPool has no dependency on build files during initialization. Passing files directly to inlineAll decouples the inliner and worker pool lifecycle from individual build runs, allowing inliner and worker pool reuse across watch mode rebuilds. It also eliminates retention of previous build file buffers on the I18nInliner instance and removes the need to pass empty outputFiles arrays when only inlineTemplateUpdate is called. --- .../build/src/builders/application/i18n.ts | 5 +- .../build/src/tools/esbuild/i18n-inliner.ts | 88 ++--- .../src/tools/esbuild/i18n-inliner_spec.ts | 312 ++++++++++-------- 3 files changed, 226 insertions(+), 179 deletions(-) diff --git a/packages/angular/build/src/builders/application/i18n.ts b/packages/angular/build/src/builders/application/i18n.ts index 5d7efd7548f9..d2db9b6babd9 100644 --- a/packages/angular/build/src/builders/application/i18n.ts +++ b/packages/angular/build/src/builders/application/i18n.ts @@ -44,11 +44,10 @@ export async function inlineI18n( }> { const { i18nOptions, baseHref, cacheOptions } = options; - // Create the multi-threaded inliner with common options and the files generated from the build. + // Create the multi-threaded inliner with common options. const inliner = new I18nInliner( { missingTranslation: i18nOptions.missingTranslationBehavior ?? 'warning', - outputFiles: executionResult.outputFiles, persistentCachePath: cacheOptions.enabled ? cacheOptions.path : undefined, localizeVersion: i18nOptions.localizeVersion, }, @@ -92,7 +91,7 @@ export async function inlineI18n( }; }); - const inlinedLocales = await inliner.inlineAll(localesToInline); + const inlinedLocales = await inliner.inlineAll(executionResult.outputFiles, localesToInline); for (const locale of i18nOptions.inlineLocales) { const localeInlineResult = inlinedLocales.get(locale); diff --git a/packages/angular/build/src/tools/esbuild/i18n-inliner.ts b/packages/angular/build/src/tools/esbuild/i18n-inliner.ts index 4350112d0cf9..84d302428342 100644 --- a/packages/angular/build/src/tools/esbuild/i18n-inliner.ts +++ b/packages/angular/build/src/tools/esbuild/i18n-inliner.ts @@ -99,7 +99,6 @@ async function serializeTranslation( */ export interface I18nInlinerOptions { missingTranslation: 'error' | 'warning' | 'ignore'; - outputFiles: BuildOutputFile[]; persistentCachePath?: string; localizeVersion?: string; } @@ -165,19 +164,36 @@ export class I18nInliner { #transformedFileCache: Cache | undefined; #translationCache: Cache | undefined; #generation = 0; - readonly #localizeFiles: ReadonlyMap; - readonly #unmodifiedFiles: Array; constructor( private readonly options: I18nInlinerOptions, maxThreads?: number, ) { - this.#unmodifiedFiles = []; - const { outputFiles, missingTranslation } = options; - const files = new Map(); + const { missingTranslation } = options; + + this.#workerPool = new WorkerPool({ + filename: require.resolve('./i18n-inliner-worker'), + maxThreads, + // Extract options to ensure only the named options are serialized and sent to the worker + workerData: { + missingTranslation, + }, + }); + } - const pendingMaps = []; - for (const file of outputFiles) { + #partitionFiles(files: Iterable): { + filenames: string[]; + localizeFiles: Map; + localizeMaps: Map; + unmodifiedFiles: BuildOutputFile[]; + } { + const filenames: string[] = []; + const localizeFiles = new Map(); + const localizeMaps = new Map(); + const unmodifiedFiles: BuildOutputFile[] = []; + + const pendingMaps: BuildOutputFile[] = []; + for (const file of files) { if (file.type === BuildOutputFileType.Root || file.type === BuildOutputFileType.ServerRoot) { // Skip also the server entry-point. // Skip stats and similar files. @@ -193,7 +209,8 @@ export class I18nInliner { const hasLocalize = contentBuffer.includes(LOCALIZE_KEYWORD); if (hasLocalize) { - files.set(file.path, file); + localizeFiles.set(file.path, file); + filenames.push(file.path); continue; } @@ -204,28 +221,20 @@ export class I18nInliner { continue; } - this.#unmodifiedFiles.push(file); + unmodifiedFiles.push(file); } // Check if any pending map files should be processed by checking if the parent JS file is present for (const file of pendingMaps) { - if (files.has(file.path.slice(0, -4))) { - files.set(file.path, file); + const jsPath = file.path.slice(0, -4); + if (localizeFiles.has(jsPath)) { + localizeMaps.set(jsPath, file); } else { - this.#unmodifiedFiles.push(file); + unmodifiedFiles.push(file); } } - this.#localizeFiles = files; - - this.#workerPool = new WorkerPool({ - filename: require.resolve('./i18n-inliner-worker'), - maxThreads, - // Extract options to ensure only the named options are serialized and sent to the worker - workerData: { - missingTranslation, - }, - }); + return { filenames, localizeFiles, localizeMaps, unmodifiedFiles }; } /** @@ -234,10 +243,12 @@ export class I18nInliner { * An adaptive 2D task-partitioning algorithm distributes (files x locales) work units * across all worker threads while caching AST metadata and sourcemaps in worker memory. * + * @param files The build output files to transform. * @param locales The locales and translations to inline. * @returns A map of locale names to their inlined output files and diagnostics. */ async inlineAll( + files: Iterable, locales: Iterable, ): Promise> { await this.initCache(); @@ -250,16 +261,14 @@ export class I18nInliner { return new Map(); } + const { filenames, localizeFiles, localizeMaps, unmodifiedFiles } = this.#partitionFiles(files); + const fileResultsByLocale = new Map>(); for (const { locale } of localeList) { assert(!fileResultsByLocale.has(locale), 'Duplicate locale provided to inliner: ' + locale); fileResultsByLocale.set(locale, new Map()); } - const filenames = Array.from(this.#localizeFiles.keys()).filter( - (name) => !name.endsWith('.map'), - ); - // Process locales in sliding windows to cap peak worker memory. // Ensure the window has at least enough locales to saturate all available workers on high-core machines. const windowSize = Math.max(DEFAULT_LOCALE_WINDOW_SIZE, this.#workerPool.maxThreads || 1); @@ -304,7 +313,7 @@ export class I18nInliner { const cacheChecks: Promise[] = []; for (const filename of filenames) { - const file = this.#localizeFiles.get(filename); + const file = localizeFiles.get(filename); assert(file !== undefined, 'Localize file must exist: ' + filename); const fileEntriesPromises = windowLocales.map( @@ -361,6 +370,8 @@ export class I18nInliner { // Adaptive 2D Sharding for uncached tasks in this window if (uncachedByFile.size > 0) { await this.#processUncachedBatches( + localizeFiles, + localizeMaps, uncachedByFile, fileResultsByLocale, activeLocales, @@ -381,7 +392,7 @@ export class I18nInliner { if (fileResults) { for (const filename of filenames) { - const originalFile = this.#localizeFiles.get(filename); + const originalFile = localizeFiles.get(filename); assert(originalFile !== undefined, 'Localize file must exist: ' + filename); const fileResult = fileResults.get(filename); @@ -396,7 +407,7 @@ export class I18nInliner { outputFiles.push(originalFile.clone()); } - const originalMap = this.#localizeFiles.get(filename + '.map'); + const originalMap = localizeMaps.get(filename); if (fileResult.map !== undefined) { outputFiles.push(createOutputFile(filename + '.map', fileResult.map, type)); } else if (originalMap !== undefined) { @@ -414,7 +425,7 @@ export class I18nInliner { } // Include cloned unmodified files for every locale - outputFiles.push(...this.#unmodifiedFiles.map((file) => file.clone())); + outputFiles.push(...unmodifiedFiles.map((file) => file.clone())); resultsByLocale.set(locale, { outputFiles, @@ -427,6 +438,8 @@ export class I18nInliner { } async #processUncachedBatches( + localizeFiles: Map, + localizeMaps: Map, uncachedByFile: Map, fileResultsByLocale: Map>, activeLocales?: string[], @@ -438,7 +451,7 @@ export class I18nInliner { // Extract file data and identify the heaviest file size in a single pass let maxFileSize = 0; const sortedFiles = Array.from(uncachedByFile, ([filename, entries]) => { - const codeFile = this.#localizeFiles.get(filename); + const codeFile = localizeFiles.get(filename); assert(codeFile !== undefined, 'Localize file must exist: ' + filename); const fileSize = codeFile.contents.byteLength; if (fileSize > maxFileSize) { @@ -456,7 +469,7 @@ export class I18nInliner { const workerTasks: Promise[] = []; for (const { filename, entries, codeFile, fileSize } of sortedFiles) { - const mapFile = this.#localizeFiles.get(filename + '.map'); + const mapFile = localizeMaps.get(filename); const codeBlob = new Blob([codeFile.contents]); const mapBlob = mapFile ? new Blob([mapFile.contents]) : undefined; @@ -548,20 +561,21 @@ export class I18nInliner { } /** - * Performs inlining of translations for the provided locale and translations. The files that - * are processed originate from the files passed to the class constructor and filter by presence - * of the localize function keyword. + * Performs inlining of translations for the provided locale and translations. + * + * @param files The build output files to transform. * @param locale The string representing the locale to inline. * @param translation The translation messages to use when inlining. * @param translationIntegrity An optional integrity value for the translation messages to use for caching. * @returns A promise that resolves to an array of OutputFiles representing a translated result. */ async inlineForLocale( + files: Iterable, locale: string, translation: Record | undefined, translationIntegrity?: string, ): Promise { - const results = await this.inlineAll([{ locale, translation, translationIntegrity }]); + const results = await this.inlineAll(files, [{ locale, translation, translationIntegrity }]); const result = results.get(locale); assert(result !== undefined, `Result for locale '${locale}' should be present.`); diff --git a/packages/angular/build/src/tools/esbuild/i18n-inliner_spec.ts b/packages/angular/build/src/tools/esbuild/i18n-inliner_spec.ts index 9cc560d038a1..8059270145bb 100644 --- a/packages/angular/build/src/tools/esbuild/i18n-inliner_spec.ts +++ b/packages/angular/build/src/tools/esbuild/i18n-inliner_spec.ts @@ -14,7 +14,7 @@ import path from 'node:path'; import { initializeHash } from '../../utils/hash'; import { type BuildOutputFile, BuildOutputFileType, createOutputFile } from './bundler-files'; import { createPersistentCacheStore } from './cache'; -import { I18nInliner } from './i18n-inliner'; +import { I18nInliner, type I18nInlinerOptions } from './i18n-inliner'; /** * A module that uses a `$localize` message with an explicit message identifier so that the @@ -63,25 +63,23 @@ describe('I18nInliner', () => { // A single thread is used throughout so that every file of every locale is inlined by the same // Worker. Any translation state that a Worker retains between requests is then observable. - function createInliner(outputFiles: BuildOutputFile[]): I18nInliner { - inliner = new I18nInliner({ missingTranslation: 'warning', outputFiles }, 1); + function createInliner(options?: Partial, maxThreads = 1): I18nInliner { + inliner = new I18nInliner({ missingTranslation: 'warning', ...options }, maxThreads); return inliner; } - beforeAll(async () => { - await initializeHash(); - }); - afterEach(async () => { await inliner?.close(); inliner = undefined; }); it('inlines the translations of a locale', async () => { - const { outputFiles, errors, warnings } = await createInliner([ - browserFile('main.js', GREETING_SOURCE), - ]).inlineForLocale('fr', { greeting: translationFor('Bonjour') }); + const { outputFiles, errors, warnings } = await createInliner().inlineForLocale( + [browserFile('main.js', GREETING_SOURCE)], + 'fr', + { greeting: translationFor('Bonjour') }, + ); expect(errors).toEqual([]); expect(warnings).toEqual([]); @@ -90,14 +88,17 @@ describe('I18nInliner', () => { }); it('inlines the translations of each locale when several are inlined in sequence', async () => { - const localeInliner = createInliner([browserFile('main.js', GREETING_SOURCE)]); + const files = [browserFile('main.js', GREETING_SOURCE)]; + const localeInliner = createInliner(); - const french = await localeInliner.inlineForLocale('fr', { + const french = await localeInliner.inlineForLocale(files, 'fr', { greeting: translationFor('Bonjour'), }); - const german = await localeInliner.inlineForLocale('de', { greeting: translationFor('Hallo') }); + const german = await localeInliner.inlineForLocale(files, 'de', { + greeting: translationFor('Hallo'), + }); // Repeats the first locale to cover a locale being inlined again after another has been. - const frenchAgain = await localeInliner.inlineForLocale('fr', { + const frenchAgain = await localeInliner.inlineForLocale(files, 'fr', { greeting: translationFor('Bonjour'), }); @@ -107,19 +108,22 @@ describe('I18nInliner', () => { }); it('inlines the translations of a locale into every file that uses them', async () => { - const { outputFiles } = await createInliner([ - browserFile('main.js', GREETING_SOURCE), - browserFile('chunk.js', GREETING_SOURCE), - ]).inlineForLocale('fr', { greeting: translationFor('Bonjour') }); + const { outputFiles } = await createInliner().inlineForLocale( + [browserFile('main.js', GREETING_SOURCE), browserFile('chunk.js', GREETING_SOURCE)], + 'fr', + { greeting: translationFor('Bonjour') }, + ); expect(findFile(outputFiles, 'main.js').text).toContain('"Bonjour"'); expect(findFile(outputFiles, 'chunk.js').text).toContain('"Bonjour"'); }); it('retains the original messages for a locale without translations', async () => { - const { outputFiles, errors, warnings } = await createInliner([ - browserFile('main.js', GREETING_SOURCE), - ]).inlineForLocale('en-US', undefined); + const { outputFiles, errors, warnings } = await createInliner().inlineForLocale( + [browserFile('main.js', GREETING_SOURCE)], + 'en-US', + undefined, + ); // A locale without translations is the source locale, so its messages are not missing. expect(errors).toEqual([]); @@ -128,9 +132,11 @@ describe('I18nInliner', () => { }); it('warns and retains the original message when a locale is missing a translation', async () => { - const { outputFiles, errors, warnings } = await createInliner([ - browserFile('main.js', GREETING_SOURCE), - ]).inlineForLocale('fr', { unrelated: translationFor('Sans rapport') }); + const { outputFiles, errors, warnings } = await createInliner().inlineForLocale( + [browserFile('main.js', GREETING_SOURCE)], + 'fr', + { unrelated: translationFor('Sans rapport') }, + ); expect(errors).toEqual([]); expect(warnings.length).toBe(1); @@ -141,9 +147,16 @@ describe('I18nInliner', () => { it('replaces the locale placeholder with the locale being inlined', async () => { // The placeholder is only inlined for files that use `$localize`, which is where the build // inserts it, so the message is present alongside it here. - const { outputFiles } = await createInliner([ - browserFile('main.js', `export const locale = "___NG_LOCALE_INSERT___";\n${GREETING_SOURCE}`), - ]).inlineForLocale('fr', { greeting: translationFor('Bonjour') }); + const { outputFiles } = await createInliner().inlineForLocale( + [ + browserFile( + 'main.js', + `export const locale = "___NG_LOCALE_INSERT___";\n${GREETING_SOURCE}`, + ), + ], + 'fr', + { greeting: translationFor('Bonjour') }, + ); expect(findFile(outputFiles, 'main.js').text).toContain('"fr"'); expect(findFile(outputFiles, 'main.js').text).not.toContain('___NG_LOCALE_INSERT___'); @@ -158,10 +171,11 @@ describe('I18nInliner', () => { sourcemap: 'external', }); - const { outputFiles } = await createInliner([ - browserFile('main.js', code), - browserFile('main.js.map', map), - ]).inlineForLocale('fr', { greeting: translationFor('Bonjour') }); + const { outputFiles } = await createInliner().inlineForLocale( + [browserFile('main.js', code), browserFile('main.js.map', map)], + 'fr', + { greeting: translationFor('Bonjour') }, + ); const outputMap = JSON.parse(findFile(outputFiles, 'main.js.map').text) as { version: number; @@ -177,7 +191,7 @@ describe('I18nInliner', () => { describe('inlineTemplateUpdate', () => { it('inlines the translations of a locale into a template update', async () => { - const { code, errors, warnings } = await createInliner([]).inlineTemplateUpdate( + const { code, errors, warnings } = await createInliner().inlineTemplateUpdate( 'fr', { greeting: translationFor('Bonjour') }, GREETING_SOURCE, @@ -191,7 +205,7 @@ describe('I18nInliner', () => { }); it('retains the original messages for a locale without translations', async () => { - const { code, errors, warnings } = await createInliner([]).inlineTemplateUpdate( + const { code, errors, warnings } = await createInliner().inlineTemplateUpdate( 'en-US', undefined, GREETING_SOURCE, @@ -205,7 +219,7 @@ describe('I18nInliner', () => { it('returns the code untouched when it has no localize calls', async () => { const source = 'export const answer = 42;\n'; - const { code } = await createInliner([]).inlineTemplateUpdate( + const { code } = await createInliner().inlineTemplateUpdate( 'fr', { greeting: translationFor('Bonjour') }, source, @@ -221,7 +235,6 @@ describe('I18nInliner', () => { try { const inliner = new I18nInliner({ missingTranslation: 'error', - outputFiles: [], persistentCachePath: cacheDir, }); @@ -245,11 +258,13 @@ describe('I18nInliner', () => { }); it('safely inlines translations containing special characters, quotes, and newlines', async () => { - const { outputFiles, errors, warnings } = await createInliner([ - browserFile('main.js', GREETING_SOURCE), - ]).inlineForLocale('fr', { - greeting: translationFor('Bonjour "mon ami" \\ \' \n '), - }); + const { outputFiles, errors, warnings } = await createInliner().inlineForLocale( + [browserFile('main.js', GREETING_SOURCE)], + 'fr', + { + greeting: translationFor('Bonjour "mon ami" \\ \' \n '), + }, + ); expect(errors).toEqual([]); expect(warnings).toEqual([]); @@ -260,11 +275,13 @@ describe('I18nInliner', () => { it('inlines translations containing placeholders', async () => { const source = 'export const welcome = (name) => $localize`:@@welcome:Hello ${name}!`;\n'; - const { outputFiles, errors, warnings } = await createInliner([ - browserFile('main.js', source), - ]).inlineForLocale('fr', { - welcome: parsedTranslation(['Bonjour ', ' !'], ['PH'], 'Bonjour {$PH} !'), - }); + const { outputFiles, errors, warnings } = await createInliner().inlineForLocale( + [browserFile('main.js', source)], + 'fr', + { + welcome: parsedTranslation(['Bonjour ', ' !'], ['PH'], 'Bonjour {$PH} !'), + }, + ); expect(errors).toEqual([]); expect(warnings).toEqual([]); @@ -276,12 +293,14 @@ describe('I18nInliner', () => { it('inlines multiple localize calls within the same file', async () => { const source = 'export const a = $localize`:@@greeting:Hello`;\nexport const b = $localize`:@@farewell:Goodbye`;\n'; - const { outputFiles, errors, warnings } = await createInliner([ - browserFile('main.js', source), - ]).inlineForLocale('fr', { - greeting: translationFor('Bonjour'), - farewell: translationFor('Au revoir'), - }); + const { outputFiles, errors, warnings } = await createInliner().inlineForLocale( + [browserFile('main.js', source)], + 'fr', + { + greeting: translationFor('Bonjour'), + farewell: translationFor('Au revoir'), + }, + ); expect(errors).toEqual([]); expect(warnings).toEqual([]); @@ -291,20 +310,20 @@ describe('I18nInliner', () => { }); it('inlines translations across multiple files using multiple worker threads in parallel', async () => { + const files = [ + browserFile('main.js', GREETING_SOURCE), + browserFile('chunk1.js', GREETING_SOURCE), + browserFile('chunk2.js', GREETING_SOURCE), + browserFile('chunk3.js', GREETING_SOURCE), + ]; inliner = new I18nInliner( { missingTranslation: 'warning', - outputFiles: [ - browserFile('main.js', GREETING_SOURCE), - browserFile('chunk1.js', GREETING_SOURCE), - browserFile('chunk2.js', GREETING_SOURCE), - browserFile('chunk3.js', GREETING_SOURCE), - ], }, 4, ); - const { outputFiles, errors, warnings } = await inliner.inlineForLocale('fr', { + const { outputFiles, errors, warnings } = await inliner.inlineForLocale(files, 'fr', { greeting: translationFor('Bonjour'), }); @@ -316,10 +335,14 @@ describe('I18nInliner', () => { }); it('leaves files without localize calls unmodified', async () => { - const { outputFiles } = await createInliner([ - browserFile('main.js', GREETING_SOURCE), - browserFile('other.js', 'export const answer = 42;\n'), - ]).inlineForLocale('fr', { greeting: translationFor('Bonjour') }); + const { outputFiles } = await createInliner().inlineForLocale( + [ + browserFile('main.js', GREETING_SOURCE), + browserFile('other.js', 'export const answer = 42;\n'), + ], + 'fr', + { greeting: translationFor('Bonjour') }, + ); expect(findFile(outputFiles, 'other.js').text).toBe('export const answer = 42;\n'); }); @@ -327,16 +350,18 @@ describe('I18nInliner', () => { it('inlines nested $localize calls in post-order', async () => { const source = 'export const msg = $localize`:@@outer:You selected ${$localize`:@@inner:Apple`} for delivery.`;\n'; - const { outputFiles, errors, warnings } = await createInliner([ - browserFile('main.js', source), - ]).inlineForLocale('fr', { - inner: translationFor('Pomme'), - outer: parsedTranslation( - ['Vous avez sélectionné ', ' pour la livraison.'], - ['PH'], - 'Vous avez sélectionné {$PH} pour la livraison.', - ), - }); + const { outputFiles, errors, warnings } = await createInliner().inlineForLocale( + [browserFile('main.js', source)], + 'fr', + { + inner: translationFor('Pomme'), + outer: parsedTranslation( + ['Vous avez sélectionné ', ' pour la livraison.'], + ['PH'], + 'Vous avez sélectionné {$PH} pour la livraison.', + ), + }, + ); expect(errors).toEqual([]); expect(warnings).toEqual([]); @@ -347,7 +372,8 @@ describe('I18nInliner', () => { it('reports an error diagnostic when a $localize template has a malformed escape sequence', async () => { const source = 'export const msg = $localize`:@@id:\\unicode:`;\n'; - const { errors } = await createInliner([browserFile('main.js', source)]).inlineForLocale( + const { errors } = await createInliner().inlineForLocale( + [browserFile('main.js', source)], 'fr', {}, ); @@ -358,9 +384,12 @@ describe('I18nInliner', () => { }); it('inlines the translations of a locale when translationIntegrity is provided', async () => { - const { outputFiles, errors, warnings } = await createInliner([ - browserFile('main.js', GREETING_SOURCE), - ]).inlineForLocale('fr', { greeting: translationFor('Bonjour') }, 'sha256-test-integrity'); + const { outputFiles, errors, warnings } = await createInliner().inlineForLocale( + [browserFile('main.js', GREETING_SOURCE)], + 'fr', + { greeting: translationFor('Bonjour') }, + 'sha256-test-integrity', + ); expect(errors).toEqual([]); expect(warnings).toEqual([]); @@ -372,13 +401,13 @@ describe('I18nInliner', () => { inliner = new I18nInliner( { missingTranslation: 'warning', - outputFiles: [browserFile('main.js', GREETING_SOURCE)], localizeVersion: '20.2.0', }, 1, ); const { outputFiles, errors, warnings } = await inliner.inlineForLocale( + [browserFile('main.js', GREETING_SOURCE)], 'fr', { greeting: translationFor('Bonjour') }, 'sha256-test-integrity', @@ -391,13 +420,14 @@ describe('I18nInliner', () => { }); it('inlines multiple locales in parallel via inlineAll', async () => { - const localeInliner = createInliner([ + const files = [ browserFile('main.js', GREETING_SOURCE), browserFile('chunk.js', GREETING_SOURCE), browserFile('other.js', 'export const answer = 42;\n'), - ]); + ]; + const localeInliner = createInliner(); - const results = await localeInliner.inlineAll([ + const results = await localeInliner.inlineAll(files, [ { locale: 'fr', translation: { greeting: translationFor('Bonjour') } }, { locale: 'de', translation: { greeting: translationFor('Hallo') } }, { locale: 'es', translation: { greeting: translationFor('Hola') } }, @@ -437,13 +467,14 @@ describe('I18nInliner', () => { sourcemap: 'external', }); - const localeInliner = createInliner([ + const files = [ browserFile('main.js', code), browserFile('main.js.map', map), browserFile('other.js', 'export const answer = 42;\n'), - ]); + ]; + const localeInliner = createInliner(); - const results = await localeInliner.inlineAll([ + const results = await localeInliner.inlineAll(files, [ { locale: 'fr', translation: { greeting: translationFor('Bonjour') } }, { locale: 'de', translation: { greeting: translationFor('Hallo') } }, { locale: 'en-US', translation: undefined }, @@ -483,13 +514,13 @@ describe('I18nInliner', () => { const cacheDir = await fs.mkdtemp(path.join(os.tmpdir(), 'i18n-cache-test-')); try { + const files = [ + browserFile('main.js', GREETING_SOURCE), + browserFile('other.js', 'export const answer = 42;\n'), + ]; const initialInliner = new I18nInliner( { missingTranslation: 'warning', - outputFiles: [ - browserFile('main.js', GREETING_SOURCE), - browserFile('other.js', 'export const answer = 42;\n'), - ], persistentCachePath: cacheDir, }, 2, @@ -497,6 +528,7 @@ describe('I18nInliner', () => { // Pre-populate cache for 'fr' await initialInliner.inlineForLocale( + files, 'fr', { greeting: translationFor('Bonjour') }, 'integrity-fr-1', @@ -507,16 +539,12 @@ describe('I18nInliner', () => { inliner = new I18nInliner( { missingTranslation: 'warning', - outputFiles: [ - browserFile('main.js', GREETING_SOURCE), - browserFile('other.js', 'export const answer = 42;\n'), - ], persistentCachePath: cacheDir, }, 2, ); - const results = await inliner.inlineAll([ + const results = await inliner.inlineAll(files, [ { locale: 'fr', translation: { greeting: translationFor('Bonjour') }, @@ -564,15 +592,15 @@ describe('I18nInliner', () => { translation: { greeting: translationFor(`Hello ${i}`) }, })); - const inliner = new I18nInliner( + const files = [browserFile('main.js', GREETING_SOURCE)]; + inliner = new I18nInliner( { missingTranslation: 'warning', - outputFiles: [browserFile('main.js', GREETING_SOURCE)], }, 2, ); - const results = await inliner.inlineAll(locales); + const results = await inliner.inlineAll(files, locales); expect(results.size).toBe(20); for (let i = 0; i < 20; i++) { @@ -584,9 +612,10 @@ describe('I18nInliner', () => { it('injects locale data alongside ___NG_LOCALE_INSERT___ for non-English locales', async () => { const source = `(globalThis.$localize ??= {}).locale = "___NG_LOCALE_INSERT___";\n${GREETING_SOURCE}`; - const localeInliner = createInliner([browserFile('polyfills.js', source)]); + const files = [browserFile('polyfills.js', source)]; + const localeInliner = createInliner(); - const results = await localeInliner.inlineAll([ + const results = await localeInliner.inlineAll(files, [ { locale: 'fr', translation: { greeting: translationFor('Bonjour') } }, { locale: 'en-US', translation: undefined }, ]); @@ -606,9 +635,10 @@ describe('I18nInliner', () => { it('warns and uses parent locale data when a subtag locale is not directly available', async () => { const source = `(globalThis.$localize ??= {}).locale = "___NG_LOCALE_INSERT___";\n${GREETING_SOURCE}`; - const localeInliner = createInliner([browserFile('polyfills.js', source)]); + const files = [browserFile('polyfills.js', source)]; + const localeInliner = createInliner(); - const results = await localeInliner.inlineAll([ + const results = await localeInliner.inlineAll(files, [ { locale: 'fr-ZZ', translation: { greeting: translationFor('Bonjour') } }, ]); @@ -624,9 +654,10 @@ describe('I18nInliner', () => { it('warns and includes no locale data when locale data cannot be found', async () => { const source = `(globalThis.$localize ??= {}).locale = "___NG_LOCALE_INSERT___";\n${GREETING_SOURCE}`; - const localeInliner = createInliner([browserFile('polyfills.js', source)]); + const files = [browserFile('polyfills.js', source)]; + const localeInliner = createInliner(); - const results = await localeInliner.inlineAll([ + const results = await localeInliner.inlineAll(files, [ { locale: 'xx-YY', translation: { greeting: translationFor('Test') } }, ]); @@ -642,9 +673,10 @@ describe('I18nInliner', () => { it('reports an error diagnostic when an invalid or unsupported locale is provided', async () => { const source = `(globalThis.$localize ??= {}).locale = "___NG_LOCALE_INSERT___";\n${GREETING_SOURCE}`; - const localeInliner = createInliner([browserFile('polyfills.js', source)]); + const files = [browserFile('polyfills.js', source)]; + const localeInliner = createInliner(); - const results = await localeInliner.inlineAll([ + const results = await localeInliner.inlineAll(files, [ { locale: 'invalid locale tag', translation: { greeting: translationFor('Test') } }, ]); @@ -658,9 +690,10 @@ describe('I18nInliner', () => { const source = `(globalThis.$localize ??= {}).locale = "___NG_LOCALE_INSERT___";\n` + `const secondary = "___NG_LOCALE_INSERT___";\n${GREETING_SOURCE}`; - const localeInliner = createInliner([browserFile('polyfills.js', source)]); + const files = [browserFile('polyfills.js', source)]; + const localeInliner = createInliner(); - const results = await localeInliner.inlineAll([ + const results = await localeInliner.inlineAll(files, [ { locale: 'fr', translation: { greeting: translationFor('Bonjour') } }, ]); @@ -682,12 +715,10 @@ describe('I18nInliner', () => { sourcemap: 'external', }); - const localeInliner = createInliner([ - browserFile('main.js', code), - browserFile('main.js.map', map), - ]); + const files = [browserFile('main.js', code), browserFile('main.js.map', map)]; + const localeInliner = createInliner(); - const results = await localeInliner.inlineAll([ + const results = await localeInliner.inlineAll(files, [ { locale: 'fr', translation: { greeting: translationFor('Bonjour') } }, { locale: 'de', translation: { greeting: translationFor('Hallo') } }, ]); @@ -713,13 +744,13 @@ describe('I18nInliner', () => { const source = '// $localize comment only\nexport const value = 123;\n'; try { + const files = [browserFile('main.js', source)]; const inliner1 = new I18nInliner({ missingTranslation: 'error', - outputFiles: [browserFile('main.js', source)], persistentCachePath: cacheDir, }); - const results1 = await inliner1.inlineAll([ + const results1 = await inliner1.inlineAll(files, [ { locale: 'fr', translation: { greeting: translationFor('Bonjour') }, @@ -733,11 +764,10 @@ describe('I18nInliner', () => { const inliner2 = new I18nInliner({ missingTranslation: 'error', - outputFiles: [browserFile('main.js', source)], persistentCachePath: cacheDir, }); - const results2 = await inliner2.inlineAll([ + const results2 = await inliner2.inlineAll(files, [ { locale: 'fr', translation: { greeting: translationFor('Bonjour') }, @@ -757,14 +787,14 @@ describe('I18nInliner', () => { const cacheDir = await fs.mkdtemp(path.join(os.tmpdir(), 'i18n-inliner-trans-cache-test-')); try { + const files = [browserFile('main.js', GREETING_SOURCE)]; const inliner1 = new I18nInliner({ missingTranslation: 'error', - outputFiles: [browserFile('main.js', GREETING_SOURCE)], persistentCachePath: cacheDir, }); const translationIntegrity = 'hash-test-integrity-12345'; - const results1 = await inliner1.inlineAll([ + const results1 = await inliner1.inlineAll(files, [ { locale: 'fr', translation: { greeting: translationFor('Bonjour') }, @@ -791,11 +821,10 @@ describe('I18nInliner', () => { const inliner2 = new I18nInliner({ missingTranslation: 'error', - outputFiles: [browserFile('main.js', GREETING_SOURCE)], persistentCachePath: cacheDir, }); - const results2 = await inliner2.inlineAll([ + const results2 = await inliner2.inlineAll(files, [ { locale: 'fr', translation: { greeting: translationFor('Bonjour') }, @@ -814,13 +843,16 @@ describe('I18nInliner', () => { }); it('throws an error when duplicate locales are provided to inlineAll', async () => { - const localeInliner = createInliner([browserFile('main.js', GREETING_SOURCE)]); + const localeInliner = createInliner(); await expectAsync( - localeInliner.inlineAll([ - { locale: 'fr', translation: { greeting: translationFor('Bonjour') } }, - { locale: 'fr', translation: { greeting: translationFor('Salut') } }, - ]), + localeInliner.inlineAll( + [browserFile('main.js', GREETING_SOURCE)], + [ + { locale: 'fr', translation: { greeting: translationFor('Bonjour') } }, + { locale: 'fr', translation: { greeting: translationFor('Salut') } }, + ], + ), ).toBeRejectedWithError(/Duplicate locale provided to inliner: fr/); }); @@ -828,14 +860,14 @@ describe('I18nInliner', () => { const localeInliner = new I18nInliner( { missingTranslation: 'warning', - outputFiles: [browserFile('main.js', GREETING_SOURCE)], }, 2, ); try { + const files1 = [browserFile('main.js', GREETING_SOURCE)]; // First generation - const results1 = await localeInliner.inlineAll([ + const results1 = await localeInliner.inlineAll(files1, [ { locale: 'fr', translation: { greeting: translationFor('Bonjour') } }, ]); expect(findFile(results1.get('fr')?.outputFiles ?? [], 'main.js').text).toContain( @@ -843,7 +875,8 @@ describe('I18nInliner', () => { ); // Second generation (e.g. watch mode rebuild with updated translation) - const results2 = await localeInliner.inlineAll([ + const files2 = [browserFile('main.js', GREETING_SOURCE)]; + const results2 = await localeInliner.inlineAll(files2, [ { locale: 'fr', translation: { greeting: translationFor('Salut') } }, { locale: 'de', translation: { greeting: translationFor('Hallo') } }, ]); @@ -856,16 +889,19 @@ describe('I18nInliner', () => { it('correctly escapes backticks, double quotes, and expression delimiters in translated template literals', async () => { const source = 'export const msg = $localize`:@@msg:Hello ${name}:name:!`;\n'; - const inliner = createInliner([browserFile('main.js', source)]); + const inliner = createInliner(); - const results = await inliner.inlineAll([ - { - locale: 'fr', - translation: { - msg: parsedTranslation(['Bonjour "', '` with ${injected} and \\backslash!'], ['name']), + const results = await inliner.inlineAll( + [browserFile('main.js', source)], + [ + { + locale: 'fr', + translation: { + msg: parsedTranslation(['Bonjour "', '` with ${injected} and \\backslash!'], ['name']), + }, }, - }, - ]); + ], + ); const outputText = findFile(results.get('fr')?.outputFiles ?? [], 'main.js').text; expect(outputText).toContain('`Bonjour "${name}\\` with \\${injected} and \\\\backslash!`'); @@ -879,13 +915,11 @@ describe('I18nInliner', () => { const largeFile = browserFile('main.js', largeSource); const smallFile = browserFile('chunk.js', smallSource); + const files = [largeFile, smallFile]; - inliner = new I18nInliner( - { missingTranslation: 'error', outputFiles: [largeFile, smallFile] }, - 2, - ); + inliner = new I18nInliner({ missingTranslation: 'error' }, 2); - const results = await inliner.inlineAll([ + const results = await inliner.inlineAll(files, [ { locale: 'fr', translation: { From b37c933299dac37e394d9f4fe0d019052db427a9 Mon Sep 17 00:00:00 2001 From: Charles Lyding <19598772+clydin@users.noreply.github.com> Date: Mon, 31 Aug 2026 09:42:56 -0400 Subject: [PATCH 384/787] fix(@angular/cli): isolate temporary package installations from parent Yarn workspace When installing a temporary CLI package during update command execution, the temporary directory is placed within the project tree (e.g. under node_modules). When using Yarn modern (v2+), Yarn searches upward for a yarn.lock file to locate the project root. Upon finding the parent project's yarn.lock, Yarn detects that the temporary directory contains a package.json but is not a declared workspace member, causing yarn add to fail with a Usage Error. To resolve this, an empty yarn.lock file is written to the temporary directory when the package manager is Yarn modern. This creates a project boundary that prevents upward workspace traversal and ensures Yarn treats the directory as an independent project. Additionally, if the parent project does not define a .yarnrc.yml or .yarnrc.yaml, a default configuration specifying 'nodeLinker: node-modules' is written to ensure packages are installed into node_modules rather than PnP. Fixes #33972 --- .../src/package-managers/package-manager.ts | 17 +++++++ .../package-managers/package-manager_spec.ts | 47 +++++++++++++++++++ 2 files changed, 64 insertions(+) diff --git a/packages/angular/cli/src/package-managers/package-manager.ts b/packages/angular/cli/src/package-managers/package-manager.ts index 32f63e51deac..234b54851232 100644 --- a/packages/angular/cli/src/package-managers/package-manager.ts +++ b/packages/angular/cli/src/package-managers/package-manager.ts @@ -724,8 +724,15 @@ export class PackageManager { } } + // To prevent Yarn modern from traversing up the directory tree and failing because the temporary + // directory is not part of the project's workspace, write an empty `yarn.lock` to act as a project boundary. + if (this.name === 'yarn') { + await this.host.writeFile(join(workingDirectory, 'yarn.lock'), ''); + } + // Copy configuration files if the package manager requires it (e.g., bun, yarn). if (this.descriptor.copyConfigFromProject) { + let copiedYarnConfig = false; for (const configFile of this.descriptor.configFiles) { try { const configPath = join(this.cwd, configFile); @@ -734,10 +741,20 @@ export class PackageManager { content = sanitizeYarnRc(content); } await this.host.writeFile(join(workingDirectory, configFile), content); + if (this.name === 'yarn') { + copiedYarnConfig = true; + } } catch { // Ignore missing config files. } } + + if (this.name === 'yarn' && !copiedYarnConfig) { + await this.host.writeFile( + join(workingDirectory, '.yarnrc.yml'), + 'nodeLinker: node-modules\n', + ); + } } const flags = [options.ignoreScripts ? this.descriptor.ignoreScriptsFlag : ''].filter( diff --git a/packages/angular/cli/src/package-managers/package-manager_spec.ts b/packages/angular/cli/src/package-managers/package-manager_spec.ts index 83709af7182b..d500a435d0df 100644 --- a/packages/angular/cli/src/package-managers/package-manager_spec.ts +++ b/packages/angular/cli/src/package-managers/package-manager_spec.ts @@ -192,6 +192,10 @@ describe('PackageManager', () => { '/tmp/project/node_modules/angular-cli-tmp-packages-abc/pnpm-workspace.yaml', '', ); + expect(writeFileSpy).not.toHaveBeenCalledWith( + '/tmp/project/node_modules/angular-cli-tmp-packages-abc/yarn.lock', + '', + ); }); it('should copy and sanitize .yarnrc.yml when package manager is yarn and it exists', async () => { @@ -244,6 +248,10 @@ describe('PackageManager', () => { 'nodeLinker: node-modules', ].join('\n'); + expect(writeFileSpy).toHaveBeenCalledWith( + '/tmp/project/node_modules/angular-cli-tmp-packages-abc/yarn.lock', + '', + ); expect(writeFileSpy).toHaveBeenCalledWith( '/tmp/project/node_modules/angular-cli-tmp-packages-abc/.yarnrc.yml', expectedYarnRcContent, @@ -254,6 +262,45 @@ describe('PackageManager', () => { ); }); + it('should write empty yarn.lock and default .yarnrc.yml when package manager is yarn and config does not exist', async () => { + const yarnDescriptor = SUPPORTED_PACKAGE_MANAGERS['yarn']; + const testHost = new MockHost({ + '/tmp/project/node_modules': true, + }); + const pm = new PackageManager(testHost, '/tmp/project', yarnDescriptor); + + const createTempDirectorySpy = spyOn(testHost, 'createTempDirectory').and.resolveTo( + '/tmp/project/node_modules/angular-cli-tmp-packages-abc', + ); + const writeFileSpy = spyOn(testHost, 'writeFile').and.resolveTo(); + + spyOn(testHost, 'readFile').and.callFake(async (filePath) => { + if (filePath.replace(/\\/g, '/').endsWith('package.json')) { + return JSON.stringify({ packageManager: 'yarn@4.4.1' }); + } + throw new Error(`ENOENT: no such file or directory, open '${filePath}'`); + }); + spyOn(testHost, 'runCommand').and.resolveTo({ stdout: '4.4.1', stderr: '' }); + + const { workingDirectory } = await pm.acquireTempPackage('foo@1.0.0'); + + expect(workingDirectory).toBe('/tmp/project/node_modules/angular-cli-tmp-packages-abc'); + expect(createTempDirectorySpy).toHaveBeenCalledWith('/tmp/project/node_modules'); + + expect(writeFileSpy).toHaveBeenCalledWith( + '/tmp/project/node_modules/angular-cli-tmp-packages-abc/yarn.lock', + '', + ); + expect(writeFileSpy).toHaveBeenCalledWith( + '/tmp/project/node_modules/angular-cli-tmp-packages-abc/.yarnrc.yml', + 'nodeLinker: node-modules\n', + ); + expect(writeFileSpy).toHaveBeenCalledWith( + '/tmp/project/node_modules/angular-cli-tmp-packages-abc/package.json', + JSON.stringify({ packageManager: 'yarn@4.4.1' }, null, 2), + ); + }); + it('should copy packageManager field to temp package.json if version is resolved', async () => { const npmDescriptor = SUPPORTED_PACKAGE_MANAGERS['npm']; const testHost = new MockHost({ From dfa7f03a93b5b24b949aea354bc40f0a91e9582d Mon Sep 17 00:00:00 2001 From: Charles Lyding <19598772+clydin@users.noreply.github.com> Date: Mon, 31 Aug 2026 10:00:49 -0400 Subject: [PATCH 385/787] fix(@angular/build): keep dev-server Vite cache worktree-local When running within a Git worktree, the persistent build cache is shared across worktrees by resolving relative to the common Git directory (main repository root). While this works for location-agnostic compilation caches (such as `ng build`'s SourceFileCache), it breaks `ng serve` when server-side rendering (SSR) is enabled. In SSR mode, Vite prebundles dependencies into `deps_ssr/`. Any external or unbundled dependencies inside those prebundles contain bare imports (e.g., `firebase-admin/data-connect`). Because Node.js resolves bare imports relative to the prebundled file's location, placing `cacheDir` under the main repository root causes Node.js to resolve imports against the main repository's `node_modules` instead of the worktree's `node_modules`, resulting in `Cannot find module` errors and HTTP 500 responses. To resolve this, `NormalizedCachedOptions` now exposes `localBasePath` and `localPath` which always resolve relative to the active workspace root. The dev-server's Vite configuration now uses `localPath` for `cacheDir`, ensuring prebundles remain within the worktree hierarchy where Node.js can resolve the worktree's dependencies. Additionally, cache purging and watcher ignore lists are updated to handle both shared and local cache paths when they diverge. Fixes #33968 --- .../src/builders/application/build-action.ts | 5 ++ .../src/builders/dev-server/vite/server.ts | 6 +- .../build/src/utils/normalize-cache.ts | 19 +++++- .../build/src/utils/normalize-cache_spec.ts | 58 +++++++++++++++++++ .../angular/build/src/utils/purge-cache.ts | 42 +++++++++----- 5 files changed, 114 insertions(+), 16 deletions(-) diff --git a/packages/angular/build/src/builders/application/build-action.ts b/packages/angular/build/src/builders/application/build-action.ts index 3f8d24da6ecc..7cc3437fa323 100644 --- a/packages/angular/build/src/builders/application/build-action.ts +++ b/packages/angular/build/src/builders/application/build-action.ts @@ -123,6 +123,11 @@ export async function* runEsBuildBuildAction( `${toPosixPath(workspaceRoot)}/**/.*/**`, ]; + if (cacheOptions.localBasePath && cacheOptions.localBasePath !== cacheOptions.basePath) { + const normalizedLocalCacheBase = toPosixPath(cacheOptions.localBasePath); + ignored.push(normalizedLocalCacheBase, `${normalizedLocalCacheBase}/**`); + } + // Setup a watcher const { createWatcher } = await import('../../tools/esbuild/watcher'); watcher = await createWatcher({ diff --git a/packages/angular/build/src/builders/dev-server/vite/server.ts b/packages/angular/build/src/builders/dev-server/vite/server.ts index b1826383fccb..7dd62aed37b6 100644 --- a/packages/angular/build/src/builders/dev-server/vite/server.ts +++ b/packages/angular/build/src/builders/dev-server/vite/server.ts @@ -165,7 +165,11 @@ export async function setupServer( */ const preTransformRequests = externalMetadata.explicitBrowser.length === 0 && ssrMode === ServerSsrMode.NoSsr; - const cacheDir = join(serverOptions.cacheOptions.path, serverOptions.buildTarget.project, 'vite'); + const cacheDir = join( + serverOptions.cacheOptions.localPath ?? serverOptions.cacheOptions.path, + serverOptions.buildTarget.project, + 'vite', + ); const configuration: Vite.InlineConfig = { configFile: false, diff --git a/packages/angular/build/src/utils/normalize-cache.ts b/packages/angular/build/src/utils/normalize-cache.ts index c2dc52514992..0c5aedc73684 100644 --- a/packages/angular/build/src/utils/normalize-cache.ts +++ b/packages/angular/build/src/utils/normalize-cache.ts @@ -21,6 +21,18 @@ export interface NormalizedCachedOptions { /** Disk cache base path. Example: `/.angular/cache`. */ basePath: string; + + /** + * Workspace-local disk cache path. Example: `/.angular/cache/v12.0.0`. + * Always resolves relative to the current workspace root, even within a Git worktree. + */ + localPath?: string; + + /** + * Workspace-local disk cache base path. Example: `/.angular/cache`. + * Always resolves relative to the current workspace root, even within a Git worktree. + */ + localBasePath?: string; } interface CacheMetadata { @@ -82,7 +94,7 @@ function getCacheBasePath(workspaceRoot: string, cachePathSetting: string): stri export function normalizeCacheOptions( projectMetadata: unknown, - worspaceRoot: string, + workspaceRoot: string, ): NormalizedCachedOptions { const cacheMetadata = hasCacheMetadata(projectMetadata) ? projectMetadata.cli.cache : {}; @@ -106,11 +118,14 @@ export function normalizeCacheOptions( } } - const cacheBasePath = getCacheBasePath(worspaceRoot, path); + const cacheBasePath = getCacheBasePath(workspaceRoot, path); + const localCacheBasePath = isAbsolute(path) ? path : resolve(workspaceRoot, path); return { enabled: cacheEnabled, basePath: cacheBasePath, path: join(cacheBasePath, VERSION), + localBasePath: localCacheBasePath, + localPath: join(localCacheBasePath, VERSION), }; } diff --git a/packages/angular/build/src/utils/normalize-cache_spec.ts b/packages/angular/build/src/utils/normalize-cache_spec.ts index c8a72870d62a..cfa98ea8a69e 100644 --- a/packages/angular/build/src/utils/normalize-cache_spec.ts +++ b/packages/angular/build/src/utils/normalize-cache_spec.ts @@ -29,6 +29,8 @@ describe('normalizeCacheOptions', () => { const options = normalizeCacheOptions({}, workspaceRoot); expect(options.basePath).toBe(resolve(workspaceRoot, '.angular/cache')); + expect(options.localBasePath).toBe(resolve(workspaceRoot, '.angular/cache')); + expect(options.localPath).toBe(resolve(workspaceRoot, '.angular/cache', '0.0.0-PLACEHOLDER')); }); it('should resolve cache path relative to main repository root in a git worktree', async () => { @@ -51,6 +53,58 @@ describe('normalizeCacheOptions', () => { const options = normalizeCacheOptions({}, worktreeRoot); expect(options.basePath).toBe(resolve(mainRepoRoot, '.angular/cache')); + expect(options.path).toBe(resolve(mainRepoRoot, '.angular/cache', '0.0.0-PLACEHOLDER')); + expect(options.localBasePath).toBe(resolve(worktreeRoot, '.angular/cache')); + expect(options.localPath).toBe(resolve(worktreeRoot, '.angular/cache', '0.0.0-PLACEHOLDER')); + }); + + it('should resolve local cache path relative to worktree root with custom relative path', async () => { + const mainRepoRoot = join(tempDir, 'main-repo'); + const mainGitDir = join(mainRepoRoot, '.git'); + const worktreeRoot = join(tempDir, 'worktree'); + + await mkdir(mainGitDir, { recursive: true }); + + const worktreeMetadataDir = join(mainGitDir, 'worktrees/wt-1'); + await mkdir(worktreeMetadataDir, { recursive: true }); + await mkdir(worktreeRoot, { recursive: true }); + await writeFile(join(worktreeRoot, '.git'), `gitdir: ${worktreeMetadataDir}`); + await writeFile(join(worktreeMetadataDir, 'commondir'), '../..'); + + const options = normalizeCacheOptions( + { cli: { cache: { path: 'custom-cache' } } }, + worktreeRoot, + ); + + expect(options.basePath).toBe(resolve(mainRepoRoot, 'custom-cache')); + expect(options.path).toBe(resolve(mainRepoRoot, 'custom-cache', '0.0.0-PLACEHOLDER')); + expect(options.localBasePath).toBe(resolve(worktreeRoot, 'custom-cache')); + expect(options.localPath).toBe(resolve(worktreeRoot, 'custom-cache', '0.0.0-PLACEHOLDER')); + }); + + it('should preserve absolute cache path for both shared and local paths', async () => { + const mainRepoRoot = join(tempDir, 'main-repo'); + const mainGitDir = join(mainRepoRoot, '.git'); + const worktreeRoot = join(tempDir, 'worktree'); + const absoluteCachePath = join(tempDir, 'absolute-cache'); + + await mkdir(mainGitDir, { recursive: true }); + + const worktreeMetadataDir = join(mainGitDir, 'worktrees/wt-1'); + await mkdir(worktreeMetadataDir, { recursive: true }); + await mkdir(worktreeRoot, { recursive: true }); + await writeFile(join(worktreeRoot, '.git'), `gitdir: ${worktreeMetadataDir}`); + await writeFile(join(worktreeMetadataDir, 'commondir'), '../..'); + + const options = normalizeCacheOptions( + { cli: { cache: { path: absoluteCachePath } } }, + worktreeRoot, + ); + + expect(options.basePath).toBe(absoluteCachePath); + expect(options.path).toBe(resolve(absoluteCachePath, '0.0.0-PLACEHOLDER')); + expect(options.localBasePath).toBe(absoluteCachePath); + expect(options.localPath).toBe(resolve(absoluteCachePath, '0.0.0-PLACEHOLDER')); }); it('should resolve cache path relative to workspace root in a git submodule', async () => { @@ -69,6 +123,8 @@ describe('normalizeCacheOptions', () => { const options = normalizeCacheOptions({}, submoduleRoot); expect(options.basePath).toBe(resolve(submoduleRoot, '.angular/cache')); + expect(options.localBasePath).toBe(resolve(submoduleRoot, '.angular/cache')); + expect(options.localPath).toBe(resolve(submoduleRoot, '.angular/cache', '0.0.0-PLACEHOLDER')); }); it('should resolve cache path relative to workspace root when there is no git repository', async () => { @@ -78,5 +134,7 @@ describe('normalizeCacheOptions', () => { const options = normalizeCacheOptions({}, workspaceRoot); expect(options.basePath).toBe(resolve(workspaceRoot, '.angular/cache')); + expect(options.localBasePath).toBe(resolve(workspaceRoot, '.angular/cache')); + expect(options.localPath).toBe(resolve(workspaceRoot, '.angular/cache', '0.0.0-PLACEHOLDER')); }); }); diff --git a/packages/angular/build/src/utils/purge-cache.ts b/packages/angular/build/src/utils/purge-cache.ts index 5851d052d54a..545d2dd97bba 100644 --- a/packages/angular/build/src/utils/purge-cache.ts +++ b/packages/angular/build/src/utils/purge-cache.ts @@ -19,25 +19,41 @@ export async function purgeStaleBuildCache(context: BuilderContext): Promise d.isDirectory()) - .map((d) => join(basePath, d.name)) - .filter((cachePath) => cachePath !== path) - .map((stalePath) => rm(stalePath, { force: true, recursive: true, maxRetries: 3 })); + for (const base of basePaths) { + let baseEntries; + try { + baseEntries = await readdir(base, { withFileTypes: true }); + } catch { + // No purging possible if base path does not exist or cannot otherwise be accessed + continue; + } + + const currentPath = base === localBasePath ? localPath : path; + if (!currentPath) { + // Avoid purging if current path is unavailable to prevent deleting the active cache + continue; + } - await Promise.allSettled(entriesToDelete); + const entriesToDelete = baseEntries + .filter((d) => d.isDirectory()) + .map((d) => join(base, d.name)) + .filter((cachePath) => cachePath !== currentPath) + .map((stalePath) => rm(stalePath, { force: true, recursive: true, maxRetries: 3 })); + + await Promise.allSettled(entriesToDelete); + } } From df0c46085a36642ec600010353e5fa2ce3befc29 Mon Sep 17 00:00:00 2001 From: Angular Robot Date: Tue, 1 Sep 2026 16:15:58 +0000 Subject: [PATCH 386/787] build: update cross-repo angular dependencies See associated pull request for more information. --- tests/e2e/ng-snapshot/package.json | 32 +++++++++++++++--------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/tests/e2e/ng-snapshot/package.json b/tests/e2e/ng-snapshot/package.json index 4cb1841981e4..b627e2364adf 100644 --- a/tests/e2e/ng-snapshot/package.json +++ b/tests/e2e/ng-snapshot/package.json @@ -2,21 +2,21 @@ "description": "snapshot versions of Angular for e2e testing", "private": true, "dependencies": { - "@angular/animations": "github:angular/animations-builds#5a17616799a04d2350bc04dbe75ae792f171ee88", - "@angular/cdk": "github:angular/cdk-builds#2e29d4c34e893b486a713f2cf6a08076f4cedcea", - "@angular/common": "github:angular/common-builds#9c9b546e71365ce9703f5dac3da1fd247ed04416", - "@angular/compiler": "github:angular/compiler-builds#8f6aa31135b34804f71ac9c5c8059d5f789be24c", - "@angular/compiler-cli": "github:angular/compiler-cli-builds#7f39ce1375237a8bc4c473a6ca1425c9183f2826", - "@angular/core": "github:angular/core-builds#3a3fcaf1499fc6050f29f75e4442dbcd2512cb43", - "@angular/forms": "github:angular/forms-builds#20542a5712b45bad559b1d32e61b85d3143532bb", - "@angular/language-service": "github:angular/language-service-builds#108c679c564ba9634779f2646de3ef291ca2fe83", - "@angular/localize": "github:angular/localize-builds#ae46c7df2563b7a9c1777fb49899645062251c4c", - "@angular/material": "github:angular/material-builds#f1ac90ea1312ab4b9fd6f9c5397700bbb5548da8", - "@angular/material-moment-adapter": "github:angular/material-moment-adapter-builds#129f7fe237ff52e6269585b363f18f282f5cfb59", - "@angular/platform-browser": "github:angular/platform-browser-builds#37d5b30e369848fea0431e55552b1724bc5da946", - "@angular/platform-browser-dynamic": "github:angular/platform-browser-dynamic-builds#47bb5f52770cc01a2f45745af5ec0f5fabf04d70", - "@angular/platform-server": "github:angular/platform-server-builds#eccecfd498b456758e98d27b5cd8210501003957", - "@angular/router": "github:angular/router-builds#0ef220c7125daf4880c6303e262a56be0b5fc361", - "@angular/service-worker": "github:angular/service-worker-builds#f62f2ab55d8eca69ddf55dc5efc55fb27c7ee35d" + "@angular/animations": "github:angular/animations-builds#fa4dc439ba3f3dc801f9dd4a08ff01a6455119d8", + "@angular/cdk": "github:angular/cdk-builds#6838b38bc85fba6d80d869339817eeac024e6d1c", + "@angular/common": "github:angular/common-builds#16e35729d950286366c72d5fc3f7254be25ab180", + "@angular/compiler": "github:angular/compiler-builds#89ffd7a672bb4e385e63af9d74d9668812c91feb", + "@angular/compiler-cli": "github:angular/compiler-cli-builds#c9acaa6a51a2548947be3c3c34f49d7f0e16b2ed", + "@angular/core": "github:angular/core-builds#52ed585b1ce1e20f4518d7c4d73911192dbd6041", + "@angular/forms": "github:angular/forms-builds#2e1ae03b48526092802894c2ea715346f381d61f", + "@angular/language-service": "github:angular/language-service-builds#49d60ace600aed18a7d04aff02f0a59b19ea4c3f", + "@angular/localize": "github:angular/localize-builds#275df390d82ec128bd5df775aa3866a43bd85563", + "@angular/material": "github:angular/material-builds#05cfaacabd1b609c6c9639c9ceb83b84e637df52", + "@angular/material-moment-adapter": "github:angular/material-moment-adapter-builds#9a87ef14ec11f09290b0d52ba8b4d07ed4c6a61a", + "@angular/platform-browser": "github:angular/platform-browser-builds#eace0b148f00e56f8ff3917350c0606ceac63843", + "@angular/platform-browser-dynamic": "github:angular/platform-browser-dynamic-builds#0326f34b7ec16be6b0085a82001530bff43de5c3", + "@angular/platform-server": "github:angular/platform-server-builds#52f6c590468ce3ce0cb0de9792628510e25ee2d1", + "@angular/router": "github:angular/router-builds#f9851d7220c8c45e676b33798ceec07320466d12", + "@angular/service-worker": "github:angular/service-worker-builds#b4509881af0aed420214e55b995f0fd8a0ca2c0d" } } From dfc933a396afae4b8a4ad0d6d2308e731f8ab245 Mon Sep 17 00:00:00 2001 From: Angular Robot Date: Tue, 1 Sep 2026 08:39:20 +0000 Subject: [PATCH 387/787] build: lock file maintenance See associated pull request for more information. --- MODULE.bazel.lock | 2 +- pnpm-lock.yaml | 938 ++++++++++++++++++++++------------------------ 2 files changed, 445 insertions(+), 495 deletions(-) diff --git a/MODULE.bazel.lock b/MODULE.bazel.lock index a4a953ee498c..dc1ef8ce7b84 100644 --- a/MODULE.bazel.lock +++ b/MODULE.bazel.lock @@ -454,7 +454,7 @@ "aspect_rules_jasmine": "2.0.4", "aspect_tools_telemetry": "0.5.1" }, - "last_notice": 1 + "last_notice": 2 } } }, diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 2338e1b07beb..dbe4ae62e56b 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -282,7 +282,7 @@ importers: version: 6.10.0(encoding@0.1.13)(supports-color@11.0.0) verdaccio-auth-memory: specifier: ^13.0.0 - version: 13.1.2(supports-color@11.0.0) + version: 13.1.3(supports-color@11.0.0) zone.js: specifier: ^0.16.0 version: 0.16.2 @@ -321,7 +321,7 @@ importers: version: 7.8.2 vitest: specifier: 4.1.11 - version: 4.1.11(@opentelemetry/api@1.9.1)(@types/node@22.20.1)(@vitest/coverage-v8@4.1.11)(esbuild@0.28.2)(jiti@2.7.0)(jsdom@30.0.1)(less@4.9.0(supports-color@11.0.0))(sass-embedded@1.103.1)(sass@1.103.1)(terser@5.50.0)(tsx@4.23.12)(yaml@2.9.0) + version: 4.1.11(@opentelemetry/api@1.9.1)(@types/node@22.20.1)(@vitest/coverage-v8@4.1.11)(esbuild@0.28.2)(jiti@2.7.0)(jsdom@30.0.1)(less@4.9.0(supports-color@11.0.0))(sass-embedded@1.103.1)(sass@1.103.1)(terser@5.51.2)(tsx@4.23.12)(yaml@2.9.0) packages/angular/build: dependencies: @@ -342,7 +342,7 @@ importers: version: 2.6.0 '@vitejs/plugin-basic-ssl': specifier: 2.3.0 - version: 2.3.0(vite@8.2.2(@types/node@22.20.1)(esbuild@0.28.2)(jiti@2.7.0)(less@4.9.0(supports-color@11.0.0))(sass-embedded@1.103.1)(sass@1.103.1)(terser@5.50.0)(tsx@4.23.12)(yaml@2.9.0)) + version: 2.3.0(vite@8.2.2(@types/node@22.20.1)(esbuild@0.28.2)(jiti@2.7.0)(less@4.9.0(supports-color@11.0.0))(sass-embedded@1.103.1)(sass@1.103.1)(terser@5.51.2)(tsx@4.23.12)(yaml@2.9.0)) beasties: specifier: 0.4.3 version: 0.4.3 @@ -402,7 +402,7 @@ importers: version: 0.2.17 vite: specifier: 8.2.2 - version: 8.2.2(@types/node@22.20.1)(esbuild@0.28.2)(jiti@2.7.0)(less@4.9.0(supports-color@11.0.0))(sass-embedded@1.103.1)(sass@1.103.1)(terser@5.50.0)(tsx@4.23.12)(yaml@2.9.0) + version: 8.2.2(@types/node@22.20.1)(esbuild@0.28.2)(jiti@2.7.0)(less@4.9.0(supports-color@11.0.0))(sass-embedded@1.103.1)(sass@1.103.1)(terser@5.51.2)(tsx@4.23.12)(yaml@2.9.0) xxhash-wasm: specifier: 1.1.0 version: 1.1.0 @@ -439,7 +439,7 @@ importers: version: 7.8.2 vitest: specifier: 4.1.11 - version: 4.1.11(@opentelemetry/api@1.9.1)(@types/node@22.20.1)(@vitest/coverage-v8@4.1.11)(esbuild@0.28.2)(jiti@2.7.0)(jsdom@30.0.1)(less@4.9.0(supports-color@11.0.0))(sass-embedded@1.103.1)(sass@1.103.1)(terser@5.50.0)(tsx@4.23.12)(yaml@2.9.0) + version: 4.1.11(@opentelemetry/api@1.9.1)(@types/node@22.20.1)(@vitest/coverage-v8@4.1.11)(esbuild@0.28.2)(jiti@2.7.0)(jsdom@30.0.1)(less@4.9.0(supports-color@11.0.0))(sass-embedded@1.103.1)(sass@1.103.1)(terser@5.51.2)(tsx@4.23.12)(yaml@2.9.0) optionalDependencies: lmdb: specifier: 3.5.6 @@ -1597,8 +1597,8 @@ packages: '@csstools/css-parser-algorithms': ^4.0.0 '@csstools/css-tokenizer': ^4.0.0 - '@csstools/css-color-parser@4.2.0': - resolution: {integrity: sha512-5+5LEmFuY1AjXdYhmgjTJogtQnP1evJ1zrBZGUNZ0thkpwnnmKxcHdAMn/OtFjAb25zA+jKDVYVRl+5G7rjv1A==} + '@csstools/css-color-parser@4.2.2': + resolution: {integrity: sha512-3QKjR/vxyjcSXBLgb6lP0S3MGdvwbmqSsvLPbYdVORqPDc8FX1HAJ0Spk38bxaRXgvENTA47tlhhbb5Z2e8hEg==} engines: {node: '>=20.19.0'} peerDependencies: '@csstools/css-parser-algorithms': ^4.0.0 @@ -1610,8 +1610,8 @@ packages: peerDependencies: '@csstools/css-tokenizer': ^4.0.0 - '@csstools/css-syntax-patches-for-csstree@1.1.8': - resolution: {integrity: sha512-CpMLjAvwQg3BL5S0IeqsZNMH7EQrEWi0kLKOC13ZBF0ZwERiLWlibNPJr8G1kdU3Ms/r2KiNrF81pUh2HwAHdg==} + '@csstools/css-syntax-patches-for-csstree@1.1.10': + resolution: {integrity: sha512-xBja6gaAaH2R2c7eNyl0TY4dhnnZ2uhj+KXpLdEQ6M/wuk9bYFZM8wY0ykw3VO4TgEJ56KGlerXS/9KBKVR/Cg==} peerDependencies: css-tree: ^3.2.1 peerDependenciesMeta: @@ -2160,15 +2160,6 @@ packages: resolution: {integrity: sha512-3eTuUO1vH2cZm2ZKHeQxnOqlTi9EfZDGgIe3BL3I4u+rJHocr9Fz86M4fjYABPvFnQG/gGK551HqDiIcETwU6Q==} engines: {node: '>=23.5.0 || ^22.13.0 || ^20.17.0'} - '@inquirer/checkbox@5.2.2': - resolution: {integrity: sha512-Y5/bAScMy5Y+9isCx0SKbyJebMCaXXX5em0kxkj115eZNscgV9srOHrgyfS0e5xAVymIfOh9piYBKDILktsMMg==} - engines: {node: '>=23.5.0 || ^22.13.0 || ^20.17.0'} - peerDependencies: - '@types/node': '>=18' - peerDependenciesMeta: - '@types/node': - optional: true - '@inquirer/checkbox@5.2.3': resolution: {integrity: sha512-XEYX2WA8SBkLPczL6/yXPHLPCvDoptmh9v56Cy05BSV1Smk1vWy19bTC4qJBuIffw7+6l4CcaYYzGqG60RfW1g==} engines: {node: '>=23.5.0 || ^22.13.0 || ^20.17.0'} @@ -2196,15 +2187,6 @@ packages: '@types/node': optional: true - '@inquirer/core@12.0.0': - resolution: {integrity: sha512-+nnvFEXIB08CZNVXpvW3B+zHW96QXvGUjNKJ8NJIPqAZi5Kd4WhYt2S3C234ReepG1qw2HOlEUbjYVHBowXObA==} - engines: {node: '>=23.5.0 || ^22.13.0 || ^20.17.0'} - peerDependencies: - '@types/node': '>=18' - peerDependenciesMeta: - '@types/node': - optional: true - '@inquirer/core@12.0.1': resolution: {integrity: sha512-JMD5Jy/ScL5TZE18m83Nw25HjqGFLoWXwnEkW7IdwwAhZpB9Bus55/WU7zn3UqR1MOCjjTQOIYpiD4vjWA3LPw==} engines: {node: '>=23.5.0 || ^22.13.0 || ^20.17.0'} @@ -2214,15 +2196,6 @@ packages: '@types/node': optional: true - '@inquirer/editor@5.3.0': - resolution: {integrity: sha512-nnsP/IdJ8s83q7ZuObmgn12QM+uLCkab9E0Oordojbn62WUg1c+v9Ou/F/057pgh0ppX0W+Hj5bO/Dp5hsxQtA==} - engines: {node: '>=23.5.0 || ^22.13.0 || ^20.17.0'} - peerDependencies: - '@types/node': '>=18' - peerDependenciesMeta: - '@types/node': - optional: true - '@inquirer/editor@5.3.1': resolution: {integrity: sha512-y43COoyVUjPWIobn2Qep/uI1drPS78aaZZZ9kVi94Tyu/GuW2N8d8Q4rifJXGAXCEAXCPTTMjD8gC1HyvM5ukA==} engines: {node: '>=23.5.0 || ^22.13.0 || ^20.17.0'} @@ -2232,15 +2205,6 @@ packages: '@types/node': optional: true - '@inquirer/expand@5.1.2': - resolution: {integrity: sha512-OWIH1IyyWqEKIyqC9Xy+Bnga7NkGMovFdo4atYZMUOTRqf6rO2WCv9E/1MyzvOErDBCxs+9UFliRUDc50xs/jw==} - engines: {node: '>=23.5.0 || ^22.13.0 || ^20.17.0'} - peerDependencies: - '@types/node': '>=18' - peerDependenciesMeta: - '@types/node': - optional: true - '@inquirer/expand@5.1.3': resolution: {integrity: sha512-3NQJiXNJ/aj9wiAsr7pECdp5Qe9J0X9YUJCKsaFXS+ddOxfL6J4AIl3w3T4Gq3kK0WsQY5GMoDokK5X94m6lHw==} engines: {node: '>=23.5.0 || ^22.13.0 || ^20.17.0'} @@ -2263,15 +2227,6 @@ packages: resolution: {integrity: sha512-tApbon79GM9ry56ja/Ud3SY2CL4TQsao9fIwDQbgTeNY55025GdMzQ2+UdegV/lx51VNGUB59M0v0nMpybYY4Q==} engines: {node: '>=23.5.0 || ^22.13.0 || ^20.17.0'} - '@inquirer/input@5.1.3': - resolution: {integrity: sha512-F/BZHtyEzP+HO+IGVd4AjBRgvX/ywm42bx8S0+dENk2YclzE9tJ3X/15THwtT6ehApmKvdYDMsVTuyyDod0gOQ==} - engines: {node: '>=23.5.0 || ^22.13.0 || ^20.17.0'} - peerDependencies: - '@types/node': '>=18' - peerDependenciesMeta: - '@types/node': - optional: true - '@inquirer/input@5.1.4': resolution: {integrity: sha512-3xQkQrOvgOzpSN2ciTVdRDlg1FWMCA8l+0KfB6SNlILoTCGzJTzO/gc0Rwjcb3usuGyKdaGtI6OiyMdeMeLWkg==} engines: {node: '>=23.5.0 || ^22.13.0 || ^20.17.0'} @@ -2281,15 +2236,6 @@ packages: '@types/node': optional: true - '@inquirer/number@4.2.0': - resolution: {integrity: sha512-ew+fSDijsQ/WhD4TV3XLb+if400cDuzTzHfGR8sTNBXkK9CYDWoGE8fhaO8GbT312pNv1AJEOsDxy/z/HVettA==} - engines: {node: '>=23.5.0 || ^22.13.0 || ^20.17.0'} - peerDependencies: - '@types/node': '>=18' - peerDependenciesMeta: - '@types/node': - optional: true - '@inquirer/number@4.2.1': resolution: {integrity: sha512-5KaqwZNLRpUuWcoCrYghPP9TMaXL5v2Sk4xqePM7RCVegcJStoXdWibio60YIC1bec+z1fCyb67N6XPJIkZtGA==} engines: {node: '>=23.5.0 || ^22.13.0 || ^20.17.0'} @@ -2299,15 +2245,6 @@ packages: '@types/node': optional: true - '@inquirer/password@5.1.2': - resolution: {integrity: sha512-nSdufycW8xynEVssFkNQEYIzTySilog0UlfOVRwh3pXzPSk4frXUT2jZWjHnKae6RU9PaoF9wfy1pGwewQuqGw==} - engines: {node: '>=23.5.0 || ^22.13.0 || ^20.17.0'} - peerDependencies: - '@types/node': '>=18' - peerDependenciesMeta: - '@types/node': - optional: true - '@inquirer/password@5.2.0': resolution: {integrity: sha512-CvVcW09emkBESEOW+4R8CjLNkP3fB3XrjeL8CDvfpjgrJN+V9oerXmJAXXM3l+4xqYPD5Yaujzy/Ph0PLOdDuA==} engines: {node: '>=23.5.0 || ^22.13.0 || ^20.17.0'} @@ -2335,15 +2272,6 @@ packages: '@types/node': optional: true - '@inquirer/rawlist@5.3.2': - resolution: {integrity: sha512-oPSKrYK1X1bMkjXDzIKHUkJp195LFSfgbnVtXnjSKGFjrCbS6I+wyvfAZTwKE9BSt3HwWgfD7JfsXALBgCogzQ==} - engines: {node: '>=23.5.0 || ^22.13.0 || ^20.17.0'} - peerDependencies: - '@types/node': '>=18' - peerDependenciesMeta: - '@types/node': - optional: true - '@inquirer/rawlist@5.3.3': resolution: {integrity: sha512-Mu7WrtmDLaXBDEyrRLS70SZgX9ZSm4Up1w0ZxiH8C1OOp9oaVCn2k8q3QGgmlnhsKYUhuaU3zFWhAP6wxkVIMA==} engines: {node: '>=23.5.0 || ^22.13.0 || ^20.17.0'} @@ -2353,15 +2281,6 @@ packages: '@types/node': optional: true - '@inquirer/search@4.3.0': - resolution: {integrity: sha512-HFxXE5w727ctSUcAwrDquftJGjMgu36OeV5SHEXMlr2j/ahzmRX9xSEeVolV8tzYnTf45cg6vGkdMMRdm3RPhQ==} - engines: {node: '>=23.5.0 || ^22.13.0 || ^20.17.0'} - peerDependencies: - '@types/node': '>=18' - peerDependenciesMeta: - '@types/node': - optional: true - '@inquirer/search@4.3.1': resolution: {integrity: sha512-0VWOvsHWI0rPj6CG70MoP4oXNCB6adcyN8bVFZXnh11eLDdPIK2f2XCmva78acPPDfJisfab7qNakwBh7hdBXw==} engines: {node: '>=23.5.0 || ^22.13.0 || ^20.17.0'} @@ -2371,15 +2290,6 @@ packages: '@types/node': optional: true - '@inquirer/select@5.2.2': - resolution: {integrity: sha512-RkI8dRHWt+bh04oLixvF1kFzKC7e5rqJoHKkzcqSHATebBXFC6GmrT8ddbVkgSzLV0HnHs2cPFuBINr8otij8Q==} - engines: {node: '>=23.5.0 || ^22.13.0 || ^20.17.0'} - peerDependencies: - '@types/node': '>=18' - peerDependenciesMeta: - '@types/node': - optional: true - '@inquirer/select@5.2.3': resolution: {integrity: sha512-KuRTodDa6xBXX2noIpjuitpX/QT7Sfav7dIZ/OfUY54Hxg95nrGoshSzxx6Ey7qqLbImKdiGkSDt7KjPXjQgmA==} engines: {node: '>=23.5.0 || ^22.13.0 || ^20.17.0'} @@ -2389,15 +2299,6 @@ packages: '@types/node': optional: true - '@inquirer/type@4.0.7': - resolution: {integrity: sha512-t28inv14nMQ1PhKpsJPY+kEs/c00qzeCOS2gTNRyTjG5d6qsVA2fItxW4hkvGZ5lvanGLdtCzVIx5dwdRpN1+g==} - engines: {node: '>=23.5.0 || ^22.13.0 || ^20.17.0'} - peerDependencies: - '@types/node': '>=18' - peerDependenciesMeta: - '@types/node': - optional: true - '@inquirer/type@4.1.0': resolution: {integrity: sha512-FMiJpuHUG3Dk0ex+UIXkre7i+i4OcwHWk9YdcVtZHFwb/r2rnrU2ipTCNAB7A+QOP0ryzIcqOfy76fRyyvOEAw==} engines: {node: '>=23.5.0 || ^22.13.0 || ^20.17.0'} @@ -2431,8 +2332,8 @@ packages: '@jridgewell/source-map@0.3.11': resolution: {integrity: sha512-ZMp1V8ZFcPG5dIWnQLr3NSI1MiCU7UETdS/A0G8V/XWHvJv3ZsFqutJn1Y5RPmAPX6F3BiE397OqveU/9NCuIA==} - '@jridgewell/sourcemap-codec@1.5.5': - resolution: {integrity: sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==} + '@jridgewell/sourcemap-codec@1.6.0': + resolution: {integrity: sha512-T7jf+5zgsZHwNJ4lvQ7/aezbyk0nNX+zJVWpmHA7VYsEx7a7qr5Rg5IbtJFqkgze5Y2sruq1RUY8Q837Od7iFw==} '@jridgewell/trace-mapping@0.3.31': resolution: {integrity: sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==} @@ -2476,50 +2377,50 @@ packages: peerDependencies: tslib: '2' - '@jsonjoy.com/fs-core@4.68.1': - resolution: {integrity: sha512-V5oZ4Gt9WJKyQef0n9cAd0N9qjSkIBm3E4MYsgNIWBk5aINCDPKxMPo1i29rBxqiT4Ixf1epklqV9VJMKIxwlw==} + '@jsonjoy.com/fs-core@4.68.2': + resolution: {integrity: sha512-PoBeUNEbjyLKKwCap2z8LkkqdhdfttS4rTHCALVuP65BdF+sAoyBqHo1m+uGTRBiQWv3H7MGfr8f7lY4pDwanw==} engines: {node: '>=10.0'} peerDependencies: tslib: '2' - '@jsonjoy.com/fs-fsa@4.68.1': - resolution: {integrity: sha512-HCG72UioncuO7Gw09XNVG+S85e3cq2hrUC/mexBrsWsa3mI7eePkkqWie3uVYbtsb64OR9YGQs5SqaufDRYBcg==} + '@jsonjoy.com/fs-fsa@4.68.2': + resolution: {integrity: sha512-h6eGXlLGGMyPfNliDQrbuHKTB9Z29ksCLjreAmdBqrDOBdfrTrHssi+b9WLfrF+J2KzAbIt9OMjJu6AEpTnYkg==} engines: {node: '>=10.0'} peerDependencies: tslib: '2' - '@jsonjoy.com/fs-node-builtins@4.68.1': - resolution: {integrity: sha512-HK1BTksysokNZxNspqDH0yPaqN9YgR/AYIlYiIaU2Ys4BOk5CdybI7r6BgiZuiiPiV8n4sK/kZdice7Znpy2Kw==} + '@jsonjoy.com/fs-node-builtins@4.68.2': + resolution: {integrity: sha512-V8WzQsW2YIrH3RxBGY6HZisxn+dDUltHgksVRuCdPEOXEkAfXuhL/01eHFrabNu84Dn13XuLqvcQUKOYVKAUOA==} engines: {node: '>=10.0'} peerDependencies: tslib: '2' - '@jsonjoy.com/fs-node-to-fsa@4.68.1': - resolution: {integrity: sha512-lpKmU4X9e/oh8GIuAI7EXaS5QiLNM3KD15CkdhfS6PYmrGvoJqKQcyEfnLgnnaGslh/PFUMYSIZBCf2ejJGw8g==} + '@jsonjoy.com/fs-node-to-fsa@4.68.2': + resolution: {integrity: sha512-4O1K4w5G4oJIpKpoa3WSLG83AsQYVnGv+aUSBGOvIUph9Axm6bB1mPlvldkNg2tBx/4dkiTlZnqNrK5SQ21Wtg==} engines: {node: '>=10.0'} peerDependencies: tslib: '2' - '@jsonjoy.com/fs-node-utils@4.68.1': - resolution: {integrity: sha512-/GxfW1DWm9SCdkfbvqevLO/P5duobQfmKkHXxdMIDbcZMQeAgooAstIfZhkXpATzq9QbCQsnoWFM/dGHdZfndw==} + '@jsonjoy.com/fs-node-utils@4.68.2': + resolution: {integrity: sha512-CxFwyG9fJr7dAKAd1uanNRNrRMtDDqbYJA8do53+M4LY7SxcBEEmMjC1zi9MOsBlVLHTXvA7OP9+n639UqtIcw==} engines: {node: '>=10.0'} peerDependencies: tslib: '2' - '@jsonjoy.com/fs-node@4.68.1': - resolution: {integrity: sha512-R5D9mWtqdURzcOWj1vdXr3APCwX0xchtFT+kmW7fXLNDifWdDrnh26jSID8pdnUfFBxTyfHtFtTL/NWKzIH7kQ==} + '@jsonjoy.com/fs-node@4.68.2': + resolution: {integrity: sha512-Kpj519Qk4OXG4+mZ8vTf9BEflliJrPueIDEVcbx8tAOufMJJ8IxR0WwdbcEvJol2KQog3PJjtALXVclorE+xbQ==} engines: {node: '>=10.0'} peerDependencies: tslib: '2' - '@jsonjoy.com/fs-print@4.68.1': - resolution: {integrity: sha512-oGeZOGPYKK9v1CgeVeEDsLomH1lCnslSpqUN5GmPzrmAVGQlsmsdcXNA2O4lV8Y4xkuSuynx2ITBkUHJVaTbow==} + '@jsonjoy.com/fs-print@4.68.2': + resolution: {integrity: sha512-cBABQmZJXig6bahwNka3+yPNGUF1GeMWbR76ZM1N2ajgCd+S+twZigCoe9+0ueZmkhM9xd2a7688Gy/ch7T+2w==} engines: {node: '>=10.0'} peerDependencies: tslib: '2' - '@jsonjoy.com/fs-snapshot@4.68.1': - resolution: {integrity: sha512-XZfP0FDZN32bbc4t2bZN2qRrYHg5AktJnzk22HRoKGK4BprrbNRH2k5ceSNS/kupKYcofCs+O841+xaAbjnxwQ==} + '@jsonjoy.com/fs-snapshot@4.68.2': + resolution: {integrity: sha512-Aix7+NM38LzvewM0T3PICSgFdF5BVCtVgsjNsrlDPGc9hiMgJzReTDDl2/elgl0A9USMl3QP27x5WwxZSOtrfw==} engines: {node: '>=10.0'} peerDependencies: tslib: '2' @@ -2794,12 +2695,12 @@ packages: resolution: {integrity: sha512-Pe3du5LrC6dlv10b0RbarBlJtIT1Urq8BFoQklK8WmBw8YKnGgrANn7cQmHiA1v8AVihgi7YutV8MncP57I4og==} engines: {node: '>= 20'} - '@octokit/auth-oauth-device@8.0.4': - resolution: {integrity: sha512-M/+34rmkxMvUnnTo/uqNeVRCXJoJ+5N34eNTbL1KMtIyJpedCTsu/iFL1cWdL+w5hQMlYt6xzXoyux2gn0OVnw==} + '@octokit/auth-oauth-device@8.0.5': + resolution: {integrity: sha512-kdJtjRhykMLJrMdcoC56XUBDfoUAuWEFKpkDxwYim+bNwYw1MreLolk+PLnwEYT8djm589YepeMuJ8+ECAIzVQ==} engines: {node: '>= 20'} - '@octokit/auth-oauth-user@6.0.3': - resolution: {integrity: sha512-t4OKUhrI5britmpRiSzPAz1TJPyUN/Hw1HEE3Hz/uElxcmnf/YCRSKtFRNc5gy4yJFTlXgk34H1lvxiotQJQvQ==} + '@octokit/auth-oauth-user@6.0.4': + resolution: {integrity: sha512-eya2pMJ9pCBq1jrm1Rf6J3NI+NemEpzDMLo9J/GpRoK0KgdxIVXWX4LESIfwJ+GYeoq6QFIlUJNi1lVp5FBgmw==} engines: {node: '>= 20'} '@octokit/auth-token@6.0.0': @@ -2810,8 +2711,8 @@ packages: resolution: {integrity: sha512-DcB0M3KFgr9ECI328lhBMVsyFT2DnmNucSBTqEN3exyNKUzkkpUSCHmTRcunF41Eou2TIQKW4seewri8ON9bSA==} engines: {node: '>= 20'} - '@octokit/endpoint@11.0.4': - resolution: {integrity: sha512-f1cOWoHPmxryJFknxbtDdjODWfV8A9tc8Aae6ermXPNgHFZ/x91AtHIz4gicEjL8hkJiip+u21QHJORfBv/qiA==} + '@octokit/endpoint@11.0.5': + resolution: {integrity: sha512-iXa654H3yFafF/ieHkukfbgWo2rmXD2ceD0ZOtrPhw1bc3FDch1d9N/TNs0FQ1/cIbwb7kspUX8jzIs8nzb9DQ==} engines: {node: '>= 20'} '@octokit/graphql-schema@15.26.1': @@ -2825,8 +2726,8 @@ packages: resolution: {integrity: sha512-7QoLPRh/ssEA/HuHBHdVdSgF8xNLz/Bc5m9fZkArJE5bb6NmVkDm3anKxXPmN1zh6b5WKZPRr3697xKT/yM3qQ==} engines: {node: '>= 20'} - '@octokit/oauth-methods@6.0.4': - resolution: {integrity: sha512-96RsnxS7Hk/BQhUA1Qo2pmcYP6LWQRWMdo7bVbNE7ZCkFLhSUYBXVUj9tVnvhl4jzbwHYt/dcIG+ioY427b2sg==} + '@octokit/oauth-methods@6.0.5': + resolution: {integrity: sha512-/mAz7taDZD7DcV4zcG6TDw3Kr6TOldmYBRpvA62C3WIxRMmcgX8XxsTvVQomqKE7VEk/BgYhUao1aR2tYGyIKg==} engines: {node: '>= 20'} '@octokit/openapi-types@27.0.0': @@ -2835,6 +2736,9 @@ packages: '@octokit/openapi-types@28.0.0': resolution: {integrity: sha512-0rFyLuyHvIj6uuZWuDslxkowFYdPXoNIkeAv4b27dzm2Tf4vGWXnPsMcxs7d65kLdMERgP3wc1AEPlqMz8e1cQ==} + '@octokit/openapi-types@29.0.1': + resolution: {integrity: sha512-9qWOMFNxxLokERcms42rU0PTLqQmVs7g5E41TI4mCOxmpFayD1rfC7XxOL55cG9MBZLFlC31BrR37myMKardwg==} + '@octokit/plugin-paginate-rest@14.0.0': resolution: {integrity: sha512-fNVRE7ufJiAA3XUrha2omTA39M6IXIc6GIZLvlbsm8QOQCYvpq/LkMNGyFlB1d8hTDzsAXa3OKtybdMAYsV/fw==} engines: {node: '>= 20'} @@ -2869,8 +2773,12 @@ packages: resolution: {integrity: sha512-+eaY7G2VVpSf2pc5Gn1+mph837V/d/TYTJAgWL9Tb0ogGYcpN3IlAVFgjL+Vv93F/sevrxkvsYCedtpLdcFLzA==} engines: {node: '>= 20'} - '@octokit/request@10.0.15': - resolution: {integrity: sha512-3CBg9aJ0hO9Pjyij8LbK/xYtEaPws9SW7xKz67daPNxQB1q5Y9OMA7DDOG0A6Hwf9ygGu3tvzusg0LXQ8/wAjA==} + '@octokit/request-error@7.1.2': + resolution: {integrity: sha512-XZRuT3xZ84D3gYErI1DZvhJ33dCWVV6uzBtWkaBB4TvA/L6eOeTZodxLFVB44bBEEo3vEx7y00UfX1tBLrtLRg==} + engines: {node: '>= 20'} + + '@octokit/request@10.0.16': + resolution: {integrity: sha512-A0zWGjHzISIb+9ccG8s0dq7LKO5zVpJLRICjgUb+sJxEWqn8RUHB1rD3AE51+PECvXHIxqZ1VVvs4fHTSD9nUQ==} engines: {node: '>= 20'} '@octokit/rest@22.0.1': @@ -2883,6 +2791,9 @@ packages: '@octokit/types@17.0.0': resolution: {integrity: sha512-ByP1v7YL5SMveFPP7+sj0/ZuWCOOg/Chs4NafOMpq6WNIM/hdGY0S7C0TCGDBWu1aGmOxmUIhMx3cO+IdwYZ1Q==} + '@octokit/types@18.0.0': + resolution: {integrity: sha512-l6bAF43PNxkJp6g+W4PjoUSSkxHomXw2nOum5CTftJz1NlV3vu93NImgOYtLf6CbBUb5j+fiuzW0PPQ5JTSvZA==} + '@open-draft/deferred-promise@2.2.0': resolution: {integrity: sha512-CecwLWx3rhxVQF6V4bAgPS5t+So2sTbPgAzafKkVizyi7tlwpcFpdFqq+wqF2OwNBmqFuu6tOyouTuxgpMfzmA==} @@ -3776,10 +3687,6 @@ packages: eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 typescript: '>=4.8.4 <6.1.0' - '@typescript-eslint/types@8.67.0': - resolution: {integrity: sha512-sBtgslww8nsMYUjhdPBiSyUqSzT8uR6g93A2QXnQC8+cGdjz0CyaOdqHDRJb1AtORbZCNUJBBeFA/tNR2uQmww==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@typescript-eslint/types@8.68.0': resolution: {integrity: sha512-9RnpsGJjrAllCMefGVVsImJM24YurhC0Q1h4UbvivtvOqXmR/vEJge2OoE++z9m6hyg8T1Q8t5SNT6tHSbrxcg==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} @@ -3813,6 +3720,10 @@ packages: resolution: {integrity: sha512-BSCCR5cFkepjL3HnosKUi6aRezwgHu1FihFtes63yxIiDXkMclVi5IekTH6SCeW/7MO1Uyp58kh1updbB6VW4w==} engines: {node: '>=22'} + '@verdaccio/core@8.3.0': + resolution: {integrity: sha512-axlsbrXnENRM1+VeTNbTrR0VOD+9pBxA8sN+41rpt9UfThIQhDgf89YPPlCfu/ks/LH1KTcSzhR7nZuDYypeCw==} + engines: {node: '>=22'} + '@verdaccio/file-locking@13.1.0': resolution: {integrity: sha512-rGFfdyCZdgpbkROJJfjOA01R5BFtzrnDAhNIkxxc/yWZ6Cir+MRHpEbN2weOEPAwYDke9Wms4JKhpsStu+iV8Q==} engines: {node: '>=22'} @@ -3978,140 +3889,140 @@ packages: '@yarnpkg/lockfile@1.1.0': resolution: {integrity: sha512-GpSwvyXOcOOlV70vbnzjj4fW5xW/FdUF6nQEt1ENy7m4ZCczi1+/buVUPAqmGfqznsORNFzUMjctTIp8a9tuCQ==} - '@yuku-codegen/binding-android-arm64@0.8.7': - resolution: {integrity: sha512-C/0zV5IhgVdYhGJTwrY0v8dknxlhiKwtVJkMUaexu9/QvRmzlV4vfU3hZlUSgqc2BxQHntL1mCVbDq8j0FRFDw==} + '@yuku-codegen/binding-android-arm64@0.9.3': + resolution: {integrity: sha512-viote6xAyL5cKLquV2X2wRfopSckH+msDYbaI8Hh8JAaogYs8MJZVRUbSrbsY29TaPrIFZwNRwQ8+YSxs0dkGw==} cpu: [arm64] os: [android] - '@yuku-codegen/binding-darwin-arm64@0.8.7': - resolution: {integrity: sha512-/u+REDMI4a0/lsJXTM4c53/w31OGZLOReZIyg62uhgLs0kc8NHsj/nOcxTdlQjq5gi0zhdkccD9LaLTXcdzPvw==} + '@yuku-codegen/binding-darwin-arm64@0.9.3': + resolution: {integrity: sha512-y2PGOLyxc724EJ+Et/5PxGfutQuV1Z2J9cxHo6W1I5CR3nk0i03J4yPrnw6rNJOfrtlISzcc7q0RrSyfPndpIg==} cpu: [arm64] os: [darwin] - '@yuku-codegen/binding-darwin-x64@0.8.7': - resolution: {integrity: sha512-sMMzFOwCo4WXR+/6zIBThOocSC50iIIZZdfiIDbaLvj0Ax/rWt/iavyfEAqajyvzydLyCqR/ZItdLWSRlu1umw==} + '@yuku-codegen/binding-darwin-x64@0.9.3': + resolution: {integrity: sha512-xZ9UpXUOLmsrKVUp7MRXxWU3drNiilRC42OLpjWEhnOehIGVF1bZgzHcqRYJxVyU53RMrkRMsaxplkGd6Qo/ow==} cpu: [x64] os: [darwin] - '@yuku-codegen/binding-freebsd-x64@0.8.7': - resolution: {integrity: sha512-MpdpKXix9P+Y1rKgjvcNeNtGjXeL1CmttNhYINrWls8kRpm4xM/oBGTmn6w7to8lAlwj5jm8q03dQPl5mRv4Qw==} + '@yuku-codegen/binding-freebsd-x64@0.9.3': + resolution: {integrity: sha512-RGCYSZw3VonreVTpur9iOfnbMngR2/f7UOE7gwcDx5WoHjIhtmTK9EIq9qs78ARdMFAPzKp5OzHljl5QMaGJ7g==} cpu: [x64] os: [freebsd] - '@yuku-codegen/binding-linux-arm-gnu@0.8.7': - resolution: {integrity: sha512-rr1srFLlPAmC1vtxfc9C1YLDe3iH09YjfSeeIidBqKhzx1MATjOAq4mjlRUOnhr/L27MotWIYOFKwVsd5JZFOg==} + '@yuku-codegen/binding-linux-arm-gnu@0.9.3': + resolution: {integrity: sha512-kjIJIw39GSPTF0hnq+jnM0tR+J5WlariAAWetxMtawNskITDT1ZigaK3YF5hMhDz2mAofaM1t+63qtx+7aXjeg==} cpu: [arm] os: [linux] libc: [glibc] - '@yuku-codegen/binding-linux-arm-musl@0.8.7': - resolution: {integrity: sha512-eAufXh8qBRpiSO6ueaMDL+yyoXIGLhpUce72YbcACtZU2qhExwBIJyEtQf5kH2Ki0X2aqkSjSfog4OPtKXan3Q==} + '@yuku-codegen/binding-linux-arm-musl@0.9.3': + resolution: {integrity: sha512-TVHeVdzaS4ub86URrQufiy4t01ZtdyKDZ5sTPqWFKAUbQJ7rQ0o5vIT+/jCeHQbP+Yf9p5peRdmPbcZewoDNiA==} cpu: [arm] os: [linux] libc: [musl] - '@yuku-codegen/binding-linux-arm64-gnu@0.8.7': - resolution: {integrity: sha512-gw4w6wPoHObBrdIC4duVWLmJOvpdE25j5D7yrM5mACNlK4klRz/lv8hK+ssQk9EJHBgZjSaqZIJVFgqNYbfv7A==} + '@yuku-codegen/binding-linux-arm64-gnu@0.9.3': + resolution: {integrity: sha512-9aQeeLh1qaCa2GcyzHnwLKGfFrsI+KOyhnh4+fICSq5kyhzCWQfXVCCK4RTEZPLcyuVwfN5Id0JEYavRN4oNTQ==} cpu: [arm64] os: [linux] libc: [glibc] - '@yuku-codegen/binding-linux-arm64-musl@0.8.7': - resolution: {integrity: sha512-L68N6Y4XkqcIaKo3Ra88JEvBEH4AHff44A4INcrxeVWZ8CZtu2tCpfVxe3hR8qQQMcvBSQlDn24KpkCKEhVvfA==} + '@yuku-codegen/binding-linux-arm64-musl@0.9.3': + resolution: {integrity: sha512-TLXA5Hd1nr8VSP2MtxcFddsBIHj+DPpyG5eberEGMATndgG7STlKQmle51MV0MZ8UgsdYM6CybIVpzlCPQwP9w==} cpu: [arm64] os: [linux] libc: [musl] - '@yuku-codegen/binding-linux-x64-gnu@0.8.7': - resolution: {integrity: sha512-dzyAbltJmf3Cqlb8HcFuYIf5Yn0fl1vTr3XJ9HiVNNvOlhqPSArOqtw9vI1p6/VTXTjrMLXlU+s+/kNHiIy/Cw==} + '@yuku-codegen/binding-linux-x64-gnu@0.9.3': + resolution: {integrity: sha512-tk0BFbF3Clb9k9biPH3qmr+Qwk24rRM26+HY91hYXmZlzlepZG0scQ6OffZFWtzwKE5JjlZpMdcWj1lTiHbEjA==} cpu: [x64] os: [linux] libc: [glibc] - '@yuku-codegen/binding-linux-x64-musl@0.8.7': - resolution: {integrity: sha512-Otw4MH3404q0Bbvl+YTdW9aoUV5vXmUw8260bWvt1XlaoIX/ceSgI4ygheRDMfBPoHt6FDayQaO9OLVUZAgkFA==} + '@yuku-codegen/binding-linux-x64-musl@0.9.3': + resolution: {integrity: sha512-xo+pXshsCXruEEkDMbwHqkeTyC4XHb6A6oXr6x2YK3jOMcS5kZz0e26BmTCr40J0nY/K3ysmwG9R1xHygtiuwQ==} cpu: [x64] os: [linux] libc: [musl] - '@yuku-codegen/binding-win32-arm64@0.8.7': - resolution: {integrity: sha512-qo/jyrzryiBuKEsFiuWaBCBe3tRMynQ0qFWFgOEjcCMQeZfBm+wKiVEUEFXXLc7bh8YezguAWp0Mtnhq4ARNyA==} + '@yuku-codegen/binding-win32-arm64@0.9.3': + resolution: {integrity: sha512-70gAQo6HZzMgIJTjeMZOEO2XaRj4GcNGP/n81R9tXQv0x8d4ZHnZDv+ygeWfHo+xchAUPwpnrVZA4p6RhJa3GQ==} cpu: [arm64] os: [win32] - '@yuku-codegen/binding-win32-x64@0.8.7': - resolution: {integrity: sha512-D5lDsVDx6m00E6bWySlWdH72Ca4TPSaphDqB6QjU6MpuNLIJqoGoatYyq2rOmBE8Zv/kunot/o58KGL03P3eiA==} + '@yuku-codegen/binding-win32-x64@0.9.3': + resolution: {integrity: sha512-7Hz3NGlq6qBBR8zMEk6GMZivofNjnYZpMXSoUwUgz9Ur2LaivuP23HQh0ern+T6HVkTJEvilw4VJrg1rX1Ugcg==} cpu: [x64] os: [win32] - '@yuku-parser/binding-android-arm64@0.8.7': - resolution: {integrity: sha512-eGKYiUDX7Y0V7tDTmg+JTVnXnjMqfXXsorZ+EDf5kxwchQ3Or1HS14MzI2fw+jFhHR85fCWt+mtX33Yao73hIQ==} + '@yuku-parser/binding-android-arm64@0.9.3': + resolution: {integrity: sha512-z3tDGTaUXD5Q4IuebFOY/QHxhR/SqujMhkMv9C5bh25upyFEXdafp0MsXQIIheWhVZzn5VMOniyxFni/7s9LgQ==} cpu: [arm64] os: [android] - '@yuku-parser/binding-darwin-arm64@0.8.7': - resolution: {integrity: sha512-Re0RHelKLnjEURulY2/KxW+Ngb8zuNA4BRZuMwgGQNzVumT6u4U2N2hc01oeYVNVof0i7GrXE4UCNBgbpRRnjQ==} + '@yuku-parser/binding-darwin-arm64@0.9.3': + resolution: {integrity: sha512-hzKvKSKS7z3ufnu1VkQYEoxmS6A5uNnkwukKnc2atxpWdq648nLVOqut4h1jUXjbM2WcoTfuZLF6AHAGFf8cmg==} cpu: [arm64] os: [darwin] - '@yuku-parser/binding-darwin-x64@0.8.7': - resolution: {integrity: sha512-Hn8DROtQkjlA1ACbPgj4a7eP9IuVOI504oiTwpkWPbpaDWD9KdmnVYCqW+1LfenNK/g7O9NhWGpXEdaCNX7lIA==} + '@yuku-parser/binding-darwin-x64@0.9.3': + resolution: {integrity: sha512-OM2PiVlPATvzlj/KGHNlu+t8FC3YzM5joVNjhsz/EaigQ8x2UUQ1Q0agQLiv5GZ2L8TSzrLUwBCZ7YOvP8q+tw==} cpu: [x64] os: [darwin] - '@yuku-parser/binding-freebsd-x64@0.8.7': - resolution: {integrity: sha512-bAP2OV8wRuzplX/jYxv9+vvqQT8JxyNphI8fLfXGL054Xs+4/J5u33cIm3y4rxY8rdoLmmdiJs2Tq7r7lrDRfA==} + '@yuku-parser/binding-freebsd-x64@0.9.3': + resolution: {integrity: sha512-WMn9M4LHNVysGNwsAJ9gpRPqQIW2lcPrDNGcyk0agx3IYqCJq1MQugh6Be8Otc5U08eGdE39o8Kx9YWJmXz7GA==} cpu: [x64] os: [freebsd] - '@yuku-parser/binding-linux-arm-gnu@0.8.7': - resolution: {integrity: sha512-kTYwJQQgmZeAWdDIWabiReIZMpmfLueIj1tCmjStUtFGhR1Z0qwxonKVfUC4N7h/VhGGzLZ//7O1kgt1QKqgCg==} + '@yuku-parser/binding-linux-arm-gnu@0.9.3': + resolution: {integrity: sha512-vqKjwiyW1FWvbykYMEQIcAJwA17WxK3rxxqDuyCvQwcNVaLEUxI4BXiUdlF3kHucc7MnoFQhoRPkySgOzlLM+Q==} cpu: [arm] os: [linux] libc: [glibc] - '@yuku-parser/binding-linux-arm-musl@0.8.7': - resolution: {integrity: sha512-uL4jE8HPT2BLlxAXyD10LqgPuXa9eDa0BKpCdSANmzIJghq/2eZo3/gQNtaxPZMupWoxjYzSad9IXrwu7aYPXQ==} + '@yuku-parser/binding-linux-arm-musl@0.9.3': + resolution: {integrity: sha512-qohilhYOT+zkt2gYzym4F1T6BzRdvPqS9/sFB03pmnVV8LrvjOXVsGwEBAa3CEvzJKhAZjdTmVz7zsVdjyHWLg==} cpu: [arm] os: [linux] libc: [musl] - '@yuku-parser/binding-linux-arm64-gnu@0.8.7': - resolution: {integrity: sha512-3gVN4pWSKZmXiNX7cU164dR9MPvesCHnlH6nPfpK+yQsCuYphjKKplcb4SnZBrhiqmXbgb2HR0c2TS0IZUPhgA==} + '@yuku-parser/binding-linux-arm64-gnu@0.9.3': + resolution: {integrity: sha512-tvTIyUvTGkeee68i4JIo9o27As+Ug6LXOZvElGgFbTs6+KBdb5LGhvugaIQljdfIsm2XnIbOLG6OnQSXHMLB9w==} cpu: [arm64] os: [linux] libc: [glibc] - '@yuku-parser/binding-linux-arm64-musl@0.8.7': - resolution: {integrity: sha512-S0mwfEjoLpxzXeZw802Wa4RaELsQiPtWqG6INcy8j4GtvNFtl4LCX3eGO1XLn9pyLAISLzTRyU3zUCBUPin8lg==} + '@yuku-parser/binding-linux-arm64-musl@0.9.3': + resolution: {integrity: sha512-OWZBHW1wuChBpFlrF+On1yiBcFPMRrj2g0VKsM/PCBGffu1OM0ORkS+vLS3Snu6wYwndM5Dd9Ctvux6eUlrQjA==} cpu: [arm64] os: [linux] libc: [musl] - '@yuku-parser/binding-linux-x64-gnu@0.8.7': - resolution: {integrity: sha512-lnbWdPmerE5D1uH1G4IEZKnPzCrWCStRGrtgpSIe1RibAo5bZIjDbbbPYXmMHCEh4F+x/JaJpElh26a3r+BPbg==} + '@yuku-parser/binding-linux-x64-gnu@0.9.3': + resolution: {integrity: sha512-/tbk1h0dlADOCngbiQO9V3SHwBIJkoGBq8BDEraSw2CC3nGxPEPTCCYUDp5738Ij2FxVwy1FWVuhFkHvpMrPbQ==} cpu: [x64] os: [linux] libc: [glibc] - '@yuku-parser/binding-linux-x64-musl@0.8.7': - resolution: {integrity: sha512-769uwndMvMzUvATWbAcEvyLHKA+DzhHSCl/obBUrRdYfRo26yxui6S8y3z7uJ+Naup7UKrDxrpK7OnQkxkl9KQ==} + '@yuku-parser/binding-linux-x64-musl@0.9.3': + resolution: {integrity: sha512-u3+0sCso/mcjDvtc3866D2giV7l34PDyDVBkMesAWa3DWbIWPlybehi2SSnmScgArV22ctqSSgUzdBBVJ6zYAg==} cpu: [x64] os: [linux] libc: [musl] - '@yuku-parser/binding-win32-arm64@0.8.7': - resolution: {integrity: sha512-mEB/9PlaAkisJ6KWGz0zvywXoU6+80dTlR2LwS7s/jcXXoU6fm2+sitBZXtqu3+Q4DcDgPxM45uWMCzPs0TSRw==} + '@yuku-parser/binding-win32-arm64@0.9.3': + resolution: {integrity: sha512-xnGEvdhyjRkXozHtpXVpEEkyGZWAxJ3RoILv7XRV5SvTEztaTCk5GQyfcOzI9An/EJtcL4ERCI8QmS0TpDPJiA==} cpu: [arm64] os: [win32] - '@yuku-parser/binding-win32-x64@0.8.7': - resolution: {integrity: sha512-8vNB2DP0ou61nGb8tc/qfi41gfyDXz1MHr2zqL3nR+cJ6CEbiuWV/l/a/vv151gCgiZLLAyGkQGENpozdg716w==} + '@yuku-parser/binding-win32-x64@0.9.3': + resolution: {integrity: sha512-N5eShGcuwnrXEprePFmEjtng6acZmtnC4zgazK9xxkavcx1q1uX8Nz8lU5RS973EMlNr902cIc6Cd2D4tqZDBg==} cpu: [x64] os: [win32] - '@yuku-toolchain/types@0.8.7': - resolution: {integrity: sha512-2Z53dNxAJL6UvFoIrDZvYf3zlO8s4VJK4O2hhaB4mXVwwpX/7ajtss3cmfqKvamlNLWyt9FSWs4eoYdlbxpnHA==} + '@yuku-toolchain/types@0.9.3': + resolution: {integrity: sha512-rFE+5P4g2wxko5C85MugJOlVjBHEQq87dIkhLkniLXLp63PEtgaFjD954i5HXlfnyzLxPcZHsSOVDVgmo1HToA==} JSONStream@1.3.5: resolution: {integrity: sha512-E+iruNOY8VV9s4JEbe1aNEm6MiszPRr/UfcHMz0TQh1BXSxHK+ASV1R6W4HpjBhSeS+54PIsAMCBmwD06LLsqQ==} @@ -4354,16 +4265,16 @@ packages: resolution: {integrity: sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA==} engines: {node: 18 || 20 || >=22} - bare-events@2.9.1: - resolution: {integrity: sha512-Z0oHEHAFDZkffN8Qc39zNZjQlMDkPJRyyyZieU1VH7u8c5S+qHZ2S8ixdKIAxEjfHO7FJxXmJWgteOghVanIsg==} + bare-events@2.9.2: + resolution: {integrity: sha512-AIPKioV7/Y/8KfZ3AAhjPJxLLbY49S64Ym5DakZlUg75qQiTgUq9hEJoEwa4eUezPUlXRy/i5NpsKvo9jgKmoA==} peerDependencies: bare-abort-controller: '*' peerDependenciesMeta: bare-abort-controller: optional: true - bare-fs@4.8.0: - resolution: {integrity: sha512-fM+MhCvdQhZ7NV6S95a07gPSqjIYKn6mFaXfx266wN3ajZGl/+1AzH+ubkXQ0fFZvOe2nk9VHkzdYkQE5zMV3Q==} + bare-fs@4.8.1: + resolution: {integrity: sha512-N1nnXdHZAOSstz0XiHikGS4HGMH4CnSwhqWdGQQMqqdvp4Jybm9sE3R1WVnpWVd4SFkc8ryPDBLViNLwiEqECg==} engines: {bare: '>=1.28.0'} peerDependencies: bare-buffer: '*' @@ -4374,8 +4285,8 @@ packages: bare-path@3.1.1: resolution: {integrity: sha512-JprUlveX3QjApC1cTpsUOiscADftCGVWkzitbHsRqv84hzYwYHw2mbluddsq5TvI8mH/8Ov1f4BiMAdcB0oYnQ==} - bare-stream@2.13.3: - resolution: {integrity: sha512-Kc+brLqvEqGkjyfiwJmImAOqLZL7OsoLKuavx+hJjgVV3nLTOjloJyPMFxjUPerGGHrNH0fLU06jjykMLWrERQ==} + bare-stream@2.13.4: + resolution: {integrity: sha512-PcrQ8lVLbiJscNm1Kez+Yp4Gy4AHGcN1lzwjvf5NybWen7VvEgUfyfnXYJ2zNqWnzOfCb1Abq6lH8ti0syQszA==} peerDependencies: bare-abort-controller: '*' bare-buffer: '*' @@ -4398,8 +4309,8 @@ packages: resolution: {integrity: sha512-lGe34o6EHj9y3Kts9R4ZYs/Gr+6N7MCaMlIFA3F1R2O5/m7K06AxfSeO5530PEERE6/WyEg3lsuyw4GHlPZHog==} engines: {node: ^4.5.0 || >= 5.9} - baseline-browser-mapping@2.11.18: - resolution: {integrity: sha512-1iEmLEYSiE1SeBoAfPo/Mnx3PzfzHUkDK61ASkCpuk3YXugYLH5DYK1SzqV55F8FMI6s0F+/tCP7Polz1QRjxw==} + baseline-browser-mapping@2.11.20: + resolution: {integrity: sha512-H0ulySigv6icDJ1F7SjtdCD6PrhTpdYCmP0CactWy1+ekh0AFd0o1Wn5T8b+hnTmdBx19u9yhL6wvCylXMY7zw==} engines: {node: '>=6.0.0'} hasBin: true @@ -4542,8 +4453,8 @@ packages: resolution: {integrity: sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==} engines: {node: '>=6'} - caniuse-lite@1.0.30001809: - resolution: {integrity: sha512-xxWVywk6a6Arlk+hymeycyn/VgqEfLDxupvhH/xiY5SJ/18kmi9o6MiO320DCUzypORHLtvh0I4i04tUhCNHNQ==} + caniuse-lite@1.0.30001810: + resolution: {integrity: sha512-TITQPUkaz+aVk5GL6NhOdwk1aEaNTSDPsGFWrTuhKGtjTF70jL/Oht2W4c6rXUe5fu7Ie19VIahAXHIIiWWNeg==} caseless@0.12.0: resolution: {integrity: sha512-4tYFyifaFfGacoiObjJegolkwSU4xQNGbVgUiNYVUxbQ2x2lUsFvY4hVgVzGiIe6WLOPqycWXA40l+PWsxthUw==} @@ -5017,8 +4928,8 @@ packages: engines: {node: '>=0.12.18'} hasBin: true - electron-to-chromium@1.5.412: - resolution: {integrity: sha512-z4rMe3esBzlzovKHj4gxJnsCGZRK5l4baUvm+gCGJBPE+gsyUMKsuU9tnEUtI1dOebXz1ytAPGjvXhmQ7rIPwA==} + electron-to-chromium@1.5.417: + resolution: {integrity: sha512-4T+DTDWuMPM4aHlHwWdAVCVWwp7LDilnhzkj+c/Lbj91XSQrLuOmZSLtS9Q4iIqjlPUbPOnC624zDVVHCHaolQ==} emoji-regex@10.6.0: resolution: {integrity: sha512-toUI84YS5YmxW219erniWD0CIVOo46xGKColeNQRgOzDorgBi1v4D71/OFzgD9GO2UGKIv1C3Sp8DAn0+j5w7A==} @@ -5333,8 +5244,8 @@ packages: fast-wrap-ansi@0.2.2: resolution: {integrity: sha512-7F2Fl+TjRSenLqlU3UjSH0iyqopqoZIu7eZVpEirP2g1GtWa2G/ecEmBdgz31+Mxr+ELclgg6sokpSFIQiZ02Q==} - fastq@1.20.1: - resolution: {integrity: sha512-GGToxJ/w1x32s/D2EKND7kTil4n8OVk/9mycTc4VDza13lOvpUZTGX3mFSCtV9ksdGBVzvsyAVLM6mHFThxXxw==} + fastq@1.20.3: + resolution: {integrity: sha512-XKv5nnLs6nLF71NgiKJLIZFLkPyIEuOselLG7ujZnGrRfQK8HpvY+WqKhAJUAdLomwVHErVS4LfxFlPq0/FTAw==} faye-websocket@0.11.4: resolution: {integrity: sha512-CzbClwlXAuiRQAlUyfqPgvPoNKTckTPGfwZV4ZdAhVcP2lh9KUxJg2b5GkE7XbjKQ3YJnQ9z6D9ntLAlB+tP8g==} @@ -5532,8 +5443,8 @@ packages: resolution: {integrity: sha512-w9UMqWwJxHNOvoNzSJ2oPF5wvYcvP7jUvYzhp67yEhTi17ZDBBC1z9pTdGuzjD+EFIqLSYRweZjqfiPzQ06Ebg==} engines: {node: '>= 0.4'} - get-tsconfig@5.0.0-beta.5: - resolution: {integrity: sha512-/6gFNr0N04nob252sTQxyFLi3eKFRqIg1I87YcqAMT1i6SQrSF6KujUEQrtrjMV0H/eejTCltLdDSTEMzHbnsQ==} + get-tsconfig@5.0.0-beta.6: + resolution: {integrity: sha512-X6fBC0pmImC70gvX2zm56go9hx0MyoGVdG0tUCkg/D+Xnh5TJsOZ7iDbOdI3PvmtrDxnu1YdDufpK2QJX1Meqw==} engines: {node: '>=20.20.0'} getpass@0.1.7: @@ -5769,8 +5680,8 @@ packages: resolution: {integrity: sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==} engines: {node: '>= 4'} - ignore@7.0.6: - resolution: {integrity: sha512-BAg6QkE8W+TuQLrrw0Ugr7HegXduRuuj8/ti2kSOc+jz1dmx8/WNcjr6XGnq5YpDWxFwwaavqD0+jIUOKelTsw==} + ignore@7.0.7: + resolution: {integrity: sha512-dML0wP6oak21rsNYCJpJB6O1BJIEwNpGrTw0URPfAk4hm0e3pRfCtzkfB6olBcXcVlU2rouCyz7lCyRB0OMVCA==} engines: {node: '>= 4'} immutable@3.8.4: @@ -6104,8 +6015,8 @@ packages: js-tokens@4.0.0: resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==} - js-yaml@4.3.1: - resolution: {integrity: sha512-CY6crGq313MX8GkwvB7tzgp99vjQxY1++5y10/BKN/GUfHqWaOGQMNZkBvqSzsZKWk/ijwHlWzzkLulsGHhjWQ==} + js-yaml@4.3.2: + resolution: {integrity: sha512-SFNOvSJ+Dgf/9An904Yx+CgSlIPCkIpao4qo51lpee25TIRejdH3rhR4EZMGoNx3/TP3O+wzWuiTFl4sqbltzA==} hasBin: true js-yaml@5.2.2: @@ -6482,8 +6393,8 @@ packages: resolution: {integrity: sha512-yz3xRaG20c6/BOzvYoDaGtPmGscs7YivItZEEqe6GbwNfHuxu9YNmvnEkMzKldAGY4/80pRcQRZSEnhquk9XuQ==} engines: {node: '>= 0.8'} - memfs@4.68.1: - resolution: {integrity: sha512-OD+IDRUvIxu3QHL+nFm9gdyugInD27FDJ+sl4B5QgomPHXMlbw+GP918P8VNKu2FkNlVeqBkpzkwROpamVifRw==} + memfs@4.68.2: + resolution: {integrity: sha512-Un1ElEBoIdPI9kg0sm3LebVEuEViodfIvlaG8Z1MFXa7ZnR9vWuPKUo3dt/vuWY2ivc05l76B5QOjdgCzAzmGw==} merge-descriptors@1.0.3: resolution: {integrity: sha512-gaNvAS7TZ897/rVaZ0nMtAyxNyi/pdbjbAwUpFQpN70GqnVfOiXpeUUMKRBmzXaSQ8DdTX4/0ms62r2K+hE6mQ==} @@ -6570,8 +6481,8 @@ packages: minimist@1.2.8: resolution: {integrity: sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==} - minimizer-webpack-plugin@5.6.1: - resolution: {integrity: sha512-DoeAZz8Q1C1znwsUzej1fdoi4jCf7/+Em27ouLqfK/+3m8G+D7yDhUwrc3CNhjSzGUN1kn7Iv4sWmjflQHenpw==} + minimizer-webpack-plugin@5.8.0: + resolution: {integrity: sha512-2cT9+goJfBhtMz+gJqejSf09ClgmYhPhccRb/fb0ztVbixt0BkO8mRuI26FoPPuUNkRk6iEDryWAIouc5W8eJA==} engines: {node: '>= 10.13.0'} peerDependencies: '@minify-html/node': '*' @@ -6754,8 +6665,8 @@ packages: resolution: {integrity: sha512-LA4ZjwlnUblHVgq0oBF3Jl/6h/Nvs5fzBLwdEF4nuxnFdsfajde4WfxtJr3CaiH+F6ewcIB/q4jQ4UzPyid+CQ==} hasBin: true - node-releases@2.0.53: - resolution: {integrity: sha512-D9UOmYG3UH1V+ENW56t5QXBwJw1YEY18ruVeus89Rw+SyIgjPkCO84bRzO3uNIYosJbNwiabWVn48o3uJLjxFQ==} + node-releases@2.0.54: + resolution: {integrity: sha512-YHs7BmmcsdAI5Ozuf8JZo6PT0mv2GIWC9vMfvUC3dp65M8hn7Ux8CPL+2oBI7juNuj9d0ndhTcznq2ODBps9cQ==} engines: {node: '>=18'} normalize-path@3.0.0: @@ -7083,8 +6994,8 @@ packages: resolution: {integrity: sha512-dM0jVuXJPsDN6DvRpea484tCUaMiXWjuCn++HGTqUWzGDjv5tZkEZldAJ/UMlqRYGFrD/etByo4/xOuC/snX2A==} engines: {node: '>=20'} - powershell-utils@0.2.0: - resolution: {integrity: sha512-ZlsFlG7MtSFCoc5xreOvBAozCJ6Pf06opgJjh9ONEv418xpZSAzNjstD36C6+JwOnfSqOW/9uDkqKjezTdxZhw==} + powershell-utils@0.2.1: + resolution: {integrity: sha512-C+y9x90UElAddDZmV4qOx9W53B61PO7cIqWz2dQsWlwswuq4mr8NEwytdGKboYbQlGZ3awrkTeNvcZiZNHnQ8A==} engines: {node: '>=20'} prelude-ls@1.2.1: @@ -7124,8 +7035,8 @@ packages: resolution: {integrity: sha512-E1sbAYg3aEbXrq0n1ojJkRHQJGE1kaE/O6GLA94y8rnJBfgvOPTOd1b9hOceQK1FFZI9qMh1vBERCyO2ifubcw==} engines: {node: '>=18'} - protobufjs@7.6.5: - resolution: {integrity: sha512-/FPD0nUc9jH6rfFjji9IBqOz4pcSE3CsT1m7Ep6Mdb0LxSUMj8hgl6GomOvZzpNpAqqGaXA0P3VSrZLFzIhQrw==} + protobufjs@7.6.6: + resolution: {integrity: sha512-dYDWdjSl5RNb7SgPxGQcRU+GtvP7s2fpkrY0r432PcOIaZ0/rBcxEZnQN67iJhFuQiVw754JDoPruPCNdGsbjg==} engines: {node: '>=12.0.0'} proxy-addr@2.0.7: @@ -7181,6 +7092,10 @@ packages: resolution: {integrity: sha512-O9gl3zCl5h5blw1KGUzQKhA5oUXSl8rwUIM5o0S3nCXMliSvy5Dzx7/DJcI+SwgICv+IneSZwhBh1oSyEHA71A==} engines: {node: '>=0.6'} + qs@6.16.0: + resolution: {integrity: sha512-h6fhOIaRrID2CbEY2fqs+7t+UXZo+MLAnU5gRIq85uFtdiUPCdsApMlHhXogKVM4HM2DVbIjGNTTYH2OcmP1vA==} + engines: {node: '>=0.6'} + queue-microtask@1.2.3: resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==} @@ -7345,8 +7260,8 @@ packages: resolution: {integrity: sha512-l0OE8wL34P4nJH/H2ffoaniAokM2qSmrtXHmlpvYr5AVVX8msAyW0l8NVJFDxlSK4u3Uh/f41cQheDVdnYijwQ==} hasBin: true - rolldown-plugin-dts@0.28.2: - resolution: {integrity: sha512-U0Ng45ZaESZ7rJtQtgCWkJYCpMgH42yIj3xv9HGAsh/dJ8XBhjI4lcqh4NOWx8+CAxoY2HWg8VYINML2yE9A5A==} + rolldown-plugin-dts@0.28.4: + resolution: {integrity: sha512-yNg16bsWNk1MQ0Pkf3bAPFoZRqSWtxhiTHxKKHCoTZIwwyWerA5pX1MOogb1mjjwusVN2/kd4pK08iQ8M8hFIw==} engines: {node: ^22.18.0 || ^24.11.0 || >=26.0.0} peerDependencies: '@typescript/native-preview': '*' @@ -7617,8 +7532,8 @@ packages: resolution: {integrity: sha512-1gnZf7DFcoIcajTjTwjwuDjzuz4PPcY2StKPlsGAQ1+YH20IRVrBaXSWmdjowTJ6u8Rc01PoYOGHXfP1mYcZNQ==} engines: {node: '>= 18'} - serialize-javascript@7.1.0: - resolution: {integrity: sha512-RNEqWOyhhUQYN9V1GfHwu9AR/g+NTciH6Z5u3/no6X3/w+04J2lVDL+svFQVXgXrEGBMG2puMVN3gq2SNGuTGw==} + serialize-javascript@7.1.1: + resolution: {integrity: sha512-k3CMsaIvvdSwm8oLB4MXSl0wH2/cwlH7xGcnRd2DaeRmBkbzYmyT8j0tsX60DwD1eRwHTpNpH8ljKu9oUT1MeQ==} engines: {node: '>=20.0.0'} serve-index@1.9.2: @@ -7824,8 +7739,8 @@ packages: resolution: {integrity: sha512-KFxaM7XT+irxvdqSP1LGLgNWbYN7ay5owZ3r/8t77p+EtSUAfUgtl7be3xtqtOmGUl9K9YPO2ca8133RlTjvKw==} engines: {node: '>=8.0'} - streamx@2.28.0: - resolution: {integrity: sha512-1Yowhzjf0ivGMrTIkY9hav5TxobO9qIVqUE41fiCGMGgc3CLlf4MY+9AHmZqBWgDTue0fY9zWjYFVyf6Diuobw==} + streamx@2.28.1: + resolution: {integrity: sha512-zEzXb0s5Cds7tqMH6rhZ05lcJydCWiQPEwiNngVqzsxCc962vLY4Uw+mW7od8kDH258k2Uz/JrOkdIAAhSh9VA==} strict-event-emitter@0.5.1: resolution: {integrity: sha512-vMgjE/GGEPEFnhFub6pa4FmJBRBVOLpIII2hvCZ8Kzb7K0hlHo7mQv6xYrBvCL2LtAIBwFUK8wvuJgTVSQ5MFQ==} @@ -7936,6 +7851,11 @@ packages: engines: {node: '>=10'} hasBin: true + terser@5.51.2: + resolution: {integrity: sha512-bWnjSNscmuI+GJze6ZupnHP8G/cTcsJF+bXCeQknk2SHQsgbNJnLrqiH9jZ2W4STPVXH2mDKKRX3iwPhc9Cn/Q==} + engines: {node: '>=10'} + hasBin: true + text-decoder@1.2.7: resolution: {integrity: sha512-vlLytXkeP4xvEq2otHeJfSQIRyWxo/oZGEbXrtEEF9Hnmrdly59sUbzZ/QgyWuLYHctCHxFF4tRQZNQ9k60ExQ==} @@ -7981,15 +7901,15 @@ packages: tldts-core@6.1.86: resolution: {integrity: sha512-Je6p7pkk+KMzMv2XXKmAE3McmolOQFdxkKw0R8EYNr7sELW46JqnNeTX8ybPiQgvg1ymCoF8LXs5fzFaZvJPTA==} - tldts-core@7.4.10: - resolution: {integrity: sha512-KnQjp53ZekKgm/r3l+u8kJGGzYgrWdP8+Mql7a4vijh2WE0IrZWspQj/TpTxDho/YxO+AnOZnIjQcCD+q6iJsw==} + tldts-core@7.4.11: + resolution: {integrity: sha512-CW3WN2rIIE/Of21mulhgnGOwoDyEFNygyIBOONSdyAuSATgMMUCpLeUlB+E8sAwA5xRV9hYPl+kyZ9citHCaKg==} tldts@6.1.86: resolution: {integrity: sha512-WMi/OQ2axVTf/ykqCQgXiIct+mSQDFdH2fkwhPwgEwvJ1kSzZRiinb0zF2Xb8u4+OqPChmyI6MEu4EezNJz+FQ==} hasBin: true - tldts@7.4.10: - resolution: {integrity: sha512-GgouD1B+sWwvkaEq8vXC15DjQitxbvs12oIXELpconwm+Tg3zfcEv4jgzq3vtKverDXsg3VI8aRgNL2Nra0Iog==} + tldts@7.4.11: + resolution: {integrity: sha512-aBiNayCfTQxuIJBm06M+xR14cYaYlDlSXZbgsnKzKNxDKUVq7KFwTjwBSsb7m9Y5xO8WfPnBc63WaYFMTGlvqw==} hasBin: true tmp@0.2.7: @@ -8073,8 +7993,8 @@ packages: resolution: {integrity: sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==} engines: {node: '>= 0.8.0'} - type-fest@5.8.0: - resolution: {integrity: sha512-YGYEVz3Fm5iy/AybuA0oyNFq7H4CgQNfRp/qfe8nurE1kuCeNm3/vfm9X4Mtl+qLyaKJUh5xrFZwogr41SMjYA==} + type-fest@5.9.0: + resolution: {integrity: sha512-yANm3Jr3GiJ1qgJlxGAVxTOIcEOk1rhQHamlXtnrCK7EHP4HeM9OGxtMg/W7HFdrVzw/ZWJKGVIJusVH85sLtw==} engines: {node: '>=20'} type-is@1.6.18: @@ -8192,8 +8112,8 @@ packages: resolution: {integrity: sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==} engines: {node: '>= 0.8'} - update-browserslist-db@1.3.1: - resolution: {integrity: sha512-ZZ61DsRsOnakl74HAmp3oSN4aXUmEWXf+i/yv0h7tIBfICc3VdrFErQKUUKPgu3AMsTUMbcongALEN4l6GSUrQ==} + update-browserslist-db@1.3.2: + resolution: {integrity: sha512-UQ+MSxlhRm1bzjhU+DcuXfjFO1FzNtqhK5+9Yvlp90ItDLk5vT932A0rFu619nf7RVS+Y/VeaUW1jaRDqZ8VJw==} hasBin: true peerDependencies: browserslist: '>= 4.21.0' @@ -8237,8 +8157,8 @@ packages: resolution: {integrity: sha512-2nHSt8qRQcCCUQX6QO72eC1D1RoqCBZVPTotVdS/CGpMtE+jUHIDnOSWWMQxtN53PHa6wjjheySJCcuEpmtJsQ==} engines: {node: '>=22'} - verdaccio-auth-memory@13.1.2: - resolution: {integrity: sha512-Z5CH/iUa37QmaNt+nbgvyjojyQ6WZA0r06ymsGjor8xCqFBzGtIlLsM8Es0Njh/fU06r928RcsfEjha7zFqv1w==} + verdaccio-auth-memory@13.1.3: + resolution: {integrity: sha512-ZE9pUeH+iYYWbAAEbgmOEX/cluk1vdWiz1FaF/Exc0Q7T4YO60WMp2ihB7W6kIYgL2UefjGM54r+lcZDNK7Vxw==} engines: {node: '>=22'} verdaccio-htpasswd@13.1.2: @@ -8588,14 +8508,14 @@ packages: resolution: {integrity: sha512-xYqdZFUK/VYazNl/oCDYN+3WloWQwMfZxBoiNt6qNyk+xfOdi598muWE42rNZFp1kNOiqW936q5RhUdnpqElSg==} engines: {node: '>=18'} - yuku-ast@0.8.7: - resolution: {integrity: sha512-h6+4bDfyootiMB9vckk5uKo5r5j0GHrkr17FQTDNfEsFT3DWlN9uu1HJwQwc64pgmLCI945fWM3lbTIqxjT3GQ==} + yuku-ast@0.9.3: + resolution: {integrity: sha512-Kt0PXlPCXdKF1fWFTl7N3DaxsVk6DHF8VAXHJMkwPtJnWYgbx20pYgGSweuC/86mIM7k1NUITQ4JffgOLUWTCw==} - yuku-codegen@0.8.7: - resolution: {integrity: sha512-adwDZSh8oVDzhE6Du9PwVWxcOxeV0e2EVhUuMKWfhSY4wkrDq9eqixlxFF3l/XGUV1E7UFzhpz9393MUumkyNw==} + yuku-codegen@0.9.3: + resolution: {integrity: sha512-7oTWwetHiMSyrVPFb8089lBBqkU1gaeQZyumNBJ0t5hocMQRaWhnMeSXTz7J1xm/rcw9+ePsajORdZbub2C35w==} - yuku-parser@0.8.7: - resolution: {integrity: sha512-vRD9nwt4L3aYpxNqeSC4WqLv58xrXef0Ong1Mc45CTXTIpvLafx7JO05sczmQZwdLEZvywrLOGdNC5+Rp5N1BQ==} + yuku-parser@0.9.3: + resolution: {integrity: sha512-96wPoHnwaXfkZv7UIOUkDb+s7ZH8lv8Qtg+MxdvHUV1LFa5jV9iKOaams1942YQt+krFQrWiD6lSg2ermv5kHA==} zod@3.25.76: resolution: {integrity: sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ==} @@ -8653,7 +8573,7 @@ snapshots: dependencies: '@angular/compiler': 22.2.0-next.4 '@babel/core': 8.0.1 - '@jridgewell/sourcemap-codec': 1.5.5 + '@jridgewell/sourcemap-codec': 1.6.0 chokidar: 5.0.0 convert-source-map: 1.9.0 reflect-metadata: 0.2.2 @@ -8798,7 +8718,7 @@ snapshots: '@asamuzakjp/css-color@6.0.7': dependencies: '@csstools/css-calc': 3.3.0(@csstools/css-parser-algorithms@4.0.0(@csstools/css-tokenizer@4.0.0))(@csstools/css-tokenizer@4.0.0) - '@csstools/css-color-parser': 4.2.0(@csstools/css-parser-algorithms@4.0.0(@csstools/css-tokenizer@4.0.0))(@csstools/css-tokenizer@4.0.0) + '@csstools/css-color-parser': 4.2.2(@csstools/css-parser-algorithms@4.0.0(@csstools/css-tokenizer@4.0.0))(@csstools/css-tokenizer@4.0.0) '@csstools/css-parser-algorithms': 4.0.0(@csstools/css-tokenizer@4.0.0) '@csstools/css-tokenizer': 4.0.0 lru-cache: 11.5.2 @@ -9515,7 +9435,7 @@ snapshots: '@csstools/css-parser-algorithms': 4.0.0(@csstools/css-tokenizer@4.0.0) '@csstools/css-tokenizer': 4.0.0 - '@csstools/css-color-parser@4.2.0(@csstools/css-parser-algorithms@4.0.0(@csstools/css-tokenizer@4.0.0))(@csstools/css-tokenizer@4.0.0)': + '@csstools/css-color-parser@4.2.2(@csstools/css-parser-algorithms@4.0.0(@csstools/css-tokenizer@4.0.0))(@csstools/css-tokenizer@4.0.0)': dependencies: '@csstools/color-helpers': 6.1.1 '@csstools/css-calc': 3.3.0(@csstools/css-parser-algorithms@4.0.0(@csstools/css-tokenizer@4.0.0))(@csstools/css-tokenizer@4.0.0) @@ -9526,7 +9446,7 @@ snapshots: dependencies: '@csstools/css-tokenizer': 4.0.0 - '@csstools/css-syntax-patches-for-csstree@1.1.8(css-tree@3.2.1)': + '@csstools/css-syntax-patches-for-csstree@1.1.10(css-tree@3.2.1)': optionalDependencies: css-tree: 3.2.1 @@ -9547,7 +9467,7 @@ snapshots: json-stringify-safe: 5.0.1 mime-types: 2.1.35 performance-now: 2.1.0 - qs: 6.15.3 + qs: 6.16.0 safe-buffer: 5.2.1 tough-cookie: 5.1.2 tunnel-agent: 0.6.0 @@ -9669,7 +9589,7 @@ snapshots: globals: 14.0.0 ignore: 5.3.2 import-fresh: 3.3.1 - js-yaml: 4.3.1 + js-yaml: 4.3.2 minimatch: 3.1.5 strip-json-comments: 3.1.1 transitivePeerDependencies: @@ -10057,7 +9977,7 @@ snapshots: lodash.snakecase: 4.1.1 merge-stream: 2.0.0 p-queue: 6.6.2 - protobufjs: 7.6.5 + protobufjs: 7.6.6 retry-request: 8.0.4(supports-color@11.0.0) split-array-stream: 2.0.0 stack-trace: 0.0.10 @@ -10071,7 +9991,7 @@ snapshots: dependencies: google-auth-library: 10.9.1(supports-color@11.0.0) p-retry: 4.6.2 - protobufjs: 7.6.5 + protobufjs: 7.6.6 ws: 8.21.3(bufferutil@4.1.0)(utf-8-validate@6.0.6) transitivePeerDependencies: - bufferutil @@ -10092,14 +10012,14 @@ snapshots: dependencies: lodash.camelcase: 4.3.0 long: 5.3.2 - protobufjs: 7.6.5 + protobufjs: 7.6.6 yargs: 17.7.3 '@grpc/proto-loader@0.8.1': dependencies: lodash.camelcase: 4.3.0 long: 5.3.2 - protobufjs: 7.6.5 + protobufjs: 7.6.6 yargs: 17.7.3 '@harperfast/extended-iterable@1.0.3': @@ -10123,12 +10043,12 @@ snapshots: '@inquirer/ansi@2.0.7': {} - '@inquirer/checkbox@5.2.2(@types/node@22.20.1)': + '@inquirer/checkbox@5.2.3(@types/node@22.20.1)': dependencies: '@inquirer/ansi': 2.0.7 - '@inquirer/core': 12.0.0(@types/node@22.20.1) + '@inquirer/core': 12.0.1(@types/node@22.20.1) '@inquirer/figures': 2.0.8 - '@inquirer/type': 4.0.7(@types/node@22.20.1) + '@inquirer/type': 4.1.0(@types/node@22.20.1) optionalDependencies: '@types/node': 22.20.1 @@ -10143,8 +10063,8 @@ snapshots: '@inquirer/confirm@6.2.0(@types/node@22.20.1)': dependencies: - '@inquirer/core': 12.0.0(@types/node@22.20.1) - '@inquirer/type': 4.0.7(@types/node@22.20.1) + '@inquirer/core': 12.0.1(@types/node@22.20.1) + '@inquirer/type': 4.1.0(@types/node@22.20.1) optionalDependencies: '@types/node': 22.20.1 @@ -10155,11 +10075,11 @@ snapshots: optionalDependencies: '@types/node': 24.13.3 - '@inquirer/core@12.0.0(@types/node@22.20.1)': + '@inquirer/core@12.0.1(@types/node@22.20.1)': dependencies: '@inquirer/ansi': 2.0.7 '@inquirer/figures': 2.0.8 - '@inquirer/type': 4.0.7(@types/node@22.20.1) + '@inquirer/type': 4.1.0(@types/node@22.20.1) cli-width: 4.1.0 fast-wrap-ansi: 0.2.2 mute-stream: 3.0.0 @@ -10179,11 +10099,11 @@ snapshots: optionalDependencies: '@types/node': 24.13.3 - '@inquirer/editor@5.3.0(@types/node@22.20.1)': + '@inquirer/editor@5.3.1(@types/node@22.20.1)': dependencies: - '@inquirer/core': 12.0.0(@types/node@22.20.1) + '@inquirer/core': 12.0.1(@types/node@22.20.1) '@inquirer/external-editor': 3.0.4(@types/node@22.20.1) - '@inquirer/type': 4.0.7(@types/node@22.20.1) + '@inquirer/type': 4.1.0(@types/node@22.20.1) optionalDependencies: '@types/node': 22.20.1 @@ -10195,10 +10115,10 @@ snapshots: optionalDependencies: '@types/node': 24.13.3 - '@inquirer/expand@5.1.2(@types/node@22.20.1)': + '@inquirer/expand@5.1.3(@types/node@22.20.1)': dependencies: - '@inquirer/core': 12.0.0(@types/node@22.20.1) - '@inquirer/type': 4.0.7(@types/node@22.20.1) + '@inquirer/core': 12.0.1(@types/node@22.20.1) + '@inquirer/type': 4.1.0(@types/node@22.20.1) optionalDependencies: '@types/node': 22.20.1 @@ -10225,10 +10145,10 @@ snapshots: '@inquirer/figures@2.0.8': {} - '@inquirer/input@5.1.3(@types/node@22.20.1)': + '@inquirer/input@5.1.4(@types/node@22.20.1)': dependencies: - '@inquirer/core': 12.0.0(@types/node@22.20.1) - '@inquirer/type': 4.0.7(@types/node@22.20.1) + '@inquirer/core': 12.0.1(@types/node@22.20.1) + '@inquirer/type': 4.1.0(@types/node@22.20.1) optionalDependencies: '@types/node': 22.20.1 @@ -10239,10 +10159,10 @@ snapshots: optionalDependencies: '@types/node': 24.13.3 - '@inquirer/number@4.2.0(@types/node@22.20.1)': + '@inquirer/number@4.2.1(@types/node@22.20.1)': dependencies: - '@inquirer/core': 12.0.0(@types/node@22.20.1) - '@inquirer/type': 4.0.7(@types/node@22.20.1) + '@inquirer/core': 12.0.1(@types/node@22.20.1) + '@inquirer/type': 4.1.0(@types/node@22.20.1) optionalDependencies: '@types/node': 22.20.1 @@ -10253,11 +10173,11 @@ snapshots: optionalDependencies: '@types/node': 24.13.3 - '@inquirer/password@5.1.2(@types/node@22.20.1)': + '@inquirer/password@5.2.0(@types/node@22.20.1)': dependencies: '@inquirer/ansi': 2.0.7 - '@inquirer/core': 12.0.0(@types/node@22.20.1) - '@inquirer/type': 4.0.7(@types/node@22.20.1) + '@inquirer/core': 12.0.1(@types/node@22.20.1) + '@inquirer/type': 4.1.0(@types/node@22.20.1) optionalDependencies: '@types/node': 22.20.1 @@ -10271,16 +10191,16 @@ snapshots: '@inquirer/prompts@8.6.0(@types/node@22.20.1)': dependencies: - '@inquirer/checkbox': 5.2.2(@types/node@22.20.1) + '@inquirer/checkbox': 5.2.3(@types/node@22.20.1) '@inquirer/confirm': 6.2.0(@types/node@22.20.1) - '@inquirer/editor': 5.3.0(@types/node@22.20.1) - '@inquirer/expand': 5.1.2(@types/node@22.20.1) - '@inquirer/input': 5.1.3(@types/node@22.20.1) - '@inquirer/number': 4.2.0(@types/node@22.20.1) - '@inquirer/password': 5.1.2(@types/node@22.20.1) - '@inquirer/rawlist': 5.3.2(@types/node@22.20.1) - '@inquirer/search': 4.3.0(@types/node@22.20.1) - '@inquirer/select': 5.2.2(@types/node@22.20.1) + '@inquirer/editor': 5.3.1(@types/node@22.20.1) + '@inquirer/expand': 5.1.3(@types/node@22.20.1) + '@inquirer/input': 5.1.4(@types/node@22.20.1) + '@inquirer/number': 4.2.1(@types/node@22.20.1) + '@inquirer/password': 5.2.0(@types/node@22.20.1) + '@inquirer/rawlist': 5.3.3(@types/node@22.20.1) + '@inquirer/search': 4.3.1(@types/node@22.20.1) + '@inquirer/select': 5.2.3(@types/node@22.20.1) optionalDependencies: '@types/node': 22.20.1 @@ -10299,10 +10219,10 @@ snapshots: optionalDependencies: '@types/node': 24.13.3 - '@inquirer/rawlist@5.3.2(@types/node@22.20.1)': + '@inquirer/rawlist@5.3.3(@types/node@22.20.1)': dependencies: - '@inquirer/core': 12.0.0(@types/node@22.20.1) - '@inquirer/type': 4.0.7(@types/node@22.20.1) + '@inquirer/core': 12.0.1(@types/node@22.20.1) + '@inquirer/type': 4.1.0(@types/node@22.20.1) optionalDependencies: '@types/node': 22.20.1 @@ -10313,11 +10233,11 @@ snapshots: optionalDependencies: '@types/node': 24.13.3 - '@inquirer/search@4.3.0(@types/node@22.20.1)': + '@inquirer/search@4.3.1(@types/node@22.20.1)': dependencies: - '@inquirer/core': 12.0.0(@types/node@22.20.1) + '@inquirer/core': 12.0.1(@types/node@22.20.1) '@inquirer/figures': 2.0.8 - '@inquirer/type': 4.0.7(@types/node@22.20.1) + '@inquirer/type': 4.1.0(@types/node@22.20.1) optionalDependencies: '@types/node': 22.20.1 @@ -10329,12 +10249,12 @@ snapshots: optionalDependencies: '@types/node': 24.13.3 - '@inquirer/select@5.2.2(@types/node@22.20.1)': + '@inquirer/select@5.2.3(@types/node@22.20.1)': dependencies: '@inquirer/ansi': 2.0.7 - '@inquirer/core': 12.0.0(@types/node@22.20.1) + '@inquirer/core': 12.0.1(@types/node@22.20.1) '@inquirer/figures': 2.0.8 - '@inquirer/type': 4.0.7(@types/node@22.20.1) + '@inquirer/type': 4.1.0(@types/node@22.20.1) optionalDependencies: '@types/node': 22.20.1 @@ -10347,7 +10267,7 @@ snapshots: optionalDependencies: '@types/node': 24.13.3 - '@inquirer/type@4.0.7(@types/node@22.20.1)': + '@inquirer/type@4.1.0(@types/node@22.20.1)': optionalDependencies: '@types/node': 22.20.1 @@ -10370,7 +10290,7 @@ snapshots: '@jridgewell/gen-mapping@0.3.13': dependencies: - '@jridgewell/sourcemap-codec': 1.5.5 + '@jridgewell/sourcemap-codec': 1.6.0 '@jridgewell/trace-mapping': 0.3.31 '@jridgewell/remapping@2.3.5': @@ -10385,12 +10305,12 @@ snapshots: '@jridgewell/gen-mapping': 0.3.13 '@jridgewell/trace-mapping': 0.3.31 - '@jridgewell/sourcemap-codec@1.5.5': {} + '@jridgewell/sourcemap-codec@1.6.0': {} '@jridgewell/trace-mapping@0.3.31': dependencies: '@jridgewell/resolve-uri': 3.1.2 - '@jridgewell/sourcemap-codec': 1.5.5 + '@jridgewell/sourcemap-codec': 1.6.0 '@js-sdsl/ordered-map@4.4.2': {} @@ -10418,59 +10338,59 @@ snapshots: dependencies: tslib: 2.8.1 - '@jsonjoy.com/fs-core@4.68.1(tslib@2.8.1)': + '@jsonjoy.com/fs-core@4.68.2(tslib@2.8.1)': dependencies: - '@jsonjoy.com/fs-node-builtins': 4.68.1(tslib@2.8.1) - '@jsonjoy.com/fs-node-utils': 4.68.1(tslib@2.8.1) + '@jsonjoy.com/fs-node-builtins': 4.68.2(tslib@2.8.1) + '@jsonjoy.com/fs-node-utils': 4.68.2(tslib@2.8.1) thingies: 2.6.1(tslib@2.8.1) tslib: 2.8.1 - '@jsonjoy.com/fs-fsa@4.68.1(tslib@2.8.1)': + '@jsonjoy.com/fs-fsa@4.68.2(tslib@2.8.1)': dependencies: - '@jsonjoy.com/fs-core': 4.68.1(tslib@2.8.1) - '@jsonjoy.com/fs-node-builtins': 4.68.1(tslib@2.8.1) - '@jsonjoy.com/fs-node-utils': 4.68.1(tslib@2.8.1) + '@jsonjoy.com/fs-core': 4.68.2(tslib@2.8.1) + '@jsonjoy.com/fs-node-builtins': 4.68.2(tslib@2.8.1) + '@jsonjoy.com/fs-node-utils': 4.68.2(tslib@2.8.1) thingies: 2.6.1(tslib@2.8.1) tslib: 2.8.1 - '@jsonjoy.com/fs-node-builtins@4.68.1(tslib@2.8.1)': + '@jsonjoy.com/fs-node-builtins@4.68.2(tslib@2.8.1)': dependencies: tslib: 2.8.1 - '@jsonjoy.com/fs-node-to-fsa@4.68.1(tslib@2.8.1)': + '@jsonjoy.com/fs-node-to-fsa@4.68.2(tslib@2.8.1)': dependencies: - '@jsonjoy.com/fs-fsa': 4.68.1(tslib@2.8.1) - '@jsonjoy.com/fs-node-builtins': 4.68.1(tslib@2.8.1) - '@jsonjoy.com/fs-node-utils': 4.68.1(tslib@2.8.1) + '@jsonjoy.com/fs-fsa': 4.68.2(tslib@2.8.1) + '@jsonjoy.com/fs-node-builtins': 4.68.2(tslib@2.8.1) + '@jsonjoy.com/fs-node-utils': 4.68.2(tslib@2.8.1) tslib: 2.8.1 - '@jsonjoy.com/fs-node-utils@4.68.1(tslib@2.8.1)': + '@jsonjoy.com/fs-node-utils@4.68.2(tslib@2.8.1)': dependencies: - '@jsonjoy.com/fs-node-builtins': 4.68.1(tslib@2.8.1) + '@jsonjoy.com/fs-node-builtins': 4.68.2(tslib@2.8.1) glob-to-regex.js: 1.2.0(tslib@2.8.1) tslib: 2.8.1 - '@jsonjoy.com/fs-node@4.68.1(tslib@2.8.1)': + '@jsonjoy.com/fs-node@4.68.2(tslib@2.8.1)': dependencies: - '@jsonjoy.com/fs-core': 4.68.1(tslib@2.8.1) - '@jsonjoy.com/fs-node-builtins': 4.68.1(tslib@2.8.1) - '@jsonjoy.com/fs-node-utils': 4.68.1(tslib@2.8.1) - '@jsonjoy.com/fs-print': 4.68.1(tslib@2.8.1) - '@jsonjoy.com/fs-snapshot': 4.68.1(tslib@2.8.1) + '@jsonjoy.com/fs-core': 4.68.2(tslib@2.8.1) + '@jsonjoy.com/fs-node-builtins': 4.68.2(tslib@2.8.1) + '@jsonjoy.com/fs-node-utils': 4.68.2(tslib@2.8.1) + '@jsonjoy.com/fs-print': 4.68.2(tslib@2.8.1) + '@jsonjoy.com/fs-snapshot': 4.68.2(tslib@2.8.1) glob-to-regex.js: 1.2.0(tslib@2.8.1) thingies: 2.6.1(tslib@2.8.1) tslib: 2.8.1 - '@jsonjoy.com/fs-print@4.68.1(tslib@2.8.1)': + '@jsonjoy.com/fs-print@4.68.2(tslib@2.8.1)': dependencies: - '@jsonjoy.com/fs-node-utils': 4.68.1(tslib@2.8.1) + '@jsonjoy.com/fs-node-utils': 4.68.2(tslib@2.8.1) tree-dump: 1.1.0(tslib@2.8.1) tslib: 2.8.1 - '@jsonjoy.com/fs-snapshot@4.68.1(tslib@2.8.1)': + '@jsonjoy.com/fs-snapshot@4.68.2(tslib@2.8.1)': dependencies: '@jsonjoy.com/buffers': 17.67.0(tslib@2.8.1) - '@jsonjoy.com/fs-node-utils': 4.68.1(tslib@2.8.1) + '@jsonjoy.com/fs-node-utils': 4.68.2(tslib@2.8.1) '@jsonjoy.com/json-pack': 17.67.0(tslib@2.8.1) '@jsonjoy.com/util': 17.67.0(tslib@2.8.1) tslib: 2.8.1 @@ -10529,7 +10449,7 @@ snapshots: '@listr2/prompt-adapter-inquirer@4.2.6(@inquirer/prompts@8.6.0(@types/node@22.20.1))(@types/node@22.20.1)(listr2@11.0.1)': dependencies: '@inquirer/prompts': 8.6.0(@types/node@22.20.1) - '@inquirer/type': 4.0.7(@types/node@22.20.1) + '@inquirer/type': 4.1.0(@types/node@22.20.1) listr2: 11.0.1 transitivePeerDependencies: - '@types/node' @@ -10678,13 +10598,13 @@ snapshots: '@nodelib/fs.walk@1.2.8': dependencies: '@nodelib/fs.scandir': 2.1.5 - fastq: 1.20.1 + fastq: 1.20.3 '@octokit/auth-app@8.3.0': dependencies: '@octokit/auth-oauth-app': 9.0.4 - '@octokit/auth-oauth-user': 6.0.3 - '@octokit/request': 10.0.15 + '@octokit/auth-oauth-user': 6.0.4 + '@octokit/request': 10.0.16 '@octokit/request-error': 7.1.1 '@octokit/types': 17.0.0 toad-cache: 3.7.4 @@ -10693,25 +10613,25 @@ snapshots: '@octokit/auth-oauth-app@9.0.4': dependencies: - '@octokit/auth-oauth-device': 8.0.4 - '@octokit/auth-oauth-user': 6.0.3 - '@octokit/request': 10.0.15 + '@octokit/auth-oauth-device': 8.0.5 + '@octokit/auth-oauth-user': 6.0.4 + '@octokit/request': 10.0.16 '@octokit/types': 17.0.0 universal-user-agent: 7.0.3 - '@octokit/auth-oauth-device@8.0.4': + '@octokit/auth-oauth-device@8.0.5': dependencies: - '@octokit/oauth-methods': 6.0.4 - '@octokit/request': 10.0.15 - '@octokit/types': 17.0.0 + '@octokit/oauth-methods': 6.0.5 + '@octokit/request': 10.0.16 + '@octokit/types': 18.0.0 universal-user-agent: 7.0.3 - '@octokit/auth-oauth-user@6.0.3': + '@octokit/auth-oauth-user@6.0.4': dependencies: - '@octokit/auth-oauth-device': 8.0.4 - '@octokit/oauth-methods': 6.0.4 - '@octokit/request': 10.0.15 - '@octokit/types': 17.0.0 + '@octokit/auth-oauth-device': 8.0.5 + '@octokit/oauth-methods': 6.0.5 + '@octokit/request': 10.0.16 + '@octokit/types': 18.0.0 universal-user-agent: 7.0.3 '@octokit/auth-token@6.0.0': {} @@ -10720,15 +10640,15 @@ snapshots: dependencies: '@octokit/auth-token': 6.0.0 '@octokit/graphql': 9.0.4 - '@octokit/request': 10.0.15 + '@octokit/request': 10.0.16 '@octokit/request-error': 7.1.1 '@octokit/types': 17.0.0 before-after-hook: 4.0.0 universal-user-agent: 7.0.3 - '@octokit/endpoint@11.0.4': + '@octokit/endpoint@11.0.5': dependencies: - '@octokit/types': 17.0.0 + '@octokit/types': 18.0.0 universal-user-agent: 7.0.3 '@octokit/graphql-schema@15.26.1': @@ -10738,23 +10658,25 @@ snapshots: '@octokit/graphql@9.0.4': dependencies: - '@octokit/request': 10.0.15 + '@octokit/request': 10.0.16 '@octokit/types': 17.0.0 universal-user-agent: 7.0.3 '@octokit/oauth-authorization-url@8.0.0': {} - '@octokit/oauth-methods@6.0.4': + '@octokit/oauth-methods@6.0.5': dependencies: '@octokit/oauth-authorization-url': 8.0.0 - '@octokit/request': 10.0.15 - '@octokit/request-error': 7.1.1 - '@octokit/types': 17.0.0 + '@octokit/request': 10.0.16 + '@octokit/request-error': 7.1.2 + '@octokit/types': 18.0.0 '@octokit/openapi-types@27.0.0': {} '@octokit/openapi-types@28.0.0': {} + '@octokit/openapi-types@29.0.1': {} + '@octokit/plugin-paginate-rest@14.0.0(@octokit/core@7.0.7)': dependencies: '@octokit/core': 7.0.7 @@ -10783,11 +10705,15 @@ snapshots: dependencies: '@octokit/types': 17.0.0 - '@octokit/request@10.0.15': + '@octokit/request-error@7.1.2': dependencies: - '@octokit/endpoint': 11.0.4 - '@octokit/request-error': 7.1.1 - '@octokit/types': 17.0.0 + '@octokit/types': 18.0.0 + + '@octokit/request@10.0.16': + dependencies: + '@octokit/endpoint': 11.0.5 + '@octokit/request-error': 7.1.2 + '@octokit/types': 18.0.0 content-type: 3.0.0 json-with-bigint: 3.5.12 universal-user-agent: 7.0.3 @@ -10807,6 +10733,10 @@ snapshots: dependencies: '@octokit/openapi-types': 28.0.0 + '@octokit/types@18.0.0': + dependencies: + '@octokit/openapi-types': 29.0.1 + '@open-draft/deferred-promise@2.2.0': {} '@open-draft/logger@0.3.0': @@ -11278,7 +11208,7 @@ snapshots: '@stylistic/eslint-plugin@5.10.0(eslint@10.9.1(jiti@2.7.0)(supports-color@11.0.0))': dependencies: '@eslint-community/eslint-utils': 4.10.1(eslint@10.9.1(jiti@2.7.0)(supports-color@11.0.0)) - '@typescript-eslint/types': 8.67.0 + '@typescript-eslint/types': 8.68.0 eslint: 10.9.1(jiti@2.7.0)(supports-color@11.0.0) eslint-visitor-keys: 4.2.1 espree: 10.4.0 @@ -11517,7 +11447,7 @@ snapshots: '@typescript-eslint/utils': 8.68.0(eslint@10.9.1(jiti@2.7.0)(supports-color@11.0.0))(supports-color@11.0.0)(typescript@6.0.3) '@typescript-eslint/visitor-keys': 8.68.0 eslint: 10.9.1(jiti@2.7.0)(supports-color@11.0.0) - ignore: 7.0.6 + ignore: 7.0.7 natural-compare: 1.4.0 ts-api-utils: 2.5.0(typescript@6.0.3) typescript: 6.0.3 @@ -11566,8 +11496,6 @@ snapshots: transitivePeerDependencies: - supports-color - '@typescript-eslint/types@8.67.0': {} - '@typescript-eslint/types@8.68.0': {} '@typescript-eslint/typescript-estree@8.68.0(supports-color@11.0.0)(typescript@6.0.3)': @@ -11631,6 +11559,16 @@ snapshots: process-warning: 1.0.0 semver: 7.8.5 + '@verdaccio/core@8.3.0': + dependencies: + ajv: 8.20.0 + http-errors: 2.0.1 + http-status-codes: 2.3.0 + lodash: 4.18.1 + minimatch: 10.2.6 + process-warning: 1.0.0 + semver: 7.8.5 + '@verdaccio/file-locking@13.1.0': dependencies: lockfile: 1.0.4 @@ -11764,9 +11702,9 @@ snapshots: lodash: 4.18.1 minimatch: 10.2.6 - '@vitejs/plugin-basic-ssl@2.3.0(vite@8.2.2(@types/node@22.20.1)(esbuild@0.28.2)(jiti@2.7.0)(less@4.9.0(supports-color@11.0.0))(sass-embedded@1.103.1)(sass@1.103.1)(terser@5.50.0)(tsx@4.23.12)(yaml@2.9.0))': + '@vitejs/plugin-basic-ssl@2.3.0(vite@8.2.2(@types/node@22.20.1)(esbuild@0.28.2)(jiti@2.7.0)(less@4.9.0(supports-color@11.0.0))(sass-embedded@1.103.1)(sass@1.103.1)(terser@5.51.2)(tsx@4.23.12)(yaml@2.9.0))': dependencies: - vite: 8.2.2(@types/node@22.20.1)(esbuild@0.28.2)(jiti@2.7.0)(less@4.9.0(supports-color@11.0.0))(sass-embedded@1.103.1)(sass@1.103.1)(terser@5.50.0)(tsx@4.23.12)(yaml@2.9.0) + vite: 8.2.2(@types/node@22.20.1)(esbuild@0.28.2)(jiti@2.7.0)(less@4.9.0(supports-color@11.0.0))(sass-embedded@1.103.1)(sass@1.103.1)(terser@5.51.2)(tsx@4.23.12)(yaml@2.9.0) '@vitest/coverage-v8@4.1.11(vitest@4.1.11)': dependencies: @@ -11780,7 +11718,7 @@ snapshots: obug: 2.1.4 std-env: 4.2.0 tinyrainbow: 3.1.1 - vitest: 4.1.11(@opentelemetry/api@1.9.1)(@types/node@22.20.1)(@vitest/coverage-v8@4.1.11)(esbuild@0.28.2)(jiti@2.7.0)(jsdom@30.0.1)(less@4.9.0(supports-color@11.0.0))(sass-embedded@1.103.1)(sass@1.103.1)(terser@5.50.0)(tsx@4.23.12)(yaml@2.9.0) + vitest: 4.1.11(@opentelemetry/api@1.9.1)(@types/node@22.20.1)(@vitest/coverage-v8@4.1.11)(esbuild@0.28.2)(jiti@2.7.0)(jsdom@30.0.1)(less@4.9.0(supports-color@11.0.0))(sass-embedded@1.103.1)(sass@1.103.1)(terser@5.51.2)(tsx@4.23.12)(yaml@2.9.0) '@vitest/expect@4.1.11': dependencies: @@ -11791,13 +11729,13 @@ snapshots: chai: 6.2.2 tinyrainbow: 3.1.1 - '@vitest/mocker@4.1.11(vite@8.2.2(@types/node@22.20.1)(esbuild@0.28.2)(jiti@2.7.0)(less@4.9.0(supports-color@11.0.0))(sass-embedded@1.103.1)(sass@1.103.1)(terser@5.50.0)(tsx@4.23.12)(yaml@2.9.0))': + '@vitest/mocker@4.1.11(vite@8.2.2(@types/node@22.20.1)(esbuild@0.28.2)(jiti@2.7.0)(less@4.9.0(supports-color@11.0.0))(sass-embedded@1.103.1)(sass@1.103.1)(terser@5.51.2)(tsx@4.23.12)(yaml@2.9.0))': dependencies: '@vitest/spy': 4.1.11 estree-walker: 3.0.3 magic-string: 0.30.21 optionalDependencies: - vite: 8.2.2(@types/node@22.20.1)(esbuild@0.28.2)(jiti@2.7.0)(less@4.9.0(supports-color@11.0.0))(sass-embedded@1.103.1)(sass@1.103.1)(terser@5.50.0)(tsx@4.23.12)(yaml@2.9.0) + vite: 8.2.2(@types/node@22.20.1)(esbuild@0.28.2)(jiti@2.7.0)(less@4.9.0(supports-color@11.0.0))(sass-embedded@1.103.1)(sass@1.103.1)(terser@5.51.2)(tsx@4.23.12)(yaml@2.9.0) '@vitest/pretty-format@4.1.11': dependencies: @@ -11907,79 +11845,79 @@ snapshots: '@yarnpkg/lockfile@1.1.0': {} - '@yuku-codegen/binding-android-arm64@0.8.7': + '@yuku-codegen/binding-android-arm64@0.9.3': optional: true - '@yuku-codegen/binding-darwin-arm64@0.8.7': + '@yuku-codegen/binding-darwin-arm64@0.9.3': optional: true - '@yuku-codegen/binding-darwin-x64@0.8.7': + '@yuku-codegen/binding-darwin-x64@0.9.3': optional: true - '@yuku-codegen/binding-freebsd-x64@0.8.7': + '@yuku-codegen/binding-freebsd-x64@0.9.3': optional: true - '@yuku-codegen/binding-linux-arm-gnu@0.8.7': + '@yuku-codegen/binding-linux-arm-gnu@0.9.3': optional: true - '@yuku-codegen/binding-linux-arm-musl@0.8.7': + '@yuku-codegen/binding-linux-arm-musl@0.9.3': optional: true - '@yuku-codegen/binding-linux-arm64-gnu@0.8.7': + '@yuku-codegen/binding-linux-arm64-gnu@0.9.3': optional: true - '@yuku-codegen/binding-linux-arm64-musl@0.8.7': + '@yuku-codegen/binding-linux-arm64-musl@0.9.3': optional: true - '@yuku-codegen/binding-linux-x64-gnu@0.8.7': + '@yuku-codegen/binding-linux-x64-gnu@0.9.3': optional: true - '@yuku-codegen/binding-linux-x64-musl@0.8.7': + '@yuku-codegen/binding-linux-x64-musl@0.9.3': optional: true - '@yuku-codegen/binding-win32-arm64@0.8.7': + '@yuku-codegen/binding-win32-arm64@0.9.3': optional: true - '@yuku-codegen/binding-win32-x64@0.8.7': + '@yuku-codegen/binding-win32-x64@0.9.3': optional: true - '@yuku-parser/binding-android-arm64@0.8.7': + '@yuku-parser/binding-android-arm64@0.9.3': optional: true - '@yuku-parser/binding-darwin-arm64@0.8.7': + '@yuku-parser/binding-darwin-arm64@0.9.3': optional: true - '@yuku-parser/binding-darwin-x64@0.8.7': + '@yuku-parser/binding-darwin-x64@0.9.3': optional: true - '@yuku-parser/binding-freebsd-x64@0.8.7': + '@yuku-parser/binding-freebsd-x64@0.9.3': optional: true - '@yuku-parser/binding-linux-arm-gnu@0.8.7': + '@yuku-parser/binding-linux-arm-gnu@0.9.3': optional: true - '@yuku-parser/binding-linux-arm-musl@0.8.7': + '@yuku-parser/binding-linux-arm-musl@0.9.3': optional: true - '@yuku-parser/binding-linux-arm64-gnu@0.8.7': + '@yuku-parser/binding-linux-arm64-gnu@0.9.3': optional: true - '@yuku-parser/binding-linux-arm64-musl@0.8.7': + '@yuku-parser/binding-linux-arm64-musl@0.9.3': optional: true - '@yuku-parser/binding-linux-x64-gnu@0.8.7': + '@yuku-parser/binding-linux-x64-gnu@0.9.3': optional: true - '@yuku-parser/binding-linux-x64-musl@0.8.7': + '@yuku-parser/binding-linux-x64-musl@0.9.3': optional: true - '@yuku-parser/binding-win32-arm64@0.8.7': + '@yuku-parser/binding-win32-arm64@0.9.3': optional: true - '@yuku-parser/binding-win32-x64@0.8.7': + '@yuku-parser/binding-win32-x64@0.9.3': optional: true - '@yuku-toolchain/types@0.8.7': {} + '@yuku-toolchain/types@0.9.3': {} JSONStream@1.3.5: dependencies: @@ -12174,7 +12112,7 @@ snapshots: autoprefixer@10.5.4(postcss@8.5.26): dependencies: browserslist: 4.28.8 - caniuse-lite: 1.0.30001809 + caniuse-lite: 1.0.30001810 fraction.js: 5.3.4 picocolors: 1.1.1 postcss: 8.5.26 @@ -12207,13 +12145,13 @@ snapshots: balanced-match@4.0.4: {} - bare-events@2.9.1: {} + bare-events@2.9.2: {} - bare-fs@4.8.0: + bare-fs@4.8.1: dependencies: - bare-events: 2.9.1 + bare-events: 2.9.2 bare-path: 3.1.1 - bare-stream: 2.13.3(bare-events@2.9.1) + bare-stream: 2.13.4(bare-events@2.9.2) bare-url: 2.5.2 fast-fifo: 1.3.2 transitivePeerDependencies: @@ -12222,13 +12160,13 @@ snapshots: bare-path@3.1.1: {} - bare-stream@2.13.3(bare-events@2.9.1): + bare-stream@2.13.4(bare-events@2.9.2): dependencies: b4a: 1.8.1 - streamx: 2.28.0 + streamx: 2.28.1 teex: 1.0.1 optionalDependencies: - bare-events: 2.9.1 + bare-events: 2.9.2 transitivePeerDependencies: - react-native-b4a @@ -12240,7 +12178,7 @@ snapshots: base64id@2.0.0: {} - baseline-browser-mapping@2.11.18: {} + baseline-browser-mapping@2.11.20: {} batch@0.6.1: {} @@ -12301,7 +12239,7 @@ snapshots: http-errors: 2.0.1 iconv-lite: 0.7.3 on-finished: 2.4.1 - qs: 6.15.3 + qs: 6.16.0 raw-body: 3.0.2 type-is: 2.1.0 transitivePeerDependencies: @@ -12395,11 +12333,11 @@ snapshots: browserslist@4.28.8: dependencies: - baseline-browser-mapping: 2.11.18 - caniuse-lite: 1.0.30001809 - electron-to-chromium: 1.5.412 - node-releases: 2.0.53 - update-browserslist-db: 1.3.1(browserslist@4.28.8) + baseline-browser-mapping: 2.11.20 + caniuse-lite: 1.0.30001810 + electron-to-chromium: 1.5.417 + node-releases: 2.0.54 + update-browserslist-db: 1.3.2(browserslist@4.28.8) bs-recipes@1.3.4: {} @@ -12457,7 +12395,7 @@ snapshots: callsites@3.1.0: {} - caniuse-lite@1.0.30001809: {} + caniuse-lite@1.0.30001810: {} caseless@0.12.0: {} @@ -12657,7 +12595,7 @@ snapshots: glob-parent: 6.0.2 normalize-path: 3.0.0 schema-utils: 4.3.3 - serialize-javascript: 7.1.0 + serialize-javascript: 7.1.1 tinyglobby: 0.2.17 webpack: 5.109.2(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.26)(uglify-js@3.19.3) @@ -12678,7 +12616,7 @@ snapshots: dependencies: env-paths: 2.2.1 import-fresh: 3.3.1 - js-yaml: 4.3.1 + js-yaml: 4.3.2 parse-json: 5.2.0 optionalDependencies: typescript: 6.0.3 @@ -12913,7 +12851,7 @@ snapshots: ejs@6.0.1: {} - electron-to-chromium@1.5.412: {} + electron-to-chromium@1.5.417: {} emoji-regex@10.6.0: {} @@ -13280,7 +13218,7 @@ snapshots: events-universal@1.0.1: dependencies: - bare-events: 2.9.1 + bare-events: 2.9.2 transitivePeerDependencies: - bare-abort-controller @@ -13348,7 +13286,7 @@ snapshots: once: 1.4.0 parseurl: 1.3.3 proxy-addr: 2.0.7 - qs: 6.15.3 + qs: 6.16.0 range-parser: 1.3.0 router: 2.2.0(supports-color@11.0.0) send: 1.2.1(supports-color@11.0.0) @@ -13391,7 +13329,7 @@ snapshots: dependencies: fast-string-width: 3.0.2 - fastq@1.20.1: + fastq@1.20.3: dependencies: reusify: 1.1.0 @@ -13666,7 +13604,7 @@ snapshots: es-errors: 1.3.0 get-intrinsic: 1.3.0 - get-tsconfig@5.0.0-beta.5: + get-tsconfig@5.0.0-beta.6: dependencies: resolve-pkg-maps: 1.0.0 @@ -13761,7 +13699,7 @@ snapshots: node-fetch: 3.3.2 object-hash: 3.0.0 proto3-json-serializer: 3.0.4 - protobufjs: 7.6.5 + protobufjs: 7.6.6 retry-request: 8.0.4(supports-color@11.0.0) rimraf: 5.0.10 transitivePeerDependencies: @@ -13783,7 +13721,7 @@ snapshots: keyv: 5.6.0 lowercase-keys: 4.0.1 responselike: 4.0.2 - type-fest: 5.8.0 + type-fest: 5.9.0 uint8array-extras: 1.5.0 graceful-fs@4.2.11: {} @@ -13798,7 +13736,7 @@ snapshots: grpc-gcp@1.1.1: dependencies: '@grpc/grpc-js': 1.14.4 - protobufjs: 7.6.5 + protobufjs: 7.6.6 gtoken@8.0.0(supports-color@11.0.0): dependencies: @@ -13977,7 +13915,7 @@ snapshots: ignore@5.3.2: {} - ignore@7.0.6: {} + ignore@7.0.7: {} immutable@3.8.4: {} @@ -14289,7 +14227,7 @@ snapshots: js-tokens@4.0.0: {} - js-yaml@4.3.1: + js-yaml@4.3.2: dependencies: argparse: 2.0.1 @@ -14304,7 +14242,7 @@ snapshots: '@asamuzakjp/css-color': 6.0.7 '@asamuzakjp/dom-selector': 8.3.2 '@bramus/specificity': 2.4.2 - '@csstools/css-syntax-patches-for-csstree': 1.1.8(css-tree@3.2.1) + '@csstools/css-syntax-patches-for-csstree': 1.1.10(css-tree@3.2.1) '@exodus/bytes': 1.15.1 css-tree: 3.2.1 data-urls: 7.0.0 @@ -14678,11 +14616,11 @@ snapshots: magic-string@0.30.21: dependencies: - '@jridgewell/sourcemap-codec': 1.5.5 + '@jridgewell/sourcemap-codec': 1.6.0 magic-string@1.2.2: dependencies: - '@jridgewell/sourcemap-codec': 1.5.5 + '@jridgewell/sourcemap-codec': 1.6.0 magicast@0.5.4: dependencies: @@ -14705,16 +14643,16 @@ snapshots: media-typer@1.1.1: {} - memfs@4.68.1: + memfs@4.68.2: dependencies: - '@jsonjoy.com/fs-core': 4.68.1(tslib@2.8.1) - '@jsonjoy.com/fs-fsa': 4.68.1(tslib@2.8.1) - '@jsonjoy.com/fs-node': 4.68.1(tslib@2.8.1) - '@jsonjoy.com/fs-node-builtins': 4.68.1(tslib@2.8.1) - '@jsonjoy.com/fs-node-to-fsa': 4.68.1(tslib@2.8.1) - '@jsonjoy.com/fs-node-utils': 4.68.1(tslib@2.8.1) - '@jsonjoy.com/fs-print': 4.68.1(tslib@2.8.1) - '@jsonjoy.com/fs-snapshot': 4.68.1(tslib@2.8.1) + '@jsonjoy.com/fs-core': 4.68.2(tslib@2.8.1) + '@jsonjoy.com/fs-fsa': 4.68.2(tslib@2.8.1) + '@jsonjoy.com/fs-node': 4.68.2(tslib@2.8.1) + '@jsonjoy.com/fs-node-builtins': 4.68.2(tslib@2.8.1) + '@jsonjoy.com/fs-node-to-fsa': 4.68.2(tslib@2.8.1) + '@jsonjoy.com/fs-node-utils': 4.68.2(tslib@2.8.1) + '@jsonjoy.com/fs-print': 4.68.2(tslib@2.8.1) + '@jsonjoy.com/fs-snapshot': 4.68.2(tslib@2.8.1) '@jsonjoy.com/json-pack': 1.21.0(tslib@2.8.1) '@jsonjoy.com/util': 1.9.0(tslib@2.8.1) glob-to-regex.js: 1.2.0(tslib@2.8.1) @@ -14783,12 +14721,12 @@ snapshots: minimist@1.2.8: {} - minimizer-webpack-plugin@5.6.1(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.26)(uglify-js@3.19.3)(webpack@5.109.2(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.26)(uglify-js@3.19.3)): + minimizer-webpack-plugin@5.8.0(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.26)(uglify-js@3.19.3)(webpack@5.109.2(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.26)(uglify-js@3.19.3)): dependencies: '@jridgewell/trace-mapping': 0.3.31 jest-worker: 27.5.1 schema-utils: 4.3.3 - terser: 5.50.0 + terser: 5.51.2 webpack: 5.109.2(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.26)(uglify-js@3.19.3) optionalDependencies: esbuild: 0.28.2 @@ -14796,12 +14734,12 @@ snapshots: postcss: 8.5.26 uglify-js: 3.19.3 - minimizer-webpack-plugin@5.6.1(esbuild@0.28.2)(webpack@5.109.2(esbuild@0.28.2)): + minimizer-webpack-plugin@5.8.0(esbuild@0.28.2)(webpack@5.109.2(esbuild@0.28.2)): dependencies: '@jridgewell/trace-mapping': 0.3.31 jest-worker: 27.5.1 schema-utils: 4.3.3 - terser: 5.50.0 + terser: 5.51.2 webpack: 5.109.2(esbuild@0.28.2) optionalDependencies: esbuild: 0.28.2 @@ -14903,7 +14841,7 @@ snapshots: piscina: 5.3.1 postcss: 8.5.26 rolldown: 1.2.5 - rolldown-plugin-dts: 0.28.2(rolldown@1.2.5)(typescript@6.0.3) + rolldown-plugin-dts: 0.28.4(rolldown@1.2.5)(typescript@6.0.3) rxjs: 7.8.2 sass: 1.103.1 tinyglobby: 0.2.17 @@ -14957,7 +14895,7 @@ snapshots: node-gyp-build@4.8.4: {} - node-releases@2.0.53: {} + node-releases@2.0.54: {} normalize-path@3.0.0: {} @@ -15046,7 +14984,7 @@ snapshots: define-lazy-prop: 3.0.0 is-in-ssh: 1.0.0 is-inside-container: 1.0.0 - powershell-utils: 0.2.0 + powershell-utils: 0.2.1 wsl-utils: 1.0.0 opn@5.3.0: @@ -15318,7 +15256,7 @@ snapshots: powershell-utils@0.1.0: {} - powershell-utils@0.2.0: {} + powershell-utils@0.2.1: {} prelude-ls@1.2.1: {} @@ -15347,9 +15285,9 @@ snapshots: proto3-json-serializer@3.0.4: dependencies: - protobufjs: 7.6.5 + protobufjs: 7.6.6 - protobufjs@7.6.5: + protobufjs@7.6.6: dependencies: '@protobufjs/aspromise': 1.1.2 '@protobufjs/base64': 1.1.2 @@ -15429,6 +15367,11 @@ snapshots: es-define-property: 1.0.1 side-channel: 1.1.1 + qs@6.16.0: + dependencies: + es-define-property: 1.0.1 + side-channel: 1.1.1 + queue-microtask@1.2.3: {} quick-format-unescaped@4.0.4: {} @@ -15629,15 +15572,15 @@ snapshots: dependencies: glob: 10.5.0 - rolldown-plugin-dts@0.28.2(rolldown@1.2.5)(typescript@6.0.3): + rolldown-plugin-dts@0.28.4(rolldown@1.2.5)(typescript@6.0.3): dependencies: dts-resolver: 3.0.0 - get-tsconfig: 5.0.0-beta.5 + get-tsconfig: 5.0.0-beta.6 obug: 2.1.4 rolldown: 1.2.5 - yuku-ast: 0.8.7 - yuku-codegen: 0.8.7 - yuku-parser: 0.8.7 + yuku-ast: 0.9.3 + yuku-codegen: 0.9.3 + yuku-parser: 0.9.3 optionalDependencies: typescript: 6.0.3 transitivePeerDependencies: @@ -15674,7 +15617,7 @@ snapshots: rollup-plugin-dts@6.5.1(rollup@4.63.0)(typescript@6.0.3): dependencies: '@jridgewell/remapping': 2.3.5 - '@jridgewell/sourcemap-codec': 1.5.5 + '@jridgewell/sourcemap-codec': 1.6.0 convert-source-map: 2.0.0 magic-string: 0.30.21 rollup: 4.63.0 @@ -15932,7 +15875,7 @@ snapshots: transitivePeerDependencies: - supports-color - serialize-javascript@7.1.0: {} + serialize-javascript@7.1.1: {} serve-index@1.9.2(supports-color@11.0.0): dependencies: @@ -16198,7 +16141,7 @@ snapshots: transitivePeerDependencies: - supports-color - streamx@2.28.0: + streamx@2.28.1: dependencies: events-universal: 1.0.1 fast-fifo: 1.3.2 @@ -16305,9 +16248,9 @@ snapshots: tar-stream@3.2.0: dependencies: b4a: 1.8.1 - bare-fs: 4.8.0 + bare-fs: 4.8.1 fast-fifo: 1.3.2 - streamx: 2.28.0 + streamx: 2.28.1 transitivePeerDependencies: - bare-abort-controller - bare-buffer @@ -16316,9 +16259,9 @@ snapshots: tar-stream@3.2.1: dependencies: b4a: 1.8.1 - bare-fs: 4.8.0 + bare-fs: 4.8.1 fast-fifo: 1.3.2 - streamx: 2.28.0 + streamx: 2.28.1 transitivePeerDependencies: - bare-abort-controller - bare-buffer @@ -16335,7 +16278,7 @@ snapshots: teex@1.0.1: dependencies: - streamx: 2.28.0 + streamx: 2.28.1 transitivePeerDependencies: - bare-abort-controller - react-native-b4a @@ -16347,6 +16290,13 @@ snapshots: commander: 2.20.3 source-map-support: 0.5.21 + terser@5.51.2: + dependencies: + '@jridgewell/source-map': 0.3.11 + acorn: 8.18.0 + commander: 2.20.3 + source-map-support: 0.5.21 + text-decoder@1.2.7: dependencies: b4a: 1.8.1 @@ -16389,15 +16339,15 @@ snapshots: tldts-core@6.1.86: {} - tldts-core@7.4.10: {} + tldts-core@7.4.11: {} tldts@6.1.86: dependencies: tldts-core: 6.1.86 - tldts@7.4.10: + tldts@7.4.11: dependencies: - tldts-core: 7.4.10 + tldts-core: 7.4.11 tmp@0.2.7: {} @@ -16415,7 +16365,7 @@ snapshots: tough-cookie@6.0.2: dependencies: - tldts: 7.4.10 + tldts: 7.4.11 tr46@0.0.3: {} @@ -16470,7 +16420,7 @@ snapshots: dependencies: prelude-ls: 1.2.1 - type-fest@5.8.0: + type-fest@5.9.0: dependencies: tagged-tag: 1.0.0 @@ -16589,7 +16539,7 @@ snapshots: unpipe@1.0.0: {} - update-browserslist-db@1.3.1(browserslist@4.28.8): + update-browserslist-db@1.3.2(browserslist@4.28.8): dependencies: browserslist: 4.28.8 escalade: 3.2.0 @@ -16630,9 +16580,9 @@ snapshots: - encoding - supports-color - verdaccio-auth-memory@13.1.2(supports-color@11.0.0): + verdaccio-auth-memory@13.1.3(supports-color@11.0.0): dependencies: - '@verdaccio/core': 8.2.2 + '@verdaccio/core': 8.3.0 debug: 4.4.3(supports-color@11.0.0) transitivePeerDependencies: - supports-color @@ -16695,7 +16645,7 @@ snapshots: core-util-is: 1.0.2 extsprintf: 1.3.0 - vite@8.2.2(@types/node@22.20.1)(esbuild@0.28.2)(jiti@2.7.0)(less@4.9.0(supports-color@11.0.0))(sass-embedded@1.103.1)(sass@1.103.1)(terser@5.50.0)(tsx@4.23.12)(yaml@2.9.0): + vite@8.2.2(@types/node@22.20.1)(esbuild@0.28.2)(jiti@2.7.0)(less@4.9.0(supports-color@11.0.0))(sass-embedded@1.103.1)(sass@1.103.1)(terser@5.51.2)(tsx@4.23.12)(yaml@2.9.0): dependencies: lightningcss: 1.33.0 picomatch: 4.0.7 @@ -16710,14 +16660,14 @@ snapshots: less: 4.9.0(supports-color@11.0.0) sass: 1.103.1 sass-embedded: 1.103.1 - terser: 5.50.0 + terser: 5.51.2 tsx: 4.23.12 yaml: 2.9.0 - vitest@4.1.11(@opentelemetry/api@1.9.1)(@types/node@22.20.1)(@vitest/coverage-v8@4.1.11)(esbuild@0.28.2)(jiti@2.7.0)(jsdom@30.0.1)(less@4.9.0(supports-color@11.0.0))(sass-embedded@1.103.1)(sass@1.103.1)(terser@5.50.0)(tsx@4.23.12)(yaml@2.9.0): + vitest@4.1.11(@opentelemetry/api@1.9.1)(@types/node@22.20.1)(@vitest/coverage-v8@4.1.11)(esbuild@0.28.2)(jiti@2.7.0)(jsdom@30.0.1)(less@4.9.0(supports-color@11.0.0))(sass-embedded@1.103.1)(sass@1.103.1)(terser@5.51.2)(tsx@4.23.12)(yaml@2.9.0): dependencies: '@vitest/expect': 4.1.11 - '@vitest/mocker': 4.1.11(vite@8.2.2(@types/node@22.20.1)(esbuild@0.28.2)(jiti@2.7.0)(less@4.9.0(supports-color@11.0.0))(sass-embedded@1.103.1)(sass@1.103.1)(terser@5.50.0)(tsx@4.23.12)(yaml@2.9.0)) + '@vitest/mocker': 4.1.11(vite@8.2.2(@types/node@22.20.1)(esbuild@0.28.2)(jiti@2.7.0)(less@4.9.0(supports-color@11.0.0))(sass-embedded@1.103.1)(sass@1.103.1)(terser@5.51.2)(tsx@4.23.12)(yaml@2.9.0)) '@vitest/pretty-format': 4.1.11 '@vitest/runner': 4.1.11 '@vitest/snapshot': 4.1.11 @@ -16734,7 +16684,7 @@ snapshots: tinyexec: 1.3.0 tinyglobby: 0.2.17 tinyrainbow: 3.1.1 - vite: 8.2.2(@types/node@22.20.1)(esbuild@0.28.2)(jiti@2.7.0)(less@4.9.0(supports-color@11.0.0))(sass-embedded@1.103.1)(sass@1.103.1)(terser@5.50.0)(tsx@4.23.12)(yaml@2.9.0) + vite: 8.2.2(@types/node@22.20.1)(esbuild@0.28.2)(jiti@2.7.0)(less@4.9.0(supports-color@11.0.0))(sass-embedded@1.103.1)(sass@1.103.1)(terser@5.51.2)(tsx@4.23.12)(yaml@2.9.0) why-is-node-running: 2.3.0 optionalDependencies: '@opentelemetry/api': 1.9.1 @@ -16780,7 +16730,7 @@ snapshots: webpack-dev-middleware@8.1.1(webpack@5.109.2(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.26)(uglify-js@3.19.3)): dependencies: - memfs: 4.68.1 + memfs: 4.68.2 mime-types: 3.0.2 range-parser: 1.3.0 schema-utils: 4.3.3 @@ -16850,7 +16800,7 @@ snapshots: events: 3.3.0 graceful-fs: 4.2.11 mime-db: 1.54.0 - minimizer-webpack-plugin: 5.6.1(esbuild@0.28.2)(webpack@5.109.2(esbuild@0.28.2)) + minimizer-webpack-plugin: 5.8.0(esbuild@0.28.2)(webpack@5.109.2(esbuild@0.28.2)) neo-async: 2.6.2 schema-utils: 4.3.3 tapable: 2.3.3 @@ -16886,7 +16836,7 @@ snapshots: events: 3.3.0 graceful-fs: 4.2.11 mime-db: 1.54.0 - minimizer-webpack-plugin: 5.6.1(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.26)(uglify-js@3.19.3)(webpack@5.109.2(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.26)(uglify-js@3.19.3)) + minimizer-webpack-plugin: 5.8.0(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.26)(uglify-js@3.19.3)(webpack@5.109.2(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.26)(uglify-js@3.19.3)) neo-async: 2.6.2 schema-utils: 4.3.3 tapable: 2.3.3 @@ -17093,44 +17043,44 @@ snapshots: yoctocolors@2.2.0: {} - yuku-ast@0.8.7: + yuku-ast@0.9.3: dependencies: - '@yuku-toolchain/types': 0.8.7 + '@yuku-toolchain/types': 0.9.3 - yuku-codegen@0.8.7: + yuku-codegen@0.9.3: dependencies: - '@yuku-toolchain/types': 0.8.7 + '@yuku-toolchain/types': 0.9.3 optionalDependencies: - '@yuku-codegen/binding-android-arm64': 0.8.7 - '@yuku-codegen/binding-darwin-arm64': 0.8.7 - '@yuku-codegen/binding-darwin-x64': 0.8.7 - '@yuku-codegen/binding-freebsd-x64': 0.8.7 - '@yuku-codegen/binding-linux-arm-gnu': 0.8.7 - '@yuku-codegen/binding-linux-arm-musl': 0.8.7 - '@yuku-codegen/binding-linux-arm64-gnu': 0.8.7 - '@yuku-codegen/binding-linux-arm64-musl': 0.8.7 - '@yuku-codegen/binding-linux-x64-gnu': 0.8.7 - '@yuku-codegen/binding-linux-x64-musl': 0.8.7 - '@yuku-codegen/binding-win32-arm64': 0.8.7 - '@yuku-codegen/binding-win32-x64': 0.8.7 - - yuku-parser@0.8.7: - dependencies: - '@yuku-toolchain/types': 0.8.7 - yuku-ast: 0.8.7 + '@yuku-codegen/binding-android-arm64': 0.9.3 + '@yuku-codegen/binding-darwin-arm64': 0.9.3 + '@yuku-codegen/binding-darwin-x64': 0.9.3 + '@yuku-codegen/binding-freebsd-x64': 0.9.3 + '@yuku-codegen/binding-linux-arm-gnu': 0.9.3 + '@yuku-codegen/binding-linux-arm-musl': 0.9.3 + '@yuku-codegen/binding-linux-arm64-gnu': 0.9.3 + '@yuku-codegen/binding-linux-arm64-musl': 0.9.3 + '@yuku-codegen/binding-linux-x64-gnu': 0.9.3 + '@yuku-codegen/binding-linux-x64-musl': 0.9.3 + '@yuku-codegen/binding-win32-arm64': 0.9.3 + '@yuku-codegen/binding-win32-x64': 0.9.3 + + yuku-parser@0.9.3: + dependencies: + '@yuku-toolchain/types': 0.9.3 + yuku-ast: 0.9.3 optionalDependencies: - '@yuku-parser/binding-android-arm64': 0.8.7 - '@yuku-parser/binding-darwin-arm64': 0.8.7 - '@yuku-parser/binding-darwin-x64': 0.8.7 - '@yuku-parser/binding-freebsd-x64': 0.8.7 - '@yuku-parser/binding-linux-arm-gnu': 0.8.7 - '@yuku-parser/binding-linux-arm-musl': 0.8.7 - '@yuku-parser/binding-linux-arm64-gnu': 0.8.7 - '@yuku-parser/binding-linux-arm64-musl': 0.8.7 - '@yuku-parser/binding-linux-x64-gnu': 0.8.7 - '@yuku-parser/binding-linux-x64-musl': 0.8.7 - '@yuku-parser/binding-win32-arm64': 0.8.7 - '@yuku-parser/binding-win32-x64': 0.8.7 + '@yuku-parser/binding-android-arm64': 0.9.3 + '@yuku-parser/binding-darwin-arm64': 0.9.3 + '@yuku-parser/binding-darwin-x64': 0.9.3 + '@yuku-parser/binding-freebsd-x64': 0.9.3 + '@yuku-parser/binding-linux-arm-gnu': 0.9.3 + '@yuku-parser/binding-linux-arm-musl': 0.9.3 + '@yuku-parser/binding-linux-arm64-gnu': 0.9.3 + '@yuku-parser/binding-linux-arm64-musl': 0.9.3 + '@yuku-parser/binding-linux-x64-gnu': 0.9.3 + '@yuku-parser/binding-linux-x64-musl': 0.9.3 + '@yuku-parser/binding-win32-arm64': 0.9.3 + '@yuku-parser/binding-win32-x64': 0.9.3 zod@3.25.76: {} From 989abb3299c12d539e111f8e09c51656e7089865 Mon Sep 17 00:00:00 2001 From: Charles Lyding <19598772+clydin@users.noreply.github.com> Date: Mon, 31 Aug 2026 14:38:26 -0400 Subject: [PATCH 388/787] refactor(@angular/build): dynamically load @babel/core in transformer worker By default, JavaScript transformations use the native OXC engine for Angular linking and advanced optimizations. The Babel-based linker is only utilized when the NG_BUILD_BABEL_LINKER environment variable is explicitly enabled. Previously, transformAsync was imported statically at the top level of javascript-transformer-worker.ts, causing Node.js to eagerly evaluate @babel/core and all its transitive dependencies on startup across every Piscina worker thread. Importing @babel/core dynamically only when the Babel linker fallback is active reduces worker thread startup latency and eliminates unnecessary worker idle memory overhead on standard builds. --- .../esbuild/javascript-transformer-worker.ts | 21 ++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-) diff --git a/packages/angular/build/src/tools/esbuild/javascript-transformer-worker.ts b/packages/angular/build/src/tools/esbuild/javascript-transformer-worker.ts index f2ec7eccce6d..99ef235f3279 100644 --- a/packages/angular/build/src/tools/esbuild/javascript-transformer-worker.ts +++ b/packages/angular/build/src/tools/esbuild/javascript-transformer-worker.ts @@ -7,7 +7,7 @@ */ import remapping, { type DecodedSourceMap, type EncodedSourceMap } from '@ampproject/remapping'; -import { type PluginItem, transformAsync } from '@babel/core'; +import type { PluginItem } from '@babel/core'; import { createRequire } from 'node:module'; import { workerData } from 'node:worker_threads'; import Piscina from 'piscina'; @@ -42,6 +42,16 @@ const { jit = false, } = (workerData || {}) as Partial; +let babelLinkerDeps: + | Promise< + [ + typeof import('@angular/compiler-cli/linker/babel'), + typeof import('@angular/compiler-cli'), + typeof import('@babel/core'), + ] + > + | undefined; + const textDecoder = new TextDecoder(); const textEncoder = new TextEncoder(); @@ -170,8 +180,13 @@ async function transformJavaScriptImpl( } if (shouldLink && useBabelLinker) { - const { createEs2015LinkerPlugin } = await import('@angular/compiler-cli/linker/babel'); - const { ConsoleLogger, LogLevel } = await import('@angular/compiler-cli'); + babelLinkerDeps ??= Promise.all([ + import('@angular/compiler-cli/linker/babel'), + import('@angular/compiler-cli'), + import('@babel/core'), + ]); + const [{ createEs2015LinkerPlugin }, { ConsoleLogger, LogLevel }, { transformAsync }] = + await babelLinkerDeps; const result = await transformAsync(code, { filename, From 18e4b93a9f092506d64fb0995fd1229f6e62d8e9 Mon Sep 17 00:00:00 2001 From: Charles Lyding <19598772+clydin@users.noreply.github.com> Date: Mon, 31 Aug 2026 14:39:21 -0400 Subject: [PATCH 389/787] refactor(@angular/build): use boundary resolution for sourcemap generation in oxc transform Generating high-resolution sourcemap tokens for every character with hires: true produces substantially larger intermediate decoded mappings and increases peak memory consumption during sourcemap remapping. Using hires: 'boundary' generates tokens only at identifier and word boundaries. This significantly reduces decoded sourcemap memory footprint and remapping time while retaining full debugging accuracy. --- packages/angular/build/src/tools/oxc/oxc-transform.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/angular/build/src/tools/oxc/oxc-transform.ts b/packages/angular/build/src/tools/oxc/oxc-transform.ts index 0ebbc04ec1e5..e4f60ff83cb2 100644 --- a/packages/angular/build/src/tools/oxc/oxc-transform.ts +++ b/packages/angular/build/src/tools/oxc/oxc-transform.ts @@ -737,7 +737,7 @@ export function transform(filename: string, code: string, options: OxcTransformO let map: DecodedSourceMap | undefined; if (options.sourcemap) { - const rawMap = source.generateDecodedMap({ hires: true, source: filename }); + const rawMap = source.generateDecodedMap({ hires: 'boundary', source: filename }); map = { ...rawMap, version: 3 }; } From b6786dc91b25b3438c0c698047026407e20f6ec9 Mon Sep 17 00:00:00 2001 From: Charles Lyding <19598772+clydin@users.noreply.github.com> Date: Tue, 1 Sep 2026 09:56:17 -0400 Subject: [PATCH 390/787] refactor(@angular/build): add typed helper for worker pool execution in i18n inliner Add a strongly-typed private helper method #runWorkerTask to I18nInliner to encapsulate worker pool execution. The helper maps worker task names ('inlineFileBatch' and 'inlineCode') to their exact request and result types exported from the worker module. This eliminates manual type assertions and untyped return values while centralizing worker pool task dispatch. --- .../src/tools/esbuild/i18n-inliner-worker.ts | 18 +++- .../build/src/tools/esbuild/i18n-inliner.ts | 95 ++++++++++--------- 2 files changed, 64 insertions(+), 49 deletions(-) diff --git a/packages/angular/build/src/tools/esbuild/i18n-inliner-worker.ts b/packages/angular/build/src/tools/esbuild/i18n-inliner-worker.ts index 2804e0ef8a9e..bc471dcb675e 100644 --- a/packages/angular/build/src/tools/esbuild/i18n-inliner-worker.ts +++ b/packages/angular/build/src/tools/esbuild/i18n-inliner-worker.ts @@ -21,7 +21,7 @@ import { createSharedTranslationProxy } from './i18n-translation-reader'; /** * The options passed to the inliner for each code request */ -interface InlineCodeRequest { +export interface InlineCodeRequest { /** * The code that should be processed. */ @@ -45,10 +45,18 @@ interface InlineCodeRequest { translation?: Blob | SharedArrayBuffer; } +/** + * The response returned from a code request. + */ +export interface InlineCodeResult { + output: string; + messages: { type: 'error' | 'warning'; message: string }[]; +} + /** * The options passed to the inliner for a batch file request */ -interface InlineFileBatchRequest { +export interface InlineFileBatchRequest { /** * The filename that should be processed. */ @@ -91,7 +99,7 @@ interface InlineFileBatchRequest { /** * The result for a single locale within a batch file request. */ -interface InlineLocaleResult { +export interface InlineLocaleResult { locale: string; code?: string; map?: string; @@ -101,7 +109,7 @@ interface InlineLocaleResult { /** * The response returned from a batch file request. */ -type InlineFileBatchResult = +export type InlineFileBatchResult = | { file: string; unmodified: true; @@ -292,7 +300,7 @@ export async function inlineFileBatch( * @param request An InlineRequest object representing the options for inlining * @returns An object containing the inlined code. */ -export async function inlineCode(request: InlineCodeRequest) { +export async function inlineCode(request: InlineCodeRequest): Promise { const metadata = extractLocalizeMetadata(request.filename, request.code); const result = await inlineLocalize( request.code, diff --git a/packages/angular/build/src/tools/esbuild/i18n-inliner.ts b/packages/angular/build/src/tools/esbuild/i18n-inliner.ts index 84d302428342..be3c73bdfce4 100644 --- a/packages/angular/build/src/tools/esbuild/i18n-inliner.ts +++ b/packages/angular/build/src/tools/esbuild/i18n-inliner.ts @@ -14,8 +14,25 @@ import { calculateHash, createContentHash, initializeHash } from '../../utils/ha import { WorkerPool } from '../../utils/worker-pool'; import { type BuildOutputFile, BuildOutputFileType, createOutputFile } from './bundler-files'; import { type Cache, type PersistentCacheStore, createPersistentCacheStore } from './cache'; +import type { + InlineCodeRequest, + InlineCodeResult, + InlineFileBatchRequest, + InlineFileBatchResult, +} from './i18n-inliner-worker'; import { encodeTranslationToBuffer } from './i18n-translation-encoder'; +interface WorkerTaskMap { + inlineFileBatch: { + request: InlineFileBatchRequest; + result: InlineFileBatchResult; + }; + inlineCode: { + request: InlineCodeRequest; + result: InlineCodeResult; + }; +} + /** * A keyword used to indicate if a JavaScript file may require inlining of translations. * This keyword is used to avoid processing files that would not otherwise need i18n processing. @@ -492,28 +509,15 @@ export class I18nInliner { for (let i = 0; i < entries.length; i += localesPerBatch) { const batchEntries = entries.slice(i, i + localesPerBatch); const task = (async () => { - const batchResult = (await this.#workerPool.run( - { - filename, - code: codeBlob, - map: mapBlob, - locales: new Map(batchEntries.map((e) => [e.locale, e.translation])), - ephemeral, - activeLocales, - generation, - }, - { name: 'inlineFileBatch' }, - )) as - | { - file: string; - unmodified: true; - messages: { type: 'error' | 'warning'; message: string }[]; - } - | { - file: string; - unmodified?: false; - results: Array; - }; + const batchResult = await this.#runWorkerTask('inlineFileBatch', { + filename, + code: codeBlob, + map: mapBlob, + locales: new Map(batchEntries.map((e) => [e.locale, e.translation])), + ephemeral, + activeLocales, + generation, + }); if (batchResult.unmodified) { const unmodifiedResult: TransformedFileResult = { @@ -535,19 +539,18 @@ export class I18nInliner { for (const res of batchResult.results) { const matchingEntry = batchEntries.find((e) => e.locale === res.locale); const cacheKey = matchingEntry?.cacheKey; + const fileResult: TransformedFileResult = { + file: filename, + code: res.code, + map: res.map, + messages: res.messages, + }; if (this.#transformedFileCache && cacheKey) { - cachePromises.push( - this.#transformedFileCache.put(cacheKey, { - file: filename, - code: res.code, - map: res.map, - messages: res.messages, - }), - ); + cachePromises.push(this.#transformedFileCache.put(cacheKey, fileResult)); } - fileResultsByLocale.get(res.locale)?.set(filename, res); + fileResultsByLocale.get(res.locale)?.set(filename, fileResult); } await Promise.allSettled(cachePromises); } @@ -560,6 +563,13 @@ export class I18nInliner { await Promise.all(workerTasks); } + #runWorkerTask( + name: T, + request: WorkerTaskMap[T]['request'], + ): Promise { + return this.#workerPool.run(request, { name }) as Promise; + } + /** * Performs inlining of translations for the provided locale and translations. * @@ -599,19 +609,16 @@ export class I18nInliner { }; } - const { output, messages } = await this.#workerPool.run( - { - code: templateCode, - filename: templateId, - locale, - translation: await serializeTranslation( - translation, - translationIntegrity, - this.#translationCache, - ), - }, - { name: 'inlineCode' }, - ); + const { output, messages } = await this.#runWorkerTask('inlineCode', { + code: templateCode, + filename: templateId, + locale, + translation: await serializeTranslation( + translation, + translationIntegrity, + this.#translationCache, + ), + }); const errors: string[] = []; const warnings: string[] = []; From ed189a2a2721daea92e184e663acdce30873f932 Mon Sep 17 00:00:00 2001 From: Charles Lyding <19598772+clydin@users.noreply.github.com> Date: Tue, 1 Sep 2026 18:07:09 -0400 Subject: [PATCH 391/787] refactor(@angular/build): pass missingTranslation per request in i18n inliner Remove workerData from the i18n inliner worker pool initialization and pass missingTranslation per task in the request payload. This decouples the worker pool from inliner-specific options, allowing worker threads to be safely shared without hardcoding the missingTranslation handling behavior at pool creation time. --- .../src/tools/esbuild/i18n-inliner-worker.ts | 20 ++++++++++----- .../build/src/tools/esbuild/i18n-inliner.ts | 8 ++---- .../src/tools/esbuild/i18n-inliner_spec.ts | 25 +++++++++++++++++++ 3 files changed, 41 insertions(+), 12 deletions(-) diff --git a/packages/angular/build/src/tools/esbuild/i18n-inliner-worker.ts b/packages/angular/build/src/tools/esbuild/i18n-inliner-worker.ts index bc471dcb675e..ac75ab246d8d 100644 --- a/packages/angular/build/src/tools/esbuild/i18n-inliner-worker.ts +++ b/packages/angular/build/src/tools/esbuild/i18n-inliner-worker.ts @@ -12,7 +12,6 @@ import type { Node } from '@oxc-project/types'; import { MagicString } from 'magic-string'; import assert from 'node:assert'; import { deserialize } from 'node:v8'; -import { workerData } from 'node:worker_threads'; import { parseSync } from 'oxc-parser'; import { traversePostOrder } from '../oxc/traversal'; import { loadLocaleData } from './i18n-locale-plugin'; @@ -43,6 +42,11 @@ export interface InlineCodeRequest { * the Worker by reference instead of being copied into it for every request. */ translation?: Blob | SharedArrayBuffer; + + /** + * How to handle missing translations. + */ + missingTranslation?: 'error' | 'warning' | 'ignore'; } /** @@ -77,6 +81,11 @@ export interface InlineFileBatchRequest { */ locales: ReadonlyMap; + /** + * How to handle missing translations. + */ + missingTranslation?: 'error' | 'warning' | 'ignore'; + /** * Whether the file data should be treated as ephemeral and not cached long-term in the Worker. * Typically true when all remaining locales for the file are processed in a single batch. @@ -121,11 +130,6 @@ export type InlineFileBatchResult = results: InlineLocaleResult[]; }; -// Extract common options used for inline requests from the Worker context -const { missingTranslation } = (workerData || {}) as { - missingTranslation: 'error' | 'warning' | 'ignore'; -}; - /** * Cached file data including code and extracted localization metadata. */ @@ -276,6 +280,7 @@ export async function inlineFileBatch( locale, await loadTranslation(locale, translation), request.filename, + request.missingTranslation, ); return { @@ -309,6 +314,7 @@ export async function inlineCode(request: InlineCodeRequest): Promise | undefined, filename: string, + missingTranslation: 'error' | 'warning' | 'ignore' = 'warning', ) { const magicString = new MagicString(code); const { Diagnostics, translate } = await loadLocalizeTools(); diff --git a/packages/angular/build/src/tools/esbuild/i18n-inliner.ts b/packages/angular/build/src/tools/esbuild/i18n-inliner.ts index be3c73bdfce4..0b5cef389de3 100644 --- a/packages/angular/build/src/tools/esbuild/i18n-inliner.ts +++ b/packages/angular/build/src/tools/esbuild/i18n-inliner.ts @@ -186,15 +186,9 @@ export class I18nInliner { private readonly options: I18nInlinerOptions, maxThreads?: number, ) { - const { missingTranslation } = options; - this.#workerPool = new WorkerPool({ filename: require.resolve('./i18n-inliner-worker'), maxThreads, - // Extract options to ensure only the named options are serialized and sent to the worker - workerData: { - missingTranslation, - }, }); } @@ -514,6 +508,7 @@ export class I18nInliner { code: codeBlob, map: mapBlob, locales: new Map(batchEntries.map((e) => [e.locale, e.translation])), + missingTranslation: this.options.missingTranslation, ephemeral, activeLocales, generation, @@ -613,6 +608,7 @@ export class I18nInliner { code: templateCode, filename: templateId, locale, + missingTranslation: this.options.missingTranslation, translation: await serializeTranslation( translation, translationIntegrity, diff --git a/packages/angular/build/src/tools/esbuild/i18n-inliner_spec.ts b/packages/angular/build/src/tools/esbuild/i18n-inliner_spec.ts index 8059270145bb..e64efe2fa05b 100644 --- a/packages/angular/build/src/tools/esbuild/i18n-inliner_spec.ts +++ b/packages/angular/build/src/tools/esbuild/i18n-inliner_spec.ts @@ -144,6 +144,31 @@ describe('I18nInliner', () => { expect(findFile(outputFiles, 'main.js').text).toContain('"Hello"'); }); + it('errors and retains the original message when missingTranslation is "error"', async () => { + const { outputFiles, errors, warnings } = await createInliner({ + missingTranslation: 'error', + }).inlineForLocale([browserFile('main.js', GREETING_SOURCE)], 'fr', { + unrelated: translationFor('Sans rapport'), + }); + + expect(errors.length).toBe(1); + expect(errors[0]).toContain('greeting'); + expect(warnings).toEqual([]); + expect(findFile(outputFiles, 'main.js').text).toContain('"Hello"'); + }); + + it('ignores missing translations when missingTranslation is "ignore"', async () => { + const { outputFiles, errors, warnings } = await createInliner({ + missingTranslation: 'ignore', + }).inlineForLocale([browserFile('main.js', GREETING_SOURCE)], 'fr', { + unrelated: translationFor('Sans rapport'), + }); + + expect(errors).toEqual([]); + expect(warnings).toEqual([]); + expect(findFile(outputFiles, 'main.js').text).toContain('"Hello"'); + }); + it('replaces the locale placeholder with the locale being inlined', async () => { // The placeholder is only inlined for files that use `$localize`, which is where the build // inserts it, so the message is present alongside it here. From c35b43c25b5a4dc35400807e482d105ca85a3e0d Mon Sep 17 00:00:00 2001 From: Charles Lyding <19598772+clydin@users.noreply.github.com> Date: Tue, 1 Sep 2026 20:37:42 -0400 Subject: [PATCH 392/787] refactor(@angular/build): explicitly target worker script in i18n inliner task execution Specify the worker target file directly in each task run option via #runWorkerTask rather than hardcoding a default filename during WorkerPool instantiation. To prepare for ESM transition and avoid reliance on ambient require, createRequire is used to resolve the inliner worker script path. Explicitly specifying the worker file per task enables the inliner to run against general-purpose or shared worker pools that do not have a preconfigured default script. --- .../angular/build/src/tools/esbuild/i18n-inliner.ts | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/packages/angular/build/src/tools/esbuild/i18n-inliner.ts b/packages/angular/build/src/tools/esbuild/i18n-inliner.ts index 0b5cef389de3..212095c38761 100644 --- a/packages/angular/build/src/tools/esbuild/i18n-inliner.ts +++ b/packages/angular/build/src/tools/esbuild/i18n-inliner.ts @@ -8,6 +8,7 @@ import type { ɵParsedTranslation } from '@angular/localize'; import assert from 'node:assert'; +import { createRequire } from 'node:module'; import { extname, join } from 'node:path'; import { serialize } from 'node:v8'; import { calculateHash, createContentHash, initializeHash } from '../../utils/hash'; @@ -22,6 +23,10 @@ import type { } from './i18n-inliner-worker'; import { encodeTranslationToBuffer } from './i18n-translation-encoder'; +// TODO: Convert to import.meta usage during ESM transition +const localRequire = createRequire(__filename); +const INLINER_WORKER_PATH = localRequire.resolve('./i18n-inliner-worker'); + interface WorkerTaskMap { inlineFileBatch: { request: InlineFileBatchRequest; @@ -187,7 +192,6 @@ export class I18nInliner { maxThreads?: number, ) { this.#workerPool = new WorkerPool({ - filename: require.resolve('./i18n-inliner-worker'), maxThreads, }); } @@ -562,7 +566,10 @@ export class I18nInliner { name: T, request: WorkerTaskMap[T]['request'], ): Promise { - return this.#workerPool.run(request, { name }) as Promise; + return this.#workerPool.run(request, { + filename: INLINER_WORKER_PATH, + name, + }) as Promise; } /** From 88e3fc05073120820dad07af0311d9b6f3fdd717 Mon Sep 17 00:00:00 2001 From: Charles Lyding <19598772+clydin@users.noreply.github.com> Date: Mon, 31 Aug 2026 13:24:34 -0400 Subject: [PATCH 393/787] refactor(@angular/build): move compiler-cli loading to TypeScriptCompilation AngularCompilation serves as the top-level compilation contract used across the build pipeline, including on the main thread via ParallelCompilation. Neither AngularCompilation nor ParallelCompilation requires loading @angular/compiler-cli or reading tsconfig.json configurations. The loadCompilerCli and loadConfiguration methods are now moved to TypeScriptCompilation, which is the base class for in-process TypeScript compilations (AotCompilation and JitCompilation). This completely decouples AngularCompilation from @angular/compiler-cli and ensures that compiler-cli loading and configuration parsing are localized exclusively to the worker compilation hierarchy. --- .../compilation/angular-compilation.ts | 33 ------------------ .../compilation/angular-compilation_spec.ts | 6 ++++ .../angular/compilation/aot-compilation.ts | 7 ++-- .../angular/compilation/jit-compilation.ts | 5 ++- .../compilation/typescript-compilation.ts | 34 ++++++++++++++++++- 5 files changed, 44 insertions(+), 41 deletions(-) diff --git a/packages/angular/build/src/tools/angular/compilation/angular-compilation.ts b/packages/angular/build/src/tools/angular/compilation/angular-compilation.ts index ea1fe00d04aa..6bd836139c5f 100644 --- a/packages/angular/build/src/tools/angular/compilation/angular-compilation.ts +++ b/packages/angular/build/src/tools/angular/compilation/angular-compilation.ts @@ -6,9 +6,7 @@ * found in the LICENSE file at https://angular.dev/license */ -import type * as ng from '@angular/compiler-cli'; import type { PartialMessage } from 'esbuild'; -import { profileSync } from '../../esbuild/profiling'; import type { AngularHostOptions } from '../angular-host'; import type { CompilerOptionOverrides } from './compiler-options'; @@ -50,37 +48,6 @@ export enum DiagnosticModes { } export abstract class AngularCompilation { - static #angularCompilerCliModule?: typeof ng; - - static async loadCompilerCli(): Promise { - AngularCompilation.#angularCompilerCliModule ??= await import('@angular/compiler-cli'); - - return AngularCompilation.#angularCompilerCliModule; - } - - protected async loadConfiguration(tsconfig: string): Promise { - const { readConfiguration } = await AngularCompilation.loadCompilerCli(); - - return profileSync('NG_READ_CONFIG', () => - readConfiguration(tsconfig, { - // Angular specific configuration defaults and overrides to ensure a functioning compilation. - suppressOutputPathCheck: true, - outDir: undefined, - sourceMap: false, - declaration: false, - declarationMap: false, - allowEmptyCodegenFiles: false, - annotationsAs: 'decorators', - enableResourceInlining: false, - supportTestBed: false, - supportJitMode: false, - // Disable removing of comments as TS is quite aggressive with these and can - // remove important annotations, such as /* @__PURE__ */ and comments like /* vite-ignore */. - removeComments: false, - }), - ); - } - abstract initialize( tsconfig: string, hostOptions: AngularHostOptions, diff --git a/packages/angular/build/src/tools/angular/compilation/angular-compilation_spec.ts b/packages/angular/build/src/tools/angular/compilation/angular-compilation_spec.ts index 5e520fbadef8..a867f666c349 100644 --- a/packages/angular/build/src/tools/angular/compilation/angular-compilation_spec.ts +++ b/packages/angular/build/src/tools/angular/compilation/angular-compilation_spec.ts @@ -128,6 +128,12 @@ describe('AngularCompilation', () => { await compilation.update?.(new Set(['/src/test.ts'])); expect(compilation.getCachedSourceFiles().has('/src/test.ts')).toBeFalse(); }); + + it('dynamically loads the @angular/compiler-cli module', async () => { + const compilerCli = await TypeScriptCompilation.loadCompilerCli(); + expect(compilerCli).toBeDefined(); + expect(typeof compilerCli.readConfiguration).toBe('function'); + }); }); describe('createAngularCompilation', () => { diff --git a/packages/angular/build/src/tools/angular/compilation/aot-compilation.ts b/packages/angular/build/src/tools/angular/compilation/aot-compilation.ts index ec68415e62fb..9fd160774cf7 100644 --- a/packages/angular/build/src/tools/angular/compilation/aot-compilation.ts +++ b/packages/angular/build/src/tools/angular/compilation/aot-compilation.ts @@ -22,10 +22,9 @@ import { replaceBootstrap } from '../transformers/jit-bootstrap-transformer'; import { lazyRoutesTransformer } from '../transformers/lazy-routes-transformer'; import { createWorkerTransformer } from '../transformers/web-worker-transformer'; import { - AngularCompilation, - AngularCompilationResult, + type AngularCompilationResult, DiagnosticModes, - EmitFileResult, + type EmitFileResult, } from './angular-compilation'; import { CompilerOptionOverrides, transformCompilerOptions } from './compiler-options'; import { collectHmrCandidates } from './hmr-candidates'; @@ -69,7 +68,7 @@ export class AotCompilation extends TypeScriptCompilation { compilerOptionOverrides?: CompilerOptionOverrides, ): Promise { // Dynamically load the Angular compiler CLI package - const { NgtscProgram, OptimizeFor } = await AngularCompilation.loadCompilerCli(); + const { NgtscProgram, OptimizeFor } = await TypeScriptCompilation.loadCompilerCli(); // Load the compiler configuration and transform as needed const { diff --git a/packages/angular/build/src/tools/angular/compilation/jit-compilation.ts b/packages/angular/build/src/tools/angular/compilation/jit-compilation.ts index b54f66701c6c..fee636219be0 100644 --- a/packages/angular/build/src/tools/angular/compilation/jit-compilation.ts +++ b/packages/angular/build/src/tools/angular/compilation/jit-compilation.ts @@ -16,10 +16,9 @@ import { createJitResourceTransformer } from '../transformers/jit-resource-trans import { lazyRoutesTransformer } from '../transformers/lazy-routes-transformer'; import { createWorkerTransformer } from '../transformers/web-worker-transformer'; import { - AngularCompilation, - AngularCompilationResult, + type AngularCompilationResult, DiagnosticModes, - EmitFileResult, + type EmitFileResult, } from './angular-compilation'; import { CompilerOptionOverrides, transformCompilerOptions } from './compiler-options'; import { TypeScriptCompilation } from './typescript-compilation'; diff --git a/packages/angular/build/src/tools/angular/compilation/typescript-compilation.ts b/packages/angular/build/src/tools/angular/compilation/typescript-compilation.ts index 7591e2028c36..970041f916fc 100644 --- a/packages/angular/build/src/tools/angular/compilation/typescript-compilation.ts +++ b/packages/angular/build/src/tools/angular/compilation/typescript-compilation.ts @@ -6,14 +6,46 @@ * found in the LICENSE file at https://angular.dev/license */ +import type * as ng from '@angular/compiler-cli'; import type { PartialMessage } from 'esbuild'; import ts from 'typescript'; import { toPosixPath } from '../../../utils/path'; -import { profileAsync } from '../../esbuild/profiling'; +import { profileAsync, profileSync } from '../../esbuild/profiling'; import { AngularCompilation, DiagnosticModes } from './angular-compilation'; import { convertTypeScriptDiagnostic } from './diagnostics'; export abstract class TypeScriptCompilation extends AngularCompilation { + static #angularCompilerCliModule?: typeof ng; + + static async loadCompilerCli(): Promise { + TypeScriptCompilation.#angularCompilerCliModule ??= await import('@angular/compiler-cli'); + + return TypeScriptCompilation.#angularCompilerCliModule; + } + + protected async loadConfiguration(tsconfig: string): Promise { + const { readConfiguration } = await TypeScriptCompilation.loadCompilerCli(); + + return profileSync('NG_READ_CONFIG', () => + readConfiguration(tsconfig, { + // Angular specific configuration defaults and overrides to ensure a functioning compilation. + suppressOutputPathCheck: true, + outDir: undefined, + sourceMap: false, + declaration: false, + declarationMap: false, + allowEmptyCodegenFiles: false, + annotationsAs: 'decorators', + enableResourceInlining: false, + supportTestBed: false, + supportJitMode: false, + // Disable removing of comments as TS is quite aggressive with these and can + // remove important annotations, such as /* @__PURE__ */ and comments like /* vite-ignore */. + removeComments: false, + }), + ); + } + protected readonly sourceFiles = new Map(); protected invalidateFiles(files: Iterable): void { From 6ee559ca9d209fb4c53de2aaf9918d10e5f062a1 Mon Sep 17 00:00:00 2001 From: Charles Lyding <19598772+clydin@users.noreply.github.com> Date: Tue, 1 Sep 2026 13:20:03 -0400 Subject: [PATCH 394/787] perf(@angular/build): bypass worker dispatch for files without transform candidates Files that require neither Angular linking nor advanced optimizations previously underwent full worker thread IPC dispatch, worker deserialization, and AST processing. By evaluating a fast candidate check on the main thread directly on raw data buffers, files that cannot be modified by advanced optimizations immediately return the original data buffer without worker dispatch or AST parsing. --- .../tools/esbuild/javascript-transformer.ts | 75 ++++++++- .../esbuild/javascript-transformer_spec.ts | 147 +++++++++++++++++- 2 files changed, 217 insertions(+), 5 deletions(-) diff --git a/packages/angular/build/src/tools/esbuild/javascript-transformer.ts b/packages/angular/build/src/tools/esbuild/javascript-transformer.ts index 3ba0dfff45b1..824ee5817606 100644 --- a/packages/angular/build/src/tools/esbuild/javascript-transformer.ts +++ b/packages/angular/build/src/tools/esbuild/javascript-transformer.ts @@ -16,6 +16,76 @@ import { Cache } from './cache'; const LINKER_DECLARATION_PREFIX = 'ɵɵngDeclare'; const LINKER_DECLARATION_PREFIX_BYTES = Buffer.from(LINKER_DECLARATION_PREFIX, 'utf-8'); +const ADVANCED_OPTIMIZATION_TOKENS = [ + 'ɵ', + 'InjectionToken', + 'INJECTOR_KEY', + 'ctorParameters', + 'decorators', + 'propDecorators', +] as const; + +const ADVANCED_OPTIMIZATION_TOKEN_BYTES = ADVANCED_OPTIMIZATION_TOKENS.map((token) => + Buffer.from(token, 'utf-8'), +); + +const DECORATOR_TOKENS = ['__decorate', '__esDecorate'] as const; +const DECORATOR_TOKEN_BYTES = DECORATOR_TOKENS.map((token) => Buffer.from(token, 'utf-8')); + +const ADVANCED_OPTIMIZATION_REGEX = new RegExp(ADVANCED_OPTIMIZATION_TOKENS.join('|')); +const ADVANCED_OPTIMIZATION_WITH_DECORATORS_REGEX = new RegExp( + [...ADVANCED_OPTIMIZATION_TOKENS, ...DECORATOR_TOKENS].join('|'), +); + +/** + * Determines whether JavaScript code contains potential candidate constructs for advanced optimizations. + * When false, advanced optimizations can be bypassed without worker dispatch or AST parsing. + * + * @param filename The full path to the file. + * @param data The data (string or Buffer) of the file. + * @param sideEffects If false, indicates the file is considered side-effect free. + * @returns True if the code may contain constructs that advanced optimizations can mutate. + */ +function hasAdvancedOptimizationCandidates( + filename: string, + data: string | Uint8Array, + sideEffects?: boolean, +): boolean { + // Side-effect-free @angular/ packages undergo top-level pure function annotations + if (sideEffects === false && /[\\/]node_modules[\\/]@angular[\\/]/.test(filename)) { + return true; + } + + if (typeof data === 'string') { + const regex = + sideEffects === false + ? ADVANCED_OPTIMIZATION_WITH_DECORATORS_REGEX + : ADVANCED_OPTIMIZATION_REGEX; + + return regex.test(data); + } + + const dataBuffer = Buffer.isBuffer(data) + ? data + : Buffer.from(data.buffer, data.byteOffset, data.byteLength); + + for (const tokenBytes of ADVANCED_OPTIMIZATION_TOKEN_BYTES) { + if (dataBuffer.includes(tokenBytes)) { + return true; + } + } + + if (sideEffects === false) { + for (const tokenBytes of DECORATOR_TOKEN_BYTES) { + if (dataBuffer.includes(tokenBytes)) { + return true; + } + } + } + + return false; +} + /** * Determines whether JavaScript code requires Angular linker processing. * @@ -220,10 +290,13 @@ export class JavaScriptTransformer { instrumentForCoverage?: boolean, ): Promise { const shouldLink = !skipLinker && requiresLinking(filename, data); + const shouldOptimize = + this.#commonOptions.advancedOptimizations && + hasAdvancedOptimizationCandidates(filename, data, sideEffects); // Perform a quick test to determine if the data needs any transformations. // This allows directly returning the data without the worker communication overhead. - if (!shouldLink && !this.#commonOptions.advancedOptimizations && !instrumentForCoverage) { + if (!shouldLink && !shouldOptimize && !instrumentForCoverage) { const keepSourcemap = this.#commonOptions.sourcemap && (!!this.#commonOptions.thirdPartySourcemaps || !/[\\/]node_modules[\\/]/.test(filename)); diff --git a/packages/angular/build/src/tools/esbuild/javascript-transformer_spec.ts b/packages/angular/build/src/tools/esbuild/javascript-transformer_spec.ts index b1cdeec07b44..3949c9efbbdc 100644 --- a/packages/angular/build/src/tools/esbuild/javascript-transformer_spec.ts +++ b/packages/angular/build/src/tools/esbuild/javascript-transformer_spec.ts @@ -38,12 +38,12 @@ describe('JavaScriptTransformer sourcemaps', () => { const inputMap = { version: 3, sources: ['src/app.ts'], - sourcesContent: ['const x = new SomeClass();'], + sourcesContent: ['export class MyClass { static ɵprov = 42; }'], mappings: 'AAAA', names: [], }; const base64Map = Buffer.from(JSON.stringify(inputMap)).toString('base64'); - const input = `var x = new SomeClass();\n//# sourceMappingURL=data:application/json;base64,${base64Map}`; + const input = `export class MyClass { static ɵprov = 42; }\n//# sourceMappingURL=data:application/json;base64,${base64Map}`; const result = await transformer.transformData('src/app.js', input, true); const text = Buffer.from(result).toString('utf-8'); @@ -157,7 +157,7 @@ describe('JavaScriptTransformer sourcemaps', () => { 1, ); - const input = 'var x = new SomeClass();'; + const input = 'export class MyClass { static ɵprov = 42; }'; const result = await transformer.transformData('src/app.js', input, true); const text = Buffer.from(result).toString('utf-8'); const map = extractSourcemap(text); @@ -249,7 +249,7 @@ describe('JavaScriptTransformer sourcemaps', () => { 1, ); - const inputBuffer = Buffer.from('var x = new SomeClass();', 'utf-8'); + const inputBuffer = Buffer.from('export class MyClass { static ɵprov = 42; }', 'utf-8'); const result = await transformer.transformData('src/app.js', inputBuffer, true); const text = Buffer.from(result).toString('utf-8'); const map = extractSourcemap(text); @@ -374,4 +374,143 @@ describe('JavaScriptTransformer sourcemaps', () => { expect(text).not.toContain('i0.ɵɵngDeclareDirective'); }); + + describe('advanced optimizations fast-path pre-filter', () => { + it('should bypass worker and return input buffer directly when no candidate tokens are present', async () => { + transformer = new JavaScriptTransformer( + { + sourcemap: false, + advancedOptimizations: true, + }, + 1, + ); + + const inputBuffer = Buffer.from( + 'function add(a, b) { return a + b; }\nconst result = add(1, 2);', + 'utf-8', + ); + const result = await transformer.transformData('src/math.js', inputBuffer, true); + + expect(result).toBe(inputBuffer); + }); + + it('should bypass worker for standard classes without static properties', async () => { + transformer = new JavaScriptTransformer( + { + sourcemap: false, + advancedOptimizations: true, + }, + 1, + ); + + const inputBuffer = Buffer.from( + `export class UserService { + constructor(http) { this.http = http; } + getUser(id) { return this.http.get('/users/' + id); } + }`, + 'utf-8', + ); + const result = await transformer.transformData('src/user.service.js', inputBuffer, true); + + expect(result).toBe(inputBuffer); + }); + + it('should bypass worker for default exports without static properties or Angular metadata', async () => { + transformer = new JavaScriptTransformer( + { + sourcemap: false, + advancedOptimizations: true, + }, + 1, + ); + + const inputBuffer = Buffer.from( + `export default class UserService { + constructor(http) { this.http = http; } + getUser(id) { return this.http.get('/users/' + id); } + }`, + 'utf-8', + ); + const result = await transformer.transformData('src/user.service.js', inputBuffer, true); + + expect(result).toBe(inputBuffer); + }); + + it('should bypass worker for classes with static members when no Angular metadata is present', async () => { + transformer = new JavaScriptTransformer( + { + sourcemap: false, + advancedOptimizations: true, + }, + 1, + ); + + const inputBuffer = Buffer.from('export class MyComponent { static prop = 42; }', 'utf-8'); + const result = await transformer.transformData('src/component.js', inputBuffer, true); + + expect(result).toBe(inputBuffer); + }); + + it('should dispatch to worker when Angular tokens are present', async () => { + transformer = new JavaScriptTransformer( + { + sourcemap: false, + advancedOptimizations: true, + }, + 1, + ); + + const input = 'export class MyService { static ɵprov = true; }'; + const result = await transformer.transformData('src/service.js', input, true); + const text = Buffer.from(result).toString('utf-8'); + + expect(text).toContain('let MyService = /*#__PURE__*/ (() => {'); + }); + + it('should dispatch to worker when decorator tokens are present and sideEffects is false', async () => { + transformer = new JavaScriptTransformer( + { + sourcemap: false, + advancedOptimizations: true, + }, + 1, + ); + + const inputBuffer = Buffer.from('const MyClass = __decorate([], class {});', 'utf-8'); + const result = await transformer.transformData('src/class.js', inputBuffer, true, false); + + expect(result).not.toBe(inputBuffer); + }); + + it('should bypass worker and return converted buffer when no candidate tokens are present in string input', async () => { + transformer = new JavaScriptTransformer( + { + sourcemap: false, + advancedOptimizations: true, + }, + 1, + ); + + const inputString = 'function multiply(a, b) { return a * b; }'; + const result = await transformer.transformData('src/math.js', inputString, true); + + expect(Buffer.from(result).toString('utf-8')).toBe(inputString); + }); + + it('should dispatch to worker when candidate tokens are present in string input', async () => { + transformer = new JavaScriptTransformer( + { + sourcemap: false, + advancedOptimizations: true, + }, + 1, + ); + + const inputString = 'export class MyService { static ɵprov = true; }'; + const result = await transformer.transformData('src/service.js', inputString, true); + const text = Buffer.from(result).toString('utf-8'); + + expect(text).toContain('let MyService = /*#__PURE__*/ (() => {'); + }); + }); }); From c05a270ea010e94f3b371aa60e014f535a1240cc Mon Sep 17 00:00:00 2001 From: Charles Lyding <19598772+clydin@users.noreply.github.com> Date: Wed, 2 Sep 2026 12:22:33 -0400 Subject: [PATCH 395/787] refactor(@angular/build): remove arbitrary cap from maxWorkers and localize bundling concurrency Previously, maxWorkers was clamped to a maximum of 4 globally across the entire build system. This limitation was originally introduced to mitigate memory pressure from Babel transforms, but subsequent optimizations such as the OXC linker migration, zero-copy shared memory for i18n translations, and bounded memory buffers have eliminated those memory constraints. Consequently, clamping maxWorkers artificially restricted post-bundle operations like translation inlining and route prerendering on high-core systems. This change decouples the global default of maxWorkers so that it scales with available parallelism minus one, ensuring the main thread is not starved while allowing parallel tasks to utilize full hardware capacity. When NG_BUILD_MAX_WORKERS is specified, it is safely parsed as a positive integer or falls back to the default available parallelism. To avoid CPU contention during bundling when esbuild concurrently executes its internal multi-threaded Go routine across all cores, transformation concurrency for JavaScriptTransformer is now locally capped to at most 4 unless NG_BUILD_MAX_WORKERS has been explicitly provided, tracked via the exported hasCustomMaxWorkers option. --- .../tools/esbuild/angular/compiler-plugin.ts | 12 +- .../build/src/utils/environment-options.ts | 26 ++-- .../src/utils/environment-options_spec.ts | 116 ++++++++++++++++++ 3 files changed, 141 insertions(+), 13 deletions(-) create mode 100644 packages/angular/build/src/utils/environment-options_spec.ts diff --git a/packages/angular/build/src/tools/esbuild/angular/compiler-plugin.ts b/packages/angular/build/src/tools/esbuild/angular/compiler-plugin.ts index 5ce1130d093a..f80f3c78afca 100644 --- a/packages/angular/build/src/tools/esbuild/angular/compiler-plugin.ts +++ b/packages/angular/build/src/tools/esbuild/angular/compiler-plugin.ts @@ -20,7 +20,11 @@ import type { import assert from 'node:assert'; import { readFile } from 'node:fs/promises'; import * as path from 'node:path'; -import { maxWorkers, useTypeChecking } from '../../../utils/environment-options'; +import { + hasCustomMaxWorkers, + maxWorkers, + useTypeChecking, +} from '../../../utils/environment-options'; import { calculateHash, initializeHash } from '../../../utils/hash'; import { AngularHostOptions } from '../../angular/angular-host'; import { AngularCompilation, DiagnosticModes } from '../../angular/compilation'; @@ -97,6 +101,10 @@ export function createCompilerPlugin( }); } } + // During bundling, esbuild runs its own multi-threaded Go process across all available cores. + // Unless explicitly configured via NG_BUILD_MAX_WORKERS, cap transformation concurrency to at + // most 4 to prevent CPU contention during bundling. + const maxTransformWorkers = hasCustomMaxWorkers ? maxWorkers : Math.min(4, maxWorkers); const javascriptTransformer = new JavaScriptTransformer( { sourcemap: !!pluginOptions.sourcemap, @@ -104,7 +112,7 @@ export function createCompilerPlugin( advancedOptimizations: pluginOptions.advancedOptimizations, jit: pluginOptions.jit || pluginOptions.includeTestMetadata, }, - maxWorkers, + maxTransformWorkers, cacheStore?.createCache('jstransformer'), ); diff --git a/packages/angular/build/src/utils/environment-options.ts b/packages/angular/build/src/utils/environment-options.ts index f008673a1552..1e225d6b7386 100644 --- a/packages/angular/build/src/utils/environment-options.ts +++ b/packages/angular/build/src/utils/environment-options.ts @@ -108,24 +108,28 @@ export const allowMinify = debugOptimize.minify; */ export const useRolldownChunks = parseTristate(process.env['NG_BUILD_CHUNKS_ROLLDOWN']) ?? true; +const maxWorkersVariable = process.env['NG_BUILD_MAX_WORKERS']; + +let customMaxWorkers: number | undefined; +if (isPresent(maxWorkersVariable)) { + const parsed = +maxWorkersVariable; + if (Number.isInteger(parsed) && parsed >= 1) { + customMaxWorkers = parsed; + } +} + /** - * Some environments, like CircleCI which use Docker report a number of CPUs by the host and not the count of available. - * This cause `Error: Call retries were exceeded` errors when trying to use them. - * - * @see https://github.com/nodejs/node/issues/28762 - * @see https://github.com/webpack-contrib/terser-webpack-plugin/issues/143 - * @see https://ithub.com/angular/angular-cli/issues/16860#issuecomment-588828079 - * + * Whether the maximum number of workers was explicitly configured via the + * `NG_BUILD_MAX_WORKERS` environment variable. */ -const maxWorkersVariable = process.env['NG_BUILD_MAX_WORKERS']; +export const hasCustomMaxWorkers = customMaxWorkers !== undefined; /** * The maximum number of workers to use for parallel processing. * This can be controlled by the `NG_BUILD_MAX_WORKERS` environment variable. + * When not set, defaults to available parallelism minus one to ensure the main thread is not starved. */ -export const maxWorkers = isPresent(maxWorkersVariable) - ? +maxWorkersVariable - : Math.min(4, Math.max(availableParallelism() - 1, 1)); +export const maxWorkers = customMaxWorkers ?? Math.max(availableParallelism() - 1, 1); /** * When `NG_BUILD_PARALLEL_TS` is set to `0` or `false`, parallel TypeScript compilation is disabled. diff --git a/packages/angular/build/src/utils/environment-options_spec.ts b/packages/angular/build/src/utils/environment-options_spec.ts new file mode 100644 index 000000000000..0d2ac7fa0c61 --- /dev/null +++ b/packages/angular/build/src/utils/environment-options_spec.ts @@ -0,0 +1,116 @@ +/** + * @license + * Copyright Google LLC All Rights Reserved. + * + * Use of this source code is governed by an MIT-style license that can be + * found in the LICENSE file at https://angular.dev/license + */ + +import { availableParallelism } from 'node:os'; + +describe('environment options - maxWorkers', () => { + const originalEnvValue = process.env['NG_BUILD_MAX_WORKERS']; + + function loadEnvironmentOptions(): typeof import('./environment-options') { + delete require.cache[require.resolve('./environment-options')]; + + return require('./environment-options'); + } + + afterEach(() => { + if (originalEnvValue !== undefined) { + process.env['NG_BUILD_MAX_WORKERS'] = originalEnvValue; + } else { + delete process.env['NG_BUILD_MAX_WORKERS']; + } + delete require.cache[require.resolve('./environment-options')]; + }); + + it('defaults maxWorkers to availableParallelism - 1 when NG_BUILD_MAX_WORKERS is unset', () => { + delete process.env['NG_BUILD_MAX_WORKERS']; + const { maxWorkers, hasCustomMaxWorkers } = loadEnvironmentOptions(); + + expect(hasCustomMaxWorkers).toBeFalse(); + expect(maxWorkers).toBe(Math.max(availableParallelism() - 1, 1)); + }); + + it('uses configured positive integer when NG_BUILD_MAX_WORKERS is set', () => { + process.env['NG_BUILD_MAX_WORKERS'] = '8'; + const { maxWorkers, hasCustomMaxWorkers } = loadEnvironmentOptions(); + + expect(hasCustomMaxWorkers).toBeTrue(); + expect(maxWorkers).toBe(8); + }); + + it('allows maxWorkers greater than 4 when explicitly configured', () => { + process.env['NG_BUILD_MAX_WORKERS'] = '32'; + const { maxWorkers, hasCustomMaxWorkers } = loadEnvironmentOptions(); + + expect(hasCustomMaxWorkers).toBeTrue(); + expect(maxWorkers).toBe(32); + }); + + it('supports maxWorkers set to 1', () => { + process.env['NG_BUILD_MAX_WORKERS'] = '1'; + const { maxWorkers, hasCustomMaxWorkers } = loadEnvironmentOptions(); + + expect(hasCustomMaxWorkers).toBeTrue(); + expect(maxWorkers).toBe(1); + }); + + it('falls back to availableParallelism - 1 when NG_BUILD_MAX_WORKERS is 0', () => { + process.env['NG_BUILD_MAX_WORKERS'] = '0'; + const { maxWorkers, hasCustomMaxWorkers } = loadEnvironmentOptions(); + + expect(hasCustomMaxWorkers).toBeFalse(); + expect(maxWorkers).toBe(Math.max(availableParallelism() - 1, 1)); + }); + + it('falls back to availableParallelism - 1 when NG_BUILD_MAX_WORKERS is negative', () => { + process.env['NG_BUILD_MAX_WORKERS'] = '-4'; + const { maxWorkers, hasCustomMaxWorkers } = loadEnvironmentOptions(); + + expect(hasCustomMaxWorkers).toBeFalse(); + expect(maxWorkers).toBe(Math.max(availableParallelism() - 1, 1)); + }); + + it('falls back to availableParallelism - 1 when NG_BUILD_MAX_WORKERS is not a number', () => { + process.env['NG_BUILD_MAX_WORKERS'] = 'invalid'; + const { maxWorkers, hasCustomMaxWorkers } = loadEnvironmentOptions(); + + expect(hasCustomMaxWorkers).toBeFalse(); + expect(maxWorkers).toBe(Math.max(availableParallelism() - 1, 1)); + }); + + it('falls back to availableParallelism - 1 when NG_BUILD_MAX_WORKERS is a float', () => { + process.env['NG_BUILD_MAX_WORKERS'] = '2.5'; + const { maxWorkers, hasCustomMaxWorkers } = loadEnvironmentOptions(); + + expect(hasCustomMaxWorkers).toBeFalse(); + expect(maxWorkers).toBe(Math.max(availableParallelism() - 1, 1)); + }); + + it('falls back to availableParallelism - 1 when NG_BUILD_MAX_WORKERS is an empty string', () => { + process.env['NG_BUILD_MAX_WORKERS'] = ''; + const { maxWorkers, hasCustomMaxWorkers } = loadEnvironmentOptions(); + + expect(hasCustomMaxWorkers).toBeFalse(); + expect(maxWorkers).toBe(Math.max(availableParallelism() - 1, 1)); + }); + + it('falls back to availableParallelism - 1 when NG_BUILD_MAX_WORKERS is whitespace only', () => { + process.env['NG_BUILD_MAX_WORKERS'] = ' '; + const { maxWorkers, hasCustomMaxWorkers } = loadEnvironmentOptions(); + + expect(hasCustomMaxWorkers).toBeFalse(); + expect(maxWorkers).toBe(Math.max(availableParallelism() - 1, 1)); + }); + + it('parses positive integers with surrounding whitespace', () => { + process.env['NG_BUILD_MAX_WORKERS'] = ' 8 '; + const { maxWorkers, hasCustomMaxWorkers } = loadEnvironmentOptions(); + + expect(hasCustomMaxWorkers).toBeTrue(); + expect(maxWorkers).toBe(8); + }); +}); From 205f128e98e58aac124b248ae3aee46f8704fd97 Mon Sep 17 00:00:00 2001 From: Angular Robot Date: Wed, 2 Sep 2026 10:53:35 +0000 Subject: [PATCH 396/787] build: update cross-repo angular dependencies See associated pull request for more information. --- modules/testing/builder/package.json | 2 +- package.json | 4 +- packages/angular/build/package.json | 2 +- .../angular_devkit/build_angular/package.json | 2 +- pnpm-lock.yaml | 46 ++++++++++--------- tests/e2e/ng-snapshot/package.json | 32 ++++++------- 6 files changed, 45 insertions(+), 43 deletions(-) diff --git a/modules/testing/builder/package.json b/modules/testing/builder/package.json index 42b38d3a02ab..176c6825b53e 100644 --- a/modules/testing/builder/package.json +++ b/modules/testing/builder/package.json @@ -8,7 +8,7 @@ "browser-sync": "3.0.4", "istanbul-lib-instrument": "6.0.3", "jsdom": "30.0.1", - "ng-packagr": "22.2.0-next.4", + "ng-packagr": "22.2.0-next.5", "rxjs": "7.8.2", "vitest": "4.1.11" } diff --git a/package.json b/package.json index e5f7f3750512..ade980daf327 100644 --- a/package.json +++ b/package.json @@ -47,13 +47,13 @@ }, "devDependencies": { "@angular/animations": "22.2.0-next.4", - "@angular/cdk": "22.2.0-next.3", + "@angular/cdk": "22.2.0-next.4", "@angular/common": "22.2.0-next.4", "@angular/compiler": "22.2.0-next.4", "@angular/core": "22.2.0-next.4", "@angular/forms": "22.2.0-next.4", "@angular/localize": "22.2.0-next.4", - "@angular/material": "22.2.0-next.3", + "@angular/material": "22.2.0-next.4", "@angular/ng-dev": "https://github.com/angular/dev-infra-private-ng-dev-builds.git#151e36ffa910f4a01aafe1c482ed8294e2050566", "@angular/platform-browser": "22.2.0-next.4", "@angular/platform-server": "22.2.0-next.4", diff --git a/packages/angular/build/package.json b/packages/angular/build/package.json index 54268c4c7df5..72bc0aa26a0c 100644 --- a/packages/angular/build/package.json +++ b/packages/angular/build/package.json @@ -56,7 +56,7 @@ "istanbul-lib-instrument": "6.0.3", "jsdom": "30.0.1", "less": "4.9.0", - "ng-packagr": "22.2.0-next.4", + "ng-packagr": "22.2.0-next.5", "postcss": "8.5.26", "rollup": "4.63.0", "rxjs": "7.8.2", diff --git a/packages/angular_devkit/build_angular/package.json b/packages/angular_devkit/build_angular/package.json index 9038b43df99a..7e7f1ff431c4 100644 --- a/packages/angular_devkit/build_angular/package.json +++ b/packages/angular_devkit/build_angular/package.json @@ -65,7 +65,7 @@ "devDependencies": { "@angular/ssr": "workspace:*", "browser-sync": "3.0.4", - "ng-packagr": "22.2.0-next.4", + "ng-packagr": "22.2.0-next.5", "sass": "1.103.1", "undici": "8.10.0" }, diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index dbe4ae62e56b..6246dc45bf59 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -29,8 +29,8 @@ importers: specifier: 22.2.0-next.4 version: 22.2.0-next.4(@angular/core@22.2.0-next.4(@angular/compiler@22.2.0-next.4)(rxjs@7.8.2)(zone.js@0.16.2)) '@angular/cdk': - specifier: 22.2.0-next.3 - version: 22.2.0-next.3(@angular/common@22.2.0-next.4(@angular/core@22.2.0-next.4(@angular/compiler@22.2.0-next.4)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2))(@angular/core@22.2.0-next.4(@angular/compiler@22.2.0-next.4)(rxjs@7.8.2)(zone.js@0.16.2))(@angular/platform-browser@22.2.0-next.4(@angular/animations@22.2.0-next.4(@angular/core@22.2.0-next.4(@angular/compiler@22.2.0-next.4)(rxjs@7.8.2)(zone.js@0.16.2)))(@angular/common@22.2.0-next.4(@angular/core@22.2.0-next.4(@angular/compiler@22.2.0-next.4)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2))(@angular/core@22.2.0-next.4(@angular/compiler@22.2.0-next.4)(rxjs@7.8.2)(zone.js@0.16.2)))(rxjs@7.8.2) + specifier: 22.2.0-next.4 + version: 22.2.0-next.4(030c3814b3581879fac755f4407156b7) '@angular/common': specifier: 22.2.0-next.4 version: 22.2.0-next.4(@angular/core@22.2.0-next.4(@angular/compiler@22.2.0-next.4)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2) @@ -47,8 +47,8 @@ importers: specifier: 22.2.0-next.4 version: 22.2.0-next.4(@angular/compiler-cli@22.2.0-next.4(@angular/compiler@22.2.0-next.4)(typescript@6.0.3))(@angular/compiler@22.2.0-next.4) '@angular/material': - specifier: 22.2.0-next.3 - version: 22.2.0-next.3(2d3d12f5adbcb81bda5dafdebadbbaef) + specifier: 22.2.0-next.4 + version: 22.2.0-next.4(e4b4733de2f6d4602c4b226512a007c3) '@angular/ng-dev': specifier: https://github.com/angular/dev-infra-private-ng-dev-builds.git#151e36ffa910f4a01aafe1c482ed8294e2050566 version: https://codeload.github.com/angular/dev-infra-private-ng-dev-builds/tar.gz/151e36ffa910f4a01aafe1c482ed8294e2050566 @@ -314,8 +314,8 @@ importers: specifier: 30.0.1 version: 30.0.1 ng-packagr: - specifier: 22.2.0-next.4 - version: 22.2.0-next.4(@angular/compiler-cli@22.2.0-next.4(@angular/compiler@22.2.0-next.4)(typescript@6.0.3))(supports-color@11.0.0)(tslib@2.8.1)(typescript@6.0.3) + specifier: 22.2.0-next.5 + version: 22.2.0-next.5(@angular/compiler-cli@22.2.0-next.4(@angular/compiler@22.2.0-next.4)(typescript@6.0.3))(supports-color@11.0.0)(tslib@2.8.1)(typescript@6.0.3) rxjs: specifier: 7.8.2 version: 7.8.2 @@ -426,8 +426,8 @@ importers: specifier: 4.9.0 version: 4.9.0(supports-color@11.0.0) ng-packagr: - specifier: 22.2.0-next.4 - version: 22.2.0-next.4(@angular/compiler-cli@22.2.0-next.4(@angular/compiler@22.2.0-next.4)(typescript@6.0.3))(supports-color@11.0.0)(tslib@2.8.1)(typescript@6.0.3) + specifier: 22.2.0-next.5 + version: 22.2.0-next.5(@angular/compiler-cli@22.2.0-next.4(@angular/compiler@22.2.0-next.4)(typescript@6.0.3))(supports-color@11.0.0)(tslib@2.8.1)(typescript@6.0.3) postcss: specifier: 8.5.26 version: 8.5.26 @@ -711,8 +711,8 @@ importers: specifier: 3.0.4 version: 3.0.4(bufferutil@4.1.0)(debug@4.4.3(supports-color@11.0.0))(supports-color@11.0.0)(utf-8-validate@6.0.6) ng-packagr: - specifier: 22.2.0-next.4 - version: 22.2.0-next.4(@angular/compiler-cli@22.2.0-next.4(@angular/compiler@22.2.0-next.4)(typescript@6.0.3))(supports-color@11.0.0)(tslib@2.8.1)(typescript@6.0.3) + specifier: 22.2.0-next.5 + version: 22.2.0-next.5(@angular/compiler-cli@22.2.0-next.4(@angular/compiler@22.2.0-next.4)(typescript@6.0.3))(supports-color@11.0.0)(tslib@2.8.1)(typescript@6.0.3) sass: specifier: 1.103.1 version: 1.103.1 @@ -870,11 +870,12 @@ packages: peerDependencies: '@angular/core': 22.2.0-next.4 - '@angular/cdk@22.2.0-next.3': - resolution: {integrity: sha512-rdba75nOYip4YLBjeocti4YMFQvvso87FEstH0qegQRuhaRo0KvTc+midQX2G73DFnhkyCR0H48TwqCSzl59Bw==} + '@angular/cdk@22.2.0-next.4': + resolution: {integrity: sha512-ZqORCqi7eGIXgiObGA1Lmf7+l+7VP5gp7/ge3cNHUOcJP6HRJlt4ISjUFT+j7t9FU1lkf6nNBSwEcIG2EI+EGw==} peerDependencies: '@angular/common': ^22.0.0-0 || ^22.1.0-0 || ^22.2.0-0 || ^22.3.0-0 || ^23.0.0-0 '@angular/core': ^22.0.0-0 || ^22.1.0-0 || ^22.2.0-0 || ^22.3.0-0 || ^23.0.0-0 + '@angular/forms': ^22.0.0-0 || ^22.1.0-0 || ^22.2.0-0 || ^22.3.0-0 || ^23.0.0-0 '@angular/platform-browser': ^22.0.0-0 || ^22.1.0-0 || ^22.2.0-0 || ^22.3.0-0 || ^23.0.0-0 rxjs: ^6.5.3 || ^7.4.0 @@ -930,10 +931,10 @@ packages: '@angular/compiler': 22.2.0-next.4 '@angular/compiler-cli': 22.2.0-next.4 - '@angular/material@22.2.0-next.3': - resolution: {integrity: sha512-IO0O1nbCH7tz2qViPkDcPG2UHEXuO8Wighfw/FCkMHSXJrcVaFFML55ZNNKMNjJBIZ88M3v5fjibu/3yX7jE2A==} + '@angular/material@22.2.0-next.4': + resolution: {integrity: sha512-BTGnryNFfLvN8jI02msMNbHdNVcOaFL0MMH8S+jpQc8ooULx8bRwQZSWk8LKusayVyZH4JbT3YvV7PW/qw0ndA==} peerDependencies: - '@angular/cdk': 22.2.0-next.3 + '@angular/cdk': 22.2.0-next.4 '@angular/common': ^22.0.0-0 || ^22.1.0-0 || ^22.2.0-0 || ^22.3.0-0 || ^23.0.0-0 '@angular/core': ^22.0.0-0 || ^22.1.0-0 || ^22.2.0-0 || ^22.3.0-0 || ^23.0.0-0 '@angular/forms': ^22.0.0-0 || ^22.1.0-0 || ^22.2.0-0 || ^22.3.0-0 || ^23.0.0-0 @@ -6609,8 +6610,8 @@ packages: neo-async@2.6.2: resolution: {integrity: sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==} - ng-packagr@22.2.0-next.4: - resolution: {integrity: sha512-wV+9/vPHP4ZmNraPgo5hH6qilZny6YgEwUt7j6N/3MGAxjQQRmc+FRp7ilQhioQht9jsddOLgSZqj9DYaYzigg==} + ng-packagr@22.2.0-next.5: + resolution: {integrity: sha512-fZixAT5MGDlxZnPISy1ml22DeOFVMwt3Ym/6l/VwzuAlj1K0YVJNgxxRQs+iX/qqDzcXjyVD+CQAAwAq5pQo3Q==} engines: {node: ^22.22.3 || ^24.15.0 || >=26.0.0} hasBin: true peerDependencies: @@ -8554,10 +8555,11 @@ snapshots: '@angular/core': 22.2.0-next.4(@angular/compiler@22.2.0-next.4)(rxjs@7.8.2)(zone.js@0.16.2) tslib: 2.8.1 - '@angular/cdk@22.2.0-next.3(@angular/common@22.2.0-next.4(@angular/core@22.2.0-next.4(@angular/compiler@22.2.0-next.4)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2))(@angular/core@22.2.0-next.4(@angular/compiler@22.2.0-next.4)(rxjs@7.8.2)(zone.js@0.16.2))(@angular/platform-browser@22.2.0-next.4(@angular/animations@22.2.0-next.4(@angular/core@22.2.0-next.4(@angular/compiler@22.2.0-next.4)(rxjs@7.8.2)(zone.js@0.16.2)))(@angular/common@22.2.0-next.4(@angular/core@22.2.0-next.4(@angular/compiler@22.2.0-next.4)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2))(@angular/core@22.2.0-next.4(@angular/compiler@22.2.0-next.4)(rxjs@7.8.2)(zone.js@0.16.2)))(rxjs@7.8.2)': + '@angular/cdk@22.2.0-next.4(030c3814b3581879fac755f4407156b7)': dependencies: '@angular/common': 22.2.0-next.4(@angular/core@22.2.0-next.4(@angular/compiler@22.2.0-next.4)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2) '@angular/core': 22.2.0-next.4(@angular/compiler@22.2.0-next.4)(rxjs@7.8.2)(zone.js@0.16.2) + '@angular/forms': 22.2.0-next.4(@angular/common@22.2.0-next.4(@angular/core@22.2.0-next.4(@angular/compiler@22.2.0-next.4)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2))(@angular/core@22.2.0-next.4(@angular/compiler@22.2.0-next.4)(rxjs@7.8.2)(zone.js@0.16.2))(@angular/platform-browser@22.2.0-next.4(@angular/animations@22.2.0-next.4(@angular/core@22.2.0-next.4(@angular/compiler@22.2.0-next.4)(rxjs@7.8.2)(zone.js@0.16.2)))(@angular/common@22.2.0-next.4(@angular/core@22.2.0-next.4(@angular/compiler@22.2.0-next.4)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2))(@angular/core@22.2.0-next.4(@angular/compiler@22.2.0-next.4)(rxjs@7.8.2)(zone.js@0.16.2)))(rxjs@7.8.2) '@angular/platform-browser': 22.2.0-next.4(@angular/animations@22.2.0-next.4(@angular/core@22.2.0-next.4(@angular/compiler@22.2.0-next.4)(rxjs@7.8.2)(zone.js@0.16.2)))(@angular/common@22.2.0-next.4(@angular/core@22.2.0-next.4(@angular/compiler@22.2.0-next.4)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2))(@angular/core@22.2.0-next.4(@angular/compiler@22.2.0-next.4)(rxjs@7.8.2)(zone.js@0.16.2)) parse5: 8.0.1 rxjs: 7.8.2 @@ -8613,9 +8615,9 @@ snapshots: tinyglobby: 0.2.17 yargs: 18.1.0 - '@angular/material@22.2.0-next.3(2d3d12f5adbcb81bda5dafdebadbbaef)': + '@angular/material@22.2.0-next.4(e4b4733de2f6d4602c4b226512a007c3)': dependencies: - '@angular/cdk': 22.2.0-next.3(@angular/common@22.2.0-next.4(@angular/core@22.2.0-next.4(@angular/compiler@22.2.0-next.4)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2))(@angular/core@22.2.0-next.4(@angular/compiler@22.2.0-next.4)(rxjs@7.8.2)(zone.js@0.16.2))(@angular/platform-browser@22.2.0-next.4(@angular/animations@22.2.0-next.4(@angular/core@22.2.0-next.4(@angular/compiler@22.2.0-next.4)(rxjs@7.8.2)(zone.js@0.16.2)))(@angular/common@22.2.0-next.4(@angular/core@22.2.0-next.4(@angular/compiler@22.2.0-next.4)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2))(@angular/core@22.2.0-next.4(@angular/compiler@22.2.0-next.4)(rxjs@7.8.2)(zone.js@0.16.2)))(rxjs@7.8.2) + '@angular/cdk': 22.2.0-next.4(030c3814b3581879fac755f4407156b7) '@angular/common': 22.2.0-next.4(@angular/core@22.2.0-next.4(@angular/compiler@22.2.0-next.4)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2) '@angular/core': 22.2.0-next.4(@angular/compiler@22.2.0-next.4)(rxjs@7.8.2)(zone.js@0.16.2) '@angular/forms': 22.2.0-next.4(@angular/common@22.2.0-next.4(@angular/core@22.2.0-next.4(@angular/compiler@22.2.0-next.4)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2))(@angular/core@22.2.0-next.4(@angular/compiler@22.2.0-next.4)(rxjs@7.8.2)(zone.js@0.16.2))(@angular/platform-browser@22.2.0-next.4(@angular/animations@22.2.0-next.4(@angular/core@22.2.0-next.4(@angular/compiler@22.2.0-next.4)(rxjs@7.8.2)(zone.js@0.16.2)))(@angular/common@22.2.0-next.4(@angular/core@22.2.0-next.4(@angular/compiler@22.2.0-next.4)(rxjs@7.8.2)(zone.js@0.16.2))(rxjs@7.8.2))(@angular/core@22.2.0-next.4(@angular/compiler@22.2.0-next.4)(rxjs@7.8.2)(zone.js@0.16.2)))(rxjs@7.8.2) @@ -14823,7 +14825,7 @@ snapshots: neo-async@2.6.2: {} - ng-packagr@22.2.0-next.4(@angular/compiler-cli@22.2.0-next.4(@angular/compiler@22.2.0-next.4)(typescript@6.0.3))(supports-color@11.0.0)(tslib@2.8.1)(typescript@6.0.3): + ng-packagr@22.2.0-next.5(@angular/compiler-cli@22.2.0-next.4(@angular/compiler@22.2.0-next.4)(typescript@6.0.3))(supports-color@11.0.0)(tslib@2.8.1)(typescript@6.0.3): dependencies: '@ampproject/remapping': 2.3.0 '@angular/compiler-cli': 22.2.0-next.4(@angular/compiler@22.2.0-next.4)(typescript@6.0.3) @@ -14838,12 +14840,12 @@ snapshots: jsonc-parser: 3.3.1 less: 4.9.0(supports-color@11.0.0) ora: 9.4.1 - piscina: 5.3.1 postcss: 8.5.26 rolldown: 1.2.5 rolldown-plugin-dts: 0.28.4(rolldown@1.2.5)(typescript@6.0.3) rxjs: 7.8.2 sass: 1.103.1 + sass-embedded: 1.103.1 tinyglobby: 0.2.17 tslib: 2.8.1 typescript: 6.0.3 diff --git a/tests/e2e/ng-snapshot/package.json b/tests/e2e/ng-snapshot/package.json index b627e2364adf..7cca9b3d70aa 100644 --- a/tests/e2e/ng-snapshot/package.json +++ b/tests/e2e/ng-snapshot/package.json @@ -2,21 +2,21 @@ "description": "snapshot versions of Angular for e2e testing", "private": true, "dependencies": { - "@angular/animations": "github:angular/animations-builds#fa4dc439ba3f3dc801f9dd4a08ff01a6455119d8", - "@angular/cdk": "github:angular/cdk-builds#6838b38bc85fba6d80d869339817eeac024e6d1c", - "@angular/common": "github:angular/common-builds#16e35729d950286366c72d5fc3f7254be25ab180", - "@angular/compiler": "github:angular/compiler-builds#89ffd7a672bb4e385e63af9d74d9668812c91feb", - "@angular/compiler-cli": "github:angular/compiler-cli-builds#c9acaa6a51a2548947be3c3c34f49d7f0e16b2ed", - "@angular/core": "github:angular/core-builds#52ed585b1ce1e20f4518d7c4d73911192dbd6041", - "@angular/forms": "github:angular/forms-builds#2e1ae03b48526092802894c2ea715346f381d61f", - "@angular/language-service": "github:angular/language-service-builds#49d60ace600aed18a7d04aff02f0a59b19ea4c3f", - "@angular/localize": "github:angular/localize-builds#275df390d82ec128bd5df775aa3866a43bd85563", - "@angular/material": "github:angular/material-builds#05cfaacabd1b609c6c9639c9ceb83b84e637df52", - "@angular/material-moment-adapter": "github:angular/material-moment-adapter-builds#9a87ef14ec11f09290b0d52ba8b4d07ed4c6a61a", - "@angular/platform-browser": "github:angular/platform-browser-builds#eace0b148f00e56f8ff3917350c0606ceac63843", - "@angular/platform-browser-dynamic": "github:angular/platform-browser-dynamic-builds#0326f34b7ec16be6b0085a82001530bff43de5c3", - "@angular/platform-server": "github:angular/platform-server-builds#52f6c590468ce3ce0cb0de9792628510e25ee2d1", - "@angular/router": "github:angular/router-builds#f9851d7220c8c45e676b33798ceec07320466d12", - "@angular/service-worker": "github:angular/service-worker-builds#b4509881af0aed420214e55b995f0fd8a0ca2c0d" + "@angular/animations": "github:angular/animations-builds#5344f19c00a8fc3f32c1a8a1cc2325de5efa855c", + "@angular/cdk": "github:angular/cdk-builds#0125e1251393903a357a8d7c4738b4280df3713a", + "@angular/common": "github:angular/common-builds#f36a8306ad1503a92d62a2f0f9889067cc5f2238", + "@angular/compiler": "github:angular/compiler-builds#a1e5b0285cec3502d2c3aae9fe7688e94a1af757", + "@angular/compiler-cli": "github:angular/compiler-cli-builds#01f89b6ac069377264ddfd45135f447954699512", + "@angular/core": "github:angular/core-builds#33d795b90ace978113ea58c34e3851a923234beb", + "@angular/forms": "github:angular/forms-builds#e6a5b03db26f8feefcc053bad5ee4adcbe4f7f33", + "@angular/language-service": "github:angular/language-service-builds#7d4e7de41eb77c529d3c8de007f47fd5ac24de0a", + "@angular/localize": "github:angular/localize-builds#e2781426b655acefea1b8fa3d2e4ec51978df1c0", + "@angular/material": "github:angular/material-builds#2ec50fd40a77896f11b255777eefa50fff645a6a", + "@angular/material-moment-adapter": "github:angular/material-moment-adapter-builds#3c65a9c0ab84edbe93dbad1edb87ae43dd684c02", + "@angular/platform-browser": "github:angular/platform-browser-builds#db04eb8cbe4eecaaba7c73b2cd3a59d230f722f5", + "@angular/platform-browser-dynamic": "github:angular/platform-browser-dynamic-builds#947e132589519a859722a049497ba19e2a22d942", + "@angular/platform-server": "github:angular/platform-server-builds#891dfe25ce6e68bf0d7a825063a5321390d1ebe5", + "@angular/router": "github:angular/router-builds#0c224c7aeed4e84231f1b21aaee69241c75f0224", + "@angular/service-worker": "github:angular/service-worker-builds#3aef3a8ad20e2bd7a88b6af4974983ae0c09d6cc" } } From 9ac45f6f643b080ebd05ac32bb690b866b0d947a Mon Sep 17 00:00:00 2001 From: Angular Robot Date: Wed, 2 Sep 2026 06:49:11 +0000 Subject: [PATCH 397/787] build: update dependency bazel to v8.8.0 See associated pull request for more information. --- .bazelversion | 2 +- MODULE.bazel.lock | 357 ++++++++++------------------------------------ 2 files changed, 78 insertions(+), 281 deletions(-) diff --git a/.bazelversion b/.bazelversion index df5119ec64e6..3b6825376add 100644 --- a/.bazelversion +++ b/.bazelversion @@ -1 +1 @@ -8.7.0 +8.8.0 diff --git a/MODULE.bazel.lock b/MODULE.bazel.lock index dc1ef8ce7b84..5aff38f70622 100644 --- a/MODULE.bazel.lock +++ b/MODULE.bazel.lock @@ -1,5 +1,5 @@ { - "lockFileVersion": 24, + "lockFileVersion": 28, "registryFileHashes": { "https://bcr.bazel.build/bazel_registry.json": "8a28e4aff06ee60aed2a8c281907fb8bcbf3b753c91fb5a5c57da3215d5b3497", "https://bcr.bazel.build/modules/abseil-cpp/20210324.2/MODULE.bazel": "7cd0312e064fde87c8d1cd79ba06c876bd23630c83466e9500321be55c96ace2", @@ -221,11 +221,30 @@ "moduleExtensions": { "@@aspect_rules_esbuild+//esbuild:extensions.bzl%esbuild": { "general": { - "bzlTransitiveDigest": "yziqvbws9noFTds23HE5koMAI5QqGgQ7qmxOQkVtiw4=", + "bzlTransitiveDigest": "ivnb7fuZRAghsUscNSqk/cyy9pTpUKwbi8xOKhgxNbo=", "usagesDigest": "LZ71sshnfqI8R/HeWwBTwawxIa7KnitayBl2hYrqPo4=", - "recordedFileInputs": {}, - "recordedDirentsInputs": {}, - "envVariables": {}, + "recordedInputs": [ + "REPO_MAPPING:aspect_rules_esbuild+,aspect_rules_js aspect_rules_js+", + "REPO_MAPPING:aspect_rules_esbuild+,aspect_tools_telemetry_report aspect_tools_telemetry++telemetry+aspect_tools_telemetry_report", + "REPO_MAPPING:aspect_rules_esbuild+,bazel_skylib bazel_skylib+", + "REPO_MAPPING:aspect_rules_js+,aspect_rules_js aspect_rules_js+", + "REPO_MAPPING:aspect_rules_js+,aspect_tools_telemetry_report aspect_tools_telemetry++telemetry+aspect_tools_telemetry_report", + "REPO_MAPPING:aspect_rules_js+,bazel_features bazel_features+", + "REPO_MAPPING:aspect_rules_js+,bazel_lib bazel_lib+", + "REPO_MAPPING:aspect_rules_js+,bazel_skylib bazel_skylib+", + "REPO_MAPPING:aspect_rules_js+,bazel_tools bazel_tools", + "REPO_MAPPING:aspect_rules_js+,protobuf protobuf+", + "REPO_MAPPING:aspect_rules_js+,tar.bzl tar.bzl+", + "REPO_MAPPING:bazel_features+,bazel_features_globals bazel_features++version_extension+bazel_features_globals", + "REPO_MAPPING:bazel_features+,bazel_features_version bazel_features++version_extension+bazel_features_version", + "REPO_MAPPING:bazel_lib+,bazel_lib bazel_lib+", + "REPO_MAPPING:bazel_lib+,bazel_skylib bazel_skylib+", + "REPO_MAPPING:bazel_lib+,bazel_tools bazel_tools", + "REPO_MAPPING:protobuf+,proto_bazel_features bazel_features+", + "REPO_MAPPING:tar.bzl+,bazel_lib bazel_lib+", + "REPO_MAPPING:tar.bzl+,bazel_skylib bazel_skylib+", + "REPO_MAPPING:tar.bzl+,tar.bzl tar.bzl+" + ], "generatedRepoSpecs": { "esbuild_darwin-x64": { "repoRuleId": "@@aspect_rules_esbuild+//esbuild:repositories.bzl%esbuild_repositories", @@ -329,120 +348,18 @@ "exclude_package_contents_presets": [] } } - }, - "recordedRepoMappingEntries": [ - [ - "aspect_rules_esbuild+", - "aspect_rules_js", - "aspect_rules_js+" - ], - [ - "aspect_rules_esbuild+", - "aspect_tools_telemetry_report", - "aspect_tools_telemetry++telemetry+aspect_tools_telemetry_report" - ], - [ - "aspect_rules_esbuild+", - "bazel_skylib", - "bazel_skylib+" - ], - [ - "aspect_rules_js+", - "aspect_rules_js", - "aspect_rules_js+" - ], - [ - "aspect_rules_js+", - "aspect_tools_telemetry_report", - "aspect_tools_telemetry++telemetry+aspect_tools_telemetry_report" - ], - [ - "aspect_rules_js+", - "bazel_features", - "bazel_features+" - ], - [ - "aspect_rules_js+", - "bazel_lib", - "bazel_lib+" - ], - [ - "aspect_rules_js+", - "bazel_skylib", - "bazel_skylib+" - ], - [ - "aspect_rules_js+", - "bazel_tools", - "bazel_tools" - ], - [ - "aspect_rules_js+", - "protobuf", - "protobuf+" - ], - [ - "aspect_rules_js+", - "tar.bzl", - "tar.bzl+" - ], - [ - "bazel_features+", - "bazel_features_globals", - "bazel_features++version_extension+bazel_features_globals" - ], - [ - "bazel_features+", - "bazel_features_version", - "bazel_features++version_extension+bazel_features_version" - ], - [ - "bazel_lib+", - "bazel_lib", - "bazel_lib+" - ], - [ - "bazel_lib+", - "bazel_skylib", - "bazel_skylib+" - ], - [ - "bazel_lib+", - "bazel_tools", - "bazel_tools" - ], - [ - "protobuf+", - "proto_bazel_features", - "bazel_features+" - ], - [ - "tar.bzl+", - "bazel_lib", - "bazel_lib+" - ], - [ - "tar.bzl+", - "bazel_skylib", - "bazel_skylib+" - ], - [ - "tar.bzl+", - "tar.bzl", - "tar.bzl+" - ] - ] + } } }, "@@aspect_tools_telemetry+//:extension.bzl%telemetry": { "general": { "bzlTransitiveDigest": "zFgbaCUuPzH6bIE7CBHBVCqjWSJ78/WNXisdzXaKSnU=", "usagesDigest": "2cLMn8ZcqY/6j/zH70TrPob+ENshTw9h48kUHxn1cUM=", - "recordedFileInputs": {}, - "recordedDirentsInputs": {}, - "envVariables": { - "ASPECT_TOOLS_TELEMETRY_TEST": null - }, + "recordedInputs": [ + "REPO_MAPPING:aspect_tools_telemetry+,bazel_lib bazel_lib+", + "REPO_MAPPING:aspect_tools_telemetry+,bazel_skylib bazel_skylib+", + "ENV:ASPECT_TOOLS_TELEMETRY_TEST \\0" + ], "generatedRepoSpecs": { "aspect_tools_telemetry_report": { "repoRuleId": "@@aspect_tools_telemetry+//:extension.bzl%tel_repository", @@ -454,37 +371,24 @@ "aspect_rules_jasmine": "2.0.4", "aspect_tools_telemetry": "0.5.1" }, - "last_notice": 2 + "last_notice": 0 } } }, "moduleExtensionMetadata": { "useAllRepos": "NO", "reproducible": false - }, - "recordedRepoMappingEntries": [ - [ - "aspect_tools_telemetry+", - "bazel_lib", - "bazel_lib+" - ], - [ - "aspect_tools_telemetry+", - "bazel_skylib", - "bazel_skylib+" - ] - ] + } } }, "@@pybind11_bazel+//:python_configure.bzl%extension": { "general": { "bzlTransitiveDigest": "VhEtmxw1yzb9rBZVsKTdti7p+nDM/Fv1p9TmKdO45+Q=", "usagesDigest": "fycyB39YnXIJkfWCIXLUKJMZzANcuLy9ZE73hRucjFk=", - "recordedFileInputs": { - "@@pybind11_bazel+//MODULE.bazel": "88af1c246226d87e65be78ed49ecd1e6f5e98648558c14ce99176da041dc378e" - }, - "recordedDirentsInputs": {}, - "envVariables": {}, + "recordedInputs": [ + "REPO_MAPPING:pybind11_bazel+,bazel_tools bazel_tools", + "FILE:@@pybind11_bazel+//MODULE.bazel 88af1c246226d87e65be78ed49ecd1e6f5e98648558c14ce99176da041dc378e" + ], "generatedRepoSpecs": { "local_config_python": { "repoRuleId": "@@pybind11_bazel+//:python_configure.bzl%python_configure", @@ -500,23 +404,14 @@ ] } } - }, - "recordedRepoMappingEntries": [ - [ - "pybind11_bazel+", - "bazel_tools", - "bazel_tools" - ] - ] + } } }, "@@rules_angular+//setup:extensions.bzl%rules_angular": { "general": { "bzlTransitiveDigest": "aS7Uud1IzoU7PPLzH3s6IfFS4b2fa0SRWDi2/fS4bQU=", "usagesDigest": "NK6UKnTWfOFl5i+flt6LxviEbMHgJEH+JyjGkTh3Vjo=", - "recordedFileInputs": {}, - "recordedDirentsInputs": {}, - "envVariables": {}, + "recordedInputs": [], "generatedRepoSpecs": { "angular_cli_rules_angular_configurable_deps": { "repoRuleId": "@@rules_angular+//setup:repositories.bzl%configurable_deps_repo", @@ -532,17 +427,14 @@ "typescript": "@@//:node_modules/typescript" } } - }, - "recordedRepoMappingEntries": [] + } } }, "@@rules_browsers+//browsers:extensions.bzl%browsers": { "general": { "bzlTransitiveDigest": "85AglD+Q1+ncEIApuW5Ng/2cY4OkSMPrOZ05Jp4CTmk=", "usagesDigest": "FmXYJVoVJlnfUU8x8gObSvu4qWcco/9Faw61aC/wBF0=", - "recordedFileInputs": {}, - "recordedDirentsInputs": {}, - "envVariables": {}, + "recordedInputs": [], "generatedRepoSpecs": { "rules_browsers_chrome_linux": { "repoRuleId": "@@rules_browsers+//browsers/private:browser_repo.bzl%browser_repo", @@ -744,17 +636,16 @@ ] } } - }, - "recordedRepoMappingEntries": [] + } } }, "@@rules_fuzzing+//fuzzing/private:extensions.bzl%non_module_dependencies": { "general": { "bzlTransitiveDigest": "CYUiFDCnL2VGx3uotIu/VuGabgObnZra2zzRUJCX0sU=", "usagesDigest": "wy6ISK6UOcBEjj/mvJ/S3WeXoO67X+1llb9yPyFtPgc=", - "recordedFileInputs": {}, - "recordedDirentsInputs": {}, - "envVariables": {}, + "recordedInputs": [ + "REPO_MAPPING:rules_fuzzing+,bazel_tools bazel_tools" + ], "generatedRepoSpecs": { "platforms": { "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", @@ -821,23 +712,16 @@ "url": "https://repo1.maven.org/maven2/com/code-intelligence/jazzer-api/0.20.1/jazzer-api-0.20.1.jar" } } - }, - "recordedRepoMappingEntries": [ - [ - "rules_fuzzing+", - "bazel_tools", - "bazel_tools" - ] - ] + } } }, "@@rules_kotlin+//src/main/starlark/core/repositories:bzlmod_setup.bzl%rules_kotlin_extensions": { "general": { "bzlTransitiveDigest": "03Qju4tW0vE+0RBuZGuV2A4Hx6AiSkdNahYvworx2aM=", "usagesDigest": "QI2z8ZUR+mqtbwsf2fLqYdJAkPOHdOV+tF2yVAUgRzw=", - "recordedFileInputs": {}, - "recordedDirentsInputs": {}, - "envVariables": {}, + "recordedInputs": [ + "REPO_MAPPING:rules_kotlin+,bazel_tools bazel_tools" + ], "generatedRepoSpecs": { "com_github_jetbrains_kotlin_git": { "repoRuleId": "@@rules_kotlin+//src/main/starlark/core/repositories:compiler.bzl%kotlin_compiler_git_repository", @@ -885,23 +769,31 @@ ] } } - }, - "recordedRepoMappingEntries": [ - [ - "rules_kotlin+", - "bazel_tools", - "bazel_tools" - ] - ] + } } }, "@@rules_python+//python/extensions:config.bzl%config": { "general": { "bzlTransitiveDigest": "1eE/aNv0So57EZMzcxgDSCFkzlydiaC4TpHowQfrcBk=", "usagesDigest": "ZVSXMAGpD+xzVNPuvF1IoLBkty7TROO0+akMapt1pAg=", - "recordedFileInputs": {}, - "recordedDirentsInputs": {}, - "envVariables": {}, + "recordedInputs": [ + "REPO_MAPPING:rules_python+,bazel_tools bazel_tools", + "REPO_MAPPING:rules_python+,pypi__build rules_python++config+pypi__build", + "REPO_MAPPING:rules_python+,pypi__click rules_python++config+pypi__click", + "REPO_MAPPING:rules_python+,pypi__colorama rules_python++config+pypi__colorama", + "REPO_MAPPING:rules_python+,pypi__importlib_metadata rules_python++config+pypi__importlib_metadata", + "REPO_MAPPING:rules_python+,pypi__installer rules_python++config+pypi__installer", + "REPO_MAPPING:rules_python+,pypi__more_itertools rules_python++config+pypi__more_itertools", + "REPO_MAPPING:rules_python+,pypi__packaging rules_python++config+pypi__packaging", + "REPO_MAPPING:rules_python+,pypi__pep517 rules_python++config+pypi__pep517", + "REPO_MAPPING:rules_python+,pypi__pip rules_python++config+pypi__pip", + "REPO_MAPPING:rules_python+,pypi__pip_tools rules_python++config+pypi__pip_tools", + "REPO_MAPPING:rules_python+,pypi__pyproject_hooks rules_python++config+pypi__pyproject_hooks", + "REPO_MAPPING:rules_python+,pypi__setuptools rules_python++config+pypi__setuptools", + "REPO_MAPPING:rules_python+,pypi__tomli rules_python++config+pypi__tomli", + "REPO_MAPPING:rules_python+,pypi__wheel rules_python++config+pypi__wheel", + "REPO_MAPPING:rules_python+,pypi__zipp rules_python++config+pypi__zipp" + ], "generatedRepoSpecs": { "rules_python_internal": { "repoRuleId": "@@rules_python+//python/private:internal_config_repo.bzl%internal_config_repo", @@ -1045,98 +937,17 @@ "build_file_content": "package(default_visibility = [\"//visibility:public\"])\n\nload(\"@rules_python//python:py_library.bzl\", \"py_library\")\n\npy_library(\n name = \"lib\",\n srcs = glob([\"**/*.py\"]),\n data = glob([\"**/*\"], exclude=[\n # These entries include those put into user-installed dependencies by\n # data_exclude to avoid non-determinism.\n \"**/*.py\",\n \"**/*.pyc\",\n \"**/*.pyc.*\", # During pyc creation, temp files named *.pyc.NNN are created\n \"**/*.dist-info/RECORD\",\n \"BUILD\",\n \"WORKSPACE\",\n ]),\n # This makes this directory a top-level in the python import\n # search path for anything that depends on this.\n imports = [\".\"],\n)\n" } } - }, - "recordedRepoMappingEntries": [ - [ - "rules_python+", - "bazel_tools", - "bazel_tools" - ], - [ - "rules_python+", - "pypi__build", - "rules_python++config+pypi__build" - ], - [ - "rules_python+", - "pypi__click", - "rules_python++config+pypi__click" - ], - [ - "rules_python+", - "pypi__colorama", - "rules_python++config+pypi__colorama" - ], - [ - "rules_python+", - "pypi__importlib_metadata", - "rules_python++config+pypi__importlib_metadata" - ], - [ - "rules_python+", - "pypi__installer", - "rules_python++config+pypi__installer" - ], - [ - "rules_python+", - "pypi__more_itertools", - "rules_python++config+pypi__more_itertools" - ], - [ - "rules_python+", - "pypi__packaging", - "rules_python++config+pypi__packaging" - ], - [ - "rules_python+", - "pypi__pep517", - "rules_python++config+pypi__pep517" - ], - [ - "rules_python+", - "pypi__pip", - "rules_python++config+pypi__pip" - ], - [ - "rules_python+", - "pypi__pip_tools", - "rules_python++config+pypi__pip_tools" - ], - [ - "rules_python+", - "pypi__pyproject_hooks", - "rules_python++config+pypi__pyproject_hooks" - ], - [ - "rules_python+", - "pypi__setuptools", - "rules_python++config+pypi__setuptools" - ], - [ - "rules_python+", - "pypi__tomli", - "rules_python++config+pypi__tomli" - ], - [ - "rules_python+", - "pypi__wheel", - "rules_python++config+pypi__wheel" - ], - [ - "rules_python+", - "pypi__zipp", - "rules_python++config+pypi__zipp" - ] - ] + } } }, "@@rules_python+//python/uv:uv.bzl%uv": { "general": { "bzlTransitiveDigest": "ijW9KS7qsIY+yBVvJ+Nr1mzwQox09j13DnE3iIwaeTM=", "usagesDigest": "H8dQoNZcoqP+Mu0tHZTi4KHATzvNkM5ePuEqoQdklIU=", - "recordedFileInputs": {}, - "recordedDirentsInputs": {}, - "envVariables": {}, + "recordedInputs": [ + "REPO_MAPPING:rules_python+,bazel_tools bazel_tools", + "REPO_MAPPING:rules_python+,platforms platforms" + ], "generatedRepoSpecs": { "uv": { "repoRuleId": "@@rules_python+//python/uv/private:uv_toolchains_repo.bzl%uv_toolchains_repo", @@ -1156,28 +967,14 @@ "toolchain_target_settings": {} } } - }, - "recordedRepoMappingEntries": [ - [ - "rules_python+", - "bazel_tools", - "bazel_tools" - ], - [ - "rules_python+", - "platforms", - "platforms" - ] - ] + } } }, "@@yq.bzl+//yq:extensions.bzl%yq": { "general": { "bzlTransitiveDigest": "UfFMy8CWK4/dVo/tfaSAIYUiDGNAPes5eRllx9O9Q9Q=", "usagesDigest": "eEOK0cJsj9/GBF2ShPyWYqgDUBnB4T9UVZlCprAY7Iw=", - "recordedFileInputs": {}, - "recordedDirentsInputs": {}, - "envVariables": {}, + "recordedInputs": [], "generatedRepoSpecs": { "yq_darwin_amd64": { "repoRuleId": "@@yq.bzl+//yq/toolchain:platforms.bzl%yq_platform_repo", @@ -1248,8 +1045,7 @@ "user_repository_name": "yq" } } - }, - "recordedRepoMappingEntries": [] + } } } }, @@ -1257,5 +1053,6 @@ "@@aspect_tools_telemetry+//:extension.bzl%telemetry": { "notice_version": "2" } - } + }, + "factsVersions": {} } From 19866370d7b33dd36e1a828ee4def49b73957a3c Mon Sep 17 00:00:00 2001 From: Doug Parker Date: Wed, 2 Sep 2026 12:29:20 -0700 Subject: [PATCH 398/787] docs: release notes for the v20.3.36 release --- CHANGELOG.md | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index e1fcb5a988ac..e46be1a3ef17 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,21 @@ + + +# 20.3.36 (2026-09-02) + +### @angular-devkit/build-angular + +| Commit | Type | Description | +| --------------------------------------------------------------------------------------------------- | ---- | -------------------- | +| [b4059cdc7](https://github.com/angular/angular-cli/commit/b4059cdc7b7a65e68abfcf9fb53a6304790b1796) | fix | update less to 4.9.0 | + +### @angular/ssr + +| Commit | Type | Description | +| --------------------------------------------------------------------------------------------------- | ---- | --------------------------------------------------- | +| [c3e5982e4](https://github.com/angular/angular-cli/commit/c3e5982e49705f0f6a913cb94622b4c555d2d914) | fix | ensure public directory containment in CommonEngine | + + + # 22.2.0-next.5 (2026-08-26) From be7b0d39e2982135888a93eec2063e375d972b43 Mon Sep 17 00:00:00 2001 From: Doug Parker Date: Wed, 2 Sep 2026 13:34:19 -0700 Subject: [PATCH 399/787] docs: release notes for the v21.2.23 release --- CHANGELOG.md | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index e46be1a3ef17..d72313321780 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,21 @@ + + +# 21.2.23 (2026-09-02) + +### @angular-devkit/build-angular + +| Commit | Type | Description | +| --------------------------------------------------------------------------------------------------- | ---- | -------------------- | +| [d3aaa48ef](https://github.com/angular/angular-cli/commit/d3aaa48ef35b80c3297ee3050cd239f84d051899) | fix | update less to 4.9.0 | + +### @angular/ssr + +| Commit | Type | Description | +| --------------------------------------------------------------------------------------------------- | ---- | --------------------------------------------------- | +| [645e41a47](https://github.com/angular/angular-cli/commit/645e41a47d21b7651837a4250de99af0509626e2) | fix | ensure public directory containment in CommonEngine | + + + # 20.3.36 (2026-09-02) From 6c1a016efa0e647ab171b27f7a2b1368beb42275 Mon Sep 17 00:00:00 2001 From: Doug Parker Date: Wed, 2 Sep 2026 14:04:17 -0700 Subject: [PATCH 400/787] docs: release notes for the v22.1.7 release --- CHANGELOG.md | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index d72313321780..14733ef85264 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,32 @@ + + +# 22.1.7 (2026-09-02) + +### @angular/cli + +| Commit | Type | Description | +| --------------------------------------------------------------------------------------------------- | ---- | ------------------------------------------------------------------ | +| [e9db85c0f](https://github.com/angular/angular-cli/commit/e9db85c0f5ef0aa0c67d2b8d90b872307af39822) | fix | isolate temporary package installations from parent Yarn workspace | + +### @angular/build + +| Commit | Type | Description | +| --------------------------------------------------------------------------------------------------- | ---- | ----------------------------------------------------- | +| [1c9b1af61](https://github.com/angular/angular-cli/commit/1c9b1af61115764e0be55f5a1ed9a9967c191a74) | fix | add splitting option to unit-test builder | +| [4b861f458](https://github.com/angular/angular-cli/commit/4b861f458c8c789a5276f7b591bebd28e2080444) | fix | enable code splitting for vitest browser tests | +| [f1fd82381](https://github.com/angular/angular-cli/commit/f1fd823814b5e3620838beb423d5f33600c2e546) | fix | fail build and exclude routes when prerendering fails | +| [a84906fe3](https://github.com/angular/angular-cli/commit/a84906fe393e8c2dee978c02631af20e93627df1) | fix | keep dev-server Vite cache worktree-local | +| [fcf883ef1](https://github.com/angular/angular-cli/commit/fcf883ef166dc2e34d86007c0fcdfad1d0434c86) | fix | preserve binary values in the SQLite cache store | + +### @angular/ssr + +| Commit | Type | Description | +| --------------------------------------------------------------------------------------------------- | ---- | --------------------------------------------------- | +| [baf1ca189](https://github.com/angular/angular-cli/commit/baf1ca189dcf1ab0e55ac853c80f892dbd1864e4) | fix | decode pathname when constructing server asset path | +| [70748ca8e](https://github.com/angular/angular-cli/commit/70748ca8e76fe4b42798719410336119d943e755) | fix | ensure public directory containment in CommonEngine | + + + # 21.2.23 (2026-09-02) From 1b03d3478d143d5734868effd5bc8a196f78bef2 Mon Sep 17 00:00:00 2001 From: Doug Parker Date: Wed, 2 Sep 2026 14:19:48 -0700 Subject: [PATCH 401/787] release: cut the v22.2.0-next.6 release --- CHANGELOG.md | 34 ++++++++++++++++++++++++++++++++++ package.json | 2 +- 2 files changed, 35 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 14733ef85264..77a769a1ebb3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,37 @@ + + +# 22.2.0-next.6 (2026-09-02) + +### @angular/cli + +| Commit | Type | Description | +| --------------------------------------------------------------------------------------------------- | ---- | ------------------------------------------------------------------ | +| [b37c93329](https://github.com/angular/angular-cli/commit/b37c933299dac37e394d9f4fe0d019052db427a9) | fix | isolate temporary package installations from parent Yarn workspace | + +### @angular/build + +| Commit | Type | Description | +| --------------------------------------------------------------------------------------------------- | ---- | ------------------------------------------------------------- | +| [4b8c62a8f](https://github.com/angular/angular-cli/commit/4b8c62a8f1a1d312ef2e1e0df6b7642bf1db5c5f) | fix | add splitting option to unit-test builder | +| [51565d4bc](https://github.com/angular/angular-cli/commit/51565d4bcbd4667c23c607d878f08301afc4c5e3) | fix | enable code splitting for vitest browser tests | +| [5b850fdfc](https://github.com/angular/angular-cli/commit/5b850fdfc7534d33db7ab4a7f1e32e143462eec7) | fix | fail build and exclude routes when prerendering fails | +| [dfa7f03a9](https://github.com/angular/angular-cli/commit/dfa7f03a93b5b24b949aea354bc40f0a91e9582d) | fix | keep dev-server Vite cache worktree-local | +| [135662d9a](https://github.com/angular/angular-cli/commit/135662d9a1de85b42292b26b547160eaca71e5da) | fix | preserve binary values in the SQLite cache store | +| [701bde481](https://github.com/angular/angular-cli/commit/701bde4818439de0e49c99d57dc749b0dd22c4dd) | fix | preserve duplicate bundle filenames across output file types | +| [6ee559ca9](https://github.com/angular/angular-cli/commit/6ee559ca9d209fb4c53de2aaf9918d10e5f062a1) | perf | bypass worker dispatch for files without transform candidates | +| [2b85529e8](https://github.com/angular/angular-cli/commit/2b85529e8290c8c916539b5a0336b4efdb68578c) | perf | use iterative post-order AST traversal for OXC transforms | +| [ecbcd87b8](https://github.com/angular/angular-cli/commit/ecbcd87b8857225e4df3df7896b3236d63553f23) | perf | use native sass-embedded compiler daemon | +| [ce83ac0e8](https://github.com/angular/angular-cli/commit/ce83ac0e82981efd9408e07a35315e3cef9e1a36) | perf | use size-weighted task heuristics in i18n inliner | + +### @angular/ssr + +| Commit | Type | Description | +| --------------------------------------------------------------------------------------------------- | ---- | --------------------------------------------------- | +| [4fa81d403](https://github.com/angular/angular-cli/commit/4fa81d403c93a7480301e58630203cb028aebc69) | fix | decode pathname when constructing server asset path | +| [bb72145f9](https://github.com/angular/angular-cli/commit/bb72145f9ab45aee29f523236b3a25cd0813a841) | fix | ensure public directory containment in CommonEngine | + + + # 22.1.7 (2026-09-02) diff --git a/package.json b/package.json index ade980daf327..f018cce39ccc 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@angular/devkit-repo", - "version": "22.2.0-next.5", + "version": "22.2.0-next.6", "private": true, "description": "Software Development Kit for Angular", "keywords": [ From 12459ee5084311c9d7be53b179e26f3860207b49 Mon Sep 17 00:00:00 2001 From: Charles Lyding <19598772+clydin@users.noreply.github.com> Date: Wed, 2 Sep 2026 09:59:04 -0400 Subject: [PATCH 402/787] refactor(@angular/build): replace maxThreads with maxConcurrency option in i18n inliner The I18nInliner constructor previously accepted an optional maxThreads parameter as a second argument, while sliding window sizing and batch sharding calculations accessed this.#workerPool.maxThreads directly. This couples the inliner concurrency planning to the worker pool construction argument and makes it awkward to configure when using or moving toward shared worker pools. This change adds maxConcurrency to I18nInlinerOptions and removes the separate maxThreads constructor parameter. The internal #maxConcurrency getter prioritizes options.maxConcurrency before falling back to the worker pool thread count. All call sites and tests now pass maxConcurrency through the options object. --- .../build/src/builders/application/i18n.ts | 14 +- .../build/src/tools/esbuild/i18n-inliner.ts | 31 ++- .../src/tools/esbuild/i18n-inliner_spec.ts | 194 ++++++++++++++---- 3 files changed, 182 insertions(+), 57 deletions(-) diff --git a/packages/angular/build/src/builders/application/i18n.ts b/packages/angular/build/src/builders/application/i18n.ts index d2db9b6babd9..f775acdc491d 100644 --- a/packages/angular/build/src/builders/application/i18n.ts +++ b/packages/angular/build/src/builders/application/i18n.ts @@ -45,14 +45,12 @@ export async function inlineI18n( const { i18nOptions, baseHref, cacheOptions } = options; // Create the multi-threaded inliner with common options. - const inliner = new I18nInliner( - { - missingTranslation: i18nOptions.missingTranslationBehavior ?? 'warning', - persistentCachePath: cacheOptions.enabled ? cacheOptions.path : undefined, - localizeVersion: i18nOptions.localizeVersion, - }, - maxWorkers, - ); + const inliner = new I18nInliner({ + missingTranslation: i18nOptions.missingTranslationBehavior ?? 'warning', + maxConcurrency: maxWorkers, + persistentCachePath: cacheOptions.enabled ? cacheOptions.path : undefined, + localizeVersion: i18nOptions.localizeVersion, + }); const inlineResult: { errors: string[]; diff --git a/packages/angular/build/src/tools/esbuild/i18n-inliner.ts b/packages/angular/build/src/tools/esbuild/i18n-inliner.ts index 212095c38761..d76b00c0a31a 100644 --- a/packages/angular/build/src/tools/esbuild/i18n-inliner.ts +++ b/packages/angular/build/src/tools/esbuild/i18n-inliner.ts @@ -121,6 +121,12 @@ async function serializeTranslation( */ export interface I18nInlinerOptions { missingTranslation: 'error' | 'warning' | 'ignore'; + + /** + * The maximum number of concurrent translation inlining operations. + * When omitted, concurrency defaults to the available worker pool threads. + */ + maxConcurrency?: number; persistentCachePath?: string; localizeVersion?: string; } @@ -187,12 +193,23 @@ export class I18nInliner { #translationCache: Cache | undefined; #generation = 0; - constructor( - private readonly options: I18nInlinerOptions, - maxThreads?: number, - ) { + get #maxConcurrency(): number { + return this.options.maxConcurrency ?? (this.#workerPool.maxThreads || 1); + } + + constructor(private readonly options: I18nInlinerOptions) { + if ( + options.maxConcurrency !== undefined && + (!Number.isInteger(options.maxConcurrency) || options.maxConcurrency < 1) + ) { + throw new RangeError('options.maxConcurrency must be an integer greater than or equal to 1.'); + } + + // Piscina uses object spread against default options internally. Only define + // maxThreads when specified to avoid overwriting Piscina's default thread count + // with undefined. this.#workerPool = new WorkerPool({ - maxThreads, + ...(options.maxConcurrency !== undefined && { maxThreads: options.maxConcurrency }), }); } @@ -286,7 +303,7 @@ export class I18nInliner { // Process locales in sliding windows to cap peak worker memory. // Ensure the window has at least enough locales to saturate all available workers on high-core machines. - const windowSize = Math.max(DEFAULT_LOCALE_WINDOW_SIZE, this.#workerPool.maxThreads || 1); + const windowSize = Math.max(DEFAULT_LOCALE_WINDOW_SIZE, this.#maxConcurrency); for (let i = 0; i < localeList.length; i += windowSize) { const windowLocales = localeList.slice(i, i + windowSize); const activeLocales = windowLocales.map((item) => item.locale); @@ -461,7 +478,7 @@ export class I18nInliner { isLastWindow = true, generation?: number, ): Promise { - const workerCount = this.#workerPool.maxThreads || 1; + const workerCount = this.#maxConcurrency; // Extract file data and identify the heaviest file size in a single pass let maxFileSize = 0; diff --git a/packages/angular/build/src/tools/esbuild/i18n-inliner_spec.ts b/packages/angular/build/src/tools/esbuild/i18n-inliner_spec.ts index e64efe2fa05b..b02b171cf399 100644 --- a/packages/angular/build/src/tools/esbuild/i18n-inliner_spec.ts +++ b/packages/angular/build/src/tools/esbuild/i18n-inliner_spec.ts @@ -12,6 +12,7 @@ import fs from 'node:fs/promises'; import os from 'node:os'; import path from 'node:path'; import { initializeHash } from '../../utils/hash'; +import { WorkerPool } from '../../utils/worker-pool'; import { type BuildOutputFile, BuildOutputFileType, createOutputFile } from './bundler-files'; import { createPersistentCacheStore } from './cache'; import { I18nInliner, type I18nInlinerOptions } from './i18n-inliner'; @@ -63,8 +64,8 @@ describe('I18nInliner', () => { // A single thread is used throughout so that every file of every locale is inlined by the same // Worker. Any translation state that a Worker retains between requests is then observable. - function createInliner(options?: Partial, maxThreads = 1): I18nInliner { - inliner = new I18nInliner({ missingTranslation: 'warning', ...options }, maxThreads); + function createInliner(options?: Partial, maxConcurrency = 1): I18nInliner { + inliner = new I18nInliner({ missingTranslation: 'warning', maxConcurrency, ...options }); return inliner; } @@ -341,12 +342,10 @@ describe('I18nInliner', () => { browserFile('chunk2.js', GREETING_SOURCE), browserFile('chunk3.js', GREETING_SOURCE), ]; - inliner = new I18nInliner( - { - missingTranslation: 'warning', - }, - 4, - ); + inliner = new I18nInliner({ + missingTranslation: 'warning', + maxConcurrency: 4, + }); const { outputFiles, errors, warnings } = await inliner.inlineForLocale(files, 'fr', { greeting: translationFor('Bonjour'), @@ -423,13 +422,11 @@ describe('I18nInliner', () => { }); it('inlines the translations of a locale when localizeVersion is configured in options', async () => { - inliner = new I18nInliner( - { - missingTranslation: 'warning', - localizeVersion: '20.2.0', - }, - 1, - ); + inliner = new I18nInliner({ + missingTranslation: 'warning', + localizeVersion: '20.2.0', + maxConcurrency: 1, + }); const { outputFiles, errors, warnings } = await inliner.inlineForLocale( [browserFile('main.js', GREETING_SOURCE)], @@ -543,13 +540,11 @@ describe('I18nInliner', () => { browserFile('main.js', GREETING_SOURCE), browserFile('other.js', 'export const answer = 42;\n'), ]; - const initialInliner = new I18nInliner( - { - missingTranslation: 'warning', - persistentCachePath: cacheDir, - }, - 2, - ); + const initialInliner = new I18nInliner({ + missingTranslation: 'warning', + persistentCachePath: cacheDir, + maxConcurrency: 2, + }); // Pre-populate cache for 'fr' await initialInliner.inlineForLocale( @@ -561,13 +556,11 @@ describe('I18nInliner', () => { await initialInliner.close(); // Create new inliner with same cache path, inlining cached 'fr' alongside uncached 'de' and 'es' - inliner = new I18nInliner( - { - missingTranslation: 'warning', - persistentCachePath: cacheDir, - }, - 2, - ); + inliner = new I18nInliner({ + missingTranslation: 'warning', + persistentCachePath: cacheDir, + maxConcurrency: 2, + }); const results = await inliner.inlineAll(files, [ { @@ -618,12 +611,10 @@ describe('I18nInliner', () => { })); const files = [browserFile('main.js', GREETING_SOURCE)]; - inliner = new I18nInliner( - { - missingTranslation: 'warning', - }, - 2, - ); + inliner = new I18nInliner({ + missingTranslation: 'warning', + maxConcurrency: 2, + }); const results = await inliner.inlineAll(files, locales); @@ -882,12 +873,10 @@ describe('I18nInliner', () => { }); it('correctly transforms files across multiple inlineAll runs on the same inliner instance', async () => { - const localeInliner = new I18nInliner( - { - missingTranslation: 'warning', - }, - 2, - ); + const localeInliner = new I18nInliner({ + missingTranslation: 'warning', + maxConcurrency: 2, + }); try { const files1 = [browserFile('main.js', GREETING_SOURCE)]; @@ -942,7 +931,7 @@ describe('I18nInliner', () => { const smallFile = browserFile('chunk.js', smallSource); const files = [largeFile, smallFile]; - inliner = new I18nInliner({ missingTranslation: 'error' }, 2); + inliner = new I18nInliner({ missingTranslation: 'error', maxConcurrency: 2 }); const results = await inliner.inlineAll(files, [ { @@ -982,4 +971,125 @@ describe('I18nInliner', () => { expect(findFile(esFiles, 'main.js').text).toContain('"Hola"'); expect(findFile(esFiles, 'chunk.js').text).toContain('"Adios"'); }); + + it('respects maxConcurrency when processing multiple locales and files', async () => { + const files = [ + browserFile('main.js', GREETING_SOURCE), + browserFile('chunk.js', 'console.log($localize`:@@farewell:Goodbye`);'), + ]; + + inliner = new I18nInliner({ + missingTranslation: 'error', + maxConcurrency: 1, + }); + + const results = await inliner.inlineAll(files, [ + { + locale: 'fr', + translation: { + greeting: translationFor('Bonjour'), + farewell: translationFor('Au revoir'), + }, + }, + { + locale: 'de', + translation: { + greeting: translationFor('Guten Tag'), + farewell: translationFor('Auf Wiedersehen'), + }, + }, + ]); + + expect(results.size).toBe(2); + expect(findFile(results.get('fr')?.outputFiles ?? [], 'main.js').text).toContain('"Bonjour"'); + expect(findFile(results.get('de')?.outputFiles ?? [], 'chunk.js').text).toContain( + '"Auf Wiedersehen"', + ); + }); + + describe('maxConcurrency validation', () => { + it('throws when maxConcurrency is less than 1', () => { + expect( + () => + new I18nInliner({ + missingTranslation: 'warning', + maxConcurrency: 0, + }), + ).toThrowError( + RangeError, + 'options.maxConcurrency must be an integer greater than or equal to 1.', + ); + + expect( + () => + new I18nInliner({ + missingTranslation: 'warning', + maxConcurrency: -1, + }), + ).toThrowError( + RangeError, + 'options.maxConcurrency must be an integer greater than or equal to 1.', + ); + }); + + it('throws when maxConcurrency is not an integer', () => { + expect( + () => + new I18nInliner({ + missingTranslation: 'warning', + maxConcurrency: 1.5, + }), + ).toThrowError( + RangeError, + 'options.maxConcurrency must be an integer greater than or equal to 1.', + ); + + expect( + () => + new I18nInliner({ + missingTranslation: 'warning', + maxConcurrency: NaN, + }), + ).toThrowError( + RangeError, + 'options.maxConcurrency must be an integer greater than or equal to 1.', + ); + + expect( + () => + new I18nInliner({ + missingTranslation: 'warning', + maxConcurrency: Infinity, + }), + ).toThrowError( + RangeError, + 'options.maxConcurrency must be an integer greater than or equal to 1.', + ); + }); + + it('defaults to worker pool concurrency when maxConcurrency is omitted', async () => { + const maxThreadsSpy = spyOnProperty( + WorkerPool.prototype, + 'maxThreads', + 'get', + ).and.callThrough(); + + inliner = new I18nInliner({ + missingTranslation: 'warning', + }); + + const files = [browserFile('main.js', GREETING_SOURCE)]; + const results = await inliner.inlineAll(files, [ + { + locale: 'fr', + translation: { greeting: translationFor('Bonjour') }, + }, + ]); + + expect(results.size).toBe(1); + expect(findFile(results.get('fr')?.outputFiles ?? [], 'main.js').text).toContain('"Bonjour"'); + expect(maxThreadsSpy).toHaveBeenCalled(); + expect(maxThreadsSpy.calls.mostRecent().returnValue).toBeGreaterThanOrEqual(1); + }); + }); }); From 675f1f5274ff853f153832f7adc69273fa63f0cd Mon Sep 17 00:00:00 2001 From: Alan Agius <17563226+alan-agius4@users.noreply.github.com> Date: Thu, 3 Sep 2026 12:52:59 +0000 Subject: [PATCH 403/787] fix(@angular/build): avoid pure comment pattern in oxc transform In Bun 1.4.0, single-line comments containing `/*#__PURE__*/` immediately preceding a call expression cause Bun's lexer/transpiler to interpret the call as pure and drop it during dead code elimination when its return value is unused. Sanitizing the comment avoids triggering this upstream Bun bug. Fixes #33973 --- packages/angular/build/src/tools/oxc/oxc-transform.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/angular/build/src/tools/oxc/oxc-transform.ts b/packages/angular/build/src/tools/oxc/oxc-transform.ts index e4f60ff83cb2..e0d6ba26a252 100644 --- a/packages/angular/build/src/tools/oxc/oxc-transform.ts +++ b/packages/angular/build/src/tools/oxc/oxc-transform.ts @@ -599,7 +599,7 @@ export function transform(filename: string, code: string, options: OxcTransformO source.appendRight(classNode.start, `let ${classIdName} = /*#__PURE__*/ (() => {\n`); source.appendLeft(lastStatement.end, `\nreturn ${classIdName};\n})();`); } else if (isVariableClass) { - // Wrap class inside init: `/*#__PURE__*/ (() => { let ClassName = class ClassName {}; return ClassName; })()` + // 2. Wrap class inside init: `(() => { let ClassName = class ClassName {}; return ClassName; })()` source.appendRight(classNode.start, `/*#__PURE__*/ (() => {\nlet ${classIdName} = `); const terminator = activeWrapPaths.length === 0 ? ';' : ''; const iifeClosing = activeWrapPaths.length === 0 ? '})()' : '})();'; From 14c54b3a3cdf9665a0b75876e6223490df65bee2 Mon Sep 17 00:00:00 2001 From: Charles Lyding <19598772+clydin@users.noreply.github.com> Date: Wed, 2 Sep 2026 17:12:47 -0400 Subject: [PATCH 404/787] refactor(@angular/build): unify configuration loading and option transformations in TypeScriptCompilation Both AotCompilation and JitCompilation previously executed identical logic during initialization to read tsconfig.json using readConfiguration and immediately pass the options to transformCompilerOptions. The loadConfiguration method on TypeScriptCompilation now accepts optional compilerOptionOverrides and applies transformCompilerOptions directly. This unifies configuration reading and option transformations into a single cohesive step, eliminates duplicate setup boilerplate across AotCompilation and JitCompilation, and reduces unnecessary direct imports of transformCompilerOptions. --- .../compilation/angular-compilation_spec.ts | 32 +++++++++++++++++- .../angular/compilation/aot-compilation.ts | 15 +++------ .../angular/compilation/jit-compilation.ts | 15 +++------ .../compilation/typescript-compilation.ts | 33 +++++++++++++++++-- 4 files changed, 70 insertions(+), 25 deletions(-) diff --git a/packages/angular/build/src/tools/angular/compilation/angular-compilation_spec.ts b/packages/angular/build/src/tools/angular/compilation/angular-compilation_spec.ts index a867f666c349..71eacd562259 100644 --- a/packages/angular/build/src/tools/angular/compilation/angular-compilation_spec.ts +++ b/packages/angular/build/src/tools/angular/compilation/angular-compilation_spec.ts @@ -8,7 +8,7 @@ import ts from 'typescript'; import type { AngularHostOptions } from '../angular-host'; -import { transformCompilerOptions } from './compiler-options'; +import { CompilerOptionOverrides, transformCompilerOptions } from './compiler-options'; import { TypeScriptCompilation } from './typescript-compilation'; import { AngularCompilation, @@ -90,6 +90,10 @@ describe('AngularCompilation', () => { public getCachedSourceFiles(): Map { return this.sourceFiles; } + + public async testLoadConfiguration(tsconfig: string, overrides?: CompilerOptionOverrides) { + return this.loadConfiguration(tsconfig, overrides); + } } it('collects and converts diagnostics categorized by error and warning', async () => { @@ -134,6 +138,32 @@ describe('AngularCompilation', () => { expect(compilerCli).toBeDefined(); expect(typeof compilerCli.readConfiguration).toBe('function'); }); + + it('loads configuration and applies compiler option transformations', async () => { + const compilation = new MockTypeScriptCompilation(); + const mockReadConfig = jasmine.createSpy('readConfiguration').and.returnValue({ + options: { target: ts.ScriptTarget.ES2020 }, + rootNames: ['/src/main.ts'], + errors: [], + }); + spyOn(TypeScriptCompilation, 'loadCompilerCli').and.resolveTo({ + readConfiguration: mockReadConfig, + } as unknown as typeof import('@angular/compiler-cli')); + + const result = await compilation.testLoadConfiguration('tsconfig.json', { sourcemap: true }); + + expect(mockReadConfig).toHaveBeenCalledWith( + 'tsconfig.json', + jasmine.objectContaining({ + suppressOutputPathCheck: true, + outDir: undefined, + }), + ); + expect(result.rootNames).toEqual(['/src/main.ts']); + expect(result.compilerOptions.target).toBe(ts.ScriptTarget.ES2022); + expect(result.compilerOptions.inlineSources).toBe(true); + expect(result.warnings.length).toBeGreaterThan(0); + }); }); describe('createAngularCompilation', () => { diff --git a/packages/angular/build/src/tools/angular/compilation/aot-compilation.ts b/packages/angular/build/src/tools/angular/compilation/aot-compilation.ts index 9fd160774cf7..ca74e721ba7d 100644 --- a/packages/angular/build/src/tools/angular/compilation/aot-compilation.ts +++ b/packages/angular/build/src/tools/angular/compilation/aot-compilation.ts @@ -7,7 +7,6 @@ */ import type * as ng from '@angular/compiler-cli'; -import type { PartialMessage } from 'esbuild'; import assert from 'node:assert'; import { relative } from 'node:path'; import ts from 'typescript'; @@ -26,7 +25,7 @@ import { DiagnosticModes, type EmitFileResult, } from './angular-compilation'; -import { CompilerOptionOverrides, transformCompilerOptions } from './compiler-options'; +import type { CompilerOptionOverrides } from './compiler-options'; import { collectHmrCandidates } from './hmr-candidates'; import { TypeScriptCompilation } from './typescript-compilation'; import { printSourceFileWithMap } from './typescript-printer'; @@ -72,17 +71,11 @@ export class AotCompilation extends TypeScriptCompilation { // Load the compiler configuration and transform as needed const { - options: originalCompilerOptions, + compilerOptions, rootNames, errors: configurationDiagnostics, - } = await this.loadConfiguration(tsconfig); - - const { compilerOptions, warnings } = transformCompilerOptions( - ts, - originalCompilerOptions, - compilerOptionOverrides, - tsconfig, - ); + warnings, + } = await this.loadConfiguration(tsconfig, compilerOptionOverrides); const useTypeScriptTranspilation = (compilerOptions['_useTypeScriptTranspilation'] as boolean | undefined) ?? diff --git a/packages/angular/build/src/tools/angular/compilation/jit-compilation.ts b/packages/angular/build/src/tools/angular/compilation/jit-compilation.ts index fee636219be0..233f5977e5a6 100644 --- a/packages/angular/build/src/tools/angular/compilation/jit-compilation.ts +++ b/packages/angular/build/src/tools/angular/compilation/jit-compilation.ts @@ -7,7 +7,6 @@ */ import type * as ng from '@angular/compiler-cli'; -import type { PartialMessage } from 'esbuild'; import assert from 'node:assert'; import ts from 'typescript'; import { profileSync } from '../../esbuild/profiling'; @@ -20,7 +19,7 @@ import { DiagnosticModes, type EmitFileResult, } from './angular-compilation'; -import { CompilerOptionOverrides, transformCompilerOptions } from './compiler-options'; +import type { CompilerOptionOverrides } from './compiler-options'; import { TypeScriptCompilation } from './typescript-compilation'; class JitCompilationState { @@ -51,17 +50,11 @@ export class JitCompilation extends TypeScriptCompilation { // Load the compiler configuration and transform as needed const { - options: originalCompilerOptions, + compilerOptions, rootNames, errors: configurationDiagnostics, - } = await this.loadConfiguration(tsconfig); - - const { compilerOptions, warnings } = transformCompilerOptions( - ts, - originalCompilerOptions, - compilerOptionOverrides, - tsconfig, - ); + warnings, + } = await this.loadConfiguration(tsconfig, compilerOptionOverrides); if (hostOptions.modifiedFiles) { this.invalidateFiles(hostOptions.modifiedFiles); diff --git a/packages/angular/build/src/tools/angular/compilation/typescript-compilation.ts b/packages/angular/build/src/tools/angular/compilation/typescript-compilation.ts index 970041f916fc..71061031f3a4 100644 --- a/packages/angular/build/src/tools/angular/compilation/typescript-compilation.ts +++ b/packages/angular/build/src/tools/angular/compilation/typescript-compilation.ts @@ -12,8 +12,16 @@ import ts from 'typescript'; import { toPosixPath } from '../../../utils/path'; import { profileAsync, profileSync } from '../../esbuild/profiling'; import { AngularCompilation, DiagnosticModes } from './angular-compilation'; +import { type CompilerOptionOverrides, transformCompilerOptions } from './compiler-options'; import { convertTypeScriptDiagnostic } from './diagnostics'; +export interface TransformedConfiguration { + compilerOptions: ng.CompilerOptions; + rootNames: string[]; + errors: ts.Diagnostic[]; + warnings: PartialMessage[]; +} + export abstract class TypeScriptCompilation extends AngularCompilation { static #angularCompilerCliModule?: typeof ng; @@ -23,10 +31,17 @@ export abstract class TypeScriptCompilation extends AngularCompilation { return TypeScriptCompilation.#angularCompilerCliModule; } - protected async loadConfiguration(tsconfig: string): Promise { + protected async loadConfiguration( + tsconfig: string, + compilerOptionOverrides?: CompilerOptionOverrides, + ): Promise { const { readConfiguration } = await TypeScriptCompilation.loadCompilerCli(); - return profileSync('NG_READ_CONFIG', () => + const { + options: originalCompilerOptions, + rootNames, + errors, + } = profileSync('NG_READ_CONFIG', () => readConfiguration(tsconfig, { // Angular specific configuration defaults and overrides to ensure a functioning compilation. suppressOutputPathCheck: true, @@ -44,6 +59,20 @@ export abstract class TypeScriptCompilation extends AngularCompilation { removeComments: false, }), ); + + const { compilerOptions, warnings } = transformCompilerOptions( + ts, + originalCompilerOptions, + compilerOptionOverrides, + tsconfig, + ); + + return { + compilerOptions, + rootNames, + errors, + warnings, + }; } protected readonly sourceFiles = new Map(); From e88610d5a71089636985e45d177a4a2638a354bf Mon Sep 17 00:00:00 2001 From: Charles Lyding <19598772+clydin@users.noreply.github.com> Date: Wed, 2 Sep 2026 13:06:03 -0400 Subject: [PATCH 405/787] refactor(@angular/build): add composite index on last_accessed in sqlite cache store Previously, the SQLite cache table had no secondary index on `last_accessed`. Cache eviction routines during `close()` required full table scans for both TTL-based pruning and LRU size-based pruning. Specifically, calculating running sizes using a window function ordered by `last_accessed DESC, key DESC` required SQLite to materialize and sort the entire table in temporary memory on every cache close. In large persistent caches, these full scans and temporary sorts introduced unnecessary CPU and I/O overhead on shutdown. A composite index `idx_cache_accessed` on `(last_accessed DESC, key DESC)` is now created on the cache table. This enables SQLite to directly seek entries older than the TTL limit using an indexed binary search and stream rows in descending access order for the window aggregate calculation without requiring an in-memory sort pass. --- .../src/tools/esbuild/sqlite-cache-store.ts | 3 +++ .../tools/esbuild/sqlite-cache-store_spec.ts | 19 +++++++++++++++++++ 2 files changed, 22 insertions(+) diff --git a/packages/angular/build/src/tools/esbuild/sqlite-cache-store.ts b/packages/angular/build/src/tools/esbuild/sqlite-cache-store.ts index cbd51d345ddd..e07eac515a3a 100644 --- a/packages/angular/build/src/tools/esbuild/sqlite-cache-store.ts +++ b/packages/angular/build/src/tools/esbuild/sqlite-cache-store.ts @@ -46,6 +46,9 @@ export class SqliteCacheStore implements PersistentCacheStore { this.#db.exec( 'CREATE TABLE IF NOT EXISTS cache (key TEXT PRIMARY KEY, value BLOB, last_accessed INTEGER NOT NULL) WITHOUT ROWID;', ); + this.#db.exec( + 'CREATE INDEX IF NOT EXISTS idx_cache_accessed ON cache (last_accessed DESC, key DESC);', + ); this.#getStmt = this.#db.prepare('SELECT value FROM cache WHERE key = ?'); this.#hasStmt = this.#db.prepare('SELECT 1 FROM cache WHERE key = ?'); diff --git a/packages/angular/build/src/tools/esbuild/sqlite-cache-store_spec.ts b/packages/angular/build/src/tools/esbuild/sqlite-cache-store_spec.ts index 75ab1a358573..9ac9bee23ddb 100644 --- a/packages/angular/build/src/tools/esbuild/sqlite-cache-store_spec.ts +++ b/packages/angular/build/src/tools/esbuild/sqlite-cache-store_spec.ts @@ -187,6 +187,25 @@ describe('SqliteCacheStore', () => { checkStore.close(); }); + it('should create an index on last_accessed and key', async () => { + // Trigger db initialization + await store.set('test-key', 'test-value'); + store.close(); + + const { DatabaseSync } = await import('node:sqlite'); + const directDb = new DatabaseSync(cachePath); + try { + const indexRows = directDb + .prepare( + "SELECT name FROM sqlite_master WHERE type = 'index' AND tbl_name = 'cache' AND name = 'idx_cache_accessed'", + ) + .all(); + expect(indexRows.length).toBe(1); + } finally { + directDb.close(); + } + }); + describe('NG_BUILD_CACHE_STORE env variable option', () => { it('should force SQLite when NG_BUILD_CACHE_STORE=sqlite', () => { const code = ` From 3b0148293f333ef7019d3444dfb3e5f0282772cd Mon Sep 17 00:00:00 2001 From: Charles Lyding <19598772+clydin@users.noreply.github.com> Date: Wed, 2 Sep 2026 13:38:54 -0400 Subject: [PATCH 406/787] refactor(@angular/build): optimize pruning in sqlite cache store Previously, cache eviction routines during close executed as independent autocommit transactions. In addition, the LRU size pruning query calculated running payload sizes with a window function across the entire cache table on every build, even when total database size was well below maxPayloadSize. Pruning operations in close are now wrapped in an immediate transaction to ensure atomicity and reduce transaction commit overhead. Furthermore, total database size is checked using SQLite page pragmas prior to size-based pruning, allowing the expensive window aggregate query to be skipped when the total cache size is already within limits. --- .../src/tools/esbuild/sqlite-cache-store.ts | 61 +++++++++++++------ .../tools/esbuild/sqlite-cache-store_spec.ts | 14 +++++ 2 files changed, 58 insertions(+), 17 deletions(-) diff --git a/packages/angular/build/src/tools/esbuild/sqlite-cache-store.ts b/packages/angular/build/src/tools/esbuild/sqlite-cache-store.ts index e07eac515a3a..a46251ce4d31 100644 --- a/packages/angular/build/src/tools/esbuild/sqlite-cache-store.ts +++ b/packages/angular/build/src/tools/esbuild/sqlite-cache-store.ts @@ -146,22 +146,45 @@ export class SqliteCacheStore implements PersistentCacheStore { // Flush any pending access updates in one transaction before pruning this.#flushAccessUpdates(); - // 1. Delete items older than N days - this.#db - .prepare("DELETE FROM cache WHERE last_accessed < unixepoch('now', ?);") - .run(`-${this.ttlDays} days`); - - // 2. Prune oldest items if payload exceeds maxPayloadSize - const pruneStmt = this.#db.prepare(` - DELETE FROM cache WHERE key IN ( - SELECT key FROM ( - SELECT key, - sum(length(key) + length(value)) OVER (ORDER BY last_accessed DESC, key DESC) as running_size - FROM cache - ) WHERE running_size > ? - ); - `); - pruneStmt.run(this.maxPayloadSize); + this.#db.exec('BEGIN IMMEDIATE TRANSACTION;'); + try { + // 1. Delete items older than N days + this.#db + .prepare("DELETE FROM cache WHERE last_accessed < unixepoch('now', ?);") + .run(`-${this.ttlDays} days`); + + // 2. Prune oldest items if payload exceeds maxPayloadSize + // Skip the expensive window aggregate query if total database size is below maxPayloadSize + const sizeResult = this.#db + .prepare( + 'SELECT (page_count - freelist_count) * page_size AS total_size ' + + 'FROM pragma_page_count(), pragma_freelist_count(), pragma_page_size();', + ) + .get() as { total_size?: number } | undefined; + + if ((sizeResult?.total_size ?? 0) > this.maxPayloadSize) { + this.#db + .prepare( + `DELETE FROM cache WHERE key IN ( + SELECT key FROM ( + SELECT key, + sum(length(key) + length(value)) OVER (ORDER BY last_accessed DESC, key DESC) as running_size + FROM cache + ) WHERE running_size > ? + );`, + ) + .run(this.maxPayloadSize); + } + + this.#db.exec('COMMIT;'); + } catch (error) { + try { + this.#db.exec('ROLLBACK;'); + } catch { + // Ignore rollback errors if transaction was not active + } + throw error; + } } catch { // Pruning errors should not block build success } finally { @@ -176,7 +199,11 @@ export class SqliteCacheStore implements PersistentCacheStore { this.#setStmt = undefined; this.#updateAccessedStmt = undefined; - this.#db.close(); + try { + this.#db.close(); + } catch { + // Failure to close should not block build success + } this.#db = undefined; } } diff --git a/packages/angular/build/src/tools/esbuild/sqlite-cache-store_spec.ts b/packages/angular/build/src/tools/esbuild/sqlite-cache-store_spec.ts index 9ac9bee23ddb..c76394cb7ee3 100644 --- a/packages/angular/build/src/tools/esbuild/sqlite-cache-store_spec.ts +++ b/packages/angular/build/src/tools/esbuild/sqlite-cache-store_spec.ts @@ -187,6 +187,20 @@ describe('SqliteCacheStore', () => { checkStore.close(); }); + it('should not prune items when total database size is within maxPayloadSize on close', async () => { + store.close(); + + const sizeStore = new SqliteCacheStore(cachePath, 1024 * 1024); + await sizeStore.set('k1', 'value1'); + await sizeStore.set('k2', 'value2'); + sizeStore.close(); + + const checkStore = new SqliteCacheStore(cachePath); + expect(checkStore.has('k1')).toBeTrue(); + expect(checkStore.has('k2')).toBeTrue(); + checkStore.close(); + }); + it('should create an index on last_accessed and key', async () => { // Trigger db initialization await store.set('test-key', 'test-value'); From f6cb128f482579d263e71e1b9ddac28d7b128433 Mon Sep 17 00:00:00 2001 From: Alan Agius <17563226+alan-agius4@users.noreply.github.com> Date: Thu, 3 Sep 2026 14:21:08 +0000 Subject: [PATCH 407/787] test: update e2e global npm version to 12.0.2 Update the npm version installed in the e2e test sandbox to 12.0.2 to avoid an upstream npm 10 Arborist crash when resolving optional peer dependencies. --- tests/e2e/setup/001-npm-sandbox.ts | 3 +++ tests/e2e/setup/100-global-cli.ts | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/tests/e2e/setup/001-npm-sandbox.ts b/tests/e2e/setup/001-npm-sandbox.ts index dcd5f8a1a021..9989beb80b36 100644 --- a/tests/e2e/setup/001-npm-sandbox.ts +++ b/tests/e2e/setup/001-npm-sandbox.ts @@ -35,6 +35,9 @@ export default async function () { process.env['NPM_CONFIG_legacy_peer_deps'] = 'true'; } + // Allow github tarballs consumption. + process.env['NPM_CONFIG_allow_remote'] = 'all'; + // Configure the registry and prefix used within the test sandbox via rc files await writeFile(npmrc, `registry=${npmRegistry}\nprefix=${npmModulesPrefix}`); await writeFile(yarnrc, `registry ${npmRegistry}\nprefix ${yarnModulesPrefix}`); diff --git a/tests/e2e/setup/100-global-cli.ts b/tests/e2e/setup/100-global-cli.ts index 9f587fa5c38d..d660fc1d1158 100644 --- a/tests/e2e/setup/100-global-cli.ts +++ b/tests/e2e/setup/100-global-cli.ts @@ -3,7 +3,7 @@ import { getActivePackageManager } from '../utils/packages'; import { globalNpm } from '../utils/process'; const PACKAGE_MANAGER_VERSION = { - 'npm': '10.8.1', + 'npm': '12.0.2', 'yarn': '1.22.22', 'pnpm': '10.17.1', 'bun': '1.3.2', From 55583c46a95a2c69b51d52c219f28276117744e9 Mon Sep 17 00:00:00 2001 From: Alan Agius <17563226+alan-agius4@users.noreply.github.com> Date: Wed, 2 Sep 2026 15:34:17 +0000 Subject: [PATCH 408/787] build: update beasties to 0.5.1 Updates Beasties to version 0.5.1 and simplifies the inline critical CSS implementation in @angular/build and @angular/ssr by using Beasties' native preload: 'media-script' and nonce callback support. Additionally, refactors `inlineCriticalCss` in @angular/build into a standalone function and relocates `InlineCriticalCssProcessor` into @angular-devkit/build-angular for Webpack-based builders. --- packages/angular/build/BUILD.bazel | 1 + packages/angular/build/package.json | 2 +- .../tests/options/app-shell_spec.ts | 4 +- .../optimization-inline-critical_spec.ts | 8 +- packages/angular/build/src/private.ts | 5 - .../src/tools/esbuild/index-html-generator.ts | 2 +- .../utils/index-file/index-html-generator.ts | 30 +- .../utils/index-file/inline-critical-css.ts | 338 +++--------------- .../index-file/inline-critical-css_spec.ts | 176 +++++---- packages/angular/ssr/package.json | 2 +- .../ssr/src/utils/inline-critical-css.ts | 197 +--------- .../THIRD_PARTY_LICENSES.txt.golden | 22 +- .../angular_devkit/build_angular/BUILD.bazel | 1 + .../angular_devkit/build_angular/package.json | 1 + .../src/builders/app-shell/app-shell_spec.ts | 4 +- .../src/builders/app-shell/index.ts | 17 +- .../src/builders/browser/index.ts | 29 +- .../tests/options/inline-critical_spec.ts | 10 +- .../src/builders/prerender/render-worker.ts | 10 +- .../src/builders/prerender/works_spec.ts | 4 +- .../plugins/index-html-webpack-plugin.ts | 17 +- .../src/utils/inline-critical-css.ts | 93 +++++ .../src/utils/inline-critical-css_spec.ts | 178 +++++++++ pnpm-lock.yaml | 140 ++++---- tests/e2e/tests/build/auto-csp.ts | 2 +- .../express-engine-csp-nonce.ts | 9 - .../express-engine-ngmodule.ts | 8 - .../express-engine-standalone.ts | 8 - 28 files changed, 604 insertions(+), 714 deletions(-) create mode 100644 packages/angular_devkit/build_angular/src/utils/inline-critical-css.ts create mode 100644 packages/angular_devkit/build_angular/src/utils/inline-critical-css_spec.ts diff --git a/packages/angular/build/BUILD.bazel b/packages/angular/build/BUILD.bazel index e63b084ec458..06f931d2b712 100644 --- a/packages/angular/build/BUILD.bazel +++ b/packages/angular/build/BUILD.bazel @@ -159,6 +159,7 @@ ts_project( jasmine_test( name = "test", data = [":unit_test_lib"], + shard_count = 4, ) ts_project( diff --git a/packages/angular/build/package.json b/packages/angular/build/package.json index 72bc0aa26a0c..d55e1809c35d 100644 --- a/packages/angular/build/package.json +++ b/packages/angular/build/package.json @@ -24,7 +24,7 @@ "@inquirer/confirm": "6.2.0", "@parcel/watcher": "2.6.0", "@vitejs/plugin-basic-ssl": "2.3.0", - "beasties": "0.4.3", + "beasties": "0.5.1", "browserslist": "^4.26.0", "chokidar": "5.0.0", "esbuild": "0.28.2", diff --git a/packages/angular/build/src/builders/application/tests/options/app-shell_spec.ts b/packages/angular/build/src/builders/application/tests/options/app-shell_spec.ts index 9c8384b29efc..a43d24f19c6d 100644 --- a/packages/angular/build/src/builders/application/tests/options/app-shell_spec.ts +++ b/packages/angular/build/src/builders/application/tests/options/app-shell_spec.ts @@ -141,7 +141,7 @@ describeBuilder(buildApplication, APPLICATION_BUILDER_INFO, (harness) => { indexFileContent.toContain('app-shell works!'); indexFileContent.toContain('p{color:#000}'); indexFileContent.toContain( - ``, + ``, ); }); @@ -170,7 +170,7 @@ describeBuilder(buildApplication, APPLICATION_BUILDER_INFO, (harness) => { indexFileContent.toContain('app-shell works!'); indexFileContent.toContain('p{color:#000}'); indexFileContent.toContain( - ``, + ``, ); indexFileContent.toContain(''); }); - it(`should process the inline 'onload' handlers if a 'autoCsp' is true`, async () => { - const inlineCssProcessor = new InlineCriticalCssProcessor({ + it('should process the inline onload handlers and style tag when ngCspNonce is specified', async () => { + const { content, errors, warnings } = await inlineCriticalCss( + getContent('', ''), + '/dist/', + undefined, + false, readAsset, - autoCsp: true, - }); - - const { content } = await inlineCssProcessor.process(getContent(''), { - outputPath: '/dist/', - }); + ); + expect(errors).toEqual([]); + expect(warnings).toEqual([]); + expect(content).toContain( + '', + ); expect(content).toContain( - '', + '', ); + // Nonces shouldn't be added inside the `noscript` tags. + expect(content).toContain(''); + expect(content).toContain(' + + + + + `; + + const { content } = await inlineCriticalCss( + initialContent, + '/dist/', + undefined, + false, + readAsset, + ); + + expect(content).toContain(''); + }); + + it('should capture warnings from beasties', async () => { + const initialContent = ` + + + + + + `; + + const { warnings } = await inlineCriticalCss( + initialContent, + '/dist/', + undefined, + false, + readAsset, + ); + + expect(warnings.length).toBeGreaterThan(0); + expect(warnings[0]).toContain('missing.css'); + }); }); diff --git a/packages/angular/ssr/package.json b/packages/angular/ssr/package.json index e832d63a1883..6bee25550ce7 100644 --- a/packages/angular/ssr/package.json +++ b/packages/angular/ssr/package.json @@ -44,7 +44,7 @@ "@angular/platform-server": "22.2.0-next.4", "@angular/router": "22.2.0-next.4", "@schematics/angular": "workspace:*", - "beasties": "0.4.3" + "beasties": "0.5.1" }, "sideEffects": false, "schematics": "./schematics/collection.json" diff --git a/packages/angular/ssr/src/utils/inline-critical-css.ts b/packages/angular/ssr/src/utils/inline-critical-css.ts index 5a5eb011c20a..f31697d9a901 100644 --- a/packages/angular/ssr/src/utils/inline-critical-css.ts +++ b/packages/angular/ssr/src/utils/inline-critical-css.ts @@ -8,94 +8,7 @@ import Beasties from '../../third_party/beasties'; -/** - * Pattern used to extract the media query set by Beasties in an `onload` handler. - */ -const MEDIA_SET_HANDLER_PATTERN = /^this\.media=["'](.*)["'];?$/; - -/** - * Name of the attribute used to save the Beasties media query so it can be re-assigned on load. - */ -const CSP_MEDIA_ATTR = 'ngCspMedia'; - -/** - * Script that dynamically updates the `media` attribute of `` tags based on a custom attribute (`CSP_MEDIA_ATTR`). - * - * NOTE: - * We do not use `document.querySelectorAll('link').forEach((s) => s.addEventListener('load', ...)` - * because load events are not always triggered reliably on Chrome. - * See: https://github.com/angular/angular-cli/issues/26932 and https://crbug.com/1521256 - * - * The script: - * - Ensures the event target is a `` tag with the `CSP_MEDIA_ATTR` attribute. - * - Updates the `media` attribute with the value of `CSP_MEDIA_ATTR` and then removes the attribute. - * - Removes the event listener when all relevant `` tags have been processed. - * - Uses event capturing (the `true` parameter) since load events do not bubble up the DOM. - */ -const LINK_LOAD_SCRIPT_CONTENT = /* @__PURE__ */ (() => `(() => { - const CSP_MEDIA_ATTR = '${CSP_MEDIA_ATTR}'; - const documentElement = document.documentElement; - - // Listener for load events on link tags. - const listener = (e) => { - const target = e.target; - if ( - !target || - target.tagName !== 'LINK' || - !target.hasAttribute(CSP_MEDIA_ATTR) - ) { - return; - } - - target.media = target.getAttribute(CSP_MEDIA_ATTR); - target.removeAttribute(CSP_MEDIA_ATTR); - - if (!document.head.querySelector(\`link[\${CSP_MEDIA_ATTR}]\`)) { - documentElement.removeEventListener('load', listener); - } - }; - - documentElement.addEventListener('load', listener, true); -})();`)(); - -/** Partial representation of an `HTMLElement`. */ -interface PartialHTMLElement { - getAttribute(name: string): string | null; - setAttribute(name: string, value: string): void; - hasAttribute(name: string): boolean; - removeAttribute(name: string): void; - appendChild(child: PartialHTMLElement): void; - insertBefore(newNode: PartialHTMLElement, referenceNode?: PartialHTMLElement): void; - remove(): void; - name: string; - textContent: string; - tagName: string | null; - children: PartialHTMLElement[]; - next: PartialHTMLElement | null; - prev: PartialHTMLElement | null; -} - -/** Partial representation of an HTML `Document`. */ -interface PartialDocument { - head: PartialHTMLElement; - createElement(tagName: string): PartialHTMLElement; - querySelector(selector: string): PartialHTMLElement | null; -} - -/* eslint-disable @typescript-eslint/no-unsafe-declaration-merging */ - -// We use Typescript declaration merging because `embedLinkedStylesheet` it's not declared in -// the `Beasties` types which means that we can't call the `super` implementation. -interface BeastiesBase { - embedLinkedStylesheet(link: PartialHTMLElement, document: PartialDocument): Promise; -} -class BeastiesBase extends Beasties {} -/* eslint-enable @typescript-eslint/no-unsafe-declaration-merging */ - -export class InlineCriticalCssProcessor extends BeastiesBase { - private addedCspScriptsDocuments = new WeakSet(); - private documentNonces = new WeakMap(); - +export class InlineCriticalCssProcessor extends Beasties { constructor( public override readFile: (path: string) => Promise, readonly outputPath?: string, @@ -115,108 +28,16 @@ export class InlineCriticalCssProcessor extends BeastiesBase { pruneSource: false, reduceInlineStyles: false, mergeStylesheets: false, - // Note: if `preload` changes to anything other than `media`, the logic in - // `embedLinkedStylesheet` will have to be updated. - preload: 'media', + preload: 'media-script', + nonce: (document) => { + const nonceElement = document.querySelector('[ngCspNonce], [ngcspnonce]'); + const cspNonce = + nonceElement?.getAttribute('ngCspNonce') || nonceElement?.getAttribute('ngcspnonce'); + + return cspNonce ?? undefined; + }, noscriptFallback: true, inlineFonts: true, }); } - - /** - * Override of the Beasties `embedLinkedStylesheet` method - * that makes it work with Angular's CSP APIs. - */ - override async embedLinkedStylesheet( - link: PartialHTMLElement, - document: PartialDocument, - ): Promise { - if (link.getAttribute('media') === 'print' && link.next?.name === 'noscript') { - // Workaround for https://github.com/GoogleChromeLabs/critters/issues/64 - // NB: this is only needed for the webpack based builders. - const media = link.getAttribute('onload')?.match(MEDIA_SET_HANDLER_PATTERN); - if (media) { - link.removeAttribute('onload'); - link.setAttribute('media', media[1]); - link?.next?.remove(); - } - } - - const returnValue = await super.embedLinkedStylesheet(link, document); - const cspNonce = this.findCspNonce(document); - - if (cspNonce) { - const beastiesMedia = link.getAttribute('onload')?.match(MEDIA_SET_HANDLER_PATTERN); - - if (beastiesMedia) { - // If there's a Beasties-generated `onload` handler and the file has an Angular CSP nonce, - // we have to remove the handler, because it's incompatible with CSP. We save the value - // in a different attribute and we generate a script tag with the nonce that uses - // `addEventListener` to apply the media query instead. - link.removeAttribute('onload'); - link.setAttribute(CSP_MEDIA_ATTR, beastiesMedia[1]); - this.conditionallyInsertCspLoadingScript(document, cspNonce, link); - } - - // Ideally we would hook in at the time Beasties inserts the `style` tags, but there isn't - // a way of doing that at the moment so we fall back to doing it any time a `link` tag is - // inserted. We mitigate it by only iterating the direct children of the `` which - // should be pretty shallow. - document.head.children.forEach((child) => { - if (child.tagName === 'style' && !child.hasAttribute('nonce')) { - child.setAttribute('nonce', cspNonce); - } - }); - } - - return returnValue; - } - - /** - * Finds the CSP nonce for a specific document. - */ - private findCspNonce(document: PartialDocument): string | null { - if (this.documentNonces.has(document)) { - // eslint-disable-next-line @typescript-eslint/no-non-null-assertion - return this.documentNonces.get(document)!; - } - - // HTML attribute are case-insensitive, but the parser used by Beasties is case-sensitive. - const nonceElement = document.querySelector('[ngCspNonce], [ngcspnonce]'); - const cspNonce = - nonceElement?.getAttribute('ngCspNonce') || nonceElement?.getAttribute('ngcspnonce') || null; - - this.documentNonces.set(document, cspNonce); - - return cspNonce; - } - - /** - * Inserts the `script` tag that swaps the critical CSS at runtime, - * if one hasn't been inserted into the document already. - */ - private conditionallyInsertCspLoadingScript( - document: PartialDocument, - nonce: string, - link: PartialHTMLElement, - ): void { - if (this.addedCspScriptsDocuments.has(document)) { - return; - } - - if (document.head.textContent.includes(LINK_LOAD_SCRIPT_CONTENT)) { - // Script was already added during the build. - this.addedCspScriptsDocuments.add(document); - - return; - } - - const script = document.createElement('script'); - script.setAttribute('nonce', nonce); - script.textContent = LINK_LOAD_SCRIPT_CONTENT; - // Prepend the script to the head since it needs to - // run as early as possible, before the `link` tags. - document.head.insertBefore(script, link); - this.addedCspScriptsDocuments.add(document); - } } diff --git a/packages/angular/ssr/test/npm_package/THIRD_PARTY_LICENSES.txt.golden b/packages/angular/ssr/test/npm_package/THIRD_PARTY_LICENSES.txt.golden index e79afcfa9a05..f90ccf916abb 100644 --- a/packages/angular/ssr/test/npm_package/THIRD_PARTY_LICENSES.txt.golden +++ b/packages/angular/ssr/test/npm_package/THIRD_PARTY_LICENSES.txt.golden @@ -209,7 +209,19 @@ Apache License Package: boolbase License: ISC +Copyright (c) 2014-2015, Felix Boehm +Permission to use, copy, modify, and/or distribute this software for any +purpose with or without fee is hereby granted, provided that the above +copyright notice and this permission notice appear in all copies. + +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -------------------------------------------------------------------------------- Package: css-select License: BSD-2-Clause @@ -244,17 +256,13 @@ EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. Package: dom-serializer License: MIT -License - -(The MIT License) - -Copyright (c) 2014 The cheeriojs contributors +Copyright © 2022 The Cheerio contributors -Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the 'Software'), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. -THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -------------------------------------------------------------------------------- Package: domelementtype License: BSD-2-Clause diff --git a/packages/angular_devkit/build_angular/BUILD.bazel b/packages/angular_devkit/build_angular/BUILD.bazel index 0a40b409a54c..e8b61f0e8785 100644 --- a/packages/angular_devkit/build_angular/BUILD.bazel +++ b/packages/angular_devkit/build_angular/BUILD.bazel @@ -128,6 +128,7 @@ ts_project( ":node_modules/ansi-colors", ":node_modules/autoprefixer", ":node_modules/babel-loader", + ":node_modules/beasties", ":node_modules/browser-sync", ":node_modules/browserslist", ":node_modules/copy-webpack-plugin", diff --git a/packages/angular_devkit/build_angular/package.json b/packages/angular_devkit/build_angular/package.json index 7e7f1ff431c4..db25b52314e8 100644 --- a/packages/angular_devkit/build_angular/package.json +++ b/packages/angular_devkit/build_angular/package.json @@ -25,6 +25,7 @@ "ansi-colors": "4.1.3", "autoprefixer": "10.5.4", "babel-loader": "10.1.1", + "beasties": "0.5.1", "browserslist": "^4.26.0", "copy-webpack-plugin": "14.0.0", "css-loader": "7.1.4", diff --git a/packages/angular_devkit/build_angular/src/builders/app-shell/app-shell_spec.ts b/packages/angular_devkit/build_angular/src/builders/app-shell/app-shell_spec.ts index 1b92a58267e9..d4a470935d10 100644 --- a/packages/angular_devkit/build_angular/src/builders/app-shell/app-shell_spec.ts +++ b/packages/angular_devkit/build_angular/src/builders/app-shell/app-shell_spec.ts @@ -169,7 +169,7 @@ describe('AppShell Builder', () => { expect(content).toContain('app-shell works!'); expect(content).toContain('p{color:#000}'); expect(content).toMatch( - //, + //, ); }); @@ -195,7 +195,7 @@ describe('AppShell Builder', () => { expect(content).toContain(''); expect(content).toMatch( - //, + //, ); }); }); diff --git a/packages/angular_devkit/build_angular/src/builders/app-shell/index.ts b/packages/angular_devkit/build_angular/src/builders/app-shell/index.ts index 685c90a48a7e..d0c6e234db05 100644 --- a/packages/angular_devkit/build_angular/src/builders/app-shell/index.ts +++ b/packages/angular_devkit/build_angular/src/builders/app-shell/index.ts @@ -19,6 +19,7 @@ import * as path from 'node:path'; import Piscina from 'piscina'; import { normalizeOptimization } from '../../utils'; import { assertIsError } from '../../utils/error'; +import { InlineCriticalCssProcessor } from '../../utils/inline-critical-css'; import { Spinner } from '../../utils/spinner'; import { BrowserBuilderOutput } from '../browser'; import { Schema as BrowserBuilderSchema } from '../browser/schema'; @@ -58,14 +59,6 @@ async function _renderUniversal( const projectRoot = path.join(root, (projectMetadata.root as string | undefined) ?? ''); const { styles } = normalizeOptimization(browserOptions.optimization); - let inlineCriticalCssProcessor; - if (styles.inlineCritical) { - const { InlineCriticalCssProcessor } = await import('@angular/build/private'); - inlineCriticalCssProcessor = new InlineCriticalCssProcessor({ - minify: styles.minify, - deployUrl: browserOptions.deployUrl, - }); - } const renderWorker = new Piscina({ filename: require.resolve('./render-worker'), @@ -98,10 +91,14 @@ async function _renderUniversal( ? path.join(root, options.outputIndexPath) : browserIndexOutputPath; - if (inlineCriticalCssProcessor) { - const { content, warnings, errors } = await inlineCriticalCssProcessor.process(html, { + if (styles.inlineCritical) { + const inlineCriticalCssProcessor = new InlineCriticalCssProcessor({ + minify: styles.minify, outputPath, + deployUrl: browserOptions.deployUrl, }); + + const { content, warnings, errors } = await inlineCriticalCssProcessor.process(html); html = content; if (warnings.length || errors.length) { diff --git a/packages/angular_devkit/build_angular/src/builders/browser/index.ts b/packages/angular_devkit/build_angular/src/builders/browser/index.ts index 355c407192e5..e8fd07c82830 100644 --- a/packages/angular_devkit/build_angular/src/builders/browser/index.ts +++ b/packages/angular_devkit/build_angular/src/builders/browser/index.ts @@ -303,21 +303,25 @@ export function buildWebpackBrowser( styles: options.styles ?? [], }); - const indexHtmlGenerator = new IndexHtmlGenerator({ - cache: cacheOptions, - indexPath: path.join(context.workspaceRoot, getIndexInputFile(options.index)), - entrypoints, - deployUrl: options.deployUrl, - sri: options.subresourceIntegrity, - optimization: normalizedOptimization, - crossOrigin: options.crossOrigin, - postTransform: transforms.indexHtml, - imageDomains: Array.from(imageDomains), - }); - let hasErrors = false; for (const [locale, outputPath] of outputPaths.entries()) { try { + const indexHtmlGenerator = new IndexHtmlGenerator({ + cache: cacheOptions, + indexPath: path.join( + context.workspaceRoot, + getIndexInputFile(options.index), + ), + entrypoints, + outputPath, + deployUrl: options.deployUrl, + sri: options.subresourceIntegrity, + optimization: normalizedOptimization, + crossOrigin: options.crossOrigin, + postTransform: transforms.indexHtml, + imageDomains: Array.from(imageDomains), + }); + const { csrContent: content, warnings, @@ -326,7 +330,6 @@ export function buildWebpackBrowser( baseHref: getLocaleBaseHref(i18n, locale) ?? options.baseHref, // i18nLocale is used when Ivy is disabled lang: locale || undefined, - outputPath, files: mapEmittedFilesToFileInfo(emittedFiles), }); diff --git a/packages/angular_devkit/build_angular/src/builders/browser/tests/options/inline-critical_spec.ts b/packages/angular_devkit/build_angular/src/builders/browser/tests/options/inline-critical_spec.ts index a7c0bc3d85f2..678a30c670c7 100644 --- a/packages/angular_devkit/build_angular/src/builders/browser/tests/options/inline-critical_spec.ts +++ b/packages/angular_devkit/build_angular/src/builders/browser/tests/options/inline-critical_spec.ts @@ -35,7 +35,7 @@ describeBuilder(buildWebpackBrowser, BROWSER_BUILDER_INFO, (harness) => { harness .expectFile('dist/index.html') .content.toContain( - ``, + ``, ); harness.expectFile('dist/index.html').content.toContain(`body{color:#000}`); }); @@ -53,7 +53,7 @@ describeBuilder(buildWebpackBrowser, BROWSER_BUILDER_INFO, (harness) => { harness .expectFile('dist/index.html') .content.toContain( - ``, + ``, ); harness.expectFile('dist/index.html').content.toContain(`body{color:#000}`); }); @@ -71,7 +71,7 @@ describeBuilder(buildWebpackBrowser, BROWSER_BUILDER_INFO, (harness) => { harness .expectFile('dist/index.html') .content.toContain( - ``, + ``, ); harness.expectFile('dist/index.html').content.toContain(`body{color:#000}`); }); @@ -129,7 +129,7 @@ describeBuilder(buildWebpackBrowser, BROWSER_BUILDER_INFO, (harness) => { harness .expectFile('dist/index.html') .content.toContain( - ``, + ``, ); harness.expectFile('dist/index.html').content.toContain(`body{color:#000}`); }); @@ -155,7 +155,7 @@ describeBuilder(buildWebpackBrowser, BROWSER_BUILDER_INFO, (harness) => { harness .expectFile('dist/index.html') .content.toContain( - ``, + ``, ); harness.expectFile('dist/index.html').content.toContain(`body{color:#000}`); }); diff --git a/packages/angular_devkit/build_angular/src/builders/prerender/render-worker.ts b/packages/angular_devkit/build_angular/src/builders/prerender/render-worker.ts index da478318ebc7..5112a88dd89a 100644 --- a/packages/angular_devkit/build_angular/src/builders/prerender/render-worker.ts +++ b/packages/angular_devkit/build_angular/src/builders/prerender/render-worker.ts @@ -13,6 +13,7 @@ import assert from 'node:assert'; import * as fs from 'node:fs'; import * as path from 'node:path'; import { workerData } from 'node:worker_threads'; +import { InlineCriticalCssProcessor } from '../../utils/inline-critical-css'; export interface RenderOptions { indexFile: string; @@ -122,16 +123,13 @@ async function render({ } if (inlineCriticalCss) { - const { InlineCriticalCssProcessor } = await import('@angular/build/private'); - const inlineCriticalCssProcessor = new InlineCriticalCssProcessor({ - deployUrl: deployUrl, + deployUrl, + outputPath, minify: minifyCss, }); - const { content, warnings, errors } = await inlineCriticalCssProcessor.process(html, { - outputPath, - }); + const { content, warnings, errors } = await inlineCriticalCssProcessor.process(html); result.errors = errors; result.warnings = warnings; html = content; diff --git a/packages/angular_devkit/build_angular/src/builders/prerender/works_spec.ts b/packages/angular_devkit/build_angular/src/builders/prerender/works_spec.ts index 797d88f8e7a6..f9dc304a5a94 100644 --- a/packages/angular_devkit/build_angular/src/builders/prerender/works_spec.ts +++ b/packages/angular_devkit/build_angular/src/builders/prerender/works_spec.ts @@ -219,11 +219,11 @@ describe('Prerender Builder', () => { ); expect(content).toMatch( - /`); + }); + + it('should inline critical css when using deployUrl', async () => { + const inlineFontsProcessor = new InlineCriticalCssProcessor({ + readAsset, + outputPath: '/dist/', + deployUrl: 'http://cdn.com', + }); + + const { content } = await inlineFontsProcessor.process(getContent('http://cdn.com/')); + + expect(content).toContain( + ``, + ); + expect(content).toContain( + ``, + ); + expect(tags.stripIndents`${content}`).toContain(tags.stripIndents` + `); + }); + + it('should compress inline critical css when minify is enabled', async () => { + const inlineFontsProcessor = new InlineCriticalCssProcessor({ + readAsset, + minify: true, + outputPath: '/dist/', + }); + + const { content } = await inlineFontsProcessor.process(getContent('')); + + expect(content).toContain( + ``, + ); + expect(content).toContain( + ``, + ); + expect(content).toContain(''); + }); + + it(`should process the inline 'onload' handlers if a 'autoCsp' is true`, async () => { + const inlineCssProcessor = new InlineCriticalCssProcessor({ + readAsset, + autoCsp: true, + outputPath: '/dist/', + }); + + const { content } = await inlineCssProcessor.process(getContent('')); + + expect(content).toContain( + '', + ); + expect(tags.stripIndents`${content}`).toContain(tags.stripIndents` + `); + }); + + it('should process the inline `onload` handlers if a CSP nonce is specified', async () => { + const inlineCssProcessor = new InlineCriticalCssProcessor({ + readAsset, + outputPath: '/dist/', + }); + + const { content } = await inlineCssProcessor.process( + getContent('', ''), + ); + + expect(content).toContain( + '', + ); + expect(content).toContain( + '', + ); + // Nonces shouldn't be added inside the `noscript` tags. + expect(content).toContain(''); + expect(content).toContain(' + + + `); + + const csps = getCsps(result); + expect(csps).toHaveSize(1); + expect(csps[0]).toMatch(CSP_SINGLE_HASH_REGEX); + expect(result).toContain( + `const scripts = [['./main.js', 'application/javascript', false, false, null, null]];`, + ); + }); + + it('should rewrite scripts with case-insensitive type and parameters with whitespace', async () => { + const result = await autoCsp(` + + + + + + + `); + + const csps = getCsps(result); + expect(csps).toHaveSize(1); + expect(csps[0]).toMatch(CSP_SINGLE_HASH_REGEX); + expect(result).toContain( + `const scripts = [['./main.js', 'Text/JavaScript ; charset=utf-8', false, false, null, null]];`, + ); + }); + + it('should rewrite scripts with case-insensitive module type', async () => { + const result = await autoCsp(` + + + + + + + `); + + const csps = getCsps(result); + expect(csps).toHaveSize(1); + expect(csps[0]).toMatch(CSP_SINGLE_HASH_REGEX); + expect(result).toContain( + `const scripts = [['./main.js', 'Module', false, false, null, null]];`, + ); + }); + + it('should not rewrite non-JavaScript script tags', async () => { + const result = await autoCsp(` + + + + + + + `); + + // No dynamic loader script is emitted because application/json is not JavaScript. + expect(result).toContain(''); + expect(result).not.toContain('const scripts ='); + }); + + describe('isJavascriptMimeType', () => { + it('should identify standard JavaScript MIME types', () => { + expect(isJavascriptMimeType('text/javascript')).toBeTrue(); + expect(isJavascriptMimeType('application/javascript')).toBeTrue(); + expect(isJavascriptMimeType('application/x-javascript')).toBeTrue(); + expect(isJavascriptMimeType('text/ecmascript')).toBeTrue(); + expect(isJavascriptMimeType('application/ecmascript')).toBeTrue(); + expect(isJavascriptMimeType('text/jscript')).toBeTrue(); + expect(isJavascriptMimeType('text/livescript')).toBeTrue(); + expect(isJavascriptMimeType('text/x-ecmascript')).toBeTrue(); + expect(isJavascriptMimeType('text/x-javascript')).toBeTrue(); + expect(isJavascriptMimeType('text/javascript1.5')).toBeTrue(); + }); + + it('should ignore parameters when matching MIME type', () => { + expect(isJavascriptMimeType('text/javascript; charset=utf-8')).toBeTrue(); + expect(isJavascriptMimeType('application/javascript;version=1.8')).toBeTrue(); + }); + + it('should handle leading, trailing, and parameter whitespace', () => { + expect(isJavascriptMimeType(' text/javascript ')).toBeTrue(); + expect(isJavascriptMimeType('text/javascript ; charset=utf-8')).toBeTrue(); + expect(isJavascriptMimeType(' application/javascript ; version=1.0 ')).toBeTrue(); + }); + + it('should be case-insensitive', () => { + expect(isJavascriptMimeType('Text/JavaScript')).toBeTrue(); + expect(isJavascriptMimeType('APPLICATION/JAVASCRIPT')).toBeTrue(); + expect(isJavascriptMimeType('text/JAVASCRIPT; charset=UTF-8')).toBeTrue(); + }); + + it('should reject non-JavaScript MIME types', () => { + expect(isJavascriptMimeType('application/json')).toBeFalse(); + expect(isJavascriptMimeType('text/html')).toBeFalse(); + expect(isJavascriptMimeType('text/css')).toBeFalse(); + expect(isJavascriptMimeType('image/svg+xml')).toBeFalse(); + expect(isJavascriptMimeType('importmap')).toBeFalse(); + expect(isJavascriptMimeType('module')).toBeFalse(); + expect(isJavascriptMimeType('')).toBeFalse(); + }); + + it('should reject invalid MIME types with whitespace inside the essence', () => { + expect(isJavascriptMimeType('text / javascript')).toBeFalse(); + expect(isJavascriptMimeType('application / javascript')).toBeFalse(); + expect(isJavascriptMimeType('text/java script')).toBeFalse(); + }); + }); }); From 8c438891c9c8be4e66a82148908343befbb462a2 Mon Sep 17 00:00:00 2001 From: rk Date: Fri, 18 Sep 2026 00:13:00 +0500 Subject: [PATCH 487/787] fix(@angular-devkit/core): name the unknown option in a schema validation error An unknown property in `angular.json` or in a builder's options reported `Data path "" must NOT have additional properties(allowedCommonJsDependencies).`, which names neither the object the property was found in nor what is valid there. It now reads `Unknown option "allowedCommonJsDependencies". Valid options are: assets, browser, ...`, with `at "/cli"` where the instance path is not empty. Errors that are not about an unknown option are unchanged. Listing the valid options needs ajv's `verbose` option, which is what puts `parentSchema` on an error. That is the schema the property was rejected by, so a `$ref` and a `oneOf` branch each list their own options; a schema that declares no `properties` at all stops after the option name rather than offering an empty list. --- .../core/src/json/schema/registry.ts | 31 ++++--- .../core/src/json/schema/registry_spec.ts | 91 +++++++++++++++++++ .../config/config-global-validation.ts | 12 +-- tests/e2e/tests/commands/config/config-set.ts | 5 +- 4 files changed, 114 insertions(+), 25 deletions(-) diff --git a/packages/angular_devkit/core/src/json/schema/registry.ts b/packages/angular_devkit/core/src/json/schema/registry.ts index 77aeab6646a1..928771337bb5 100644 --- a/packages/angular_devkit/core/src/json/schema/registry.ts +++ b/packages/angular_devkit/core/src/json/schema/registry.ts @@ -61,19 +61,24 @@ export class SchemaValidationException extends BaseException { } const messages = errors.map((err) => { + if (err.keyword === 'additionalProperties') { + const unknown = err.params?.additionalProperty; + // `parentSchema` is the schema that rejected the property, which ajv only attaches when + // the validator was created with `verbose: true`. A schema that declares no `properties` + // of its own, such as one using only `patternProperties`, has no options to offer. + const known = Object.keys(err.parentSchema?.properties ?? {}); + + return ( + `Unknown option "${unknown}"${err.instancePath ? ` at "${err.instancePath}"` : ''}.` + + (known.length ? ` Valid options are: ${known.join(', ')}.` : '') + ); + } + let message = `Data path ${JSON.stringify(err.instancePath)} ${err.message}`; - if (err.params) { - switch (err.keyword) { - case 'additionalProperties': - message += `(${err.params.additionalProperty})`; - break; - - case 'enum': - message += `. Allowed values are: ${(err.params.allowedValues as string[] | undefined) - ?.map((v) => `"${v}"`) - .join(', ')}`; - break; - } + if (err.keyword === 'enum' && err.params) { + message += `. Allowed values are: ${(err.params.allowedValues as string[] | undefined) + ?.map((v) => `"${v}"`) + .join(', ')}`; } return message + '.'; @@ -106,6 +111,8 @@ export class CoreSchemaRegistry implements SchemaRegistry { strict: false, loadSchema: (uri: string) => this._fetch(uri), passContext: true, + // Needed to list the valid options of the object an unknown option was found in. + verbose: true, }); ajvAddFormats(this._ajv); diff --git a/packages/angular_devkit/core/src/json/schema/registry_spec.ts b/packages/angular_devkit/core/src/json/schema/registry_spec.ts index 34e404a63b29..32c601154d16 100644 --- a/packages/angular_devkit/core/src/json/schema/registry_spec.ts +++ b/packages/angular_devkit/core/src/json/schema/registry_spec.ts @@ -7,8 +7,10 @@ */ /* eslint-disable @typescript-eslint/no-explicit-any */ +import { JsonValue } from '../utils'; import { SchemaFormat } from './interface'; import { CoreSchemaRegistry, SchemaValidationException } from './registry'; +import { JsonSchema } from './schema'; import { addUndefinedDefaults } from './transforms'; describe('CoreSchemaRegistry', () => { @@ -340,4 +342,93 @@ describe('CoreSchemaRegistry', () => { expect(deprecatedMessages[1]).toBe('Option "bar" is deprecated.'); expect(result.success).toBe(true, result.errors); }); + + describe('error messages', () => { + async function messagesFor(schema: JsonSchema, data: JsonValue): Promise { + const registry = new CoreSchemaRegistry(); + const validator = await registry.compile(schema); + const result = await validator(data); + expect(result.success).toBe(false); + + return SchemaValidationException.createMessages(result.errors); + } + + it('names an unknown option and the options that are valid there', async () => { + const messages = await messagesFor( + { + properties: { version: { type: 'number' }, projects: { type: 'object' } }, + additionalProperties: false, + }, + { allowedCommonJsDependencies: [] }, + ); + + expect(messages).toEqual([ + 'Unknown option "allowedCommonJsDependencies". Valid options are: version, projects.', + ]); + }); + + it('points at the object an unknown option was found in', async () => { + const messages = await messagesFor( + { + properties: { + cli: { + type: 'object', + properties: { cache: { type: 'object' }, packageManager: { type: 'string' } }, + additionalProperties: false, + }, + }, + }, + { cli: { completion: true } }, + ); + + expect(messages).toEqual([ + 'Unknown option "completion" at "/cli". Valid options are: cache, packageManager.', + ]); + }); + + it('looks through a $ref for the valid options', async () => { + const messages = await messagesFor( + { + $ref: '#/definitions/global', + definitions: { + global: { + type: 'object', + properties: { cli: { type: 'object' }, schematics: { type: 'object' } }, + additionalProperties: false, + }, + }, + }, + { version: 1 }, + ); + + expect(messages).toEqual(['Unknown option "version". Valid options are: cli, schematics.']); + }); + + it('omits the valid options when the schema does not list any', async () => { + const messages = await messagesFor( + { + $ref: '#/definitions/cli', + definitions: { + cli: { + type: 'object', + patternProperties: { '^x-': { type: 'string' } }, + additionalProperties: false, + }, + }, + }, + { completion: true }, + ); + + expect(messages).toEqual(['Unknown option "completion".']); + }); + + it('leaves an error that is not about an unknown option alone', async () => { + const messages = await messagesFor( + { properties: { outputPath: { type: 'string' } } }, + { outputPath: 42 }, + ); + + expect(messages).toEqual(['Data path "/outputPath" must be string.']); + }); + }); }); diff --git a/tests/e2e/tests/commands/config/config-global-validation.ts b/tests/e2e/tests/commands/config/config-global-validation.ts index 7be29130dca0..39fa611075a9 100644 --- a/tests/e2e/tests/commands/config/config-global-validation.ts +++ b/tests/e2e/tests/commands/config/config-global-validation.ts @@ -9,21 +9,15 @@ export default async function () { let ngError: Error; ngError = await expectToFail(() => silentNg('config', 'cli.completion.prompted', 'true')); - assert.match( - ngError.message, - /Data path "\/cli" must NOT have additional properties\(completion\)\./, - ); + assert.match(ngError.message, /Unknown option "completion" at "\/cli"\./); ngError = await expectToFail(() => silentNg('config', '--global', 'cli.completion.invalid', 'true'), ); - assert.match( - ngError.message, - /Data path "\/cli\/completion" must NOT have additional properties\(invalid\)\./, - ); + assert.match(ngError.message, /Unknown option "invalid" at "\/cli\/completion"\./); ngError = await expectToFail(() => silentNg('config', '--global', 'cli.cache.enabled', 'true')); - assert.match(ngError.message, /Data path "\/cli" must NOT have additional properties\(cache\)\./); + assert.match(ngError.message, /Unknown option "cache" at "\/cli"\./); ngError = await expectToFail(() => silentNg('config', 'cli.completion.prompted')); assert.match(ngError.message, /Value cannot be found\./); diff --git a/tests/e2e/tests/commands/config/config-set.ts b/tests/e2e/tests/commands/config/config-set.ts index 2152e573132e..05fa364bcb37 100644 --- a/tests/e2e/tests/commands/config/config-set.ts +++ b/tests/e2e/tests/commands/config/config-set.ts @@ -6,10 +6,7 @@ export default async function () { let ngError: Error; ngError = await expectToFail(() => silentNg('config', 'cli.warnings.zzzz', 'true')); - assert.match( - ngError.message, - /Data path "\/cli\/warnings" must NOT have additional properties\(zzzz\)\./, - ); + assert.match(ngError.message, /Unknown option "zzzz" at "\/cli\/warnings"\./); ngError = await expectToFail(() => silentNg('config', 'cli.warnings.zzzz')); assert.match(ngError.message, /Value cannot be found\./); From 1627ccbc1f61cd0a9ff093bb23cefc9d90b338ba Mon Sep 17 00:00:00 2001 From: rk Date: Fri, 18 Sep 2026 15:09:17 +0500 Subject: [PATCH 488/787] fix(@schematics/angular): update @types/node to a version vitest 5 accepts `ng new --ssr` and `ng add @angular/ssr` fail to install their dependencies: the server schematic adds `@types/node@^20.17.19`, and vitest 5, which the same schematics now add, has `@types/node@^22.0.0 || >=24.0.0` as a peer. npm refuses the tree and the workspace is left without `node_modules`. `^22.12.0` is what this repository uses for `@types/node` itself, and Node 20 is already outside the `engines.node` range of the generated project. --- .../schematics/angular/utility/latest-versions/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/schematics/angular/utility/latest-versions/package.json b/packages/schematics/angular/utility/latest-versions/package.json index 111c8296c202..75481eb2b23d 100644 --- a/packages/schematics/angular/utility/latest-versions/package.json +++ b/packages/schematics/angular/utility/latest-versions/package.json @@ -5,7 +5,7 @@ "dependencies": { "@types/express": "^5.0.1", "@types/jasmine": "~6.0.0", - "@types/node": "^20.17.19", + "@types/node": "^22.12.0", "browser-sync": "^3.0.0", "express": "^5.1.0", "istanbul-lib-instrument": "^6.0.3", From 18602224886b47fc3be4157c574bd9cb7da1db39 Mon Sep 17 00:00:00 2001 From: Charles Lyding <19598772+clydin@users.noreply.github.com> Date: Fri, 18 Sep 2026 10:50:36 -0400 Subject: [PATCH 489/787] refactor(@angular/cli): use static import for Module in update command Replace the inline dynamic require('node:module') call with a top-level static import of Module in UpdateCommandModule. Also update the _pathCache check to use the 'in' operator for safer property access and cleaner type narrowing. --- packages/angular/cli/src/commands/update/cli.ts | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/packages/angular/cli/src/commands/update/cli.ts b/packages/angular/cli/src/commands/update/cli.ts index 6418bfc13ce4..45a4468e0c85 100644 --- a/packages/angular/cli/src/commands/update/cli.ts +++ b/packages/angular/cli/src/commands/update/cli.ts @@ -9,7 +9,7 @@ import { NodeWorkflow } from '@angular-devkit/schematics/tools'; import { Listr } from 'listr2'; import { existsSync, promises as fs } from 'node:fs'; -import { createRequire } from 'node:module'; +import { Module, createRequire } from 'node:module'; import * as path from 'node:path'; import npa from 'npm-package-arg'; import { Argv } from 'yargs'; @@ -607,8 +607,7 @@ export default class UpdateCommandModule extends CommandModule Date: Fri, 18 Sep 2026 18:36:24 +0200 Subject: [PATCH 490/787] fix(@angular/build): ensure chokidar watcher is ready before returning When initializing chokidar.watch with ignoreInitial: true, files visited during the initial scan are treated as the initial baseline and do not emit change events. If createChokidarWatcher returns before the initial scan completes, subsequent file modifications made shortly after setup can be visited for the first time during the initial scan, causing the change event to be dropped. --- .../dev-server/tests/behavior/build-errors_spec.ts | 4 ++-- packages/angular/build/src/tools/esbuild/watcher.ts | 8 ++++++++ 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/packages/angular/build/src/builders/dev-server/tests/behavior/build-errors_spec.ts b/packages/angular/build/src/builders/dev-server/tests/behavior/build-errors_spec.ts index 424c520eab2d..9608e0dc976e 100644 --- a/packages/angular/build/src/builders/dev-server/tests/behavior/build-errors_spec.ts +++ b/packages/angular/build/src/builders/dev-server/tests/behavior/build-errors_spec.ts @@ -38,8 +38,8 @@ describeServeBuilder(executeDevServer, DEV_SERVER_BUILDER_INFO, (harness, setupT expectNoLog(logs, 'Unexpected character "EOF"'); }, ], - { outputLogsOnFailure: false, timeout: 90_000 }, + { outputLogsOnFailure: false }, ); - }, 120_000); + }); }); }); diff --git a/packages/angular/build/src/tools/esbuild/watcher.ts b/packages/angular/build/src/tools/esbuild/watcher.ts index 9923f08fea7f..e30909fa6813 100644 --- a/packages/angular/build/src/tools/esbuild/watcher.ts +++ b/packages/angular/build/src/tools/esbuild/watcher.ts @@ -8,6 +8,7 @@ import type * as ParcelWatcher from '@parcel/watcher'; import type * as Chokidar from 'chokidar'; +import { once } from 'node:events'; import * as fs from 'node:fs'; import * as path from 'node:path'; import picomatch from 'picomatch'; @@ -663,8 +664,15 @@ async function createChokidarWatcher( usePolling: !!options?.polling, interval: options?.interval, }); + const initTime = Date.now(); + // Wait for the watcher to complete its initial filesystem scan before returning. + // With `ignoreInitial: true`, any file visited during the initial scan is treated as the initial baseline + // and will not emit 'add' or 'change' events. Awaiting 'ready' ensures that rapid file modifications + // made right after watcher setup (e.g. in rebuild tests) are not swallowed as initial files. + await once(watcher, 'ready'); + const handleEvent = (type: 'added' | 'modified' | 'removed', rawPath: string) => { const posixPath = toPosixPathNormalized(rawPath); const lookupKey = toLookupKey(posixPath, isCaseSensitive); From cbac34a65a6e9da3efc9a63b22811cf1a742cc68 Mon Sep 17 00:00:00 2001 From: Angular Robot Date: Mon, 21 Sep 2026 10:37:35 +0000 Subject: [PATCH 491/787] build: update cross-repo angular dependencies See associated pull request for more information. --- .../assistant-to-the-branch-manager.yml | 2 +- .github/workflows/ci.yml | 52 +-- .github/workflows/dev-infra.yml | 6 +- .github/workflows/perf.yml | 6 +- .github/workflows/pr.yml | 44 +- MODULE.bazel | 6 +- package.json | 2 +- pnpm-lock.yaml | 439 ++++++++---------- tests/e2e/ng-snapshot/package.json | 32 +- 9 files changed, 280 insertions(+), 309 deletions(-) diff --git a/.github/workflows/assistant-to-the-branch-manager.yml b/.github/workflows/assistant-to-the-branch-manager.yml index 1fcd15f0c5b9..37a87ef062e5 100644 --- a/.github/workflows/assistant-to-the-branch-manager.yml +++ b/.github/workflows/assistant-to-the-branch-manager.yml @@ -18,6 +18,6 @@ jobs: - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: persist-credentials: false - - uses: angular/dev-infra/github-actions/branch-manager@99d57027286c71dda92d8b91a3607abcf92d8bbd # main + - uses: angular/dev-infra/github-actions/branch-manager@56bab29d886fd34280b1ccc203d8817e9725f0af # main with: angular-robot-key: ${{ secrets.ANGULAR_ROBOT_PRIVATE_KEY }} diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index cee6fbdfbda5..8838142cebd4 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -21,9 +21,9 @@ jobs: runs-on: ubuntu-latest steps: - name: Initialize environment - uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@99d57027286c71dda92d8b91a3607abcf92d8bbd # main + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@56bab29d886fd34280b1ccc203d8817e9725f0af # main - name: Setup Bazel - uses: angular/dev-infra/github-actions/bazel/setup@99d57027286c71dda92d8b91a3607abcf92d8bbd # main + uses: angular/dev-infra/github-actions/bazel/setup@56bab29d886fd34280b1ccc203d8817e9725f0af # main - name: Install node modules run: pnpm install --frozen-lockfile - name: Generate JSON schema types @@ -44,11 +44,11 @@ jobs: runs-on: ubuntu-latest steps: - name: Initialize environment - uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@99d57027286c71dda92d8b91a3607abcf92d8bbd # main + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@56bab29d886fd34280b1ccc203d8817e9725f0af # main - name: Setup Bazel - uses: angular/dev-infra/github-actions/bazel/setup@99d57027286c71dda92d8b91a3607abcf92d8bbd # main + uses: angular/dev-infra/github-actions/bazel/setup@56bab29d886fd34280b1ccc203d8817e9725f0af # main - name: Setup Bazel RBE - uses: angular/dev-infra/github-actions/bazel/configure-remote@99d57027286c71dda92d8b91a3607abcf92d8bbd # main + uses: angular/dev-infra/github-actions/bazel/configure-remote@56bab29d886fd34280b1ccc203d8817e9725f0af # main with: google_credential: ${{ secrets.RBE_TRUSTED_BUILDS_USER }} - name: Install node modules @@ -61,11 +61,11 @@ jobs: runs-on: ubuntu-latest steps: - name: Initialize environment - uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@99d57027286c71dda92d8b91a3607abcf92d8bbd # main + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@56bab29d886fd34280b1ccc203d8817e9725f0af # main - name: Setup Bazel - uses: angular/dev-infra/github-actions/bazel/setup@99d57027286c71dda92d8b91a3607abcf92d8bbd # main + uses: angular/dev-infra/github-actions/bazel/setup@56bab29d886fd34280b1ccc203d8817e9725f0af # main - name: Setup Bazel RBE - uses: angular/dev-infra/github-actions/bazel/configure-remote@99d57027286c71dda92d8b91a3607abcf92d8bbd # main + uses: angular/dev-infra/github-actions/bazel/configure-remote@56bab29d886fd34280b1ccc203d8817e9725f0af # main with: google_credential: ${{ secrets.RBE_TRUSTED_BUILDS_USER }} - name: Install node modules @@ -84,13 +84,13 @@ jobs: runs-on: ubuntu-latest steps: - name: Initialize environment - uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@99d57027286c71dda92d8b91a3607abcf92d8bbd # main + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@56bab29d886fd34280b1ccc203d8817e9725f0af # main - name: Install node modules run: pnpm install --frozen-lockfile - name: Setup Bazel - uses: angular/dev-infra/github-actions/bazel/setup@99d57027286c71dda92d8b91a3607abcf92d8bbd # main + uses: angular/dev-infra/github-actions/bazel/setup@56bab29d886fd34280b1ccc203d8817e9725f0af # main - name: Setup Bazel RBE - uses: angular/dev-infra/github-actions/bazel/configure-remote@99d57027286c71dda92d8b91a3607abcf92d8bbd # main + uses: angular/dev-infra/github-actions/bazel/configure-remote@56bab29d886fd34280b1ccc203d8817e9725f0af # main with: google_credential: ${{ secrets.RBE_TRUSTED_BUILDS_USER }} - name: Run CLI E2E tests @@ -100,11 +100,11 @@ jobs: runs-on: ubuntu-latest steps: - name: Initialize environment - uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@99d57027286c71dda92d8b91a3607abcf92d8bbd # main + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@56bab29d886fd34280b1ccc203d8817e9725f0af # main - name: Setup Bazel - uses: angular/dev-infra/github-actions/bazel/setup@99d57027286c71dda92d8b91a3607abcf92d8bbd # main + uses: angular/dev-infra/github-actions/bazel/setup@56bab29d886fd34280b1ccc203d8817e9725f0af # main - name: Setup Bazel RBE - uses: angular/dev-infra/github-actions/bazel/configure-remote@99d57027286c71dda92d8b91a3607abcf92d8bbd # main + uses: angular/dev-infra/github-actions/bazel/configure-remote@56bab29d886fd34280b1ccc203d8817e9725f0af # main with: google_credential: ${{ secrets.RBE_TRUSTED_BUILDS_USER }} - name: Install node modules @@ -137,7 +137,7 @@ jobs: runs-on: windows-2025 steps: - name: Initialize environment - uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@99d57027286c71dda92d8b91a3607abcf92d8bbd # main + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@56bab29d886fd34280b1ccc203d8817e9725f0af # main - name: Install node modules run: pnpm install --frozen-lockfile - name: Download built Windows E2E tests @@ -164,13 +164,13 @@ jobs: runs-on: ubuntu-latest steps: - name: Initialize environment - uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@99d57027286c71dda92d8b91a3607abcf92d8bbd # main + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@56bab29d886fd34280b1ccc203d8817e9725f0af # main - name: Install node modules run: pnpm install --frozen-lockfile - name: Setup Bazel - uses: angular/dev-infra/github-actions/bazel/setup@99d57027286c71dda92d8b91a3607abcf92d8bbd # main + uses: angular/dev-infra/github-actions/bazel/setup@56bab29d886fd34280b1ccc203d8817e9725f0af # main - name: Setup Bazel RBE - uses: angular/dev-infra/github-actions/bazel/configure-remote@99d57027286c71dda92d8b91a3607abcf92d8bbd # main + uses: angular/dev-infra/github-actions/bazel/configure-remote@56bab29d886fd34280b1ccc203d8817e9725f0af # main with: google_credential: ${{ secrets.RBE_TRUSTED_BUILDS_USER }} - name: Run CLI E2E tests @@ -188,13 +188,13 @@ jobs: runs-on: ubuntu-latest steps: - name: Initialize environment - uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@99d57027286c71dda92d8b91a3607abcf92d8bbd # main + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@56bab29d886fd34280b1ccc203d8817e9725f0af # main - name: Install node modules run: pnpm install --frozen-lockfile - name: Setup Bazel - uses: angular/dev-infra/github-actions/bazel/setup@99d57027286c71dda92d8b91a3607abcf92d8bbd # main + uses: angular/dev-infra/github-actions/bazel/setup@56bab29d886fd34280b1ccc203d8817e9725f0af # main - name: Setup Bazel RBE - uses: angular/dev-infra/github-actions/bazel/configure-remote@99d57027286c71dda92d8b91a3607abcf92d8bbd # main + uses: angular/dev-infra/github-actions/bazel/configure-remote@56bab29d886fd34280b1ccc203d8817e9725f0af # main with: google_credential: ${{ secrets.RBE_TRUSTED_BUILDS_USER }} - name: Run CLI E2E tests @@ -208,13 +208,13 @@ jobs: SAUCE_TUNNEL_IDENTIFIER: angular-cli-${{ github.workflow }}-${{ github.run_number }} steps: - name: Initialize environment - uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@99d57027286c71dda92d8b91a3607abcf92d8bbd # main + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@56bab29d886fd34280b1ccc203d8817e9725f0af # main - name: Install node modules run: pnpm install --frozen-lockfile - name: Setup Bazel - uses: angular/dev-infra/github-actions/bazel/setup@99d57027286c71dda92d8b91a3607abcf92d8bbd # main + uses: angular/dev-infra/github-actions/bazel/setup@56bab29d886fd34280b1ccc203d8817e9725f0af # main - name: Setup Bazel RBE - uses: angular/dev-infra/github-actions/bazel/configure-remote@99d57027286c71dda92d8b91a3607abcf92d8bbd # main + uses: angular/dev-infra/github-actions/bazel/configure-remote@56bab29d886fd34280b1ccc203d8817e9725f0af # main with: google_credential: ${{ secrets.RBE_TRUSTED_BUILDS_USER }} - name: Start Sauce Connect @@ -245,11 +245,11 @@ jobs: CIRCLE_BRANCH: ${{ github.ref_name }} steps: - name: Initialize environment - uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@99d57027286c71dda92d8b91a3607abcf92d8bbd # main + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@56bab29d886fd34280b1ccc203d8817e9725f0af # main - name: Install node modules run: pnpm install --frozen-lockfile - name: Setup Bazel - uses: angular/dev-infra/github-actions/bazel/setup@99d57027286c71dda92d8b91a3607abcf92d8bbd # main + uses: angular/dev-infra/github-actions/bazel/setup@56bab29d886fd34280b1ccc203d8817e9725f0af # main - run: pnpm admin snapshots --verbose env: SNAPSHOT_BUILDS_GITHUB_TOKEN: ${{ secrets.SNAPSHOT_BUILDS_GITHUB_TOKEN }} diff --git a/.github/workflows/dev-infra.yml b/.github/workflows/dev-infra.yml index b12b3dc168ea..6066f04957ee 100644 --- a/.github/workflows/dev-infra.yml +++ b/.github/workflows/dev-infra.yml @@ -16,21 +16,21 @@ jobs: if: github.event_name == 'pull_request_target' runs-on: ubuntu-latest steps: - - uses: angular/dev-infra/github-actions/labeling/pull-request@99d57027286c71dda92d8b91a3607abcf92d8bbd # main + - uses: angular/dev-infra/github-actions/labeling/pull-request@56bab29d886fd34280b1ccc203d8817e9725f0af # main with: angular-robot-key: ${{ secrets.ANGULAR_ROBOT_PRIVATE_KEY }} post_approval_changes: if: github.event_name == 'pull_request_target' runs-on: ubuntu-latest steps: - - uses: angular/dev-infra/github-actions/post-approval-changes@99d57027286c71dda92d8b91a3607abcf92d8bbd # main + - uses: angular/dev-infra/github-actions/post-approval-changes@56bab29d886fd34280b1ccc203d8817e9725f0af # main with: angular-robot-key: ${{ secrets.ANGULAR_ROBOT_PRIVATE_KEY }} issue_labels: if: github.event_name == 'issues' runs-on: ubuntu-latest steps: - - uses: angular/dev-infra/github-actions/labeling/issue@99d57027286c71dda92d8b91a3607abcf92d8bbd # main + - uses: angular/dev-infra/github-actions/labeling/issue@56bab29d886fd34280b1ccc203d8817e9725f0af # main with: angular-robot-key: ${{ secrets.ANGULAR_ROBOT_PRIVATE_KEY }} google-generative-ai-key: ${{ secrets.GOOGLE_GENERATIVE_AI_KEY }} diff --git a/.github/workflows/perf.yml b/.github/workflows/perf.yml index b837b722a4f4..e2c9f91e726d 100644 --- a/.github/workflows/perf.yml +++ b/.github/workflows/perf.yml @@ -22,7 +22,7 @@ jobs: workflows: ${{ steps.workflows.outputs.workflows }} steps: - name: Initialize environment - uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@99d57027286c71dda92d8b91a3607abcf92d8bbd # main + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@56bab29d886fd34280b1ccc203d8817e9725f0af # main - name: Install node modules run: pnpm install --frozen-lockfile - id: workflows @@ -40,9 +40,9 @@ jobs: workflow: ${{ fromJSON(needs.list.outputs.workflows) }} steps: - name: Initialize environment - uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@99d57027286c71dda92d8b91a3607abcf92d8bbd # main + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@56bab29d886fd34280b1ccc203d8817e9725f0af # main - name: Setup Bazel - uses: angular/dev-infra/github-actions/bazel/setup@99d57027286c71dda92d8b91a3607abcf92d8bbd # main + uses: angular/dev-infra/github-actions/bazel/setup@56bab29d886fd34280b1ccc203d8817e9725f0af # main - name: Install node modules run: pnpm install --frozen-lockfile # We utilize the google-github-actions/auth action to allow us to get an active credential using workflow diff --git a/.github/workflows/pr.yml b/.github/workflows/pr.yml index c62816440333..a826cfeba4f3 100644 --- a/.github/workflows/pr.yml +++ b/.github/workflows/pr.yml @@ -34,9 +34,9 @@ jobs: runs-on: ubuntu-latest steps: - name: Initialize environment - uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@99d57027286c71dda92d8b91a3607abcf92d8bbd # main + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@56bab29d886fd34280b1ccc203d8817e9725f0af # main - name: Setup Bazel - uses: angular/dev-infra/github-actions/bazel/setup@99d57027286c71dda92d8b91a3607abcf92d8bbd # main + uses: angular/dev-infra/github-actions/bazel/setup@56bab29d886fd34280b1ccc203d8817e9725f0af # main - name: Setup ESLint Caching uses: actions/cache@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0 with: @@ -66,17 +66,17 @@ jobs: # it has been merged. run: pnpm ng-dev format changed --check ${{ github.event.pull_request.base.sha }} - name: Check Package Licenses - uses: angular/dev-infra/github-actions/linting/licenses@99d57027286c71dda92d8b91a3607abcf92d8bbd # main + uses: angular/dev-infra/github-actions/linting/licenses@56bab29d886fd34280b1ccc203d8817e9725f0af # main build: runs-on: ubuntu-latest steps: - name: Initialize environment - uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@99d57027286c71dda92d8b91a3607abcf92d8bbd # main + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@56bab29d886fd34280b1ccc203d8817e9725f0af # main - name: Setup Bazel - uses: angular/dev-infra/github-actions/bazel/setup@99d57027286c71dda92d8b91a3607abcf92d8bbd # main + uses: angular/dev-infra/github-actions/bazel/setup@56bab29d886fd34280b1ccc203d8817e9725f0af # main - name: Setup Bazel RBE - uses: angular/dev-infra/github-actions/bazel/configure-remote@99d57027286c71dda92d8b91a3607abcf92d8bbd # main + uses: angular/dev-infra/github-actions/bazel/configure-remote@56bab29d886fd34280b1ccc203d8817e9725f0af # main - name: Install node modules run: pnpm install --frozen-lockfile - name: Build release targets @@ -93,11 +93,11 @@ jobs: runs-on: ubuntu-latest steps: - name: Initialize environment - uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@99d57027286c71dda92d8b91a3607abcf92d8bbd # main + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@56bab29d886fd34280b1ccc203d8817e9725f0af # main - name: Setup Bazel - uses: angular/dev-infra/github-actions/bazel/setup@99d57027286c71dda92d8b91a3607abcf92d8bbd # main + uses: angular/dev-infra/github-actions/bazel/setup@56bab29d886fd34280b1ccc203d8817e9725f0af # main - name: Setup Bazel RBE - uses: angular/dev-infra/github-actions/bazel/configure-remote@99d57027286c71dda92d8b91a3607abcf92d8bbd # main + uses: angular/dev-infra/github-actions/bazel/configure-remote@56bab29d886fd34280b1ccc203d8817e9725f0af # main - name: Install node modules run: pnpm install --frozen-lockfile - name: Run module and package tests @@ -114,13 +114,13 @@ jobs: runs-on: ubuntu-latest steps: - name: Initialize environment - uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@99d57027286c71dda92d8b91a3607abcf92d8bbd # main + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@56bab29d886fd34280b1ccc203d8817e9725f0af # main - name: Install node modules run: pnpm install --frozen-lockfile - name: Setup Bazel - uses: angular/dev-infra/github-actions/bazel/setup@99d57027286c71dda92d8b91a3607abcf92d8bbd # main + uses: angular/dev-infra/github-actions/bazel/setup@56bab29d886fd34280b1ccc203d8817e9725f0af # main - name: Setup Bazel RBE - uses: angular/dev-infra/github-actions/bazel/configure-remote@99d57027286c71dda92d8b91a3607abcf92d8bbd # main + uses: angular/dev-infra/github-actions/bazel/configure-remote@56bab29d886fd34280b1ccc203d8817e9725f0af # main - name: Run CLI E2E tests run: pnpm bazel test --test_env=E2E_SHARD_TOTAL=6 --test_env=E2E_SHARD_INDEX=${{ matrix.shard }} --config=e2e //tests:e2e.${{ matrix.subset }}_node${{ matrix.node }} @@ -128,11 +128,11 @@ jobs: runs-on: ubuntu-latest steps: - name: Initialize environment - uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@99d57027286c71dda92d8b91a3607abcf92d8bbd # main + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@56bab29d886fd34280b1ccc203d8817e9725f0af # main - name: Setup Bazel - uses: angular/dev-infra/github-actions/bazel/setup@99d57027286c71dda92d8b91a3607abcf92d8bbd # main + uses: angular/dev-infra/github-actions/bazel/setup@56bab29d886fd34280b1ccc203d8817e9725f0af # main - name: Setup Bazel RBE - uses: angular/dev-infra/github-actions/bazel/configure-remote@99d57027286c71dda92d8b91a3607abcf92d8bbd # main + uses: angular/dev-infra/github-actions/bazel/configure-remote@56bab29d886fd34280b1ccc203d8817e9725f0af # main - name: Install node modules run: pnpm install --frozen-lockfile - name: Build E2E tests for Windows on Linux @@ -156,7 +156,7 @@ jobs: runs-on: windows-2025 steps: - name: Initialize environment - uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@99d57027286c71dda92d8b91a3607abcf92d8bbd # main + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@56bab29d886fd34280b1ccc203d8817e9725f0af # main - name: Install node modules run: pnpm install --frozen-lockfile - name: Download built Windows E2E tests @@ -183,13 +183,13 @@ jobs: runs-on: ubuntu-latest steps: - name: Initialize environment - uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@99d57027286c71dda92d8b91a3607abcf92d8bbd # main + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@56bab29d886fd34280b1ccc203d8817e9725f0af # main - name: Install node modules run: pnpm install --frozen-lockfile - name: Setup Bazel - uses: angular/dev-infra/github-actions/bazel/setup@99d57027286c71dda92d8b91a3607abcf92d8bbd # main + uses: angular/dev-infra/github-actions/bazel/setup@56bab29d886fd34280b1ccc203d8817e9725f0af # main - name: Setup Bazel RBE - uses: angular/dev-infra/github-actions/bazel/configure-remote@99d57027286c71dda92d8b91a3607abcf92d8bbd # main + uses: angular/dev-infra/github-actions/bazel/configure-remote@56bab29d886fd34280b1ccc203d8817e9725f0af # main - name: Run CLI E2E tests run: pnpm bazel test --test_env=E2E_SHARD_TOTAL=3 --test_env=E2E_SHARD_INDEX=${{ matrix.shard }} --config=e2e //tests:e2e.${{ matrix.subset }}_node${{ matrix.node }} @@ -205,12 +205,12 @@ jobs: runs-on: ubuntu-latest steps: - name: Initialize environment - uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@99d57027286c71dda92d8b91a3607abcf92d8bbd # main + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@56bab29d886fd34280b1ccc203d8817e9725f0af # main - name: Install node modules run: pnpm install --frozen-lockfile - name: Setup Bazel - uses: angular/dev-infra/github-actions/bazel/setup@99d57027286c71dda92d8b91a3607abcf92d8bbd # main + uses: angular/dev-infra/github-actions/bazel/setup@56bab29d886fd34280b1ccc203d8817e9725f0af # main - name: Setup Bazel RBE - uses: angular/dev-infra/github-actions/bazel/configure-remote@99d57027286c71dda92d8b91a3607abcf92d8bbd # main + uses: angular/dev-infra/github-actions/bazel/configure-remote@56bab29d886fd34280b1ccc203d8817e9725f0af # main - name: Run CLI E2E tests run: pnpm bazel test --test_env=E2E_SHARD_TOTAL=6 --test_env=E2E_SHARD_INDEX=${{ matrix.shard }} --config=e2e //tests:e2e.snapshots.${{ matrix.subset }}_node${{ matrix.node }} diff --git a/MODULE.bazel b/MODULE.bazel index 595813a5abf1..ef8a2c95e1fd 100644 --- a/MODULE.bazel +++ b/MODULE.bazel @@ -19,21 +19,21 @@ bazel_dep(name = "aspect_rules_jasmine", version = "2.0.4") bazel_dep(name = "rules_angular") git_override( module_name = "rules_angular", - commit = "7fdee07b9989b92b88f24c84471e01d6a0a9bc34", + commit = "6468bfd6c2f90b7a025d86273b070d0dd0a443db", remote = "https://github.com/angular/rules_angular.git", ) bazel_dep(name = "devinfra") git_override( module_name = "devinfra", - commit = "99d57027286c71dda92d8b91a3607abcf92d8bbd", + commit = "56bab29d886fd34280b1ccc203d8817e9725f0af", remote = "https://github.com/angular/dev-infra.git", ) bazel_dep(name = "rules_browsers") git_override( module_name = "rules_browsers", - commit = "f87a5f7fc587219ff328da2972e06370f297a621", + commit = "ba55f13997d951c9ac02192cf6d1cadad03c1237", remote = "https://github.com/angular/rules_browsers.git", ) diff --git a/package.json b/package.json index 75b435b1af65..3cf313dbfe2f 100644 --- a/package.json +++ b/package.json @@ -55,7 +55,7 @@ "@angular/forms": "22.2.0-rc.0", "@angular/localize": "22.2.0-rc.0", "@angular/material": "22.2.0-rc.0", - "@angular/ng-dev": "https://github.com/angular/dev-infra-private-ng-dev-builds.git#f5de34cabca7e005dc8102d3abb026d01a7a881a", + "@angular/ng-dev": "https://github.com/angular/dev-infra-private-ng-dev-builds.git#90a76327155df50e90a41fe76aed67b98a9cf954", "@angular/platform-browser": "22.2.0-rc.0", "@angular/platform-server": "22.2.0-rc.0", "@angular/router": "22.2.0-rc.0", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 44df5d7bd1b1..bc209c16d2f3 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -208,8 +208,8 @@ importers: specifier: 22.2.0-rc.0 version: 22.2.0-rc.0(25ddf4063a130bbf19862bd16a6ab5d4) '@angular/ng-dev': - specifier: https://github.com/angular/dev-infra-private-ng-dev-builds.git#f5de34cabca7e005dc8102d3abb026d01a7a881a - version: https://codeload.github.com/angular/dev-infra-private-ng-dev-builds/tar.gz/f5de34cabca7e005dc8102d3abb026d01a7a881a + specifier: https://github.com/angular/dev-infra-private-ng-dev-builds.git#90a76327155df50e90a41fe76aed67b98a9cf954 + version: https://codeload.github.com/angular/dev-infra-private-ng-dev-builds/tar.gz/90a76327155df50e90a41fe76aed67b98a9cf954 '@angular/platform-browser': specifier: 22.2.0-rc.0 version: 22.2.0-rc.0(@angular/animations@22.2.0-rc.0(@angular/core@22.2.0-rc.0(@angular/compiler@22.2.0-rc.0)(rxjs@7.8.2)(zone.js@0.16.3)))(@angular/common@22.2.0-rc.0(@angular/core@22.2.0-rc.0(@angular/compiler@22.2.0-rc.0)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2))(@angular/core@22.2.0-rc.0(@angular/compiler@22.2.0-rc.0)(rxjs@7.8.2)(zone.js@0.16.3)) @@ -1103,9 +1103,9 @@ packages: '@angular/platform-browser': ^22.0.0-0 || ^22.1.0-0 || ^22.2.0-0 || ^22.3.0-0 || ^23.0.0-0 rxjs: ^6.5.3 || ^7.4.0 - '@angular/ng-dev@https://codeload.github.com/angular/dev-infra-private-ng-dev-builds/tar.gz/f5de34cabca7e005dc8102d3abb026d01a7a881a': - resolution: {gitHosted: true, integrity: sha512-JEXOlRtQ50aV/E2C+PeGKYCmGHWOi6G70kiS0tTjKGAn+qrYTRQQzFSm4YB2VVYnL16s3jg8oAIwZ4pl/t9WgQ==, tarball: https://codeload.github.com/angular/dev-infra-private-ng-dev-builds/tar.gz/f5de34cabca7e005dc8102d3abb026d01a7a881a} - version: 0.0.0-71e60c68d9d483b0d763b8e6ed4dd9deb8da3b1a + '@angular/ng-dev@https://codeload.github.com/angular/dev-infra-private-ng-dev-builds/tar.gz/90a76327155df50e90a41fe76aed67b98a9cf954': + resolution: {gitHosted: true, integrity: sha512-VmtUf+oZIHjATMGTjURjB3gJJ72gPo4nCDWEDUtW3MqgLPl088ISDgnV9CPXEt62EbByn9+0vVULCCk4p8YcVg==, tarball: https://codeload.github.com/angular/dev-infra-private-ng-dev-builds/tar.gz/90a76327155df50e90a41fe76aed67b98a9cf954} + version: 0.0.0-20b69d39859eae19d7ac04b6f1902f73286f7686 hasBin: true '@angular/platform-browser@22.2.0-rc.0': @@ -2020,15 +2020,15 @@ packages: '@noble/hashes': optional: true - '@firebase/ai@2.15.0': - resolution: {integrity: sha512-Aj7TbFdAIWZdkX8JfdDStERpR35g6WNs+7XhNPtFLFOizUotj6k4N/D8HJkR45165HhnMJBe4hjOeeaxnnn56Q==} + '@firebase/ai@2.16.0': + resolution: {integrity: sha512-WRVxl58B61Orwf7st7949ZIW2L4huV80Gpaum1z8v2eH+m2xaxWtC8mOjQyVAOirr6O/yf89cBjlPvoyBpBfTg==} engines: {node: '>=20.0.0'} peerDependencies: '@firebase/app': 0.x '@firebase/app-types': 0.x - '@firebase/analytics-compat@0.2.30': - resolution: {integrity: sha512-uVZEKlLaW4AHAhv8zoN9cTmveX6v86AVqcJ4LCaRCMTChTH8/NsjbisTq1lpBfWCLWS1spqwSHB4vol/YSCdMA==} + '@firebase/analytics-compat@0.2.31': + resolution: {integrity: sha512-msTlG9REujk5rjtOHNLngiuPmvaWGQte8ugL4/F6ZCMb+92Ue7SgjSEpNxINkM8ZtTrbGS83j5SZkt0r+M1Tjw==} peerDependencies: '@firebase/app': 0.x '@firebase/app-compat': 0.x @@ -2036,8 +2036,8 @@ packages: '@firebase/analytics-types@0.8.5': resolution: {integrity: sha512-kdnooE7Bis2jEnsqcerRwn/UQpH5D3uvHpku7OdUM9TJN3omlu6iYtbyAQ6XkAJRgJtO0aNf9OOkW8J6D59oCA==} - '@firebase/analytics@0.10.24': - resolution: {integrity: sha512-OfIAcIIwoqXjBzS+DnUQpOZ7i3ePaNFg83KPpDWjBZUKJmqMwzzAtLJqmKZOkQnW8im6vFR6f2I3M/9hxVd+QA==} + '@firebase/analytics@0.10.25': + resolution: {integrity: sha512-oDagV3PHeNXBdxemksZCdj+GmUT19eCnTOcLdQePIIovFXlm3zWy3Gjeaokt9Nqx24kc4ljK8lU0XGcGmmKZ1A==} peerDependencies: '@firebase/app': 0.x @@ -2060,19 +2060,19 @@ packages: peerDependencies: '@firebase/app': 0.x - '@firebase/app-compat@0.5.17': - resolution: {integrity: sha512-5GdJWobqs6jbNYOnaQiSa4Ng8gnFerhqr7nY+v5jlnT7o9QbEeIZRLPQpnLe0TxYSWfRV2lAMbyR0kbXeIos9Q==} + '@firebase/app-compat@0.5.18': + resolution: {integrity: sha512-77H57WuGEsgrv59HdtuhHG+eQdP8di6myz7O93yW6yTZlR/tLSmsCxCq5vHp6AWWDwSV0EVtKUvizXQiQZVBWA==} engines: {node: '>=20.0.0'} '@firebase/app-types@0.9.6': resolution: {integrity: sha512-yPLahy7Esfu2w/yme3msVK4xTkDXQqq6szfQn8yVOQpCKiT5GVFjqNpLbuz6NkX0WuTwUidkmPewW3r4xkvpeg==} - '@firebase/app@0.16.1': - resolution: {integrity: sha512-tjUEorFyKrurH7PbLWv9zDHRuU4mLefgD/yY38D584ziorIRlQz/PVjx4c/SCGyCuUlmyzt72mK+Lh+COAywNQ==} + '@firebase/app@0.16.2': + resolution: {integrity: sha512-fyCLPahl3r0Zb7Wzm+JLWcOOH3SaDgAyJzJ8EWIDiv51aNiv+2Pjbpa6myEuP7iXxjmJqrcbVm0GUF7h229T1Q==} engines: {node: '>=20.0.0'} - '@firebase/auth-compat@0.6.10': - resolution: {integrity: sha512-Bvklg2nL7BrBFCAqdsleW8fse9Jh0fARqJPlJmA40uermfWx1bJiO7dnKyZN3J39d2TFVd4VJXtg3i6Wg92/YQ==} + '@firebase/auth-compat@0.6.11': + resolution: {integrity: sha512-L+xp3DTJQrBV08Vt0UhcL/ofUOSjXom7JOJfbT6oas4o7gCrQnTYFKs8wfiuKLmHoo8BxMr5LdgjAs7o6aAsqQ==} engines: {node: '>=20.0.0'} peerDependencies: '@firebase/app': 0.x @@ -2087,8 +2087,8 @@ packages: '@firebase/app-types': 0.x '@firebase/util': 1.x - '@firebase/auth@1.13.5': - resolution: {integrity: sha512-1AXoBJqBVD8WL8FZYo3S2GmJF9YUoom6Y6ngMxOSkzzhW5sT83pLchb6TGFgxes91dfXx8s/VYc5VrLDNqpLog==} + '@firebase/auth@1.13.6': + resolution: {integrity: sha512-MKRLvF72HJ/irNn2fJR0Gv5FOZNtqv1IBeJHRwK8l8pZ/wi9vuUw8ecyCMvQDDNxfS6uW0MWACL5KC4Y8Pp+fA==} engines: {node: '>=20.0.0'} peerDependencies: '@firebase/app': 0.x @@ -2125,8 +2125,8 @@ packages: resolution: {integrity: sha512-/JGpvszLoNXNgzilRXocigGfFF4hbcPA9wN1i1kjJx6oKkXgkHteZYl3lQs1lJX3ETDf6bv7zI15lPMVUp4sAQ==} engines: {node: '>=20.0.0'} - '@firebase/firestore-compat@0.4.13': - resolution: {integrity: sha512-l9dCewxMzzLOIhcwTjERCKxrWOn1kZ9JvwOQq9zZNq4I/Nbvb/B9njT230V61uvQ9qZ3/qpUG758D8DDTEFXnw==} + '@firebase/firestore-compat@0.4.14': + resolution: {integrity: sha512-HJ2HBNgNPrRsWIJ4E+Kc0u0h1U7HlF7If8AtYjie9HZXlMUmwYSJaXBj9VFm6gkSj5dlKZNcOQ0Ou25CVVG6rA==} engines: {node: '>=20.0.0'} peerDependencies: '@firebase/app': 0.x @@ -2138,8 +2138,8 @@ packages: '@firebase/app-types': 0.x '@firebase/util': 1.x - '@firebase/firestore@4.17.1': - resolution: {integrity: sha512-8lqPNf2w10CtYG+tayVjZO1pSyQpnhztQRudeD109VtXDzNbASTaYdO43sj5PMsDcWq0aOYY3RmJOUlXu9++jw==} + '@firebase/firestore@4.17.2': + resolution: {integrity: sha512-SiyQEK1dYPOjItFVA+kZGdvOoRAtMebDBvUaSxJPNZMkKcRwYYK2kzWo5UXTZZj523uMxJnkr+KKVySEMme3kQ==} engines: {node: '>=20.0.0'} peerDependencies: '@firebase/app': 0.x @@ -2180,8 +2180,8 @@ packages: resolution: {integrity: sha512-J2VO4NFTc0xQFrxV1B/lm5balicm9cwuX2acR9Yn41fN8KgUeQFo+VJV222IqW2FPSXKDu9uo5WdQFWf9TPbYg==} engines: {node: '>=20.0.0'} - '@firebase/messaging-compat@0.2.29': - resolution: {integrity: sha512-8Twe4CeYvAx8AzjBxyyQFKzinaMGGt13hPQBqaARQ2QZjagrEaqSVBe+Zy6F4L/vT8DV168yRgRu7W/RK7p+4w==} + '@firebase/messaging-compat@0.2.30': + resolution: {integrity: sha512-m1DPT2ET5x0qYqXLoHwKMAyf1mgZZOhuoE6H6/H4OPsp8zSxMIDEFPaW7MaffPJsCA5J7kHzo+BHVNXK4ZoV+w==} peerDependencies: '@firebase/app': 0.x '@firebase/app-compat': 0.x @@ -2189,8 +2189,8 @@ packages: '@firebase/messaging-interop-types@0.2.6': resolution: {integrity: sha512-MVzvkKe2V4H2dHu5oOxRfeKQcfTwWmCgnzsC4V1q3ixun5iiL8riCZ2qI35rDhCL4glPGiu0jHxDbpVNuTKfow==} - '@firebase/messaging@0.13.2': - resolution: {integrity: sha512-KcZoqUu2ih4sLH91dW9tmyHjCR0IQyNzSLZunX5uq7cLeImXb4uO2I0wq5FACduO2I+FoTeWa2BtUv7Jpowqdw==} + '@firebase/messaging@0.13.3': + resolution: {integrity: sha512-nRXPAp+z0kA3KziJtRY9kktHECvRwaaONzHvislFgllhCwJMscW7icWNQA5IjyP8Uc2+GS/4px8Uz6rx6ftTag==} peerDependencies: '@firebase/app': 0.x @@ -2279,8 +2279,8 @@ packages: resolution: {integrity: sha512-IJn+8A3QZJfe7FUtWqHVNo3xJs7KFpurCWGWCiCz3oEh+BkRymKZ1QxfAbU2yGMDzTytLGQ2IV6T2r3cuo75/w==} engines: {node: '>=18'} - '@google/genai@2.20.0': - resolution: {integrity: sha512-kFEzARfA064oCNAmYTyOaAeJ9KSkbZ2Upxz36oO5eVNlcxAXsixLlGbwY1oy+Ab8HJ6nMWMD9hg+NdIron6wJw==} + '@google/genai@2.22.0': + resolution: {integrity: sha512-NE90Nl0AP75YZ2tGxXjQQs6Gkunma7a1JmPCx5g5CxvjHXshmuI2aNoPJ1xLrRixjkNxog898oylM+MyNudUQw==} engines: {node: '>=20.0.0'} peerDependencies: '@modelcontextprotocol/sdk': ^1.25.2 @@ -2418,15 +2418,6 @@ packages: '@types/node': optional: true - '@inquirer/prompts@8.7.0': - resolution: {integrity: sha512-yQwBMYvpJ6jqrXtKiOwRD5XezjJoyt3VQvIyjsr5Arqb519nfIohOQymWVJ8/vEgg8xtZerrCsqlSaqt/LPC9A==} - engines: {node: '>=23.5.0 || ^22.13.0 || ^20.17.0'} - peerDependencies: - '@types/node': '>=18' - peerDependenciesMeta: - '@types/node': - optional: true - '@inquirer/prompts@8.7.2': resolution: {integrity: sha512-QoRB4wFIjgH5iOhSjoIKMkTvSHDuV+O3OITlIqAYO0oK5x364GJILXiMBvlPiE+klg7Xx9tq5XVqQHcGUDYYPA==} engines: {node: '>=23.5.0 || ^22.13.0 || ^20.17.0'} @@ -2463,15 +2454,6 @@ packages: '@types/node': optional: true - '@inquirer/type@4.1.0': - resolution: {integrity: sha512-FMiJpuHUG3Dk0ex+UIXkre7i+i4OcwHWk9YdcVtZHFwb/r2rnrU2ipTCNAB7A+QOP0ryzIcqOfy76fRyyvOEAw==} - engines: {node: '>=23.5.0 || ^22.13.0 || ^20.17.0'} - peerDependencies: - '@types/node': '>=18' - peerDependenciesMeta: - '@types/node': - optional: true - '@inquirer/type@4.1.1': resolution: {integrity: sha512-yJoHYrMnxIsJZCY+0Vb66Dy3he3kL3e2wOBKhoSwWWAzZAY82emlxwgprCtp6yRixvNRNq9ztfRWQYPNr3Go7A==} engines: {node: '>=23.5.0 || ^22.13.0 || ^20.17.0'} @@ -3729,8 +3711,8 @@ packages: '@types/node@22.20.2': resolution: {integrity: sha512-xlvWf4Vs9n1PEVYwP1n4vvG07M6y8WgvJ2t0vbrWTmijsIHp1cS+uJ2kMIRdY3nHZK0nCYKrPeD171+SzF4/zw==} - '@types/node@24.13.3': - resolution: {integrity: sha512-Dh8vAsV36ig5wa9OX4pXvMc9D3Veibfw2wix0CUwYODLD8nkj9UsLjASr49nPg+2eKzxhBV+v7L8pXvT4e639Q==} + '@types/node@24.13.5': + resolution: {integrity: sha512-TXyindR+lBr22aJIdMQzCFHPHR6cR4js838mRDCSz5hOKWZvZwsXSSiXDmjRj4iJmgl+sR9O+1mkoVBSMadNug==} '@types/npm-package-arg@6.1.4': resolution: {integrity: sha512-vDgdbMy2QXHnAruzlv68pUtXCjmqUk3WrBAsRboRovsOmxbfn/WiYCjmecyKjGztnMps5dWp4Uq2prp+Ilo17Q==} @@ -5419,8 +5401,8 @@ packages: resolution: {integrity: sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==} engines: {node: '>=10'} - firebase@12.18.0: - resolution: {integrity: sha512-XaL6tlE5Xd20ZDhckqOMIw+JJTET+wTdeZPxQ7ihc42oxRb7kWUyn/j1LO5V9dH1xq8Rv5R71Pv1fBCdIkt9Rw==} + firebase@12.19.0: + resolution: {integrity: sha512-kwXCLcI0ly2lkwygkbuRx6SsX3DSO96355YrWh9SWZ5ncsxK/y5cirn3sY6nZVSiBVE++2nL6Hchzu1EB8uohQ==} flat-cache@6.1.23: resolution: {integrity: sha512-f++BY9pTk+983xK1FLzlLpmM0i0z+jHmx3QESGkURMXujQZz1k5wzwX6hjnQ8goaD0B+sYnDK1yZ6MTyZfUaqA==} @@ -8711,11 +8693,6 @@ packages: yallist@3.1.1: resolution: {integrity: sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==} - yaml@2.9.0: - resolution: {integrity: sha512-2AvhNX3mb8zd6Zy7INTtSpl1F15HW6Wnqj0srWlkKLcpYl/gMIMJiyuGq2KeI2YFxUPjdlB+3Lc10seMLtL4cA==} - engines: {node: '>= 14.6'} - hasBin: true - yaml@2.9.1: resolution: {integrity: sha512-3NxN8+78OdzbT7C/WjGsyfPAtJaN3FNDsWxv7Y7mcDsT/oOmgW8BpyQQFFBnvZE3j9Y2Sdz1ULFLezL7Eb2yFw==} engines: {node: '>= 14.6'} @@ -8869,14 +8846,14 @@ snapshots: rxjs: 7.8.2 tslib: 2.8.1 - '@angular/ng-dev@https://codeload.github.com/angular/dev-infra-private-ng-dev-builds/tar.gz/f5de34cabca7e005dc8102d3abb026d01a7a881a': + '@angular/ng-dev@https://codeload.github.com/angular/dev-infra-private-ng-dev-builds/tar.gz/90a76327155df50e90a41fe76aed67b98a9cf954': dependencies: '@actions/core': 3.0.1 '@conventional-changelog/git-client': 3.1.2(conventional-commits-filter@6.0.1)(conventional-commits-parser@7.1.2) '@google-cloud/spanner': 8.0.0(supports-color@11.0.0) - '@google/genai': 2.20.0(bufferutil@4.1.0)(supports-color@11.0.0)(utf-8-validate@6.0.6) - '@inquirer/prompts': 8.7.0(@types/node@24.13.3) - '@inquirer/type': 4.1.0(@types/node@24.13.3) + '@google/genai': 2.22.0(bufferutil@4.1.0)(supports-color@11.0.0)(utf-8-validate@6.0.6) + '@inquirer/prompts': 8.7.2(@types/node@24.13.5) + '@inquirer/type': 4.1.1(@types/node@24.13.5) '@octokit/auth-app': 8.3.1 '@octokit/core': 7.0.8 '@octokit/graphql': 9.0.5 @@ -8892,7 +8869,7 @@ snapshots: '@types/events': 3.0.3 '@types/folder-hash': 4.0.4 '@types/jasmine': 6.0.0 - '@types/node': 24.13.3 + '@types/node': 24.13.5 '@types/semver': 7.8.0 '@types/which': 3.0.4 '@types/yargs': 17.0.35 @@ -8905,7 +8882,7 @@ snapshots: ejs: 6.0.1 encoding: 0.1.13 fast-glob: 3.3.3 - firebase: 12.18.0 + firebase: 12.19.0 folder-hash: 4.1.3(supports-color@11.0.0) jasmine: 6.3.0 jasmine-core: 6.3.0 @@ -8921,7 +8898,7 @@ snapshots: typescript: 6.0.3 utf-8-validate: 6.0.6 which: 7.0.0 - yaml: 2.9.0 + yaml: 2.9.1 yargs: 18.1.0 zod: 4.6.5 transitivePeerDependencies: @@ -9884,9 +9861,9 @@ snapshots: '@exodus/bytes@1.15.1': {} - '@firebase/ai@2.15.0(@firebase/app-types@0.9.6)(@firebase/app@0.16.1)': + '@firebase/ai@2.16.0(@firebase/app-types@0.9.6)(@firebase/app@0.16.2)': dependencies: - '@firebase/app': 0.16.1 + '@firebase/app': 0.16.2 '@firebase/app-check-interop-types': 0.3.5 '@firebase/app-types': 0.9.6 '@firebase/component': 0.7.5 @@ -9894,33 +9871,33 @@ snapshots: '@firebase/util': 1.15.3 tslib: 2.8.1 - '@firebase/analytics-compat@0.2.30(@firebase/app-compat@0.5.17)(@firebase/app@0.16.1)': + '@firebase/analytics-compat@0.2.31(@firebase/app-compat@0.5.18)(@firebase/app@0.16.2)': dependencies: - '@firebase/analytics': 0.10.24(@firebase/app@0.16.1) + '@firebase/analytics': 0.10.25(@firebase/app@0.16.2) '@firebase/analytics-types': 0.8.5 - '@firebase/app': 0.16.1 - '@firebase/app-compat': 0.5.17 + '@firebase/app': 0.16.2 + '@firebase/app-compat': 0.5.18 '@firebase/component': 0.7.5 '@firebase/util': 1.15.3 tslib: 2.8.1 '@firebase/analytics-types@0.8.5': {} - '@firebase/analytics@0.10.24(@firebase/app@0.16.1)': + '@firebase/analytics@0.10.25(@firebase/app@0.16.2)': dependencies: - '@firebase/app': 0.16.1 + '@firebase/app': 0.16.2 '@firebase/component': 0.7.5 - '@firebase/installations': 0.6.24(@firebase/app@0.16.1) + '@firebase/installations': 0.6.24(@firebase/app@0.16.2) '@firebase/logger': 0.5.2 '@firebase/util': 1.15.3 tslib: 2.8.1 - '@firebase/app-check-compat@0.4.7(@firebase/app-compat@0.5.17)(@firebase/app@0.16.1)': + '@firebase/app-check-compat@0.4.7(@firebase/app-compat@0.5.18)(@firebase/app@0.16.2)': dependencies: - '@firebase/app': 0.16.1 - '@firebase/app-check': 0.13.1(@firebase/app@0.16.1) + '@firebase/app': 0.16.2 + '@firebase/app-check': 0.13.1(@firebase/app@0.16.2) '@firebase/app-check-types': 0.5.5 - '@firebase/app-compat': 0.5.17 + '@firebase/app-compat': 0.5.18 '@firebase/component': 0.7.5 '@firebase/logger': 0.5.2 '@firebase/util': 1.15.3 @@ -9930,17 +9907,17 @@ snapshots: '@firebase/app-check-types@0.5.5': {} - '@firebase/app-check@0.13.1(@firebase/app@0.16.1)': + '@firebase/app-check@0.13.1(@firebase/app@0.16.2)': dependencies: - '@firebase/app': 0.16.1 + '@firebase/app': 0.16.2 '@firebase/component': 0.7.5 '@firebase/logger': 0.5.2 '@firebase/util': 1.15.3 tslib: 2.8.1 - '@firebase/app-compat@0.5.17': + '@firebase/app-compat@0.5.18': dependencies: - '@firebase/app': 0.16.1 + '@firebase/app': 0.16.2 '@firebase/component': 0.7.5 '@firebase/logger': 0.5.2 '@firebase/util': 1.15.3 @@ -9950,7 +9927,7 @@ snapshots: dependencies: '@firebase/logger': 0.5.2 - '@firebase/app@0.16.1': + '@firebase/app@0.16.2': dependencies: '@firebase/component': 0.7.5 '@firebase/logger': 0.5.2 @@ -9958,11 +9935,11 @@ snapshots: idb: 7.1.1 tslib: 2.8.1 - '@firebase/auth-compat@0.6.10(@firebase/app-compat@0.5.17)(@firebase/app-types@0.9.6)(@firebase/app@0.16.1)': + '@firebase/auth-compat@0.6.11(@firebase/app-compat@0.5.18)(@firebase/app-types@0.9.6)(@firebase/app@0.16.2)': dependencies: - '@firebase/app': 0.16.1 - '@firebase/app-compat': 0.5.17 - '@firebase/auth': 1.13.5(@firebase/app@0.16.1) + '@firebase/app': 0.16.2 + '@firebase/app-compat': 0.5.18 + '@firebase/auth': 1.13.6(@firebase/app@0.16.2) '@firebase/auth-types': 0.13.2(@firebase/app-types@0.9.6)(@firebase/util@1.15.3) '@firebase/component': 0.7.5 '@firebase/util': 1.15.3 @@ -9978,9 +9955,9 @@ snapshots: '@firebase/app-types': 0.9.6 '@firebase/util': 1.15.3 - '@firebase/auth@1.13.5(@firebase/app@0.16.1)': + '@firebase/auth@1.13.6(@firebase/app@0.16.2)': dependencies: - '@firebase/app': 0.16.1 + '@firebase/app': 0.16.2 '@firebase/component': 0.7.5 '@firebase/logger': 0.5.2 '@firebase/util': 1.15.3 @@ -9991,16 +9968,16 @@ snapshots: '@firebase/util': 1.15.3 tslib: 2.8.1 - '@firebase/data-connect@0.7.4(@firebase/app@0.16.1)': + '@firebase/data-connect@0.7.4(@firebase/app@0.16.2)': dependencies: - '@firebase/app': 0.16.1 + '@firebase/app': 0.16.2 '@firebase/auth-interop-types': 0.2.6 '@firebase/component': 0.7.5 '@firebase/logger': 0.5.2 '@firebase/util': 1.15.3 tslib: 2.8.1 - '@firebase/database-compat@2.1.7(@firebase/app-compat@0.5.17)(@firebase/app@0.16.1)': + '@firebase/database-compat@2.1.7(@firebase/app-compat@0.5.18)(@firebase/app@0.16.2)': dependencies: '@firebase/component': 0.7.5 '@firebase/database': 1.1.5 @@ -10009,8 +9986,8 @@ snapshots: '@firebase/util': 1.15.3 tslib: 2.8.1 optionalDependencies: - '@firebase/app': 0.16.1 - '@firebase/app-compat': 0.5.17 + '@firebase/app': 0.16.2 + '@firebase/app-compat': 0.5.18 '@firebase/database-types@1.0.22': dependencies: @@ -10027,12 +10004,12 @@ snapshots: faye-websocket: 0.11.4 tslib: 2.8.1 - '@firebase/firestore-compat@0.4.13(@firebase/app-compat@0.5.17)(@firebase/app-types@0.9.6)(@firebase/app@0.16.1)': + '@firebase/firestore-compat@0.4.14(@firebase/app-compat@0.5.18)(@firebase/app-types@0.9.6)(@firebase/app@0.16.2)': dependencies: - '@firebase/app': 0.16.1 - '@firebase/app-compat': 0.5.17 + '@firebase/app': 0.16.2 + '@firebase/app-compat': 0.5.18 '@firebase/component': 0.7.5 - '@firebase/firestore': 4.17.1(@firebase/app@0.16.1) + '@firebase/firestore': 4.17.2(@firebase/app@0.16.2) '@firebase/firestore-types': 3.0.5(@firebase/app-types@0.9.6)(@firebase/util@1.15.3) '@firebase/util': 1.15.3 tslib: 2.8.1 @@ -10044,9 +10021,9 @@ snapshots: '@firebase/app-types': 0.9.6 '@firebase/util': 1.15.3 - '@firebase/firestore@4.17.1(@firebase/app@0.16.1)': + '@firebase/firestore@4.17.2(@firebase/app@0.16.2)': dependencies: - '@firebase/app': 0.16.1 + '@firebase/app': 0.16.2 '@firebase/component': 0.7.5 '@firebase/logger': 0.5.2 '@firebase/util': 1.15.3 @@ -10056,21 +10033,21 @@ snapshots: re2js: 2.8.6 tslib: 2.8.1 - '@firebase/functions-compat@0.5.0(@firebase/app-compat@0.5.17)(@firebase/app@0.16.1)': + '@firebase/functions-compat@0.5.0(@firebase/app-compat@0.5.18)(@firebase/app@0.16.2)': dependencies: - '@firebase/app': 0.16.1 - '@firebase/app-compat': 0.5.17 + '@firebase/app': 0.16.2 + '@firebase/app-compat': 0.5.18 '@firebase/component': 0.7.5 - '@firebase/functions': 0.14.0(@firebase/app@0.16.1) + '@firebase/functions': 0.14.0(@firebase/app@0.16.2) '@firebase/functions-types': 0.6.5 '@firebase/util': 1.15.3 tslib: 2.8.1 '@firebase/functions-types@0.6.5': {} - '@firebase/functions@0.14.0(@firebase/app@0.16.1)': + '@firebase/functions@0.14.0(@firebase/app@0.16.2)': dependencies: - '@firebase/app': 0.16.1 + '@firebase/app': 0.16.2 '@firebase/app-check-interop-types': 0.3.5 '@firebase/auth-interop-types': 0.2.6 '@firebase/component': 0.7.5 @@ -10078,12 +10055,12 @@ snapshots: '@firebase/util': 1.15.3 tslib: 2.8.1 - '@firebase/installations-compat@0.2.24(@firebase/app-compat@0.5.17)(@firebase/app-types@0.9.6)(@firebase/app@0.16.1)': + '@firebase/installations-compat@0.2.24(@firebase/app-compat@0.5.18)(@firebase/app-types@0.9.6)(@firebase/app@0.16.2)': dependencies: - '@firebase/app': 0.16.1 - '@firebase/app-compat': 0.5.17 + '@firebase/app': 0.16.2 + '@firebase/app-compat': 0.5.18 '@firebase/component': 0.7.5 - '@firebase/installations': 0.6.24(@firebase/app@0.16.1) + '@firebase/installations': 0.6.24(@firebase/app@0.16.2) '@firebase/installations-types': 0.5.5(@firebase/app-types@0.9.6) '@firebase/util': 1.15.3 tslib: 2.8.1 @@ -10094,9 +10071,9 @@ snapshots: dependencies: '@firebase/app-types': 0.9.6 - '@firebase/installations@0.6.24(@firebase/app@0.16.1)': + '@firebase/installations@0.6.24(@firebase/app@0.16.2)': dependencies: - '@firebase/app': 0.16.1 + '@firebase/app': 0.16.2 '@firebase/component': 0.7.5 '@firebase/util': 1.15.3 idb: 7.1.1 @@ -10106,78 +10083,78 @@ snapshots: dependencies: tslib: 2.8.1 - '@firebase/messaging-compat@0.2.29(@firebase/app-compat@0.5.17)(@firebase/app@0.16.1)': + '@firebase/messaging-compat@0.2.30(@firebase/app-compat@0.5.18)(@firebase/app@0.16.2)': dependencies: - '@firebase/app': 0.16.1 - '@firebase/app-compat': 0.5.17 + '@firebase/app': 0.16.2 + '@firebase/app-compat': 0.5.18 '@firebase/component': 0.7.5 - '@firebase/messaging': 0.13.2(@firebase/app@0.16.1) + '@firebase/messaging': 0.13.3(@firebase/app@0.16.2) '@firebase/util': 1.15.3 tslib: 2.8.1 '@firebase/messaging-interop-types@0.2.6': {} - '@firebase/messaging@0.13.2(@firebase/app@0.16.1)': + '@firebase/messaging@0.13.3(@firebase/app@0.16.2)': dependencies: - '@firebase/app': 0.16.1 + '@firebase/app': 0.16.2 '@firebase/component': 0.7.5 - '@firebase/installations': 0.6.24(@firebase/app@0.16.1) + '@firebase/installations': 0.6.24(@firebase/app@0.16.2) '@firebase/messaging-interop-types': 0.2.6 '@firebase/util': 1.15.3 idb: 7.1.1 tslib: 2.8.1 - '@firebase/performance-compat@0.2.27(@firebase/app-compat@0.5.17)(@firebase/app@0.16.1)': + '@firebase/performance-compat@0.2.27(@firebase/app-compat@0.5.18)(@firebase/app@0.16.2)': dependencies: - '@firebase/app': 0.16.1 - '@firebase/app-compat': 0.5.17 + '@firebase/app': 0.16.2 + '@firebase/app-compat': 0.5.18 '@firebase/component': 0.7.5 '@firebase/logger': 0.5.2 - '@firebase/performance': 0.7.14(@firebase/app@0.16.1) + '@firebase/performance': 0.7.14(@firebase/app@0.16.2) '@firebase/performance-types': 0.2.5 '@firebase/util': 1.15.3 tslib: 2.8.1 '@firebase/performance-types@0.2.5': {} - '@firebase/performance@0.7.14(@firebase/app@0.16.1)': + '@firebase/performance@0.7.14(@firebase/app@0.16.2)': dependencies: - '@firebase/app': 0.16.1 + '@firebase/app': 0.16.2 '@firebase/component': 0.7.5 - '@firebase/installations': 0.6.24(@firebase/app@0.16.1) + '@firebase/installations': 0.6.24(@firebase/app@0.16.2) '@firebase/logger': 0.5.2 '@firebase/util': 1.15.3 tslib: 2.8.1 web-vitals: 4.2.4 - '@firebase/remote-config-compat@0.2.29(@firebase/app-compat@0.5.17)(@firebase/app@0.16.1)': + '@firebase/remote-config-compat@0.2.29(@firebase/app-compat@0.5.18)(@firebase/app@0.16.2)': dependencies: - '@firebase/app': 0.16.1 - '@firebase/app-compat': 0.5.17 + '@firebase/app': 0.16.2 + '@firebase/app-compat': 0.5.18 '@firebase/component': 0.7.5 '@firebase/logger': 0.5.2 - '@firebase/remote-config': 0.9.2(@firebase/app@0.16.1) + '@firebase/remote-config': 0.9.2(@firebase/app@0.16.2) '@firebase/remote-config-types': 0.5.2 '@firebase/util': 1.15.3 tslib: 2.8.1 '@firebase/remote-config-types@0.5.2': {} - '@firebase/remote-config@0.9.2(@firebase/app@0.16.1)': + '@firebase/remote-config@0.9.2(@firebase/app@0.16.2)': dependencies: - '@firebase/app': 0.16.1 + '@firebase/app': 0.16.2 '@firebase/component': 0.7.5 - '@firebase/installations': 0.6.24(@firebase/app@0.16.1) + '@firebase/installations': 0.6.24(@firebase/app@0.16.2) '@firebase/logger': 0.5.2 '@firebase/util': 1.15.3 tslib: 2.8.1 - '@firebase/storage-compat@0.4.5(@firebase/app-compat@0.5.17)(@firebase/app-types@0.9.6)(@firebase/app@0.16.1)': + '@firebase/storage-compat@0.4.5(@firebase/app-compat@0.5.18)(@firebase/app-types@0.9.6)(@firebase/app@0.16.2)': dependencies: - '@firebase/app': 0.16.1 - '@firebase/app-compat': 0.5.17 + '@firebase/app': 0.16.2 + '@firebase/app-compat': 0.5.18 '@firebase/component': 0.7.5 - '@firebase/storage': 0.14.5(@firebase/app@0.16.1) + '@firebase/storage': 0.14.5(@firebase/app@0.16.2) '@firebase/storage-types': 0.8.5(@firebase/app-types@0.9.6)(@firebase/util@1.15.3) '@firebase/util': 1.15.3 tslib: 2.8.1 @@ -10189,9 +10166,9 @@ snapshots: '@firebase/app-types': 0.9.6 '@firebase/util': 1.15.3 - '@firebase/storage@0.14.5(@firebase/app@0.16.1)': + '@firebase/storage@0.14.5(@firebase/app@0.16.2)': dependencies: - '@firebase/app': 0.16.1 + '@firebase/app': 0.16.2 '@firebase/component': 0.7.5 '@firebase/util': 1.15.3 tslib: 2.8.1 @@ -10263,7 +10240,7 @@ snapshots: transitivePeerDependencies: - supports-color - '@google/genai@2.20.0(bufferutil@4.1.0)(supports-color@11.0.0)(utf-8-validate@6.0.6)': + '@google/genai@2.22.0(bufferutil@4.1.0)(supports-color@11.0.0)(utf-8-validate@6.0.6)': dependencies: google-auth-library: 10.9.1(supports-color@11.0.0) p-retry: 4.6.2 @@ -10328,14 +10305,14 @@ snapshots: optionalDependencies: '@types/node': 22.20.2 - '@inquirer/checkbox@5.2.5(@types/node@24.13.3)': + '@inquirer/checkbox@5.2.5(@types/node@24.13.5)': dependencies: '@inquirer/ansi': 2.0.8 - '@inquirer/core': 12.0.3(@types/node@24.13.3) + '@inquirer/core': 12.0.3(@types/node@24.13.5) '@inquirer/figures': 2.0.9 - '@inquirer/type': 4.1.1(@types/node@24.13.3) + '@inquirer/type': 4.1.1(@types/node@24.13.5) optionalDependencies: - '@types/node': 24.13.3 + '@types/node': 24.13.5 '@inquirer/confirm@6.3.2(@types/node@22.20.2)': dependencies: @@ -10344,12 +10321,12 @@ snapshots: optionalDependencies: '@types/node': 22.20.2 - '@inquirer/confirm@6.3.2(@types/node@24.13.3)': + '@inquirer/confirm@6.3.2(@types/node@24.13.5)': dependencies: - '@inquirer/core': 12.0.3(@types/node@24.13.3) - '@inquirer/type': 4.1.1(@types/node@24.13.3) + '@inquirer/core': 12.0.3(@types/node@24.13.5) + '@inquirer/type': 4.1.1(@types/node@24.13.5) optionalDependencies: - '@types/node': 24.13.3 + '@types/node': 24.13.5 '@inquirer/core@12.0.3(@types/node@22.20.2)': dependencies: @@ -10363,17 +10340,17 @@ snapshots: optionalDependencies: '@types/node': 22.20.2 - '@inquirer/core@12.0.3(@types/node@24.13.3)': + '@inquirer/core@12.0.3(@types/node@24.13.5)': dependencies: '@inquirer/ansi': 2.0.8 '@inquirer/figures': 2.0.9 - '@inquirer/type': 4.1.1(@types/node@24.13.3) + '@inquirer/type': 4.1.1(@types/node@24.13.5) cli-width: 4.1.0 fast-wrap-ansi: 0.2.2 mute-stream: 3.0.0 signal-exit: 4.1.0 optionalDependencies: - '@types/node': 24.13.3 + '@types/node': 24.13.5 '@inquirer/editor@5.3.3(@types/node@22.20.2)': dependencies: @@ -10383,13 +10360,13 @@ snapshots: optionalDependencies: '@types/node': 22.20.2 - '@inquirer/editor@5.3.3(@types/node@24.13.3)': + '@inquirer/editor@5.3.3(@types/node@24.13.5)': dependencies: - '@inquirer/core': 12.0.3(@types/node@24.13.3) - '@inquirer/external-editor': 3.0.5(@types/node@24.13.3) - '@inquirer/type': 4.1.1(@types/node@24.13.3) + '@inquirer/core': 12.0.3(@types/node@24.13.5) + '@inquirer/external-editor': 3.0.5(@types/node@24.13.5) + '@inquirer/type': 4.1.1(@types/node@24.13.5) optionalDependencies: - '@types/node': 24.13.3 + '@types/node': 24.13.5 '@inquirer/expand@5.1.5(@types/node@22.20.2)': dependencies: @@ -10398,12 +10375,12 @@ snapshots: optionalDependencies: '@types/node': 22.20.2 - '@inquirer/expand@5.1.5(@types/node@24.13.3)': + '@inquirer/expand@5.1.5(@types/node@24.13.5)': dependencies: - '@inquirer/core': 12.0.3(@types/node@24.13.3) - '@inquirer/type': 4.1.1(@types/node@24.13.3) + '@inquirer/core': 12.0.3(@types/node@24.13.5) + '@inquirer/type': 4.1.1(@types/node@24.13.5) optionalDependencies: - '@types/node': 24.13.3 + '@types/node': 24.13.5 '@inquirer/external-editor@3.0.5(@types/node@22.20.2)': dependencies: @@ -10412,12 +10389,12 @@ snapshots: optionalDependencies: '@types/node': 22.20.2 - '@inquirer/external-editor@3.0.5(@types/node@24.13.3)': + '@inquirer/external-editor@3.0.5(@types/node@24.13.5)': dependencies: chardet: 2.2.0 iconv-lite: 0.7.3 optionalDependencies: - '@types/node': 24.13.3 + '@types/node': 24.13.5 '@inquirer/figures@2.0.9': {} @@ -10428,12 +10405,12 @@ snapshots: optionalDependencies: '@types/node': 22.20.2 - '@inquirer/input@5.1.6(@types/node@24.13.3)': + '@inquirer/input@5.1.6(@types/node@24.13.5)': dependencies: - '@inquirer/core': 12.0.3(@types/node@24.13.3) - '@inquirer/type': 4.1.1(@types/node@24.13.3) + '@inquirer/core': 12.0.3(@types/node@24.13.5) + '@inquirer/type': 4.1.1(@types/node@24.13.5) optionalDependencies: - '@types/node': 24.13.3 + '@types/node': 24.13.5 '@inquirer/number@4.2.3(@types/node@22.20.2)': dependencies: @@ -10442,12 +10419,12 @@ snapshots: optionalDependencies: '@types/node': 22.20.2 - '@inquirer/number@4.2.3(@types/node@24.13.3)': + '@inquirer/number@4.2.3(@types/node@24.13.5)': dependencies: - '@inquirer/core': 12.0.3(@types/node@24.13.3) - '@inquirer/type': 4.1.1(@types/node@24.13.3) + '@inquirer/core': 12.0.3(@types/node@24.13.5) + '@inquirer/type': 4.1.1(@types/node@24.13.5) optionalDependencies: - '@types/node': 24.13.3 + '@types/node': 24.13.5 '@inquirer/password@5.2.2(@types/node@22.20.2)': dependencies: @@ -10457,28 +10434,13 @@ snapshots: optionalDependencies: '@types/node': 22.20.2 - '@inquirer/password@5.2.2(@types/node@24.13.3)': + '@inquirer/password@5.2.2(@types/node@24.13.5)': dependencies: '@inquirer/ansi': 2.0.8 - '@inquirer/core': 12.0.3(@types/node@24.13.3) - '@inquirer/type': 4.1.1(@types/node@24.13.3) + '@inquirer/core': 12.0.3(@types/node@24.13.5) + '@inquirer/type': 4.1.1(@types/node@24.13.5) optionalDependencies: - '@types/node': 24.13.3 - - '@inquirer/prompts@8.7.0(@types/node@24.13.3)': - dependencies: - '@inquirer/checkbox': 5.2.5(@types/node@24.13.3) - '@inquirer/confirm': 6.3.2(@types/node@24.13.3) - '@inquirer/editor': 5.3.3(@types/node@24.13.3) - '@inquirer/expand': 5.1.5(@types/node@24.13.3) - '@inquirer/input': 5.1.6(@types/node@24.13.3) - '@inquirer/number': 4.2.3(@types/node@24.13.3) - '@inquirer/password': 5.2.2(@types/node@24.13.3) - '@inquirer/rawlist': 5.3.5(@types/node@24.13.3) - '@inquirer/search': 4.3.3(@types/node@24.13.3) - '@inquirer/select': 5.2.5(@types/node@24.13.3) - optionalDependencies: - '@types/node': 24.13.3 + '@types/node': 24.13.5 '@inquirer/prompts@8.7.2(@types/node@22.20.2)': dependencies: @@ -10495,6 +10457,21 @@ snapshots: optionalDependencies: '@types/node': 22.20.2 + '@inquirer/prompts@8.7.2(@types/node@24.13.5)': + dependencies: + '@inquirer/checkbox': 5.2.5(@types/node@24.13.5) + '@inquirer/confirm': 6.3.2(@types/node@24.13.5) + '@inquirer/editor': 5.3.3(@types/node@24.13.5) + '@inquirer/expand': 5.1.5(@types/node@24.13.5) + '@inquirer/input': 5.1.6(@types/node@24.13.5) + '@inquirer/number': 4.2.3(@types/node@24.13.5) + '@inquirer/password': 5.2.2(@types/node@24.13.5) + '@inquirer/rawlist': 5.3.5(@types/node@24.13.5) + '@inquirer/search': 4.3.3(@types/node@24.13.5) + '@inquirer/select': 5.2.5(@types/node@24.13.5) + optionalDependencies: + '@types/node': 24.13.5 + '@inquirer/rawlist@5.3.5(@types/node@22.20.2)': dependencies: '@inquirer/core': 12.0.3(@types/node@22.20.2) @@ -10502,12 +10479,12 @@ snapshots: optionalDependencies: '@types/node': 22.20.2 - '@inquirer/rawlist@5.3.5(@types/node@24.13.3)': + '@inquirer/rawlist@5.3.5(@types/node@24.13.5)': dependencies: - '@inquirer/core': 12.0.3(@types/node@24.13.3) - '@inquirer/type': 4.1.1(@types/node@24.13.3) + '@inquirer/core': 12.0.3(@types/node@24.13.5) + '@inquirer/type': 4.1.1(@types/node@24.13.5) optionalDependencies: - '@types/node': 24.13.3 + '@types/node': 24.13.5 '@inquirer/search@4.3.3(@types/node@22.20.2)': dependencies: @@ -10517,13 +10494,13 @@ snapshots: optionalDependencies: '@types/node': 22.20.2 - '@inquirer/search@4.3.3(@types/node@24.13.3)': + '@inquirer/search@4.3.3(@types/node@24.13.5)': dependencies: - '@inquirer/core': 12.0.3(@types/node@24.13.3) + '@inquirer/core': 12.0.3(@types/node@24.13.5) '@inquirer/figures': 2.0.9 - '@inquirer/type': 4.1.1(@types/node@24.13.3) + '@inquirer/type': 4.1.1(@types/node@24.13.5) optionalDependencies: - '@types/node': 24.13.3 + '@types/node': 24.13.5 '@inquirer/select@5.2.5(@types/node@22.20.2)': dependencies: @@ -10534,26 +10511,22 @@ snapshots: optionalDependencies: '@types/node': 22.20.2 - '@inquirer/select@5.2.5(@types/node@24.13.3)': + '@inquirer/select@5.2.5(@types/node@24.13.5)': dependencies: '@inquirer/ansi': 2.0.8 - '@inquirer/core': 12.0.3(@types/node@24.13.3) + '@inquirer/core': 12.0.3(@types/node@24.13.5) '@inquirer/figures': 2.0.9 - '@inquirer/type': 4.1.1(@types/node@24.13.3) + '@inquirer/type': 4.1.1(@types/node@24.13.5) optionalDependencies: - '@types/node': 24.13.3 - - '@inquirer/type@4.1.0(@types/node@24.13.3)': - optionalDependencies: - '@types/node': 24.13.3 + '@types/node': 24.13.5 '@inquirer/type@4.1.1(@types/node@22.20.2)': optionalDependencies: '@types/node': 22.20.2 - '@inquirer/type@4.1.1(@types/node@24.13.3)': + '@inquirer/type@4.1.1(@types/node@24.13.5)': optionalDependencies: - '@types/node': 24.13.3 + '@types/node': 24.13.5 '@isaacs/cliui@8.0.2': dependencies: @@ -11636,7 +11609,7 @@ snapshots: dependencies: undici-types: 6.21.0 - '@types/node@24.13.3': + '@types/node@24.13.5': dependencies: undici-types: 7.18.2 @@ -13649,35 +13622,35 @@ snapshots: locate-path: 6.0.0 path-exists: 4.0.0 - firebase@12.18.0: + firebase@12.19.0: dependencies: - '@firebase/ai': 2.15.0(@firebase/app-types@0.9.6)(@firebase/app@0.16.1) - '@firebase/analytics': 0.10.24(@firebase/app@0.16.1) - '@firebase/analytics-compat': 0.2.30(@firebase/app-compat@0.5.17)(@firebase/app@0.16.1) - '@firebase/app': 0.16.1 - '@firebase/app-check': 0.13.1(@firebase/app@0.16.1) - '@firebase/app-check-compat': 0.4.7(@firebase/app-compat@0.5.17)(@firebase/app@0.16.1) - '@firebase/app-compat': 0.5.17 + '@firebase/ai': 2.16.0(@firebase/app-types@0.9.6)(@firebase/app@0.16.2) + '@firebase/analytics': 0.10.25(@firebase/app@0.16.2) + '@firebase/analytics-compat': 0.2.31(@firebase/app-compat@0.5.18)(@firebase/app@0.16.2) + '@firebase/app': 0.16.2 + '@firebase/app-check': 0.13.1(@firebase/app@0.16.2) + '@firebase/app-check-compat': 0.4.7(@firebase/app-compat@0.5.18)(@firebase/app@0.16.2) + '@firebase/app-compat': 0.5.18 '@firebase/app-types': 0.9.6 - '@firebase/auth': 1.13.5(@firebase/app@0.16.1) - '@firebase/auth-compat': 0.6.10(@firebase/app-compat@0.5.17)(@firebase/app-types@0.9.6)(@firebase/app@0.16.1) - '@firebase/data-connect': 0.7.4(@firebase/app@0.16.1) + '@firebase/auth': 1.13.6(@firebase/app@0.16.2) + '@firebase/auth-compat': 0.6.11(@firebase/app-compat@0.5.18)(@firebase/app-types@0.9.6)(@firebase/app@0.16.2) + '@firebase/data-connect': 0.7.4(@firebase/app@0.16.2) '@firebase/database': 1.1.5 - '@firebase/database-compat': 2.1.7(@firebase/app-compat@0.5.17)(@firebase/app@0.16.1) - '@firebase/firestore': 4.17.1(@firebase/app@0.16.1) - '@firebase/firestore-compat': 0.4.13(@firebase/app-compat@0.5.17)(@firebase/app-types@0.9.6)(@firebase/app@0.16.1) - '@firebase/functions': 0.14.0(@firebase/app@0.16.1) - '@firebase/functions-compat': 0.5.0(@firebase/app-compat@0.5.17)(@firebase/app@0.16.1) - '@firebase/installations': 0.6.24(@firebase/app@0.16.1) - '@firebase/installations-compat': 0.2.24(@firebase/app-compat@0.5.17)(@firebase/app-types@0.9.6)(@firebase/app@0.16.1) - '@firebase/messaging': 0.13.2(@firebase/app@0.16.1) - '@firebase/messaging-compat': 0.2.29(@firebase/app-compat@0.5.17)(@firebase/app@0.16.1) - '@firebase/performance': 0.7.14(@firebase/app@0.16.1) - '@firebase/performance-compat': 0.2.27(@firebase/app-compat@0.5.17)(@firebase/app@0.16.1) - '@firebase/remote-config': 0.9.2(@firebase/app@0.16.1) - '@firebase/remote-config-compat': 0.2.29(@firebase/app-compat@0.5.17)(@firebase/app@0.16.1) - '@firebase/storage': 0.14.5(@firebase/app@0.16.1) - '@firebase/storage-compat': 0.4.5(@firebase/app-compat@0.5.17)(@firebase/app-types@0.9.6)(@firebase/app@0.16.1) + '@firebase/database-compat': 2.1.7(@firebase/app-compat@0.5.18)(@firebase/app@0.16.2) + '@firebase/firestore': 4.17.2(@firebase/app@0.16.2) + '@firebase/firestore-compat': 0.4.14(@firebase/app-compat@0.5.18)(@firebase/app-types@0.9.6)(@firebase/app@0.16.2) + '@firebase/functions': 0.14.0(@firebase/app@0.16.2) + '@firebase/functions-compat': 0.5.0(@firebase/app-compat@0.5.18)(@firebase/app@0.16.2) + '@firebase/installations': 0.6.24(@firebase/app@0.16.2) + '@firebase/installations-compat': 0.2.24(@firebase/app-compat@0.5.18)(@firebase/app-types@0.9.6)(@firebase/app@0.16.2) + '@firebase/messaging': 0.13.3(@firebase/app@0.16.2) + '@firebase/messaging-compat': 0.2.30(@firebase/app-compat@0.5.18)(@firebase/app@0.16.2) + '@firebase/performance': 0.7.14(@firebase/app@0.16.2) + '@firebase/performance-compat': 0.2.27(@firebase/app-compat@0.5.18)(@firebase/app@0.16.2) + '@firebase/remote-config': 0.9.2(@firebase/app@0.16.2) + '@firebase/remote-config-compat': 0.2.29(@firebase/app-compat@0.5.18)(@firebase/app@0.16.2) + '@firebase/storage': 0.14.5(@firebase/app@0.16.2) + '@firebase/storage-compat': 0.4.5(@firebase/app-compat@0.5.18)(@firebase/app-types@0.9.6)(@firebase/app@0.16.2) '@firebase/util': 1.15.3 transitivePeerDependencies: - '@react-native-async-storage/async-storage' @@ -17334,8 +17307,6 @@ snapshots: yallist@3.1.1: {} - yaml@2.9.0: {} - yaml@2.9.1: {} yargs-parser@20.2.9: {} diff --git a/tests/e2e/ng-snapshot/package.json b/tests/e2e/ng-snapshot/package.json index f424fe017d74..53a12d9add6c 100644 --- a/tests/e2e/ng-snapshot/package.json +++ b/tests/e2e/ng-snapshot/package.json @@ -2,21 +2,21 @@ "description": "snapshot versions of Angular for e2e testing", "private": true, "dependencies": { - "@angular/animations": "github:angular/animations-builds#7bed8f1be7bb346ec00a8095bd05a6277b7dcc87", - "@angular/cdk": "github:angular/cdk-builds#549227973881b56e660ac023c27923c283b9af94", - "@angular/common": "github:angular/common-builds#8dd45020d575fefcf98d5c72fb391532ce197274", - "@angular/compiler": "github:angular/compiler-builds#8d600612ab702d6a2f71603e6a5ff87edd3a04df", - "@angular/compiler-cli": "github:angular/compiler-cli-builds#632d579c8c9990d2110e2eb868a288da313bf907", - "@angular/core": "github:angular/core-builds#de42b59315d8056af6f03de90b2b976134a4a1df", - "@angular/forms": "github:angular/forms-builds#14ee0386670ac721d4db077c3c94a24683facfd0", - "@angular/language-service": "github:angular/language-service-builds#bebb5d27849b07375f97d67a4dbdef344787ffd7", - "@angular/localize": "github:angular/localize-builds#bb42829b66295a8e0d6c5fd7ad74381dc5cd566a", - "@angular/material": "github:angular/material-builds#f71c66098b73e5c4881e776cc1f781a0fad14ecb", - "@angular/material-moment-adapter": "github:angular/material-moment-adapter-builds#1d6c8bc8e153ce415ac69c1967eb4fe6f7f2ee20", - "@angular/platform-browser": "github:angular/platform-browser-builds#a5d0e51ccf0cea4774c4f16f59305792e495dde7", - "@angular/platform-browser-dynamic": "github:angular/platform-browser-dynamic-builds#a17081a0752b8578c458790480970ea1a4a89e78", - "@angular/platform-server": "github:angular/platform-server-builds#6289b867993c4555cebfd2e2d99bce1d65c780ef", - "@angular/router": "github:angular/router-builds#22872f4b8aa692b63bb3a77cf5d8252dbe12b6aa", - "@angular/service-worker": "github:angular/service-worker-builds#aedb70e37e445e07b355f84265d38eb29cde1482" + "@angular/animations": "github:angular/animations-builds#3d1c250f4edacfe60355fd3133353fdb037b03df", + "@angular/cdk": "github:angular/cdk-builds#1ce55365568b0b1be4d17e9040d5d846f7b414d8", + "@angular/common": "github:angular/common-builds#de1e477d0c03e9bf626f7ab62d5446b9f6f37e87", + "@angular/compiler": "github:angular/compiler-builds#f79a1335c78a63896769fa5818d0566cf84b37fc", + "@angular/compiler-cli": "github:angular/compiler-cli-builds#2807f37e39aece8f0abdbb6104da7e005199f56d", + "@angular/core": "github:angular/core-builds#50463c19a9bddb492112ceb8a549a6724b6378ba", + "@angular/forms": "github:angular/forms-builds#f9b2189afac1130d800634a02d3758e3c1998894", + "@angular/language-service": "github:angular/language-service-builds#2dabb85c3b136eee41d191d6434731e422217ab0", + "@angular/localize": "github:angular/localize-builds#34cbcda2d4a59c3586ffcff6f66cb203fb9e470f", + "@angular/material": "github:angular/material-builds#ddde2cfce1af33b5274b93d5d7d542bdc6bca22c", + "@angular/material-moment-adapter": "github:angular/material-moment-adapter-builds#174487e1cd9237dbf14cbdfea84bb5a08562b2be", + "@angular/platform-browser": "github:angular/platform-browser-builds#61d8e66aa018e1f8e5d3bb890aea3ea8d62560c5", + "@angular/platform-browser-dynamic": "github:angular/platform-browser-dynamic-builds#f4fe6bc35c19f408fc5b92fcbfb1e6c3e08c15fe", + "@angular/platform-server": "github:angular/platform-server-builds#b52d8244fc19f92aa927e2de66dcba86b98f41a3", + "@angular/router": "github:angular/router-builds#020e5395f7c0f60472d4d591da897c3d43058a8f", + "@angular/service-worker": "github:angular/service-worker-builds#70d34a6671dce54610568f2ae29395a833a2bb2e" } } From 3921ce674db5a3f951274e231ade4f8c72591760 Mon Sep 17 00:00:00 2001 From: Alan Agius <17563226+alan-agius4@users.noreply.github.com> Date: Mon, 21 Sep 2026 10:38:32 +0000 Subject: [PATCH 492/787] build: forward data and package.json to strict_deps_test Forward `data` and `package.json` to `strict_deps_test` in the `ts_project` macro. With `data` assets included in strict deps checks, the `@ts-ignore strict-deps` workarounds on markdown asset imports across CLI commands are no longer needed. --- packages/angular/cli/src/commands/add/cli.ts | 2 -- packages/angular/cli/src/commands/analytics/cli.ts | 2 -- packages/angular/cli/src/commands/build/cli.ts | 2 -- packages/angular/cli/src/commands/cache/cli.ts | 2 -- packages/angular/cli/src/commands/completion/cli.ts | 2 -- packages/angular/cli/src/commands/config/cli.ts | 2 -- packages/angular/cli/src/commands/deploy/cli.ts | 2 -- packages/angular/cli/src/commands/lint/cli.ts | 2 -- packages/angular/cli/src/commands/new/cli.ts | 2 -- packages/angular/cli/src/commands/run/cli.ts | 2 -- packages/angular/cli/src/commands/test/cli.ts | 2 -- packages/angular/cli/src/commands/update/cli.ts | 2 -- tools/defaults.bzl | 6 ++++++ 13 files changed, 6 insertions(+), 24 deletions(-) diff --git a/packages/angular/cli/src/commands/add/cli.ts b/packages/angular/cli/src/commands/add/cli.ts index fb352f70edfd..d7efd10906d9 100644 --- a/packages/angular/cli/src/commands/add/cli.ts +++ b/packages/angular/cli/src/commands/add/cli.ts @@ -29,8 +29,6 @@ import { NgAddSaveDependency, PackageManifest, PackageMetadata } from '../../pac import { assertIsError } from '../../utilities/error'; import { isTTY } from '../../utilities/tty'; import { VERSION } from '../../utilities/version'; -// eslint-disable-next-line @typescript-eslint/ban-ts-comment -// @ts-ignore strict-deps: Markdown files are asset dependencies bundled/loaded at runtime import longDescription from './long-description.md'; class CommandError extends Error {} diff --git a/packages/angular/cli/src/commands/analytics/cli.ts b/packages/angular/cli/src/commands/analytics/cli.ts index 9639cbab50e6..bcd67b0bba45 100644 --- a/packages/angular/cli/src/commands/analytics/cli.ts +++ b/packages/angular/cli/src/commands/analytics/cli.ts @@ -17,8 +17,6 @@ import { demandCommandFailureMessage, } from '../../command-builder/utilities/command'; import { AnalyticsInfoCommandModule } from './info/cli'; -// eslint-disable-next-line @typescript-eslint/ban-ts-comment -// @ts-ignore strict-deps: Markdown files are asset dependencies bundled/loaded at runtime import longDescription from './long-description.md'; import { AnalyticsDisableModule, diff --git a/packages/angular/cli/src/commands/build/cli.ts b/packages/angular/cli/src/commands/build/cli.ts index 031e31b5140f..c722f70709e3 100644 --- a/packages/angular/cli/src/commands/build/cli.ts +++ b/packages/angular/cli/src/commands/build/cli.ts @@ -9,8 +9,6 @@ import { ArchitectCommandModule } from '../../command-builder/architect-command-module'; import { CommandModuleImplementation } from '../../command-builder/command-module'; import { RootCommands } from '../command-config'; -// eslint-disable-next-line @typescript-eslint/ban-ts-comment -// @ts-ignore strict-deps: Markdown files are asset dependencies bundled/loaded at runtime import longDescription from './long-description.md'; export default class BuildCommandModule diff --git a/packages/angular/cli/src/commands/cache/cli.ts b/packages/angular/cli/src/commands/cache/cli.ts index 25140041ae0e..4ce2b7ebd1e4 100644 --- a/packages/angular/cli/src/commands/cache/cli.ts +++ b/packages/angular/cli/src/commands/cache/cli.ts @@ -19,8 +19,6 @@ import { } from '../../command-builder/utilities/command'; import { CacheCleanModule } from './clean/cli'; import { CacheInfoCommandModule } from './info/cli'; -// eslint-disable-next-line @typescript-eslint/ban-ts-comment -// @ts-ignore strict-deps: Markdown files are asset dependencies bundled/loaded at runtime import longDescription from './long-description.md'; import { CacheDisableModule, CacheEnableModule } from './settings/cli'; diff --git a/packages/angular/cli/src/commands/completion/cli.ts b/packages/angular/cli/src/commands/completion/cli.ts index ab81ce5636d8..5b7bc066e577 100644 --- a/packages/angular/cli/src/commands/completion/cli.ts +++ b/packages/angular/cli/src/commands/completion/cli.ts @@ -12,8 +12,6 @@ import { addCommandModuleToYargs } from '../../command-builder/utilities/command import { colors } from '../../utilities/color'; import { hasGlobalCliInstall, initializeAutocomplete } from '../../utilities/completion'; import { assertIsError } from '../../utilities/error'; -// eslint-disable-next-line @typescript-eslint/ban-ts-comment -// @ts-ignore strict-deps: Markdown files are asset dependencies bundled/loaded at runtime import longDescription from './long-description.md'; export default class CompletionCommandModule diff --git a/packages/angular/cli/src/commands/config/cli.ts b/packages/angular/cli/src/commands/config/cli.ts index f339fd9bb1ba..ae25f3839e22 100644 --- a/packages/angular/cli/src/commands/config/cli.ts +++ b/packages/angular/cli/src/commands/config/cli.ts @@ -17,8 +17,6 @@ import { } from '../../command-builder/command-module'; import { getWorkspaceRaw, validateWorkspace } from '../../utilities/config'; import { JSONFile, parseJson } from '../../utilities/json-file'; -// eslint-disable-next-line @typescript-eslint/ban-ts-comment -// @ts-ignore strict-deps: Markdown files are asset dependencies bundled/loaded at runtime import longDescription from './long-description.md'; interface ConfigCommandArgs { diff --git a/packages/angular/cli/src/commands/deploy/cli.ts b/packages/angular/cli/src/commands/deploy/cli.ts index 28317cff1ee1..fb305c94aaf1 100644 --- a/packages/angular/cli/src/commands/deploy/cli.ts +++ b/packages/angular/cli/src/commands/deploy/cli.ts @@ -9,8 +9,6 @@ import { MissingTargetChoice } from '../../command-builder/architect-base-command-module'; import { ArchitectCommandModule } from '../../command-builder/architect-command-module'; import { CommandModuleImplementation } from '../../command-builder/command-module'; -// eslint-disable-next-line @typescript-eslint/ban-ts-comment -// @ts-ignore strict-deps: Markdown files are asset dependencies bundled/loaded at runtime import longDescription from './long-description.md'; export default class DeployCommandModule diff --git a/packages/angular/cli/src/commands/lint/cli.ts b/packages/angular/cli/src/commands/lint/cli.ts index 3fdd38fc169c..dd7e7c6f193b 100644 --- a/packages/angular/cli/src/commands/lint/cli.ts +++ b/packages/angular/cli/src/commands/lint/cli.ts @@ -9,8 +9,6 @@ import { MissingTargetChoice } from '../../command-builder/architect-base-command-module'; import { ArchitectCommandModule } from '../../command-builder/architect-command-module'; import { CommandModuleImplementation } from '../../command-builder/command-module'; -// eslint-disable-next-line @typescript-eslint/ban-ts-comment -// @ts-ignore strict-deps: Markdown files are asset dependencies bundled/loaded at runtime import longDescription from './long-description.md'; export default class LintCommandModule diff --git a/packages/angular/cli/src/commands/new/cli.ts b/packages/angular/cli/src/commands/new/cli.ts index c47f3c63153b..a873fefeefe0 100644 --- a/packages/angular/cli/src/commands/new/cli.ts +++ b/packages/angular/cli/src/commands/new/cli.ts @@ -20,8 +20,6 @@ import { } from '../../command-builder/schematics-command-module'; import { VERSION } from '../../utilities/version'; import { RootCommands } from '../command-config'; -// eslint-disable-next-line @typescript-eslint/ban-ts-comment -// @ts-ignore strict-deps: Markdown files are asset dependencies bundled/loaded at runtime import longDescription from './long-description.md'; interface NewCommandArgs extends SchematicsCommandArgs { diff --git a/packages/angular/cli/src/commands/run/cli.ts b/packages/angular/cli/src/commands/run/cli.ts index 774f811aa2a5..134910ef2885 100644 --- a/packages/angular/cli/src/commands/run/cli.ts +++ b/packages/angular/cli/src/commands/run/cli.ts @@ -16,8 +16,6 @@ import { Options, OtherOptions, } from '../../command-builder/command-module'; -// eslint-disable-next-line @typescript-eslint/ban-ts-comment -// @ts-ignore strict-deps: Markdown files are asset dependencies bundled/loaded at runtime import longDescription from './long-description.md'; export interface RunCommandArgs { diff --git a/packages/angular/cli/src/commands/test/cli.ts b/packages/angular/cli/src/commands/test/cli.ts index f9dcaaf92c8c..c08789714c1c 100644 --- a/packages/angular/cli/src/commands/test/cli.ts +++ b/packages/angular/cli/src/commands/test/cli.ts @@ -9,8 +9,6 @@ import { ArchitectCommandModule } from '../../command-builder/architect-command-module'; import { CommandModuleImplementation } from '../../command-builder/command-module'; import { RootCommands } from '../command-config'; -// eslint-disable-next-line @typescript-eslint/ban-ts-comment -// @ts-ignore strict-deps: Markdown files are asset dependencies bundled/loaded at runtime import longDescription from './long-description.md'; export default class TestCommandModule diff --git a/packages/angular/cli/src/commands/update/cli.ts b/packages/angular/cli/src/commands/update/cli.ts index 45a4468e0c85..cbe703552c9a 100644 --- a/packages/angular/cli/src/commands/update/cli.ts +++ b/packages/angular/cli/src/commands/update/cli.ts @@ -24,8 +24,6 @@ import type { InstalledPackage, PackageManager, PackageManifest } from '../../pa import { colors } from '../../utilities/color'; import { disableVersionCheck } from '../../utilities/environment-options'; import { assertIsError } from '../../utilities/error'; -// eslint-disable-next-line @typescript-eslint/ban-ts-comment -// @ts-ignore strict-deps: Markdown files are asset dependencies bundled/loaded at runtime import longDescription from './long-description.md'; import { UpdatePlan, diff --git a/tools/defaults.bzl b/tools/defaults.bzl index dd054c9c1462..20153614ac80 100644 --- a/tools/defaults.bzl +++ b/tools/defaults.bzl @@ -18,6 +18,10 @@ def ts_project( if tsconfig == None: tsconfig = "//:test-tsconfig" if testonly else "//:build-tsconfig" + package_json = kwargs.pop("package_json", None) + if not package_json and native.glob(["package.json"], allow_empty = True): + package_json = "package.json" + _ts_project( name = name, testonly = testonly, @@ -32,6 +36,8 @@ def ts_project( strict_deps_test( name = "%s_strict_deps_test" % name, srcs = kwargs.get("srcs", []), + data = kwargs.get("data", []), + package_json = package_json, tsconfig = tsconfig, deps = deps, ) From eb1edeb5147adf51ef6261c04cd0c79bad9d6cd3 Mon Sep 17 00:00:00 2001 From: Alan Agius <17563226+alan-agius4@users.noreply.github.com> Date: Mon, 21 Sep 2026 09:42:58 +0000 Subject: [PATCH 493/787] refactor(@angular/build): relocate non-esbuild utilities out of tools/esbuild Relocate several utilities from `src/tools/esbuild` to more appropriate locations, as they are not specific to esbuild: - `watcher.ts`: moved to `src/utils/watcher.ts`. - `profiling.ts`: moved to `src/utils/profiling.ts`. - `cache.ts`, `sqlite-cache-store.ts`, `lmdb-cache-store.ts`: moved to `src/utils/cache/`. - `javascript-transformer.ts`, `javascript-transformer-worker.ts`: moved to `src/tools/javascript-transformer/`. - `i18n-inliner.ts`, `i18n-inliner-worker.ts`, `i18n-translation-*`: moved to `src/tools/i18n/`, with locale data helpers in `src/tools/i18n/locale-data.ts`. - `index-html-generator.ts`: moved to `src/builders/application/index-html-generator.ts`. --- .../src/builders/application/build-action.ts | 6 +- .../src/builders/application/execute-build.ts | 2 +- .../application/execute-post-bundle.ts | 7 +- .../build/src/builders/application/i18n.ts | 2 +- .../application}/index-html-generator.ts | 8 +- .../build/src/builders/dev-server/internal.ts | 2 +- packages/angular/build/src/private.ts | 4 +- .../angular/compilation/aot-compilation.ts | 2 +- .../angular/compilation/jit-compilation.ts | 2 +- .../compilation/parallel-compilation.ts | 2 +- .../angular/compilation/parallel-worker.ts | 2 +- .../compilation/typescript-compilation.ts | 2 +- .../tools/esbuild/angular/compiler-plugin.ts | 10 +- .../esbuild/angular/component-stylesheets.ts | 2 +- .../tools/esbuild/bundler-execution-result.ts | 2 +- .../src/tools/esbuild/i18n-locale-plugin.ts | 145 ++---------------- .../esbuild/persistent-load-result-cache.ts | 2 +- .../persistent-load-result-cache_spec.ts | 2 +- .../esbuild/stylesheets/sass-language.ts | 2 +- .../{esbuild => i18n}/i18n-inliner-worker.ts | 4 +- .../tools/{esbuild => i18n}/i18n-inliner.ts | 12 +- .../{esbuild => i18n}/i18n-inliner_spec.ts | 8 +- .../i18n-translation-encoder.ts | 0 .../i18n-translation-encoder_spec.ts | 0 .../i18n-translation-reader.ts | 0 .../angular/build/src/tools/i18n/index.ts | 12 ++ .../build/src/tools/i18n/locale-data.ts | 138 +++++++++++++++++ .../src/tools/javascript-transformer/index.ts | 9 ++ .../javascript-transformer-worker.ts | 0 .../javascript-transformer.ts | 2 +- .../javascript-transformer_spec.ts | 0 .../angular/build/src/tools/vite/utils.ts | 2 +- .../{tools/esbuild => utils/cache}/cache.ts | 4 +- .../esbuild => utils/cache}/cache_spec.ts | 0 .../angular/build/src/utils/cache/index.ts | 9 ++ .../cache}/lmdb-cache-store.ts | 0 .../cache}/sqlite-cache-store.ts | 0 .../cache}/sqlite-cache-store_spec.ts | 0 .../src/{tools/esbuild => utils}/profiling.ts | 2 +- .../src/{tools/esbuild => utils}/watcher.ts | 4 +- .../{tools/esbuild => utils}/watcher_spec.ts | 0 scripts/benchmark.mts | 4 +- scripts/benchmarks/i18n/fixtures.mts | 2 +- scripts/benchmarks/i18n/scenarios.mts | 6 +- 44 files changed, 247 insertions(+), 177 deletions(-) rename packages/angular/build/src/{tools/esbuild => builders/application}/index-html-generator.ts (96%) rename packages/angular/build/src/tools/{esbuild => i18n}/i18n-inliner-worker.ts (99%) rename packages/angular/build/src/tools/{esbuild => i18n}/i18n-inliner.ts (99%) rename packages/angular/build/src/tools/{esbuild => i18n}/i18n-inliner_spec.ts (99%) rename packages/angular/build/src/tools/{esbuild => i18n}/i18n-translation-encoder.ts (100%) rename packages/angular/build/src/tools/{esbuild => i18n}/i18n-translation-encoder_spec.ts (100%) rename packages/angular/build/src/tools/{esbuild => i18n}/i18n-translation-reader.ts (100%) create mode 100644 packages/angular/build/src/tools/i18n/index.ts create mode 100644 packages/angular/build/src/tools/i18n/locale-data.ts create mode 100644 packages/angular/build/src/tools/javascript-transformer/index.ts rename packages/angular/build/src/tools/{esbuild => javascript-transformer}/javascript-transformer-worker.ts (100%) rename packages/angular/build/src/tools/{esbuild => javascript-transformer}/javascript-transformer.ts (99%) rename packages/angular/build/src/tools/{esbuild => javascript-transformer}/javascript-transformer_spec.ts (100%) rename packages/angular/build/src/{tools/esbuild => utils/cache}/cache.ts (98%) rename packages/angular/build/src/{tools/esbuild => utils/cache}/cache_spec.ts (100%) create mode 100644 packages/angular/build/src/utils/cache/index.ts rename packages/angular/build/src/{tools/esbuild => utils/cache}/lmdb-cache-store.ts (100%) rename packages/angular/build/src/{tools/esbuild => utils/cache}/sqlite-cache-store.ts (100%) rename packages/angular/build/src/{tools/esbuild => utils/cache}/sqlite-cache-store_spec.ts (100%) rename packages/angular/build/src/{tools/esbuild => utils}/profiling.ts (97%) rename packages/angular/build/src/{tools/esbuild => utils}/watcher.ts (99%) rename packages/angular/build/src/{tools/esbuild => utils}/watcher_spec.ts (100%) diff --git a/packages/angular/build/src/builders/application/build-action.ts b/packages/angular/build/src/builders/application/build-action.ts index 299d7cf88ef4..52e70ff87e99 100644 --- a/packages/angular/build/src/builders/application/build-action.ts +++ b/packages/angular/build/src/builders/application/build-action.ts @@ -18,9 +18,9 @@ import { shutdownSassWorkerPool, } from '../../tools/esbuild/stylesheets/sass-language'; import { logMessages, withNoProgress, withSpinner } from '../../tools/esbuild/utils'; -import { ChangedFiles } from '../../tools/esbuild/watcher'; import { initializeHash } from '../../utils/hash'; import { NormalizedCachedOptions } from '../../utils/normalize-cache'; +import { ChangedFiles } from '../../utils/watcher'; import { NormalizedApplicationBuildOptions, NormalizedOutputOptions } from './options'; import { ComponentUpdateResult, @@ -88,7 +88,7 @@ export async function* runEsBuildBuildAction( } } - let watcher: import('../../tools/esbuild/watcher').BuildWatcher | undefined; + let watcher: import('../../utils/watcher').BuildWatcher | undefined; let watchLoopStarted = false; try { // Setup watcher if watch mode enabled @@ -98,7 +98,7 @@ export async function* runEsBuildBuildAction( } // Setup a watcher - const { setupWatcher } = await import('../../tools/esbuild/watcher'); + const { setupWatcher } = await import('../../utils/watcher'); watcher = await setupWatcher({ workspaceRoot, projectRoot, diff --git a/packages/angular/build/src/builders/application/execute-build.ts b/packages/angular/build/src/builders/application/execute-build.ts index 379566e4de4d..d3b628a169e2 100644 --- a/packages/angular/build/src/builders/application/execute-build.ts +++ b/packages/angular/build/src/builders/application/execute-build.ts @@ -20,7 +20,6 @@ import { BuildOutputFileType } from '../../tools/esbuild/bundler-files'; import { checkCommonJSModules } from '../../tools/esbuild/commonjs-checker'; import { LOCALE_DATA_BASE_MODULE } from '../../tools/esbuild/i18n-locale-plugin'; import { extractLicenses } from '../../tools/esbuild/license-extractor'; -import { profileAsync } from '../../tools/esbuild/profiling'; import { transformSupportedBrowsersToTargets } from '../../tools/esbuild/target'; import { calculateEstimatedTransferSizes, @@ -29,6 +28,7 @@ import { } from '../../tools/esbuild/utils'; import { BudgetCalculatorResult, checkBudgets } from '../../utils/bundle-calculator'; import { optimizeChunksThreshold } from '../../utils/environment-options'; +import { profileAsync } from '../../utils/profiling'; import { resolveAssets } from '../../utils/resolve-assets'; import { SERVER_APP_ENGINE_MANIFEST_FILENAME, diff --git a/packages/angular/build/src/builders/application/execute-post-bundle.ts b/packages/angular/build/src/builders/application/execute-post-bundle.ts index 07639a43c3e5..99e23bcb30c9 100644 --- a/packages/angular/build/src/builders/application/execute-post-bundle.ts +++ b/packages/angular/build/src/builders/application/execute-post-bundle.ts @@ -18,18 +18,15 @@ import { type InitialFileRecord, createOutputFile, } from '../../tools/esbuild/bundler-files'; -import { generateIndexHtml } from '../../tools/esbuild/index-html-generator'; import { maxWorkers } from '../../utils/environment-options'; import { SERVER_APP_MANIFEST_FILENAME, generateAngularServerAppManifest, } from '../../utils/server-rendering/manifest'; -import { - RouteRenderMode, - WritableSerializableRouteTreeNode, -} from '../../utils/server-rendering/models'; +import { WritableSerializableRouteTreeNode } from '../../utils/server-rendering/models'; import { prerenderPages } from '../../utils/server-rendering/prerender'; import { augmentAppWithServiceWorkerEsbuild } from '../../utils/service-worker'; +import { generateIndexHtml } from './index-html-generator'; import { injectDebugIds } from './inject-debug-ids'; import { INDEX_HTML_CSR, INDEX_HTML_SERVER, NormalizedApplicationBuildOptions } from './options'; import { OutputMode } from './schema'; diff --git a/packages/angular/build/src/builders/application/i18n.ts b/packages/angular/build/src/builders/application/i18n.ts index 0d6ae77cdea7..839384421f1f 100644 --- a/packages/angular/build/src/builders/application/i18n.ts +++ b/packages/angular/build/src/builders/application/i18n.ts @@ -16,7 +16,7 @@ import { PrerenderedRoutesRecord, } from '../../tools/esbuild/bundler-execution-result'; import { BuildOutputFileType, InitialFileRecord } from '../../tools/esbuild/bundler-files'; -import { I18nInliner } from '../../tools/esbuild/i18n-inliner'; +import { I18nInliner } from '../../tools/i18n'; import { maxInlinerWorkers } from '../../utils/environment-options'; import { loadTranslations } from '../../utils/i18n-options'; import { createTranslationLoader } from '../../utils/load-translations'; diff --git a/packages/angular/build/src/tools/esbuild/index-html-generator.ts b/packages/angular/build/src/builders/application/index-html-generator.ts similarity index 96% rename from packages/angular/build/src/tools/esbuild/index-html-generator.ts rename to packages/angular/build/src/builders/application/index-html-generator.ts index a7ad3fd47e7f..d89eadf8b9b0 100644 --- a/packages/angular/build/src/tools/esbuild/index-html-generator.ts +++ b/packages/angular/build/src/builders/application/index-html-generator.ts @@ -9,9 +9,13 @@ import assert from 'node:assert'; import { createHash } from 'node:crypto'; import path from 'node:path'; -import { NormalizedApplicationBuildOptions } from '../../builders/application/options'; +import { + BuildOutputFile, + BuildOutputFileType, + InitialFileRecord, +} from '../../tools/esbuild/bundler-files'; import { IndexHtmlGenerator } from '../../utils/index-file/index-html-generator'; -import { BuildOutputFile, BuildOutputFileType, InitialFileRecord } from './bundler-files'; +import { NormalizedApplicationBuildOptions } from './options'; /** * The maximum number of module preload link elements that should be added for diff --git a/packages/angular/build/src/builders/dev-server/internal.ts b/packages/angular/build/src/builders/dev-server/internal.ts index 96587acb5cff..19ca0cf3e92e 100644 --- a/packages/angular/build/src/builders/dev-server/internal.ts +++ b/packages/angular/build/src/builders/dev-server/internal.ts @@ -8,7 +8,7 @@ export { type BuildOutputFile, BuildOutputFileType } from '../../tools/esbuild/bundler-files'; export { createRxjsEsmResolutionPlugin } from '../../tools/esbuild/rxjs-esm-resolution-plugin'; -export { JavaScriptTransformer } from '../../tools/esbuild/javascript-transformer'; +export { JavaScriptTransformer } from '../../tools/javascript-transformer'; export { getFeatureSupport, isZonelessApp } from '../../tools/esbuild/utils'; export { type IndexHtmlTransform } from '../../utils/index-file/index-html-generator'; export { purgeStaleBuildCache } from '../../utils/purge-cache'; diff --git a/packages/angular/build/src/private.ts b/packages/angular/build/src/private.ts index 1fe8765b2646..9db709640b57 100644 --- a/packages/angular/build/src/private.ts +++ b/packages/angular/build/src/private.ts @@ -39,9 +39,9 @@ export { transformSupportedBrowsersToTargets } from './tools/esbuild/target'; export { SassCompiler } from './tools/sass/sass-service'; export { SourceFileCache } from './tools/esbuild/angular/source-file-cache'; -export { Cache } from './tools/esbuild/cache'; +export { Cache } from './utils/cache'; export { createJitResourceTransformer } from './tools/angular/transformers/jit-resource-transformer'; -export { JavaScriptTransformer } from './tools/esbuild/javascript-transformer'; +export { JavaScriptTransformer } from './tools/javascript-transformer'; export function createCompilerPlugin( pluginOptions: CompilerPluginOptions & { diff --git a/packages/angular/build/src/tools/angular/compilation/aot-compilation.ts b/packages/angular/build/src/tools/angular/compilation/aot-compilation.ts index ca74e721ba7d..b42b1273592d 100644 --- a/packages/angular/build/src/tools/angular/compilation/aot-compilation.ts +++ b/packages/angular/build/src/tools/angular/compilation/aot-compilation.ts @@ -11,7 +11,7 @@ import assert from 'node:assert'; import { relative } from 'node:path'; import ts from 'typescript'; import { useTypeChecking } from '../../../utils/environment-options'; -import { profileAsync, profileSync } from '../../esbuild/profiling'; +import { profileAsync, profileSync } from '../../../utils/profiling'; import { AngularHostOptions, createAngularCompilerHost, diff --git a/packages/angular/build/src/tools/angular/compilation/jit-compilation.ts b/packages/angular/build/src/tools/angular/compilation/jit-compilation.ts index 233f5977e5a6..e89db1e75aa4 100644 --- a/packages/angular/build/src/tools/angular/compilation/jit-compilation.ts +++ b/packages/angular/build/src/tools/angular/compilation/jit-compilation.ts @@ -9,7 +9,7 @@ import type * as ng from '@angular/compiler-cli'; import assert from 'node:assert'; import ts from 'typescript'; -import { profileSync } from '../../esbuild/profiling'; +import { profileSync } from '../../../utils/profiling'; import { AngularHostOptions, createAngularCompilerHost } from '../angular-host'; import { createJitResourceTransformer } from '../transformers/jit-resource-transformer'; import { lazyRoutesTransformer } from '../transformers/lazy-routes-transformer'; diff --git a/packages/angular/build/src/tools/angular/compilation/parallel-compilation.ts b/packages/angular/build/src/tools/angular/compilation/parallel-compilation.ts index 4df13b3a500e..0b58423a418b 100644 --- a/packages/angular/build/src/tools/angular/compilation/parallel-compilation.ts +++ b/packages/angular/build/src/tools/angular/compilation/parallel-compilation.ts @@ -9,8 +9,8 @@ import type { PartialMessage } from 'esbuild'; import { createRequire } from 'node:module'; import { MessageChannel } from 'node:worker_threads'; +import { mergeCumulativeDurations } from '../../../utils/profiling'; import { WorkerPool } from '../../../utils/worker-pool'; -import { mergeCumulativeDurations } from '../../esbuild/profiling'; import type { AngularHostOptions } from '../angular-host'; import { AngularCompilation, diff --git a/packages/angular/build/src/tools/angular/compilation/parallel-worker.ts b/packages/angular/build/src/tools/angular/compilation/parallel-worker.ts index 71b4d34e2756..5bf293da727d 100644 --- a/packages/angular/build/src/tools/angular/compilation/parallel-worker.ts +++ b/packages/angular/build/src/tools/angular/compilation/parallel-worker.ts @@ -11,7 +11,7 @@ import assert from 'node:assert'; import { randomUUID } from 'node:crypto'; import { type MessagePort, receiveMessageOnPort } from 'node:worker_threads'; import { initializeHash } from '../../../utils/hash'; -import { getAndClearCumulativeDurations } from '../../esbuild/profiling'; +import { getAndClearCumulativeDurations } from '../../../utils/profiling'; import type { AngularCompilation, AngularCompilationResult, diff --git a/packages/angular/build/src/tools/angular/compilation/typescript-compilation.ts b/packages/angular/build/src/tools/angular/compilation/typescript-compilation.ts index 71061031f3a4..05403b728fda 100644 --- a/packages/angular/build/src/tools/angular/compilation/typescript-compilation.ts +++ b/packages/angular/build/src/tools/angular/compilation/typescript-compilation.ts @@ -10,7 +10,7 @@ import type * as ng from '@angular/compiler-cli'; import type { PartialMessage } from 'esbuild'; import ts from 'typescript'; import { toPosixPath } from '../../../utils/path'; -import { profileAsync, profileSync } from '../../esbuild/profiling'; +import { profileAsync, profileSync } from '../../../utils/profiling'; import { AngularCompilation, DiagnosticModes } from './angular-compilation'; import { type CompilerOptionOverrides, transformCompilerOptions } from './compiler-options'; import { convertTypeScriptDiagnostic } from './diagnostics'; diff --git a/packages/angular/build/src/tools/esbuild/angular/compiler-plugin.ts b/packages/angular/build/src/tools/esbuild/angular/compiler-plugin.ts index 00c82b328085..a9c71e8db888 100644 --- a/packages/angular/build/src/tools/esbuild/angular/compiler-plugin.ts +++ b/packages/angular/build/src/tools/esbuild/angular/compiler-plugin.ts @@ -20,14 +20,18 @@ import type { import assert from 'node:assert'; import { readFile } from 'node:fs/promises'; import * as path from 'node:path'; +import { type PersistentCacheStore, createPersistentCacheStore } from '../../../utils/cache'; import { maxTransformWorkers, useTypeChecking } from '../../../utils/environment-options'; import { calculateHash, initializeHash } from '../../../utils/hash'; +import { + logCumulativeDurations, + profileAsync, + resetCumulativeDurations, +} from '../../../utils/profiling'; import { AngularHostOptions } from '../../angular/angular-host'; import { AngularCompilation, DiagnosticModes } from '../../angular/compilation'; -import { type PersistentCacheStore, createPersistentCacheStore } from '../cache'; -import { JavaScriptTransformer } from '../javascript-transformer'; +import { JavaScriptTransformer } from '../../javascript-transformer'; import { LoadResultCache, createCachedLoad } from '../load-result-cache'; -import { logCumulativeDurations, profileAsync, resetCumulativeDurations } from '../profiling'; import { AngularCompilationContext, PrimaryCompilationContext } from './compilation-state'; import { ComponentStylesheetBundler } from './component-stylesheets'; import { FileReferenceTracker } from './file-reference-tracker'; diff --git a/packages/angular/build/src/tools/esbuild/angular/component-stylesheets.ts b/packages/angular/build/src/tools/esbuild/angular/component-stylesheets.ts index 75ce354341ad..b5d2e453b57e 100644 --- a/packages/angular/build/src/tools/esbuild/angular/component-stylesheets.ts +++ b/packages/angular/build/src/tools/esbuild/angular/component-stylesheets.ts @@ -8,10 +8,10 @@ import assert from 'node:assert'; import path from 'node:path'; +import { MemoryCache } from '../../../utils/cache'; import { createContentHash } from '../../../utils/hash'; import { BundleContextResult, BundlerContext } from '../bundler-context'; import { type BuildOutputFile, BuildOutputFileType } from '../bundler-files'; -import { MemoryCache } from '../cache'; import { MemoryLoadResultCache } from '../load-result-cache'; import { BundleStylesheetOptions, diff --git a/packages/angular/build/src/tools/esbuild/bundler-execution-result.ts b/packages/angular/build/src/tools/esbuild/bundler-execution-result.ts index eeb7045dfb61..991ad988662b 100644 --- a/packages/angular/build/src/tools/esbuild/bundler-execution-result.ts +++ b/packages/angular/build/src/tools/esbuild/bundler-execution-result.ts @@ -8,7 +8,7 @@ import type { Message, PartialMessage } from 'esbuild'; import { normalize } from 'node:path'; -import type { ChangedFiles } from '../../tools/esbuild/watcher'; +import type { ChangedFiles } from '../../utils/watcher'; import type { ComponentStylesheetBundler } from './angular/component-stylesheets'; import type { SourceFileCache } from './angular/source-file-cache'; import type { BundlerContext } from './bundler-context'; diff --git a/packages/angular/build/src/tools/esbuild/i18n-locale-plugin.ts b/packages/angular/build/src/tools/esbuild/i18n-locale-plugin.ts index 8ffddf19adb7..b4c89cf644c1 100644 --- a/packages/angular/build/src/tools/esbuild/i18n-locale-plugin.ts +++ b/packages/angular/build/src/tools/esbuild/i18n-locale-plugin.ts @@ -7,136 +7,23 @@ */ import type { Plugin } from 'esbuild'; -import { readFile } from 'node:fs/promises'; import { createProjectResolver } from '../../utils/resolve-project'; - -/** - * The internal namespace used by generated locale import statements and Angular locale data plugin. - */ -export const LOCALE_DATA_NAMESPACE = 'angular:locale/data'; - -/** - * The base module location used to search for locale specific data. - */ -export const LOCALE_DATA_BASE_MODULE = '@angular/common/locales/global'; - -/** - * Result of resolving locale data for a given locale tag. - */ -export interface LocaleDataResolution { - path?: string; - warning?: string; - error?: string; -} - -/** - * Result of loading locale data for a given locale tag. - */ -export interface LoadedLocaleData { - code?: string; - warning?: string; - error?: string; -} - -const localeDataCache = new Map>(); - -/** - * Resolves the path to the Angular locale data file for a given locale tag. - * - * @param rawLocaleTag The raw locale identifier (e.g. "fr-CA", "de", "en-US"). - * @param projectResolve A function that attempts to resolve a path string to an absolute file path. - * @returns Resolution result with file path, or warning/error diagnostics if applicable. - */ -export function resolveLocaleDataPath( - rawLocaleTag: string, - projectResolve: (potentialPath: string) => string | undefined, -): LocaleDataResolution { - let partialLocaleTag: string; - try { - const locale = new Intl.Locale(rawLocaleTag); - partialLocaleTag = locale.baseName; - } catch { - return { - error: `Invalid or unsupported locale provided in configuration: "${rawLocaleTag}"`, - }; - } - - let exact = true; - while (partialLocaleTag) { - // Angular embeds the `en`/`en-US` locale into the framework and it does not need to be included again here. - if (partialLocaleTag === 'en' || partialLocaleTag === 'en-US') { - return {}; - } - - const potentialPath = `${LOCALE_DATA_BASE_MODULE}/${partialLocaleTag}`; - try { - const resolvedPath = projectResolve(potentialPath); - if (resolvedPath) { - return { - path: resolvedPath, - warning: exact - ? undefined - : `Locale data for '${rawLocaleTag}' cannot be found. Using locale data for '${partialLocaleTag}'.`, - }; - } - } catch {} - - // Remove the last subtag and try again with a less specific locale. - const parts = partialLocaleTag.split('-'); - partialLocaleTag = parts.slice(0, -1).join('-'); - exact = false; - } - - return { - warning: `Locale data for '${rawLocaleTag}' cannot be found. No locale data will be included for this locale.`, - }; -} - -/** - * Loads the Angular global locale data script for a specified locale tag. - * - * @param rawLocaleTag The raw locale identifier (e.g. "fr-CA", "de", "en-US"). - * @param projectRoot Optional project root for module resolution. - * @returns A promise resolving to the loaded locale data script code and any diagnostic warnings. - */ -export function loadLocaleData( - rawLocaleTag: string, - projectRoot?: string, -): Promise { - let cached = localeDataCache.get(rawLocaleTag); - if (!cached) { - cached = (async () => { - const projectResolve = createProjectResolver(projectRoot ?? process.cwd()); - const resolution = resolveLocaleDataPath(rawLocaleTag, (potentialPath) => { - try { - return projectResolve(potentialPath); - } catch { - return undefined; - } - }); - - if (resolution.error) { - return { error: resolution.error }; - } - - if (resolution.path) { - try { - const code = await readFile(resolution.path, 'utf8'); - - return { code, warning: resolution.warning }; - } catch (e) { - return { error: `Failed to read locale data file: ${(e as Error).message}` }; - } - } - - return { warning: resolution.warning }; - })(); - - localeDataCache.set(rawLocaleTag, cached); - } - - return cached; -} +import { + LOCALE_DATA_NAMESPACE, + type LoadedLocaleData, + type LocaleDataResolution, + loadLocaleData, + resolveLocaleDataPath, +} from '../i18n/locale-data'; + +export { + LOCALE_DATA_NAMESPACE, + LOCALE_DATA_BASE_MODULE, + type LoadedLocaleData, + type LocaleDataResolution, + loadLocaleData, + resolveLocaleDataPath, +} from '../i18n/locale-data'; /** * Creates an esbuild plugin that resolves Angular locale data files from `@angular/common`. diff --git a/packages/angular/build/src/tools/esbuild/persistent-load-result-cache.ts b/packages/angular/build/src/tools/esbuild/persistent-load-result-cache.ts index 9761ff9aff64..c5dcee90ccf9 100644 --- a/packages/angular/build/src/tools/esbuild/persistent-load-result-cache.ts +++ b/packages/angular/build/src/tools/esbuild/persistent-load-result-cache.ts @@ -31,9 +31,9 @@ import type { Loader, OnLoadResult, PartialMessage } from 'esbuild'; import { readFile, stat } from 'node:fs/promises'; import { isAbsolute } from 'node:path'; import { fileURLToPath } from 'node:url'; +import type { Cache as PersistentCacheStore } from '../../utils/cache'; import { mapConcurrent, runConcurrent } from '../../utils/concurrency'; import { calculateHash, createContentHash } from '../../utils/hash'; -import type { Cache as PersistentCacheStore } from './cache'; import { LoadResultCache, MemoryLoadResultCache } from './load-result-cache'; /** diff --git a/packages/angular/build/src/tools/esbuild/persistent-load-result-cache_spec.ts b/packages/angular/build/src/tools/esbuild/persistent-load-result-cache_spec.ts index f8ecc0611818..b41add55031d 100644 --- a/packages/angular/build/src/tools/esbuild/persistent-load-result-cache_spec.ts +++ b/packages/angular/build/src/tools/esbuild/persistent-load-result-cache_spec.ts @@ -10,8 +10,8 @@ import type { OnLoadResult } from 'esbuild'; import fs from 'node:fs'; import os from 'node:os'; import path from 'node:path'; +import type { Cache as PersistentCacheStore } from '../../utils/cache'; import { initializeHash } from '../../utils/hash'; -import type { Cache as PersistentCacheStore } from './cache'; import { type CachedLoadResultEntry, PersistentLoadResultCache, diff --git a/packages/angular/build/src/tools/esbuild/stylesheets/sass-language.ts b/packages/angular/build/src/tools/esbuild/stylesheets/sass-language.ts index cce85f61b9a2..b519a408bfb8 100644 --- a/packages/angular/build/src/tools/esbuild/stylesheets/sass-language.ts +++ b/packages/angular/build/src/tools/esbuild/stylesheets/sass-language.ts @@ -10,8 +10,8 @@ import type { OnLoadResult, PartialMessage, PartialNote, ResolveResult } from 'e import { dirname, join } from 'node:path'; import { fileURLToPath, pathToFileURL } from 'node:url'; import type { CanonicalizeContext, CompileResult, Exception, Syntax } from 'sass-embedded'; +import { MemoryCache } from '../../../utils/cache'; import type { SassCompiler } from '../../sass/sass-service'; -import { MemoryCache } from '../cache'; import { StylesheetLanguage, StylesheetPluginOptions } from './stylesheet-plugin-factory'; let sassService: SassCompiler | undefined; diff --git a/packages/angular/build/src/tools/esbuild/i18n-inliner-worker.ts b/packages/angular/build/src/tools/i18n/i18n-inliner-worker.ts similarity index 99% rename from packages/angular/build/src/tools/esbuild/i18n-inliner-worker.ts rename to packages/angular/build/src/tools/i18n/i18n-inliner-worker.ts index ac75ab246d8d..6a7e84b308b7 100644 --- a/packages/angular/build/src/tools/esbuild/i18n-inliner-worker.ts +++ b/packages/angular/build/src/tools/i18n/i18n-inliner-worker.ts @@ -8,14 +8,12 @@ import remapping, { type DecodedSourceMap, type SourceMapInput } from '@ampproject/remapping'; import type { ɵParsedTranslation } from '@angular/localize'; -import type { Node } from '@oxc-project/types'; import { MagicString } from 'magic-string'; -import assert from 'node:assert'; import { deserialize } from 'node:v8'; import { parseSync } from 'oxc-parser'; import { traversePostOrder } from '../oxc/traversal'; -import { loadLocaleData } from './i18n-locale-plugin'; import { createSharedTranslationProxy } from './i18n-translation-reader'; +import { loadLocaleData } from './locale-data'; /** * The options passed to the inliner for each code request diff --git a/packages/angular/build/src/tools/esbuild/i18n-inliner.ts b/packages/angular/build/src/tools/i18n/i18n-inliner.ts similarity index 99% rename from packages/angular/build/src/tools/esbuild/i18n-inliner.ts rename to packages/angular/build/src/tools/i18n/i18n-inliner.ts index e5ec68f48e26..581a2477adc5 100644 --- a/packages/angular/build/src/tools/esbuild/i18n-inliner.ts +++ b/packages/angular/build/src/tools/i18n/i18n-inliner.ts @@ -11,10 +11,18 @@ import assert from 'node:assert'; import { createRequire } from 'node:module'; import { extname, join } from 'node:path'; import { serialize } from 'node:v8'; +import { + type Cache, + type PersistentCacheStore, + createPersistentCacheStore, +} from '../../utils/cache'; import { calculateHash, createContentHash, initializeHash } from '../../utils/hash'; import { WorkerPool } from '../../utils/worker-pool'; -import { type BuildOutputFile, BuildOutputFileType, createOutputFile } from './bundler-files'; -import { type Cache, type PersistentCacheStore, createPersistentCacheStore } from './cache'; +import { + type BuildOutputFile, + BuildOutputFileType, + createOutputFile, +} from '../esbuild/bundler-files'; import type { InlineCodeRequest, InlineCodeResult, diff --git a/packages/angular/build/src/tools/esbuild/i18n-inliner_spec.ts b/packages/angular/build/src/tools/i18n/i18n-inliner_spec.ts similarity index 99% rename from packages/angular/build/src/tools/esbuild/i18n-inliner_spec.ts rename to packages/angular/build/src/tools/i18n/i18n-inliner_spec.ts index 8f73c018e4bd..bbc827b94c7f 100644 --- a/packages/angular/build/src/tools/esbuild/i18n-inliner_spec.ts +++ b/packages/angular/build/src/tools/i18n/i18n-inliner_spec.ts @@ -11,10 +11,14 @@ import { transform } from 'esbuild'; import fs from 'node:fs/promises'; import os from 'node:os'; import path from 'node:path'; +import { createPersistentCacheStore } from '../../utils/cache'; import { initializeHash } from '../../utils/hash'; import { WorkerPool } from '../../utils/worker-pool'; -import { type BuildOutputFile, BuildOutputFileType, createOutputFile } from './bundler-files'; -import { createPersistentCacheStore } from './cache'; +import { + type BuildOutputFile, + BuildOutputFileType, + createOutputFile, +} from '../esbuild/bundler-files'; import { I18nInliner, type I18nInlinerOptions } from './i18n-inliner'; /** diff --git a/packages/angular/build/src/tools/esbuild/i18n-translation-encoder.ts b/packages/angular/build/src/tools/i18n/i18n-translation-encoder.ts similarity index 100% rename from packages/angular/build/src/tools/esbuild/i18n-translation-encoder.ts rename to packages/angular/build/src/tools/i18n/i18n-translation-encoder.ts diff --git a/packages/angular/build/src/tools/esbuild/i18n-translation-encoder_spec.ts b/packages/angular/build/src/tools/i18n/i18n-translation-encoder_spec.ts similarity index 100% rename from packages/angular/build/src/tools/esbuild/i18n-translation-encoder_spec.ts rename to packages/angular/build/src/tools/i18n/i18n-translation-encoder_spec.ts diff --git a/packages/angular/build/src/tools/esbuild/i18n-translation-reader.ts b/packages/angular/build/src/tools/i18n/i18n-translation-reader.ts similarity index 100% rename from packages/angular/build/src/tools/esbuild/i18n-translation-reader.ts rename to packages/angular/build/src/tools/i18n/i18n-translation-reader.ts diff --git a/packages/angular/build/src/tools/i18n/index.ts b/packages/angular/build/src/tools/i18n/index.ts new file mode 100644 index 000000000000..a2f8cdd2d8f3 --- /dev/null +++ b/packages/angular/build/src/tools/i18n/index.ts @@ -0,0 +1,12 @@ +/** + * @license + * Copyright Google LLC All Rights Reserved. + * + * Use of this source code is governed by an MIT-style license that can be + * found in the LICENSE file at https://angular.dev/license + */ + +export * from './i18n-inliner'; +export * from './i18n-translation-encoder'; +export * from './i18n-translation-reader'; +export * from './locale-data'; diff --git a/packages/angular/build/src/tools/i18n/locale-data.ts b/packages/angular/build/src/tools/i18n/locale-data.ts new file mode 100644 index 000000000000..0418830b69a8 --- /dev/null +++ b/packages/angular/build/src/tools/i18n/locale-data.ts @@ -0,0 +1,138 @@ +/** + * @license + * Copyright Google LLC All Rights Reserved. + * + * Use of this source code is governed by an MIT-style license that can be + * found in the LICENSE file at https://angular.dev/license + */ + +import { readFile } from 'node:fs/promises'; +import { createProjectResolver } from '../../utils/resolve-project'; + +/** + * The internal namespace used by generated locale import statements and Angular locale data plugin. + */ +export const LOCALE_DATA_NAMESPACE = 'angular:locale/data'; + +/** + * The base module location used to search for locale specific data. + */ +export const LOCALE_DATA_BASE_MODULE = '@angular/common/locales/global'; + +/** + * Result of resolving locale data for a given locale tag. + */ +export interface LocaleDataResolution { + path?: string; + warning?: string; + error?: string; +} + +/** + * Result of loading locale data for a given locale tag. + */ +export interface LoadedLocaleData { + code?: string; + warning?: string; + error?: string; +} + +const localeDataCache = new Map>(); + +/** + * Resolves the path to the Angular locale data file for a given locale tag. + * + * @param rawLocaleTag The raw locale identifier (e.g. "fr-CA", "de", "en-US"). + * @param projectResolve A function that attempts to resolve a path string to an absolute file path. + * @returns Resolution result with file path, or warning/error diagnostics if applicable. + */ +export function resolveLocaleDataPath( + rawLocaleTag: string, + projectResolve: (potentialPath: string) => string | undefined, +): LocaleDataResolution { + let partialLocaleTag: string; + try { + const locale = new Intl.Locale(rawLocaleTag); + partialLocaleTag = locale.baseName; + } catch { + return { + error: `Invalid or unsupported locale provided in configuration: "${rawLocaleTag}"`, + }; + } + + let exact = true; + while (partialLocaleTag) { + // Angular embeds the `en`/`en-US` locale into the framework and it does not need to be included again here. + if (partialLocaleTag === 'en' || partialLocaleTag === 'en-US') { + return {}; + } + + const potentialPath = `${LOCALE_DATA_BASE_MODULE}/${partialLocaleTag}`; + try { + const resolvedPath = projectResolve(potentialPath); + if (resolvedPath) { + return { + path: resolvedPath, + warning: exact + ? undefined + : `Locale data for '${rawLocaleTag}' cannot be found. Using locale data for '${partialLocaleTag}'.`, + }; + } + } catch {} + + // Remove the last subtag and try again with a less specific locale. + const parts = partialLocaleTag.split('-'); + partialLocaleTag = parts.slice(0, -1).join('-'); + exact = false; + } + + return { + warning: `Locale data for '${rawLocaleTag}' cannot be found. No locale data will be included for this locale.`, + }; +} + +/** + * Loads the Angular global locale data script for a specified locale tag. + * + * @param rawLocaleTag The raw locale identifier (e.g. "fr-CA", "de", "en-US"). + * @param projectRoot Optional project root for module resolution. + * @returns A promise resolving to the loaded locale data script code and any diagnostic warnings. + */ +export function loadLocaleData( + rawLocaleTag: string, + projectRoot?: string, +): Promise { + let cached = localeDataCache.get(rawLocaleTag); + if (!cached) { + cached = (async () => { + const projectResolve = createProjectResolver(projectRoot ?? process.cwd()); + const resolution = resolveLocaleDataPath(rawLocaleTag, (potentialPath) => { + try { + return projectResolve(potentialPath); + } catch { + return undefined; + } + }); + + if (resolution.error) { + return { error: resolution.error }; + } + + if (resolution.path) { + try { + const code = await readFile(resolution.path, 'utf8'); + + return { code, warning: resolution.warning }; + } catch (e) { + return { error: `Failed to read locale data file: ${(e as Error).message}` }; + } + } + + return { warning: resolution.warning }; + })(); + + localeDataCache.set(rawLocaleTag, cached); + } + + return cached; +} diff --git a/packages/angular/build/src/tools/javascript-transformer/index.ts b/packages/angular/build/src/tools/javascript-transformer/index.ts new file mode 100644 index 000000000000..399eea87e644 --- /dev/null +++ b/packages/angular/build/src/tools/javascript-transformer/index.ts @@ -0,0 +1,9 @@ +/** + * @license + * Copyright Google LLC All Rights Reserved. + * + * Use of this source code is governed by an MIT-style license that can be + * found in the LICENSE file at https://angular.dev/license + */ + +export * from './javascript-transformer'; diff --git a/packages/angular/build/src/tools/esbuild/javascript-transformer-worker.ts b/packages/angular/build/src/tools/javascript-transformer/javascript-transformer-worker.ts similarity index 100% rename from packages/angular/build/src/tools/esbuild/javascript-transformer-worker.ts rename to packages/angular/build/src/tools/javascript-transformer/javascript-transformer-worker.ts diff --git a/packages/angular/build/src/tools/esbuild/javascript-transformer.ts b/packages/angular/build/src/tools/javascript-transformer/javascript-transformer.ts similarity index 99% rename from packages/angular/build/src/tools/esbuild/javascript-transformer.ts rename to packages/angular/build/src/tools/javascript-transformer/javascript-transformer.ts index 2917222a3277..56a7b4eb6ed9 100644 --- a/packages/angular/build/src/tools/esbuild/javascript-transformer.ts +++ b/packages/angular/build/src/tools/javascript-transformer/javascript-transformer.ts @@ -7,11 +7,11 @@ */ import { readFile } from 'node:fs/promises'; +import { Cache } from '../../utils/cache'; import { createContentHash } from '../../utils/hash'; import { IMPORT_EXEC_ARGV } from '../../utils/server-rendering/esm-in-memory-loader/utils'; import { removeSourceMappingURL } from '../../utils/source-map'; import { WorkerPool, WorkerPoolOptions } from '../../utils/worker-pool'; -import { Cache } from './cache'; const LINKER_DECLARATION_PREFIX = 'ɵɵngDeclare'; const LINKER_DECLARATION_PREFIX_BYTES = Buffer.from(LINKER_DECLARATION_PREFIX, 'utf-8'); diff --git a/packages/angular/build/src/tools/esbuild/javascript-transformer_spec.ts b/packages/angular/build/src/tools/javascript-transformer/javascript-transformer_spec.ts similarity index 100% rename from packages/angular/build/src/tools/esbuild/javascript-transformer_spec.ts rename to packages/angular/build/src/tools/javascript-transformer/javascript-transformer_spec.ts diff --git a/packages/angular/build/src/tools/vite/utils.ts b/packages/angular/build/src/tools/vite/utils.ts index dc7094b8ffe4..fa833066f8ed 100644 --- a/packages/angular/build/src/tools/vite/utils.ts +++ b/packages/angular/build/src/tools/vite/utils.ts @@ -13,7 +13,7 @@ import type { DepOptimizationConfig } from 'vite' with { 'resolution-mode': 'import', }; import type { ExternalResultMetadata } from '../esbuild/bundler-execution-result'; -import { JavaScriptTransformer } from '../esbuild/javascript-transformer'; +import { JavaScriptTransformer } from '../javascript-transformer'; export type AngularMemoryOutputFiles = Map< string, diff --git a/packages/angular/build/src/tools/esbuild/cache.ts b/packages/angular/build/src/utils/cache/cache.ts similarity index 98% rename from packages/angular/build/src/tools/esbuild/cache.ts rename to packages/angular/build/src/utils/cache/cache.ts index 40c6787abee3..1773caca71ea 100644 --- a/packages/angular/build/src/tools/esbuild/cache.ts +++ b/packages/angular/build/src/utils/cache/cache.ts @@ -11,8 +11,8 @@ * Provides infrastructure for common caching functionality within the build system. */ -import { persistentCacheStoreSetting } from '../../utils/environment-options'; -import { assertIsError } from '../../utils/error'; +import { persistentCacheStoreSetting } from '../environment-options'; +import { assertIsError } from '../error'; /** * A backing data store for one or more Cache instances. diff --git a/packages/angular/build/src/tools/esbuild/cache_spec.ts b/packages/angular/build/src/utils/cache/cache_spec.ts similarity index 100% rename from packages/angular/build/src/tools/esbuild/cache_spec.ts rename to packages/angular/build/src/utils/cache/cache_spec.ts diff --git a/packages/angular/build/src/utils/cache/index.ts b/packages/angular/build/src/utils/cache/index.ts new file mode 100644 index 000000000000..417d13326f50 --- /dev/null +++ b/packages/angular/build/src/utils/cache/index.ts @@ -0,0 +1,9 @@ +/** + * @license + * Copyright Google LLC All Rights Reserved. + * + * Use of this source code is governed by an MIT-style license that can be + * found in the LICENSE file at https://angular.dev/license + */ + +export * from './cache'; diff --git a/packages/angular/build/src/tools/esbuild/lmdb-cache-store.ts b/packages/angular/build/src/utils/cache/lmdb-cache-store.ts similarity index 100% rename from packages/angular/build/src/tools/esbuild/lmdb-cache-store.ts rename to packages/angular/build/src/utils/cache/lmdb-cache-store.ts diff --git a/packages/angular/build/src/tools/esbuild/sqlite-cache-store.ts b/packages/angular/build/src/utils/cache/sqlite-cache-store.ts similarity index 100% rename from packages/angular/build/src/tools/esbuild/sqlite-cache-store.ts rename to packages/angular/build/src/utils/cache/sqlite-cache-store.ts diff --git a/packages/angular/build/src/tools/esbuild/sqlite-cache-store_spec.ts b/packages/angular/build/src/utils/cache/sqlite-cache-store_spec.ts similarity index 100% rename from packages/angular/build/src/tools/esbuild/sqlite-cache-store_spec.ts rename to packages/angular/build/src/utils/cache/sqlite-cache-store_spec.ts diff --git a/packages/angular/build/src/tools/esbuild/profiling.ts b/packages/angular/build/src/utils/profiling.ts similarity index 97% rename from packages/angular/build/src/tools/esbuild/profiling.ts rename to packages/angular/build/src/utils/profiling.ts index 80fd26c32d0e..762a739bd318 100644 --- a/packages/angular/build/src/tools/esbuild/profiling.ts +++ b/packages/angular/build/src/utils/profiling.ts @@ -6,7 +6,7 @@ * found in the LICENSE file at https://angular.dev/license */ -import { debugPerformance } from '../../utils/environment-options'; +import { debugPerformance } from './environment-options'; let cumulativeDurations: Map | undefined; diff --git a/packages/angular/build/src/tools/esbuild/watcher.ts b/packages/angular/build/src/utils/watcher.ts similarity index 99% rename from packages/angular/build/src/tools/esbuild/watcher.ts rename to packages/angular/build/src/utils/watcher.ts index e30909fa6813..be38151f7a48 100644 --- a/packages/angular/build/src/tools/esbuild/watcher.ts +++ b/packages/angular/build/src/utils/watcher.ts @@ -12,8 +12,8 @@ import { once } from 'node:events'; import * as fs from 'node:fs'; import * as path from 'node:path'; import picomatch from 'picomatch'; -import { shouldWatchRoot } from '../../utils/environment-options'; -import { toPosixPath } from '../../utils/path'; +import { shouldWatchRoot } from './environment-options'; +import { toPosixPath } from './path'; export class ChangedFiles { readonly added = new Set(); diff --git a/packages/angular/build/src/tools/esbuild/watcher_spec.ts b/packages/angular/build/src/utils/watcher_spec.ts similarity index 100% rename from packages/angular/build/src/tools/esbuild/watcher_spec.ts rename to packages/angular/build/src/utils/watcher_spec.ts diff --git a/scripts/benchmark.mts b/scripts/benchmark.mts index bf35b97808e3..0237f5101bc4 100644 --- a/scripts/benchmark.mts +++ b/scripts/benchmark.mts @@ -11,8 +11,8 @@ import path from 'node:path'; import { type BenchmarkCliOptions, runI18nBenchmarks } from './benchmarks/i18n/index.mts'; function checkBuildStatus(logger: Console): boolean { - const distFile = 'dist/@angular/build/src/tools/esbuild/i18n-inliner.js'; - const srcFile = 'packages/angular/build/src/tools/esbuild/i18n-inliner.ts'; + const distFile = 'dist/@angular/build/src/tools/i18n/i18n-inliner.js'; + const srcFile = 'packages/angular/build/src/tools/i18n/i18n-inliner.ts'; if (!fs.existsSync(distFile)) { logger.error( diff --git a/scripts/benchmarks/i18n/fixtures.mts b/scripts/benchmarks/i18n/fixtures.mts index 3d53c3dbff5b..6a926d07a29e 100644 --- a/scripts/benchmarks/i18n/fixtures.mts +++ b/scripts/benchmarks/i18n/fixtures.mts @@ -14,7 +14,7 @@ import { createRequire } from 'node:module'; import path from 'node:path'; import type { BuildOutputFile } from '../../../packages/angular/build/src/tools/esbuild/bundler-files.js'; -import type { LocaleInlineOptions } from '../../../packages/angular/build/src/tools/esbuild/i18n-inliner.js'; +import type { LocaleInlineOptions } from '../../../packages/angular/build/src/tools/i18n/i18n-inliner.js'; // Setup module paths to resolve dependencies from packages/angular/build const requireFromBuild = createRequire( diff --git a/scripts/benchmarks/i18n/scenarios.mts b/scripts/benchmarks/i18n/scenarios.mts index c00f34ded8a2..d1bdcb8cfa40 100644 --- a/scripts/benchmarks/i18n/scenarios.mts +++ b/scripts/benchmarks/i18n/scenarios.mts @@ -16,7 +16,7 @@ import path from 'node:path'; import { pathToFileURL } from 'node:url'; import type { BuildOutputFile } from '../../../packages/angular/build/src/tools/esbuild/bundler-files.js'; -import type { LocaleInlineOptions } from '../../../packages/angular/build/src/tools/esbuild/i18n-inliner.js'; +import type { LocaleInlineOptions } from '../../../packages/angular/build/src/tools/i18n/i18n-inliner.js'; import { generateSyntheticBundle, generateTranslations, initializeFixtures } from './fixtures.mts'; import type { BenchmarkScenario } from './harness.mts'; @@ -25,8 +25,8 @@ const requireFromBuild = createRequire( ); const { I18nInliner } = requireFromBuild( - '../../../dist/@angular/build/src/tools/esbuild/i18n-inliner.js', -) as typeof import('../../../packages/angular/build/src/tools/esbuild/i18n-inliner.js'); + '../../../dist/@angular/build/src/tools/i18n/i18n-inliner.js', +) as typeof import('../../../packages/angular/build/src/tools/i18n/i18n-inliner.js'); export interface ScenarioFactoryOptions { concurrency?: number; From 6b0b9bec61fdcdb6c3e8bd022e46c5b35d8a86fc Mon Sep 17 00:00:00 2001 From: Charles Lyding <19598772+clydin@users.noreply.github.com> Date: Wed, 16 Sep 2026 08:54:34 -0400 Subject: [PATCH 494/787] build(@angular/cli): bundle CLI first-party code into ESM chunks with esbuild Bundle @angular/cli first-party entry points (`lib/cli/index.js` and `lib/init.js`) into ESM chunks using `aspect_rules_esbuild` targeting Node 22 with external packages, code splitting, and bundle sourcemaps disabled. The package `package.json` is now designated as "type": "module", while `bin/package.json` retains CommonJS to allow the `ng` binary bootstrap to validate older Node.js runtimes. A dedicated ES5/CommonJS `bin/version.js` file is stamped by Bazel during release packaging and exposed through a `#version` package subpath import. This enables `bin/ng.js` to perform runtime compatibility checks safely before dynamic ESM import, while allowing bundled chunks to access stamped versions without runtime file I/O. Inlined markdown assets, including MCP resources and command long descriptions, are bundled directly into output chunks via esbuild's text loader, removing the need for runtime filesystem reads and the CommonJS `require.extensions` loader workaround. Ambient `__dirname`, `__filename`, and `createRequire` usages are replaced with `import.meta.dirname` and `import.meta.url`, with `pathToFileURL` used for Windows dynamic imports. A standalone `index.d.ts` declaration file is provided for programmatic package consumers, and unit tests are updated to execute under native Node.js ESM. --- packages/angular/cli/BUILD.bazel | 72 ++++++++++++++++--- packages/angular/cli/bin/ng.js | 2 +- packages/angular/cli/bin/version.js | 64 +++++++++++++++++ packages/angular/cli/index.d.ts | 19 +++++ packages/angular/cli/lib/init.ts | 9 ++- packages/angular/cli/package.json | 5 ++ .../cli/src/command-builder/command-module.ts | 1 - .../cli/src/command-builder/definitions.ts | 2 +- .../schematics-command-module.ts | 8 +-- .../utilities/json-schema_spec.ts | 3 +- .../utilities/schematic-engine-host.ts | 4 +- .../commands/mcp/resources/instructions.ts | 11 ++- .../cli/src/commands/mcp/tools/ai-tutor.ts | 31 ++++---- .../src/commands/mcp/tools/best-practices.ts | 16 +---- .../angular/cli/src/commands/update/cli.ts | 4 +- packages/angular/cli/src/typings.d.ts | 9 ++- packages/angular/cli/src/utilities/config.ts | 13 +++- .../cli/src/utilities/markdown-loader.ts | 35 --------- .../angular/cli/src/utilities/node-version.ts | 40 +---------- packages/angular/cli/src/utilities/version.ts | 4 +- packages/angular/cli/test-esm-loader.mjs | 48 +++++++++++++ packages/angular/cli/tsconfig-build.json | 9 +++ packages/angular/cli/tsconfig-test.json | 6 ++ 23 files changed, 276 insertions(+), 139 deletions(-) create mode 100644 packages/angular/cli/bin/version.js create mode 100644 packages/angular/cli/index.d.ts delete mode 100644 packages/angular/cli/src/utilities/markdown-loader.ts create mode 100644 packages/angular/cli/test-esm-loader.mjs create mode 100644 packages/angular/cli/tsconfig-build.json create mode 100644 packages/angular/cli/tsconfig-test.json diff --git a/packages/angular/cli/BUILD.bazel b/packages/angular/cli/BUILD.bazel index 1eb48f2fc6f2..2fbad284fd31 100644 --- a/packages/angular/cli/BUILD.bazel +++ b/packages/angular/cli/BUILD.bazel @@ -3,6 +3,8 @@ # Use of this source code is governed by an MIT-style license that can be # found in the LICENSE file at https://angular.dev/license +load("@aspect_rules_esbuild//esbuild:defs.bzl", "esbuild") +load("@aspect_rules_ts//ts:defs.bzl", "ts_config") load("@npm//:defs.bzl", "npm_link_all_packages") load("//tools:defaults.bzl", "jasmine_test", "npm_package", "ts_project") load("//tools:ng_cli_schema_generator.bzl", "cli_json_schema") @@ -14,6 +16,24 @@ package(default_visibility = ["//visibility:public"]) npm_link_all_packages() +ts_config( + name = "tsconfig-build", + src = "tsconfig-build.json", + deps = [ + "//:build-tsconfig", + ], +) + +ts_config( + name = "tsconfig-test", + src = "tsconfig-test.json", + deps = [ + ":tsconfig-build", + "//:node_modules/@types/jasmine", + "//:node_modules/@types/node", + ], +) + genrule( name = "angular_best_practices", srcs = [ @@ -25,19 +45,19 @@ genrule( """, ) -RUNTIME_ASSETS = glob( +PACKAGE_ASSETS = glob( include = [ "bin/**/*", - "src/**/*.md", ], exclude = [ "lib/config/workspace-schema.json", ], ) + [ "//packages/angular/cli:lib/config/schema.json", - ":angular_best_practices", ] +RUNTIME_ASSETS = PACKAGE_ASSETS + glob(["src/**/*.md"]) + [":angular_best_practices"] + ts_project( name = "angular-cli", srcs = glob( @@ -54,6 +74,7 @@ ts_project( "//packages/angular/cli:lib/config/workspace-schema.ts", ], data = RUNTIME_ASSETS, + tsconfig = ":tsconfig-build", deps = [ ":node_modules/@angular-devkit/architect", ":node_modules/@angular-devkit/core", @@ -77,6 +98,30 @@ ts_project( ], ) +esbuild( + name = "bundled_cli", + srcs = [ + ":angular-cli", + ":angular_best_practices", + ] + glob(["src/**/*.md"]), + config = { + "packages": "external", + "loader": { + ".md": "text", + }, + }, + entry_points = [ + "lib/cli/index.js", + "lib/init.js", + ], + format = "esm", + output_dir = True, + platform = "node", + sourcemap = False, + splitting = True, + target = "node22", +) + CLI_SCHEMA_DATA = [ "//packages/angular/build:schemas", "//packages/angular_devkit/build_angular:schemas", @@ -109,6 +154,7 @@ ts_project( "node_modules/**", ], ), + tsconfig = ":tsconfig-test", deps = [ ":angular-cli", ":node_modules/@angular-devkit/core", @@ -124,7 +170,14 @@ ts_project( jasmine_test( name = "test", - data = [":angular-cli_test_lib"], + data = [ + "package.json", + "test-esm-loader.mjs", + ":angular-cli_test_lib", + ], + node_options = [ + "--import=./test-esm-loader.mjs", + ], ) genrule( @@ -144,14 +197,17 @@ npm_package( "//packages/angular_devkit/schematics:package.json", "//packages/schematics/angular:package.json", ], + replace_prefixes = { + "bundled_cli/": "lib/", + }, stamp_files = [ - "src/utilities/version.js", - "src/utilities/node-version.js", + "bin/version.js", ], tags = ["release-package"], - deps = RUNTIME_ASSETS + [ + deps = PACKAGE_ASSETS + [ ":README.md", - ":angular-cli", + ":bundled_cli", + ":index.d.ts", ":license", ], ) diff --git a/packages/angular/cli/bin/ng.js b/packages/angular/cli/bin/ng.js index ac01a0935fc0..a95f51b8def4 100755 --- a/packages/angular/cli/bin/ng.js +++ b/packages/angular/cli/bin/ng.js @@ -12,7 +12,7 @@ 'use strict'; const path = require('path'); -const nodeUtils = require('../src/utilities/node-version'); +const nodeUtils = require('./version'); // Error if the external CLI appears to be used inside a google3 context. if (process.cwd().split(path.sep).includes('google3')) { diff --git a/packages/angular/cli/bin/version.js b/packages/angular/cli/bin/version.js new file mode 100644 index 000000000000..38edd4e299c7 --- /dev/null +++ b/packages/angular/cli/bin/version.js @@ -0,0 +1,64 @@ +'use strict'; +/** + * @license + * Copyright Google LLC All Rights Reserved. + * + * Use of this source code is governed by an MIT-style license that can be + * found in the LICENSE file at https://angular.dev/license + */ + +/** + * The supported Node.js version for the Angular CLI. + */ +var SUPPORTED_NODE_VERSIONS = '0.0.0-ENGINES-NODE'; + +/** + * The version of the Angular CLI. + */ +var VERSION = '0.0.0-PLACEHOLDER'; + +/** + * The supported Node.js versions. + */ +var supportedNodeVersions = SUPPORTED_NODE_VERSIONS.replace(/[\^~<>=]/g, '') + .split('||') + .map(function (v) { + return v.trim(); + }); + +/** + * Checks if the current Node.js version is supported. + * @returns `true` if the current Node.js version is supported, `false` otherwise. + */ +function isNodeVersionSupported() { + if (SUPPORTED_NODE_VERSIONS.charAt(0) === '0') { + return true; + } + + var parts = process.versions.node.split('.', 3).map(Number); + var processMajor = parts[0]; + var processMinor = parts[1]; + var processPatch = parts[2]; + + for (var i = 0; i < supportedNodeVersions.length; i++) { + var vParts = supportedNodeVersions[i].split('.', 3).map(Number); + var major = vParts[0]; + var minor = vParts[1]; + var patch = vParts[2]; + if ( + (major === processMajor && processMinor === minor && processPatch >= patch) || + (major === processMajor && processMinor > minor) + ) { + return true; + } + } + + return false; +} + +module.exports = { + VERSION: VERSION, + SUPPORTED_NODE_VERSIONS: SUPPORTED_NODE_VERSIONS, + supportedNodeVersions: supportedNodeVersions, + isNodeVersionSupported: isNodeVersionSupported, +}; diff --git a/packages/angular/cli/index.d.ts b/packages/angular/cli/index.d.ts new file mode 100644 index 000000000000..2a73c4bbc059 --- /dev/null +++ b/packages/angular/cli/index.d.ts @@ -0,0 +1,19 @@ +/** + * @license + * Copyright Google LLC All Rights Reserved. + * + * Use of this source code is governed by an MIT-style license that can be + * found in the LICENSE file at https://angular.dev/license + */ + +export declare class Version { + readonly full: string; + readonly major: string; + readonly minor: string; + readonly patch: string; + constructor(full: string); +} + +export declare const VERSION: Version; + +export default function (options: { cliArgs: string[] }): Promise; diff --git a/packages/angular/cli/lib/init.ts b/packages/angular/cli/lib/init.ts index 97d410890955..a503d9a87f70 100644 --- a/packages/angular/cli/lib/init.ts +++ b/packages/angular/cli/lib/init.ts @@ -9,6 +9,7 @@ import { readFile } from 'node:fs/promises'; import { createRequire } from 'node:module'; import * as path from 'node:path'; +import { pathToFileURL } from 'node:url'; import { SemVer, major } from 'semver'; import { disableVersionCheck } from '../src/utilities/environment-options'; import { VERSION } from '../src/utilities/version'; @@ -71,7 +72,7 @@ let forceExit = false; // version of ng-cli you have installed in a local package.json const cwdRequire = createRequire(process.cwd() + '/'); const projectLocalCli = cwdRequire.resolve('@angular/cli'); - cli = await import(projectLocalCli); + cli = await import(pathToFileURL(projectLocalCli).href); const globalVersion = new SemVer(VERSION.full); @@ -150,7 +151,11 @@ let forceExit = false; cli = await import('./cli'); } - if ('default' in cli) { + // Support both ESM and CommonJS local CLI packages. When importing older CommonJS + // packages with an `__esModule` default export, Node.js wraps the exports in an ESM + // namespace requiring the default export to be unwrapped multiple times. + let depth = 0; + while (typeof cli === 'object' && cli !== null && 'default' in cli && depth++ < 3) { cli = cli['default']; } diff --git a/packages/angular/cli/package.json b/packages/angular/cli/package.json index 2504ea0da35b..bae0b97abe97 100644 --- a/packages/angular/cli/package.json +++ b/packages/angular/cli/package.json @@ -3,6 +3,8 @@ "version": "0.0.0-PLACEHOLDER", "description": "CLI tool for Angular", "main": "lib/cli/index.js", + "typings": "index.d.ts", + "type": "module", "bin": { "ng": "bin/ng.js" }, @@ -11,6 +13,9 @@ "angular-cli", "Angular CLI" ], + "imports": { + "#version": "./bin/version.js" + }, "dependencies": { "@angular-devkit/architect": "workspace:0.0.0-EXPERIMENTAL-PLACEHOLDER", "@angular-devkit/core": "workspace:0.0.0-PLACEHOLDER", diff --git a/packages/angular/cli/src/command-builder/command-module.ts b/packages/angular/cli/src/command-builder/command-module.ts index 35e0d4f8201d..ec92bc452d5b 100644 --- a/packages/angular/cli/src/command-builder/command-module.ts +++ b/packages/angular/cli/src/command-builder/command-module.ts @@ -18,7 +18,6 @@ import { AngularWorkspace } from '../utilities/config'; import { memoize } from '../utilities/memoize'; import { CommandContext, CommandScope, Options, OtherOptions } from './definitions'; import { Option, addSchemaOptionsToCommand } from './utilities/json-schema'; -import '../utilities/markdown-loader'; export { CommandScope }; export type { CommandContext, Options, OtherOptions }; diff --git a/packages/angular/cli/src/command-builder/definitions.ts b/packages/angular/cli/src/command-builder/definitions.ts index d552b432b685..27c6dc8a6ae9 100644 --- a/packages/angular/cli/src/command-builder/definitions.ts +++ b/packages/angular/cli/src/command-builder/definitions.ts @@ -7,7 +7,7 @@ */ import { logging } from '@angular-devkit/core'; -import type { Argv, CamelCaseKey } from 'yargs'; +import type { Argv, CamelCaseKey } from 'yargs' with { 'resolution-mode': 'require' }; import type { PackageManager } from '../package-managers/package-manager'; import { AngularWorkspace } from '../utilities/config'; diff --git a/packages/angular/cli/src/command-builder/schematics-command-module.ts b/packages/angular/cli/src/command-builder/schematics-command-module.ts index c74b44101e93..e2561fd1c273 100644 --- a/packages/angular/cli/src/command-builder/schematics-command-module.ts +++ b/packages/angular/cli/src/command-builder/schematics-command-module.ts @@ -420,10 +420,10 @@ export abstract class SchematicsCommandModule return workspace ? // Workspace collectionName === DEFAULT_SCHEMATICS_COLLECTION - ? // Favor __dirname for @schematics/angular to use the build-in version - [__dirname, process.cwd(), root] - : [process.cwd(), root, __dirname] + ? // Favor import.meta.dirname for @schematics/angular to use the build-in version + [import.meta.dirname, process.cwd(), root] + : [process.cwd(), root, import.meta.dirname] : // Global - [__dirname, process.cwd()]; + [import.meta.dirname, process.cwd()]; } } diff --git a/packages/angular/cli/src/command-builder/utilities/json-schema_spec.ts b/packages/angular/cli/src/command-builder/utilities/json-schema_spec.ts index 11228e4adca0..496a2094b62c 100644 --- a/packages/angular/cli/src/command-builder/utilities/json-schema_spec.ts +++ b/packages/angular/cli/src/command-builder/utilities/json-schema_spec.ts @@ -7,6 +7,7 @@ */ import { JsonObject, schema } from '@angular-devkit/core'; +import type { Argv } from 'yargs'; import yargs from 'yargs'; import { Option, addSchemaOptionsToCommand, parseJsonSchemaToOptions } from './json-schema'; @@ -20,7 +21,7 @@ describe('parseJsonSchemaToOptions', () => { return localYargs.parseAsync(args); }; - let localYargs: yargs.Argv; + let localYargs: Argv; let options: Option[]; beforeAll(async () => { diff --git a/packages/angular/cli/src/command-builder/utilities/schematic-engine-host.ts b/packages/angular/cli/src/command-builder/utilities/schematic-engine-host.ts index 25b723c467a2..067d4cd00460 100644 --- a/packages/angular/cli/src/command-builder/utilities/schematic-engine-host.ts +++ b/packages/angular/cli/src/command-builder/utilities/schematic-engine-host.ts @@ -73,7 +73,7 @@ export class SchematicEngineHost extends NodeModulesEngineHost { // Mimic behavior of ExportStringRef class used in default behavior const fullPath = path[0] === '.' ? resolve(parentPath ?? process.cwd(), path) : path; - const referenceRequire = createRequire(__filename); + const referenceRequire = createRequire(import.meta.url); const schematicFile = referenceRequire.resolve(fullPath, { paths: [parentPath] }); if (shouldWrapSchematic(schematicFile, collectionDescription?.encapsulation)) { @@ -139,7 +139,7 @@ function wrap( moduleCache: Map, exportName?: string, ): () => unknown { - const hostRequire = createRequire(__filename); + const hostRequire = createRequire(import.meta.url); const schematicRequire = createRequire(schematicFile); const customRequire = function (id: string) { diff --git a/packages/angular/cli/src/commands/mcp/resources/instructions.ts b/packages/angular/cli/src/commands/mcp/resources/instructions.ts index 90902d60b389..636de5471a1c 100644 --- a/packages/angular/cli/src/commands/mcp/resources/instructions.ts +++ b/packages/angular/cli/src/commands/mcp/resources/instructions.ts @@ -7,8 +7,7 @@ */ import type { McpServer } from '@modelcontextprotocol/server'; -import { readFile } from 'node:fs/promises'; -import { join } from 'node:path'; +import bestPracticesText from './best-practices.md'; export function registerInstructionsResource(server: McpServer): void { server.registerResource( @@ -23,10 +22,8 @@ export function registerInstructionsResource(server: McpServer): void { ' typed forms, modern control flow syntax, and other current conventions.', mimeType: 'text/markdown', }, - async () => { - const text = await readFile(join(__dirname, 'best-practices.md'), 'utf-8'); - - return { contents: [{ uri: 'instructions://best-practices', text }] }; - }, + async () => ({ + contents: [{ uri: 'instructions://best-practices', text: bestPracticesText }], + }), ); } diff --git a/packages/angular/cli/src/commands/mcp/tools/ai-tutor.ts b/packages/angular/cli/src/commands/mcp/tools/ai-tutor.ts index 590d0940c747..c72f0fe42a12 100644 --- a/packages/angular/cli/src/commands/mcp/tools/ai-tutor.ts +++ b/packages/angular/cli/src/commands/mcp/tools/ai-tutor.ts @@ -6,8 +6,7 @@ * found in the LICENSE file at https://angular.dev/license */ -import { readFile } from 'node:fs/promises'; -import { join } from 'node:path'; +import aiTutorText from '../resources/ai-tutor.md'; import { declareTool } from './tool-registry'; export const AI_TUTOR_TOOL = declareTool({ @@ -37,23 +36,17 @@ with a new core identity and knowledge base. isReadOnly: true, isLocalOnly: true, factory: () => { - let aiTutorText: string; - - return async () => { - aiTutorText ??= await readFile(join(__dirname, '../resources/ai-tutor.md'), 'utf-8'); - - return { - content: [ - { - type: 'text', - text: aiTutorText, - annotations: { - audience: ['assistant'], - priority: 1.0, - }, + return async () => ({ + content: [ + { + type: 'text', + text: aiTutorText, + annotations: { + audience: ['assistant'], + priority: 1.0, }, - ], - }; - }; + }, + ], + }); }, }); diff --git a/packages/angular/cli/src/commands/mcp/tools/best-practices.ts b/packages/angular/cli/src/commands/mcp/tools/best-practices.ts index 0b40c5c0c207..d8a8d1251604 100644 --- a/packages/angular/cli/src/commands/mcp/tools/best-practices.ts +++ b/packages/angular/cli/src/commands/mcp/tools/best-practices.ts @@ -17,9 +17,10 @@ import { readFile, stat } from 'node:fs/promises'; import { createRequire } from 'node:module'; -import { dirname, isAbsolute, join, relative, resolve } from 'node:path'; +import { dirname, isAbsolute, relative, resolve } from 'node:path'; import { z } from 'zod'; import { VERSION } from '../../../utilities/version'; +import bundledBestPractices from '../resources/best-practices.md'; import { isAllowedWorkspacePath } from '../workspace-utils'; import { type McpToolContext, declareTool } from './tool-registry'; @@ -59,15 +60,6 @@ that must be followed for any task involving the creation, analysis, or modifica factory: createBestPracticesHandler, }); -/** - * Retrieves the content of the generic best practices guide that is bundled with the CLI. - * This serves as a fallback when a version-specific guide cannot be found. - * @returns A promise that resolves to the string content of the bundled markdown file. - */ -async function getBundledBestPractices(): Promise { - return readFile(join(__dirname, '../resources/best-practices.md'), 'utf-8'); -} - /** * Attempts to find and read a version-specific best practices guide from the user's installed * version of `@angular/core`. It looks for a custom `angular` metadata property in the @@ -200,8 +192,6 @@ async function getVersionSpecificBestPractices( * @returns An async function that serves as the tool's executor. */ function createBestPracticesHandler({ logger, server }: McpToolContext) { - let bundledBestPractices: Promise; - return async (input: BestPracticesInput) => { let content: string | undefined; let source: string | undefined; @@ -221,7 +211,7 @@ function createBestPracticesHandler({ logger, server }: McpToolContext) { // If the version-specific guide was not found for any reason, fall back to the bundled version. if (content === undefined) { - content = await (bundledBestPractices ??= getBundledBestPractices()); + content = bundledBestPractices; source = `bundled (CLI v${VERSION.full})`; } diff --git a/packages/angular/cli/src/commands/update/cli.ts b/packages/angular/cli/src/commands/update/cli.ts index cbe703552c9a..fd0eeca166a3 100644 --- a/packages/angular/cli/src/commands/update/cli.ts +++ b/packages/angular/cli/src/commands/update/cli.ts @@ -60,7 +60,7 @@ class CommandError extends Error {} export default class UpdateCommandModule extends CommandModule { override scope = CommandScope.In; protected override shouldReportAnalytics = false; - private readonly resolvePaths = [__dirname, this.context.root]; + private readonly resolvePaths = [import.meta.dirname, this.context.root]; command = 'update [packages..]'; describe = 'Updates your workspace and its dependencies. See https://update.angular.dev/.'; @@ -237,7 +237,7 @@ export default class UpdateCommandModule extends CommandModule favor @schematics/update from this package + // import.meta.dirname -> favor @schematics/update from this package // Otherwise, use packages from the active workspace (migrations) resolvePaths: this.resolvePaths, schemaValidation: true, diff --git a/packages/angular/cli/src/typings.d.ts b/packages/angular/cli/src/typings.d.ts index 12e7de03c204..948d7b1d2280 100644 --- a/packages/angular/cli/src/typings.d.ts +++ b/packages/angular/cli/src/typings.d.ts @@ -6,7 +6,14 @@ * found in the LICENSE file at https://angular.dev/license */ -declare module '*/long-description.md' { +declare module '*.md' { const content: string; export default content; } + +declare module '#version' { + export const VERSION: string; + export const SUPPORTED_NODE_VERSIONS: string; + export const supportedNodeVersions: string[]; + export function isNodeVersionSupported(): boolean; +} diff --git a/packages/angular/cli/src/utilities/config.ts b/packages/angular/cli/src/utilities/config.ts index 7b9188bb3d89..6aa762aa264f 100644 --- a/packages/angular/cli/src/utilities/config.ts +++ b/packages/angular/cli/src/utilities/config.ts @@ -11,7 +11,7 @@ import { existsSync, promises as fs } from 'node:fs'; import * as os from 'node:os'; import * as path from 'node:path'; import { PackageManager } from '../../lib/config/workspace-schema'; -import { findUp, findUpSync } from './find-up'; +import { findUp } from './find-up'; import { JSONFile, readAndParseJson } from './json-file'; function isJsonObject(value: json.JsonValue | undefined): value is json.JsonObject { @@ -47,7 +47,14 @@ function createWorkspaceHost(): workspaces.WorkspaceHost { }; } -export const workspaceSchemaPath = path.join(__dirname, '../../lib/config/schema.json'); +const currentDirectory = import.meta.dirname; + +// In bundled ESM output, files are located in `lib/` directly adjacent to `config/schema.json` +// whereas in unbundled development/tests, `config.js` is in `src/utilities/`. +const bundledSchemaPath = path.join(currentDirectory, 'config/schema.json'); +export const workspaceSchemaPath = existsSync(bundledSchemaPath) + ? bundledSchemaPath + : path.join(currentDirectory, '../../lib/config/schema.json'); const configNames = ['angular.json', '.angular.json']; const globalFileName = '.angular-config.json'; @@ -76,7 +83,7 @@ async function projectFilePath(projectPath?: string): Promise { return ( (projectPath && (await findUp(configNames, projectPath))) || (await findUp(configNames, process.cwd())) || - (await findUp(configNames, __dirname)) + (await findUp(configNames, currentDirectory)) ); } diff --git a/packages/angular/cli/src/utilities/markdown-loader.ts b/packages/angular/cli/src/utilities/markdown-loader.ts deleted file mode 100644 index 3a70a5eaae1c..000000000000 --- a/packages/angular/cli/src/utilities/markdown-loader.ts +++ /dev/null @@ -1,35 +0,0 @@ -/** - * @license - * Copyright Google LLC All Rights Reserved. - * - * Use of this source code is governed by an MIT-style license that can be - * found in the LICENSE file at https://angular.dev/license - */ - -import { readFileSync } from 'node:fs'; - -const LONG_DESCRIPTION_REGEXP = /[/\\]long-description\.md$/; - -function isCommandLongDescription(filePath: string | undefined): boolean { - return !!filePath && LONG_DESCRIPTION_REGEXP.test(filePath); -} - -// Register markdown extension hook for CommonJS execution -if (typeof require !== 'undefined' && require.extensions) { - const originalMdExtension = require.extensions['.md']; - require.extensions['.md'] = (module, filename) => { - if (isCommandLongDescription(filename)) { - module.exports = readFileSync(filename, 'utf8'); - - return; - } - - if (originalMdExtension) { - originalMdExtension(module, filename); - } else { - const err = new Error(`Cannot find module '${filename}'`); - (err as NodeJS.ErrnoException).code = 'MODULE_NOT_FOUND'; - throw err; - } - }; -} diff --git a/packages/angular/cli/src/utilities/node-version.ts b/packages/angular/cli/src/utilities/node-version.ts index 7bed934428c8..18f06b960369 100644 --- a/packages/angular/cli/src/utilities/node-version.ts +++ b/packages/angular/cli/src/utilities/node-version.ts @@ -11,45 +11,9 @@ * @important This file must not import any other modules. */ -/** - * The supported Node.js version for the Angular CLI. - */ - -const SUPPORTED_NODE_VERSIONS = '0.0.0-ENGINES-NODE'; - -/** - * The supported Node.js versions. - */ -export const supportedNodeVersions = SUPPORTED_NODE_VERSIONS.replace(/[\^~<>=]/g, '') - .split('||') - .map((v) => v.trim()); - -/** - * Checks if the current Node.js version is supported. - * @returns `true` if the current Node.js version is supported, `false` otherwise. - */ -export function isNodeVersionSupported(): boolean { - if (SUPPORTED_NODE_VERSIONS.charAt(0) === '0') { - // Unlike `pkg_npm`, `ts_library` which is used to run unit tests does not support substitutions. - return true; - } - - const [processMajor, processMinor, processPatch] = process.versions.node - .split('.', 3) - .map((part) => Number(part)); +import { SUPPORTED_NODE_VERSIONS, supportedNodeVersions } from '#version'; - for (const version of supportedNodeVersions) { - const [major, minor, patch] = version.split('.', 3).map((part) => Number(part)); - if ( - (major === processMajor && processMinor === minor && processPatch >= patch) || - (major === processMajor && processMinor > minor) - ) { - return true; - } - } - - return false; -} +export { SUPPORTED_NODE_VERSIONS, supportedNodeVersions, isNodeVersionSupported } from '#version'; /** * Checks if the current Node.js version is the minimum supported version. diff --git a/packages/angular/cli/src/utilities/version.ts b/packages/angular/cli/src/utilities/version.ts index d16feb2d4b15..2218a39b3e78 100644 --- a/packages/angular/cli/src/utilities/version.ts +++ b/packages/angular/cli/src/utilities/version.ts @@ -6,6 +6,8 @@ * found in the LICENSE file at https://angular.dev/license */ +import { VERSION as versionString } from '#version'; + // Same structure as used in framework packages class Version { readonly major: string; @@ -20,4 +22,4 @@ class Version { } } -export const VERSION = new Version('0.0.0-PLACEHOLDER'); +export const VERSION = new Version(versionString); diff --git a/packages/angular/cli/test-esm-loader.mjs b/packages/angular/cli/test-esm-loader.mjs new file mode 100644 index 000000000000..200010ad19d4 --- /dev/null +++ b/packages/angular/cli/test-esm-loader.mjs @@ -0,0 +1,48 @@ +/** + * @license + * Copyright Google LLC All Rights Reserved. + * + * Use of this source code is governed by an MIT-style license that can be + * found in the LICENSE file at https://angular.dev/license + */ + +import { readFile } from 'node:fs/promises'; +import { register } from 'node:module'; +import { fileURLToPath } from 'node:url'; + +if (!globalThis.__angularCliTestEsmHookRegistered) { + globalThis.__angularCliTestEsmHookRegistered = true; + register(import.meta.url); +} + +export async function resolve(specifier, context, nextResolve) { + try { + const res = await nextResolve(specifier, context); + if (res.url.endsWith('.md')) { + return { ...res, format: 'module' }; + } + return res; + } catch (err) { + if (err && (err.code === 'ERR_MODULE_NOT_FOUND' || err.code === 'ERR_UNSUPPORTED_DIR_IMPORT')) { + for (const suffix of ['.js', '/index.js', '.json']) { + try { + return await nextResolve(specifier + suffix, context); + } catch {} + } + } + throw err; + } +} + +export async function load(url, context, nextLoad) { + if (url.endsWith('.md')) { + const content = await readFile(fileURLToPath(url), 'utf-8'); + return { + format: 'module', + shortCircuit: true, + source: `export default ${JSON.stringify(content)};`, + }; + } + + return nextLoad(url, context); +} diff --git a/packages/angular/cli/tsconfig-build.json b/packages/angular/cli/tsconfig-build.json new file mode 100644 index 000000000000..dc9987dba856 --- /dev/null +++ b/packages/angular/cli/tsconfig-build.json @@ -0,0 +1,9 @@ +{ + "extends": "../../../tsconfig-build.json", + "compilerOptions": { + "module": "preserve", + "moduleResolution": "bundler", + "target": "es2022", + "types": ["node"] + } +} diff --git a/packages/angular/cli/tsconfig-test.json b/packages/angular/cli/tsconfig-test.json new file mode 100644 index 000000000000..d275aef0a373 --- /dev/null +++ b/packages/angular/cli/tsconfig-test.json @@ -0,0 +1,6 @@ +{ + "extends": "./tsconfig-build.json", + "compilerOptions": { + "types": ["node", "jasmine"] + } +} From 69acf5b822bebc0b4bebd30f1db6cc7b8d624531 Mon Sep 17 00:00:00 2001 From: Charles Lyding <19598772+clydin@users.noreply.github.com> Date: Mon, 21 Sep 2026 11:40:15 -0400 Subject: [PATCH 495/787] fix(@angular/build): include dataurl option in global stylesheet config hash The global stylesheet configuration hash did not include the 'dataurl' option from 'BundleStylesheetOptions'. When persistent stylesheet caching is enabled, toggling or changing the 'dataurl' option should invalidate cached stylesheet bundles. --- .../esbuild/stylesheets/stylesheet-cache-key.ts | 2 ++ .../stylesheets/stylesheet-cache-key_spec.ts | 15 +++++++++++++++ 2 files changed, 17 insertions(+) diff --git a/packages/angular/build/src/tools/esbuild/stylesheets/stylesheet-cache-key.ts b/packages/angular/build/src/tools/esbuild/stylesheets/stylesheet-cache-key.ts index 22397ab189b3..d760a14197ec 100644 --- a/packages/angular/build/src/tools/esbuild/stylesheets/stylesheet-cache-key.ts +++ b/packages/angular/build/src/tools/esbuild/stylesheets/stylesheet-cache-key.ts @@ -26,6 +26,7 @@ import type { BundleStylesheetOptions } from './bundle-options'; * - `publicPath`: Affects relative asset URL rewriting (`url('...')`) inside CSS output. * - `outputNames`: Affects asset output filename hashing schemes. * - `inlineFonts`: Controls whether external web font `@import` / `` directives are inlined. + * - `dataurl`: Controls whether referenced assets are inlined as base64 data URIs. * - `preserveSymlinks`: Controls symlink realpath resolution in monorepos/pnpm workspace packages. * - `externalDependencies`: Controls which CSS modules/urls are excluded from bundling. * - `postcssConfig`: Path to custom PostCSS configuration file. @@ -56,6 +57,7 @@ export function calculateGlobalStylesheetConfigHash( publicPath: options.publicPath, outputNames: options.outputNames, inlineFonts: options.inlineFonts, + dataurl: options.dataurl ?? false, preserveSymlinks: options.preserveSymlinks, externalDependencies: options.externalDependencies, postcssConfig: options.postcssConfiguration?.configPath diff --git a/packages/angular/build/src/tools/esbuild/stylesheets/stylesheet-cache-key_spec.ts b/packages/angular/build/src/tools/esbuild/stylesheets/stylesheet-cache-key_spec.ts index c524a2d0c36b..49b232720fbf 100644 --- a/packages/angular/build/src/tools/esbuild/stylesheets/stylesheet-cache-key_spec.ts +++ b/packages/angular/build/src/tools/esbuild/stylesheets/stylesheet-cache-key_spec.ts @@ -70,5 +70,20 @@ describe('Stylesheet Global Config Hash', () => { ); expect(hash1).not.toBe(hash2); }); + + it('should produce different hashes when dataurl changes', () => { + const hash1 = calculateGlobalStylesheetConfigHash(baseOptions, '1.0.0'); + const hash2 = calculateGlobalStylesheetConfigHash({ ...baseOptions, dataurl: true }, '1.0.0'); + expect(hash1).not.toBe(hash2); + }); + + it('should produce the same hash when dataurl is undefined or false', () => { + const hash1 = calculateGlobalStylesheetConfigHash(baseOptions, '1.0.0'); + const hash2 = calculateGlobalStylesheetConfigHash( + { ...baseOptions, dataurl: false }, + '1.0.0', + ); + expect(hash1).toBe(hash2); + }); }); }); From 42eaa9779c88f75e24f7ceeae19da24bb1e0d741 Mon Sep 17 00:00:00 2001 From: Alan Agius <17563226+alan-agius4@users.noreply.github.com> Date: Fri, 18 Sep 2026 08:20:21 +0000 Subject: [PATCH 496/787] perf(@angular/build): only reset Sass worker pool caches when stylesheet files change --- .../angular/build/src/builders/application/build-action.ts | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/packages/angular/build/src/builders/application/build-action.ts b/packages/angular/build/src/builders/application/build-action.ts index 52e70ff87e99..b728ab9a8df5 100644 --- a/packages/angular/build/src/builders/application/build-action.ts +++ b/packages/angular/build/src/builders/application/build-action.ts @@ -158,7 +158,10 @@ export async function* runEsBuildBuildAction( // Clear removed files from current watch files changes.removed.forEach((removedPath) => currentWatchFiles.delete(removedPath)); - resetSassWorkerPoolCaches(); + const hasSassChanges = changes.all.some((f) => /\.(scss|sass|css)$/i.test(f)); + if (hasSassChanges) { + resetSassWorkerPoolCaches(); + } const rebuildState = result.createRebuildState(changes); result = await withProgress('Changes detected. Rebuilding...', () => action(rebuildState)); From 43aab6a1cf4f15e420c5fb8fe17ab38583d11c25 Mon Sep 17 00:00:00 2001 From: Charles Lyding <19598772+clydin@users.noreply.github.com> Date: Mon, 21 Sep 2026 12:25:56 -0400 Subject: [PATCH 497/787] fix(@angular/build): support parenthesized expressions in oxc linker Unwrap parenthesized expressions in `OxcAstHost` to ensure parity with Babel and prevent fatal linker errors when parsing functions returning parenthesized expressions (such as `resolveMetadata: () => ({ ... })` in deferred component metadata) and other parenthesized declaration properties. Fixes #34129 --- .../src/tools/angular/linker/oxc-ast-host.ts | 63 +++++++++++++--- .../tools/angular/linker/oxc-ast-host_spec.ts | 74 +++++++++++++++++++ .../tools/angular/linker/oxc-linker_spec.ts | 23 ++++++ 3 files changed, 149 insertions(+), 11 deletions(-) diff --git a/packages/angular/build/src/tools/angular/linker/oxc-ast-host.ts b/packages/angular/build/src/tools/angular/linker/oxc-ast-host.ts index 5a11959fff66..245443781601 100644 --- a/packages/angular/build/src/tools/angular/linker/oxc-ast-host.ts +++ b/packages/angular/build/src/tools/angular/linker/oxc-ast-host.ts @@ -26,11 +26,20 @@ function isNode(node: unknown): node is Node { return typeof node === 'object' && node !== null && 'type' in node; } +function unwrapParentheses(node: unknown): unknown { + while (isNode(node) && node.type === 'ParenthesizedExpression') { + node = node.expression; + } + + return node; +} + /** * An implementation of `AstHost` that queries information from `oxc-parser` AST nodes. */ export class OxcAstHost implements AstHost { getSymbolName(node: unknown): string | null { + node = unwrapParentheses(node); if (!isNode(node)) { return null; } @@ -47,10 +56,13 @@ export class OxcAstHost implements AstHost { } isStringLiteral(node: unknown): node is StringLiteral { + node = unwrapParentheses(node); + return isNode(node) && node.type === 'Literal' && typeof node.value === 'string'; } parseStringLiteral(str: unknown): string { + str = unwrapParentheses(str); if (!this.isStringLiteral(str)) { throw new FatalLinkerError(str as object, 'Unsupported syntax, expected a string literal.'); } @@ -59,10 +71,13 @@ export class OxcAstHost implements AstHost { } isNumericLiteral(node: unknown): node is NumericLiteral { + node = unwrapParentheses(node); + return isNode(node) && node.type === 'Literal' && typeof node.value === 'number'; } parseNumericLiteral(num: unknown): number { + num = unwrapParentheses(num); if (!this.isNumericLiteral(num)) { throw new FatalLinkerError(num as object, 'Unsupported syntax, expected a numeric literal.'); } @@ -71,6 +86,7 @@ export class OxcAstHost implements AstHost { } isBooleanLiteral(node: unknown): node is BooleanLiteral | UnaryExpression { + node = unwrapParentheses(node); if (!isNode(node)) { return false; } @@ -81,6 +97,7 @@ export class OxcAstHost implements AstHost { } parseBooleanLiteral(bool: unknown): boolean { + bool = unwrapParentheses(bool); if (isNode(bool)) { if (bool.type === 'Literal' && typeof bool.value === 'boolean') { return bool.value; @@ -94,14 +111,19 @@ export class OxcAstHost implements AstHost { } isNull(node: unknown): node is NullLiteral { + node = unwrapParentheses(node); + return isNode(node) && node.type === 'Literal' && node.value === null; } isArrayLiteral(node: unknown): node is ArrayExpression { + node = unwrapParentheses(node); + return isNode(node) && node.type === 'ArrayExpression'; } parseArrayLiteral(array: unknown): unknown[] { + array = unwrapParentheses(array); if (!this.isArrayLiteral(array)) { throw new FatalLinkerError(array as object, 'Unsupported syntax, expected an array literal.'); } @@ -115,23 +137,27 @@ export class OxcAstHost implements AstHost { 'Unsupported syntax, element in array not to be empty.', ); } - if (element.type === 'SpreadElement') { + const unwrappedElement = unwrapParentheses(element); + if (isNode(unwrappedElement) && unwrappedElement.type === 'SpreadElement') { throw new FatalLinkerError( - element as object, + unwrappedElement as object, 'Unsupported syntax, element in array not to use spread syntax.', ); } - result.push(element); + result.push(unwrappedElement); } return result; } isObjectLiteral(node: unknown): node is ObjectExpression { + node = unwrapParentheses(node); + return isNode(node) && node.type === 'ObjectExpression'; } parseObjectLiteral(obj: unknown): Map { + obj = unwrapParentheses(obj); if (!this.isObjectLiteral(obj)) { throw new FatalLinkerError(obj as object, 'Unsupported syntax, expected an object literal.'); } @@ -146,7 +172,13 @@ export class OxcAstHost implements AstHost { ); } - const keyNode = property.key; + const keyNode = unwrapParentheses(property.key); + if (!isNode(keyNode)) { + throw new FatalLinkerError( + property.key as object, + 'Unsupported syntax, expected a property name.', + ); + } let key: string; if (keyNode.type === 'Identifier') { @@ -162,13 +194,14 @@ export class OxcAstHost implements AstHost { ); } - result.set(key, property.value); + result.set(key, unwrapParentheses(property.value)); } return result; } isFunctionExpression(node: unknown): node is FunctionNode | ArrowFunctionExpression { + node = unwrapParentheses(node); if (!isNode(node)) { return false; } @@ -181,6 +214,7 @@ export class OxcAstHost implements AstHost { } parseReturnValue(fn: unknown): unknown { + fn = unwrapParentheses(fn); if (!this.isFunctionExpression(fn)) { throw new FatalLinkerError(fn as object, 'Unsupported syntax, expected a function.'); } @@ -191,7 +225,7 @@ export class OxcAstHost implements AstHost { } if (body.type !== 'BlockStatement') { - return body; + return unwrapParentheses(body); } const statements = body.body; @@ -217,10 +251,11 @@ export class OxcAstHost implements AstHost { ); } - return stmt.argument; + return unwrapParentheses(stmt.argument); } parseParameters(fn: unknown): unknown[] { + fn = unwrapParentheses(fn); if (!this.isFunctionExpression(fn)) { throw new FatalLinkerError(fn as object, 'Unsupported syntax, expected a function.'); } @@ -229,18 +264,22 @@ export class OxcAstHost implements AstHost { } isCallExpression(node: unknown): node is CallExpression { + node = unwrapParentheses(node); + return isNode(node) && node.type === 'CallExpression'; } parseCallee(call: unknown): unknown { + call = unwrapParentheses(call); if (!this.isCallExpression(call)) { throw new FatalLinkerError(call as object, 'Unsupported syntax, expected a call expression.'); } - return call.callee; + return unwrapParentheses(call.callee); } parseArguments(call: unknown): unknown[] { + call = unwrapParentheses(call); if (!this.isCallExpression(call)) { throw new FatalLinkerError(call as object, 'Unsupported syntax, expected a call expression.'); } @@ -248,19 +287,21 @@ export class OxcAstHost implements AstHost { const result: unknown[] = []; for (const arg of call.arguments) { - if (arg.type === 'SpreadElement') { + const unwrappedArg = unwrapParentheses(arg); + if (isNode(unwrappedArg) && unwrappedArg.type === 'SpreadElement') { throw new FatalLinkerError( - arg as object, + unwrappedArg as object, 'Unsupported syntax, argument not to use spread syntax.', ); } - result.push(arg); + result.push(unwrappedArg); } return result; } getRange(node: unknown): Range { + node = unwrapParentheses(node); if (!isNode(node) || typeof node.start !== 'number' || typeof node.end !== 'number') { throw new FatalLinkerError( node as object, diff --git a/packages/angular/build/src/tools/angular/linker/oxc-ast-host_spec.ts b/packages/angular/build/src/tools/angular/linker/oxc-ast-host_spec.ts index 79027584066d..cbe0d6a25292 100644 --- a/packages/angular/build/src/tools/angular/linker/oxc-ast-host_spec.ts +++ b/packages/angular/build/src/tools/angular/linker/oxc-ast-host_spec.ts @@ -34,11 +34,13 @@ describe('OxcAstHost', () => { it('should return the name of an identifier', () => { const expr = parseExpression('foo'); expect(host.getSymbolName(expr)).toBe('foo'); + expect(host.getSymbolName(parseExpression('(foo)'))).toBe('foo'); }); it('should return the property name of a member expression', () => { const expr = parseExpression('foo.bar'); expect(host.getSymbolName(expr)).toBe('bar'); + expect(host.getSymbolName(parseExpression('(foo.bar)'))).toBe('bar'); }); it('should return null for non-identifier or computed member expressions', () => { @@ -53,6 +55,10 @@ describe('OxcAstHost', () => { const expr = parseExpression('"hello"'); expect(host.isStringLiteral(expr)).toBe(true); expect(host.parseStringLiteral(expr)).toBe('hello'); + + const parenthesized = parseExpression('("hello")'); + expect(host.isStringLiteral(parenthesized)).toBe(true); + expect(host.parseStringLiteral(parenthesized)).toBe('hello'); }); it('should throw when parsing non-string literals', () => { @@ -67,6 +73,10 @@ describe('OxcAstHost', () => { const expr = parseExpression('123'); expect(host.isNumericLiteral(expr)).toBe(true); expect(host.parseNumericLiteral(expr)).toBe(123); + + const parenthesized = parseExpression('(123)'); + expect(host.isNumericLiteral(parenthesized)).toBe(true); + expect(host.parseNumericLiteral(parenthesized)).toBe(123); }); it('should throw when parsing non-numeric literals', () => { @@ -84,6 +94,10 @@ describe('OxcAstHost', () => { expect(host.parseBooleanLiteral(trueExpr)).toBe(true); expect(host.isBooleanLiteral(falseExpr)).toBe(true); expect(host.parseBooleanLiteral(falseExpr)).toBe(false); + + const parenthesizedTrue = parseExpression('(true)'); + expect(host.isBooleanLiteral(parenthesizedTrue)).toBe(true); + expect(host.parseBooleanLiteral(parenthesizedTrue)).toBe(true); }); it('should recognize and parse minified boolean literals (!0 and !1)', () => { @@ -93,6 +107,10 @@ describe('OxcAstHost', () => { expect(host.parseBooleanLiteral(trueExpr)).toBe(true); expect(host.isBooleanLiteral(falseExpr)).toBe(true); expect(host.parseBooleanLiteral(falseExpr)).toBe(false); + + const parenthesizedMinified = parseExpression('(!0)'); + expect(host.isBooleanLiteral(parenthesizedMinified)).toBe(true); + expect(host.parseBooleanLiteral(parenthesizedMinified)).toBe(true); }); it('should return false for invalid boolean expressions', () => { @@ -106,6 +124,18 @@ describe('OxcAstHost', () => { const expr = parseExpression('[1, "a", true]'); expect(host.isArrayLiteral(expr)).toBe(true); expect(host.parseArrayLiteral(expr).length).toBe(3); + + const parenthesized = parseExpression('([1, "a", true])'); + expect(host.isArrayLiteral(parenthesized)).toBe(true); + expect(host.parseArrayLiteral(parenthesized).length).toBe(3); + }); + + it('should unwrap parenthesized elements in array literals', () => { + const expr = parseExpression('[(1), ("a")]'); + const elements = host.parseArrayLiteral(expr); + expect(elements.length).toBe(2); + expect(host.isNumericLiteral(elements[0])).toBe(true); + expect(host.isStringLiteral(elements[1])).toBe(true); }); it('should throw when array contains empty elements or spread syntax', () => { @@ -115,6 +145,9 @@ describe('OxcAstHost', () => { expect(() => host.parseArrayLiteral(parseExpression('[1, ...a]'))).toThrowError( FatalLinkerError, ); + expect(() => host.parseArrayLiteral(parseExpression('[1, ...(a)]'))).toThrowError( + FatalLinkerError, + ); }); }); @@ -130,6 +163,16 @@ describe('OxcAstHost', () => { expect(map.has('3')).toBe(true); }); + it('should recognize and parse parenthesized object literals', () => { + const expr = parseExpression('({ a: (1), b: ("c") })'); + expect(host.isObjectLiteral(expr)).toBe(true); + + const map = host.parseObjectLiteral(expr); + expect(map.size).toBe(2); + expect(host.isNumericLiteral(map.get('a'))).toBe(true); + expect(host.isStringLiteral(map.get('b'))).toBe(true); + }); + it('should throw when object literal contains spread or non-property assignments', () => { expect(() => host.parseObjectLiteral(parseExpression('{ ...a }'))).toThrowError( FatalLinkerError, @@ -147,6 +190,21 @@ describe('OxcAstHost', () => { expect(host.isNumericLiteral(returnValue)).toBe(true); }); + it('should parse parenthesized arrow functions and concise bodies returning parenthesized object literals', () => { + const expr = parseExpression('() => ({ a: 1 })'); + expect(host.isFunctionExpression(expr)).toBe(true); + + const returnValue = host.parseReturnValue(expr); + expect(host.isObjectLiteral(returnValue)).toBe(true); + const map = host.parseObjectLiteral(returnValue); + expect(map.has('a')).toBe(true); + + const wrappedArrow = parseExpression('((a) => (42))'); + expect(host.isFunctionExpression(wrappedArrow)).toBe(true); + expect(host.parseParameters(wrappedArrow).length).toBe(1); + expect(host.isNumericLiteral(host.parseReturnValue(wrappedArrow))).toBe(true); + }); + it('should parse return value from function with block statement containing single return', () => { const stmt = parseStatement('function foo(a) { return "hello"; }'); expect(host.isFunctionExpression(stmt)).toBe(true); @@ -155,6 +213,14 @@ describe('OxcAstHost', () => { expect(host.isStringLiteral(returnValue)).toBe(true); }); + it('should parse return value from function returning parenthesized expression', () => { + const stmt = parseStatement('function foo() { return ({ a: 1 }); }'); + expect(host.isFunctionExpression(stmt)).toBe(true); + + const returnValue = host.parseReturnValue(stmt); + expect(host.isObjectLiteral(returnValue)).toBe(true); + }); + it('should throw when function body has multiple statements or no return', () => { expect(() => host.parseReturnValue(parseStatement('function foo() { const x = 1; return x; }')), @@ -171,6 +237,14 @@ describe('OxcAstHost', () => { expect(host.isCallExpression(expr)).toBe(true); expect(host.getSymbolName(host.parseCallee(expr))).toBe('foo'); expect(host.parseArguments(expr).length).toBe(2); + + const parenthesized = parseExpression('((foo)((1), ("a")))'); + expect(host.isCallExpression(parenthesized)).toBe(true); + expect(host.getSymbolName(host.parseCallee(parenthesized))).toBe('foo'); + const args = host.parseArguments(parenthesized); + expect(args.length).toBe(2); + expect(host.isNumericLiteral(args[0])).toBe(true); + expect(host.isStringLiteral(args[1])).toBe(true); }); it('should throw when call expression arguments contain spread syntax', () => { diff --git a/packages/angular/build/src/tools/angular/linker/oxc-linker_spec.ts b/packages/angular/build/src/tools/angular/linker/oxc-linker_spec.ts index fa62c1c5ece1..467658eb1991 100644 --- a/packages/angular/build/src/tools/angular/linker/oxc-linker_spec.ts +++ b/packages/angular/build/src/tools/angular/linker/oxc-linker_spec.ts @@ -76,4 +76,27 @@ describe('oxc-linker', () => { expect(result.map?.version).toBe(3); expect(result.map?.sources).toContain('test.js'); }); + + it('should link ɵɵngDeclareClassMetadataAsync with parenthesized resolveMetadata return', () => { + const input = ` + import * as i0 from "@angular/core"; + export class DeferredFixture {} + i0.ɵɵngDeclareClassMetadataAsync({ + minVersion: "18.0.0", + version: "22.1.7", + ngImport: i0, + type: DeferredFixture, + resolveDeferredDeps: () => [], + resolveMetadata: () => ({ + decorators: [], + ctorParameters: null, + propDecorators: null, + }), + }); + `; + + const result = transform('test.js', input, { link: true, advancedOptimizations: false }); + expect(result.code).toContain('ɵsetClassMetadataAsync'); + expect(result.code).not.toContain('ɵɵngDeclareClassMetadataAsync'); + }); }); From cea7febe5203715a99346bfc6c2a157821952b7b Mon Sep 17 00:00:00 2001 From: Alan Agius <17563226+alan-agius4@users.noreply.github.com> Date: Tue, 22 Sep 2026 11:29:16 +0000 Subject: [PATCH 498/787] fix(@angular/build): execute setup file hooks for each spec file when coverage is enabled When code coverage is enabled with the Vitest runner, test entry points are served as a virtual one-line import stub (`import "./${outputPath}";`) so that the test files themselves can be excluded from coverage reports after sourcemap remapping. However, setup files configured via `setupFiles` were also treated as test entry points and served as virtual stubs. Because Vitest only invalidates the top-level setup module between spec files, the imported intermediate bundle was cached in `vite-node` after its initial evaluation and never re-evaluated on subsequent spec files. This caused setup file hooks (e.g. `beforeEach` / `afterEach`) to silently only run for the first spec file of each worker. This commit excludes setup files from being wrapped in the virtual coverage stub, allowing them to be directly evaluated and re-evaluated by Vitest before each spec file. Fixes #34137 --- .../unit-test/runners/vitest/executor.ts | 1 + .../unit-test/runners/vitest/plugins.ts | 14 ++++- .../tests/options/setup-files_spec.ts | 63 +++++++++++++++++++ 3 files changed, 76 insertions(+), 2 deletions(-) diff --git a/packages/angular/build/src/builders/unit-test/runners/vitest/executor.ts b/packages/angular/build/src/builders/unit-test/runners/vitest/executor.ts index fc64e432e19f..55003b4fc82a 100644 --- a/packages/angular/build/src/builders/unit-test/runners/vitest/executor.ts +++ b/packages/angular/build/src/builders/unit-test/runners/vitest/executor.ts @@ -333,6 +333,7 @@ export class VitestExecutor implements TestExecutor { projectName, buildResultFiles: this.buildResultFiles, testFileToEntryPoint: this.testFileToEntryPoint, + setupFiles: testSetupFiles, }); const debugOptions = debug diff --git a/packages/angular/build/src/builders/unit-test/runners/vitest/plugins.ts b/packages/angular/build/src/builders/unit-test/runners/vitest/plugins.ts index ee81e417bb5d..6be4c6e8ebe3 100644 --- a/packages/angular/build/src/builders/unit-test/runners/vitest/plugins.ts +++ b/packages/angular/build/src/builders/unit-test/runners/vitest/plugins.ts @@ -37,6 +37,7 @@ interface PluginOptions { projectName: string; buildResultFiles: ReadonlyMap; testFileToEntryPoint: ReadonlyMap; + setupFiles: readonly string[]; } type VitestCoverageOption = Exclude; @@ -313,8 +314,13 @@ async function loadResultFile(file: ResultFile): Promise { } export function createVitestPlugins(pluginOptions: PluginOptions): Vite.Plugin[] { - const { workspaceRoot, buildResultFiles, testFileToEntryPoint } = pluginOptions; + const { workspaceRoot, buildResultFiles, testFileToEntryPoint, setupFiles } = pluginOptions; const isWindows = platform() === 'win32'; + const setupFileSet = new Set( + setupFiles.map((file) => + toPosixPath(path.isAbsolute(file) ? file : path.join(workspaceRoot, file)), + ), + ); let vitestConfig: ResolvedConfig; return [ @@ -387,7 +393,11 @@ export function createVitestPlugins(pluginOptions: PluginOptions): Vite.Plugin[] if (entryPoint) { outputPath = entryPoint + '.js'; - if (vitestConfig?.coverage?.enabled) { + // Setup files must not be wrapped in a virtual import stub because Vitest only invalidates + // the setup file itself between test files; wrapping it would cause the underlying bundle + // to be cached, preventing per-test hooks from running on subsequent test files. + const isSetupFile = setupFileSet.has(id); + if (vitestConfig?.coverage?.enabled && !isSetupFile) { // To support coverage exclusion of the actual test file, the virtual // test entry point only references the built and bundled intermediate file. // If vitest supported an "excludeOnlyAfterRemap" option, this could be removed completely. diff --git a/packages/angular/build/src/builders/unit-test/tests/options/setup-files_spec.ts b/packages/angular/build/src/builders/unit-test/tests/options/setup-files_spec.ts index 65d0dadf17b8..44241bbcfd8a 100644 --- a/packages/angular/build/src/builders/unit-test/tests/options/setup-files_spec.ts +++ b/packages/angular/build/src/builders/unit-test/tests/options/setup-files_spec.ts @@ -54,5 +54,68 @@ describeBuilder(execute, UNIT_TEST_BUILDER_INFO, (harness) => { const { result } = await harness.executeOnce(); expect(result?.success).toBeTrue(); }); + + it('should run setup file hooks for each spec file when coverage is enabled', async () => { + await harness.writeFiles({ + 'custom-vitest.config.mts': ` + import { defineConfig } from 'vitest/config'; + + export default defineConfig({ + test: { + fileParallelism: false, + }, + }); + `, + 'src/setup.ts': ` + import { afterEach, beforeEach, expect } from 'vitest'; + const global = globalThis as typeof globalThis & { + setupHookCalls?: string[]; + }; + const setupHookCalls = (global.setupHookCalls ??= []); + beforeEach(() => { + const testName = expect.getState().currentTestName ?? ''; + setupHookCalls.push('beforeEach:' + testName); + }); + afterEach(() => { + const testName = expect.getState().currentTestName ?? ''; + setupHookCalls.push('afterEach:' + testName); + }); + `, + 'src/app/app.component.spec.ts': ` + import { expect, it } from 'vitest'; + it('runs setup hooks for first test in app.component.spec', () => { + const global = globalThis as typeof globalThis & { setupHookCalls?: string[] }; + expect(global.setupHookCalls).toContain('beforeEach:runs setup hooks for first test in app.component.spec'); + }); + it('runs setup hooks for second test in app.component.spec', () => { + const global = globalThis as typeof globalThis & { setupHookCalls?: string[] }; + expect(global.setupHookCalls).toContain('beforeEach:runs setup hooks for second test in app.component.spec'); + expect(global.setupHookCalls).toContain('afterEach:runs setup hooks for first test in app.component.spec'); + }); + `, + 'src/app/second.spec.ts': ` + import { expect, it } from 'vitest'; + it('runs setup hooks for first test in second.spec', () => { + const global = globalThis as typeof globalThis & { setupHookCalls?: string[] }; + expect(global.setupHookCalls).toContain('beforeEach:runs setup hooks for first test in second.spec'); + }); + it('runs setup hooks for second test in second.spec', () => { + const global = globalThis as typeof globalThis & { setupHookCalls?: string[] }; + expect(global.setupHookCalls).toContain('beforeEach:runs setup hooks for second test in second.spec'); + expect(global.setupHookCalls).toContain('afterEach:runs setup hooks for first test in second.spec'); + }); + `, + }); + + harness.useTarget('test', { + ...BASE_OPTIONS, + coverage: true, + runnerConfig: 'custom-vitest.config.mts', + setupFiles: ['src/setup.ts'], + }); + + const { result } = await harness.executeOnce(); + expect(result?.success).toBeTrue(); + }); }); }); From 5e0537350725027d0eeb2f09c4823acb870a589b Mon Sep 17 00:00:00 2001 From: Alan Agius <17563226+alan-agius4@users.noreply.github.com> Date: Tue, 22 Sep 2026 14:43:38 +0000 Subject: [PATCH 499/787] fix(@angular/build): only compile included test files in unit-test builder When running the `unit-test` builder with `--include`, TypeScript compilation previously compiled all test files matched by the tsconfig file, causing compilation errors in unrelated test files to fail the test run. This change introduces a `rootFiles` option that restricts the TypeScript program's root files to only the test files to be executed (plus setup files and providers), while preserving ambient `.d.ts` declaration files discovered by `readConfiguration`. Fixes #34089 --- .../build/src/builders/application/options.ts | 7 +++++ .../unit-test/runners/vitest/build-options.ts | 22 ++++++++++++--- .../unit-test/tests/options/include_spec.ts | 27 +++++++++++++++++++ .../angular/compilation/compiler-options.ts | 1 + .../compilation/typescript-compilation.ts | 17 ++++++++++-- .../tools/esbuild/angular/compiler-plugin.ts | 5 ++++ .../tools/esbuild/compiler-plugin-options.ts | 2 ++ 7 files changed, 76 insertions(+), 5 deletions(-) diff --git a/packages/angular/build/src/builders/application/options.ts b/packages/angular/build/src/builders/application/options.ts index 785d07371d93..f7e60f4cc029 100644 --- a/packages/angular/build/src/builders/application/options.ts +++ b/packages/angular/build/src/builders/application/options.ts @@ -138,6 +138,11 @@ interface InternalOptions { * there. Used exclusively for tests and shouldn't be used for other kinds of builds. */ disableCodeSplitting?: boolean; + + /** + * An array of files to restrict the TypeScript compilation root names to. + */ + rootFiles?: string[]; } /** Full set of options for `application` builder. */ @@ -447,6 +452,7 @@ export async function normalizeOptions( verbose, watch, progress = true, + rootFiles, externalPackages, namedChunks, budgets, @@ -494,6 +500,7 @@ export async function normalizeOptions( workspaceRoot, entryPoints, disableCodeSplitting, + rootFiles: rootFiles?.map((file: string) => path.resolve(workspaceRoot, file)), optimizationOptions, outputOptions, outExtension, diff --git a/packages/angular/build/src/builders/unit-test/runners/vitest/build-options.ts b/packages/angular/build/src/builders/unit-test/runners/vitest/build-options.ts index 9c5abb9386bf..622ca7beebd3 100644 --- a/packages/angular/build/src/builders/unit-test/runners/vitest/build-options.ts +++ b/packages/angular/build/src/builders/unit-test/runners/vitest/build-options.ts @@ -198,7 +198,15 @@ export async function getVitestBuildOptions( options: NormalizedUnitTestBuilderOptions, baseBuildOptions: Partial, ): Promise { - const { workspaceRoot, projectSourceRoot, include, exclude = [], watch, providersFile } = options; + const { + workspaceRoot, + projectSourceRoot, + include, + exclude = [], + watch, + providersFile, + setupFiles, + } = options; // Find test files const testFiles = await findTests(include, exclude, workspaceRoot, projectSourceRoot); @@ -217,8 +225,15 @@ export async function getVitestBuildOptions( removeTestExtension: true, }); - if (options.setupFiles?.length) { - const setupEntryPoints = getTestEntrypoints(options.setupFiles, { + const rootFiles = [...testFiles]; + if (providersFile) { + rootFiles.push(providersFile); + } + + if (setupFiles?.length) { + rootFiles.push(...setupFiles); + + const setupEntryPoints = getTestEntrypoints(setupFiles, { projectSourceRoot, workspaceRoot, removeTestExtension: false, @@ -258,6 +273,7 @@ export async function getVitestBuildOptions( optimization: false, namedChunks: false, entryPoints, + rootFiles, // Vitest's Node-based module loading emulation (vite-node) is not fully spec compliant and lacks // live ESM bindings across chunk boundaries. This can cause uninitialized exports or break mocking. // Disabling code splitting avoids shared chunks, but increases build and coverage memory/time. diff --git a/packages/angular/build/src/builders/unit-test/tests/options/include_spec.ts b/packages/angular/build/src/builders/unit-test/tests/options/include_spec.ts index f1cdd4a14f0b..d3d4e19a30f9 100644 --- a/packages/angular/build/src/builders/unit-test/tests/options/include_spec.ts +++ b/packages/angular/build/src/builders/unit-test/tests/options/include_spec.ts @@ -83,5 +83,32 @@ describeBuilder(execute, UNIT_TEST_BUILDER_INFO, (harness) => { expect(result?.success).toBeTrue(); }); }); + + it('should ignore TypeScript compilation errors in non-included test files', async () => { + await harness.writeFiles({ + 'src/app/services/test.service.spec.ts': ` + describe('TestService', () => { + it('should succeed', () => { + expect(true).toBe(true); + }); + });`, + 'src/app/broken.service.spec.ts': ` + // This test has a TypeScript type error that would fail compilation if compiled + const invalidNumber: number = 'not a number'; + describe('BrokenService', () => { + it('should fail compilation', () => { + expect(invalidNumber).toBe(1); + }); + });`, + }); + + harness.useTarget('test', { + ...BASE_OPTIONS, + include: ['src/app/services/test.service.spec.ts'], + }); + + const { result } = await harness.executeOnce(); + expect(result?.success).toBeTrue(); + }); }); }); diff --git a/packages/angular/build/src/tools/angular/compilation/compiler-options.ts b/packages/angular/build/src/tools/angular/compilation/compiler-options.ts index bb8c494f2213..45af80eae6d3 100644 --- a/packages/angular/build/src/tools/angular/compilation/compiler-options.ts +++ b/packages/angular/build/src/tools/angular/compilation/compiler-options.ts @@ -20,6 +20,7 @@ export interface CompilerOptionOverrides { instrumentForCoverage?: boolean; includeTestMetadata?: boolean; customConditions?: string[]; + rootFiles?: string[]; } export function transformCompilerOptions( diff --git a/packages/angular/build/src/tools/angular/compilation/typescript-compilation.ts b/packages/angular/build/src/tools/angular/compilation/typescript-compilation.ts index 05403b728fda..48975b672154 100644 --- a/packages/angular/build/src/tools/angular/compilation/typescript-compilation.ts +++ b/packages/angular/build/src/tools/angular/compilation/typescript-compilation.ts @@ -9,7 +9,7 @@ import type * as ng from '@angular/compiler-cli'; import type { PartialMessage } from 'esbuild'; import ts from 'typescript'; -import { toPosixPath } from '../../../utils/path'; +import { canonicalizePath, toPosixPath } from '../../../utils/path'; import { profileAsync, profileSync } from '../../../utils/profiling'; import { AngularCompilation, DiagnosticModes } from './angular-compilation'; import { type CompilerOptionOverrides, transformCompilerOptions } from './compiler-options'; @@ -39,7 +39,7 @@ export abstract class TypeScriptCompilation extends AngularCompilation { const { options: originalCompilerOptions, - rootNames, + rootNames: originalRootNames, errors, } = profileSync('NG_READ_CONFIG', () => readConfiguration(tsconfig, { @@ -60,6 +60,19 @@ export abstract class TypeScriptCompilation extends AngularCompilation { }), ); + let rootNames = originalRootNames; + if (compilerOptionOverrides?.rootFiles?.length) { + const rootFilesSet = new Set( + compilerOptionOverrides.rootFiles.map((file) => canonicalizePath(toPosixPath(file))), + ); + for (const file of originalRootNames) { + if (/\.d\.[cm]?ts$/i.test(file)) { + rootFilesSet.add(canonicalizePath(toPosixPath(file))); + } + } + rootNames = [...rootFilesSet]; + } + const { compilerOptions, warnings } = transformCompilerOptions( ts, originalCompilerOptions, diff --git a/packages/angular/build/src/tools/esbuild/angular/compiler-plugin.ts b/packages/angular/build/src/tools/esbuild/angular/compiler-plugin.ts index a9c71e8db888..9a36eea56d61 100644 --- a/packages/angular/build/src/tools/esbuild/angular/compiler-plugin.ts +++ b/packages/angular/build/src/tools/esbuild/angular/compiler-plugin.ts @@ -61,6 +61,7 @@ export interface CompilerPluginOptions { externalRuntimeStyles?: boolean; instrumentForCoverage?: (request: string) => boolean; templateUpdates?: Map; + rootFiles?: string[]; } // eslint-disable-next-line max-lines-per-function @@ -329,17 +330,21 @@ export function createCompilerPlugin( instrumentForCoverage: !!pluginOptions.instrumentForCoverage, includeTestMetadata: !!pluginOptions.includeTestMetadata, customConditions: build.initialOptions.conditions, + rootFiles: pluginOptions.rootFiles, }, ); + if (initializationResult.warnings?.length) { setupWarnings?.push(...initializationResult.warnings); } + angularCompilationContext.setCompilerOptions(initializationResult.compilerOptions); shouldTsIgnoreJs = !initializationResult.compilerOptions.allowJs; useTypeScriptTranspilation = !!initializationResult.compilerOptions['_useTypeScriptTranspilation']; referencedFiles = initializationResult.referencedFiles; externalStylesheets = initializationResult.externalStylesheets; + if (initializationResult.templateUpdates) { // Propagate any template updates initializationResult.templateUpdates.forEach((value, key) => diff --git a/packages/angular/build/src/tools/esbuild/compiler-plugin-options.ts b/packages/angular/build/src/tools/esbuild/compiler-plugin-options.ts index 04ce3ef94f4a..573b8616da60 100644 --- a/packages/angular/build/src/tools/esbuild/compiler-plugin-options.ts +++ b/packages/angular/build/src/tools/esbuild/compiler-plugin-options.ts @@ -28,6 +28,7 @@ export function createCompilerPluginOptions( externalRuntimeStyles, instrumentForCoverage, optimizationOptions, + rootFiles, } = options; const incremental = !!options.watch; @@ -45,5 +46,6 @@ export function createCompilerPluginOptions( instrumentForCoverage, templateUpdates, includeTestMetadata: !optimizationOptions.scripts, + rootFiles, }; } From f52fb536a1fddabee42448a050961c7986314992 Mon Sep 17 00:00:00 2001 From: Charles Lyding <19598772+clydin@users.noreply.github.com> Date: Tue, 22 Sep 2026 11:35:31 -0400 Subject: [PATCH 500/787] fix(@angular/cli): decouple official Node.js support check from execution gate The `isNodeVersionSupported` function strictly validates whether a Node.js runtime matches an officially supported LTS track (such as `^22.22.3`, `^24.15.0`, or `^26.0.0`). Non-LTS odd releases (Node 23, 25) and uncertified newer releases (Node 27, 28+) return `false`, ensuring that `ng version` accurately marks them as unsupported. The `isNodeVersionRunnable` function dynamically determines whether an unsupported runtime can safely execute the CLI by checking if the major is an odd release between the minimum and maximum supported versions or higher than the maximum supported LTS major. The `bin/ng.js` bootstrap script now warns and continues execution on runnable unsupported runtimes instead of hardcoding specific major versions or aborting execution with an exit code of 3. --- packages/angular/cli/bin/ng.js | 15 ++- packages/angular/cli/bin/version.js | 48 ++++++++-- packages/angular/cli/src/typings.d.ts | 9 +- .../angular/cli/src/utilities/node-version.ts | 20 +++- .../cli/src/utilities/node-version_spec.ts | 96 +++++++++++++++++++ 5 files changed, 166 insertions(+), 22 deletions(-) create mode 100644 packages/angular/cli/src/utilities/node-version_spec.ts diff --git a/packages/angular/cli/bin/ng.js b/packages/angular/cli/bin/ng.js index a95f51b8def4..d503fb895f5f 100755 --- a/packages/angular/cli/bin/ng.js +++ b/packages/angular/cli/bin/ng.js @@ -43,20 +43,19 @@ if (rawCommandName === '--get-yargs-completions' || rawCommandName === 'completi // This node version check ensures that extremely old versions of node are not used. // These may not support ES2015 features such as const/let/async/await/etc. // These would then crash with a hard to diagnose error message. -const [major] = process.versions.node.split('.', 1).map((part) => Number(part)); - -if (major === 23 || major === 25) { - // Allow new odd numbered releases with a warning. +if (nodeUtils.isNodeVersionSupported()) { + require('./bootstrap'); +} else if (nodeUtils.isNodeVersionRunnable()) { console.warn( 'Node.js version ' + process.version + ' detected.\n' + - 'Prior to version 27, odd numbered Node.js versions will not enter LTS status and should not be used for production.' + - ' For more information, please see https://nodejs.org/en/about/previous-releases/.', + 'The Angular CLI has not been officially tested on this Node.js version and it is not supported for production use.\n' + + 'For more information, please see https://nodejs.org/en/about/previous-releases/.', ); require('./bootstrap'); -} else if (!nodeUtils.isNodeVersionSupported()) { +} else { // Error and exit if less than the supported versions. console.error( 'Node.js version ' + @@ -69,6 +68,4 @@ if (major === 23 || major === 25) { ); process.exitCode = 3; -} else { - require('./bootstrap'); } diff --git a/packages/angular/cli/bin/version.js b/packages/angular/cli/bin/version.js index 38edd4e299c7..1755c1ed55c8 100644 --- a/packages/angular/cli/bin/version.js +++ b/packages/angular/cli/bin/version.js @@ -27,21 +27,24 @@ var supportedNodeVersions = SUPPORTED_NODE_VERSIONS.replace(/[\^~<>=]/g, '') }); /** - * Checks if the current Node.js version is supported. - * @returns `true` if the current Node.js version is supported, `false` otherwise. + * Checks if the current Node.js version is officially supported. + * @param {string} [currentVersion] Optional Node.js version string to check. Defaults to `process.versions.node`. + * @param {string[]} [supportedVersions] Optional supported versions array. Defaults to `supportedNodeVersions`. + * @returns {boolean} `true` if the current Node.js version is officially supported, `false` otherwise. */ -function isNodeVersionSupported() { - if (SUPPORTED_NODE_VERSIONS.charAt(0) === '0') { +function isNodeVersionSupported(currentVersion, supportedVersions) { + if (SUPPORTED_NODE_VERSIONS.charAt(0) === '0' && !supportedVersions && !currentVersion) { return true; } - var parts = process.versions.node.split('.', 3).map(Number); + var parts = (currentVersion || process.versions.node).split('.', 3).map(Number); var processMajor = parts[0]; var processMinor = parts[1]; var processPatch = parts[2]; - for (var i = 0; i < supportedNodeVersions.length; i++) { - var vParts = supportedNodeVersions[i].split('.', 3).map(Number); + var versions = supportedVersions || supportedNodeVersions; + for (var i = 0; i < versions.length; i++) { + var vParts = versions[i].split('.', 3).map(Number); var major = vParts[0]; var minor = vParts[1]; var patch = vParts[2]; @@ -56,9 +59,40 @@ function isNodeVersionSupported() { return false; } +/** + * Checks if the current Node.js version is runnable (newer than supported LTS or an interim odd release). + * @param {string} [currentVersion] Optional Node.js version string to check. Defaults to `process.versions.node`. + * @param {string[]} [supportedVersions] Optional supported versions array. Defaults to `supportedNodeVersions`. + * @returns {boolean} `true` if the current Node.js version is runnable, `false` otherwise. + */ +function isNodeVersionRunnable(currentVersion, supportedVersions) { + if (SUPPORTED_NODE_VERSIONS.charAt(0) === '0' && !supportedVersions && !currentVersion) { + return false; + } + + var processMajor = Number((currentVersion || process.versions.node).split('.', 1)[0]); + var versions = supportedVersions || supportedNodeVersions; + + var minMajor = Number(versions[0].split('.', 1)[0]); + var maxMajor = Number(versions[versions.length - 1].split('.', 1)[0]); + + // Versions newer than the maximum supported major (e.g. Node 27, 28+) + if (processMajor > maxMajor) { + return true; + } + + // Odd-numbered interim releases between min and max (e.g. Node 23, 25) + if (processMajor > minMajor && processMajor % 2 === 1) { + return true; + } + + return false; +} + module.exports = { VERSION: VERSION, SUPPORTED_NODE_VERSIONS: SUPPORTED_NODE_VERSIONS, supportedNodeVersions: supportedNodeVersions, isNodeVersionSupported: isNodeVersionSupported, + isNodeVersionRunnable: isNodeVersionRunnable, }; diff --git a/packages/angular/cli/src/typings.d.ts b/packages/angular/cli/src/typings.d.ts index 948d7b1d2280..43b81c1b0229 100644 --- a/packages/angular/cli/src/typings.d.ts +++ b/packages/angular/cli/src/typings.d.ts @@ -15,5 +15,12 @@ declare module '#version' { export const VERSION: string; export const SUPPORTED_NODE_VERSIONS: string; export const supportedNodeVersions: string[]; - export function isNodeVersionSupported(): boolean; + export function isNodeVersionSupported( + currentVersion?: string, + supportedVersions?: string[], + ): boolean; + export function isNodeVersionRunnable( + currentVersion?: string, + supportedVersions?: string[], + ): boolean; } diff --git a/packages/angular/cli/src/utilities/node-version.ts b/packages/angular/cli/src/utilities/node-version.ts index 18f06b960369..87eb4fa377b6 100644 --- a/packages/angular/cli/src/utilities/node-version.ts +++ b/packages/angular/cli/src/utilities/node-version.ts @@ -13,22 +13,32 @@ import { SUPPORTED_NODE_VERSIONS, supportedNodeVersions } from '#version'; -export { SUPPORTED_NODE_VERSIONS, supportedNodeVersions, isNodeVersionSupported } from '#version'; +export { + SUPPORTED_NODE_VERSIONS, + supportedNodeVersions, + isNodeVersionSupported, + isNodeVersionRunnable, +} from '#version'; /** * Checks if the current Node.js version is the minimum supported version. + * @param currentVersion Optional Node.js version string to check. Defaults to `process.versions.node`. + * @param supportedVersions Optional supported versions array. Defaults to `supportedNodeVersions`. * @returns `true` if the current Node.js version is the minimum supported version, `false` otherwise. */ -export function isNodeVersionMinSupported(): boolean { - if (SUPPORTED_NODE_VERSIONS.charAt(0) === '0') { +export function isNodeVersionMinSupported( + currentVersion = process.versions.node, + supportedVersions = supportedNodeVersions, +): boolean { + if (SUPPORTED_NODE_VERSIONS.charAt(0) === '0' && currentVersion === process.versions.node) { // Unlike `pkg_npm`, `ts_library` which is used to run unit tests does not support substitutions. return true; } - const [processMajor, processMinor, processPatch] = process.versions.node + const [processMajor, processMinor, processPatch] = currentVersion .split('.', 3) .map((part) => Number(part)); - const [major, minor, patch] = supportedNodeVersions[0].split('.', 3).map((part) => Number(part)); + const [major, minor, patch] = supportedVersions[0].split('.', 3).map((part) => Number(part)); return ( processMajor > major || diff --git a/packages/angular/cli/src/utilities/node-version_spec.ts b/packages/angular/cli/src/utilities/node-version_spec.ts new file mode 100644 index 000000000000..9426521faf65 --- /dev/null +++ b/packages/angular/cli/src/utilities/node-version_spec.ts @@ -0,0 +1,96 @@ +/** + * @license + * Copyright Google LLC All Rights Reserved. + * + * Use of this source code is governed by an MIT-style license that can be + * found in the LICENSE file at https://angular.dev/license + */ + +import { + isNodeVersionMinSupported, + isNodeVersionRunnable, + isNodeVersionSupported, +} from './node-version'; + +describe('node-version', () => { + const supportedVersions = ['22.22.3', '24.15.0', '26.0.0']; + + describe('isNodeVersionSupported', () => { + it('should accept valid LTS versions', () => { + expect(isNodeVersionSupported('22.22.3', supportedVersions)).toBeTrue(); + expect(isNodeVersionSupported('22.23.0', supportedVersions)).toBeTrue(); + expect(isNodeVersionSupported('24.15.0', supportedVersions)).toBeTrue(); + expect(isNodeVersionSupported('24.16.0', supportedVersions)).toBeTrue(); + expect(isNodeVersionSupported('26.0.0', supportedVersions)).toBeTrue(); + expect(isNodeVersionSupported('26.1.0', supportedVersions)).toBeTrue(); + }); + + it('should reject versions below the minimum for a supported major', () => { + expect(isNodeVersionSupported('22.22.2', supportedVersions)).toBeFalse(); + expect(isNodeVersionSupported('22.0.0', supportedVersions)).toBeFalse(); + expect(isNodeVersionSupported('24.14.9', supportedVersions)).toBeFalse(); + expect(isNodeVersionSupported('20.18.0', supportedVersions)).toBeFalse(); + }); + + it('should reject odd-numbered major versions', () => { + expect(isNodeVersionSupported('23.0.0', supportedVersions)).toBeFalse(); + expect(isNodeVersionSupported('25.0.0', supportedVersions)).toBeFalse(); + }); + + it('should reject versions higher than the maximum supported LTS version', () => { + expect(isNodeVersionSupported('27.0.0', supportedVersions)).toBeFalse(); + expect(isNodeVersionSupported('28.0.0', supportedVersions)).toBeFalse(); + expect(isNodeVersionSupported('29.1.2', supportedVersions)).toBeFalse(); + }); + + it('should return true when unstamped (0.0.0-ENGINES-NODE)', () => { + expect(isNodeVersionSupported()).toBeTrue(); + }); + }); + + describe('isNodeVersionRunnable', () => { + it('should allow odd-numbered interim releases between min and max major', () => { + expect(isNodeVersionRunnable('23.0.0', supportedVersions)).toBeTrue(); + expect(isNodeVersionRunnable('25.0.0', supportedVersions)).toBeTrue(); + }); + + it('should allow versions higher than the maximum supported major', () => { + expect(isNodeVersionRunnable('27.0.0', supportedVersions)).toBeTrue(); + expect(isNodeVersionRunnable('28.0.0', supportedVersions)).toBeTrue(); + expect(isNodeVersionRunnable('29.1.2', supportedVersions)).toBeTrue(); + }); + + it('should return false for supported LTS versions', () => { + expect(isNodeVersionRunnable('22.22.3', supportedVersions)).toBeFalse(); + expect(isNodeVersionRunnable('24.15.0', supportedVersions)).toBeFalse(); + expect(isNodeVersionRunnable('26.0.0', supportedVersions)).toBeFalse(); + }); + + it('should return false for versions below the minimum major', () => { + expect(isNodeVersionRunnable('18.0.0', supportedVersions)).toBeFalse(); + expect(isNodeVersionRunnable('20.0.0', supportedVersions)).toBeFalse(); + expect(isNodeVersionRunnable('21.0.0', supportedVersions)).toBeFalse(); + }); + + it('should return false for outdated minors of supported majors', () => { + expect(isNodeVersionRunnable('22.0.0', supportedVersions)).toBeFalse(); + expect(isNodeVersionRunnable('24.10.0', supportedVersions)).toBeFalse(); + }); + }); + + describe('isNodeVersionMinSupported', () => { + it('should accept versions at or above the minimum supported version', () => { + expect(isNodeVersionMinSupported('22.22.3', supportedVersions)).toBeTrue(); + expect(isNodeVersionMinSupported('22.25.0', supportedVersions)).toBeTrue(); + expect(isNodeVersionMinSupported('23.0.0', supportedVersions)).toBeTrue(); + expect(isNodeVersionMinSupported('24.0.0', supportedVersions)).toBeTrue(); + expect(isNodeVersionMinSupported('28.0.0', supportedVersions)).toBeTrue(); + }); + + it('should reject versions below the minimum supported version', () => { + expect(isNodeVersionMinSupported('22.22.2', supportedVersions)).toBeFalse(); + expect(isNodeVersionMinSupported('20.0.0', supportedVersions)).toBeFalse(); + expect(isNodeVersionMinSupported('18.19.0', supportedVersions)).toBeFalse(); + }); + }); +}); From ed52db253ffb98ad7b591fbb53ed5e1d54850828 Mon Sep 17 00:00:00 2001 From: rk Date: Fri, 18 Sep 2026 15:39:58 +0500 Subject: [PATCH 501/787] fix(@angular/build): scope Sass package resolution caching for stylesheets in node_modules Package specifiers were cached without any qualification, so the resolution made for one stylesheet was reused for every other stylesheet in the build. A dependency within `node_modules` that has its own nested version of a package received the version resolved for the application, the application received the nested version when the dependency was compiled first, and a failed resolution was reused for a dependency that is able to resolve the package. Which of these occurred depended on the order the stylesheets were compiled in. Package resolutions and package roots are now qualified with a scope. A stylesheet within `node_modules` uses the root of its enclosing package as the scope, so every file of a package shares one resolution while nested dependency versions stay isolated. All other stylesheets use the working directory of the build, so the component stylesheets of an application continue to share a single resolution. The scope is derived from the path of the stylesheet alone and requires no file system access. A containing URL that does not use the `file:` scheme is resolved from the working directory instead of causing an error. --- .../esbuild/stylesheets/sass-language.ts | 62 ++++- .../esbuild/stylesheets/sass-language_spec.ts | 243 +++++++++++++++++- 2 files changed, 290 insertions(+), 15 deletions(-) diff --git a/packages/angular/build/src/tools/esbuild/stylesheets/sass-language.ts b/packages/angular/build/src/tools/esbuild/stylesheets/sass-language.ts index b519a408bfb8..432ae7ba79b8 100644 --- a/packages/angular/build/src/tools/esbuild/stylesheets/sass-language.ts +++ b/packages/angular/build/src/tools/esbuild/stylesheets/sass-language.ts @@ -9,7 +9,7 @@ import type { OnLoadResult, PartialMessage, PartialNote, ResolveResult } from 'esbuild'; import { dirname, join } from 'node:path'; import { fileURLToPath, pathToFileURL } from 'node:url'; -import type { CanonicalizeContext, CompileResult, Exception, Syntax } from 'sass-embedded'; +import type { CompileResult, Exception, Syntax } from 'sass-embedded'; import { MemoryCache } from '../../../utils/cache'; import type { SassCompiler } from '../../sass/sass-service'; import { StylesheetLanguage, StylesheetPluginOptions } from './stylesheet-plugin-factory'; @@ -50,12 +50,7 @@ export const SassStylesheetLanguage = Object.freeze({ fileFilter: /\.s[ac]ss$/, process(data, file, format, options, build) { const syntax = format === 'sass' ? 'indented' : 'scss'; - const resolveUrl = async (url: string, options: CanonicalizeContext) => { - let resolveDir = build.initialOptions.absWorkingDir; - if (options.containingUrl) { - resolveDir = dirname(fileURLToPath(options.containingUrl)); - } - + const resolveUrl = async (url: string, resolveDir: string | undefined) => { const path = url.startsWith('pkg:') ? url.slice(4) : url; const result = await build.resolve(path, { kind: 'import-rule', @@ -65,7 +60,14 @@ export const SassStylesheetLanguage = Object.freeze({ return result; }; - return compileString(data, file, syntax, options, resolveUrl); + return compileString( + data, + file, + syntax, + options, + resolveUrl, + build.initialOptions.absWorkingDir, + ); }, }); @@ -97,12 +99,35 @@ function parsePackageName(url: string): { packageName: string; readonly pathSegm }; } +/** + * Returns the scope that qualifies the cached package resolutions of a stylesheet. A stylesheet + * within `node_modules` uses the root of its enclosing package, since every file of a package + * resolves its dependencies against the same `node_modules` directories. All other stylesheets use + * the working directory, allowing component stylesheets to share package resolutions. + */ +export function getPackageScope( + containingPath: string | undefined, + workingDirectory: string | undefined, +): string { + // The directory segments of the stylesheet, excluding the file name + const segments = containingPath?.split(/[\\/]/).slice(0, -1) ?? []; + const index = segments.lastIndexOf('node_modules'); + if (index === -1) { + return workingDirectory ?? ''; + } + + const packageNameLength = segments[index + 1]?.[0] === '@' ? 2 : 1; + + return segments.slice(0, index + 1 + packageNameLength).join('/'); +} + async function compileString( data: string, filePath: string, syntax: Syntax, options: StylesheetPluginOptions, - resolveUrl: (url: string, options: CanonicalizeContext) => Promise, + resolveUrl: (url: string, resolveDir: string | undefined) => Promise, + workingDirectory: string | undefined, ): Promise { // Lazily load Sass when a Sass file is found if (sassService === undefined) { @@ -119,7 +144,8 @@ async function compileString( } // Caching follows Sass behavior where a given package url will always resolve to the same value - // regardless of its importer's path. Relative paths are qualified with the containing URL. + // regardless of its importer's path, except for importers within `node_modules`, which are + // scoped to their enclosing package. Relative paths are qualified with the containing URL. // A null value indicates that the cached resolution attempt failed to find a location and // later stage resolution should be attempted. This avoids potentially expensive repeat // failing resolution attempts. @@ -145,11 +171,19 @@ async function compileString( importers: [ { findFileUrl: (url, options) => { + const containingPath = + options.containingUrl?.protocol === 'file:' + ? fileURLToPath(options.containingUrl) + : undefined; + const resolveDir = containingPath ? dirname(containingPath) : workingDirectory; const isPackage = isPackageUrl(url); - const cacheKey = isPackage ? url : `${options.containingUrl?.href ?? ''}:${url}`; + const scope = getPackageScope(containingPath, workingDirectory); + const cacheKey = isPackage + ? `${scope}:${url}` + : `${options.containingUrl?.href ?? ''}:${url}`; return currentResolutionCache.getOrCreate(cacheKey, async () => { - const result = await resolveUrl(url, options); + const result = await resolveUrl(url, resolveDir); if (result.path) { return pathToFileURL(result.path); } @@ -164,10 +198,10 @@ async function compileString( // Caching package root locations is particularly beneficial for `@material/*` packages // which extensively use deep imports. const packageRoot = await currentPackageRootCache.getOrCreate( - packageName, + `${scope}:${packageName}`, async () => { // Use the required presence of a package root `package.json` file to resolve the location - const packageResult = await resolveUrl(packageName + '/package.json', options); + const packageResult = await resolveUrl(packageName + '/package.json', resolveDir); return packageResult.path ? dirname(packageResult.path) : null; }, diff --git a/packages/angular/build/src/tools/esbuild/stylesheets/sass-language_spec.ts b/packages/angular/build/src/tools/esbuild/stylesheets/sass-language_spec.ts index 7be104741caa..cdd4d7e7c8db 100644 --- a/packages/angular/build/src/tools/esbuild/stylesheets/sass-language_spec.ts +++ b/packages/angular/build/src/tools/esbuild/stylesheets/sass-language_spec.ts @@ -6,7 +6,20 @@ * found in the LICENSE file at https://angular.dev/license */ -import { isPackageUrl } from './sass-language'; +import type { PluginBuild } from 'esbuild'; +import assert from 'node:assert'; +import { statSync } from 'node:fs'; +import { mkdir, mkdtemp, rm, writeFile } from 'node:fs/promises'; +import { dirname, join } from 'node:path'; +import { pathToFileURL } from 'node:url'; +import { SassCompiler } from '../../sass/sass-service'; +import { + SassStylesheetLanguage, + getPackageScope, + isPackageUrl, + resetSassWorkerPoolCaches, + shutdownSassWorkerPool, +} from './sass-language'; describe('sass-language', () => { describe('isPackageUrl', () => { @@ -46,4 +59,232 @@ describe('sass-language', () => { expect(isPackageUrl('')).toBeFalse(); }); }); + + describe('getPackageScope', () => { + const scope = (containingPath?: string) => getPackageScope(containingPath, '/app'); + + it('should use the working directory for a stylesheet outside node_modules', () => { + expect(scope('/app/src/app.scss')).toBe('/app'); + expect(scope('/app/src/foo-node_modules/a.scss')).toBe('/app'); + expect(scope('/app/src/node_modules.scss')).toBe('/app'); + expect(scope(undefined)).toBe('/app'); + }); + + it('should use the enclosing package root for a stylesheet within node_modules', () => { + expect(scope('/app/node_modules/pkg/a.scss')).toBe('/app/node_modules/pkg'); + expect(scope('/app/node_modules/pkg/sub/a.scss')).toBe('/app/node_modules/pkg'); + expect(scope('/app/node_modules/@scope/pkg/sub/a.scss')).toBe('/app/node_modules/@scope/pkg'); + expect(scope('/app/node_modules/foo-node_modules/a.scss')).toBe( + '/app/node_modules/foo-node_modules', + ); + expect(scope('/app/node_modules/a.scss')).toBe('/app/node_modules'); + }); + + it('should use the innermost package root for a nested dependency', () => { + expect(scope('/app/node_modules/dep/node_modules/pkg/a.scss')).toBe( + '/app/node_modules/dep/node_modules/pkg', + ); + expect(scope('/app/node_modules/.pnpm/pkg@1.0.0/node_modules/pkg/a.scss')).toBe( + '/app/node_modules/.pnpm/pkg@1.0.0/node_modules/pkg', + ); + }); + + it('should support Windows path separators', () => { + expect(getPackageScope('C:\\app\\node_modules\\pkg\\sub\\a.scss', 'C:\\app')).toBe( + 'C:/app/node_modules/pkg', + ); + expect(getPackageScope('C:\\app\\src\\app.scss', 'C:\\app')).toBe('C:\\app'); + }); + }); + + describe('package resolution caching', () => { + let temporaryRoot: string; + let projectRoot: string; + let buttonStylesheet: string; + let cardStylesheet: string; + let dependencyStylesheet: string; + let resolveRequests: string[]; + + /** + * Creates a build stub that resolves a package specifier by searching the `node_modules` + * directories visible from the resolve directory, which is how esbuild resolves the + * package specifiers of a stylesheet. + */ + function createBuildStub(): PluginBuild { + return { + initialOptions: { absWorkingDir: projectRoot }, + resolve: async (path: string, options: { resolveDir: string }) => { + resolveRequests.push(`${options.resolveDir}:${path}`); + + for (let directory = options.resolveDir; ; directory = dirname(directory)) { + // A package specifier resolves to the index file of the package, and an explicit file + // within it to that file. A deeper subpath is left unresolved, as esbuild leaves one + // that the `exports` of the package does not name; the Sass importer then resolves it + // against the package root instead. + for (const candidate of [ + join(directory, 'node_modules', path, '_index.scss'), + join(directory, 'node_modules', path), + ]) { + if (statSync(candidate, { throwIfNoEntry: false })?.isFile()) { + return { path: candidate, errors: [], warnings: [] }; + } + } + + if (dirname(directory) === directory) { + return { path: undefined, errors: [], warnings: [] }; + } + } + }, + } as unknown as PluginBuild; + } + + async function compile(stylesheet: string, source = "@use 'theme';"): Promise { + const result = await SassStylesheetLanguage.process?.( + source, + stylesheet, + 'scss', + { sourcemap: false }, + createBuildStub(), + ); + if (!result) { + throw new Error('The Sass stylesheet language has no process function.'); + } + + if (result.errors?.length) { + return `error: ${result.errors[0].text}`; + } + + return (result.contents as string).trim(); + } + + async function writePackage(directory: string, marker: string): Promise { + await mkdir(join(directory, 'sub'), { recursive: true }); + await writeFile(join(directory, 'package.json'), '{}'); + await writeFile(join(directory, '_index.scss'), `.marker { content: "${marker}"; }`); + await writeFile( + join(directory, 'sub', '_other.scss'), + `.deep { content: "${marker} deep"; }`, + ); + } + + beforeAll(async () => { + const baseTmpDir = process.env['TEST_TMPDIR']; + assert(baseTmpDir, 'TEST_TMPDIR is not set'); + temporaryRoot = await mkdtemp(join(baseTmpDir, 'angular-cli-sass-language-')); + projectRoot = join(temporaryRoot, 'project'); + const dependencyRoot = join(projectRoot, 'node_modules', 'dependency'); + + // An application using a `theme` package, and a dependency with its own nested version of + // `theme` plus an `extra` package that only the dependency can see. + await writePackage(join(projectRoot, 'node_modules', 'theme'), 'project'); + await writePackage(join(dependencyRoot, 'node_modules', 'theme'), 'dependency'); + await writePackage(join(dependencyRoot, 'node_modules', 'extra'), 'extra'); + + buttonStylesheet = join(projectRoot, 'src', 'app', 'button', 'button.scss'); + cardStylesheet = join(projectRoot, 'src', 'app', 'card', 'card.scss'); + dependencyStylesheet = join(dependencyRoot, 'styles.scss'); + for (const stylesheet of [buttonStylesheet, cardStylesheet]) { + await mkdir(dirname(stylesheet), { recursive: true }); + } + }); + + afterAll(async () => { + shutdownSassWorkerPool(); + await rm(temporaryRoot, { force: true, recursive: true }); + }); + + beforeEach(() => { + resetSassWorkerPoolCaches(); + resolveRequests = []; + }); + + it('should not use the package resolution of a dependency for the application', async () => { + const dependency = await compile(dependencyStylesheet); + const application = await compile(buttonStylesheet); + + expect(dependency).toContain('content: "dependency";'); + expect(application).toContain('content: "project";'); + }); + + it('should not use the package resolution of the application for a dependency', async () => { + const application = await compile(buttonStylesheet); + const dependency = await compile(dependencyStylesheet); + + expect(application).toContain('content: "project";'); + expect(dependency).toContain('content: "dependency";'); + }); + + it('should not reuse a failed package resolution of the application for a dependency', async () => { + const source = "@use 'extra';"; + const application = await compile(buttonStylesheet, source); + const dependency = await compile(dependencyStylesheet, source); + + expect(application).toContain("Can't find stylesheet to import."); + expect(dependency).toContain('content: "extra";'); + }); + + it('should not use the package root of a dependency for a deep import of the application', async () => { + // A subpath that resolves to no file of its own is located through the root of the package, + // which is cached separately from the resolution of the specifier. + const source = "@use 'theme/sub/other';"; + const dependency = await compile(dependencyStylesheet, source); + const application = await compile(buttonStylesheet, source); + + expect(dependency).toContain('content: "dependency deep";'); + expect(application).toContain('content: "project deep";'); + }); + + it('should share a package resolution between the stylesheets of different components', async () => { + const button = await compile(buttonStylesheet); + const card = await compile(cardStylesheet); + + expect(button).toContain('content: "project";'); + expect(card).toContain('content: "project";'); + expect(resolveRequests.length).toBe(1); + }); + + it('should share a package resolution between the stylesheets of different folders of a dependency', async () => { + const dependencyRoot = join(projectRoot, 'node_modules', 'dependency'); + const first = await compile(join(dependencyRoot, 'sub1', 'styles.scss')); + const second = await compile(join(dependencyRoot, 'sub2', 'styles.scss')); + + expect(first).toContain('content: "dependency";'); + expect(second).toContain('content: "dependency";'); + expect(resolveRequests.length).toBe(1); + }); + + it('should share a package resolution between the stylesheets of different folders of a scoped package', async () => { + const packageRoot = join(projectRoot, 'node_modules', '@scope', 'pkg'); + const first = await compile(join(packageRoot, 'sub1', 'styles.scss')); + const second = await compile(join(packageRoot, 'sub2', 'styles.scss')); + + expect(first).toContain('content: "project";'); + expect(second).toContain('content: "project";'); + expect(resolveRequests.length).toBe(1); + }); + + it('should resolve a package url of a non-file containing URL from the working directory', async () => { + // The stylesheets of a build have file URLs, but Sass does not limit a containing URL to them. + spyOn(SassCompiler.prototype, 'compileStringAsync').and.callFake(async (_, options) => { + const importer = options.importers?.[0] as { + findFileUrl( + url: string, + context: { containingUrl: URL; fromImport: boolean }, + ): Promise; + }; + const url = await importer.findFileUrl('theme', { + containingUrl: new URL('custom:styles.scss'), + fromImport: false, + }); + + return { css: url?.href ?? '', loadedUrls: [] }; + }); + + const result = await compile(buttonStylesheet); + + expect(result).toBe( + pathToFileURL(join(projectRoot, 'node_modules', 'theme', '_index.scss')).href, + ); + }); + }); }); From c084a648a6e082c3de2af0d1c9f888bbe52a310c Mon Sep 17 00:00:00 2001 From: Angular Robot Date: Tue, 22 Sep 2026 18:36:48 +0000 Subject: [PATCH 502/787] build: update cross-repo angular dependencies See associated pull request for more information. --- .../assistant-to-the-branch-manager.yml | 2 +- .github/workflows/ci.yml | 52 +++++++++---------- .github/workflows/dev-infra.yml | 6 +-- .github/workflows/perf.yml | 6 +-- .github/workflows/pr.yml | 44 ++++++++-------- MODULE.bazel | 2 +- tests/e2e/ng-snapshot/package.json | 26 +++++----- 7 files changed, 69 insertions(+), 69 deletions(-) diff --git a/.github/workflows/assistant-to-the-branch-manager.yml b/.github/workflows/assistant-to-the-branch-manager.yml index 37a87ef062e5..d96db1e3d645 100644 --- a/.github/workflows/assistant-to-the-branch-manager.yml +++ b/.github/workflows/assistant-to-the-branch-manager.yml @@ -18,6 +18,6 @@ jobs: - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: persist-credentials: false - - uses: angular/dev-infra/github-actions/branch-manager@56bab29d886fd34280b1ccc203d8817e9725f0af # main + - uses: angular/dev-infra/github-actions/branch-manager@bf1d18837b5aaed70cf858ecd177583bf320be50 # main with: angular-robot-key: ${{ secrets.ANGULAR_ROBOT_PRIVATE_KEY }} diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 8838142cebd4..5bc5ede289ce 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -21,9 +21,9 @@ jobs: runs-on: ubuntu-latest steps: - name: Initialize environment - uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@56bab29d886fd34280b1ccc203d8817e9725f0af # main + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@bf1d18837b5aaed70cf858ecd177583bf320be50 # main - name: Setup Bazel - uses: angular/dev-infra/github-actions/bazel/setup@56bab29d886fd34280b1ccc203d8817e9725f0af # main + uses: angular/dev-infra/github-actions/bazel/setup@bf1d18837b5aaed70cf858ecd177583bf320be50 # main - name: Install node modules run: pnpm install --frozen-lockfile - name: Generate JSON schema types @@ -44,11 +44,11 @@ jobs: runs-on: ubuntu-latest steps: - name: Initialize environment - uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@56bab29d886fd34280b1ccc203d8817e9725f0af # main + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@bf1d18837b5aaed70cf858ecd177583bf320be50 # main - name: Setup Bazel - uses: angular/dev-infra/github-actions/bazel/setup@56bab29d886fd34280b1ccc203d8817e9725f0af # main + uses: angular/dev-infra/github-actions/bazel/setup@bf1d18837b5aaed70cf858ecd177583bf320be50 # main - name: Setup Bazel RBE - uses: angular/dev-infra/github-actions/bazel/configure-remote@56bab29d886fd34280b1ccc203d8817e9725f0af # main + uses: angular/dev-infra/github-actions/bazel/configure-remote@bf1d18837b5aaed70cf858ecd177583bf320be50 # main with: google_credential: ${{ secrets.RBE_TRUSTED_BUILDS_USER }} - name: Install node modules @@ -61,11 +61,11 @@ jobs: runs-on: ubuntu-latest steps: - name: Initialize environment - uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@56bab29d886fd34280b1ccc203d8817e9725f0af # main + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@bf1d18837b5aaed70cf858ecd177583bf320be50 # main - name: Setup Bazel - uses: angular/dev-infra/github-actions/bazel/setup@56bab29d886fd34280b1ccc203d8817e9725f0af # main + uses: angular/dev-infra/github-actions/bazel/setup@bf1d18837b5aaed70cf858ecd177583bf320be50 # main - name: Setup Bazel RBE - uses: angular/dev-infra/github-actions/bazel/configure-remote@56bab29d886fd34280b1ccc203d8817e9725f0af # main + uses: angular/dev-infra/github-actions/bazel/configure-remote@bf1d18837b5aaed70cf858ecd177583bf320be50 # main with: google_credential: ${{ secrets.RBE_TRUSTED_BUILDS_USER }} - name: Install node modules @@ -84,13 +84,13 @@ jobs: runs-on: ubuntu-latest steps: - name: Initialize environment - uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@56bab29d886fd34280b1ccc203d8817e9725f0af # main + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@bf1d18837b5aaed70cf858ecd177583bf320be50 # main - name: Install node modules run: pnpm install --frozen-lockfile - name: Setup Bazel - uses: angular/dev-infra/github-actions/bazel/setup@56bab29d886fd34280b1ccc203d8817e9725f0af # main + uses: angular/dev-infra/github-actions/bazel/setup@bf1d18837b5aaed70cf858ecd177583bf320be50 # main - name: Setup Bazel RBE - uses: angular/dev-infra/github-actions/bazel/configure-remote@56bab29d886fd34280b1ccc203d8817e9725f0af # main + uses: angular/dev-infra/github-actions/bazel/configure-remote@bf1d18837b5aaed70cf858ecd177583bf320be50 # main with: google_credential: ${{ secrets.RBE_TRUSTED_BUILDS_USER }} - name: Run CLI E2E tests @@ -100,11 +100,11 @@ jobs: runs-on: ubuntu-latest steps: - name: Initialize environment - uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@56bab29d886fd34280b1ccc203d8817e9725f0af # main + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@bf1d18837b5aaed70cf858ecd177583bf320be50 # main - name: Setup Bazel - uses: angular/dev-infra/github-actions/bazel/setup@56bab29d886fd34280b1ccc203d8817e9725f0af # main + uses: angular/dev-infra/github-actions/bazel/setup@bf1d18837b5aaed70cf858ecd177583bf320be50 # main - name: Setup Bazel RBE - uses: angular/dev-infra/github-actions/bazel/configure-remote@56bab29d886fd34280b1ccc203d8817e9725f0af # main + uses: angular/dev-infra/github-actions/bazel/configure-remote@bf1d18837b5aaed70cf858ecd177583bf320be50 # main with: google_credential: ${{ secrets.RBE_TRUSTED_BUILDS_USER }} - name: Install node modules @@ -137,7 +137,7 @@ jobs: runs-on: windows-2025 steps: - name: Initialize environment - uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@56bab29d886fd34280b1ccc203d8817e9725f0af # main + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@bf1d18837b5aaed70cf858ecd177583bf320be50 # main - name: Install node modules run: pnpm install --frozen-lockfile - name: Download built Windows E2E tests @@ -164,13 +164,13 @@ jobs: runs-on: ubuntu-latest steps: - name: Initialize environment - uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@56bab29d886fd34280b1ccc203d8817e9725f0af # main + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@bf1d18837b5aaed70cf858ecd177583bf320be50 # main - name: Install node modules run: pnpm install --frozen-lockfile - name: Setup Bazel - uses: angular/dev-infra/github-actions/bazel/setup@56bab29d886fd34280b1ccc203d8817e9725f0af # main + uses: angular/dev-infra/github-actions/bazel/setup@bf1d18837b5aaed70cf858ecd177583bf320be50 # main - name: Setup Bazel RBE - uses: angular/dev-infra/github-actions/bazel/configure-remote@56bab29d886fd34280b1ccc203d8817e9725f0af # main + uses: angular/dev-infra/github-actions/bazel/configure-remote@bf1d18837b5aaed70cf858ecd177583bf320be50 # main with: google_credential: ${{ secrets.RBE_TRUSTED_BUILDS_USER }} - name: Run CLI E2E tests @@ -188,13 +188,13 @@ jobs: runs-on: ubuntu-latest steps: - name: Initialize environment - uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@56bab29d886fd34280b1ccc203d8817e9725f0af # main + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@bf1d18837b5aaed70cf858ecd177583bf320be50 # main - name: Install node modules run: pnpm install --frozen-lockfile - name: Setup Bazel - uses: angular/dev-infra/github-actions/bazel/setup@56bab29d886fd34280b1ccc203d8817e9725f0af # main + uses: angular/dev-infra/github-actions/bazel/setup@bf1d18837b5aaed70cf858ecd177583bf320be50 # main - name: Setup Bazel RBE - uses: angular/dev-infra/github-actions/bazel/configure-remote@56bab29d886fd34280b1ccc203d8817e9725f0af # main + uses: angular/dev-infra/github-actions/bazel/configure-remote@bf1d18837b5aaed70cf858ecd177583bf320be50 # main with: google_credential: ${{ secrets.RBE_TRUSTED_BUILDS_USER }} - name: Run CLI E2E tests @@ -208,13 +208,13 @@ jobs: SAUCE_TUNNEL_IDENTIFIER: angular-cli-${{ github.workflow }}-${{ github.run_number }} steps: - name: Initialize environment - uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@56bab29d886fd34280b1ccc203d8817e9725f0af # main + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@bf1d18837b5aaed70cf858ecd177583bf320be50 # main - name: Install node modules run: pnpm install --frozen-lockfile - name: Setup Bazel - uses: angular/dev-infra/github-actions/bazel/setup@56bab29d886fd34280b1ccc203d8817e9725f0af # main + uses: angular/dev-infra/github-actions/bazel/setup@bf1d18837b5aaed70cf858ecd177583bf320be50 # main - name: Setup Bazel RBE - uses: angular/dev-infra/github-actions/bazel/configure-remote@56bab29d886fd34280b1ccc203d8817e9725f0af # main + uses: angular/dev-infra/github-actions/bazel/configure-remote@bf1d18837b5aaed70cf858ecd177583bf320be50 # main with: google_credential: ${{ secrets.RBE_TRUSTED_BUILDS_USER }} - name: Start Sauce Connect @@ -245,11 +245,11 @@ jobs: CIRCLE_BRANCH: ${{ github.ref_name }} steps: - name: Initialize environment - uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@56bab29d886fd34280b1ccc203d8817e9725f0af # main + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@bf1d18837b5aaed70cf858ecd177583bf320be50 # main - name: Install node modules run: pnpm install --frozen-lockfile - name: Setup Bazel - uses: angular/dev-infra/github-actions/bazel/setup@56bab29d886fd34280b1ccc203d8817e9725f0af # main + uses: angular/dev-infra/github-actions/bazel/setup@bf1d18837b5aaed70cf858ecd177583bf320be50 # main - run: pnpm admin snapshots --verbose env: SNAPSHOT_BUILDS_GITHUB_TOKEN: ${{ secrets.SNAPSHOT_BUILDS_GITHUB_TOKEN }} diff --git a/.github/workflows/dev-infra.yml b/.github/workflows/dev-infra.yml index 6066f04957ee..0f4aea85fdb0 100644 --- a/.github/workflows/dev-infra.yml +++ b/.github/workflows/dev-infra.yml @@ -16,21 +16,21 @@ jobs: if: github.event_name == 'pull_request_target' runs-on: ubuntu-latest steps: - - uses: angular/dev-infra/github-actions/labeling/pull-request@56bab29d886fd34280b1ccc203d8817e9725f0af # main + - uses: angular/dev-infra/github-actions/labeling/pull-request@bf1d18837b5aaed70cf858ecd177583bf320be50 # main with: angular-robot-key: ${{ secrets.ANGULAR_ROBOT_PRIVATE_KEY }} post_approval_changes: if: github.event_name == 'pull_request_target' runs-on: ubuntu-latest steps: - - uses: angular/dev-infra/github-actions/post-approval-changes@56bab29d886fd34280b1ccc203d8817e9725f0af # main + - uses: angular/dev-infra/github-actions/post-approval-changes@bf1d18837b5aaed70cf858ecd177583bf320be50 # main with: angular-robot-key: ${{ secrets.ANGULAR_ROBOT_PRIVATE_KEY }} issue_labels: if: github.event_name == 'issues' runs-on: ubuntu-latest steps: - - uses: angular/dev-infra/github-actions/labeling/issue@56bab29d886fd34280b1ccc203d8817e9725f0af # main + - uses: angular/dev-infra/github-actions/labeling/issue@bf1d18837b5aaed70cf858ecd177583bf320be50 # main with: angular-robot-key: ${{ secrets.ANGULAR_ROBOT_PRIVATE_KEY }} google-generative-ai-key: ${{ secrets.GOOGLE_GENERATIVE_AI_KEY }} diff --git a/.github/workflows/perf.yml b/.github/workflows/perf.yml index e2c9f91e726d..a3170cf0add5 100644 --- a/.github/workflows/perf.yml +++ b/.github/workflows/perf.yml @@ -22,7 +22,7 @@ jobs: workflows: ${{ steps.workflows.outputs.workflows }} steps: - name: Initialize environment - uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@56bab29d886fd34280b1ccc203d8817e9725f0af # main + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@bf1d18837b5aaed70cf858ecd177583bf320be50 # main - name: Install node modules run: pnpm install --frozen-lockfile - id: workflows @@ -40,9 +40,9 @@ jobs: workflow: ${{ fromJSON(needs.list.outputs.workflows) }} steps: - name: Initialize environment - uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@56bab29d886fd34280b1ccc203d8817e9725f0af # main + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@bf1d18837b5aaed70cf858ecd177583bf320be50 # main - name: Setup Bazel - uses: angular/dev-infra/github-actions/bazel/setup@56bab29d886fd34280b1ccc203d8817e9725f0af # main + uses: angular/dev-infra/github-actions/bazel/setup@bf1d18837b5aaed70cf858ecd177583bf320be50 # main - name: Install node modules run: pnpm install --frozen-lockfile # We utilize the google-github-actions/auth action to allow us to get an active credential using workflow diff --git a/.github/workflows/pr.yml b/.github/workflows/pr.yml index a826cfeba4f3..5d86977c77a4 100644 --- a/.github/workflows/pr.yml +++ b/.github/workflows/pr.yml @@ -34,9 +34,9 @@ jobs: runs-on: ubuntu-latest steps: - name: Initialize environment - uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@56bab29d886fd34280b1ccc203d8817e9725f0af # main + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@bf1d18837b5aaed70cf858ecd177583bf320be50 # main - name: Setup Bazel - uses: angular/dev-infra/github-actions/bazel/setup@56bab29d886fd34280b1ccc203d8817e9725f0af # main + uses: angular/dev-infra/github-actions/bazel/setup@bf1d18837b5aaed70cf858ecd177583bf320be50 # main - name: Setup ESLint Caching uses: actions/cache@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0 with: @@ -66,17 +66,17 @@ jobs: # it has been merged. run: pnpm ng-dev format changed --check ${{ github.event.pull_request.base.sha }} - name: Check Package Licenses - uses: angular/dev-infra/github-actions/linting/licenses@56bab29d886fd34280b1ccc203d8817e9725f0af # main + uses: angular/dev-infra/github-actions/linting/licenses@bf1d18837b5aaed70cf858ecd177583bf320be50 # main build: runs-on: ubuntu-latest steps: - name: Initialize environment - uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@56bab29d886fd34280b1ccc203d8817e9725f0af # main + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@bf1d18837b5aaed70cf858ecd177583bf320be50 # main - name: Setup Bazel - uses: angular/dev-infra/github-actions/bazel/setup@56bab29d886fd34280b1ccc203d8817e9725f0af # main + uses: angular/dev-infra/github-actions/bazel/setup@bf1d18837b5aaed70cf858ecd177583bf320be50 # main - name: Setup Bazel RBE - uses: angular/dev-infra/github-actions/bazel/configure-remote@56bab29d886fd34280b1ccc203d8817e9725f0af # main + uses: angular/dev-infra/github-actions/bazel/configure-remote@bf1d18837b5aaed70cf858ecd177583bf320be50 # main - name: Install node modules run: pnpm install --frozen-lockfile - name: Build release targets @@ -93,11 +93,11 @@ jobs: runs-on: ubuntu-latest steps: - name: Initialize environment - uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@56bab29d886fd34280b1ccc203d8817e9725f0af # main + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@bf1d18837b5aaed70cf858ecd177583bf320be50 # main - name: Setup Bazel - uses: angular/dev-infra/github-actions/bazel/setup@56bab29d886fd34280b1ccc203d8817e9725f0af # main + uses: angular/dev-infra/github-actions/bazel/setup@bf1d18837b5aaed70cf858ecd177583bf320be50 # main - name: Setup Bazel RBE - uses: angular/dev-infra/github-actions/bazel/configure-remote@56bab29d886fd34280b1ccc203d8817e9725f0af # main + uses: angular/dev-infra/github-actions/bazel/configure-remote@bf1d18837b5aaed70cf858ecd177583bf320be50 # main - name: Install node modules run: pnpm install --frozen-lockfile - name: Run module and package tests @@ -114,13 +114,13 @@ jobs: runs-on: ubuntu-latest steps: - name: Initialize environment - uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@56bab29d886fd34280b1ccc203d8817e9725f0af # main + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@bf1d18837b5aaed70cf858ecd177583bf320be50 # main - name: Install node modules run: pnpm install --frozen-lockfile - name: Setup Bazel - uses: angular/dev-infra/github-actions/bazel/setup@56bab29d886fd34280b1ccc203d8817e9725f0af # main + uses: angular/dev-infra/github-actions/bazel/setup@bf1d18837b5aaed70cf858ecd177583bf320be50 # main - name: Setup Bazel RBE - uses: angular/dev-infra/github-actions/bazel/configure-remote@56bab29d886fd34280b1ccc203d8817e9725f0af # main + uses: angular/dev-infra/github-actions/bazel/configure-remote@bf1d18837b5aaed70cf858ecd177583bf320be50 # main - name: Run CLI E2E tests run: pnpm bazel test --test_env=E2E_SHARD_TOTAL=6 --test_env=E2E_SHARD_INDEX=${{ matrix.shard }} --config=e2e //tests:e2e.${{ matrix.subset }}_node${{ matrix.node }} @@ -128,11 +128,11 @@ jobs: runs-on: ubuntu-latest steps: - name: Initialize environment - uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@56bab29d886fd34280b1ccc203d8817e9725f0af # main + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@bf1d18837b5aaed70cf858ecd177583bf320be50 # main - name: Setup Bazel - uses: angular/dev-infra/github-actions/bazel/setup@56bab29d886fd34280b1ccc203d8817e9725f0af # main + uses: angular/dev-infra/github-actions/bazel/setup@bf1d18837b5aaed70cf858ecd177583bf320be50 # main - name: Setup Bazel RBE - uses: angular/dev-infra/github-actions/bazel/configure-remote@56bab29d886fd34280b1ccc203d8817e9725f0af # main + uses: angular/dev-infra/github-actions/bazel/configure-remote@bf1d18837b5aaed70cf858ecd177583bf320be50 # main - name: Install node modules run: pnpm install --frozen-lockfile - name: Build E2E tests for Windows on Linux @@ -156,7 +156,7 @@ jobs: runs-on: windows-2025 steps: - name: Initialize environment - uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@56bab29d886fd34280b1ccc203d8817e9725f0af # main + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@bf1d18837b5aaed70cf858ecd177583bf320be50 # main - name: Install node modules run: pnpm install --frozen-lockfile - name: Download built Windows E2E tests @@ -183,13 +183,13 @@ jobs: runs-on: ubuntu-latest steps: - name: Initialize environment - uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@56bab29d886fd34280b1ccc203d8817e9725f0af # main + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@bf1d18837b5aaed70cf858ecd177583bf320be50 # main - name: Install node modules run: pnpm install --frozen-lockfile - name: Setup Bazel - uses: angular/dev-infra/github-actions/bazel/setup@56bab29d886fd34280b1ccc203d8817e9725f0af # main + uses: angular/dev-infra/github-actions/bazel/setup@bf1d18837b5aaed70cf858ecd177583bf320be50 # main - name: Setup Bazel RBE - uses: angular/dev-infra/github-actions/bazel/configure-remote@56bab29d886fd34280b1ccc203d8817e9725f0af # main + uses: angular/dev-infra/github-actions/bazel/configure-remote@bf1d18837b5aaed70cf858ecd177583bf320be50 # main - name: Run CLI E2E tests run: pnpm bazel test --test_env=E2E_SHARD_TOTAL=3 --test_env=E2E_SHARD_INDEX=${{ matrix.shard }} --config=e2e //tests:e2e.${{ matrix.subset }}_node${{ matrix.node }} @@ -205,12 +205,12 @@ jobs: runs-on: ubuntu-latest steps: - name: Initialize environment - uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@56bab29d886fd34280b1ccc203d8817e9725f0af # main + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@bf1d18837b5aaed70cf858ecd177583bf320be50 # main - name: Install node modules run: pnpm install --frozen-lockfile - name: Setup Bazel - uses: angular/dev-infra/github-actions/bazel/setup@56bab29d886fd34280b1ccc203d8817e9725f0af # main + uses: angular/dev-infra/github-actions/bazel/setup@bf1d18837b5aaed70cf858ecd177583bf320be50 # main - name: Setup Bazel RBE - uses: angular/dev-infra/github-actions/bazel/configure-remote@56bab29d886fd34280b1ccc203d8817e9725f0af # main + uses: angular/dev-infra/github-actions/bazel/configure-remote@bf1d18837b5aaed70cf858ecd177583bf320be50 # main - name: Run CLI E2E tests run: pnpm bazel test --test_env=E2E_SHARD_TOTAL=6 --test_env=E2E_SHARD_INDEX=${{ matrix.shard }} --config=e2e //tests:e2e.snapshots.${{ matrix.subset }}_node${{ matrix.node }} diff --git a/MODULE.bazel b/MODULE.bazel index ef8a2c95e1fd..5e0096477618 100644 --- a/MODULE.bazel +++ b/MODULE.bazel @@ -26,7 +26,7 @@ git_override( bazel_dep(name = "devinfra") git_override( module_name = "devinfra", - commit = "56bab29d886fd34280b1ccc203d8817e9725f0af", + commit = "bf1d18837b5aaed70cf858ecd177583bf320be50", remote = "https://github.com/angular/dev-infra.git", ) diff --git a/tests/e2e/ng-snapshot/package.json b/tests/e2e/ng-snapshot/package.json index 53a12d9add6c..09c58bceafaf 100644 --- a/tests/e2e/ng-snapshot/package.json +++ b/tests/e2e/ng-snapshot/package.json @@ -2,21 +2,21 @@ "description": "snapshot versions of Angular for e2e testing", "private": true, "dependencies": { - "@angular/animations": "github:angular/animations-builds#3d1c250f4edacfe60355fd3133353fdb037b03df", + "@angular/animations": "github:angular/animations-builds#3629fd701ede78443109c1b3f8859df7210590fa", "@angular/cdk": "github:angular/cdk-builds#1ce55365568b0b1be4d17e9040d5d846f7b414d8", - "@angular/common": "github:angular/common-builds#de1e477d0c03e9bf626f7ab62d5446b9f6f37e87", - "@angular/compiler": "github:angular/compiler-builds#f79a1335c78a63896769fa5818d0566cf84b37fc", - "@angular/compiler-cli": "github:angular/compiler-cli-builds#2807f37e39aece8f0abdbb6104da7e005199f56d", - "@angular/core": "github:angular/core-builds#50463c19a9bddb492112ceb8a549a6724b6378ba", - "@angular/forms": "github:angular/forms-builds#f9b2189afac1130d800634a02d3758e3c1998894", - "@angular/language-service": "github:angular/language-service-builds#2dabb85c3b136eee41d191d6434731e422217ab0", - "@angular/localize": "github:angular/localize-builds#34cbcda2d4a59c3586ffcff6f66cb203fb9e470f", + "@angular/common": "github:angular/common-builds#9cc550da9cb1ddab14909300c6743c372890f7de", + "@angular/compiler": "github:angular/compiler-builds#3374daba464eaff8c9b7b6a5cbc4aafcf90f0f0d", + "@angular/compiler-cli": "github:angular/compiler-cli-builds#7ebc08586fd5efc81b876f37925e77ac35a8a085", + "@angular/core": "github:angular/core-builds#85e3d69306a27133011cc04abfe9c41f0de29cab", + "@angular/forms": "github:angular/forms-builds#3be01184155b0da47be9a7f412be3084743dbc81", + "@angular/language-service": "github:angular/language-service-builds#4f7fd2efabf368003ebd80570325d5d66de04ad3", + "@angular/localize": "github:angular/localize-builds#a5fe9a09abef68f8f097f0a25b5b848000d01583", "@angular/material": "github:angular/material-builds#ddde2cfce1af33b5274b93d5d7d542bdc6bca22c", "@angular/material-moment-adapter": "github:angular/material-moment-adapter-builds#174487e1cd9237dbf14cbdfea84bb5a08562b2be", - "@angular/platform-browser": "github:angular/platform-browser-builds#61d8e66aa018e1f8e5d3bb890aea3ea8d62560c5", - "@angular/platform-browser-dynamic": "github:angular/platform-browser-dynamic-builds#f4fe6bc35c19f408fc5b92fcbfb1e6c3e08c15fe", - "@angular/platform-server": "github:angular/platform-server-builds#b52d8244fc19f92aa927e2de66dcba86b98f41a3", - "@angular/router": "github:angular/router-builds#020e5395f7c0f60472d4d591da897c3d43058a8f", - "@angular/service-worker": "github:angular/service-worker-builds#70d34a6671dce54610568f2ae29395a833a2bb2e" + "@angular/platform-browser": "github:angular/platform-browser-builds#a654af512152687b53db07d42cfbf579e6d78577", + "@angular/platform-browser-dynamic": "github:angular/platform-browser-dynamic-builds#f13404dd1ab7b165d23aa9878dc9ceb35e4633c7", + "@angular/platform-server": "github:angular/platform-server-builds#7458cac7beb0e0ce9e20302e53ad536071642b60", + "@angular/router": "github:angular/router-builds#ab7a8c986d9ad71b55decd76fedfd4e1e3e0649e", + "@angular/service-worker": "github:angular/service-worker-builds#3e63f2bf5ab32dd3763508f08786fa72a3c04eee" } } From 5b7f0a54ac4d31f4b542e6ec9e8d103f361c8fc6 Mon Sep 17 00:00:00 2001 From: Angular Robot Date: Tue, 22 Sep 2026 05:31:32 +0000 Subject: [PATCH 503/787] build: lock file maintenance See associated pull request for more information. --- MODULE.bazel.lock | 2 +- pnpm-lock.yaml | 1650 ++++++++++++++++++--------------------------- 2 files changed, 671 insertions(+), 981 deletions(-) diff --git a/MODULE.bazel.lock b/MODULE.bazel.lock index 2f5985594341..21303bfb9125 100644 --- a/MODULE.bazel.lock +++ b/MODULE.bazel.lock @@ -378,7 +378,7 @@ "aspect_rules_jasmine": "2.0.4", "aspect_tools_telemetry": "0.5.1" }, - "last_notice": 2 + "last_notice": 0 } } }, diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index bc209c16d2f3..9bd424b55840 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -290,13 +290,13 @@ importers: version: 3.0.8 '@types/loader-utils': specifier: ^3.0.0 - version: 3.0.0(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.28)(uglify-js@3.19.3) + version: 3.0.0(esbuild@0.28.2)(lightningcss@1.33.0)(uglify-js@3.19.3) '@types/lodash': specifier: ^4.17.0 version: 4.17.25 '@types/node': specifier: ^22.12.0 - version: 22.20.2 + version: 22.20.4 '@types/npm-package-arg': specifier: ^6.1.0 version: 6.1.4 @@ -398,7 +398,7 @@ importers: version: 1.4.1 prettier: specifier: ^3.0.0 - version: 3.9.6 + version: 3.9.8 puppeteer: specifier: 25.11.0 version: 25.11.0(bufferutil@4.1.0)(utf-8-validate@6.0.6) @@ -413,7 +413,7 @@ importers: version: 6.5.1(rollup@4.63.3)(typescript@6.0.3) rollup-plugin-sourcemaps2: specifier: 0.5.8 - version: 0.5.8(@types/node@22.20.2)(rollup@4.63.3) + version: 0.5.8(@types/node@22.20.4)(rollup@4.63.3) semver: specifier: 7.8.5 version: 7.8.5 @@ -461,7 +461,7 @@ importers: version: 6.0.3(supports-color@11.0.0) jsdom: specifier: 30.0.1 - version: 30.0.1 + version: 30.0.1(@noble/hashes@1.8.0) ng-packagr: specifier: 22.2.0-rc.0 version: 22.2.0-rc.0(@angular/compiler-cli@22.2.0-rc.0(@angular/compiler@22.2.0-rc.0)(typescript@6.0.3))(supports-color@11.0.0)(tslib@2.8.1)(typescript@6.0.3) @@ -470,7 +470,7 @@ importers: version: 7.8.2 vitest: specifier: 5.0.1 - version: 5.0.1(@opentelemetry/api@1.9.1)(@types/node@22.20.2)(@vitest/coverage-v8@5.0.1)(jsdom@30.0.1)(vite@8.3.0(@types/node@22.20.2)(esbuild@0.28.2)(jiti@2.7.0)(less@4.9.1(supports-color@11.0.0))(sass-embedded@1.104.0)(sass@1.104.0)(terser@5.51.2)(tsx@4.23.13)(yaml@2.9.1)) + version: 5.0.1(@opentelemetry/api@1.9.1)(@types/node@22.20.4)(@vitest/coverage-v8@5.0.1)(jsdom@30.0.1(@noble/hashes@1.8.0))(vite@8.3.0(@types/node@22.20.4)(esbuild@0.28.2)(jiti@2.7.0)(less@4.9.1(supports-color@11.0.0))(sass-embedded@1.104.1)(sass@1.104.1)(terser@5.51.2)(tsx@4.23.13)(yaml@2.9.1)) packages/angular/build: dependencies: @@ -485,19 +485,19 @@ importers: version: 8.0.5 '@inquirer/confirm': specifier: 6.3.2 - version: 6.3.2(@types/node@22.20.2) + version: 6.3.2(@types/node@22.20.4) '@parcel/watcher': specifier: 2.6.0 version: 2.6.0 '@vitejs/plugin-basic-ssl': specifier: 2.3.0 - version: 2.3.0(vite@8.3.0(@types/node@22.20.2)(esbuild@0.28.2)(jiti@2.7.0)(less@4.9.1(supports-color@11.0.0))(sass-embedded@1.104.1)(sass@1.104.1)(terser@5.51.2)(tsx@4.23.13)(yaml@2.9.1)) + version: 2.3.0(vite@8.3.0(@types/node@22.20.4)(esbuild@0.28.2)(jiti@2.7.0)(less@4.9.1(supports-color@11.0.0))(sass-embedded@1.104.1)(sass@1.104.1)(terser@5.51.2)(tsx@4.23.13)(yaml@2.9.1)) beasties: specifier: 0.5.4 version: 0.5.4 browserslist: specifier: ^4.26.0 - version: 4.28.9 + version: 4.29.0 chokidar: specifier: 5.0.0 version: 5.0.0 @@ -551,7 +551,7 @@ importers: version: 0.2.17 vite: specifier: 8.3.0 - version: 8.3.0(@types/node@22.20.2)(esbuild@0.28.2)(jiti@2.7.0)(less@4.9.1(supports-color@11.0.0))(sass-embedded@1.104.1)(sass@1.104.1)(terser@5.51.2)(tsx@4.23.13)(yaml@2.9.1) + version: 8.3.0(@types/node@22.20.4)(esbuild@0.28.2)(jiti@2.7.0)(less@4.9.1(supports-color@11.0.0))(sass-embedded@1.104.1)(sass@1.104.1)(terser@5.51.2)(tsx@4.23.13)(yaml@2.9.1) xxhash-wasm: specifier: 1.1.0 version: 1.1.0 @@ -573,7 +573,7 @@ importers: version: 6.0.3(supports-color@11.0.0) jsdom: specifier: 30.0.1 - version: 30.0.1 + version: 30.0.1(@noble/hashes@1.8.0) less: specifier: 4.9.1 version: 4.9.1(supports-color@11.0.0) @@ -591,7 +591,7 @@ importers: version: 7.8.2 vitest: specifier: 5.0.1 - version: 5.0.1(@opentelemetry/api@1.9.1)(@types/node@22.20.2)(@vitest/coverage-v8@5.0.1)(jsdom@30.0.1)(vite@8.3.0(@types/node@22.20.2)(esbuild@0.28.2)(jiti@2.7.0)(less@4.9.1(supports-color@11.0.0))(sass-embedded@1.104.1)(sass@1.104.1)(terser@5.51.2)(tsx@4.23.13)(yaml@2.9.1)) + version: 5.0.1(@opentelemetry/api@1.9.1)(@types/node@22.20.4)(@vitest/coverage-v8@5.0.1)(jsdom@30.0.1(@noble/hashes@1.8.0))(vite@8.3.0(@types/node@22.20.4)(esbuild@0.28.2)(jiti@2.7.0)(less@4.9.1(supports-color@11.0.0))(sass-embedded@1.104.1)(sass@1.104.1)(terser@5.51.2)(tsx@4.23.13)(yaml@2.9.1)) optionalDependencies: lmdb: specifier: 3.5.6 @@ -610,10 +610,10 @@ importers: version: link:../../angular_devkit/schematics '@inquirer/prompts': specifier: 8.7.2 - version: 8.7.2(@types/node@22.20.2) + version: 8.7.2(@types/node@22.20.4) '@listr2/prompt-adapter-inquirer': specifier: 4.2.7 - version: 4.2.7(@inquirer/prompts@8.7.2(@types/node@22.20.2))(@types/node@22.20.2)(listr2@11.1.0) + version: 4.2.7(@inquirer/prompts@8.7.2(@types/node@22.20.4))(@types/node@22.20.4)(listr2@11.1.0) '@modelcontextprotocol/server': specifier: 2.0.0 version: 2.0.0 @@ -761,7 +761,7 @@ importers: version: 0.5.4 browserslist: specifier: ^4.26.0 - version: 4.28.9 + version: 4.29.0 copy-webpack-plugin: specifier: 14.0.0 version: 14.0.0(webpack@5.111.0(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.28)(uglify-js@3.19.3)) @@ -824,7 +824,7 @@ importers: version: 7.8.2 sass-loader: specifier: 17.0.1 - version: 17.0.1(sass-embedded@1.104.0)(sass@1.104.1)(webpack@5.111.0(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.28)(uglify-js@3.19.3)) + version: 17.0.1(sass-embedded@1.104.1)(sass@1.104.1)(webpack@5.111.0(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.28)(uglify-js@3.19.3)) semver: specifier: 7.8.5 version: 7.8.5 @@ -848,10 +848,10 @@ importers: version: 5.111.0(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.28)(uglify-js@3.19.3) webpack-dev-middleware: specifier: 8.3.0 - version: 8.3.0(webpack@5.111.0(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.28)(uglify-js@3.19.3)) + version: 8.3.0(webpack@5.111.0(esbuild@0.28.2)(lightningcss@1.33.0)(uglify-js@3.19.3)) webpack-dev-server: specifier: 6.0.0 - version: 6.0.0(bufferutil@4.1.0)(supports-color@11.0.0)(utf-8-validate@6.0.6)(webpack@5.111.0(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.28)(uglify-js@3.19.3)) + version: 6.0.0(bufferutil@4.1.0)(supports-color@11.0.0)(utf-8-validate@6.0.6)(webpack@5.111.0(esbuild@0.28.2)(lightningcss@1.33.0)(uglify-js@3.19.3)) webpack-merge: specifier: 6.0.1 version: 6.0.1 @@ -899,7 +899,7 @@ importers: version: 5.111.0(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.28)(uglify-js@3.19.3) webpack-dev-server: specifier: 6.0.0 - version: 6.0.0(bufferutil@4.1.0)(supports-color@11.0.0)(utf-8-validate@6.0.6)(webpack@5.111.0(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.28)(uglify-js@3.19.3)) + version: 6.0.0(bufferutil@4.1.0)(supports-color@11.0.0)(utf-8-validate@6.0.6)(webpack@5.111.0(esbuild@0.28.2)(lightningcss@1.33.0)(uglify-js@3.19.3)) packages/angular_devkit/core: dependencies: @@ -954,7 +954,7 @@ importers: version: link:../schematics '@inquirer/prompts': specifier: 8.7.2 - version: 8.7.2(@types/node@22.20.2) + version: 8.7.2(@types/node@22.20.4) packages/ngtools/webpack: devDependencies: @@ -1158,8 +1158,8 @@ packages: resolution: {integrity: sha512-Aup7aUOfpbAUg2ROOJN6Iw5f9DMBlzu0mIkm/malLQFN/YQgO48wCj0Kxa3sEHJvPVFg7siR+qRInwXd2qhQKw==} engines: {node: '>=6.9.0'} - '@babel/code-frame@8.0.0': - resolution: {integrity: sha512-dYYg153EyN2Ekbqw2zAsbd6/JR+9N2SEoC7YV2GyyqMM7x9bLDTjBD6XBhSMLH0wtIVyJj03jWNriQhaN+eoCw==} + '@babel/code-frame@8.0.6': + resolution: {integrity: sha512-uMHhvmDmwFiLuiozaoRYTZHqMFuu3fem/X9JY78lohAuLoh8LSGGC8JqUzo2cVuBsBxkjMZNk56CE7ock8Xxkw==} engines: {node: ^22.18.0 || >=24.11.0} '@babel/compat-data@7.29.7': @@ -1190,6 +1190,10 @@ packages: resolution: {integrity: sha512-f/TuhuMAxJqhwxEGNsJrswuG9VHmh0oNFoQoo6TbpgtFAz9wYZXcTAcWZMHfp7ljesr0RG04bp3Aos9GI59L7w==} engines: {node: ^22.18.0 || >=24.11.0} + '@babel/generator@8.0.6': + resolution: {integrity: sha512-/pcanjdRsonCexCuxgGD8fKnBLLzk2i9uM4kmcmGyyev2R5YDs+rafMYZ89RvaGY1mW8T7C5au0TyYaEeHBGng==} + engines: {node: ^22.18.0 || >=24.11.0} + '@babel/helper-annotate-as-pure@8.0.0': resolution: {integrity: sha512-NSpMkMsvvZqzThJ0p1B02cbtA2ObEyfBvq950bmNkyxsxvcxwhvvCB036rKhlEnuBBo30bOrk13u3FzlKSoRrw==} engines: {node: ^22.18.0 || >=24.11.0} @@ -1198,12 +1202,12 @@ packages: resolution: {integrity: sha512-wem6WaBj4NaVYVdNhLPPVacES6ZJ+KBBfSkTMD3YZxbP3rm3Di85tJU5ljaUNhaOynt+Aj0xruhYuzQBt8n71g==} engines: {node: '>=6.9.0'} - '@babel/helper-compilation-targets@8.0.5': - resolution: {integrity: sha512-Qk8ahMGooH5mz6uuhoDvfZGkUf/Mf3RTBucVVl4MKx4LKMTv872TeW8O92h15iVtlN8wAROBIpI1aV6x1z0LCQ==} + '@babel/helper-compilation-targets@8.0.6': + resolution: {integrity: sha512-HTrtZ4+iA0+kzdbCgvdSk1U4pEl3BvpGnlUbualCGNbrVhhQvhgBzurTUmqpWyvyHbWYWaIfdx2mOlL9LJjsew==} engines: {node: ^22.18.0 || >=24.11.0} - '@babel/helper-create-class-features-plugin@8.0.5': - resolution: {integrity: sha512-ckUE7tmolBbW4QV02lD874sWSPy8da2A09i/h0qS+IWolR+WiNhpq7C/rHZm00uOIkUb0Cp6+0Cy1ku/wj5uQQ==} + '@babel/helper-create-class-features-plugin@8.0.6': + resolution: {integrity: sha512-Hy7wG2Pk1LnAkFMq0CbBk789XMTYVzYGxR7tKgk+TOpZckQRME3Tdou4mMT/8DFjJFxFZ8R6UsS4DR/duBKlVA==} engines: {node: ^22.18.0 || >=24.11.0} peerDependencies: '@babel/core': ^8.0.0 @@ -1224,8 +1228,8 @@ packages: resolution: {integrity: sha512-3nQVUAtvkKH9zahfWgw96Jc/uFOmjACE1kQz82E2lqWmHBgjzbNlsC22nuQTfahmWeQtTq5nQ/4Nnd2A1wj4zA==} engines: {node: '>=6.9.0'} - '@babel/helper-globals@8.0.0': - resolution: {integrity: sha512-lLozHOM6sWWlxNo8CYqHy4MBZeTvHXNgVPBfPOGsjPKUzHC2Az9QwB6gxdQmpwHl6GlQtbGgS+lj5887guDiLw==} + '@babel/helper-globals@8.0.6': + resolution: {integrity: sha512-OdnA/N52LhzFpeUuVz5YGuSWjc7TPHiFmVYZbPlSgExocO2GwbxVpSni9MVs5wwW+wZ4kPuwBEBN9pIPDYz1mA==} engines: {node: ^22.18.0 || >=24.11.0} '@babel/helper-member-expression-to-functions@8.0.5': @@ -1246,8 +1250,8 @@ packages: peerDependencies: '@babel/core': ^7.0.0 - '@babel/helper-module-transforms@8.0.5': - resolution: {integrity: sha512-lUsSqMD0l5cJKl+3vlTV/hPDA/IvNkcHWVI3zFud2Vur+C9bCKdpqbpkN9eABembedbdWwF0qow6nbdIpNlpcw==} + '@babel/helper-module-transforms@8.0.6': + resolution: {integrity: sha512-YUi+3X0cb0v97xKhuqkLdrwQtP6XXv1eVbhLRCFyMwG481UskbMQk4mjH7K/Jg3oJ1KLskvFwwq4kF/QnABkWQ==} engines: {node: ^22.18.0 || >=24.11.0} peerDependencies: '@babel/core': ^8.0.0 @@ -1286,16 +1290,16 @@ packages: resolution: {integrity: sha512-Pb5ijPrZ89GDH8223L4UP8i6QApWxs04RbPQJTeWDV0/keR2E36MeKnyr6LYmUUvqRRI+Iv87SuF1W6ErINzYw==} engines: {node: '>=6.9.0'} - '@babel/helper-string-parser@8.0.0': - resolution: {integrity: sha512-6mJgmFFFIIO82vvoLt9XtRC7/TkzXfts1t/SpRX4IHSzMgqoPYCWesVu1udUPUWioAE/2fcG6WuI8zrkE1gwrg==} + '@babel/helper-string-parser@8.0.6': + resolution: {integrity: sha512-+6HYEBnsDRZHJtUTAEfMQd0zMDqdFHS7C+5vAsEZqBUr3vEMWOWlHJ0Jz1gS8jJIlCvLsuA6ivmeoqzH936YcA==} engines: {node: ^22.18.0 || >=24.11.0} '@babel/helper-validator-identifier@7.29.7': resolution: {integrity: sha512-qehxGkRj55h/ff8EMaJ+cYhyaKlHIxqYDn682wQD7RNp9UujOQsHog2uS0r2vzr4pW+sXf90NeeayjcNaX3fFg==} engines: {node: '>=6.9.0'} - '@babel/helper-validator-identifier@8.0.4': - resolution: {integrity: sha512-4wFaiLd0bVo4cIoTXI3zKI038NIWE/cr3jvBjejOVYVxV/m8Ltav1USiGzG1fmS5J2RhgEOgXNNK46cRPnRsrg==} + '@babel/helper-validator-identifier@8.0.6': + resolution: {integrity: sha512-HYx0YmuchRxRSpnjvcNffnPS8DCauKNmnumIuHG3jnQAVewRA7kfJGwF13ayEpSZs7s4R/oBH4eppuXcAQd5JQ==} engines: {node: ^22.18.0 || >=24.11.0} '@babel/helper-validator-option@7.29.7': @@ -1318,13 +1322,13 @@ packages: resolution: {integrity: sha512-fQtPOXjYOYv85PIdwotp2TJGVYOycX0PQq+l844fFAxOULtBy8BVF35GyeueX0r4KvDthqPH5xAI1clQPk/2uA==} engines: {node: ^22.18.0 || >=24.11.0} - '@babel/parser@7.29.8': - resolution: {integrity: sha512-E8lTAYNB1KW+FH+VGJuZM1ioAx2E6oVlvQFRrf5P8ZZmsiJXYAD9vTFV7yyEURNzgh1dFqMZuO6tUwcARbqFCA==} + '@babel/parser@7.29.9': + resolution: {integrity: sha512-CjXrNHTnvqBVqHgdBysY3vk2T8tpJHb5/RMeHJBTyVa9xgugCB0CJTx/3oO8RV2QRQP391RWpB7D6hLjm8V9uA==} engines: {node: '>=6.0.0'} hasBin: true - '@babel/parser@8.0.5': - resolution: {integrity: sha512-51RXvQNFakaS0bTpYiGkxNbUVwkPO4kONv6EVLorZABxsx+KZ6Z7uSYvi/wmKS/+X+rfj9RvOw0/ZNh+cmI0Rw==} + '@babel/parser@8.0.6': + resolution: {integrity: sha512-LpGDIYJAzc3Y3PT9x+FxBrGYu2PlWxLmyN7SwPTzaX0LSwEmFJBsRnPBqmaXF2r1v+Zhz6lNiEJ+7yKtM5+Ugg==} engines: {node: ^22.18.0 || >=24.11.0} hasBin: true @@ -1346,8 +1350,8 @@ packages: peerDependencies: '@babel/core': ^8.0.0 - '@babel/plugin-bugfix-safari-rest-destructuring-rhs-array@8.0.5': - resolution: {integrity: sha512-e5eeoBASO+893sCNdFE/vQ9STIxkSRtIcQwBmLdfDOWn1nnXDY+/ngqFC5zTSUTRl0yWR3inkPRlOQD4MMHeFg==} + '@babel/plugin-bugfix-safari-rest-destructuring-rhs-array@8.0.6': + resolution: {integrity: sha512-vk9CzgaQGcTTBL8F0YNr7LBEka6pXP/I5KcMj0oicGXUquWSNqxiijHGQkHF+s8m910NbGMpn5mU2sFV7AQjBA==} engines: {node: ^22.18.0 || >=24.11.0} peerDependencies: '@babel/core': ^8.0.0 @@ -1598,8 +1602,8 @@ packages: peerDependencies: '@babel/core': ^8.0.0 - '@babel/plugin-transform-regenerator@8.0.5': - resolution: {integrity: sha512-eSjLoICd0l8SkUAyV7hnVrsDycTVK7DRKXi3Pr1oqAVe37vdd4sesp8t6aZ/Wa23rV2ZQbnYJWDn7pOIf9Z/Jw==} + '@babel/plugin-transform-regenerator@8.0.6': + resolution: {integrity: sha512-ky/yW+PcQfHyOhbQFNkcHOCIHXaEANYaXCucZ1MY1PdSJRjaf3AX/TMKS6nCij73YtU1bVNy7Zx5NWAJy42TQA==} engines: {node: ^22.18.0 || >=24.11.0} peerDependencies: '@babel/core': ^8.0.0 @@ -1702,16 +1706,16 @@ packages: resolution: {integrity: sha512-I5z7H3bf/41ktsNVLtpN0wAa336HkqIHQ5BuPLEhTkt1jVSyZpeNKIzTgEWmlxjdg81R0IgUCcaE+Ok3NvrfZg==} engines: {node: '>=6.9.0'} - '@babel/traverse@8.0.5': - resolution: {integrity: sha512-XFfnuvapSc/vJOcUO7kwORSvpBIvraofKEZ2dhT0PjiF21BRCD7YbAFC8UEeDJNeLoQz82/gVqzgX5hCzkCbdg==} + '@babel/traverse@8.0.6': + resolution: {integrity: sha512-ilYV+qLStGzSKLipJlETdvdtpK3rAuwfCmCoGKv15MU4EoeIuLkespSNoNLFGOPSciEHx9TLWtN5mv0fz5w5mQ==} engines: {node: ^22.18.0 || >=24.11.0} '@babel/types@7.29.8': resolution: {integrity: sha512-Vj1jF3cPfxg7OAfoI7QnVKLoILlm2JF9pnVHrX8qx7AHMiYWT+NDAA7jChlNgRS4WTLc/fD1lXLmPixluj+3Gg==} engines: {node: '>=6.9.0'} - '@babel/types@8.0.5': - resolution: {integrity: sha512-eVdMqi3ej5aHhyQ2Si6yD2cAWeV8FJK9UrhK5aL0Sd8hu5GhT+YswhVNbVheOGVYMg8kuGuMaUpkB3stjj4z8A==} + '@babel/types@8.0.6': + resolution: {integrity: sha512-c+xgSWboV2pdwXP67BUWDVRHi2BO5Q3KwxyFVs7taVTY+fsK47/L51ZXQoV9rozHJDNHvJ4v4WEsI/IlxV2l2A==} engines: {node: ^22.18.0 || >=24.11.0} '@bazel/bazelisk@1.28.1': @@ -1783,16 +1787,16 @@ packages: peerDependencies: '@csstools/css-tokenizer': ^4.0.0 - '@csstools/css-syntax-patches-for-csstree@1.1.13': - resolution: {integrity: sha512-i9ZylF5QNhmNfPA9l0vHAWK4kPrbIp6g9lKgaiIFsIBz2F/WNB7OLrzlNNcCOm+h42bkaSD2v1PG+IBPHhc3ZA==} + '@csstools/css-syntax-patches-for-csstree@1.1.14': + resolution: {integrity: sha512-HpbVXyrofRXpHpgkNIjU/3EWR4WJvOkO3emNK/L6X/mTJU7bGUI3AkkpoTNXznQLp0KRjLHELTGeKI5dIkI9JQ==} peerDependencies: css-tree: ^3.2.1 peerDependenciesMeta: css-tree: optional: true - '@csstools/css-tokenizer@4.0.0': - resolution: {integrity: sha512-QxULHAm7cNu72w97JUNCBFODFaXpbDg+dP8b/oWFAZ2MTRppA3U00Y2L1HqaS4J6yBqxwa/Y3nMBaxVKbB/NsA==} + '@csstools/css-tokenizer@4.0.1': + resolution: {integrity: sha512-bPlN9S9O1A0euCpEWE4qnvB5YDuyYVsUTrxSgmAM1Is0j4tICHoVyOVAXfWMP/kS9ZrjvyIXWV2PmomiAXXqOw==} engines: {node: '>=20.19.0'} '@cypress/request@4.0.1': @@ -2288,8 +2292,8 @@ packages: '@modelcontextprotocol/sdk': optional: true - '@grpc/grpc-js@1.14.4': - resolution: {integrity: sha512-k9Dj3DV/itK9D06Y8f190Qgop7/Ui+D0njFV3LHMPwPT75DpXLQohE9Wmz0QElrJnzsjB7KPWiKJbOl7IPDArQ==} + '@grpc/grpc-js@1.14.5': + resolution: {integrity: sha512-7VZM+SVdEcUUqSQeNI3zM8Qs/BhQKZndPo2h5VkYkAM8Iz0wJIa8mKV5ekQGqG8UUsnkQ0NMxIxwkIHYvj0qOw==} engines: {node: '>=12.10.0'} '@grpc/grpc-js@1.9.16': @@ -2535,50 +2539,50 @@ packages: peerDependencies: tslib: '2' - '@jsonjoy.com/fs-core@4.78.0': - resolution: {integrity: sha512-0YE5XQj383AwNj5fG0Mm1gyx/ViVe2DJzS5FeVbJulw0pteEK9mfbeB0MWH3/ARoXb2AhHHuiiNthdWF0Y6EYQ==} + '@jsonjoy.com/fs-core@4.78.1': + resolution: {integrity: sha512-UUGcxEah6eb6PyrF8RDEuVgR0Cs2K6XTiLH7YxNR3DknL3wZCNx1nU5m2Gq5Wq8ipy4uHDay3xt/50KyoTN6Zg==} engines: {node: '>=10.0'} peerDependencies: tslib: '2' - '@jsonjoy.com/fs-fsa@4.78.0': - resolution: {integrity: sha512-V1lUo5k4xUypsfdmvCrrUJ44BCixbgvpus71WI3a3BOQt39bK2LasU/HgpJ1P9or8a2d5mWR3kk26sRoehDlaw==} + '@jsonjoy.com/fs-fsa@4.78.1': + resolution: {integrity: sha512-PaoXI4HAELQ/DYxCtqHne7ijrTE0BIEFYXI/qTy4f6pThXiYT5QyJkk96bzpcjdo2D+OM0pUv7mkwffSAl/GSQ==} engines: {node: '>=10.0'} peerDependencies: tslib: '2' - '@jsonjoy.com/fs-node-builtins@4.78.0': - resolution: {integrity: sha512-yiyMh9uKnQvRVDYzINP9P2AXZPdHYM2iVsQ/2U2V+g+gfTr4vPcT1Ox0aQs0IIXGQRAnksyA63KSqpOOJ/O3lA==} + '@jsonjoy.com/fs-node-builtins@4.78.1': + resolution: {integrity: sha512-yaGM1l77yYANFl+w2gdixRZhcQhKodtbI4FZgJg2ApfTTSJcxdYEekU+Ta92sCqSwrOtY+ru4IP81tgJxWXIyA==} engines: {node: '>=10.0'} peerDependencies: tslib: '2' - '@jsonjoy.com/fs-node-to-fsa@4.78.0': - resolution: {integrity: sha512-L1e0UgRJ/igqt3JUDJh3z8YXTKqJc9r9MY4ZakEMOqqEDq/C5fmSZDDzq03d7HqdG1rehkmCDpKyXWqQEVpQGw==} + '@jsonjoy.com/fs-node-to-fsa@4.78.1': + resolution: {integrity: sha512-/Z00TkjLD8zPRimbINaiAQRqpE9HZmiGfxQFMqNcHncmhijS3JsAW21gcNO/16jujoDwXOyEaSSeK+pBtv8QHQ==} engines: {node: '>=10.0'} peerDependencies: tslib: '2' - '@jsonjoy.com/fs-node-utils@4.78.0': - resolution: {integrity: sha512-Am25+Y/rEFtkJBZCFgs84XPXqeqXq4FvXmCYMZ0bEC/M+vT0e6tHBU4Camp9/Yzuf6NoxaInC3iXIN791wVu9g==} + '@jsonjoy.com/fs-node-utils@4.78.1': + resolution: {integrity: sha512-wm0PVK6XpjHH6GLGVi60+ubD7pNv91KwQ8SBWwn+orRTYdfEIci59/VlOddIGhUSde0t9W9gLNetlPKQHQJsSQ==} engines: {node: '>=10.0'} peerDependencies: tslib: '2' - '@jsonjoy.com/fs-node@4.78.0': - resolution: {integrity: sha512-AhoKCEEzsTU5C+9pSegNkErrQijvpHj10kzVhaXIxjs/0taxjCCLG7zE+Y+EWCMNCVmgFEyca+oTQQWm2RO+sg==} + '@jsonjoy.com/fs-node@4.78.1': + resolution: {integrity: sha512-3z6o4qVdKUZTHNXiV+3bKAUkQSD5a2kFwwwag8fe6VvgZ4WNfDbMzWdGvoGx+oRpOcr1iWA9WYwVeVMjSir4mA==} engines: {node: '>=10.0'} peerDependencies: tslib: '2' - '@jsonjoy.com/fs-print@4.78.0': - resolution: {integrity: sha512-Uwk0SvDN1X+5FNW3MxibrFVXXUnd0nTUP6qwvPikg3QDeXRiRww91mz34lXYa/xO5eVuUqa1WXmd0ljy1+Ej0w==} + '@jsonjoy.com/fs-print@4.78.1': + resolution: {integrity: sha512-NUwSD+BOz0TUpBc+riQpI1G1vOhViSZePeqUPxKznelsk3Iwotu6T/02UAY9WdaGcLdlDX8pllEIyxehnYo9Ng==} engines: {node: '>=10.0'} peerDependencies: tslib: '2' - '@jsonjoy.com/fs-snapshot@4.78.0': - resolution: {integrity: sha512-+HvPGwV1IcXtwFFxMBK5x8rmqBuIkPpEFZMGkO8BolJH+AuSvQGVwvlKulUjQ9KECpN4GTCcgeQtyUvYC8heSA==} + '@jsonjoy.com/fs-snapshot@4.78.1': + resolution: {integrity: sha512-gejpLh45sgYGEHWZP/LP2etxaUOYawDfbFVckl9xDDEvgSAtZf700MzCAGbPBPBzRL+qW5UDDwacIgYXHY3C9Q==} engines: {node: '>=10.0'} peerDependencies: tslib: '2' @@ -2835,9 +2839,9 @@ packages: resolution: {integrity: sha512-xJIPs+bYuc9ASBl+cvGsKbGrJmS6fAKaSZCnT0lhahT5rhA2VVy9/EcIgd2JhtEuFOJNx7UHNn/qiTPTY4nrQw==} engines: {node: '>= 10'} - '@noble/hashes@1.4.0': - resolution: {integrity: sha512-V1JJ1WTRUqHHrOSh597hURcMqVKVGL/ea3kv0gSnEdsEZ0/+VyPghM1lMNGc00z7CIQorSvbKpuJkxvuHbvdbg==} - engines: {node: '>= 16'} + '@noble/hashes@1.8.0': + resolution: {integrity: sha512-jCs9ldd7NwzpgXDIf6P3+NrHh9/sD6CQdxHyjQI+h/6rDNo88ypBxxz45UDuZHz9r3tNz7N/VInSVoVdtXEI4A==} + engines: {node: ^14.21.3 || >=16} '@nodelib/fs.scandir@2.1.5': resolution: {integrity: sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==} @@ -3193,44 +3197,44 @@ packages: resolution: {integrity: sha512-7FNeNl8NCE7aINx7WXiKQrPYZWC/hvrTsmk6zmxbI7LTXE7hVek/n8AfVgpe2y82zl3w0HvCHN0bVKMBoJcC0w==} engines: {node: '>= 10.0.0'} - '@peculiar/asn1-cms@2.9.4': - resolution: {integrity: sha512-cben7oxmQsUGZqotus7yt0srYdncOT6RNWcTQ77T2RFOXejYVYkXadrfePdRcrVpO9K95IRLKKglG2k38jKXuw==} + '@peculiar/asn1-cms@2.9.5': + resolution: {integrity: sha512-4Ivz0fsyFofe0bslNsYcGN9+iETdHX4v+BFwIPr+K/BAt61sHXECP63ff9FntU9zcfVQELJFdUG9so44OjUlBQ==} engines: {node: '>=14'} - '@peculiar/asn1-csr@2.9.4': - resolution: {integrity: sha512-xd4YN4vpRjkDAQWVfZZkeu12IEND7DOpkqaHSIHxZl1uggUNa9Ju0QxY2jHvDAS9pP0zhRBytg8ifsnGo3V0jw==} + '@peculiar/asn1-csr@2.9.5': + resolution: {integrity: sha512-9dO6PcoJeI+1xJ4rG7eINMa6f9Ix/QdRs5UGZ0D7v/R3TzmsbVr5cqAgfYw4xgS9U54ouHYqEz0bIZBbM/UY1g==} engines: {node: '>=14'} - '@peculiar/asn1-ecc@2.9.4': - resolution: {integrity: sha512-JJXefFshRAuVAjWQo/39bkg1ywc1VaiO44S8RRC+Ykvf/u2KDmYffoDb0ZBPCR5uJy4AGKQhl8mX+Q8ShcWaXQ==} + '@peculiar/asn1-ecc@2.9.5': + resolution: {integrity: sha512-OD+HLlcV7wCL64w0rheX/C0J31DbJce0nf8ulv3UNftQ617JEZE3sQ4cMN6PotXWlJ1M5GQx90G3bywtdKOstw==} engines: {node: '>=14'} - '@peculiar/asn1-pfx@2.9.4': - resolution: {integrity: sha512-khuGzHTzNzk4GDlIBEILyIs6Lce0yn0ZBdoI9v93kmNncfZRhD+AQ5ODFqdhvoE8cMJF/JMTQ8yA+t1D14kqCw==} + '@peculiar/asn1-pfx@2.9.5': + resolution: {integrity: sha512-btcH7lbcD4410qnjHvv7F0kEuMNKbX8CFAZSs9CDPWHKzT1byLPHYeR40AnUw9z4CzsijMY0daBFYUvVx75sdA==} engines: {node: '>=14'} - '@peculiar/asn1-pkcs8@2.9.4': - resolution: {integrity: sha512-duRdotlUx9eDZe6QrQpQKl61RbWykCHBCkKayP8V8XdEFwlKHZ8qGGDMyS6Pye7OX7nLFttTTpRkJeet78ckwQ==} + '@peculiar/asn1-pkcs8@2.9.5': + resolution: {integrity: sha512-c7UghAGQdBfAHL9JdwcJkAc/lDJKNXfCdYXPXlf8BZdD/fVJjJnXKHxX4gyLhkFTvnGhME7caieSgc2ROtqYTQ==} engines: {node: '>=14'} - '@peculiar/asn1-pkcs9@2.9.4': - resolution: {integrity: sha512-kaL4cNxBpdQE2dKlyZBqz4ygCrwffO+8wfoxTEqM1Z8RadvCeELBRzcv0dzM8aY9azHMwODO5nxU65zXmhToOQ==} + '@peculiar/asn1-pkcs9@2.9.5': + resolution: {integrity: sha512-4R/zMgLSHbQIZRBwP1KzX6iuNHmW3xFWwu9TS9A00N60fmQqp9DkkqnQFyd0mAYMQTrQefuzQ/yP4U8sOLGUgQ==} engines: {node: '>=14'} - '@peculiar/asn1-rsa@2.9.4': - resolution: {integrity: sha512-pZ96eD1PptovcWQ/GSmuNFXd/7EQJNlKfDaNCyE2rx3W0v6QFelkzquVqRSRyyDXXCYD69ZXJDzZ8GhIiQzKoA==} + '@peculiar/asn1-rsa@2.9.5': + resolution: {integrity: sha512-kHwBLVMkm9ljlM521ovS7y4z4mr8xuHTdNyyoPlDvckBwFKSgs9HqKBryLBeqHqL2YpIgl+Vspl7kzNGG2phzA==} engines: {node: '>=14'} - '@peculiar/asn1-schema@2.9.4': - resolution: {integrity: sha512-GjzePcT9Iw8NzeOPf73iNS9xM+TBhd/FilAfP+RQGkTMQJTVWtytN3JHJACCjf/ABNau5S7mS3g+DcuxmRgYEg==} + '@peculiar/asn1-schema@2.9.5': + resolution: {integrity: sha512-Ez3wLKVjaxdsLcgeWN4OE31QkM7oBOgKuuBJxldRYAkfYw2C+8zJPcSd/SThnbhszsEOlAmoaS5kIIkN29fGKQ==} engines: {node: '>=14'} - '@peculiar/asn1-x509-attr@2.9.4': - resolution: {integrity: sha512-ehQXbpQaQYycgu8OrvigwSPTFfVRcu0ECNYCWw+yzBp02Lw5paRqzzhUpfOgO2K38+WfFZuEz/0RPtam5g0OMg==} + '@peculiar/asn1-x509-attr@2.9.5': + resolution: {integrity: sha512-PlbL1a74RZiry7puPCZ5hdk/puvivxYJPbjadr2i7DBjHCJFEKCfTRPKL3DILeZFtzJjn95J5EBtSc4/TB9/6Q==} engines: {node: '>=14'} - '@peculiar/asn1-x509@2.9.4': - resolution: {integrity: sha512-CxhBo/RdEbMMob7T31ZdQjGuoyRFLVwrDzTn25bihzBasRg9kRm/0IxIPvhgQtcK/9dNcO1XQL2fuPugwELL0Q==} + '@peculiar/asn1-x509@2.9.5': + resolution: {integrity: sha512-NP3ecvN6zTDlwCvogIWL7MJN9AZNuskkIbnlhrlkB97Mn2EqirBUQ8GKzsOmdAL3pRvjGu1Uk/a4DNfiZrWxhw==} engines: {node: '>=14'} '@peculiar/utils@2.0.3': @@ -3708,8 +3712,8 @@ packages: '@types/micromatch@2.3.35': resolution: {integrity: sha512-J749bHo/Zu56w0G0NI/IGHLQPiSsjx//0zJhfEVAN95K/xM5C8ZDmhkXtU3qns0sBOao7HuQzr8XV1/2o5LbXA==} - '@types/node@22.20.2': - resolution: {integrity: sha512-xlvWf4Vs9n1PEVYwP1n4vvG07M6y8WgvJ2t0vbrWTmijsIHp1cS+uJ2kMIRdY3nHZK0nCYKrPeD171+SzF4/zw==} + '@types/node@22.20.4': + resolution: {integrity: sha512-zJRE40jpHtKqE/C4fgHrAKQLJuSpzEnP9ff9Y7YtoR3Wd2pwqzlekDeEuUQXjRd+QCYnVnNwuJYmhdk9XV8gvA==} '@types/node@24.13.5': resolution: {integrity: sha512-TXyindR+lBr22aJIdMQzCFHPHR6cR4js838mRDCSz5hOKWZvZwsXSSiXDmjRj4iJmgl+sR9O+1mkoVBSMadNug==} @@ -4005,140 +4009,140 @@ packages: '@yarnpkg/lockfile@1.1.0': resolution: {integrity: sha512-GpSwvyXOcOOlV70vbnzjj4fW5xW/FdUF6nQEt1ENy7m4ZCczi1+/buVUPAqmGfqznsORNFzUMjctTIp8a9tuCQ==} - '@yuku-codegen/binding-android-arm64@0.9.5': - resolution: {integrity: sha512-jrOY5WM+AaAqkv51fHP1x28ifto4WgcZVzodLUyMU1jMWn5Sq+VciRdk/n8E0Ey5w4p4cWWE+m5GfXWOYh7Kzw==} + '@yuku-codegen/binding-android-arm64@0.10.2': + resolution: {integrity: sha512-Oc2KInVkPfUjEB4PeV6X0NvIoyYTzDe/WmqFrTwBqKs6YKnz4A7XwWQvJTb7M0rLz9a6WgpUUiiS5QKaCi4O/g==} cpu: [arm64] os: [android] - '@yuku-codegen/binding-darwin-arm64@0.9.5': - resolution: {integrity: sha512-4O4lkCQIzPZGjiNB1GORSI6hBECbiiSBS/APZXPvNKYH+nhY4uuqv03LNXA+SET3hoBjvr95P5rIhY8KQaQUBA==} + '@yuku-codegen/binding-darwin-arm64@0.10.2': + resolution: {integrity: sha512-3H7eNPIHJndUJXZ4QUGBPq1zC6RGcUZfm7bymJes+/N7wTVWUn1bxZ9JcozYHpkWQNm9f23G8YWbaHD9aYH72A==} cpu: [arm64] os: [darwin] - '@yuku-codegen/binding-darwin-x64@0.9.5': - resolution: {integrity: sha512-9EvoUO0SEhD6/d8VHdWuPerepPMSR1y84+UEgz8Un1Ope14Oe7xMvePpEQLTLovoIFZ8Zg3iZ8z8E11pZMqC3g==} + '@yuku-codegen/binding-darwin-x64@0.10.2': + resolution: {integrity: sha512-AJOUpR2s3LF9AWiiub/Uyc/UoXNTWcq8hK3cVI6fUSXtwh34dG21J6hRuNlO6JVJFTo4o3ScVvZOrh/YFfUEAA==} cpu: [x64] os: [darwin] - '@yuku-codegen/binding-freebsd-x64@0.9.5': - resolution: {integrity: sha512-HqT78WwgHTmp8lwujoUa9CrIortX4DdpuiVC18ZPSGvuuJf4ylpIEI6QrQEM78Zwz3muhAWAOXZ5irdiYY+AyA==} + '@yuku-codegen/binding-freebsd-x64@0.10.2': + resolution: {integrity: sha512-ms7DcZu87u5CiK/wMwvpKAvAmtaqKjCQIXNweMLypG6qbuiaOMQf1jpbB5+j46xBcgCovo8TQMcv0bCQLKIL9w==} cpu: [x64] os: [freebsd] - '@yuku-codegen/binding-linux-arm-gnu@0.9.5': - resolution: {integrity: sha512-QJXwIW6Ms3QIawbcBIedmrmXnfdpuAOjZJ/eAABq5XTzWvSxZ7lutu9W5yIHahlaTaFnBo7ikrVMD1szLTpPUw==} + '@yuku-codegen/binding-linux-arm-gnu@0.10.2': + resolution: {integrity: sha512-xJDpYAsKV5+eaiBhTYl05fvT6sst4PsCeuIFMRu9b0/WCSrNQPfCDtAQ5/MS6xNpsdujdZEPR+gmfWk3ZG5i3A==} cpu: [arm] os: [linux] libc: [glibc] - '@yuku-codegen/binding-linux-arm-musl@0.9.5': - resolution: {integrity: sha512-eHbFy3IHGb+IYarrYwAo0yWSEQV3eAmEn6VrsKA6I1Wy1YPJxWqSJlV69JhqsHtJuJlljUIF3ex0y46yaKIu9w==} + '@yuku-codegen/binding-linux-arm-musl@0.10.2': + resolution: {integrity: sha512-qfTkgd7AEx61l4K9VtXWCGTxc/fmXJ4ZheDz3i+/AAJUtg4sa0bPrc0VBxPggB/rayR8Z3+JfrBItuyanBJJ9Q==} cpu: [arm] os: [linux] libc: [musl] - '@yuku-codegen/binding-linux-arm64-gnu@0.9.5': - resolution: {integrity: sha512-ByoJMbySTaDhjAXSu8q6Lh7HKg3YoesXpcT72aYk0Aiw4PCznmY4ybpLTq0RCvp0RIPhFm/6yECFiGBwyCC1nw==} + '@yuku-codegen/binding-linux-arm64-gnu@0.10.2': + resolution: {integrity: sha512-4e6Mifm/4UdjtU3D8mATIrvgP+xEiH8xtQOjd0zpd72XKWT7ug3sdyhq2utkkZFP6BvYp7SgZrI+aR4VeIOHdw==} cpu: [arm64] os: [linux] libc: [glibc] - '@yuku-codegen/binding-linux-arm64-musl@0.9.5': - resolution: {integrity: sha512-gD9vfXIoBw1toSxhO9rgmSu/FEfy3PMznJAxVjIuH8DrWEiDKXmJO0pJKfj1Ltbe/TmtWVZR+TjISqeSIGQzMg==} + '@yuku-codegen/binding-linux-arm64-musl@0.10.2': + resolution: {integrity: sha512-RdsJrUfDYFVV3JOmWFUWwSu31fa1APn12xDeIKxgl/YWxrabwtxsDBNjF2561c7tmcbiewdCUvngqRs8AyGVLA==} cpu: [arm64] os: [linux] libc: [musl] - '@yuku-codegen/binding-linux-x64-gnu@0.9.5': - resolution: {integrity: sha512-BARvdnvqMGjOr5Iel2JH+9H5vAIE0R6H0Z2fsT02xrvmI/1ZXNB8lkuX+ZGevPhZb3zJ9WeC/R8JZstrsUOK5g==} + '@yuku-codegen/binding-linux-x64-gnu@0.10.2': + resolution: {integrity: sha512-mVzWimEPPreaPyXIUvxsHoJzvO7ckZ5j0LgQFHz04zQIRwt9A9T2hA7K5/jYjJKkMxWG/U2VjhGNwVhtyU+uqg==} cpu: [x64] os: [linux] libc: [glibc] - '@yuku-codegen/binding-linux-x64-musl@0.9.5': - resolution: {integrity: sha512-x8flcevS1fbb7ESrmpOY/pON4eInSaE/7Ktjqx2udOE2W33BNSZmJuwpyUgo54AoHNqrcaM7szqydyJn5fNvew==} + '@yuku-codegen/binding-linux-x64-musl@0.10.2': + resolution: {integrity: sha512-Y77fyISurmr2mvO1yeq3u+x/WJbACgPR4w+lzEVx30ViCxZzIGrZPRN1yEdZ9xUNPNsIO5thBHIdRNG+UGUG+Q==} cpu: [x64] os: [linux] libc: [musl] - '@yuku-codegen/binding-win32-arm64@0.9.5': - resolution: {integrity: sha512-KOL/rBatWqH4ZpCNoF8ZtSNdOJbAxBJLmk/VeRciepGROPTbPum1A9t67GpFgOU7qrkUWlPJdJ+KHKbvbmOt+w==} + '@yuku-codegen/binding-win32-arm64@0.10.2': + resolution: {integrity: sha512-1+tGLyG0u5YYy0lev4ck7/0sd8xJ9SZde0dLut7qLDPZV5WVTV8x6OxNXUne/PGuHZyO1vK+txPQzzHOyXHGSw==} cpu: [arm64] os: [win32] - '@yuku-codegen/binding-win32-x64@0.9.5': - resolution: {integrity: sha512-FxENahEjWSan59Syh/us/Kf4wNq8qrJLFJ3R2N4Oiwtb6yNdz/rWLNTIoNSssnsp7IoWJdUP6o/Z8ppg7lXMcg==} + '@yuku-codegen/binding-win32-x64@0.10.2': + resolution: {integrity: sha512-8a2SExRohRbwC0MY4VpOF0/RSckrJ2ASZqAor5/RYSJJaeadR93n10gZzcKT6pY9ukiSOIZCRKVRD2tH73T0qA==} cpu: [x64] os: [win32] - '@yuku-parser/binding-android-arm64@0.9.5': - resolution: {integrity: sha512-A2JCFCSHfnficqYEw4Iujpx7XrkMM3UfFcgJFmYpZSo9zM4nyhmdIIE0FogSduuU60lhM0/UcfuUBXIVNBMlGQ==} + '@yuku-parser/binding-android-arm64@0.10.2': + resolution: {integrity: sha512-2VPBU9fRGRAQ2xPAvghnec3oou5Nrxm2Bezhf+13UMspAxQSkF/32r+ySKXSwIPA5/RivumDJDxAxc301Sgicw==} cpu: [arm64] os: [android] - '@yuku-parser/binding-darwin-arm64@0.9.5': - resolution: {integrity: sha512-3PiyU+Eare4YuKaQ22N98/yAiROPY5o/NQJHraICzDvk4pgS+m+bgLKOvkGBRn33OnV95Vdv1Mn38b+MQHpULQ==} + '@yuku-parser/binding-darwin-arm64@0.10.2': + resolution: {integrity: sha512-LD+PMZE51tCYTOss5HBkm3/AE39MvcMDBfWJx7A4yDcjfNbAQDnHZKtzSOuqrswx+TQHY0ws5xn6+fWOwtmfBA==} cpu: [arm64] os: [darwin] - '@yuku-parser/binding-darwin-x64@0.9.5': - resolution: {integrity: sha512-blFMAFI7AInI83XaiOF8cIeiRM46Nz9EfpZtZPRLbKxSA9aAr5v8aHYpmfN6NoyXxAv/10pwS4gsAuc1W6fy5Q==} + '@yuku-parser/binding-darwin-x64@0.10.2': + resolution: {integrity: sha512-mmZ8cND+AoIIMRERyMinlg5ApHxP23B9jH2B5wT7T+dliPa9rubLxneB/SUjFwyUjGaFnB5G7t4YvpfbO5zbkQ==} cpu: [x64] os: [darwin] - '@yuku-parser/binding-freebsd-x64@0.9.5': - resolution: {integrity: sha512-TsNuL4qsZdO0tHp5GW43Y5fHeLPpPHA675wdcPNTcdq2ZO5AvsQWFFoiDg8CH4oBktfsQ9tdvKhjLnLYwKvp4g==} + '@yuku-parser/binding-freebsd-x64@0.10.2': + resolution: {integrity: sha512-gVIjaaIddbRfAhHlC8N809wQWml7mxfSVnzaLtzGXObTeFTPAg/YVnQXt1UOhPM1ah5eG/8Y0RUlNpB4GVe7eQ==} cpu: [x64] os: [freebsd] - '@yuku-parser/binding-linux-arm-gnu@0.9.5': - resolution: {integrity: sha512-b0afYK5gHeV8RdmOcqAlgM8ONsye4cax4DMnIBaoJyPMd1UTGvTbpkqQcPVdhmHlcfcGVGMV1laeVovlr/dscw==} + '@yuku-parser/binding-linux-arm-gnu@0.10.2': + resolution: {integrity: sha512-q/XPPQQAPdlw05aPj30ygBhekmQryGOwxVraBgApjKK8yY1kNQgqq6XCYLF1WHSee+lhxclrTO7W0/bt7dR1GA==} cpu: [arm] os: [linux] libc: [glibc] - '@yuku-parser/binding-linux-arm-musl@0.9.5': - resolution: {integrity: sha512-fD3lKzl+r6j6n8DwiMY53qnh5DLqD8KJjCp+NbVud54Nnh3Q9Wprqss3YzyMHP3NSJk663Wlg1E1X5qOuFVFig==} + '@yuku-parser/binding-linux-arm-musl@0.10.2': + resolution: {integrity: sha512-A+Cb0I1hFF4wilTQpWs79k1aNnj4B2tkrHx3zsuUNF9BtVY2zPZ4yeQEM/zjXrS/qJlNMZVK9NrWJjwdpnTrfg==} cpu: [arm] os: [linux] libc: [musl] - '@yuku-parser/binding-linux-arm64-gnu@0.9.5': - resolution: {integrity: sha512-aRU/aCphV1MWCl/lvI6NX8LgucHQ68Fx+vz7NBb/5MEr2EuzCxiPOQqeFcMdWh+2AED/p0AvAREch0c+cSnlhA==} + '@yuku-parser/binding-linux-arm64-gnu@0.10.2': + resolution: {integrity: sha512-aGNSzqIqqphFwAdIFwVvKIyXD1Iy3CxrEJVIZAT87Ecyi4vCmmDD2v2l9h+Gd3/wSy3JZlOI792LJbKAjyy9rQ==} cpu: [arm64] os: [linux] libc: [glibc] - '@yuku-parser/binding-linux-arm64-musl@0.9.5': - resolution: {integrity: sha512-5+Guro0l8H473YXlEjVNBRLN/IbPbJdnQh1zo0OLt49xxnON+XMJRRaEyTOTfkn9QSRg0+BhEKGR4W9Gu2uZJQ==} + '@yuku-parser/binding-linux-arm64-musl@0.10.2': + resolution: {integrity: sha512-Ddl1sF0rtuCXyHGSOV6dcmdx+ETv1iD+IVFqQuOjzkJZWclxJxdBWX6ZJMRtTiGqGUTbqLEKiTXxpR/Bvqk+2A==} cpu: [arm64] os: [linux] libc: [musl] - '@yuku-parser/binding-linux-x64-gnu@0.9.5': - resolution: {integrity: sha512-pwwSyV9q+GlvzSXlsMZBMlgk22L5bud714/vqZCdeUTivzeUVltQzUaf3IQXOGXdpc59JYTeuMCtbGquaAUoCA==} + '@yuku-parser/binding-linux-x64-gnu@0.10.2': + resolution: {integrity: sha512-/nlcpR6IF5U+0m5L9wvAIXeQa2DT+BXuvqKDsTcOTlcc0B4dHNyqE5hTXsS4hAyimpy2ZK8A1zMNF5hTrjg2cg==} cpu: [x64] os: [linux] libc: [glibc] - '@yuku-parser/binding-linux-x64-musl@0.9.5': - resolution: {integrity: sha512-z18j6JN3lBHH8vzN7gG1M8fI0nlgItSfnC9PfbmUbt97iHViKfw2iA2G9fGwRMe5LyPRZBrejIlapbygPbpdaw==} + '@yuku-parser/binding-linux-x64-musl@0.10.2': + resolution: {integrity: sha512-GX80dxTQD/M/OryyuxJcFzFENzry3cDFPvCFTyWogNWQH3fSHfMrNfpwpl1YzMos1eV9NygK5GSDG7VArQlb4w==} cpu: [x64] os: [linux] libc: [musl] - '@yuku-parser/binding-win32-arm64@0.9.5': - resolution: {integrity: sha512-s6Gwttb1dQvtPX6Bgkw+UPC9IO3UBDXc6Zezog8MMgvu3UfJBBB9TQqKBX/2quu0Eyh+lLSAyNlIyyecaagUPg==} + '@yuku-parser/binding-win32-arm64@0.10.2': + resolution: {integrity: sha512-agePQBV4VHewiGU0ACSjscZ/hJd283f9JfAF19Gf1rI5+wy5tTgx4GS36i0b3xim15AQ4RCpDRosEvhLZ4zAOw==} cpu: [arm64] os: [win32] - '@yuku-parser/binding-win32-x64@0.9.5': - resolution: {integrity: sha512-FrERt9YWatY3bJfSUdi4YWY+6iQcyo3MzCC821BxlWM5TFZEHijnpz/bknR79VHlXY/9CvXz8ZlaAGPsTtN3nw==} + '@yuku-parser/binding-win32-x64@0.10.2': + resolution: {integrity: sha512-s8//CMpgL5+y1lvDCdyh1rwGI5+ytDJywFJRe1vnhI7n0j+caxshNucurikYLLVeQ2SYFex6aPrzgQxkabBQRA==} cpu: [x64] os: [win32] - '@yuku-toolchain/types@0.9.5': - resolution: {integrity: sha512-KiuLNNgX9uNealaWAR+G3/cMXnRk9x4TY2EkYe/KIag+UPdwiA0RRf1hr1WAxzTP8KGzCTkqUdLPvqh32sEO3w==} + '@yuku-toolchain/types@0.10.2': + resolution: {integrity: sha512-sSeo4SSSToiS+sSD+bwn/s94EEcaLJ7tG5LCp8gFYC1G5VzxzX7fqB6m9RU1yMD8KTpu6zdU/I1NlQf8hVBJ9Q==} JSONStream@1.3.5: resolution: {integrity: sha512-E+iruNOY8VV9s4JEbe1aNEm6MiszPRr/UfcHMz0TQh1BXSxHK+ASV1R6W4HpjBhSeS+54PIsAMCBmwD06LLsqQ==} @@ -4422,8 +4426,8 @@ packages: resolution: {integrity: sha512-lGe34o6EHj9y3Kts9R4ZYs/Gr+6N7MCaMlIFA3F1R2O5/m7K06AxfSeO5530PEERE6/WyEg3lsuyw4GHlPZHog==} engines: {node: ^4.5.0 || >= 5.9} - baseline-browser-mapping@2.11.23: - resolution: {integrity: sha512-le521dGVfxM7yRX0EikCoSz+rOK+hHzdDt/E7mG1jOJB/6WAAUuwVroLwaB7ApaUsz5Q0kFlDXLSA9MheUIfRQ==} + baseline-browser-mapping@2.11.25: + resolution: {integrity: sha512-gMmEShwwq7FJqMwvfRwvCl00v4kN+KOfJqXn+f4nrufak5gNHJOksd/60Dvjuz7sI8Y5WiSFBa8FEYr+zoyqCw==} engines: {node: '>=6.0.0'} hasBin: true @@ -4474,14 +4478,14 @@ packages: resolution: {integrity: sha512-DkVaaQHymRhpYEYo9x1oo7Q7B0Y6KJUsjm3c9eTyFDby4MHLBTwZ6ZDWBel5zrYxj1WsZgC5oLpiz+93MluXeA==} engines: {node: '>=20.19.0'} - brace-expansion@1.1.18: - resolution: {integrity: sha512-Edep/X9fGqVNmzKBVsDYIOtD+z1tuezV70LBjdCst9Tqu76lsnvRiZ6oTic1n+/BIwX6QDGAO94PN4N2SADvtw==} + brace-expansion@1.1.21: + resolution: {integrity: sha512-9zeA+KLZNNzglF2TPKRQEDyx6Yby7daAkuy8MiPzpXPsYDWi/DRM8jmwUDxokQjYqBpv5DgPiwD4h4ZZSy1Ujw==} - brace-expansion@2.1.4: - resolution: {integrity: sha512-hGfVzPxthbf3+2yjg/RBs60cB0FhqBS/zvdV/4wn4/BmN0bNMMHPc4V/BbFieqf1TKAGGAHnY4eSjajCl0f2Xg==} + brace-expansion@2.1.7: + resolution: {integrity: sha512-uZbew1NqdmPDTMJ8ah1y+b+9QEJrfkXFk3RcTQw3X0jW/xRUvFKsg1CfQdSYGdTbXZWExtU3J3ccxtnfw1Fi0g==} - brace-expansion@5.0.9: - resolution: {integrity: sha512-ScQ4IuvIEF1TMlP7Zt+vjJ//9zlPb2SDcxWxM3bk8s6t6GGdJ7KO1dCcTidOPJKePW30LE/2cT7wCyPho9/Wxg==} + brace-expansion@5.0.12: + resolution: {integrity: sha512-YovQ3rzhaLMIrDjNDMkNS01tea93qhEhG5xy8f6+R0l+dw3Ki+5sCoIoI942iuLZTHWogWktgwVDhU09iNEimQ==} engines: {node: 20 || >=22} braces@3.0.3: @@ -4506,8 +4510,8 @@ packages: browserify-zlib@0.1.4: resolution: {integrity: sha512-19OEpq7vWgsH6WkvkBJQDFvJS1uPcbFOQ4v9CU839dO+ZZXUZO6XpE6hNCqvlIIj+4fZvRiJ6DsAQ382GwiyTQ==} - browserslist@4.28.9: - resolution: {integrity: sha512-EWazOblFYUvlGZcfGhPUPmYh3nikUxBVb+y9MJun5f3hBi812X+8MSQTujLBtgK3cf51fJWbWfOjyeO954d+Eg==} + browserslist@4.29.0: + resolution: {integrity: sha512-3GSvyjvDI4Dur1Meg2BekJquu5uF+9R9a1+5M1Mde192eZoXbeXjzgOsgqPS2V8D5wrrip0gR5Hf/GhWQ9ZzaA==} engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7} hasBin: true @@ -4738,8 +4742,8 @@ packages: resolution: {integrity: sha512-mj7UPXE0jaqaOsukNZRUEfEi2AcL7C/vwmwcHV0O97eO1E1pxBZuyjlZrx5seTaNBg1U6+o35wpa35Qfcc+7ag==} engines: {node: '>=18'} - content-type@3.1.0: - resolution: {integrity: sha512-z26wZR7iXahgpSK7XgnB4IbRVmUNSODvsX9qC9TAru7AcWGiqn5YKy+OH3PLRrwyAnewykKhCqnD+VV3a8uT8Q==} + content-type@3.1.1: + resolution: {integrity: sha512-GW4qUsfFo59d0HbUibDlWv5wPz+vAAcaTWbKIuKCf0JkC7wWkSyf8f13IpXn5JkeMlB2P8iTSSIjwXljorg2vA==} engines: {node: '>=22'} conventional-commits-filter@6.0.1: @@ -5046,8 +5050,8 @@ packages: engines: {node: '>=0.12.18'} hasBin: true - electron-to-chromium@1.5.427: - resolution: {integrity: sha512-n14zb3FdsChZ2BNobqNHAJMcP3ifFv4paox2LvCrfVAQcqGiSURgbJl+PfMpHVCNFkStnNc+RRVtPBTVW5PDgw==} + electron-to-chromium@1.5.433: + resolution: {integrity: sha512-5lCAbyZBjtmUt/RAGHRqrL2q0oEFRThDAsZHHDn9XHa89Qw7gMYOeSicBTy+AHfvo0r6vwsZvqNJTQIQy1BLzA==} emoji-regex@10.6.0: resolution: {integrity: sha512-toUI84YS5YmxW219erniWD0CIVOo46xGKColeNQRgOzDorgBi1v4D71/OFzgD9GO2UGKIv1C3Sp8DAn0+j5w7A==} @@ -5062,8 +5066,8 @@ packages: resolution: {integrity: sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q==} engines: {node: '>= 4'} - empathic@2.0.1: - resolution: {integrity: sha512-YGRs8knHhKHVShLkFET/rWAU8kmHbOV5LwN938RHI0pljAJ1Gf6SzXsSmRaEzcXTtOOmVqJ5+WtQPL5uigY50Q==} + empathic@2.1.0: + resolution: {integrity: sha512-AnfC1ATldl49/cvZdLPDjBfrRNwbDO05aibiOtzQu3qtlbJtomNLhF30HEtn/7iBz50dlMECqATo3fG0LrdEgw==} engines: {node: '>=14'} encodeurl@1.0.2: @@ -5340,8 +5344,8 @@ packages: fast-string-width@3.0.2: resolution: {integrity: sha512-gX8LrtNEI5hq8DVUfRQMbr5lpaS4nMIWV+7XEbXk2b8kiQIizgnlr12B4dA3ZEx3308ze0O4Q1R+cHts8kyUJg==} - fast-uri@3.1.7: - resolution: {integrity: sha512-dOvZVzjdZdz7phd9v6jCbwxrBW3fK6n8Rc0CtdmM4bumzMnxywBYhuph6J819RRw/ku+rLbelwfMunktuzVVHg==} + fast-uri@3.1.8: + resolution: {integrity: sha512-GZMtZUTNRpOVIECoXwLNZS5xUGE+mVNbTB8h/7Rwh2TFWcBQiPzTgyZi05BF9UMZKkLJv8XBRJTlU7zg8+ZfMg==} fast-wrap-ansi@0.2.2: resolution: {integrity: sha512-7F2Fl+TjRSenLqlU3UjSH0iyqopqoZIu7eZVpEirP2g1GtWa2G/ecEmBdgz31+Mxr+ELclgg6sokpSFIQiZ02Q==} @@ -5414,6 +5418,10 @@ packages: flatted@3.4.4: resolution: {integrity: sha512-5+ybhBZANEJxaH3X5evAFatUxLfEHSr7n6kYJ+1Qd0mUqr4eu9gIf6GDbWHf8RJijHrjjO8G+la14SlL2SeS1Q==} + flru@1.0.2: + resolution: {integrity: sha512-kWyh8ADvHBFz6ua5xYOPnUroZTT/bwWfrCeL0Wj1dzG4/YOmOcfJ99W8dOVyyynJN35rZ9aCOtHChqQovV7yog==} + engines: {node: '>=6'} + folder-hash@4.1.3: resolution: {integrity: sha512-94fj+fXj1XHT8zGumUy/VlyFARc/yrslKJ2+vjrP/U6ftTdL7u68+gQhvSBjz9wrwTuty6BpZ7JsbEK5OU9RNw==} engines: {node: '>=10.10.0'} @@ -5519,8 +5527,8 @@ packages: resolution: {integrity: sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==} engines: {node: 6.* || 8.* || >= 10.*} - get-east-asian-width@1.6.0: - resolution: {integrity: sha512-QRbvDIbx6YklUe6RxeTeleMR0yv3cYH6PsPZHcnVn7xv7zO1BHN8r0XETu8n6Ye3Q+ahtSarc3WgtNWmehIBfA==} + get-east-asian-width@1.7.0: + resolution: {integrity: sha512-XjH1AECxf0giL2V1aU8vKyRR2ppRUb5c0EvT7zuJTokQ74bNo52zOtghqdWIqrhUD79fo3x0WfKZdOqxF6LG1Q==} engines: {node: '>=18'} get-intrinsic@1.3.0: @@ -5858,8 +5866,8 @@ packages: resolution: {integrity: sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==} engines: {node: '>= 0.4'} - is-core-module@2.16.2: - resolution: {integrity: sha512-evOr8xfXKxE6qSR0hSXL2r3sd7ALj8+7jQEUvPYcm5sgZFdJ+AYzT6yNmJenvIYQBgIGwfwz08sL8zoL7yq2BA==} + is-core-module@2.17.0: + resolution: {integrity: sha512-J/vG0zBCbIKOQFfufSwyXdMrsohyJIUNkrnmo6WZGzoM7tr/lsbfW5b2BvisL6zsyMzK9UxV9L6c7AoFbyXHOA==} engines: {node: '>= 0.4'} is-data-view@1.0.2: @@ -6451,8 +6459,8 @@ packages: lru-cache@10.4.3: resolution: {integrity: sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==} - lru-cache@11.5.2: - resolution: {integrity: sha512-4pfM1Ff0x50o0tQwb5ucw/RzNyD0/YJME6IVcStalZuMWxdt3sR3huStTtxz4PUmvZfRguvDejasvQ2kifR11g==} + lru-cache@11.5.3: + resolution: {integrity: sha512-U4N8FgzmWxc8k1VH8Kr6lQg18U7Fjvby6wXHVRX/ZZ7IwWbRMgrRbP0Wrb5q5NVinryp4SQampHKdvtecItxUg==} engines: {node: 20 || >=22} lru-cache@5.1.1: @@ -6465,9 +6473,6 @@ packages: magic-string@0.30.21: resolution: {integrity: sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==} - magic-string@1.2.3: - resolution: {integrity: sha512-Bpb0W2TbLKOZ7vJnOUnVRGq3WL2p+ISV29M6hYPL1AFCpyKZpdr5ytiXoTSSxRVhg8YW7f65+6gbG8WG6PCa/g==} - magic-string@1.4.1: resolution: {integrity: sha512-8lyCu36ErXR0J9uaGKlKQoiLZKmtI63YGLE8G2o9jyRPdr4X47LusSOwgOJOzcVtp81fTAAjxR7BwKz682Jhow==} @@ -6497,8 +6502,8 @@ packages: resolution: {integrity: sha512-yz3xRaG20c6/BOzvYoDaGtPmGscs7YivItZEEqe6GbwNfHuxu9YNmvnEkMzKldAGY4/80pRcQRZSEnhquk9XuQ==} engines: {node: '>= 0.8'} - memfs@4.78.0: - resolution: {integrity: sha512-gX14RGPP+fyNodL8g9jc5DfKtWNCronEMItOKDyZatTI3CPpMZDPtm7rAbftDqQAFovP4nzR0RO80sESSEnI4g==} + memfs@4.78.1: + resolution: {integrity: sha512-SkSlK6DZbzekBoiu0mcHUx9RRPnsBdaKQ36u8F3HvYZm/lRiD34YabQ2Xr76r+zYENzRPFKBsanAZPSl+r3Nqg==} merge-descriptors@1.0.3: resolution: {integrity: sha512-gaNvAS7TZ897/rVaZ0nMtAyxNyi/pdbjbAwUpFQpN70GqnVfOiXpeUUMKRBmzXaSQ8DdTX4/0ms62r2K+hE6mQ==} @@ -6585,8 +6590,8 @@ packages: minimist@1.2.8: resolution: {integrity: sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==} - minimizer-webpack-plugin@5.10.1: - resolution: {integrity: sha512-+dsZEyTcy1lkq41lxdiOqvb26gXbYGgwY+30w37f9PqUVkuEBejBLDotsHOTjuga9xJyGLW2DqzKDUyJ4W/PMQ==} + minimizer-webpack-plugin@5.11.0: + resolution: {integrity: sha512-2JVy2DY+iBtfRyrQB5cRM7lfurnJIi6jFTgLip/7FxDu0WxswrIRzr4fBySQ0X7HqM7BcwE28zm+HfQ5V6y4Cg==} engines: {node: '>= 10.13.0'} peerDependencies: '@minify-html/node': '*' @@ -6778,8 +6783,8 @@ packages: resolution: {integrity: sha512-LA4ZjwlnUblHVgq0oBF3Jl/6h/Nvs5fzBLwdEF4nuxnFdsfajde4WfxtJr3CaiH+F6ewcIB/q4jQ4UzPyid+CQ==} hasBin: true - node-releases@2.0.55: - resolution: {integrity: sha512-mIrE/Cw9y+9Au6dS5vDKDhQza9YvG6w+ZrS6X+ZzA7yFW/soAeaups4Qzn1bL6g5FVy8WtP79+0j82oPIbqRjQ==} + node-releases@2.0.56: + resolution: {integrity: sha512-x0InOIyzgdk+eyaWaRJFH5snEtiImgBgblZ2CyPrLmqqcuMQkEvcDPHbzqbD8eDsSeJbVOjn+crzyzHaM4D+/A==} engines: {node: '>=18'} normalize-path@3.0.0: @@ -6838,6 +6843,10 @@ packages: resolution: {integrity: sha512-XrsrhT5sybtKI6wakr2SPOlGZWWYbUXZ7a0jT8/QOeAPau+1X/bSegNe5YR75oJmEZQbKningirmGOEJCIk61Q==} engines: {node: '>=12.20.0'} + obug@3.0.0: + resolution: {integrity: sha512-5vvB5+W7ePv+p3uqxi+RcW1XAzLW0/hxt3/4X4Lc4qHudzOhmBiBwOY6DRob4WnanAEGvNcLjF+KNOufrUoEQw==} + engines: {node: '>=12.20.0'} + on-exit-leak-free@2.1.2: resolution: {integrity: sha512-0eJJY6hXLGf1udHwfNftBqH+g73EU4B504nZeKpz1sYRKafAghwxEJunB2O7rDZkL4PGfsMVnTXZ2EjibbqcsA==} engines: {node: '>=14.0.0'} @@ -7025,8 +7034,8 @@ packages: resolution: {integrity: sha512-4peoBq4Wks0riS0z8741NVv+/8IiTvqnZAr8QGgtdifrtpdXbNw/FxRS1l6NFqm4EMzuS0EDqNNx4XGaz8cuyQ==} engines: {node: '>=18'} - pkijs@3.4.0: - resolution: {integrity: sha512-emEcLuomt2j03vxD54giVB4SxTjnsqkU692xZOZXHDVoYyypEm+b3jpiTcc+Cf+myooc+/Ly0z01jqeNHVgJGw==} + pkijs@3.4.1: + resolution: {integrity: sha512-Oo/NZcSWccq8KyoG7gLE9fnltgHns+pNCjCAp/WmjsUySi+sX7y4z4Xqu4fVb42CDHzRPl33fjzT15V1wvcyhA==} engines: {node: '>=16.0.0'} pluralize@8.0.0: @@ -7110,8 +7119,8 @@ packages: resolution: {integrity: sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==} engines: {node: '>= 0.8.0'} - prettier@3.9.6: - resolution: {integrity: sha512-OpN0zzVdiaiAhxpuuj5efpIS4sY9j7bY6uR5mnj5yPzGkdkjNKSJeUThPb60Jw29QuAZgA4o+/iB49kFiaBX6g==} + prettier@3.9.8: + resolution: {integrity: sha512-WRFq3Wn3WId7LLROfMLdH7xaFr2jR62wU8nLO6rQUOLOxNZUviyJQs1M0iIhLexSFy+L+w0ch66wtoO2jRjG0A==} engines: {node: '>=14'} hasBin: true @@ -7147,8 +7156,8 @@ packages: resolution: {integrity: sha512-dYDWdjSl5RNb7SgPxGQcRU+GtvP7s2fpkrY0r432PcOIaZ0/rBcxEZnQN67iJhFuQiVw754JDoPruPCNdGsbjg==} engines: {node: '>=12.0.0'} - proxy-addr@2.0.7: - resolution: {integrity: sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==} + proxy-addr@2.0.8: + resolution: {integrity: sha512-5nnx0yGyVUcY6t9RnWcARWtwT9F1D8O9rt08htPvnd49W1IgZtmLkhu9WfMzQj1cFxjHIO6connUNVW5k7AVyQ==} engines: {node: '>= 0.10'} proxy-agent-negotiate@1.1.0: @@ -7297,8 +7306,8 @@ packages: regjsgen@0.8.0: resolution: {integrity: sha512-RvwtGe3d7LvWiDQXeQw8p5asZUmfU1G/l6WbUXeHta7Y2PEIvBTwH6E2EfmYUK8pxcxEdEmaomqyp0vZZ7C+3Q==} - regjsparser@0.13.2: - resolution: {integrity: sha512-NgRBy2Nx/bE+9F27nVHnqcN5HjyLmecqsqx2PJHu3/IEtADD4WuxuXIVExD5PoSDFVrl78dOonfcOe5O+5nbzQ==} + regjsparser@0.13.3: + resolution: {integrity: sha512-ycwFAS14Jw4mppvmK4GR/J6u3WpWpjkEApehuHtLc/8VpPNpDMbQ4WjqwplXifGeyKOzHSFLmSPqzksDQE2Sfg==} hasBin: true require-directory@2.1.1: @@ -7372,12 +7381,13 @@ packages: resolution: {integrity: sha512-l0OE8wL34P4nJH/H2ffoaniAokM2qSmrtXHmlpvYr5AVVX8msAyW0l8NVJFDxlSK4u3Uh/f41cQheDVdnYijwQ==} hasBin: true - rolldown-plugin-dts@0.28.5: - resolution: {integrity: sha512-yYd3C9CeJwqjOc9X23m0Tyxcqic491uLZlfg51szT287S8zCCqLR2uoySoElgqy2CLn7PdXcEo1dlkBs4n1WHg==} + rolldown-plugin-dts@0.28.6: + resolution: {integrity: sha512-qKrFtBfRfR2hP233m7Ic9zf3wv6MSYdZghWKMdEO6dRYZGlNfINJAa1P5ZVvyHh3mrcd7IJQvIY8L9vnm+v5rQ==} engines: {node: ^22.18.0 || ^24.11.0 || >=26.0.0} peerDependencies: '@typescript/native-preview': '*' '@volar/typescript': ~2.4.0 + '@vue/language-core': ~3.2.0 || ~3.3.0 rolldown: ^1.2.0 typescript: ^5.0.0 || ^6.0.0 || ~7.0.0 vue-tsc: ~3.2.0 || ~3.3.0 @@ -7386,6 +7396,8 @@ packages: optional: true '@volar/typescript': optional: true + '@vue/language-core': + optional: true typescript: optional: true vue-tsc: @@ -7467,93 +7479,46 @@ packages: sanitize-filename@1.6.4: resolution: {integrity: sha512-9ZyI08PsvdQl2r/bBIGubpVdR3RR9sY6RDiWFPreA21C/EFlQhmgo20UZlNjZMMZNubusLhAQozkA0Od5J21Eg==} - sass-embedded-all-unknown@1.104.0: - resolution: {integrity: sha512-+S5We++QAg0/wXeVstn4kaZQNZiHi/1FHFsuVRu6Qns/9+YH6aIExg5e8dE+ceNpnYIZUpoK3mdBJoxJhirReQ==} - cpu: ['!arm', '!arm64', '!riscv64', '!x64'] - sass-embedded-all-unknown@1.104.1: resolution: {integrity: sha512-toyMCyUKkT6DsYlHuKZGjd8T6WltaW4TGX07F7HnF4tNJM5m/8VaVsd74zrq3QSPqGE9JjxIDK4NrNc/QY9pkA==} cpu: ['!arm', '!arm64', '!riscv64', '!x64'] - sass-embedded-android-arm64@1.104.0: - resolution: {integrity: sha512-Trknl/A+KTTGRsPWrKaVIF/uq468iTqZzXWMEK/e707bqnbodYvWBBkA7uOM1wtnJQIrepeYSp/CIQJnFr95EQ==} - engines: {node: '>=14.0.0'} - cpu: [arm64] - os: [android] - sass-embedded-android-arm64@1.104.1: resolution: {integrity: sha512-yW3BVW4YFpN2vu2cVQ+Pz5JrRTvoIz36aCdo+J/Mo1A9gEN8eVPV/AL7aeZ803YdKgIitd3qw3pY4wpmT6TXNg==} engines: {node: '>=14.0.0'} cpu: [arm64] os: [android] - sass-embedded-android-arm@1.104.0: - resolution: {integrity: sha512-yojf6KAo4EKbXVzzy4FkYJAez+qzj6NV2inEzsQQxvNfKxfX9INtC6u8UNwSjXL40M9vzAH03lygutq9zmhTCg==} - engines: {node: '>=14.0.0'} - cpu: [arm] - os: [android] - sass-embedded-android-arm@1.104.1: resolution: {integrity: sha512-g/XPAJYAzSSQZFP4xCdGD0HLKB4mf24cJ/+5Nls8rMool3jNkBv9+AFO4EV0b+RxN8rLcEsMccH1CR64yIFYcQ==} engines: {node: '>=14.0.0'} cpu: [arm] os: [android] - sass-embedded-android-riscv64@1.104.0: - resolution: {integrity: sha512-UPR1U/qsTzIikl/DAmZn/11oPrz4DrnrbWANB7WGwz3AtYvLZeixEiVj8Yo2jNy6749zPD09Pyo352io8Y2Mxw==} - engines: {node: '>=14.0.0'} - cpu: [riscv64] - os: [android] - sass-embedded-android-riscv64@1.104.1: resolution: {integrity: sha512-ZYY8oMKQS7Q/6FBoC8w3T16O3MucDe3xv8iKym41Nht5uvLCGGpm4fC4OF5nlv7wQkJv8oactYddGG3Wd0Rqkg==} engines: {node: '>=14.0.0'} cpu: [riscv64] os: [android] - sass-embedded-android-x64@1.104.0: - resolution: {integrity: sha512-NebAKvwfj4a7EbOf9LAzgo4f/uO1xFJbIoebzW8bmqdjeIMSAwJvFToIizxjDuOsIJ9M6AaADxwvDxgm8JTq+w==} - engines: {node: '>=14.0.0'} - cpu: [x64] - os: [android] - sass-embedded-android-x64@1.104.1: resolution: {integrity: sha512-5WZKC4lSfjMIjzZdQUlYQUAV+UiatBhD8w28U7cYLLj4/dMgEPOBd4g3VMv0BwpgH2JOaycMS42dXq29W2bcDg==} engines: {node: '>=14.0.0'} cpu: [x64] os: [android] - sass-embedded-darwin-arm64@1.104.0: - resolution: {integrity: sha512-DYxsoOtA90/LabvQiFs/UVo6jrPbIlIvelSC0B9fxlB051ZBpEFnWamjLV2Xncp48E63voWTYGKpLlsHsi7clg==} - engines: {node: '>=14.0.0'} - cpu: [arm64] - os: [darwin] - sass-embedded-darwin-arm64@1.104.1: resolution: {integrity: sha512-oatuHzn0NsEg0d9Dcze6CuWUPvuETtMxRK4cv0eRAg7p6R0vHnv5GZRyWG6gEy3nc/ha/L+GtTasWVU82f4jrQ==} engines: {node: '>=14.0.0'} cpu: [arm64] os: [darwin] - sass-embedded-darwin-x64@1.104.0: - resolution: {integrity: sha512-zozGKOnR3mnlBqKhzfGH8ZqjPphaDzE5Zjx+H/IOb/ruR/KApTvYkRdi9Eq7OQvSJwL/EHYiyT2jgHaqQulOWw==} - engines: {node: '>=14.0.0'} - cpu: [x64] - os: [darwin] - sass-embedded-darwin-x64@1.104.1: resolution: {integrity: sha512-gql/5sHGzUTVwuHfM3QLCDeb6NYwen+LLj22gz81C2NKHF/4nUtDyh4N+fURWdT7J0/EhtMOd0+FLML3sGNP7g==} engines: {node: '>=14.0.0'} cpu: [x64] os: [darwin] - sass-embedded-linux-arm64@1.104.0: - resolution: {integrity: sha512-2TWOQodxIbwcp9fS01FCUbO2c8bnsdOgUCLB7aZDAhm6ZAkEL8GNIAyKxSMkVIjxndMqNHsG2UtCR2++03DQ+Q==} - engines: {node: '>=14.0.0'} - cpu: [arm64] - os: [linux] - libc: glibc - sass-embedded-linux-arm64@1.104.1: resolution: {integrity: sha512-sVWUKXNTu8sP3X95Df0xo/t49Ce5IseTIMqXHxhFBKVmx7gf7kBWNLK0wH5ym+4khc+B5nNJPgq4IxpelG8tMQ==} engines: {node: '>=14.0.0'} @@ -7561,13 +7526,6 @@ packages: os: [linux] libc: glibc - sass-embedded-linux-arm@1.104.0: - resolution: {integrity: sha512-RX4t5jBlYtGrZwpuc1mtD3lzGuat+jyPidyN5hD5DURV7q39y4IampzopVJ9fvNZqsiGElYWnKyRJA49Q4xk7w==} - engines: {node: '>=14.0.0'} - cpu: [arm] - os: [linux] - libc: glibc - sass-embedded-linux-arm@1.104.1: resolution: {integrity: sha512-WfmshPJOp9vUKxgp8wZ2ncaKBbyrlW9J51M2aUQHWECjMNxTULnGOHWSmD7FViXv4zwn1Co5FIFQUipW7RCxtA==} engines: {node: '>=14.0.0'} @@ -7575,13 +7533,6 @@ packages: os: [linux] libc: glibc - sass-embedded-linux-musl-arm64@1.104.0: - resolution: {integrity: sha512-NPcl0Cw9QXdGzYgjtLZD9MU3Mmr+N31R+Wa+hbbmlNwg1yghbF/bWrpE96oixrQivtCsY1yh9cONl6d+9NrS6Q==} - engines: {node: '>=14.0.0'} - cpu: [arm64] - os: [linux] - libc: musl - sass-embedded-linux-musl-arm64@1.104.1: resolution: {integrity: sha512-H7b+LzZ/w8pwNExInM8HDHraqvxCMdUc5ZRGU/aSJJhZ9HjeRKBjF3GxaisVHnx7o18j1l4VQ5cLBL9tTmNzZw==} engines: {node: '>=14.0.0'} @@ -7589,13 +7540,6 @@ packages: os: [linux] libc: musl - sass-embedded-linux-musl-arm@1.104.0: - resolution: {integrity: sha512-KjXKRY/1TDCNbRg/Htq4puzf5etQ9eFXG83O/328Km/1x2FuQMCmD+pSFTqQrj2LskZ8if+NYZJb3CQ1wzF0Pw==} - engines: {node: '>=14.0.0'} - cpu: [arm] - os: [linux] - libc: musl - sass-embedded-linux-musl-arm@1.104.1: resolution: {integrity: sha512-k0cQ/CxBzFVYiQEObg6CpF6CUglkdEhi/DZgZXQbwC27kbGGY+fatmIs/cFPJL2z1ulACwoAr86RQUFzYvw5eg==} engines: {node: '>=14.0.0'} @@ -7603,13 +7547,6 @@ packages: os: [linux] libc: musl - sass-embedded-linux-musl-riscv64@1.104.0: - resolution: {integrity: sha512-/1JR6G1AfGs/paJk5nemuJmg7pOUgwXlz/WW2NhSDRHBgZnb6Zy6yMpkSHoienAOJSBGUmKceT03dQ/4b409CA==} - engines: {node: '>=14.0.0'} - cpu: [riscv64] - os: [linux] - libc: musl - sass-embedded-linux-musl-riscv64@1.104.1: resolution: {integrity: sha512-9DYdn4wfrkidjxJVtEd2iCx8HKdZe+uF82GDmrYEZhgu4NjVE6a4fQyW7OLwzn3erZMHKBaObBOH1d37DnXI1A==} engines: {node: '>=14.0.0'} @@ -7617,13 +7554,6 @@ packages: os: [linux] libc: musl - sass-embedded-linux-musl-x64@1.104.0: - resolution: {integrity: sha512-5wVjkPR74JdsoH9+NSKV7UCPAdMTxNoayZdu7B9PnmNkOJMRE5O8Jb2oJ3JXgSH/kcGXJ6Vl6dL8/EPLBAKkcg==} - engines: {node: '>=14.0.0'} - cpu: [x64] - os: [linux] - libc: musl - sass-embedded-linux-musl-x64@1.104.1: resolution: {integrity: sha512-5xz+nAr01b6yaRdrGVgE7lNvm1lGFjwNdUvnz+teidvHCbD5oTcbhrRVrnDoLHHvq5n3Jve9TzWaaHhezaEfHA==} engines: {node: '>=14.0.0'} @@ -7631,13 +7561,6 @@ packages: os: [linux] libc: musl - sass-embedded-linux-riscv64@1.104.0: - resolution: {integrity: sha512-Bq9xrONn23cyv5bdSuLm0RG1dcKl+lFQRc1k1UlncI2B2gqb6/OdakEa4Gv2HAmo+O6iOtK39lG9XT1ivTIoww==} - engines: {node: '>=14.0.0'} - cpu: [riscv64] - os: [linux] - libc: glibc - sass-embedded-linux-riscv64@1.104.1: resolution: {integrity: sha512-oWryPJWTXK5adtlz/FD7wd2kS4I0CEgp6mWLUVb4oMFURMLz9bA9fO87D7lc4SV++lds7T51PU1kykCbOvNHMg==} engines: {node: '>=14.0.0'} @@ -7645,13 +7568,6 @@ packages: os: [linux] libc: glibc - sass-embedded-linux-x64@1.104.0: - resolution: {integrity: sha512-xznKQzFnNVNq+GiXPmBXIHLL2rlIoekDxE8HXNKgxXX6bn4fByuHApCmj5Uz+MpVOB154EYCbErztyoEcmnb9Q==} - engines: {node: '>=14.0.0'} - cpu: [x64] - os: [linux] - libc: glibc - sass-embedded-linux-x64@1.104.1: resolution: {integrity: sha512-j/sX/yKTx/wJKepC5/ISlR6kPeSuHKThf76D2za5i2VnbHg0MN19jQq3WMorowR3kRghqt6azs3awogG+e7IRA==} engines: {node: '>=14.0.0'} @@ -7659,43 +7575,22 @@ packages: os: [linux] libc: glibc - sass-embedded-unknown-all@1.104.0: - resolution: {integrity: sha512-0+zhxrAt9PIsdWEVTe5Wgo+gtYdlyv0ASuuAEXT4e9w2yNArUqZ9Gez4Jn8EmtbF7x9uuZxPWbdnq9z65gCH7g==} - os: ['!android', '!darwin', '!linux', '!win32'] - sass-embedded-unknown-all@1.104.1: resolution: {integrity: sha512-RaMsYZB5mRioL4qhoI7T5mmNb2OunakbPTJW2cuu3MeIULnGoxo7Wd5QKFxeQvF7sSQL57RuaQ+q9pH+/pQ9Fg==} os: ['!android', '!darwin', '!linux', '!win32'] - sass-embedded-win32-arm64@1.104.0: - resolution: {integrity: sha512-b8dKmgdgmTx0rSBLNPqLQiq4r/SDau0/3we7MG/8ULMneMSl2OoVttN2ilKSz993lqQu8FJSjx5fEjLSeXVaiA==} - engines: {node: '>=14.0.0'} - cpu: [arm64] - os: [win32] - sass-embedded-win32-arm64@1.104.1: resolution: {integrity: sha512-fS6DL7lcnTPclqGLF4xRt8egZlFY9cU23d57ufbWqaUbCFu9JTu0+8qB4jMxfx1la6byi3GoSTfbnNOLfWv8sw==} engines: {node: '>=14.0.0'} cpu: [arm64] os: [win32] - sass-embedded-win32-x64@1.104.0: - resolution: {integrity: sha512-tVL4NZKUo0+fIO2sT9V1DnBOo9wUbkRoic/NbVBThQdCjl07dn7PKW+ISSnY0EwQhCxdulMDek/JZT7c46vTCA==} - engines: {node: '>=14.0.0'} - cpu: [x64] - os: [win32] - sass-embedded-win32-x64@1.104.1: resolution: {integrity: sha512-/c4N2A93Ckms6DuRFVftKYISuI1tyC8gmlVJ8WaWFzgCBN/Swq2rARJIBUNeuxlmxjmYXfd3+2f/u887K63wbA==} engines: {node: '>=14.0.0'} cpu: [x64] os: [win32] - sass-embedded@1.104.0: - resolution: {integrity: sha512-AW1ZaKM/o4t137+FNe9zkMFWAZlw+EbWuHopVbP0yc0vpvlYj8NqxgKKSsSqODZVgGON2FzKeFMJJHR+tXNzqA==} - engines: {node: '>=20.19.0'} - hasBin: true - sass-embedded@1.104.1: resolution: {integrity: sha512-7LxbtPJ1MWKVbhzOnGx1sHTkHTcHVJ9hbgVsU29p/8gY1VeXt19fcJFr5xsx2f6zfrrR3FeOcYMt0uYDLAxpgw==} engines: {node: '>=20.19.0'} @@ -7719,11 +7614,6 @@ packages: webpack: optional: true - sass@1.104.0: - resolution: {integrity: sha512-btHMApW2bgolvClhRW8AlQJzgI9lUB3pPSofBQQT+E46GWvf9o0TVQ13SYv5riWZVFyPN+JNz3TKW9XhBlc10w==} - engines: {node: '>=20.19.0'} - hasBin: true - sass@1.104.1: resolution: {integrity: sha512-yDA+1aIG3EHgN4V/BvuhCvu61FF6hEd4e+9DxikUm9U0CAGuvdIZ/UYy7qbOxjhbbWQraoyLlMuzdRGOSV5Bmw==} engines: {node: '>=20.19.0'} @@ -7842,8 +7732,8 @@ packages: resolution: {integrity: sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==} engines: {node: '>=8'} - slice-ansi@9.0.0: - resolution: {integrity: sha512-SO/3iYL5S3W57LLEniscOGPZgOqZUPCx6d3dB+52B80yJ0XstzsC/eV8gnA4tM3MHDrKz+OCFSLNjswdSC+/bA==} + slice-ansi@9.0.1: + resolution: {integrity: sha512-aBY19bn/XA+hKOKX0qL7Z0UfdBsbQvc9hn993U8ALUjzxCvDcuZqLoRXjGJrUARWAlwMnsRVD9sw2AFNOYvalA==} engines: {node: '>=22'} socket.io-adapter@2.5.8: @@ -8203,8 +8093,8 @@ packages: resolution: {integrity: sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==} engines: {node: '>= 0.8.0'} - type-fest@5.9.0: - resolution: {integrity: sha512-yANm3Jr3GiJ1qgJlxGAVxTOIcEOk1rhQHamlXtnrCK7EHP4HeM9OGxtMg/W7HFdrVzw/ZWJKGVIJusVH85sLtw==} + type-fest@5.10.0: + resolution: {integrity: sha512-NoSdpq/WEiAg5sjmBkmV/hfxv6HJH4NqPNrqjtSO5CwRmpsDfaf4begxW34KdJykH/l1yHtwBWQkCRdoXO8mPA==} engines: {node: '>=20'} type-is@1.6.18: @@ -8223,8 +8113,8 @@ packages: resolution: {integrity: sha512-BaXgOuIxz8n8pIq3e7Atg/7s+DpiYrxn4vdot3w9KbnBhcRQq6o3xemQdIfynqSeXeDrF32x+WvfzmOjPiY9lg==} engines: {node: '>= 0.4'} - typed-array-byte-offset@1.0.4: - resolution: {integrity: sha512-bTlAFB/FBYMcuX81gbL4OcpH5PmlFHqlCCpAl8AlEzMz5k53oNDvN8p1PNOWLEmI2x4orp3raOFB51tv9X+MFQ==} + typed-array-byte-offset@1.0.5: + resolution: {integrity: sha512-0FHJvLPqZ7KJzp17O13jfsAjsqazgrxBu2zEK95PmUz8lv2+GjRuxUInCr2Rk9Dms3ihN21zJ929ZO43yJ95QQ==} engines: {node: '>= 0.4'} typed-array-length@1.0.8: @@ -8541,16 +8431,6 @@ packages: html-webpack-plugin: optional: true - webpack@5.110.3: - resolution: {integrity: sha512-GuizBzRvo9YPpyoNMf3ag7AzxbaW85qrRSqTha345KyJbAFPt3/cMzBM0h+RWg7SK/7DdzRLINP3LvQ0hvr4hg==} - engines: {node: '>=10.13.0'} - hasBin: true - peerDependencies: - webpack-cli: '*' - peerDependenciesMeta: - webpack-cli: - optional: true - webpack@5.111.0: resolution: {integrity: sha512-A2R74kfE6b3eLKS91iZiol03Ebx7avmJJBOyiP+4LePW9NNeNJGQkKeSQos4dk6R4H0YAMYlv+aOrs1CyWT3eA==} engines: {node: '>=10.13.0'} @@ -8577,8 +8457,8 @@ packages: resolution: {integrity: sha512-1to4zXBxmXHV3IiSSEInrreIlu02vUOvrhxJJH5vcxYTBDAx51cqZiKdyTxlecdKNSjj8EcxGBxNf6Vg+945gw==} engines: {node: ^20.19.0 || ^22.12.0 || >=24.0.0} - whatwg-url@17.1.1: - resolution: {integrity: sha512-ohjk1mdUebJVadRt3bAhQhx8lSnISq+GDttK79LFl8EHQkAPvzwctoasC4hs8tBt6kLAncBWWyq1N52qEfKvDw==} + whatwg-url@17.1.2: + resolution: {integrity: sha512-TEZA+Zqxin7Jjsm2cjRohCmen5awh+hT6Zi3VZdqZlNRk7zvOI/9WpBFg/DWlA56bWnzwm6DuB8NS0EsxQH9uQ==} engines: {node: ^22.14.0 || >=24.0.0} whatwg-url@5.0.0: @@ -8596,8 +8476,8 @@ packages: resolution: {integrity: sha512-K4jVyjnBdgvc86Y6BkaLZEN933SwYOuBFkdmBu9ZfkcAbdVbpITnDmjvZ/aQjRXQrv5EPkTnD1s39GiiqbngCw==} engines: {node: '>= 0.4'} - which-typed-array@1.1.22: - resolution: {integrity: sha512-fvO4ExWMFsqyhG3AiPAObMuY1lxaqgYcxbc49CNdWDDECOJNgQyvsOWVwbZc+qf3rzRtxojBK+CMEv0Ld5CYpw==} + which-typed-array@1.1.24: + resolution: {integrity: sha512-wk4Mf4pR5mRP7eYuuTBCIQ9d0ud2Fv2jRLQpfgnRjbOxAFHmjKFValgTpitVKzJJS8ajnYQV2Du1SZ8j6b/EUQ==} engines: {node: '>= 0.4'} which@1.3.1: @@ -8629,8 +8509,8 @@ packages: wordwrap@1.0.0: resolution: {integrity: sha512-gvVzJFlPycKc5dZN4yPkP8w7Dc37BtP1yczEneOb4uq34pXZcvrtRTmWV8W+Ume+XCxKgbjM+nevkyFPMybd4Q==} - wrap-ansi@10.0.1: - resolution: {integrity: sha512-M0N4xzyzosiIok3svYlEo1sdLZts/8FPgYH/GPC3wvlmPoRvnoManGMrE54waYj3tISA8w6lsdesfVv67qSr8Q==} + wrap-ansi@10.0.2: + resolution: {integrity: sha512-6OLRNZqRntVGBm26ghZ5eZhCuWWyOkRCSn8XsOIuq5stpCE/tjLbdozd93naILZig0lmD8ANfRwnhn0DLeXGlg==} engines: {node: '>=20'} wrap-ansi@7.0.0: @@ -8730,14 +8610,14 @@ packages: resolution: {integrity: sha512-xYqdZFUK/VYazNl/oCDYN+3WloWQwMfZxBoiNt6qNyk+xfOdi598muWE42rNZFp1kNOiqW936q5RhUdnpqElSg==} engines: {node: '>=18'} - yuku-ast@0.9.5: - resolution: {integrity: sha512-Q8qW8WwQnN5Cm0ZZivdRIfv0sRLTjUq0YumXJkw8CYN1aCdICH9rk4C47/4n6kA5EqDtlj+F608twoTSV2MwdQ==} + yuku-ast@0.10.2: + resolution: {integrity: sha512-UnG9mA6giglCvSErft2/40TVFX750Sj1xgwddPLpG7J7rlr/P1wPADg9G2RK+d/1tNLtRVoLdMMOMVBB9561TQ==} - yuku-codegen@0.9.5: - resolution: {integrity: sha512-zGUVyDpSK4b6c9B0yyxi2P0wujn1XZTbG9dCb7d6gyAoP63EMgyLzUwPUvwxPG5jgYqhlI7w+S3oCyapqGr4PA==} + yuku-codegen@0.10.2: + resolution: {integrity: sha512-hentl2dtrF6cPjiAirtkfxfFZBA6Hdm61UqRJ7cA0qrlDNMk9PZGOjw5w1mx3E0hu/6pHcJF4dJW+D0SXHPZOA==} - yuku-parser@0.9.5: - resolution: {integrity: sha512-IBnAdNVMswWbJcM7woPluOudectJzFjJ1N8jVRxP9Uq4CIv5hZdBIcdmtRbFDYF/Ph2j2gVup4YJ4N9mh0jYFA==} + yuku-parser@0.10.2: + resolution: {integrity: sha512-CgaU0/PPjCAIEZ3WQroosOxTY3eeKldAN3h+vk8pMNz4+jl1CZzBR4pW+K/rRPF112VooCL5FdjJoiMNjDrL2A==} zod@3.25.76: resolution: {integrity: sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ==} @@ -8939,18 +8819,18 @@ snapshots: '@asamuzakjp/css-color@6.0.7': dependencies: - '@csstools/css-calc': 3.4.0(@csstools/css-parser-algorithms@4.0.0(@csstools/css-tokenizer@4.0.0))(@csstools/css-tokenizer@4.0.0) - '@csstools/css-color-parser': 4.2.3(@csstools/css-parser-algorithms@4.0.0(@csstools/css-tokenizer@4.0.0))(@csstools/css-tokenizer@4.0.0) - '@csstools/css-parser-algorithms': 4.0.0(@csstools/css-tokenizer@4.0.0) - '@csstools/css-tokenizer': 4.0.0 - lru-cache: 11.5.2 + '@csstools/css-calc': 3.4.0(@csstools/css-parser-algorithms@4.0.0(@csstools/css-tokenizer@4.0.1))(@csstools/css-tokenizer@4.0.1) + '@csstools/css-color-parser': 4.2.3(@csstools/css-parser-algorithms@4.0.0(@csstools/css-tokenizer@4.0.1))(@csstools/css-tokenizer@4.0.1) + '@csstools/css-parser-algorithms': 4.0.0(@csstools/css-tokenizer@4.0.1) + '@csstools/css-tokenizer': 4.0.1 + lru-cache: 11.5.3 '@asamuzakjp/dom-selector@8.3.2': dependencies: bidi-js: 1.1.0 css-tree: 3.2.1 is-potential-custom-element-name: 1.0.1 - lru-cache: 11.5.2 + lru-cache: 11.5.3 '@babel/code-frame@7.29.7': dependencies: @@ -8958,9 +8838,9 @@ snapshots: js-tokens: 4.0.0 picocolors: 1.1.1 - '@babel/code-frame@8.0.0': + '@babel/code-frame@8.0.6': dependencies: - '@babel/helper-validator-identifier': 8.0.4 + '@babel/helper-validator-identifier': 8.0.6 js-tokens: 10.0.0 '@babel/compat-data@7.29.7': {} @@ -8974,7 +8854,7 @@ snapshots: '@babel/helper-compilation-targets': 7.29.7 '@babel/helper-module-transforms': 7.29.7(@babel/core@7.29.7(supports-color@11.0.0))(supports-color@11.0.0) '@babel/helpers': 7.29.7 - '@babel/parser': 7.29.8 + '@babel/parser': 7.29.9 '@babel/template': 7.29.7 '@babel/traverse': 7.29.8(supports-color@11.0.0) '@babel/types': 7.29.8 @@ -8989,17 +8869,17 @@ snapshots: '@babel/core@8.0.1': dependencies: - '@babel/code-frame': 8.0.0 + '@babel/code-frame': 8.0.6 '@babel/generator': 8.0.5 - '@babel/helper-compilation-targets': 8.0.5 + '@babel/helper-compilation-targets': 8.0.6 '@babel/helpers': 8.0.5 - '@babel/parser': 8.0.5 + '@babel/parser': 8.0.6 '@babel/template': 8.0.0 - '@babel/traverse': 8.0.5 - '@babel/types': 8.0.5 + '@babel/traverse': 8.0.6 + '@babel/types': 8.0.6 '@types/gensync': 1.0.5 convert-source-map: 2.0.0 - empathic: 2.0.1 + empathic: 2.1.0 gensync: 1.0.0-beta.2 import-meta-resolve: 4.2.0 json5: 2.2.3 @@ -9008,17 +8888,17 @@ snapshots: '@babel/core@8.0.5': dependencies: - '@babel/code-frame': 8.0.0 + '@babel/code-frame': 8.0.6 '@babel/generator': 8.0.5 - '@babel/helper-compilation-targets': 8.0.5 + '@babel/helper-compilation-targets': 8.0.6 '@babel/helpers': 8.0.5 - '@babel/parser': 8.0.5 + '@babel/parser': 8.0.6 '@babel/template': 8.0.0 - '@babel/traverse': 8.0.5 - '@babel/types': 8.0.5 + '@babel/traverse': 8.0.6 + '@babel/types': 8.0.6 '@types/gensync': 1.0.5 convert-source-map: 2.0.0 - empathic: 2.0.1 + empathic: 2.1.0 gensync: 1.0.0-beta.2 import-meta-resolve: 4.2.0 json5: 2.2.3 @@ -9027,7 +8907,7 @@ snapshots: '@babel/generator@7.29.8': dependencies: - '@babel/parser': 7.29.8 + '@babel/parser': 7.29.9 '@babel/types': 7.29.8 '@jridgewell/gen-mapping': 0.3.13 '@jridgewell/trace-mapping': 0.3.31 @@ -9035,8 +8915,17 @@ snapshots: '@babel/generator@8.0.5': dependencies: - '@babel/parser': 8.0.5 - '@babel/types': 8.0.5 + '@babel/parser': 8.0.6 + '@babel/types': 8.0.6 + '@jridgewell/gen-mapping': 0.4.0-beta.0 + '@jridgewell/trace-mapping': 0.3.31 + '@types/jsesc': 2.5.1 + jsesc: 3.1.0 + + '@babel/generator@8.0.6': + dependencies: + '@babel/parser': 8.0.6 + '@babel/types': 8.0.6 '@jridgewell/gen-mapping': 0.4.0-beta.0 '@jridgewell/trace-mapping': 0.3.31 '@types/jsesc': 2.5.1 @@ -9044,25 +8933,25 @@ snapshots: '@babel/helper-annotate-as-pure@8.0.0': dependencies: - '@babel/types': 8.0.5 + '@babel/types': 8.0.6 '@babel/helper-compilation-targets@7.29.7': dependencies: '@babel/compat-data': 7.29.7 '@babel/helper-validator-option': 7.29.7 - browserslist: 4.28.9 + browserslist: 4.29.0 lru-cache: 5.1.1 semver: 6.3.1 - '@babel/helper-compilation-targets@8.0.5': + '@babel/helper-compilation-targets@8.0.6': dependencies: '@babel/compat-data': 8.0.5 '@babel/helper-validator-option': 8.0.0 - browserslist: 4.28.9 - lru-cache: 11.5.2 + browserslist: 4.29.0 + flru: 1.0.2 verkit: 0.3.2 - '@babel/helper-create-class-features-plugin@8.0.5(@babel/core@8.0.5)': + '@babel/helper-create-class-features-plugin@8.0.6(@babel/core@8.0.5)': dependencies: '@babel/core': 8.0.5 '@babel/helper-annotate-as-pure': 8.0.0 @@ -9070,7 +8959,7 @@ snapshots: '@babel/helper-optimise-call-expression': 8.0.0 '@babel/helper-replace-supers': 8.0.1(@babel/core@8.0.5) '@babel/helper-skip-transparent-expression-wrappers': 8.0.0 - '@babel/traverse': 8.0.5 + '@babel/traverse': 8.0.6 verkit: 0.3.2 '@babel/helper-create-regexp-features-plugin@8.0.5(@babel/core@8.0.5)': @@ -9083,18 +8972,18 @@ snapshots: '@babel/helper-define-polyfill-provider@1.0.0(@babel/core@8.0.5)': dependencies: '@babel/core': 8.0.5 - '@babel/helper-compilation-targets': 8.0.5 + '@babel/helper-compilation-targets': 8.0.6 '@babel/helper-plugin-utils': 8.0.1(@babel/core@8.0.5) lodash.debounce: 4.0.8 '@babel/helper-globals@7.29.7': {} - '@babel/helper-globals@8.0.0': {} + '@babel/helper-globals@8.0.6': {} '@babel/helper-member-expression-to-functions@8.0.5': dependencies: - '@babel/traverse': 8.0.5 - '@babel/types': 8.0.5 + '@babel/traverse': 8.0.6 + '@babel/types': 8.0.6 '@babel/helper-module-imports@7.29.7(supports-color@11.0.0)': dependencies: @@ -9105,8 +8994,8 @@ snapshots: '@babel/helper-module-imports@8.0.0': dependencies: - '@babel/traverse': 8.0.5 - '@babel/types': 8.0.5 + '@babel/traverse': 8.0.6 + '@babel/types': 8.0.6 '@babel/helper-module-transforms@7.29.7(@babel/core@7.29.7(supports-color@11.0.0))(supports-color@11.0.0)': dependencies: @@ -9117,16 +9006,16 @@ snapshots: transitivePeerDependencies: - supports-color - '@babel/helper-module-transforms@8.0.5(@babel/core@8.0.5)': + '@babel/helper-module-transforms@8.0.6(@babel/core@8.0.5)': dependencies: '@babel/core': 8.0.5 '@babel/helper-module-imports': 8.0.0 - '@babel/helper-validator-identifier': 8.0.4 - '@babel/traverse': 8.0.5 + '@babel/helper-validator-identifier': 8.0.6 + '@babel/traverse': 8.0.6 '@babel/helper-optimise-call-expression@8.0.0': dependencies: - '@babel/types': 8.0.5 + '@babel/types': 8.0.6 '@babel/helper-plugin-utils@8.0.1(@babel/core@8.0.5)': dependencies: @@ -9137,19 +9026,19 @@ snapshots: '@babel/core': 8.0.5 '@babel/helper-annotate-as-pure': 8.0.0 '@babel/helper-wrap-function': 8.0.0 - '@babel/traverse': 8.0.5 + '@babel/traverse': 8.0.6 '@babel/helper-replace-supers@8.0.1(@babel/core@8.0.5)': dependencies: '@babel/core': 8.0.5 '@babel/helper-member-expression-to-functions': 8.0.5 '@babel/helper-optimise-call-expression': 8.0.0 - '@babel/traverse': 8.0.5 + '@babel/traverse': 8.0.6 '@babel/helper-skip-transparent-expression-wrappers@8.0.0': dependencies: - '@babel/traverse': 8.0.5 - '@babel/types': 8.0.5 + '@babel/traverse': 8.0.6 + '@babel/types': 8.0.6 '@babel/helper-split-export-declaration@7.24.7': dependencies: @@ -9157,11 +9046,11 @@ snapshots: '@babel/helper-string-parser@7.29.7': {} - '@babel/helper-string-parser@8.0.0': {} + '@babel/helper-string-parser@8.0.6': {} '@babel/helper-validator-identifier@7.29.7': {} - '@babel/helper-validator-identifier@8.0.4': {} + '@babel/helper-validator-identifier@8.0.6': {} '@babel/helper-validator-option@7.29.7': {} @@ -9170,8 +9059,8 @@ snapshots: '@babel/helper-wrap-function@8.0.0': dependencies: '@babel/template': 8.0.0 - '@babel/traverse': 8.0.5 - '@babel/types': 8.0.5 + '@babel/traverse': 8.0.6 + '@babel/types': 8.0.6 '@babel/helpers@7.29.7': dependencies: @@ -9181,15 +9070,15 @@ snapshots: '@babel/helpers@8.0.5': dependencies: '@babel/template': 8.0.0 - '@babel/types': 8.0.5 + '@babel/types': 8.0.6 - '@babel/parser@7.29.8': + '@babel/parser@7.29.9': dependencies: '@babel/types': 7.29.8 - '@babel/parser@8.0.5': + '@babel/parser@8.0.6': dependencies: - '@babel/types': 8.0.5 + '@babel/types': 8.0.6 '@babel/plugin-bugfix-firefox-class-in-computed-class-key@8.0.1(@babel/core@8.0.5)': dependencies: @@ -9206,7 +9095,7 @@ snapshots: '@babel/core': 8.0.5 '@babel/helper-plugin-utils': 8.0.1(@babel/core@8.0.5) - '@babel/plugin-bugfix-safari-rest-destructuring-rhs-array@8.0.5(@babel/core@8.0.5)': + '@babel/plugin-bugfix-safari-rest-destructuring-rhs-array@8.0.6(@babel/core@8.0.5)': dependencies: '@babel/core': 8.0.5 '@babel/helper-plugin-utils': 8.0.1(@babel/core@8.0.5) @@ -9234,7 +9123,7 @@ snapshots: '@babel/core': 8.0.5 '@babel/helper-plugin-utils': 8.0.1(@babel/core@8.0.5) '@babel/helper-remap-async-to-generator': 8.0.1(@babel/core@8.0.5) - '@babel/traverse': 8.0.5 + '@babel/traverse': 8.0.6 '@babel/plugin-transform-async-to-generator@8.0.1(@babel/core@8.0.5)': dependencies: @@ -9256,24 +9145,24 @@ snapshots: '@babel/plugin-transform-class-properties@8.0.1(@babel/core@8.0.5)': dependencies: '@babel/core': 8.0.5 - '@babel/helper-create-class-features-plugin': 8.0.5(@babel/core@8.0.5) + '@babel/helper-create-class-features-plugin': 8.0.6(@babel/core@8.0.5) '@babel/helper-plugin-utils': 8.0.1(@babel/core@8.0.5) '@babel/plugin-transform-class-static-block@8.0.5(@babel/core@8.0.5)': dependencies: '@babel/core': 8.0.5 - '@babel/helper-create-class-features-plugin': 8.0.5(@babel/core@8.0.5) + '@babel/helper-create-class-features-plugin': 8.0.6(@babel/core@8.0.5) '@babel/helper-plugin-utils': 8.0.1(@babel/core@8.0.5) '@babel/plugin-transform-classes@8.0.5(@babel/core@8.0.5)': dependencies: '@babel/core': 8.0.5 '@babel/helper-annotate-as-pure': 8.0.0 - '@babel/helper-compilation-targets': 8.0.5 - '@babel/helper-globals': 8.0.0 + '@babel/helper-compilation-targets': 8.0.6 + '@babel/helper-globals': 8.0.6 '@babel/helper-plugin-utils': 8.0.1(@babel/core@8.0.5) '@babel/helper-replace-supers': 8.0.1(@babel/core@8.0.5) - '@babel/traverse': 8.0.5 + '@babel/traverse': 8.0.6 '@babel/plugin-transform-computed-properties@8.0.1(@babel/core@8.0.5)': dependencies: @@ -9332,7 +9221,7 @@ snapshots: '@babel/plugin-transform-function-name@8.0.1(@babel/core@8.0.5)': dependencies: '@babel/core': 8.0.5 - '@babel/helper-compilation-targets': 8.0.5 + '@babel/helper-compilation-targets': 8.0.6 '@babel/helper-plugin-utils': 8.0.1(@babel/core@8.0.5) '@babel/plugin-transform-json-strings@8.0.1(@babel/core@8.0.5)': @@ -9358,26 +9247,26 @@ snapshots: '@babel/plugin-transform-modules-amd@8.0.1(@babel/core@8.0.5)': dependencies: '@babel/core': 8.0.5 - '@babel/helper-module-transforms': 8.0.5(@babel/core@8.0.5) + '@babel/helper-module-transforms': 8.0.6(@babel/core@8.0.5) '@babel/helper-plugin-utils': 8.0.1(@babel/core@8.0.5) '@babel/plugin-transform-modules-commonjs@8.0.1(@babel/core@8.0.5)': dependencies: '@babel/core': 8.0.5 - '@babel/helper-module-transforms': 8.0.5(@babel/core@8.0.5) + '@babel/helper-module-transforms': 8.0.6(@babel/core@8.0.5) '@babel/helper-plugin-utils': 8.0.1(@babel/core@8.0.5) '@babel/plugin-transform-modules-systemjs@8.0.1(@babel/core@8.0.5)': dependencies: '@babel/core': 8.0.5 - '@babel/helper-module-transforms': 8.0.5(@babel/core@8.0.5) + '@babel/helper-module-transforms': 8.0.6(@babel/core@8.0.5) '@babel/helper-plugin-utils': 8.0.1(@babel/core@8.0.5) - '@babel/helper-validator-identifier': 8.0.4 + '@babel/helper-validator-identifier': 8.0.6 '@babel/plugin-transform-modules-umd@8.0.1(@babel/core@8.0.5)': dependencies: '@babel/core': 8.0.5 - '@babel/helper-module-transforms': 8.0.5(@babel/core@8.0.5) + '@babel/helper-module-transforms': 8.0.6(@babel/core@8.0.5) '@babel/helper-plugin-utils': 8.0.1(@babel/core@8.0.5) '@babel/plugin-transform-named-capturing-groups-regex@8.0.1(@babel/core@8.0.5)': @@ -9404,7 +9293,7 @@ snapshots: '@babel/plugin-transform-object-rest-spread@8.0.1(@babel/core@8.0.5)': dependencies: '@babel/core': 8.0.5 - '@babel/helper-compilation-targets': 8.0.5 + '@babel/helper-compilation-targets': 8.0.6 '@babel/helper-plugin-utils': 8.0.1(@babel/core@8.0.5) '@babel/plugin-transform-destructuring': 8.0.5(@babel/core@8.0.5) '@babel/plugin-transform-parameters': 8.0.5(@babel/core@8.0.5) @@ -9434,14 +9323,14 @@ snapshots: '@babel/plugin-transform-private-methods@8.0.1(@babel/core@8.0.5)': dependencies: '@babel/core': 8.0.5 - '@babel/helper-create-class-features-plugin': 8.0.5(@babel/core@8.0.5) + '@babel/helper-create-class-features-plugin': 8.0.6(@babel/core@8.0.5) '@babel/helper-plugin-utils': 8.0.1(@babel/core@8.0.5) '@babel/plugin-transform-private-property-in-object@8.0.5(@babel/core@8.0.5)': dependencies: '@babel/core': 8.0.5 '@babel/helper-annotate-as-pure': 8.0.0 - '@babel/helper-create-class-features-plugin': 8.0.5(@babel/core@8.0.5) + '@babel/helper-create-class-features-plugin': 8.0.6(@babel/core@8.0.5) '@babel/helper-plugin-utils': 8.0.1(@babel/core@8.0.5) '@babel/plugin-transform-property-literals@8.0.1(@babel/core@8.0.5)': @@ -9449,7 +9338,7 @@ snapshots: '@babel/core': 8.0.5 '@babel/helper-plugin-utils': 8.0.1(@babel/core@8.0.5) - '@babel/plugin-transform-regenerator@8.0.5(@babel/core@8.0.5)': + '@babel/plugin-transform-regenerator@8.0.6(@babel/core@8.0.5)': dependencies: '@babel/core': 8.0.5 '@babel/helper-plugin-utils': 8.0.1(@babel/core@8.0.5) @@ -9524,13 +9413,13 @@ snapshots: dependencies: '@babel/compat-data': 8.0.5 '@babel/core': 8.0.5 - '@babel/helper-compilation-targets': 8.0.5 + '@babel/helper-compilation-targets': 8.0.6 '@babel/helper-plugin-utils': 8.0.1(@babel/core@8.0.5) '@babel/helper-validator-option': 8.0.0 '@babel/plugin-bugfix-firefox-class-in-computed-class-key': 8.0.1(@babel/core@8.0.5) '@babel/plugin-bugfix-safari-class-field-initializer-scope': 8.0.1(@babel/core@8.0.5) '@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression': 8.0.1(@babel/core@8.0.5) - '@babel/plugin-bugfix-safari-rest-destructuring-rhs-array': 8.0.5(@babel/core@8.0.5) + '@babel/plugin-bugfix-safari-rest-destructuring-rhs-array': 8.0.6(@babel/core@8.0.5) '@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining': 8.0.1(@babel/core@8.0.5) '@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly': 8.0.1(@babel/core@8.0.5) '@babel/plugin-transform-arrow-functions': 8.0.1(@babel/core@8.0.5) @@ -9572,7 +9461,7 @@ snapshots: '@babel/plugin-transform-private-methods': 8.0.1(@babel/core@8.0.5) '@babel/plugin-transform-private-property-in-object': 8.0.5(@babel/core@8.0.5) '@babel/plugin-transform-property-literals': 8.0.1(@babel/core@8.0.5) - '@babel/plugin-transform-regenerator': 8.0.5(@babel/core@8.0.5) + '@babel/plugin-transform-regenerator': 8.0.6(@babel/core@8.0.5) '@babel/plugin-transform-regexp-modifiers': 8.0.1(@babel/core@8.0.5) '@babel/plugin-transform-reserved-words': 8.0.1(@babel/core@8.0.5) '@babel/plugin-transform-shorthand-properties': 8.0.1(@babel/core@8.0.5) @@ -9595,7 +9484,7 @@ snapshots: '@babel/helper-plugin-utils': 8.0.1(@babel/core@8.0.5) '@babel/plugin-transform-dotall-regex': 8.0.1(@babel/core@8.0.5) '@babel/plugin-transform-unicode-property-regex': 8.0.1(@babel/core@8.0.5) - '@babel/types': 8.0.5 + '@babel/types': 8.0.6 esutils: 2.0.3 '@babel/runtime@8.0.5': {} @@ -9603,35 +9492,35 @@ snapshots: '@babel/template@7.29.7': dependencies: '@babel/code-frame': 7.29.7 - '@babel/parser': 7.29.8 + '@babel/parser': 7.29.9 '@babel/types': 7.29.8 '@babel/template@8.0.0': dependencies: - '@babel/code-frame': 8.0.0 - '@babel/parser': 8.0.5 - '@babel/types': 8.0.5 + '@babel/code-frame': 8.0.6 + '@babel/parser': 8.0.6 + '@babel/types': 8.0.6 '@babel/traverse@7.29.8(supports-color@11.0.0)': dependencies: '@babel/code-frame': 7.29.7 '@babel/generator': 7.29.8 '@babel/helper-globals': 7.29.7 - '@babel/parser': 7.29.8 + '@babel/parser': 7.29.9 '@babel/template': 7.29.7 '@babel/types': 7.29.8 debug: 4.4.3(supports-color@11.0.0) transitivePeerDependencies: - supports-color - '@babel/traverse@8.0.5': + '@babel/traverse@8.0.6': dependencies: - '@babel/code-frame': 8.0.0 - '@babel/generator': 8.0.5 - '@babel/helper-globals': 8.0.0 - '@babel/parser': 8.0.5 + '@babel/code-frame': 8.0.6 + '@babel/generator': 8.0.6 + '@babel/helper-globals': 8.0.6 + '@babel/parser': 8.0.6 '@babel/template': 8.0.0 - '@babel/types': 8.0.5 + '@babel/types': 8.0.6 obug: 2.2.1 '@babel/types@7.29.8': @@ -9639,10 +9528,10 @@ snapshots: '@babel/helper-string-parser': 7.29.7 '@babel/helper-validator-identifier': 7.29.7 - '@babel/types@8.0.5': + '@babel/types@8.0.6': dependencies: - '@babel/helper-string-parser': 8.0.0 - '@babel/helper-validator-identifier': 8.0.4 + '@babel/helper-string-parser': 8.0.6 + '@babel/helper-validator-identifier': 8.0.6 '@bazel/bazelisk@1.28.1': {} @@ -9683,27 +9572,27 @@ snapshots: '@csstools/color-helpers@6.1.1': {} - '@csstools/css-calc@3.4.0(@csstools/css-parser-algorithms@4.0.0(@csstools/css-tokenizer@4.0.0))(@csstools/css-tokenizer@4.0.0)': + '@csstools/css-calc@3.4.0(@csstools/css-parser-algorithms@4.0.0(@csstools/css-tokenizer@4.0.1))(@csstools/css-tokenizer@4.0.1)': dependencies: - '@csstools/css-parser-algorithms': 4.0.0(@csstools/css-tokenizer@4.0.0) - '@csstools/css-tokenizer': 4.0.0 + '@csstools/css-parser-algorithms': 4.0.0(@csstools/css-tokenizer@4.0.1) + '@csstools/css-tokenizer': 4.0.1 - '@csstools/css-color-parser@4.2.3(@csstools/css-parser-algorithms@4.0.0(@csstools/css-tokenizer@4.0.0))(@csstools/css-tokenizer@4.0.0)': + '@csstools/css-color-parser@4.2.3(@csstools/css-parser-algorithms@4.0.0(@csstools/css-tokenizer@4.0.1))(@csstools/css-tokenizer@4.0.1)': dependencies: '@csstools/color-helpers': 6.1.1 - '@csstools/css-calc': 3.4.0(@csstools/css-parser-algorithms@4.0.0(@csstools/css-tokenizer@4.0.0))(@csstools/css-tokenizer@4.0.0) - '@csstools/css-parser-algorithms': 4.0.0(@csstools/css-tokenizer@4.0.0) - '@csstools/css-tokenizer': 4.0.0 + '@csstools/css-calc': 3.4.0(@csstools/css-parser-algorithms@4.0.0(@csstools/css-tokenizer@4.0.1))(@csstools/css-tokenizer@4.0.1) + '@csstools/css-parser-algorithms': 4.0.0(@csstools/css-tokenizer@4.0.1) + '@csstools/css-tokenizer': 4.0.1 - '@csstools/css-parser-algorithms@4.0.0(@csstools/css-tokenizer@4.0.0)': + '@csstools/css-parser-algorithms@4.0.0(@csstools/css-tokenizer@4.0.1)': dependencies: - '@csstools/css-tokenizer': 4.0.0 + '@csstools/css-tokenizer': 4.0.1 - '@csstools/css-syntax-patches-for-csstree@1.1.13(css-tree@3.2.1)': + '@csstools/css-syntax-patches-for-csstree@1.1.14(css-tree@3.2.1)': optionalDependencies: css-tree: 3.2.1 - '@csstools/css-tokenizer@4.0.0': {} + '@csstools/css-tokenizer@4.0.1': {} '@cypress/request@4.0.1': dependencies: @@ -9859,7 +9748,9 @@ snapshots: '@eslint/core': 1.2.1 levn: 0.4.1 - '@exodus/bytes@1.15.1': {} + '@exodus/bytes@1.15.1(@noble/hashes@1.8.0)': + optionalDependencies: + '@noble/hashes': 1.8.0 '@firebase/ai@2.16.0(@firebase/app-types@0.9.6)(@firebase/app@0.16.2)': dependencies: @@ -10251,7 +10142,7 @@ snapshots: - supports-color - utf-8-validate - '@grpc/grpc-js@1.14.4': + '@grpc/grpc-js@1.14.5': dependencies: '@grpc/proto-loader': 0.8.1 '@js-sdsl/ordered-map': 4.4.2 @@ -10259,7 +10150,7 @@ snapshots: '@grpc/grpc-js@1.9.16': dependencies: '@grpc/proto-loader': 0.7.15 - '@types/node': 22.20.2 + '@types/node': 22.20.4 '@grpc/proto-loader@0.7.15': dependencies: @@ -10296,14 +10187,14 @@ snapshots: '@inquirer/ansi@2.0.8': {} - '@inquirer/checkbox@5.2.5(@types/node@22.20.2)': + '@inquirer/checkbox@5.2.5(@types/node@22.20.4)': dependencies: '@inquirer/ansi': 2.0.8 - '@inquirer/core': 12.0.3(@types/node@22.20.2) + '@inquirer/core': 12.0.3(@types/node@22.20.4) '@inquirer/figures': 2.0.9 - '@inquirer/type': 4.1.1(@types/node@22.20.2) + '@inquirer/type': 4.1.1(@types/node@22.20.4) optionalDependencies: - '@types/node': 22.20.2 + '@types/node': 22.20.4 '@inquirer/checkbox@5.2.5(@types/node@24.13.5)': dependencies: @@ -10314,12 +10205,12 @@ snapshots: optionalDependencies: '@types/node': 24.13.5 - '@inquirer/confirm@6.3.2(@types/node@22.20.2)': + '@inquirer/confirm@6.3.2(@types/node@22.20.4)': dependencies: - '@inquirer/core': 12.0.3(@types/node@22.20.2) - '@inquirer/type': 4.1.1(@types/node@22.20.2) + '@inquirer/core': 12.0.3(@types/node@22.20.4) + '@inquirer/type': 4.1.1(@types/node@22.20.4) optionalDependencies: - '@types/node': 22.20.2 + '@types/node': 22.20.4 '@inquirer/confirm@6.3.2(@types/node@24.13.5)': dependencies: @@ -10328,17 +10219,17 @@ snapshots: optionalDependencies: '@types/node': 24.13.5 - '@inquirer/core@12.0.3(@types/node@22.20.2)': + '@inquirer/core@12.0.3(@types/node@22.20.4)': dependencies: '@inquirer/ansi': 2.0.8 '@inquirer/figures': 2.0.9 - '@inquirer/type': 4.1.1(@types/node@22.20.2) + '@inquirer/type': 4.1.1(@types/node@22.20.4) cli-width: 4.1.0 fast-wrap-ansi: 0.2.2 mute-stream: 3.0.0 signal-exit: 4.1.0 optionalDependencies: - '@types/node': 22.20.2 + '@types/node': 22.20.4 '@inquirer/core@12.0.3(@types/node@24.13.5)': dependencies: @@ -10352,13 +10243,13 @@ snapshots: optionalDependencies: '@types/node': 24.13.5 - '@inquirer/editor@5.3.3(@types/node@22.20.2)': + '@inquirer/editor@5.3.3(@types/node@22.20.4)': dependencies: - '@inquirer/core': 12.0.3(@types/node@22.20.2) - '@inquirer/external-editor': 3.0.5(@types/node@22.20.2) - '@inquirer/type': 4.1.1(@types/node@22.20.2) + '@inquirer/core': 12.0.3(@types/node@22.20.4) + '@inquirer/external-editor': 3.0.5(@types/node@22.20.4) + '@inquirer/type': 4.1.1(@types/node@22.20.4) optionalDependencies: - '@types/node': 22.20.2 + '@types/node': 22.20.4 '@inquirer/editor@5.3.3(@types/node@24.13.5)': dependencies: @@ -10368,12 +10259,12 @@ snapshots: optionalDependencies: '@types/node': 24.13.5 - '@inquirer/expand@5.1.5(@types/node@22.20.2)': + '@inquirer/expand@5.1.5(@types/node@22.20.4)': dependencies: - '@inquirer/core': 12.0.3(@types/node@22.20.2) - '@inquirer/type': 4.1.1(@types/node@22.20.2) + '@inquirer/core': 12.0.3(@types/node@22.20.4) + '@inquirer/type': 4.1.1(@types/node@22.20.4) optionalDependencies: - '@types/node': 22.20.2 + '@types/node': 22.20.4 '@inquirer/expand@5.1.5(@types/node@24.13.5)': dependencies: @@ -10382,12 +10273,12 @@ snapshots: optionalDependencies: '@types/node': 24.13.5 - '@inquirer/external-editor@3.0.5(@types/node@22.20.2)': + '@inquirer/external-editor@3.0.5(@types/node@22.20.4)': dependencies: chardet: 2.2.0 iconv-lite: 0.7.3 optionalDependencies: - '@types/node': 22.20.2 + '@types/node': 22.20.4 '@inquirer/external-editor@3.0.5(@types/node@24.13.5)': dependencies: @@ -10398,12 +10289,12 @@ snapshots: '@inquirer/figures@2.0.9': {} - '@inquirer/input@5.1.6(@types/node@22.20.2)': + '@inquirer/input@5.1.6(@types/node@22.20.4)': dependencies: - '@inquirer/core': 12.0.3(@types/node@22.20.2) - '@inquirer/type': 4.1.1(@types/node@22.20.2) + '@inquirer/core': 12.0.3(@types/node@22.20.4) + '@inquirer/type': 4.1.1(@types/node@22.20.4) optionalDependencies: - '@types/node': 22.20.2 + '@types/node': 22.20.4 '@inquirer/input@5.1.6(@types/node@24.13.5)': dependencies: @@ -10412,12 +10303,12 @@ snapshots: optionalDependencies: '@types/node': 24.13.5 - '@inquirer/number@4.2.3(@types/node@22.20.2)': + '@inquirer/number@4.2.3(@types/node@22.20.4)': dependencies: - '@inquirer/core': 12.0.3(@types/node@22.20.2) - '@inquirer/type': 4.1.1(@types/node@22.20.2) + '@inquirer/core': 12.0.3(@types/node@22.20.4) + '@inquirer/type': 4.1.1(@types/node@22.20.4) optionalDependencies: - '@types/node': 22.20.2 + '@types/node': 22.20.4 '@inquirer/number@4.2.3(@types/node@24.13.5)': dependencies: @@ -10426,13 +10317,13 @@ snapshots: optionalDependencies: '@types/node': 24.13.5 - '@inquirer/password@5.2.2(@types/node@22.20.2)': + '@inquirer/password@5.2.2(@types/node@22.20.4)': dependencies: '@inquirer/ansi': 2.0.8 - '@inquirer/core': 12.0.3(@types/node@22.20.2) - '@inquirer/type': 4.1.1(@types/node@22.20.2) + '@inquirer/core': 12.0.3(@types/node@22.20.4) + '@inquirer/type': 4.1.1(@types/node@22.20.4) optionalDependencies: - '@types/node': 22.20.2 + '@types/node': 22.20.4 '@inquirer/password@5.2.2(@types/node@24.13.5)': dependencies: @@ -10442,20 +10333,20 @@ snapshots: optionalDependencies: '@types/node': 24.13.5 - '@inquirer/prompts@8.7.2(@types/node@22.20.2)': - dependencies: - '@inquirer/checkbox': 5.2.5(@types/node@22.20.2) - '@inquirer/confirm': 6.3.2(@types/node@22.20.2) - '@inquirer/editor': 5.3.3(@types/node@22.20.2) - '@inquirer/expand': 5.1.5(@types/node@22.20.2) - '@inquirer/input': 5.1.6(@types/node@22.20.2) - '@inquirer/number': 4.2.3(@types/node@22.20.2) - '@inquirer/password': 5.2.2(@types/node@22.20.2) - '@inquirer/rawlist': 5.3.5(@types/node@22.20.2) - '@inquirer/search': 4.3.3(@types/node@22.20.2) - '@inquirer/select': 5.2.5(@types/node@22.20.2) + '@inquirer/prompts@8.7.2(@types/node@22.20.4)': + dependencies: + '@inquirer/checkbox': 5.2.5(@types/node@22.20.4) + '@inquirer/confirm': 6.3.2(@types/node@22.20.4) + '@inquirer/editor': 5.3.3(@types/node@22.20.4) + '@inquirer/expand': 5.1.5(@types/node@22.20.4) + '@inquirer/input': 5.1.6(@types/node@22.20.4) + '@inquirer/number': 4.2.3(@types/node@22.20.4) + '@inquirer/password': 5.2.2(@types/node@22.20.4) + '@inquirer/rawlist': 5.3.5(@types/node@22.20.4) + '@inquirer/search': 4.3.3(@types/node@22.20.4) + '@inquirer/select': 5.2.5(@types/node@22.20.4) optionalDependencies: - '@types/node': 22.20.2 + '@types/node': 22.20.4 '@inquirer/prompts@8.7.2(@types/node@24.13.5)': dependencies: @@ -10472,12 +10363,12 @@ snapshots: optionalDependencies: '@types/node': 24.13.5 - '@inquirer/rawlist@5.3.5(@types/node@22.20.2)': + '@inquirer/rawlist@5.3.5(@types/node@22.20.4)': dependencies: - '@inquirer/core': 12.0.3(@types/node@22.20.2) - '@inquirer/type': 4.1.1(@types/node@22.20.2) + '@inquirer/core': 12.0.3(@types/node@22.20.4) + '@inquirer/type': 4.1.1(@types/node@22.20.4) optionalDependencies: - '@types/node': 22.20.2 + '@types/node': 22.20.4 '@inquirer/rawlist@5.3.5(@types/node@24.13.5)': dependencies: @@ -10486,13 +10377,13 @@ snapshots: optionalDependencies: '@types/node': 24.13.5 - '@inquirer/search@4.3.3(@types/node@22.20.2)': + '@inquirer/search@4.3.3(@types/node@22.20.4)': dependencies: - '@inquirer/core': 12.0.3(@types/node@22.20.2) + '@inquirer/core': 12.0.3(@types/node@22.20.4) '@inquirer/figures': 2.0.9 - '@inquirer/type': 4.1.1(@types/node@22.20.2) + '@inquirer/type': 4.1.1(@types/node@22.20.4) optionalDependencies: - '@types/node': 22.20.2 + '@types/node': 22.20.4 '@inquirer/search@4.3.3(@types/node@24.13.5)': dependencies: @@ -10502,14 +10393,14 @@ snapshots: optionalDependencies: '@types/node': 24.13.5 - '@inquirer/select@5.2.5(@types/node@22.20.2)': + '@inquirer/select@5.2.5(@types/node@22.20.4)': dependencies: '@inquirer/ansi': 2.0.8 - '@inquirer/core': 12.0.3(@types/node@22.20.2) + '@inquirer/core': 12.0.3(@types/node@22.20.4) '@inquirer/figures': 2.0.9 - '@inquirer/type': 4.1.1(@types/node@22.20.2) + '@inquirer/type': 4.1.1(@types/node@22.20.4) optionalDependencies: - '@types/node': 22.20.2 + '@types/node': 22.20.4 '@inquirer/select@5.2.5(@types/node@24.13.5)': dependencies: @@ -10520,9 +10411,9 @@ snapshots: optionalDependencies: '@types/node': 24.13.5 - '@inquirer/type@4.1.1(@types/node@22.20.2)': + '@inquirer/type@4.1.1(@types/node@22.20.4)': optionalDependencies: - '@types/node': 22.20.2 + '@types/node': 22.20.4 '@inquirer/type@4.1.1(@types/node@24.13.5)': optionalDependencies: @@ -10596,59 +10487,59 @@ snapshots: dependencies: tslib: 2.8.1 - '@jsonjoy.com/fs-core@4.78.0(tslib@2.8.1)': + '@jsonjoy.com/fs-core@4.78.1(tslib@2.8.1)': dependencies: - '@jsonjoy.com/fs-node-builtins': 4.78.0(tslib@2.8.1) - '@jsonjoy.com/fs-node-utils': 4.78.0(tslib@2.8.1) + '@jsonjoy.com/fs-node-builtins': 4.78.1(tslib@2.8.1) + '@jsonjoy.com/fs-node-utils': 4.78.1(tslib@2.8.1) thingies: 2.6.1(tslib@2.8.1) tslib: 2.8.1 - '@jsonjoy.com/fs-fsa@4.78.0(tslib@2.8.1)': + '@jsonjoy.com/fs-fsa@4.78.1(tslib@2.8.1)': dependencies: - '@jsonjoy.com/fs-core': 4.78.0(tslib@2.8.1) - '@jsonjoy.com/fs-node-builtins': 4.78.0(tslib@2.8.1) - '@jsonjoy.com/fs-node-utils': 4.78.0(tslib@2.8.1) + '@jsonjoy.com/fs-core': 4.78.1(tslib@2.8.1) + '@jsonjoy.com/fs-node-builtins': 4.78.1(tslib@2.8.1) + '@jsonjoy.com/fs-node-utils': 4.78.1(tslib@2.8.1) thingies: 2.6.1(tslib@2.8.1) tslib: 2.8.1 - '@jsonjoy.com/fs-node-builtins@4.78.0(tslib@2.8.1)': + '@jsonjoy.com/fs-node-builtins@4.78.1(tslib@2.8.1)': dependencies: tslib: 2.8.1 - '@jsonjoy.com/fs-node-to-fsa@4.78.0(tslib@2.8.1)': + '@jsonjoy.com/fs-node-to-fsa@4.78.1(tslib@2.8.1)': dependencies: - '@jsonjoy.com/fs-fsa': 4.78.0(tslib@2.8.1) - '@jsonjoy.com/fs-node-builtins': 4.78.0(tslib@2.8.1) - '@jsonjoy.com/fs-node-utils': 4.78.0(tslib@2.8.1) + '@jsonjoy.com/fs-fsa': 4.78.1(tslib@2.8.1) + '@jsonjoy.com/fs-node-builtins': 4.78.1(tslib@2.8.1) + '@jsonjoy.com/fs-node-utils': 4.78.1(tslib@2.8.1) tslib: 2.8.1 - '@jsonjoy.com/fs-node-utils@4.78.0(tslib@2.8.1)': + '@jsonjoy.com/fs-node-utils@4.78.1(tslib@2.8.1)': dependencies: - '@jsonjoy.com/fs-node-builtins': 4.78.0(tslib@2.8.1) + '@jsonjoy.com/fs-node-builtins': 4.78.1(tslib@2.8.1) glob-to-regex.js: 1.3.1(tslib@2.8.1) tslib: 2.8.1 - '@jsonjoy.com/fs-node@4.78.0(tslib@2.8.1)': + '@jsonjoy.com/fs-node@4.78.1(tslib@2.8.1)': dependencies: - '@jsonjoy.com/fs-core': 4.78.0(tslib@2.8.1) - '@jsonjoy.com/fs-node-builtins': 4.78.0(tslib@2.8.1) - '@jsonjoy.com/fs-node-utils': 4.78.0(tslib@2.8.1) - '@jsonjoy.com/fs-print': 4.78.0(tslib@2.8.1) - '@jsonjoy.com/fs-snapshot': 4.78.0(tslib@2.8.1) + '@jsonjoy.com/fs-core': 4.78.1(tslib@2.8.1) + '@jsonjoy.com/fs-node-builtins': 4.78.1(tslib@2.8.1) + '@jsonjoy.com/fs-node-utils': 4.78.1(tslib@2.8.1) + '@jsonjoy.com/fs-print': 4.78.1(tslib@2.8.1) + '@jsonjoy.com/fs-snapshot': 4.78.1(tslib@2.8.1) glob-to-regex.js: 1.3.1(tslib@2.8.1) thingies: 2.6.1(tslib@2.8.1) tslib: 2.8.1 - '@jsonjoy.com/fs-print@4.78.0(tslib@2.8.1)': + '@jsonjoy.com/fs-print@4.78.1(tslib@2.8.1)': dependencies: - '@jsonjoy.com/fs-node-utils': 4.78.0(tslib@2.8.1) + '@jsonjoy.com/fs-node-utils': 4.78.1(tslib@2.8.1) tree-dump: 1.1.0(tslib@2.8.1) tslib: 2.8.1 - '@jsonjoy.com/fs-snapshot@4.78.0(tslib@2.8.1)': + '@jsonjoy.com/fs-snapshot@4.78.1(tslib@2.8.1)': dependencies: '@jsonjoy.com/buffers': 17.67.0(tslib@2.8.1) - '@jsonjoy.com/fs-node-utils': 4.78.0(tslib@2.8.1) + '@jsonjoy.com/fs-node-utils': 4.78.1(tslib@2.8.1) '@jsonjoy.com/json-pack': 17.67.0(tslib@2.8.1) '@jsonjoy.com/util': 17.67.0(tslib@2.8.1) tslib: 2.8.1 @@ -10710,10 +10601,10 @@ snapshots: '@leichtgewicht/ip-codec@2.0.5': {} - '@listr2/prompt-adapter-inquirer@4.2.7(@inquirer/prompts@8.7.2(@types/node@22.20.2))(@types/node@22.20.2)(listr2@11.1.0)': + '@listr2/prompt-adapter-inquirer@4.2.7(@inquirer/prompts@8.7.2(@types/node@22.20.4))(@types/node@22.20.4)(listr2@11.1.0)': dependencies: - '@inquirer/prompts': 8.7.2(@types/node@22.20.2) - '@inquirer/type': 4.1.1(@types/node@22.20.2) + '@inquirer/prompts': 8.7.2(@types/node@22.20.4) + '@inquirer/type': 4.1.1(@types/node@22.20.4) listr2: 11.1.0 transitivePeerDependencies: - '@types/node' @@ -10850,7 +10741,7 @@ snapshots: '@napi-rs/nice-win32-x64-msvc': 1.1.1 optional: true - '@noble/hashes@1.4.0': {} + '@noble/hashes@1.8.0': {} '@nodelib/fs.scandir@2.1.5': dependencies: @@ -10974,7 +10865,7 @@ snapshots: '@octokit/endpoint': 11.0.5 '@octokit/request-error': 7.1.2 '@octokit/types': 18.0.0 - content-type: 3.1.0 + content-type: 3.1.1 json-with-bigint: 3.5.12 universal-user-agent: 7.0.3 @@ -11136,78 +11027,78 @@ snapshots: '@parcel/watcher-win32-arm64': 2.6.0 '@parcel/watcher-win32-x64': 2.6.0 - '@peculiar/asn1-cms@2.9.4': + '@peculiar/asn1-cms@2.9.5': dependencies: - '@peculiar/asn1-schema': 2.9.4 - '@peculiar/asn1-x509': 2.9.4 - '@peculiar/asn1-x509-attr': 2.9.4 + '@peculiar/asn1-schema': 2.9.5 + '@peculiar/asn1-x509': 2.9.5 + '@peculiar/asn1-x509-attr': 2.9.5 asn1js: 3.0.10 tslib: 2.8.1 - '@peculiar/asn1-csr@2.9.4': + '@peculiar/asn1-csr@2.9.5': dependencies: - '@peculiar/asn1-schema': 2.9.4 - '@peculiar/asn1-x509': 2.9.4 + '@peculiar/asn1-schema': 2.9.5 + '@peculiar/asn1-x509': 2.9.5 asn1js: 3.0.10 tslib: 2.8.1 - '@peculiar/asn1-ecc@2.9.4': + '@peculiar/asn1-ecc@2.9.5': dependencies: - '@peculiar/asn1-schema': 2.9.4 - '@peculiar/asn1-x509': 2.9.4 + '@peculiar/asn1-schema': 2.9.5 + '@peculiar/asn1-x509': 2.9.5 asn1js: 3.0.10 tslib: 2.8.1 - '@peculiar/asn1-pfx@2.9.4': + '@peculiar/asn1-pfx@2.9.5': dependencies: - '@peculiar/asn1-cms': 2.9.4 - '@peculiar/asn1-pkcs8': 2.9.4 - '@peculiar/asn1-rsa': 2.9.4 - '@peculiar/asn1-schema': 2.9.4 + '@peculiar/asn1-cms': 2.9.5 + '@peculiar/asn1-pkcs8': 2.9.5 + '@peculiar/asn1-rsa': 2.9.5 + '@peculiar/asn1-schema': 2.9.5 asn1js: 3.0.10 tslib: 2.8.1 - '@peculiar/asn1-pkcs8@2.9.4': + '@peculiar/asn1-pkcs8@2.9.5': dependencies: - '@peculiar/asn1-schema': 2.9.4 - '@peculiar/asn1-x509': 2.9.4 + '@peculiar/asn1-schema': 2.9.5 + '@peculiar/asn1-x509': 2.9.5 asn1js: 3.0.10 tslib: 2.8.1 - '@peculiar/asn1-pkcs9@2.9.4': + '@peculiar/asn1-pkcs9@2.9.5': dependencies: - '@peculiar/asn1-cms': 2.9.4 - '@peculiar/asn1-pfx': 2.9.4 - '@peculiar/asn1-pkcs8': 2.9.4 - '@peculiar/asn1-schema': 2.9.4 - '@peculiar/asn1-x509': 2.9.4 - '@peculiar/asn1-x509-attr': 2.9.4 + '@peculiar/asn1-cms': 2.9.5 + '@peculiar/asn1-pfx': 2.9.5 + '@peculiar/asn1-pkcs8': 2.9.5 + '@peculiar/asn1-schema': 2.9.5 + '@peculiar/asn1-x509': 2.9.5 + '@peculiar/asn1-x509-attr': 2.9.5 asn1js: 3.0.10 tslib: 2.8.1 - '@peculiar/asn1-rsa@2.9.4': + '@peculiar/asn1-rsa@2.9.5': dependencies: - '@peculiar/asn1-schema': 2.9.4 - '@peculiar/asn1-x509': 2.9.4 + '@peculiar/asn1-schema': 2.9.5 + '@peculiar/asn1-x509': 2.9.5 asn1js: 3.0.10 tslib: 2.8.1 - '@peculiar/asn1-schema@2.9.4': + '@peculiar/asn1-schema@2.9.5': dependencies: '@peculiar/utils': 2.0.3 asn1js: 3.0.10 tslib: 2.8.1 - '@peculiar/asn1-x509-attr@2.9.4': + '@peculiar/asn1-x509-attr@2.9.5': dependencies: - '@peculiar/asn1-schema': 2.9.4 - '@peculiar/asn1-x509': 2.9.4 + '@peculiar/asn1-schema': 2.9.5 + '@peculiar/asn1-x509': 2.9.5 asn1js: 3.0.10 tslib: 2.8.1 - '@peculiar/asn1-x509@2.9.4': + '@peculiar/asn1-x509@2.9.5': dependencies: - '@peculiar/asn1-schema': 2.9.4 + '@peculiar/asn1-schema': 2.9.5 '@peculiar/utils': 2.0.3 asn1js: 3.0.10 tslib: 2.8.1 @@ -11218,13 +11109,13 @@ snapshots: '@peculiar/x509@1.14.3': dependencies: - '@peculiar/asn1-cms': 2.9.4 - '@peculiar/asn1-csr': 2.9.4 - '@peculiar/asn1-ecc': 2.9.4 - '@peculiar/asn1-pkcs9': 2.9.4 - '@peculiar/asn1-rsa': 2.9.4 - '@peculiar/asn1-schema': 2.9.4 - '@peculiar/asn1-x509': 2.9.4 + '@peculiar/asn1-cms': 2.9.5 + '@peculiar/asn1-csr': 2.9.5 + '@peculiar/asn1-ecc': 2.9.5 + '@peculiar/asn1-pkcs9': 2.9.5 + '@peculiar/asn1-rsa': 2.9.5 + '@peculiar/asn1-schema': 2.9.5 + '@peculiar/asn1-x509': 2.9.5 pvtsutils: 1.3.6 reflect-metadata: 0.2.2 tslib: 2.8.1 @@ -11457,7 +11348,7 @@ snapshots: '@types/babel__core@7.20.5': dependencies: - '@babel/parser': 7.29.8 + '@babel/parser': 7.29.9 '@babel/types': 7.29.8 '@types/babel__generator': 7.27.0 '@types/babel__template': 7.4.4 @@ -11469,7 +11360,7 @@ snapshots: '@types/babel__template@7.4.4': dependencies: - '@babel/parser': 7.29.8 + '@babel/parser': 7.29.9 '@babel/types': 7.29.8 '@types/babel__traverse@7.28.0': @@ -11481,16 +11372,16 @@ snapshots: '@types/body-parser@1.19.6': dependencies: '@types/connect': 3.4.38 - '@types/node': 22.20.2 + '@types/node': 22.20.4 '@types/bonjour@3.5.13': dependencies: - '@types/node': 22.20.2 + '@types/node': 22.20.4 '@types/browser-sync@2.29.1': dependencies: '@types/micromatch': 2.3.35 - '@types/node': 22.20.2 + '@types/node': 22.20.4 '@types/serve-static': 2.2.0 chokidar: 3.6.0 @@ -11501,26 +11392,26 @@ snapshots: '@types/cli-progress@3.11.6': dependencies: - '@types/node': 22.20.2 + '@types/node': 22.20.4 '@types/connect-history-api-fallback@1.5.4': dependencies: '@types/express-serve-static-core': 5.1.3 - '@types/node': 22.20.2 + '@types/node': 22.20.4 '@types/connect@3.4.38': dependencies: - '@types/node': 22.20.2 + '@types/node': 22.20.4 '@types/cors@2.8.19': dependencies: - '@types/node': 22.20.2 + '@types/node': 22.20.4 '@types/deep-eql@4.0.2': {} '@types/duplexify@3.6.5': dependencies: - '@types/node': 22.20.2 + '@types/node': 22.20.4 '@types/ejs@3.1.5': {} @@ -11532,7 +11423,7 @@ snapshots: '@types/express-serve-static-core@5.1.3': dependencies: - '@types/node': 22.20.2 + '@types/node': 22.20.4 '@types/qs': 6.15.1 '@types/range-parser': 1.2.7 '@types/send': 1.2.1 @@ -11553,7 +11444,7 @@ snapshots: '@types/http-proxy@1.17.17': dependencies: - '@types/node': 22.20.2 + '@types/node': 22.20.4 '@types/jasmine-reporters@2.5.3': dependencies: @@ -11569,17 +11460,17 @@ snapshots: '@types/karma@6.3.9(supports-color@11.0.0)': dependencies: - '@types/node': 22.20.2 + '@types/node': 22.20.4 log4js: 6.9.1(supports-color@11.0.0) transitivePeerDependencies: - supports-color '@types/less@3.0.8': {} - '@types/loader-utils@3.0.0(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.28)(uglify-js@3.19.3)': + '@types/loader-utils@3.0.0(esbuild@0.28.2)(lightningcss@1.33.0)(uglify-js@3.19.3)': dependencies: - '@types/node': 22.20.2 - webpack: 5.110.3(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.28)(uglify-js@3.19.3) + '@types/node': 22.20.4 + webpack: 5.111.0(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.28)(uglify-js@3.19.3) transitivePeerDependencies: - '@minify-html/node' - '@napi-rs/image' @@ -11605,7 +11496,7 @@ snapshots: dependencies: '@types/parse-glob': 3.0.32 - '@types/node@22.20.2': + '@types/node@22.20.4': dependencies: undici-types: 6.21.0 @@ -11621,12 +11512,12 @@ snapshots: '@types/progress@2.0.7': dependencies: - '@types/node': 22.20.2 + '@types/node': 22.20.4 '@types/pumpify@1.4.5': dependencies: '@types/duplexify': 3.6.5 - '@types/node': 22.20.2 + '@types/node': 22.20.4 '@types/qs@6.15.1': {} @@ -11634,7 +11525,7 @@ snapshots: '@types/readable-stream@4.0.10': dependencies: - '@types/node': 22.20.2 + '@types/node': 22.20.4 safe-buffer: 5.1.2 '@types/resolve@1.20.2': {} @@ -11645,7 +11536,7 @@ snapshots: '@types/send@1.2.1': dependencies: - '@types/node': 22.20.2 + '@types/node': 22.20.4 '@types/serve-index@1.9.4': dependencies: @@ -11654,13 +11545,13 @@ snapshots: '@types/serve-static@2.2.0': dependencies: '@types/http-errors': 2.0.5 - '@types/node': 22.20.2 + '@types/node': 22.20.4 '@types/stack-trace@0.0.33': {} '@types/tar-stream@3.1.4': dependencies: - '@types/node': 22.20.2 + '@types/node': 22.20.4 '@types/urijs@1.19.26': {} @@ -11668,7 +11559,7 @@ snapshots: '@types/ws@8.18.1': dependencies: - '@types/node': 22.20.2 + '@types/node': 22.20.4 '@types/yargs-parser@21.0.3': {} @@ -11927,9 +11818,9 @@ snapshots: transitivePeerDependencies: - supports-color - '@vitejs/plugin-basic-ssl@2.3.0(vite@8.3.0(@types/node@22.20.2)(esbuild@0.28.2)(jiti@2.7.0)(less@4.9.1(supports-color@11.0.0))(sass-embedded@1.104.1)(sass@1.104.1)(terser@5.51.2)(tsx@4.23.13)(yaml@2.9.1))': + '@vitejs/plugin-basic-ssl@2.3.0(vite@8.3.0(@types/node@22.20.4)(esbuild@0.28.2)(jiti@2.7.0)(less@4.9.1(supports-color@11.0.0))(sass-embedded@1.104.1)(sass@1.104.1)(terser@5.51.2)(tsx@4.23.13)(yaml@2.9.1))': dependencies: - vite: 8.3.0(@types/node@22.20.2)(esbuild@0.28.2)(jiti@2.7.0)(less@4.9.1(supports-color@11.0.0))(sass-embedded@1.104.1)(sass@1.104.1)(terser@5.51.2)(tsx@4.23.13)(yaml@2.9.1) + vite: 8.3.0(@types/node@22.20.4)(esbuild@0.28.2)(jiti@2.7.0)(less@4.9.1(supports-color@11.0.0))(sass-embedded@1.104.1)(sass@1.104.1)(terser@5.51.2)(tsx@4.23.13)(yaml@2.9.1) '@vitest/coverage-v8@5.0.1(vitest@5.0.1)': dependencies: @@ -11941,7 +11832,7 @@ snapshots: obug: 2.2.1 std-env: 4.2.0 tinyrainbow: 3.1.1 - vitest: 5.0.1(@opentelemetry/api@1.9.1)(@types/node@22.20.2)(@vitest/coverage-v8@5.0.1)(jsdom@30.0.1)(vite@8.3.0(@types/node@22.20.2)(esbuild@0.28.2)(jiti@2.7.0)(less@4.9.1(supports-color@11.0.0))(sass-embedded@1.104.0)(sass@1.104.0)(terser@5.51.2)(tsx@4.23.13)(yaml@2.9.1)) + vitest: 5.0.1(@opentelemetry/api@1.9.1)(@types/node@22.20.4)(@vitest/coverage-v8@5.0.1)(jsdom@30.0.1(@noble/hashes@1.8.0))(vite@8.3.0(@types/node@22.20.4)(esbuild@0.28.2)(jiti@2.7.0)(less@4.9.1(supports-color@11.0.0))(sass-embedded@1.104.1)(sass@1.104.1)(terser@5.51.2)(tsx@4.23.13)(yaml@2.9.1)) '@vitest/istanbul-lib-coverage@1.0.1': {} @@ -11949,23 +11840,14 @@ snapshots: dependencies: '@vitest/istanbul-lib-coverage': 1.0.1 - '@vitest/mocker@5.0.1(vite@8.3.0(@types/node@22.20.2)(esbuild@0.28.2)(jiti@2.7.0)(less@4.9.1(supports-color@11.0.0))(sass-embedded@1.104.0)(sass@1.104.0)(terser@5.51.2)(tsx@4.23.13)(yaml@2.9.1))': + '@vitest/mocker@5.0.1(vite@8.3.0(@types/node@22.20.4)(esbuild@0.28.2)(jiti@2.7.0)(less@4.9.1(supports-color@11.0.0))(sass-embedded@1.104.1)(sass@1.104.1)(terser@5.51.2)(tsx@4.23.13)(yaml@2.9.1))': dependencies: '@jridgewell/trace-mapping': 0.3.31 '@vitest/spy': 5.0.1 estree-walker: 3.0.3 - magic-string: 1.2.3 + magic-string: 1.4.1 optionalDependencies: - vite: 8.3.0(@types/node@22.20.2)(esbuild@0.28.2)(jiti@2.7.0)(less@4.9.1(supports-color@11.0.0))(sass-embedded@1.104.0)(sass@1.104.0)(terser@5.51.2)(tsx@4.23.13)(yaml@2.9.1) - - '@vitest/mocker@5.0.1(vite@8.3.0(@types/node@22.20.2)(esbuild@0.28.2)(jiti@2.7.0)(less@4.9.1(supports-color@11.0.0))(sass-embedded@1.104.1)(sass@1.104.1)(terser@5.51.2)(tsx@4.23.13)(yaml@2.9.1))': - dependencies: - '@jridgewell/trace-mapping': 0.3.31 - '@vitest/spy': 5.0.1 - estree-walker: 3.0.3 - magic-string: 1.2.3 - optionalDependencies: - vite: 8.3.0(@types/node@22.20.2)(esbuild@0.28.2)(jiti@2.7.0)(less@4.9.1(supports-color@11.0.0))(sass-embedded@1.104.1)(sass@1.104.1)(terser@5.51.2)(tsx@4.23.13)(yaml@2.9.1) + vite: 8.3.0(@types/node@22.20.4)(esbuild@0.28.2)(jiti@2.7.0)(less@4.9.1(supports-color@11.0.0))(sass-embedded@1.104.1)(sass@1.104.1)(terser@5.51.2)(tsx@4.23.13)(yaml@2.9.1) '@vitest/spy@5.0.1': {} @@ -12053,79 +11935,79 @@ snapshots: '@yarnpkg/lockfile@1.1.0': {} - '@yuku-codegen/binding-android-arm64@0.9.5': + '@yuku-codegen/binding-android-arm64@0.10.2': optional: true - '@yuku-codegen/binding-darwin-arm64@0.9.5': + '@yuku-codegen/binding-darwin-arm64@0.10.2': optional: true - '@yuku-codegen/binding-darwin-x64@0.9.5': + '@yuku-codegen/binding-darwin-x64@0.10.2': optional: true - '@yuku-codegen/binding-freebsd-x64@0.9.5': + '@yuku-codegen/binding-freebsd-x64@0.10.2': optional: true - '@yuku-codegen/binding-linux-arm-gnu@0.9.5': + '@yuku-codegen/binding-linux-arm-gnu@0.10.2': optional: true - '@yuku-codegen/binding-linux-arm-musl@0.9.5': + '@yuku-codegen/binding-linux-arm-musl@0.10.2': optional: true - '@yuku-codegen/binding-linux-arm64-gnu@0.9.5': + '@yuku-codegen/binding-linux-arm64-gnu@0.10.2': optional: true - '@yuku-codegen/binding-linux-arm64-musl@0.9.5': + '@yuku-codegen/binding-linux-arm64-musl@0.10.2': optional: true - '@yuku-codegen/binding-linux-x64-gnu@0.9.5': + '@yuku-codegen/binding-linux-x64-gnu@0.10.2': optional: true - '@yuku-codegen/binding-linux-x64-musl@0.9.5': + '@yuku-codegen/binding-linux-x64-musl@0.10.2': optional: true - '@yuku-codegen/binding-win32-arm64@0.9.5': + '@yuku-codegen/binding-win32-arm64@0.10.2': optional: true - '@yuku-codegen/binding-win32-x64@0.9.5': + '@yuku-codegen/binding-win32-x64@0.10.2': optional: true - '@yuku-parser/binding-android-arm64@0.9.5': + '@yuku-parser/binding-android-arm64@0.10.2': optional: true - '@yuku-parser/binding-darwin-arm64@0.9.5': + '@yuku-parser/binding-darwin-arm64@0.10.2': optional: true - '@yuku-parser/binding-darwin-x64@0.9.5': + '@yuku-parser/binding-darwin-x64@0.10.2': optional: true - '@yuku-parser/binding-freebsd-x64@0.9.5': + '@yuku-parser/binding-freebsd-x64@0.10.2': optional: true - '@yuku-parser/binding-linux-arm-gnu@0.9.5': + '@yuku-parser/binding-linux-arm-gnu@0.10.2': optional: true - '@yuku-parser/binding-linux-arm-musl@0.9.5': + '@yuku-parser/binding-linux-arm-musl@0.10.2': optional: true - '@yuku-parser/binding-linux-arm64-gnu@0.9.5': + '@yuku-parser/binding-linux-arm64-gnu@0.10.2': optional: true - '@yuku-parser/binding-linux-arm64-musl@0.9.5': + '@yuku-parser/binding-linux-arm64-musl@0.10.2': optional: true - '@yuku-parser/binding-linux-x64-gnu@0.9.5': + '@yuku-parser/binding-linux-x64-gnu@0.10.2': optional: true - '@yuku-parser/binding-linux-x64-musl@0.9.5': + '@yuku-parser/binding-linux-x64-musl@0.10.2': optional: true - '@yuku-parser/binding-win32-arm64@0.9.5': + '@yuku-parser/binding-win32-arm64@0.10.2': optional: true - '@yuku-parser/binding-win32-x64@0.9.5': + '@yuku-parser/binding-win32-x64@0.10.2': optional: true - '@yuku-toolchain/types@0.9.5': {} + '@yuku-toolchain/types@0.10.2': {} JSONStream@1.3.5: dependencies: @@ -12186,7 +12068,7 @@ snapshots: ajv@8.20.0: dependencies: fast-deep-equal: 3.1.3 - fast-uri: 3.1.7 + fast-uri: 3.1.8 json-schema-traverse: 1.0.0 require-from-string: 2.0.2 @@ -12315,7 +12197,7 @@ snapshots: autoprefixer@10.6.1(postcss@8.5.28): dependencies: - browserslist: 4.28.9 + browserslist: 4.29.0 caniuse-lite: 1.0.30001810 fraction.js: 5.3.4 picocolors: 1.1.1 @@ -12382,7 +12264,7 @@ snapshots: base64id@2.0.0: {} - baseline-browser-mapping@2.11.23: {} + baseline-browser-mapping@2.11.25: {} batch@0.6.1: {} @@ -12456,16 +12338,16 @@ snapshots: boolbase@2.0.0: {} - brace-expansion@1.1.18: + brace-expansion@1.1.21: dependencies: balanced-match: 1.0.2 concat-map: 0.0.1 - brace-expansion@2.1.4: + brace-expansion@2.1.7: dependencies: balanced-match: 1.0.2 - brace-expansion@5.0.9: + brace-expansion@5.0.12: dependencies: balanced-match: 4.0.4 @@ -12535,13 +12417,13 @@ snapshots: dependencies: pako: 0.2.9 - browserslist@4.28.9: + browserslist@4.29.0: dependencies: - baseline-browser-mapping: 2.11.23 + baseline-browser-mapping: 2.11.25 caniuse-lite: 1.0.30001810 - electron-to-chromium: 1.5.427 - node-releases: 2.0.55 - update-browserslist-db: 1.3.3(browserslist@4.28.9) + electron-to-chromium: 1.5.433 + node-releases: 2.0.56 + update-browserslist-db: 1.3.3(browserslist@4.29.0) bs-recipes@1.3.4: {} @@ -12668,7 +12550,7 @@ snapshots: cli-truncate@6.1.1: dependencies: - slice-ansi: 9.0.0 + slice-ansi: 9.0.1 string-width: 8.2.2 cli-width@4.1.0: {} @@ -12790,7 +12672,7 @@ snapshots: content-type@2.1.0: {} - content-type@3.1.0: {} + content-type@3.1.1: {} conventional-commits-filter@6.0.1: {} @@ -12824,7 +12706,7 @@ snapshots: core-js-compat@3.50.0: dependencies: - browserslist: 4.28.9 + browserslist: 4.29.0 core-util-is@1.0.2: {} @@ -12888,10 +12770,10 @@ snapshots: data-uri-to-buffer@4.0.1: {} - data-urls@7.0.0: + data-urls@7.0.0(@noble/hashes@1.8.0): dependencies: whatwg-mimetype: 5.0.0 - whatwg-url: 16.0.1 + whatwg-url: 16.0.1(@noble/hashes@1.8.0) transitivePeerDependencies: - '@noble/hashes' @@ -13072,7 +12954,7 @@ snapshots: ejs@6.0.1: {} - electron-to-chromium@1.5.427: {} + electron-to-chromium@1.5.433: {} emoji-regex@10.6.0: {} @@ -13082,7 +12964,7 @@ snapshots: emojis-list@3.0.0: {} - empathic@2.0.1: {} + empathic@2.1.0: {} encodeurl@1.0.2: {} @@ -13113,7 +12995,7 @@ snapshots: engine.io@6.6.10(bufferutil@4.1.0)(supports-color@11.0.0)(utf-8-validate@6.0.6): dependencies: '@types/cors': 2.8.19 - '@types/node': 22.20.2 + '@types/node': 22.20.4 '@types/ws': 8.18.1 accepts: 1.3.8 cookie: 0.7.2 @@ -13214,10 +13096,10 @@ snapshots: string.prototype.trimstart: 1.0.8 typed-array-buffer: 1.0.3 typed-array-byte-length: 1.0.3 - typed-array-byte-offset: 1.0.4 + typed-array-byte-offset: 1.0.5 typed-array-length: 1.0.8 unbox-primitive: 1.1.0 - which-typed-array: 1.1.22 + which-typed-array: 1.1.24 es-define-property@1.0.1: {} @@ -13293,7 +13175,7 @@ snapshots: eslint-import-resolver-node@0.3.10(supports-color@11.0.0): dependencies: debug: 3.2.7(supports-color@11.0.0) - is-core-module: 2.16.2 + is-core-module: 2.17.0 resolve: 2.0.0-next.7 transitivePeerDependencies: - supports-color @@ -13321,7 +13203,7 @@ snapshots: eslint-import-resolver-node: 0.3.10(supports-color@11.0.0) eslint-module-utils: 2.14.0(@typescript-eslint/parser@8.70.0(eslint@10.10.0(jiti@2.7.0)(supports-color@11.0.0))(supports-color@11.0.0)(typescript@6.0.3))(eslint-import-resolver-node@0.3.10(supports-color@11.0.0))(eslint@10.10.0(jiti@2.7.0)(supports-color@11.0.0))(supports-color@11.0.0) hasown: 2.0.4 - is-core-module: 2.16.2 + is-core-module: 2.17.0 is-glob: 4.0.3 minimatch: 3.1.5 object.fromentries: 2.0.8 @@ -13459,7 +13341,7 @@ snapshots: on-finished: 2.4.1 parseurl: 1.3.3 path-to-regexp: 0.1.13 - proxy-addr: 2.0.7 + proxy-addr: 2.0.8 qs: 6.15.3 range-parser: 1.2.1 safe-buffer: 5.2.1 @@ -13494,7 +13376,7 @@ snapshots: on-finished: 2.4.1 once: 1.4.0 parseurl: 1.3.3 - proxy-addr: 2.0.7 + proxy-addr: 2.0.8 qs: 6.16.0 range-parser: 1.3.0 router: 2.2.0(supports-color@11.0.0) @@ -13532,7 +13414,7 @@ snapshots: dependencies: fast-string-truncated-width: 3.0.3 - fast-uri@3.1.7: {} + fast-uri@3.1.8: {} fast-wrap-ansi@0.2.2: dependencies: @@ -13665,6 +13547,8 @@ snapshots: flatted@3.4.4: {} + flru@1.0.2: {} + folder-hash@4.1.3(supports-color@11.0.0): dependencies: debug: 4.4.0(supports-color@11.0.0) @@ -13781,7 +13665,7 @@ snapshots: get-caller-file@2.0.5: {} - get-east-asian-width@1.6.0: {} + get-east-asian-width@1.7.0: {} get-intrinsic@1.3.0: dependencies: @@ -13899,7 +13783,7 @@ snapshots: google-gax@5.0.8(supports-color@11.0.0): dependencies: - '@grpc/grpc-js': 1.14.4 + '@grpc/grpc-js': 1.14.5 '@grpc/proto-loader': 0.8.1 duplexify: 4.1.3 google-auth-library: 10.5.0(supports-color@11.0.0) @@ -13929,7 +13813,7 @@ snapshots: keyv: 5.6.0 lowercase-keys: 4.0.1 responselike: 4.0.2 - type-fest: 5.9.0 + type-fest: 5.10.0 uint8array-extras: 1.5.0 graceful-fs@4.2.11: {} @@ -13943,7 +13827,7 @@ snapshots: grpc-gcp@1.1.1: dependencies: - '@grpc/grpc-js': 1.14.4 + '@grpc/grpc-js': 1.14.5 protobufjs: 7.6.6 gtoken@8.0.0(supports-color@11.0.0): @@ -14003,11 +13887,11 @@ snapshots: hosted-git-info@10.1.1: dependencies: - lru-cache: 11.5.2 + lru-cache: 11.5.3 - html-encoding-sniffer@6.0.0: + html-encoding-sniffer@6.0.0(@noble/hashes@1.8.0): dependencies: - '@exodus/bytes': 1.15.1 + '@exodus/bytes': 1.15.1(@noble/hashes@1.8.0) transitivePeerDependencies: - '@noble/hashes' @@ -14198,7 +14082,7 @@ snapshots: is-callable@1.2.7: {} - is-core-module@2.16.2: + is-core-module@2.17.0: dependencies: hasown: 2.0.4 @@ -14231,7 +14115,7 @@ snapshots: is-fullwidth-code-point@5.1.0: dependencies: - get-east-asian-width: 1.6.0 + get-east-asian-width: 1.7.0 is-generator-function@1.1.2: dependencies: @@ -14322,7 +14206,7 @@ snapshots: is-typed-array@1.1.15: dependencies: - which-typed-array: 1.1.22 + which-typed-array: 1.1.24 is-typedarray@1.0.0: {} @@ -14370,7 +14254,7 @@ snapshots: istanbul-lib-instrument@5.2.1(supports-color@11.0.0): dependencies: '@babel/core': 7.29.7(supports-color@11.0.0) - '@babel/parser': 7.29.8 + '@babel/parser': 7.29.9 '@istanbuljs/schema': 0.1.6 istanbul-lib-coverage: 3.2.2 semver: 6.3.1 @@ -14380,7 +14264,7 @@ snapshots: istanbul-lib-instrument@6.0.3(supports-color@11.0.0): dependencies: '@babel/core': 7.29.7(supports-color@11.0.0) - '@babel/parser': 7.29.8 + '@babel/parser': 7.29.9 '@istanbuljs/schema': 0.1.6 istanbul-lib-coverage: 3.2.2 semver: 7.8.5 @@ -14433,7 +14317,7 @@ snapshots: jest-worker@27.5.1: dependencies: - '@types/node': 22.20.2 + '@types/node': 22.20.4 merge-stream: 2.0.0 supports-color: 8.1.1 @@ -14453,19 +14337,19 @@ snapshots: jsbn@0.1.1: {} - jsdom@30.0.1: + jsdom@30.0.1(@noble/hashes@1.8.0): dependencies: '@asamuzakjp/css-color': 6.0.7 '@asamuzakjp/dom-selector': 8.3.2 '@bramus/specificity': 2.4.2 - '@csstools/css-syntax-patches-for-csstree': 1.1.13(css-tree@3.2.1) - '@exodus/bytes': 1.15.1 + '@csstools/css-syntax-patches-for-csstree': 1.1.14(css-tree@3.2.1) + '@exodus/bytes': 1.15.1(@noble/hashes@1.8.0) css-tree: 3.2.1 - data-urls: 7.0.0 + data-urls: 7.0.0(@noble/hashes@1.8.0) decimal.js: 10.6.0 - html-encoding-sniffer: 6.0.0 + html-encoding-sniffer: 6.0.0(@noble/hashes@1.8.0) is-potential-custom-element-name: 1.0.1 - lru-cache: 11.5.2 + lru-cache: 11.5.3 parse5: 8.0.1 saxes: 6.0.0 symbol-tree: 3.2.4 @@ -14474,7 +14358,7 @@ snapshots: w3c-xmlserializer: 5.0.0 webidl-conversions: 8.0.1 whatwg-mimetype: 5.0.0 - whatwg-url: 17.1.1 + whatwg-url: 17.1.2(@noble/hashes@1.8.0) xml-name-validator: 5.0.0 transitivePeerDependencies: - '@noble/hashes' @@ -14713,7 +14597,7 @@ snapshots: dependencies: cli-truncate: 6.1.1 log-update: 8.0.0 - wrap-ansi: 10.0.1 + wrap-ansi: 10.0.2 lmdb@3.5.6: dependencies: @@ -14785,10 +14669,10 @@ snapshots: dependencies: ansi-escapes: 7.3.0 cli-cursor: 5.0.0 - slice-ansi: 9.0.0 + slice-ansi: 9.0.1 string-width: 8.2.2 strip-ansi: 7.2.0 - wrap-ansi: 10.0.1 + wrap-ansi: 10.0.2 log4js@6.9.1(supports-color@11.0.0): dependencies: @@ -14816,7 +14700,7 @@ snapshots: lru-cache@10.4.3: {} - lru-cache@11.5.2: {} + lru-cache@11.5.3: {} lru-cache@5.1.1: dependencies: @@ -14828,17 +14712,13 @@ snapshots: dependencies: '@jridgewell/sourcemap-codec': 1.6.0 - magic-string@1.2.3: - dependencies: - '@jridgewell/sourcemap-codec': 1.6.0 - magic-string@1.4.1: dependencies: '@jridgewell/sourcemap-codec': 1.6.0 magicast@0.5.5: dependencies: - '@babel/parser': 7.29.8 + '@babel/parser': 7.29.9 '@babel/types': 7.29.8 source-map-js: 1.2.1 @@ -14857,16 +14737,16 @@ snapshots: media-typer@1.1.1: {} - memfs@4.78.0: + memfs@4.78.1: dependencies: - '@jsonjoy.com/fs-core': 4.78.0(tslib@2.8.1) - '@jsonjoy.com/fs-fsa': 4.78.0(tslib@2.8.1) - '@jsonjoy.com/fs-node': 4.78.0(tslib@2.8.1) - '@jsonjoy.com/fs-node-builtins': 4.78.0(tslib@2.8.1) - '@jsonjoy.com/fs-node-to-fsa': 4.78.0(tslib@2.8.1) - '@jsonjoy.com/fs-node-utils': 4.78.0(tslib@2.8.1) - '@jsonjoy.com/fs-print': 4.78.0(tslib@2.8.1) - '@jsonjoy.com/fs-snapshot': 4.78.0(tslib@2.8.1) + '@jsonjoy.com/fs-core': 4.78.1(tslib@2.8.1) + '@jsonjoy.com/fs-fsa': 4.78.1(tslib@2.8.1) + '@jsonjoy.com/fs-node': 4.78.1(tslib@2.8.1) + '@jsonjoy.com/fs-node-builtins': 4.78.1(tslib@2.8.1) + '@jsonjoy.com/fs-node-to-fsa': 4.78.1(tslib@2.8.1) + '@jsonjoy.com/fs-node-utils': 4.78.1(tslib@2.8.1) + '@jsonjoy.com/fs-print': 4.78.1(tslib@2.8.1) + '@jsonjoy.com/fs-snapshot': 4.78.1(tslib@2.8.1) '@jsonjoy.com/json-pack': 1.21.0(tslib@2.8.1) '@jsonjoy.com/util': 1.9.0(tslib@2.8.1) glob-to-regex.js: 1.3.1(tslib@2.8.1) @@ -14919,36 +14799,23 @@ snapshots: minimatch@10.2.6: dependencies: - brace-expansion: 5.0.9 + brace-expansion: 5.0.12 minimatch@3.1.5: dependencies: - brace-expansion: 1.1.18 + brace-expansion: 1.1.21 minimatch@7.4.9: dependencies: - brace-expansion: 2.1.4 + brace-expansion: 2.1.7 minimatch@9.0.9: dependencies: - brace-expansion: 2.1.4 + brace-expansion: 2.1.7 minimist@1.2.8: {} - minimizer-webpack-plugin@5.10.1(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.28)(uglify-js@3.19.3)(webpack@5.110.3(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.28)(uglify-js@3.19.3)): - dependencies: - '@jridgewell/trace-mapping': 0.3.31 - jest-worker: 27.5.1 - schema-utils: 4.5.0 - terser: 5.51.2 - webpack: 5.110.3(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.28)(uglify-js@3.19.3) - optionalDependencies: - esbuild: 0.28.2 - lightningcss: 1.33.0 - postcss: 8.5.28 - uglify-js: 3.19.3 - - minimizer-webpack-plugin@5.10.1(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.28)(uglify-js@3.19.3)(webpack@5.111.0(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.28)(uglify-js@3.19.3)): + minimizer-webpack-plugin@5.11.0(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.28)(uglify-js@3.19.3)(webpack@5.111.0(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.28)(uglify-js@3.19.3)): dependencies: '@jridgewell/trace-mapping': 0.3.31 jest-worker: 27.5.1 @@ -15045,7 +14912,7 @@ snapshots: '@ampproject/remapping': 2.3.0 '@angular/compiler-cli': 22.2.0-rc.0(@angular/compiler@22.2.0-rc.0)(typescript@6.0.3) ajv: 8.20.0 - browserslist: 4.28.9 + browserslist: 4.29.0 chokidar: 5.0.0 commander: 15.0.0 dependency-graph: 1.0.0 @@ -15057,7 +14924,7 @@ snapshots: ora: 9.4.1 postcss: 8.5.28 rolldown: 1.2.8 - rolldown-plugin-dts: 0.28.5(rolldown@1.2.8)(typescript@6.0.3) + rolldown-plugin-dts: 0.28.6(rolldown@1.2.8)(typescript@6.0.3) rxjs: 7.8.2 sass: 1.104.1 sass-embedded: 1.104.1 @@ -15067,6 +14934,7 @@ snapshots: transitivePeerDependencies: - '@typescript/native-preview' - '@volar/typescript' + - '@vue/language-core' - oxc-resolver - supports-color - vue-tsc @@ -15110,7 +14978,7 @@ snapshots: node-gyp-build@4.8.4: {} - node-releases@2.0.55: {} + node-releases@2.0.56: {} normalize-path@3.0.0: {} @@ -15173,6 +15041,8 @@ snapshots: obug@2.2.1: {} + obug@3.0.0: {} + on-exit-leak-free@2.1.2: {} on-finished@2.3.0: @@ -15338,7 +15208,7 @@ snapshots: path-scurry@2.0.2: dependencies: - lru-cache: 11.5.2 + lru-cache: 11.5.3 minipass: 7.1.3 path-to-regexp@0.1.13: {} @@ -15396,9 +15266,9 @@ snapshots: dependencies: find-up-simple: 1.0.1 - pkijs@3.4.0: + pkijs@3.4.1: dependencies: - '@noble/hashes': 1.4.0 + '@noble/hashes': 1.8.0 asn1js: 3.0.10 bytestreamjs: 2.0.1 pvtsutils: 1.3.6 @@ -15471,7 +15341,7 @@ snapshots: prelude-ls@1.2.1: {} - prettier@3.9.6: {} + prettier@3.9.8: {} probe-image-size@7.4.0(supports-color@11.0.0): dependencies: @@ -15509,10 +15379,10 @@ snapshots: '@protobufjs/path': 1.1.2 '@protobufjs/pool': 1.1.0 '@protobufjs/utf8': 1.1.2 - '@types/node': 22.20.2 + '@types/node': 22.20.4 long: 5.3.2 - proxy-addr@2.0.7: + proxy-addr@2.0.8: dependencies: forwarded: 0.2.0 ipaddr.js: 1.9.1 @@ -15704,13 +15574,13 @@ snapshots: regenerate: 1.4.2 regenerate-unicode-properties: 10.2.2 regjsgen: 0.8.0 - regjsparser: 0.13.2 + regjsparser: 0.13.3 unicode-match-property-ecmascript: 2.0.0 unicode-match-property-value-ecmascript: 2.2.1 regjsgen@0.8.0: {} - regjsparser@0.13.2: + regjsparser@0.13.3: dependencies: jsesc: 3.1.0 @@ -15737,14 +15607,14 @@ snapshots: resolve@1.22.12: dependencies: es-errors: 1.3.0 - is-core-module: 2.16.2 + is-core-module: 2.17.0 path-parse: 1.0.7 supports-preserve-symlinks-flag: 1.0.0 resolve@2.0.0-next.7: dependencies: es-errors: 1.3.0 - is-core-module: 2.16.2 + is-core-module: 2.17.0 node-exports-info: 1.6.2 object-keys: 1.1.1 path-parse: 1.0.7 @@ -15787,15 +15657,15 @@ snapshots: dependencies: glob: 10.5.0 - rolldown-plugin-dts@0.28.5(rolldown@1.2.8)(typescript@6.0.3): + rolldown-plugin-dts@0.28.6(rolldown@1.2.8)(typescript@6.0.3): dependencies: dts-resolver: 3.0.0 get-tsconfig: 5.0.0-beta.6 - obug: 2.2.1 + obug: 3.0.0 rolldown: 1.2.8 - yuku-ast: 0.9.5 - yuku-codegen: 0.9.5 - yuku-parser: 0.9.5 + yuku-ast: 0.10.2 + yuku-codegen: 0.10.2 + yuku-parser: 0.10.2 optionalDependencies: typescript: 6.0.3 transitivePeerDependencies: @@ -15831,14 +15701,14 @@ snapshots: rollup: 4.63.3 typescript: 6.0.3 optionalDependencies: - '@babel/code-frame': 8.0.0 + '@babel/code-frame': 8.0.6 - rollup-plugin-sourcemaps2@0.5.8(@types/node@22.20.2)(rollup@4.63.3): + rollup-plugin-sourcemaps2@0.5.8(@types/node@22.20.4)(rollup@4.63.3): dependencies: '@rollup/pluginutils': 5.4.0(rollup@4.63.3) rollup: 4.63.3 optionalDependencies: - '@types/node': 22.20.2 + '@types/node': 22.20.4 rollup@4.63.3: dependencies: @@ -15925,152 +15795,64 @@ snapshots: dependencies: truncate-utf8-bytes: 1.0.2 - sass-embedded-all-unknown@1.104.0: - dependencies: - sass: 1.104.0 - optional: true - sass-embedded-all-unknown@1.104.1: dependencies: sass: 1.104.1 optional: true - sass-embedded-android-arm64@1.104.0: - optional: true - sass-embedded-android-arm64@1.104.1: optional: true - sass-embedded-android-arm@1.104.0: - optional: true - sass-embedded-android-arm@1.104.1: optional: true - sass-embedded-android-riscv64@1.104.0: - optional: true - sass-embedded-android-riscv64@1.104.1: optional: true - sass-embedded-android-x64@1.104.0: - optional: true - sass-embedded-android-x64@1.104.1: optional: true - sass-embedded-darwin-arm64@1.104.0: - optional: true - sass-embedded-darwin-arm64@1.104.1: optional: true - sass-embedded-darwin-x64@1.104.0: - optional: true - sass-embedded-darwin-x64@1.104.1: optional: true - sass-embedded-linux-arm64@1.104.0: - optional: true - sass-embedded-linux-arm64@1.104.1: optional: true - sass-embedded-linux-arm@1.104.0: - optional: true - sass-embedded-linux-arm@1.104.1: optional: true - sass-embedded-linux-musl-arm64@1.104.0: - optional: true - sass-embedded-linux-musl-arm64@1.104.1: optional: true - sass-embedded-linux-musl-arm@1.104.0: - optional: true - sass-embedded-linux-musl-arm@1.104.1: optional: true - sass-embedded-linux-musl-riscv64@1.104.0: - optional: true - sass-embedded-linux-musl-riscv64@1.104.1: optional: true - sass-embedded-linux-musl-x64@1.104.0: - optional: true - sass-embedded-linux-musl-x64@1.104.1: optional: true - sass-embedded-linux-riscv64@1.104.0: - optional: true - sass-embedded-linux-riscv64@1.104.1: optional: true - sass-embedded-linux-x64@1.104.0: - optional: true - sass-embedded-linux-x64@1.104.1: optional: true - sass-embedded-unknown-all@1.104.0: - dependencies: - sass: 1.104.0 - optional: true - sass-embedded-unknown-all@1.104.1: dependencies: sass: 1.104.1 optional: true - sass-embedded-win32-arm64@1.104.0: - optional: true - sass-embedded-win32-arm64@1.104.1: optional: true - sass-embedded-win32-x64@1.104.0: - optional: true - sass-embedded-win32-x64@1.104.1: optional: true - sass-embedded@1.104.0: - dependencies: - '@bufbuild/protobuf': 2.15.0 - colorjs.io: 0.7.1 - immutable: 5.1.9 - rxjs: 7.8.2 - supports-color: 8.1.1 - sync-child-process: 1.0.2 - varint: 6.0.0 - optionalDependencies: - sass-embedded-all-unknown: 1.104.0 - sass-embedded-android-arm: 1.104.0 - sass-embedded-android-arm64: 1.104.0 - sass-embedded-android-riscv64: 1.104.0 - sass-embedded-android-x64: 1.104.0 - sass-embedded-darwin-arm64: 1.104.0 - sass-embedded-darwin-x64: 1.104.0 - sass-embedded-linux-arm: 1.104.0 - sass-embedded-linux-arm64: 1.104.0 - sass-embedded-linux-musl-arm: 1.104.0 - sass-embedded-linux-musl-arm64: 1.104.0 - sass-embedded-linux-musl-riscv64: 1.104.0 - sass-embedded-linux-musl-x64: 1.104.0 - sass-embedded-linux-riscv64: 1.104.0 - sass-embedded-linux-x64: 1.104.0 - sass-embedded-unknown-all: 1.104.0 - sass-embedded-win32-arm64: 1.104.0 - sass-embedded-win32-x64: 1.104.0 - optional: true - sass-embedded@1.104.1: dependencies: '@bufbuild/protobuf': 2.15.0 @@ -16100,21 +15882,12 @@ snapshots: sass-embedded-win32-arm64: 1.104.1 sass-embedded-win32-x64: 1.104.1 - sass-loader@17.0.1(sass-embedded@1.104.0)(sass@1.104.1)(webpack@5.111.0(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.28)(uglify-js@3.19.3)): + sass-loader@17.0.1(sass-embedded@1.104.1)(sass@1.104.1)(webpack@5.111.0(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.28)(uglify-js@3.19.3)): optionalDependencies: sass: 1.104.1 - sass-embedded: 1.104.0 + sass-embedded: 1.104.1 webpack: 5.111.0(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.28)(uglify-js@3.19.3) - sass@1.104.0: - dependencies: - chokidar: 5.0.0 - immutable: 5.1.9 - source-map-js: 1.2.1 - optionalDependencies: - '@parcel/watcher': 2.6.0 - optional: true - sass@1.104.1: dependencies: chokidar: 5.0.0 @@ -16140,7 +15913,7 @@ snapshots: selfsigned@5.5.0: dependencies: '@peculiar/x509': 1.14.3 - pkijs: 3.4.0 + pkijs: 3.4.1 semver@6.3.1: {} @@ -16286,7 +16059,7 @@ snapshots: slash@3.0.0: {} - slice-ansi@9.0.0: + slice-ansi@9.0.1: dependencies: ansi-styles: 6.2.3 is-fullwidth-code-point: 5.1.0 @@ -16455,12 +16228,12 @@ snapshots: string-width@7.2.0: dependencies: emoji-regex: 10.6.0 - get-east-asian-width: 1.6.0 + get-east-asian-width: 1.7.0 strip-ansi: 7.2.0 string-width@8.2.2: dependencies: - get-east-asian-width: 1.6.0 + get-east-asian-width: 1.7.0 strip-ansi: 7.2.0 string.prototype.trim@1.2.11: @@ -16701,7 +16474,7 @@ snapshots: dependencies: prelude-ls: 1.2.1 - type-fest@5.9.0: + type-fest@5.10.0: dependencies: tagged-tag: 1.0.0 @@ -16730,13 +16503,12 @@ snapshots: has-proto: 1.2.0 is-typed-array: 1.1.15 - typed-array-byte-offset@1.0.4: + typed-array-byte-offset@1.0.5: dependencies: available-typed-arrays: 1.0.7 call-bind: 1.0.9 for-each: 0.3.5 gopd: 1.2.0 - has-proto: 1.2.0 is-typed-array: 1.1.15 reflect.getprototypeof: 1.0.10 @@ -16812,9 +16584,9 @@ snapshots: unpipe@1.0.0: {} - update-browserslist-db@1.3.3(browserslist@4.28.9): + update-browserslist-db@1.3.3(browserslist@4.29.0): dependencies: - browserslist: 4.28.9 + browserslist: 4.29.0 escalade: 3.2.0 picocolors: 1.1.1 @@ -16919,7 +16691,7 @@ snapshots: core-util-is: 1.0.2 extsprintf: 1.3.0 - vite@8.3.0(@types/node@22.20.2)(esbuild@0.28.2)(jiti@2.7.0)(less@4.9.1(supports-color@11.0.0))(sass-embedded@1.104.0)(sass@1.104.0)(terser@5.51.2)(tsx@4.23.13)(yaml@2.9.1): + vite@8.3.0(@types/node@22.20.4)(esbuild@0.28.2)(jiti@2.7.0)(less@4.9.1(supports-color@11.0.0))(sass-embedded@1.104.1)(sass@1.104.1)(terser@5.51.2)(tsx@4.23.13)(yaml@2.9.1): dependencies: lightningcss: 1.33.0 picomatch: 4.0.7 @@ -16927,26 +16699,7 @@ snapshots: rolldown: 1.2.8 tinyglobby: 0.2.17 optionalDependencies: - '@types/node': 22.20.2 - esbuild: 0.28.2 - fsevents: 2.3.3 - jiti: 2.7.0 - less: 4.9.1(supports-color@11.0.0) - sass: 1.104.0 - sass-embedded: 1.104.0 - terser: 5.51.2 - tsx: 4.23.13 - yaml: 2.9.1 - - vite@8.3.0(@types/node@22.20.2)(esbuild@0.28.2)(jiti@2.7.0)(less@4.9.1(supports-color@11.0.0))(sass-embedded@1.104.1)(sass@1.104.1)(terser@5.51.2)(tsx@4.23.13)(yaml@2.9.1): - dependencies: - lightningcss: 1.33.0 - picomatch: 4.0.7 - postcss: 8.5.28 - rolldown: 1.2.8 - tinyglobby: 0.2.17 - optionalDependencies: - '@types/node': 22.20.2 + '@types/node': 22.20.4 esbuild: 0.28.2 fsevents: 2.3.3 jiti: 2.7.0 @@ -16957,51 +16710,27 @@ snapshots: tsx: 4.23.13 yaml: 2.9.1 - vitest@5.0.1(@opentelemetry/api@1.9.1)(@types/node@22.20.2)(@vitest/coverage-v8@5.0.1)(jsdom@30.0.1)(vite@8.3.0(@types/node@22.20.2)(esbuild@0.28.2)(jiti@2.7.0)(less@4.9.1(supports-color@11.0.0))(sass-embedded@1.104.0)(sass@1.104.0)(terser@5.51.2)(tsx@4.23.13)(yaml@2.9.1)): + vitest@5.0.1(@opentelemetry/api@1.9.1)(@types/node@22.20.4)(@vitest/coverage-v8@5.0.1)(jsdom@30.0.1(@noble/hashes@1.8.0))(vite@8.3.0(@types/node@22.20.4)(esbuild@0.28.2)(jiti@2.7.0)(less@4.9.1(supports-color@11.0.0))(sass-embedded@1.104.1)(sass@1.104.1)(terser@5.51.2)(tsx@4.23.13)(yaml@2.9.1)): dependencies: '@types/chai': 5.2.3 - '@vitest/mocker': 5.0.1(vite@8.3.0(@types/node@22.20.2)(esbuild@0.28.2)(jiti@2.7.0)(less@4.9.1(supports-color@11.0.0))(sass-embedded@1.104.0)(sass@1.104.0)(terser@5.51.2)(tsx@4.23.13)(yaml@2.9.1)) + '@vitest/mocker': 5.0.1(vite@8.3.0(@types/node@22.20.4)(esbuild@0.28.2)(jiti@2.7.0)(less@4.9.1(supports-color@11.0.0))(sass-embedded@1.104.1)(sass@1.104.1)(terser@5.51.2)(tsx@4.23.13)(yaml@2.9.1)) chai: 6.2.2 es-module-lexer: 2.3.2 expect-type: 1.4.0 - magic-string: 1.2.3 + magic-string: 1.4.1 obug: 2.2.1 picomatch: 4.0.7 std-env: 4.2.0 tinybench: 6.1.4 tinyexec: 1.3.0 tinyglobby: 0.2.17 - vite: 8.3.0(@types/node@22.20.2)(esbuild@0.28.2)(jiti@2.7.0)(less@4.9.1(supports-color@11.0.0))(sass-embedded@1.104.0)(sass@1.104.0)(terser@5.51.2)(tsx@4.23.13)(yaml@2.9.1) + vite: 8.3.0(@types/node@22.20.4)(esbuild@0.28.2)(jiti@2.7.0)(less@4.9.1(supports-color@11.0.0))(sass-embedded@1.104.1)(sass@1.104.1)(terser@5.51.2)(tsx@4.23.13)(yaml@2.9.1) why-is-node-running: 2.3.0 optionalDependencies: '@opentelemetry/api': 1.9.1 - '@types/node': 22.20.2 + '@types/node': 22.20.4 '@vitest/coverage-v8': 5.0.1(vitest@5.0.1) - jsdom: 30.0.1 - transitivePeerDependencies: - - msw - - vitest@5.0.1(@opentelemetry/api@1.9.1)(@types/node@22.20.2)(@vitest/coverage-v8@5.0.1)(jsdom@30.0.1)(vite@8.3.0(@types/node@22.20.2)(esbuild@0.28.2)(jiti@2.7.0)(less@4.9.1(supports-color@11.0.0))(sass-embedded@1.104.1)(sass@1.104.1)(terser@5.51.2)(tsx@4.23.13)(yaml@2.9.1)): - dependencies: - '@types/chai': 5.2.3 - '@vitest/mocker': 5.0.1(vite@8.3.0(@types/node@22.20.2)(esbuild@0.28.2)(jiti@2.7.0)(less@4.9.1(supports-color@11.0.0))(sass-embedded@1.104.1)(sass@1.104.1)(terser@5.51.2)(tsx@4.23.13)(yaml@2.9.1)) - chai: 6.2.2 - es-module-lexer: 2.3.2 - expect-type: 1.4.0 - magic-string: 1.2.3 - obug: 2.2.1 - picomatch: 4.0.7 - std-env: 4.2.0 - tinybench: 6.1.4 - tinyexec: 1.3.0 - tinyglobby: 0.2.17 - vite: 8.3.0(@types/node@22.20.2)(esbuild@0.28.2)(jiti@2.7.0)(less@4.9.1(supports-color@11.0.0))(sass-embedded@1.104.1)(sass@1.104.1)(terser@5.51.2)(tsx@4.23.13)(yaml@2.9.1) - why-is-node-running: 2.3.0 - optionalDependencies: - '@opentelemetry/api': 1.9.1 - '@types/node': 22.20.2 - '@vitest/coverage-v8': 5.0.1(vitest@5.0.1) - jsdom: 30.0.1 + jsdom: 30.0.1(@noble/hashes@1.8.0) transitivePeerDependencies: - msw @@ -17028,17 +16757,17 @@ snapshots: webidl-conversions@8.0.1: {} - webpack-dev-middleware@8.3.0(webpack@5.111.0(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.28)(uglify-js@3.19.3)): + webpack-dev-middleware@8.3.0(webpack@5.111.0(esbuild@0.28.2)(lightningcss@1.33.0)(uglify-js@3.19.3)): dependencies: ansi-html-community: 0.0.8 - memfs: 4.78.0 + memfs: 4.78.1 mime-types: 3.0.2 range-parser: 1.3.0 schema-utils: 4.5.0 optionalDependencies: webpack: 5.111.0(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.28)(uglify-js@3.19.3) - webpack-dev-server@6.0.0(bufferutil@4.1.0)(supports-color@11.0.0)(utf-8-validate@6.0.6)(webpack@5.111.0(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.28)(uglify-js@3.19.3)): + webpack-dev-server@6.0.0(bufferutil@4.1.0)(supports-color@11.0.0)(utf-8-validate@6.0.6)(webpack@5.111.0(esbuild@0.28.2)(lightningcss@1.33.0)(uglify-js@3.19.3)): dependencies: '@types/bonjour': 3.5.13 '@types/connect-history-api-fallback': 1.5.4 @@ -17063,7 +16792,7 @@ snapshots: selfsigned: 5.5.0 serve-index: 1.9.2(supports-color@11.0.0) tinyglobby: 0.2.17 - webpack-dev-middleware: 8.3.0(webpack@5.111.0(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.28)(uglify-js@3.19.3)) + webpack-dev-middleware: 8.3.0(webpack@5.111.0(esbuild@0.28.2)(lightningcss@1.33.0)(uglify-js@3.19.3)) ws: 8.21.3(bufferutil@4.1.0)(utf-8-validate@6.0.6) optionalDependencies: webpack: 5.111.0(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.28)(uglify-js@3.19.3) @@ -17085,45 +16814,6 @@ snapshots: typed-assert: 1.0.9 webpack: 5.111.0(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.28)(uglify-js@3.19.3) - webpack@5.110.3(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.28)(uglify-js@3.19.3): - dependencies: - '@types/estree': 1.0.9 - '@types/json-schema': 7.0.15 - '@webassemblyjs/ast': 1.14.1 - '@webassemblyjs/wasm-edit': 1.14.1 - '@webassemblyjs/wasm-parser': 1.14.1 - acorn: 8.18.0 - browserslist: 4.28.9 - chrome-trace-event: 1.0.4 - enhanced-resolve: 5.25.1 - es-module-lexer: 2.3.2 - events: 3.3.0 - graceful-fs: 4.2.11 - mime-db: 1.54.0 - minimizer-webpack-plugin: 5.10.1(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.28)(uglify-js@3.19.3)(webpack@5.110.3(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.28)(uglify-js@3.19.3)) - neo-async: 2.6.2 - schema-utils: 4.5.0 - tapable: 2.3.3 - watchpack: 2.5.2 - webpack-sources: 3.5.1 - transitivePeerDependencies: - - '@minify-html/node' - - '@napi-rs/image' - - '@swc/core' - - '@swc/css' - - '@swc/html' - - clean-css - - cssnano - - csso - - esbuild - - html-minifier-terser - - imagemin - - lightningcss - - postcss - - sharp - - svgo - - uglify-js - webpack@5.111.0(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.28)(uglify-js@3.19.3): dependencies: '@types/estree': 1.0.9 @@ -17131,14 +16821,14 @@ snapshots: '@webassemblyjs/ast': 1.14.1 '@webassemblyjs/wasm-edit': 1.14.1 '@webassemblyjs/wasm-parser': 1.14.1 - browserslist: 4.28.9 + browserslist: 4.29.0 chrome-trace-event: 1.0.4 enhanced-resolve: 5.25.1 es-module-lexer: 2.3.2 events: 3.3.0 graceful-fs: 4.2.11 mime-db: 1.54.0 - minimizer-webpack-plugin: 5.10.1(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.28)(uglify-js@3.19.3)(webpack@5.111.0(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.28)(uglify-js@3.19.3)) + minimizer-webpack-plugin: 5.11.0(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.28)(uglify-js@3.19.3)(webpack@5.111.0(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.28)(uglify-js@3.19.3)) schema-utils: 4.5.0 tapable: 2.3.3 watchpack: 2.5.2 @@ -17171,17 +16861,17 @@ snapshots: whatwg-mimetype@5.0.0: {} - whatwg-url@16.0.1: + whatwg-url@16.0.1(@noble/hashes@1.8.0): dependencies: - '@exodus/bytes': 1.15.1 + '@exodus/bytes': 1.15.1(@noble/hashes@1.8.0) tr46: 6.0.0 webidl-conversions: 8.0.1 transitivePeerDependencies: - '@noble/hashes' - whatwg-url@17.1.1: + whatwg-url@17.1.2(@noble/hashes@1.8.0): dependencies: - '@exodus/bytes': 1.15.1 + '@exodus/bytes': 1.15.1(@noble/hashes@1.8.0) tr46: 6.0.0 webidl-conversions: 8.0.1 transitivePeerDependencies: @@ -17214,7 +16904,7 @@ snapshots: isarray: 2.0.5 which-boxed-primitive: 1.1.1 which-collection: 1.0.2 - which-typed-array: 1.1.22 + which-typed-array: 1.1.24 which-collection@1.0.2: dependencies: @@ -17223,7 +16913,7 @@ snapshots: is-weakmap: 2.0.2 is-weakset: 2.0.4 - which-typed-array@1.1.22: + which-typed-array@1.1.24: dependencies: available-typed-arrays: 1.0.7 call-bind: 1.0.9 @@ -17256,7 +16946,7 @@ snapshots: wordwrap@1.0.0: {} - wrap-ansi@10.0.1: + wrap-ansi@10.0.2: dependencies: ansi-styles: 6.2.3 string-width: 8.2.2 @@ -17348,44 +17038,44 @@ snapshots: yoctocolors@2.2.0: {} - yuku-ast@0.9.5: + yuku-ast@0.10.2: dependencies: - '@yuku-toolchain/types': 0.9.5 + '@yuku-toolchain/types': 0.10.2 - yuku-codegen@0.9.5: + yuku-codegen@0.10.2: dependencies: - '@yuku-toolchain/types': 0.9.5 + '@yuku-toolchain/types': 0.10.2 optionalDependencies: - '@yuku-codegen/binding-android-arm64': 0.9.5 - '@yuku-codegen/binding-darwin-arm64': 0.9.5 - '@yuku-codegen/binding-darwin-x64': 0.9.5 - '@yuku-codegen/binding-freebsd-x64': 0.9.5 - '@yuku-codegen/binding-linux-arm-gnu': 0.9.5 - '@yuku-codegen/binding-linux-arm-musl': 0.9.5 - '@yuku-codegen/binding-linux-arm64-gnu': 0.9.5 - '@yuku-codegen/binding-linux-arm64-musl': 0.9.5 - '@yuku-codegen/binding-linux-x64-gnu': 0.9.5 - '@yuku-codegen/binding-linux-x64-musl': 0.9.5 - '@yuku-codegen/binding-win32-arm64': 0.9.5 - '@yuku-codegen/binding-win32-x64': 0.9.5 - - yuku-parser@0.9.5: - dependencies: - '@yuku-toolchain/types': 0.9.5 - yuku-ast: 0.9.5 + '@yuku-codegen/binding-android-arm64': 0.10.2 + '@yuku-codegen/binding-darwin-arm64': 0.10.2 + '@yuku-codegen/binding-darwin-x64': 0.10.2 + '@yuku-codegen/binding-freebsd-x64': 0.10.2 + '@yuku-codegen/binding-linux-arm-gnu': 0.10.2 + '@yuku-codegen/binding-linux-arm-musl': 0.10.2 + '@yuku-codegen/binding-linux-arm64-gnu': 0.10.2 + '@yuku-codegen/binding-linux-arm64-musl': 0.10.2 + '@yuku-codegen/binding-linux-x64-gnu': 0.10.2 + '@yuku-codegen/binding-linux-x64-musl': 0.10.2 + '@yuku-codegen/binding-win32-arm64': 0.10.2 + '@yuku-codegen/binding-win32-x64': 0.10.2 + + yuku-parser@0.10.2: + dependencies: + '@yuku-toolchain/types': 0.10.2 + yuku-ast: 0.10.2 optionalDependencies: - '@yuku-parser/binding-android-arm64': 0.9.5 - '@yuku-parser/binding-darwin-arm64': 0.9.5 - '@yuku-parser/binding-darwin-x64': 0.9.5 - '@yuku-parser/binding-freebsd-x64': 0.9.5 - '@yuku-parser/binding-linux-arm-gnu': 0.9.5 - '@yuku-parser/binding-linux-arm-musl': 0.9.5 - '@yuku-parser/binding-linux-arm64-gnu': 0.9.5 - '@yuku-parser/binding-linux-arm64-musl': 0.9.5 - '@yuku-parser/binding-linux-x64-gnu': 0.9.5 - '@yuku-parser/binding-linux-x64-musl': 0.9.5 - '@yuku-parser/binding-win32-arm64': 0.9.5 - '@yuku-parser/binding-win32-x64': 0.9.5 + '@yuku-parser/binding-android-arm64': 0.10.2 + '@yuku-parser/binding-darwin-arm64': 0.10.2 + '@yuku-parser/binding-darwin-x64': 0.10.2 + '@yuku-parser/binding-freebsd-x64': 0.10.2 + '@yuku-parser/binding-linux-arm-gnu': 0.10.2 + '@yuku-parser/binding-linux-arm-musl': 0.10.2 + '@yuku-parser/binding-linux-arm64-gnu': 0.10.2 + '@yuku-parser/binding-linux-arm64-musl': 0.10.2 + '@yuku-parser/binding-linux-x64-gnu': 0.10.2 + '@yuku-parser/binding-linux-x64-musl': 0.10.2 + '@yuku-parser/binding-win32-arm64': 0.10.2 + '@yuku-parser/binding-win32-x64': 0.10.2 zod@3.25.76: {} From 19e1eb71959e40c3b978c698d6d7a0184d3ba0bc Mon Sep 17 00:00:00 2001 From: Doug Parker Date: Wed, 23 Sep 2026 14:05:35 -0700 Subject: [PATCH 504/787] docs: release notes for the v22.1.9 release --- CHANGELOG.md | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index a67b3ed682d2..208c002bef15 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,27 @@ + + +# 22.1.9 (2026-09-23) + +### @schematics/angular + +| Commit | Type | Description | +| --------------------------------------------------------------------------------------------------- | ---- | ------------------------------------------------ | +| [b94dabdb7](https://github.com/angular/angular-cli/commit/b94dabdb744ff1fe72b79bfbda5f5c8749c58f71) | fix | update @types/node to a version vitest 5 accepts | + +### @angular-devkit/core + +| Commit | Type | Description | +| --------------------------------------------------------------------------------------------------- | ---- | ---------------------------------------------------- | +| [5aaad0a13](https://github.com/angular/angular-cli/commit/5aaad0a13a3dc65b07347dde313ac9ae2aa013ac) | fix | name the unknown option in a schema validation error | + +### @angular/build + +| Commit | Type | Description | +| --------------------------------------------------------------------------------------------------- | ---- | ------------------------------------------------------------------------- | +| [bfec8bac4](https://github.com/angular/angular-cli/commit/bfec8bac4d6185efa768b4387ed9e8926979954f) | fix | support standard JavaScript MIME types and case insensitivity in auto-CSP | + + + # 22.2.0-rc.0 (2026-09-16) From 4a080b671b4e2313cdd2a14b70132e12008a5995 Mon Sep 17 00:00:00 2001 From: Doug Parker Date: Wed, 23 Sep 2026 14:36:03 -0700 Subject: [PATCH 505/787] docs: release notes for the v22.2.0 release --- CHANGELOG.md | 331 +++++++++++---------------------------------------- 1 file changed, 70 insertions(+), 261 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 208c002bef15..fb8ea2b1ceeb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,85 +1,96 @@ - - -# 22.1.9 (2026-09-23) + -### @schematics/angular +# 22.2.0 (2026-09-23) -| Commit | Type | Description | -| --------------------------------------------------------------------------------------------------- | ---- | ------------------------------------------------ | -| [b94dabdb7](https://github.com/angular/angular-cli/commit/b94dabdb744ff1fe72b79bfbda5f5c8749c58f71) | fix | update @types/node to a version vitest 5 accepts | - -### @angular-devkit/core - -| Commit | Type | Description | -| --------------------------------------------------------------------------------------------------- | ---- | ---------------------------------------------------- | -| [5aaad0a13](https://github.com/angular/angular-cli/commit/5aaad0a13a3dc65b07347dde313ac9ae2aa013ac) | fix | name the unknown option in a schema validation error | +## Deprecations ### @angular/build -| Commit | Type | Description | -| --------------------------------------------------------------------------------------------------- | ---- | ------------------------------------------------------------------------- | -| [bfec8bac4](https://github.com/angular/angular-cli/commit/bfec8bac4d6185efa768b4387ed9e8926979954f) | fix | support standard JavaScript MIME types and case insensitivity in auto-CSP | - - - - +- The `splitting` option in the unit-test builder is deprecated as it is no longer needed with Vitest 5. -# 22.2.0-rc.0 (2026-09-16) + Disabling code splitting is no longer necessary with Vitest 5, as the issue where shared-module exports were uninitialized in class-field initializers under JSDOM has been resolved. ### @angular/cli -| Commit | Type | Description | -| ---------------------------------------------------------------------------------------------------- | ---- | ----------------------------------------------------------------- | -| [6e7f809a7d](https://github.com/angular/angular-cli/commit/6e7f809a7d66e4b8d260a1c00297812412a926f1) | perf | skip eager yargs help message formatting during command execution | +| Commit | Type | Description | +| --------------------------------------------------------------------------------------------------- | ---- | ----------------------------------------------------------------- | +| [41555dfb3](https://github.com/angular/angular-cli/commit/41555dfb3b71d08cdfe2853bf2cbeca5b6942f67) | feat | add `--root` command line option to `mcp` command | +| [6e7f809a7](https://github.com/angular/angular-cli/commit/6e7f809a7d66e4b8d260a1c00297812412a926f1) | perf | skip eager yargs help message formatting during command execution | ### @angular/build -| Commit | Type | Description | -| ---------------------------------------------------------------------------------------------------- | ---- | -------------------------------------------------------------------------- | -| [978351af71](https://github.com/angular/angular-cli/commit/978351af71889d4786a18fec9e193eb5b16af7dd) | fix | include inline component stylesheets in referenced watch files | -| [72dc9677cf](https://github.com/angular/angular-cli/commit/72dc9677cf743243d6cb22d2b81782022f71356e) | fix | pass load cache to compiler plugin and escape extension regex in polyfills | -| [31c045639e](https://github.com/angular/angular-cli/commit/31c045639e8bfd114cbd552d83cc70a968fe7f81) | fix | prevent stale bundler caching and correctly resolve load cache | -| [d97c8857c1](https://github.com/angular/angular-cli/commit/d97c8857c18da02fcc6c69a0ea652cc706c5c9b6) | perf | key Sass package resolutions without containing URL qualification | +| Commit | Type | Description | +| --------------------------------------------------------------------------------------------------- | -------- | -------------------------------------------------------------------------------- | +| [ad8271320](https://github.com/angular/angular-cli/commit/ad8271320f67c2b1502e446f1e3cb0a05444d04f) | feat | migrate Angular Linker to oxc-parser and magic-string | +| [175273931](https://github.com/angular/angular-cli/commit/175273931ebb0cf08bf62dd1694dbde5ff5229b6) | feat | Support splitting browser and server stats jsonfiles for easier consumption | +| [fe2f180fd](https://github.com/angular/angular-cli/commit/fe2f180fd0c2fa02706353ca6a034d235feb6c59) | fix | add automatic corruption recovery in SQLite cache store | +| [675f1f527](https://github.com/angular/angular-cli/commit/675f1f5274ff853f153832f7adc69273fa63f0cd) | fix | avoid pure comment pattern in oxc transform | +| [d396324b4](https://github.com/angular/angular-cli/commit/d396324b4eb3b16640526a64365d953642bc7ca1) | fix | default preloadInitial to false when serviceWorker is enabled | +| [7e5510e46](https://github.com/angular/angular-cli/commit/7e5510e464eb423d8757ae6f058f73fc17249d81) | fix | disable linker internal source mapping in OXC linker | +| [8504cfffc](https://github.com/angular/angular-cli/commit/8504cfffcfb943fcd8fda62507e4b236e4bf429a) | fix | disable root config extension for inline test project | +| [ee3041325](https://github.com/angular/angular-cli/commit/ee3041325cd2400c26e239e64e14a0e314ab6031) | fix | ensure chokidar watcher is ready before returning | +| [54d712f57](https://github.com/angular/angular-cli/commit/54d712f57904d2f612eec27a0507ea298b40915e) | fix | ensure parent directory exists in SQLite cache store | +| [80acd6236](https://github.com/angular/angular-cli/commit/80acd6236eac6b1b07543583717e94cbd1de1180) | fix | execute setup file hooks for each spec file when coverage is enabled | +| [978351af7](https://github.com/angular/angular-cli/commit/978351af71889d4786a18fec9e193eb5b16af7dd) | fix | include inline component stylesheets in referenced watch files | +| [f47f77f5f](https://github.com/angular/angular-cli/commit/f47f77f5f6db5cda1493652f813c98c26f172ea9) | fix | only compile included test files in unit-test builder | +| [72dc9677c](https://github.com/angular/angular-cli/commit/72dc9677cf743243d6cb22d2b81782022f71356e) | fix | pass load cache to compiler plugin and escape extension regex in polyfills | +| [701bde481](https://github.com/angular/angular-cli/commit/701bde4818439de0e49c99d57dc749b0dd22c4dd) | fix | preserve duplicate bundle filenames across output file types | +| [e4111ae81](https://github.com/angular/angular-cli/commit/e4111ae8180f3cd5800f248c23010844aa1730ad) | fix | prevent memory leaks in parallel compilation and caches | +| [31c045639](https://github.com/angular/angular-cli/commit/31c045639e8bfd114cbd552d83cc70a968fe7f81) | fix | prevent stale bundler caching and correctly resolve load cache | +| [bad31421c](https://github.com/angular/angular-cli/commit/bad31421cbf23339d4fbd389a91d198df405697d) | fix | prevent syntax corruption in linker and oxc transform | +| [0d9851600](https://github.com/angular/angular-cli/commit/0d9851600ca618ccabfc3143a9c552a5448d6eec) | fix | recursively ignore output and cache paths in watch mode | +| [040bc21ec](https://github.com/angular/angular-cli/commit/040bc21ec3d4fa1bdfa8513206f463d89e20d9a1) | fix | scope Sass package resolution caching for stylesheets in node_modules | +| [1fc273279](https://github.com/angular/angular-cli/commit/1fc2732795069ad521645b06a94e5df3a55c3d9c) | fix | support parenthesized expressions in oxc linker | +| [b423bc39c](https://github.com/angular/angular-cli/commit/b423bc39cd59c73ae79402c6cccdc0ecf1d7aaa1) | fix | use chokidar watcher when followSymlinks is enabled | +| [87551ad5c](https://github.com/angular/angular-cli/commit/87551ad5c53f90cbdc68fdb5e47007b9436c7f75) | perf | avoid encoding intermediate source maps before remapping | +| [6ee559ca9](https://github.com/angular/angular-cli/commit/6ee559ca9d209fb4c53de2aaf9918d10e5f062a1) | perf | bypass worker dispatch for files without transform candidates | +| [0589edd9c](https://github.com/angular/angular-cli/commit/0589edd9cdc493ecf34a160cc7b8491618b59f72) | perf | consolidate component stylesheet bundling with shared load result cache | +| [482f6d8aa](https://github.com/angular/angular-cli/commit/482f6d8aab289fbd6dc5f9aecdcf7b8e1b6cac4f) | perf | decouple diagnostic type checking from build start | +| [a877aa7eb](https://github.com/angular/angular-cli/commit/a877aa7ebdbf919d6bc17e6ec0920ca702db0db4) | perf | implement SharedArrayBuffer translation dictionaries for zero-copy worker access | +| [f1cc95943](https://github.com/angular/angular-cli/commit/f1cc959439d8ca11a45d693520c34dd94e0b6548) | perf | implement sliding-window batching and worker translation eviction | +| [d97c8857c](https://github.com/angular/angular-cli/commit/d97c8857c18da02fcc6c69a0ea652cc706c5c9b6) | perf | key Sass package resolutions without containing URL qualification | +| [5cd20e141](https://github.com/angular/angular-cli/commit/5cd20e141ad176c87e4002da2d4ee3755f97cd3e) | perf | only reset Sass worker pool caches when stylesheet files change | +| [1c00edce0](https://github.com/angular/angular-cli/commit/1c00edce02bdd0201546417d71518f78bfb89d34) | perf | optimize sourcemap stripping and loading with buffer fast path | +| [0ba4d8e29](https://github.com/angular/angular-cli/commit/0ba4d8e29c0fb9abe6b07432edfab9e39066ca29) | perf | reduce watcher debounce latency for faster incremental rebuilds | +| [a6ef9cfbe](https://github.com/angular/angular-cli/commit/a6ef9cfbeace725d58c0f7f65640ef6de9b39c33) | perf | replace watchpack with @parcel/watcher and chokidar | +| [4d11a1334](https://github.com/angular/angular-cli/commit/4d11a1334ff5fabfe5338cc3de5ce4f45f6afa5f) | perf | selectively compress large entries in SQLite cache store | +| [0a137f98d](https://github.com/angular/angular-cli/commit/0a137f98d035f3dbd9a5daf1b6999246f73610c8) | perf | share sass directory and resolution caches across stylesheets | +| [f4dad31cc](https://github.com/angular/angular-cli/commit/f4dad31cce41bc3e8ed8767256d9e50a712c3a72) | perf | unify Oxc linking and optimization AST traversal passes | +| [2b85529e8](https://github.com/angular/angular-cli/commit/2b85529e8290c8c916539b5a0336b4efdb68578c) | perf | use iterative post-order AST traversal for OXC transforms | +| [ecbcd87b8](https://github.com/angular/angular-cli/commit/ecbcd87b8857225e4df3df7896b3236d63553f23) | perf | use native sass-embedded compiler daemon | +| [ce83ac0e8](https://github.com/angular/angular-cli/commit/ce83ac0e82981efd9408e07a35315e3cef9e1a36) | perf | use size-weighted task heuristics in i18n inliner | +| [d11a663e7](https://github.com/angular/angular-cli/commit/d11a663e77dad3dc9dbb6336e782f23b8a6f595c) | perf | verify cache metadata before reading file and eliminate sqlite read-locks | +| [66bd6bd1e](https://github.com/angular/angular-cli/commit/66bd6bd1eab41484ed5db38f5545e80de4090b34) | refactor | deprecate splitting option in unit-test builder | - +### @angular/ssr - +| Commit | Type | Description | +| --------------------------------------------------------------------------------------------------- | ---- | -------------------------------------------- | +| [23e3d44a7](https://github.com/angular/angular-cli/commit/23e3d44a7f051cd3bb67700b8d8407f73b7aa7f3) | perf | pre-compile critical CSS plans at build time | -# 22.2.0-next.7 (2026-09-10) + -## Deprecations + -### @angular/build +# 22.1.9 (2026-09-23) -- The `splitting` option in the unit-test builder is deprecated as it is no longer needed with Vitest 5. +### @schematics/angular - Disabling code splitting is no longer necessary with Vitest 5, as the issue where shared-module exports were uninitialized in class-field initializers under JSDOM has been resolved. +| Commit | Type | Description | +| --------------------------------------------------------------------------------------------------- | ---- | ------------------------------------------------ | +| [b94dabdb7](https://github.com/angular/angular-cli/commit/b94dabdb744ff1fe72b79bfbda5f5c8749c58f71) | fix | update @types/node to a version vitest 5 accepts | -### @angular/build +### @angular-devkit/core -| Commit | Type | Description | -| ---------------------------------------------------------------------------------------------------- | -------- | ---------------------------------------------------------------------------------------------------------------------------- | -| [fe2f180fd0](https://github.com/angular/angular-cli/commit/fe2f180fd0c2fa02706353ca6a034d235feb6c59) | fix | add automatic corruption recovery in SQLite cache store | -| [675f1f5274](https://github.com/angular/angular-cli/commit/675f1f5274ff853f153832f7adc69273fa63f0cd) | fix | avoid pure comment pattern in oxc transform | -| [d396324b4e](https://github.com/angular/angular-cli/commit/d396324b4eb3b16640526a64365d953642bc7ca1) | fix | default preloadInitial to false when serviceWorker is enabled | -| [8504cfffcf](https://github.com/angular/angular-cli/commit/8504cfffcfb943fcd8fda62507e4b236e4bf429a) | fix | disable root config extension for inline test project | -| [5d21812aae](https://github.com/angular/angular-cli/commit/5d21812aaedc57cbd9378a99d9747f80c413cdc3) | fix | disable strictPort when port 0 is used in dev-server | -| [54d712f579](https://github.com/angular/angular-cli/commit/54d712f57904d2f612eec27a0507ea298b40915e) | fix | ensure parent directory exists in SQLite cache store | -| [b423bc39cd](https://github.com/angular/angular-cli/commit/b423bc39cd59c73ae79402c6cccdc0ecf1d7aaa1) | fix | use chokidar watcher when followSymlinks is enabled | -| [5a0d226b7c](https://github.com/angular/angular-cli/commit/5a0d226b7ccb945edd234fa0c839994f4876e2ee) | perf | avoid full JSON parsing when updating sourcemap ignore list | -| [482f6d8aab](https://github.com/angular/angular-cli/commit/482f6d8aab289fbd6dc5f9aecdcf7b8e1b6cac4f) | perf | decouple diagnostic type checking from build start | -| [f1afa603b4](https://github.com/angular/angular-cli/commit/f1afa603b48566e45dfb8d95930375a71f0bfa0b) | perf | read rendered module length once per module in chunk optimizer ([#34045](https://github.com/angular/angular-cli/pull/34045)) | -| [0ba4d8e29c](https://github.com/angular/angular-cli/commit/0ba4d8e29c0fb9abe6b07432edfab9e39066ca29) | perf | reduce watcher debounce latency for faster incremental rebuilds | -| [4d11a1334f](https://github.com/angular/angular-cli/commit/4d11a1334ff5fabfe5338cc3de5ce4f45f6afa5f) | perf | selectively compress large entries in SQLite cache store | -| [0a137f98d0](https://github.com/angular/angular-cli/commit/0a137f98d035f3dbd9a5daf1b6999246f73610c8) | perf | share sass directory and resolution caches across stylesheets | -| [d11a663e77](https://github.com/angular/angular-cli/commit/d11a663e77dad3dc9dbb6336e782f23b8a6f595c) | perf | verify cache metadata before reading file and eliminate sqlite read-locks | -| [66bd6bd1ea](https://github.com/angular/angular-cli/commit/66bd6bd1eab41484ed5db38f5545e80de4090b34) | refactor | deprecate splitting option in unit-test builder | +| Commit | Type | Description | +| --------------------------------------------------------------------------------------------------- | ---- | ---------------------------------------------------- | +| [5aaad0a13](https://github.com/angular/angular-cli/commit/5aaad0a13a3dc65b07347dde313ac9ae2aa013ac) | fix | name the unknown option in a schema validation error | -### @angular/ssr +### @angular/build -| Commit | Type | Description | -| ---------------------------------------------------------------------------------------------------- | ---- | -------------------------------------------- | -| [23e3d44a7f](https://github.com/angular/angular-cli/commit/23e3d44a7f051cd3bb67700b8d8407f73b7aa7f3) | perf | pre-compile critical CSS plans at build time | +| Commit | Type | Description | +| --------------------------------------------------------------------------------------------------- | ---- | ------------------------------------------------------------------------- | +| [bfec8bac4](https://github.com/angular/angular-cli/commit/bfec8bac4d6185efa768b4387ed9e8926979954f) | fix | support standard JavaScript MIME types and case insensitivity in auto-CSP | @@ -121,40 +132,6 @@ - - -# 22.2.0-next.6 (2026-09-02) - -### @angular/cli - -| Commit | Type | Description | -| --------------------------------------------------------------------------------------------------- | ---- | ------------------------------------------------------------------ | -| [b37c93329](https://github.com/angular/angular-cli/commit/b37c933299dac37e394d9f4fe0d019052db427a9) | fix | isolate temporary package installations from parent Yarn workspace | - -### @angular/build - -| Commit | Type | Description | -| --------------------------------------------------------------------------------------------------- | ---- | ------------------------------------------------------------- | -| [4b8c62a8f](https://github.com/angular/angular-cli/commit/4b8c62a8f1a1d312ef2e1e0df6b7642bf1db5c5f) | fix | add splitting option to unit-test builder | -| [51565d4bc](https://github.com/angular/angular-cli/commit/51565d4bcbd4667c23c607d878f08301afc4c5e3) | fix | enable code splitting for vitest browser tests | -| [5b850fdfc](https://github.com/angular/angular-cli/commit/5b850fdfc7534d33db7ab4a7f1e32e143462eec7) | fix | fail build and exclude routes when prerendering fails | -| [dfa7f03a9](https://github.com/angular/angular-cli/commit/dfa7f03a93b5b24b949aea354bc40f0a91e9582d) | fix | keep dev-server Vite cache worktree-local | -| [135662d9a](https://github.com/angular/angular-cli/commit/135662d9a1de85b42292b26b547160eaca71e5da) | fix | preserve binary values in the SQLite cache store | -| [701bde481](https://github.com/angular/angular-cli/commit/701bde4818439de0e49c99d57dc749b0dd22c4dd) | fix | preserve duplicate bundle filenames across output file types | -| [6ee559ca9](https://github.com/angular/angular-cli/commit/6ee559ca9d209fb4c53de2aaf9918d10e5f062a1) | perf | bypass worker dispatch for files without transform candidates | -| [2b85529e8](https://github.com/angular/angular-cli/commit/2b85529e8290c8c916539b5a0336b4efdb68578c) | perf | use iterative post-order AST traversal for OXC transforms | -| [ecbcd87b8](https://github.com/angular/angular-cli/commit/ecbcd87b8857225e4df3df7896b3236d63553f23) | perf | use native sass-embedded compiler daemon | -| [ce83ac0e8](https://github.com/angular/angular-cli/commit/ce83ac0e82981efd9408e07a35315e3cef9e1a36) | perf | use size-weighted task heuristics in i18n inliner | - -### @angular/ssr - -| Commit | Type | Description | -| --------------------------------------------------------------------------------------------------- | ---- | --------------------------------------------------- | -| [4fa81d403](https://github.com/angular/angular-cli/commit/4fa81d403c93a7480301e58630203cb028aebc69) | fix | decode pathname when constructing server asset path | -| [bb72145f9](https://github.com/angular/angular-cli/commit/bb72145f9ab45aee29f523236b3a25cd0813a841) | fix | ensure public directory containment in CommonEngine | - - - # 22.1.7 (2026-09-02) @@ -220,30 +197,6 @@ - - -# 22.2.0-next.5 (2026-08-26) - -### @angular/build - -| Commit | Type | Description | -| ---------------------------------------------------------------------------------------------------- | ---- | -------------------------------------------------------------------------------- | -| [4d0be683b7](https://github.com/angular/angular-cli/commit/4d0be683b780a9a1629dc8f9cddad49153bddabf) | fix | ignore side-effect annotations in unit test builds | -| [e4111ae818](https://github.com/angular/angular-cli/commit/e4111ae8180f3cd5800f248c23010844aa1730ad) | fix | prevent memory leaks in parallel compilation and caches | -| [62999cabf4](https://github.com/angular/angular-cli/commit/62999cabf4d65cf1060598150a77494e147fcc2a) | perf | batch prerender routes and share in-memory server bundles | -| [0589edd9cd](https://github.com/angular/angular-cli/commit/0589edd9cdc493ecf34a160cc7b8491618b59f72) | perf | consolidate component stylesheet bundling with shared load result cache | -| [a877aa7ebd](https://github.com/angular/angular-cli/commit/a877aa7ebdbf919d6bc17e6ec0920ca702db0db4) | perf | implement SharedArrayBuffer translation dictionaries for zero-copy worker access | -| [f1cc959439](https://github.com/angular/angular-cli/commit/f1cc959439d8ca11a45d693520c34dd94e0b6548) | perf | implement sliding-window batching and worker translation eviction | -| [f4dad31cce](https://github.com/angular/angular-cli/commit/f4dad31cce41bc3e8ed8767256d9e50a712c3a72) | perf | unify Oxc linking and optimization AST traversal passes | - -### @angular/ssr - -| Commit | Type | Description | -| ---------------------------------------------------------------------------------------------------- | ---- | ----------------------------------------------------- | -| [f8576e3c8b](https://github.com/angular/angular-cli/commit/f8576e3c8bfe3490b1b0b85832b489593a4e43ac) | fix | abort web request signal when node request is aborted | - - - # 22.1.6 (2026-08-26) @@ -287,36 +240,6 @@ - - -# 22.2.0-next.4 (2026-08-19) - -### @angular/cli - -| Commit | Type | Description | -| --------------------------------------------------------------------------------------------------- | ---- | ---------------------------------------------------------------- | -| [34e1e0bb5](https://github.com/angular/angular-cli/commit/34e1e0bb5d5ccf374f51a1b241158f6f2ea0dd42) | fix | enforce MCP roots in get_best_practices tool | -| [2b060630c](https://github.com/angular/angular-cli/commit/2b060630c66ce688b7ecbe51d282955869e5d4b0) | fix | handle errors from isAllowedWorkspacePath in best-practices tool | -| [24fd8fce2](https://github.com/angular/angular-cli/commit/24fd8fce2a3ff035acdc5f3e036eb4ba21f71a76) | fix | throw on out-of-roots workspace in best-practices tool | - -### @schematics/angular - -| Commit | Type | Description | -| --------------------------------------------------------------------------------------------------- | ---- | ------------------------------------------------------------ | -| [ce1b60f89](https://github.com/angular/angular-cli/commit/ce1b60f89699c3a76496a0489e5f2b9e4fe62429) | fix | transform fail() to expect.fail() in refactor-jasmine-vitest | - -### @angular/build - -| Commit | Type | Description | -| --------------------------------------------------------------------------------------------------- | ---- | --------------------------------------------------------------------------- | -| [175273931](https://github.com/angular/angular-cli/commit/175273931ebb0cf08bf62dd1694dbde5ff5229b6) | feat | Support splitting browser and server stats jsonfiles for easier consumption | -| [1ee0beca7](https://github.com/angular/angular-cli/commit/1ee0beca7b243cc4c06eb42b25d216d7b256b097) | fix | correct misleading error message for top-level await | -| [0ffe2d27f](https://github.com/angular/angular-cli/commit/0ffe2d27f256a5755809fa4788e4adb97c65b806) | fix | disable code splitting for unit test builds | -| [50994d76e](https://github.com/angular/angular-cli/commit/50994d76e59a4b632f1782c51cd60f80c9cd50fb) | fix | preserve integrity and crossorigin in autoCsp loader | -| [d6fd24320](https://github.com/angular/angular-cli/commit/d6fd243207ad1c3e242b8592698afa986320cc6c) | perf | traverse AST with iterative post-order walker in i18n inliner | - - - # 22.1.5 (2026-08-19) @@ -346,54 +269,6 @@ - - -# 22.2.0-next.3 (2026-08-13) - -### @angular/cli - -| Commit | Type | Description | -| --------------------------------------------------------------------------------------------------- | ---- | ------------------------------------------------------------------------------------------------------------------------------------- | -| [7106676e6](https://github.com/angular/angular-cli/commit/7106676e64ee234641b1b3cbd88fc058703d4d3e) | fix | disable searching current directory for bare executable names on Windows | -| [ecf8c0822](https://github.com/angular/angular-cli/commit/ecf8c0822e5d56b44a0be4be8fccb41373135d3e) | fix | serialize configuration as a single argv token in run_target strategies ([#33657](https://github.com/angular/angular-cli/pull/33657)) | -| [2e4dd90c3](https://github.com/angular/angular-cli/commit/2e4dd90c3ae898bf36af42f699c7b7d560bfc66a) | perf | avoid eager module loading during global bootstrap | - -### @schematics/angular - -| Commit | Type | Description | -| --------------------------------------------------------------------------------------------------- | ---- | ------------------------------------------------------- | -| [1161e6c99](https://github.com/angular/angular-cli/commit/1161e6c99992c884e2e0ce9fc295b0e60b2ae1df) | fix | generate CLAUDE.md for Claude Code instead of AGENTS.md | -| [c536ae364](https://github.com/angular/angular-cli/commit/c536ae364975dd0088fd8717464c723a4dcb74e3) | fix | import UrlSegment instead of subPath in guard generator | - -### @angular/build - -| Commit | Type | Description | -| --------------------------------------------------------------------------------------------------- | ---- | ----------------------------------------------------------------- | -| [04b532772](https://github.com/angular/angular-cli/commit/04b532772f6347d341b182135dee1758616a69d6) | fix | count statically imported chunks in the initial total | -| [2274babb6](https://github.com/angular/angular-cli/commit/2274babb662b8da2189f1ae9faaa528838052c32) | fix | normalize setupFiles paths to POSIX for vitest runner | -| [199a864df](https://github.com/angular/angular-cli/commit/199a864df97fc8c20b8d4e1fc8b891c61140671a) | fix | prevent syntax corruption for Crockford-style enum IIFE | -| [0d9851600](https://github.com/angular/angular-cli/commit/0d9851600ca618ccabfc3143a9c552a5448d6eec) | fix | recursively ignore output and cache paths in watch mode | -| [3eba6f726](https://github.com/angular/angular-cli/commit/3eba6f7269f3b0f8556510d0b668e978ea686c88) | fix | return direct file contents for non-Angular TypeScript files | -| [3c7ac1518](https://github.com/angular/angular-cli/commit/3c7ac1518b062f14409b4d3c6c3e65c956424ad9) | fix | return only lowest version per target engine | -| [3e9fed9a6](https://github.com/angular/angular-cli/commit/3e9fed9a6a1d24f30812ca29ca621d9d9a14496f) | fix | set target for Rolldown dependency prebundling in Vite dev server | -| [87551ad5c](https://github.com/angular/angular-cli/commit/87551ad5c53f90cbdc68fdb5e47007b9436c7f75) | perf | avoid encoding intermediate source maps before remapping | -| [194be2088](https://github.com/angular/angular-cli/commit/194be2088587918ed7b47ed606ea587a7116608a) | perf | avoid encoding the inline source map before remapping | -| [a55a6b78e](https://github.com/angular/angular-cli/commit/a55a6b78e89debb9c93c83375c54f6716bc26c65) | perf | batch last_accessed updates in sqlite cache store | -| [33b305416](https://github.com/angular/angular-cli/commit/33b3054169929dc98f93a758a90da5d26cf522f7) | perf | hash the i18n inline cache key options once per locale | -| [1c00edce0](https://github.com/angular/angular-cli/commit/1c00edce02bdd0201546417d71518f78bfb89d34) | perf | optimize sourcemap stripping and loading with buffer fast path | -| [b6269a816](https://github.com/angular/angular-cli/commit/b6269a8169046a78281808dcf92054140912a77d) | perf | optimize template string size calculation in server manifest | -| [a6ef9cfbe](https://github.com/angular/angular-cli/commit/a6ef9cfbeace725d58c0f7f65640ef6de9b39c33) | perf | replace watchpack with @parcel/watcher and chokidar | -| [596847f89](https://github.com/angular/angular-cli/commit/596847f89913684a84465d004aa3d6c7e1a40b06) | perf | share i18n translations with the inliner workers by reference | -| [19c91e48d](https://github.com/angular/angular-cli/commit/19c91e48d4b8a95a76dfe4bffd105130b416843d) | perf | use Map for chunk asset size lookups in budget calculator | - -### @angular/ssr - -| Commit | Type | Description | -| --------------------------------------------------------------------------------------------------- | ---- | -------------------------------------------------- | -| [6a3446770](https://github.com/angular/angular-cli/commit/6a3446770a8fbfecc7265eb2a6d764e2f1614b3a) | fix | destroy platform when response stream is cancelled | - - - # 22.1.4 (2026-08-13) @@ -475,54 +350,6 @@ - - -# 22.2.0-next.2 (2026-08-05) - -### @angular/build - -| Commit | Type | Description | -| ---------------------------------------------------------------------------------------------------- | ---- | ----------------------------------------------------- | -| [7e5510e464](https://github.com/angular/angular-cli/commit/7e5510e464eb423d8757ae6f058f73fc17249d81) | fix | disable linker internal source mapping in OXC linker | -| [bad31421cb](https://github.com/angular/angular-cli/commit/bad31421cbf23339d4fbd389a91d198df405697d) | fix | prevent syntax corruption in linker and oxc transform | - - - - - -# 22.2.0-next.1 (2026-08-05) - -### @angular/cli - -| Commit | Type | Description | -| ---------------------------------------------------------------------------------------------------- | ---- | --------------------------------------------------------------------------------------------------------------------------------------------- | -| [41555dfb3b](https://github.com/angular/angular-cli/commit/41555dfb3b71d08cdfe2853bf2cbeca5b6942f67) | feat | add `--root` command line option to `mcp` command | -| [035b9d5c9b](https://github.com/angular/angular-cli/commit/035b9d5c9bca624b98e14480f599481f294b49f3) | fix | add packages with built-in schematics to devDependencies only | -| [0ae5690c35](https://github.com/angular/angular-cli/commit/0ae5690c35b9af00f60d4851f1bab4ba5ec8eb19) | fix | always install package during ng add to inspect manifest on disk for schematics ([#33718](https://github.com/angular/angular-cli/pull/33718)) | -| [44ff584b33](https://github.com/angular/angular-cli/commit/44ff584b33830aa839c08feb205f014e4e7b5dca) | fix | correctly report available package updates during bare ng update | -| [1d4f9ebbe9](https://github.com/angular/angular-cli/commit/1d4f9ebbe993a5eb8b23929a3fc55b506597e5aa) | fix | discover migrations from installed packages when omitted by registry metadata ([#33718](https://github.com/angular/angular-cli/pull/33718)) | -| [25034f97ad](https://github.com/angular/angular-cli/commit/25034f97ad1b9a12f4080f646a0e2705425f9726) | fix | normalize Windows drive-letter casing for process.cwd | - -### @angular/build - -| Commit | Type | Description | -| ---------------------------------------------------------------------------------------------------- | ---- | ------------------------------------------------------------------------------------------------------------- | -| [ad8271320f](https://github.com/angular/angular-cli/commit/ad8271320f67c2b1502e446f1e3cb0a05444d04f) | feat | migrate Angular Linker to oxc-parser and magic-string | -| [4fb12292c2](https://github.com/angular/angular-cli/commit/4fb12292c21498c59836f7c80e4f824bb7751cac) | fix | prevent build process hang on unhandled error ([#33715](https://github.com/angular/angular-cli/pull/33715)) | -| [abd8ec9f3e](https://github.com/angular/angular-cli/commit/abd8ec9f3e11f1410fcb87d0d9d60f56016912fe) | fix | prevent IIFE wrapper interleaving for adjacent classes in minified files | -| [bcadbbef20](https://github.com/angular/angular-cli/commit/bcadbbef2054e897b9d22c1456883fc68f0383c0) | fix | retain watch files on error in load result cache | -| [e1c7193dce](https://github.com/angular/angular-cli/commit/e1c7193dcee1c7f2feb07fdf24a6e0656f29cfaf) | fix | support case-insensitive and alternative license file names | -| [f4a0f846e7](https://github.com/angular/angular-cli/commit/f4a0f846e7d14b5ff58c91d04461ef4a027c56b8) | perf | release build resources early in non-watch mode ([#33715](https://github.com/angular/angular-cli/pull/33715)) | - -### @angular/ssr - -| Commit | Type | Description | -| ---------------------------------------------------------------------------------------------------- | ---- | ---------------------------------------------------------- | -| [b74eef889f](https://github.com/angular/angular-cli/commit/b74eef889f9c8812dcbe116400663fa3d68d6b4f) | fix | settle writeResponseToNodeResponse when client disconnects | -| [33169801c6](https://github.com/angular/angular-cli/commit/33169801c6ed7fc7c7dca2c04008e5d405374983) | perf | avoid buffering request body when sanitizing headers | - - - # 22.1.3 (2026-08-05) @@ -626,24 +453,6 @@ - - -# 22.2.0-next.0 (2026-07-30) - -### @angular/cli - -| Commit | Type | Description | -| ---------------------------------------------------------------------------------------------------- | ---- | ----------------------------------------------- | -| [e148a8df93](https://github.com/angular/angular-cli/commit/e148a8df93b309dcd51698b4ce4f9343560edd8e) | fix | support npm 12 metadata array and error formats | - -### @angular/build - -| Commit | Type | Description | -| ---------------------------------------------------------------------------------------------------- | ---- | --------------------------------------------------------------- | -| [6469b5f1f5](https://github.com/angular/angular-cli/commit/6469b5f1f5946415f49000f26bddd88b5647ac3d) | fix | rewrite paths from sandboxed execroots when running under Bazel | - - - # 22.1.0 (2026-07-29) From feb41cc9341ff001a67ffc22ac9816aba8750e65 Mon Sep 17 00:00:00 2001 From: Charles Lyding <19598772+clydin@users.noreply.github.com> Date: Wed, 23 Sep 2026 19:53:18 -0400 Subject: [PATCH 506/787] feat(@angular/build): add polyfills option to unit-test builder Adds an optional 'polyfills' array option to the 'unit-test' builder. When omitted, polyfills continue to be inherited from the specified 'buildTarget'. When defined, the test target's 'polyfills' option takes precedence, allowing projects to configure test-specific polyfills or provide polyfills for library test targets that build with '@angular/build:ng-packagr'. --- goldens/public-api/angular/build/index.api.md | 1 + .../build/src/builders/unit-test/builder.ts | 3 + .../build/src/builders/unit-test/options.ts | 2 + .../unit-test/runners/karma/executor.ts | 2 +- .../unit-test/runners/vitest/build-options.ts | 3 +- .../build/src/builders/unit-test/schema.json | 8 ++ .../unit-test/tests/options/polyfills_spec.ts | 96 +++++++++++++++++++ 7 files changed, 113 insertions(+), 2 deletions(-) create mode 100644 packages/angular/build/src/builders/unit-test/tests/options/polyfills_spec.ts diff --git a/goldens/public-api/angular/build/index.api.md b/goldens/public-api/angular/build/index.api.md index c9d83bc6fd9b..b08d70c07e64 100644 --- a/goldens/public-api/angular/build/index.api.md +++ b/goldens/public-api/angular/build/index.api.md @@ -236,6 +236,7 @@ export type UnitTestBuilderOptions = { isolate?: boolean; listTests?: boolean; outputFile?: string; + polyfills?: string[]; progress?: boolean; providersFile?: string; quiet?: boolean; diff --git a/packages/angular/build/src/builders/unit-test/builder.ts b/packages/angular/build/src/builders/unit-test/builder.ts index 755b91c40544..dc8751778368 100644 --- a/packages/angular/build/src/builders/unit-test/builder.ts +++ b/packages/angular/build/src/builders/unit-test/builder.ts @@ -323,6 +323,9 @@ export async function* execute( const applicationBuildOptions = { ...buildTargetOptions, ...runnerBuildOptions, + ...(normalizedOptions.polyfills !== undefined + ? { polyfills: normalizedOptions.polyfills } + : {}), watch: normalizedOptions.watch, progress: normalizedOptions.buildProgress ?? buildTargetOptions.progress, quiet: normalizedOptions.quiet, diff --git a/packages/angular/build/src/builders/unit-test/options.ts b/packages/angular/build/src/builders/unit-test/options.ts index 44f6b6b9208b..5328a5861219 100644 --- a/packages/angular/build/src/builders/unit-test/options.ts +++ b/packages/angular/build/src/builders/unit-test/options.ts @@ -77,6 +77,7 @@ export async function normalizeOptions( runnerConfig, isolate, splitting = true, + polyfills, } = options; if (ui && runner !== Runner.Vitest) { @@ -158,6 +159,7 @@ export async function normalizeOptions( dumpVirtualFiles: options.dumpVirtualFiles, listTests: options.listTests, preserveSymlinks, + polyfills, runnerConfig: typeof runnerConfig === 'string' ? runnerConfig.length === 0 diff --git a/packages/angular/build/src/builders/unit-test/runners/karma/executor.ts b/packages/angular/build/src/builders/unit-test/runners/karma/executor.ts index 8b82857258b9..e558a3a1f3a7 100644 --- a/packages/angular/build/src/builders/unit-test/runners/karma/executor.ts +++ b/packages/angular/build/src/builders/unit-test/runners/karma/executor.ts @@ -76,7 +76,7 @@ export class KarmaExecutor implements TestExecutor { const karmaOptions: KarmaBuilderOptions = { karmaConfig, tsConfig: unitTestOptions.tsConfig ?? buildTargetOptions.tsConfig, - polyfills: injectTestingPolyfills(buildTargetOptions.polyfills), + polyfills: injectTestingPolyfills(unitTestOptions.polyfills ?? buildTargetOptions.polyfills), assets: buildTargetOptions.assets, scripts: buildTargetOptions.scripts, styles: buildTargetOptions.styles, diff --git a/packages/angular/build/src/builders/unit-test/runners/vitest/build-options.ts b/packages/angular/build/src/builders/unit-test/runners/vitest/build-options.ts index 622ca7beebd3..a97cf05cb9e2 100644 --- a/packages/angular/build/src/builders/unit-test/runners/vitest/build-options.ts +++ b/packages/angular/build/src/builders/unit-test/runners/vitest/build-options.ts @@ -178,7 +178,7 @@ function getZoneTestingStrategy( return 'dynamic-zone'; } - return 'dynamic'; + return 'none'; } catch { return 'none'; } @@ -256,6 +256,7 @@ export async function getVitestBuildOptions( const buildOptions: Partial = { ...baseBuildOptions, + ...(options.polyfills !== undefined ? { polyfills: options.polyfills } : {}), watch, incrementalResults: watch, index: false, diff --git a/packages/angular/build/src/builders/unit-test/schema.json b/packages/angular/build/src/builders/unit-test/schema.json index 58a9592986b1..7064243c8832 100644 --- a/packages/angular/build/src/builders/unit-test/schema.json +++ b/packages/angular/build/src/builders/unit-test/schema.json @@ -265,6 +265,14 @@ "description": "Specifies the path to a TypeScript file that provides an array of Angular providers for the test environment. The file must contain a default export of the provider array.", "minLength": 1 }, + "polyfills": { + "description": "A list of polyfills to include in the build. Can be a full path for a file, relative to the current workspace or module specifier. Example: 'zone.js'. If not specified, polyfills will be inherited from the build target.", + "type": "array", + "items": { + "type": "string", + "uniqueItems": true + } + }, "setupFiles": { "type": "array", "items": { diff --git a/packages/angular/build/src/builders/unit-test/tests/options/polyfills_spec.ts b/packages/angular/build/src/builders/unit-test/tests/options/polyfills_spec.ts new file mode 100644 index 000000000000..06bc3bd8fc98 --- /dev/null +++ b/packages/angular/build/src/builders/unit-test/tests/options/polyfills_spec.ts @@ -0,0 +1,96 @@ +/** + * @license + * Copyright Google LLC All Rights Reserved. + * + * Use of this source code is governed by an MIT-style license that can be + * found in the LICENSE file at https://angular.dev/license + */ + +import { execute } from '../../index'; +import { + BASE_OPTIONS, + describeBuilder, + UNIT_TEST_BUILDER_INFO, + setupApplicationTarget, +} from '../setup'; + +describeBuilder(execute, UNIT_TEST_BUILDER_INFO, (harness) => { + describe('Option: "polyfills"', () => { + beforeEach(async () => { + setupApplicationTarget(harness); + }); + + it('should include polyfills specified on test target', async () => { + await harness.writeFiles({ + 'src/custom-polyfill.js': `globalThis['CUSTOM_POLYFILL_RAN'] = true;`, + 'src/app/app.component.spec.ts': ` + import { describe, expect, test } from 'vitest'; + describe('Polyfill Test', () => { + test('should have run test polyfill', () => { + expect((globalThis as any)['CUSTOM_POLYFILL_RAN']).toBe(true); + }); + });`, + }); + + harness.useTarget('test', { + ...BASE_OPTIONS, + polyfills: ['src/custom-polyfill.js'], + }); + + const { result } = await harness.executeOnce(); + expect(result?.success).toBeTrue(); + }); + + it('should override buildTarget polyfills when polyfills is specified on test target', async () => { + setupApplicationTarget(harness, { + polyfills: ['src/app-polyfill.js'], + }); + + await harness.writeFiles({ + 'src/app-polyfill.js': `globalThis['APP_POLYFILL_RAN'] = true;`, + 'src/test-polyfill.js': `globalThis['TEST_POLYFILL_RAN'] = true;`, + 'src/app/app.component.spec.ts': ` + import { describe, expect, test } from 'vitest'; + describe('Polyfill Override Test', () => { + test('should have run test polyfill and not app polyfill', () => { + expect((globalThis as any)['TEST_POLYFILL_RAN']).toBe(true); + expect((globalThis as any)['APP_POLYFILL_RAN']).toBeUndefined(); + }); + });`, + }); + + harness.useTarget('test', { + ...BASE_OPTIONS, + polyfills: ['src/test-polyfill.js'], + }); + + const { result } = await harness.executeOnce(); + expect(result?.success).toBeTrue(); + }); + + it('should allow overriding buildTarget polyfills with an empty array', async () => { + setupApplicationTarget(harness, { + polyfills: ['src/app-polyfill.js'], + }); + + await harness.writeFiles({ + 'src/app-polyfill.js': `globalThis['APP_POLYFILL_RAN'] = true;`, + 'src/app/app.component.spec.ts': ` + import { describe, expect, test } from 'vitest'; + describe('Empty Polyfill Override Test', () => { + test('should not have run app polyfill', () => { + expect((globalThis as any)['APP_POLYFILL_RAN']).toBeUndefined(); + }); + });`, + }); + + harness.useTarget('test', { + ...BASE_OPTIONS, + polyfills: [], + }); + + const { result } = await harness.executeOnce(); + expect(result?.success).toBeTrue(); + }); + }); +}); From d09f98ee701754bdb4eca7d56dcf506c8d8b6729 Mon Sep 17 00:00:00 2001 From: Alan Agius <17563226+alan-agius4@users.noreply.github.com> Date: Thu, 24 Sep 2026 07:54:38 +0000 Subject: [PATCH 507/787] fix(@angular/build): avoid top-level await for Zone.js injection in Vitest runner Previously, the Vitest unit-test runner used dynamic import strategies (`'dynamic'` and `'dynamic-zone'`) within the generated TestBed initialization virtual file (`createTestBedInitVirtualFile`) to load `zone.js` and `zone.js/testing`. This logic was fundamentally flawed: 1. When Zone.js was loaded dynamically at runtime via the `'dynamic'` strategy, esbuild did not downlevel `async`/`await` because `isZonelessApp` checked the build target's `polyfills` configuration (which did not explicitly list `zone.js`). Consequently, native async/await microtasks bypassed Zone.js context tracking, breaking Zone.js at runtime. 2. If a project used a local polyfills file (e.g. `polyfills: ["src/polyfills.ts"]`), `isZonelessApp` considered the application zoneful and disabled `async-await` support in esbuild. However, esbuild cannot downlevel top-level await when async/await is downleveled, causing esbuild to reject top-level await unconditionally. Hence, the `'dynamic'` strategy never worked as intended. 3. For zoneless applications (such as `polyfills: []`), the syntactic presence of top-level `await` in the virtual file caused esbuild builds to fail when targeting older browsers or Browserslist targets that lack top-level await support, even though Zone was never present at runtime. This commit resolves these issues by: - Eliminating top-level `await import()` from `createTestBedInitVirtualFile` entirely. - Inverting the polyfill strategy so that `zone.js` and `zone.js/testing` are injected directly into `buildOptions.polyfills` before bundling based on the configured `polyfills` option (from the `test` target or inherited from the `build` target). - For library targets where `polyfills` is undefined, `zone.js` and `zone.js/testing` are injected if `zone.js` is installed, accompanied by a deprecation warning advising users to configure the `polyfills` option in their test configuration (`[]` for zoneless projects or `["zone.js"]` for Zone.js projects). Fixes #33324 --- .../build/src/builders/unit-test/builder.ts | 6 +- .../src/builders/unit-test/runners/api.ts | 1 + .../unit-test/runners/vitest/build-options.ts | 73 +++++------- .../unit-test/runners/vitest/index.ts | 5 +- .../tests/behavior/vitest-zone-init_spec.ts | 106 +++++++++++++++++- 5 files changed, 138 insertions(+), 53 deletions(-) diff --git a/packages/angular/build/src/builders/unit-test/builder.ts b/packages/angular/build/src/builders/unit-test/builder.ts index dc8751778368..bb1da57a7108 100644 --- a/packages/angular/build/src/builders/unit-test/builder.ts +++ b/packages/angular/build/src/builders/unit-test/builder.ts @@ -295,7 +295,7 @@ export async function* execute( buildOptions: runnerBuildOptions, virtualFiles, testEntryPointMappings, - } = await runner.getBuildOptions(normalizedOptions, buildTargetOptions)); + } = await runner.getBuildOptions(normalizedOptions, buildTargetOptions, context.logger)); } catch (e) { assertIsError(e); context.logger.error( @@ -323,9 +323,7 @@ export async function* execute( const applicationBuildOptions = { ...buildTargetOptions, ...runnerBuildOptions, - ...(normalizedOptions.polyfills !== undefined - ? { polyfills: normalizedOptions.polyfills } - : {}), + polyfills: runnerBuildOptions.polyfills ?? normalizedOptions.polyfills, watch: normalizedOptions.watch, progress: normalizedOptions.buildProgress ?? buildTargetOptions.progress, quiet: normalizedOptions.quiet, diff --git a/packages/angular/build/src/builders/unit-test/runners/api.ts b/packages/angular/build/src/builders/unit-test/runners/api.ts index 43f65ef68adc..4cd455472bfa 100644 --- a/packages/angular/build/src/builders/unit-test/runners/api.ts +++ b/packages/angular/build/src/builders/unit-test/runners/api.ts @@ -63,6 +63,7 @@ export interface TestRunner { getBuildOptions( options: NormalizedUnitTestBuilderOptions, baseBuildOptions: Partial, + logger: BuilderContext['logger'], ): RunnerOptions | Promise; /** diff --git a/packages/angular/build/src/builders/unit-test/runners/vitest/build-options.ts b/packages/angular/build/src/builders/unit-test/runners/vitest/build-options.ts index a97cf05cb9e2..b3a7d8f37662 100644 --- a/packages/angular/build/src/builders/unit-test/runners/vitest/build-options.ts +++ b/packages/angular/build/src/builders/unit-test/runners/vitest/build-options.ts @@ -11,12 +11,13 @@ * Provides Vitest-specific build options and virtual file contents for Angular unit testing. */ +import type { BuilderContext } from '@angular-devkit/architect'; import path from 'node:path'; import { toPosixPath } from '../../../../utils/path'; import { createProjectResolver } from '../../../../utils/resolve-project'; import type { ApplicationBuilderInternalOptions } from '../../../application/options'; import { OutputHashing } from '../../../application/schema'; -import { NormalizedUnitTestBuilderOptions } from '../../options'; +import { type NormalizedUnitTestBuilderOptions, injectTestingPolyfills } from '../../options'; import { findTests, getTestEntrypoints } from '../../test-discovery'; import { RunnerOptions } from '../api'; @@ -26,14 +27,12 @@ import { RunnerOptions } from '../api'; * @param providersFile Optional path to a file that exports default providers. * @param projectSourceRoot The root directory of the project source. * @param teardown Whether to configure TestBed to destroy after each test. - * @param zoneTestingStrategy How zone.js should be loaded during initialization. * @returns The string content of the virtual initialization file. */ function createTestBedInitVirtualFile( providersFile: string | undefined, projectSourceRoot: string, teardown: boolean, - zoneTestingStrategy: 'none' | 'static' | 'dynamic' | 'dynamic-zone', hasLocalize: boolean, ): string { let providersImport = 'const providers = [];'; @@ -44,21 +43,6 @@ function createTestBedInitVirtualFile( providersImport = `import providers from './${importPath}';`; } - let zoneTestingSnippet = ''; - if (zoneTestingStrategy === 'static') { - zoneTestingSnippet = `import 'zone.js/testing';`; - } else if (zoneTestingStrategy === 'dynamic') { - zoneTestingSnippet = `if (typeof Zone !== 'undefined') { - // 'zone.js/testing' is used to initialize the ZoneJS testing environment. - // It must be imported dynamically to avoid a static dependency on 'zone.js'. - await import('zone.js/testing'); - }`; - } else if (zoneTestingStrategy === 'dynamic-zone') { - zoneTestingSnippet = ` - await import('zone.js'); - await import('zone.js/testing');`; - } - // The DynamicDOMTestComponentRenderer is used to avoid stale document references // when running Vitest in non-isolated mode with JSDOM. It looks up the // document dynamically on every operation instead of caching it. @@ -72,8 +56,6 @@ function createTestBedInitVirtualFile( import { afterEach, beforeEach } from 'vitest'; ${providersImport} - ${zoneTestingSnippet} - // The beforeEach and afterEach hooks are registered outside the globalThis guard. // This ensures that the hooks are always applied, even in non-isolated browser environments. // Same as https://github.com/angular/angular/blob/05a03d3f975771bb59c7eefd37c01fa127ee2229/packages/core/testing/srcs/test_hooks.ts#L21-L29 @@ -150,37 +132,37 @@ function adjustOutputHashing(hashing?: OutputHashing): OutputHashing { } /** - * Resolves the Zone.js testing strategy by inspecting polyfills and resolving zone.js package. + * Injects Zone.js and Zone.js testing polyfills into the build options based on the + * project configuration and `polyfills` option. * - * @param buildOptions The partial application builder options. + * @param polyfills The configured polyfills from the test or build target. * @param projectSourceRoot The root directory of the project source. - * @returns The resolved zone testing strategy ('none', 'static', 'dynamic', 'dynamic-zone'). + * @param logger The logger instance for reporting deprecation warnings. + * @returns An array of polyfill specifiers to use for testing. */ -function getZoneTestingStrategy( - buildOptions: Partial, +function injectZoneJsTestingPolyfills( + polyfills: string[] | undefined, projectSourceRoot: string, -): 'none' | 'static' | 'dynamic' | 'dynamic-zone' { - if (buildOptions.polyfills?.includes('zone.js/testing')) { - return 'none'; - } - - if (buildOptions.polyfills?.includes('zone.js')) { - return 'static'; + logger: BuilderContext['logger'], +): string[] { + if (polyfills) { + return injectTestingPolyfills(polyfills); } + // If polyfills is undefined (e.g. library build target), attempt to load zone.js if installed. try { const projectResolve = createProjectResolver(projectSourceRoot); projectResolve('zone.js'); - // If polyfills is undefined (e.g. library build target), load zone.js dynamically. - // If polyfills is defined but doesn't include zone.js (e.g. zoneless application), do NOT load zone.js. - if (buildOptions.polyfills === undefined) { - return 'dynamic-zone'; - } + logger.warn( + 'Zone.js polyfills are being automatically injected because "zone.js" was detected in the project dependencies. ' + + 'This behavior is deprecated. If your project is zoneless, set the "polyfills" option to an empty array ("[]") in the ' + + 'test configuration. Otherwise, explicitly add "zone.js" to the "polyfills" option.', + ); - return 'none'; + return ['zone.js', 'zone.js/testing']; } catch { - return 'none'; + return []; } } @@ -192,16 +174,19 @@ function getZoneTestingStrategy( * * @param options The normalized unit test builder options. * @param baseBuildOptions The base build config to derive testing config from. + * @param logger The logger instance for reporting deprecation warnings. * @returns An async RunnerOptions configuration. */ export async function getVitestBuildOptions( options: NormalizedUnitTestBuilderOptions, baseBuildOptions: Partial, + logger: BuilderContext['logger'], ): Promise { const { workspaceRoot, projectSourceRoot, include, + polyfills, exclude = [], watch, providersFile, @@ -256,7 +241,11 @@ export async function getVitestBuildOptions( const buildOptions: Partial = { ...baseBuildOptions, - ...(options.polyfills !== undefined ? { polyfills: options.polyfills } : {}), + polyfills: injectZoneJsTestingPolyfills( + polyfills ?? baseBuildOptions.polyfills, + projectSourceRoot, + logger, + ), watch, incrementalResults: watch, index: false, @@ -285,9 +274,6 @@ export async function getVitestBuildOptions( externalDependencies, }; - // Inject the zone.js testing polyfill if Zone.js is installed. - const zoneTestingStrategy = getZoneTestingStrategy(buildOptions, projectSourceRoot); - let hasLocalize = false; try { const projectResolve = createProjectResolver(projectSourceRoot); @@ -299,7 +285,6 @@ export async function getVitestBuildOptions( providersFile, projectSourceRoot, !options.debug, - zoneTestingStrategy, hasLocalize, ); diff --git a/packages/angular/build/src/builders/unit-test/runners/vitest/index.ts b/packages/angular/build/src/builders/unit-test/runners/vitest/index.ts index a1342e5abba8..f879628a2462 100644 --- a/packages/angular/build/src/builders/unit-test/runners/vitest/index.ts +++ b/packages/angular/build/src/builders/unit-test/runners/vitest/index.ts @@ -9,7 +9,6 @@ import assert from 'node:assert'; import type { TestRunner } from '../api'; import { DependencyChecker } from '../dependency-checker'; -import { normalizeBrowserName } from './browser-provider'; import { getVitestBuildOptions } from './build-options'; import { VitestExecutor } from './executor'; @@ -60,8 +59,8 @@ const VitestTestRunner: TestRunner = { checker.report(); }, - getBuildOptions(options, baseBuildOptions) { - return getVitestBuildOptions(options, baseBuildOptions); + getBuildOptions(options, baseBuildOptions, logger) { + return getVitestBuildOptions(options, baseBuildOptions, logger); }, async createExecutor(context, options, testEntryPointMappings) { diff --git a/packages/angular/build/src/builders/unit-test/tests/behavior/vitest-zone-init_spec.ts b/packages/angular/build/src/builders/unit-test/tests/behavior/vitest-zone-init_spec.ts index 3caf15a2cf3f..147cfc31c53e 100644 --- a/packages/angular/build/src/builders/unit-test/tests/behavior/vitest-zone-init_spec.ts +++ b/packages/angular/build/src/builders/unit-test/tests/behavior/vitest-zone-init_spec.ts @@ -4,6 +4,8 @@ import { describeBuilder, UNIT_TEST_BUILDER_INFO, setupApplicationTarget, + expectLog, + expectNoLog, } from '../setup'; describeBuilder(execute, UNIT_TEST_BUILDER_INFO, (harness) => { @@ -68,7 +70,61 @@ describeBuilder(execute, UNIT_TEST_BUILDER_INFO, (harness) => { expect(result?.success).toBe(true); }); - it('should load Zone and Zone testing support when testing a library and zone.js is installed', async () => { + it('should NOT load Zone when test polyfills is empty even if zone.js is in build polyfills', async () => { + setupApplicationTarget(harness, { + polyfills: ['zone.js'], + }); + + harness.useTarget('test', { + ...BASE_OPTIONS, + polyfills: [], + }); + + harness.writeFile( + 'src/app/app.component.spec.ts', + ` + import { describe, it, expect } from 'vitest'; + + describe('Zoneless Override Test', () => { + it('should NOT have Zone defined', () => { + expect((globalThis as any).Zone).toBeUndefined(); + }); + }); + `, + ); + + const { result } = await harness.executeOnce(); + expect(result?.success).toBeTrue(); + }); + + it('should load Zone when test polyfills includes zone.js even if build polyfills is empty', async () => { + setupApplicationTarget(harness, { + polyfills: [], + }); + + harness.useTarget('test', { + ...BASE_OPTIONS, + polyfills: ['zone.js'], + }); + + harness.writeFile( + 'src/app/app.component.spec.ts', + ` + import { describe, it, expect } from 'vitest'; + + describe('Zone Forced Test', () => { + it('should have Zone defined', () => { + expect((globalThis as any).Zone).toBeDefined(); + }); + }); + `, + ); + + const { result } = await harness.executeOnce(); + expect(result?.success).toBeTrue(); + }); + + it('should load Zone and emit a deprecation warning when testing a library and zone.js is installed', async () => { harness.withBuilderTarget( 'build', async () => ({ success: true }), @@ -107,8 +163,54 @@ describeBuilder(execute, UNIT_TEST_BUILDER_INFO, (harness) => { `, ); - const { result } = await harness.executeOnce(); + const { result, logs } = await harness.executeOnce(); + expect(result?.success).toBeTrue(); + expectLog(logs, /Zone\.js polyfills are being automatically injected/); + }); + + it('should NOT load Zone and not emit warning when testing a library with polyfills: []', async () => { + harness.withBuilderTarget( + 'build', + async () => ({ success: true }), + { + project: 'ng-package.json', + }, + { + builderName: '@angular/build:ng-packagr', + }, + ); + + await harness.writeFile( + 'ng-package.json', + JSON.stringify({ + lib: { + entryFile: 'src/public-api.ts', + }, + }), + ); + + harness.useTarget('test', { + ...BASE_OPTIONS, + polyfills: [], + include: ['src/app.component.spec.ts'], + }); + + await harness.writeFile( + 'src/app.component.spec.ts', + ` + import { describe, it, expect } from 'vitest'; + + describe('Library Zoneless Test', () => { + it('should NOT have Zone defined', () => { + expect((globalThis as any).Zone).toBeUndefined(); + }); + }); + `, + ); + + const { result, logs } = await harness.executeOnce(); expect(result?.success).toBeTrue(); + expectNoLog(logs, /Zone\.js polyfills are being automatically injected/); }); }); }); From 297ef9cc4a8985a1acb220e870237f5ffee75fba Mon Sep 17 00:00:00 2001 From: Angular Robot Date: Thu, 24 Sep 2026 12:42:57 +0000 Subject: [PATCH 508/787] build: update cross-repo angular dependencies See associated pull request for more information. --- .../assistant-to-the-branch-manager.yml | 2 +- .github/workflows/ci.yml | 52 ++--- .github/workflows/dev-infra.yml | 6 +- .github/workflows/perf.yml | 6 +- .github/workflows/pr.yml | 44 ++-- MODULE.bazel | 6 +- modules/testing/builder/package.json | 2 +- package.json | 2 +- packages/angular/build/package.json | 2 +- .../angular_devkit/build_angular/package.json | 2 +- pnpm-lock.yaml | 215 ++++++++++-------- tests/e2e/ng-snapshot/package.json | 32 +-- 12 files changed, 198 insertions(+), 173 deletions(-) diff --git a/.github/workflows/assistant-to-the-branch-manager.yml b/.github/workflows/assistant-to-the-branch-manager.yml index d96db1e3d645..715bb9bf0c56 100644 --- a/.github/workflows/assistant-to-the-branch-manager.yml +++ b/.github/workflows/assistant-to-the-branch-manager.yml @@ -18,6 +18,6 @@ jobs: - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: persist-credentials: false - - uses: angular/dev-infra/github-actions/branch-manager@bf1d18837b5aaed70cf858ecd177583bf320be50 # main + - uses: angular/dev-infra/github-actions/branch-manager@a948cdfda182b725e3abad445b2e6264508db3ed # main with: angular-robot-key: ${{ secrets.ANGULAR_ROBOT_PRIVATE_KEY }} diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 5bc5ede289ce..a8dffcf5aac3 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -21,9 +21,9 @@ jobs: runs-on: ubuntu-latest steps: - name: Initialize environment - uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@bf1d18837b5aaed70cf858ecd177583bf320be50 # main + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@a948cdfda182b725e3abad445b2e6264508db3ed # main - name: Setup Bazel - uses: angular/dev-infra/github-actions/bazel/setup@bf1d18837b5aaed70cf858ecd177583bf320be50 # main + uses: angular/dev-infra/github-actions/bazel/setup@a948cdfda182b725e3abad445b2e6264508db3ed # main - name: Install node modules run: pnpm install --frozen-lockfile - name: Generate JSON schema types @@ -44,11 +44,11 @@ jobs: runs-on: ubuntu-latest steps: - name: Initialize environment - uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@bf1d18837b5aaed70cf858ecd177583bf320be50 # main + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@a948cdfda182b725e3abad445b2e6264508db3ed # main - name: Setup Bazel - uses: angular/dev-infra/github-actions/bazel/setup@bf1d18837b5aaed70cf858ecd177583bf320be50 # main + uses: angular/dev-infra/github-actions/bazel/setup@a948cdfda182b725e3abad445b2e6264508db3ed # main - name: Setup Bazel RBE - uses: angular/dev-infra/github-actions/bazel/configure-remote@bf1d18837b5aaed70cf858ecd177583bf320be50 # main + uses: angular/dev-infra/github-actions/bazel/configure-remote@a948cdfda182b725e3abad445b2e6264508db3ed # main with: google_credential: ${{ secrets.RBE_TRUSTED_BUILDS_USER }} - name: Install node modules @@ -61,11 +61,11 @@ jobs: runs-on: ubuntu-latest steps: - name: Initialize environment - uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@bf1d18837b5aaed70cf858ecd177583bf320be50 # main + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@a948cdfda182b725e3abad445b2e6264508db3ed # main - name: Setup Bazel - uses: angular/dev-infra/github-actions/bazel/setup@bf1d18837b5aaed70cf858ecd177583bf320be50 # main + uses: angular/dev-infra/github-actions/bazel/setup@a948cdfda182b725e3abad445b2e6264508db3ed # main - name: Setup Bazel RBE - uses: angular/dev-infra/github-actions/bazel/configure-remote@bf1d18837b5aaed70cf858ecd177583bf320be50 # main + uses: angular/dev-infra/github-actions/bazel/configure-remote@a948cdfda182b725e3abad445b2e6264508db3ed # main with: google_credential: ${{ secrets.RBE_TRUSTED_BUILDS_USER }} - name: Install node modules @@ -84,13 +84,13 @@ jobs: runs-on: ubuntu-latest steps: - name: Initialize environment - uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@bf1d18837b5aaed70cf858ecd177583bf320be50 # main + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@a948cdfda182b725e3abad445b2e6264508db3ed # main - name: Install node modules run: pnpm install --frozen-lockfile - name: Setup Bazel - uses: angular/dev-infra/github-actions/bazel/setup@bf1d18837b5aaed70cf858ecd177583bf320be50 # main + uses: angular/dev-infra/github-actions/bazel/setup@a948cdfda182b725e3abad445b2e6264508db3ed # main - name: Setup Bazel RBE - uses: angular/dev-infra/github-actions/bazel/configure-remote@bf1d18837b5aaed70cf858ecd177583bf320be50 # main + uses: angular/dev-infra/github-actions/bazel/configure-remote@a948cdfda182b725e3abad445b2e6264508db3ed # main with: google_credential: ${{ secrets.RBE_TRUSTED_BUILDS_USER }} - name: Run CLI E2E tests @@ -100,11 +100,11 @@ jobs: runs-on: ubuntu-latest steps: - name: Initialize environment - uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@bf1d18837b5aaed70cf858ecd177583bf320be50 # main + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@a948cdfda182b725e3abad445b2e6264508db3ed # main - name: Setup Bazel - uses: angular/dev-infra/github-actions/bazel/setup@bf1d18837b5aaed70cf858ecd177583bf320be50 # main + uses: angular/dev-infra/github-actions/bazel/setup@a948cdfda182b725e3abad445b2e6264508db3ed # main - name: Setup Bazel RBE - uses: angular/dev-infra/github-actions/bazel/configure-remote@bf1d18837b5aaed70cf858ecd177583bf320be50 # main + uses: angular/dev-infra/github-actions/bazel/configure-remote@a948cdfda182b725e3abad445b2e6264508db3ed # main with: google_credential: ${{ secrets.RBE_TRUSTED_BUILDS_USER }} - name: Install node modules @@ -137,7 +137,7 @@ jobs: runs-on: windows-2025 steps: - name: Initialize environment - uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@bf1d18837b5aaed70cf858ecd177583bf320be50 # main + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@a948cdfda182b725e3abad445b2e6264508db3ed # main - name: Install node modules run: pnpm install --frozen-lockfile - name: Download built Windows E2E tests @@ -164,13 +164,13 @@ jobs: runs-on: ubuntu-latest steps: - name: Initialize environment - uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@bf1d18837b5aaed70cf858ecd177583bf320be50 # main + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@a948cdfda182b725e3abad445b2e6264508db3ed # main - name: Install node modules run: pnpm install --frozen-lockfile - name: Setup Bazel - uses: angular/dev-infra/github-actions/bazel/setup@bf1d18837b5aaed70cf858ecd177583bf320be50 # main + uses: angular/dev-infra/github-actions/bazel/setup@a948cdfda182b725e3abad445b2e6264508db3ed # main - name: Setup Bazel RBE - uses: angular/dev-infra/github-actions/bazel/configure-remote@bf1d18837b5aaed70cf858ecd177583bf320be50 # main + uses: angular/dev-infra/github-actions/bazel/configure-remote@a948cdfda182b725e3abad445b2e6264508db3ed # main with: google_credential: ${{ secrets.RBE_TRUSTED_BUILDS_USER }} - name: Run CLI E2E tests @@ -188,13 +188,13 @@ jobs: runs-on: ubuntu-latest steps: - name: Initialize environment - uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@bf1d18837b5aaed70cf858ecd177583bf320be50 # main + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@a948cdfda182b725e3abad445b2e6264508db3ed # main - name: Install node modules run: pnpm install --frozen-lockfile - name: Setup Bazel - uses: angular/dev-infra/github-actions/bazel/setup@bf1d18837b5aaed70cf858ecd177583bf320be50 # main + uses: angular/dev-infra/github-actions/bazel/setup@a948cdfda182b725e3abad445b2e6264508db3ed # main - name: Setup Bazel RBE - uses: angular/dev-infra/github-actions/bazel/configure-remote@bf1d18837b5aaed70cf858ecd177583bf320be50 # main + uses: angular/dev-infra/github-actions/bazel/configure-remote@a948cdfda182b725e3abad445b2e6264508db3ed # main with: google_credential: ${{ secrets.RBE_TRUSTED_BUILDS_USER }} - name: Run CLI E2E tests @@ -208,13 +208,13 @@ jobs: SAUCE_TUNNEL_IDENTIFIER: angular-cli-${{ github.workflow }}-${{ github.run_number }} steps: - name: Initialize environment - uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@bf1d18837b5aaed70cf858ecd177583bf320be50 # main + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@a948cdfda182b725e3abad445b2e6264508db3ed # main - name: Install node modules run: pnpm install --frozen-lockfile - name: Setup Bazel - uses: angular/dev-infra/github-actions/bazel/setup@bf1d18837b5aaed70cf858ecd177583bf320be50 # main + uses: angular/dev-infra/github-actions/bazel/setup@a948cdfda182b725e3abad445b2e6264508db3ed # main - name: Setup Bazel RBE - uses: angular/dev-infra/github-actions/bazel/configure-remote@bf1d18837b5aaed70cf858ecd177583bf320be50 # main + uses: angular/dev-infra/github-actions/bazel/configure-remote@a948cdfda182b725e3abad445b2e6264508db3ed # main with: google_credential: ${{ secrets.RBE_TRUSTED_BUILDS_USER }} - name: Start Sauce Connect @@ -245,11 +245,11 @@ jobs: CIRCLE_BRANCH: ${{ github.ref_name }} steps: - name: Initialize environment - uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@bf1d18837b5aaed70cf858ecd177583bf320be50 # main + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@a948cdfda182b725e3abad445b2e6264508db3ed # main - name: Install node modules run: pnpm install --frozen-lockfile - name: Setup Bazel - uses: angular/dev-infra/github-actions/bazel/setup@bf1d18837b5aaed70cf858ecd177583bf320be50 # main + uses: angular/dev-infra/github-actions/bazel/setup@a948cdfda182b725e3abad445b2e6264508db3ed # main - run: pnpm admin snapshots --verbose env: SNAPSHOT_BUILDS_GITHUB_TOKEN: ${{ secrets.SNAPSHOT_BUILDS_GITHUB_TOKEN }} diff --git a/.github/workflows/dev-infra.yml b/.github/workflows/dev-infra.yml index 0f4aea85fdb0..7ac22449d1f1 100644 --- a/.github/workflows/dev-infra.yml +++ b/.github/workflows/dev-infra.yml @@ -16,21 +16,21 @@ jobs: if: github.event_name == 'pull_request_target' runs-on: ubuntu-latest steps: - - uses: angular/dev-infra/github-actions/labeling/pull-request@bf1d18837b5aaed70cf858ecd177583bf320be50 # main + - uses: angular/dev-infra/github-actions/labeling/pull-request@a948cdfda182b725e3abad445b2e6264508db3ed # main with: angular-robot-key: ${{ secrets.ANGULAR_ROBOT_PRIVATE_KEY }} post_approval_changes: if: github.event_name == 'pull_request_target' runs-on: ubuntu-latest steps: - - uses: angular/dev-infra/github-actions/post-approval-changes@bf1d18837b5aaed70cf858ecd177583bf320be50 # main + - uses: angular/dev-infra/github-actions/post-approval-changes@a948cdfda182b725e3abad445b2e6264508db3ed # main with: angular-robot-key: ${{ secrets.ANGULAR_ROBOT_PRIVATE_KEY }} issue_labels: if: github.event_name == 'issues' runs-on: ubuntu-latest steps: - - uses: angular/dev-infra/github-actions/labeling/issue@bf1d18837b5aaed70cf858ecd177583bf320be50 # main + - uses: angular/dev-infra/github-actions/labeling/issue@a948cdfda182b725e3abad445b2e6264508db3ed # main with: angular-robot-key: ${{ secrets.ANGULAR_ROBOT_PRIVATE_KEY }} google-generative-ai-key: ${{ secrets.GOOGLE_GENERATIVE_AI_KEY }} diff --git a/.github/workflows/perf.yml b/.github/workflows/perf.yml index a3170cf0add5..4ebe4ce4c1bd 100644 --- a/.github/workflows/perf.yml +++ b/.github/workflows/perf.yml @@ -22,7 +22,7 @@ jobs: workflows: ${{ steps.workflows.outputs.workflows }} steps: - name: Initialize environment - uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@bf1d18837b5aaed70cf858ecd177583bf320be50 # main + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@a948cdfda182b725e3abad445b2e6264508db3ed # main - name: Install node modules run: pnpm install --frozen-lockfile - id: workflows @@ -40,9 +40,9 @@ jobs: workflow: ${{ fromJSON(needs.list.outputs.workflows) }} steps: - name: Initialize environment - uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@bf1d18837b5aaed70cf858ecd177583bf320be50 # main + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@a948cdfda182b725e3abad445b2e6264508db3ed # main - name: Setup Bazel - uses: angular/dev-infra/github-actions/bazel/setup@bf1d18837b5aaed70cf858ecd177583bf320be50 # main + uses: angular/dev-infra/github-actions/bazel/setup@a948cdfda182b725e3abad445b2e6264508db3ed # main - name: Install node modules run: pnpm install --frozen-lockfile # We utilize the google-github-actions/auth action to allow us to get an active credential using workflow diff --git a/.github/workflows/pr.yml b/.github/workflows/pr.yml index 5d86977c77a4..ae130af4ec3d 100644 --- a/.github/workflows/pr.yml +++ b/.github/workflows/pr.yml @@ -34,9 +34,9 @@ jobs: runs-on: ubuntu-latest steps: - name: Initialize environment - uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@bf1d18837b5aaed70cf858ecd177583bf320be50 # main + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@a948cdfda182b725e3abad445b2e6264508db3ed # main - name: Setup Bazel - uses: angular/dev-infra/github-actions/bazel/setup@bf1d18837b5aaed70cf858ecd177583bf320be50 # main + uses: angular/dev-infra/github-actions/bazel/setup@a948cdfda182b725e3abad445b2e6264508db3ed # main - name: Setup ESLint Caching uses: actions/cache@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0 with: @@ -66,17 +66,17 @@ jobs: # it has been merged. run: pnpm ng-dev format changed --check ${{ github.event.pull_request.base.sha }} - name: Check Package Licenses - uses: angular/dev-infra/github-actions/linting/licenses@bf1d18837b5aaed70cf858ecd177583bf320be50 # main + uses: angular/dev-infra/github-actions/linting/licenses@a948cdfda182b725e3abad445b2e6264508db3ed # main build: runs-on: ubuntu-latest steps: - name: Initialize environment - uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@bf1d18837b5aaed70cf858ecd177583bf320be50 # main + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@a948cdfda182b725e3abad445b2e6264508db3ed # main - name: Setup Bazel - uses: angular/dev-infra/github-actions/bazel/setup@bf1d18837b5aaed70cf858ecd177583bf320be50 # main + uses: angular/dev-infra/github-actions/bazel/setup@a948cdfda182b725e3abad445b2e6264508db3ed # main - name: Setup Bazel RBE - uses: angular/dev-infra/github-actions/bazel/configure-remote@bf1d18837b5aaed70cf858ecd177583bf320be50 # main + uses: angular/dev-infra/github-actions/bazel/configure-remote@a948cdfda182b725e3abad445b2e6264508db3ed # main - name: Install node modules run: pnpm install --frozen-lockfile - name: Build release targets @@ -93,11 +93,11 @@ jobs: runs-on: ubuntu-latest steps: - name: Initialize environment - uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@bf1d18837b5aaed70cf858ecd177583bf320be50 # main + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@a948cdfda182b725e3abad445b2e6264508db3ed # main - name: Setup Bazel - uses: angular/dev-infra/github-actions/bazel/setup@bf1d18837b5aaed70cf858ecd177583bf320be50 # main + uses: angular/dev-infra/github-actions/bazel/setup@a948cdfda182b725e3abad445b2e6264508db3ed # main - name: Setup Bazel RBE - uses: angular/dev-infra/github-actions/bazel/configure-remote@bf1d18837b5aaed70cf858ecd177583bf320be50 # main + uses: angular/dev-infra/github-actions/bazel/configure-remote@a948cdfda182b725e3abad445b2e6264508db3ed # main - name: Install node modules run: pnpm install --frozen-lockfile - name: Run module and package tests @@ -114,13 +114,13 @@ jobs: runs-on: ubuntu-latest steps: - name: Initialize environment - uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@bf1d18837b5aaed70cf858ecd177583bf320be50 # main + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@a948cdfda182b725e3abad445b2e6264508db3ed # main - name: Install node modules run: pnpm install --frozen-lockfile - name: Setup Bazel - uses: angular/dev-infra/github-actions/bazel/setup@bf1d18837b5aaed70cf858ecd177583bf320be50 # main + uses: angular/dev-infra/github-actions/bazel/setup@a948cdfda182b725e3abad445b2e6264508db3ed # main - name: Setup Bazel RBE - uses: angular/dev-infra/github-actions/bazel/configure-remote@bf1d18837b5aaed70cf858ecd177583bf320be50 # main + uses: angular/dev-infra/github-actions/bazel/configure-remote@a948cdfda182b725e3abad445b2e6264508db3ed # main - name: Run CLI E2E tests run: pnpm bazel test --test_env=E2E_SHARD_TOTAL=6 --test_env=E2E_SHARD_INDEX=${{ matrix.shard }} --config=e2e //tests:e2e.${{ matrix.subset }}_node${{ matrix.node }} @@ -128,11 +128,11 @@ jobs: runs-on: ubuntu-latest steps: - name: Initialize environment - uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@bf1d18837b5aaed70cf858ecd177583bf320be50 # main + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@a948cdfda182b725e3abad445b2e6264508db3ed # main - name: Setup Bazel - uses: angular/dev-infra/github-actions/bazel/setup@bf1d18837b5aaed70cf858ecd177583bf320be50 # main + uses: angular/dev-infra/github-actions/bazel/setup@a948cdfda182b725e3abad445b2e6264508db3ed # main - name: Setup Bazel RBE - uses: angular/dev-infra/github-actions/bazel/configure-remote@bf1d18837b5aaed70cf858ecd177583bf320be50 # main + uses: angular/dev-infra/github-actions/bazel/configure-remote@a948cdfda182b725e3abad445b2e6264508db3ed # main - name: Install node modules run: pnpm install --frozen-lockfile - name: Build E2E tests for Windows on Linux @@ -156,7 +156,7 @@ jobs: runs-on: windows-2025 steps: - name: Initialize environment - uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@bf1d18837b5aaed70cf858ecd177583bf320be50 # main + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@a948cdfda182b725e3abad445b2e6264508db3ed # main - name: Install node modules run: pnpm install --frozen-lockfile - name: Download built Windows E2E tests @@ -183,13 +183,13 @@ jobs: runs-on: ubuntu-latest steps: - name: Initialize environment - uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@bf1d18837b5aaed70cf858ecd177583bf320be50 # main + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@a948cdfda182b725e3abad445b2e6264508db3ed # main - name: Install node modules run: pnpm install --frozen-lockfile - name: Setup Bazel - uses: angular/dev-infra/github-actions/bazel/setup@bf1d18837b5aaed70cf858ecd177583bf320be50 # main + uses: angular/dev-infra/github-actions/bazel/setup@a948cdfda182b725e3abad445b2e6264508db3ed # main - name: Setup Bazel RBE - uses: angular/dev-infra/github-actions/bazel/configure-remote@bf1d18837b5aaed70cf858ecd177583bf320be50 # main + uses: angular/dev-infra/github-actions/bazel/configure-remote@a948cdfda182b725e3abad445b2e6264508db3ed # main - name: Run CLI E2E tests run: pnpm bazel test --test_env=E2E_SHARD_TOTAL=3 --test_env=E2E_SHARD_INDEX=${{ matrix.shard }} --config=e2e //tests:e2e.${{ matrix.subset }}_node${{ matrix.node }} @@ -205,12 +205,12 @@ jobs: runs-on: ubuntu-latest steps: - name: Initialize environment - uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@bf1d18837b5aaed70cf858ecd177583bf320be50 # main + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@a948cdfda182b725e3abad445b2e6264508db3ed # main - name: Install node modules run: pnpm install --frozen-lockfile - name: Setup Bazel - uses: angular/dev-infra/github-actions/bazel/setup@bf1d18837b5aaed70cf858ecd177583bf320be50 # main + uses: angular/dev-infra/github-actions/bazel/setup@a948cdfda182b725e3abad445b2e6264508db3ed # main - name: Setup Bazel RBE - uses: angular/dev-infra/github-actions/bazel/configure-remote@bf1d18837b5aaed70cf858ecd177583bf320be50 # main + uses: angular/dev-infra/github-actions/bazel/configure-remote@a948cdfda182b725e3abad445b2e6264508db3ed # main - name: Run CLI E2E tests run: pnpm bazel test --test_env=E2E_SHARD_TOTAL=6 --test_env=E2E_SHARD_INDEX=${{ matrix.shard }} --config=e2e //tests:e2e.snapshots.${{ matrix.subset }}_node${{ matrix.node }} diff --git a/MODULE.bazel b/MODULE.bazel index 5e0096477618..53a88fa03302 100644 --- a/MODULE.bazel +++ b/MODULE.bazel @@ -19,21 +19,21 @@ bazel_dep(name = "aspect_rules_jasmine", version = "2.0.4") bazel_dep(name = "rules_angular") git_override( module_name = "rules_angular", - commit = "6468bfd6c2f90b7a025d86273b070d0dd0a443db", + commit = "c40fd63ad915b6c159a7eba93079757024ad2844", remote = "https://github.com/angular/rules_angular.git", ) bazel_dep(name = "devinfra") git_override( module_name = "devinfra", - commit = "bf1d18837b5aaed70cf858ecd177583bf320be50", + commit = "a948cdfda182b725e3abad445b2e6264508db3ed", remote = "https://github.com/angular/dev-infra.git", ) bazel_dep(name = "rules_browsers") git_override( module_name = "rules_browsers", - commit = "ba55f13997d951c9ac02192cf6d1cadad03c1237", + commit = "a73e3fb4819202ed84bad97e19039e7591b7e87a", remote = "https://github.com/angular/rules_browsers.git", ) diff --git a/modules/testing/builder/package.json b/modules/testing/builder/package.json index d76148352027..f576c6875289 100644 --- a/modules/testing/builder/package.json +++ b/modules/testing/builder/package.json @@ -8,7 +8,7 @@ "browser-sync": "3.0.4", "istanbul-lib-instrument": "6.0.3", "jsdom": "30.0.1", - "ng-packagr": "22.2.0-rc.0", + "ng-packagr": "22.3.0-next.1", "rxjs": "7.8.2", "vitest": "5.0.1" } diff --git a/package.json b/package.json index 3cf313dbfe2f..835bfa5ecdd3 100644 --- a/package.json +++ b/package.json @@ -55,7 +55,7 @@ "@angular/forms": "22.2.0-rc.0", "@angular/localize": "22.2.0-rc.0", "@angular/material": "22.2.0-rc.0", - "@angular/ng-dev": "https://github.com/angular/dev-infra-private-ng-dev-builds.git#90a76327155df50e90a41fe76aed67b98a9cf954", + "@angular/ng-dev": "https://github.com/angular/dev-infra-private-ng-dev-builds.git#df3931fca45cce0a2fa74c9ccc5876c571ef8406", "@angular/platform-browser": "22.2.0-rc.0", "@angular/platform-server": "22.2.0-rc.0", "@angular/router": "22.2.0-rc.0", diff --git a/packages/angular/build/package.json b/packages/angular/build/package.json index 9e0b0b7c4ff1..9a7908005064 100644 --- a/packages/angular/build/package.json +++ b/packages/angular/build/package.json @@ -57,7 +57,7 @@ "istanbul-lib-instrument": "6.0.3", "jsdom": "30.0.1", "less": "4.9.1", - "ng-packagr": "22.2.0-rc.0", + "ng-packagr": "22.3.0-next.1", "postcss": "8.5.28", "rollup": "4.63.3", "rxjs": "7.8.2", diff --git a/packages/angular_devkit/build_angular/package.json b/packages/angular_devkit/build_angular/package.json index fe24d7a53284..9e8de726b3c9 100644 --- a/packages/angular_devkit/build_angular/package.json +++ b/packages/angular_devkit/build_angular/package.json @@ -66,7 +66,7 @@ "devDependencies": { "@angular/ssr": "workspace:*", "browser-sync": "3.0.4", - "ng-packagr": "22.2.0-rc.0", + "ng-packagr": "22.3.0-next.1", "sass": "1.104.1", "undici": "8.10.2" }, diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 9bd424b55840..2837e5199bd2 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -208,8 +208,8 @@ importers: specifier: 22.2.0-rc.0 version: 22.2.0-rc.0(25ddf4063a130bbf19862bd16a6ab5d4) '@angular/ng-dev': - specifier: https://github.com/angular/dev-infra-private-ng-dev-builds.git#90a76327155df50e90a41fe76aed67b98a9cf954 - version: https://codeload.github.com/angular/dev-infra-private-ng-dev-builds/tar.gz/90a76327155df50e90a41fe76aed67b98a9cf954 + specifier: https://github.com/angular/dev-infra-private-ng-dev-builds.git#df3931fca45cce0a2fa74c9ccc5876c571ef8406 + version: https://codeload.github.com/angular/dev-infra-private-ng-dev-builds/tar.gz/df3931fca45cce0a2fa74c9ccc5876c571ef8406 '@angular/platform-browser': specifier: 22.2.0-rc.0 version: 22.2.0-rc.0(@angular/animations@22.2.0-rc.0(@angular/core@22.2.0-rc.0(@angular/compiler@22.2.0-rc.0)(rxjs@7.8.2)(zone.js@0.16.3)))(@angular/common@22.2.0-rc.0(@angular/core@22.2.0-rc.0(@angular/compiler@22.2.0-rc.0)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2))(@angular/core@22.2.0-rc.0(@angular/compiler@22.2.0-rc.0)(rxjs@7.8.2)(zone.js@0.16.3)) @@ -463,8 +463,8 @@ importers: specifier: 30.0.1 version: 30.0.1(@noble/hashes@1.8.0) ng-packagr: - specifier: 22.2.0-rc.0 - version: 22.2.0-rc.0(@angular/compiler-cli@22.2.0-rc.0(@angular/compiler@22.2.0-rc.0)(typescript@6.0.3))(supports-color@11.0.0)(tslib@2.8.1)(typescript@6.0.3) + specifier: 22.3.0-next.1 + version: 22.3.0-next.1(@angular/compiler-cli@22.2.0-rc.0(@angular/compiler@22.2.0-rc.0)(typescript@6.0.3))(supports-color@11.0.0)(tslib@2.8.1)(typescript@6.0.3) rxjs: specifier: 7.8.2 version: 7.8.2 @@ -578,8 +578,8 @@ importers: specifier: 4.9.1 version: 4.9.1(supports-color@11.0.0) ng-packagr: - specifier: 22.2.0-rc.0 - version: 22.2.0-rc.0(@angular/compiler-cli@22.2.0-rc.0(@angular/compiler@22.2.0-rc.0)(typescript@6.0.3))(supports-color@11.0.0)(tslib@2.8.1)(typescript@6.0.3) + specifier: 22.3.0-next.1 + version: 22.3.0-next.1(@angular/compiler-cli@22.2.0-rc.0(@angular/compiler@22.2.0-rc.0)(typescript@6.0.3))(supports-color@11.0.0)(tslib@2.8.1)(typescript@6.0.3) postcss: specifier: 8.5.28 version: 8.5.28 @@ -848,10 +848,10 @@ importers: version: 5.111.0(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.28)(uglify-js@3.19.3) webpack-dev-middleware: specifier: 8.3.0 - version: 8.3.0(webpack@5.111.0(esbuild@0.28.2)(lightningcss@1.33.0)(uglify-js@3.19.3)) + version: 8.3.0(webpack@5.111.0(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.28)(uglify-js@3.19.3)) webpack-dev-server: specifier: 6.0.0 - version: 6.0.0(bufferutil@4.1.0)(supports-color@11.0.0)(utf-8-validate@6.0.6)(webpack@5.111.0(esbuild@0.28.2)(lightningcss@1.33.0)(uglify-js@3.19.3)) + version: 6.0.0(bufferutil@4.1.0)(supports-color@11.0.0)(utf-8-validate@6.0.6)(webpack@5.111.0(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.28)(uglify-js@3.19.3)) webpack-merge: specifier: 6.0.1 version: 6.0.1 @@ -866,8 +866,8 @@ importers: specifier: 3.0.4 version: 3.0.4(bufferutil@4.1.0)(debug@4.4.3(supports-color@11.0.0))(supports-color@11.0.0)(utf-8-validate@6.0.6) ng-packagr: - specifier: 22.2.0-rc.0 - version: 22.2.0-rc.0(@angular/compiler-cli@22.2.0-rc.0(@angular/compiler@22.2.0-rc.0)(typescript@6.0.3))(supports-color@11.0.0)(tslib@2.8.1)(typescript@6.0.3) + specifier: 22.3.0-next.1 + version: 22.3.0-next.1(@angular/compiler-cli@22.2.0-rc.0(@angular/compiler@22.2.0-rc.0)(typescript@6.0.3))(supports-color@11.0.0)(tslib@2.8.1)(typescript@6.0.3) sass: specifier: 1.104.1 version: 1.104.1 @@ -899,7 +899,7 @@ importers: version: 5.111.0(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.28)(uglify-js@3.19.3) webpack-dev-server: specifier: 6.0.0 - version: 6.0.0(bufferutil@4.1.0)(supports-color@11.0.0)(utf-8-validate@6.0.6)(webpack@5.111.0(esbuild@0.28.2)(lightningcss@1.33.0)(uglify-js@3.19.3)) + version: 6.0.0(bufferutil@4.1.0)(supports-color@11.0.0)(utf-8-validate@6.0.6)(webpack@5.111.0(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.28)(uglify-js@3.19.3)) packages/angular_devkit/core: dependencies: @@ -1103,9 +1103,9 @@ packages: '@angular/platform-browser': ^22.0.0-0 || ^22.1.0-0 || ^22.2.0-0 || ^22.3.0-0 || ^23.0.0-0 rxjs: ^6.5.3 || ^7.4.0 - '@angular/ng-dev@https://codeload.github.com/angular/dev-infra-private-ng-dev-builds/tar.gz/90a76327155df50e90a41fe76aed67b98a9cf954': - resolution: {gitHosted: true, integrity: sha512-VmtUf+oZIHjATMGTjURjB3gJJ72gPo4nCDWEDUtW3MqgLPl088ISDgnV9CPXEt62EbByn9+0vVULCCk4p8YcVg==, tarball: https://codeload.github.com/angular/dev-infra-private-ng-dev-builds/tar.gz/90a76327155df50e90a41fe76aed67b98a9cf954} - version: 0.0.0-20b69d39859eae19d7ac04b6f1902f73286f7686 + '@angular/ng-dev@https://codeload.github.com/angular/dev-infra-private-ng-dev-builds/tar.gz/df3931fca45cce0a2fa74c9ccc5876c571ef8406': + resolution: {gitHosted: true, integrity: sha512-tyRa8ookiGkLtXBEOK9KSOkp+OgCOKhK7WW0Sv9RYeZZ0fqQHZrYvW+M9v2xBE3TNi/rD3iHXqkH6I5prls10Q==, tarball: https://codeload.github.com/angular/dev-infra-private-ng-dev-builds/tar.gz/df3931fca45cce0a2fa74c9ccc5876c571ef8406} + version: 0.0.0-a98a0a6d48067af7768f4dded0c4f159af687e2b hasBin: true '@angular/platform-browser@22.2.0-rc.0': @@ -2283,8 +2283,8 @@ packages: resolution: {integrity: sha512-IJn+8A3QZJfe7FUtWqHVNo3xJs7KFpurCWGWCiCz3oEh+BkRymKZ1QxfAbU2yGMDzTytLGQ2IV6T2r3cuo75/w==} engines: {node: '>=18'} - '@google/genai@2.22.0': - resolution: {integrity: sha512-NE90Nl0AP75YZ2tGxXjQQs6Gkunma7a1JmPCx5g5CxvjHXshmuI2aNoPJ1xLrRixjkNxog898oylM+MyNudUQw==} + '@google/genai@2.24.0': + resolution: {integrity: sha512-bIu5eoxF1AaPWs9ivmUJGp1RpDHyapoODvWvnkzRDx2CTIW6UJXFhDdjj0BlRve3ZHMMuEkQBVrA/ALqpW4apA==} engines: {node: '>=20.0.0'} peerDependencies: '@modelcontextprotocol/sdk': ^1.25.2 @@ -3715,8 +3715,8 @@ packages: '@types/node@22.20.4': resolution: {integrity: sha512-zJRE40jpHtKqE/C4fgHrAKQLJuSpzEnP9ff9Y7YtoR3Wd2pwqzlekDeEuUQXjRd+QCYnVnNwuJYmhdk9XV8gvA==} - '@types/node@24.13.5': - resolution: {integrity: sha512-TXyindR+lBr22aJIdMQzCFHPHR6cR4js838mRDCSz5hOKWZvZwsXSSiXDmjRj4iJmgl+sR9O+1mkoVBSMadNug==} + '@types/node@24.13.6': + resolution: {integrity: sha512-SGrw/h3KPFshy3OE6ZL53LMBG5vGQQ8/gIpiqz/kRZhPJ7HgwCEs8LBuNtWLa8dvGZVpSF7+Bf+c11HUrCb/yg==} '@types/npm-package-arg@6.1.4': resolution: {integrity: sha512-vDgdbMy2QXHnAruzlv68pUtXCjmqUk3WrBAsRboRovsOmxbfn/WiYCjmecyKjGztnMps5dWp4Uq2prp+Ilo17Q==} @@ -6730,12 +6730,12 @@ packages: neo-async@2.6.2: resolution: {integrity: sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==} - ng-packagr@22.2.0-rc.0: - resolution: {integrity: sha512-l91WqbCFBKpVmDwW/rttDNe6kpRjsIlHnUf55YTH5JqN0Q7uVGBy6QbRUV2S+4/StyFqc+keOAtVPJUdO2bvxw==} + ng-packagr@22.3.0-next.1: + resolution: {integrity: sha512-vzf/MorcWgxDt4thjL01COSRGYCBBH/GBFChTIaaHE1xorhcCtt9o9JJiX5L2BcLvQbMndb+MMk3TPGzWdoJ+g==} engines: {node: ^22.22.3 || ^24.15.0 || >=26.0.0} hasBin: true peerDependencies: - '@angular/compiler-cli': ^22.2.0-next + '@angular/compiler-cli': ^22.0.0 || ^22.2.0-next || ^22.3.0-next tailwindcss: ^2.0.0 || ^3.0.0 || ^4.0.0 tslib: ^2.3.0 typescript: '>=6.0 <6.1' @@ -8072,6 +8072,11 @@ packages: engines: {node: '>=18.0.0'} hasBin: true + tsx@4.23.15: + resolution: {integrity: sha512-Yiex1Ovn8z2xPpOWckIiysV1SSyRMY9BkLF++q0yKiDxCqRhosKfMg3janKkiLBwZ5c/YryloKwGZcrEmtwxKw==} + engines: {node: '>=18.0.0'} + hasBin: true + tsyringe@4.10.0: resolution: {integrity: sha512-axr3IdNuVIxnaK5XGEUFTu3YmAQ6lllgrvqfEoR16g/HGnYY/6We4oWENtAnzK6/LpJ2ur9PAb80RBt7/U4ugw==} engines: {node: '>= 6.0.0'} @@ -8602,6 +8607,10 @@ packages: resolution: {integrity: sha512-2rAgRKu54VsHkqI0/tYkmluGXHD4KW7yZoycuqDQ15QOTnc2VVfy0nN/1eMhnQLO00A+dwtK20xuCnc1YGeUyg==} engines: {node: ^20.19.0 || ^22.12.0 || >=23} + yargs@18.2.0: + resolution: {integrity: sha512-9OpKOLeaoNFecEp7P6iYbzze/5CqWoH7N3SMs/6y1XF4nMvFMspEGZzJ6uFi9MmQwXhyzqYoSEKO3tvA3Z/o2w==} + engines: {node: ^20.19.0 || ^22.12.0 || >=23} + yocto-queue@0.1.0: resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==} engines: {node: '>=10'} @@ -8726,14 +8735,14 @@ snapshots: rxjs: 7.8.2 tslib: 2.8.1 - '@angular/ng-dev@https://codeload.github.com/angular/dev-infra-private-ng-dev-builds/tar.gz/90a76327155df50e90a41fe76aed67b98a9cf954': + '@angular/ng-dev@https://codeload.github.com/angular/dev-infra-private-ng-dev-builds/tar.gz/df3931fca45cce0a2fa74c9ccc5876c571ef8406': dependencies: '@actions/core': 3.0.1 '@conventional-changelog/git-client': 3.1.2(conventional-commits-filter@6.0.1)(conventional-commits-parser@7.1.2) '@google-cloud/spanner': 8.0.0(supports-color@11.0.0) - '@google/genai': 2.22.0(bufferutil@4.1.0)(supports-color@11.0.0)(utf-8-validate@6.0.6) - '@inquirer/prompts': 8.7.2(@types/node@24.13.5) - '@inquirer/type': 4.1.1(@types/node@24.13.5) + '@google/genai': 2.24.0(bufferutil@4.1.0)(supports-color@11.0.0)(utf-8-validate@6.0.6) + '@inquirer/prompts': 8.7.2(@types/node@24.13.6) + '@inquirer/type': 4.1.1(@types/node@24.13.6) '@octokit/auth-app': 8.3.1 '@octokit/core': 7.0.8 '@octokit/graphql': 9.0.5 @@ -8749,7 +8758,7 @@ snapshots: '@types/events': 3.0.3 '@types/folder-hash': 4.0.4 '@types/jasmine': 6.0.0 - '@types/node': 24.13.5 + '@types/node': 24.13.6 '@types/semver': 7.8.0 '@types/which': 3.0.4 '@types/yargs': 17.0.35 @@ -8773,13 +8782,13 @@ snapshots: nock: 14.0.17 semver: 7.8.5 supports-color: 11.0.0 - tsx: 4.23.13 + tsx: 4.23.15 typed-graphqlify: 3.1.6 typescript: 6.0.3 utf-8-validate: 6.0.6 which: 7.0.0 yaml: 2.9.1 - yargs: 18.1.0 + yargs: 18.2.0 zod: 4.6.5 transitivePeerDependencies: - '@modelcontextprotocol/sdk' @@ -10131,7 +10140,7 @@ snapshots: transitivePeerDependencies: - supports-color - '@google/genai@2.22.0(bufferutil@4.1.0)(supports-color@11.0.0)(utf-8-validate@6.0.6)': + '@google/genai@2.24.0(bufferutil@4.1.0)(supports-color@11.0.0)(utf-8-validate@6.0.6)': dependencies: google-auth-library: 10.9.1(supports-color@11.0.0) p-retry: 4.6.2 @@ -10196,14 +10205,14 @@ snapshots: optionalDependencies: '@types/node': 22.20.4 - '@inquirer/checkbox@5.2.5(@types/node@24.13.5)': + '@inquirer/checkbox@5.2.5(@types/node@24.13.6)': dependencies: '@inquirer/ansi': 2.0.8 - '@inquirer/core': 12.0.3(@types/node@24.13.5) + '@inquirer/core': 12.0.3(@types/node@24.13.6) '@inquirer/figures': 2.0.9 - '@inquirer/type': 4.1.1(@types/node@24.13.5) + '@inquirer/type': 4.1.1(@types/node@24.13.6) optionalDependencies: - '@types/node': 24.13.5 + '@types/node': 24.13.6 '@inquirer/confirm@6.3.2(@types/node@22.20.4)': dependencies: @@ -10212,12 +10221,12 @@ snapshots: optionalDependencies: '@types/node': 22.20.4 - '@inquirer/confirm@6.3.2(@types/node@24.13.5)': + '@inquirer/confirm@6.3.2(@types/node@24.13.6)': dependencies: - '@inquirer/core': 12.0.3(@types/node@24.13.5) - '@inquirer/type': 4.1.1(@types/node@24.13.5) + '@inquirer/core': 12.0.3(@types/node@24.13.6) + '@inquirer/type': 4.1.1(@types/node@24.13.6) optionalDependencies: - '@types/node': 24.13.5 + '@types/node': 24.13.6 '@inquirer/core@12.0.3(@types/node@22.20.4)': dependencies: @@ -10231,17 +10240,17 @@ snapshots: optionalDependencies: '@types/node': 22.20.4 - '@inquirer/core@12.0.3(@types/node@24.13.5)': + '@inquirer/core@12.0.3(@types/node@24.13.6)': dependencies: '@inquirer/ansi': 2.0.8 '@inquirer/figures': 2.0.9 - '@inquirer/type': 4.1.1(@types/node@24.13.5) + '@inquirer/type': 4.1.1(@types/node@24.13.6) cli-width: 4.1.0 fast-wrap-ansi: 0.2.2 mute-stream: 3.0.0 signal-exit: 4.1.0 optionalDependencies: - '@types/node': 24.13.5 + '@types/node': 24.13.6 '@inquirer/editor@5.3.3(@types/node@22.20.4)': dependencies: @@ -10251,13 +10260,13 @@ snapshots: optionalDependencies: '@types/node': 22.20.4 - '@inquirer/editor@5.3.3(@types/node@24.13.5)': + '@inquirer/editor@5.3.3(@types/node@24.13.6)': dependencies: - '@inquirer/core': 12.0.3(@types/node@24.13.5) - '@inquirer/external-editor': 3.0.5(@types/node@24.13.5) - '@inquirer/type': 4.1.1(@types/node@24.13.5) + '@inquirer/core': 12.0.3(@types/node@24.13.6) + '@inquirer/external-editor': 3.0.5(@types/node@24.13.6) + '@inquirer/type': 4.1.1(@types/node@24.13.6) optionalDependencies: - '@types/node': 24.13.5 + '@types/node': 24.13.6 '@inquirer/expand@5.1.5(@types/node@22.20.4)': dependencies: @@ -10266,12 +10275,12 @@ snapshots: optionalDependencies: '@types/node': 22.20.4 - '@inquirer/expand@5.1.5(@types/node@24.13.5)': + '@inquirer/expand@5.1.5(@types/node@24.13.6)': dependencies: - '@inquirer/core': 12.0.3(@types/node@24.13.5) - '@inquirer/type': 4.1.1(@types/node@24.13.5) + '@inquirer/core': 12.0.3(@types/node@24.13.6) + '@inquirer/type': 4.1.1(@types/node@24.13.6) optionalDependencies: - '@types/node': 24.13.5 + '@types/node': 24.13.6 '@inquirer/external-editor@3.0.5(@types/node@22.20.4)': dependencies: @@ -10280,12 +10289,12 @@ snapshots: optionalDependencies: '@types/node': 22.20.4 - '@inquirer/external-editor@3.0.5(@types/node@24.13.5)': + '@inquirer/external-editor@3.0.5(@types/node@24.13.6)': dependencies: chardet: 2.2.0 iconv-lite: 0.7.3 optionalDependencies: - '@types/node': 24.13.5 + '@types/node': 24.13.6 '@inquirer/figures@2.0.9': {} @@ -10296,12 +10305,12 @@ snapshots: optionalDependencies: '@types/node': 22.20.4 - '@inquirer/input@5.1.6(@types/node@24.13.5)': + '@inquirer/input@5.1.6(@types/node@24.13.6)': dependencies: - '@inquirer/core': 12.0.3(@types/node@24.13.5) - '@inquirer/type': 4.1.1(@types/node@24.13.5) + '@inquirer/core': 12.0.3(@types/node@24.13.6) + '@inquirer/type': 4.1.1(@types/node@24.13.6) optionalDependencies: - '@types/node': 24.13.5 + '@types/node': 24.13.6 '@inquirer/number@4.2.3(@types/node@22.20.4)': dependencies: @@ -10310,12 +10319,12 @@ snapshots: optionalDependencies: '@types/node': 22.20.4 - '@inquirer/number@4.2.3(@types/node@24.13.5)': + '@inquirer/number@4.2.3(@types/node@24.13.6)': dependencies: - '@inquirer/core': 12.0.3(@types/node@24.13.5) - '@inquirer/type': 4.1.1(@types/node@24.13.5) + '@inquirer/core': 12.0.3(@types/node@24.13.6) + '@inquirer/type': 4.1.1(@types/node@24.13.6) optionalDependencies: - '@types/node': 24.13.5 + '@types/node': 24.13.6 '@inquirer/password@5.2.2(@types/node@22.20.4)': dependencies: @@ -10325,13 +10334,13 @@ snapshots: optionalDependencies: '@types/node': 22.20.4 - '@inquirer/password@5.2.2(@types/node@24.13.5)': + '@inquirer/password@5.2.2(@types/node@24.13.6)': dependencies: '@inquirer/ansi': 2.0.8 - '@inquirer/core': 12.0.3(@types/node@24.13.5) - '@inquirer/type': 4.1.1(@types/node@24.13.5) + '@inquirer/core': 12.0.3(@types/node@24.13.6) + '@inquirer/type': 4.1.1(@types/node@24.13.6) optionalDependencies: - '@types/node': 24.13.5 + '@types/node': 24.13.6 '@inquirer/prompts@8.7.2(@types/node@22.20.4)': dependencies: @@ -10348,20 +10357,20 @@ snapshots: optionalDependencies: '@types/node': 22.20.4 - '@inquirer/prompts@8.7.2(@types/node@24.13.5)': - dependencies: - '@inquirer/checkbox': 5.2.5(@types/node@24.13.5) - '@inquirer/confirm': 6.3.2(@types/node@24.13.5) - '@inquirer/editor': 5.3.3(@types/node@24.13.5) - '@inquirer/expand': 5.1.5(@types/node@24.13.5) - '@inquirer/input': 5.1.6(@types/node@24.13.5) - '@inquirer/number': 4.2.3(@types/node@24.13.5) - '@inquirer/password': 5.2.2(@types/node@24.13.5) - '@inquirer/rawlist': 5.3.5(@types/node@24.13.5) - '@inquirer/search': 4.3.3(@types/node@24.13.5) - '@inquirer/select': 5.2.5(@types/node@24.13.5) + '@inquirer/prompts@8.7.2(@types/node@24.13.6)': + dependencies: + '@inquirer/checkbox': 5.2.5(@types/node@24.13.6) + '@inquirer/confirm': 6.3.2(@types/node@24.13.6) + '@inquirer/editor': 5.3.3(@types/node@24.13.6) + '@inquirer/expand': 5.1.5(@types/node@24.13.6) + '@inquirer/input': 5.1.6(@types/node@24.13.6) + '@inquirer/number': 4.2.3(@types/node@24.13.6) + '@inquirer/password': 5.2.2(@types/node@24.13.6) + '@inquirer/rawlist': 5.3.5(@types/node@24.13.6) + '@inquirer/search': 4.3.3(@types/node@24.13.6) + '@inquirer/select': 5.2.5(@types/node@24.13.6) optionalDependencies: - '@types/node': 24.13.5 + '@types/node': 24.13.6 '@inquirer/rawlist@5.3.5(@types/node@22.20.4)': dependencies: @@ -10370,12 +10379,12 @@ snapshots: optionalDependencies: '@types/node': 22.20.4 - '@inquirer/rawlist@5.3.5(@types/node@24.13.5)': + '@inquirer/rawlist@5.3.5(@types/node@24.13.6)': dependencies: - '@inquirer/core': 12.0.3(@types/node@24.13.5) - '@inquirer/type': 4.1.1(@types/node@24.13.5) + '@inquirer/core': 12.0.3(@types/node@24.13.6) + '@inquirer/type': 4.1.1(@types/node@24.13.6) optionalDependencies: - '@types/node': 24.13.5 + '@types/node': 24.13.6 '@inquirer/search@4.3.3(@types/node@22.20.4)': dependencies: @@ -10385,13 +10394,13 @@ snapshots: optionalDependencies: '@types/node': 22.20.4 - '@inquirer/search@4.3.3(@types/node@24.13.5)': + '@inquirer/search@4.3.3(@types/node@24.13.6)': dependencies: - '@inquirer/core': 12.0.3(@types/node@24.13.5) + '@inquirer/core': 12.0.3(@types/node@24.13.6) '@inquirer/figures': 2.0.9 - '@inquirer/type': 4.1.1(@types/node@24.13.5) + '@inquirer/type': 4.1.1(@types/node@24.13.6) optionalDependencies: - '@types/node': 24.13.5 + '@types/node': 24.13.6 '@inquirer/select@5.2.5(@types/node@22.20.4)': dependencies: @@ -10402,22 +10411,22 @@ snapshots: optionalDependencies: '@types/node': 22.20.4 - '@inquirer/select@5.2.5(@types/node@24.13.5)': + '@inquirer/select@5.2.5(@types/node@24.13.6)': dependencies: '@inquirer/ansi': 2.0.8 - '@inquirer/core': 12.0.3(@types/node@24.13.5) + '@inquirer/core': 12.0.3(@types/node@24.13.6) '@inquirer/figures': 2.0.9 - '@inquirer/type': 4.1.1(@types/node@24.13.5) + '@inquirer/type': 4.1.1(@types/node@24.13.6) optionalDependencies: - '@types/node': 24.13.5 + '@types/node': 24.13.6 '@inquirer/type@4.1.1(@types/node@22.20.4)': optionalDependencies: '@types/node': 22.20.4 - '@inquirer/type@4.1.1(@types/node@24.13.5)': + '@inquirer/type@4.1.1(@types/node@24.13.6)': optionalDependencies: - '@types/node': 24.13.5 + '@types/node': 24.13.6 '@isaacs/cliui@8.0.2': dependencies: @@ -11500,7 +11509,7 @@ snapshots: dependencies: undici-types: 6.21.0 - '@types/node@24.13.5': + '@types/node@24.13.6': dependencies: undici-types: 7.18.2 @@ -14907,7 +14916,7 @@ snapshots: neo-async@2.6.2: {} - ng-packagr@22.2.0-rc.0(@angular/compiler-cli@22.2.0-rc.0(@angular/compiler@22.2.0-rc.0)(typescript@6.0.3))(supports-color@11.0.0)(tslib@2.8.1)(typescript@6.0.3): + ng-packagr@22.3.0-next.1(@angular/compiler-cli@22.2.0-rc.0(@angular/compiler@22.2.0-rc.0)(typescript@6.0.3))(supports-color@11.0.0)(tslib@2.8.1)(typescript@6.0.3): dependencies: '@ampproject/remapping': 2.3.0 '@angular/compiler-cli': 22.2.0-rc.0(@angular/compiler@22.2.0-rc.0)(typescript@6.0.3) @@ -16455,6 +16464,13 @@ snapshots: esbuild: 0.28.2 optionalDependencies: fsevents: 2.3.3 + optional: true + + tsx@4.23.15: + dependencies: + esbuild: 0.28.2 + optionalDependencies: + fsevents: 2.3.3 tsyringe@4.10.0: dependencies: @@ -16757,7 +16773,7 @@ snapshots: webidl-conversions@8.0.1: {} - webpack-dev-middleware@8.3.0(webpack@5.111.0(esbuild@0.28.2)(lightningcss@1.33.0)(uglify-js@3.19.3)): + webpack-dev-middleware@8.3.0(webpack@5.111.0(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.28)(uglify-js@3.19.3)): dependencies: ansi-html-community: 0.0.8 memfs: 4.78.1 @@ -16767,7 +16783,7 @@ snapshots: optionalDependencies: webpack: 5.111.0(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.28)(uglify-js@3.19.3) - webpack-dev-server@6.0.0(bufferutil@4.1.0)(supports-color@11.0.0)(utf-8-validate@6.0.6)(webpack@5.111.0(esbuild@0.28.2)(lightningcss@1.33.0)(uglify-js@3.19.3)): + webpack-dev-server@6.0.0(bufferutil@4.1.0)(supports-color@11.0.0)(utf-8-validate@6.0.6)(webpack@5.111.0(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.28)(uglify-js@3.19.3)): dependencies: '@types/bonjour': 3.5.13 '@types/connect-history-api-fallback': 1.5.4 @@ -16792,7 +16808,7 @@ snapshots: selfsigned: 5.5.0 serve-index: 1.9.2(supports-color@11.0.0) tinyglobby: 0.2.17 - webpack-dev-middleware: 8.3.0(webpack@5.111.0(esbuild@0.28.2)(lightningcss@1.33.0)(uglify-js@3.19.3)) + webpack-dev-middleware: 8.3.0(webpack@5.111.0(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.28)(uglify-js@3.19.3)) ws: 8.21.3(bufferutil@4.1.0)(utf-8-validate@6.0.6) optionalDependencies: webpack: 5.111.0(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.28)(uglify-js@3.19.3) @@ -17034,6 +17050,15 @@ snapshots: y18n: 5.0.8 yargs-parser: 22.0.0 + yargs@18.2.0: + dependencies: + cliui: 9.0.1 + escalade: 3.2.0 + get-caller-file: 2.0.5 + string-width: 8.2.2 + y18n: 5.0.8 + yargs-parser: 22.0.0 + yocto-queue@0.1.0: {} yoctocolors@2.2.0: {} diff --git a/tests/e2e/ng-snapshot/package.json b/tests/e2e/ng-snapshot/package.json index 09c58bceafaf..94cfc59a8fbc 100644 --- a/tests/e2e/ng-snapshot/package.json +++ b/tests/e2e/ng-snapshot/package.json @@ -2,21 +2,21 @@ "description": "snapshot versions of Angular for e2e testing", "private": true, "dependencies": { - "@angular/animations": "github:angular/animations-builds#3629fd701ede78443109c1b3f8859df7210590fa", - "@angular/cdk": "github:angular/cdk-builds#1ce55365568b0b1be4d17e9040d5d846f7b414d8", - "@angular/common": "github:angular/common-builds#9cc550da9cb1ddab14909300c6743c372890f7de", - "@angular/compiler": "github:angular/compiler-builds#3374daba464eaff8c9b7b6a5cbc4aafcf90f0f0d", - "@angular/compiler-cli": "github:angular/compiler-cli-builds#7ebc08586fd5efc81b876f37925e77ac35a8a085", - "@angular/core": "github:angular/core-builds#85e3d69306a27133011cc04abfe9c41f0de29cab", - "@angular/forms": "github:angular/forms-builds#3be01184155b0da47be9a7f412be3084743dbc81", - "@angular/language-service": "github:angular/language-service-builds#4f7fd2efabf368003ebd80570325d5d66de04ad3", - "@angular/localize": "github:angular/localize-builds#a5fe9a09abef68f8f097f0a25b5b848000d01583", - "@angular/material": "github:angular/material-builds#ddde2cfce1af33b5274b93d5d7d542bdc6bca22c", - "@angular/material-moment-adapter": "github:angular/material-moment-adapter-builds#174487e1cd9237dbf14cbdfea84bb5a08562b2be", - "@angular/platform-browser": "github:angular/platform-browser-builds#a654af512152687b53db07d42cfbf579e6d78577", - "@angular/platform-browser-dynamic": "github:angular/platform-browser-dynamic-builds#f13404dd1ab7b165d23aa9878dc9ceb35e4633c7", - "@angular/platform-server": "github:angular/platform-server-builds#7458cac7beb0e0ce9e20302e53ad536071642b60", - "@angular/router": "github:angular/router-builds#ab7a8c986d9ad71b55decd76fedfd4e1e3e0649e", - "@angular/service-worker": "github:angular/service-worker-builds#3e63f2bf5ab32dd3763508f08786fa72a3c04eee" + "@angular/animations": "github:angular/animations-builds#2f24800116a9ec7c753415e37168e35db0631128", + "@angular/cdk": "github:angular/cdk-builds#2d281bf4a19f9d7288d049bb25e5c3dda33b9e29", + "@angular/common": "github:angular/common-builds#e4cfaccc87a81e99295cfc87d049d6a5bd54b4fe", + "@angular/compiler": "github:angular/compiler-builds#e0e3723c18c2f37ea7dc4a19982e2dd354764f98", + "@angular/compiler-cli": "github:angular/compiler-cli-builds#de7a4f7a4ab751a672dce79aea28cde0bb127bb6", + "@angular/core": "github:angular/core-builds#d5e356996b818ced8c110e9244c6462cb76a4da8", + "@angular/forms": "github:angular/forms-builds#bde1c2c065f5bc59ff64d036047939890a12f649", + "@angular/language-service": "github:angular/language-service-builds#1ed23868f96b217c9cafbe7149879f1d8462ecca", + "@angular/localize": "github:angular/localize-builds#553ddb1954599093f9aebe6bc7b9fb0e4055cc52", + "@angular/material": "github:angular/material-builds#7e6bb5409fafc31357ad8339d66204e2fe878b0c", + "@angular/material-moment-adapter": "github:angular/material-moment-adapter-builds#190ee1896b13c29b3b8b766e6d34dfecd814894c", + "@angular/platform-browser": "github:angular/platform-browser-builds#0e587a01536a951c6bcde751743cddc78ce59c6b", + "@angular/platform-browser-dynamic": "github:angular/platform-browser-dynamic-builds#c6636d91276dbed9471edacd722707cab9bb382d", + "@angular/platform-server": "github:angular/platform-server-builds#4192fd34b84a67928582a19bdcace46dceafdb2c", + "@angular/router": "github:angular/router-builds#68b2c79d788e7b1a94caf206ce763c21a941816c", + "@angular/service-worker": "github:angular/service-worker-builds#902a33b18e039a66f89f42636020a2e654dfdf13" } } From d9682594bd15a2ca234f01104941480233dda5a6 Mon Sep 17 00:00:00 2001 From: ZainnQureshii <43629888+ZainnQureshii@users.noreply.github.com> Date: Thu, 24 Sep 2026 16:02:47 +0200 Subject: [PATCH 509/787] docs: fix stale Bazel test targets and toolchain versions --- docs/DEVELOPER.md | 8 ++++---- docs/process/bazel.md | 4 ++-- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/docs/DEVELOPER.md b/docs/DEVELOPER.md index 35b07adf1e89..ddb8341e662b 100644 --- a/docs/DEVELOPER.md +++ b/docs/DEVELOPER.md @@ -7,9 +7,9 @@ To get started locally, follow these instructions: 1. If you haven't done it already, [make a fork of this repo](https://github.com/angular/angular-cli/fork). 2. If you are on Windows, see [the extra steps needed for contributing on Windows](#windows) 3. Clone to your local computer using `git`. -4. Make sure that you have Node `v20.19.0` or higher installed. See instructions [here](https://nodejs.org/en/download/). +4. Make sure that you have Node `v22.22.3` or higher installed (see `engines` in `package.json`). See instructions [here](https://nodejs.org/en/download/). 5. Install `pnpm`. - - You can install pnpm by running `npm i -g pnpm@9`. + - You can install pnpm by running `npm i -g pnpm@12`. - See detailed instructions [here](https://pnpm.io/installation). 6. Run `pnpm install` from the root of your clone of this project to install dependencies. @@ -78,7 +78,7 @@ There are two different test suites which can be run locally: ### Unit tests - Run all tests: `pnpm bazel test //packages/...` -- Run a subset of the tests, use the full Bazel target example: `pnpm bazel test //packages/schematics/angular:angular_test` +- Run a subset of the tests, use the full Bazel target example: `pnpm bazel test //packages/schematics/angular:test` - For a complete list of test targets use the following Bazel query: `pnpm bazel query "tests(//packages/...)"` When debugging a specific test, change `describe()` or `it()` to `fdescribe()` @@ -166,7 +166,7 @@ You can use the Chrome Devtools to process it. To do so: Adding a package to this repository means running two separate commands: -1. `schematics devkit:package PACKAGE_NAME`. This will update the `.monorepo` file, and create the +1. `schematics devkit:package PACKAGE_NAME`. This will update the `.monorepo.json` file, and create the base files for the new package (package.json, src/index, etc). 1. `pnpm admin templates`. This will update the README and all other template files that might have changed when adding a new package. diff --git a/docs/process/bazel.md b/docs/process/bazel.md index 86542047745e..458d634ba9b6 100644 --- a/docs/process/bazel.md +++ b/docs/process/bazel.md @@ -65,7 +65,7 @@ the reruns of tests that have been marked as `flaky`. The `.bazelrc` includes a config for running tests with remote debugging enabled: ```sh -pnpm bazel test --config=debug //packages/angular/cli:angular-cli_test +pnpm bazel test --config=debug //packages/angular/cli:test # Also disable reruns of failing tests that were marked as flaky: -pnpm bazel test --config=debug --config=no-sharding //packages/angular/cli:angular-cli_test +pnpm bazel test --config=debug --config=no-sharding //packages/angular/cli:test ``` From 7ce093f6766d8499c57c4b4ad920e8e4005010b3 Mon Sep 17 00:00:00 2001 From: Alan Agius <17563226+alan-agius4@users.noreply.github.com> Date: Fri, 25 Sep 2026 08:08:12 +0000 Subject: [PATCH 510/787] refactor(@angular/build): export DEFAULT_ASSET_IGNORE from resolve-assets --- packages/angular/build/src/utils/resolve-assets.ts | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/packages/angular/build/src/utils/resolve-assets.ts b/packages/angular/build/src/utils/resolve-assets.ts index 71b1c0e4768b..41ae41d66b9b 100644 --- a/packages/angular/build/src/utils/resolve-assets.ts +++ b/packages/angular/build/src/utils/resolve-assets.ts @@ -10,6 +10,11 @@ import path from 'node:path'; import { glob } from 'tinyglobby'; import { isSubDirectory } from './path'; +/** + * Default glob ignore patterns for assets. + */ +export const DEFAULT_ASSET_IGNORE = ['.gitkeep', '**/.DS_Store', '**/Thumbs.db'] as const; + export async function resolveAssets( entries: { glob: string; @@ -21,8 +26,6 @@ export async function resolveAssets( }[], root: string, ): Promise<{ source: string; destination: string }[]> { - const defaultIgnore = ['.gitkeep', '**/.DS_Store', '**/Thumbs.db']; - const outputFiles: { source: string; destination: string }[] = []; for (const entry of entries) { @@ -35,7 +38,7 @@ export async function resolveAssets( const files = await glob(entry.glob, { cwd, dot: true, - ignore: entry.ignore ? defaultIgnore.concat(entry.ignore) : defaultIgnore, + ignore: entry.ignore ? [...DEFAULT_ASSET_IGNORE, ...entry.ignore] : DEFAULT_ASSET_IGNORE, followSymbolicLinks: entry.followSymlinks, }); From de91345c13640c6ad462e7ffa124a1e6faca20f1 Mon Sep 17 00:00:00 2001 From: Alan Agius <17563226+alan-agius4@users.noreply.github.com> Date: Fri, 25 Sep 2026 08:46:23 +0000 Subject: [PATCH 511/787] fix(@angular/build): reset component updates on dev-server SSR page request When server-side rendering is enabled (either internal or external mode), page reload requests are handled by the SSR middleware before reaching the index HTML middleware. As a result, `resetComponentUpdates` was never invoked on page reloads, causing stale component HMR updates to persist in `templateUpdates` and be re-applied over freshly rendered pages. We now pass `resetComponentUpdates` to `createAngularSsrInternalMiddleware` and `createAngularSsrExternalMiddleware`, and trigger it when an SSR HTML transform occurs (`html:transform:pre`). Fixes #34163 --- packages/angular/build/BUILD.bazel | 1 + .../tools/vite/middlewares/ssr-middleware.ts | 8 +- .../vite/middlewares/ssr-middleware_spec.ts | 130 ++++++++++++++++++ .../vite/plugins/setup-middlewares-plugin.ts | 12 +- 4 files changed, 147 insertions(+), 4 deletions(-) create mode 100644 packages/angular/build/src/tools/vite/middlewares/ssr-middleware_spec.ts diff --git a/packages/angular/build/BUILD.bazel b/packages/angular/build/BUILD.bazel index 9a4de3b5aa64..d648331b70de 100644 --- a/packages/angular/build/BUILD.bazel +++ b/packages/angular/build/BUILD.bazel @@ -148,6 +148,7 @@ ts_project( ":node_modules/@babel/core", ":node_modules/oxc-parser", "//:node_modules/@angular/compiler-cli", + "//:node_modules/@angular/router", "//:node_modules/@types/jasmine", "//:node_modules/esbuild", "//:node_modules/prettier", diff --git a/packages/angular/build/src/tools/vite/middlewares/ssr-middleware.ts b/packages/angular/build/src/tools/vite/middlewares/ssr-middleware.ts index 78458624c4db..c75c63e992bb 100644 --- a/packages/angular/build/src/tools/vite/middlewares/ssr-middleware.ts +++ b/packages/angular/build/src/tools/vite/middlewares/ssr-middleware.ts @@ -21,6 +21,7 @@ import { export function createAngularSsrInternalMiddleware( server: ViteDevServer, + resetComponentUpdates: () => void, indexHtmlTransformer?: (content: string) => Promise, ): Connect.NextHandleFunction { let cachedAngularServerApp: ReturnType | undefined; @@ -53,6 +54,7 @@ export function createAngularSsrInternalMiddleware( // Only Add the transform hook only if it's a different instance. if (cachedAngularServerApp !== angularServerApp) { angularServerApp.hooks.on('html:transform:pre', async ({ html, url }) => { + resetComponentUpdates(); const processedHtml = await server.transformIndexHtml(url.pathname, html); return indexHtmlTransformer?.(processedHtml) ?? processedHtml; @@ -76,13 +78,13 @@ export function createAngularSsrInternalMiddleware( export async function createAngularSsrExternalMiddleware( server: ViteDevServer, + resetComponentUpdates: () => void, indexHtmlTransformer?: (content: string) => Promise, ): Promise { let fallbackWarningShown = false; let cachedAngularAppEngine: typeof SSRAngularAppEngine | undefined; let angularSsrInternalMiddleware: - | ReturnType - | undefined; + ReturnType | undefined; // Load the compiler because `@angular/ssr/node` depends on `@angular/` packages, // which must be processed by the runtime linker, even if they are not used. @@ -120,6 +122,7 @@ export async function createAngularSsrExternalMiddleware( angularSsrInternalMiddleware ??= createAngularSsrInternalMiddleware( server, + resetComponentUpdates, indexHtmlTransformer, ); @@ -132,6 +135,7 @@ export async function createAngularSsrExternalMiddleware( AngularAppEngine.ɵdisableAllowedHostsCheck = disableAllowedHostsCheck; AngularAppEngine.ɵallowStaticRouteRender = true; AngularAppEngine.ɵhooks.on('html:transform:pre', async ({ html, url }) => { + resetComponentUpdates(); const processedHtml = await server.transformIndexHtml(url.pathname, html); return indexHtmlTransformer?.(processedHtml) ?? processedHtml; diff --git a/packages/angular/build/src/tools/vite/middlewares/ssr-middleware_spec.ts b/packages/angular/build/src/tools/vite/middlewares/ssr-middleware_spec.ts new file mode 100644 index 000000000000..a61011043a43 --- /dev/null +++ b/packages/angular/build/src/tools/vite/middlewares/ssr-middleware_spec.ts @@ -0,0 +1,130 @@ +/** + * @license + * Copyright Google LLC All Rights Reserved. + * + * Use of this source code is governed by an MIT-style license that can be + * found in the LICENSE file at https://angular.dev/license + */ + +import type { IncomingMessage, ServerResponse } from 'node:http'; +import { + createAngularSsrExternalMiddleware, + createAngularSsrInternalMiddleware, +} from './ssr-middleware'; + +type ViteDevServer = Parameters[0]; + +describe('SSR dev-server middleware', () => { + function createMockReqRes(): { req: IncomingMessage; res: ServerResponse } { + const req = { + url: '/', + method: 'GET', + headers: { host: 'localhost' }, + } as unknown as IncomingMessage; + + const res = { + statusCode: 200, + setHeader: jasmine.createSpy('setHeader'), + writeHead: jasmine.createSpy('writeHead'), + end: jasmine.createSpy('end'), + } as unknown as ServerResponse; + + return { req, res }; + } + + it('resets component updates when html:transform:pre executes in internal SSR middleware', async () => { + let hookCallback: ((args: { html: string; url: URL }) => Promise) | undefined; + const resetComponentUpdates = jasmine.createSpy('resetComponentUpdates'); + let resolveHookRegistered!: () => void; + const hookRegistered = new Promise((resolve) => { + resolveHookRegistered = resolve; + }); + + const fakeAngularServerApp = { + hooks: { + on: (_name: string, cb: typeof hookCallback) => { + hookCallback = cb; + resolveHookRegistered(); + }, + }, + handle: jasmine.createSpy('handle').and.resolveTo(new Response('rendered')), + }; + + const server = { + config: { server: { allowedHosts: true }, base: '/' }, + ssrLoadModule: jasmine.createSpy('ssrLoadModule').and.resolveTo({ + ɵgetOrCreateAngularServerApp: () => fakeAngularServerApp, + }), + transformIndexHtml: jasmine + .createSpy('transformIndexHtml') + .and.callFake(async (_path: string, html: string) => html), + } as unknown as ViteDevServer; + + const middleware = createAngularSsrInternalMiddleware( + server, + resetComponentUpdates, + async (html) => html + '', + ); + + const { req, res } = createMockReqRes(); + middleware(req, res, () => {}); + + await hookRegistered; + + expect(resetComponentUpdates).not.toHaveBeenCalled(); + expect(hookCallback).toBeDefined(); + const result = await hookCallback?.({ + html: '
test
', + url: new URL('http://localhost/'), + }); + expect(resetComponentUpdates).toHaveBeenCalledTimes(1); + expect(result).toBe('
test
'); + }); + + it('resets component updates when html:transform:pre executes in external SSR middleware', async () => { + let hookCallback: ((args: { html: string; url: URL }) => Promise) | undefined; + const resetComponentUpdates = jasmine.createSpy('resetComponentUpdates'); + let resolveHookRegistered!: () => void; + const hookRegistered = new Promise((resolve) => { + resolveHookRegistered = resolve; + }); + + class FakeAngularAppEngine { + static ɵhooks = { + on: (_name: string, cb: typeof hookCallback) => { + hookCallback = cb; + resolveHookRegistered(); + }, + }; + static ɵdisableAllowedHostsCheck: boolean; + static ɵallowStaticRouteRender: boolean; + } + + const server = { + config: { server: { allowedHosts: true }, base: '/' }, + ssrLoadModule: jasmine.createSpy('ssrLoadModule').and.resolveTo({ + reqHandler: Object.assign(() => new Response('ok'), { __ng_request_handler__: true }), + AngularAppEngine: FakeAngularAppEngine, + }), + transformIndexHtml: jasmine + .createSpy('transformIndexHtml') + .and.callFake(async (_path: string, html: string) => html + ''), + } as unknown as ViteDevServer; + + const middleware = await createAngularSsrExternalMiddleware(server, resetComponentUpdates); + + const { req, res } = createMockReqRes(); + middleware(req, res, () => {}); + + await hookRegistered; + + expect(resetComponentUpdates).not.toHaveBeenCalled(); + expect(hookCallback).toBeDefined(); + const result = await hookCallback?.({ + html: '
test
', + url: new URL('http://localhost/'), + }); + expect(resetComponentUpdates).toHaveBeenCalledTimes(1); + expect(result).toBe('
test
'); + }); +}); diff --git a/packages/angular/build/src/tools/vite/plugins/setup-middlewares-plugin.ts b/packages/angular/build/src/tools/vite/plugins/setup-middlewares-plugin.ts index 78e16304f01d..34b0704f4091 100644 --- a/packages/angular/build/src/tools/vite/plugins/setup-middlewares-plugin.ts +++ b/packages/angular/build/src/tools/vite/plugins/setup-middlewares-plugin.ts @@ -117,13 +117,21 @@ export function createAngularSetupMiddlewaresPlugin( if (ssrMode === ServerSsrMode.ExternalSsrMiddleware) { patchBaseMiddleware(server.middlewares, server.config.base); - middlewares.use(await createAngularSsrExternalMiddleware(server, indexHtmlTransformer)); + middlewares.use( + await createAngularSsrExternalMiddleware( + server, + resetComponentUpdates, + indexHtmlTransformer, + ), + ); return; } if (ssrMode === ServerSsrMode.InternalSsrMiddleware) { - middlewares.use(createAngularSsrInternalMiddleware(server, indexHtmlTransformer)); + middlewares.use( + createAngularSsrInternalMiddleware(server, resetComponentUpdates, indexHtmlTransformer), + ); } middlewares.use(angularHtmlFallbackMiddleware); From 91b0947898cef9de69d8aa337927fc12806065f6 Mon Sep 17 00:00:00 2001 From: Charles Lyding <19598772+clydin@users.noreply.github.com> Date: Thu, 24 Sep 2026 15:09:21 -0400 Subject: [PATCH 512/787] fix(@angular/build): prevent chokidar from scanning unimported node_modules in watch mode When using Chokidar (such as when `preserveSymlinks: true` is configured or polling is active), Chokidar's initial filesystem scan previously walked the entire `workspaceRoot`, including all of `node_modules`. Because `await once(watcher, 'ready')` blocks until the initial scan completes, this caused watch mode in commands like `ng test`, `ng serve`, and `ng build --watch` to hang for minutes before emitting the first build result. This commit introduces selective `node_modules` filtering in Chokidar: - `node_modules` packages corresponding to imported build files (e.g. `npm link` libraries, both unscoped and scoped) are allowed and their directories watched, retaining native symlink traversal. - All other unimported subdirectories in `node_modules` are pruned and ignored during the initial scan and subsequent directory visits. - Packages added dynamically via `watcher.add()` are registered and watched on the fly. Fixes #34162 --- packages/angular/build/src/utils/watcher.ts | 173 ++++++++++- .../angular/build/src/utils/watcher_spec.ts | 282 +++++++++++++++++- 2 files changed, 433 insertions(+), 22 deletions(-) diff --git a/packages/angular/build/src/utils/watcher.ts b/packages/angular/build/src/utils/watcher.ts index be38151f7a48..8d47ba48e907 100644 --- a/packages/angular/build/src/utils/watcher.ts +++ b/packages/angular/build/src/utils/watcher.ts @@ -49,6 +49,9 @@ export interface WatcherOptions { cwd?: string; } +const NODE_MODULES = 'node_modules'; +const NODE_MODULES_SEGMENT = `/${NODE_MODULES}/`; + // Watch workspace for package manager changes const packageWatchFiles = [ // manifest can affect module resolution @@ -109,7 +112,7 @@ export async function setupWatcher(options: SetupWatcherOptions): Promise(); private readonly pendingSubscriptions = new Map< @@ -625,6 +658,94 @@ async function createParcelWatcher( return buildWatcher; } +/** + * Manages selective node_modules watching for Chokidar. + * + * During Chokidar's initial scan, the allowed packages set is empty, causing Chokidar to prune the entire + * node_modules directory immediately and avoid blocking the 'ready' event for minutes. + * Packages are dynamically allowed and watched at the package root level as files are added via `watcher.add`. + * Tracking files per package allows reference-counting so that package directories are unwatched when no + * longer needed. + */ +class ChokidarNodeModulesManager { + private readonly allowedPackages = new Map>(); + + constructor(private readonly isCaseSensitive: boolean) {} + + registerPackage( + posixPath: string, + lookupKey: string, + ): { isPackage: boolean; newPkgDir?: string } { + const packageDir = extractNodeModulesPackageDir(posixPath); + if (!packageDir) { + return { isPackage: false }; + } + + const packageKey = toLookupKey(packageDir, this.isCaseSensitive); + let watchedInPkg = this.allowedPackages.get(packageKey); + if (!watchedInPkg) { + watchedInPkg = new Set(); + this.allowedPackages.set(packageKey, watchedInPkg); + watchedInPkg.add(lookupKey); + + return { isPackage: true, newPkgDir: packageDir }; + } + + watchedInPkg.add(lookupKey); + + return { isPackage: true }; + } + + removePackageFile( + posixPath: string, + lookupKey: string, + ): { isPackage: boolean; unwatchPkgDir?: string } { + const packageDir = extractNodeModulesPackageDir(posixPath); + if (!packageDir) { + return { isPackage: false }; + } + + const packageKey = toLookupKey(packageDir, this.isCaseSensitive); + const watchedInPkg = this.allowedPackages.get(packageKey); + if (watchedInPkg) { + watchedInPkg.delete(lookupKey); + if (watchedInPkg.size === 0) { + this.allowedPackages.delete(packageKey); + + return { isPackage: true, unwatchPkgDir: packageDir }; + } + } + + return { isPackage: true }; + } + + isIgnored(filePath: string): boolean { + // Fast path: avoid expensive normalization for non-node_modules files + if (!filePath.includes(NODE_MODULES)) { + return false; + } + + const posixPath = toPosixPathNormalized(filePath); + const lookupKey = toLookupKey(posixPath, this.isCaseSensitive); + + if (!`${lookupKey}/`.includes(NODE_MODULES_SEGMENT)) { + return false; + } + + if (this.allowedPackages.has(lookupKey)) { + return false; + } + + for (const pkg of this.allowedPackages.keys()) { + if (isPathInside(lookupKey, pkg)) { + return false; + } + } + + return true; + } +} + async function createChokidarWatcher( options?: WatcherOptions, chokidarModule?: typeof Chokidar, @@ -647,15 +768,25 @@ async function createChokidarWatcher( const rootDirPosix = toPosixPathNormalized(rootDir); const rootDirLookupKey = toLookupKey(rootDirPosix, isCaseSensitive); - const ignored = options?.ignored?.map((pattern) => { - if (/[*?[\]{}()]/.test(pattern)) { - const isMatch = picomatch(pattern, { dot: true }); + const nodeModulesManager = new ChokidarNodeModulesManager(isCaseSensitive); - return (filePath: string) => isMatch(toPosixPathNormalized(filePath)); - } + // Strip static node_modules ignore patterns (e.g. `**/node_modules/**` from setupWatcher). + // If left in place, picomatch would unconditionally ignore all node_modules files and override + // our dynamic package allowlist above. + const customIgnored = + options?.ignored + ?.filter((pattern) => !pattern.includes(NODE_MODULES)) + .map((pattern) => { + if (/[*?[\]{}()]/.test(pattern)) { + const isMatch = picomatch(pattern, { dot: true }); - return { path: toPosixPathNormalized(pattern), recursive: true }; - }); + return (filePath: string) => isMatch(toPosixPathNormalized(filePath)); + } + + return { path: toPosixPathNormalized(pattern), recursive: true }; + }) ?? []; + + const ignored = [...customIgnored, (filePath: string) => nodeModulesManager.isIgnored(filePath)]; const watcher = chokidar.watch(rootDir, { ignoreInitial: true, @@ -714,7 +845,17 @@ async function createChokidarWatcher( const lookupKey = toLookupKey(posixPath, isCaseSensitive); if (!watchedFiles.has(lookupKey)) { watchedFiles.add(lookupKey); - if (!isPathInside(lookupKey, rootDirLookupKey) && lookupKey !== rootDirLookupKey) { + + // For files inside node_modules, register their package directory. Only newly encountered + // package directories need to be added to Chokidar. + const { isPackage, newPkgDir } = nodeModulesManager.registerPackage(posixPath, lookupKey); + if (newPkgDir) { + newPaths.push(newPkgDir); + } else if ( + !isPackage && + !isPathInside(lookupKey, rootDirLookupKey) && + lookupKey !== rootDirLookupKey + ) { newPaths.push(posixPath); } } @@ -732,7 +873,19 @@ async function createChokidarWatcher( const lookupKey = toLookupKey(posixPath, isCaseSensitive); if (watchedFiles.has(lookupKey)) { watchedFiles.delete(lookupKey); - if (!isPathInside(lookupKey, rootDirLookupKey) && lookupKey !== rootDirLookupKey) { + + // When the last watched file in a package is removed, unwatch the package directory. + const { isPackage, unwatchPkgDir } = nodeModulesManager.removePackageFile( + posixPath, + lookupKey, + ); + if (unwatchPkgDir) { + removePaths.push(unwatchPkgDir); + } else if ( + !isPackage && + !isPathInside(lookupKey, rootDirLookupKey) && + lookupKey !== rootDirLookupKey + ) { removePaths.push(posixPath); } } diff --git a/packages/angular/build/src/utils/watcher_spec.ts b/packages/angular/build/src/utils/watcher_spec.ts index e051c44bd3f2..547ad2695f90 100644 --- a/packages/angular/build/src/utils/watcher_spec.ts +++ b/packages/angular/build/src/utils/watcher_spec.ts @@ -6,14 +6,15 @@ * found in the LICENSE file at https://angular.dev/license */ +import assert from 'node:assert'; import * as fs from 'node:fs'; -import * as os from 'node:os'; import * as path from 'node:path'; import { setTimeout } from 'node:timers/promises'; import { type BuildWatcher, ChangedFiles, createWatcher, + extractNodeModulesPackageDir, getDirectoryPath, isPathInside, setupWatcher, @@ -21,6 +22,9 @@ import { } from './watcher'; describe('Watcher', () => { + const TMP_DIR = process.env['TEST_TMPDIR']; + assert(TMP_DIR, 'TEST_TMPDIR must be set'); + describe('toPosixPathNormalized', () => { it('should strip trailing slashes for standard directories', () => { expect(toPosixPathNormalized('/src/app/')).toBe('/src/app'); @@ -57,6 +61,30 @@ describe('Watcher', () => { }); }); + describe('extractNodeModulesPackageDir', () => { + it('should extract unscoped package directory', () => { + expect(extractNodeModulesPackageDir('/project/node_modules/my-lib/index.js')).toBe( + '/project/node_modules/my-lib', + ); + }); + + it('should extract scoped package directory', () => { + expect( + extractNodeModulesPackageDir('/project/node_modules/@my-scope/my-lib/src/index.js'), + ).toBe('/project/node_modules/@my-scope/my-lib'); + }); + + it('should handle package directory path directly', () => { + expect(extractNodeModulesPackageDir('/project/node_modules/my-lib')).toBe( + '/project/node_modules/my-lib', + ); + }); + + it('should return undefined for paths outside node_modules', () => { + expect(extractNodeModulesPackageDir('/project/src/main.ts')).toBeUndefined(); + }); + }); + describe('isPathInside', () => { it('should return true for a file inside a directory', () => { expect(isPathInside('/src/app/main.ts', '/src/app')).toBeTrue(); @@ -122,7 +150,7 @@ describe('Watcher', () => { let tempDir: string; beforeEach(() => { - tempDir = fs.realpathSync(fs.mkdtempSync(path.join(os.tmpdir(), 'setup-watcher-spec-'))); + tempDir = fs.mkdtempSync(path.join(TMP_DIR, 'setup-watcher-spec-')); }); afterEach(() => { @@ -166,13 +194,53 @@ describe('Watcher', () => { await watcher.close(); expect(removeSpy).toHaveBeenCalledWith('abort', jasmine.any(Function)); }); + + it('should setup watcher with preserveSymlinks: true and detect changes in linked package in node_modules', async () => { + const externalDir = fs.mkdtempSync(path.join(TMP_DIR, 'setup-watcher-npm-link-')); + + try { + const externalTargetFile = path.join(externalDir, 'index.ts'); + fs.writeFileSync(externalTargetFile, 'export const a = 1;'); + + const nodeModulesDir = path.join(tempDir, 'node_modules'); + fs.mkdirSync(nodeModulesDir); + + const linkedPkgDir = path.join(nodeModulesDir, 'linked-pkg'); + fs.symlinkSync(externalDir, linkedPkgDir, 'junction'); + const linkedFile = path.join(linkedPkgDir, 'index.ts'); + + const watcher = await setupWatcher({ + workspaceRoot: tempDir, + projectRoot: tempDir, + outputPath: path.join(tempDir, 'dist'), + cacheOptions: { basePath: path.join(tempDir, '.cache') }, + preserveSymlinks: true, + watchFiles: [linkedFile], + }); + + await setTimeout(250); + + const iterator = watcher[Symbol.asyncIterator](); + const nextPromise = iterator.next(); + + fs.writeFileSync(externalTargetFile, 'export const a = 2;'); + + const result = await nextPromise; + expect(result.done).toBeFalsy(); + expect(result.value?.all.some((f: string) => f.includes('linked-pkg'))).toBeTrue(); + + await watcher.close(); + } finally { + fs.rmSync(externalDir, { recursive: true, force: true }); + } + }, 10000); }); describe('createWatcher', () => { let tempDir: string; beforeEach(() => { - tempDir = fs.realpathSync(fs.mkdtempSync(path.join(os.tmpdir(), 'watcher-spec-'))); + tempDir = fs.mkdtempSync(path.join(TMP_DIR, 'watcher-spec-')); }); afterEach(() => { @@ -279,7 +347,7 @@ describe('Watcher', () => { }, 10000); it('should support watching paths outside cwd', async () => { - const externalDir = fs.mkdtempSync(path.join(os.tmpdir(), 'external-watcher-spec-')); + const externalDir = fs.mkdtempSync(path.join(TMP_DIR, 'external-watcher-spec-')); const externalFile = path.join(externalDir, 'external.txt'); fs.writeFileSync(externalFile, 'initial'); @@ -305,7 +373,7 @@ describe('Watcher', () => { }, 10000); it('should handle adding multiple external files in the same directory concurrently', async () => { - const externalDir = fs.mkdtempSync(path.join(os.tmpdir(), 'external-watcher-spec-')); + const externalDir = fs.mkdtempSync(path.join(TMP_DIR, 'external-watcher-spec-')); const file1 = path.join(externalDir, 'file1.txt'); const file2 = path.join(externalDir, 'file2.txt'); fs.writeFileSync(file1, 'initial1'); @@ -335,7 +403,7 @@ describe('Watcher', () => { }, 10000); it('should clean up external subscriptions when all external files in a directory are removed', async () => { - const externalDir = fs.mkdtempSync(path.join(os.tmpdir(), 'external-watcher-spec-')); + const externalDir = fs.mkdtempSync(path.join(TMP_DIR, 'external-watcher-spec-')); const file1 = path.join(externalDir, 'file1.txt'); const file2 = path.join(externalDir, 'file2.txt'); fs.writeFileSync(file1, 'initial1'); @@ -358,7 +426,7 @@ describe('Watcher', () => { }); it('should handle nested external directories without creating duplicate subscriptions', async () => { - const externalDir = fs.mkdtempSync(path.join(os.tmpdir(), 'external-watcher-spec-')); + const externalDir = fs.mkdtempSync(path.join(TMP_DIR, 'external-watcher-spec-')); const subDir = path.join(externalDir, 'sub'); fs.mkdirSync(subDir); const parentFile = path.join(externalDir, 'parent.txt'); @@ -389,7 +457,7 @@ describe('Watcher', () => { }, 10000); it('should subscribe to subsumed external child directory when parent external subscription is removed', async () => { - const externalDir = fs.mkdtempSync(path.join(os.tmpdir(), 'external-watcher-spec-')); + const externalDir = fs.mkdtempSync(path.join(TMP_DIR, 'external-watcher-spec-')); const subDir = path.join(externalDir, 'sub'); fs.mkdirSync(subDir); const parentFile = path.join(externalDir, 'parent.txt'); @@ -536,9 +604,7 @@ describe('Watcher', () => { }, 10000); it('should detect changes behind a directory symlink when followSymlinks is true', async () => { - const externalDir = fs.realpathSync( - fs.mkdtempSync(path.join(os.tmpdir(), 'watcher-external-')), - ); + const externalDir = fs.mkdtempSync(path.join(TMP_DIR, 'watcher-external-')); let watcher: BuildWatcher | undefined; try { @@ -556,7 +622,7 @@ describe('Watcher', () => { }); watcher.add(symlinkedFile); - await setTimeout(150); + await setTimeout(250); const iterator = watcher[Symbol.asyncIterator](); const nextPromise = iterator.next(); @@ -571,5 +637,197 @@ describe('Watcher', () => { fs.rmSync(externalDir, { recursive: true, force: true }); } }, 10000); + + it('should detect changes in linked package in node_modules while ignoring unimported packages', async () => { + const externalDir = fs.mkdtempSync(path.join(TMP_DIR, 'watcher-npm-link-')); + let watcher: BuildWatcher | undefined; + + try { + const externalTargetFile = path.join(externalDir, 'index.ts'); + fs.writeFileSync(externalTargetFile, 'export const a = 1;'); + + const nodeModulesDir = path.join(tempDir, 'node_modules'); + fs.mkdirSync(nodeModulesDir); + + // Unimported package that should be ignored + const unimportedPkgDir = path.join(nodeModulesDir, 'unimported-pkg'); + fs.mkdirSync(unimportedPkgDir); + const unimportedFile = path.join(unimportedPkgDir, 'dep.ts'); + fs.writeFileSync(unimportedFile, 'export const dep = 1;'); + + // Linked package in node_modules + const linkedPkgDir = path.join(nodeModulesDir, 'linked-pkg'); + fs.symlinkSync(externalDir, linkedPkgDir, 'junction'); + const linkedFile = path.join(linkedPkgDir, 'index.ts'); + + watcher = await createWatcher({ + followSymlinks: true, + cwd: tempDir, + }); + + watcher.add(linkedFile); + await setTimeout(250); + + const iterator = watcher[Symbol.asyncIterator](); + const nextPromise = iterator.next(); + + // Modify both the linked file and the unimported file + fs.writeFileSync(unimportedFile, 'export const dep = 2;'); + fs.writeFileSync(externalTargetFile, 'export const a = 2;'); + + const result = await nextPromise; + expect(result.done).toBeFalsy(); + const changed = result.value?.all ?? []; + expect(changed.some((f: string) => f.includes('linked-pkg'))).toBeTrue(); + expect(changed.some((f: string) => f.includes('unimported-pkg'))).toBeFalse(); + } finally { + await watcher?.close(); + fs.rmSync(externalDir, { recursive: true, force: true }); + } + }, 10000); + + it('should detect changes in scoped linked package in node_modules', async () => { + const externalDir = fs.mkdtempSync(path.join(TMP_DIR, 'watcher-scoped-npm-link-')); + let watcher: BuildWatcher | undefined; + + try { + const externalTargetFile = path.join(externalDir, 'index.ts'); + fs.writeFileSync(externalTargetFile, 'export const a = 1;'); + + const nodeModulesDir = path.join(tempDir, 'node_modules'); + const scopeDir = path.join(nodeModulesDir, '@my-scope'); + fs.mkdirSync(scopeDir, { recursive: true }); + + // Unimported package in scope + const unimportedScopedDir = path.join(scopeDir, 'unimported-scoped'); + fs.mkdirSync(unimportedScopedDir); + const unimportedFile = path.join(unimportedScopedDir, 'dep.ts'); + fs.writeFileSync(unimportedFile, 'export const dep = 1;'); + + // Linked scoped package in node_modules + const linkedPkgDir = path.join(scopeDir, 'linked-pkg'); + fs.symlinkSync(externalDir, linkedPkgDir, 'junction'); + const linkedFile = path.join(linkedPkgDir, 'index.ts'); + + watcher = await createWatcher({ + followSymlinks: true, + cwd: tempDir, + }); + + watcher.add(linkedFile); + await setTimeout(250); + + const iterator = watcher[Symbol.asyncIterator](); + const nextPromise = iterator.next(); + + fs.writeFileSync(unimportedFile, 'export const dep = 2;'); + fs.writeFileSync(externalTargetFile, 'export const a = 2;'); + + const result = await nextPromise; + expect(result.done).toBeFalsy(); + const changed = result.value?.all ?? []; + expect(changed.some((f: string) => f.includes('linked-pkg'))).toBeTrue(); + expect(changed.some((f: string) => f.includes('unimported-scoped'))).toBeFalse(); + } finally { + await watcher?.close(); + fs.rmSync(externalDir, { recursive: true, force: true }); + } + }, 10000); + + it('should detect changes in linked package added dynamically via watcher.add', async () => { + const externalDir = fs.mkdtempSync(path.join(TMP_DIR, 'watcher-dynamic-npm-link-')); + let watcher: BuildWatcher | undefined; + + try { + const externalTargetFile = path.join(externalDir, 'index.ts'); + fs.writeFileSync(externalTargetFile, 'export const a = 1;'); + + const nodeModulesDir = path.join(tempDir, 'node_modules'); + fs.mkdirSync(nodeModulesDir); + + const linkedPkgDir = path.join(nodeModulesDir, 'linked-pkg'); + fs.symlinkSync(externalDir, linkedPkgDir, 'junction'); + const linkedFile = path.join(linkedPkgDir, 'index.ts'); + + // Initially create watcher with no watchFiles + watcher = await createWatcher({ + followSymlinks: true, + cwd: tempDir, + }); + + // Add linked file dynamically after watcher creation + watcher.add(linkedFile); + await setTimeout(250); + + const iterator = watcher[Symbol.asyncIterator](); + const nextPromise = iterator.next(); + + fs.writeFileSync(externalTargetFile, 'export const a = 2;'); + + const result = await nextPromise; + expect(result.done).toBeFalsy(); + expect(result.value?.all.some((f: string) => f.includes('linked-pkg'))).toBeTrue(); + } finally { + await watcher?.close(); + fs.rmSync(externalDir, { recursive: true, force: true }); + } + }, 10000); + + it('should unwatch linked package directory when all its files are removed via watcher.remove', async () => { + const externalDir = fs.mkdtempSync(path.join(TMP_DIR, 'watcher-remove-npm-link-')); + let watcher: BuildWatcher | undefined; + + try { + const externalTargetFile = path.join(externalDir, 'index.ts'); + fs.writeFileSync(externalTargetFile, 'export const a = 1;'); + + const nodeModulesDir = path.join(tempDir, 'node_modules'); + fs.mkdirSync(nodeModulesDir); + + const linkedPkgDir = path.join(nodeModulesDir, 'linked-pkg'); + fs.symlinkSync(externalDir, linkedPkgDir, 'junction'); + const linkedFile = path.join(linkedPkgDir, 'index.ts'); + + const regularFile = path.join(tempDir, 'main.ts'); + fs.writeFileSync(regularFile, 'export const main = 1;'); + + watcher = await createWatcher({ + followSymlinks: true, + cwd: tempDir, + }); + + watcher.add([linkedFile, regularFile]); + // Allow a brief moment for Chokidar to register the new watch paths + await setTimeout(250); + + const iterator = watcher[Symbol.asyncIterator](); + + // Verify changes in the linked package are detected initially + let nextPromise = iterator.next(); + fs.writeFileSync(externalTargetFile, 'export const a = 2;'); + let result = await nextPromise; + expect(result.done).toBeFalsy(); + expect(result.value?.all.some((f: string) => f.includes('linked-pkg'))).toBeTrue(); + + // Remove the linked file from the watcher + watcher.remove(linkedFile); + // Allow a brief moment for Chokidar to asynchronously complete unwatching the package directory + await setTimeout(250); + + // Modify both the removed linked file and the regular file + nextPromise = iterator.next(); + fs.writeFileSync(externalTargetFile, 'export const a = 3;'); + fs.writeFileSync(regularFile, 'export const main = 2;'); + + result = await nextPromise; + expect(result.done).toBeFalsy(); + const changed = result.value?.all ?? []; + expect(changed.some((f: string) => f.includes('main.ts'))).toBeTrue(); + expect(changed.some((f: string) => f.includes('linked-pkg'))).toBeFalse(); + } finally { + await watcher?.close(); + fs.rmSync(externalDir, { recursive: true, force: true }); + } + }, 10000); }); }); From 05309443082bb2edc43b18da4f3e51d176d5b761 Mon Sep 17 00:00:00 2001 From: Maruthan G Date: Fri, 25 Sep 2026 09:46:41 +0000 Subject: [PATCH 513/787] fix(@schematics/angular): add browsers option to angular.json during vitest browser provider ng-add When adding a Vitest browser provider via ng-add, the schematic now automatically configures the 'browsers' option in angular.json with an appropriate default browser (chromium for Playwright/Preview, chrome for WebDriverIO) instead of only logging a manual instruction. Fixes #32401 --- .../angular/vitest-browser/index.ts | 16 ++++- .../angular/vitest-browser/index_spec.ts | 70 ++++++++++++++----- 2 files changed, 64 insertions(+), 22 deletions(-) diff --git a/packages/schematics/angular/vitest-browser/index.ts b/packages/schematics/angular/vitest-browser/index.ts index 78c3bdc6179d..927ac81aa4f1 100644 --- a/packages/schematics/angular/vitest-browser/index.ts +++ b/packages/schematics/angular/vitest-browser/index.ts @@ -22,7 +22,7 @@ import { } from '../utility/dependency'; import { JSONFile } from '../utility/json-file'; import { latestVersions } from '../utility/latest-versions'; -import { getWorkspace } from '../utility/workspace'; +import { getWorkspace, updateWorkspace } from '../utility/workspace'; import { Builders } from '../utility/workspace-models'; import { Schema as VitestBrowserOptions } from './schema'; @@ -89,8 +89,19 @@ export default function (options: VitestBrowserOptions): Rule { } }; + // Update angular.json to add the browsers option to the test target + const defaultBrowser = packageName === '@vitest/browser-webdriverio' ? 'chrome' : 'chromium'; + return chain([ updateTsConfigRule, + updateWorkspace((workspace) => { + const testTarget = workspace.projects.get(options.project)?.targets.get('test'); + + if (testTarget) { + testTarget.options ??= {}; + testTarget.options['browsers'] ??= [defaultBrowser]; + } + }), ...dependencies.map((name) => addDependency(name, latestVersions[name], { type: DependencyType.Dev, @@ -101,8 +112,7 @@ export default function (options: VitestBrowserOptions): Rule { (_, context) => { context.logger.info( 'Vitest browser testing support has been added. ' + - "To run tests in a browser, add a 'browsers' field to the 'test' target in 'angular.json', " + - "or use the '--browsers' command line option.", + `The test target has been configured with '${defaultBrowser}' as browser.`, ); }, ]); diff --git a/packages/schematics/angular/vitest-browser/index_spec.ts b/packages/schematics/angular/vitest-browser/index_spec.ts index 9027742f73a9..83ac0a9d55a6 100644 --- a/packages/schematics/angular/vitest-browser/index_spec.ts +++ b/packages/schematics/angular/vitest-browser/index_spec.ts @@ -35,37 +35,69 @@ describe('Vitest Browser Provider Schematic', () => { ); }); - it('should add dependencies and update tsconfig.spec.json', async () => { - const options = { - project: 'app', - package: '@vitest/browser-playwright', - skipInstall: true, - }; + [ + { pkg: '@vitest/browser-playwright', browser: 'chromium', extraDeps: ['playwright'] }, + { pkg: '@vitest/browser-webdriverio', browser: 'chrome', extraDeps: ['webdriverio'] }, + { pkg: '@vitest/browser-preview', browser: 'chromium', extraDeps: [] as string[] }, + ].forEach(({ pkg, browser, extraDeps }) => { + it(`should add ${browser} to browsers option in angular.json for ${pkg}`, async () => { + const options = { + project: 'app', + package: pkg, + skipInstall: true, + }; - const resultTree = await schematicRunner.runSchematic('vitest-browser', options, tree); + const resultTree = await schematicRunner.runSchematic('vitest-browser', options, tree); - const packageJson = parse(resultTree.readContent('/package.json')); - expect(packageJson.devDependencies['@vitest/browser-playwright']).toBeDefined(); - expect(packageJson.devDependencies['playwright']).toBeDefined(); + const angularJson = parse(resultTree.readContent('/angular.json')); + const project = angularJson.projects.app; + const targets = project.architect || project.targets; + expect(targets.test.options.browsers).toEqual([browser]); + }); - const tsConfig = parse(resultTree.readContent('/projects/app/tsconfig.spec.json')); - expect(tsConfig.compilerOptions.types).toContain('vitest/globals'); - expect(tsConfig.compilerOptions.types).toContain('@vitest/browser-playwright'); - expect(tsConfig.compilerOptions.types).not.toContain('jasmine'); + it(`should add dependencies and update tsconfig.spec.json for ${pkg}`, async () => { + const options = { + project: 'app', + package: pkg, + skipInstall: true, + }; + + const resultTree = await schematicRunner.runSchematic('vitest-browser', options, tree); + + const packageJson = parse(resultTree.readContent('/package.json')); + expect(packageJson.devDependencies[pkg]).toBeDefined(); + for (const dep of extraDeps) { + expect(packageJson.devDependencies[dep]).toBeDefined(); + } + + const tsConfig = parse(resultTree.readContent('/projects/app/tsconfig.spec.json')); + expect(tsConfig.compilerOptions.types).toContain('vitest/globals'); + expect(tsConfig.compilerOptions.types).toContain(pkg); + expect(tsConfig.compilerOptions.types).not.toContain('jasmine'); + }); }); - it('should add webdriverio dependency when @vitest/browser-webdriverio is used', async () => { + it('should not overwrite existing browsers option in angular.json', async () => { + // Set up existing browsers option + const angularJson = parse(tree.readContent('/angular.json')); + const project = angularJson.projects.app; + const targets = project.architect || project.targets; + targets.test.options ??= {}; + targets.test.options.browsers = ['firefox']; + tree.overwrite('/angular.json', JSON.stringify(angularJson)); + const options = { project: 'app', - package: '@vitest/browser-webdriverio', + package: '@vitest/browser-playwright', skipInstall: true, }; const resultTree = await schematicRunner.runSchematic('vitest-browser', options, tree); - const packageJson = parse(resultTree.readContent('/package.json')); - expect(packageJson.devDependencies['@vitest/browser-webdriverio']).toBeDefined(); - expect(packageJson.devDependencies['webdriverio']).toBeDefined(); + const updatedAngularJson = parse(resultTree.readContent('/angular.json')); + const updatedProject = updatedAngularJson.projects.app; + const updatedTargets = updatedProject.architect || updatedProject.targets; + expect(updatedTargets.test.options.browsers).toEqual(['firefox']); }); it('should update tsconfig.spec.json for a library project', async () => { From 07e608dd27a44816ad0360ce47aa8ec31c03afec Mon Sep 17 00:00:00 2001 From: yoggydev <280342032+yoggydev@users.noreply.github.com> Date: Tue, 8 Sep 2026 13:49:39 +0900 Subject: [PATCH 514/787] fix(@angular/build): encode script type in auto-CSP loader createLoaderScript() interpolates four script attributes into the generated loader. integrity and crossOrigin are encoded with JSON.stringify and \u003c, but type is inserted directly into a single-quoted JavaScript string literal. The comment above the function states that type can only be 'module', a JS MIME type or an empty string, but isJavascriptMimeType() only compares the part before the first ';', so a value such as text/javascript; reaches the loader unchanged. A quote in that value closes the string literal, and a closing script tag terminates the generated element. Encode type the same way as its neighbours. Both branches of createLoaderScript() share srcListFormatted, so one change covers Trusted Types enabled and disabled. --- .../build/src/utils/index-file/auto-csp.ts | 6 +- .../src/utils/index-file/auto-csp_spec.ts | 60 +++++++++++++++---- 2 files changed, 53 insertions(+), 13 deletions(-) diff --git a/packages/angular/build/src/utils/index-file/auto-csp.ts b/packages/angular/build/src/utils/index-file/auto-csp.ts index 5c1899015a7e..cd07fb821640 100644 --- a/packages/angular/build/src/utils/index-file/auto-csp.ts +++ b/packages/angular/build/src/utils/index-file/auto-csp.ts @@ -299,8 +299,10 @@ function createLoaderScript(srcList: SrcScriptTag[], enableTrustedTypes = false) .map((s) => { // URI encoding means value can't escape string, JS, or HTML context. const srcAttr = encodeURI(s.src).replaceAll("'", "\\'"); - // Can only be 'module' or a JS MIME type or an empty string. - const typeAttr = s.type ? "'" + s.type + "'" : "''"; + // 'module', a JS MIME type, or an empty string. A JS MIME type may carry + // parameters after a ';', which isJavascriptMimeType() does not constrain, + // so encode this the same way as integrity and crossOrigin below. + const typeAttr = JSON.stringify(s.type ?? '').replaceAll('<', '\\u003c'); const asyncAttr = !!s.async; const deferAttr = !!s.defer; const integrityAttr = JSON.stringify(s.integrity ?? null).replaceAll('<', '\\u003c'); diff --git a/packages/angular/build/src/utils/index-file/auto-csp_spec.ts b/packages/angular/build/src/utils/index-file/auto-csp_spec.ts index 4fe2888efa42..037ab605253a 100644 --- a/packages/angular/build/src/utils/index-file/auto-csp_spec.ts +++ b/packages/angular/build/src/utils/index-file/auto-csp_spec.ts @@ -58,7 +58,7 @@ describe('auto-csp', () => { const csps = getCsps(result); expect(csps).toHaveSize(1); expect(csps[0]).toMatch(CSP_SINGLE_HASH_REGEX); - expect(result).toContain(`const scripts = [['./main.js', '', false, false, null, null]];`); + expect(result).toContain(`const scripts = [['./main.js', "", false, false, null, null]];`); }); it('should rewrite a single source script in place', async () => { @@ -78,7 +78,7 @@ describe('auto-csp', () => { expect(csps[0]).toMatch(CSP_SINGLE_HASH_REGEX); // Our loader script appears after the HTML text content. expect(result).toMatch( - /Some text<\/div>\s*`); @@ -166,12 +166,12 @@ describe('auto-csp', () => { // Loader script for main.js and main2.js appear after 'foo' and before 'bar'. expect(result).toMatch( // eslint-disable-next-line max-len - /console.log\('foo'\);<\/script>\s* + + + `); + + const csps = getCsps(result); + expect(csps).toHaveSize(1); + expect(csps[0]).toMatch(CSP_SINGLE_HASH_REGEX); + // The type stays inside its string literal. + expect(result).toContain( + `const scripts = [['./main.js', "text/javascript;']];var x=1;var junk=[['a','b", false, false, null, null]];`, + ); + }); + + it('should encode a script type that contains a closing script tag', async () => { + const result = await autoCsp(` + + + + + + + + `); + + const csps = getCsps(result); + expect(csps).toHaveSize(1); + expect(csps[0]).toMatch(CSP_SINGLE_HASH_REGEX); + // Only the loader element is emitted. + expect(Array.from(result.matchAll(/'); expect(result).toContain(``); }); + + it('should add the nonce expression to stylesheet and modulepreload link tags', async () => { + const result = await addNonce(` + + + + + + + + + + + `); + + expect(result).toContain(''); + expect(result).toContain(''); + expect(result).toContain(''); + }); + + it('should add the nonce expression when link rel has mixed case or multiple tokens', async () => { + const result = await addNonce(` + + + + + + + + + + `); + + expect(result).toContain(''); + expect(result).toContain(''); + }); }); diff --git a/packages/angular_devkit/build_angular/src/builders/app-shell/app-shell_spec.ts b/packages/angular_devkit/build_angular/src/builders/app-shell/app-shell_spec.ts index d4a470935d10..f39d8da34114 100644 --- a/packages/angular_devkit/build_angular/src/builders/app-shell/app-shell_spec.ts +++ b/packages/angular_devkit/build_angular/src/builders/app-shell/app-shell_spec.ts @@ -195,7 +195,7 @@ describe('AppShell Builder', () => { expect(content).toContain(''); expect(content).toMatch( - //, + //, ); }); }); From dcf906a6261a00f95cfbdb18cf9065e1c966e182 Mon Sep 17 00:00:00 2001 From: Alan Agius <17563226+alan-agius4@users.noreply.github.com> Date: Mon, 28 Sep 2026 17:32:16 +0000 Subject: [PATCH 582/787] perf(@angular/build): reuse extendedConfigCache in TypeScript compilation Reusing TypeScript's extendedConfigCache across watch rebuilds eliminates redundant reading and re-parsing of extended tsconfig files from disk. The referenced configuration files are also tracked so that entries in the cache are invalidated when those files change on disk. See: https://github.com/angular/angular/pull/71034 --- .../compilation/angular-compilation_spec.ts | 50 ++++++++++++++++ .../angular/compilation/aot-compilation.ts | 42 +++++++------- .../angular/compilation/jit-compilation.ts | 8 ++- .../compilation/typescript-compilation.ts | 57 +++++++++++++------ 4 files changed, 118 insertions(+), 39 deletions(-) diff --git a/packages/angular/build/src/tools/angular/compilation/angular-compilation_spec.ts b/packages/angular/build/src/tools/angular/compilation/angular-compilation_spec.ts index 71eacd562259..2d001dfeff7c 100644 --- a/packages/angular/build/src/tools/angular/compilation/angular-compilation_spec.ts +++ b/packages/angular/build/src/tools/angular/compilation/angular-compilation_spec.ts @@ -158,11 +158,61 @@ describe('AngularCompilation', () => { suppressOutputPathCheck: true, outDir: undefined, }), + undefined, + jasmine.any(Map), ); expect(result.rootNames).toEqual(['/src/main.ts']); expect(result.compilerOptions.target).toBe(ts.ScriptTarget.ES2022); expect(result.compilerOptions.inlineSources).toBe(true); expect(result.warnings.length).toBeGreaterThan(0); + expect(result.tsConfigFiles).toEqual(['tsconfig.json']); + }); + + it('passes extendedConfigCache to readConfiguration and invalidates entries on config change', async () => { + const compilation = new MockTypeScriptCompilation(); + let passedCache: Map | undefined; + const mockReadConfig = jasmine + .createSpy('readConfiguration') + .and.callFake((_project, _options, _host, extendedConfigCache) => { + passedCache = extendedConfigCache; + extendedConfigCache?.set( + '/path/to/tsconfig.base.json', + {} as ts.ExtendedConfigCacheEntry, + ); + + return { + options: { target: ts.ScriptTarget.ES2020 }, + rootNames: ['/src/main.ts'], + errors: [], + }; + }); + spyOn(TypeScriptCompilation, 'loadCompilerCli').and.resolveTo({ + readConfiguration: mockReadConfig, + } as unknown as typeof import('@angular/compiler-cli')); + + const result1 = await compilation.testLoadConfiguration('tsconfig.json'); + expect(mockReadConfig).toHaveBeenCalledTimes(1); + expect(passedCache).toBeDefined(); + expect(passedCache?.has('/path/to/tsconfig.base.json')).toBeTrue(); + expect(result1.tsConfigFiles).toEqual(['tsconfig.json', '/path/to/tsconfig.base.json']); + + // Invalidation of non-config file should keep extended config cache intact + await compilation.update?.(new Set(['/src/main.ts'])); + expect(passedCache?.has('/path/to/tsconfig.base.json')).toBeTrue(); + + // Invalidation of extended tsconfig file should remove it from cache + await compilation.update?.(new Set(['/path/to/tsconfig.base.json'])); + expect(passedCache?.has('/path/to/tsconfig.base.json')).toBeFalse(); + + // Invalidation with different casing should also remove it from cache + passedCache?.set('/path/to/tsconfig.base.json', {} as ts.ExtendedConfigCacheEntry); + await compilation.update?.(new Set(['/PATH/TO/TSCONFIG.BASE.JSON'])); + expect(passedCache?.has('/path/to/tsconfig.base.json')).toBeFalse(); + + // Subsequent configuration load re-uses the same cache instance + await compilation.testLoadConfiguration('tsconfig.json'); + expect(mockReadConfig).toHaveBeenCalledTimes(2); + expect(mockReadConfig.calls.argsFor(1)[3]).toBe(passedCache); }); }); diff --git a/packages/angular/build/src/tools/angular/compilation/aot-compilation.ts b/packages/angular/build/src/tools/angular/compilation/aot-compilation.ts index 9381812a74ce..6f45199d1421 100644 --- a/packages/angular/build/src/tools/angular/compilation/aot-compilation.ts +++ b/packages/angular/build/src/tools/angular/compilation/aot-compilation.ts @@ -77,6 +77,7 @@ export class AotCompilation extends TypeScriptCompilation { rootNames, errors: configurationDiagnostics, warnings, + tsConfigFiles, } = await this.loadConfiguration(tsconfig, compilerOptionOverrides, buildType); const useTypeScriptTranspilation = @@ -209,28 +210,31 @@ export class AotCompilation extends TypeScriptCompilation { const componentResourcesDependencies = new Map(); // Get all files referenced in the TypeScript/Angular program including component resources - const referencedFiles = typeScriptProgram - .getSourceFiles() - .filter((sourceFile) => !angularCompiler.ignoreForEmit.has(sourceFile)) - .flatMap((sourceFile) => { - const resourceDependencies = angularCompiler.getResourceDependencies(sourceFile); - componentResourcesDependencies.set(sourceFile.fileName, resourceDependencies); - // Also invalidate Angular diagnostics for a source file if component resources are modified - if (this.#state && hostOptions.modifiedFiles?.size) { - for (const resourceDependency of resourceDependencies) { - if ( - hostOptions.modifiedFiles.has(resourceDependency) && - !/\.(?:css|scss|sass|less)$/i.test(resourceDependency) - ) { - this.#state.diagnosticCache.delete(sourceFile); - // Also mark as affected in case changed template affects diagnostics - affectedFiles.add(sourceFile); + const referencedFiles = [ + ...tsConfigFiles, + ...typeScriptProgram + .getSourceFiles() + .filter((sourceFile) => !angularCompiler.ignoreForEmit.has(sourceFile)) + .flatMap((sourceFile) => { + const resourceDependencies = angularCompiler.getResourceDependencies(sourceFile); + componentResourcesDependencies.set(sourceFile.fileName, resourceDependencies); + // Also invalidate Angular diagnostics for a source file if component resources are modified + if (this.#state && hostOptions.modifiedFiles?.size) { + for (const resourceDependency of resourceDependencies) { + if ( + hostOptions.modifiedFiles.has(resourceDependency) && + !/\.(?:css|scss|sass|less)$/i.test(resourceDependency) + ) { + this.#state.diagnosticCache.delete(sourceFile); + // Also mark as affected in case changed template affects diagnostics + affectedFiles.add(sourceFile); + } } } - } - return [sourceFile.fileName, ...resourceDependencies]; - }); + return [sourceFile.fileName, ...resourceDependencies]; + }), + ]; this.#state = new AngularCompilationState( angularProgram, diff --git a/packages/angular/build/src/tools/angular/compilation/jit-compilation.ts b/packages/angular/build/src/tools/angular/compilation/jit-compilation.ts index 773279e236a9..ec88987369b0 100644 --- a/packages/angular/build/src/tools/angular/compilation/jit-compilation.ts +++ b/packages/angular/build/src/tools/angular/compilation/jit-compilation.ts @@ -55,6 +55,7 @@ export class JitCompilation extends TypeScriptCompilation { rootNames, errors: configurationDiagnostics, warnings, + tsConfigFiles, } = await this.loadConfiguration(tsconfig, compilerOptionOverrides, buildType); if (hostOptions.modifiedFiles) { @@ -89,9 +90,10 @@ export class JitCompilation extends TypeScriptCompilation { createWorkerTransformer(hostOptions.processWebWorker.bind(hostOptions)), ); - const referencedFiles = typeScriptProgram - .getSourceFiles() - .map((sourceFile) => sourceFile.fileName); + const referencedFiles = [ + ...tsConfigFiles, + ...typeScriptProgram.getSourceFiles().map((sourceFile) => sourceFile.fileName), + ]; return { compilerOptions, referencedFiles, warnings }; } diff --git a/packages/angular/build/src/tools/angular/compilation/typescript-compilation.ts b/packages/angular/build/src/tools/angular/compilation/typescript-compilation.ts index 2595bc60f55a..5310219d2c1c 100644 --- a/packages/angular/build/src/tools/angular/compilation/typescript-compilation.ts +++ b/packages/angular/build/src/tools/angular/compilation/typescript-compilation.ts @@ -20,10 +20,12 @@ export interface TransformedConfiguration { rootNames: string[]; errors: ts.Diagnostic[]; warnings: PartialMessage[]; + tsConfigFiles: readonly string[]; } export abstract class TypeScriptCompilation extends AngularCompilation { static #angularCompilerCliModule?: typeof ng; + readonly #extendedConfigCache = new Map(); static async loadCompilerCli(): Promise { TypeScriptCompilation.#angularCompilerCliModule ??= await import('@angular/compiler-cli'); @@ -43,24 +45,31 @@ export abstract class TypeScriptCompilation extends AngularCompilation { rootNames: originalRootNames, errors, } = profileSync('NG_READ_CONFIG', () => - readConfiguration(tsconfig, { - // Angular specific configuration defaults and overrides to ensure a functioning compilation. - suppressOutputPathCheck: true, - outDir: undefined, - sourceMap: false, - declaration: false, - declarationMap: false, - allowEmptyCodegenFiles: false, - annotationsAs: 'decorators', - enableResourceInlining: false, - supportTestBed: false, - supportJitMode: false, - // Disable removing of comments as TS is quite aggressive with these and can - // remove important annotations, such as /* @__PURE__ */ and comments like /* vite-ignore */. - removeComments: false, - }), + readConfiguration( + tsconfig, + { + // Angular specific configuration defaults and overrides to ensure a functioning compilation. + suppressOutputPathCheck: true, + outDir: undefined, + sourceMap: false, + declaration: false, + declarationMap: false, + allowEmptyCodegenFiles: false, + annotationsAs: 'decorators', + enableResourceInlining: false, + supportTestBed: false, + supportJitMode: false, + // Disable removing of comments as TS is quite aggressive with these and can + // remove important annotations, such as /* @__PURE__ */ and comments like /* vite-ignore */. + removeComments: false, + }, + undefined, + this.#extendedConfigCache, + ), ); + const tsConfigFiles = [toPosixPath(tsconfig), ...this.#extendedConfigCache.keys()]; + let rootNames = originalRootNames; if (compilerOptionOverrides?.rootFiles?.length) { const rootFilesSet = new Set( @@ -87,6 +96,7 @@ export abstract class TypeScriptCompilation extends AngularCompilation { rootNames, errors, warnings, + tsConfigFiles, }; } @@ -94,7 +104,20 @@ export abstract class TypeScriptCompilation extends AngularCompilation { protected invalidateFiles(files: Iterable): void { for (const file of files) { - this.sourceFiles.delete(toPosixPath(file)); + const posixFile = toPosixPath(file); + this.sourceFiles.delete(posixFile); + + if (this.#extendedConfigCache.size === 0) { + continue; + } + + if (this.#extendedConfigCache.delete(posixFile)) { + continue; + } + + // Check with lowercased key because TypeScript lowercases the keys + // of the extended config cache on case-insensitive operating systems. + this.#extendedConfigCache.delete(posixFile.toLowerCase()); } } From 6ecbadaba2c3b3493b67d10b7757d8974bf9b8a1 Mon Sep 17 00:00:00 2001 From: Angular Robot Date: Fri, 9 Oct 2026 01:13:20 +0000 Subject: [PATCH 583/787] build: update cross-repo angular dependencies See associated pull request for more information. --- package.json | 22 +-- packages/angular/ssr/package.json | 12 +- packages/ngtools/webpack/package.json | 4 +- pnpm-lock.yaml | 275 +++++++++++++------------- tests/e2e/ng-snapshot/package.json | 26 +-- 5 files changed, 165 insertions(+), 174 deletions(-) diff --git a/package.json b/package.json index 644a28edac5d..1037a8bfa7c6 100644 --- a/package.json +++ b/package.json @@ -43,23 +43,23 @@ }, "homepage": "https://github.com/angular/angular-cli", "dependencies": { - "@angular/compiler-cli": "22.3.0-next.0", + "@angular/compiler-cli": "22.3.0-next.1", "typescript": "6.0.3" }, "devDependencies": { - "@angular/animations": "22.3.0-next.0", + "@angular/animations": "22.3.0-next.1", "@angular/cdk": "22.3.0-next.1", - "@angular/common": "22.3.0-next.0", - "@angular/compiler": "22.3.0-next.0", - "@angular/core": "22.3.0-next.0", - "@angular/forms": "22.3.0-next.0", - "@angular/localize": "22.3.0-next.0", + "@angular/common": "22.3.0-next.1", + "@angular/compiler": "22.3.0-next.1", + "@angular/core": "22.3.0-next.1", + "@angular/forms": "22.3.0-next.1", + "@angular/localize": "22.3.0-next.1", "@angular/material": "22.3.0-next.1", "@angular/ng-dev": "https://github.com/angular/dev-infra-private-ng-dev-builds.git#89b8c002e5d47ba1cbc4483d3ec06b0ae0aaccb7", - "@angular/platform-browser": "22.3.0-next.0", - "@angular/platform-server": "22.3.0-next.0", - "@angular/router": "22.3.0-next.0", - "@angular/service-worker": "22.3.0-next.0", + "@angular/platform-browser": "22.3.0-next.1", + "@angular/platform-server": "22.3.0-next.1", + "@angular/router": "22.3.0-next.1", + "@angular/service-worker": "22.3.0-next.1", "@babel/core": "8.0.7", "@bazel/bazelisk": "1.28.1", "@bazel/buildifier": "8.2.1", diff --git a/packages/angular/ssr/package.json b/packages/angular/ssr/package.json index 3af5124825ad..6e3596ca6aae 100644 --- a/packages/angular/ssr/package.json +++ b/packages/angular/ssr/package.json @@ -38,12 +38,12 @@ }, "devDependencies": { "@angular-devkit/schematics": "workspace:*", - "@angular/common": "22.3.0-next.0", - "@angular/compiler": "22.3.0-next.0", - "@angular/core": "22.3.0-next.0", - "@angular/platform-browser": "22.3.0-next.0", - "@angular/platform-server": "22.3.0-next.0", - "@angular/router": "22.3.0-next.0", + "@angular/common": "22.3.0-next.1", + "@angular/compiler": "22.3.0-next.1", + "@angular/core": "22.3.0-next.1", + "@angular/platform-browser": "22.3.0-next.1", + "@angular/platform-server": "22.3.0-next.1", + "@angular/router": "22.3.0-next.1", "@schematics/angular": "workspace:*" }, "sideEffects": false, diff --git a/packages/ngtools/webpack/package.json b/packages/ngtools/webpack/package.json index 402dcae8632a..a7488b0d9316 100644 --- a/packages/ngtools/webpack/package.json +++ b/packages/ngtools/webpack/package.json @@ -17,8 +17,8 @@ }, "devDependencies": { "@angular-devkit/core": "workspace:0.0.0-PLACEHOLDER", - "@angular/compiler": "22.3.0-next.0", - "@angular/compiler-cli": "22.3.0-next.0", + "@angular/compiler": "22.3.0-next.1", + "@angular/compiler-cli": "22.3.0-next.1", "typescript": "6.0.3", "webpack": "5.111.1" } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 5a5f64776bca..e6b9e456459e 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -172,8 +172,8 @@ importers: .: dependencies: '@angular/compiler-cli': - specifier: 22.3.0-next.0 - version: 22.3.0-next.0(@angular/compiler@22.3.0-next.0)(typescript@6.0.3) + specifier: 22.3.0-next.1 + version: 22.3.0-next.1(@angular/compiler@22.3.0-next.1)(typescript@6.0.3) typescript: specifier: 6.0.3 version: 6.0.3 @@ -184,44 +184,44 @@ importers: built: true devDependencies: '@angular/animations': - specifier: 22.3.0-next.0 - version: 22.3.0-next.0(@angular/core@22.3.0-next.0(@angular/compiler@22.3.0-next.0)(rxjs@7.8.2)(zone.js@0.16.3)) + specifier: 22.3.0-next.1 + version: 22.3.0-next.1(@angular/core@22.3.0-next.1(@angular/compiler@22.3.0-next.1)(rxjs@7.8.2)(zone.js@0.16.3)) '@angular/cdk': specifier: 22.3.0-next.1 - version: 22.3.0-next.1(ea6b1043a273b7eace12f9dcd4a0b86a) + version: 22.3.0-next.1(1e228ab395252fe57958c1335d3a301f) '@angular/common': - specifier: 22.3.0-next.0 - version: 22.3.0-next.0(@angular/core@22.3.0-next.0(@angular/compiler@22.3.0-next.0)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2) + specifier: 22.3.0-next.1 + version: 22.3.0-next.1(@angular/core@22.3.0-next.1(@angular/compiler@22.3.0-next.1)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2) '@angular/compiler': - specifier: 22.3.0-next.0 - version: 22.3.0-next.0 + specifier: 22.3.0-next.1 + version: 22.3.0-next.1 '@angular/core': - specifier: 22.3.0-next.0 - version: 22.3.0-next.0(@angular/compiler@22.3.0-next.0)(rxjs@7.8.2)(zone.js@0.16.3) + specifier: 22.3.0-next.1 + version: 22.3.0-next.1(@angular/compiler@22.3.0-next.1)(rxjs@7.8.2)(zone.js@0.16.3) '@angular/forms': - specifier: 22.3.0-next.0 - version: 22.3.0-next.0(@angular/common@22.3.0-next.0(@angular/core@22.3.0-next.0(@angular/compiler@22.3.0-next.0)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2))(@angular/core@22.3.0-next.0(@angular/compiler@22.3.0-next.0)(rxjs@7.8.2)(zone.js@0.16.3))(@angular/platform-browser@22.3.0-next.0(@angular/animations@22.3.0-next.0(@angular/core@22.3.0-next.0(@angular/compiler@22.3.0-next.0)(rxjs@7.8.2)(zone.js@0.16.3)))(@angular/common@22.3.0-next.0(@angular/core@22.3.0-next.0(@angular/compiler@22.3.0-next.0)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2))(@angular/core@22.3.0-next.0(@angular/compiler@22.3.0-next.0)(rxjs@7.8.2)(zone.js@0.16.3)))(rxjs@7.8.2) + specifier: 22.3.0-next.1 + version: 22.3.0-next.1(@angular/common@22.3.0-next.1(@angular/core@22.3.0-next.1(@angular/compiler@22.3.0-next.1)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2))(@angular/core@22.3.0-next.1(@angular/compiler@22.3.0-next.1)(rxjs@7.8.2)(zone.js@0.16.3))(@angular/platform-browser@22.3.0-next.1(@angular/animations@22.3.0-next.1(@angular/core@22.3.0-next.1(@angular/compiler@22.3.0-next.1)(rxjs@7.8.2)(zone.js@0.16.3)))(@angular/common@22.3.0-next.1(@angular/core@22.3.0-next.1(@angular/compiler@22.3.0-next.1)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2))(@angular/core@22.3.0-next.1(@angular/compiler@22.3.0-next.1)(rxjs@7.8.2)(zone.js@0.16.3)))(rxjs@7.8.2) '@angular/localize': - specifier: 22.3.0-next.0 - version: 22.3.0-next.0(@angular/compiler-cli@22.3.0-next.0(@angular/compiler@22.3.0-next.0)(typescript@6.0.3))(@angular/compiler@22.3.0-next.0) + specifier: 22.3.0-next.1 + version: 22.3.0-next.1(@angular/compiler-cli@22.3.0-next.1(@angular/compiler@22.3.0-next.1)(typescript@6.0.3))(@angular/compiler@22.3.0-next.1) '@angular/material': specifier: 22.3.0-next.1 - version: 22.3.0-next.1(b10c01331e6aa755f0c8f999dcc12d73) + version: 22.3.0-next.1(837417520965053888cf2615dc986a27) '@angular/ng-dev': specifier: https://github.com/angular/dev-infra-private-ng-dev-builds.git#89b8c002e5d47ba1cbc4483d3ec06b0ae0aaccb7 version: https://codeload.github.com/angular/dev-infra-private-ng-dev-builds/tar.gz/89b8c002e5d47ba1cbc4483d3ec06b0ae0aaccb7 '@angular/platform-browser': - specifier: 22.3.0-next.0 - version: 22.3.0-next.0(@angular/animations@22.3.0-next.0(@angular/core@22.3.0-next.0(@angular/compiler@22.3.0-next.0)(rxjs@7.8.2)(zone.js@0.16.3)))(@angular/common@22.3.0-next.0(@angular/core@22.3.0-next.0(@angular/compiler@22.3.0-next.0)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2))(@angular/core@22.3.0-next.0(@angular/compiler@22.3.0-next.0)(rxjs@7.8.2)(zone.js@0.16.3)) + specifier: 22.3.0-next.1 + version: 22.3.0-next.1(@angular/animations@22.3.0-next.1(@angular/core@22.3.0-next.1(@angular/compiler@22.3.0-next.1)(rxjs@7.8.2)(zone.js@0.16.3)))(@angular/common@22.3.0-next.1(@angular/core@22.3.0-next.1(@angular/compiler@22.3.0-next.1)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2))(@angular/core@22.3.0-next.1(@angular/compiler@22.3.0-next.1)(rxjs@7.8.2)(zone.js@0.16.3)) '@angular/platform-server': - specifier: 22.3.0-next.0 - version: 22.3.0-next.0(@angular/common@22.3.0-next.0(@angular/core@22.3.0-next.0(@angular/compiler@22.3.0-next.0)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2))(@angular/compiler@22.3.0-next.0)(@angular/core@22.3.0-next.0(@angular/compiler@22.3.0-next.0)(rxjs@7.8.2)(zone.js@0.16.3))(@angular/platform-browser@22.3.0-next.0(@angular/animations@22.3.0-next.0(@angular/core@22.3.0-next.0(@angular/compiler@22.3.0-next.0)(rxjs@7.8.2)(zone.js@0.16.3)))(@angular/common@22.3.0-next.0(@angular/core@22.3.0-next.0(@angular/compiler@22.3.0-next.0)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2))(@angular/core@22.3.0-next.0(@angular/compiler@22.3.0-next.0)(rxjs@7.8.2)(zone.js@0.16.3)))(rxjs@7.8.2) + specifier: 22.3.0-next.1 + version: 22.3.0-next.1(@angular/common@22.3.0-next.1(@angular/core@22.3.0-next.1(@angular/compiler@22.3.0-next.1)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2))(@angular/compiler@22.3.0-next.1)(@angular/core@22.3.0-next.1(@angular/compiler@22.3.0-next.1)(rxjs@7.8.2)(zone.js@0.16.3))(@angular/platform-browser@22.3.0-next.1(@angular/animations@22.3.0-next.1(@angular/core@22.3.0-next.1(@angular/compiler@22.3.0-next.1)(rxjs@7.8.2)(zone.js@0.16.3)))(@angular/common@22.3.0-next.1(@angular/core@22.3.0-next.1(@angular/compiler@22.3.0-next.1)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2))(@angular/core@22.3.0-next.1(@angular/compiler@22.3.0-next.1)(rxjs@7.8.2)(zone.js@0.16.3)))(rxjs@7.8.2) '@angular/router': - specifier: 22.3.0-next.0 - version: 22.3.0-next.0(@angular/common@22.3.0-next.0(@angular/core@22.3.0-next.0(@angular/compiler@22.3.0-next.0)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2))(@angular/core@22.3.0-next.0(@angular/compiler@22.3.0-next.0)(rxjs@7.8.2)(zone.js@0.16.3))(@angular/platform-browser@22.3.0-next.0(@angular/animations@22.3.0-next.0(@angular/core@22.3.0-next.0(@angular/compiler@22.3.0-next.0)(rxjs@7.8.2)(zone.js@0.16.3)))(@angular/common@22.3.0-next.0(@angular/core@22.3.0-next.0(@angular/compiler@22.3.0-next.0)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2))(@angular/core@22.3.0-next.0(@angular/compiler@22.3.0-next.0)(rxjs@7.8.2)(zone.js@0.16.3)))(rxjs@7.8.2) + specifier: 22.3.0-next.1 + version: 22.3.0-next.1(@angular/common@22.3.0-next.1(@angular/core@22.3.0-next.1(@angular/compiler@22.3.0-next.1)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2))(@angular/core@22.3.0-next.1(@angular/compiler@22.3.0-next.1)(rxjs@7.8.2)(zone.js@0.16.3))(@angular/platform-browser@22.3.0-next.1(@angular/animations@22.3.0-next.1(@angular/core@22.3.0-next.1(@angular/compiler@22.3.0-next.1)(rxjs@7.8.2)(zone.js@0.16.3)))(@angular/common@22.3.0-next.1(@angular/core@22.3.0-next.1(@angular/compiler@22.3.0-next.1)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2))(@angular/core@22.3.0-next.1(@angular/compiler@22.3.0-next.1)(rxjs@7.8.2)(zone.js@0.16.3)))(rxjs@7.8.2) '@angular/service-worker': - specifier: 22.3.0-next.0 - version: 22.3.0-next.0(@angular/core@22.3.0-next.0(@angular/compiler@22.3.0-next.0)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2) + specifier: 22.3.0-next.1 + version: 22.3.0-next.1(@angular/core@22.3.0-next.1(@angular/compiler@22.3.0-next.1)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2) '@babel/core': specifier: 8.0.7 version: 8.0.7 @@ -464,7 +464,7 @@ importers: version: 30.1.2(@noble/hashes@1.8.0) ng-packagr: specifier: 22.3.0-next.2 - version: 22.3.0-next.2(@angular/compiler-cli@22.3.0-next.0(@angular/compiler@22.3.0-next.0)(typescript@6.0.3))(supports-color@11.0.0)(tslib@2.8.1)(typescript@6.0.3) + version: 22.3.0-next.2(@angular/compiler-cli@22.3.0-next.1(@angular/compiler@22.3.0-next.1)(typescript@6.0.3))(supports-color@11.0.0)(tslib@2.8.1)(typescript@6.0.3) rxjs: specifier: 7.8.2 version: 7.8.2 @@ -582,7 +582,7 @@ importers: version: 4.9.1(supports-color@11.0.0) ng-packagr: specifier: 22.3.0-next.2 - version: 22.3.0-next.2(@angular/compiler-cli@22.3.0-next.0(@angular/compiler@22.3.0-next.0)(typescript@6.0.3))(supports-color@11.0.0)(tslib@2.8.1)(typescript@6.0.3) + version: 22.3.0-next.2(@angular/compiler-cli@22.3.0-next.1(@angular/compiler@22.3.0-next.1)(typescript@6.0.3))(supports-color@11.0.0)(tslib@2.8.1)(typescript@6.0.3) postcss: specifier: 8.5.29 version: 8.5.29 @@ -670,23 +670,23 @@ importers: specifier: workspace:* version: link:../../angular_devkit/schematics '@angular/common': - specifier: 22.3.0-next.0 - version: 22.3.0-next.0(@angular/core@22.3.0-next.0(@angular/compiler@22.3.0-next.0)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2) + specifier: 22.3.0-next.1 + version: 22.3.0-next.1(@angular/core@22.3.0-next.1(@angular/compiler@22.3.0-next.1)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2) '@angular/compiler': - specifier: 22.3.0-next.0 - version: 22.3.0-next.0 + specifier: 22.3.0-next.1 + version: 22.3.0-next.1 '@angular/core': - specifier: 22.3.0-next.0 - version: 22.3.0-next.0(@angular/compiler@22.3.0-next.0)(rxjs@7.8.2)(zone.js@0.16.3) + specifier: 22.3.0-next.1 + version: 22.3.0-next.1(@angular/compiler@22.3.0-next.1)(rxjs@7.8.2)(zone.js@0.16.3) '@angular/platform-browser': - specifier: 22.3.0-next.0 - version: 22.3.0-next.0(@angular/animations@22.3.0-next.0(@angular/core@22.3.0-next.0(@angular/compiler@22.3.0-next.0)(rxjs@7.8.2)(zone.js@0.16.3)))(@angular/common@22.3.0-next.0(@angular/core@22.3.0-next.0(@angular/compiler@22.3.0-next.0)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2))(@angular/core@22.3.0-next.0(@angular/compiler@22.3.0-next.0)(rxjs@7.8.2)(zone.js@0.16.3)) + specifier: 22.3.0-next.1 + version: 22.3.0-next.1(@angular/animations@22.3.0-next.1(@angular/core@22.3.0-next.1(@angular/compiler@22.3.0-next.1)(rxjs@7.8.2)(zone.js@0.16.3)))(@angular/common@22.3.0-next.1(@angular/core@22.3.0-next.1(@angular/compiler@22.3.0-next.1)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2))(@angular/core@22.3.0-next.1(@angular/compiler@22.3.0-next.1)(rxjs@7.8.2)(zone.js@0.16.3)) '@angular/platform-server': - specifier: 22.3.0-next.0 - version: 22.3.0-next.0(@angular/common@22.3.0-next.0(@angular/core@22.3.0-next.0(@angular/compiler@22.3.0-next.0)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2))(@angular/compiler@22.3.0-next.0)(@angular/core@22.3.0-next.0(@angular/compiler@22.3.0-next.0)(rxjs@7.8.2)(zone.js@0.16.3))(@angular/platform-browser@22.3.0-next.0(@angular/animations@22.3.0-next.0(@angular/core@22.3.0-next.0(@angular/compiler@22.3.0-next.0)(rxjs@7.8.2)(zone.js@0.16.3)))(@angular/common@22.3.0-next.0(@angular/core@22.3.0-next.0(@angular/compiler@22.3.0-next.0)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2))(@angular/core@22.3.0-next.0(@angular/compiler@22.3.0-next.0)(rxjs@7.8.2)(zone.js@0.16.3)))(rxjs@7.8.2) + specifier: 22.3.0-next.1 + version: 22.3.0-next.1(@angular/common@22.3.0-next.1(@angular/core@22.3.0-next.1(@angular/compiler@22.3.0-next.1)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2))(@angular/compiler@22.3.0-next.1)(@angular/core@22.3.0-next.1(@angular/compiler@22.3.0-next.1)(rxjs@7.8.2)(zone.js@0.16.3))(@angular/platform-browser@22.3.0-next.1(@angular/animations@22.3.0-next.1(@angular/core@22.3.0-next.1(@angular/compiler@22.3.0-next.1)(rxjs@7.8.2)(zone.js@0.16.3)))(@angular/common@22.3.0-next.1(@angular/core@22.3.0-next.1(@angular/compiler@22.3.0-next.1)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2))(@angular/core@22.3.0-next.1(@angular/compiler@22.3.0-next.1)(rxjs@7.8.2)(zone.js@0.16.3)))(rxjs@7.8.2) '@angular/router': - specifier: 22.3.0-next.0 - version: 22.3.0-next.0(@angular/common@22.3.0-next.0(@angular/core@22.3.0-next.0(@angular/compiler@22.3.0-next.0)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2))(@angular/core@22.3.0-next.0(@angular/compiler@22.3.0-next.0)(rxjs@7.8.2)(zone.js@0.16.3))(@angular/platform-browser@22.3.0-next.0(@angular/animations@22.3.0-next.0(@angular/core@22.3.0-next.0(@angular/compiler@22.3.0-next.0)(rxjs@7.8.2)(zone.js@0.16.3)))(@angular/common@22.3.0-next.0(@angular/core@22.3.0-next.0(@angular/compiler@22.3.0-next.0)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2))(@angular/core@22.3.0-next.0(@angular/compiler@22.3.0-next.0)(rxjs@7.8.2)(zone.js@0.16.3)))(rxjs@7.8.2) + specifier: 22.3.0-next.1 + version: 22.3.0-next.1(@angular/common@22.3.0-next.1(@angular/core@22.3.0-next.1(@angular/compiler@22.3.0-next.1)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2))(@angular/core@22.3.0-next.1(@angular/compiler@22.3.0-next.1)(rxjs@7.8.2)(zone.js@0.16.3))(@angular/platform-browser@22.3.0-next.1(@angular/animations@22.3.0-next.1(@angular/core@22.3.0-next.1(@angular/compiler@22.3.0-next.1)(rxjs@7.8.2)(zone.js@0.16.3)))(@angular/common@22.3.0-next.1(@angular/core@22.3.0-next.1(@angular/compiler@22.3.0-next.1)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2))(@angular/core@22.3.0-next.1(@angular/compiler@22.3.0-next.1)(rxjs@7.8.2)(zone.js@0.16.3)))(rxjs@7.8.2) '@schematics/angular': specifier: workspace:* version: link:../../schematics/angular @@ -870,7 +870,7 @@ importers: version: 3.0.4(bufferutil@4.1.0)(debug@4.4.3(supports-color@11.0.0))(supports-color@11.0.0)(utf-8-validate@6.0.6) ng-packagr: specifier: 22.3.0-next.2 - version: 22.3.0-next.2(@angular/compiler-cli@22.3.0-next.0(@angular/compiler@22.3.0-next.0)(typescript@6.0.3))(supports-color@11.0.0)(tslib@2.8.1)(typescript@6.0.3) + version: 22.3.0-next.2(@angular/compiler-cli@22.3.0-next.1(@angular/compiler@22.3.0-next.1)(typescript@6.0.3))(supports-color@11.0.0)(tslib@2.8.1)(typescript@6.0.3) sass: specifier: 1.105.1 version: 1.105.1 @@ -965,11 +965,11 @@ importers: specifier: workspace:0.0.0-PLACEHOLDER version: link:../../angular_devkit/core '@angular/compiler': - specifier: 22.3.0-next.0 - version: 22.3.0-next.0 + specifier: 22.3.0-next.1 + version: 22.3.0-next.1 '@angular/compiler-cli': - specifier: 22.3.0-next.0 - version: 22.3.0-next.0(@angular/compiler@22.3.0-next.0)(typescript@6.0.3) + specifier: 22.3.0-next.1 + version: 22.3.0-next.1(@angular/compiler@22.3.0-next.1)(typescript@6.0.3) typescript: specifier: 6.0.3 version: 6.0.3 @@ -1029,11 +1029,11 @@ packages: resolution: {integrity: sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==} engines: {node: '>=6.0.0'} - '@angular/animations@22.3.0-next.0': - resolution: {integrity: sha512-iAIfm2b0SgEYskcpvnJz5vYYyT0EaSHvwz6rFh6XfiUtDI4oudBFFWDyyLqGR1gy+/UAIKG+e75SQOnaurbYdg==} + '@angular/animations@22.3.0-next.1': + resolution: {integrity: sha512-YdJE9xE7EO9xJtXNcWFXCatofYRXmkZm5oPOaKBCTHvX12Iw3SQsybxXr23Lq1gHscAZnqffEfhQ78TdnSl5wA==} engines: {node: ^22.22.3 || ^24.15.0 || >=26.0.0} peerDependencies: - '@angular/core': 22.3.0-next.0 + '@angular/core': 22.3.0-next.1 '@angular/cdk@22.3.0-next.1': resolution: {integrity: sha512-WAOIXq+8KtLn59xdt7rRKgdxO3VUCGSlSzoUJQez4EM+/MFa8GPMTHZ392ewBA3R2XpEJNFbSIH61A0+yfNBMg==} @@ -1044,33 +1044,33 @@ packages: '@angular/platform-browser': ^22.0.0-0 || ^22.1.0-0 || ^22.2.0-0 || ^22.3.0-0 || ^23.0.0-0 rxjs: ^6.5.3 || ^7.4.0 - '@angular/common@22.3.0-next.0': - resolution: {integrity: sha512-phGl0A7G7H3BhxaGHUVWe7AXrmqmUlfEumHJLBQL0iOWefDsnEGSgJghyHI6Rx7Sra0x6B46VwBw0CUeAblXYg==} + '@angular/common@22.3.0-next.1': + resolution: {integrity: sha512-vJ4X+f43MIfOMKJc53ttkwxKSP6pfOFgfZ1m+W6fAIF5Ydy49/GnXIUbM2rtcbhsSYgh+95YMs3lhUrgyMXEUw==} engines: {node: ^22.22.3 || ^24.15.0 || >=26.0.0} peerDependencies: - '@angular/core': 22.3.0-next.0 + '@angular/core': 22.3.0-next.1 rxjs: ^6.5.3 || ^7.4.0 - '@angular/compiler-cli@22.3.0-next.0': - resolution: {integrity: sha512-DBw+9LVLpKzQr1aN7vU3zJcXaavovLUlA0o71EuuBrt5Yf9NejUvSVZ++ZJNMOkChlL2fRe8HwOl7gUhScsFoQ==} + '@angular/compiler-cli@22.3.0-next.1': + resolution: {integrity: sha512-yfJ4jfjdTjTJYhWT3A8aEWZsk4xwTTB/S0oVi9VWm7HAb2trn5c3F5B/nWUJSSX5CXQ8TAnzN27mca2ZhyUPLw==} engines: {node: ^22.22.3 || ^24.15.0 || >=26.0.0} hasBin: true peerDependencies: - '@angular/compiler': 22.3.0-next.0 + '@angular/compiler': 22.3.0-next.1 typescript: '>=6.0 <6.1' peerDependenciesMeta: typescript: optional: true - '@angular/compiler@22.3.0-next.0': - resolution: {integrity: sha512-5MajR2yL5zj3REBGr7/XLBa+sqfabY4E9wNKxSrBc7E7+sdkmnRhdmU1vJg99+9Kv0FXihRjqM8c33D0yoX79A==} + '@angular/compiler@22.3.0-next.1': + resolution: {integrity: sha512-58W3f6lwfMwAlmoKfK4qigYuRQkRF0ZGZiSjAEXFhU1sV48pgQaADiz/2cfNGD3pEcb99sW9853XzDA9zzcbqA==} engines: {node: ^22.22.3 || ^24.15.0 || >=26.0.0} - '@angular/core@22.3.0-next.0': - resolution: {integrity: sha512-9KIK1hQlK5DXk+UHmT9IjQryGY3ilo0GY9NIviS9ctTJ4CRHSBhY5x7lK26bBLGrGOYqXM+NaAA9kdgHARVAmw==} + '@angular/core@22.3.0-next.1': + resolution: {integrity: sha512-6Y4bgGkZmje+7Ct8L3PARXfpm5ZrUYuWYKNz4Xtlr08Fsx1Fp2oroUQ8BsPgZGgfzmHaWyTBE/fvK7ZbybKcjw==} engines: {node: ^22.22.3 || ^24.15.0 || >=26.0.0} peerDependencies: - '@angular/compiler': 22.3.0-next.0 + '@angular/compiler': 22.3.0-next.1 rxjs: ^6.5.3 || ^7.4.0 zone.js: ~0.15.0 || ~0.16.0 peerDependenciesMeta: @@ -1079,22 +1079,22 @@ packages: zone.js: optional: true - '@angular/forms@22.3.0-next.0': - resolution: {integrity: sha512-BPGC8WaoZpkB1kvLuKLi59M/mh0tYBy630kI8tERHZUbt5mitjSGDtYXMSWlCZPi08OP4aMTQhTSpARh0yeYjQ==} + '@angular/forms@22.3.0-next.1': + resolution: {integrity: sha512-dssi5/s/DekmNKDA8zFDgfDVLrK2akZxg0lFO+e/pDeSYBKoalbljtAssPFEdGCiDdfmz6pFasvRw50TYI1ErQ==} engines: {node: ^22.22.3 || ^24.15.0 || >=26.0.0} peerDependencies: - '@angular/common': 22.3.0-next.0 - '@angular/core': 22.3.0-next.0 - '@angular/platform-browser': 22.3.0-next.0 + '@angular/common': 22.3.0-next.1 + '@angular/core': 22.3.0-next.1 + '@angular/platform-browser': 22.3.0-next.1 rxjs: ^6.5.3 || ^7.4.0 - '@angular/localize@22.3.0-next.0': - resolution: {integrity: sha512-y1tqTRyl1Fig2ayX2p53n/I4UEIrs64i1yLGphCRR2mfjmIVW1zRaRjRtXgkEuvZVq9ROCTY/m+dLxI1ZT3Nsw==} + '@angular/localize@22.3.0-next.1': + resolution: {integrity: sha512-KPZuMWghal8+ZQn3N8s6shDZTyKTFSyw55ooxxhJNt+bOQ++mmjPJ7JCen39qAAILYpgI3IriLnswsbhGnGDNQ==} engines: {node: ^22.22.3 || ^24.15.0 || >=26.0.0} hasBin: true peerDependencies: - '@angular/compiler': 22.3.0-next.0 - '@angular/compiler-cli': 22.3.0-next.0 + '@angular/compiler': 22.3.0-next.1 + '@angular/compiler-cli': 22.3.0-next.1 '@angular/material@22.3.0-next.1': resolution: {integrity: sha512-iQrlvYiHEwY9p7c8CIa9pPXfWDuE+4cU3c64X3w8i7ChDBSj/dzsGK31X4EstZ+PXozDzcLH+JXuHkWPg81CVQ==} @@ -1111,42 +1111,42 @@ packages: version: 0.0.0-8b6cbbca278a26f2495275c5d9d0d8633573162d hasBin: true - '@angular/platform-browser@22.3.0-next.0': - resolution: {integrity: sha512-H2cnVa7k1S8eRkO53VZbZL435rrjwk/veVm8/vga04RXl/8eoRixpB4rwolzWiL0VQP9ERMVWNQxX0rCy6Zb2w==} + '@angular/platform-browser@22.3.0-next.1': + resolution: {integrity: sha512-2mhIqbG0U75M3m2zICdF1qInDsuwiS+asx/xHWXPNAC1Igsiiq2DrCo9lGfKAuYpORvRWJfppXSD88atBeiDJw==} engines: {node: ^22.22.3 || ^24.15.0 || >=26.0.0} peerDependencies: - '@angular/animations': 22.3.0-next.0 - '@angular/common': 22.3.0-next.0 - '@angular/core': 22.3.0-next.0 + '@angular/animations': 22.3.0-next.1 + '@angular/common': 22.3.0-next.1 + '@angular/core': 22.3.0-next.1 peerDependenciesMeta: '@angular/animations': optional: true - '@angular/platform-server@22.3.0-next.0': - resolution: {integrity: sha512-Pm7HWNuoImEKlRKgKPeML/PoGtSRSaIcfGVwXBPdydsbYjEvxIdPZWFDgSjrSFD4VNfyZuggufRvwTbOcXKE3w==} + '@angular/platform-server@22.3.0-next.1': + resolution: {integrity: sha512-sGX0TGZMoN2c5j3kC6egIoTaD8lNurzIlRbbOAlFhkv6I8NJuyStk74pXn9yTsi2co+i/b8eAQe7Jw0mRXa6gA==} engines: {node: ^22.22.3 || ^24.15.0 || >=26.0.0} peerDependencies: - '@angular/common': 22.3.0-next.0 - '@angular/compiler': 22.3.0-next.0 - '@angular/core': 22.3.0-next.0 - '@angular/platform-browser': 22.3.0-next.0 + '@angular/common': 22.3.0-next.1 + '@angular/compiler': 22.3.0-next.1 + '@angular/core': 22.3.0-next.1 + '@angular/platform-browser': 22.3.0-next.1 rxjs: ^6.5.3 || ^7.4.0 - '@angular/router@22.3.0-next.0': - resolution: {integrity: sha512-y0iqqJ48heOZvHqbD7k2IwBDfQOk1h63D7ZNngRK4xNmx9sWjIgO+aYifB8KnHUytaO1OYm1oJlYiqdiDHkekQ==} + '@angular/router@22.3.0-next.1': + resolution: {integrity: sha512-Syu0u+mWinMzwLYidzi1yy2wbXmljRucsLE1jwaaf97rZ6Lqqc8cgnfWBSwxVdZ1r8qhR5zlauvAN/+cbiMF3g==} engines: {node: ^22.22.3 || ^24.15.0 || >=26.0.0} peerDependencies: - '@angular/common': 22.3.0-next.0 - '@angular/core': 22.3.0-next.0 - '@angular/platform-browser': 22.3.0-next.0 + '@angular/common': 22.3.0-next.1 + '@angular/core': 22.3.0-next.1 + '@angular/platform-browser': 22.3.0-next.1 rxjs: ^6.5.3 || ^7.4.0 - '@angular/service-worker@22.3.0-next.0': - resolution: {integrity: sha512-fMZIS9qOf06YsEuqcwUZhook83ipg3guazPaCDTx/zfPZAtjO416quxM+GO6nx9OBr55tCzW1Rip9ERSXcluKg==} + '@angular/service-worker@22.3.0-next.1': + resolution: {integrity: sha512-KStwvrt0vE8UAfXEE1GtIJm1b/oKu5XNSzCMqF/xE+VjSTrhnwNaKfyqXbK+7dVwr42AcUifTkOKJLq8zlz8fQ==} engines: {node: ^22.22.3 || ^24.15.0 || >=26.0.0} hasBin: true peerDependencies: - '@angular/core': 22.3.0-next.0 + '@angular/core': 22.3.0-next.1 rxjs: ^6.5.3 || ^7.4.0 '@asamuzakjp/css-color@7.1.3': @@ -1321,10 +1321,6 @@ packages: resolution: {integrity: sha512-1k2lAGRMfHTcwuNYcCNUmaUffmQv8KWMfh2iJUUeRlwlwH4FdNG7mfPI10NPfLHJFThE4Tyr4mv7kTNZOiPuBg==} engines: {node: '>=6.9.0'} - '@babel/helpers@8.0.5': - resolution: {integrity: sha512-fQtPOXjYOYv85PIdwotp2TJGVYOycX0PQq+l844fFAxOULtBy8BVF35GyeueX0r4KvDthqPH5xAI1clQPk/2uA==} - engines: {node: ^22.18.0 || >=24.11.0} - '@babel/helpers@8.0.7': resolution: {integrity: sha512-5dMj5kFwS2AY7Dt4PZp4px3c5ThMbbEa7tZfuHTncCGSFYq8uoA1ufDE1IS/lYpQedE+3+GQ3cPZUiplIu195w==} engines: {node: ^22.18.0 || >=24.11.0} @@ -8819,30 +8815,30 @@ snapshots: '@jridgewell/gen-mapping': 0.3.13 '@jridgewell/trace-mapping': 0.3.31 - '@angular/animations@22.3.0-next.0(@angular/core@22.3.0-next.0(@angular/compiler@22.3.0-next.0)(rxjs@7.8.2)(zone.js@0.16.3))': + '@angular/animations@22.3.0-next.1(@angular/core@22.3.0-next.1(@angular/compiler@22.3.0-next.1)(rxjs@7.8.2)(zone.js@0.16.3))': dependencies: - '@angular/core': 22.3.0-next.0(@angular/compiler@22.3.0-next.0)(rxjs@7.8.2)(zone.js@0.16.3) + '@angular/core': 22.3.0-next.1(@angular/compiler@22.3.0-next.1)(rxjs@7.8.2)(zone.js@0.16.3) tslib: 2.8.1 - '@angular/cdk@22.3.0-next.1(ea6b1043a273b7eace12f9dcd4a0b86a)': + '@angular/cdk@22.3.0-next.1(1e228ab395252fe57958c1335d3a301f)': dependencies: - '@angular/common': 22.3.0-next.0(@angular/core@22.3.0-next.0(@angular/compiler@22.3.0-next.0)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2) - '@angular/core': 22.3.0-next.0(@angular/compiler@22.3.0-next.0)(rxjs@7.8.2)(zone.js@0.16.3) - '@angular/forms': 22.3.0-next.0(@angular/common@22.3.0-next.0(@angular/core@22.3.0-next.0(@angular/compiler@22.3.0-next.0)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2))(@angular/core@22.3.0-next.0(@angular/compiler@22.3.0-next.0)(rxjs@7.8.2)(zone.js@0.16.3))(@angular/platform-browser@22.3.0-next.0(@angular/animations@22.3.0-next.0(@angular/core@22.3.0-next.0(@angular/compiler@22.3.0-next.0)(rxjs@7.8.2)(zone.js@0.16.3)))(@angular/common@22.3.0-next.0(@angular/core@22.3.0-next.0(@angular/compiler@22.3.0-next.0)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2))(@angular/core@22.3.0-next.0(@angular/compiler@22.3.0-next.0)(rxjs@7.8.2)(zone.js@0.16.3)))(rxjs@7.8.2) - '@angular/platform-browser': 22.3.0-next.0(@angular/animations@22.3.0-next.0(@angular/core@22.3.0-next.0(@angular/compiler@22.3.0-next.0)(rxjs@7.8.2)(zone.js@0.16.3)))(@angular/common@22.3.0-next.0(@angular/core@22.3.0-next.0(@angular/compiler@22.3.0-next.0)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2))(@angular/core@22.3.0-next.0(@angular/compiler@22.3.0-next.0)(rxjs@7.8.2)(zone.js@0.16.3)) + '@angular/common': 22.3.0-next.1(@angular/core@22.3.0-next.1(@angular/compiler@22.3.0-next.1)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2) + '@angular/core': 22.3.0-next.1(@angular/compiler@22.3.0-next.1)(rxjs@7.8.2)(zone.js@0.16.3) + '@angular/forms': 22.3.0-next.1(@angular/common@22.3.0-next.1(@angular/core@22.3.0-next.1(@angular/compiler@22.3.0-next.1)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2))(@angular/core@22.3.0-next.1(@angular/compiler@22.3.0-next.1)(rxjs@7.8.2)(zone.js@0.16.3))(@angular/platform-browser@22.3.0-next.1(@angular/animations@22.3.0-next.1(@angular/core@22.3.0-next.1(@angular/compiler@22.3.0-next.1)(rxjs@7.8.2)(zone.js@0.16.3)))(@angular/common@22.3.0-next.1(@angular/core@22.3.0-next.1(@angular/compiler@22.3.0-next.1)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2))(@angular/core@22.3.0-next.1(@angular/compiler@22.3.0-next.1)(rxjs@7.8.2)(zone.js@0.16.3)))(rxjs@7.8.2) + '@angular/platform-browser': 22.3.0-next.1(@angular/animations@22.3.0-next.1(@angular/core@22.3.0-next.1(@angular/compiler@22.3.0-next.1)(rxjs@7.8.2)(zone.js@0.16.3)))(@angular/common@22.3.0-next.1(@angular/core@22.3.0-next.1(@angular/compiler@22.3.0-next.1)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2))(@angular/core@22.3.0-next.1(@angular/compiler@22.3.0-next.1)(rxjs@7.8.2)(zone.js@0.16.3)) parse5: 8.0.1 rxjs: 7.8.2 tslib: 2.8.1 - '@angular/common@22.3.0-next.0(@angular/core@22.3.0-next.0(@angular/compiler@22.3.0-next.0)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2)': + '@angular/common@22.3.0-next.1(@angular/core@22.3.0-next.1(@angular/compiler@22.3.0-next.1)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2)': dependencies: - '@angular/core': 22.3.0-next.0(@angular/compiler@22.3.0-next.0)(rxjs@7.8.2)(zone.js@0.16.3) + '@angular/core': 22.3.0-next.1(@angular/compiler@22.3.0-next.1)(rxjs@7.8.2)(zone.js@0.16.3) rxjs: 7.8.2 tslib: 2.8.1 - '@angular/compiler-cli@22.3.0-next.0(@angular/compiler@22.3.0-next.0)(typescript@6.0.3)': + '@angular/compiler-cli@22.3.0-next.1(@angular/compiler@22.3.0-next.1)(typescript@6.0.3)': dependencies: - '@angular/compiler': 22.3.0-next.0 + '@angular/compiler': 22.3.0-next.1 '@babel/core': 8.0.6 '@jridgewell/sourcemap-codec': 1.6.0 chokidar: 5.0.0 @@ -8854,43 +8850,43 @@ snapshots: optionalDependencies: typescript: 6.0.3 - '@angular/compiler@22.3.0-next.0': + '@angular/compiler@22.3.0-next.1': dependencies: tslib: 2.8.1 - '@angular/core@22.3.0-next.0(@angular/compiler@22.3.0-next.0)(rxjs@7.8.2)(zone.js@0.16.3)': + '@angular/core@22.3.0-next.1(@angular/compiler@22.3.0-next.1)(rxjs@7.8.2)(zone.js@0.16.3)': dependencies: rxjs: 7.8.2 tslib: 2.8.1 optionalDependencies: - '@angular/compiler': 22.3.0-next.0 + '@angular/compiler': 22.3.0-next.1 zone.js: 0.16.3 - '@angular/forms@22.3.0-next.0(@angular/common@22.3.0-next.0(@angular/core@22.3.0-next.0(@angular/compiler@22.3.0-next.0)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2))(@angular/core@22.3.0-next.0(@angular/compiler@22.3.0-next.0)(rxjs@7.8.2)(zone.js@0.16.3))(@angular/platform-browser@22.3.0-next.0(@angular/animations@22.3.0-next.0(@angular/core@22.3.0-next.0(@angular/compiler@22.3.0-next.0)(rxjs@7.8.2)(zone.js@0.16.3)))(@angular/common@22.3.0-next.0(@angular/core@22.3.0-next.0(@angular/compiler@22.3.0-next.0)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2))(@angular/core@22.3.0-next.0(@angular/compiler@22.3.0-next.0)(rxjs@7.8.2)(zone.js@0.16.3)))(rxjs@7.8.2)': + '@angular/forms@22.3.0-next.1(@angular/common@22.3.0-next.1(@angular/core@22.3.0-next.1(@angular/compiler@22.3.0-next.1)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2))(@angular/core@22.3.0-next.1(@angular/compiler@22.3.0-next.1)(rxjs@7.8.2)(zone.js@0.16.3))(@angular/platform-browser@22.3.0-next.1(@angular/animations@22.3.0-next.1(@angular/core@22.3.0-next.1(@angular/compiler@22.3.0-next.1)(rxjs@7.8.2)(zone.js@0.16.3)))(@angular/common@22.3.0-next.1(@angular/core@22.3.0-next.1(@angular/compiler@22.3.0-next.1)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2))(@angular/core@22.3.0-next.1(@angular/compiler@22.3.0-next.1)(rxjs@7.8.2)(zone.js@0.16.3)))(rxjs@7.8.2)': dependencies: - '@angular/common': 22.3.0-next.0(@angular/core@22.3.0-next.0(@angular/compiler@22.3.0-next.0)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2) - '@angular/core': 22.3.0-next.0(@angular/compiler@22.3.0-next.0)(rxjs@7.8.2)(zone.js@0.16.3) - '@angular/platform-browser': 22.3.0-next.0(@angular/animations@22.3.0-next.0(@angular/core@22.3.0-next.0(@angular/compiler@22.3.0-next.0)(rxjs@7.8.2)(zone.js@0.16.3)))(@angular/common@22.3.0-next.0(@angular/core@22.3.0-next.0(@angular/compiler@22.3.0-next.0)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2))(@angular/core@22.3.0-next.0(@angular/compiler@22.3.0-next.0)(rxjs@7.8.2)(zone.js@0.16.3)) + '@angular/common': 22.3.0-next.1(@angular/core@22.3.0-next.1(@angular/compiler@22.3.0-next.1)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2) + '@angular/core': 22.3.0-next.1(@angular/compiler@22.3.0-next.1)(rxjs@7.8.2)(zone.js@0.16.3) + '@angular/platform-browser': 22.3.0-next.1(@angular/animations@22.3.0-next.1(@angular/core@22.3.0-next.1(@angular/compiler@22.3.0-next.1)(rxjs@7.8.2)(zone.js@0.16.3)))(@angular/common@22.3.0-next.1(@angular/core@22.3.0-next.1(@angular/compiler@22.3.0-next.1)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2))(@angular/core@22.3.0-next.1(@angular/compiler@22.3.0-next.1)(rxjs@7.8.2)(zone.js@0.16.3)) '@standard-schema/spec': 1.1.0 rxjs: 7.8.2 tslib: 2.8.1 zod: 4.6.5 - '@angular/localize@22.3.0-next.0(@angular/compiler-cli@22.3.0-next.0(@angular/compiler@22.3.0-next.0)(typescript@6.0.3))(@angular/compiler@22.3.0-next.0)': + '@angular/localize@22.3.0-next.1(@angular/compiler-cli@22.3.0-next.1(@angular/compiler@22.3.0-next.1)(typescript@6.0.3))(@angular/compiler@22.3.0-next.1)': dependencies: - '@angular/compiler': 22.3.0-next.0 - '@angular/compiler-cli': 22.3.0-next.0(@angular/compiler@22.3.0-next.0)(typescript@6.0.3) + '@angular/compiler': 22.3.0-next.1 + '@angular/compiler-cli': 22.3.0-next.1(@angular/compiler@22.3.0-next.1)(typescript@6.0.3) '@babel/core': 8.0.6 tinyglobby: 0.2.17 yargs: 18.2.0 - '@angular/material@22.3.0-next.1(b10c01331e6aa755f0c8f999dcc12d73)': + '@angular/material@22.3.0-next.1(837417520965053888cf2615dc986a27)': dependencies: - '@angular/cdk': 22.3.0-next.1(ea6b1043a273b7eace12f9dcd4a0b86a) - '@angular/common': 22.3.0-next.0(@angular/core@22.3.0-next.0(@angular/compiler@22.3.0-next.0)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2) - '@angular/core': 22.3.0-next.0(@angular/compiler@22.3.0-next.0)(rxjs@7.8.2)(zone.js@0.16.3) - '@angular/forms': 22.3.0-next.0(@angular/common@22.3.0-next.0(@angular/core@22.3.0-next.0(@angular/compiler@22.3.0-next.0)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2))(@angular/core@22.3.0-next.0(@angular/compiler@22.3.0-next.0)(rxjs@7.8.2)(zone.js@0.16.3))(@angular/platform-browser@22.3.0-next.0(@angular/animations@22.3.0-next.0(@angular/core@22.3.0-next.0(@angular/compiler@22.3.0-next.0)(rxjs@7.8.2)(zone.js@0.16.3)))(@angular/common@22.3.0-next.0(@angular/core@22.3.0-next.0(@angular/compiler@22.3.0-next.0)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2))(@angular/core@22.3.0-next.0(@angular/compiler@22.3.0-next.0)(rxjs@7.8.2)(zone.js@0.16.3)))(rxjs@7.8.2) - '@angular/platform-browser': 22.3.0-next.0(@angular/animations@22.3.0-next.0(@angular/core@22.3.0-next.0(@angular/compiler@22.3.0-next.0)(rxjs@7.8.2)(zone.js@0.16.3)))(@angular/common@22.3.0-next.0(@angular/core@22.3.0-next.0(@angular/compiler@22.3.0-next.0)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2))(@angular/core@22.3.0-next.0(@angular/compiler@22.3.0-next.0)(rxjs@7.8.2)(zone.js@0.16.3)) + '@angular/cdk': 22.3.0-next.1(1e228ab395252fe57958c1335d3a301f) + '@angular/common': 22.3.0-next.1(@angular/core@22.3.0-next.1(@angular/compiler@22.3.0-next.1)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2) + '@angular/core': 22.3.0-next.1(@angular/compiler@22.3.0-next.1)(rxjs@7.8.2)(zone.js@0.16.3) + '@angular/forms': 22.3.0-next.1(@angular/common@22.3.0-next.1(@angular/core@22.3.0-next.1(@angular/compiler@22.3.0-next.1)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2))(@angular/core@22.3.0-next.1(@angular/compiler@22.3.0-next.1)(rxjs@7.8.2)(zone.js@0.16.3))(@angular/platform-browser@22.3.0-next.1(@angular/animations@22.3.0-next.1(@angular/core@22.3.0-next.1(@angular/compiler@22.3.0-next.1)(rxjs@7.8.2)(zone.js@0.16.3)))(@angular/common@22.3.0-next.1(@angular/core@22.3.0-next.1(@angular/compiler@22.3.0-next.1)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2))(@angular/core@22.3.0-next.1(@angular/compiler@22.3.0-next.1)(rxjs@7.8.2)(zone.js@0.16.3)))(rxjs@7.8.2) + '@angular/platform-browser': 22.3.0-next.1(@angular/animations@22.3.0-next.1(@angular/core@22.3.0-next.1(@angular/compiler@22.3.0-next.1)(rxjs@7.8.2)(zone.js@0.16.3)))(@angular/common@22.3.0-next.1(@angular/core@22.3.0-next.1(@angular/compiler@22.3.0-next.1)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2))(@angular/core@22.3.0-next.1(@angular/compiler@22.3.0-next.1)(rxjs@7.8.2)(zone.js@0.16.3)) rxjs: 7.8.2 tslib: 2.8.1 @@ -8953,35 +8949,35 @@ snapshots: - '@modelcontextprotocol/sdk' - '@react-native-async-storage/async-storage' - '@angular/platform-browser@22.3.0-next.0(@angular/animations@22.3.0-next.0(@angular/core@22.3.0-next.0(@angular/compiler@22.3.0-next.0)(rxjs@7.8.2)(zone.js@0.16.3)))(@angular/common@22.3.0-next.0(@angular/core@22.3.0-next.0(@angular/compiler@22.3.0-next.0)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2))(@angular/core@22.3.0-next.0(@angular/compiler@22.3.0-next.0)(rxjs@7.8.2)(zone.js@0.16.3))': + '@angular/platform-browser@22.3.0-next.1(@angular/animations@22.3.0-next.1(@angular/core@22.3.0-next.1(@angular/compiler@22.3.0-next.1)(rxjs@7.8.2)(zone.js@0.16.3)))(@angular/common@22.3.0-next.1(@angular/core@22.3.0-next.1(@angular/compiler@22.3.0-next.1)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2))(@angular/core@22.3.0-next.1(@angular/compiler@22.3.0-next.1)(rxjs@7.8.2)(zone.js@0.16.3))': dependencies: - '@angular/common': 22.3.0-next.0(@angular/core@22.3.0-next.0(@angular/compiler@22.3.0-next.0)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2) - '@angular/core': 22.3.0-next.0(@angular/compiler@22.3.0-next.0)(rxjs@7.8.2)(zone.js@0.16.3) + '@angular/common': 22.3.0-next.1(@angular/core@22.3.0-next.1(@angular/compiler@22.3.0-next.1)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2) + '@angular/core': 22.3.0-next.1(@angular/compiler@22.3.0-next.1)(rxjs@7.8.2)(zone.js@0.16.3) tslib: 2.8.1 optionalDependencies: - '@angular/animations': 22.3.0-next.0(@angular/core@22.3.0-next.0(@angular/compiler@22.3.0-next.0)(rxjs@7.8.2)(zone.js@0.16.3)) + '@angular/animations': 22.3.0-next.1(@angular/core@22.3.0-next.1(@angular/compiler@22.3.0-next.1)(rxjs@7.8.2)(zone.js@0.16.3)) - '@angular/platform-server@22.3.0-next.0(@angular/common@22.3.0-next.0(@angular/core@22.3.0-next.0(@angular/compiler@22.3.0-next.0)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2))(@angular/compiler@22.3.0-next.0)(@angular/core@22.3.0-next.0(@angular/compiler@22.3.0-next.0)(rxjs@7.8.2)(zone.js@0.16.3))(@angular/platform-browser@22.3.0-next.0(@angular/animations@22.3.0-next.0(@angular/core@22.3.0-next.0(@angular/compiler@22.3.0-next.0)(rxjs@7.8.2)(zone.js@0.16.3)))(@angular/common@22.3.0-next.0(@angular/core@22.3.0-next.0(@angular/compiler@22.3.0-next.0)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2))(@angular/core@22.3.0-next.0(@angular/compiler@22.3.0-next.0)(rxjs@7.8.2)(zone.js@0.16.3)))(rxjs@7.8.2)': + '@angular/platform-server@22.3.0-next.1(@angular/common@22.3.0-next.1(@angular/core@22.3.0-next.1(@angular/compiler@22.3.0-next.1)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2))(@angular/compiler@22.3.0-next.1)(@angular/core@22.3.0-next.1(@angular/compiler@22.3.0-next.1)(rxjs@7.8.2)(zone.js@0.16.3))(@angular/platform-browser@22.3.0-next.1(@angular/animations@22.3.0-next.1(@angular/core@22.3.0-next.1(@angular/compiler@22.3.0-next.1)(rxjs@7.8.2)(zone.js@0.16.3)))(@angular/common@22.3.0-next.1(@angular/core@22.3.0-next.1(@angular/compiler@22.3.0-next.1)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2))(@angular/core@22.3.0-next.1(@angular/compiler@22.3.0-next.1)(rxjs@7.8.2)(zone.js@0.16.3)))(rxjs@7.8.2)': dependencies: - '@angular/common': 22.3.0-next.0(@angular/core@22.3.0-next.0(@angular/compiler@22.3.0-next.0)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2) - '@angular/compiler': 22.3.0-next.0 - '@angular/core': 22.3.0-next.0(@angular/compiler@22.3.0-next.0)(rxjs@7.8.2)(zone.js@0.16.3) - '@angular/platform-browser': 22.3.0-next.0(@angular/animations@22.3.0-next.0(@angular/core@22.3.0-next.0(@angular/compiler@22.3.0-next.0)(rxjs@7.8.2)(zone.js@0.16.3)))(@angular/common@22.3.0-next.0(@angular/core@22.3.0-next.0(@angular/compiler@22.3.0-next.0)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2))(@angular/core@22.3.0-next.0(@angular/compiler@22.3.0-next.0)(rxjs@7.8.2)(zone.js@0.16.3)) + '@angular/common': 22.3.0-next.1(@angular/core@22.3.0-next.1(@angular/compiler@22.3.0-next.1)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2) + '@angular/compiler': 22.3.0-next.1 + '@angular/core': 22.3.0-next.1(@angular/compiler@22.3.0-next.1)(rxjs@7.8.2)(zone.js@0.16.3) + '@angular/platform-browser': 22.3.0-next.1(@angular/animations@22.3.0-next.1(@angular/core@22.3.0-next.1(@angular/compiler@22.3.0-next.1)(rxjs@7.8.2)(zone.js@0.16.3)))(@angular/common@22.3.0-next.1(@angular/core@22.3.0-next.1(@angular/compiler@22.3.0-next.1)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2))(@angular/core@22.3.0-next.1(@angular/compiler@22.3.0-next.1)(rxjs@7.8.2)(zone.js@0.16.3)) rxjs: 7.8.2 tslib: 2.8.1 xhr2: 0.2.1 - '@angular/router@22.3.0-next.0(@angular/common@22.3.0-next.0(@angular/core@22.3.0-next.0(@angular/compiler@22.3.0-next.0)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2))(@angular/core@22.3.0-next.0(@angular/compiler@22.3.0-next.0)(rxjs@7.8.2)(zone.js@0.16.3))(@angular/platform-browser@22.3.0-next.0(@angular/animations@22.3.0-next.0(@angular/core@22.3.0-next.0(@angular/compiler@22.3.0-next.0)(rxjs@7.8.2)(zone.js@0.16.3)))(@angular/common@22.3.0-next.0(@angular/core@22.3.0-next.0(@angular/compiler@22.3.0-next.0)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2))(@angular/core@22.3.0-next.0(@angular/compiler@22.3.0-next.0)(rxjs@7.8.2)(zone.js@0.16.3)))(rxjs@7.8.2)': + '@angular/router@22.3.0-next.1(@angular/common@22.3.0-next.1(@angular/core@22.3.0-next.1(@angular/compiler@22.3.0-next.1)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2))(@angular/core@22.3.0-next.1(@angular/compiler@22.3.0-next.1)(rxjs@7.8.2)(zone.js@0.16.3))(@angular/platform-browser@22.3.0-next.1(@angular/animations@22.3.0-next.1(@angular/core@22.3.0-next.1(@angular/compiler@22.3.0-next.1)(rxjs@7.8.2)(zone.js@0.16.3)))(@angular/common@22.3.0-next.1(@angular/core@22.3.0-next.1(@angular/compiler@22.3.0-next.1)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2))(@angular/core@22.3.0-next.1(@angular/compiler@22.3.0-next.1)(rxjs@7.8.2)(zone.js@0.16.3)))(rxjs@7.8.2)': dependencies: - '@angular/common': 22.3.0-next.0(@angular/core@22.3.0-next.0(@angular/compiler@22.3.0-next.0)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2) - '@angular/core': 22.3.0-next.0(@angular/compiler@22.3.0-next.0)(rxjs@7.8.2)(zone.js@0.16.3) - '@angular/platform-browser': 22.3.0-next.0(@angular/animations@22.3.0-next.0(@angular/core@22.3.0-next.0(@angular/compiler@22.3.0-next.0)(rxjs@7.8.2)(zone.js@0.16.3)))(@angular/common@22.3.0-next.0(@angular/core@22.3.0-next.0(@angular/compiler@22.3.0-next.0)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2))(@angular/core@22.3.0-next.0(@angular/compiler@22.3.0-next.0)(rxjs@7.8.2)(zone.js@0.16.3)) + '@angular/common': 22.3.0-next.1(@angular/core@22.3.0-next.1(@angular/compiler@22.3.0-next.1)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2) + '@angular/core': 22.3.0-next.1(@angular/compiler@22.3.0-next.1)(rxjs@7.8.2)(zone.js@0.16.3) + '@angular/platform-browser': 22.3.0-next.1(@angular/animations@22.3.0-next.1(@angular/core@22.3.0-next.1(@angular/compiler@22.3.0-next.1)(rxjs@7.8.2)(zone.js@0.16.3)))(@angular/common@22.3.0-next.1(@angular/core@22.3.0-next.1(@angular/compiler@22.3.0-next.1)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2))(@angular/core@22.3.0-next.1(@angular/compiler@22.3.0-next.1)(rxjs@7.8.2)(zone.js@0.16.3)) rxjs: 7.8.2 tslib: 2.8.1 - '@angular/service-worker@22.3.0-next.0(@angular/core@22.3.0-next.0(@angular/compiler@22.3.0-next.0)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2)': + '@angular/service-worker@22.3.0-next.1(@angular/core@22.3.0-next.1(@angular/compiler@22.3.0-next.1)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2)': dependencies: - '@angular/core': 22.3.0-next.0(@angular/compiler@22.3.0-next.0)(rxjs@7.8.2)(zone.js@0.16.3) + '@angular/core': 22.3.0-next.1(@angular/compiler@22.3.0-next.1)(rxjs@7.8.2)(zone.js@0.16.3) rxjs: 7.8.2 tslib: 2.8.1 @@ -9039,11 +9035,11 @@ snapshots: dependencies: '@babel/code-frame': 8.0.6 '@babel/generator': 8.0.6 - '@babel/helper-compilation-targets': 8.0.6 - '@babel/helpers': 8.0.5 - '@babel/parser': 8.0.6 + '@babel/helper-compilation-targets': 8.0.7 + '@babel/helpers': 8.0.7 + '@babel/parser': 8.0.7 '@babel/template': 8.0.0 - '@babel/traverse': 8.0.6 + '@babel/traverse': 8.0.7 '@babel/types': 8.0.6 '@types/gensync': 1.0.5 convert-source-map: 2.0.0 @@ -9234,11 +9230,6 @@ snapshots: '@babel/template': 7.29.7 '@babel/types': 7.29.8 - '@babel/helpers@8.0.5': - dependencies: - '@babel/template': 8.0.0 - '@babel/types': 8.0.6 - '@babel/helpers@8.0.7': dependencies: '@babel/template': 8.0.0 @@ -15160,10 +15151,10 @@ snapshots: neo-async@2.6.2: {} - ng-packagr@22.3.0-next.2(@angular/compiler-cli@22.3.0-next.0(@angular/compiler@22.3.0-next.0)(typescript@6.0.3))(supports-color@11.0.0)(tslib@2.8.1)(typescript@6.0.3): + ng-packagr@22.3.0-next.2(@angular/compiler-cli@22.3.0-next.1(@angular/compiler@22.3.0-next.1)(typescript@6.0.3))(supports-color@11.0.0)(tslib@2.8.1)(typescript@6.0.3): dependencies: '@ampproject/remapping': 2.3.0 - '@angular/compiler-cli': 22.3.0-next.0(@angular/compiler@22.3.0-next.0)(typescript@6.0.3) + '@angular/compiler-cli': 22.3.0-next.1(@angular/compiler@22.3.0-next.1)(typescript@6.0.3) ajv: 8.20.0 browserslist: 4.29.3 chokidar: 5.0.0 diff --git a/tests/e2e/ng-snapshot/package.json b/tests/e2e/ng-snapshot/package.json index bb953133b7d2..a3e554ca1640 100644 --- a/tests/e2e/ng-snapshot/package.json +++ b/tests/e2e/ng-snapshot/package.json @@ -2,21 +2,21 @@ "description": "snapshot versions of Angular for e2e testing", "private": true, "dependencies": { - "@angular/animations": "github:angular/animations-builds#9e24af5126eb428ddb52ca7d05958521a94b70b1", + "@angular/animations": "github:angular/animations-builds#3ec405d1cb11a6f18eacdd7e09378cd097a9a427", "@angular/cdk": "github:angular/cdk-builds#8eedcdb798ec78b2c0191953b46804f54296ed4f", - "@angular/common": "github:angular/common-builds#4a8c0898c5f1396d06b40809933fc1c543c9af02", - "@angular/compiler": "github:angular/compiler-builds#157f0763bb55cc3e8149420ee7e7e1096ab4e22c", - "@angular/compiler-cli": "github:angular/compiler-cli-builds#95336134d6901900087391b94b3ce65e3be33e62", - "@angular/core": "github:angular/core-builds#e654a614cbd7e658aad2d01365f008c253b6c0a2", - "@angular/forms": "github:angular/forms-builds#d376d01dda51bf3d05a357c14c45fd2879eeb39d", - "@angular/language-service": "github:angular/language-service-builds#3ddaa8598aa9a80fe07d0f47e2bc49333c85d1de", - "@angular/localize": "github:angular/localize-builds#b494cd4ff05b6c7d59be3e98890b5f53f246ee0c", + "@angular/common": "github:angular/common-builds#bae1a4226a83f02bcb77b6ef447e039d8b5081f3", + "@angular/compiler": "github:angular/compiler-builds#fc8fced0b21574f7846b999a751511f9a453e0cd", + "@angular/compiler-cli": "github:angular/compiler-cli-builds#20b42c8d2e12f28eea2376ff0b0f1f5ec59cac63", + "@angular/core": "github:angular/core-builds#080d86fc456c2029952d72e43ae5e019374a3546", + "@angular/forms": "github:angular/forms-builds#b8ff96856639a22bb3dec5c8bebb562c5395c638", + "@angular/language-service": "github:angular/language-service-builds#9e0a5e50a0f37d5671fc2478ebf2626399fb23f4", + "@angular/localize": "github:angular/localize-builds#fec5dc5c69698fbf47aa794ac8fd80a2baa9b1d5", "@angular/material": "github:angular/material-builds#72d50c0fd59ea4d1f7fc2053d74d4f2610503730", "@angular/material-moment-adapter": "github:angular/material-moment-adapter-builds#30012ad773e0536aa4e5ff009c1b65ec8bb1e5f2", - "@angular/platform-browser": "github:angular/platform-browser-builds#481662d30ee37502a19925b40bc64104d45f5e27", - "@angular/platform-browser-dynamic": "github:angular/platform-browser-dynamic-builds#1bf7ebb2e4213b0b4c4ad4ec19be6fb388d4bf13", - "@angular/platform-server": "github:angular/platform-server-builds#98b84d4d641602bc0863f4ba5d2a303036c811fb", - "@angular/router": "github:angular/router-builds#bda66334596e52fdd93f67756875a7d638b5964d", - "@angular/service-worker": "github:angular/service-worker-builds#9427e75866a3e1c0135278a22a482ab6f62ab4eb" + "@angular/platform-browser": "github:angular/platform-browser-builds#ca08a1a24ac892344fb1f69c6f5ac15eb504370b", + "@angular/platform-browser-dynamic": "github:angular/platform-browser-dynamic-builds#163f8f1af3365efeab12b2656ad229a8d76e39b9", + "@angular/platform-server": "github:angular/platform-server-builds#fe61afa721e53041b0bac92f0241a82326d72a47", + "@angular/router": "github:angular/router-builds#7df611a733d4a35d41fd4b5596e0a9800cc67e8e", + "@angular/service-worker": "github:angular/service-worker-builds#3ef11b4fbbd965535f0f45de2ba41a4e3886b918" } } From 2e0f48e3ff40289725d3590fa8e1fc059fbaeb88 Mon Sep 17 00:00:00 2001 From: rk Date: Sat, 10 Oct 2026 19:06:37 +0500 Subject: [PATCH 584/787] fix(@angular/cli): keep ng version working when the package manager is not installed `getVersion()` throws when configured package manager is missing, so `ng version` crashed insted of printing `` Version is left undefined now, same as analytics in command-module.ts --- .../cli/src/commands/version/version-info.ts | 9 ++- .../src/commands/version/version-info_spec.ts | 64 +++++++++++++++++++ 2 files changed, 72 insertions(+), 1 deletion(-) create mode 100644 packages/angular/cli/src/commands/version/version-info_spec.ts diff --git a/packages/angular/cli/src/commands/version/version-info.ts b/packages/angular/cli/src/commands/version/version-info.ts index 128cc8ef5449..9709567e382b 100644 --- a/packages/angular/cli/src/commands/version/version-info.ts +++ b/packages/angular/cli/src/commands/version/version-info.ts @@ -104,6 +104,13 @@ export async function gatherVersionInfo(context: CommandContext): Promise { + let tempRoot: string; + + beforeEach(async () => { + const baseTmpDir = process.env['TEST_TMPDIR']; + assert(baseTmpDir, 'TEST_TMPDIR is not set'); + tempRoot = await mkdtemp(join(baseTmpDir, 'angular-cli-version-info-test-')); + }); + + afterEach(async () => { + await rm(tempRoot, { recursive: true, force: true }); + }); + + function createContext(packageManager: PackageManager): CommandContext { + return { root: tempRoot, packageManager } as unknown as CommandContext; + } + + it('should report the package manager version when it is available', async () => { + const packageManager = new PackageManager( + new MockHost(), + tempRoot, + SUPPORTED_PACKAGE_MANAGERS['npm'], + { version: '10.9.0' }, + ); + + const info = await gatherVersionInfo(createContext(packageManager)); + + expect(info.system.packageManager).toEqual({ name: 'npm', version: '10.9.0' }); + }); + + it('should not fail when the package manager is not installed', async () => { + const packageManager = new PackageManager( + new MockHost(), + tempRoot, + SUPPORTED_PACKAGE_MANAGERS['bun'], + { + initializationError: new Error( + `The project is configured to use 'bun', but it is not installed.`, + ), + }, + ); + + const info = await gatherVersionInfo(createContext(packageManager)); + + expect(info.system.packageManager).toEqual({ name: 'bun', version: undefined }); + }); +}); From 5c656152ef91e2731155f6027a845d8014b53e4f Mon Sep 17 00:00:00 2001 From: rk Date: Sat, 10 Oct 2026 18:53:58 +0500 Subject: [PATCH 585/787] fix(@angular/cli): accept multi-digit array indices in ng config multi-digit index like `styles[10]` stayed string, so get failed and set threw now any run of digits is parsed as array idnex --- .../angular/cli/src/commands/config/cli.ts | 5 +-- .../cli/src/commands/config/cli_spec.ts | 37 +++++++++++++++++++ 2 files changed, 39 insertions(+), 3 deletions(-) create mode 100644 packages/angular/cli/src/commands/config/cli_spec.ts diff --git a/packages/angular/cli/src/commands/config/cli.ts b/packages/angular/cli/src/commands/config/cli.ts index ae25f3839e22..ef7cfd95d5a5 100644 --- a/packages/angular/cli/src/commands/config/cli.ts +++ b/packages/angular/cli/src/commands/config/cli.ts @@ -133,9 +133,8 @@ export default class ConfigCommandModule * ["a", 3, "foo", "bar", 2]. * @param path The JSON string to parse. * @returns {(string|number)[]} The fragments for the string. - * @private */ -function parseJsonPath(path: string): (string | number)[] { +export function parseJsonPath(path: string): (string | number)[] { const fragments = (path || '').split(/\./g); const result: (string | number)[] = []; @@ -155,7 +154,7 @@ function parseJsonPath(path: string): (string | number)[] { const indices = match[2] .slice(1, -1) .split('][') - .map((x) => (/^\d$/.test(x) ? +x : x.replace(/"|'/g, ''))); + .map((x) => (/^\d+$/.test(x) ? +x : x.replace(/"|'/g, ''))); result.push(...indices); } } diff --git a/packages/angular/cli/src/commands/config/cli_spec.ts b/packages/angular/cli/src/commands/config/cli_spec.ts new file mode 100644 index 000000000000..dd8fe4790e16 --- /dev/null +++ b/packages/angular/cli/src/commands/config/cli_spec.ts @@ -0,0 +1,37 @@ +/** + * @license + * Copyright Google LLC All Rights Reserved. + * + * Use of this source code is governed by an MIT-style license that can be + * found in the LICENSE file at https://angular.dev/license + */ + +import { parseJsonPath } from './cli'; + +describe('parseJsonPath', () => { + it('should parse single digit array indices', () => { + expect(parseJsonPath('a[3].foo.bar[2]')).toEqual(['a', 3, 'foo', 'bar', 2]); + }); + + it('should parse multi digit array indices', () => { + expect(parseJsonPath('projects.app.architect.build.options.styles[10]')).toEqual([ + 'projects', + 'app', + 'architect', + 'build', + 'options', + 'styles', + 10, + ]); + expect(parseJsonPath('a[2][13].b')).toEqual(['a', 2, 13, 'b']); + }); + + it('should keep quoted keys as strings', () => { + expect(parseJsonPath('projects["test-project"].root')).toEqual([ + 'projects', + 'test-project', + 'root', + ]); + expect(parseJsonPath(`a['10']`)).toEqual(['a', '10']); + }); +}); From 445cc767e62b72631dd53c0c5324b458fee76608 Mon Sep 17 00:00:00 2001 From: rk Date: Sat, 10 Oct 2026 18:54:01 +0500 Subject: [PATCH 586/787] fix(@schematics/angular): keep the workspace build version in the use-application-builder migration migration added `@angular/build` at version of CLI running it, so `ng update --name` on older workspace pulled newest major now it reuses `@angular-devkit/build-angular` specifer and leaves existing `@angular/build` alone Fixes #30696 --- .../use-application-builder/migration.ts | 9 +++- .../use-application-builder/migration_spec.ts | 42 +++++++++++++++++++ 2 files changed, 49 insertions(+), 2 deletions(-) diff --git a/packages/schematics/angular/migrations/use-application-builder/migration.ts b/packages/schematics/angular/migrations/use-application-builder/migration.ts index b481c4f30034..dcf0526a3945 100644 --- a/packages/schematics/angular/migrations/use-application-builder/migration.ts +++ b/packages/schematics/angular/migrations/use-application-builder/migration.ts @@ -19,6 +19,7 @@ import { DependencyType, ExistingBehavior, addDependency, + getDependency, removeDependency, } from '../../utility/dependency'; import { JSONFile } from '../../utility/json-file'; @@ -270,10 +271,14 @@ function updateProjects(tree: Tree, context: SchematicContext) { } // Add direct @angular/build dependencies and remove @angular-devkit/build-angular + // Keep the workspace version since this migration can run from a newer temporary CLI + const buildAngularVersion = + getDependency(tree, '@angular-devkit/build-angular')?.version ?? + latestVersions.AngularBuild; rules.push( - addDependency('@angular/build', latestVersions.DevkitBuildAngular, { + addDependency('@angular/build', buildAngularVersion, { type: DependencyType.Dev, - existing: ExistingBehavior.Replace, + existing: ExistingBehavior.Skip, }), removeDependency('@angular-devkit/build-angular'), ); diff --git a/packages/schematics/angular/migrations/use-application-builder/migration_spec.ts b/packages/schematics/angular/migrations/use-application-builder/migration_spec.ts index fd10352c6eac..05259962dc5d 100644 --- a/packages/schematics/angular/migrations/use-application-builder/migration_spec.ts +++ b/packages/schematics/angular/migrations/use-application-builder/migration_spec.ts @@ -9,6 +9,7 @@ import { JsonObject } from '@angular-devkit/core'; import { EmptyTree } from '@angular-devkit/schematics'; import { SchematicTestRunner, UnitTestTree } from '@angular-devkit/schematics/testing'; +import { latestVersions } from '../../utility/latest-versions'; import { Builders, ProjectType, WorkspaceSchema } from '../../utility/workspace-models'; function createWorkSpaceConfig(tree: UnitTestTree) { @@ -450,6 +451,47 @@ describe(`Migration to use the application builder`, () => { expect(devDependencies['postcss']).toBeUndefined(); }); + describe('"@angular/build" version', () => { + async function migrateWith( + manifest: object, + ): Promise<{ devDependencies: Record }> { + tree.overwrite('/package.json', JSON.stringify(manifest)); + const newTree = await schematicRunner.runSchematic(schematicName, {}, tree); + + return JSON.parse(newTree.readContent('/package.json')); + } + + it('should follow the "@angular-devkit/build-angular" range of the workspace', async () => { + const { devDependencies } = await migrateWith({ + devDependencies: { '@angular-devkit/build-angular': '~19.1.4' }, + }); + + expect(devDependencies['@angular/build']).toBe('~19.1.4'); + }); + + it('should read "@angular-devkit/build-angular" from "dependencies" as well', async () => { + const { devDependencies } = await migrateWith({ + dependencies: { '@angular-devkit/build-angular': '18.2.1' }, + }); + + expect(devDependencies['@angular/build']).toBe('18.2.1'); + }); + + it('should keep an "@angular/build" that is already installed', async () => { + const { devDependencies } = await migrateWith({ + devDependencies: { '@angular-devkit/build-angular': '^19.2.0', '@angular/build': '19.0.3' }, + }); + + expect(devDependencies['@angular/build']).toBe('19.0.3'); + }); + + it('should fall back to the latest "@angular/build" without "@angular-devkit/build-angular"', async () => { + const { devDependencies } = await migrateWith({}); + + expect(devDependencies['@angular/build']).toBe(latestVersions.AngularBuild); + }); + }); + it('it should not add esModuleInterop and moduleResolution when module is preserve', async () => { tree.overwrite( 'tsconfig.json', From 13923047f64b6e1063f7f07029c70295b5c99d69 Mon Sep 17 00:00:00 2001 From: rk Date: Sat, 10 Oct 2026 19:16:57 +0500 Subject: [PATCH 587/787] fix(@angular/build): always use AOT when extracting i18n messages with `aot: false` on build target, extraction built app in JIT and template messages never got into extracted file webpack extraction alredy forced AOT, application extraction now does same --- .../builders/extract-i18n/application-extraction.ts | 1 + .../builders/extract-i18n/application-extraction.ts | 1 + tests/e2e/tests/i18n/extract-ivy.ts | 11 ++++++++++- 3 files changed, 12 insertions(+), 1 deletion(-) diff --git a/packages/angular/build/src/builders/extract-i18n/application-extraction.ts b/packages/angular/build/src/builders/extract-i18n/application-extraction.ts index ff223ba0bd16..b18c8164481f 100644 --- a/packages/angular/build/src/builders/extract-i18n/application-extraction.ts +++ b/packages/angular/build/src/builders/extract-i18n/application-extraction.ts @@ -39,6 +39,7 @@ export async function extractMessages( await context.getTargetOptions(options.buildTarget), builderName, )) as unknown as ApplicationBuilderInternalOptions; + buildOptions.aot = true; buildOptions.optimization = false; buildOptions.sourceMap = { scripts: true, vendor: true, styles: false }; buildOptions.localize = false; diff --git a/packages/angular_devkit/build_angular/src/builders/extract-i18n/application-extraction.ts b/packages/angular_devkit/build_angular/src/builders/extract-i18n/application-extraction.ts index 8de8b6863aaf..68347fa0fb24 100644 --- a/packages/angular_devkit/build_angular/src/builders/extract-i18n/application-extraction.ts +++ b/packages/angular_devkit/build_angular/src/builders/extract-i18n/application-extraction.ts @@ -45,6 +45,7 @@ export async function extractMessages( ); } + buildOptions.aot = true; buildOptions.optimization = false; buildOptions.sourceMap = { scripts: true, vendor: true, styles: false }; buildOptions.localize = false; diff --git a/tests/e2e/tests/i18n/extract-ivy.ts b/tests/e2e/tests/i18n/extract-ivy.ts index 382051e83cce..cf0d23da08e3 100644 --- a/tests/e2e/tests/i18n/extract-ivy.ts +++ b/tests/e2e/tests/i18n/extract-ivy.ts @@ -1,8 +1,9 @@ import { join } from 'node:path'; import { getGlobalVariable } from '../../utils/env'; -import { expectFileToMatch, writeFile } from '../../utils/fs'; +import { deleteFile, expectFileToMatch, writeFile } from '../../utils/fs'; import { uninstallPackage } from '../../utils/packages'; import { ng } from '../../utils/process'; +import { updateJsonFile } from '../../utils/project'; import { expectToFail } from '../../utils/utils'; import { readNgVersion } from '../../utils/version'; @@ -52,5 +53,13 @@ export default async function () { await expectFileToMatch('messages.xlf', 'Hello world'); + // Template messages should also be extracted when the build target disables AOT + await updateJsonFile('angular.json', (workspaceJson) => { + workspaceJson.projects['test-project'].architect.build.options.aot = false; + }); + await deleteFile('messages.xlf'); + await ng('extract-i18n'); + await expectFileToMatch('messages.xlf', 'Hello world'); + await uninstallPackage('@angular/localize'); } From f2cd8c8cf7c5aa7e7076c87e9c0c55b3bf880f4b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Benjamin=20Sch=C3=A4ublin?= Date: Mon, 12 Oct 2026 10:08:49 +0200 Subject: [PATCH 588/787] fix(@angular/ssr): preserve query parameters on relative route redirects Route redirects are answered on the server from the route configuration, without running the router. For a relative `redirectTo`, the router keeps the query string of the current URL and ignores a query string in `redirectTo`, but the server did the opposite. It now does the same as the router. Absolute redirects are unchanged, as the router does not keep the query string of the current URL for them either. --- packages/angular/ssr/src/app.ts | 13 ++- packages/angular/ssr/src/routes/ng-routes.ts | 9 +- packages/angular/ssr/src/routes/route-tree.ts | 3 + packages/angular/ssr/test/app_spec.ts | 33 +++++++ .../angular/ssr/test/routes/ng-routes_spec.ts | 99 +++++++++++++++++-- .../angular/ssr/test/routes/router_spec.ts | 3 + 6 files changed, 146 insertions(+), 14 deletions(-) diff --git a/packages/angular/ssr/src/app.ts b/packages/angular/ssr/src/app.ts index 6c0202a8f9b3..517cf1e31727 100644 --- a/packages/angular/ssr/src/app.ts +++ b/packages/angular/ssr/src/app.ts @@ -163,14 +163,17 @@ export class AngularServerApp { return null; } - const { redirectTo, status, renderMode, headers } = matchedRoute; + const { redirectTo, relativeRedirect, status, renderMode, headers } = matchedRoute; if (redirectTo !== undefined) { + const location = joinUrlParts( + request.headers.get('X-Forwarded-Prefix') ?? '', + buildPathWithParams(redirectTo, url.pathname), + ); + + // Match Angular router behavior: relative redirects keep the query string. return createRedirectResponse( - joinUrlParts( - request.headers.get('X-Forwarded-Prefix') ?? '', - buildPathWithParams(redirectTo, url.pathname), - ), + relativeRedirect ? location + url.search : location, status, headers, ); diff --git a/packages/angular/ssr/src/routes/ng-routes.ts b/packages/angular/ssr/src/routes/ng-routes.ts index ac83aae8cd4f..63313b875d34 100644 --- a/packages/angular/ssr/src/routes/ng-routes.ts +++ b/packages/angular/ssr/src/routes/ng-routes.ts @@ -192,6 +192,7 @@ async function* handleRoute(options: { yield { ...metadata, redirectTo: resolveRedirectTo(metadata.route, redirectTo), + relativeRedirect: redirectTo[0] !== '/' ? true : undefined, }; } else { yield metadata; @@ -421,6 +422,7 @@ async function* handleSSGRoute( if (redirectTo !== undefined) { meta.redirectTo = resolveRedirectTo(currentRoutePath, redirectTo); + meta.relativeRedirect = redirectTo[0] !== '/' ? true : undefined; } const isCatchAllRoute = CATCH_ALL_REGEXP.test(currentRoutePath); @@ -534,7 +536,8 @@ function handlePrerenderParamsReplacement( * * This function processes the `redirectTo` property to ensure that it correctly * resolves relative to the current route path. If `redirectTo` is an absolute path, - * it is returned as is. If it is a relative path, it is resolved based on the current route path. + * it is returned as is. If it is a relative path, it is resolved based on the current route path, + * and, like in the Angular router, its query and fragment are ignored. * * @param routePath - The current route path. * @param redirectTo - The target path for redirection. @@ -550,7 +553,9 @@ function resolveRedirectTo(routePath: string, redirectTo: string): string { const segments = routePath.replace(URL_PARAMETER_GLOBAL_REGEXP, '*').split('/'); segments.pop(); // Remove the last segment to make it relative. - return joinUrlParts(...segments, redirectTo); + const [path] = redirectTo.split(/[?#]/, 1); + + return joinUrlParts(...segments, path); } /** diff --git a/packages/angular/ssr/src/routes/route-tree.ts b/packages/angular/ssr/src/routes/route-tree.ts index ff689a3c90f5..253783a5f13c 100644 --- a/packages/angular/ssr/src/routes/route-tree.ts +++ b/packages/angular/ssr/src/routes/route-tree.ts @@ -31,6 +31,9 @@ export interface RouteTreeNodeMetadata { */ redirectTo?: string; + /** Indicates if `redirectTo` was defined as a relative path. */ + relativeRedirect?: boolean; + /** * The route path for this node. * diff --git a/packages/angular/ssr/test/app_spec.ts b/packages/angular/ssr/test/app_spec.ts index b317f99f1d3a..91e847f0bf80 100644 --- a/packages/angular/ssr/test/app_spec.ts +++ b/packages/angular/ssr/test/app_spec.ts @@ -88,6 +88,7 @@ describe('AngularServerApp', () => { { path: 'redirect/relative', redirectTo: 'home' }, { path: 'redirect/:param/relative', redirectTo: 'home' }, { path: 'redirect/absolute', redirectTo: '/home' }, + { path: 'redirect-with-query', redirectTo: 'home?param=value' }, { path: 'redirect-to-function', redirectTo: () => 'home', @@ -222,6 +223,28 @@ describe('AngularServerApp', () => { expect(response?.status).toBe(302); }); + it('should preserve query parameters on relative redirects', async () => { + const response = await app.handle(new Request('http://localhost/redirect?filter=test')); + expect(response?.headers.get('location')).toBe('/home?filter=test'); + expect(response?.status).toBe(302); + }); + + it('should ignore query parameters of relative redirect targets', async () => { + const response = await app.handle( + new Request('http://localhost/redirect-with-query?filter=test'), + ); + expect(response?.headers.get('location')).toBe('/home?filter=test'); + expect(response?.status).toBe(302); + }); + + it('should not preserve query parameters on absolute redirects', async () => { + const response = await app.handle( + new Request('http://localhost/redirect/absolute?filter=test'), + ); + expect(response?.headers.get('location')).toBe('/home'); + expect(response?.status).toBe(302); + }); + it('should handle request abortion gracefully', async () => { const controller = new AbortController(); const request = new Request('http://localhost/home', { signal: controller.signal }); @@ -498,6 +521,16 @@ describe('AngularServerApp', () => { expect(response?.headers.get('location')).toBe('/base/home'); expect(response?.status).toBe(302); }); + + it('returns a 302 status and keeps the query string for relative redirects', async () => { + const response = await app.handle( + new Request('http://localhost/redirect?filter=test', { + headers, + }), + ); + expect(response?.headers.get('location')).toBe('/base/home?filter=test'); + expect(response?.status).toBe(302); + }); }); describe('Critical CSS inlining', () => { diff --git a/packages/angular/ssr/test/routes/ng-routes_spec.ts b/packages/angular/ssr/test/routes/ng-routes_spec.ts index e214c31eab71..f26d6fb4913c 100644 --- a/packages/angular/ssr/test/routes/ng-routes_spec.ts +++ b/packages/angular/ssr/test/routes/ng-routes_spec.ts @@ -51,7 +51,13 @@ describe('extractRoutesAndCreateRouteTree', () => { expect(routeTree.toObject()).toEqual([ { route: '/', renderMode: RenderMode.Server }, { route: '/home', renderMode: RenderMode.Client }, - { route: '/redirect', renderMode: RenderMode.Server, status: 301, redirectTo: '/home' }, + { + route: '/redirect', + renderMode: RenderMode.Server, + status: 301, + redirectTo: '/home', + relativeRedirect: true, + }, { route: '/user/*', renderMode: RenderMode.Server }, ]); }); @@ -371,10 +377,25 @@ describe('extractRoutesAndCreateRouteTree', () => { expect(errors).toHaveSize(0); expect(routeTree.toObject()).toEqual([ - { route: '/', renderMode: RenderMode.Prerender, redirectTo: '/some' }, - { route: '/some', renderMode: RenderMode.Prerender, redirectTo: '/some/thing' }, + { + route: '/', + renderMode: RenderMode.Prerender, + redirectTo: '/some', + relativeRedirect: true, + }, + { + route: '/some', + renderMode: RenderMode.Prerender, + redirectTo: '/some/thing', + relativeRedirect: true, + }, { route: '/some/thing', renderMode: RenderMode.Prerender }, - { redirectTo: '/*/thing', route: '/*', renderMode: RenderMode.Server }, + { + redirectTo: '/*/thing', + relativeRedirect: true, + route: '/*', + renderMode: RenderMode.Server, + }, { route: '/*/thing', renderMode: RenderMode.Server }, ]); }); @@ -496,8 +517,13 @@ describe('extractRoutesAndCreateRouteTree', () => { const { routeTree, errors } = await extractRoutesAndCreateRouteTree({ url }); expect(errors).toHaveSize(0); expect(routeTree.toObject()).toEqual([ - { route: '/', renderMode: RenderMode.Server, redirectTo: '/some' }, - { route: '/*', renderMode: RenderMode.Server, redirectTo: '/*/thing' }, + { route: '/', renderMode: RenderMode.Server, redirectTo: '/some', relativeRedirect: true }, + { + route: '/*', + renderMode: RenderMode.Server, + redirectTo: '/*/thing', + relativeRedirect: true, + }, { route: '/*/thing', renderMode: RenderMode.Server }, ]); }); @@ -526,11 +552,70 @@ describe('extractRoutesAndCreateRouteTree', () => { const { routeTree, errors } = await extractRoutesAndCreateRouteTree({ url }); expect(errors).toHaveSize(0); expect(routeTree.toObject()).toEqual([ - { route: '/*/*', renderMode: RenderMode.Server, redirectTo: '/*/*/thing' }, + { + route: '/*/*', + renderMode: RenderMode.Server, + redirectTo: '/*/*/thing', + relativeRedirect: true, + }, { route: '/*/*/thing', renderMode: RenderMode.Server }, ]); }); + it('should not mark absolute redirects as relative', async () => { + setAngularAppTestingManifest( + [ + { path: 'server', redirectTo: '/home' }, + { path: 'prerender', redirectTo: '/home' }, + { path: 'home', component: DummyComponent }, + ], + [ + { path: 'prerender', renderMode: RenderMode.Prerender }, + { path: '**', renderMode: RenderMode.Server }, + ], + ); + + const { routeTree, errors } = await extractRoutesAndCreateRouteTree({ url }); + expect(errors).toHaveSize(0); + expect(routeTree.toObject()).toEqual([ + { route: '/server', renderMode: RenderMode.Server, redirectTo: '/home' }, + { route: '/prerender', renderMode: RenderMode.Prerender, redirectTo: '/home' }, + { route: '/home', renderMode: RenderMode.Server }, + ]); + }); + + it('should ignore the query and fragment of relative redirect targets', async () => { + setAngularAppTestingManifest( + [ + { path: 'server', redirectTo: 'home?param=value#fragment' }, + { path: 'prerender', redirectTo: 'home?param=value#fragment' }, + { path: 'home', component: DummyComponent }, + ], + [ + { path: 'prerender', renderMode: RenderMode.Prerender }, + { path: '**', renderMode: RenderMode.Server }, + ], + ); + + const { routeTree, errors } = await extractRoutesAndCreateRouteTree({ url }); + expect(errors).toHaveSize(0); + expect(routeTree.toObject()).toEqual([ + { + route: '/server', + renderMode: RenderMode.Server, + redirectTo: '/home', + relativeRedirect: true, + }, + { + route: '/prerender', + renderMode: RenderMode.Prerender, + redirectTo: '/home', + relativeRedirect: true, + }, + { route: '/home', renderMode: RenderMode.Server }, + ]); + }); + it('should not resolve parameterized routes for SSG when `invokeGetPrerenderParams` is false', async () => { setAngularAppTestingManifest( [ diff --git a/packages/angular/ssr/test/routes/router_spec.ts b/packages/angular/ssr/test/routes/router_spec.ts index 380bc659549a..95006eda5f5b 100644 --- a/packages/angular/ssr/test/routes/router_spec.ts +++ b/packages/angular/ssr/test/routes/router_spec.ts @@ -55,6 +55,7 @@ describe('ServerRouter', () => { }); expect(router.match(new URL('http://localhost/redirect'))).toEqual({ redirectTo: '/home', + relativeRedirect: true, route: '/redirect', renderMode: RenderMode.Server, status: 301, @@ -89,6 +90,7 @@ describe('ServerRouter', () => { }); expect(redirectMetadata).toEqual({ redirectTo: '/home', + relativeRedirect: true, route: '/redirect', status: 301, renderMode: RenderMode.Server, @@ -110,6 +112,7 @@ describe('ServerRouter', () => { }); expect(redirectMetadata).toEqual({ redirectTo: '/home', + relativeRedirect: true, route: '/redirect', status: 301, renderMode: RenderMode.Server, From b3bbada1efd0d3a414cce8843b7284e9560f66fc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Benjamin=20Sch=C3=A4ublin?= Date: Mon, 12 Oct 2026 13:07:00 +0200 Subject: [PATCH 589/787] fix(@angular/ssr): resolve relative redirects against the parent route When a route's own path has several segments, such as `old/page`, only its last segment was replaced when resolving a relative `redirectTo` on the server. A redirect to `new/page` was therefore sent to `/old/new/page`, while the router navigates to `/new/page` because it replaces all segments matched by the route. The server now does the same. --- packages/angular/ssr/src/routes/ng-routes.ts | 29 +++-- packages/angular/ssr/test/app_spec.ts | 17 ++- .../angular/ssr/test/routes/ng-routes_spec.ts | 118 ++++++++++++++++++ 3 files changed, 147 insertions(+), 17 deletions(-) diff --git a/packages/angular/ssr/src/routes/ng-routes.ts b/packages/angular/ssr/src/routes/ng-routes.ts index 63313b875d34..915d7c2b9a47 100644 --- a/packages/angular/ssr/src/routes/ng-routes.ts +++ b/packages/angular/ssr/src/routes/ng-routes.ts @@ -146,6 +146,7 @@ type EntryPointToBrowserMapping = AngularAppManifest['entryPointToBrowserMapping async function* handleRoute(options: { metadata: ServerConfigRouteTreeNodeMetadata; currentRoutePath: string; + parentRoute: string; route: Route; compiler: Compiler; parentInjector: Injector; @@ -158,6 +159,7 @@ async function* handleRoute(options: { const { metadata, currentRoutePath, + parentRoute, route, compiler, parentInjector, @@ -176,6 +178,7 @@ async function* handleRoute(options: { yield* handleSSGRoute( serverConfigRouteTree, typeof redirectTo === 'string' ? redirectTo : undefined, + parentRoute, metadata, parentInjector, invokeGetPrerenderParams, @@ -191,7 +194,7 @@ async function* handleRoute(options: { } else if (typeof redirectTo === 'string') { yield { ...metadata, - redirectTo: resolveRedirectTo(metadata.route, redirectTo), + redirectTo: resolveRedirectTo(parentRoute, redirectTo), relativeRedirect: redirectTo[0] !== '/' ? true : undefined, }; } else { @@ -393,6 +396,7 @@ function appendPreloadToMetadata( * * @param serverConfigRouteTree - The tree representing the server's routing setup. * @param redirectTo - Optional path to redirect to, if specified. + * @param parentRoute - The path of the parent route. * @param metadata - The metadata associated with the route tree node. * @param parentInjector - The dependency injection container for the parent route. * @param invokeGetPrerenderParams - A flag indicating whether to invoke the `getPrerenderParams` function. @@ -402,6 +406,7 @@ function appendPreloadToMetadata( async function* handleSSGRoute( serverConfigRouteTree: RouteTree | undefined, redirectTo: string | undefined, + parentRoute: string, metadata: ServerConfigRouteTreeNodeMetadata, parentInjector: Injector, invokeGetPrerenderParams: boolean, @@ -421,7 +426,7 @@ async function* handleSSGRoute( } if (redirectTo !== undefined) { - meta.redirectTo = resolveRedirectTo(currentRoutePath, redirectTo); + meta.redirectTo = resolveRedirectTo(parentRoute, redirectTo); meta.relativeRedirect = redirectTo[0] !== '/' ? true : undefined; } @@ -480,7 +485,10 @@ async function* handleSSGRoute( redirectTo: redirectTo === undefined ? undefined - : resolveRedirectTo(routeWithResolvedParams, redirectTo), + : resolveRedirectTo( + parentRoute.replace(URL_PARAMETER_GLOBAL_REGEXP, replacer), + redirectTo, + ), }; } } catch (error) { @@ -535,27 +543,24 @@ function handlePrerenderParamsReplacement( * Resolves the `redirectTo` property for a given route. * * This function processes the `redirectTo` property to ensure that it correctly - * resolves relative to the current route path. If `redirectTo` is an absolute path, - * it is returned as is. If it is a relative path, it is resolved based on the current route path, + * resolves relative to the parent route path. If `redirectTo` is an absolute path, + * it is returned as is. If it is a relative path, it is resolved based on the parent route path, * and, like in the Angular router, its query and fragment are ignored. * - * @param routePath - The current route path. + * @param parentRoute - The path of the parent route. * @param redirectTo - The target path for redirection. * @returns The resolved redirect path as a string. */ -function resolveRedirectTo(routePath: string, redirectTo: string): string { +function resolveRedirectTo(parentRoute: string, redirectTo: string): string { if (redirectTo[0] === '/') { // If the redirectTo path is absolute, return it as is. return redirectTo; } - // Resolve relative redirectTo based on the current route path. - const segments = routePath.replace(URL_PARAMETER_GLOBAL_REGEXP, '*').split('/'); - segments.pop(); // Remove the last segment to make it relative. - + // Match Angular router behavior: replace all segments matched by the route. const [path] = redirectTo.split(/[?#]/, 1); - return joinUrlParts(...segments, path); + return joinUrlParts(parentRoute.replace(URL_PARAMETER_GLOBAL_REGEXP, '*'), path); } /** diff --git a/packages/angular/ssr/test/app_spec.ts b/packages/angular/ssr/test/app_spec.ts index 91e847f0bf80..8d8ee9add00b 100644 --- a/packages/angular/ssr/test/app_spec.ts +++ b/packages/angular/ssr/test/app_spec.ts @@ -89,6 +89,7 @@ describe('AngularServerApp', () => { { path: 'redirect/:param/relative', redirectTo: 'home' }, { path: 'redirect/absolute', redirectTo: '/home' }, { path: 'redirect-with-query', redirectTo: 'home?param=value' }, + { path: 'redirect-nested/:param', children: [{ path: 'old', redirectTo: 'new' }] }, { path: 'redirect-to-function', redirectTo: () => 'home', @@ -205,19 +206,25 @@ describe('AngularServerApp', () => { expect(response?.status).toBe(302); }); - it('should correctly handle relative nested redirects', async () => { + it('should correctly handle relative redirects on multi-segment routes', async () => { const response = await app.handle(new Request('http://localhost/redirect/relative')); - expect(response?.headers.get('location')).toBe('/redirect/home'); + expect(response?.headers.get('location')).toBe('/home'); expect(response?.status).toBe(302); }); - it('should correctly handle relative nested redirects with parameter', async () => { + it('should correctly handle relative redirects on multi-segment routes with parameter', async () => { const response = await app.handle(new Request('http://localhost/redirect/param/relative')); - expect(response?.headers.get('location')).toBe('/redirect/param/home'); + expect(response?.headers.get('location')).toBe('/home'); + expect(response?.status).toBe(302); + }); + + it('should correctly handle relative redirects of parameterized parent routes', async () => { + const response = await app.handle(new Request('http://localhost/redirect-nested/x/old')); + expect(response?.headers.get('location')).toBe('/redirect-nested/x/new'); expect(response?.status).toBe(302); }); - it('should correctly handle absolute nested redirects', async () => { + it('should correctly handle absolute redirects on multi-segment routes', async () => { const response = await app.handle(new Request('http://localhost/redirect/absolute')); expect(response?.headers.get('location')).toBe('/home'); expect(response?.status).toBe(302); diff --git a/packages/angular/ssr/test/routes/ng-routes_spec.ts b/packages/angular/ssr/test/routes/ng-routes_spec.ts index f26d6fb4913c..1af823f8f2ba 100644 --- a/packages/angular/ssr/test/routes/ng-routes_spec.ts +++ b/packages/angular/ssr/test/routes/ng-routes_spec.ts @@ -399,6 +399,96 @@ describe('extractRoutesAndCreateRouteTree', () => { { route: '/*/thing', renderMode: RenderMode.Server }, ]); }); + + it('should resolve multi-segment relative redirects of prerendered routes', async () => { + setAngularAppTestingManifest( + [ + { + path: ':param', + children: [ + { path: 'old/page', redirectTo: 'new/page' }, + { path: 'new/page', component: DummyComponent }, + ], + }, + ], + [ + { + path: ':param/old/page', + renderMode: RenderMode.Prerender, + async getPrerenderParams() { + return [{ param: 'some' }]; + }, + }, + { path: '**', renderMode: RenderMode.Server }, + ], + ); + + const { routeTree, errors } = await extractRoutesAndCreateRouteTree({ + url, + invokeGetPrerenderParams: true, + includePrerenderFallbackRoutes: true, + }); + + expect(errors).toHaveSize(0); + expect(routeTree.toObject()).toEqual([ + { route: '/*', renderMode: RenderMode.Server }, + { + route: '/*/old/page', + renderMode: RenderMode.Server, + redirectTo: '/*/new/page', + relativeRedirect: true, + }, + { route: '/*/new/page', renderMode: RenderMode.Server }, + { + route: '/some/old/page', + renderMode: RenderMode.Prerender, + redirectTo: '/some/new/page', + relativeRedirect: true, + }, + ]); + }); + + it('should resolve relative redirects of prerendered catch-all routes', async () => { + setAngularAppTestingManifest( + [ + { path: 'docs/**', redirectTo: 'new' }, + { path: 'new', component: DummyComponent }, + ], + [ + { + path: 'docs/**', + renderMode: RenderMode.Prerender, + async getPrerenderParams() { + return [{ '**': 'a/b' }]; + }, + }, + { path: '**', renderMode: RenderMode.Server }, + ], + ); + + const { routeTree, errors } = await extractRoutesAndCreateRouteTree({ + url, + invokeGetPrerenderParams: true, + includePrerenderFallbackRoutes: true, + }); + + expect(errors).toHaveSize(0); + expect(routeTree.toObject()).toEqual([ + { + route: '/docs/a/b', + renderMode: RenderMode.Prerender, + redirectTo: '/new', + relativeRedirect: true, + }, + { + route: '/docs/**', + renderMode: RenderMode.Server, + redirectTo: '/new', + relativeRedirect: true, + }, + { route: '/new', renderMode: RenderMode.Server }, + ]); + }); }); it('should extract routes with a route level matcher', async () => { @@ -562,6 +652,34 @@ describe('extractRoutesAndCreateRouteTree', () => { ]); }); + it('should resolve multi-segment relative redirects against the parent route', async () => { + setAngularAppTestingManifest( + [ + { + path: ':param', + children: [ + { path: 'old/page', redirectTo: 'new/page' }, + { path: 'new/page', component: DummyComponent }, + ], + }, + ], + [{ path: '**', renderMode: RenderMode.Server }], + ); + + const { routeTree, errors } = await extractRoutesAndCreateRouteTree({ url }); + expect(errors).toHaveSize(0); + expect(routeTree.toObject()).toEqual([ + { route: '/*', renderMode: RenderMode.Server }, + { + route: '/*/old/page', + renderMode: RenderMode.Server, + redirectTo: '/*/new/page', + relativeRedirect: true, + }, + { route: '/*/new/page', renderMode: RenderMode.Server }, + ]); + }); + it('should not mark absolute redirects as relative', async () => { setAngularAppTestingManifest( [ From f0a74e8f0ea04fd3f839be0120346067440b1350 Mon Sep 17 00:00:00 2001 From: Alan Agius <17563226+alan-agius4@users.noreply.github.com> Date: Mon, 12 Oct 2026 11:06:33 +0000 Subject: [PATCH 590/787] fix(@angular/build): disable Vitest fsModuleCache in unit-test builder Vitest 5.0.4 enabled `fsModuleCache` by default, which caches transformed modules on disk keyed by the raw source file content on disk before calling Vite's `load()` hook. Because `@angular/build:unit-test` pre-bundles test entry points and their imported application modules into memory, changes to imported application files do not change the on-disk `.spec.ts` file content, causing Vitest's `fsModuleCache` to serve stale cached bundles across test runs. --- .../build/src/builders/unit-test/runners/vitest/plugins.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/packages/angular/build/src/builders/unit-test/runners/vitest/plugins.ts b/packages/angular/build/src/builders/unit-test/runners/vitest/plugins.ts index 6be4c6e8ebe3..ec0cd0a8f269 100644 --- a/packages/angular/build/src/builders/unit-test/runners/vitest/plugins.ts +++ b/packages/angular/build/src/builders/unit-test/runners/vitest/plugins.ts @@ -271,6 +271,7 @@ export async function createVitestConfigPlugin( test: { name: projectName, include, + fsModuleCache: false, // CLI provider browser options override, if present ...(browser ? { browser } : {}), // Only override if the user explicitly set it via CLI @@ -290,6 +291,7 @@ export async function createVitestConfigPlugin( return { test: { + fsModuleCache: false, coverage: await generateCoverageOption( options.coverage, testConfig?.coverage, From ad4845583b8d1b8de26ccc0e45b4e6e58d95b362 Mon Sep 17 00:00:00 2001 From: Alan Agius <17563226+alan-agius4@users.noreply.github.com> Date: Mon, 12 Oct 2026 13:37:06 +0000 Subject: [PATCH 591/787] fix(@angular/build): respect tsconfig declarationMap and compilationMode in library builder Remove schema defaults for `declarationMap` and `compilationMode` in `@angular/build:library` and preserve `declarationMap` when reading TypeScript configuration for library builds so values configured in `tsconfig.lib.json` / `tsconfig.lib.prod.json` are respected unless explicitly overridden in `angular.json`. --- .../projects/lib/tsconfig.lib.json | 1 - .../build/src/builders/library/options.ts | 4 +- .../builders/library/pipeline/build-action.ts | 25 ++++++++-- .../src/builders/library/pipeline/bundler.ts | 4 +- .../builders/library/pipeline/compilation.ts | 10 +++- .../build/src/builders/library/schema.json | 6 +-- .../tests/options/compilation-mode_spec.ts | 48 +++++++++++++++++++ .../tests/options/declaration-map_spec.ts | 38 +++++++++++++++ .../build/src/builders/library/types.ts | 7 ++- .../compilation/angular-compilation.ts | 1 + .../angular/compilation/compiler-options.ts | 6 ++- .../angular/compilation/parallel-worker.ts | 1 + .../compilation/typescript-compilation.ts | 8 +++- 13 files changed, 141 insertions(+), 18 deletions(-) diff --git a/modules/testing/builder/projects/hello-world-lib/projects/lib/tsconfig.lib.json b/modules/testing/builder/projects/hello-world-lib/projects/lib/tsconfig.lib.json index fe12470400e2..23e851ac9c8b 100644 --- a/modules/testing/builder/projects/hello-world-lib/projects/lib/tsconfig.lib.json +++ b/modules/testing/builder/projects/hello-world-lib/projects/lib/tsconfig.lib.json @@ -2,7 +2,6 @@ "extends": "../../tsconfig.json", "compilerOptions": { "declaration": true, - "declarationMap": true, "inlineSources": true, "types": [] }, diff --git a/packages/angular/build/src/builders/library/options.ts b/packages/angular/build/src/builders/library/options.ts index 450dce36cab5..c90fd525e1f2 100644 --- a/packages/angular/build/src/builders/library/options.ts +++ b/packages/angular/build/src/builders/library/options.ts @@ -38,8 +38,8 @@ export async function normalizeLibraryOptions( assets: rawAssets, stylePreprocessorOptions, inlineStyleLanguage = 'css', - compilationMode = 'partial', - declarationMap = false, + compilationMode, + declarationMap, allowedNonPeerDependencies: rawAllowedNonPeerDependencies = [], keepLifecycleScripts = false, watch = false, diff --git a/packages/angular/build/src/builders/library/pipeline/build-action.ts b/packages/angular/build/src/builders/library/pipeline/build-action.ts index 19718a793deb..294eb954421b 100644 --- a/packages/angular/build/src/builders/library/pipeline/build-action.ts +++ b/packages/angular/build/src/builders/library/pipeline/build-action.ts @@ -124,6 +124,8 @@ export async function buildAction(actionContext: BuildActionContext): Promise; + + /** Effective declarationMap setting resolved from builder options and tsconfig. */ + readonly declarationMap: boolean; + + /** Effective compilationMode setting resolved from builder options and tsconfig. */ + readonly compilationMode: 'partial' | 'full'; } /** @@ -125,7 +131,7 @@ export async function compileLibrary( processWebWorker: () => '', }; - const { referencedFiles } = await compilationInstance.initialize( + const { referencedFiles, compilerOptions } = await compilationInstance.initialize( tsConfigPath, hostOptions, { @@ -220,6 +226,8 @@ export async function compileLibrary( failedFiles: failedFiles.size > 0 ? failedFiles : undefined, }, diagnosePromise, + declarationMap: !!compilerOptions.declarationMap, + compilationMode: compilerOptions.compilationMode === 'full' ? 'full' : 'partial', }; } catch (error) { if (!cached) { diff --git a/packages/angular/build/src/builders/library/schema.json b/packages/angular/build/src/builders/library/schema.json index bac9944091f6..ee34936bdd62 100644 --- a/packages/angular/build/src/builders/library/schema.json +++ b/packages/angular/build/src/builders/library/schema.json @@ -71,14 +71,12 @@ }, "declarationMap": { "type": "boolean", - "description": "Generates a sourcemap for each corresponding '.d.ts' file.", - "default": false + "description": "Generates a sourcemap for each corresponding '.d.ts' file." }, "compilationMode": { "type": "string", "description": "Angular compilation mode. Use 'partial' when publishing to npm (APF requirement). Use 'full' only during development or for private, internal monorepo packages that are never published.", - "enum": ["partial", "full"], - "default": "partial" + "enum": ["partial", "full"] }, "allowedNonPeerDependencies": { "description": "A list of package names allowed in the 'dependencies' and 'optionalDependencies' sections of package.json. Values can be regular expression patterns.", diff --git a/packages/angular/build/src/builders/library/tests/options/compilation-mode_spec.ts b/packages/angular/build/src/builders/library/tests/options/compilation-mode_spec.ts index cd794206960d..0efedef5708f 100644 --- a/packages/angular/build/src/builders/library/tests/options/compilation-mode_spec.ts +++ b/packages/angular/build/src/builders/library/tests/options/compilation-mode_spec.ts @@ -37,5 +37,53 @@ describeLibraryBuilder(executeLibraryBuilder, LIBRARY_BUILDER_INFO, (harness) => const fesm = harness.readFile('dist/lib/fesm2022/lib.mjs'); expect(fesm).toContain('ɵɵdefineComponent'); }); + + it('should respect angularCompilerOptions.compilationMode from tsconfig when not set in builder options', async () => { + await harness.modifyFile('projects/lib/tsconfig.lib.json', (content) => { + const tsconfig = JSON.parse(content); + tsconfig.angularCompilerOptions = { + ...tsconfig.angularCompilerOptions, + compilationMode: 'full', + }; + + return JSON.stringify(tsconfig, null, 2); + }); + + harness.useTarget('build', { + ...BASE_OPTIONS, + }); + + const { result } = await harness.executeOnce(); + expect(result?.success).toBeTrue(); + + const fesm = harness.readFile('dist/lib/fesm2022/lib.mjs'); + expect(fesm).toContain('ɵɵdefineComponent'); + + const pkgJson = JSON.parse(harness.readFile('dist/lib/package.json')); + expect(pkgJson.scripts?.prepublishOnly).toContain('full compilation mode'); + }); + + it('should override angularCompilerOptions.compilationMode from tsconfig when set in builder options', async () => { + await harness.modifyFile('projects/lib/tsconfig.lib.json', (content) => { + const tsconfig = JSON.parse(content); + tsconfig.angularCompilerOptions = { + ...tsconfig.angularCompilerOptions, + compilationMode: 'full', + }; + + return JSON.stringify(tsconfig, null, 2); + }); + + harness.useTarget('build', { + ...BASE_OPTIONS, + compilationMode: CompilationMode.Partial, + }); + + const { result } = await harness.executeOnce(); + expect(result?.success).toBeTrue(); + + const fesm = harness.readFile('dist/lib/fesm2022/lib.mjs'); + expect(fesm).toContain('ɵɵngDeclareComponent'); + }); }); }); diff --git a/packages/angular/build/src/builders/library/tests/options/declaration-map_spec.ts b/packages/angular/build/src/builders/library/tests/options/declaration-map_spec.ts index a37e2f0dd255..2e30109d6a03 100644 --- a/packages/angular/build/src/builders/library/tests/options/declaration-map_spec.ts +++ b/packages/angular/build/src/builders/library/tests/options/declaration-map_spec.ts @@ -44,5 +44,43 @@ describeLibraryBuilder(executeLibraryBuilder, LIBRARY_BUILDER_INFO, (harness) => expect(dtsMap.sources).toContain('../../../projects/lib/src/lib/lib.component.ts'); harness.expectFile(join('dist/lib/types', dtsMap.sources[0])).toExist(); }); + + it('should respect declarationMap from tsconfig when not set in builder options', async () => { + await harness.modifyFile('projects/lib/tsconfig.lib.json', (content) => { + const tsconfig = JSON.parse(content); + tsconfig.compilerOptions.declarationMap = true; + + return JSON.stringify(tsconfig, null, 2); + }); + + harness.useTarget('build', { + ...BASE_OPTIONS, + }); + + const { result } = await harness.executeOnce(); + expect(result?.success).toBeTrue(); + + harness.expectFile('dist/lib/types/lib.d.ts.map').toExist(); + }); + + it('should override declarationMap from tsconfig when declarationMap is false', async () => { + await harness.modifyFile('projects/lib/tsconfig.lib.json', (content) => { + const tsconfig = JSON.parse(content); + tsconfig.compilerOptions.declarationMap = true; + + return JSON.stringify(tsconfig, null, 2); + }); + + harness.useTarget('build', { + ...BASE_OPTIONS, + declarationMap: false, + }); + + const { result } = await harness.executeOnce(); + expect(result?.success).toBeTrue(); + + harness.expectFile('dist/lib/fesm2022/lib.mjs.map').toExist(); + harness.expectFile('dist/lib/types/lib.d.ts.map').toNotExist(); + }); }); }); diff --git a/packages/angular/build/src/builders/library/types.ts b/packages/angular/build/src/builders/library/types.ts index dfe91c36f3c5..7ec8545a9c8e 100644 --- a/packages/angular/build/src/builders/library/types.ts +++ b/packages/angular/build/src/builders/library/types.ts @@ -74,8 +74,8 @@ export interface NormalizedLibraryOptions { styleIncludePaths: string[]; sass?: StylesheetPluginsass; assets: ReturnType; - compilationMode: 'partial' | 'full'; - declarationMap: boolean; + compilationMode?: 'partial' | 'full'; + declarationMap?: boolean; allowedNonPeerDependencies: RegExp[]; keepLifecycleScripts: boolean; watch: boolean; @@ -127,6 +127,9 @@ export interface SingleBuildState { /** Cached unified TypeScript and Angular compilation state. */ singleProgramCache?: SingleProgramCache; + /** Effective compilation mode resolved from builder options and tsconfig. */ + compilationMode?: 'partial' | 'full'; + /** Map of entry point names to their previous bundle results. */ previousBundleResults: Map; diff --git a/packages/angular/build/src/tools/angular/compilation/angular-compilation.ts b/packages/angular/build/src/tools/angular/compilation/angular-compilation.ts index d766680d1674..3da78cdf0275 100644 --- a/packages/angular/build/src/tools/angular/compilation/angular-compilation.ts +++ b/packages/angular/build/src/tools/angular/compilation/angular-compilation.ts @@ -23,6 +23,7 @@ export interface FileTransformResult { export interface AngularCompilationOptions { allowJs?: boolean; + compilationMode?: 'full' | 'partial' | 'experimental-local'; declarationMap?: boolean; isolatedModules?: boolean; sourceMap?: boolean; diff --git a/packages/angular/build/src/tools/angular/compilation/compiler-options.ts b/packages/angular/build/src/tools/angular/compilation/compiler-options.ts index 1720a8bb0516..b2c83d616f08 100644 --- a/packages/angular/build/src/tools/angular/compilation/compiler-options.ts +++ b/packages/angular/build/src/tools/angular/compilation/compiler-options.ts @@ -71,6 +71,8 @@ export function transformCompilerOptions( compilerOptions.compilationMode = 'full'; } else if (overrides?.compilationMode) { compilerOptions.compilationMode = overrides.compilationMode; + } else if (isLibrary) { + compilerOptions.compilationMode ??= 'partial'; } // Enable incremental compilation by default if caching is enabled and incremental is not explicitly disabled @@ -114,7 +116,9 @@ export function transformCompilerOptions( compilerOptions.moduleResolution = typeScript.ModuleResolutionKind.Bundler; compilerOptions.importHelpers = true; compilerOptions.declaration = true; - compilerOptions.declarationMap = overrides?.declarationMap; + compilerOptions.declarationMap = !!( + overrides?.declarationMap ?? compilerOptions.declarationMap + ); compilerOptions.declarationDir = undefined; } diff --git a/packages/angular/build/src/tools/angular/compilation/parallel-worker.ts b/packages/angular/build/src/tools/angular/compilation/parallel-worker.ts index a74c032a1b70..475592bd478b 100644 --- a/packages/angular/build/src/tools/angular/compilation/parallel-worker.ts +++ b/packages/angular/build/src/tools/angular/compilation/parallel-worker.ts @@ -125,6 +125,7 @@ export async function initialize(request: InitRequest): Promise Date: Mon, 12 Oct 2026 19:18:38 +0200 Subject: [PATCH 592/787] fix(@angular/build): filter Rolldown warnings and disable .d.ts annotation comments in library builder Suppress noisy Rolldown warnings (`EMPTY_BUNDLE`, `UNUSED_EXTERNAL_IMPORT`, and `THIS_IS_UNDEFINED`) and disable annotation comments in `.d.ts` output bundles to match `ng-packagr` behavior. --- .../src/builders/library/pipeline/bundler.ts | 16 +++++++- .../library/tests/behavior/build_spec.ts | 41 +++++++++++++++++++ 2 files changed, 56 insertions(+), 1 deletion(-) diff --git a/packages/angular/build/src/builders/library/pipeline/bundler.ts b/packages/angular/build/src/builders/library/pipeline/bundler.ts index 314a8e205b2d..64042bd37f92 100644 --- a/packages/angular/build/src/builders/library/pipeline/bundler.ts +++ b/packages/angular/build/src/builders/library/pipeline/bundler.ts @@ -300,6 +300,15 @@ function processRolldownOutput( return { filesToEmit, moduleIdsByBundle, tslibBundles }; } +/** + * Set of Rolldown warning codes that should be ignored. + */ +const IGNORED_ROLLDOWN_WARNING_CODES: ReadonlySet = new Set([ + 'EMPTY_BUNDLE', + 'UNUSED_EXTERNAL_IMPORT', + 'THIS_IS_UNDEFINED', +]); + /** * Executes a Rolldown bundle build across all provided entry inputs. * @@ -341,7 +350,12 @@ async function executeMultiBundle( resolve: { symlinks: !preserveSymlinks }, checks: { circularDependency: false }, onLog(level, log) { + // Ignore specified warning codes if (level === 'warn') { + if (log.code && IGNORED_ROLLDOWN_WARNING_CODES.has(log.code)) { + return; + } + warnings.push(log.message); } }, @@ -358,7 +372,7 @@ async function executeMultiBundle( chunkFileNames: `[name]-[hash].${extension}`, sourcemap, hoistTransitiveImports: false, - comments: { jsdoc: isDts, legal: true, annotation: true }, + comments: { jsdoc: isDts, legal: true, annotation: !isDts }, }); return { diff --git a/packages/angular/build/src/builders/library/tests/behavior/build_spec.ts b/packages/angular/build/src/builders/library/tests/behavior/build_spec.ts index 74150e57acb7..996001db209d 100644 --- a/packages/angular/build/src/builders/library/tests/behavior/build_spec.ts +++ b/packages/angular/build/src/builders/library/tests/behavior/build_spec.ts @@ -74,6 +74,47 @@ describeLibraryBuilder(executeLibraryBuilder, LIBRARY_BUILDER_INFO, (harness) => ); }); + it('should not log EMPTY_BUNDLE warnings for type-only entry points', async () => { + await harness.writeFile( + 'projects/lib/src/public-api.ts', + `export interface OnlyType { id: string; }`, + ); + + harness.useTarget('build', { + ...BASE_OPTIONS, + }); + + const { result, logs } = await harness.executeOnce(); + expect(result?.success).toBeTrue(); + expect(logs.some((l) => l.level === 'warn')).toBeFalse(); + }); + + it('should preserve JSDoc comments in .d.ts and annotation comments in .mjs bundles', async () => { + await harness.writeFile( + 'projects/lib/src/public-api.ts', + ` + function identity(x: T): T { return x; } + /** Public API JSDoc comment */ + export const VALUE = /* @__PURE__ */ identity('test'); + `, + ); + + harness.useTarget('build', { + ...BASE_OPTIONS, + }); + + const { result } = await harness.executeOnce(); + expect(result?.success).toBeTrue(); + + const fesmContent = harness.readFile('dist/lib/fesm2022/lib.mjs'); + expect(fesmContent).toContain('@__PURE__'); + expect(fesmContent).not.toContain('Public API JSDoc comment'); + + const dtsContent = harness.readFile('dist/lib/types/lib.d.ts'); + expect(dtsContent).toContain('Public API JSDoc comment'); + expect(dtsContent).not.toContain('@__PURE__'); + }); + it('should automatically add tslib to dependencies when output chunks import tslib', async () => { await harness.writeFile( 'projects/lib/src/public-api.ts', From 1559380cb6e4768c387946cd889beb75eb138779 Mon Sep 17 00:00:00 2001 From: Angular Robot Date: Mon, 12 Oct 2026 19:01:36 +0000 Subject: [PATCH 593/787] build: update cross-repo angular dependencies See associated pull request for more information. --- .../assistant-to-the-branch-manager.yml | 2 +- .github/workflows/ci.yml | 52 +- .github/workflows/dev-infra.yml | 6 +- .github/workflows/perf.yml | 6 +- .github/workflows/pr.yml | 44 +- MODULE.bazel | 6 +- MODULE.bazel.lock | 36 +- package.json | 2 +- pnpm-lock.yaml | 606 ++++++++---------- tests/e2e/ng-snapshot/package.json | 32 +- 10 files changed, 363 insertions(+), 429 deletions(-) diff --git a/.github/workflows/assistant-to-the-branch-manager.yml b/.github/workflows/assistant-to-the-branch-manager.yml index 5431306096a7..8c6035d666dc 100644 --- a/.github/workflows/assistant-to-the-branch-manager.yml +++ b/.github/workflows/assistant-to-the-branch-manager.yml @@ -18,6 +18,6 @@ jobs: - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: persist-credentials: false - - uses: angular/dev-infra/github-actions/branch-manager@b137f89f74478e0d2b3902372c538d5656795e9a # main + - uses: angular/dev-infra/github-actions/branch-manager@28ae58d2ad683fb3991006c23a9829c08b65aaec # main with: angular-robot-key: ${{ secrets.ANGULAR_ROBOT_PRIVATE_KEY }} diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index ad97a6cf125e..56dde16b608c 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -21,9 +21,9 @@ jobs: runs-on: ubuntu-latest steps: - name: Initialize environment - uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@b137f89f74478e0d2b3902372c538d5656795e9a # main + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@28ae58d2ad683fb3991006c23a9829c08b65aaec # main - name: Setup Bazel - uses: angular/dev-infra/github-actions/bazel/setup@b137f89f74478e0d2b3902372c538d5656795e9a # main + uses: angular/dev-infra/github-actions/bazel/setup@28ae58d2ad683fb3991006c23a9829c08b65aaec # main - name: Install node modules run: pnpm install --frozen-lockfile - name: Generate JSON schema types @@ -44,11 +44,11 @@ jobs: runs-on: ubuntu-latest steps: - name: Initialize environment - uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@b137f89f74478e0d2b3902372c538d5656795e9a # main + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@28ae58d2ad683fb3991006c23a9829c08b65aaec # main - name: Setup Bazel - uses: angular/dev-infra/github-actions/bazel/setup@b137f89f74478e0d2b3902372c538d5656795e9a # main + uses: angular/dev-infra/github-actions/bazel/setup@28ae58d2ad683fb3991006c23a9829c08b65aaec # main - name: Setup Bazel RBE - uses: angular/dev-infra/github-actions/bazel/configure-remote@b137f89f74478e0d2b3902372c538d5656795e9a # main + uses: angular/dev-infra/github-actions/bazel/configure-remote@28ae58d2ad683fb3991006c23a9829c08b65aaec # main with: google_credential: ${{ secrets.RBE_TRUSTED_BUILDS_USER }} - name: Install node modules @@ -61,11 +61,11 @@ jobs: runs-on: ubuntu-latest steps: - name: Initialize environment - uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@b137f89f74478e0d2b3902372c538d5656795e9a # main + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@28ae58d2ad683fb3991006c23a9829c08b65aaec # main - name: Setup Bazel - uses: angular/dev-infra/github-actions/bazel/setup@b137f89f74478e0d2b3902372c538d5656795e9a # main + uses: angular/dev-infra/github-actions/bazel/setup@28ae58d2ad683fb3991006c23a9829c08b65aaec # main - name: Setup Bazel RBE - uses: angular/dev-infra/github-actions/bazel/configure-remote@b137f89f74478e0d2b3902372c538d5656795e9a # main + uses: angular/dev-infra/github-actions/bazel/configure-remote@28ae58d2ad683fb3991006c23a9829c08b65aaec # main with: google_credential: ${{ secrets.RBE_TRUSTED_BUILDS_USER }} - name: Install node modules @@ -84,13 +84,13 @@ jobs: runs-on: ubuntu-latest steps: - name: Initialize environment - uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@b137f89f74478e0d2b3902372c538d5656795e9a # main + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@28ae58d2ad683fb3991006c23a9829c08b65aaec # main - name: Install node modules run: pnpm install --frozen-lockfile - name: Setup Bazel - uses: angular/dev-infra/github-actions/bazel/setup@b137f89f74478e0d2b3902372c538d5656795e9a # main + uses: angular/dev-infra/github-actions/bazel/setup@28ae58d2ad683fb3991006c23a9829c08b65aaec # main - name: Setup Bazel RBE - uses: angular/dev-infra/github-actions/bazel/configure-remote@b137f89f74478e0d2b3902372c538d5656795e9a # main + uses: angular/dev-infra/github-actions/bazel/configure-remote@28ae58d2ad683fb3991006c23a9829c08b65aaec # main with: google_credential: ${{ secrets.RBE_TRUSTED_BUILDS_USER }} - name: Run CLI E2E tests @@ -100,11 +100,11 @@ jobs: runs-on: ubuntu-latest steps: - name: Initialize environment - uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@b137f89f74478e0d2b3902372c538d5656795e9a # main + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@28ae58d2ad683fb3991006c23a9829c08b65aaec # main - name: Setup Bazel - uses: angular/dev-infra/github-actions/bazel/setup@b137f89f74478e0d2b3902372c538d5656795e9a # main + uses: angular/dev-infra/github-actions/bazel/setup@28ae58d2ad683fb3991006c23a9829c08b65aaec # main - name: Setup Bazel RBE - uses: angular/dev-infra/github-actions/bazel/configure-remote@b137f89f74478e0d2b3902372c538d5656795e9a # main + uses: angular/dev-infra/github-actions/bazel/configure-remote@28ae58d2ad683fb3991006c23a9829c08b65aaec # main with: google_credential: ${{ secrets.RBE_TRUSTED_BUILDS_USER }} - name: Install node modules @@ -137,7 +137,7 @@ jobs: runs-on: windows-2025 steps: - name: Initialize environment - uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@b137f89f74478e0d2b3902372c538d5656795e9a # main + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@28ae58d2ad683fb3991006c23a9829c08b65aaec # main - name: Install node modules run: pnpm install --frozen-lockfile - name: Download built Windows E2E tests @@ -164,13 +164,13 @@ jobs: runs-on: ubuntu-latest steps: - name: Initialize environment - uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@b137f89f74478e0d2b3902372c538d5656795e9a # main + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@28ae58d2ad683fb3991006c23a9829c08b65aaec # main - name: Install node modules run: pnpm install --frozen-lockfile - name: Setup Bazel - uses: angular/dev-infra/github-actions/bazel/setup@b137f89f74478e0d2b3902372c538d5656795e9a # main + uses: angular/dev-infra/github-actions/bazel/setup@28ae58d2ad683fb3991006c23a9829c08b65aaec # main - name: Setup Bazel RBE - uses: angular/dev-infra/github-actions/bazel/configure-remote@b137f89f74478e0d2b3902372c538d5656795e9a # main + uses: angular/dev-infra/github-actions/bazel/configure-remote@28ae58d2ad683fb3991006c23a9829c08b65aaec # main with: google_credential: ${{ secrets.RBE_TRUSTED_BUILDS_USER }} - name: Run CLI E2E tests @@ -188,13 +188,13 @@ jobs: runs-on: ubuntu-latest steps: - name: Initialize environment - uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@b137f89f74478e0d2b3902372c538d5656795e9a # main + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@28ae58d2ad683fb3991006c23a9829c08b65aaec # main - name: Install node modules run: pnpm install --frozen-lockfile - name: Setup Bazel - uses: angular/dev-infra/github-actions/bazel/setup@b137f89f74478e0d2b3902372c538d5656795e9a # main + uses: angular/dev-infra/github-actions/bazel/setup@28ae58d2ad683fb3991006c23a9829c08b65aaec # main - name: Setup Bazel RBE - uses: angular/dev-infra/github-actions/bazel/configure-remote@b137f89f74478e0d2b3902372c538d5656795e9a # main + uses: angular/dev-infra/github-actions/bazel/configure-remote@28ae58d2ad683fb3991006c23a9829c08b65aaec # main with: google_credential: ${{ secrets.RBE_TRUSTED_BUILDS_USER }} - name: Run CLI E2E tests @@ -208,13 +208,13 @@ jobs: SAUCE_TUNNEL_IDENTIFIER: angular-cli-${{ github.workflow }}-${{ github.run_number }} steps: - name: Initialize environment - uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@b137f89f74478e0d2b3902372c538d5656795e9a # main + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@28ae58d2ad683fb3991006c23a9829c08b65aaec # main - name: Install node modules run: pnpm install --frozen-lockfile - name: Setup Bazel - uses: angular/dev-infra/github-actions/bazel/setup@b137f89f74478e0d2b3902372c538d5656795e9a # main + uses: angular/dev-infra/github-actions/bazel/setup@28ae58d2ad683fb3991006c23a9829c08b65aaec # main - name: Setup Bazel RBE - uses: angular/dev-infra/github-actions/bazel/configure-remote@b137f89f74478e0d2b3902372c538d5656795e9a # main + uses: angular/dev-infra/github-actions/bazel/configure-remote@28ae58d2ad683fb3991006c23a9829c08b65aaec # main with: google_credential: ${{ secrets.RBE_TRUSTED_BUILDS_USER }} - name: Start Sauce Connect @@ -245,11 +245,11 @@ jobs: CIRCLE_BRANCH: ${{ github.ref_name }} steps: - name: Initialize environment - uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@b137f89f74478e0d2b3902372c538d5656795e9a # main + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@28ae58d2ad683fb3991006c23a9829c08b65aaec # main - name: Install node modules run: pnpm install --frozen-lockfile - name: Setup Bazel - uses: angular/dev-infra/github-actions/bazel/setup@b137f89f74478e0d2b3902372c538d5656795e9a # main + uses: angular/dev-infra/github-actions/bazel/setup@28ae58d2ad683fb3991006c23a9829c08b65aaec # main - run: pnpm admin snapshots --verbose env: SNAPSHOT_BUILDS_GITHUB_TOKEN: ${{ secrets.SNAPSHOT_BUILDS_GITHUB_TOKEN }} diff --git a/.github/workflows/dev-infra.yml b/.github/workflows/dev-infra.yml index 98d8d726c99b..f508452e9456 100644 --- a/.github/workflows/dev-infra.yml +++ b/.github/workflows/dev-infra.yml @@ -16,21 +16,21 @@ jobs: if: github.event_name == 'pull_request_target' runs-on: ubuntu-latest steps: - - uses: angular/dev-infra/github-actions/labeling/pull-request@b137f89f74478e0d2b3902372c538d5656795e9a # main + - uses: angular/dev-infra/github-actions/labeling/pull-request@28ae58d2ad683fb3991006c23a9829c08b65aaec # main with: angular-robot-key: ${{ secrets.ANGULAR_ROBOT_PRIVATE_KEY }} post_approval_changes: if: github.event_name == 'pull_request_target' runs-on: ubuntu-latest steps: - - uses: angular/dev-infra/github-actions/post-approval-changes@b137f89f74478e0d2b3902372c538d5656795e9a # main + - uses: angular/dev-infra/github-actions/post-approval-changes@28ae58d2ad683fb3991006c23a9829c08b65aaec # main with: angular-robot-key: ${{ secrets.ANGULAR_ROBOT_PRIVATE_KEY }} issue_labels: if: github.event_name == 'issues' runs-on: ubuntu-latest steps: - - uses: angular/dev-infra/github-actions/labeling/issue@b137f89f74478e0d2b3902372c538d5656795e9a # main + - uses: angular/dev-infra/github-actions/labeling/issue@28ae58d2ad683fb3991006c23a9829c08b65aaec # main with: angular-robot-key: ${{ secrets.ANGULAR_ROBOT_PRIVATE_KEY }} google-generative-ai-key: ${{ secrets.GOOGLE_GENERATIVE_AI_KEY }} diff --git a/.github/workflows/perf.yml b/.github/workflows/perf.yml index e61e4d1bb083..1c275f2d1a0d 100644 --- a/.github/workflows/perf.yml +++ b/.github/workflows/perf.yml @@ -22,7 +22,7 @@ jobs: workflows: ${{ steps.workflows.outputs.workflows }} steps: - name: Initialize environment - uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@b137f89f74478e0d2b3902372c538d5656795e9a # main + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@28ae58d2ad683fb3991006c23a9829c08b65aaec # main - name: Install node modules run: pnpm install --frozen-lockfile - id: workflows @@ -40,9 +40,9 @@ jobs: workflow: ${{ fromJSON(needs.list.outputs.workflows) }} steps: - name: Initialize environment - uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@b137f89f74478e0d2b3902372c538d5656795e9a # main + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@28ae58d2ad683fb3991006c23a9829c08b65aaec # main - name: Setup Bazel - uses: angular/dev-infra/github-actions/bazel/setup@b137f89f74478e0d2b3902372c538d5656795e9a # main + uses: angular/dev-infra/github-actions/bazel/setup@28ae58d2ad683fb3991006c23a9829c08b65aaec # main - name: Install node modules run: pnpm install --frozen-lockfile # We utilize the google-github-actions/auth action to allow us to get an active credential using workflow diff --git a/.github/workflows/pr.yml b/.github/workflows/pr.yml index 7cf337949011..d9195bdf9f8c 100644 --- a/.github/workflows/pr.yml +++ b/.github/workflows/pr.yml @@ -34,9 +34,9 @@ jobs: runs-on: ubuntu-latest steps: - name: Initialize environment - uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@b137f89f74478e0d2b3902372c538d5656795e9a # main + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@28ae58d2ad683fb3991006c23a9829c08b65aaec # main - name: Setup Bazel - uses: angular/dev-infra/github-actions/bazel/setup@b137f89f74478e0d2b3902372c538d5656795e9a # main + uses: angular/dev-infra/github-actions/bazel/setup@28ae58d2ad683fb3991006c23a9829c08b65aaec # main - name: Setup ESLint Caching uses: actions/cache@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0 with: @@ -66,17 +66,17 @@ jobs: # it has been merged. run: pnpm ng-dev format changed --check ${{ github.event.pull_request.base.sha }} - name: Check Package Licenses - uses: angular/dev-infra/github-actions/linting/licenses@b137f89f74478e0d2b3902372c538d5656795e9a # main + uses: angular/dev-infra/github-actions/linting/licenses@28ae58d2ad683fb3991006c23a9829c08b65aaec # main build: runs-on: ubuntu-latest steps: - name: Initialize environment - uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@b137f89f74478e0d2b3902372c538d5656795e9a # main + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@28ae58d2ad683fb3991006c23a9829c08b65aaec # main - name: Setup Bazel - uses: angular/dev-infra/github-actions/bazel/setup@b137f89f74478e0d2b3902372c538d5656795e9a # main + uses: angular/dev-infra/github-actions/bazel/setup@28ae58d2ad683fb3991006c23a9829c08b65aaec # main - name: Setup Bazel RBE - uses: angular/dev-infra/github-actions/bazel/configure-remote@b137f89f74478e0d2b3902372c538d5656795e9a # main + uses: angular/dev-infra/github-actions/bazel/configure-remote@28ae58d2ad683fb3991006c23a9829c08b65aaec # main - name: Install node modules run: pnpm install --frozen-lockfile - name: Build release targets @@ -93,11 +93,11 @@ jobs: runs-on: ubuntu-latest steps: - name: Initialize environment - uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@b137f89f74478e0d2b3902372c538d5656795e9a # main + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@28ae58d2ad683fb3991006c23a9829c08b65aaec # main - name: Setup Bazel - uses: angular/dev-infra/github-actions/bazel/setup@b137f89f74478e0d2b3902372c538d5656795e9a # main + uses: angular/dev-infra/github-actions/bazel/setup@28ae58d2ad683fb3991006c23a9829c08b65aaec # main - name: Setup Bazel RBE - uses: angular/dev-infra/github-actions/bazel/configure-remote@b137f89f74478e0d2b3902372c538d5656795e9a # main + uses: angular/dev-infra/github-actions/bazel/configure-remote@28ae58d2ad683fb3991006c23a9829c08b65aaec # main - name: Install node modules run: pnpm install --frozen-lockfile - name: Run module and package tests @@ -114,13 +114,13 @@ jobs: runs-on: ubuntu-latest steps: - name: Initialize environment - uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@b137f89f74478e0d2b3902372c538d5656795e9a # main + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@28ae58d2ad683fb3991006c23a9829c08b65aaec # main - name: Install node modules run: pnpm install --frozen-lockfile - name: Setup Bazel - uses: angular/dev-infra/github-actions/bazel/setup@b137f89f74478e0d2b3902372c538d5656795e9a # main + uses: angular/dev-infra/github-actions/bazel/setup@28ae58d2ad683fb3991006c23a9829c08b65aaec # main - name: Setup Bazel RBE - uses: angular/dev-infra/github-actions/bazel/configure-remote@b137f89f74478e0d2b3902372c538d5656795e9a # main + uses: angular/dev-infra/github-actions/bazel/configure-remote@28ae58d2ad683fb3991006c23a9829c08b65aaec # main - name: Run CLI E2E tests run: pnpm bazel test --test_env=E2E_SHARD_TOTAL=6 --test_env=E2E_SHARD_INDEX=${{ matrix.shard }} --config=e2e //tests:e2e.${{ matrix.subset }}_node${{ matrix.node }} @@ -128,11 +128,11 @@ jobs: runs-on: ubuntu-latest steps: - name: Initialize environment - uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@b137f89f74478e0d2b3902372c538d5656795e9a # main + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@28ae58d2ad683fb3991006c23a9829c08b65aaec # main - name: Setup Bazel - uses: angular/dev-infra/github-actions/bazel/setup@b137f89f74478e0d2b3902372c538d5656795e9a # main + uses: angular/dev-infra/github-actions/bazel/setup@28ae58d2ad683fb3991006c23a9829c08b65aaec # main - name: Setup Bazel RBE - uses: angular/dev-infra/github-actions/bazel/configure-remote@b137f89f74478e0d2b3902372c538d5656795e9a # main + uses: angular/dev-infra/github-actions/bazel/configure-remote@28ae58d2ad683fb3991006c23a9829c08b65aaec # main - name: Install node modules run: pnpm install --frozen-lockfile - name: Build E2E tests for Windows on Linux @@ -156,7 +156,7 @@ jobs: runs-on: windows-2025 steps: - name: Initialize environment - uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@b137f89f74478e0d2b3902372c538d5656795e9a # main + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@28ae58d2ad683fb3991006c23a9829c08b65aaec # main - name: Install node modules run: pnpm install --frozen-lockfile - name: Download built Windows E2E tests @@ -183,13 +183,13 @@ jobs: runs-on: ubuntu-latest steps: - name: Initialize environment - uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@b137f89f74478e0d2b3902372c538d5656795e9a # main + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@28ae58d2ad683fb3991006c23a9829c08b65aaec # main - name: Install node modules run: pnpm install --frozen-lockfile - name: Setup Bazel - uses: angular/dev-infra/github-actions/bazel/setup@b137f89f74478e0d2b3902372c538d5656795e9a # main + uses: angular/dev-infra/github-actions/bazel/setup@28ae58d2ad683fb3991006c23a9829c08b65aaec # main - name: Setup Bazel RBE - uses: angular/dev-infra/github-actions/bazel/configure-remote@b137f89f74478e0d2b3902372c538d5656795e9a # main + uses: angular/dev-infra/github-actions/bazel/configure-remote@28ae58d2ad683fb3991006c23a9829c08b65aaec # main - name: Run CLI E2E tests run: pnpm bazel test --test_env=E2E_SHARD_TOTAL=3 --test_env=E2E_SHARD_INDEX=${{ matrix.shard }} --config=e2e //tests:e2e.${{ matrix.subset }}_node${{ matrix.node }} @@ -205,12 +205,12 @@ jobs: runs-on: ubuntu-latest steps: - name: Initialize environment - uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@b137f89f74478e0d2b3902372c538d5656795e9a # main + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@28ae58d2ad683fb3991006c23a9829c08b65aaec # main - name: Install node modules run: pnpm install --frozen-lockfile - name: Setup Bazel - uses: angular/dev-infra/github-actions/bazel/setup@b137f89f74478e0d2b3902372c538d5656795e9a # main + uses: angular/dev-infra/github-actions/bazel/setup@28ae58d2ad683fb3991006c23a9829c08b65aaec # main - name: Setup Bazel RBE - uses: angular/dev-infra/github-actions/bazel/configure-remote@b137f89f74478e0d2b3902372c538d5656795e9a # main + uses: angular/dev-infra/github-actions/bazel/configure-remote@28ae58d2ad683fb3991006c23a9829c08b65aaec # main - name: Run CLI E2E tests run: pnpm bazel test --test_env=E2E_SHARD_TOTAL=6 --test_env=E2E_SHARD_INDEX=${{ matrix.shard }} --config=e2e //tests:e2e.snapshots.${{ matrix.subset }}_node${{ matrix.node }} diff --git a/MODULE.bazel b/MODULE.bazel index 1a6f890d5188..a4caf9a9bc97 100644 --- a/MODULE.bazel +++ b/MODULE.bazel @@ -19,21 +19,21 @@ bazel_dep(name = "aspect_rules_jasmine", version = "2.0.4") bazel_dep(name = "rules_angular") git_override( module_name = "rules_angular", - commit = "2d9142c529ac31dddf1bb4e7e5a61c696f97a8f4", + commit = "b5869cff3db5d2217b8896d483e75af8a1d26712", remote = "https://github.com/angular/rules_angular.git", ) bazel_dep(name = "devinfra") git_override( module_name = "devinfra", - commit = "b137f89f74478e0d2b3902372c538d5656795e9a", + commit = "28ae58d2ad683fb3991006c23a9829c08b65aaec", remote = "https://github.com/angular/dev-infra.git", ) bazel_dep(name = "rules_browsers") git_override( module_name = "rules_browsers", - commit = "dba44a25ad8789113c37c2aace5574d794faa7ef", + commit = "4b53d68eed02bbb0901b21fb02b8cf99f4f59a52", remote = "https://github.com/angular/rules_browsers.git", ) diff --git a/MODULE.bazel.lock b/MODULE.bazel.lock index c29e353e22a7..38524a59eced 100644 --- a/MODULE.bazel.lock +++ b/MODULE.bazel.lock @@ -93,7 +93,6 @@ "https://bcr.bazel.build/modules/hermetic_launcher/0.0.15/source.json": "aceb903a3bda5131b0a3132ccf77f36f32b96dcb70864049ec8cfdf9c0b0f068", "https://bcr.bazel.build/modules/jq.bzl/0.1.0/MODULE.bazel": "2ce69b1af49952cd4121a9c3055faa679e748ce774c7f1fda9657f936cae902f", "https://bcr.bazel.build/modules/jq.bzl/0.4.0/MODULE.bazel": "a7b39b37589f2b0dad53fd6c1ccaabbdb290330caa920d7ef3e6aad068cd4ab2", - "https://bcr.bazel.build/modules/jq.bzl/0.7.0/MODULE.bazel": "9d382531c42e7a7f6f2ea486aa8f27c605c54f6109e565f04056015e5764deca", "https://bcr.bazel.build/modules/jq.bzl/0.7.1/MODULE.bazel": "2dc4fd806df09b30aa7e0339f141a661f72df6af237f6db1fc4ca5c5045f1772", "https://bcr.bazel.build/modules/jq.bzl/0.7.1/source.json": "0dbd7febb9361e34247c952e749f21f258b5123126248624c0d921c4592eac96", "https://bcr.bazel.build/modules/jsoncpp/1.9.5/MODULE.bazel": "31271aedc59e815656f5736f282bb7509a97c7ecb43e927ac1a37966e0578075", @@ -181,7 +180,6 @@ "https://bcr.bazel.build/modules/rules_nodejs/6.2.0/MODULE.bazel": "ec27907f55eb34705adb4e8257952162a2d4c3ed0f0b3b4c3c1aad1fac7be35e", "https://bcr.bazel.build/modules/rules_nodejs/6.5.0/MODULE.bazel": "546d0cf79f36f9f6e080816045f97234b071c205f4542e3351bd4424282a8810", "https://bcr.bazel.build/modules/rules_nodejs/6.7.3/MODULE.bazel": "c22a48b2a0dbf05a9dc5f83837bbc24c226c1f6e618de3c3a610044c9f336056", - "https://bcr.bazel.build/modules/rules_nodejs/6.7.5/MODULE.bazel": "97e6794043821d23c013baa4a50fd1c599f2e6ae92b06e2c5f1cd7074fd83e7c", "https://bcr.bazel.build/modules/rules_nodejs/6.7.6/MODULE.bazel": "45f203b9c0d721bcb1a5932815f218091fa2169cede2af3d88a8a17a4fb7676a", "https://bcr.bazel.build/modules/rules_nodejs/6.7.6/source.json": "ad9987b7979be1ce93d10ffee9b6af4f84f8835cbc7def27937d632da2e4750e", "https://bcr.bazel.build/modules/rules_pkg/0.7.0/MODULE.bazel": "df99f03fc7934a4737122518bb87e667e62d780b610910f0447665a7e2be62dc", @@ -447,16 +445,16 @@ }, "@@rules_browsers+//browsers:extensions.bzl%browsers": { "general": { - "bzlTransitiveDigest": "v0vEY6SvVg9HBAENk4KWY5NR6epcg4ucdSnkhcCNv8E=", + "bzlTransitiveDigest": "/FonktAou7w4aKjGZUZDFFOlASeGnKNw0QALxUIdtuE=", "usagesDigest": "FmXYJVoVJlnfUU8x8gObSvu4qWcco/9Faw61aC/wBF0=", "recordedInputs": [], "generatedRepoSpecs": { "rules_browsers_chrome_linux": { "repoRuleId": "@@rules_browsers+//browsers/private:browser_repo.bzl%browser_repo", "attributes": { - "sha256": "272b05d40a44082c82d09beb35c7cb7116564a6a85ff2f7a48bc161129fc5772", + "sha256": "9541eafbc02f85e3ec0c24b05f8bbffe88094389949860681bf6055aef668d7b", "urls": [ - "https://storage.googleapis.com/chrome-for-testing-public/157.0.8089.0/linux64/chrome-headless-shell-linux64.zip" + "https://storage.googleapis.com/chrome-for-testing-public/157.0.8099.0/linux64/chrome-headless-shell-linux64.zip" ], "named_files": { "CHROME-HEADLESS-SHELL": "chrome-headless-shell-linux64/chrome-headless-shell" @@ -472,9 +470,9 @@ "rules_browsers_chrome_mac": { "repoRuleId": "@@rules_browsers+//browsers/private:browser_repo.bzl%browser_repo", "attributes": { - "sha256": "9c28150b8c24fa99ac1e9e39fa07247b61d7f6f15f1c25ca9273c1b4273e2afd", + "sha256": "358f032d48a0b825b0601b89b970da5a7c245344ed7a557a3ef8613c342521b0", "urls": [ - "https://storage.googleapis.com/chrome-for-testing-public/157.0.8089.0/mac-x64/chrome-headless-shell-mac-x64.zip" + "https://storage.googleapis.com/chrome-for-testing-public/157.0.8099.0/mac-x64/chrome-headless-shell-mac-x64.zip" ], "named_files": { "CHROME-HEADLESS-SHELL": "chrome-headless-shell-mac-x64/chrome-headless-shell" @@ -490,9 +488,9 @@ "rules_browsers_chrome_mac_arm": { "repoRuleId": "@@rules_browsers+//browsers/private:browser_repo.bzl%browser_repo", "attributes": { - "sha256": "a6471f52b4eeb52af88d2f45e16125a9327517fd8b43512fc5561a3318487640", + "sha256": "c3de600edda5e11aa40918f123781040cd6e9c2509a2acfc466b773bf7c9b326", "urls": [ - "https://storage.googleapis.com/chrome-for-testing-public/157.0.8089.0/mac-arm64/chrome-headless-shell-mac-arm64.zip" + "https://storage.googleapis.com/chrome-for-testing-public/157.0.8099.0/mac-arm64/chrome-headless-shell-mac-arm64.zip" ], "named_files": { "CHROME-HEADLESS-SHELL": "chrome-headless-shell-mac-arm64/chrome-headless-shell" @@ -508,9 +506,9 @@ "rules_browsers_chrome_win64": { "repoRuleId": "@@rules_browsers+//browsers/private:browser_repo.bzl%browser_repo", "attributes": { - "sha256": "64332865f3d250a66f704e90d37a3d57f9800d6ea774138ede35ea37d1af7f2c", + "sha256": "b2e81e06ac46d3355bc6428b3abe97308d34e810d4404427bbd14665111e67a1", "urls": [ - "https://storage.googleapis.com/chrome-for-testing-public/157.0.8089.0/win64/chrome-headless-shell-win64.zip" + "https://storage.googleapis.com/chrome-for-testing-public/157.0.8099.0/win64/chrome-headless-shell-win64.zip" ], "named_files": { "CHROME-HEADLESS-SHELL": "chrome-headless-shell-win64/chrome-headless-shell.exe" @@ -526,9 +524,9 @@ "rules_browsers_chromedriver_linux": { "repoRuleId": "@@rules_browsers+//browsers/private:browser_repo.bzl%browser_repo", "attributes": { - "sha256": "0901026cbac4cce608a95bcbdcc87166e7736c9cc0431f5d3466058c9e570aec", + "sha256": "cf16fed1899de0f0b8999389779cefbb6696c5fd44ad9718ce2195a3ff5ca029", "urls": [ - "https://storage.googleapis.com/chrome-for-testing-public/157.0.8089.0/linux64/chromedriver-linux64.zip" + "https://storage.googleapis.com/chrome-for-testing-public/157.0.8099.0/linux64/chromedriver-linux64.zip" ], "named_files": { "CHROMEDRIVER": "chromedriver-linux64/chromedriver" @@ -542,9 +540,9 @@ "rules_browsers_chromedriver_mac": { "repoRuleId": "@@rules_browsers+//browsers/private:browser_repo.bzl%browser_repo", "attributes": { - "sha256": "69b0982bfe954c969cbc9357a39efb2f1861447f4168017831ffafec62448d90", + "sha256": "ba472bdd32ee62a98f04fcca364015a0df241fdf85ee7d834a048b5fdfd90fd3", "urls": [ - "https://storage.googleapis.com/chrome-for-testing-public/157.0.8089.0/mac-x64/chromedriver-mac-x64.zip" + "https://storage.googleapis.com/chrome-for-testing-public/157.0.8099.0/mac-x64/chromedriver-mac-x64.zip" ], "named_files": { "CHROMEDRIVER": "chromedriver-mac-x64/chromedriver" @@ -558,9 +556,9 @@ "rules_browsers_chromedriver_mac_arm": { "repoRuleId": "@@rules_browsers+//browsers/private:browser_repo.bzl%browser_repo", "attributes": { - "sha256": "18d30af4843f5535d56ab615702749650f1fc9c6b67ec3fd419ed5a9d4fcbf58", + "sha256": "8fe44ebac5303278a5d533c114ad0dbed0df9c218bce5b80d606078472ea95bd", "urls": [ - "https://storage.googleapis.com/chrome-for-testing-public/157.0.8089.0/mac-arm64/chromedriver-mac-arm64.zip" + "https://storage.googleapis.com/chrome-for-testing-public/157.0.8099.0/mac-arm64/chromedriver-mac-arm64.zip" ], "named_files": { "CHROMEDRIVER": "chromedriver-mac-arm64/chromedriver" @@ -574,9 +572,9 @@ "rules_browsers_chromedriver_win64": { "repoRuleId": "@@rules_browsers+//browsers/private:browser_repo.bzl%browser_repo", "attributes": { - "sha256": "9b79fc95eed9212d5888a1a7de456eba68df54d65b6fb490ce34d55efdc5cd48", + "sha256": "1fadd71af32db4e3497ce4faac3f07503f4c4cdad8747e71ff62c5c9c3dd05e1", "urls": [ - "https://storage.googleapis.com/chrome-for-testing-public/157.0.8089.0/win64/chromedriver-win64.zip" + "https://storage.googleapis.com/chrome-for-testing-public/157.0.8099.0/win64/chromedriver-win64.zip" ], "named_files": { "CHROMEDRIVER": "chromedriver-win64/chromedriver.exe" diff --git a/package.json b/package.json index 1037a8bfa7c6..6541f5d157af 100644 --- a/package.json +++ b/package.json @@ -55,7 +55,7 @@ "@angular/forms": "22.3.0-next.1", "@angular/localize": "22.3.0-next.1", "@angular/material": "22.3.0-next.1", - "@angular/ng-dev": "https://github.com/angular/dev-infra-private-ng-dev-builds.git#89b8c002e5d47ba1cbc4483d3ec06b0ae0aaccb7", + "@angular/ng-dev": "https://github.com/angular/dev-infra-private-ng-dev-builds.git#fa4308affb4a0dde34ebc95196b58550752485a2", "@angular/platform-browser": "22.3.0-next.1", "@angular/platform-server": "22.3.0-next.1", "@angular/router": "22.3.0-next.1", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index e6b9e456459e..b6cf96a9c926 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -208,8 +208,8 @@ importers: specifier: 22.3.0-next.1 version: 22.3.0-next.1(837417520965053888cf2615dc986a27) '@angular/ng-dev': - specifier: https://github.com/angular/dev-infra-private-ng-dev-builds.git#89b8c002e5d47ba1cbc4483d3ec06b0ae0aaccb7 - version: https://codeload.github.com/angular/dev-infra-private-ng-dev-builds/tar.gz/89b8c002e5d47ba1cbc4483d3ec06b0ae0aaccb7 + specifier: https://github.com/angular/dev-infra-private-ng-dev-builds.git#fa4308affb4a0dde34ebc95196b58550752485a2 + version: https://codeload.github.com/angular/dev-infra-private-ng-dev-builds/tar.gz/fa4308affb4a0dde34ebc95196b58550752485a2 '@angular/platform-browser': specifier: 22.3.0-next.1 version: 22.3.0-next.1(@angular/animations@22.3.0-next.1(@angular/core@22.3.0-next.1(@angular/compiler@22.3.0-next.1)(rxjs@7.8.2)(zone.js@0.16.3)))(@angular/common@22.3.0-next.1(@angular/core@22.3.0-next.1(@angular/compiler@22.3.0-next.1)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2))(@angular/core@22.3.0-next.1(@angular/compiler@22.3.0-next.1)(rxjs@7.8.2)(zone.js@0.16.3)) @@ -1106,9 +1106,9 @@ packages: '@angular/platform-browser': ^22.0.0-0 || ^22.1.0-0 || ^22.2.0-0 || ^22.3.0-0 || ^23.0.0-0 rxjs: ^6.5.3 || ^7.4.0 - '@angular/ng-dev@https://codeload.github.com/angular/dev-infra-private-ng-dev-builds/tar.gz/89b8c002e5d47ba1cbc4483d3ec06b0ae0aaccb7': - resolution: {gitHosted: true, integrity: sha512-vfMwQfoXYY5dX8IISR/9DpsLT+py7Zm2Nqj6CybryjFosxMxW4ajXKfJ3Zywu2k0wPfRVoQY+PMZ78vfPji+qQ==, tarball: https://codeload.github.com/angular/dev-infra-private-ng-dev-builds/tar.gz/89b8c002e5d47ba1cbc4483d3ec06b0ae0aaccb7} - version: 0.0.0-8b6cbbca278a26f2495275c5d9d0d8633573162d + '@angular/ng-dev@https://codeload.github.com/angular/dev-infra-private-ng-dev-builds/tar.gz/fa4308affb4a0dde34ebc95196b58550752485a2': + resolution: {gitHosted: true, integrity: sha512-zq1Lg7edQb2cf9QrSiQEU/+LwY4e/af9tN9W3hO5jDdYK+gp+sYZbBbuzounSWkmK+j+oG0K5CA9/kmyHAimZg==, tarball: https://codeload.github.com/angular/dev-infra-private-ng-dev-builds/tar.gz/fa4308affb4a0dde34ebc95196b58550752485a2} + version: 0.0.0-f28485704b2d1f81ae380a8296a4f14d9852c248 hasBin: true '@angular/platform-browser@22.3.0-next.1': @@ -1763,12 +1763,12 @@ packages: resolution: {integrity: sha512-ooWCrlZP11i8GImSjTHYHLkvFDP48nS4+204nGb1RiX/WXYHmJA2III9/e2DWVabCESdW7hBAEzHRqUn9OUVvQ==} engines: {node: '>=0.1.90'} - '@conventional-changelog/git-client@3.1.2': - resolution: {integrity: sha512-jZqwnJwf7nboIlAcw/mkOjVa6DexCcUOgT2oOQgkoi3z9vR8tGFkcMy2BFcYwjhL9sYcDDXkRQDayiDieCoW7A==} + '@conventional-changelog/git-client@3.2.0': + resolution: {integrity: sha512-sD/E0vzpkoDz/dqM1Hhv0ihC4KBw6RXjefeO8SG1XrX+wGkMxe1pKeedkKDPCtr2JjuhbuS9aJNgOvnT8hbeBw==} engines: {node: '>=22'} peerDependencies: conventional-commits-filter: ^6.0.1 - conventional-commits-parser: ^7.1.2 + conventional-commits-parser: ^7.1.3 peerDependenciesMeta: conventional-commits-filter: optional: true @@ -2036,9 +2036,9 @@ packages: '@noble/hashes': optional: true - '@firebase/ai@2.16.0': - resolution: {integrity: sha512-WRVxl58B61Orwf7st7949ZIW2L4huV80Gpaum1z8v2eH+m2xaxWtC8mOjQyVAOirr6O/yf89cBjlPvoyBpBfTg==} - engines: {node: '>=20.0.0'} + '@firebase/ai@3.0.0': + resolution: {integrity: sha512-66jJAi6JUmyXna89xaDONmfvupO1wNc3f2BegPwUImagbbpKdVeycE3kMqbU4jiDLL14N5PHzadovvxpaqD2hw==} + engines: {node: '>=24.12.0'} peerDependencies: '@firebase/app': 0.x '@firebase/app-types': 0.x @@ -2076,20 +2076,20 @@ packages: peerDependencies: '@firebase/app': 0.x - '@firebase/app-compat@0.5.18': - resolution: {integrity: sha512-77H57WuGEsgrv59HdtuhHG+eQdP8di6myz7O93yW6yTZlR/tLSmsCxCq5vHp6AWWDwSV0EVtKUvizXQiQZVBWA==} - engines: {node: '>=20.0.0'} + '@firebase/app-compat@0.5.19': + resolution: {integrity: sha512-pdT+THcv3h43LcawVJ+MUTzofL7umBaCvCgdbr01fnTXrbQU2RSHb0Po/YsF7w+tgjCycg84zCgZbd51NmoIaA==} + engines: {node: '>=24.12.0'} '@firebase/app-types@0.9.6': resolution: {integrity: sha512-yPLahy7Esfu2w/yme3msVK4xTkDXQqq6szfQn8yVOQpCKiT5GVFjqNpLbuz6NkX0WuTwUidkmPewW3r4xkvpeg==} - '@firebase/app@0.16.2': - resolution: {integrity: sha512-fyCLPahl3r0Zb7Wzm+JLWcOOH3SaDgAyJzJ8EWIDiv51aNiv+2Pjbpa6myEuP7iXxjmJqrcbVm0GUF7h229T1Q==} - engines: {node: '>=20.0.0'} + '@firebase/app@0.16.3': + resolution: {integrity: sha512-L2mYqVV2ilnek+W4JG7yasA97TsXCwx+f7/abweX5uSp3dkPa5Luiglt3s9YWfh1fBR3SWH/AkRgAwUpDGyCjg==} + engines: {node: '>=24.12.0'} - '@firebase/auth-compat@0.6.11': - resolution: {integrity: sha512-L+xp3DTJQrBV08Vt0UhcL/ofUOSjXom7JOJfbT6oas4o7gCrQnTYFKs8wfiuKLmHoo8BxMr5LdgjAs7o6aAsqQ==} - engines: {node: '>=20.0.0'} + '@firebase/auth-compat@0.6.12': + resolution: {integrity: sha512-Vspo2zx1RR6LB7zuM7TduD1clMLT/x3Wr97u2jf9s2JrhYArJAFKeEu8bRWF1DoX54z6W9N77SdPRbPAiLKPpg==} + engines: {node: '>=24.12.0'} peerDependencies: '@firebase/app': 0.x '@firebase/app-compat': 0.x @@ -2103,9 +2103,9 @@ packages: '@firebase/app-types': 0.x '@firebase/util': 1.x - '@firebase/auth@1.13.6': - resolution: {integrity: sha512-MKRLvF72HJ/irNn2fJR0Gv5FOZNtqv1IBeJHRwK8l8pZ/wi9vuUw8ecyCMvQDDNxfS6uW0MWACL5KC4Y8Pp+fA==} - engines: {node: '>=20.0.0'} + '@firebase/auth@1.13.7': + resolution: {integrity: sha512-00wn8cMrh1ZyEPF6RO5G081Xq1b57FN0QxChiAda0hy/D3Q5TrMk30qhWszRWCgXPRipw6yM6qtqUew3u3qEjA==} + engines: {node: '>=24.12.0'} peerDependencies: '@firebase/app': 0.x '@react-native-async-storage/async-storage': ^2.2.0 || ^3.0.0 @@ -2141,9 +2141,9 @@ packages: resolution: {integrity: sha512-/JGpvszLoNXNgzilRXocigGfFF4hbcPA9wN1i1kjJx6oKkXgkHteZYl3lQs1lJX3ETDf6bv7zI15lPMVUp4sAQ==} engines: {node: '>=20.0.0'} - '@firebase/firestore-compat@0.4.14': - resolution: {integrity: sha512-HJ2HBNgNPrRsWIJ4E+Kc0u0h1U7HlF7If8AtYjie9HZXlMUmwYSJaXBj9VFm6gkSj5dlKZNcOQ0Ou25CVVG6rA==} - engines: {node: '>=20.0.0'} + '@firebase/firestore-compat@0.4.15': + resolution: {integrity: sha512-/hWibRTNFsWkZZi1dbDS1hiJIMezYUMPrRjMmBXevel5b368XWY+NvfOaSxgy3+fDb6I+uZ7SKGFyL06gW3vTA==} + engines: {node: '>=24.12.0'} peerDependencies: '@firebase/app': 0.x '@firebase/app-compat': 0.x @@ -2154,9 +2154,9 @@ packages: '@firebase/app-types': 0.x '@firebase/util': 1.x - '@firebase/firestore@4.17.2': - resolution: {integrity: sha512-SiyQEK1dYPOjItFVA+kZGdvOoRAtMebDBvUaSxJPNZMkKcRwYYK2kzWo5UXTZZj523uMxJnkr+KKVySEMme3kQ==} - engines: {node: '>=20.0.0'} + '@firebase/firestore@4.18.0': + resolution: {integrity: sha512-28aKMUeM+L4fuxx5hurvQK31KLh/KRutaP1544avVWuR4mNTAC0FQoHg8gbkN5NoJj3yN9/ZFGSFSVPR8/x/BQ==} + engines: {node: '>=24.12.0'} peerDependencies: '@firebase/app': 0.x @@ -2224,8 +2224,8 @@ packages: peerDependencies: '@firebase/app': 0.x - '@firebase/remote-config-compat@0.2.29': - resolution: {integrity: sha512-mY7JtTISK6F4g4T0x3kVepr5cp0NXL7f5yjIUXXGaTrg4qUlFBWRbENaHaqZ78dwmNcLm24h/yPsOVRlDXEXhA==} + '@firebase/remote-config-compat@0.2.30': + resolution: {integrity: sha512-Q4sQKhQ8TPEMOcCUvUBfGeAP1DfcG7FGBfA9yFUn/XRr4vSToY0DTmK28Nh7lgLQYzs6D5Ng6knSoXH+aGn1Tg==} peerDependencies: '@firebase/app': 0.x '@firebase/app-compat': 0.x @@ -2233,14 +2233,14 @@ packages: '@firebase/remote-config-types@0.5.2': resolution: {integrity: sha512-i8k1omVfoAnaT1ZPv2FFjxMZrATYsO/GnFgHEj5+7fAJLzi8wLnGGv1WK06oEAD6ltrWXSO1HzeNyajn/NjMWw==} - '@firebase/remote-config@0.9.2': - resolution: {integrity: sha512-Rii93DkXjM+RE/ytHdYa7EIiQLJbdBr+W8EEiqd/vbLCOC+1FdkDuRiumJBp6t3yewHGbdqbpjB3fk3z0cZ+8g==} + '@firebase/remote-config@0.9.3': + resolution: {integrity: sha512-9DbuFNAFeUbVJQZmwLZfdoLRNFWV43V4UqaRpDkaSIdTmVWhzctPeISGkWe4sKTsqpoyldRumquS0gqWZg05fQ==} peerDependencies: '@firebase/app': 0.x - '@firebase/storage-compat@0.4.5': - resolution: {integrity: sha512-vO0tFPxXbKDKdlTu8tYT08S9t9ezUTJYEdLCULpWxWq2aq6zojwN1QmAB+1a50AI/g47GlWUJn1XPncm/PDZsw==} - engines: {node: '>=20.0.0'} + '@firebase/storage-compat@0.4.6': + resolution: {integrity: sha512-te0IsqX1bM+OZCJF7jNSKXcMqCA2yYmpshRHjX4axy0lI/P9ZP9GLjEZMVL8wrjUWF4e3cZxMZTbck3Zd5E1hA==} + engines: {node: '>=24.12.0'} peerDependencies: '@firebase/app': 0.x '@firebase/app-compat': 0.x @@ -2251,9 +2251,9 @@ packages: '@firebase/app-types': 0.x '@firebase/util': 1.x - '@firebase/storage@0.14.5': - resolution: {integrity: sha512-r2tozN/BlEewLi70tJNUQPzWwbex9GM7NgXZsamHKQrjKEfcR0i4jGgHBKAKA4hbwiPE9eNMb3hcxWnDpeJZwg==} - engines: {node: '>=20.0.0'} + '@firebase/storage@0.14.6': + resolution: {integrity: sha512-9WjohxpjbfcySjCp8kIbd1ZhtmCQFQLqPtDQ+wmZ5PVXimTDjDsSx/RZjwwK89MjCTXB9fCdmvZkJxplZn4W1A==} + engines: {node: '>=24.12.0'} peerDependencies: '@firebase/app': 0.x @@ -2295,8 +2295,8 @@ packages: resolution: {integrity: sha512-IJn+8A3QZJfe7FUtWqHVNo3xJs7KFpurCWGWCiCz3oEh+BkRymKZ1QxfAbU2yGMDzTytLGQ2IV6T2r3cuo75/w==} engines: {node: '>=18'} - '@google/genai@2.25.0': - resolution: {integrity: sha512-g1hyidWxahzIg+hh+lLqPeBJl+Fu6051we2QKhFXdWgE4yGYf8PWOS8S3mMAdpe3eLx3KCWmhQR7GWyd3LYT1A==} + '@google/genai@2.28.0': + resolution: {integrity: sha512-hyNAJj+ywu3L46qlZod6KO/JvcT3QONz6VCiPevC/FWOjAD+LQb7DMLUoV8vzoLpt61Q0ruQX99iqbxEjPJWmw==} engines: {node: '>=20.0.0'} peerDependencies: '@modelcontextprotocol/sdk': ^1.25.2 @@ -2358,15 +2358,6 @@ packages: '@types/node': optional: true - '@inquirer/confirm@6.3.2': - resolution: {integrity: sha512-Xvr/0HggjddPtGppuqVmxhTw+Hr8PvsZ/k0HmOEaAqQEt80OITNkFWnsdNmyT0/eM4Ab+iJLx2R8rctlEyfSVg==} - engines: {node: '>=23.5.0 || ^22.13.0 || ^20.17.0'} - peerDependencies: - '@types/node': '>=18' - peerDependenciesMeta: - '@types/node': - optional: true - '@inquirer/confirm@6.3.3': resolution: {integrity: sha512-ImOBgpl/sJTFp8naeSkNu4S0Sf8F8pxv3/CUx+LoBAdQvCVqFz6rSB2A/oZYsJge3+yphbEDxEkfaRNYq1OU0A==} engines: {node: '>=23.5.0 || ^22.13.0 || ^20.17.0'} @@ -2443,15 +2434,6 @@ packages: '@types/node': optional: true - '@inquirer/prompts@8.7.2': - resolution: {integrity: sha512-QoRB4wFIjgH5iOhSjoIKMkTvSHDuV+O3OITlIqAYO0oK5x364GJILXiMBvlPiE+klg7Xx9tq5XVqQHcGUDYYPA==} - engines: {node: '>=23.5.0 || ^22.13.0 || ^20.17.0'} - peerDependencies: - '@types/node': '>=18' - peerDependenciesMeta: - '@types/node': - optional: true - '@inquirer/prompts@8.7.3': resolution: {integrity: sha512-DHK20kO+H5k/XcJQpHQUpVQbMYHHhZchlGWhZVMUV4WIuRuBW5744hipOtriE1vMqPLgnIyXFMHWKkIbTepa4Q==} engines: {node: '>=23.5.0 || ^22.13.0 || ^20.17.0'} @@ -2488,15 +2470,6 @@ packages: '@types/node': optional: true - '@inquirer/type@4.1.1': - resolution: {integrity: sha512-yJoHYrMnxIsJZCY+0Vb66Dy3he3kL3e2wOBKhoSwWWAzZAY82emlxwgprCtp6yRixvNRNq9ztfRWQYPNr3Go7A==} - engines: {node: '>=23.5.0 || ^22.13.0 || ^20.17.0'} - peerDependencies: - '@types/node': '>=18' - peerDependenciesMeta: - '@types/node': - optional: true - '@inquirer/type@4.2.0': resolution: {integrity: sha512-2rnHX8RPo4glJYqnFc/v3nQeIhDcjyRRyaT7MGcfL/8xv/8K03SXYoA2tX06WVSKywWOE/ncbG3dtuzLjR5TCQ==} engines: {node: '>=23.5.0 || ^22.13.0 || ^20.17.0'} @@ -2754,9 +2727,9 @@ packages: cpu: [x64] os: [win32] - '@mswjs/interceptors@0.41.9': - resolution: {integrity: sha512-VVPPgHyQ6ShqnrmDWuxjmUIsO9gWyOZFmuOfLd9LfBGQJwZfy0gvv9pbHSJuoFNIYC7ZDX9aoFwowjcdSC4E8w==} - engines: {node: '>=18'} + '@mswjs/interceptors@0.44.0': + resolution: {integrity: sha512-IYHevRStF4ijM20GI9c9Ndhw483NSAjCydQhUr4/zIB0BNLsTVw3vFAxTo6TlvX4QnV60wEHttUa9539TTAq+A==} + engines: {node: '>=22'} '@napi-rs/lzma-linux-x64-gnu@1.5.1': resolution: {integrity: sha512-oTXEIha4SsuXdTA4Iyskj0kpdx2yVXdhd75c2v3xGrHFfVMsbhTPZU/nMPL4sWKo4pBHm3aucLaqGlF696dTyQ==} @@ -2952,12 +2925,6 @@ packages: peerDependencies: '@octokit/core': '>=6' - '@octokit/plugin-paginate-rest@15.0.0': - resolution: {integrity: sha512-lw9A9YL5s4VPj+VEx8uMxaxQm2YTgrPDkrLEuZuu18R8TK3oPcXF4K6t52nx6xn1RcogZC9i188sAr/4XYJaQQ==} - engines: {node: '>= 20'} - peerDependencies: - '@octokit/core': '>=6' - '@octokit/plugin-request-log@6.0.0': resolution: {integrity: sha512-UkOzeEN3W91/eBq9sPZNQ7sUBvYCqYbrrD8gTbBuGtHEuycE4/awMXcYvx6sVYo7LypPhmQwwpUe4Yyu4QZN5Q==} engines: {node: '>= 20'} @@ -2997,14 +2964,8 @@ packages: '@octokit/types@18.0.0': resolution: {integrity: sha512-l6bAF43PNxkJp6g+W4PjoUSSkxHomXw2nOum5CTftJz1NlV3vu93NImgOYtLf6CbBUb5j+fiuzW0PPQ5JTSvZA==} - '@open-draft/deferred-promise@2.2.0': - resolution: {integrity: sha512-CecwLWx3rhxVQF6V4bAgPS5t+So2sTbPgAzafKkVizyi7tlwpcFpdFqq+wqF2OwNBmqFuu6tOyouTuxgpMfzmA==} - - '@open-draft/logger@0.3.0': - resolution: {integrity: sha512-X2g45fzhxH238HKO4xbSr7+wBS8Fvw6ixhTDuvLd5mqh6bJJCFAPwU9mPDxbcrRtfxv4u5IHCEH77BmxvXmmxQ==} - - '@open-draft/until@2.1.0': - resolution: {integrity: sha512-U69T3ItWHvLwGg5eJ0n3I62nWuE6ilHlmz7zM0npLBRvPRd7e6NYmg54vvRtP5mZG7kZqZCFVdsTWo7BPtBujg==} + '@open-draft/until@3.0.1': + resolution: {integrity: sha512-s7/9ELP4aP9YZtW7RJaa0Xf3RISaRH9+EFN18FtykJYRHGNrl8f9ymvoNXzjhrjmftFvkQudtuDU9RYhk0xs3A==} '@opentelemetry/api@1.9.1': resolution: {integrity: sha512-gLyJlPHPZYdAk1JENA9LeHejZe1Ti77/pTeFm/nMXmQH/HFZlcS/O2XJB+L8fkbrNSqhdtlvjBVjxwUYanNH5Q==} @@ -3781,6 +3742,9 @@ packages: '@types/cors@2.8.19': resolution: {integrity: sha512-mFNylyeyqN93lfe/9CSxOGREz8cpzAhH+E93xJ4xWQf62V8sQ/24reV2nyzUWM6H6Xji+GGHpkbLe7pVoUEskg==} + '@types/debug@4.1.13': + resolution: {integrity: sha512-KSVgmQmzMwPlmtljOomayoR89W4FynCAi3E8PPs7vmDVPe84hT+vGPKkJfThkmXs0x0jAaa9U8uW8bbfyS2fWw==} + '@types/deep-eql@4.0.2': resolution: {integrity: sha512-c9h9dVVMigMPc4bwTvC5dxqtqJZwQPePsWjPlpSOnojbor6pGqdk541lfA7AqFQr5pB1BRdq0juY9db81BwyFw==} @@ -3850,11 +3814,14 @@ packages: '@types/micromatch@2.3.35': resolution: {integrity: sha512-J749bHo/Zu56w0G0NI/IGHLQPiSsjx//0zJhfEVAN95K/xM5C8ZDmhkXtU3qns0sBOao7HuQzr8XV1/2o5LbXA==} + '@types/ms@2.1.0': + resolution: {integrity: sha512-GsCCIZDE/p3i96vtEqx+7dBUGXrc7zeSK3wwPHIaRThS+9OhWIXRqzs4d6k1SVU8g91DrNRWxWUGhp5KXQb2VA==} + '@types/node@22.20.5': resolution: {integrity: sha512-U2+DNr+wSjpsTS/wZGYHq7GcwfuSmKiKvoPvK22zwTlRhU91yOniN4qRR5KhIjvif7ysw/dz/hKmfDH0Ris4aA==} - '@types/node@24.19.0': - resolution: {integrity: sha512-zY+5tKxXdhGh1PYI0ac+7juvEu4OI6vWtVVoj5i2m42jxAY1U+zHGt6QCyOFwykdP62sM3MJ9stoYYUw5aCWew==} + '@types/node@24.19.1': + resolution: {integrity: sha512-aS3/DG0oM05K0RIXXP+hKjinGG5IgSSVGzswZxW3O0sS3pH4/fycXundUC9XsszgKCk4gHXylTEK6hyFxVxnoQ==} '@types/npm-package-arg@6.1.4': resolution: {integrity: sha512-vDgdbMy2QXHnAruzlv68pUtXCjmqUk3WrBAsRboRovsOmxbfn/WiYCjmecyKjGztnMps5dWp4Uq2prp+Ilo17Q==} @@ -4911,8 +4878,8 @@ packages: resolution: {integrity: sha512-cs+LadpH7Kpw0M3k8wurk+sOVVDAENA0iK4OBOrkL94j5lEVYRJ4j3zd2bhY9qgzyrPqthdcYT3axzRN7AliMg==} engines: {node: '>=22'} - conventional-commits-parser@7.1.2: - resolution: {integrity: sha512-O+x4N2yH+ijvqWlIyTHsXTAP+algNWgGbjY2duCe8w2vUMvUB95cLRslCPfTMQyLAKlet3bhZTdu6ozn4M+QJQ==} + conventional-commits-parser@7.1.3: + resolution: {integrity: sha512-Q9oWm1o9uy/oEsZQIraoFMZ4RuPD+79KgwWj6mJVP356tazolCB0piRLZ5Kz9te9p027uSEcUW+Gu44Eh+X79g==} engines: {node: '>=22'} hasBin: true @@ -5049,15 +5016,6 @@ packages: supports-color: optional: true - debug@4.4.0: - resolution: {integrity: sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA==} - engines: {node: '>=6.0'} - peerDependencies: - supports-color: '*' - peerDependenciesMeta: - supports-color: - optional: true - debug@4.4.3: resolution: {integrity: sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==} engines: {node: '>=6.0'} @@ -5565,8 +5523,8 @@ packages: resolution: {integrity: sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==} engines: {node: '>=10'} - firebase@12.19.0: - resolution: {integrity: sha512-kwXCLcI0ly2lkwygkbuRx6SsX3DSO96355YrWh9SWZ5ncsxK/y5cirn3sY6nZVSiBVE++2nL6Hchzu1EB8uohQ==} + firebase@13.0.0: + resolution: {integrity: sha512-4cChZajVtuOijT/t7Vw1GZRTuohCxw+aoc8DAwhF+CSbS+zhqHE+i5PzEVttIySw7oKerBDRZRyDt4FynrWecg==} flat-cache@6.1.23: resolution: {integrity: sha512-f++BY9pTk+983xK1FLzlLpmM0i0z+jHmx3QESGkURMXujQZz1k5wzwX6hjnQ8goaD0B+sYnDK1yZ6MTyZfUaqA==} @@ -5582,8 +5540,8 @@ packages: resolution: {integrity: sha512-kWyh8ADvHBFz6ua5xYOPnUroZTT/bwWfrCeL0Wj1dzG4/YOmOcfJ99W8dOVyyynJN35rZ9aCOtHChqQovV7yog==} engines: {node: '>=6'} - folder-hash@4.1.3: - resolution: {integrity: sha512-94fj+fXj1XHT8zGumUy/VlyFARc/yrslKJ2+vjrP/U6ftTdL7u68+gQhvSBjz9wrwTuty6BpZ7JsbEK5OU9RNw==} + folder-hash@4.1.4: + resolution: {integrity: sha512-BhHpJCYoTej4YH0C3HY4X49C2uOcWntjSD24T1GBYlfWcW/7mkHZov9HbvzCHQO+ZLbJ3VRE+cL1uEiaQvacLw==} engines: {node: '>=10.10.0'} hasBin: true @@ -6904,9 +6862,9 @@ packages: tailwindcss: optional: true - nock@14.0.17: - resolution: {integrity: sha512-EjRr1weMa4ALQX35AgZTEnP+weJJjlW1KGDiNM2IQC2069YDHas4f4B4UUYR+TTLyKWxJvOz2wObDKQs/LNreA==} - engines: {node: '>=18.20.0 <20 || >=20.12.1'} + nock@15.0.1: + resolution: {integrity: sha512-Mjx5Xl4t9vP13eUZPWqwwpjjXNjvhUTo1qTdryVM3+7t6Z2w6WHZ9GVZk/zQ8Ym1vbmloWaglye3cloyHAJ8FA==} + engines: {node: '>=20.12.1'} node-addon-api@6.1.0: resolution: {integrity: sha512-+eawOlIgy680F0kBzPUNFhMZGtJ1YmqM6l4+Crf4IkImjYrO/mqPwRMh352g23uIaQKFItcQ64I7KMaJxHgAVA==} @@ -7305,10 +7263,6 @@ packages: resolution: {integrity: sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A==} engines: {node: '>= 0.6.0'} - propagate@2.0.1: - resolution: {integrity: sha512-vGrhOavPSTz4QVNuBNdcNXePNdNMaO1xj9yBeH1ScQPjk/rhg9sSlCXPhMkFuaNNW/syTvYqsnbIJxMBfRbbag==} - engines: {node: '>= 8'} - proto3-json-serializer@3.0.4: resolution: {integrity: sha512-E1sbAYg3aEbXrq0n1ojJkRHQJGE1kaE/O6GLA94y8rnJBfgvOPTOd1b9hOceQK1FFZI9qMh1vBERCyO2ifubcw==} engines: {node: '>=18'} @@ -7522,6 +7476,9 @@ packages: resolution: {integrity: sha512-XQBQ3I8W1Cge0Seh+6gjj03LbmRFWuoszgK9ooCpwYIrhhoO80pfq4cUkU5DkknwfOfFteRwlZ56PYOGYyFWdg==} engines: {node: '>= 4'} + rettime@0.11.12: + resolution: {integrity: sha512-5ExtR1ppiDBQkVoPw5NAqdbfH4Iq2VOmQKHMtUoaFxA9bo2krzFYBtyq6K40xxbYp+2w/YOr6D+1ToF6tTN53A==} + reusify@1.1.0: resolution: {integrity: sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==} engines: {iojs: '>=1.0.0', node: '>=0.10.0'} @@ -8002,9 +7959,6 @@ packages: streamx@2.28.1: resolution: {integrity: sha512-zEzXb0s5Cds7tqMH6rhZ05lcJydCWiQPEwiNngVqzsxCc962vLY4Uw+mW7od8kDH258k2Uz/JrOkdIAAhSh9VA==} - strict-event-emitter@0.5.1: - resolution: {integrity: sha512-vMgjE/GGEPEFnhFub6pa4FmJBRBVOLpIII2hvCZ8Kzb7K0hlHo7mQv6xYrBvCL2LtAIBwFUK8wvuJgTVSQ5MFQ==} - string-width@4.2.3: resolution: {integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==} engines: {node: '>=8'} @@ -8890,30 +8844,28 @@ snapshots: rxjs: 7.8.2 tslib: 2.8.1 - '@angular/ng-dev@https://codeload.github.com/angular/dev-infra-private-ng-dev-builds/tar.gz/89b8c002e5d47ba1cbc4483d3ec06b0ae0aaccb7': + '@angular/ng-dev@https://codeload.github.com/angular/dev-infra-private-ng-dev-builds/tar.gz/fa4308affb4a0dde34ebc95196b58550752485a2': dependencies: '@actions/core': 3.0.1 - '@conventional-changelog/git-client': 3.1.2(conventional-commits-filter@6.0.1)(conventional-commits-parser@7.1.2) + '@conventional-changelog/git-client': 3.2.0(conventional-commits-filter@6.0.1)(conventional-commits-parser@7.1.3) '@google-cloud/spanner': 8.0.0(supports-color@11.0.0) - '@google/genai': 2.25.0(bufferutil@4.1.0)(supports-color@11.0.0)(utf-8-validate@6.0.6) - '@inquirer/prompts': 8.7.2(@types/node@24.19.0) - '@inquirer/type': 4.1.1(@types/node@24.19.0) + '@google/genai': 2.28.0(bufferutil@4.1.0)(supports-color@11.0.0)(utf-8-validate@6.0.6) + '@inquirer/prompts': 8.7.3(@types/node@24.19.1) + '@inquirer/type': 4.2.0(@types/node@24.19.1) '@octokit/auth-app': 8.3.1 '@octokit/core': 7.0.8 '@octokit/graphql': 9.0.5 '@octokit/graphql-schema': 15.26.1 - '@octokit/openapi-types': 28.0.0 - '@octokit/plugin-paginate-rest': 15.0.0(@octokit/core@7.0.8) '@octokit/plugin-rest-endpoint-methods': 18.0.0(@octokit/core@7.0.8) '@octokit/request-error': 7.1.2 '@octokit/rest': 22.0.1 - '@octokit/types': 17.0.0 + '@octokit/types': 18.0.0 '@types/cli-progress': 3.11.6 '@types/ejs': 3.1.5 '@types/events': 3.0.3 '@types/folder-hash': 4.0.4 '@types/jasmine': 6.0.0 - '@types/node': 24.19.0 + '@types/node': 24.19.1 '@types/semver': 7.8.0 '@types/which': 3.0.4 '@types/yargs': 17.0.35 @@ -8922,19 +8874,19 @@ snapshots: bufferutil: 4.1.0 cli-progress: 3.12.0 conventional-commits-filter: 6.0.1 - conventional-commits-parser: 7.1.2 + conventional-commits-parser: 7.1.3 ejs: 7.0.1 encoding: 0.1.13 fast-glob: 3.3.3 - firebase: 12.19.0 - folder-hash: 4.1.3(supports-color@11.0.0) + firebase: 13.0.0 + folder-hash: 4.1.4(supports-color@11.0.0) jasmine: 6.3.0 jasmine-core: 6.3.0 jasmine-reporters: 2.5.2 jsonc-parser: 3.3.1 minimatch: 10.2.6 multimatch: 8.0.0 - nock: 14.0.17 + nock: 15.0.1(supports-color@11.0.0) semver: 7.8.5 supports-color: 11.0.0 tsx: 4.23.15 @@ -9738,14 +9690,14 @@ snapshots: '@colors/colors@1.5.0': {} - '@conventional-changelog/git-client@3.1.2(conventional-commits-filter@6.0.1)(conventional-commits-parser@7.1.2)': + '@conventional-changelog/git-client@3.2.0(conventional-commits-filter@6.0.1)(conventional-commits-parser@7.1.3)': dependencies: '@simple-libs/child-process-utils': 2.0.0 '@simple-libs/stream-utils': 2.0.0 - semver: 7.8.5 + verkit: 0.5.0 optionalDependencies: conventional-commits-filter: 6.0.1 - conventional-commits-parser: 7.1.2 + conventional-commits-parser: 7.1.3 '@csstools/color-helpers@6.1.2': {} @@ -9929,9 +9881,9 @@ snapshots: optionalDependencies: '@noble/hashes': 1.8.0 - '@firebase/ai@2.16.0(@firebase/app-types@0.9.6)(@firebase/app@0.16.2)': + '@firebase/ai@3.0.0(@firebase/app-types@0.9.6)(@firebase/app@0.16.3)': dependencies: - '@firebase/app': 0.16.2 + '@firebase/app': 0.16.3 '@firebase/app-check-interop-types': 0.3.5 '@firebase/app-types': 0.9.6 '@firebase/component': 0.7.5 @@ -9939,33 +9891,33 @@ snapshots: '@firebase/util': 1.15.3 tslib: 2.8.1 - '@firebase/analytics-compat@0.2.31(@firebase/app-compat@0.5.18)(@firebase/app@0.16.2)': + '@firebase/analytics-compat@0.2.31(@firebase/app-compat@0.5.19)(@firebase/app@0.16.3)': dependencies: - '@firebase/analytics': 0.10.25(@firebase/app@0.16.2) + '@firebase/analytics': 0.10.25(@firebase/app@0.16.3) '@firebase/analytics-types': 0.8.5 - '@firebase/app': 0.16.2 - '@firebase/app-compat': 0.5.18 + '@firebase/app': 0.16.3 + '@firebase/app-compat': 0.5.19 '@firebase/component': 0.7.5 '@firebase/util': 1.15.3 tslib: 2.8.1 '@firebase/analytics-types@0.8.5': {} - '@firebase/analytics@0.10.25(@firebase/app@0.16.2)': + '@firebase/analytics@0.10.25(@firebase/app@0.16.3)': dependencies: - '@firebase/app': 0.16.2 + '@firebase/app': 0.16.3 '@firebase/component': 0.7.5 - '@firebase/installations': 0.6.24(@firebase/app@0.16.2) + '@firebase/installations': 0.6.24(@firebase/app@0.16.3) '@firebase/logger': 0.5.2 '@firebase/util': 1.15.3 tslib: 2.8.1 - '@firebase/app-check-compat@0.4.7(@firebase/app-compat@0.5.18)(@firebase/app@0.16.2)': + '@firebase/app-check-compat@0.4.7(@firebase/app-compat@0.5.19)(@firebase/app@0.16.3)': dependencies: - '@firebase/app': 0.16.2 - '@firebase/app-check': 0.13.1(@firebase/app@0.16.2) + '@firebase/app': 0.16.3 + '@firebase/app-check': 0.13.1(@firebase/app@0.16.3) '@firebase/app-check-types': 0.5.5 - '@firebase/app-compat': 0.5.18 + '@firebase/app-compat': 0.5.19 '@firebase/component': 0.7.5 '@firebase/logger': 0.5.2 '@firebase/util': 1.15.3 @@ -9975,17 +9927,17 @@ snapshots: '@firebase/app-check-types@0.5.5': {} - '@firebase/app-check@0.13.1(@firebase/app@0.16.2)': + '@firebase/app-check@0.13.1(@firebase/app@0.16.3)': dependencies: - '@firebase/app': 0.16.2 + '@firebase/app': 0.16.3 '@firebase/component': 0.7.5 '@firebase/logger': 0.5.2 '@firebase/util': 1.15.3 tslib: 2.8.1 - '@firebase/app-compat@0.5.18': + '@firebase/app-compat@0.5.19': dependencies: - '@firebase/app': 0.16.2 + '@firebase/app': 0.16.3 '@firebase/component': 0.7.5 '@firebase/logger': 0.5.2 '@firebase/util': 1.15.3 @@ -9995,7 +9947,7 @@ snapshots: dependencies: '@firebase/logger': 0.5.2 - '@firebase/app@0.16.2': + '@firebase/app@0.16.3': dependencies: '@firebase/component': 0.7.5 '@firebase/logger': 0.5.2 @@ -10003,11 +9955,11 @@ snapshots: idb: 7.1.1 tslib: 2.8.1 - '@firebase/auth-compat@0.6.11(@firebase/app-compat@0.5.18)(@firebase/app-types@0.9.6)(@firebase/app@0.16.2)': + '@firebase/auth-compat@0.6.12(@firebase/app-compat@0.5.19)(@firebase/app-types@0.9.6)(@firebase/app@0.16.3)': dependencies: - '@firebase/app': 0.16.2 - '@firebase/app-compat': 0.5.18 - '@firebase/auth': 1.13.6(@firebase/app@0.16.2) + '@firebase/app': 0.16.3 + '@firebase/app-compat': 0.5.19 + '@firebase/auth': 1.13.7(@firebase/app@0.16.3) '@firebase/auth-types': 0.13.2(@firebase/app-types@0.9.6)(@firebase/util@1.15.3) '@firebase/component': 0.7.5 '@firebase/util': 1.15.3 @@ -10023,9 +9975,9 @@ snapshots: '@firebase/app-types': 0.9.6 '@firebase/util': 1.15.3 - '@firebase/auth@1.13.6(@firebase/app@0.16.2)': + '@firebase/auth@1.13.7(@firebase/app@0.16.3)': dependencies: - '@firebase/app': 0.16.2 + '@firebase/app': 0.16.3 '@firebase/component': 0.7.5 '@firebase/logger': 0.5.2 '@firebase/util': 1.15.3 @@ -10036,16 +9988,16 @@ snapshots: '@firebase/util': 1.15.3 tslib: 2.8.1 - '@firebase/data-connect@0.7.4(@firebase/app@0.16.2)': + '@firebase/data-connect@0.7.4(@firebase/app@0.16.3)': dependencies: - '@firebase/app': 0.16.2 + '@firebase/app': 0.16.3 '@firebase/auth-interop-types': 0.2.6 '@firebase/component': 0.7.5 '@firebase/logger': 0.5.2 '@firebase/util': 1.15.3 tslib: 2.8.1 - '@firebase/database-compat@2.1.7(@firebase/app-compat@0.5.18)(@firebase/app@0.16.2)': + '@firebase/database-compat@2.1.7(@firebase/app-compat@0.5.19)(@firebase/app@0.16.3)': dependencies: '@firebase/component': 0.7.5 '@firebase/database': 1.1.5 @@ -10054,8 +10006,8 @@ snapshots: '@firebase/util': 1.15.3 tslib: 2.8.1 optionalDependencies: - '@firebase/app': 0.16.2 - '@firebase/app-compat': 0.5.18 + '@firebase/app': 0.16.3 + '@firebase/app-compat': 0.5.19 '@firebase/database-types@1.0.22': dependencies: @@ -10072,12 +10024,12 @@ snapshots: faye-websocket: 0.11.4 tslib: 2.8.1 - '@firebase/firestore-compat@0.4.14(@firebase/app-compat@0.5.18)(@firebase/app-types@0.9.6)(@firebase/app@0.16.2)': + '@firebase/firestore-compat@0.4.15(@firebase/app-compat@0.5.19)(@firebase/app-types@0.9.6)(@firebase/app@0.16.3)': dependencies: - '@firebase/app': 0.16.2 - '@firebase/app-compat': 0.5.18 + '@firebase/app': 0.16.3 + '@firebase/app-compat': 0.5.19 '@firebase/component': 0.7.5 - '@firebase/firestore': 4.17.2(@firebase/app@0.16.2) + '@firebase/firestore': 4.18.0(@firebase/app@0.16.3) '@firebase/firestore-types': 3.0.5(@firebase/app-types@0.9.6)(@firebase/util@1.15.3) '@firebase/util': 1.15.3 tslib: 2.8.1 @@ -10089,9 +10041,9 @@ snapshots: '@firebase/app-types': 0.9.6 '@firebase/util': 1.15.3 - '@firebase/firestore@4.17.2(@firebase/app@0.16.2)': + '@firebase/firestore@4.18.0(@firebase/app@0.16.3)': dependencies: - '@firebase/app': 0.16.2 + '@firebase/app': 0.16.3 '@firebase/component': 0.7.5 '@firebase/logger': 0.5.2 '@firebase/util': 1.15.3 @@ -10101,21 +10053,21 @@ snapshots: re2js: 2.8.6 tslib: 2.8.1 - '@firebase/functions-compat@0.5.0(@firebase/app-compat@0.5.18)(@firebase/app@0.16.2)': + '@firebase/functions-compat@0.5.0(@firebase/app-compat@0.5.19)(@firebase/app@0.16.3)': dependencies: - '@firebase/app': 0.16.2 - '@firebase/app-compat': 0.5.18 + '@firebase/app': 0.16.3 + '@firebase/app-compat': 0.5.19 '@firebase/component': 0.7.5 - '@firebase/functions': 0.14.0(@firebase/app@0.16.2) + '@firebase/functions': 0.14.0(@firebase/app@0.16.3) '@firebase/functions-types': 0.6.5 '@firebase/util': 1.15.3 tslib: 2.8.1 '@firebase/functions-types@0.6.5': {} - '@firebase/functions@0.14.0(@firebase/app@0.16.2)': + '@firebase/functions@0.14.0(@firebase/app@0.16.3)': dependencies: - '@firebase/app': 0.16.2 + '@firebase/app': 0.16.3 '@firebase/app-check-interop-types': 0.3.5 '@firebase/auth-interop-types': 0.2.6 '@firebase/component': 0.7.5 @@ -10123,12 +10075,12 @@ snapshots: '@firebase/util': 1.15.3 tslib: 2.8.1 - '@firebase/installations-compat@0.2.24(@firebase/app-compat@0.5.18)(@firebase/app-types@0.9.6)(@firebase/app@0.16.2)': + '@firebase/installations-compat@0.2.24(@firebase/app-compat@0.5.19)(@firebase/app-types@0.9.6)(@firebase/app@0.16.3)': dependencies: - '@firebase/app': 0.16.2 - '@firebase/app-compat': 0.5.18 + '@firebase/app': 0.16.3 + '@firebase/app-compat': 0.5.19 '@firebase/component': 0.7.5 - '@firebase/installations': 0.6.24(@firebase/app@0.16.2) + '@firebase/installations': 0.6.24(@firebase/app@0.16.3) '@firebase/installations-types': 0.5.5(@firebase/app-types@0.9.6) '@firebase/util': 1.15.3 tslib: 2.8.1 @@ -10139,9 +10091,9 @@ snapshots: dependencies: '@firebase/app-types': 0.9.6 - '@firebase/installations@0.6.24(@firebase/app@0.16.2)': + '@firebase/installations@0.6.24(@firebase/app@0.16.3)': dependencies: - '@firebase/app': 0.16.2 + '@firebase/app': 0.16.3 '@firebase/component': 0.7.5 '@firebase/util': 1.15.3 idb: 7.1.1 @@ -10151,78 +10103,78 @@ snapshots: dependencies: tslib: 2.8.1 - '@firebase/messaging-compat@0.2.30(@firebase/app-compat@0.5.18)(@firebase/app@0.16.2)': + '@firebase/messaging-compat@0.2.30(@firebase/app-compat@0.5.19)(@firebase/app@0.16.3)': dependencies: - '@firebase/app': 0.16.2 - '@firebase/app-compat': 0.5.18 + '@firebase/app': 0.16.3 + '@firebase/app-compat': 0.5.19 '@firebase/component': 0.7.5 - '@firebase/messaging': 0.13.3(@firebase/app@0.16.2) + '@firebase/messaging': 0.13.3(@firebase/app@0.16.3) '@firebase/util': 1.15.3 tslib: 2.8.1 '@firebase/messaging-interop-types@0.2.6': {} - '@firebase/messaging@0.13.3(@firebase/app@0.16.2)': + '@firebase/messaging@0.13.3(@firebase/app@0.16.3)': dependencies: - '@firebase/app': 0.16.2 + '@firebase/app': 0.16.3 '@firebase/component': 0.7.5 - '@firebase/installations': 0.6.24(@firebase/app@0.16.2) + '@firebase/installations': 0.6.24(@firebase/app@0.16.3) '@firebase/messaging-interop-types': 0.2.6 '@firebase/util': 1.15.3 idb: 7.1.1 tslib: 2.8.1 - '@firebase/performance-compat@0.2.27(@firebase/app-compat@0.5.18)(@firebase/app@0.16.2)': + '@firebase/performance-compat@0.2.27(@firebase/app-compat@0.5.19)(@firebase/app@0.16.3)': dependencies: - '@firebase/app': 0.16.2 - '@firebase/app-compat': 0.5.18 + '@firebase/app': 0.16.3 + '@firebase/app-compat': 0.5.19 '@firebase/component': 0.7.5 '@firebase/logger': 0.5.2 - '@firebase/performance': 0.7.14(@firebase/app@0.16.2) + '@firebase/performance': 0.7.14(@firebase/app@0.16.3) '@firebase/performance-types': 0.2.5 '@firebase/util': 1.15.3 tslib: 2.8.1 '@firebase/performance-types@0.2.5': {} - '@firebase/performance@0.7.14(@firebase/app@0.16.2)': + '@firebase/performance@0.7.14(@firebase/app@0.16.3)': dependencies: - '@firebase/app': 0.16.2 + '@firebase/app': 0.16.3 '@firebase/component': 0.7.5 - '@firebase/installations': 0.6.24(@firebase/app@0.16.2) + '@firebase/installations': 0.6.24(@firebase/app@0.16.3) '@firebase/logger': 0.5.2 '@firebase/util': 1.15.3 tslib: 2.8.1 web-vitals: 4.2.4 - '@firebase/remote-config-compat@0.2.29(@firebase/app-compat@0.5.18)(@firebase/app@0.16.2)': + '@firebase/remote-config-compat@0.2.30(@firebase/app-compat@0.5.19)(@firebase/app@0.16.3)': dependencies: - '@firebase/app': 0.16.2 - '@firebase/app-compat': 0.5.18 + '@firebase/app': 0.16.3 + '@firebase/app-compat': 0.5.19 '@firebase/component': 0.7.5 '@firebase/logger': 0.5.2 - '@firebase/remote-config': 0.9.2(@firebase/app@0.16.2) + '@firebase/remote-config': 0.9.3(@firebase/app@0.16.3) '@firebase/remote-config-types': 0.5.2 '@firebase/util': 1.15.3 tslib: 2.8.1 '@firebase/remote-config-types@0.5.2': {} - '@firebase/remote-config@0.9.2(@firebase/app@0.16.2)': + '@firebase/remote-config@0.9.3(@firebase/app@0.16.3)': dependencies: - '@firebase/app': 0.16.2 + '@firebase/app': 0.16.3 '@firebase/component': 0.7.5 - '@firebase/installations': 0.6.24(@firebase/app@0.16.2) + '@firebase/installations': 0.6.24(@firebase/app@0.16.3) '@firebase/logger': 0.5.2 '@firebase/util': 1.15.3 tslib: 2.8.1 - '@firebase/storage-compat@0.4.5(@firebase/app-compat@0.5.18)(@firebase/app-types@0.9.6)(@firebase/app@0.16.2)': + '@firebase/storage-compat@0.4.6(@firebase/app-compat@0.5.19)(@firebase/app-types@0.9.6)(@firebase/app@0.16.3)': dependencies: - '@firebase/app': 0.16.2 - '@firebase/app-compat': 0.5.18 + '@firebase/app': 0.16.3 + '@firebase/app-compat': 0.5.19 '@firebase/component': 0.7.5 - '@firebase/storage': 0.14.5(@firebase/app@0.16.2) + '@firebase/storage': 0.14.6(@firebase/app@0.16.3) '@firebase/storage-types': 0.8.5(@firebase/app-types@0.9.6)(@firebase/util@1.15.3) '@firebase/util': 1.15.3 tslib: 2.8.1 @@ -10234,9 +10186,9 @@ snapshots: '@firebase/app-types': 0.9.6 '@firebase/util': 1.15.3 - '@firebase/storage@0.14.5(@firebase/app@0.16.2)': + '@firebase/storage@0.14.6(@firebase/app@0.16.3)': dependencies: - '@firebase/app': 0.16.2 + '@firebase/app': 0.16.3 '@firebase/component': 0.7.5 '@firebase/util': 1.15.3 tslib: 2.8.1 @@ -10308,7 +10260,7 @@ snapshots: transitivePeerDependencies: - supports-color - '@google/genai@2.25.0(bufferutil@4.1.0)(supports-color@11.0.0)(utf-8-validate@6.0.6)': + '@google/genai@2.28.0(bufferutil@4.1.0)(supports-color@11.0.0)(utf-8-validate@6.0.6)': dependencies: google-auth-library: 10.9.1(supports-color@11.0.0) p-retry: 4.6.2 @@ -10373,21 +10325,14 @@ snapshots: optionalDependencies: '@types/node': 22.20.5 - '@inquirer/checkbox@5.2.6(@types/node@24.19.0)': + '@inquirer/checkbox@5.2.6(@types/node@24.19.1)': dependencies: '@inquirer/ansi': 2.0.9 - '@inquirer/core': 12.0.4(@types/node@24.19.0) + '@inquirer/core': 12.0.4(@types/node@24.19.1) '@inquirer/figures': 2.0.9 - '@inquirer/type': 4.2.0(@types/node@24.19.0) - optionalDependencies: - '@types/node': 24.19.0 - - '@inquirer/confirm@6.3.2(@types/node@24.19.0)': - dependencies: - '@inquirer/core': 12.0.4(@types/node@24.19.0) - '@inquirer/type': 4.1.1(@types/node@24.19.0) + '@inquirer/type': 4.2.0(@types/node@24.19.1) optionalDependencies: - '@types/node': 24.19.0 + '@types/node': 24.19.1 '@inquirer/confirm@6.3.3(@types/node@22.20.5)': dependencies: @@ -10396,6 +10341,13 @@ snapshots: optionalDependencies: '@types/node': 22.20.5 + '@inquirer/confirm@6.3.3(@types/node@24.19.1)': + dependencies: + '@inquirer/core': 12.0.4(@types/node@24.19.1) + '@inquirer/type': 4.2.0(@types/node@24.19.1) + optionalDependencies: + '@types/node': 24.19.1 + '@inquirer/core@12.0.4(@types/node@22.20.5)': dependencies: '@inquirer/ansi': 2.0.9 @@ -10408,17 +10360,17 @@ snapshots: optionalDependencies: '@types/node': 22.20.5 - '@inquirer/core@12.0.4(@types/node@24.19.0)': + '@inquirer/core@12.0.4(@types/node@24.19.1)': dependencies: '@inquirer/ansi': 2.0.9 '@inquirer/figures': 2.0.9 - '@inquirer/type': 4.2.0(@types/node@24.19.0) + '@inquirer/type': 4.2.0(@types/node@24.19.1) cli-width: 4.1.0 fast-wrap-ansi: 0.2.2 mute-stream: 3.0.0 signal-exit: 4.1.0 optionalDependencies: - '@types/node': 24.19.0 + '@types/node': 24.19.1 '@inquirer/editor@5.3.4(@types/node@22.20.5)': dependencies: @@ -10428,13 +10380,13 @@ snapshots: optionalDependencies: '@types/node': 22.20.5 - '@inquirer/editor@5.3.4(@types/node@24.19.0)': + '@inquirer/editor@5.3.4(@types/node@24.19.1)': dependencies: - '@inquirer/core': 12.0.4(@types/node@24.19.0) - '@inquirer/external-editor': 3.0.6(@types/node@24.19.0) - '@inquirer/type': 4.2.0(@types/node@24.19.0) + '@inquirer/core': 12.0.4(@types/node@24.19.1) + '@inquirer/external-editor': 3.0.6(@types/node@24.19.1) + '@inquirer/type': 4.2.0(@types/node@24.19.1) optionalDependencies: - '@types/node': 24.19.0 + '@types/node': 24.19.1 '@inquirer/expand@5.1.6(@types/node@22.20.5)': dependencies: @@ -10443,12 +10395,12 @@ snapshots: optionalDependencies: '@types/node': 22.20.5 - '@inquirer/expand@5.1.6(@types/node@24.19.0)': + '@inquirer/expand@5.1.6(@types/node@24.19.1)': dependencies: - '@inquirer/core': 12.0.4(@types/node@24.19.0) - '@inquirer/type': 4.2.0(@types/node@24.19.0) + '@inquirer/core': 12.0.4(@types/node@24.19.1) + '@inquirer/type': 4.2.0(@types/node@24.19.1) optionalDependencies: - '@types/node': 24.19.0 + '@types/node': 24.19.1 '@inquirer/external-editor@3.0.6(@types/node@22.20.5)': dependencies: @@ -10457,12 +10409,12 @@ snapshots: optionalDependencies: '@types/node': 22.20.5 - '@inquirer/external-editor@3.0.6(@types/node@24.19.0)': + '@inquirer/external-editor@3.0.6(@types/node@24.19.1)': dependencies: chardet: 2.2.0 iconv-lite: 0.7.3 optionalDependencies: - '@types/node': 24.19.0 + '@types/node': 24.19.1 '@inquirer/figures@2.0.9': {} @@ -10473,12 +10425,12 @@ snapshots: optionalDependencies: '@types/node': 22.20.5 - '@inquirer/input@5.1.7(@types/node@24.19.0)': + '@inquirer/input@5.1.7(@types/node@24.19.1)': dependencies: - '@inquirer/core': 12.0.4(@types/node@24.19.0) - '@inquirer/type': 4.2.0(@types/node@24.19.0) + '@inquirer/core': 12.0.4(@types/node@24.19.1) + '@inquirer/type': 4.2.0(@types/node@24.19.1) optionalDependencies: - '@types/node': 24.19.0 + '@types/node': 24.19.1 '@inquirer/number@4.2.4(@types/node@22.20.5)': dependencies: @@ -10487,12 +10439,12 @@ snapshots: optionalDependencies: '@types/node': 22.20.5 - '@inquirer/number@4.2.4(@types/node@24.19.0)': + '@inquirer/number@4.2.4(@types/node@24.19.1)': dependencies: - '@inquirer/core': 12.0.4(@types/node@24.19.0) - '@inquirer/type': 4.2.0(@types/node@24.19.0) + '@inquirer/core': 12.0.4(@types/node@24.19.1) + '@inquirer/type': 4.2.0(@types/node@24.19.1) optionalDependencies: - '@types/node': 24.19.0 + '@types/node': 24.19.1 '@inquirer/password@5.2.3(@types/node@22.20.5)': dependencies: @@ -10502,28 +10454,13 @@ snapshots: optionalDependencies: '@types/node': 22.20.5 - '@inquirer/password@5.2.3(@types/node@24.19.0)': + '@inquirer/password@5.2.3(@types/node@24.19.1)': dependencies: '@inquirer/ansi': 2.0.9 - '@inquirer/core': 12.0.4(@types/node@24.19.0) - '@inquirer/type': 4.2.0(@types/node@24.19.0) + '@inquirer/core': 12.0.4(@types/node@24.19.1) + '@inquirer/type': 4.2.0(@types/node@24.19.1) optionalDependencies: - '@types/node': 24.19.0 - - '@inquirer/prompts@8.7.2(@types/node@24.19.0)': - dependencies: - '@inquirer/checkbox': 5.2.6(@types/node@24.19.0) - '@inquirer/confirm': 6.3.2(@types/node@24.19.0) - '@inquirer/editor': 5.3.4(@types/node@24.19.0) - '@inquirer/expand': 5.1.6(@types/node@24.19.0) - '@inquirer/input': 5.1.7(@types/node@24.19.0) - '@inquirer/number': 4.2.4(@types/node@24.19.0) - '@inquirer/password': 5.2.3(@types/node@24.19.0) - '@inquirer/rawlist': 5.3.6(@types/node@24.19.0) - '@inquirer/search': 4.3.4(@types/node@24.19.0) - '@inquirer/select': 5.2.6(@types/node@24.19.0) - optionalDependencies: - '@types/node': 24.19.0 + '@types/node': 24.19.1 '@inquirer/prompts@8.7.3(@types/node@22.20.5)': dependencies: @@ -10540,6 +10477,21 @@ snapshots: optionalDependencies: '@types/node': 22.20.5 + '@inquirer/prompts@8.7.3(@types/node@24.19.1)': + dependencies: + '@inquirer/checkbox': 5.2.6(@types/node@24.19.1) + '@inquirer/confirm': 6.3.3(@types/node@24.19.1) + '@inquirer/editor': 5.3.4(@types/node@24.19.1) + '@inquirer/expand': 5.1.6(@types/node@24.19.1) + '@inquirer/input': 5.1.7(@types/node@24.19.1) + '@inquirer/number': 4.2.4(@types/node@24.19.1) + '@inquirer/password': 5.2.3(@types/node@24.19.1) + '@inquirer/rawlist': 5.3.6(@types/node@24.19.1) + '@inquirer/search': 4.3.4(@types/node@24.19.1) + '@inquirer/select': 5.2.6(@types/node@24.19.1) + optionalDependencies: + '@types/node': 24.19.1 + '@inquirer/rawlist@5.3.6(@types/node@22.20.5)': dependencies: '@inquirer/core': 12.0.4(@types/node@22.20.5) @@ -10547,12 +10499,12 @@ snapshots: optionalDependencies: '@types/node': 22.20.5 - '@inquirer/rawlist@5.3.6(@types/node@24.19.0)': + '@inquirer/rawlist@5.3.6(@types/node@24.19.1)': dependencies: - '@inquirer/core': 12.0.4(@types/node@24.19.0) - '@inquirer/type': 4.2.0(@types/node@24.19.0) + '@inquirer/core': 12.0.4(@types/node@24.19.1) + '@inquirer/type': 4.2.0(@types/node@24.19.1) optionalDependencies: - '@types/node': 24.19.0 + '@types/node': 24.19.1 '@inquirer/search@4.3.4(@types/node@22.20.5)': dependencies: @@ -10562,13 +10514,13 @@ snapshots: optionalDependencies: '@types/node': 22.20.5 - '@inquirer/search@4.3.4(@types/node@24.19.0)': + '@inquirer/search@4.3.4(@types/node@24.19.1)': dependencies: - '@inquirer/core': 12.0.4(@types/node@24.19.0) + '@inquirer/core': 12.0.4(@types/node@24.19.1) '@inquirer/figures': 2.0.9 - '@inquirer/type': 4.2.0(@types/node@24.19.0) + '@inquirer/type': 4.2.0(@types/node@24.19.1) optionalDependencies: - '@types/node': 24.19.0 + '@types/node': 24.19.1 '@inquirer/select@5.2.6(@types/node@22.20.5)': dependencies: @@ -10579,26 +10531,22 @@ snapshots: optionalDependencies: '@types/node': 22.20.5 - '@inquirer/select@5.2.6(@types/node@24.19.0)': + '@inquirer/select@5.2.6(@types/node@24.19.1)': dependencies: '@inquirer/ansi': 2.0.9 - '@inquirer/core': 12.0.4(@types/node@24.19.0) + '@inquirer/core': 12.0.4(@types/node@24.19.1) '@inquirer/figures': 2.0.9 - '@inquirer/type': 4.2.0(@types/node@24.19.0) + '@inquirer/type': 4.2.0(@types/node@24.19.1) optionalDependencies: - '@types/node': 24.19.0 - - '@inquirer/type@4.1.1(@types/node@24.19.0)': - optionalDependencies: - '@types/node': 24.19.0 + '@types/node': 24.19.1 '@inquirer/type@4.2.0(@types/node@22.20.5)': optionalDependencies: '@types/node': 22.20.5 - '@inquirer/type@4.2.0(@types/node@24.19.0)': + '@inquirer/type@4.2.0(@types/node@24.19.1)': optionalDependencies: - '@types/node': 24.19.0 + '@types/node': 24.19.1 '@isaacs/cliui@8.0.2': dependencies: @@ -10838,14 +10786,16 @@ snapshots: '@msgpackr-extract/msgpackr-extract-win32-x64@3.0.4': optional: true - '@mswjs/interceptors@0.41.9': + '@mswjs/interceptors@0.44.0(supports-color@11.0.0)': dependencies: - '@open-draft/deferred-promise': 2.2.0 - '@open-draft/logger': 0.3.0 - '@open-draft/until': 2.1.0 + '@open-draft/until': 3.0.1 + '@types/debug': 4.1.13 + debug: 4.4.3(supports-color@11.0.0) is-node-process: 1.2.0 outvariant: 1.4.3 - strict-event-emitter: 0.5.1 + rettime: 0.11.12 + transitivePeerDependencies: + - supports-color '@napi-rs/lzma-linux-x64-gnu@1.5.1': optional: true @@ -11018,11 +10968,6 @@ snapshots: '@octokit/core': 7.0.8 '@octokit/types': 16.0.0 - '@octokit/plugin-paginate-rest@15.0.0(@octokit/core@7.0.8)': - dependencies: - '@octokit/core': 7.0.8 - '@octokit/types': 17.0.0 - '@octokit/plugin-request-log@6.0.0(@octokit/core@7.0.8)': dependencies: '@octokit/core': 7.0.8 @@ -11069,14 +11014,7 @@ snapshots: dependencies: '@octokit/openapi-types': 29.0.1 - '@open-draft/deferred-promise@2.2.0': {} - - '@open-draft/logger@0.3.0': - dependencies: - is-node-process: 1.2.0 - outvariant: 1.4.3 - - '@open-draft/until@2.1.0': {} + '@open-draft/until@3.0.1': {} '@opentelemetry/api@1.9.1': {} @@ -11635,6 +11573,10 @@ snapshots: dependencies: '@types/node': 22.20.5 + '@types/debug@4.1.13': + dependencies: + '@types/ms': 2.1.0 + '@types/deep-eql@4.0.2': {} '@types/duplexify@3.6.5': @@ -11724,11 +11666,13 @@ snapshots: dependencies: '@types/parse-glob': 3.0.32 + '@types/ms@2.1.0': {} + '@types/node@22.20.5': dependencies: undici-types: 6.21.0 - '@types/node@24.19.0': + '@types/node@24.19.1': dependencies: undici-types: 7.24.6 @@ -12904,7 +12848,7 @@ snapshots: conventional-commits-filter@6.0.1: {} - conventional-commits-parser@7.1.2: + conventional-commits-parser@7.1.3: dependencies: '@simple-libs/stream-utils': 2.0.0 argue-cli: 3.2.0 @@ -13039,12 +12983,6 @@ snapshots: optionalDependencies: supports-color: 11.0.0 - debug@4.4.0(supports-color@11.0.0): - dependencies: - ms: 2.1.3 - optionalDependencies: - supports-color: 11.0.0 - debug@4.4.3(supports-color@11.0.0): dependencies: ms: 2.1.3 @@ -13732,35 +13670,35 @@ snapshots: locate-path: 6.0.0 path-exists: 4.0.0 - firebase@12.19.0: + firebase@13.0.0: dependencies: - '@firebase/ai': 2.16.0(@firebase/app-types@0.9.6)(@firebase/app@0.16.2) - '@firebase/analytics': 0.10.25(@firebase/app@0.16.2) - '@firebase/analytics-compat': 0.2.31(@firebase/app-compat@0.5.18)(@firebase/app@0.16.2) - '@firebase/app': 0.16.2 - '@firebase/app-check': 0.13.1(@firebase/app@0.16.2) - '@firebase/app-check-compat': 0.4.7(@firebase/app-compat@0.5.18)(@firebase/app@0.16.2) - '@firebase/app-compat': 0.5.18 + '@firebase/ai': 3.0.0(@firebase/app-types@0.9.6)(@firebase/app@0.16.3) + '@firebase/analytics': 0.10.25(@firebase/app@0.16.3) + '@firebase/analytics-compat': 0.2.31(@firebase/app-compat@0.5.19)(@firebase/app@0.16.3) + '@firebase/app': 0.16.3 + '@firebase/app-check': 0.13.1(@firebase/app@0.16.3) + '@firebase/app-check-compat': 0.4.7(@firebase/app-compat@0.5.19)(@firebase/app@0.16.3) + '@firebase/app-compat': 0.5.19 '@firebase/app-types': 0.9.6 - '@firebase/auth': 1.13.6(@firebase/app@0.16.2) - '@firebase/auth-compat': 0.6.11(@firebase/app-compat@0.5.18)(@firebase/app-types@0.9.6)(@firebase/app@0.16.2) - '@firebase/data-connect': 0.7.4(@firebase/app@0.16.2) + '@firebase/auth': 1.13.7(@firebase/app@0.16.3) + '@firebase/auth-compat': 0.6.12(@firebase/app-compat@0.5.19)(@firebase/app-types@0.9.6)(@firebase/app@0.16.3) + '@firebase/data-connect': 0.7.4(@firebase/app@0.16.3) '@firebase/database': 1.1.5 - '@firebase/database-compat': 2.1.7(@firebase/app-compat@0.5.18)(@firebase/app@0.16.2) - '@firebase/firestore': 4.17.2(@firebase/app@0.16.2) - '@firebase/firestore-compat': 0.4.14(@firebase/app-compat@0.5.18)(@firebase/app-types@0.9.6)(@firebase/app@0.16.2) - '@firebase/functions': 0.14.0(@firebase/app@0.16.2) - '@firebase/functions-compat': 0.5.0(@firebase/app-compat@0.5.18)(@firebase/app@0.16.2) - '@firebase/installations': 0.6.24(@firebase/app@0.16.2) - '@firebase/installations-compat': 0.2.24(@firebase/app-compat@0.5.18)(@firebase/app-types@0.9.6)(@firebase/app@0.16.2) - '@firebase/messaging': 0.13.3(@firebase/app@0.16.2) - '@firebase/messaging-compat': 0.2.30(@firebase/app-compat@0.5.18)(@firebase/app@0.16.2) - '@firebase/performance': 0.7.14(@firebase/app@0.16.2) - '@firebase/performance-compat': 0.2.27(@firebase/app-compat@0.5.18)(@firebase/app@0.16.2) - '@firebase/remote-config': 0.9.2(@firebase/app@0.16.2) - '@firebase/remote-config-compat': 0.2.29(@firebase/app-compat@0.5.18)(@firebase/app@0.16.2) - '@firebase/storage': 0.14.5(@firebase/app@0.16.2) - '@firebase/storage-compat': 0.4.5(@firebase/app-compat@0.5.18)(@firebase/app-types@0.9.6)(@firebase/app@0.16.2) + '@firebase/database-compat': 2.1.7(@firebase/app-compat@0.5.19)(@firebase/app@0.16.3) + '@firebase/firestore': 4.18.0(@firebase/app@0.16.3) + '@firebase/firestore-compat': 0.4.15(@firebase/app-compat@0.5.19)(@firebase/app-types@0.9.6)(@firebase/app@0.16.3) + '@firebase/functions': 0.14.0(@firebase/app@0.16.3) + '@firebase/functions-compat': 0.5.0(@firebase/app-compat@0.5.19)(@firebase/app@0.16.3) + '@firebase/installations': 0.6.24(@firebase/app@0.16.3) + '@firebase/installations-compat': 0.2.24(@firebase/app-compat@0.5.19)(@firebase/app-types@0.9.6)(@firebase/app@0.16.3) + '@firebase/messaging': 0.13.3(@firebase/app@0.16.3) + '@firebase/messaging-compat': 0.2.30(@firebase/app-compat@0.5.19)(@firebase/app@0.16.3) + '@firebase/performance': 0.7.14(@firebase/app@0.16.3) + '@firebase/performance-compat': 0.2.27(@firebase/app-compat@0.5.19)(@firebase/app@0.16.3) + '@firebase/remote-config': 0.9.3(@firebase/app@0.16.3) + '@firebase/remote-config-compat': 0.2.30(@firebase/app-compat@0.5.19)(@firebase/app@0.16.3) + '@firebase/storage': 0.14.6(@firebase/app@0.16.3) + '@firebase/storage-compat': 0.4.6(@firebase/app-compat@0.5.19)(@firebase/app-types@0.9.6)(@firebase/app@0.16.3) '@firebase/util': 1.15.3 transitivePeerDependencies: - '@react-native-async-storage/async-storage' @@ -13777,9 +13715,9 @@ snapshots: flru@1.0.2: {} - folder-hash@4.1.3(supports-color@11.0.0): + folder-hash@4.1.4(supports-color@11.0.0): dependencies: - debug: 4.4.0(supports-color@11.0.0) + debug: 4.4.3(supports-color@11.0.0) minimatch: 7.4.9 transitivePeerDependencies: - supports-color @@ -15183,11 +15121,11 @@ snapshots: - supports-color - vue-tsc - nock@14.0.17: + nock@15.0.1(supports-color@11.0.0): dependencies: - '@mswjs/interceptors': 0.41.9 - json-stringify-safe: 5.0.1 - propagate: 2.0.1 + '@mswjs/interceptors': 0.44.0(supports-color@11.0.0) + transitivePeerDependencies: + - supports-color node-addon-api@6.1.0: optional: true @@ -15610,8 +15548,6 @@ snapshots: process@0.11.10: {} - propagate@2.0.1: {} - proto3-json-serializer@3.0.4: dependencies: protobufjs: 7.6.6 @@ -15888,6 +15824,8 @@ snapshots: retry@0.13.1: {} + rettime@0.11.12: {} + reusify@1.1.0: {} rfdc@1.4.1: {} @@ -16484,8 +16422,6 @@ snapshots: - bare-abort-controller - react-native-b4a - strict-event-emitter@0.5.1: {} - string-width@4.2.3: dependencies: emoji-regex: 8.0.0 diff --git a/tests/e2e/ng-snapshot/package.json b/tests/e2e/ng-snapshot/package.json index a3e554ca1640..7bf474571ca6 100644 --- a/tests/e2e/ng-snapshot/package.json +++ b/tests/e2e/ng-snapshot/package.json @@ -2,21 +2,21 @@ "description": "snapshot versions of Angular for e2e testing", "private": true, "dependencies": { - "@angular/animations": "github:angular/animations-builds#3ec405d1cb11a6f18eacdd7e09378cd097a9a427", - "@angular/cdk": "github:angular/cdk-builds#8eedcdb798ec78b2c0191953b46804f54296ed4f", - "@angular/common": "github:angular/common-builds#bae1a4226a83f02bcb77b6ef447e039d8b5081f3", - "@angular/compiler": "github:angular/compiler-builds#fc8fced0b21574f7846b999a751511f9a453e0cd", - "@angular/compiler-cli": "github:angular/compiler-cli-builds#20b42c8d2e12f28eea2376ff0b0f1f5ec59cac63", - "@angular/core": "github:angular/core-builds#080d86fc456c2029952d72e43ae5e019374a3546", - "@angular/forms": "github:angular/forms-builds#b8ff96856639a22bb3dec5c8bebb562c5395c638", - "@angular/language-service": "github:angular/language-service-builds#9e0a5e50a0f37d5671fc2478ebf2626399fb23f4", - "@angular/localize": "github:angular/localize-builds#fec5dc5c69698fbf47aa794ac8fd80a2baa9b1d5", - "@angular/material": "github:angular/material-builds#72d50c0fd59ea4d1f7fc2053d74d4f2610503730", - "@angular/material-moment-adapter": "github:angular/material-moment-adapter-builds#30012ad773e0536aa4e5ff009c1b65ec8bb1e5f2", - "@angular/platform-browser": "github:angular/platform-browser-builds#ca08a1a24ac892344fb1f69c6f5ac15eb504370b", - "@angular/platform-browser-dynamic": "github:angular/platform-browser-dynamic-builds#163f8f1af3365efeab12b2656ad229a8d76e39b9", - "@angular/platform-server": "github:angular/platform-server-builds#fe61afa721e53041b0bac92f0241a82326d72a47", - "@angular/router": "github:angular/router-builds#7df611a733d4a35d41fd4b5596e0a9800cc67e8e", - "@angular/service-worker": "github:angular/service-worker-builds#3ef11b4fbbd965535f0f45de2ba41a4e3886b918" + "@angular/animations": "github:angular/animations-builds#49e5662e0f5a6a052d8b66bd639ce261b231c807", + "@angular/cdk": "github:angular/cdk-builds#8aa05501715c9b9b0fc95625f52b3b536c35cc4a", + "@angular/common": "github:angular/common-builds#e75bc632bb0f4c992336add2cd9429a5fc580165", + "@angular/compiler": "github:angular/compiler-builds#12aa4df6f3b1bc8402d329301391ab4f52179111", + "@angular/compiler-cli": "github:angular/compiler-cli-builds#051fd3767d2922649e6630cdbd4d726e99900949", + "@angular/core": "github:angular/core-builds#7b84cd24ec45174b8cc0a42e821a98b1a0d330eb", + "@angular/forms": "github:angular/forms-builds#fea1091472626b0c62c1300a4822216a55092cf6", + "@angular/language-service": "github:angular/language-service-builds#60d0bc6afa8bba745ba051afb88a8ccc6d72f61d", + "@angular/localize": "github:angular/localize-builds#5f21029e84cf4fab2902818b5351a9b131cef532", + "@angular/material": "github:angular/material-builds#5f4d7a4724a306e1e24d55f53564eebfa22dbdd4", + "@angular/material-moment-adapter": "github:angular/material-moment-adapter-builds#a600a485f5c91b376684763cbf00b158f85502f0", + "@angular/platform-browser": "github:angular/platform-browser-builds#69be31f21a8df04fd8157676b7d885c94de8bdc6", + "@angular/platform-browser-dynamic": "github:angular/platform-browser-dynamic-builds#f8c0d0c407dd393e8f49593039ae2100f4504e11", + "@angular/platform-server": "github:angular/platform-server-builds#8e9d51d325c6575b54e118410281b6ffb2bd76a9", + "@angular/router": "github:angular/router-builds#42ae1c53acc2bcf444ef4d4d3e84ccdda61486db", + "@angular/service-worker": "github:angular/service-worker-builds#5ac1b5c6526c04ac8d1ba1e74f22f9998020eaf7" } } From 47c328d3ef7b409af02f270a48f5e99a520fbe14 Mon Sep 17 00:00:00 2001 From: Alan Agius Date: Mon, 12 Oct 2026 22:45:00 +0200 Subject: [PATCH 594/787] fix(@angular/build): ensure Sass importers return global Promise instances `sass-embedded` checks whether an importer's `canonicalize` or `findFileUrl` method returned a promise using `result instanceof Promise`. When SSR executes in the same process during `ng serve` for an application using Zone.js, `zone.js/node` replaces `globalThis.Promise` with `ZoneAwarePromise`. Because native V8 `async` functions always return instances of the intrinsic V8 `%Promise%` rather than `globalThis.Promise`, `result instanceof Promise` evaluates to `false` and `sass-embedded` treats the returned Promise as a synchronous URL value (`"[object Promise]"` / `"%5Bobject%20Promise%5D"`). --- .../esbuild/stylesheets/sass-language_spec.ts | 64 +++++++++++++++++++ .../build/src/tools/sass/rebasing-importer.ts | 12 ++-- 2 files changed, 72 insertions(+), 4 deletions(-) diff --git a/packages/angular/build/src/tools/esbuild/stylesheets/sass-language_spec.ts b/packages/angular/build/src/tools/esbuild/stylesheets/sass-language_spec.ts index cdd4d7e7c8db..216a2d18fc47 100644 --- a/packages/angular/build/src/tools/esbuild/stylesheets/sass-language_spec.ts +++ b/packages/angular/build/src/tools/esbuild/stylesheets/sass-language_spec.ts @@ -286,5 +286,69 @@ describe('sass-language', () => { pathToFileURL(join(projectRoot, 'node_modules', 'theme', '_index.scss')).href, ); }); + + it('should resolve imports when globalThis.Promise is replaced (e.g., by Zone.js)', async () => { + const originalPromise = globalThis.Promise; + + // Simulate Zone.js replacing globalThis.Promise with a constructor where + // native V8 async function return values fail `instanceof globalThis.Promise`. + class ZoneLikePromise { + #inner: Promise; + + constructor( + executor: ( + resolve: (value: T | PromiseLike) => void, + reject: (reason?: unknown) => void, + ) => void, + ) { + this.#inner = new originalPromise(executor); + } + + then( + onfulfilled?: ((value: T) => TResult1 | PromiseLike) | null, + onrejected?: ((reason: unknown) => TResult2 | PromiseLike) | null, + ): ZoneLikePromise { + return new ZoneLikePromise((resolve, reject) => { + this.#inner.then(onfulfilled, onrejected).then(resolve, reject); + }); + } + + catch( + onrejected?: ((reason: unknown) => TResult | PromiseLike) | null, + ): ZoneLikePromise { + return this.then(undefined, onrejected); + } + + finally(onfinally?: (() => void) | null): ZoneLikePromise { + return new ZoneLikePromise((resolve, reject) => { + this.#inner.finally(onfinally).then(resolve, reject); + }); + } + + static resolve(value?: U | PromiseLike): ZoneLikePromise> { + if (value instanceof ZoneLikePromise) { + return value; + } + + return new ZoneLikePromise((resolve) => resolve(value as Awaited)); + } + + static reject(reason?: unknown): ZoneLikePromise { + return new ZoneLikePromise((_, reject) => reject(reason)); + } + + static all(values: Iterable): ZoneLikePromise { + return ZoneLikePromise.resolve(originalPromise.all(values)); + } + } + + globalThis.Promise = ZoneLikePromise as unknown as PromiseConstructor; + try { + const application = await compile(buttonStylesheet); + expect(application).toContain('content: "project";'); + } finally { + globalThis.Promise = originalPromise; + } + }); }); }); diff --git a/packages/angular/build/src/tools/sass/rebasing-importer.ts b/packages/angular/build/src/tools/sass/rebasing-importer.ts index 7198d8b74f1e..889d26ef567e 100644 --- a/packages/angular/build/src/tools/sass/rebasing-importer.ts +++ b/packages/angular/build/src/tools/sass/rebasing-importer.ts @@ -344,14 +344,18 @@ export class AsyncModuleUrlRebasingImporter implements Importer<'async'> { this.load = this.load.bind(this); } - async canonicalize(url: string, options: CanonicalizeContext): Promise { + canonicalize(url: string, options: CanonicalizeContext): Promise | URL | null { if (url.startsWith('file://')) { return this.relativeImporter.canonicalize(url, options); } - const result = await this.finder(url, options); - - return result ? this.relativeImporter.canonicalize(result.href, options) : null; + // Use `Promise.resolve` instead of an `async` method so the returned promise is an + // instance of the current `globalThis.Promise` (e.g., `ZoneAwarePromise` when Zone.js + // is loaded during SSR). `sass-embedded` checks `result instanceof Promise`, which fails + // for native `async` function return values when `globalThis.Promise` has been replaced. + return Promise.resolve(this.finder(url, options)).then((result) => + result ? this.relativeImporter.canonicalize(result.href, options) : null, + ); } load(canonicalUrl: URL): ImporterResult | null { From 5e0fd4f134967ac879d6f7d34a4b06f69534d0c0 Mon Sep 17 00:00:00 2001 From: Charles Lyding <19598772+clydin@users.noreply.github.com> Date: Mon, 12 Oct 2026 09:14:07 -0400 Subject: [PATCH 595/787] test(@angular/build): verify Vitest fsModuleCache is disabled across test runs Add an integration test to ensure that modifying an imported application module between test runs is reflected even when `fsModuleCache` is explicitly enabled in the Vitest runner configuration, and that the `.vitest-cache` directory is not created. --- .../behavior/runner-config-vitest_spec.ts | 38 +++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/packages/angular/build/src/builders/unit-test/tests/behavior/runner-config-vitest_spec.ts b/packages/angular/build/src/builders/unit-test/tests/behavior/runner-config-vitest_spec.ts index 95107d1baec2..53039adf53e8 100644 --- a/packages/angular/build/src/builders/unit-test/tests/behavior/runner-config-vitest_spec.ts +++ b/packages/angular/build/src/builders/unit-test/tests/behavior/runner-config-vitest_spec.ts @@ -614,5 +614,43 @@ describeBuilder(execute, UNIT_TEST_BUILDER_INFO, (harness) => { const { result } = await harness.executeOnce(); expect(result?.success).toBeTrue(); }); + + it('should not serve stale cached modules across runs when an imported file changes', async () => { + harness.useTarget('test', { + ...BASE_OPTIONS, + runnerConfig: 'vitest.config.mts', + }); + + await harness.writeFiles({ + 'vitest.config.mts': ` + import { defineConfig } from 'vitest/config'; + export default defineConfig({ + test: { + fsModuleCache: true, + fsModuleCachePath: './.vitest-cache', + }, + }); + `, + 'src/app/value.ts': `export const VALUE = 'initial';`, + 'src/app/app.component.spec.ts': ` + import { test, expect } from 'vitest'; + import { VALUE } from './value'; + + test('should use the latest value from imported module', () => { + expect(VALUE).toBe('updated'); + }); + `, + }); + + const firstRun = await harness.executeOnce(); + expect(firstRun.result?.success).toBeFalse(); + + // Update the imported application file without modifying the .spec.ts file on disk + await harness.writeFile('src/app/value.ts', `export const VALUE = 'updated';`); + + const secondRun = await harness.executeOnce(); + expect(secondRun.result?.success).toBeTrue(); + harness.expectDirectory('.vitest-cache').toNotExist(); + }); }); }); From 0306faf9e4f9b1c746672711fe107e2e2f0bd406 Mon Sep 17 00:00:00 2001 From: Charles Lyding <19598772+clydin@users.noreply.github.com> Date: Mon, 12 Oct 2026 09:25:13 -0400 Subject: [PATCH 596/787] test(@angular/build): await file writes in unit-test watch rebuild spec Ensure `harness.writeFiles` calls inside `executeWithCases` callbacks are awaited so file modifications complete before the next watch cycle. --- .../unit-test/tests/behavior/watch_rebuild_spec.ts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/packages/angular/build/src/builders/unit-test/tests/behavior/watch_rebuild_spec.ts b/packages/angular/build/src/builders/unit-test/tests/behavior/watch_rebuild_spec.ts index 6ff753c7eac7..cab5afd48a2c 100644 --- a/packages/angular/build/src/builders/unit-test/tests/behavior/watch_rebuild_spec.ts +++ b/packages/angular/build/src/builders/unit-test/tests/behavior/watch_rebuild_spec.ts @@ -28,11 +28,11 @@ describeBuilder(execute, UNIT_TEST_BUILDER_INFO, (harness) => { await harness.executeWithCases([ // 1. Initial success - ({ result }) => { + async ({ result }) => { expect(result?.success).toBeTrue(); // 2. Introduce compilation error - harness.writeFiles({ + await harness.writeFiles({ 'src/app/app.component.spec.ts': ` import { describe, expect, test } from 'vitest' describe('AppComponent', () => { @@ -44,11 +44,11 @@ describeBuilder(execute, UNIT_TEST_BUILDER_INFO, (harness) => { }); }, // 3. Expect compilation error - ({ result }) => { + async ({ result }) => { expect(result?.success).toBeFalse(); // 4. Fix compilation error BUT introduce test failure - harness.writeFiles({ + await harness.writeFiles({ 'src/app/app.component.spec.ts': ` import { describe, expect, test } from 'vitest' describe('AppComponent', () => { From 39d230e1862f2f626d3fba03bbf51873f3578153 Mon Sep 17 00:00:00 2001 From: Charles Lyding <19598772+clydin@users.noreply.github.com> Date: Mon, 12 Oct 2026 09:37:15 -0400 Subject: [PATCH 597/787] fix(@angular/build): keep Vite server file watcher disabled in Vitest watch mode In Vitest 5, the internal `vitest:config:append` plugin uses a post `configResolved` hook that resets `server.watch` to `{}` when watch mode is enabled (`server.watch ??= {}`), overriding the `server: { watch: null }` setting passed in `vitestServerConfig`. This caused Vite to start a duplicate Chokidar file watcher alongside the Angular CLI build watcher and trigger redundant, racing test reruns on file changes. Enforce `post` ordering on `angular:vitest-configuration` and reset `config.server.watch = null` in a post `configResolved` hook so Vite uses its no-op watcher. --- .../unit-test/runners/vitest/executor.ts | 5 --- .../unit-test/runners/vitest/plugins.ts | 10 ++++++ .../unit-test/tests/options/watch_spec.ts | 33 +++++++++++++++++++ 3 files changed, 43 insertions(+), 5 deletions(-) diff --git a/packages/angular/build/src/builders/unit-test/runners/vitest/executor.ts b/packages/angular/build/src/builders/unit-test/runners/vitest/executor.ts index aa201e24c578..b5c7841c799b 100644 --- a/packages/angular/build/src/builders/unit-test/runners/vitest/executor.ts +++ b/packages/angular/build/src/builders/unit-test/runners/vitest/executor.ts @@ -398,11 +398,6 @@ export class VitestExecutor implements TestExecutor { const vitestServerConfig = { // Note `.vitest` is auto appended to the path. cacheDir: cacheOptions.path, - server: { - // Disable the actual file watcher. The boolean watch option above should still - // be enabled as it controls other internal behavior related to rerunning tests. - watch: null, - }, plugins: [ await createVitestConfigPlugin({ browser: browserOptions.browser, diff --git a/packages/angular/build/src/builders/unit-test/runners/vitest/plugins.ts b/packages/angular/build/src/builders/unit-test/runners/vitest/plugins.ts index ec0cd0a8f269..0a8a2c8990b4 100644 --- a/packages/angular/build/src/builders/unit-test/runners/vitest/plugins.ts +++ b/packages/angular/build/src/builders/unit-test/runners/vitest/plugins.ts @@ -164,6 +164,16 @@ export async function createVitestConfigPlugin( return { name: 'angular:vitest-configuration', + enforce: 'post', + configResolved: { + order: 'post', + handler(config: Vite.ResolvedConfig) { + // Vitest's internal post-configResolved hook resets `server.watch` to `{}` when + // `watch` is enabled (`server.watch ??= {}`). Force it back to `null` so Vite uses + // a no-op watcher and relies solely on the Angular CLI build watcher. + config.server.watch = null; + }, + }, async config(config: UserWorkspaceConfig & Vite.UserConfig) { const testConfig = config.test; diff --git a/packages/angular/build/src/builders/unit-test/tests/options/watch_spec.ts b/packages/angular/build/src/builders/unit-test/tests/options/watch_spec.ts index d1840beb4a96..79e25ca84b27 100644 --- a/packages/angular/build/src/builders/unit-test/tests/options/watch_spec.ts +++ b/packages/angular/build/src/builders/unit-test/tests/options/watch_spec.ts @@ -55,5 +55,38 @@ describeBuilder(execute, UNIT_TEST_BUILDER_INFO, (harness) => { }, ]); }); + + it('should disable the Vite server file watcher when watch is true', async () => { + harness.useTarget('test', { + ...BASE_OPTIONS, + watch: true, + runnerConfig: 'vitest.config.mts', + }); + + await harness.writeFile( + 'vitest.config.mts', + ` + import { defineConfig } from 'vitest/config'; + export default defineConfig({ + plugins: [ + { + name: 'assert-watch-disabled', + configureVitest({ vitest, project }) { + if (vitest.vite.config.server.watch !== null || project.vite.config.server.watch !== null) { + throw new Error('Expected Vite server.watch to be null'); + } + }, + }, + ], + }); + `, + ); + + await harness.executeWithCases([ + ({ result }) => { + expect(result?.success).toBeTrue(); + }, + ]); + }); }); }); From a1cf33bc45882fb74578cc7d1faeba8cecec7b73 Mon Sep 17 00:00:00 2001 From: Alan Agius Date: Tue, 13 Oct 2026 08:00:44 +0200 Subject: [PATCH 598/787] fix(@angular/cli): resolve package name in npm workspace members Read `package.json` in the working directory first in `getCurrentPackageName` to avoid spawning an unnecessary child process, and handle single-entry workspace objects returned by `npm pkg get name` when falling back to the package manager command. --- .../src/package-managers/package-manager.ts | 34 ++++++--- .../package-managers/package-manager_spec.ts | 69 +++++++++++++++++++ 2 files changed, 93 insertions(+), 10 deletions(-) diff --git a/packages/angular/cli/src/package-managers/package-manager.ts b/packages/angular/cli/src/package-managers/package-manager.ts index 234b54851232..272454c21cbd 100644 --- a/packages/angular/cli/src/package-managers/package-manager.ts +++ b/packages/angular/cli/src/package-managers/package-manager.ts @@ -393,25 +393,39 @@ export class PackageManager { * Gets the name of the package in the current project. */ async getCurrentPackageName(): Promise { + try { + const content = await this.host.readFile(join(this.cwd, 'package.json')); + const { name } = JSON.parse(content) as { name?: unknown }; + if (typeof name === 'string') { + return name; + } + } catch { + // Fall back to package manager command if reading file fails + } + if (this.descriptor.getPackageNameCommand) { try { const { stdout } = await this.#run(this.descriptor.getPackageNameCommand); if (stdout) { - return JSON.parse(stdout); + const name = JSON.parse(stdout); + if (typeof name === 'string') { + return name; + } + + // In a workspace member npm prints an object keyed by workspace name instead of a string. + if (name && typeof name === 'object') { + const values = Object.values(name); + if (values.length === 1 && typeof values[0] === 'string') { + return values[0]; + } + } } } catch { - // Fall back to reading file if command fails + // Ignore command failure } } - try { - const content = await this.host.readFile(join(this.cwd, 'package.json')); - const pkgJson = JSON.parse(content); - - return pkgJson.name; - } catch { - return undefined; - } + return undefined; } /** diff --git a/packages/angular/cli/src/package-managers/package-manager_spec.ts b/packages/angular/cli/src/package-managers/package-manager_spec.ts index d500a435d0df..37e0d8aae113 100644 --- a/packages/angular/cli/src/package-managers/package-manager_spec.ts +++ b/packages/angular/cli/src/package-managers/package-manager_spec.ts @@ -378,6 +378,75 @@ describe('PackageManager', () => { }); }); + describe('getCurrentPackageName', () => { + it('should return the name from package.json without running the package manager command', async () => { + const pm = new PackageManager(host, '/repo/app', descriptor); + const readFileSpy = spyOn(host, 'readFile').and.resolveTo('{"name": "app"}'); + + expect(await pm.getCurrentPackageName()).toBe('app'); + expect(readFileSpy).toHaveBeenCalledWith(jasmine.stringMatching(/package\.json$/)); + expect(runCommandSpy).not.toHaveBeenCalled(); + }); + + it('should fall back to the package manager command when reading package.json fails', async () => { + const pm = new PackageManager(host, '/repo/app/src', descriptor); + spyOn(host, 'readFile').and.rejectWith(new Error('ENOENT')); + runCommandSpy.and.resolveTo({ stdout: '"app"', stderr: '' }); + + expect(await pm.getCurrentPackageName()).toBe('app'); + expect(runCommandSpy).toHaveBeenCalledWith( + descriptor.binary, + descriptor.getPackageNameCommand, + jasmine.objectContaining({ cwd: '/repo/app/src' }), + ); + }); + + it('should extract the package name when npm prints a single-entry workspace object', async () => { + const pm = new PackageManager(host, '/repo/apps/app/src', descriptor); + spyOn(host, 'readFile').and.rejectWith(new Error('ENOENT')); + // Inside a workspace member, `npm pkg get name` prints `{ "app": "app" }` instead of `"app"`. + runCommandSpy.and.resolveTo({ stdout: '{\n "app": "app"\n}', stderr: '' }); + + expect(await pm.getCurrentPackageName()).toBe('app'); + }); + + it('should return undefined when npm prints multiple workspace entries and package.json is unavailable', async () => { + const pm = new PackageManager(host, '/repo', descriptor); + spyOn(host, 'readFile').and.rejectWith(new Error('ENOENT')); + runCommandSpy.and.resolveTo({ + stdout: '{\n "app-a": "app-a",\n "app-b": "app-b"\n}', + stderr: '', + }); + + expect(await pm.getCurrentPackageName()).toBeUndefined(); + }); + }); + + describe('getProjectDependencies', () => { + it('should list the dependencies of an npm workspace member', async () => { + const pm = new PackageManager(host, '/repo/apps/app', descriptor); + runCommandSpy.and.resolveTo({ + stdout: JSON.stringify({ + name: 'monorepo', + dependencies: { + app: { + version: '0.0.0', + resolved: 'file:../apps/app', + dependencies: { '@angular/core': { version: '22.0.0' } }, + }, + }, + }), + stderr: '', + }); + spyOn(host, 'readFile').and.resolveTo('{"name": "app"}'); + + const dependencies = await pm.getProjectDependencies(); + + expect([...dependencies.keys()]).toEqual(['@angular/core']); + expect(dependencies.get('@angular/core')?.version).toBe('22.0.0'); + }); + }); + describe('initializationError', () => { it('should throw initializationError when running commands', async () => { const error = new Error('Not installed'); From 40cb9f850606f43ae7388473d0f3d05577b692bb Mon Sep 17 00:00:00 2001 From: Alan Agius <17563226+alan-agius4@users.noreply.github.com> Date: Fri, 9 Oct 2026 13:20:41 +0000 Subject: [PATCH 599/787] refactor(@angular/build): run initialization tasks concurrently in library builder Moving target project name validation before async operations allows early exit if missing. Additionally, normalizing library options, initializing xxHash, and purging the stale build disk cache concurrently via Promise.all avoids serial awaiting during builder startup. --- .../angular/build/src/builders/library/builder.ts | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/packages/angular/build/src/builders/library/builder.ts b/packages/angular/build/src/builders/library/builder.ts index 33df771fc6ab..2435d5db5f18 100644 --- a/packages/angular/build/src/builders/library/builder.ts +++ b/packages/angular/build/src/builders/library/builder.ts @@ -42,10 +42,6 @@ export async function* executeLibraryBuilder( context: BuilderContext & { signal?: AbortSignal }, ): AsyncIterableIterator { assertCompatibleAngularVersion(context.workspaceRoot); - await initializeHash(); - - // Purge old build disk cache - await purgeStaleBuildCache(context); const projectName = context.target?.project; if (!projectName) { @@ -54,7 +50,13 @@ export async function* executeLibraryBuilder( return; } - const normalizedOptions = await normalizeLibraryOptions(context, projectName, options); + const [normalizedOptions] = await Promise.all([ + normalizeLibraryOptions(context, projectName, options), + initializeHash(), + // Purge old build disk cache + purgeStaleBuildCache(context), + ]); + const { workspaceRoot, projectRoot, From 4034fc5cd03c9966eb596ded4173194a13901a60 Mon Sep 17 00:00:00 2001 From: Alan Agius <17563226+alan-agius4@users.noreply.github.com> Date: Fri, 9 Oct 2026 09:07:39 +0000 Subject: [PATCH 600/787] refactor(@angular/build): make getTailwindConfig synchronous getTailwindConfig only performs synchronous path searches and module resolution. Removing async avoids unnecessary Promise allocations and simplifies option normalization callers. --- .../angular/build/src/builders/application/options.ts | 2 +- packages/angular/build/src/builders/library/options.ts | 2 +- packages/angular/build/src/utils/postcss-configuration.ts | 8 ++++---- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/packages/angular/build/src/builders/application/options.ts b/packages/angular/build/src/builders/application/options.ts index 322c2dbef897..0e225be24045 100644 --- a/packages/angular/build/src/builders/application/options.ts +++ b/packages/angular/build/src/builders/application/options.ts @@ -287,7 +287,7 @@ export async function normalizeOptions( // Skip tailwind configuration if postcss is customized const tailwindConfiguration = postcssConfiguration ? undefined - : await getTailwindConfig(searchDirectories, workspaceRoot, context.logger); + : getTailwindConfig(searchDirectories, workspaceRoot, context.logger); let serverEntryPoint: string | undefined; if (typeof options.server === 'string') { diff --git a/packages/angular/build/src/builders/library/options.ts b/packages/angular/build/src/builders/library/options.ts index c90fd525e1f2..b7747fb6db27 100644 --- a/packages/angular/build/src/builders/library/options.ts +++ b/packages/angular/build/src/builders/library/options.ts @@ -126,7 +126,7 @@ export async function normalizeLibraryOptions( const postcssConfiguration = await loadPostcssConfiguration(searchDirectories); const tailwindConfiguration = postcssConfiguration ? undefined - : await getTailwindConfig(searchDirectories, workspaceRoot, context.logger); + : getTailwindConfig(searchDirectories, workspaceRoot, context.logger); return { workspaceRoot, diff --git a/packages/angular/build/src/utils/postcss-configuration.ts b/packages/angular/build/src/utils/postcss-configuration.ts index abde0e632b30..e5a4076232a0 100644 --- a/packages/angular/build/src/utils/postcss-configuration.ts +++ b/packages/angular/build/src/utils/postcss-configuration.ts @@ -31,8 +31,8 @@ export interface SearchDirectory { files: Set; } -export async function generateSearchDirectories(roots: string[]): Promise { - return await Promise.all( +export function generateSearchDirectories(roots: string[]): Promise { + return Promise.all( roots.map((root) => readdir(root, { withFileTypes: true }).then((entries) => ({ root, @@ -63,11 +63,11 @@ export function findTailwindConfiguration( return findFile(searchDirectories, tailwindConfigFiles); } -export async function getTailwindConfig( +export function getTailwindConfig( searchDirectories: SearchDirectory[], workspaceRoot: string, logger?: { warn(message: string): void }, -): Promise<{ file: string; package: string } | undefined> { +): { file: string; package: string } | undefined { const tailwindConfigurationPath = findTailwindConfiguration(searchDirectories); if (!tailwindConfigurationPath) { return undefined; From fb7efc86228164330f68ed86801f9d5bbe9ad5b0 Mon Sep 17 00:00:00 2001 From: Alan Agius Date: Tue, 13 Oct 2026 08:02:42 +0200 Subject: [PATCH 601/787] perf(@angular/build): resolve asset patterns concurrently with bounded concurrency Avoid sequentially globbing asset entries one-by-one in `resolveAssets` by utilizing `mapConcurrent` bounded by `MAX_CONCURRENT_READS` (16). Additionally, add a fast path for static, non-dynamic file patterns using direct file stats instead of directory walks. --- .../esbuild/persistent-load-result-cache.ts | 5 +-- .../angular/build/src/utils/concurrency.ts | 5 +++ .../angular/build/src/utils/resolve-assets.ts | 43 +++++++++++++------ 3 files changed, 37 insertions(+), 16 deletions(-) diff --git a/packages/angular/build/src/tools/esbuild/persistent-load-result-cache.ts b/packages/angular/build/src/tools/esbuild/persistent-load-result-cache.ts index c5dcee90ccf9..7eaf11806f1d 100644 --- a/packages/angular/build/src/tools/esbuild/persistent-load-result-cache.ts +++ b/packages/angular/build/src/tools/esbuild/persistent-load-result-cache.ts @@ -32,7 +32,7 @@ import { readFile, stat } from 'node:fs/promises'; import { isAbsolute } from 'node:path'; import { fileURLToPath } from 'node:url'; import type { Cache as PersistentCacheStore } from '../../utils/cache'; -import { mapConcurrent, runConcurrent } from '../../utils/concurrency'; +import { MAX_CONCURRENT_READS, mapConcurrent, runConcurrent } from '../../utils/concurrency'; import { calculateHash, createContentHash } from '../../utils/hash'; import { LoadResultCache, MemoryLoadResultCache } from './load-result-cache'; @@ -112,9 +112,6 @@ export function extractDiskFilePath(path: string): string | undefined { return isAbsolute(path) ? path : undefined; } -/** Maximum number of concurrent file system read/stat operations to prevent OS file descriptor exhaustion. */ -const MAX_CONCURRENT_READS = 16; - /** * Validates that all imported watch files exist on disk and their contents match. * Performs a fast-path metadata check (mtime + size) first, falling back to content hashing. diff --git a/packages/angular/build/src/utils/concurrency.ts b/packages/angular/build/src/utils/concurrency.ts index a38a9a57fa36..39f2b70c95df 100644 --- a/packages/angular/build/src/utils/concurrency.ts +++ b/packages/angular/build/src/utils/concurrency.ts @@ -6,6 +6,11 @@ * found in the LICENSE file at https://angular.dev/license */ +/** + * Maximum number of concurrent file system read/stat operations to prevent OS file descriptor exhaustion. + */ +export const MAX_CONCURRENT_READS = 16; + /** * Executes an asynchronous function for each item in an array concurrently up to a specified limit. * diff --git a/packages/angular/build/src/utils/resolve-assets.ts b/packages/angular/build/src/utils/resolve-assets.ts index 79ddd8548266..06a6c6c157e9 100644 --- a/packages/angular/build/src/utils/resolve-assets.ts +++ b/packages/angular/build/src/utils/resolve-assets.ts @@ -6,8 +6,10 @@ * found in the LICENSE file at https://angular.dev/license */ +import { lstat, stat } from 'node:fs/promises'; import path from 'node:path'; -import { glob } from 'tinyglobby'; +import { glob, isDynamicPattern } from 'tinyglobby'; +import { MAX_CONCURRENT_READS, mapConcurrent } from './concurrency'; import { isSubDirectory } from './path'; /** @@ -26,15 +28,34 @@ export async function resolveAssets( }[], root: string, ): Promise<{ source: string; destination: string }[]> { - const outputFiles: { source: string; destination: string }[] = []; - - for (const entry of entries) { + const resolvedEntries = await mapConcurrent(entries, MAX_CONCURRENT_READS, async (entry) => { if (!isSubDirectory(root, entry.input)) { throw new Error(`The ${entry.input} asset path must be within the workspace root.`); } const cwd = path.resolve(root, entry.input); + if (!entry.ignore?.length && !isDynamicPattern(entry.glob)) { + const src = path.join(cwd, entry.glob); + if (isSubDirectory(cwd, src)) { + try { + const stats = await (entry.followSymlinks ? stat(src) : lstat(src)); + if (stats.isFile()) { + const filePath = entry.flatten ? path.basename(entry.glob) : entry.glob; + + return [{ source: src, destination: path.join(entry.output, filePath) }]; + } + + if (!stats.isSymbolicLink()) { + return []; + } + } catch { + // File does not exist or cannot be accessed. + return []; + } + } + } + const files = await glob(entry.glob, { cwd, dot: true, @@ -42,13 +63,11 @@ export async function resolveAssets( followSymbolicLinks: entry.followSymlinks ?? false, }); - for (const file of files) { - const src = path.join(cwd, file); - const filePath = entry.flatten ? path.basename(file) : file; - - outputFiles.push({ source: src, destination: path.join(entry.output, filePath) }); - } - } + return files.map((file) => ({ + source: path.join(cwd, file), + destination: path.join(entry.output, entry.flatten ? path.basename(file) : file), + })); + }); - return outputFiles; + return resolvedEntries.flat(); } From 2c518a6dbe8734d247dfe4eb2c1c4af5e169fa94 Mon Sep 17 00:00:00 2001 From: Alan Agius Date: Tue, 13 Oct 2026 08:49:46 +0200 Subject: [PATCH 602/787] fix(@angular/build): enhance build logs and output location for library builder Align library builder logs with the application builder format by logging: - `Library bundle generation complete. [X seconds] - ` on build completion - `Output location: ` for successful builds - `Watch mode enabled. Watching for file changes...` after initial build when watch mode is active --- .../build/src/builders/library/builder.ts | 34 ++++++++----- .../library/tests/behavior/build_spec.ts | 50 +++++++++++++++++++ 2 files changed, 72 insertions(+), 12 deletions(-) diff --git a/packages/angular/build/src/builders/library/builder.ts b/packages/angular/build/src/builders/library/builder.ts index 2435d5db5f18..948f53ae568b 100644 --- a/packages/angular/build/src/builders/library/builder.ts +++ b/packages/angular/build/src/builders/library/builder.ts @@ -120,10 +120,6 @@ export async function* executeLibraryBuilder( } if (isWatchMode) { - if (progress) { - logger.info('Watch mode enabled. Watching for file changes...'); - } - const { setupWatcher } = await import('../../utils/watcher'); watcher = await setupWatcher({ workspaceRoot, @@ -154,6 +150,11 @@ export async function* executeLibraryBuilder( watcher, buildAction, ); + + if (isWatchMode && progress) { + logger.info('Watch mode enabled. Watching for file changes...'); + } + yield initialResult; if (!isWatchMode || !watcher) { @@ -192,11 +193,11 @@ async function executeBuild( buildAction: typeof import('./pipeline/build-action').buildAction, ): Promise { const startTime = process.hrtime.bigint(); - const { context, watchedCompilationFiles, isWatchMode } = actionContext; + const { context, watchedCompilationFiles, isWatchMode, options } = actionContext; try { await withProgress(message, () => buildAction(actionContext)); - logBuildResult(context.logger, startTime, true); + logBuildResult(context.logger, startTime, true, options.outputPath); if (isWatchMode) { logCumulativeDurations(); } @@ -345,14 +346,23 @@ async function* runWatchLoop( /** * Logs the build completion time and status. */ -function logBuildResult(logger: logging.LoggerApi, startTime: bigint, success: boolean): void { - const durationMs = Number(process.hrtime.bigint() - startTime) / 1_000_000; - const durationSec = (durationMs / 1000).toFixed(2); +function logBuildResult( + logger: logging.LoggerApi, + startTime: bigint, + success: boolean, + outputPath?: string, +): void { + const buildTime = Number(process.hrtime.bigint() - startTime) / 10 ** 9; + const message = + `Library bundle generation ${success ? 'complete' : 'failed'}.` + + ` [${buildTime.toFixed(3)} seconds] - ${new Date().toISOString()}`; if (success) { - logger.info(`Build at: ${new Date().toISOString()} - Time: ${durationMs.toFixed(0)}ms`); - logger.info(`Built Angular library in ${durationSec}s.`); + logger.info(message); + if (outputPath) { + logger.info(`Output location: ${outputPath}\n`); + } } else { - logger.error(`Build failed after ${durationSec}s.`); + logger.error(message); } } diff --git a/packages/angular/build/src/builders/library/tests/behavior/build_spec.ts b/packages/angular/build/src/builders/library/tests/behavior/build_spec.ts index 996001db209d..e55a414c1ada 100644 --- a/packages/angular/build/src/builders/library/tests/behavior/build_spec.ts +++ b/packages/angular/build/src/builders/library/tests/behavior/build_spec.ts @@ -180,5 +180,55 @@ describeLibraryBuilder(executeLibraryBuilder, LIBRARY_BUILDER_INFO, (harness) => tslib: '^2.0.0', }); }); + + it('should log completion and output location', async () => { + harness.useTarget('build', { + ...BASE_OPTIONS, + }); + + const { result, logs } = await harness.executeOnce(); + expect(result?.success).toBeTrue(); + expect(logs).toContain( + jasmine.objectContaining({ + level: 'info', + message: jasmine.stringMatching( + /Library bundle generation complete\. \[\d+\.\d{3} seconds\] - \d{4}-\d{2}-\d{2}T/, + ), + }), + ); + expect(logs).toContain( + jasmine.objectContaining({ + level: 'info', + message: jasmine.stringMatching(/Output location: .*dist[/\\]lib/), + }), + ); + }); + + it('should log failure on build error', async () => { + await harness.writeFile( + 'projects/lib/src/public-api.ts', + `export const title: number = 'invalid type';`, + ); + + harness.useTarget('build', { + ...BASE_OPTIONS, + }); + + const { result, logs } = await harness.executeOnce({ outputLogsOnFailure: false }); + expect(result?.success).toBeFalse(); + expect(logs).toContain( + jasmine.objectContaining({ + level: 'error', + message: jasmine.stringMatching( + /Library bundle generation failed\. \[\d+\.\d{3} seconds\] - \d{4}-\d{2}-\d{2}T/, + ), + }), + ); + expect(logs).not.toContain( + jasmine.objectContaining({ + message: jasmine.stringMatching(/Output location:/), + }), + ); + }); }); }); From 07845f019cf7d70c17f037d711b430a776f96031 Mon Sep 17 00:00:00 2001 From: Alan Agius Date: Tue, 13 Oct 2026 09:09:21 +0200 Subject: [PATCH 603/787] perf(@angular/build): optimize incremental watch rebuilds in AOT compilation - Pre-populate `.d.ts` shape signatures on the previous `BuilderProgram` for modified files prior to diffing when type-checking or TypeScript transpilation is active, preventing false-positive `.d.ts` cascades on incremental watch edits. - Synchronize `typeScriptProgram` with `angularCompiler.getCurrentProgram()` after `collectDiagnostics()` and clear uncommitted `changedFilesSet` and `oldSignatures` entries so subsequent incremental builds preserve `.d.ts` signatures and do not treat `.ngtypecheck.ts` shims as newly added files. - Detect affected dependent `.ngtypecheck.ts` shims in `isolatedModules` / `verbatimModuleSyntax` mode via TypeScript's `state.hasCalledUpdateShapeSignature`, ensuring cross-component template diagnostics are re-evaluated when a dependency's `.d.ts` shape changes without cascading on private edits. - Avoid `filter().flatMap()` allocations and skip `getResourceDependencies()` for declaration files when collecting `referencedFiles`. --- .../tests/behavior/rebuild-errors_spec.ts | 237 ++++++++- .../build/src/tools/angular/angular-host.ts | 11 +- .../angular/compilation/aot-compilation.ts | 467 ++++++++++++++---- .../src/tools/esbuild/bundler-context.ts | 6 +- 4 files changed, 613 insertions(+), 108 deletions(-) diff --git a/packages/angular/build/src/builders/application/tests/behavior/rebuild-errors_spec.ts b/packages/angular/build/src/builders/application/tests/behavior/rebuild-errors_spec.ts index de53c7223fff..5e7bdeb3fd9c 100644 --- a/packages/angular/build/src/builders/application/tests/behavior/rebuild-errors_spec.ts +++ b/packages/angular/build/src/builders/application/tests/behavior/rebuild-errors_spec.ts @@ -15,12 +15,6 @@ import { expectNoLog, } from '../setup'; -/** - * Maximum time in milliseconds for single build/rebuild - * This accounts for CI variability. - */ -export const BUILD_TIMEOUT = 30_000; - describeBuilder(buildApplication, APPLICATION_BUILDER_INFO, (harness) => { describe('Behavior: "Rebuild Error Detection"', () => { it('detects template errors with no AOT codegen or TS emit differences', async () => { @@ -128,6 +122,235 @@ describeBuilder(buildApplication, APPLICATION_BUILDER_INFO, (harness) => { ); }); + it('detects template errors across components on watch rebuild when isolatedModules is enabled', async () => { + harness.useTarget('build', { + ...BASE_OPTIONS, + watch: true, + }); + + await harness.modifyFile('tsconfig.json', (content) => { + const tsconfig = JSON.parse(content); + tsconfig.compilerOptions = { + ...tsconfig.compilerOptions, + isolatedModules: true, + }; + + return JSON.stringify(tsconfig); + }); + + const goodChildComponentContents = ` + import { Component, Input } from '@angular/core'; + @Component({ + selector: 'child', + standalone: true, + template: '

{{ value }}

', + }) + export class ChildComponent { + @Input() value!: number; + } + `; + + const typeErrorText = `Type 'number' is not assignable to type 'string'.`; + + await harness.writeFiles({ + 'src/app/child.component.ts': goodChildComponentContents, + 'src/app/app.module.ts': ` + import { NgModule } from '@angular/core'; + import { BrowserModule } from '@angular/platform-browser'; + import { AppComponent } from './app.component'; + @NgModule({ + imports: [ + BrowserModule, + AppComponent, + ], + providers: [], + bootstrap: [AppComponent] + }) + export class AppModule { } + `, + 'src/app/app.component.ts': ` + import { Component } from '@angular/core'; + import { ChildComponent } from './child.component'; + @Component({ + selector: 'app-root', + standalone: true, + imports: [ChildComponent], + template: '', + }) + export class AppComponent {} + `, + }); + + await harness.executeWithCases( + [ + async ({ result }) => { + expect(result?.success).toBeTrue(); + + // Update child component to change input type from number to string + await harness.writeFile( + 'src/app/child.component.ts', + ` + import { Component, Input } from '@angular/core'; + @Component({ + selector: 'child', + standalone: true, + template: '

{{ value }}

', + }) + export class ChildComponent { + @Input() value!: string; + } + `, + ); + }, + async ({ result, logs }) => { + expect(result?.success).toBeFalse(); + expectLog(logs, typeErrorText); + + // Make an unrelated change to verify error persists + await harness.modifyFile('src/main.ts', (content) => content + '\n'); + }, + async ({ result, logs }) => { + expect(result?.success).toBeFalse(); + expectLog(logs, typeErrorText); + + // Revert back to number + await harness.writeFile('src/app/child.component.ts', goodChildComponentContents); + }, + async ({ result, logs }) => { + expect(result?.success).toBeTrue(); + expectNoLog(logs, typeErrorText); + + // Make an unrelated change to verify error cache cleared + await harness.modifyFile('src/main.ts', (content) => content + '\n'); + }, + ({ result, logs }) => { + expect(result?.success).toBeTrue(); + expectNoLog(logs, typeErrorText); + }, + ], + { outputLogsOnFailure: false }, + ); + }); + + it('detects template errors when an input becomes required or a selector is renamed on watch rebuild', async () => { + harness.useTarget('build', { + ...BASE_OPTIONS, + watch: true, + }); + + await harness.modifyFile('tsconfig.json', (content) => { + const tsconfig = JSON.parse(content); + tsconfig.compilerOptions = { + ...tsconfig.compilerOptions, + isolatedModules: true, + }; + + return JSON.stringify(tsconfig); + }); + + const goodChildComponentContents = ` + import { Component, input } from '@angular/core'; + @Component({ + selector: 'app-child', + standalone: true, + template: '

{{ label() }}

', + }) + export class ChildComponent { + label = input(''); + } + `; + + const requiredInputErrorText = `Required input 'label' from component ChildComponent must be specified.`; + const unknownElementErrorText = `'app-child' is not a known element`; + + await harness.writeFiles({ + 'src/app/child.component.ts': goodChildComponentContents, + 'src/app/app.module.ts': ` + import { NgModule } from '@angular/core'; + import { BrowserModule } from '@angular/platform-browser'; + import { AppComponent } from './app.component'; + @NgModule({ + imports: [ + BrowserModule, + AppComponent, + ], + providers: [], + bootstrap: [AppComponent] + }) + export class AppModule { } + `, + 'src/app/app.component.ts': ` + import { Component } from '@angular/core'; + import { ChildComponent } from './child.component'; + @Component({ + selector: 'app-root', + standalone: true, + imports: [ChildComponent], + template: '', + }) + export class AppComponent {} + `, + }); + + await harness.executeWithCases( + [ + async ({ result }) => { + expect(result?.success).toBeTrue(); + + // Make input required using signal input.required() (which has the same TS .d.ts type InputSignal) + await harness.writeFile( + 'src/app/child.component.ts', + ` + import { Component, input } from '@angular/core'; + @Component({ + selector: 'app-child', + standalone: true, + template: '

{{ label() }}

', + }) + export class ChildComponent { + label = input.required(); + } + `, + ); + }, + async ({ result, logs }) => { + expect(result?.success).toBeFalse(); + expectLog(logs, requiredInputErrorText); + + // Revert required input and rename selector instead + await harness.writeFile( + 'src/app/child.component.ts', + ` + import { Component, input } from '@angular/core'; + @Component({ + selector: 'app-child-renamed', + standalone: true, + template: '

{{ label() }}

', + }) + export class ChildComponent { + label = input(''); + } + `, + ); + }, + async ({ result, logs }) => { + expect(result?.success).toBeFalse(); + expectNoLog(logs, requiredInputErrorText); + expectLog(logs, unknownElementErrorText); + + // Revert back to valid child component + await harness.writeFile('src/app/child.component.ts', goodChildComponentContents); + }, + ({ result, logs }) => { + expect(result?.success).toBeTrue(); + expectNoLog(logs, requiredInputErrorText); + expectNoLog(logs, unknownElementErrorText); + }, + ], + { outputLogsOnFailure: false }, + ); + }); + it('detects cumulative block syntax errors', async () => { harness.useTarget('build', { ...BASE_OPTIONS, @@ -234,7 +457,7 @@ describeBuilder(buildApplication, APPLICATION_BUILDER_INFO, (harness) => { await harness.appendToFile('src/app/app.component.html', '
Guten Tag
'); }, ({ logs }) => { - expectNoLog(logs, 'invalid-css-content'); + expectNoLog(logs, 'Unexpected character "EOF"'); harness.expectFile('dist/browser/main.js').content.toContain('Hello, world!'); harness.expectFile('dist/browser/main.js').content.toContain('Guten Tag'); diff --git a/packages/angular/build/src/tools/angular/angular-host.ts b/packages/angular/build/src/tools/angular/angular-host.ts index 9322b5683dc5..f30df5bab64d 100644 --- a/packages/angular/build/src/tools/angular/angular-host.ts +++ b/packages/angular/build/src/tools/angular/angular-host.ts @@ -35,7 +35,10 @@ export interface AngularHostOptions { * field. The `version` field is required when used with a TypeScript BuilderProgram. * @param program The TypeScript Program instance to patch. */ -export function ensureSourceFileVersions(program: ts.Program): void { +export function ensureSourceFileVersions( + program: ts.Program, + previousProgram?: ts.BuilderProgram, +): void { const baseGetSourceFiles = program.getSourceFiles; // TODO: Update Angular compiler to add versions to all internal files and remove this program.getSourceFiles = function (...parameters) { @@ -45,7 +48,11 @@ export function ensureSourceFileVersions(program: ts.Program): void { for (const file of files) { if (file.version === undefined) { - file.version = calculateHash(file.text); + const previousFile: (ts.SourceFile & { version?: string }) | undefined = + previousProgram && !file.fileName.endsWith('.ngtypecheck.ts') + ? previousProgram.getSourceFile(file.fileName) + : undefined; + file.version = previousFile?.version ?? calculateHash(file.text); } } diff --git a/packages/angular/build/src/tools/angular/compilation/aot-compilation.ts b/packages/angular/build/src/tools/angular/compilation/aot-compilation.ts index 6f45199d1421..749962e3def6 100644 --- a/packages/angular/build/src/tools/angular/compilation/aot-compilation.ts +++ b/packages/angular/build/src/tools/angular/compilation/aot-compilation.ts @@ -37,16 +37,41 @@ import { printSourceFileWithMap } from './typescript-printer'; */ const HMR_MODIFIED_FILE_LIMIT = 32; +/** + * Extension for Angular type-checking files. + */ +const TTC_EXTENSION = '.ngtypecheck.ts'; + +/** + * Length of the `.ngtypecheck.ts` extension. + */ +const TTC_EXTENSION_LENGTH = TTC_EXTENSION.length; + +/** + * Checks if a file is an Angular type-checking shim file. + */ +function isNgTypeCheckFile(fileName: string): boolean { + return fileName.endsWith(TTC_EXTENSION); +} + +/** + * Returns the original filename for a type-checking shim file. + */ +function getOriginalFilename(fileName: string): string { + return fileName.slice(0, -TTC_EXTENSION_LENGTH) + '.ts'; +} + class AngularCompilationState { constructor( public readonly angularProgram: ng.NgtscProgram, public readonly compilerHost: ng.CompilerHost, - public readonly typeScriptProgram: ts.EmitAndSemanticDiagnosticsBuilderProgram, + public typeScriptProgram: ts.EmitAndSemanticDiagnosticsBuilderProgram, public readonly affectedFiles: ReadonlySet, public readonly templateDiagnosticsOptimization: ng.OptimizeFor, public readonly webWorkerTransform: ts.TransformerFactory, public readonly useTypeScriptTranspilation: boolean, public readonly diagnosticCache = new WeakMap(), + public readonly filesWithoutDtsSignature = new Set(), ) {} get angularCompiler() { @@ -103,8 +128,8 @@ export class AotCompilation extends TypeScriptCompilation { if (hostOptions.modifiedFiles) { this.invalidateFiles(hostOptions.modifiedFiles); - for (const modifiedFile of hostOptions.modifiedFiles) { - if (this.#state) { + if (this.#state && hostOptions.modifiedFiles.size > 0) { + for (const modifiedFile of hostOptions.modifiedFiles) { // Clear package.json cache if a node modules file was modified if (!clearPackageJsonCache && modifiedFile.includes('node_modules')) { clearPackageJsonCache = true; @@ -120,6 +145,14 @@ export class AotCompilation extends TypeScriptCompilation { } } } + + if (useTypeChecking || useTypeScriptTranspilation) { + populatePreviousDtsSignatures( + this.#state.typeScriptProgram, + hostOptions.modifiedFiles, + this.#state.filesWithoutDtsSignature, + ); + } } } @@ -155,6 +188,18 @@ export class AotCompilation extends TypeScriptCompilation { configurationDiagnostics, ); + const filesWithoutDtsSignature = this.#state?.filesWithoutDtsSignature ?? new Set(); + if (!this.#state) { + for (const sourceFile of typeScriptProgram.getSourceFiles()) { + if ( + !sourceFile.isDeclarationFile && + !angularCompiler.ignoreForDiagnostics.has(sourceFile) + ) { + filesWithoutDtsSignature.add(sourceFile.fileName); + } + } + } + await profileAsync('NG_ANALYZE_PROGRAM', () => angularCompiler.analyzeAsync()); let templateUpdates; @@ -203,38 +248,62 @@ export class AotCompilation extends TypeScriptCompilation { const affectedFiles = useTypeChecking || useTypeScriptTranspilation ? profileSync('NG_FIND_AFFECTED', () => - findAffectedFiles(typeScriptProgram, angularCompiler, usingBuildInfo), + findAffectedFiles( + typeScriptProgram, + angularCompiler, + usingBuildInfo, + this.#state?.typeScriptProgram, + filesWithoutDtsSignature, + ), ) : new Set(); const componentResourcesDependencies = new Map(); // Get all files referenced in the TypeScript/Angular program including component resources - const referencedFiles = [ - ...tsConfigFiles, - ...typeScriptProgram - .getSourceFiles() - .filter((sourceFile) => !angularCompiler.ignoreForEmit.has(sourceFile)) - .flatMap((sourceFile) => { - const resourceDependencies = angularCompiler.getResourceDependencies(sourceFile); - componentResourcesDependencies.set(sourceFile.fileName, resourceDependencies); - // Also invalidate Angular diagnostics for a source file if component resources are modified - if (this.#state && hostOptions.modifiedFiles?.size) { - for (const resourceDependency of resourceDependencies) { - if ( - hostOptions.modifiedFiles.has(resourceDependency) && - !/\.(?:css|scss|sass|less)$/i.test(resourceDependency) - ) { - this.#state.diagnosticCache.delete(sourceFile); - // Also mark as affected in case changed template affects diagnostics - affectedFiles.add(sourceFile); - } - } + const referencedFiles = [...tsConfigFiles]; + for (const sourceFile of typeScriptProgram.getSourceFiles()) { + if (angularCompiler.ignoreForEmit.has(sourceFile)) { + continue; + } + + referencedFiles.push(sourceFile.fileName); + if (sourceFile.isDeclarationFile) { + continue; + } + + const resourceDependencies = angularCompiler.getResourceDependencies(sourceFile); + componentResourcesDependencies.set(sourceFile.fileName, resourceDependencies); + + if (resourceDependencies.length === 0) { + continue; + } + + referencedFiles.push(...resourceDependencies); + + // Also invalidate Angular diagnostics for a source file if component resources are modified + if (this.#state && hostOptions.modifiedFiles?.size) { + for (const resourceDependency of resourceDependencies) { + if ( + !hostOptions.modifiedFiles.has(resourceDependency) || + /\.(?:css|scss|sass|less)$/i.test(resourceDependency) + ) { + continue; } - return [sourceFile.fileName, ...resourceDependencies]; - }), - ]; + this.#state.diagnosticCache.delete(sourceFile); + + const oldSourceFile = this.#state.typeScriptProgram.getSourceFile(sourceFile.fileName); + if (oldSourceFile) { + this.#state.diagnosticCache.delete(oldSourceFile); + } + + // Also mark as affected in case changed template affects diagnostics + affectedFiles.add(sourceFile); + break; + } + } + } this.#state = new AngularCompilationState( angularProgram, @@ -245,6 +314,7 @@ export class AotCompilation extends TypeScriptCompilation { createWorkerTransformer(hostOptions.processWebWorker.bind(hostOptions)), useTypeScriptTranspilation, this.#state?.diagnosticCache, + filesWithoutDtsSignature, ); return { @@ -270,61 +340,92 @@ export class AotCompilation extends TypeScriptCompilation { const syntactic = modes & DiagnosticModes.Syntactic; const semantic = modes & DiagnosticModes.Semantic; - // Collect program level diagnostics - if (modes & DiagnosticModes.Option) { - yield* typeScriptProgram.getConfigFileParsingDiagnostics(); - yield* angularCompiler.getOptionDiagnostics(); - yield* typeScriptProgram.getOptionsDiagnostics(); - } - if (syntactic) { - yield* typeScriptProgram.getGlobalDiagnostics(); - } - - // Collect source file specific diagnostics - for (const sourceFile of typeScriptProgram.getSourceFiles()) { - if (angularCompiler.ignoreForDiagnostics.has(sourceFile)) { - continue; + try { + // Collect program level diagnostics + if (modes & DiagnosticModes.Option) { + yield* typeScriptProgram.getConfigFileParsingDiagnostics(); + yield* angularCompiler.getOptionDiagnostics(); + yield* typeScriptProgram.getOptionsDiagnostics(); } - if (syntactic) { - // TypeScript will use cached diagnostics for files that have not been - // changed or affected for this build when using incremental building. - yield* profileSync( - 'NG_DIAGNOSTICS_SYNTACTIC', - () => typeScriptProgram.getSyntacticDiagnostics(sourceFile), - true, - ); + yield* typeScriptProgram.getGlobalDiagnostics(); } - if (!semantic) { - continue; - } + // Collect source file specific diagnostics + for (const sourceFile of typeScriptProgram.getSourceFiles()) { + if (angularCompiler.ignoreForDiagnostics.has(sourceFile)) { + continue; + } - yield* profileSync( - 'NG_DIAGNOSTICS_SEMANTIC', - () => typeScriptProgram.getSemanticDiagnostics(sourceFile), - true, - ); + if (syntactic) { + // TypeScript will use cached diagnostics for files that have not been + // changed or affected for this build when using incremental building. + yield* profileSync( + 'NG_DIAGNOSTICS_SYNTACTIC', + () => typeScriptProgram.getSyntacticDiagnostics(sourceFile), + true, + ); + } - // Declaration files cannot have template diagnostics - if (sourceFile.isDeclarationFile) { - continue; - } + if (!semantic) { + continue; + } - // Only request Angular template diagnostics for affected files to avoid - // overhead of template diagnostics for unchanged files. - if (affectedFiles.has(sourceFile)) { - const angularDiagnostics = profileSync( - 'NG_DIAGNOSTICS_TEMPLATE', - () => angularCompiler.getDiagnosticsForFile(sourceFile, templateDiagnosticsOptimization), + yield* profileSync( + 'NG_DIAGNOSTICS_SEMANTIC', + () => typeScriptProgram.getSemanticDiagnostics(sourceFile), true, ); - diagnosticCache.set(sourceFile, angularDiagnostics); - yield* angularDiagnostics; - } else { - const angularDiagnostics = diagnosticCache.get(sourceFile); - if (angularDiagnostics) { + + // Declaration files cannot have template diagnostics + if (sourceFile.isDeclarationFile) { + continue; + } + + // Only request Angular template diagnostics for affected files to avoid + // overhead of template diagnostics for unchanged files. + if (affectedFiles.has(sourceFile)) { + const angularDiagnostics = profileSync( + 'NG_DIAGNOSTICS_TEMPLATE', + () => + angularCompiler.getDiagnosticsForFile(sourceFile, templateDiagnosticsOptimization), + true, + ); + diagnosticCache.set(sourceFile, angularDiagnostics); yield* angularDiagnostics; + } else { + const angularDiagnostics = diagnosticCache.get(sourceFile); + if (angularDiagnostics) { + yield* angularDiagnostics; + } + } + } + } finally { + // Angular's template typechecker lazily creates `.ngtypecheck.ts` shims in a new `ts.Program` + // during `getDiagnosticsForFile`. Sync the builder program with `angularCompiler.getCurrentProgram()` + // so the next incremental build does not treat all `.ngtypecheck.ts` files as newly added files. + const currentTsProgram = angularCompiler.getCurrentProgram(); + if (currentTsProgram !== typeScriptProgram.getProgram()) { + ensureSourceFileVersions(currentTsProgram, typeScriptProgram); + this.#state.typeScriptProgram = ts.createEmitAndSemanticDiagnosticsBuilderProgram( + currentTsProgram, + this.#state.compilerHost, + typeScriptProgram, + ); + + const baseEmit = currentTsProgram.emit; + currentTsProgram.emit = () => ({ emitSkipped: true, diagnostics: [] }); + try { + while ( + this.#state.typeScriptProgram.getSemanticDiagnosticsOfNextAffectedFile( + undefined, + () => true, + ) + ) { + /* empty */ + } + } finally { + currentTsProgram.emit = baseEmit; } } } @@ -419,7 +520,7 @@ export class AotCompilation extends TypeScriptCompilation { if ( angularCompiler.incrementalCompilation.safeToSkipEmit(sourceFile) && - !affectedFiles.has(sourceFile) + (!useTypeScriptTranspilation || !affectedFiles.has(sourceFile)) ) { continue; } @@ -483,40 +584,138 @@ export class AotCompilation extends TypeScriptCompilation { function findAffectedFiles( builder: ts.EmitAndSemanticDiagnosticsBuilderProgram, - { ignoreForDiagnostics }: ng.NgtscProgram['compiler'], + { ignoreForDiagnostics, incrementalCompilation }: ng.NgtscProgram['compiler'], includeTTC: boolean, + oldBuilder: ts.EmitAndSemanticDiagnosticsBuilderProgram | undefined, + filesWithoutDtsSignature: Set, ): Set { const affectedFiles = new Set(); - // eslint-disable-next-line no-constant-condition - while (true) { - const result = builder.getSemanticDiagnosticsOfNextAffectedFile(undefined, (sourceFile) => { - // If the affected file is a TTC shim, add the shim's original source file. - // This ensures that changes that affect TTC are typechecked even when the changes - // are otherwise unrelated from a TS perspective and do not result in Ivy codegen changes. - // For example, changing @Input property types of a directive used in another component's - // template. - // A TTC shim is a file that has been ignored for diagnostics and has a filename ending in `.ngtypecheck.ts`. - if (ignoreForDiagnostics.has(sourceFile) && sourceFile.fileName.endsWith('.ngtypecheck.ts')) { - // This file name conversion relies on internal compiler logic and should be converted - // to an official method when available. 15 is length of `.ngtypecheck.ts` - const originalFilename = sourceFile.fileName.slice(0, -15) + '.ts'; - const originalSourceFile = builder.getSourceFile(originalFilename); - if (originalSourceFile) { - affectedFiles.add(originalSourceFile); + // Temporarily disable `isolatedModules` and `verbatimModuleSyntax` while walking affected + // files so TypeScript's `getFilesAffectedByUpdatedShapeWhenModuleEmit` yields dependent + // `.ngtypecheck.ts` shims to the `ignoreSourceFile` callback when a file's `.d.ts` shape + // changes, instead of returning only the modified file itself. + const compilerOptions = builder.getCompilerOptions(); + const prevIsolatedModules = compilerOptions.isolatedModules; + const prevVerbatimModuleSyntax = compilerOptions.verbatimModuleSyntax; + compilerOptions.isolatedModules = false; + compilerOptions.verbatimModuleSyntax = false; + + const program = builder.getProgram(); + const baseEmit = program.emit; + const oldProgram = oldBuilder?.getProgram(); + program.emit = ( + targetSourceFile, + writeFile, + cancellationToken, + emitOnly, + customTransformers, + ...rest + ) => { + if (targetSourceFile) { + if (isNgTypeCheckFile(targetSourceFile.fileName)) { + return { emitSkipped: true, diagnostics: [] }; + } + + if (oldProgram && filesWithoutDtsSignature.has(targetSourceFile.fileName)) { + const oldSourceFile = oldProgram.getSourceFile(targetSourceFile.fileName); + if (oldSourceFile) { + let oldDtsText: string | undefined; + let oldHasDiagnostics = false; + oldProgram.emit( + oldSourceFile, + (_fileName, text, _bom, _onError, _sourceFiles, data) => { + oldDtsText = text; + oldHasDiagnostics = !!(data as { diagnostics?: unknown[] } | undefined)?.diagnostics + ?.length; + }, + cancellationToken, + emitOnly, + customTransformers, + ...(rest as []), + ); + + return baseEmit.call( + program, + targetSourceFile, + (fileName, text, writeByteOrderMark, onError, sourceFiles, data) => { + const newHasDiagnostics = !!(data as { diagnostics?: unknown[] } | undefined) + ?.diagnostics?.length; + if (text !== oldDtsText || newHasDiagnostics !== oldHasDiagnostics) { + filesWithoutDtsSignature.delete(targetSourceFile.fileName); + writeFile?.(fileName, text, writeByteOrderMark, onError, sourceFiles, data); + } + }, + cancellationToken, + emitOnly, + customTransformers, + ...(rest as []), + ); } - return true; + filesWithoutDtsSignature.delete(targetSourceFile.fileName); } + } + + return baseEmit.call( + program, + targetSourceFile, + writeFile, + cancellationToken, + emitOnly, + customTransformers, + ...(rest as []), + ); + }; + + try { + while ( + builder.getSemanticDiagnosticsOfNextAffectedFile(undefined, (sourceFile) => { + if (ignoreForDiagnostics.has(sourceFile)) { + // If the affected file is a TTC shim, add the shim's original source file. + // This ensures that changes that affect TTC are typechecked even when the changes + // are otherwise unrelated from a TS perspective and do not result in Ivy codegen changes. + // For example, changing @Input property types of a directive used in another component's + // template. + // A TTC shim is a file that has been ignored for diagnostics and has a filename ending in `.ngtypecheck.ts`. + if (isNgTypeCheckFile(sourceFile.fileName)) { + // This file name conversion relies on internal compiler logic and should be converted + // to an official method when available. 15 is length of `.ngtypecheck.ts` + const originalFilename = getOriginalFilename(sourceFile.fileName); + const originalSourceFile = builder.getSourceFile(originalFilename); + if (originalSourceFile) { + affectedFiles.add(originalSourceFile); + } + } + } else { + affectedFiles.add(sourceFile); + } - return false; - }); + return true; + }) + ) { + /* empty */ + } + } finally { + program.emit = baseEmit; + compilerOptions.isolatedModules = prevIsolatedModules; + compilerOptions.verbatimModuleSyntax = prevVerbatimModuleSyntax; + } - if (!result) { - break; + // Also include files identified by Angular's incremental compilation graph as needing + // re-emission or template re-typechecking (such as selector renames or required input changes + // that only affect Angular metadata without altering standard TypeScript `.d.ts` signatures). + for (const sourceFile of builder.getSourceFiles()) { + if (sourceFile.isDeclarationFile || ignoreForDiagnostics.has(sourceFile)) { + continue; } - affectedFiles.add(result.affected as ts.SourceFile); + if ( + !incrementalCompilation.safeToSkipEmit(sourceFile) || + incrementalCompilation.priorTypeCheckingResultsFor(sourceFile) === null + ) { + affectedFiles.add(sourceFile); + } } // Add all files with associated template type checking files. @@ -525,10 +724,10 @@ function findAffectedFiles( // info is present. if (includeTTC) { for (const sourceFile of builder.getSourceFiles()) { - if (ignoreForDiagnostics.has(sourceFile) && sourceFile.fileName.endsWith('.ngtypecheck.ts')) { + if (ignoreForDiagnostics.has(sourceFile) && isNgTypeCheckFile(sourceFile.fileName)) { // This file name conversion relies on internal compiler logic and should be converted // to an official method when available. 15 is length of `.ngtypecheck.ts` - const originalFilename = sourceFile.fileName.slice(0, -15) + '.ts'; + const originalFilename = getOriginalFilename(sourceFile.fileName); const originalSourceFile = builder.getSourceFile(originalFilename); if (originalSourceFile) { affectedFiles.add(originalSourceFile); @@ -539,3 +738,75 @@ function findAffectedFiles( return affectedFiles; } + +/** + * Ensures `.d.ts` shape signatures are computed on the previous `BuilderProgram` for modified + * files before the next `BuilderProgram` is created. + * + * On the initial build (`oldProgram === undefined`), TypeScript initializes each file's shape + * signature to its `.ts` source version hash rather than emitting `.d.ts` declarations for every + * file. When a file is modified on a watch rebuild, TypeScript computes its new `.d.ts` signature + * and compares it against the previous program's stored signature. Emitting the `.d.ts` signature + * on `oldProgram` for the modified file replaces its initial `.ts` version hash with its true + * `.d.ts` signature prior to diffing, avoiding false-positive `.d.ts` cascades across importers. + */ +function populatePreviousDtsSignatures( + oldProgram: ts.EmitAndSemanticDiagnosticsBuilderProgram, + modifiedFiles: ReadonlySet, + filesWithoutDtsSignature: Set, +): void { + const filesToUpdate: ts.SourceFile[] = []; + for (const modifiedFile of modifiedFiles) { + const sf = oldProgram.getSourceFile(modifiedFile); + if (sf && !sf.isDeclarationFile && filesWithoutDtsSignature.delete(sf.fileName)) { + filesToUpdate.push(sf); + } + } + + if (filesToUpdate.length === 0) { + return; + } + + const compilerOptions = oldProgram.getCompilerOptions(); + const prevDeclaration = compilerOptions.declaration; + const prevComposite = compilerOptions.composite; + const prevNoEmit = compilerOptions.noEmit; + const prevNoEmitOnError = compilerOptions.noEmitOnError; + + compilerOptions.declaration = true; + compilerOptions.composite = false; + compilerOptions.noEmit = false; + compilerOptions.noEmitOnError = false; + + const program = oldProgram.getProgram(); + const baseEmit = program.emit as ( + targetSourceFile?: ts.SourceFile, + writeFile?: ts.WriteFileCallback, + cancellationToken?: ts.CancellationToken, + emitOnlyDtsFiles?: boolean | number, + customTransformers?: ts.CustomTransformers, + forceDtsEmit?: boolean, + ) => ts.EmitResult; + program.emit = (targetSourceFile, writeFile, cancellationToken) => + baseEmit.call( + program, + targetSourceFile, + writeFile, + cancellationToken, + 2, // ts.EmitOnly.BuilderSignature + undefined, + true, // forceDtsEmit + ); + + try { + for (const sf of filesToUpdate) { + oldProgram.emit(sf, () => {}, undefined, true); + } + } finally { + program.emit = baseEmit; + compilerOptions.declaration = prevDeclaration; + compilerOptions.composite = prevComposite; + compilerOptions.noEmit = prevNoEmit; + compilerOptions.noEmitOnError = prevNoEmitOnError; + } +} diff --git a/packages/angular/build/src/tools/esbuild/bundler-context.ts b/packages/angular/build/src/tools/esbuild/bundler-context.ts index a4228caa5782..202ab514cbfe 100644 --- a/packages/angular/build/src/tools/esbuild/bundler-context.ts +++ b/packages/angular/build/src/tools/esbuild/bundler-context.ts @@ -328,7 +328,11 @@ export class BundlerContext { const initialFiles = new Map(); for (const outputFile of result.outputFiles) { // Entries in the metafile are relative to the `absWorkingDir` option which is set to the workspaceRoot - const relativeFilePath = relative(this.workspaceRoot, outputFile.path); + // `outputFile.path` may already be relative if the `OutputFile` instance was cached in `additionalResults` + // across an incremental rebuild. + const relativeFilePath = isAbsolute(outputFile.path) + ? relative(this.workspaceRoot, outputFile.path) + : outputFile.path; const entryPoint = result.metafile.outputs[relativeFilePath]?.entryPoint; outputFile.path = relativeFilePath; From 1f31103f206c41226e057f396e1ea1e574a6a650 Mon Sep 17 00:00:00 2001 From: Alan Agius <17563226+alan-agius4@users.noreply.github.com> Date: Tue, 13 Oct 2026 13:28:36 +0000 Subject: [PATCH 604/787] refactor(@angular/build): flatten builderName in cache directory path Strip '@' and replace '/' in addition to ':' when normalizing builderName in normalizeCacheOptions so scoped builder names produce a single flat cache directory instead of nested subdirectories. --- packages/angular/build/src/utils/normalize-cache.ts | 2 +- packages/angular/build/src/utils/normalize-cache_spec.ts | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/angular/build/src/utils/normalize-cache.ts b/packages/angular/build/src/utils/normalize-cache.ts index e24eaf8627c8..bb24f774f79b 100644 --- a/packages/angular/build/src/utils/normalize-cache.ts +++ b/packages/angular/build/src/utils/normalize-cache.ts @@ -140,7 +140,7 @@ export function normalizeCacheOptions( const cacheBasePath = getCacheBasePath(workspaceRoot, path); const localCacheBasePath = isAbsolute(path) ? path : resolve(workspaceRoot, path); - const normalizedBuilderName = builderName.replaceAll(':', '-'); + const normalizedBuilderName = builderName.replace('@', '').replaceAll(/[:/]/g, '-'); return { enabled: cacheEnabled, diff --git a/packages/angular/build/src/utils/normalize-cache_spec.ts b/packages/angular/build/src/utils/normalize-cache_spec.ts index 18e75403756d..1a0520c96a96 100644 --- a/packages/angular/build/src/utils/normalize-cache_spec.ts +++ b/packages/angular/build/src/utils/normalize-cache_spec.ts @@ -283,10 +283,10 @@ describe('normalizeCacheOptions', () => { const options = normalizeCacheOptions({}, workspaceRoot, 'my-app', '@angular/build:unit-test'); expect(options.path).toBe( - resolve(workspaceRoot, '.angular/cache/0.0.0-PLACEHOLDER/my-app/@angular/build-unit-test'), + resolve(workspaceRoot, '.angular/cache/0.0.0-PLACEHOLDER/my-app/angular-build-unit-test'), ); expect(options.localPath).toBe( - resolve(workspaceRoot, '.angular/cache/0.0.0-PLACEHOLDER/my-app/@angular/build-unit-test'), + resolve(workspaceRoot, '.angular/cache/0.0.0-PLACEHOLDER/my-app/angular-build-unit-test'), ); }); }); From 4951994f64f6243f88f28b1174e38e3b25f69ea4 Mon Sep 17 00:00:00 2001 From: Alan Agius Date: Tue, 13 Oct 2026 16:52:05 +0200 Subject: [PATCH 605/787] refactor(@angular/build): unify and deduplicate emitFilesToDisk across builders Relocate emitFilesToDisk into src/utils/emit-files-to-disk.ts and unify the file emission descriptor shape across the application and library builders around origin ('memory' | 'disk') and source. --- .../src/builders/application/build-action.ts | 4 +- .../build/src/builders/application/index.ts | 40 +++-------- .../build/src/builders/application/results.ts | 2 +- .../src/builders/dev-server/vite/utils.ts | 2 +- .../extract-i18n/application-extraction.ts | 2 +- .../src/builders/karma/assets-middleware.ts | 2 +- .../builders/library/pipeline/build-action.ts | 21 +----- .../src/builders/library/pipeline/utils.ts | 8 +-- .../library/tests/behavior/watch_spec.ts | 38 ++++++++++ .../build/src/builders/library/types.ts | 3 - .../unit-test/runners/vitest/plugins.ts | 2 +- packages/angular/build/src/private.ts | 2 +- .../angular/build/src/tools/esbuild/utils.ts | 24 +------ .../vite/middlewares/assets-middleware.ts | 2 +- .../build/src/utils/emit-files-to-disk.ts | 71 +++++++++++++++++++ .../src/utils/emit-files-to-disk_spec.ts | 53 ++++++++++++++ .../angular/build/src/utils/test-files.ts | 33 ++------- .../extract-i18n/application-extraction.ts | 2 +- 18 files changed, 196 insertions(+), 115 deletions(-) create mode 100644 packages/angular/build/src/utils/emit-files-to-disk.ts create mode 100644 packages/angular/build/src/utils/emit-files-to-disk_spec.ts diff --git a/packages/angular/build/src/builders/application/build-action.ts b/packages/angular/build/src/builders/application/build-action.ts index b728ab9a8df5..eaae50848a48 100644 --- a/packages/angular/build/src/builders/application/build-action.ts +++ b/packages/angular/build/src/builders/application/build-action.ts @@ -333,7 +333,7 @@ function* emitOutputResults( incrementalResult.files.push({ path: destination, type: BuildOutputFileType.Browser, - inputPath: source, + source, origin: 'disk', }); } @@ -406,7 +406,7 @@ function createFullResult( ...assetFiles.map(({ source, destination }) => ({ path: destination, type: BuildOutputFileType.Browser, - inputPath: source, + source, origin: 'disk' as const, })), ...outputFiles.map((file) => ({ diff --git a/packages/angular/build/src/builders/application/index.ts b/packages/angular/build/src/builders/application/index.ts index 59ded1cd8182..f1b16a27e394 100644 --- a/packages/angular/build/src/builders/application/index.ts +++ b/packages/angular/build/src/builders/application/index.ts @@ -11,9 +11,10 @@ import assert from 'node:assert'; import fs from 'node:fs/promises'; import path from 'node:path'; import { BuildOutputFileType } from '../../tools/esbuild/bundler-files'; -import { createJsonBuildManifest, emitFilesToDisk } from '../../tools/esbuild/utils'; +import { createJsonBuildManifest } from '../../tools/esbuild/utils'; import { colors as ansiColors } from '../../utils/color'; import { deleteOutputDir } from '../../utils/delete-output-dir'; +import { emitFilesToDisk } from '../../utils/emit-files-to-disk'; import { bazelEsbuildPluginPath, useJSONBuildLogs } from '../../utils/environment-options'; import { isSubDirectory } from '../../utils/path'; import { purgeStaleBuildCache } from '../../utils/purge-cache'; @@ -197,37 +198,14 @@ export async function* buildApplication( } // Writes the output files to disk and ensures the containing directories are present - const directoryExists = new Set(); try { - await emitFilesToDisk(result.files, async (file) => { - if ( - outputOptions.ignoreServer && - (file.type === BuildOutputFileType.ServerApplication || - file.type === BuildOutputFileType.ServerRoot) - ) { - return; - } - - const fullFilePath = generateFullPath(file.path, file.type, outputOptions); - - // Ensure output subdirectories exist - const fileBasePath = path.dirname(fullFilePath); - if (fileBasePath && !directoryExists.has(fileBasePath)) { - await fs.mkdir(fileBasePath, { recursive: true }); - directoryExists.add(fileBasePath); - } - - if (file.origin === 'memory') { - // Write file contents - await fs.writeFile(fullFilePath, file.contents); - } else { - // Copy file contents - await fs.cp(file.inputPath, fullFilePath, { - mode: fs.constants.COPYFILE_FICLONE, - preserveTimestamps: true, - }); - } - }); + await emitFilesToDisk(result.files, (file) => + outputOptions.ignoreServer && + (file.type === BuildOutputFileType.ServerApplication || + file.type === BuildOutputFileType.ServerRoot) + ? undefined + : generateFullPath(file.path, file.type, outputOptions), + ); } catch (error) { context.logger.error(error instanceof Error ? error.message : String(error)); yield { success: false }; diff --git a/packages/angular/build/src/builders/application/results.ts b/packages/angular/build/src/builders/application/results.ts index 8e95176639f5..e9bd786a3fe6 100644 --- a/packages/angular/build/src/builders/application/results.ts +++ b/packages/angular/build/src/builders/application/results.ts @@ -53,7 +53,7 @@ export interface BaseResultFile { export interface DiskFile extends BaseResultFile { origin: 'disk'; - inputPath: string; + source: string; } export interface MemoryFile extends BaseResultFile { diff --git a/packages/angular/build/src/builders/dev-server/vite/utils.ts b/packages/angular/build/src/builders/dev-server/vite/utils.ts index bc2d4a513b5a..4a0b85b9324a 100644 --- a/packages/angular/build/src/builders/dev-server/vite/utils.ts +++ b/packages/angular/build/src/builders/dev-server/vite/utils.ts @@ -40,7 +40,7 @@ export function updateResultRecord( ): void { if (file.origin === 'disk') { assetFiles.set('/' + normalizePath(file.path), { - source: normalizePath(file.inputPath), + source: normalizePath(file.source), updated: !initial, }); diff --git a/packages/angular/build/src/builders/extract-i18n/application-extraction.ts b/packages/angular/build/src/builders/extract-i18n/application-extraction.ts index b18c8164481f..02233fade493 100644 --- a/packages/angular/build/src/builders/extract-i18n/application-extraction.ts +++ b/packages/angular/build/src/builders/extract-i18n/application-extraction.ts @@ -107,7 +107,7 @@ function setupLocalizeExtractor( if (file?.origin === 'memory') { content = textDecoder.decode(file.contents); } else if (file?.origin === 'disk') { - content = readFileSync(file.inputPath, 'utf-8'); + content = readFileSync(file.source, 'utf-8'); } if (content === undefined) { throw new Error('Unknown file requested: ' + requestedPath); diff --git a/packages/angular/build/src/builders/karma/assets-middleware.ts b/packages/angular/build/src/builders/karma/assets-middleware.ts index 45483cb4ec41..6f04faffae46 100644 --- a/packages/angular/build/src/builders/karma/assets-middleware.ts +++ b/packages/angular/build/src/builders/karma/assets-middleware.ts @@ -60,7 +60,7 @@ export class AngularAssetsMiddleware { // https://github.com/karma-runner/karma/blob/84f85e7016efc2266fa6b3465f494a3fa151c85c/lib/middleware/common.js#L10 switch (file.origin) { case 'disk': - this.serveFile(file.inputPath, undefined, res, undefined, undefined, /* doNotCache */ true); + this.serveFile(file.source, undefined, res, undefined, undefined, /* doNotCache */ true); break; case 'memory': // Include pathname to help with Content-Type headers. diff --git a/packages/angular/build/src/builders/library/pipeline/build-action.ts b/packages/angular/build/src/builders/library/pipeline/build-action.ts index 294eb954421b..a430312ac925 100644 --- a/packages/angular/build/src/builders/library/pipeline/build-action.ts +++ b/packages/angular/build/src/builders/library/pipeline/build-action.ts @@ -7,10 +7,9 @@ */ import type { BuilderContext } from '@angular-devkit/architect'; -import { constants, copyFile, mkdir, writeFile } from 'node:fs/promises'; import path from 'node:path'; import type { ComponentStylesheetBundler } from '../../../tools/esbuild/angular/component-stylesheets'; -import { emitFilesToDisk } from '../../../tools/esbuild/utils'; +import { emitFilesToDisk } from '../../../utils/emit-files-to-disk'; import { toPosixPath } from '../../../utils/path'; import type { NormalizedLibraryOptions, SingleBuildState } from '../types'; import { collectAssetsToEmit } from './assets'; @@ -27,7 +26,6 @@ export function createSingleBuildState(): SingleBuildState { previousBundleResults: new Map(), pendingChangedEsmFiles: new Set(), pendingChangedDtsFiles: new Set(), - directoryExists: new Set(), }; } @@ -90,7 +88,7 @@ export async function buildAction(actionContext: BuildActionContext): Promise(filesToEmit, async (file) => { - const fullFilePath = path.join(options.outputPath, file.path); - const fileBasePath = path.dirname(fullFilePath); - if (fileBasePath && !directoryExists.has(fileBasePath)) { - await mkdir(fileBasePath, { recursive: true }); - directoryExists.add(fileBasePath); - } - - if (file.type === 'memory') { - await writeFile(fullFilePath, file.contents); - } else { - await copyFile(file.source, fullFilePath, constants.COPYFILE_FICLONE); - } - }); + await emitFilesToDisk(filesToEmit, (file) => path.join(options.outputPath, file.path)); buildState.hasEmittedManifests = true; buildState.hasEmittedTslib = hasTslibImport; diff --git a/packages/angular/build/src/builders/library/pipeline/utils.ts b/packages/angular/build/src/builders/library/pipeline/utils.ts index 8258c8874e42..9092a73005ef 100644 --- a/packages/angular/build/src/builders/library/pipeline/utils.ts +++ b/packages/angular/build/src/builders/library/pipeline/utils.ts @@ -26,7 +26,7 @@ export const TYPES_OUTPUT_DIR = 'types'; * Represents an in-memory file to be emitted to disk. */ export interface MemoryOutputFile { - type: 'memory'; + origin: 'memory'; /** The destination path where the file should be written. */ path: string; @@ -39,7 +39,7 @@ export interface MemoryOutputFile { * Represents an existing file on disk to be copied to a destination path. */ export interface DiskOutputFile { - type: 'disk'; + origin: 'disk'; /** The path to the source file on disk. */ source: string; @@ -62,7 +62,7 @@ export type OutputFile = MemoryOutputFile | DiskOutputFile; */ export function createDiskOutputFile(source: string, path: string): DiskOutputFile { return { - type: 'disk', + origin: 'disk', source, path, }; @@ -80,7 +80,7 @@ export function createMemoryOutputFile( contents: string | Uint8Array | Record, ): MemoryOutputFile { return { - type: 'memory', + origin: 'memory', path, contents: typeof contents === 'string' || contents instanceof Uint8Array diff --git a/packages/angular/build/src/builders/library/tests/behavior/watch_spec.ts b/packages/angular/build/src/builders/library/tests/behavior/watch_spec.ts index 2533da417909..415f24d269c0 100644 --- a/packages/angular/build/src/builders/library/tests/behavior/watch_spec.ts +++ b/packages/angular/build/src/builders/library/tests/behavior/watch_spec.ts @@ -6,6 +6,7 @@ * found in the LICENSE file at https://angular.dev/license */ +import { rm } from 'node:fs/promises'; import { executeLibraryBuilder } from '../../builder'; import { BASE_OPTIONS, LIBRARY_BUILDER_INFO, describeLibraryBuilder } from '../setup'; @@ -563,5 +564,42 @@ describeLibraryBuilder(executeLibraryBuilder, LIBRARY_BUILDER_INFO, (harness) => }, ]); }); + + it('should recreate deleted output directories on subsequent watch rebuilds', async () => { + harness.useTarget('build', { + ...BASE_OPTIONS, + watch: true, + }); + + await harness.executeWithCases([ + async ({ result }) => { + expect(result?.success).toBeTrue(); + expect(harness.hasFile('dist/lib/fesm2022/lib.mjs')).toBeTrue(); + + // Remove output subdirectory externally between rebuilds + await rm(harness.resolvePath('dist/lib/fesm2022'), { recursive: true, force: true }); + expect(harness.hasFile('dist/lib/fesm2022/lib.mjs')).toBeFalse(); + + // Trigger a rebuild + await harness.writeFile( + 'projects/lib/src/lib/lib.component.ts', + ` + import { Component } from '@angular/core'; + + @Component({ + selector: 'lib-recreated', + template: 'Recreated', + }) + export class LibComponent {} + `, + ); + }, + ({ result }) => { + expect(result?.success).toBeTrue(); + const content = harness.readFile('dist/lib/fesm2022/lib.mjs'); + expect(content).toContain('lib-recreated'); + }, + ]); + }); }); }); diff --git a/packages/angular/build/src/builders/library/types.ts b/packages/angular/build/src/builders/library/types.ts index 7ec8545a9c8e..d360cfe2c868 100644 --- a/packages/angular/build/src/builders/library/types.ts +++ b/packages/angular/build/src/builders/library/types.ts @@ -153,7 +153,4 @@ export interface SingleBuildState { /** Whether entry points in package.json changed since the last compilation. */ hasEntryPointsChanges?: boolean; - - /** Cache of output directory paths known to exist on disk. */ - directoryExists: Set; } diff --git a/packages/angular/build/src/builders/unit-test/runners/vitest/plugins.ts b/packages/angular/build/src/builders/unit-test/runners/vitest/plugins.ts index 0a8a2c8990b4..72308b6b57d6 100644 --- a/packages/angular/build/src/builders/unit-test/runners/vitest/plugins.ts +++ b/packages/angular/build/src/builders/unit-test/runners/vitest/plugins.ts @@ -322,7 +322,7 @@ async function loadResultFile(file: ResultFile): Promise { return textDecoder.decode(file.contents); } - return readFile(file.inputPath, 'utf-8'); + return readFile(file.source, 'utf-8'); } export function createVitestPlugins(pluginOptions: PluginOptions): Vite.Plugin[] { diff --git a/packages/angular/build/src/private.ts b/packages/angular/build/src/private.ts index 9db709640b57..6f98e4f8f0e9 100644 --- a/packages/angular/build/src/private.ts +++ b/packages/angular/build/src/private.ts @@ -34,7 +34,6 @@ export { // Tools export type { ExternalResultMetadata } from './tools/esbuild/bundler-execution-result'; -export { emitFilesToDisk } from './tools/esbuild/utils'; export { transformSupportedBrowsersToTargets } from './tools/esbuild/target'; export { SassCompiler } from './tools/sass/sass-service'; @@ -73,6 +72,7 @@ export { ComponentStylesheetBundler } from './tools/esbuild/angular/component-st export * from './utils/bundle-calculator'; export { checkPort } from './utils/check-port'; export { deleteOutputDir } from './utils/delete-output-dir'; +export { emitFilesToDisk } from './utils/emit-files-to-disk'; export { type I18nOptions, createI18nOptions, loadTranslations } from './utils/i18n-options'; export { IndexHtmlGenerator, diff --git a/packages/angular/build/src/tools/esbuild/utils.ts b/packages/angular/build/src/tools/esbuild/utils.ts index 3bbaabdd2400..e93bb295b439 100644 --- a/packages/angular/build/src/tools/esbuild/utils.ts +++ b/packages/angular/build/src/tools/esbuild/utils.ts @@ -17,11 +17,7 @@ import { OutputMode } from '../../builders/application/schema'; import { BudgetCalculatorResult } from '../../utils/bundle-calculator'; import { BundleStats, generateEsbuildBuildStatsTable } from '../../utils/stats-table'; -import { - BuildOutputAsset, - ExecutionResult, - PrerenderedRoutesRecord, -} from './bundler-execution-result'; +import { ExecutionResult, PrerenderedRoutesRecord } from './bundler-execution-result'; import { type BuildOutputFile, BuildOutputFileType, type InitialFileRecord } from './bundler-files'; export function logBuildStats( @@ -212,24 +208,6 @@ export function getFeatureSupport(nativeAsyncAwait: boolean): BuildOptions['supp }; } -const MAX_CONCURRENT_WRITES = 64; -export async function emitFilesToDisk( - files: readonly T[], - writeFileCallback: (file: T) => Promise, -): Promise { - // Write files in groups of MAX_CONCURRENT_WRITES to avoid too many open files - for (let fileIndex = 0; fileIndex < files.length;) { - const groupMax = Math.min(fileIndex + MAX_CONCURRENT_WRITES, files.length); - - const actions = []; - while (fileIndex < groupMax) { - actions.push(writeFileCallback(files[fileIndex++])); - } - - await Promise.all(actions); - } -} - interface BuildManifest { errors: string[]; warnings: string[]; diff --git a/packages/angular/build/src/tools/vite/middlewares/assets-middleware.ts b/packages/angular/build/src/tools/vite/middlewares/assets-middleware.ts index 3c38d000b30c..a1aa19361c5c 100644 --- a/packages/angular/build/src/tools/vite/middlewares/assets-middleware.ts +++ b/packages/angular/build/src/tools/vite/middlewares/assets-middleware.ts @@ -236,7 +236,7 @@ export function createBuildAssetsMiddleware( const outputFile = buildResultFiles.get(pathname.slice(1)); if (outputFile) { const contents = - outputFile.origin === 'memory' ? outputFile.contents : readHandler(outputFile.inputPath); + outputFile.origin === 'memory' ? outputFile.contents : readHandler(outputFile.source); const etag = `W/${calculateHash(contents)}`; if (checkAndHandleEtag(req, res, etag)) { diff --git a/packages/angular/build/src/utils/emit-files-to-disk.ts b/packages/angular/build/src/utils/emit-files-to-disk.ts new file mode 100644 index 000000000000..b6df74088451 --- /dev/null +++ b/packages/angular/build/src/utils/emit-files-to-disk.ts @@ -0,0 +1,71 @@ +/** + * @license + * Copyright Google LLC All Rights Reserved. + * + * Use of this source code is governed by an MIT-style license that can be + * found in the LICENSE file at https://angular.dev/license + */ + +import { constants, cp, mkdir, writeFile } from 'node:fs/promises'; +import { dirname } from 'node:path'; +import { runConcurrent } from './concurrency'; + +/** + * Maximum number of concurrent file system write/copy operations to avoid open file descriptor exhaustion. + */ +const MAX_CONCURRENT_WRITES = 64; + +/** + * Represents a file that can be emitted to disk from memory or copied from an existing path on disk. + */ +export type EmittableFile = + { origin: 'memory'; contents: string | Uint8Array } | { origin: 'disk'; source: string }; + +/** + * Writes or copies a collection of files to disk with bounded concurrency, + * ensuring parent directories are created once per invocation. + * + * @param files The collection of files to emit. + * @param resolveDestinationPath Callback returning the absolute destination path for a file, or `undefined` to skip it. + */ +export async function emitFilesToDisk( + files: readonly T[], + resolveDestinationPath: (file: T) => string | undefined, +): Promise { + if (files.length === 0) { + return; + } + + const directoryCreationPromises = new Map>(); + + await runConcurrent(files, MAX_CONCURRENT_WRITES, async (file) => { + const fullFilePath = resolveDestinationPath(file); + if (!fullFilePath) { + return; + } + + // Ensure output subdirectories exist + const fileBasePath = dirname(fullFilePath); + if (fileBasePath) { + let mkdirPromise = directoryCreationPromises.get(fileBasePath); + if (!mkdirPromise) { + mkdirPromise = mkdir(fileBasePath, { recursive: true }); + directoryCreationPromises.set(fileBasePath, mkdirPromise); + } + await mkdirPromise; + } + + if (file.origin === 'memory') { + // Write file contents + await writeFile(fullFilePath, file.contents); + + return; + } + + // Copy file contents + await cp(file.source, fullFilePath, { + mode: constants.COPYFILE_FICLONE, + preserveTimestamps: true, + }); + }); +} diff --git a/packages/angular/build/src/utils/emit-files-to-disk_spec.ts b/packages/angular/build/src/utils/emit-files-to-disk_spec.ts new file mode 100644 index 000000000000..028653028b43 --- /dev/null +++ b/packages/angular/build/src/utils/emit-files-to-disk_spec.ts @@ -0,0 +1,53 @@ +/** + * @license + * Copyright Google LLC All Rights Reserved. + * + * Use of this source code is governed by an MIT-style license that can be + * found in the LICENSE file at https://angular.dev/license + */ + +import assert from 'node:assert'; +import { existsSync } from 'node:fs'; +import { mkdtemp, readFile, rm, writeFile } from 'node:fs/promises'; +import { join } from 'node:path'; +import { type EmittableFile, emitFilesToDisk } from './emit-files-to-disk'; + +describe('emitFilesToDisk', () => { + let tempRoot: string; + + beforeEach(async () => { + const baseTmpDir = process.env['TEST_TMPDIR']; + assert(baseTmpDir, 'TEST_TMPDIR is not set'); + tempRoot = await mkdtemp(join(baseTmpDir, 'angular-cli-emit-files-test-')); + }); + + afterEach(async () => { + if (tempRoot) { + await rm(tempRoot, { recursive: true, force: true }); + } + }); + + it('should write memory files and copy disk files while creating nested directories', async () => { + const sourceFile = join(tempRoot, 'source-asset.txt'); + await writeFile(sourceFile, 'from-disk'); + + const files: (EmittableFile & { path: string })[] = [ + { origin: 'memory', path: 'nested/a/mem1.txt', contents: new TextEncoder().encode('mem-1') }, + { origin: 'memory', path: 'nested/a/mem2.txt', contents: 'mem-2' }, + { origin: 'disk', path: 'nested/b/disk1.txt', source: sourceFile }, + { origin: 'disk', path: 'nested/c/disk2.txt', source: sourceFile }, + { origin: 'memory', path: 'skipped/file.txt', contents: 'should-not-exist' }, + ]; + + const outDir = join(tempRoot, 'out'); + await emitFilesToDisk(files, (file) => + file.path.startsWith('skipped/') ? undefined : join(outDir, file.path), + ); + + expect(await readFile(join(outDir, 'nested/a/mem1.txt'), 'utf-8')).toBe('mem-1'); + expect(await readFile(join(outDir, 'nested/a/mem2.txt'), 'utf-8')).toBe('mem-2'); + expect(await readFile(join(outDir, 'nested/b/disk1.txt'), 'utf-8')).toBe('from-disk'); + expect(await readFile(join(outDir, 'nested/c/disk2.txt'), 'utf-8')).toBe('from-disk'); + expect(existsSync(join(outDir, 'skipped/file.txt'))).toBeFalse(); + }); +}); diff --git a/packages/angular/build/src/utils/test-files.ts b/packages/angular/build/src/utils/test-files.ts index 6790d007e220..db480686b66a 100644 --- a/packages/angular/build/src/utils/test-files.ts +++ b/packages/angular/build/src/utils/test-files.ts @@ -6,11 +6,10 @@ * found in the LICENSE file at https://angular.dev/license */ -import * as fs from 'node:fs/promises'; import path from 'node:path'; import { ResultFile } from '../builders/application/results'; import { BuildOutputFileType } from '../tools/esbuild/bundler-files'; -import { emitFilesToDisk } from '../tools/esbuild/utils'; +import { emitFilesToDisk } from './emit-files-to-disk'; /** * Writes a collection of build result files to a specified directory. @@ -20,29 +19,11 @@ import { emitFilesToDisk } from '../tools/esbuild/utils'; * @param files A collection of `ResultFile` objects, representing the build output. * @param testDir The absolute path to the directory where the files should be written. */ -export async function writeTestFiles(files: readonly ResultFile[], testDir: string): Promise { - const directoryExists = new Set(); +export function writeTestFiles(files: readonly ResultFile[], testDir: string): Promise { // Writes the test related output files to disk and ensures the containing directories are present - await emitFilesToDisk(files, async (file) => { - if (file.type !== BuildOutputFileType.Browser && file.type !== BuildOutputFileType.Media) { - return; - } - - const fullFilePath = path.join(testDir, file.path); - - // Ensure output subdirectories exist - const fileBasePath = path.dirname(fullFilePath); - if (fileBasePath && !directoryExists.has(fileBasePath)) { - await fs.mkdir(fileBasePath, { recursive: true }); - directoryExists.add(fileBasePath); - } - - if (file.origin === 'memory') { - // Write file contents - await fs.writeFile(fullFilePath, file.contents); - } else { - // Copy file contents - await fs.copyFile(file.inputPath, fullFilePath, fs.constants.COPYFILE_FICLONE); - } - }); + return emitFilesToDisk(files, (file) => + file.type === BuildOutputFileType.Browser || file.type === BuildOutputFileType.Media + ? path.join(testDir, file.path) + : undefined, + ); } diff --git a/packages/angular_devkit/build_angular/src/builders/extract-i18n/application-extraction.ts b/packages/angular_devkit/build_angular/src/builders/extract-i18n/application-extraction.ts index 68347fa0fb24..508b27e2d833 100644 --- a/packages/angular_devkit/build_angular/src/builders/extract-i18n/application-extraction.ts +++ b/packages/angular_devkit/build_angular/src/builders/extract-i18n/application-extraction.ts @@ -112,7 +112,7 @@ function setupLocalizeExtractor( if (file?.origin === 'memory') { content = textDecoder.decode(file.contents); } else if (file?.origin === 'disk') { - content = readFileSync(file.inputPath, 'utf-8'); + content = readFileSync(file.source, 'utf-8'); } if (content === undefined) { throw new Error('Unknown file requested: ' + requestedPath); From 9c645ece55f190ed7176ed8135ee0e5d30103c1e Mon Sep 17 00:00:00 2001 From: Alan Agius <17563226+alan-agius4@users.noreply.github.com> Date: Tue, 13 Oct 2026 15:21:37 +0000 Subject: [PATCH 606/787] refactor(@angular/build): use import resolution-mode for rolldown-plugin-dts types Use `{ with: { 'resolution-mode': 'import' } }` on the dynamic import type assertion for `rolldown-plugin-dts` and remove the custom ambient module declaration file (`types.d.ts`). --- .../src/builders/library/pipeline/bundler.ts | 5 +- .../src/builders/library/pipeline/types.d.ts | 54 ------------------- 2 files changed, 4 insertions(+), 55 deletions(-) delete mode 100644 packages/angular/build/src/builders/library/pipeline/types.d.ts diff --git a/packages/angular/build/src/builders/library/pipeline/bundler.ts b/packages/angular/build/src/builders/library/pipeline/bundler.ts index 64042bd37f92..5cd89a4b110d 100644 --- a/packages/angular/build/src/builders/library/pipeline/bundler.ts +++ b/packages/angular/build/src/builders/library/pipeline/bundler.ts @@ -439,7 +439,10 @@ async function bundleAllDts( // Ensure Rolldown's native binding is initialized via `loadRolldown()` before evaluating // `rolldown-plugin-dts`, which has top-level imports of `rolldown/experimental`. await loadRolldown(); - const { dts } = await import('rolldown-plugin-dts'); + const { dts } = (await import('rolldown-plugin-dts' as string)) as typeof import( + 'rolldown-plugin-dts', + { with: { 'resolution-mode': 'import' } } + ); const dtsSourcemap = !!options.declarationMap; // Filter out `rolldown-plugin-dts:resolver` because all `.d.ts` files are already emitted diff --git a/packages/angular/build/src/builders/library/pipeline/types.d.ts b/packages/angular/build/src/builders/library/pipeline/types.d.ts deleted file mode 100644 index 100c539f098c..000000000000 --- a/packages/angular/build/src/builders/library/pipeline/types.d.ts +++ /dev/null @@ -1,54 +0,0 @@ -/** - * @license - * Copyright Google LLC All Rights Reserved. - * - * Use of this source code is governed by an MIT-style license that can be - * found in the LICENSE file at https://angular.dev/license - */ - -declare module 'rolldown-plugin-dts' { - import type { Plugin } from 'rolldown'; - import type { IsolatedDeclarationsOptions } from 'rolldown/experimental'; - - interface Logger { - info: (...args: unknown[]) => void; - warn: (...args: unknown[]) => void; - error: (...args: unknown[]) => void; - } - interface GeneralOptions { - generator?: 'tsc' | 'oxc' | 'tsgo'; - entry?: string | string[]; - cwd?: string; - dtsInput?: boolean; - emitDtsOnly?: boolean; - tsconfig?: string | boolean; - tsconfigRaw?: unknown; - compilerOptions?: unknown; - sourcemap?: boolean; - resolver?: 'oxc' | 'tsc'; - cjsDefault?: boolean; - sideEffects?: boolean; - logger?: Logger; - } - - interface TscOptions { - build?: boolean; - incremental?: boolean; - parallel?: boolean; - eager?: boolean; - newContext?: boolean; - emitJs?: boolean; - } - - interface Options extends GeneralOptions, TscOptions { - oxc?: Omit; - tsgo?: TsgoOptions; - customLanguages?: unknown[]; - } - - interface TsgoOptions { - path?: string; - } - - export declare function dts(options?: Options): Plugin[]; -} From 95548f5ca757ec8305a633df85a198d68c4eae4a Mon Sep 17 00:00:00 2001 From: Angular Robot Date: Tue, 13 Oct 2026 06:55:37 +0000 Subject: [PATCH 607/787] build: lock file maintenance See associated pull request for more information. --- MODULE.bazel.lock | 2 +- pnpm-lock.yaml | 684 ++++++++++++---------------------------------- 2 files changed, 181 insertions(+), 505 deletions(-) diff --git a/MODULE.bazel.lock b/MODULE.bazel.lock index 38524a59eced..5f2282f7683b 100644 --- a/MODULE.bazel.lock +++ b/MODULE.bazel.lock @@ -384,7 +384,7 @@ "aspect_rules_jasmine": "2.0.4", "aspect_tools_telemetry": "0.5.2" }, - "last_notice": 3 + "last_notice": 0 } } }, diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index b6cf96a9c926..2d1df736b28c 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -293,7 +293,7 @@ importers: version: 3.0.0(esbuild@0.28.2)(lightningcss@1.33.0)(uglify-js@3.19.3) '@types/lodash': specifier: ^4.17.0 - version: 4.17.25 + version: 4.17.26 '@types/node': specifier: ^22.12.0 version: 22.20.5 @@ -398,7 +398,7 @@ importers: version: 1.4.3 prettier: specifier: ^3.0.0 - version: 3.9.9 + version: 3.9.10 puppeteer: specifier: 25.12.0 version: 25.12.0(bufferutil@4.1.0)(utf-8-validate@6.0.6) @@ -431,7 +431,7 @@ importers: version: 6.10.5(encoding@0.1.13)(supports-color@11.0.0) verdaccio-auth-memory: specifier: ^13.0.0 - version: 13.1.5(supports-color@11.0.0) + version: 13.1.6(supports-color@11.0.0) zone.js: specifier: ^0.16.0 version: 0.16.3 @@ -899,10 +899,10 @@ importers: version: link:../../ngtools/webpack webpack: specifier: 5.111.1 - version: 5.111.1(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.28)(uglify-js@3.19.3) + version: 5.111.1(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.29)(uglify-js@3.19.3) webpack-dev-server: specifier: 6.0.0 - version: 6.0.0(bufferutil@4.1.0)(supports-color@11.0.0)(utf-8-validate@6.0.6)(webpack@5.111.1(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.28)(uglify-js@3.19.3)) + version: 6.0.0(bufferutil@4.1.0)(supports-color@11.0.0)(utf-8-validate@6.0.6)(webpack@5.111.1(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.29)(uglify-js@3.19.3)) packages/angular_devkit/core: dependencies: @@ -975,7 +975,7 @@ importers: version: 6.0.3 webpack: specifier: 5.111.1 - version: 5.111.1(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.28)(uglify-js@3.19.3) + version: 5.111.1(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.29)(uglify-js@3.19.3) packages/schematics/angular: dependencies: @@ -1149,8 +1149,8 @@ packages: '@angular/core': 22.3.0-next.1 rxjs: ^6.5.3 || ^7.4.0 - '@asamuzakjp/css-color@7.1.3': - resolution: {integrity: sha512-1t1U8Cm3RBl9vh3RAZhjkPaduzLSvQJRToRrxpGR/eDRW99mOREleuu+mWfiFa795bUzjwht7NgphCKTs2ianQ==} + '@asamuzakjp/css-color@7.1.5': + resolution: {integrity: sha512-jCpAvj8apa7SKHZYogk0rbXB3Kb0hLFrpkWF+Ap+vBA5rirItnpv9NKyAyEuDuFizvl0qwnj6JWR70RGJ0rOlw==} engines: {node: ^22.22.2 || ^24.15.0 || >=26.0.0} '@asamuzakjp/dom-selector@9.2.4': @@ -1201,22 +1201,18 @@ packages: resolution: {integrity: sha512-wem6WaBj4NaVYVdNhLPPVacES6ZJ+KBBfSkTMD3YZxbP3rm3Di85tJU5ljaUNhaOynt+Aj0xruhYuzQBt8n71g==} engines: {node: '>=6.9.0'} - '@babel/helper-compilation-targets@8.0.6': - resolution: {integrity: sha512-HTrtZ4+iA0+kzdbCgvdSk1U4pEl3BvpGnlUbualCGNbrVhhQvhgBzurTUmqpWyvyHbWYWaIfdx2mOlL9LJjsew==} - engines: {node: ^22.18.0 || >=24.11.0} - '@babel/helper-compilation-targets@8.0.7': resolution: {integrity: sha512-ilAZCdOOlOVA7dQbaFNw2f/59p6GW33NxTopc3DvEE3efp3ZXTrGX/yZScaKw8/vd9bq31Ag0EcXiLw32bAgJg==} engines: {node: ^22.18.0 || >=24.11.0} - '@babel/helper-create-class-features-plugin@8.0.6': - resolution: {integrity: sha512-Hy7wG2Pk1LnAkFMq0CbBk789XMTYVzYGxR7tKgk+TOpZckQRME3Tdou4mMT/8DFjJFxFZ8R6UsS4DR/duBKlVA==} + '@babel/helper-create-class-features-plugin@8.0.7': + resolution: {integrity: sha512-7ug3KrOhNVPPxFFLTel0/pMzimKzU/vTlNJKVL/dKguCpmNJZjjibyFbWg+Qs8QHmiIZPNuZ2UNnDGdHWGEpOg==} engines: {node: ^22.18.0 || >=24.11.0} peerDependencies: '@babel/core': ^8.0.0 - '@babel/helper-create-regexp-features-plugin@8.0.5': - resolution: {integrity: sha512-TWnIgw21pAv/FbBKB8ks26DMxQ+A3aBdi1HUBp+QhqSE8QdOqJgSK/FEvdMYPTZcHBBJPZ5pN6DDKmC5ZYPJbg==} + '@babel/helper-create-regexp-features-plugin@8.0.7': + resolution: {integrity: sha512-pyia4a5cQ9fmUuimPO4pl3p8aX9aGBBMqZyNUmwhJGO/e3bIbbt/26Zun6SE1CRvNaUWiTsfLuZeaLX6EIIUWQ==} engines: {node: ^22.18.0 || >=24.11.0} peerDependencies: '@babel/core': ^8.0.0 @@ -1317,8 +1313,8 @@ packages: resolution: {integrity: sha512-Qpm8+wi5xfDkBfollanwriCcKniFfBmMmaKB01GVM6VGzKXo1fdxosZp04qEr5HM+LKhwr3hG1yRy8+ORsficA==} engines: {node: ^22.18.0 || >=24.11.0} - '@babel/helpers@7.29.7': - resolution: {integrity: sha512-1k2lAGRMfHTcwuNYcCNUmaUffmQv8KWMfh2iJUUeRlwlwH4FdNG7mfPI10NPfLHJFThE4Tyr4mv7kTNZOiPuBg==} + '@babel/helpers@7.29.10': + resolution: {integrity: sha512-EMCx3AGZ3WfAl6ht7AyQoPm2Lh+BGYEMdc4Q6Hf7uSCDOZFuLq44qNwL+iaim8VlyYhRAo4X43+weadK8ZB4Yg==} engines: {node: '>=6.9.0'} '@babel/helpers@8.0.7': @@ -1330,11 +1326,6 @@ packages: engines: {node: '>=6.0.0'} hasBin: true - '@babel/parser@8.0.6': - resolution: {integrity: sha512-LpGDIYJAzc3Y3PT9x+FxBrGYu2PlWxLmyN7SwPTzaX0LSwEmFJBsRnPBqmaXF2r1v+Zhz6lNiEJ+7yKtM5+Ugg==} - engines: {node: ^22.18.0 || >=24.11.0} - hasBin: true - '@babel/parser@8.0.7': resolution: {integrity: sha512-UkDwEbPO1px2JQSrdh4qIgaH1JgG7GO/pFeJkpxhDxIETkT/QvGpnigXIw75ViHYPtIgKITmVUJqLjiO+JuWjA==} engines: {node: ^22.18.0 || >=24.11.0} @@ -1710,14 +1701,10 @@ packages: resolution: {integrity: sha512-eAD0QW/AlbamBbw0FeGiwasbCVPq5ncW0HNVyLP3B9czqLyh4gvw+5JTSNt6le9+ziAU7mqDZsKTHf3jTb4chQ==} engines: {node: ^22.18.0 || >=24.11.0} - '@babel/traverse@7.29.8': - resolution: {integrity: sha512-I5z7H3bf/41ktsNVLtpN0wAa336HkqIHQ5BuPLEhTkt1jVSyZpeNKIzTgEWmlxjdg81R0IgUCcaE+Ok3NvrfZg==} + '@babel/traverse@7.29.10': + resolution: {integrity: sha512-B3lYAs2nkKskbgQ1nfy8Ma9ao9Q1rntTAQHrzzyDuj+TSO+X3le6PfWwqDvodsb+OumE10eMFfuMCTQSQ5iuIQ==} engines: {node: '>=6.9.0'} - '@babel/traverse@8.0.6': - resolution: {integrity: sha512-ilYV+qLStGzSKLipJlETdvdtpK3rAuwfCmCoGKv15MU4EoeIuLkespSNoNLFGOPSciEHx9TLWtN5mv0fz5w5mQ==} - engines: {node: ^22.18.0 || >=24.11.0} - '@babel/traverse@8.0.7': resolution: {integrity: sha512-bVV0brinsTWgc6ptSIoQo3GbITtl0VZAqEUJbHHcyfDPEu+q/fEvlYEa+6H85HoK8IdksKBFtKJbJFZ6Kff+zg==} engines: {node: ^22.18.0 || >=24.11.0} @@ -1746,8 +1733,8 @@ packages: resolution: {integrity: sha512-6zABk/ECA/QYSCQ1NGiVwwbQerUCZ+TQbp64Q3AgmfNvurHH0j8TtXa1qbShXA6qqkpAj4V5W8pP6mLe1mcMqA==} engines: {node: '>=18'} - '@bramus/specificity@2.4.2': - resolution: {integrity: sha512-ctxtJ/eA+t+6q2++vj5j7FYX3nRu311q1wfYH3xjlLOsczhlhxAg2FWNUXhpGvAw3BWo1xBcvOV6/YLc2r5FJw==} + '@bramus/specificity@2.4.3': + resolution: {integrity: sha512-0GEz8qJWokkUVYQYRukmkSHIFNoBH8QTreeHrAFbvz1XFYc3Y+puhMs8PQ5x8GNugiC2l5jvDBXKLbBIByeSBw==} hasBin: true '@bufbuild/protobuf@2.16.0': @@ -2304,8 +2291,8 @@ packages: '@modelcontextprotocol/sdk': optional: true - '@grpc/grpc-js@1.14.5': - resolution: {integrity: sha512-7VZM+SVdEcUUqSQeNI3zM8Qs/BhQKZndPo2h5VkYkAM8Iz0wJIa8mKV5ekQGqG8UUsnkQ0NMxIxwkIHYvj0qOw==} + '@grpc/grpc-js@1.14.6': + resolution: {integrity: sha512-SgC/B3/VZ8lTyOZ4Cwk6f1skWhmkNAaVfiX90qd5u1rRXGKk1//8FTUEN9GvOUq7rfWIqAYkA3CoyumYVpOS6g==} engines: {node: '>=12.10.0'} '@grpc/grpc-js@1.9.16': @@ -2971,14 +2958,14 @@ packages: resolution: {integrity: sha512-gLyJlPHPZYdAk1JENA9LeHejZe1Ti77/pTeFm/nMXmQH/HFZlcS/O2XJB+L8fkbrNSqhdtlvjBVjxwUYanNH5Q==} engines: {node: '>=8.0.0'} - '@opentelemetry/context-async-hooks@2.11.0': - resolution: {integrity: sha512-Tr79DyWI8itsBdg+jH+opjfrwLzX+erk1/ExkIwhWoAVjVrJIn2y5+cGjTC0Vy8fyNIA/y8wuJPZwr1T3xCZeQ==} + '@opentelemetry/context-async-hooks@2.12.0': + resolution: {integrity: sha512-iK/1nD7mmZVkuYjVjkdFBiCvzntJdFny1S3CYbUYyOq7V5enL6XX+gJ7eh965L1LnS11VA8mQ7Ej/ck04SB0MQ==} engines: {node: ^18.19.0 || >=20.6.0} peerDependencies: '@opentelemetry/api': '>=1.0.0 <1.10.0' - '@opentelemetry/core@2.11.0': - resolution: {integrity: sha512-7YP44XH0tV6+Mb54x2YGf84i7yi+31MBZlE8JwvozkxyTvXbSp10X7cI7YE49ChJ3shMJoBmCJF3+1QFBJctGA==} + '@opentelemetry/core@2.12.0': + resolution: {integrity: sha512-1HsSAuvT4/my0QrXWsyXFdWjKaPeCHsismKZgEEIb8NK13LP6DrMRlsUbvD/0F9mDWK3xDom9AMv3IscxgOnOQ==} engines: {node: ^18.19.0 || >=20.6.0} peerDependencies: '@opentelemetry/api': '>=1.0.0 <1.10.0' @@ -3109,9 +3096,6 @@ packages: cpu: [x64] os: [win32] - '@oxc-project/types@0.151.0': - resolution: {integrity: sha512-J1yXrIlNDZVzE3ada310xeAw7nH8yCAyLPuUIsjKatFPmfn5bS1oW+cM+QsGOtVWd5nhSpbwZWx/rue+r5Z+PA==} - '@oxc-project/types@0.152.0': resolution: {integrity: sha512-oM/5rLBm2tPkg0iBgkH/FOeR3PCDpY19GTgAZjMFM8h9WI9VW7cLgzp6nwtarYKmovavIQZ+Fe/RKX/8C8O/Rw==} @@ -3294,85 +3278,42 @@ packages: yauzl: optional: true - '@rolldown/binding-android-arm-eabi@1.2.11': - resolution: {integrity: sha512-A5kXfGKvKWWZE0TtPrfsvT+q4Y5d1QG8gGUzpYjGydM+fARM9MuX90PrXYXe0XbsDVgyxxNzHo6giCj90bsFNw==} - engines: {node: ^20.19.0 || >=22.12.0} - cpu: [arm] - os: [android] - '@rolldown/binding-android-arm-eabi@1.2.12': resolution: {integrity: sha512-dB/a1214qKfHMXCpgqR4OZT+jS4kTyEXbQGJPqzobt5EwH5rX080pxE37alt3RzvR1bf1Yz/yGqRfrYAxuPw0A==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm] os: [android] - '@rolldown/binding-android-arm64@1.2.11': - resolution: {integrity: sha512-z6cTycz+iJ4PVkuL4HHW4DfTfoeU/2nqYYuSOrTmH7yHK5Y0LCOnA03V4ZNxavyVaU1oOqUgIg2klN/s+USGOA==} - engines: {node: ^20.19.0 || >=22.12.0} - cpu: [arm64] - os: [android] - '@rolldown/binding-android-arm64@1.2.12': resolution: {integrity: sha512-7KHFgQ5VJxIHcLlrwrc3Xbds7oTNQT7Pgi9gQCJKrd2VGab/UksIOYp6VD8MzCstGxOKMgNamPwUCfxPdP1OHg==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [android] - '@rolldown/binding-darwin-arm64@1.2.11': - resolution: {integrity: sha512-jShvqNtP6vDC6/A5JOAzbVV+DkgHqhl/ScVCJEbt+TUY6QYz7YnXcrg3sLtFBniro0f/Ld50ZwCWA6f7KYD1nQ==} - engines: {node: ^20.19.0 || >=22.12.0} - cpu: [arm64] - os: [darwin] - '@rolldown/binding-darwin-arm64@1.2.12': resolution: {integrity: sha512-3YIhqHD96nA5SaYNRBR16HnGv4oavZvXfD/ayHM+oYZ0WD/8lBAtf6zQua4kEyAvpqrluKXl0lnOBoiNby7x9w==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [darwin] - '@rolldown/binding-darwin-x64@1.2.11': - resolution: {integrity: sha512-f2i2xiNWq1Z1l2++q2fuhZRdLAT3aqxD6vRNm1RAxpUoBcdqNB3C0s1Bt+K+PbEx2F5F4gQp6hqKkphCY/xF9w==} - engines: {node: ^20.19.0 || >=22.12.0} - cpu: [x64] - os: [darwin] - '@rolldown/binding-darwin-x64@1.2.12': resolution: {integrity: sha512-UuuJ35MFw4gmFOrE9pEqIV+K3syIKveph+Qc1/ljHZVdoDW4pz/JHR/eMVom+TZGl/5OOvGJOWaOCVt3ZfqhxA==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [darwin] - '@rolldown/binding-freebsd-x64@1.2.11': - resolution: {integrity: sha512-4Ir5FSOKIAMr4r0kExpt1s3bMgzJU3rA45AYOHtQpls0oNeqcYBKrWMlckrYH4KCfGLfkfn1tN1dmZPMVsdXow==} - engines: {node: ^20.19.0 || >=22.12.0} - cpu: [x64] - os: [freebsd] - '@rolldown/binding-freebsd-x64@1.2.12': resolution: {integrity: sha512-uMvssit0a4W+/7D8CbHUvG719mH3R2jwXAlh/XcPvuHTE0g++LymF88DCGNX0HM2rBOn0xrzgXktIB6fLSJBTQ==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [freebsd] - '@rolldown/binding-linux-arm-gnueabihf@1.2.11': - resolution: {integrity: sha512-/gnRDM+39BROzAN/k1OZjDPnDMcZxB/0EUxKjONO5yVkNEvlsoMDrxGNKgZi/ttFriS2gwlDNzB65pvNbFOXIQ==} - engines: {node: ^20.19.0 || >=22.12.0} - cpu: [arm] - os: [linux] - '@rolldown/binding-linux-arm-gnueabihf@1.2.12': resolution: {integrity: sha512-XcFu0R0xWnwzSf4IQgFH1rJIckPN1pLy2R+4r9IDB7Yfu/ys9cVqfa4pBrMHj7a3gl8mIR4nRNPg0e5IvEVs6g==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm] os: [linux] - '@rolldown/binding-linux-arm64-gnu@1.2.11': - resolution: {integrity: sha512-PFaK8HwvAHbaKbBcDNQihjMKYvFnA5hiENx/l5tphTDz1E0WFp32l0A7aq7lyUwGsRw/xSrNIy/gIK4thrSCrw==} - engines: {node: ^20.19.0 || >=22.12.0} - cpu: [arm64] - os: [linux] - libc: [glibc] - '@rolldown/binding-linux-arm64-gnu@1.2.12': resolution: {integrity: sha512-260UrKgn8tz39ak+SMDOirKzr7V04M9dWPw5llW00SwBivCZoWcRBKV1d8cXnRkUmSZA3BdiUmBHWk7734Ulpw==} engines: {node: ^20.19.0 || >=22.12.0} @@ -3380,13 +3321,6 @@ packages: os: [linux] libc: [glibc] - '@rolldown/binding-linux-arm64-musl@1.2.11': - resolution: {integrity: sha512-AskzJUIKRLPxkruR1wLKewGbOw+EYfU/9lOrBFj4AFrEA8hPpKFnODWNu2WLaNs0QNkEb9QIJufmVZZIL/bJlg==} - engines: {node: ^20.19.0 || >=22.12.0} - cpu: [arm64] - os: [linux] - libc: [musl] - '@rolldown/binding-linux-arm64-musl@1.2.12': resolution: {integrity: sha512-5YK1I9SqDkbPgc1IA8BgDl34suqUS2q0KWnBrirm0E51YjOs6eo6dV6jbQfNE/argHRSvd0QUGgtpIoYx+WWpw==} engines: {node: ^20.19.0 || >=22.12.0} @@ -3394,13 +3328,6 @@ packages: os: [linux] libc: [musl] - '@rolldown/binding-linux-ppc64-gnu@1.2.11': - resolution: {integrity: sha512-qlUGAheh2yh8afH7QBgx0PrRHN85hKnNd78x8MeMhXivuevgd8vgf6/CstOzmNKY/lLTHvNTrPy98cLnAugzJw==} - engines: {node: ^20.19.0 || >=22.12.0} - cpu: [ppc64] - os: [linux] - libc: [glibc] - '@rolldown/binding-linux-ppc64-gnu@1.2.12': resolution: {integrity: sha512-Rkcrmp7eFRg74yL5fXEU91JEWbdEPLevWwGtXpmhbjlD1StScbWTmO94Bhly+Mo+ketKYkdmM1vNUKeWSlx8cQ==} engines: {node: ^20.19.0 || >=22.12.0} @@ -3408,13 +3335,6 @@ packages: os: [linux] libc: [glibc] - '@rolldown/binding-linux-s390x-gnu@1.2.11': - resolution: {integrity: sha512-secpEad+0vCbSfn8upFySkDskv+bGPk3THSDS9Y89yc4rb4kzqHp8Dmyd9BkQW4SnhNXBZCl/6CrO//hZahNJQ==} - engines: {node: ^20.19.0 || >=22.12.0} - cpu: [s390x] - os: [linux] - libc: [glibc] - '@rolldown/binding-linux-s390x-gnu@1.2.12': resolution: {integrity: sha512-qvK4DuAsQc2BSjlx+Xr+IzOIvvxbGZqxFwdWfG6F518Erj0GGISyQbJ6pIappnOxlNPzNHvo/L0BwB30GZ+zVw==} engines: {node: ^20.19.0 || >=22.12.0} @@ -3422,13 +3342,6 @@ packages: os: [linux] libc: [glibc] - '@rolldown/binding-linux-x64-gnu@1.2.11': - resolution: {integrity: sha512-mOVBT3dPpkWm8XBWPmU4bf+U6dYDLeMo/9ojUmis4N0L5uu10qra5vOyngZ7/PSdoE4G9KvRt4bloRxNjLas7A==} - engines: {node: ^20.19.0 || >=22.12.0} - cpu: [x64] - os: [linux] - libc: [glibc] - '@rolldown/binding-linux-x64-gnu@1.2.12': resolution: {integrity: sha512-Q9uLBO53Xd4QIq1WOycVQyPP1O4HhraEV2qqb3uTrnVw6QZih9duY4vNXOivL1xoUS1/z+W8eF4NMfl2a8Sdjw==} engines: {node: ^20.19.0 || >=22.12.0} @@ -3436,13 +3349,6 @@ packages: os: [linux] libc: [glibc] - '@rolldown/binding-linux-x64-musl@1.2.11': - resolution: {integrity: sha512-Is78i9A8Ui4SqcxUwFJ9uMmjDn58IbVTjFWYdQestFEgeuEmHMLGNriXnVJKkwG2YiZjw8cP0zCTyDMdDGtOOg==} - engines: {node: ^20.19.0 || >=22.12.0} - cpu: [x64] - os: [linux] - libc: [musl] - '@rolldown/binding-linux-x64-musl@1.2.12': resolution: {integrity: sha512-3IBxWFMjbOZskDPKv8Lf9BCnahlKuHthWkYnyIxOH/QcJrFcS4EmcenthApkwr/5+nEqZlLzeYbxeMaX7A5u4g==} engines: {node: ^20.19.0 || >=22.12.0} @@ -3450,36 +3356,18 @@ packages: os: [linux] libc: [musl] - '@rolldown/binding-openharmony-arm64@1.2.11': - resolution: {integrity: sha512-dUCXneZ87INUMyQ0D+C0HrEBNUPNXHaPmU5GTjyKTJEiussw9Kaj5Ln8UztPe4epV/ffvgNBEadksdYhmW6xJA==} - engines: {node: ^20.19.0 || >=22.12.0} - cpu: [arm64] - os: [openharmony] - '@rolldown/binding-openharmony-arm64@1.2.12': resolution: {integrity: sha512-xtX61xg4LKPkPWilZU1ynKClz5Gj4bf74LML4r3eVLWumKnGjoEr1OSHQhMdbBDoYTi+yjrujvpZe2pUnqCrrA==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [openharmony] - '@rolldown/binding-win32-arm64-msvc@1.2.11': - resolution: {integrity: sha512-jByxb6qfd+bH1xUd0qnfFnb17i9sWBPY2tOavJ0l3tdr3OTu+Kvtm8cd/JV5nFt657b1VqGltxg9olOEfofXWw==} - engines: {node: ^20.19.0 || >=22.12.0} - cpu: [arm64] - os: [win32] - '@rolldown/binding-win32-arm64-msvc@1.2.12': resolution: {integrity: sha512-At7fPB6PCaIjzgIhEZFxuT+BBFqiQibJDT4d3PhiR3f4E7bbMZF4aKblbFfEM3sETRDd1YiQx/+U/g/B/ou5Ew==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [win32] - '@rolldown/binding-win32-x64-msvc@1.2.11': - resolution: {integrity: sha512-/PzKqzAJ03i19oy2ItPvyvaVjOjBCNnfaJs8yvUdGBKmiESgnrJSQ2awd81QzFbbnAmu7YO9ZnJrDCb9VSJPRA==} - engines: {node: ^20.19.0 || >=22.12.0} - cpu: [x64] - os: [win32] - '@rolldown/binding-win32-x64-msvc@1.2.12': resolution: {integrity: sha512-WIw2haVKwjuYdXkHaoC0mF8Le71TuCBxjrdKqLbJGctbBABj+ClfmNvtbOnzpq3RokNo5+V1qhtSzJyXorsklQ==} engines: {node: ^20.19.0 || >=22.12.0} @@ -3808,8 +3696,8 @@ packages: '@types/loader-utils@3.0.0': resolution: {integrity: sha512-oOi4OGpiLUbb+Q/cN9FIkkDFgOpOGZ2cUAzb5i03wrGstnG6Syx1WDMhSiB5rcP10XX7cw7Uev8mv++/aplnNg==} - '@types/lodash@4.17.25': - resolution: {integrity: sha512-+K1NIO8I+F9/wNulfVvu23QYd0Pe9/OCqRrim4NoYIf1VoEDL90Ve4ClzpyqBLc7NpGGWRvYNCKZ1BE/Jpf8dQ==} + '@types/lodash@4.17.26': + resolution: {integrity: sha512-48NWfiY6oNcKOh47Z4h+sIvwcQR91h6KPhaYKgeMIrkT2jV82Gy90SErj60vW8jQbeMSOSbhIv3bZ7JoqPPVhA==} '@types/micromatch@2.3.35': resolution: {integrity: sha512-J749bHo/Zu56w0G0NI/IGHLQPiSsjx//0zJhfEVAN95K/xM5C8ZDmhkXtU3qns0sBOao7HuQzr8XV1/2o5LbXA==} @@ -3927,10 +3815,6 @@ packages: eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 typescript: '>=4.8.4 <6.1.0' - '@typescript-eslint/types@8.71.0': - resolution: {integrity: sha512-cJ4OoxPGWvFnBTnSZyaU+qJzGTqPTGJY+gDchj6cRyLRdmIdt4rcsE4twj+zPfrNiWuVi38wijHzShL++Z9atQ==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@typescript-eslint/types@8.71.1': resolution: {integrity: sha512-ybYnPTUwg3VQQOFEiBPLs8Jxl1ry2vXdn1kVKguomBbvxpetdu3MKTNDqFNUrlG8ylP9MpZosmXMFYlGQHk1oQ==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} @@ -3964,6 +3848,10 @@ packages: resolution: {integrity: sha512-KRYepjgpSgrYYNHjmg77F9Mp7FMzQ0f9dcNc2AP3fmCmQMx0IWH6TYe4okvqkASoYhLnil5NRWqjO4Z4qSOHVg==} engines: {node: '>=22'} + '@verdaccio/core@8.3.3': + resolution: {integrity: sha512-Vhfpo9MIwUOIsNQCGmTKqYn2l73261YQ6NCmRS47NbpXi5YWuSGf7I6i4dIVMZVG7UUtz9633754WtzFFAgFvg==} + engines: {node: '>=22'} + '@verdaccio/file-locking@13.1.0': resolution: {integrity: sha512-rGFfdyCZdgpbkROJJfjOA01R5BFtzrnDAhNIkxxc/yWZ6Cir+MRHpEbN2weOEPAwYDke9Wms4JKhpsStu+iV8Q==} engines: {node: '>=22'} @@ -4298,8 +4186,8 @@ packages: peerDependencies: acorn: ^6.0.0 || ^7.0.0 || ^8.0.0 - acorn@8.18.0: - resolution: {integrity: sha512-lGq+9yr1/GuAWaVYIHRjvvySG5/4VfKIvC8EWxStPdcDh/Ka7FG3twP6v4d5BkravUilhIAsG4Qj83t02LWUPQ==} + acorn@8.19.0: + resolution: {integrity: sha512-oJlA3XiRm7Cyk6qFD2Jn8ak9B7jSy0qy00ADO3+8dpT0LSjFihQYv4C02LFCSYJV3Q37xYwwRy5m+IpIiUzqWw==} engines: {node: '>=0.4.0'} hasBin: true @@ -4522,8 +4410,8 @@ packages: bare-abort-controller: optional: true - bare-fs@4.8.2: - resolution: {integrity: sha512-+ZI68KHMUvosXfKbg/UOHK0tbCdRnegbvPEdEcZ3Nd6TetieQsJPRXBRXPdLyy8+3VSEbPXtsumTpEtt78xv9w==} + bare-fs@4.8.4: + resolution: {integrity: sha512-MPC2eyrpbk3A873sK4y6rk+Iv4o2enxTjHZ8zH3HO0mjrpm5XjnguY2XmfidIsDV6vnjpbMBKUAJpV0ISD2SsQ==} engines: {bare: '>=1.28.0'} peerDependencies: bare-buffer: '*' @@ -4554,8 +4442,8 @@ packages: base64-js@1.5.1: resolution: {integrity: sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==} - baseline-browser-mapping@2.11.27: - resolution: {integrity: sha512-ElY12DaROGuan+lMmZ8Cvo/ZUbXPe7Enc/9VU/b1T3Kp4dwytRcNdR8DoSJN5SNJT/CuvcCA0DHDVmMOCePdRQ==} + baseline-browser-mapping@2.11.28: + resolution: {integrity: sha512-br0LOmjJqr6Rt4AEkadbcNf67Zpo7EPwKsWbjnRrJIa1QYFHQBqM4C7F2WTbV8ahTEcg1Eo+Y0aWjjORInYFyA==} engines: {node: '>=6.0.0'} hasBin: true @@ -4702,8 +4590,8 @@ packages: resolution: {integrity: sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==} engines: {node: '>=6'} - caniuse-lite@1.0.30001814: - resolution: {integrity: sha512-/Uaf1lAzr59XcMpW0o96WoEfr+VXK2OX4U9AgFoiSHsVJ4HppnIFUjtYzsyDH2+tgANaQb2/oxYGwCPapN1FpA==} + caniuse-lite@1.0.30001815: + resolution: {integrity: sha512-uDybUEyfgbyJJ93J1vikTylBX31AkdVYeVPeffMQpf8XN7hSfr0oZOn4VFOIMNvtU5+rHvC5Udg2TgtJKHm23Q==} caseless@0.12.0: resolution: {integrity: sha512-4tYFyifaFfGacoiObjJegolkwSU4xQNGbVgUiNYVUxbQ2x2lUsFvY4hVgVzGiIe6WLOPqycWXA40l+PWsxthUw==} @@ -5169,8 +5057,8 @@ packages: engines: {node: '>=0.12.18'} hasBin: true - electron-to-chromium@1.5.444: - resolution: {integrity: sha512-5ss/uJfoDYDHT0lfJzT6FbcskIzROIOPf0BbbFkGcvDzoJU7i//9GDrwwIHQVmIsrAGiF3ihpADBRIsrEFt1rQ==} + electron-to-chromium@1.5.452: + resolution: {integrity: sha512-cVvk1YBSj6571VmV6hdJTqj94Y79xSu8cj6Y9t6ae4Y4431z8/7EJFvu3rVp90xhfuv9BpPKUmaLfTo4+FOGBg==} emoji-regex@10.6.0: resolution: {integrity: sha512-toUI84YS5YmxW219erniWD0CIVOo46xGKColeNQRgOzDorgBi1v4D71/OFzgD9GO2UGKIv1C3Sp8DAn0+j5w7A==} @@ -6366,8 +6254,8 @@ packages: resolution: {integrity: sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==} engines: {node: '>=0.10.0'} - launch-editor@2.14.1: - resolution: {integrity: sha512-QWBrQsMpH7gPr965dsKD/3cKWiNoTjpATQf++Xq63N6sKRGMwlVXz41O1IZTMfZQgBctD/K5Zt06+/I6pP6+HA==} + launch-editor@2.14.2: + resolution: {integrity: sha512-NHJEb30MGBCkmZXLZwz25t37QR4aY03ZzPYUJXOJaOa92uWwExI9SBQUuIznBYc1xkD7cJNGX7oc3Nl3sq2kQQ==} less-loader@13.0.0: resolution: {integrity: sha512-TIa8d6znKH634Mg+7OU3jevZT6KeOhh0amW+YeMPD0GM9buUn5Y7HvtyCR5pUDdLaFfqLA8AX5PTSIHMNSexEA==} @@ -6589,9 +6477,6 @@ packages: magic-string@0.30.21: resolution: {integrity: sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==} - magic-string@1.4.2: - resolution: {integrity: sha512-vG+rjFRj1PqdIBozIxAGMjPlOhaVe+GXpbttY/iSK7rGcJRMlwNJO7dcUwmUqkymsFLJiNGI06t4D7Fr7yRC9g==} - magic-string@1.4.3: resolution: {integrity: sha512-z12OxmaPGE0F4xlpGdjuAUckipLpQlTAuAmyGhNoD7ODpYUzvDfvtxUbjM/jwznyP178oju/KDdyi220wNJ0RQ==} @@ -6816,8 +6701,8 @@ packages: resolution: {integrity: sha512-dkEJPVvun4FryqBmZ5KhDo0K9iDXAwn08tMLDinNdRBNPcYEDiWYysLcc6k3mjTMlbP9KyylvRpd4wFtwrT9rw==} engines: {node: ^20.17.0 || >=22.9.0} - nanoid@3.3.19: - resolution: {integrity: sha512-Y2tUNy4ouw6tq5oDSKeQYGOyhkUBhNOcGV/02KC+6kd9eDGqdZd++mjMiIDilrBYvjEnCYvVtsuHCuP+okSfug==} + nanoid@3.3.20: + resolution: {integrity: sha512-uKdg2G3GNCKQn9byYOpxbGqrT2fGO5KRt5J/8b3pok8rT6qxGWF6hxMyJiEYtAf+FVyYuD9hRaDqX5uPFYJ4ZQ==} engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} hasBin: true @@ -6902,8 +6787,8 @@ packages: resolution: {integrity: sha512-LA4ZjwlnUblHVgq0oBF3Jl/6h/Nvs5fzBLwdEF4nuxnFdsfajde4WfxtJr3CaiH+F6ewcIB/q4jQ4UzPyid+CQ==} hasBin: true - node-releases@2.0.57: - resolution: {integrity: sha512-kQK9LGGFiHtrWiNhZtA7Qbw17AQz+dmsEKODRIVTXA9+e5MS/2gZEBhYJt13GrAz5/IOZKddH/0Z3TP/Zgo+yw==} + node-releases@2.0.58: + resolution: {integrity: sha512-BdiKAgbfRlvfMq/XzO/AF9NPmaA8a+YpLAyAFTVFBj3gARrAIfWvNq7Q7NE4se3KgFu0KkrvQMxTS0XVnsGzHg==} engines: {node: '>=18'} normalize-path@3.0.0: @@ -7222,10 +7107,6 @@ packages: postcss-value-parser@4.2.0: resolution: {integrity: sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==} - postcss@8.5.28: - resolution: {integrity: sha512-RRuzqDtt5Y9h3quz5hWhK+TPnsmVs6WwSU6LkJMeY4HstUEDuYTG8UJSdawMRzmzAtV+KEoG8N3Qg2qLy5vM/A==} - engines: {node: ^10 || ^12 || >=14} - postcss@8.5.29: resolution: {integrity: sha512-49cGhUbXj8Qenv0iTMxA1cFBzxXoctpC9Ujd77t1WcbJIr6nF/eI7g/8MgxrYldFRuAXvja7xQRwavoW7kgrxQ==} engines: {node: ^10 || ^12 || >=14} @@ -7238,8 +7119,8 @@ packages: resolution: {integrity: sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==} engines: {node: '>= 0.8.0'} - prettier@3.9.9: - resolution: {integrity: sha512-Z/CJHIkdujO/OtN7nXUii0Rf3VT5SRuhjBA82Xvu2XhBUgX3nhP67T0LHceBdQLex7OOFGTox+Q5Yg8Jk2Qivg==} + prettier@3.9.10: + resolution: {integrity: sha512-skGHTH1Yb9QvaTC4hWnRTzEYtCpApF0UMBPz+t/0ZPzP8ihefo/btKd+QA7pUE0fEwA1SbS/NmhyEcstdXOIdA==} engines: {node: '>=14'} hasBin: true @@ -7256,8 +7137,8 @@ packages: process-warning@1.0.0: resolution: {integrity: sha512-du4wfLyj4yCZq1VupnVSZmRsPJsNuxoDQFdCFHLaYiEbFBD7QE0a+I4D7hOxrVnh78QE/YipFAj9lXHiXocV+Q==} - process-warning@5.1.0: - resolution: {integrity: sha512-jQSaVHsPgtyw60e1rQ/A+/ArPEj/S8pS/vFnyGa/gYFXrKk/6RuDkoqVDQ5NI5MmS01698ltlAk0NoDBNLujRw==} + process-warning@5.1.1: + resolution: {integrity: sha512-oCkNVj4OKnKEcocVBcDfiIugN1/cE6rgfT3nCtzeqZPA8+rIxMaQ0xXzIkGP8Gj2qUaP1UR7uhJ1VD8lUCpzCg==} process@0.11.10: resolution: {integrity: sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A==} @@ -7373,8 +7254,8 @@ packages: resolution: {integrity: sha512-yjavECdqeZ3GLXNgRXgeQEdz9fvDDkNKyHnbHRFtOr7/LcfgBcmct7t/ET+HaCTqfh06OzoAxrkN/IfjJBVe+g==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} - readable-stream@4.7.0: - resolution: {integrity: sha512-oIGGmcpTLwPga8Bn6/Z75SVaH1z5dUut2ibSyAMVhmUggWpmDn2dapB0n7f8nwaSiRtepAsfJyfXIO5DCVAODg==} + readable-stream@4.8.0: + resolution: {integrity: sha512-2jhTTU3Eilp/2DMT71gbcoqC35eQHasMJH0RHkYxwlxIv3+FR6Y5xAFZIwEGLxKkjZYEFlsiMNIdwUqjK2lLHQ==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} readdirp@3.6.0: @@ -7410,15 +7291,15 @@ packages: resolution: {integrity: sha512-dYqgNSZbDwkaJ2ceRd9ojCGjBq+mOm9LmtXnAnEGyHhN/5R7iDW2TRw3h+o/jCFxus3P2LfWIIiwowAjANm7IA==} engines: {node: '>= 0.4'} - regexpu-core@6.5.2: - resolution: {integrity: sha512-zkmVH92DlzjSFc4xKGZp/2BXIFrDIdBQBC8gUXKCsMgKYb1bkCkxfSuoW1werDjaTEMTbULkHtKFHe1L+Abnaw==} + regexpu-core@6.5.3: + resolution: {integrity: sha512-E8VgUoSK+LMQrLboDxavm76MTBGrQhx9RiNuomRmYnZ10Uw12HrI8fkxOOncktb2hBpzIZ9SV/347euQHG5z+g==} engines: {node: '>=4'} regjsgen@0.8.0: resolution: {integrity: sha512-RvwtGe3d7LvWiDQXeQw8p5asZUmfU1G/l6WbUXeHta7Y2PEIvBTwH6E2EfmYUK8pxcxEdEmaomqyp0vZZ7C+3Q==} - regjsparser@0.13.3: - resolution: {integrity: sha512-ycwFAS14Jw4mppvmK4GR/J6u3WpWpjkEApehuHtLc/8VpPNpDMbQ4WjqwplXifGeyKOzHSFLmSPqzksDQE2Sfg==} + regjsparser@0.13.4: + resolution: {integrity: sha512-EWV80YgFaVgFrjGCAsV7oybp4GOxbls5RzBg8OB0nKEVXsBJR1JlV8Di1JhCROg3MzTfe1RI8yitIm1eOs68iA==} hasBin: true require-directory@2.1.1: @@ -7446,8 +7327,8 @@ packages: resolution: {integrity: sha512-uZtduh8/8srhBoMx//5bwqjQ+rfYOUq8zC9NrMUGtjBiGTtFJM42s58/36+hTqeqINcnYe08Nj3LkK9lW4N8Xg==} engines: {node: '>=12'} - resolve@1.22.12: - resolution: {integrity: sha512-TyeJ1zif53BPfHootBGwPRYT1RUt6oGWsaQr8UyZW/eAm9bKoijtvruSDEmZHm92CwS9nj7/fWttqPCgzep8CA==} + resolve@1.22.13: + resolution: {integrity: sha512-Dj/cW9zBV2aRj6XzCxuGIs3ESZKv02jixne3q6jFZYZ3/Tg09gHHviSMDL4kObh9pqSahdRHEnDoaP2gn8YLhA==} engines: {node: '>= 0.4'} hasBin: true @@ -7517,11 +7398,6 @@ packages: vue-tsc: optional: true - rolldown@1.2.11: - resolution: {integrity: sha512-qpSwIyz0jHQq5qXBTNxFmE6664rJ7O+4TvPFOiOaBSrz8IOHc1koKKSqTM2H6u1UG1+TveuC6vaDHKXFOvb1Kw==} - engines: {node: ^20.19.0 || >=22.12.0} - hasBin: true - rolldown@1.2.12: resolution: {integrity: sha512-8wafseiaG80xmXSfqidUNqZcylTlhmPZZt+za2m+js2sFZ8dTNlhIOV2WcbIPx2hgwPBJpEUGFAMZ9bgBBLTSQ==} engines: {node: ^20.19.0 || >=22.12.0} @@ -8089,8 +7965,8 @@ packages: tiny-inflate@1.0.3: resolution: {integrity: sha512-pkY1fj1cKHb2seWDy0B16HeWyczlJA9/WW3u3c4z/NiWDsO3DOU5D7nhTLE9CF0yXv/QZFY7sEJmj24dK+Rrqw==} - tinybench@6.2.0: - resolution: {integrity: sha512-78U2TlB2CnVenajOFzf3BKSm0J6oz5L0NV7g32LCPccvYc0lbWvys4d3uUUCS2B1N8PAf2+aekR8i1KbC3HO7Q==} + tinybench@6.2.2: + resolution: {integrity: sha512-nIZ2N2dFpjBsg2hgitKu7mA+FvsIJuGJOwysRngmVRRmWgR/UyPjwJj8c/fT/dhm8EkHnF5EOogRf+0Z2qrimA==} engines: {node: '>=20.0.0'} tinyexec@1.3.1: @@ -8108,15 +7984,15 @@ packages: tldts-core@6.1.86: resolution: {integrity: sha512-Je6p7pkk+KMzMv2XXKmAE3McmolOQFdxkKw0R8EYNr7sELW46JqnNeTX8ybPiQgvg1ymCoF8LXs5fzFaZvJPTA==} - tldts-core@7.4.16: - resolution: {integrity: sha512-MDolfaSJtlSK5Y0A1xl3277ekubZwobpBjugknDizI9O5Rm60a1m8k4ICK+MRsCDzPygT81mp3BBf5RKDlFRfA==} + tldts-core@7.4.18: + resolution: {integrity: sha512-KI2PKvCmvQI/xD6ypPqkU0i7oxNXR/O58RLRaHR4svsgVUQ2JE/XC8BtMbG6PSehD27I8sZJRcC1ASnCy6lp3g==} tldts@6.1.86: resolution: {integrity: sha512-WMi/OQ2axVTf/ykqCQgXiIct+mSQDFdH2fkwhPwgEwvJ1kSzZRiinb0zF2Xb8u4+OqPChmyI6MEu4EezNJz+FQ==} hasBin: true - tldts@7.4.16: - resolution: {integrity: sha512-QwBER5KMR86IIjpIiO7H/Z3IMJPsZ1A6RKPAqzTTgOyUQUSt9FdnKcqhTaJmkY6HVrgouZHZR0ncK5QxvmnQeg==} + tldts@7.4.18: + resolution: {integrity: sha512-somxA8xKAUzlAxl0TX/jMSYIbRNFIVGnI96pVGJPeMc5BsHmfVXn6mOJT6U++ELnl04eGfzpfcEuZe8WiASkXg==} hasBin: true tmp@0.2.7: @@ -8316,8 +8192,8 @@ packages: resolution: {integrity: sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==} engines: {node: '>= 0.8'} - update-browserslist-db@1.3.3: - resolution: {integrity: sha512-pJ2sYawQS0R/WI928Gj5GlPhTGzbMelq0+4INtSYNDV9ErKJcX6xjGWkoG/VnB3dpUm00zALaqkrUD77pO5TDQ==} + update-browserslist-db@1.3.4: + resolution: {integrity: sha512-t8wonIOdQyOjtPd2VktlBu6QjTVTks6v8bSi7kd0r2Vll8TK1JYDZtRRdbmCHOAMphkZgrzK+L+vXK4pyZ8t4A==} hasBin: true peerDependencies: browserslist: '>= 4.21.0' @@ -8361,8 +8237,8 @@ packages: resolution: {integrity: sha512-Q5dkR66lSUpzoR2xKWFiFCYXlvC8hJqV+ZMMLgt9/vm9355VnH25ueIJzrpunO/QjhhgcT5yBlR6wGQjPHeHkA==} engines: {node: '>=22'} - verdaccio-auth-memory@13.1.5: - resolution: {integrity: sha512-rfKDhm1DzZoFdHUjiSwpe8hlXkiKB4brtzagaZcBnZXyBEASwW6SK/mdr4yU4asMcf+Zc8MjUJYnjlI7ji1yaw==} + verdaccio-auth-memory@13.1.6: + resolution: {integrity: sha512-L9LNz1q/JW1I9mPLch+8LUGnma/amo4EpS/+hZA6ZJJRIN7G5QAOKU9hLLPV6WqxO/I8T0KPtwNhyav9Aopqtg==} engines: {node: '>=22'} verdaccio-htpasswd@13.1.5: @@ -8933,7 +8809,7 @@ snapshots: rxjs: 7.8.2 tslib: 2.8.1 - '@asamuzakjp/css-color@7.1.3': + '@asamuzakjp/css-color@7.1.5': dependencies: '@csstools/css-calc': 3.4.3(@csstools/css-parser-algorithms@4.0.2(@csstools/css-tokenizer@4.0.2))(@csstools/css-tokenizer@4.0.2) '@csstools/css-color-parser': 4.2.6(@csstools/css-parser-algorithms@4.0.2(@csstools/css-tokenizer@4.0.2))(@csstools/css-tokenizer@4.0.2) @@ -8969,10 +8845,10 @@ snapshots: '@babel/generator': 7.29.8 '@babel/helper-compilation-targets': 7.29.7 '@babel/helper-module-transforms': 7.29.7(@babel/core@7.29.7(supports-color@11.0.0))(supports-color@11.0.0) - '@babel/helpers': 7.29.7 + '@babel/helpers': 7.29.10 '@babel/parser': 7.29.9 '@babel/template': 7.29.7 - '@babel/traverse': 7.29.8(supports-color@11.0.0) + '@babel/traverse': 7.29.10(supports-color@11.0.0) '@babel/types': 7.29.8 '@jridgewell/remapping': 2.3.5 convert-source-map: 2.0.0 @@ -9031,7 +8907,7 @@ snapshots: '@babel/generator@8.0.6': dependencies: - '@babel/parser': 8.0.6 + '@babel/parser': 8.0.7 '@babel/types': 8.0.6 '@jridgewell/gen-mapping': 0.4.0-beta.0 '@jridgewell/trace-mapping': 0.3.31 @@ -9050,14 +8926,6 @@ snapshots: lru-cache: 5.1.1 semver: 6.3.1 - '@babel/helper-compilation-targets@8.0.6': - dependencies: - '@babel/compat-data': 8.0.5 - '@babel/helper-validator-option': 8.0.0 - browserslist: 4.29.3 - flru: 1.0.2 - verkit: 0.3.2 - '@babel/helper-compilation-targets@8.0.7': dependencies: '@babel/compat-data': 8.0.5 @@ -9066,7 +8934,7 @@ snapshots: flru: 1.0.2 verkit: 0.5.0 - '@babel/helper-create-class-features-plugin@8.0.6(@babel/core@8.0.7)': + '@babel/helper-create-class-features-plugin@8.0.7(@babel/core@8.0.7)': dependencies: '@babel/core': 8.0.7 '@babel/helper-annotate-as-pure': 8.0.0 @@ -9074,20 +8942,20 @@ snapshots: '@babel/helper-optimise-call-expression': 8.0.0 '@babel/helper-replace-supers': 8.0.1(@babel/core@8.0.7) '@babel/helper-skip-transparent-expression-wrappers': 8.0.0 - '@babel/traverse': 8.0.6 - verkit: 0.3.2 + '@babel/traverse': 8.0.7 + verkit: 0.5.0 - '@babel/helper-create-regexp-features-plugin@8.0.5(@babel/core@8.0.7)': + '@babel/helper-create-regexp-features-plugin@8.0.7(@babel/core@8.0.7)': dependencies: '@babel/core': 8.0.7 '@babel/helper-annotate-as-pure': 8.0.0 - regexpu-core: 6.5.2 - verkit: 0.3.2 + regexpu-core: 6.5.3 + verkit: 0.5.0 '@babel/helper-define-polyfill-provider@1.0.0(@babel/core@8.0.7)': dependencies: '@babel/core': 8.0.7 - '@babel/helper-compilation-targets': 8.0.6 + '@babel/helper-compilation-targets': 8.0.7 '@babel/helper-plugin-utils': 8.0.1(@babel/core@8.0.7) lodash.debounce: 4.0.8 @@ -9097,19 +8965,19 @@ snapshots: '@babel/helper-member-expression-to-functions@8.0.5': dependencies: - '@babel/traverse': 8.0.6 + '@babel/traverse': 8.0.7 '@babel/types': 8.0.6 '@babel/helper-module-imports@7.29.7(supports-color@11.0.0)': dependencies: - '@babel/traverse': 7.29.8(supports-color@11.0.0) + '@babel/traverse': 7.29.10(supports-color@11.0.0) '@babel/types': 7.29.8 transitivePeerDependencies: - supports-color '@babel/helper-module-imports@8.0.0': dependencies: - '@babel/traverse': 8.0.6 + '@babel/traverse': 8.0.7 '@babel/types': 8.0.6 '@babel/helper-module-transforms@7.29.7(@babel/core@7.29.7(supports-color@11.0.0))(supports-color@11.0.0)': @@ -9117,7 +8985,7 @@ snapshots: '@babel/core': 7.29.7(supports-color@11.0.0) '@babel/helper-module-imports': 7.29.7(supports-color@11.0.0) '@babel/helper-validator-identifier': 7.29.7 - '@babel/traverse': 7.29.8(supports-color@11.0.0) + '@babel/traverse': 7.29.10(supports-color@11.0.0) transitivePeerDependencies: - supports-color @@ -9126,7 +8994,7 @@ snapshots: '@babel/core': 8.0.7 '@babel/helper-module-imports': 8.0.0 '@babel/helper-validator-identifier': 8.0.6 - '@babel/traverse': 8.0.6 + '@babel/traverse': 8.0.7 '@babel/helper-optimise-call-expression@8.0.0': dependencies: @@ -9141,18 +9009,18 @@ snapshots: '@babel/core': 8.0.7 '@babel/helper-annotate-as-pure': 8.0.0 '@babel/helper-wrap-function': 8.0.0 - '@babel/traverse': 8.0.6 + '@babel/traverse': 8.0.7 '@babel/helper-replace-supers@8.0.1(@babel/core@8.0.7)': dependencies: '@babel/core': 8.0.7 '@babel/helper-member-expression-to-functions': 8.0.5 '@babel/helper-optimise-call-expression': 8.0.0 - '@babel/traverse': 8.0.6 + '@babel/traverse': 8.0.7 '@babel/helper-skip-transparent-expression-wrappers@8.0.0': dependencies: - '@babel/traverse': 8.0.6 + '@babel/traverse': 8.0.7 '@babel/types': 8.0.6 '@babel/helper-split-export-declaration@7.24.7': @@ -9174,10 +9042,10 @@ snapshots: '@babel/helper-wrap-function@8.0.0': dependencies: '@babel/template': 8.0.0 - '@babel/traverse': 8.0.6 + '@babel/traverse': 8.0.7 '@babel/types': 8.0.6 - '@babel/helpers@7.29.7': + '@babel/helpers@7.29.10': dependencies: '@babel/template': 7.29.7 '@babel/types': 7.29.8 @@ -9191,10 +9059,6 @@ snapshots: dependencies: '@babel/types': 7.29.8 - '@babel/parser@8.0.6': - dependencies: - '@babel/types': 8.0.6 - '@babel/parser@8.0.7': dependencies: '@babel/types': 8.0.6 @@ -9242,7 +9106,7 @@ snapshots: '@babel/core': 8.0.7 '@babel/helper-plugin-utils': 8.0.1(@babel/core@8.0.7) '@babel/helper-remap-async-to-generator': 8.0.1(@babel/core@8.0.7) - '@babel/traverse': 8.0.6 + '@babel/traverse': 8.0.7 '@babel/plugin-transform-async-to-generator@8.0.1(@babel/core@8.0.7)': dependencies: @@ -9264,24 +9128,24 @@ snapshots: '@babel/plugin-transform-class-properties@8.0.1(@babel/core@8.0.7)': dependencies: '@babel/core': 8.0.7 - '@babel/helper-create-class-features-plugin': 8.0.6(@babel/core@8.0.7) + '@babel/helper-create-class-features-plugin': 8.0.7(@babel/core@8.0.7) '@babel/helper-plugin-utils': 8.0.1(@babel/core@8.0.7) '@babel/plugin-transform-class-static-block@8.0.5(@babel/core@8.0.7)': dependencies: '@babel/core': 8.0.7 - '@babel/helper-create-class-features-plugin': 8.0.6(@babel/core@8.0.7) + '@babel/helper-create-class-features-plugin': 8.0.7(@babel/core@8.0.7) '@babel/helper-plugin-utils': 8.0.1(@babel/core@8.0.7) '@babel/plugin-transform-classes@8.0.5(@babel/core@8.0.7)': dependencies: '@babel/core': 8.0.7 '@babel/helper-annotate-as-pure': 8.0.0 - '@babel/helper-compilation-targets': 8.0.6 + '@babel/helper-compilation-targets': 8.0.7 '@babel/helper-globals': 8.0.6 '@babel/helper-plugin-utils': 8.0.1(@babel/core@8.0.7) '@babel/helper-replace-supers': 8.0.1(@babel/core@8.0.7) - '@babel/traverse': 8.0.6 + '@babel/traverse': 8.0.7 '@babel/plugin-transform-computed-properties@8.0.1(@babel/core@8.0.7)': dependencies: @@ -9296,7 +9160,7 @@ snapshots: '@babel/plugin-transform-dotall-regex@8.0.1(@babel/core@8.0.7)': dependencies: '@babel/core': 8.0.7 - '@babel/helper-create-regexp-features-plugin': 8.0.5(@babel/core@8.0.7) + '@babel/helper-create-regexp-features-plugin': 8.0.7(@babel/core@8.0.7) '@babel/helper-plugin-utils': 8.0.1(@babel/core@8.0.7) '@babel/plugin-transform-duplicate-keys@8.0.1(@babel/core@8.0.7)': @@ -9307,7 +9171,7 @@ snapshots: '@babel/plugin-transform-duplicate-named-capturing-groups-regex@8.0.1(@babel/core@8.0.7)': dependencies: '@babel/core': 8.0.7 - '@babel/helper-create-regexp-features-plugin': 8.0.5(@babel/core@8.0.7) + '@babel/helper-create-regexp-features-plugin': 8.0.7(@babel/core@8.0.7) '@babel/helper-plugin-utils': 8.0.1(@babel/core@8.0.7) '@babel/plugin-transform-dynamic-import@8.0.1(@babel/core@8.0.7)': @@ -9340,7 +9204,7 @@ snapshots: '@babel/plugin-transform-function-name@8.0.1(@babel/core@8.0.7)': dependencies: '@babel/core': 8.0.7 - '@babel/helper-compilation-targets': 8.0.6 + '@babel/helper-compilation-targets': 8.0.7 '@babel/helper-plugin-utils': 8.0.1(@babel/core@8.0.7) '@babel/plugin-transform-json-strings@8.0.1(@babel/core@8.0.7)': @@ -9391,7 +9255,7 @@ snapshots: '@babel/plugin-transform-named-capturing-groups-regex@8.0.1(@babel/core@8.0.7)': dependencies: '@babel/core': 8.0.7 - '@babel/helper-create-regexp-features-plugin': 8.0.5(@babel/core@8.0.7) + '@babel/helper-create-regexp-features-plugin': 8.0.7(@babel/core@8.0.7) '@babel/helper-plugin-utils': 8.0.1(@babel/core@8.0.7) '@babel/plugin-transform-new-target@8.0.1(@babel/core@8.0.7)': @@ -9412,7 +9276,7 @@ snapshots: '@babel/plugin-transform-object-rest-spread@8.0.1(@babel/core@8.0.7)': dependencies: '@babel/core': 8.0.7 - '@babel/helper-compilation-targets': 8.0.6 + '@babel/helper-compilation-targets': 8.0.7 '@babel/helper-plugin-utils': 8.0.1(@babel/core@8.0.7) '@babel/plugin-transform-destructuring': 8.0.5(@babel/core@8.0.7) '@babel/plugin-transform-parameters': 8.0.5(@babel/core@8.0.7) @@ -9442,14 +9306,14 @@ snapshots: '@babel/plugin-transform-private-methods@8.0.1(@babel/core@8.0.7)': dependencies: '@babel/core': 8.0.7 - '@babel/helper-create-class-features-plugin': 8.0.6(@babel/core@8.0.7) + '@babel/helper-create-class-features-plugin': 8.0.7(@babel/core@8.0.7) '@babel/helper-plugin-utils': 8.0.1(@babel/core@8.0.7) '@babel/plugin-transform-private-property-in-object@8.0.5(@babel/core@8.0.7)': dependencies: '@babel/core': 8.0.7 '@babel/helper-annotate-as-pure': 8.0.0 - '@babel/helper-create-class-features-plugin': 8.0.6(@babel/core@8.0.7) + '@babel/helper-create-class-features-plugin': 8.0.7(@babel/core@8.0.7) '@babel/helper-plugin-utils': 8.0.1(@babel/core@8.0.7) '@babel/plugin-transform-property-literals@8.0.1(@babel/core@8.0.7)': @@ -9465,7 +9329,7 @@ snapshots: '@babel/plugin-transform-regexp-modifiers@8.0.1(@babel/core@8.0.7)': dependencies: '@babel/core': 8.0.7 - '@babel/helper-create-regexp-features-plugin': 8.0.5(@babel/core@8.0.7) + '@babel/helper-create-regexp-features-plugin': 8.0.7(@babel/core@8.0.7) '@babel/helper-plugin-utils': 8.0.1(@babel/core@8.0.7) '@babel/plugin-transform-reserved-words@8.0.1(@babel/core@8.0.7)': @@ -9513,19 +9377,19 @@ snapshots: '@babel/plugin-transform-unicode-property-regex@8.0.1(@babel/core@8.0.7)': dependencies: '@babel/core': 8.0.7 - '@babel/helper-create-regexp-features-plugin': 8.0.5(@babel/core@8.0.7) + '@babel/helper-create-regexp-features-plugin': 8.0.7(@babel/core@8.0.7) '@babel/helper-plugin-utils': 8.0.1(@babel/core@8.0.7) '@babel/plugin-transform-unicode-regex@8.0.1(@babel/core@8.0.7)': dependencies: '@babel/core': 8.0.7 - '@babel/helper-create-regexp-features-plugin': 8.0.5(@babel/core@8.0.7) + '@babel/helper-create-regexp-features-plugin': 8.0.7(@babel/core@8.0.7) '@babel/helper-plugin-utils': 8.0.1(@babel/core@8.0.7) '@babel/plugin-transform-unicode-sets-regex@8.0.1(@babel/core@8.0.7)': dependencies: '@babel/core': 8.0.7 - '@babel/helper-create-regexp-features-plugin': 8.0.5(@babel/core@8.0.7) + '@babel/helper-create-regexp-features-plugin': 8.0.7(@babel/core@8.0.7) '@babel/helper-plugin-utils': 8.0.1(@babel/core@8.0.7) '@babel/preset-env@8.0.7(@babel/core@8.0.7)': @@ -9617,10 +9481,10 @@ snapshots: '@babel/template@8.0.0': dependencies: '@babel/code-frame': 8.0.6 - '@babel/parser': 8.0.6 + '@babel/parser': 8.0.7 '@babel/types': 8.0.6 - '@babel/traverse@7.29.8(supports-color@11.0.0)': + '@babel/traverse@7.29.10(supports-color@11.0.0)': dependencies: '@babel/code-frame': 7.29.7 '@babel/generator': 7.29.8 @@ -9632,16 +9496,6 @@ snapshots: transitivePeerDependencies: - supports-color - '@babel/traverse@8.0.6': - dependencies: - '@babel/code-frame': 8.0.6 - '@babel/generator': 8.0.6 - '@babel/helper-globals': 8.0.6 - '@babel/parser': 8.0.6 - '@babel/template': 8.0.0 - '@babel/types': 8.0.6 - obug: 2.2.1 - '@babel/traverse@8.0.7': dependencies: '@babel/code-frame': 8.0.6 @@ -9670,7 +9524,7 @@ snapshots: '@bcoe/v8-coverage@1.0.2': {} - '@bramus/specificity@2.4.2': + '@bramus/specificity@2.4.3': dependencies: css-tree: 3.2.1 @@ -10233,8 +10087,8 @@ snapshots: '@google-cloud/promisify': 5.1.0 '@grpc/proto-loader': 0.7.15 '@opentelemetry/api': 1.9.1 - '@opentelemetry/context-async-hooks': 2.11.0(@opentelemetry/api@1.9.1) - '@opentelemetry/core': 2.11.0(@opentelemetry/api@1.9.1) + '@opentelemetry/context-async-hooks': 2.12.0(@opentelemetry/api@1.9.1) + '@opentelemetry/core': 2.12.0(@opentelemetry/api@1.9.1) '@opentelemetry/semantic-conventions': 1.43.0 '@types/big.js': 6.2.2 '@types/stack-trace': 0.0.33 @@ -10271,7 +10125,7 @@ snapshots: - supports-color - utf-8-validate - '@grpc/grpc-js@1.14.5': + '@grpc/grpc-js@1.14.6': dependencies: '@grpc/proto-loader': 0.8.1 '@js-sdsl/ordered-map': 4.4.2 @@ -11018,11 +10872,11 @@ snapshots: '@opentelemetry/api@1.9.1': {} - '@opentelemetry/context-async-hooks@2.11.0(@opentelemetry/api@1.9.1)': + '@opentelemetry/context-async-hooks@2.12.0(@opentelemetry/api@1.9.1)': dependencies: '@opentelemetry/api': 1.9.1 - '@opentelemetry/core@2.11.0(@opentelemetry/api@1.9.1)': + '@opentelemetry/core@2.12.0(@opentelemetry/api@1.9.1)': dependencies: '@opentelemetry/api': 1.9.1 '@opentelemetry/semantic-conventions': 1.43.0 @@ -11086,8 +10940,6 @@ snapshots: '@oxc-parser/binding-win32-x64-msvc@0.153.0': optional: true - '@oxc-project/types@0.151.0': {} - '@oxc-project/types@0.152.0': {} '@oxc-project/types@0.153.0': {} @@ -11272,93 +11124,48 @@ snapshots: modern-tar: 0.8.5 yargs: 18.2.0 - '@rolldown/binding-android-arm-eabi@1.2.11': - optional: true - '@rolldown/binding-android-arm-eabi@1.2.12': optional: true - '@rolldown/binding-android-arm64@1.2.11': - optional: true - '@rolldown/binding-android-arm64@1.2.12': optional: true - '@rolldown/binding-darwin-arm64@1.2.11': - optional: true - '@rolldown/binding-darwin-arm64@1.2.12': optional: true - '@rolldown/binding-darwin-x64@1.2.11': - optional: true - '@rolldown/binding-darwin-x64@1.2.12': optional: true - '@rolldown/binding-freebsd-x64@1.2.11': - optional: true - '@rolldown/binding-freebsd-x64@1.2.12': optional: true - '@rolldown/binding-linux-arm-gnueabihf@1.2.11': - optional: true - '@rolldown/binding-linux-arm-gnueabihf@1.2.12': optional: true - '@rolldown/binding-linux-arm64-gnu@1.2.11': - optional: true - '@rolldown/binding-linux-arm64-gnu@1.2.12': optional: true - '@rolldown/binding-linux-arm64-musl@1.2.11': - optional: true - '@rolldown/binding-linux-arm64-musl@1.2.12': optional: true - '@rolldown/binding-linux-ppc64-gnu@1.2.11': - optional: true - '@rolldown/binding-linux-ppc64-gnu@1.2.12': optional: true - '@rolldown/binding-linux-s390x-gnu@1.2.11': - optional: true - '@rolldown/binding-linux-s390x-gnu@1.2.12': optional: true - '@rolldown/binding-linux-x64-gnu@1.2.11': - optional: true - '@rolldown/binding-linux-x64-gnu@1.2.12': optional: true - '@rolldown/binding-linux-x64-musl@1.2.11': - optional: true - '@rolldown/binding-linux-x64-musl@1.2.12': optional: true - '@rolldown/binding-openharmony-arm64@1.2.11': - optional: true - '@rolldown/binding-openharmony-arm64@1.2.12': optional: true - '@rolldown/binding-win32-arm64-msvc@1.2.11': - optional: true - '@rolldown/binding-win32-arm64-msvc@1.2.12': optional: true - '@rolldown/binding-win32-x64-msvc@1.2.11': - optional: true - '@rolldown/binding-win32-x64-msvc@1.2.12': optional: true @@ -11388,7 +11195,7 @@ snapshots: '@types/resolve': 1.20.2 deepmerge: 4.3.1 is-module: 1.0.0 - resolve: 1.22.12 + resolve: 1.22.13 optionalDependencies: rollup: 4.64.1 @@ -11501,7 +11308,7 @@ snapshots: '@stylistic/eslint-plugin@5.10.0(eslint@10.12.0(jiti@2.7.0)(supports-color@11.0.0))': dependencies: '@eslint-community/eslint-utils': 4.10.1(eslint@10.12.0(jiti@2.7.0)(supports-color@11.0.0)) - '@typescript-eslint/types': 8.71.0 + '@typescript-eslint/types': 8.71.1 eslint: 10.12.0(jiti@2.7.0)(supports-color@11.0.0) eslint-visitor-keys: 4.2.1 espree: 10.4.0 @@ -11660,7 +11467,7 @@ snapshots: - uglify-js - webpack-cli - '@types/lodash@4.17.25': {} + '@types/lodash@4.17.26': {} '@types/micromatch@2.3.35': dependencies: @@ -11799,8 +11606,6 @@ snapshots: transitivePeerDependencies: - supports-color - '@typescript-eslint/types@8.71.0': {} - '@typescript-eslint/types@8.71.1': {} '@typescript-eslint/typescript-estree@8.71.1(supports-color@11.0.0)(typescript@6.0.3)': @@ -11865,6 +11670,16 @@ snapshots: process-warning: 1.0.0 semver: 7.8.5 + '@verdaccio/core@8.3.3': + dependencies: + ajv: 8.20.0 + http-errors: 2.0.1 + http-status-codes: 2.3.0 + lodash: 4.18.1 + minimatch: 10.2.6 + process-warning: 1.0.0 + semver: 7.8.5 + '@verdaccio/file-locking@13.1.0': dependencies: lockfile: 1.0.4 @@ -12019,7 +11834,7 @@ snapshots: '@jridgewell/trace-mapping': 0.3.31 '@vitest/spy': 5.0.3 estree-walker: 3.0.3 - magic-string: 1.4.2 + magic-string: 1.4.3 optionalDependencies: vite: 8.3.3(@types/node@22.20.5)(esbuild@0.28.2)(jiti@2.7.0)(less@4.9.1(supports-color@11.0.0))(sass-embedded@1.105.1)(sass@1.105.1)(terser@5.51.2)(tsx@4.23.15)(yaml@2.9.1) @@ -12202,11 +12017,11 @@ snapshots: mime-types: 3.0.2 negotiator: 1.1.0 - acorn-jsx@5.3.2(acorn@8.18.0): + acorn-jsx@5.3.2(acorn@8.19.0): dependencies: - acorn: 8.18.0 + acorn: 8.19.0 - acorn@8.18.0: {} + acorn@8.19.0: {} adjust-sourcemap-loader@4.0.0: dependencies: @@ -12372,7 +12187,7 @@ snapshots: autoprefixer@10.6.1(postcss@8.5.29): dependencies: browserslist: 4.29.3 - caniuse-lite: 1.0.30001814 + caniuse-lite: 1.0.30001815 fraction.js: 5.3.4 picocolors: 1.1.1 postcss: 8.5.29 @@ -12407,7 +12222,7 @@ snapshots: bare-events@2.9.2: {} - bare-fs@4.8.2: + bare-fs@4.8.4: dependencies: bare-events: 2.9.2 bare-path: 3.1.2 @@ -12436,7 +12251,7 @@ snapshots: base64-js@1.5.1: {} - baseline-browser-mapping@2.11.27: {} + baseline-browser-mapping@2.11.28: {} batch@0.6.1: {} @@ -12591,11 +12406,11 @@ snapshots: browserslist@4.29.3: dependencies: - baseline-browser-mapping: 2.11.27 - caniuse-lite: 1.0.30001814 - electron-to-chromium: 1.5.444 - node-releases: 2.0.57 - update-browserslist-db: 1.3.3(browserslist@4.29.3) + baseline-browser-mapping: 2.11.28 + caniuse-lite: 1.0.30001815 + electron-to-chromium: 1.5.452 + node-releases: 2.0.58 + update-browserslist-db: 1.3.4(browserslist@4.29.3) bs-recipes@1.3.4: {} @@ -12661,7 +12476,7 @@ snapshots: callsites@3.1.0: {} - caniuse-lite@1.0.30001814: {} + caniuse-lite@1.0.30001815: {} caseless@0.12.0: {} @@ -13120,7 +12935,7 @@ snapshots: ejs@7.0.1: {} - electron-to-chromium@1.5.444: {} + electron-to-chromium@1.5.452: {} emoji-regex@10.6.0: {} @@ -13437,14 +13252,14 @@ snapshots: espree@10.4.0: dependencies: - acorn: 8.18.0 - acorn-jsx: 5.3.2(acorn@8.18.0) + acorn: 8.19.0 + acorn-jsx: 5.3.2(acorn@8.19.0) eslint-visitor-keys: 4.2.1 espree@11.2.0: dependencies: - acorn: 8.18.0 - acorn-jsx: 5.3.2(acorn@8.18.0) + acorn: 8.19.0 + acorn-jsx: 5.3.2(acorn@8.19.0) eslint-visitor-keys: 5.0.1 esquery@1.7.0: @@ -13949,7 +13764,7 @@ snapshots: google-gax@5.0.8(supports-color@11.0.0): dependencies: - '@grpc/grpc-js': 1.14.5 + '@grpc/grpc-js': 1.14.6 '@grpc/proto-loader': 0.8.1 duplexify: 4.1.3 google-auth-library: 10.5.0(supports-color@11.0.0) @@ -13993,7 +13808,7 @@ snapshots: grpc-gcp@1.1.1: dependencies: - '@grpc/grpc-js': 1.14.5 + '@grpc/grpc-js': 1.14.6 protobufjs: 7.6.6 gtoken@8.0.0(supports-color@11.0.0): @@ -14505,9 +14320,9 @@ snapshots: jsdom@30.1.2(@noble/hashes@1.8.0): dependencies: - '@asamuzakjp/css-color': 7.1.3 + '@asamuzakjp/css-color': 7.1.5 '@asamuzakjp/dom-selector': 9.2.4 - '@bramus/specificity': 2.4.2 + '@bramus/specificity': 2.4.3 '@csstools/css-syntax-patches-for-csstree': 1.1.15(css-tree@3.2.1) '@exodus/bytes': 1.16.0(@noble/hashes@1.8.0) css-tree: 3.2.1 @@ -14665,7 +14480,7 @@ snapshots: kind-of@6.0.3: {} - launch-editor@2.14.1: + launch-editor@2.14.2: dependencies: picocolors: 1.1.1 shell-quote: 1.12.0 @@ -14877,10 +14692,6 @@ snapshots: dependencies: '@jridgewell/sourcemap-codec': 1.6.0 - magic-string@1.4.2: - dependencies: - '@jridgewell/sourcemap-codec': 1.6.0 - magic-string@1.4.3: dependencies: '@jridgewell/sourcemap-codec': 1.6.0 @@ -14984,19 +14795,6 @@ snapshots: minimist@1.2.8: {} - minimizer-webpack-plugin@5.13.0(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.28)(uglify-js@3.19.3)(webpack@5.111.1(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.28)(uglify-js@3.19.3)): - dependencies: - '@jridgewell/trace-mapping': 0.3.31 - jest-worker: 27.5.1 - schema-utils: 4.5.0 - terser: 5.51.2 - webpack: 5.111.1(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.28)(uglify-js@3.19.3) - optionalDependencies: - esbuild: 0.28.2 - lightningcss: 1.33.0 - postcss: 8.5.28 - uglify-js: 3.19.3 - minimizer-webpack-plugin@5.13.0(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.29)(uglify-js@3.19.3)(webpack@5.111.1(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.29)(uglify-js@3.19.3)): dependencies: '@jridgewell/trace-mapping': 0.3.31 @@ -15060,7 +14858,7 @@ snapshots: mute-stream@3.0.0: {} - nanoid@3.3.19: {} + nanoid@3.3.20: {} natural-compare@1.4.0: {} @@ -15104,9 +14902,9 @@ snapshots: jsonc-parser: 3.3.1 less: 4.9.1(supports-color@11.0.0) ora: 9.4.1 - postcss: 8.5.28 - rolldown: 1.2.11 - rolldown-plugin-dts: 0.28.6(rolldown@1.2.11)(typescript@6.0.3) + postcss: 8.5.29 + rolldown: 1.2.12 + rolldown-plugin-dts: 0.28.6(rolldown@1.2.12)(typescript@6.0.3) rxjs: 7.8.2 sass: 1.105.1 sass-embedded: 1.105.1 @@ -15160,7 +14958,7 @@ snapshots: node-gyp-build@4.8.4: {} - node-releases@2.0.57: {} + node-releases@2.0.58: {} normalize-path@3.0.0: {} @@ -15417,7 +15215,7 @@ snapshots: pino-abstract-transport@1.2.0: dependencies: - readable-stream: 4.7.0 + readable-stream: 4.8.0 split2: 4.2.0 pino-abstract-transport@2.0.0: @@ -15433,7 +15231,7 @@ snapshots: on-exit-leak-free: 2.1.2 pino-abstract-transport: 2.0.0 pino-std-serializers: 7.1.0 - process-warning: 5.1.0 + process-warning: 5.1.1 quick-format-unescaped: 4.0.4 real-require: 0.2.0 safe-stable-stringify: 2.5.0 @@ -15511,15 +15309,9 @@ snapshots: postcss-value-parser@4.2.0: {} - postcss@8.5.28: - dependencies: - nanoid: 3.3.19 - picocolors: 1.1.1 - source-map-js: 1.2.2 - postcss@8.5.29: dependencies: - nanoid: 3.3.19 + nanoid: 3.3.20 picocolors: 1.1.1 source-map-js: 1.2.2 @@ -15527,7 +15319,7 @@ snapshots: prelude-ls@1.2.1: {} - prettier@3.9.9: {} + prettier@3.9.10: {} probe-image-size@7.4.0(supports-color@11.0.0): dependencies: @@ -15544,7 +15336,7 @@ snapshots: process-warning@1.0.0: {} - process-warning@5.1.0: {} + process-warning@5.1.1: {} process@0.11.10: {} @@ -15702,7 +15494,7 @@ snapshots: process: 0.11.10 string_decoder: 1.3.0 - readable-stream@4.7.0: + readable-stream@4.8.0: dependencies: abort-controller: 3.0.0 buffer: 6.0.3 @@ -15748,18 +15540,18 @@ snapshots: gopd: 1.2.0 set-function-name: 2.0.2 - regexpu-core@6.5.2: + regexpu-core@6.5.3: dependencies: regenerate: 1.5.0 regenerate-unicode-properties: 10.3.0 regjsgen: 0.8.0 - regjsparser: 0.13.3 + regjsparser: 0.13.4 unicode-match-property-ecmascript: 2.0.0 unicode-match-property-value-ecmascript: 2.2.1 regjsgen@0.8.0: {} - regjsparser@0.13.3: + regjsparser@0.13.4: dependencies: jsesc: 3.1.0 @@ -15783,7 +15575,7 @@ snapshots: postcss: 8.5.29 source-map: 0.6.1 - resolve@1.22.12: + resolve@1.22.13: dependencies: es-errors: 1.3.0 is-core-module: 2.17.0 @@ -15838,20 +15630,6 @@ snapshots: dependencies: glob: 10.5.0 - rolldown-plugin-dts@0.28.6(rolldown@1.2.11)(typescript@6.0.3): - dependencies: - dts-resolver: 3.0.0 - get-tsconfig: 5.0.0-beta.6 - obug: 3.0.0 - rolldown: 1.2.11 - yuku-ast: 0.10.2 - yuku-codegen: 0.10.2 - yuku-parser: 0.10.2 - optionalDependencies: - typescript: 6.0.3 - transitivePeerDependencies: - - oxc-resolver - rolldown-plugin-dts@0.28.6(rolldown@1.2.12)(typescript@6.0.3): dependencies: dts-resolver: 3.0.0 @@ -15866,27 +15644,6 @@ snapshots: transitivePeerDependencies: - oxc-resolver - rolldown@1.2.11: - dependencies: - '@oxc-project/types': 0.151.0 - '@rolldown/pluginutils': 1.0.1 - optionalDependencies: - '@rolldown/binding-android-arm-eabi': 1.2.11 - '@rolldown/binding-android-arm64': 1.2.11 - '@rolldown/binding-darwin-arm64': 1.2.11 - '@rolldown/binding-darwin-x64': 1.2.11 - '@rolldown/binding-freebsd-x64': 1.2.11 - '@rolldown/binding-linux-arm-gnueabihf': 1.2.11 - '@rolldown/binding-linux-arm64-gnu': 1.2.11 - '@rolldown/binding-linux-arm64-musl': 1.2.11 - '@rolldown/binding-linux-ppc64-gnu': 1.2.11 - '@rolldown/binding-linux-s390x-gnu': 1.2.11 - '@rolldown/binding-linux-x64-gnu': 1.2.11 - '@rolldown/binding-linux-x64-musl': 1.2.11 - '@rolldown/binding-openharmony-arm64': 1.2.11 - '@rolldown/binding-win32-arm64-msvc': 1.2.11 - '@rolldown/binding-win32-x64-msvc': 1.2.11 - rolldown@1.2.12: dependencies: '@oxc-project/types': 0.152.0 @@ -16516,7 +16273,7 @@ snapshots: tar-stream@3.2.0: dependencies: b4a: 1.9.0 - bare-fs: 4.8.2 + bare-fs: 4.8.4 fast-fifo: 1.3.2 streamx: 2.28.1 transitivePeerDependencies: @@ -16527,7 +16284,7 @@ snapshots: tar-stream@3.2.2: dependencies: b4a: 1.9.0 - bare-fs: 4.8.2 + bare-fs: 4.8.4 fast-fifo: 1.3.2 streamx: 2.28.1 transitivePeerDependencies: @@ -16554,7 +16311,7 @@ snapshots: terser@5.51.2: dependencies: '@jridgewell/source-map': 0.3.11 - acorn: 8.18.0 + acorn: 8.19.0 commander: 2.20.3 source-map-support: 0.5.21 @@ -16587,7 +16344,7 @@ snapshots: tiny-inflate@1.0.3: {} - tinybench@6.2.0: {} + tinybench@6.2.2: {} tinyexec@1.3.1: {} @@ -16600,15 +16357,15 @@ snapshots: tldts-core@6.1.86: {} - tldts-core@7.4.16: {} + tldts-core@7.4.18: {} tldts@6.1.86: dependencies: tldts-core: 6.1.86 - tldts@7.4.16: + tldts@7.4.18: dependencies: - tldts-core: 7.4.16 + tldts-core: 7.4.18 tmp@0.2.7: {} @@ -16626,7 +16383,7 @@ snapshots: tough-cookie@6.0.2: dependencies: - tldts: 7.4.16 + tldts: 7.4.18 tr46@0.0.3: {} @@ -16791,7 +16548,7 @@ snapshots: unpipe@1.0.0: {} - update-browserslist-db@1.3.3(browserslist@4.29.3): + update-browserslist-db@1.3.4(browserslist@4.29.3): dependencies: browserslist: 4.29.3 escalade: 3.2.0 @@ -16832,9 +16589,9 @@ snapshots: - encoding - supports-color - verdaccio-auth-memory@13.1.5(supports-color@11.0.0): + verdaccio-auth-memory@13.1.6(supports-color@11.0.0): dependencies: - '@verdaccio/core': 8.3.2 + '@verdaccio/core': 8.3.3 debug: 4.4.3(supports-color@11.0.0) transitivePeerDependencies: - supports-color @@ -16904,8 +16661,8 @@ snapshots: dependencies: lightningcss: 1.33.0 picomatch: 4.0.7 - postcss: 8.5.28 - rolldown: 1.2.11 + postcss: 8.5.29 + rolldown: 1.2.12 tinyglobby: 0.2.17 optionalDependencies: '@types/node': 22.20.5 @@ -16926,11 +16683,11 @@ snapshots: chai: 6.3.0 es-module-lexer: 2.3.2 expect-type: 1.4.0 - magic-string: 1.4.2 + magic-string: 1.4.3 obug: 2.2.1 picomatch: 4.0.7 std-env: 4.3.0 - tinybench: 6.2.0 + tinybench: 6.2.2 tinyexec: 1.3.1 tinyglobby: 0.2.17 vite: 8.3.3(@types/node@22.20.5)(esbuild@0.28.2)(jiti@2.7.0)(less@4.9.1(supports-color@11.0.0))(sass-embedded@1.105.1)(sass@1.105.1)(terser@5.51.2)(tsx@4.23.15)(yaml@2.9.1) @@ -16966,16 +16723,6 @@ snapshots: webidl-conversions@8.0.1: {} - webpack-dev-middleware@8.3.0(webpack@5.111.1(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.28)(uglify-js@3.19.3)): - dependencies: - ansi-html-community: 0.0.8 - memfs: 4.80.0 - mime-types: 3.0.2 - range-parser: 1.3.0 - schema-utils: 4.5.0 - optionalDependencies: - webpack: 5.111.1(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.28)(uglify-js@3.19.3) - webpack-dev-middleware@8.3.0(webpack@5.111.1(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.29)(uglify-js@3.19.3)): dependencies: ansi-html-community: 0.0.8 @@ -16986,40 +16733,6 @@ snapshots: optionalDependencies: webpack: 5.111.1(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.29)(uglify-js@3.19.3) - webpack-dev-server@6.0.0(bufferutil@4.1.0)(supports-color@11.0.0)(utf-8-validate@6.0.6)(webpack@5.111.1(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.28)(uglify-js@3.19.3)): - dependencies: - '@types/bonjour': 3.5.13 - '@types/connect-history-api-fallback': 1.5.4 - '@types/express': 5.0.6 - '@types/express-serve-static-core': 5.1.3 - '@types/serve-index': 1.9.4 - '@types/serve-static': 2.2.0 - '@types/ws': 8.18.2 - ansi-html-community: 0.0.8 - bonjour-service: 1.4.4 - chokidar: 5.0.0 - compression: 1.8.2(supports-color@11.0.0) - connect-history-api-fallback: 2.0.0 - express: 5.2.1(supports-color@11.0.0) - graceful-fs: 4.2.11 - http-proxy-middleware: 4.2.0(supports-color@11.0.0) - ipaddr.js: 2.5.0 - launch-editor: 2.14.1 - open: 11.0.4 - p-retry: 8.0.1 - schema-utils: 4.5.0 - selfsigned: 5.5.0 - serve-index: 1.9.2(supports-color@11.0.0) - tinyglobby: 0.2.17 - webpack-dev-middleware: 8.3.0(webpack@5.111.1(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.28)(uglify-js@3.19.3)) - ws: 8.22.0(bufferutil@4.1.0)(utf-8-validate@6.0.6) - optionalDependencies: - webpack: 5.111.1(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.28)(uglify-js@3.19.3) - transitivePeerDependencies: - - bufferutil - - supports-color - - utf-8-validate - webpack-dev-server@6.0.0(bufferutil@4.1.0)(supports-color@11.0.0)(utf-8-validate@6.0.6)(webpack@5.111.1(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.29)(uglify-js@3.19.3)): dependencies: '@types/bonjour': 3.5.13 @@ -17038,7 +16751,7 @@ snapshots: graceful-fs: 4.2.11 http-proxy-middleware: 4.2.0(supports-color@11.0.0) ipaddr.js: 2.5.0 - launch-editor: 2.14.1 + launch-editor: 2.14.2 open: 11.0.4 p-retry: 8.0.1 schema-utils: 4.5.0 @@ -17067,43 +16780,6 @@ snapshots: typed-assert: 1.0.9 webpack: 5.111.1(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.29)(uglify-js@3.19.3) - webpack@5.111.1(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.28)(uglify-js@3.19.3): - dependencies: - '@types/estree': 1.0.9 - '@types/json-schema': 7.0.15 - '@webassemblyjs/ast': 1.14.1 - '@webassemblyjs/wasm-edit': 1.14.1 - '@webassemblyjs/wasm-parser': 1.14.1 - browserslist: 4.29.3 - chrome-trace-event: 1.0.4 - enhanced-resolve: 5.26.0 - es-module-lexer: 2.3.2 - events: 3.3.0 - graceful-fs: 4.2.11 - mime-db: 1.54.0 - minimizer-webpack-plugin: 5.13.0(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.28)(uglify-js@3.19.3)(webpack@5.111.1(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.28)(uglify-js@3.19.3)) - schema-utils: 4.5.0 - tapable: 2.3.3 - watchpack: 2.5.2 - webpack-sources: 3.6.0 - transitivePeerDependencies: - - '@minify-html/node' - - '@napi-rs/image' - - '@swc/core' - - '@swc/css' - - '@swc/html' - - clean-css - - cssnano - - csso - - esbuild - - html-minifier-terser - - imagemin - - lightningcss - - postcss - - sharp - - svgo - - uglify-js - webpack@5.111.1(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.29)(uglify-js@3.19.3): dependencies: '@types/estree': 1.0.9 From 22efeff5aa8eb50e3b507cfdd1da70283b6a9ef1 Mon Sep 17 00:00:00 2001 From: Angular Robot Date: Tue, 13 Oct 2026 03:46:16 +0000 Subject: [PATCH 608/787] build: update cross-repo angular dependencies See associated pull request for more information. --- tests/e2e/ng-snapshot/package.json | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/tests/e2e/ng-snapshot/package.json b/tests/e2e/ng-snapshot/package.json index 7bf474571ca6..0618eb046f57 100644 --- a/tests/e2e/ng-snapshot/package.json +++ b/tests/e2e/ng-snapshot/package.json @@ -2,21 +2,21 @@ "description": "snapshot versions of Angular for e2e testing", "private": true, "dependencies": { - "@angular/animations": "github:angular/animations-builds#49e5662e0f5a6a052d8b66bd639ce261b231c807", + "@angular/animations": "github:angular/animations-builds#7ef64e48fbd50c668e386243a1d4c2f1ef84675b", "@angular/cdk": "github:angular/cdk-builds#8aa05501715c9b9b0fc95625f52b3b536c35cc4a", - "@angular/common": "github:angular/common-builds#e75bc632bb0f4c992336add2cd9429a5fc580165", - "@angular/compiler": "github:angular/compiler-builds#12aa4df6f3b1bc8402d329301391ab4f52179111", - "@angular/compiler-cli": "github:angular/compiler-cli-builds#051fd3767d2922649e6630cdbd4d726e99900949", - "@angular/core": "github:angular/core-builds#7b84cd24ec45174b8cc0a42e821a98b1a0d330eb", - "@angular/forms": "github:angular/forms-builds#fea1091472626b0c62c1300a4822216a55092cf6", - "@angular/language-service": "github:angular/language-service-builds#60d0bc6afa8bba745ba051afb88a8ccc6d72f61d", - "@angular/localize": "github:angular/localize-builds#5f21029e84cf4fab2902818b5351a9b131cef532", + "@angular/common": "github:angular/common-builds#96bb8a452e96a75e2130519f1301b25a08e408ec", + "@angular/compiler": "github:angular/compiler-builds#c94e6865d332afa0694d24049624ef23d1923089", + "@angular/compiler-cli": "github:angular/compiler-cli-builds#2d4f2f5eede86c9f3fa7ec4e8ce4cf03fc502d54", + "@angular/core": "github:angular/core-builds#f43cfb919a0da367f40da1bd07e67cd1845388c2", + "@angular/forms": "github:angular/forms-builds#a181c75be824e20dcc653e7e029217014aaae777", + "@angular/language-service": "github:angular/language-service-builds#3224af77e1a302a3ba6a5620fce41879c8c8158e", + "@angular/localize": "github:angular/localize-builds#b1148951f8251042228b544facb01d24f40d7380", "@angular/material": "github:angular/material-builds#5f4d7a4724a306e1e24d55f53564eebfa22dbdd4", "@angular/material-moment-adapter": "github:angular/material-moment-adapter-builds#a600a485f5c91b376684763cbf00b158f85502f0", - "@angular/platform-browser": "github:angular/platform-browser-builds#69be31f21a8df04fd8157676b7d885c94de8bdc6", - "@angular/platform-browser-dynamic": "github:angular/platform-browser-dynamic-builds#f8c0d0c407dd393e8f49593039ae2100f4504e11", - "@angular/platform-server": "github:angular/platform-server-builds#8e9d51d325c6575b54e118410281b6ffb2bd76a9", - "@angular/router": "github:angular/router-builds#42ae1c53acc2bcf444ef4d4d3e84ccdda61486db", - "@angular/service-worker": "github:angular/service-worker-builds#5ac1b5c6526c04ac8d1ba1e74f22f9998020eaf7" + "@angular/platform-browser": "github:angular/platform-browser-builds#b8cd3c70f3e83ccc2675345dbaef19406c274814", + "@angular/platform-browser-dynamic": "github:angular/platform-browser-dynamic-builds#81f80d43de410f7d4a2f0da625ca5882b7c3f71a", + "@angular/platform-server": "github:angular/platform-server-builds#b94ffc850d236d03d53460c6bb72b23eb7e21920", + "@angular/router": "github:angular/router-builds#cbe6196b50ea6948bb8ade7ac32f26029d37ca45", + "@angular/service-worker": "github:angular/service-worker-builds#5bb5c383c8e2323d28a2347a784327e031a4b101" } } From 48f8c0ca9c6615bdc28272970cc3091ee4e64426 Mon Sep 17 00:00:00 2001 From: Angular Robot Date: Tue, 13 Oct 2026 19:53:16 +0000 Subject: [PATCH 609/787] build: update all non-major dependencies See associated pull request for more information. --- modules/testing/builder/package.json | 4 +- package.json | 16 +- packages/angular/build/package.json | 16 +- packages/angular/cli/package.json | 6 +- packages/angular/ssr/package.json | 2 +- .../angular_devkit/build_angular/package.json | 2 +- pnpm-lock.yaml | 1137 +++++++++++------ 7 files changed, 794 insertions(+), 389 deletions(-) diff --git a/modules/testing/builder/package.json b/modules/testing/builder/package.json index 8823cbf0c68e..398a200cdf8a 100644 --- a/modules/testing/builder/package.json +++ b/modules/testing/builder/package.json @@ -4,12 +4,12 @@ "@angular-devkit/build-angular": "workspace:*", "@angular-devkit/core": "workspace:*", "@angular/ssr": "workspace:*", - "@vitest/coverage-v8": "5.0.3", + "@vitest/coverage-v8": "5.0.4", "browser-sync": "3.0.4", "istanbul-lib-instrument": "6.0.3", "jsdom": "30.1.2", "ng-packagr": "22.3.0-next.2", "rxjs": "7.8.2", - "vitest": "5.0.3" + "vitest": "5.0.4" } } diff --git a/package.json b/package.json index 6541f5d157af..c2efa7133c4f 100644 --- a/package.json +++ b/package.json @@ -29,12 +29,12 @@ "type": "git", "url": "git+https://github.com/angular/angular-cli.git" }, - "packageManager": "pnpm@12.10.1", + "packageManager": "pnpm@12.11.2", "engines": { "node": "^22.22.3 || ^24.15.0 || >=26.0.0", "npm": "Please use pnpm instead of NPM to install dependencies", "yarn": "Please use pnpm instead of Yarn to install dependencies", - "pnpm": "12.10.1" + "pnpm": "12.11.2" }, "author": "Angular Authors", "license": "MIT", @@ -70,7 +70,7 @@ "@rollup/plugin-commonjs": "^29.0.0", "@rollup/plugin-json": "^6.1.0", "@rollup/plugin-node-resolve": "16.0.3", - "@rollup/wasm-node": "4.64.1", + "@rollup/wasm-node": "4.64.5", "@stylistic/eslint-plugin": "^5.0.0", "@tony.ganchev/eslint-plugin-header": "~3.4.0", "@types/babel__core": "7.20.5", @@ -91,8 +91,8 @@ "@types/semver": "^7.3.12", "@types/yargs": "^17.0.20", "@types/yargs-parser": "^21.0.0", - "@typescript-eslint/eslint-plugin": "8.71.1", - "@typescript-eslint/parser": "8.71.1", + "@typescript-eslint/eslint-plugin": "8.71.2", + "@typescript-eslint/parser": "8.71.2", "ajv": "8.20.0", "buffer": "6.0.3", "esbuild": "0.28.2", @@ -100,7 +100,7 @@ "eslint": "10.12.0", "eslint-config-prettier": "10.1.8", "eslint-plugin-import": "2.32.0", - "express": "5.2.1", + "express": "5.3.0", "fast-glob": "3.3.3", "globals": "17.13.0", "http-proxy": "^1.18.1", @@ -119,9 +119,9 @@ "lodash": "^4.17.21", "magic-string": "1.4.3", "prettier": "^3.0.0", - "puppeteer": "25.12.0", + "puppeteer": "25.13.0", "quicktype-core": "26.0.0", - "rollup": "4.64.1", + "rollup": "4.64.5", "rollup-plugin-dts": "6.5.1", "rollup-plugin-sourcemaps2": "0.5.9", "semver": "7.8.5", diff --git a/packages/angular/build/package.json b/packages/angular/build/package.json index 2aa20f0c6b8f..a5227c45c526 100644 --- a/packages/angular/build/package.json +++ b/packages/angular/build/package.json @@ -24,27 +24,27 @@ "@inquirer/confirm": "6.3.3", "@parcel/watcher": "2.6.0", "@vitejs/plugin-basic-ssl": "2.3.0", - "beasties": "0.5.4", + "beasties": "0.5.5", "browserslist": "^4.26.0", "chokidar": "5.0.0", "esbuild": "0.28.2", "https-proxy-agent": "9.1.0", "jsonc-parser": "3.3.1", - "listr2": "11.1.1", + "listr2": "11.2.0", "magic-string": "1.4.3", "mrmime": "2.0.1", "oxc-parser": "0.153.0", "parse5-html-rewriting-stream": "8.0.1", "picomatch": "4.0.7", "piscina": "5.3.2", - "rolldown": "1.2.12", - "rolldown-plugin-dts": "0.28.6", + "rolldown": "1.2.13", + "rolldown-plugin-dts": "0.28.8", "sass": "1.105.1", "sass-embedded": "1.105.1", "semver": "7.8.5", "source-map-support": "0.5.21", "tinyglobby": "0.2.17", - "vite": "8.3.3", + "vite": "8.3.4", "xxhash-wasm": "1.1.0" }, "optionalDependencies": { @@ -54,15 +54,15 @@ "@angular-devkit/core": "workspace:*", "@angular/ssr": "workspace:*", "@oxc-project/types": "0.153.0", - "@vitest/coverage-v8": "5.0.3", + "@vitest/coverage-v8": "5.0.4", "istanbul-lib-instrument": "6.0.3", "jsdom": "30.1.2", "less": "4.9.1", "ng-packagr": "22.3.0-next.2", "postcss": "8.5.29", - "rollup": "4.64.1", + "rollup": "4.64.5", "rxjs": "7.8.2", - "vitest": "5.0.3" + "vitest": "5.0.4" }, "peerDependencies": { "@angular/compiler": "0.0.0-ANGULAR-FW-PEER-DEP", diff --git a/packages/angular/cli/package.json b/packages/angular/cli/package.json index ef6e3407b670..f558e7a6293d 100644 --- a/packages/angular/cli/package.json +++ b/packages/angular/cli/package.json @@ -21,16 +21,16 @@ "@angular-devkit/core": "workspace:0.0.0-PLACEHOLDER", "@angular-devkit/schematics": "workspace:0.0.0-PLACEHOLDER", "@inquirer/prompts": "8.7.3", - "@listr2/prompt-adapter-inquirer": "4.2.7", + "@listr2/prompt-adapter-inquirer": "4.3.1", "@modelcontextprotocol/server": "2.3.1", "@schematics/angular": "workspace:0.0.0-PLACEHOLDER", "jsonc-parser": "3.3.1", - "listr2": "11.1.1", + "listr2": "11.2.0", "npm-package-arg": "14.0.0", "parse5-html-rewriting-stream": "8.0.1", "semver": "7.8.5", "yargs": "18.2.0", - "zod": "4.6.5" + "zod": "4.6.7" }, "ng-update": { "migrations": "@schematics/angular/migrations/migration-collection.json", diff --git a/packages/angular/ssr/package.json b/packages/angular/ssr/package.json index 6e3596ca6aae..9d86125f4aad 100644 --- a/packages/angular/ssr/package.json +++ b/packages/angular/ssr/package.json @@ -22,7 +22,7 @@ "save": "dependencies" }, "dependencies": { - "beasties": "0.5.4", + "beasties": "0.5.5", "tslib": "^2.3.0" }, "peerDependencies": { diff --git a/packages/angular_devkit/build_angular/package.json b/packages/angular_devkit/build_angular/package.json index 6976448a01c0..502d27aa5975 100644 --- a/packages/angular_devkit/build_angular/package.json +++ b/packages/angular_devkit/build_angular/package.json @@ -25,7 +25,7 @@ "ansi-colors": "4.1.3", "autoprefixer": "10.6.1", "babel-loader": "10.1.1", - "beasties": "0.5.4", + "beasties": "0.5.5", "browserslist": "^4.26.0", "copy-webpack-plugin": "14.0.0", "css-loader": "7.1.5", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 2d1df736b28c..b2b2fdfdffd9 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -7,153 +7,153 @@ importers: configDependencies: {} packageManagerDependencies: pnpm: - specifier: 12.10.1 - version: 12.10.1 + specifier: 12.11.2 + version: 12.11.2 packages: - '@pnpm/exe.android-arm64@12.10.1': - resolution: {integrity: sha512-CVTlHPwNvadQCJD9bGSMzWIhFX8QpjtqC2c27dhdnn/9iKzEjZ3qL62o3gHpKbIuo6qn4WxTKRoaokgNdReBig==} + '@pnpm/exe.android-arm64@12.11.2': + resolution: {integrity: sha512-owLw13OfPkEoY+hLBNeeG+dCFhywr7q2d/EHPz4mNL2RhKnv8gNwMARkjkiDQu234aItVwFNDeGnmQXm+ikkAg==} cpu: [arm64] os: [android] - '@pnpm/exe.android-x64@12.10.1': - resolution: {integrity: sha512-NFiYLIaodY7da0XIebwcU3JoP7IK/lzF7zgKSSP+9H+QcFnQ1GDfBkuBKCYJzZ+Xu0WH54neIPLBBCaOjaaauA==} + '@pnpm/exe.android-x64@12.11.2': + resolution: {integrity: sha512-GYPkVebl4iokOA/4MPSpGoUVfFlsth7uqOCe1XiaiM23LAdvUOMJBObqHJijr89ZqjwHm9pO6vO45GRwJ2U2qA==} cpu: [x64] os: [android] - '@pnpm/exe.darwin-arm64@12.10.1': - resolution: {integrity: sha512-0O8tdQ8ijlPJudXspLMTcitMkdBEz6uUflazL5uQE0WMs85oQIp0U+5hfEktMFB64QqEhjqlvvujTwbzdr9oMg==} + '@pnpm/exe.darwin-arm64@12.11.2': + resolution: {integrity: sha512-n9M4On66y8FDxUAKgMO1FXt0qihyG4e+56p3/F0uo8Bx9KplW8BwKVnXigzCJ8aNM6sVVPkOE6M9XXbeVIxnZA==} cpu: [arm64] os: [darwin] - '@pnpm/exe.darwin-x64@12.10.1': - resolution: {integrity: sha512-ud+1/uZOKEo8P/AsPynOJc/LNwfI0j6WwCElibj71rU9l4nIBnsSn+wWTIPZPkZ4BBSH5+82azSnAARMyJ1lNA==} + '@pnpm/exe.darwin-x64@12.11.2': + resolution: {integrity: sha512-oSW7n3sBT0c0cyk4kj10T2Y6Mpm+OFEiCAWozgX039tdoI6yqJF1uaFD3sw7ugLdu6VV3+uY0pa1TUZIPdxDWA==} cpu: [x64] os: [darwin] - '@pnpm/exe.freebsd-x64@12.10.1': - resolution: {integrity: sha512-mj9PE5rf8uAfQQ2K66HSATMSut+lNiB4eSqFd5+azFVCMnxNSy/32xpZQJT21PhnN3Y4qbK+iKHe5nWAxSuRhw==} + '@pnpm/exe.freebsd-x64@12.11.2': + resolution: {integrity: sha512-qbzc3KoDpa/Lkf8vs3jnDe6dUUbso+6eLIyssYFMiliLpYNxn8dirk11YoNnOQcdHVB50v5RFls1Yid6ttT5pg==} cpu: [x64] os: [freebsd] - '@pnpm/exe.linux-arm64-musl@12.10.1': - resolution: {integrity: sha512-xba+00wZJ8Um6rBJJjWl88uJj0tydB8dtomvjlCLvi0uL32vpa9CRP8Vv26FIXvbiZ1bo2RCzYt/eChxJVV52w==} + '@pnpm/exe.linux-arm64-musl@12.11.2': + resolution: {integrity: sha512-uMEYDwKRktGwANubQ+kYCwmhNwg3Ik6qK89ahsbQ5cP30R/5FVJb/T99vr9XRUBC/A7mZI6eeT92oyVas9ACyg==} cpu: [arm64] os: [linux] libc: [musl] - '@pnpm/exe.linux-arm64@12.10.1': - resolution: {integrity: sha512-oBdMp69ScC9UnniG4qZAQVr2fBDSXjm4yk/72vkEVyrlwS23yMxcRQl7Qdo3sgXPAygY6TWnPRKm4rXzjoyW7w==} + '@pnpm/exe.linux-arm64@12.11.2': + resolution: {integrity: sha512-6e8ZAQUwFXAWHHHv5FesWqf/kEK04wuitBv5f/gxzkC0DiBfaixr+f+6JQede8SF4Ji5LcMwVFJbzAtffpWxEg==} cpu: [arm64] os: [linux] libc: [glibc] - '@pnpm/exe.linux-ppc64@12.10.1': - resolution: {integrity: sha512-Yyb3wu09h3c7mLme270uHFiVaAIUHC411Ru9LIU2BKUIstrGlXa9OqqVWoXaRgYRdFdOFknkwG7GNn6ygwLbnw==} + '@pnpm/exe.linux-ppc64@12.11.2': + resolution: {integrity: sha512-Ui8A4nepkVupx2VpuFfysEluMvWK6gTB5rgVts7Ss/+8dj0RD28x3F/seNeH/zSypgC6yKdV6qsKVQh/uffTuQ==} cpu: [ppc64] os: [linux] libc: [glibc] - '@pnpm/exe.linux-riscv64@12.10.1': - resolution: {integrity: sha512-PdkeUFFkybknnGkWP0H22eMpIiS4OZXL5BcQzF4lh+vmrW3IaC2HOkbANKgot/PKO0Kl77pzA/6PKFxgbgfXIQ==} + '@pnpm/exe.linux-riscv64@12.11.2': + resolution: {integrity: sha512-i1yLdQ5bu+wjQ+srtFoJAaY2gN/+oXHFdjul4llCeoDxHE0rTIG3R41NhHfCjyFPW4+CpbBT58933CL9sMOCnA==} cpu: [riscv64] os: [linux] libc: [glibc] - '@pnpm/exe.linux-s390x@12.10.1': - resolution: {integrity: sha512-1okKuHKJwJPAbofDxfhZWAUxEWtee4ZSf7Pah8kcvocaJkf2WxFJ5KVTiNIvDml5GLidDQsgf7Pcf/WHbCak7Q==} + '@pnpm/exe.linux-s390x@12.11.2': + resolution: {integrity: sha512-YS1/lhPjjTsN4QL50VaFZKRa3Uc/bDnhE8eKbJMFvuX06UuFS5YaiDg04APoZdfVSGqTfX27QAg7rfLMSWaqxA==} cpu: [s390x] os: [linux] libc: [glibc] - '@pnpm/exe.linux-x64-musl@12.10.1': - resolution: {integrity: sha512-e6IqzVNkPa7srFKJKnY23uWJ+qz0LaRWiTUo/sHfFXRRMRzB5uNOr6qWWip/jqhdGwU91n9J7LrEYZ6e0tRczw==} + '@pnpm/exe.linux-x64-musl@12.11.2': + resolution: {integrity: sha512-7eIxQR05fvJxCujUSKp5KTtehJ7QqrgqP/HD1+BcB/SaV2Be4XI1PEHiOgA1zxsiMIeMvTF6E4G4dYHrFjeXRg==} cpu: [x64] os: [linux] libc: [musl] - '@pnpm/exe.linux-x64@12.10.1': - resolution: {integrity: sha512-ZByV0DRgWzGaDSjT5ddRBASdwz+r/qPMYh7o6RGmPQjtRGNFbSl94xY2DcAM8mqCOZJUUDtAXQ+wpBXcdpKlkg==} + '@pnpm/exe.linux-x64@12.11.2': + resolution: {integrity: sha512-FK7QKe24AYgppJwO3mpooYptduuvIGqKJPi5ac7MdnWkjUy46JBfYhCW0grnkWKC8YOf0x+vGviuQqJEj3SpQQ==} cpu: [x64] os: [linux] libc: [glibc] - '@pnpm/exe.win32-arm64@12.10.1': - resolution: {integrity: sha512-I7QZHcjioG7orFeCRUFUHByJ1G0zFPnAlaGGyrUvb6MGkv5oeNwNPl7t+Gp+7zHfnMcgLGJ1a+Wfim0IDw3lOw==} + '@pnpm/exe.win32-arm64@12.11.2': + resolution: {integrity: sha512-PCTjVDdJb6VvraZxrEeFv6EqEA0hhIsAySx28e95J2Tqpi88hLpgOXgNqV0vpxq9A+b8GLQfyk/D+1UlJPv/YQ==} cpu: [arm64] os: [win32] - '@pnpm/exe.win32-x64@12.10.1': - resolution: {integrity: sha512-4WJFdp58EKlCj0zLobrXU0vpszSZIr4X/3y/uNbAQqGW0zE+VdruZB0gFc3L2kzsUzVwTYbaCn+XEhnCYSAlTg==} + '@pnpm/exe.win32-x64@12.11.2': + resolution: {integrity: sha512-8sgX86OvRjJ3yZs/TvGR2L31wH9ScPZ+f+geKI3ikuB0RRiK3i4LlTRO8OXN6pdRqj8epMde4312MCjj7JsJdA==} cpu: [x64] os: [win32] - pnpm@12.10.1: - resolution: {integrity: sha512-ukCjfrGjcNYP6oxM8dNkwTvMzvUY6YrSvO6VT1OdONo3RY5YJho/pV4GUjRQ6g//+fSXsTW+QfLBXBZCusrObA==} + pnpm@12.11.2: + resolution: {integrity: sha512-JaUWUqGWeFr18ovabf6NxYLr76SsHRgCIc4TkCMcX7dmN4IupLbkYzznSs3LCnf3Ja8RutOBd/3t2u6BipVcuQ==} engines: {node: '>=18.*'} hasBin: true snapshots: - '@pnpm/exe.android-arm64@12.10.1': + '@pnpm/exe.android-arm64@12.11.2': optional: true - '@pnpm/exe.android-x64@12.10.1': + '@pnpm/exe.android-x64@12.11.2': optional: true - '@pnpm/exe.darwin-arm64@12.10.1': + '@pnpm/exe.darwin-arm64@12.11.2': optional: true - '@pnpm/exe.darwin-x64@12.10.1': + '@pnpm/exe.darwin-x64@12.11.2': optional: true - '@pnpm/exe.freebsd-x64@12.10.1': + '@pnpm/exe.freebsd-x64@12.11.2': optional: true - '@pnpm/exe.linux-arm64-musl@12.10.1': + '@pnpm/exe.linux-arm64-musl@12.11.2': optional: true - '@pnpm/exe.linux-arm64@12.10.1': + '@pnpm/exe.linux-arm64@12.11.2': optional: true - '@pnpm/exe.linux-ppc64@12.10.1': + '@pnpm/exe.linux-ppc64@12.11.2': optional: true - '@pnpm/exe.linux-riscv64@12.10.1': + '@pnpm/exe.linux-riscv64@12.11.2': optional: true - '@pnpm/exe.linux-s390x@12.10.1': + '@pnpm/exe.linux-s390x@12.11.2': optional: true - '@pnpm/exe.linux-x64-musl@12.10.1': + '@pnpm/exe.linux-x64-musl@12.11.2': optional: true - '@pnpm/exe.linux-x64@12.10.1': + '@pnpm/exe.linux-x64@12.11.2': optional: true - '@pnpm/exe.win32-arm64@12.10.1': + '@pnpm/exe.win32-arm64@12.11.2': optional: true - '@pnpm/exe.win32-x64@12.10.1': + '@pnpm/exe.win32-x64@12.11.2': optional: true - pnpm@12.10.1: + pnpm@12.11.2: optionalDependencies: - '@pnpm/exe.android-arm64': 12.10.1 - '@pnpm/exe.android-x64': 12.10.1 - '@pnpm/exe.darwin-arm64': 12.10.1 - '@pnpm/exe.darwin-x64': 12.10.1 - '@pnpm/exe.freebsd-x64': 12.10.1 - '@pnpm/exe.linux-arm64': 12.10.1 - '@pnpm/exe.linux-arm64-musl': 12.10.1 - '@pnpm/exe.linux-ppc64': 12.10.1 - '@pnpm/exe.linux-riscv64': 12.10.1 - '@pnpm/exe.linux-s390x': 12.10.1 - '@pnpm/exe.linux-x64': 12.10.1 - '@pnpm/exe.linux-x64-musl': 12.10.1 - '@pnpm/exe.win32-arm64': 12.10.1 - '@pnpm/exe.win32-x64': 12.10.1 + '@pnpm/exe.android-arm64': 12.11.2 + '@pnpm/exe.android-x64': 12.11.2 + '@pnpm/exe.darwin-arm64': 12.11.2 + '@pnpm/exe.darwin-x64': 12.11.2 + '@pnpm/exe.freebsd-x64': 12.11.2 + '@pnpm/exe.linux-arm64': 12.11.2 + '@pnpm/exe.linux-arm64-musl': 12.11.2 + '@pnpm/exe.linux-ppc64': 12.11.2 + '@pnpm/exe.linux-riscv64': 12.11.2 + '@pnpm/exe.linux-s390x': 12.11.2 + '@pnpm/exe.linux-x64': 12.11.2 + '@pnpm/exe.linux-x64-musl': 12.11.2 + '@pnpm/exe.win32-arm64': 12.11.2 + '@pnpm/exe.win32-x64': 12.11.2 --- lockfileVersion: '9.0' @@ -245,16 +245,16 @@ importers: version: 10.0.1(eslint@10.12.0(jiti@2.7.0)(supports-color@11.0.0)) '@rollup/plugin-commonjs': specifier: ^29.0.0 - version: 29.0.3(rollup@4.64.1) + version: 29.0.3(rollup@4.64.5) '@rollup/plugin-json': specifier: ^6.1.0 - version: 6.1.0(rollup@4.64.1) + version: 6.1.0(rollup@4.64.5) '@rollup/plugin-node-resolve': specifier: 16.0.3 - version: 16.0.3(rollup@4.64.1) + version: 16.0.3(rollup@4.64.5) '@rollup/wasm-node': - specifier: 4.64.1 - version: 4.64.1 + specifier: 4.64.5 + version: 4.64.5 '@stylistic/eslint-plugin': specifier: ^5.0.0 version: 5.10.0(eslint@10.12.0(jiti@2.7.0)(supports-color@11.0.0)) @@ -316,11 +316,11 @@ importers: specifier: ^21.0.0 version: 21.0.3 '@typescript-eslint/eslint-plugin': - specifier: 8.71.1 - version: 8.71.1(@typescript-eslint/parser@8.71.1(eslint@10.12.0(jiti@2.7.0)(supports-color@11.0.0))(supports-color@11.0.0)(typescript@6.0.3))(eslint@10.12.0(jiti@2.7.0)(supports-color@11.0.0))(supports-color@11.0.0)(typescript@6.0.3) + specifier: 8.71.2 + version: 8.71.2(@typescript-eslint/parser@8.71.2(eslint@10.12.0(jiti@2.7.0)(supports-color@11.0.0))(supports-color@11.0.0)(typescript@6.0.3))(eslint@10.12.0(jiti@2.7.0)(supports-color@11.0.0))(supports-color@11.0.0)(typescript@6.0.3) '@typescript-eslint/parser': - specifier: 8.71.1 - version: 8.71.1(eslint@10.12.0(jiti@2.7.0)(supports-color@11.0.0))(supports-color@11.0.0)(typescript@6.0.3) + specifier: 8.71.2 + version: 8.71.2(eslint@10.12.0(jiti@2.7.0)(supports-color@11.0.0))(supports-color@11.0.0)(typescript@6.0.3) ajv: specifier: 8.20.0 version: 8.20.0 @@ -341,10 +341,10 @@ importers: version: 10.1.8(eslint@10.12.0(jiti@2.7.0)(supports-color@11.0.0)) eslint-plugin-import: specifier: 2.32.0 - version: 2.32.0(@typescript-eslint/parser@8.71.1(eslint@10.12.0(jiti@2.7.0)(supports-color@11.0.0))(supports-color@11.0.0)(typescript@6.0.3))(eslint@10.12.0(jiti@2.7.0)(supports-color@11.0.0))(supports-color@11.0.0) + version: 2.32.0(@typescript-eslint/parser@8.71.2(eslint@10.12.0(jiti@2.7.0)(supports-color@11.0.0))(supports-color@11.0.0)(typescript@6.0.3))(eslint@10.12.0(jiti@2.7.0)(supports-color@11.0.0))(supports-color@11.0.0) express: - specifier: 5.2.1 - version: 5.2.1(supports-color@11.0.0) + specifier: 5.3.0 + version: 5.3.0(supports-color@11.0.0) fast-glob: specifier: 3.3.3 version: 3.3.3 @@ -400,20 +400,20 @@ importers: specifier: ^3.0.0 version: 3.9.10 puppeteer: - specifier: 25.12.0 - version: 25.12.0(bufferutil@4.1.0)(utf-8-validate@6.0.6) + specifier: 25.13.0 + version: 25.13.0(bufferutil@4.1.0)(utf-8-validate@6.0.6) quicktype-core: specifier: 26.0.0 version: 26.0.0 rollup: - specifier: 4.64.1 - version: 4.64.1 + specifier: 4.64.5 + version: 4.64.5 rollup-plugin-dts: specifier: 6.5.1 - version: 6.5.1(rollup@4.64.1)(typescript@6.0.3) + version: 6.5.1(rollup@4.64.5)(typescript@6.0.3) rollup-plugin-sourcemaps2: specifier: 0.5.9 - version: 0.5.9(@types/node@22.20.5)(rollup@4.64.1) + version: 0.5.9(@types/node@22.20.5)(rollup@4.64.5) semver: specifier: 7.8.5 version: 7.8.5 @@ -451,8 +451,8 @@ importers: specifier: workspace:* version: link:../../../packages/angular/ssr '@vitest/coverage-v8': - specifier: 5.0.3 - version: 5.0.3(vitest@5.0.3) + specifier: 5.0.4 + version: 5.0.4(vitest@5.0.4) browser-sync: specifier: 3.0.4 version: 3.0.4(bufferutil@4.1.0)(debug@4.4.3(supports-color@11.0.0))(supports-color@11.0.0)(utf-8-validate@6.0.6) @@ -469,8 +469,8 @@ importers: specifier: 7.8.2 version: 7.8.2 vitest: - specifier: 5.0.3 - version: 5.0.3(@opentelemetry/api@1.9.1)(@types/node@22.20.5)(@vitest/coverage-v8@5.0.3)(jsdom@30.1.2(@noble/hashes@1.8.0))(vite@8.3.3(@types/node@22.20.5)(esbuild@0.28.2)(jiti@2.7.0)(less@4.9.1(supports-color@11.0.0))(sass-embedded@1.105.1)(sass@1.105.1)(terser@5.51.2)(tsx@4.23.15)(yaml@2.9.1)) + specifier: 5.0.4 + version: 5.0.4(@opentelemetry/api@1.9.1)(@types/node@22.20.5)(@vitest/coverage-v8@5.0.4)(jsdom@30.1.2(@noble/hashes@1.8.0))(vite@8.3.4(@types/node@22.20.5)(esbuild@0.28.2)(jiti@2.7.0)(less@4.9.1(supports-color@11.0.0))(sass-embedded@1.105.1)(sass@1.105.1)(terser@5.51.2)(tsx@4.23.15)(yaml@2.9.1)) packages/angular/build: dependencies: @@ -491,10 +491,10 @@ importers: version: 2.6.0 '@vitejs/plugin-basic-ssl': specifier: 2.3.0 - version: 2.3.0(vite@8.3.3(@types/node@22.20.5)(esbuild@0.28.2)(jiti@2.7.0)(less@4.9.1(supports-color@11.0.0))(sass-embedded@1.105.1)(sass@1.105.1)(terser@5.51.2)(tsx@4.23.15)(yaml@2.9.1)) + version: 2.3.0(vite@8.3.4(@types/node@22.20.5)(esbuild@0.28.2)(jiti@2.7.0)(less@4.9.1(supports-color@11.0.0))(sass-embedded@1.105.1)(sass@1.105.1)(terser@5.51.2)(tsx@4.23.15)(yaml@2.9.1)) beasties: - specifier: 0.5.4 - version: 0.5.4 + specifier: 0.5.5 + version: 0.5.5 browserslist: specifier: ^4.26.0 version: 4.29.3 @@ -511,8 +511,8 @@ importers: specifier: 3.3.1 version: 3.3.1 listr2: - specifier: 11.1.1 - version: 11.1.1 + specifier: 11.2.0 + version: 11.2.0 magic-string: specifier: 1.4.3 version: 1.4.3 @@ -532,11 +532,11 @@ importers: specifier: 5.3.2 version: 5.3.2 rolldown: - specifier: 1.2.12 - version: 1.2.12 + specifier: 1.2.13 + version: 1.2.13 rolldown-plugin-dts: - specifier: 0.28.6 - version: 0.28.6(rolldown@1.2.12)(typescript@6.0.3) + specifier: 0.28.8 + version: 0.28.8(rolldown@1.2.13)(typescript@6.0.3) sass: specifier: 1.105.1 version: 1.105.1 @@ -553,8 +553,8 @@ importers: specifier: 0.2.17 version: 0.2.17 vite: - specifier: 8.3.3 - version: 8.3.3(@types/node@22.20.5)(esbuild@0.28.2)(jiti@2.7.0)(less@4.9.1(supports-color@11.0.0))(sass-embedded@1.105.1)(sass@1.105.1)(terser@5.51.2)(tsx@4.23.15)(yaml@2.9.1) + specifier: 8.3.4 + version: 8.3.4(@types/node@22.20.5)(esbuild@0.28.2)(jiti@2.7.0)(less@4.9.1(supports-color@11.0.0))(sass-embedded@1.105.1)(sass@1.105.1)(terser@5.51.2)(tsx@4.23.15)(yaml@2.9.1) xxhash-wasm: specifier: 1.1.0 version: 1.1.0 @@ -569,8 +569,8 @@ importers: specifier: 0.153.0 version: 0.153.0 '@vitest/coverage-v8': - specifier: 5.0.3 - version: 5.0.3(vitest@5.0.3) + specifier: 5.0.4 + version: 5.0.4(vitest@5.0.4) istanbul-lib-instrument: specifier: 6.0.3 version: 6.0.3(supports-color@11.0.0) @@ -587,14 +587,14 @@ importers: specifier: 8.5.29 version: 8.5.29 rollup: - specifier: 4.64.1 - version: 4.64.1 + specifier: 4.64.5 + version: 4.64.5 rxjs: specifier: 7.8.2 version: 7.8.2 vitest: - specifier: 5.0.3 - version: 5.0.3(@opentelemetry/api@1.9.1)(@types/node@22.20.5)(@vitest/coverage-v8@5.0.3)(jsdom@30.1.2(@noble/hashes@1.8.0))(vite@8.3.3(@types/node@22.20.5)(esbuild@0.28.2)(jiti@2.7.0)(less@4.9.1(supports-color@11.0.0))(sass-embedded@1.105.1)(sass@1.105.1)(terser@5.51.2)(tsx@4.23.15)(yaml@2.9.1)) + specifier: 5.0.4 + version: 5.0.4(@opentelemetry/api@1.9.1)(@types/node@22.20.5)(@vitest/coverage-v8@5.0.4)(jsdom@30.1.2(@noble/hashes@1.8.0))(vite@8.3.4(@types/node@22.20.5)(esbuild@0.28.2)(jiti@2.7.0)(less@4.9.1(supports-color@11.0.0))(sass-embedded@1.105.1)(sass@1.105.1)(terser@5.51.2)(tsx@4.23.15)(yaml@2.9.1)) optionalDependencies: lmdb: specifier: 3.5.7 @@ -615,8 +615,8 @@ importers: specifier: 8.7.3 version: 8.7.3(@types/node@22.20.5) '@listr2/prompt-adapter-inquirer': - specifier: 4.2.7 - version: 4.2.7(@inquirer/prompts@8.7.3(@types/node@22.20.5))(@types/node@22.20.5)(listr2@11.1.1) + specifier: 4.3.1 + version: 4.3.1(@inquirer/prompts@8.7.3(@types/node@22.20.5))(@types/node@22.20.5)(listr2@11.2.0) '@modelcontextprotocol/server': specifier: 2.3.1 version: 2.3.1 @@ -627,8 +627,8 @@ importers: specifier: 3.3.1 version: 3.3.1 listr2: - specifier: 11.1.1 - version: 11.1.1 + specifier: 11.2.0 + version: 11.2.0 npm-package-arg: specifier: 14.0.0 version: 14.0.0 @@ -642,8 +642,8 @@ importers: specifier: 18.2.0 version: 18.2.0 zod: - specifier: 4.6.5 - version: 4.6.5 + specifier: 4.6.7 + version: 4.6.7 packages/angular/pwa: dependencies: @@ -660,8 +660,8 @@ importers: packages/angular/ssr: dependencies: beasties: - specifier: 0.5.4 - version: 0.5.4 + specifier: 0.5.5 + version: 0.5.5 tslib: specifier: ^2.3.0 version: 2.8.1 @@ -760,8 +760,8 @@ importers: specifier: 10.1.1 version: 10.1.1(@babel/core@8.0.7)(webpack@5.111.1(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.29)(uglify-js@3.19.3)) beasties: - specifier: 0.5.4 - version: 0.5.4 + specifier: 0.5.5 + version: 0.5.5 browserslist: specifier: ^4.26.0 version: 4.29.3 @@ -2634,12 +2634,12 @@ packages: '@leichtgewicht/ip-codec@2.0.5': resolution: {integrity: sha512-Vo+PSpZG2/fmgmiNzYK9qWRh8h/CHrwD0mo1h1DzL4yzHNSfWYujGTYsWGreD000gcgmZ7K4Ys6Tx9TxtsKdDw==} - '@listr2/prompt-adapter-inquirer@4.2.7': - resolution: {integrity: sha512-k180vxSv2KqmnDxoato6pCqEJsov4U5C0EVmldZkAdNeVBxY48A/LM6TCNPGIzDK/iZSfsZP0Mw+gbWc5hXLyA==} + '@listr2/prompt-adapter-inquirer@4.3.1': + resolution: {integrity: sha512-NnKK9IrkBPr3v9DxXz/MTxQ989bJEfH1Q6Qr+MA9XU0QRXEgAQJO4XjFs8OzPQI5WYScz0kXi9WNDkANr2bRVw==} engines: {node: '>=22.13.0'} peerDependencies: '@inquirer/prompts': '>= 3 < 9' - listr2: 11.1.0 + listr2: ^11.0.0 '@lmdb/lmdb-darwin-arm64@3.5.7': resolution: {integrity: sha512-Y0CUvoj3ToaPQGdiqtodR0yrbAToNV74ylGQGSsNzmACO6iqKIUdU2OyFhkB+AAYpyfCA6oYh8hxbtc7eZhklA==} @@ -3265,8 +3265,8 @@ packages: '@protobufjs/utf8@1.1.2': resolution: {integrity: sha512-b1UQwcEZ4yCnMCD8DAL1VlbvBJE9/IX4FTIp7BG1xYpf29SLazLSrqUkj4w7Y5y7cCVP6E5tcqqcI0xemPkHug==} - '@puppeteer/browsers@3.2.3': - resolution: {integrity: sha512-2Bt3m6dDAJqmZehn0wiXSYyQmuhyiHHZ7FjvrVaS1W2RoFGV6eCK71UvKYkNJjkwC1Q9nobjhvTMhLQztFVINA==} + '@puppeteer/browsers@3.2.4': + resolution: {integrity: sha512-okJ6yQMc0SBexOKxMi966omwAV1uAPwgF/YMZdb04gZQPXVjWHl9bmXjZYtIcsN1+PN3Bz4iFfGK3g+c6lZJ0Q==} engines: {node: '>=22.12.0'} hasBin: true peerDependencies: @@ -3284,36 +3284,72 @@ packages: cpu: [arm] os: [android] + '@rolldown/binding-android-arm-eabi@1.2.13': + resolution: {integrity: sha512-Vu/NICrgdRvUOeaJZIyB2FP63s6fO/4ud5l8dXmxDx9yDyn+mN0y+gsvsVviSli+T361Aqo0h46EuMoobrwawA==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm] + os: [android] + '@rolldown/binding-android-arm64@1.2.12': resolution: {integrity: sha512-7KHFgQ5VJxIHcLlrwrc3Xbds7oTNQT7Pgi9gQCJKrd2VGab/UksIOYp6VD8MzCstGxOKMgNamPwUCfxPdP1OHg==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [android] + '@rolldown/binding-android-arm64@1.2.13': + resolution: {integrity: sha512-6LEoIrGy5vvCd2boNnv2soPSUZj/PRvhp8R/t9KlX+mIZxThIE/ZqxrGXxmuNX0FuvQFvLdZr7S4HrYpYBVhEQ==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [android] + '@rolldown/binding-darwin-arm64@1.2.12': resolution: {integrity: sha512-3YIhqHD96nA5SaYNRBR16HnGv4oavZvXfD/ayHM+oYZ0WD/8lBAtf6zQua4kEyAvpqrluKXl0lnOBoiNby7x9w==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [darwin] + '@rolldown/binding-darwin-arm64@1.2.13': + resolution: {integrity: sha512-CaJSRzlQ6Q+zkDMVA9OkVxBjVoPRCDEE3v0FSJ9kIQBgRjFApA3Si4ijhbNVUji7ZJt+PfO0e46qy4nPInHUPA==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [darwin] + '@rolldown/binding-darwin-x64@1.2.12': resolution: {integrity: sha512-UuuJ35MFw4gmFOrE9pEqIV+K3syIKveph+Qc1/ljHZVdoDW4pz/JHR/eMVom+TZGl/5OOvGJOWaOCVt3ZfqhxA==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [darwin] + '@rolldown/binding-darwin-x64@1.2.13': + resolution: {integrity: sha512-e4r340I5hxSzJkD3YJBxgzq/rJ3wwxwdLLb2FPt1Zpyem20nrQPT11DDEEkazwxaHumH8wpglsp/Ozgj/wT6mw==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [x64] + os: [darwin] + '@rolldown/binding-freebsd-x64@1.2.12': resolution: {integrity: sha512-uMvssit0a4W+/7D8CbHUvG719mH3R2jwXAlh/XcPvuHTE0g++LymF88DCGNX0HM2rBOn0xrzgXktIB6fLSJBTQ==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [freebsd] + '@rolldown/binding-freebsd-x64@1.2.13': + resolution: {integrity: sha512-hoBWDZ4/K/mJKVMbsgUd1jfpA2DiOrJ54mpegObU9TBHBBrtX4FLIXJJQRDPZ/2Dn91GvPob+Z2hwKJzf4E5SQ==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [x64] + os: [freebsd] + '@rolldown/binding-linux-arm-gnueabihf@1.2.12': resolution: {integrity: sha512-XcFu0R0xWnwzSf4IQgFH1rJIckPN1pLy2R+4r9IDB7Yfu/ys9cVqfa4pBrMHj7a3gl8mIR4nRNPg0e5IvEVs6g==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm] os: [linux] + '@rolldown/binding-linux-arm-gnueabihf@1.2.13': + resolution: {integrity: sha512-oF9fZu3vTWnTiVAkDFxU9PJLt1nh20K9RRpuHsR7ZnE2L7XookBbDBVLojCVSLGbvtSlxeUNnjAj6DbNsKyzbg==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm] + os: [linux] + '@rolldown/binding-linux-arm64-gnu@1.2.12': resolution: {integrity: sha512-260UrKgn8tz39ak+SMDOirKzr7V04M9dWPw5llW00SwBivCZoWcRBKV1d8cXnRkUmSZA3BdiUmBHWk7734Ulpw==} engines: {node: ^20.19.0 || >=22.12.0} @@ -3321,6 +3357,13 @@ packages: os: [linux] libc: [glibc] + '@rolldown/binding-linux-arm64-gnu@1.2.13': + resolution: {integrity: sha512-DTpb/+jMiqWMPgphn4ksW1zW+XLJ6dJJ9FMvnIk9I291LhCctMPhMYJrP5t9p6C9qa3KXadDdUEZHBaPh3kNxQ==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [linux] + libc: [glibc] + '@rolldown/binding-linux-arm64-musl@1.2.12': resolution: {integrity: sha512-5YK1I9SqDkbPgc1IA8BgDl34suqUS2q0KWnBrirm0E51YjOs6eo6dV6jbQfNE/argHRSvd0QUGgtpIoYx+WWpw==} engines: {node: ^20.19.0 || >=22.12.0} @@ -3328,6 +3371,13 @@ packages: os: [linux] libc: [musl] + '@rolldown/binding-linux-arm64-musl@1.2.13': + resolution: {integrity: sha512-xU+Kvv9N2A3SY35zFh1FWWNjxbadE/BKeqnkXe7vScU4GZsw757BlVmDLITZEq8DPpk6m7uoDYkK7P+x/uU5Ow==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [linux] + libc: [musl] + '@rolldown/binding-linux-ppc64-gnu@1.2.12': resolution: {integrity: sha512-Rkcrmp7eFRg74yL5fXEU91JEWbdEPLevWwGtXpmhbjlD1StScbWTmO94Bhly+Mo+ketKYkdmM1vNUKeWSlx8cQ==} engines: {node: ^20.19.0 || >=22.12.0} @@ -3335,6 +3385,13 @@ packages: os: [linux] libc: [glibc] + '@rolldown/binding-linux-ppc64-gnu@1.2.13': + resolution: {integrity: sha512-XMk/hnhh25oQ756Lclb1Q11h4ll0xC0Esa5w4Vzp+mAE2S3AGJgeM0SonrIgY8fHhjarb6hcoTuwoFG0VVP2ig==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [ppc64] + os: [linux] + libc: [glibc] + '@rolldown/binding-linux-s390x-gnu@1.2.12': resolution: {integrity: sha512-qvK4DuAsQc2BSjlx+Xr+IzOIvvxbGZqxFwdWfG6F518Erj0GGISyQbJ6pIappnOxlNPzNHvo/L0BwB30GZ+zVw==} engines: {node: ^20.19.0 || >=22.12.0} @@ -3342,6 +3399,13 @@ packages: os: [linux] libc: [glibc] + '@rolldown/binding-linux-s390x-gnu@1.2.13': + resolution: {integrity: sha512-U1BoTHYmlywE2n3HUWjzZ+8EQsKr+OwpxYuDWaubx42tUL8QSL7nOqRz/NVHanibbFP3M1Rxuprz/wNcbMKjqw==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [s390x] + os: [linux] + libc: [glibc] + '@rolldown/binding-linux-x64-gnu@1.2.12': resolution: {integrity: sha512-Q9uLBO53Xd4QIq1WOycVQyPP1O4HhraEV2qqb3uTrnVw6QZih9duY4vNXOivL1xoUS1/z+W8eF4NMfl2a8Sdjw==} engines: {node: ^20.19.0 || >=22.12.0} @@ -3349,6 +3413,13 @@ packages: os: [linux] libc: [glibc] + '@rolldown/binding-linux-x64-gnu@1.2.13': + resolution: {integrity: sha512-J4cm80Pc6wEwV5AZ42o62sIQgDk+Y7R2s646jIwuvO+4V46QB58N4vVuMPWCBaNgursXLpmUWJV//WQAkPvHBQ==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [x64] + os: [linux] + libc: [glibc] + '@rolldown/binding-linux-x64-musl@1.2.12': resolution: {integrity: sha512-3IBxWFMjbOZskDPKv8Lf9BCnahlKuHthWkYnyIxOH/QcJrFcS4EmcenthApkwr/5+nEqZlLzeYbxeMaX7A5u4g==} engines: {node: ^20.19.0 || >=22.12.0} @@ -3356,24 +3427,49 @@ packages: os: [linux] libc: [musl] + '@rolldown/binding-linux-x64-musl@1.2.13': + resolution: {integrity: sha512-W0euZS40U4V6JkmEnVCIX9mcsL6cbXQ4X8c2w+MMOIjFg68TXUW+u3RT+2e1t1pv9mg/EP3pDtK3POXdQ7Rxyw==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [x64] + os: [linux] + libc: [musl] + '@rolldown/binding-openharmony-arm64@1.2.12': resolution: {integrity: sha512-xtX61xg4LKPkPWilZU1ynKClz5Gj4bf74LML4r3eVLWumKnGjoEr1OSHQhMdbBDoYTi+yjrujvpZe2pUnqCrrA==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [openharmony] + '@rolldown/binding-openharmony-arm64@1.2.13': + resolution: {integrity: sha512-do/AF/4n9MRshia3a5aXoy8xM2c6mgfT6D7H/dY6my5z+hfCIR4ab7mk4IRj++nsEQpKy39kd0DQnDq+r692tw==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [openharmony] + '@rolldown/binding-win32-arm64-msvc@1.2.12': resolution: {integrity: sha512-At7fPB6PCaIjzgIhEZFxuT+BBFqiQibJDT4d3PhiR3f4E7bbMZF4aKblbFfEM3sETRDd1YiQx/+U/g/B/ou5Ew==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [win32] + '@rolldown/binding-win32-arm64-msvc@1.2.13': + resolution: {integrity: sha512-6FtUf2cJZobutJdxnGYX8z0vtbgqU0b2v8vfBhkXb9wp2MppMFtkunE+IaOntyi01rkIQoPW2GHABtfzsC0BRQ==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [win32] + '@rolldown/binding-win32-x64-msvc@1.2.12': resolution: {integrity: sha512-WIw2haVKwjuYdXkHaoC0mF8Le71TuCBxjrdKqLbJGctbBABj+ClfmNvtbOnzpq3RokNo5+V1qhtSzJyXorsklQ==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [win32] + '@rolldown/binding-win32-x64-msvc@1.2.13': + resolution: {integrity: sha512-UKhFaZTeTcbKrb3iU82m17jVcPEAoqDkCN5MBqgPyZSwp/cQmib21crTS0DdH7T1B7wZRWEI89YQAOJMet5yhg==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [x64] + os: [win32] + '@rolldown/pluginutils@1.0.1': resolution: {integrity: sha512-2j9bGt5Jh8hj+vPtgzPtl72j0yRxHAyumoo6TNfAjsLB04UtpSvPbPcDcBMxz7n+9CYB0c1GxQFxYRg2jimqGw==} @@ -3413,146 +3509,146 @@ packages: rollup: optional: true - '@rollup/rollup-android-arm-eabi@4.64.1': - resolution: {integrity: sha512-QRU7UpoS9hd8Ij5I6fCVBxZ0UpdfAbZ5y7BWG5STFGMoM9jGzUP464yYAa3CzZxvG+jBwq1kI8L07xx0ReAdGA==} + '@rollup/rollup-android-arm-eabi@4.64.5': + resolution: {integrity: sha512-MrfgRQSpD5hkkRg6XI16B6EDLb+6+xp8xje6bpdSwkYw+qxrBKbUVrRAQu9h82UT+QumSIVQ8HXsXjPd2dlhqw==} cpu: [arm] os: [android] - '@rollup/rollup-android-arm64@4.64.1': - resolution: {integrity: sha512-ttQF6Rp4MrNy9/2AOPmHmMXbNE8kIlNPYoGC3ksid9tonleMQALfrhTFJiQxobBvXYKG5Wcc8VGcHWTHR0ik8w==} + '@rollup/rollup-android-arm64@4.64.5': + resolution: {integrity: sha512-+uu2p/R9Tzn8GpoQyX1pAo5dmKT1DhXevfaCzqzmPFhnLjHLWw7uWkaVGlxmhwYoRiYYhsGfRcD5cTBpL7rgSw==} cpu: [arm64] os: [android] - '@rollup/rollup-darwin-arm64@4.64.1': - resolution: {integrity: sha512-MvzZ+qbBi5jrafURHsASUF1qW/58tOJFt/gFVJo2znQWrKX4CSf/Lt/qGONtoA4yHsNL5QzgdXMuITZxAs62Vg==} + '@rollup/rollup-darwin-arm64@4.64.5': + resolution: {integrity: sha512-17dys+YEmzwzzFVHQAVDONg5FALXY9kd99HFEpfk4gJVHYxoh5bGea3D4t1fXXnwkTcOe25wPyd6nWS0I8IdLQ==} cpu: [arm64] os: [darwin] - '@rollup/rollup-darwin-x64@4.64.1': - resolution: {integrity: sha512-9uj1VBuiPK5ij/+g0mCK17X+V/4SbErvRQMXIQjZAtbl4VcUhv63RhPZsFSWHrCRkTd3FKDtaVTrtT0+8bIhhQ==} + '@rollup/rollup-darwin-x64@4.64.5': + resolution: {integrity: sha512-wg0zQEKkEvFZf1UaaX1UELOoPs//OSKUG7D+yITuqOsAvza7LvHTv5Wu4nmMfzNG7EYI2jp2PJC7Id6OETmsYQ==} cpu: [x64] os: [darwin] - '@rollup/rollup-freebsd-arm64@4.64.1': - resolution: {integrity: sha512-FCoXm836IqcXWhWPRkqlLx3Hjnv9S7c8tg5MFwsgHB3aFCz1JjUy6b1ssrxEjEbqaHpnvRmNjUUHxsXuU85NYA==} + '@rollup/rollup-freebsd-arm64@4.64.5': + resolution: {integrity: sha512-CoJmWcpEMuwin+TZ/ev/H9uDyF/uxUKQSWXdmIPn/UBx/uGV9+4ebMp0FwnlhWR9PE1AdzYsKf3bZevhif38+A==} cpu: [arm64] os: [freebsd] - '@rollup/rollup-freebsd-x64@4.64.1': - resolution: {integrity: sha512-Xa6Oxo86Ilx1hq1vNb69541NOuUyhGEH3Sc0g7eGkfsfRblWh4hAa4Lj2GWwZyfUVYL+Z4xK3TxhwIuZ3fNPLg==} + '@rollup/rollup-freebsd-x64@4.64.5': + resolution: {integrity: sha512-PxZnLAaTUAL5xG0W2BXLeYPKrK2b3LIASV2/e/Kf7PZvSLI1iAQIm9B9aJD+YyFIT7hc6qaMV3+OOO35R28LfA==} cpu: [x64] os: [freebsd] - '@rollup/rollup-linux-arm-gnueabihf@4.64.1': - resolution: {integrity: sha512-Nkw7cVMu1yrczpzr42Mh1BZ5Ai5A4Fsz2Je/frbwHmazpQTJzP+qo7pNjdxHrxVj56ivKTJihNoN90OD1hGxBA==} + '@rollup/rollup-linux-arm-gnueabihf@4.64.5': + resolution: {integrity: sha512-uPo3IvnONjhbFXwWgroBeFwOicuhT7ZwQrnzkzmOtBJzeQbkUJUE1SJDfDI31ijQ5+ZUIA6sPrdUMxTSnxUWAg==} cpu: [arm] os: [linux] libc: [glibc] - '@rollup/rollup-linux-arm-musleabihf@4.64.1': - resolution: {integrity: sha512-JONaLM9mZPXbSetxMzYG3496qoJuWvG2ERCTrrVptfw/Fwe4UzrQoEx/mYEeZCRv/Xz0RldOLFeqDfqmH75/Zg==} + '@rollup/rollup-linux-arm-musleabihf@4.64.5': + resolution: {integrity: sha512-ywI8Jyuc4LyHYTjC0mw4yA1ulvZBkHusdpWnoiEBsmBuHvSnt90btTBGCZ+s/2y+YNNfVAEKy33nPo5UI9zTmg==} cpu: [arm] os: [linux] libc: [musl] - '@rollup/rollup-linux-arm64-gnu@4.64.1': - resolution: {integrity: sha512-OfimHma+prmdoobHI3tfYud2enQ2LXYaMu+iMUQH7IjJkykJ6qUmAs1M/scdQaEKRWysiKwTctsDa2LXvaO0xw==} + '@rollup/rollup-linux-arm64-gnu@4.64.5': + resolution: {integrity: sha512-tmuXJoQ/3ovSr637aykZMdQteU/CB2APAz2CrvsbibuoHZi1BS1Db13cVViBdEARGwXCLn1DSJ8wsjoThLJPGA==} cpu: [arm64] os: [linux] libc: [glibc] - '@rollup/rollup-linux-arm64-musl@4.64.1': - resolution: {integrity: sha512-X5fwh2HM8EHbgfFwpf4m2x2pG/AHdQ2aPDPk+JCDwV4DPeM8yxYmKG1vvm123JSc9gBSu8tu9NECA99wHPztsw==} + '@rollup/rollup-linux-arm64-musl@4.64.5': + resolution: {integrity: sha512-5FMjSYNcUOHx7oW8Qu9KB6jGPpvF/8sG7+BDHwU/Ihh1/6FMJ9ySmsFG4tJ1qbNRuP8OLzCBDso4sF0mQaLuFQ==} cpu: [arm64] os: [linux] libc: [musl] - '@rollup/rollup-linux-loong64-gnu@4.64.1': - resolution: {integrity: sha512-8dp2TxKdjiX/4f7Da9gF7BR29hygxOQlHxKNa8qxJHoqZ13ytrogFTpMPhtVEFrgFu9MSOabAn006PeoygavjA==} + '@rollup/rollup-linux-loong64-gnu@4.64.5': + resolution: {integrity: sha512-K8ZJ+neLDbUkIrL8dqF/5LtuVCrKwo27kREgOlxjBEjlOXwHvDnHLU8Z/UKv/B49qi7e8hsSDOyoJwhwqhvX4w==} cpu: [loong64] os: [linux] libc: [glibc] - '@rollup/rollup-linux-loong64-musl@4.64.1': - resolution: {integrity: sha512-YuYDpRSZnU9qLf6sqyhiBdMRCw5ImECGLNqRjM2hZrJIEwAckameWkRJ3SUnn0oxSewZIib/4iLwyEXj40QqQQ==} + '@rollup/rollup-linux-loong64-musl@4.64.5': + resolution: {integrity: sha512-NlVxsq7PFPv0DBKGuNWRDKixQYQCjM53zl04mxEcKMBmJbCBIUm1JdPfIWDRHyOOFzzYPmLQzfeEwh4716ayQg==} cpu: [loong64] os: [linux] libc: [musl] - '@rollup/rollup-linux-ppc64-gnu@4.64.1': - resolution: {integrity: sha512-gGj3v7YYkysy7IbfclMI4PDtHaa6YX4nU1D5NR1fyvXAGqM4TDk28ZWvrpOkkK92eoQRryAludWz6jNjsm77Qg==} + '@rollup/rollup-linux-ppc64-gnu@4.64.5': + resolution: {integrity: sha512-ARhRHJYs5eCFet5azfrHD97vOkD8OzNW2RSMlvo5CcBqXaTOLfp0OHDtUQh7/K5AL5fUYoFp2fgC9KDg4vVYMQ==} cpu: [ppc64] os: [linux] libc: [glibc] - '@rollup/rollup-linux-ppc64-musl@4.64.1': - resolution: {integrity: sha512-DTZVwvS94FUYpP0CjCfz2iT0XTmBfQGc/arx9IdwUbDImpe9h8dWuMT/oPUvcGiwLKMQoNmuFBx3AVajm+FNjA==} + '@rollup/rollup-linux-ppc64-musl@4.64.5': + resolution: {integrity: sha512-atSgreM5C7jpxd9aEXN+6vJ5wTd05iYw+S3FiQpw7VsoEl8B90llbq35ARON+GOHj5QlVQEq2vOKWCHTob/BSQ==} cpu: [ppc64] os: [linux] libc: [musl] - '@rollup/rollup-linux-riscv64-gnu@4.64.1': - resolution: {integrity: sha512-NWnyiq2moc8iEHGyTjIFadJTy8VCvCU/rUBfor+3l30JOQKAifpmKdxX4ZxRRPSPE/rLhFpLADdzNjS3Ldctdw==} + '@rollup/rollup-linux-riscv64-gnu@4.64.5': + resolution: {integrity: sha512-vmlmwBFGnjVWxSRoVabNkyYuscSmg52Pd0fM8jEbNT3Jmka4A6HcB84x4uAmuumznWfBVaxKOqU6jbEgomWKCA==} cpu: [riscv64] os: [linux] libc: [glibc] - '@rollup/rollup-linux-riscv64-musl@4.64.1': - resolution: {integrity: sha512-yIz+7L37g7bVOGLaUQmGqiYADH262krL4dtf5zU6QGldPgOairLEgW1FTs5pP0UFkHq5uf2qxDttOFsVAX6kxg==} + '@rollup/rollup-linux-riscv64-musl@4.64.5': + resolution: {integrity: sha512-hhJrP6S9WkbsbcHgUkvCBS5Cn8IdsG8XjlLZyxjnv9+NdoYfbbZE4TWJYr8apdaj1M5t5Y1id2StnEslxpNFyA==} cpu: [riscv64] os: [linux] libc: [musl] - '@rollup/rollup-linux-s390x-gnu@4.64.1': - resolution: {integrity: sha512-sRK+GWovJZV6ijyV/k1Ft3FL5+4DscF5OYsJolTbhVTTLFxKOPVjS0wxUUHakvL0vRw/cbFxZNeZLfM/EzuQhA==} + '@rollup/rollup-linux-s390x-gnu@4.64.5': + resolution: {integrity: sha512-NNVCyN9pGrwFmQa4bf+Cnf5aVH3g6ZpnlOg1Cs/H9swIHT9bRixijfzUqyEIWm1WtiAuR1LJ+rJH6zpBm8kgQA==} cpu: [s390x] os: [linux] libc: [glibc] - '@rollup/rollup-linux-x64-gnu@4.64.1': - resolution: {integrity: sha512-T2C0NXqqD063yJdm8UGdcoudBATDODdphEXWS7rEoh0jOITfoEBv7LHfRBYVsy+pI7wwxgScoZpkFiQOf40ryQ==} + '@rollup/rollup-linux-x64-gnu@4.64.5': + resolution: {integrity: sha512-dR9nd6OKnvSS60Ifz/L7Mj5zzYyoqyRn2NwTuaOONKaa3xsVGXyp8YusMbvFyEOR94DxnwgcbgsFqkHd29ZSzQ==} cpu: [x64] os: [linux] libc: [glibc] - '@rollup/rollup-linux-x64-musl@4.64.1': - resolution: {integrity: sha512-05wl8uRZMkcobB6YZrzskr2SiM0VOdzlFw3bAxOjKKTt3M6o3O0X/hE/8xk15u8oQY17xUCdTKcNMMg45ZAFog==} + '@rollup/rollup-linux-x64-musl@4.64.5': + resolution: {integrity: sha512-1tzsMjaqhsh3bAO6SJiJqh8hIr9sSPRd+i2vPPxJHod8/XYnf9TEnK0z/u3r1z1AkI347X0KbRSg9dWcxeGahw==} cpu: [x64] os: [linux] libc: [musl] - '@rollup/rollup-openbsd-x64@4.64.1': - resolution: {integrity: sha512-NoRZK1VclOgn9x3b9vPJ3sTxwvQ/F+Hf93xurRKSFJKiwNZyQZnLxVpqlCejhDvesMLMF8VNN+Y4jHTFddV/Xg==} + '@rollup/rollup-openbsd-x64@4.64.5': + resolution: {integrity: sha512-01mWMQblKoXXsmk28KXtpbA96w7g/aOWUoV3AC16fdHdqkykGalqyyM+5u8M7uP5/MEMiiPv69Hv7iv/hEH/dA==} cpu: [x64] os: [openbsd] - '@rollup/rollup-openharmony-arm64@4.64.1': - resolution: {integrity: sha512-SDkX4OkZBePUPf0/XsXVJLwS+O61CmkDKuIyk5CeWddK3vkE8AZjmWK+p1ILRez4wnbS5rTK+U9YmcbRyx2dHw==} + '@rollup/rollup-openharmony-arm64@4.64.5': + resolution: {integrity: sha512-trdnMPb/DNm4V/CgsaoGgr90HfQQ071wfK0KoIs4YpLvjBgVQGXhGabg2Z6nK4EcYNilrb9ZZPcsP6+zpJIdxQ==} cpu: [arm64] os: [openharmony] - '@rollup/rollup-win32-arm64-msvc@4.64.1': - resolution: {integrity: sha512-JQ7el/Plr3juYFxIVu9YXDPNl57XR2L8WIc87JX9wj0L3goV8fXQPQXb3DaHVXq61X/WCGWsTCQsQHo6/Mz5UQ==} + '@rollup/rollup-win32-arm64-msvc@4.64.5': + resolution: {integrity: sha512-x2LxZlfdfsw99T6/qb9EqE/Qi84JWzibjyOJyhJsgFJy6CafaTiqIXCCnslCGrV5XWNh7fwrS3FbRENcuKnooA==} cpu: [arm64] os: [win32] - '@rollup/rollup-win32-ia32-msvc@4.64.1': - resolution: {integrity: sha512-oZSlQ2H3ZDOz3ce1jEyuOZKuD0tPY/D2cKGMcMl0jhHQauBvkHHKAGR1OeRiMluvu3itzLRU2xCTUZptLayObA==} + '@rollup/rollup-win32-ia32-msvc@4.64.5': + resolution: {integrity: sha512-/Qd/9aDQIo0+jmItgBmPIs8195YVbDxRRApn47GyufgbutCDOh7eP5vSKKlI4QNFeaI+wKQAkSMsPnF3EuMpaA==} cpu: [ia32] os: [win32] - '@rollup/rollup-win32-x64-gnu@4.64.1': - resolution: {integrity: sha512-Do2m3jUeVAvUDpee/yVZYRqhO8Ecx4x5sX3EVGalqLx+OxecLDGx3sIwPEm1Nq+MFK2FV3pgdpwWP4624b85Og==} + '@rollup/rollup-win32-x64-gnu@4.64.5': + resolution: {integrity: sha512-ngUJ/XvOWrqbd2IMsfXfh2xXFLTP3sY7sCKvxbGvYdBZ1KmXFd3ewDZ9n3/GNzAUgzRuhLT/UvJRivbNoAQRBw==} cpu: [x64] os: [win32] - '@rollup/rollup-win32-x64-msvc@4.64.1': - resolution: {integrity: sha512-KpxCwRn1Qh3tmBHAqIAF4HtUCVKqZd0w57TsItWblx3QVeJLtXaSgeBFAj1WAvBSpBo+Mh9iZCjj6YW/HaBVMw==} + '@rollup/rollup-win32-x64-msvc@4.64.5': + resolution: {integrity: sha512-IhV6ew/DuzUWwHaYmlh7MrPCV3lKFUq/amTEwysi4r/mwNPAEfAMh5dYWeTSPTeMy2pFHGMEWYtPkHzfX3tG5A==} cpu: [x64] os: [win32] - '@rollup/wasm-node@4.64.1': - resolution: {integrity: sha512-NX7sXK/FT9RBgFxkMKB3jFcc3LCcUL/44PMJ8BBE0t0ljgXih0tZrUPUdZEN/JnN1N7i5axbGQtt5iPwlFJDQw==} + '@rollup/wasm-node@4.64.5': + resolution: {integrity: sha512-kN33cPixKuDMgrYkRnkAW7iwiDWzRhNUgVY+IpcniQNXuIvDAAv0cFgZsaLEFP1z8eqVGhKG13dy5hFN3yBy+g==} engines: {node: '>=18.0.0', npm: '>=8.0.0'} hasBin: true @@ -3777,39 +3873,39 @@ packages: '@types/yarnpkg__lockfile@1.1.9': resolution: {integrity: sha512-GD4Fk15UoP5NLCNor51YdfL9MSdldKCqOC9EssrRw3HVfar9wUZ5y8Lfnp+qVD6hIinLr8ygklDYnmlnlQo12Q==} - '@typescript-eslint/eslint-plugin@8.71.1': - resolution: {integrity: sha512-nNlBf6HuotqMgZvSkWD5hNdemiBIxQ2NmrlgfcUIeZRs+BbakjscCQRq/Hb74EFVnFiSWWdL12JruqwBy3ERDw==} + '@typescript-eslint/eslint-plugin@8.71.2': + resolution: {integrity: sha512-K72/pvT7qpm8q3k8G5u93NCSN1RcLxX5h7Gw0bQpbMXviBHeY6Nx1WEwmk9wP+eKTSQ8ecxvcgt/ZX/rB938xQ==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: - '@typescript-eslint/parser': ^8.71.1 + '@typescript-eslint/parser': ^8.71.2 eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 typescript: '>=4.8.4 <6.1.0' - '@typescript-eslint/parser@8.71.1': - resolution: {integrity: sha512-oM/5sAqz/l1v/zYK1qTOPrn2+JIrBGC1V6uNYucRO5gh6eT9vWJ/RhPbGE59byvZEUQ4VP6XkLBaS5Jti5jpvw==} + '@typescript-eslint/parser@8.71.2': + resolution: {integrity: sha512-aTtmZjp/x3gsGHkDs04/1I8kNogBJkpQaeGaN0PfiG43NzDEmW2n+OP5im9wfsvyX0yP1UZWBrAGtDBfH9jEVw==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 typescript: '>=4.8.4 <6.1.0' - '@typescript-eslint/project-service@8.71.1': - resolution: {integrity: sha512-Oijc9RUsohHjncg6iGi7gCtjnEjYt9FWv9u6ygK8uKcHK5eLjLAkqERQ9BaytbpceOFdk6kifPCS/zAZE+A99g==} + '@typescript-eslint/project-service@8.71.2': + resolution: {integrity: sha512-Pd68GsLVh5ZXlcEccFPdhSOvtHZ/2WU0XsA8zmXOS3F158lVlcTLhfQ6qvtL1RzbMie0Kp8xtbVwAg4nejKPHw==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: typescript: '>=4.8.4 <6.1.0' - '@typescript-eslint/scope-manager@8.71.1': - resolution: {integrity: sha512-1YUDZXdTnXLlob03SFHBipdyMBsDVm7zoSz0ytTJ39dk5J1TgsTK03VlR/dLXG/RLLUrPcYbD4rp23BmHxHP0w==} + '@typescript-eslint/scope-manager@8.71.2': + resolution: {integrity: sha512-YF4wgg5iUX5Obywoac27B56FhozMNFhdJSbh11H5GBAwmBtfyRhmgTQqW9tRNNmHDvsZ2CX6UGzoz+YfYn2Leg==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@typescript-eslint/tsconfig-utils@8.71.1': - resolution: {integrity: sha512-oTvkml5SxXhgg+WWKhod5qWQICDXtOB+/Hi9VdPKFAANJ2b7YOgMffgvzXuqog7R6A/JtrzRf128dsxummyWhg==} + '@typescript-eslint/tsconfig-utils@8.71.2': + resolution: {integrity: sha512-jz49TAWokm/7yWD9/o837nYax9DyALxIPOImdImvVzo6canBCZYzin8zJyqNR5k1j9K1DE0bVvr0XYB+99uAdg==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: typescript: '>=4.8.4 <6.1.0' - '@typescript-eslint/type-utils@8.71.1': - resolution: {integrity: sha512-kH3t3jZCYv2PZSBEWPKTariLrCaoF1CLoPitYFBJOhAGEwWnSRAtGEifrfrpBa4K9JlwWNZotgA5w3/wLSk/FQ==} + '@typescript-eslint/type-utils@8.71.2': + resolution: {integrity: sha512-cC8UaalCViJkb3rH/xLIvidEwoFRtMZMUqDjjJMGEKaTFwYRHYBcoczlEGHuvkHEO8svRDrgZ0yQgOArFmwang==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 @@ -3819,21 +3915,25 @@ packages: resolution: {integrity: sha512-ybYnPTUwg3VQQOFEiBPLs8Jxl1ry2vXdn1kVKguomBbvxpetdu3MKTNDqFNUrlG8ylP9MpZosmXMFYlGQHk1oQ==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@typescript-eslint/typescript-estree@8.71.1': - resolution: {integrity: sha512-pSKSEK1JJpHs6KiKVtABCE4iJK5d7FLFzDXQNBQ2oRY7LEd3UwOt3TZemTgu9syTIf56dJWlTn/pdmrO9oKUXQ==} + '@typescript-eslint/types@8.71.2': + resolution: {integrity: sha512-y5Ukl3oVp7e/VGxqIoEXoeb/Roj71PAJ4WG/N/RGj+eeDvKRLM15kGr9MijLbN0i03S52zxu31Z98E5gWChJKw==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@typescript-eslint/typescript-estree@8.71.2': + resolution: {integrity: sha512-DgNOEsl4pdYzwSL+N/Cl33tX1Hlw3FvId73LnKXfq7jnrF2viOEn7X+P7RBkkSWCVm92gnWd28GIC5vJuLREeA==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: typescript: '>=4.8.4 <6.1.0' - '@typescript-eslint/utils@8.71.1': - resolution: {integrity: sha512-CBjT6gfAz3DW2j9Q4moFnqt208Aq+506sVGXfpRcyAeqn0EpayL0mjdWoCO2t3RC7GewNrFxdeehuEaPg6DMzQ==} + '@typescript-eslint/utils@8.71.2': + resolution: {integrity: sha512-RyKa1G1M9rKHDhrk+HJtiF1MvLD5Ux2JW3TSkzw+02pRALdpJb+QzG1Y5em+LvCgzGwgg8H7mBRFKljNz7ImPw==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 typescript: '>=4.8.4 <6.1.0' - '@typescript-eslint/visitor-keys@8.71.1': - resolution: {integrity: sha512-0GxiUGqMU0qXJt58cBsiG3DP8lUmBaFo2vChtUX+CT7PnR3v/VGLLrzVP4K9r1lNiZXjHYefMBbPunplr09v6w==} + '@typescript-eslint/visitor-keys@8.71.2': + resolution: {integrity: sha512-zozlN0UA32bSG2zkKAgQyRYSbEISVoyU6vvkKYo2aSny74D8Jh4e+POkJ6Lk0dlezZi5x7TtD+88Xb06IB8nhg==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} '@verdaccio/auth@8.1.5': @@ -3917,11 +4017,11 @@ packages: peerDependencies: vite: ^6.0.0 || ^7.0.0 || ^8.0.0 - '@vitest/coverage-v8@5.0.3': - resolution: {integrity: sha512-+klsyz7BvT1vCU28Zkfzms1Ia78XD0V41U3FUtRaa3S+vOr/EXvK1O6BvVD7l1RzEjm6SONR2aybOvDDf9u0mQ==} + '@vitest/coverage-v8@5.0.4': + resolution: {integrity: sha512-P5YcQY8Y6RmoE9xRXI38rT8pssbcubEzqtYTM2XQoxOXMDn04nRaTI1SM8qCl9/NfW3ag9GlzdSXu7IwO5Ft8A==} peerDependencies: - '@vitest/browser': 5.0.3 - vitest: 5.0.3 + '@vitest/browser': 5.0.4 + vitest: 5.0.4 peerDependenciesMeta: '@vitest/browser': optional: true @@ -3934,10 +4034,10 @@ packages: resolution: {integrity: sha512-gUsfXZJbzPamoIY5TvHFiMMoXESBrUMo+xqaj+rYrWI69+EnvRlYBlP96ZnHPY4vX8kyUpgAnFUCg5wZG/HkDQ==} engines: {node: '>=22'} - '@vitest/mocker@5.0.3': - resolution: {integrity: sha512-T8sWAIbkSyAjkwTcaEc3Iu0o9A27X1/kdXrizhZkGuSKScRQtRzclfAMpOTcGdXCsqxeWlpGy3XjqaW8CpLORg==} + '@vitest/mocker@5.0.4': + resolution: {integrity: sha512-tqAlrYWce4iUxhr3ncNohejtCTOcHeE8XWrSNZY3OhPoDn01yeGv+gnaBy64ATp7o6pb03eIbBAjzmibpc9vIQ==} peerDependencies: - msw: ^2.4.9 + msw: ^2.4.9 || ^3.0.0 vite: ^6.0.0 || ^7.0.0 || ^8.0.0 peerDependenciesMeta: msw: @@ -3945,8 +4045,8 @@ packages: vite: optional: true - '@vitest/spy@5.0.3': - resolution: {integrity: sha512-XhFysQTB8AZ+P4gMi+Lpo99vg2AZi0qKpaB9yXQl37+CaMEAPO3iH/wGVnSyL5MPERiLezpqTVtrR6UZH5GCXg==} + '@vitest/spy@5.0.4': + resolution: {integrity: sha512-MZKk/gSkm2q+ICobMxCpH1mA+cCAWm8WV7UhxlqGjq/sJ3AGc1BqFOs5CRVXxH78wQtme9q/NAAgBquj4AcyMw==} '@webassemblyjs/ast@1.14.1': resolution: {integrity: sha512-nuBEDgQfm1ccRp/8bCQrx1frohyufl4JlbMMZ4P1wpeOfDhF6FQkxZJ1b/e+PLwr6X1Nhw6OLme5usuBWYBvuQ==} @@ -4084,6 +4184,72 @@ packages: os: [win32] deprecated: yuku-codegen is pure JavaScript since 0.14 + '@yuku-core/binding-android-arm64@0.19.0': + resolution: {integrity: sha512-wdL2XmTiZixAOaHk9Z0JJZ8u9Qm8d333Zjpc6gaxXFX+UR5BlsfxZ7a2+2Rm71pamppsPYGUGFq2oVLbh6DISw==} + cpu: [arm64] + os: [android] + + '@yuku-core/binding-darwin-arm64@0.19.0': + resolution: {integrity: sha512-7sNJa6XJhyetnTy64jw3NEi4YgUcezHk1G5GH9FSvXAuC8wIlbaOwT9lgq5qo5sspjrZJQlBR1TWflP49uRpMw==} + cpu: [arm64] + os: [darwin] + + '@yuku-core/binding-darwin-x64@0.19.0': + resolution: {integrity: sha512-pTC7dYEc59isdyizc3nsuyFNBu2LU5wMYZ1be6UMr59PY/AJNtO1aBLWV0MgL/z7C1nv/2sX4TNjGgKLoeevJw==} + cpu: [x64] + os: [darwin] + + '@yuku-core/binding-freebsd-x64@0.19.0': + resolution: {integrity: sha512-xrZjF6XOEwyLOiDIfrwDdRCS6ghxcJeirNC1KivQhVcUwlRonaU79S3/Uiyx3lBylPnT8qKJ3/aMT+H52nGTJQ==} + cpu: [x64] + os: [freebsd] + + '@yuku-core/binding-linux-arm-gnu@0.19.0': + resolution: {integrity: sha512-0OyIH53C0I1CbADHn9FSdCfX5qbpeLwJhmOVhonFJNYheybOnkSJ50qGMfTJIb8y5zrwqvLs7FVBvz6Fk8maZg==} + cpu: [arm] + os: [linux] + libc: [glibc] + + '@yuku-core/binding-linux-arm-musl@0.19.0': + resolution: {integrity: sha512-z/iPfkCOCSXE34VXNt0uP1ORSW+4mEa9b5CiJcWZeqZH08g49bFU/jRM2T04f+Wpw5mJ6HIzNBiojxeAbrHjeg==} + cpu: [arm] + os: [linux] + libc: [musl] + + '@yuku-core/binding-linux-arm64-gnu@0.19.0': + resolution: {integrity: sha512-jLNTi+gzaRwBJ+gwhCJ+rDb5dmx/8hEBx93UWd7hjMSqPTL1D1wvVSvXVAldV5kALvju7b0/m51EHEhs4+I1fA==} + cpu: [arm64] + os: [linux] + libc: [glibc] + + '@yuku-core/binding-linux-arm64-musl@0.19.0': + resolution: {integrity: sha512-YwyPIdW/rN2Fmv0MTFWi47FaB3F9g+2b+sJISyAw83Yd60RWH4T3Nx6XkAHHVN+uKJNBAd6So7/BVihSiFYvuQ==} + cpu: [arm64] + os: [linux] + libc: [musl] + + '@yuku-core/binding-linux-x64-gnu@0.19.0': + resolution: {integrity: sha512-/vskaAXVX3ESR43FiTdfiYS7z1b9uoQJwVQ/0RgUHgN2sWoAyCZs+aX4CgU7eKGIHTVfp9VFwv+c+2XchYiEtQ==} + cpu: [x64] + os: [linux] + libc: [glibc] + + '@yuku-core/binding-linux-x64-musl@0.19.0': + resolution: {integrity: sha512-FuXL5igeSKib9Rye02TdH+D6SQezTyGxIATMu1Qsn/QywrzwpGl35OLpS2C1x5vpGLeVE2XgiLd5mVPFHmIglQ==} + cpu: [x64] + os: [linux] + libc: [musl] + + '@yuku-core/binding-win32-arm64@0.19.0': + resolution: {integrity: sha512-YuJAe7zEKT1Xa7LuHlhGJpPnYQeVtvo0rZvNjJRqkH0hQGOw4C8QeP30Tg5VKGzZfo2x8CjhjEhKt4TmLwfmdg==} + cpu: [arm64] + os: [win32] + + '@yuku-core/binding-win32-x64@0.19.0': + resolution: {integrity: sha512-o8iY/mXwlRkedp0LNTr4+TEfXTPQwoNZmv6k+1WIAd1ZXEn8xJJTBCtB0osaVvdZo/x/cNmV16UrWrrGpM5Mvw==} + cpu: [x64] + os: [win32] + '@yuku-parser/binding-android-arm64@0.10.2': resolution: {integrity: sha512-2VPBU9fRGRAQ2xPAvghnec3oou5Nrxm2Bezhf+13UMspAxQSkF/32r+ySKXSwIPA5/RivumDJDxAxc301Sgicw==} cpu: [arm64] @@ -4165,6 +4331,9 @@ packages: '@yuku-toolchain/types@0.10.2': resolution: {integrity: sha512-sSeo4SSSToiS+sSD+bwn/s94EEcaLJ7tG5LCp8gFYC1G5VzxzX7fqB6m9RU1yMD8KTpu6zdU/I1NlQf8hVBJ9Q==} + '@yuku-toolchain/types@0.19.0': + resolution: {integrity: sha512-tFkNbsP4WXX9UMUC5syJGdK9dPMLK0PPaIuXCcCYH75sZ8MrebfBZ2XvCILRTw8AgLivSSCfDa4R67iYBDa4Kg==} + JSONStream@1.3.5: resolution: {integrity: sha512-E+iruNOY8VV9s4JEbe1aNEm6MiszPRr/UfcHMz0TQh1BXSxHK+ASV1R6W4HpjBhSeS+54PIsAMCBmwD06LLsqQ==} hasBin: true @@ -4456,8 +4625,8 @@ packages: bcryptjs@2.4.3: resolution: {integrity: sha512-V/Hy/X9Vt7f3BbPJEi8BdVFMByHi+jNXrYkW3huaybV/kQ0KJg0Y6PkEMbn+zeT+i+SiKZ/HMqJGIIt4LZDqNQ==} - beasties@0.5.4: - resolution: {integrity: sha512-8/lOOjT+PElYCnaUbmhgd3Uad5R1VTQ4Wg0k4rK8bX04m5WEqHNmnlLy3Q/lJ7dk25XA+72gayzc/skTfKKpcA==} + beasties@0.5.5: + resolution: {integrity: sha512-4mUqdlIqPmHlX5qwkGmunWnhi406XcT5AfmwltoiDCToyGP2pSxS9ClfURL14IRwPYHq/JAIrtjNptbpSvUTPA==} engines: {node: '>=20.19.0'} before-after-hook@4.0.0: @@ -4626,8 +4795,8 @@ packages: resolution: {integrity: sha512-rNjApaLzuwaOTjCiT8lSDdGN1APCiqkChLMJxJPWLunPAt5fy8xgU9/jNOchV84wfIxrA0lRQB7oCT8jrn/wrQ==} engines: {node: '>=6.0'} - chromium-bidi@17.0.2: - resolution: {integrity: sha512-5v9GQFhTktFvotn/OFNJBmKLKRAb6n9r0bVCwf7sHgWc3/JryK0bj1nn93L3pHFrfgcsu6Be6EWsDi+1XHTGDg==} + chromium-bidi@157.0.8090-0: + resolution: {integrity: sha512-KJw7IQgqXwxpJgJlEIPg5mr2ZoqA+jkTRtc5EABI7sUJ3bu3cpI7NuEBoj4Gn1AsF78CaT9So5WQWspK3/wYag==} engines: {node: '>=20.19.0 <22.0.0 || >=22.12.0'} peerDependencies: devtools-protocol: '*' @@ -4750,6 +4919,10 @@ packages: resolution: {integrity: sha512-5jRCH9Z/+DRP7rkvY83B+yGIGX96OYdJmzngqnw2SBSxqCFPd0w2km3s5iawpGX8krnwSGmF0FW5Nhr0Hfai3g==} engines: {node: '>=18'} + content-disposition@2.0.1: + resolution: {integrity: sha512-e+H0ZXHSWYrENhQzw1LPuP4oF5MzVKmDU6d3hxlvaPEYLLg62MxtQNPRx4SYSuYJSBUgnQIG4HIN2tEtNv7Dog==} + engines: {node: '>=18'} + content-type@1.0.5: resolution: {integrity: sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==} engines: {node: '>= 0.6'} @@ -4976,8 +5149,8 @@ packages: engines: {node: '>= 0.8.0'} hasBin: true - devtools-protocol@0.0.1687809: - resolution: {integrity: sha512-t7kSb+UKYdyxcmqy98U2P86ne6rCve3DIJ4+lp54i/hhClgFuG35JrLj23rO14Jw3sWDsp7i+22QhNU0+/qk8g==} + devtools-protocol@0.0.1696802: + resolution: {integrity: sha512-FO5/SENfvc2K8wRnWQflKcwuoTH4dBkXCWTQ9ebIWtuX8JM5+ZvCotaEmkfh21pO7TvIKGTM3hG4xFiq9WTwmg==} di@0.0.1: resolution: {integrity: sha512-uJaamHkagcZtHPqCIHZxnFrXlunQXgBOsZSUOWwFw31QJCAbyTBoHMW75YOTur5ZNx8pIeAKgf6GWIgaqqiLhA==} @@ -5322,6 +5495,10 @@ packages: resolution: {integrity: sha512-hIS4idWWai69NezIdRt2xFVofaF4j+6INOpJlVOLDO8zXGpUVEVzIYk12UUi2JzjEzWL3IOAxcTubgz9Po0yXw==} engines: {node: '>= 18'} + express@5.3.0: + resolution: {integrity: sha512-qCqy1xSoaugxOD4IVHb1ZWdkvCF2W3aE2okKouWj8VwJ+ztskSiXoBnCSJqfKT+cVPJhuJqe9YLbY425+Zh00g==} + engines: {node: '>= 18'} + extend@3.0.2: resolution: {integrity: sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==} @@ -6371,8 +6548,8 @@ packages: lines-and-columns@1.2.4: resolution: {integrity: sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==} - listr2@11.1.1: - resolution: {integrity: sha512-zArGFXg2/nhA1vYBz789VpwzMQQXkGZiRxeguxFCsDrg4S+LOR22v4oQlSdTN7dR14XgOW+pW33UfvKf+i8nrQ==} + listr2@11.2.0: + resolution: {integrity: sha512-+H/hEo9EA7tyLY0ZihpDg76jHWolc0nCjbjnXFguSm4Epk+WYtL1w1tYs1kjEo229NmhgLmUrncyn81K1vBoRw==} engines: {node: '>=22.13.0'} lmdb@3.5.7: @@ -7181,12 +7358,12 @@ packages: resolution: {integrity: sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==} engines: {node: '>=6'} - puppeteer-core@25.12.0: - resolution: {integrity: sha512-z6LQUt5SH7jwGtGA+nMtJuEjZIsqPiwQ+EFHCYuVDQrJpvifNmmGuyDvTzAKPyFzihxgHc5f3aMzu2kn8Ps37A==} + puppeteer-core@25.13.0: + resolution: {integrity: sha512-cyBS0OEx3e9NS53B5F6+UazXtR7f9Tw0cR1/FbPW59/hV6JPZbkIiMnxK2543IkFp3rsGlLn1iPDLF77TJsJsA==} engines: {node: '>=22.12.0'} - puppeteer@25.12.0: - resolution: {integrity: sha512-agM9cYcxbvmU17w9qtF17s7/Vv7Dhbyig6AWwIgvQQLR2dKZdPqNvRPanac7xH4iMPcNYOCfyCkwqCnR4nVOcA==} + puppeteer@25.13.0: + resolution: {integrity: sha512-vB4KLXTT5QqlikcOQ/xV0RY18bBVtNyLUTfqJ9mW+penHyoM+5DmANYuDCI4jgBtiL0eD9I5ZFSafW6/a6Trpg==} engines: {node: '>=22.12.0'} hasBin: true @@ -7398,11 +7575,38 @@ packages: vue-tsc: optional: true + rolldown-plugin-dts@0.28.8: + resolution: {integrity: sha512-FVhfqxorCWcc20BVT5eVRfRjzLLl6mgzjcMR4gSBf0K4oQMXT0qoHhhzfXy0L7y83fQy7Ug5ZDNk90xM3/LiCQ==} + engines: {node: ^22.18.0 || ^24.11.0 || >=26.0.0} + peerDependencies: + '@typescript/native-preview': '*' + '@volar/typescript': ~2.4.0 + '@vue/language-core': ~3.2.0 || ~3.3.0 + rolldown: ^1.2.0 + typescript: ^5.0.0 || ^6.0.0 || ~7.0.0 + vue-tsc: ~3.2.0 || ~3.3.0 + peerDependenciesMeta: + '@typescript/native-preview': + optional: true + '@volar/typescript': + optional: true + '@vue/language-core': + optional: true + typescript: + optional: true + vue-tsc: + optional: true + rolldown@1.2.12: resolution: {integrity: sha512-8wafseiaG80xmXSfqidUNqZcylTlhmPZZt+za2m+js2sFZ8dTNlhIOV2WcbIPx2hgwPBJpEUGFAMZ9bgBBLTSQ==} engines: {node: ^20.19.0 || >=22.12.0} hasBin: true + rolldown@1.2.13: + resolution: {integrity: sha512-/5apOkwWxtACcQtZ5WlrAsKS4JwXVThQPJZ3RqIruRY9UG9M8e0VlXN068xum/JRKA4aIUoJ13ghe/kGCvidiQ==} + engines: {node: ^20.19.0 || >=22.12.0} + hasBin: true + rollup-plugin-dts@6.5.1: resolution: {integrity: sha512-jODTXp3H7MK/Ur/ErtsrQ0G1GvaCmc3du+y5pNrdBMf6d7HlL2Nd/N6TkEr+f75CkUj01zEoEd7y2elH0eHi1Q==} engines: {node: '>=20'} @@ -7424,8 +7628,8 @@ packages: '@types/node': optional: true - rollup@4.64.1: - resolution: {integrity: sha512-7s4V+3J8ux75WNj9qwSJnrWmlCmZ2YHr2fojtHy5RiIMvhJv6DGe7HKKz7L6G1sq1Eg1fLC8SjYtAtDis1F4CQ==} + rollup@4.64.5: + resolution: {integrity: sha512-EAP5ZHcz2ijbgCWwPkpI7zh6bfsri2Ez5FtCy2dCp1k62duXzfG7DLGGh7RU2QQXWwavT+u4qpvDF/TWOiiGTw==} engines: {node: '>=18.0.0', npm: '>=8.0.0'} hasBin: true @@ -8261,8 +8465,8 @@ packages: verror@1.10.0: resolution: {integrity: sha512-ZZKSmDAEFOijERBLkmYfJ+vmk3w+7hOLYDNkRCuRuMJGEmqYNCNLyBBFwWKVMhfwaEF3WOd0Zlw86U/WC/+nYw==} - vite@8.3.3: - resolution: {integrity: sha512-cTAldKPImjg6c+gk48U19POPn3GCBzZwpdsN8ZMEEcbpes+6/wvfqUd0C2y3qYY4wsj8PwgFwrZ/1jBPVttMSg==} + vite@8.3.4: + resolution: {integrity: sha512-IftLE8phJhdNRIGNEV4JCCvfNScoZQVfcXaN8TQropWGJtOHcu+iAB9pHcuGvmEb/kddw0LBe/jS8ztdC6xdiQ==} engines: {node: ^20.19.0 || >=22.12.0} hasBin: true peerDependencies: @@ -8304,20 +8508,20 @@ packages: yaml: optional: true - vitest@5.0.3: - resolution: {integrity: sha512-xMw97S3rjdtj5dkVat7jCsqWBpvchs3RlpQctUqwJD0KkERk40vz2fJ77lDwW/Vzh/pk18eItYAzkodhSes3jQ==} + vitest@5.0.4: + resolution: {integrity: sha512-z0WxZRV2Sg48wF0FSgMq3TFG8JS38/Qr96vZVZdX6+Em9raQTvnXQvdTFJe2m3rfyJnEHeHQ/snceIdi8D1pVg==} engines: {node: ^22.12.0 || ^24.0.0 || >=26.0.0} hasBin: true peerDependencies: '@edge-runtime/vm': '*' '@opentelemetry/api': ^1.9.0 '@types/node': ^22.0.0 || >=24.0.0 - '@vitest/browser-playwright': 5.0.3 - '@vitest/browser-preview': 5.0.3 + '@vitest/browser-playwright': 5.0.4 + '@vitest/browser-preview': 5.0.4 '@vitest/browser-webdriverio': ^5.0.0-beta.5 || >=5.0.0 - '@vitest/coverage-istanbul': 5.0.3 - '@vitest/coverage-v8': 5.0.3 - '@vitest/ui': 5.0.3 + '@vitest/coverage-istanbul': 5.0.4 + '@vitest/coverage-v8': 5.0.4 + '@vitest/ui': 5.0.4 happy-dom: '*' jsdom: '*' vite: ^6.4.0 || ^7.0.0 || ^8.0.0 @@ -8367,8 +8571,8 @@ packages: web-vitals@4.2.4: resolution: {integrity: sha512-r4DIlprAGwJ7YM11VZp4R884m0Vmgr6EAKe3P+kO0PPj3Unqyvv59rczf6UiGcb9Z8QxZVcqKNwv/g0WNdWwsw==} - webdriver-bidi-protocol@0.4.3: - resolution: {integrity: sha512-uuN0goWfxP22B7J/uAgBpOYNPttC+XVseYE+rSY5+rQ+YBeVz/VORw8WbmLVcqW78zNg5A4qnjNXYUWR3il2ig==} + webdriver-bidi-protocol@1.0.1: + resolution: {integrity: sha512-WXWs/aXF2a6Al1Z2/V/7Gp2oPZOAAmHjJOTmv4KCXRJ122IMj3tSSMc6a4q3K4QOmhQbse/Ahr+oTVJOU2dUiw==} webidl-conversions@3.0.1: resolution: {integrity: sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==} @@ -8607,18 +8811,34 @@ packages: yuku-ast@0.10.2: resolution: {integrity: sha512-UnG9mA6giglCvSErft2/40TVFX750Sj1xgwddPLpG7J7rlr/P1wPADg9G2RK+d/1tNLtRVoLdMMOMVBB9561TQ==} + yuku-ast@0.19.0: + resolution: {integrity: sha512-PyCsiScaelhxBGzL8dyeJkLqvRZycoh78R31Vrt/WqYrm0hMFoKwIw/X7Dx5mBKLWAMlV9I9HEyBOHnj2gZVyw==} + engines: {node: '>=14.18.0'} + yuku-codegen@0.10.2: resolution: {integrity: sha512-hentl2dtrF6cPjiAirtkfxfFZBA6Hdm61UqRJ7cA0qrlDNMk9PZGOjw5w1mx3E0hu/6pHcJF4dJW+D0SXHPZOA==} + yuku-codegen@0.19.0: + resolution: {integrity: sha512-uymAKHjDuaP4BEpkXC/BSLz4DUEF5oArZ5AuD3888nb2miChjWSgpPdojEJxm3pjpXkgUaCRJQyNAbnMN33wHg==} + engines: {node: '>=14.18.0'} + + yuku-core@0.19.0: + resolution: {integrity: sha512-kYK9e1XdfirNhkipzW0wmMcSWcVF/CWnuugodfVYRCUwvoBefweL9HzB96OiKEhsx78V5WbUxbJqlizMX869Qg==} + engines: {node: '>=14.18.0'} + yuku-parser@0.10.2: resolution: {integrity: sha512-CgaU0/PPjCAIEZ3WQroosOxTY3eeKldAN3h+vk8pMNz4+jl1CZzBR4pW+K/rRPF112VooCL5FdjJoiMNjDrL2A==} - zod@3.25.76: - resolution: {integrity: sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ==} + yuku-parser@0.19.0: + resolution: {integrity: sha512-XrBh9ZiQK5mJVRxZBAvD6LwRyAYrK3MFtH3+onyuxFL5hFD44EC3QOmIC1FjTj6H2MMwq46/NAI+NZxLZPZgxg==} + engines: {node: '>=14.18.0'} zod@4.6.5: resolution: {integrity: sha512-v5l/aFXZQeai4awLbOpSoHecE9UiMrnfx75tEXLjNonXVARxQ5mOeipTjROUchszUNCqnE+hqAMujRsRHsut2Q==} + zod@4.6.7: + resolution: {integrity: sha512-g8W2D2kU6a8untc053fX1uVBKzM7yqAxW/3zwk83+6RyF2+SKOuV+c0wBDhUwzV1PaGapmZH+rmcUzPf+3CGwg==} + zone.js@0.16.3: resolution: {integrity: sha512-ihXL9+vhYyEhXz4TDNpHeAOZN9FVrbog0Il64OIEI28UP/n5AaI6gsccRuOHBfx+206agzyoK527bYIO0Foy6A==} @@ -10584,11 +10804,11 @@ snapshots: '@leichtgewicht/ip-codec@2.0.5': {} - '@listr2/prompt-adapter-inquirer@4.2.7(@inquirer/prompts@8.7.3(@types/node@22.20.5))(@types/node@22.20.5)(listr2@11.1.1)': + '@listr2/prompt-adapter-inquirer@4.3.1(@inquirer/prompts@8.7.3(@types/node@22.20.5))(@types/node@22.20.5)(listr2@11.2.0)': dependencies: '@inquirer/prompts': 8.7.3(@types/node@22.20.5) '@inquirer/type': 4.2.0(@types/node@22.20.5) - listr2: 11.1.1 + listr2: 11.2.0 transitivePeerDependencies: - '@types/node' @@ -10615,12 +10835,12 @@ snapshots: '@modelcontextprotocol/core@2.3.1': dependencies: - zod: 4.6.5 + zod: 4.6.7 '@modelcontextprotocol/server@2.3.1': dependencies: '@modelcontextprotocol/core': 2.3.1 - zod: 4.6.5 + zod: 4.6.7 '@msgpackr-extract/msgpackr-extract-darwin-arm64@3.0.4': optional: true @@ -11119,7 +11339,7 @@ snapshots: '@protobufjs/utf8@1.1.2': {} - '@puppeteer/browsers@3.2.3': + '@puppeteer/browsers@3.2.4': dependencies: modern-tar: 0.8.5 yargs: 18.2.0 @@ -11127,53 +11347,98 @@ snapshots: '@rolldown/binding-android-arm-eabi@1.2.12': optional: true + '@rolldown/binding-android-arm-eabi@1.2.13': + optional: true + '@rolldown/binding-android-arm64@1.2.12': optional: true + '@rolldown/binding-android-arm64@1.2.13': + optional: true + '@rolldown/binding-darwin-arm64@1.2.12': optional: true + '@rolldown/binding-darwin-arm64@1.2.13': + optional: true + '@rolldown/binding-darwin-x64@1.2.12': optional: true + '@rolldown/binding-darwin-x64@1.2.13': + optional: true + '@rolldown/binding-freebsd-x64@1.2.12': optional: true + '@rolldown/binding-freebsd-x64@1.2.13': + optional: true + '@rolldown/binding-linux-arm-gnueabihf@1.2.12': optional: true + '@rolldown/binding-linux-arm-gnueabihf@1.2.13': + optional: true + '@rolldown/binding-linux-arm64-gnu@1.2.12': optional: true + '@rolldown/binding-linux-arm64-gnu@1.2.13': + optional: true + '@rolldown/binding-linux-arm64-musl@1.2.12': optional: true + '@rolldown/binding-linux-arm64-musl@1.2.13': + optional: true + '@rolldown/binding-linux-ppc64-gnu@1.2.12': optional: true + '@rolldown/binding-linux-ppc64-gnu@1.2.13': + optional: true + '@rolldown/binding-linux-s390x-gnu@1.2.12': optional: true + '@rolldown/binding-linux-s390x-gnu@1.2.13': + optional: true + '@rolldown/binding-linux-x64-gnu@1.2.12': optional: true + '@rolldown/binding-linux-x64-gnu@1.2.13': + optional: true + '@rolldown/binding-linux-x64-musl@1.2.12': optional: true + '@rolldown/binding-linux-x64-musl@1.2.13': + optional: true + '@rolldown/binding-openharmony-arm64@1.2.12': optional: true + '@rolldown/binding-openharmony-arm64@1.2.13': + optional: true + '@rolldown/binding-win32-arm64-msvc@1.2.12': optional: true + '@rolldown/binding-win32-arm64-msvc@1.2.13': + optional: true + '@rolldown/binding-win32-x64-msvc@1.2.12': optional: true + '@rolldown/binding-win32-x64-msvc@1.2.13': + optional: true + '@rolldown/pluginutils@1.0.1': {} - '@rollup/plugin-commonjs@29.0.3(rollup@4.64.1)': + '@rollup/plugin-commonjs@29.0.3(rollup@4.64.5)': dependencies: - '@rollup/pluginutils': 5.4.0(rollup@4.64.1) + '@rollup/pluginutils': 5.4.0(rollup@4.64.5) commondir: 1.0.1 estree-walker: 2.0.2 fdir: 6.5.0(picomatch@4.0.7) @@ -11181,108 +11446,108 @@ snapshots: magic-string: 0.30.21 picomatch: 4.0.7 optionalDependencies: - rollup: 4.64.1 + rollup: 4.64.5 - '@rollup/plugin-json@6.1.0(rollup@4.64.1)': + '@rollup/plugin-json@6.1.0(rollup@4.64.5)': dependencies: - '@rollup/pluginutils': 5.4.0(rollup@4.64.1) + '@rollup/pluginutils': 5.4.0(rollup@4.64.5) optionalDependencies: - rollup: 4.64.1 + rollup: 4.64.5 - '@rollup/plugin-node-resolve@16.0.3(rollup@4.64.1)': + '@rollup/plugin-node-resolve@16.0.3(rollup@4.64.5)': dependencies: - '@rollup/pluginutils': 5.4.0(rollup@4.64.1) + '@rollup/pluginutils': 5.4.0(rollup@4.64.5) '@types/resolve': 1.20.2 deepmerge: 4.3.1 is-module: 1.0.0 resolve: 1.22.13 optionalDependencies: - rollup: 4.64.1 + rollup: 4.64.5 - '@rollup/pluginutils@5.4.0(rollup@4.64.1)': + '@rollup/pluginutils@5.4.0(rollup@4.64.5)': dependencies: '@types/estree': 1.0.9 estree-walker: 2.0.2 picomatch: 4.0.7 optionalDependencies: - rollup: 4.64.1 + rollup: 4.64.5 - '@rollup/rollup-android-arm-eabi@4.64.1': + '@rollup/rollup-android-arm-eabi@4.64.5': optional: true - '@rollup/rollup-android-arm64@4.64.1': + '@rollup/rollup-android-arm64@4.64.5': optional: true - '@rollup/rollup-darwin-arm64@4.64.1': + '@rollup/rollup-darwin-arm64@4.64.5': optional: true - '@rollup/rollup-darwin-x64@4.64.1': + '@rollup/rollup-darwin-x64@4.64.5': optional: true - '@rollup/rollup-freebsd-arm64@4.64.1': + '@rollup/rollup-freebsd-arm64@4.64.5': optional: true - '@rollup/rollup-freebsd-x64@4.64.1': + '@rollup/rollup-freebsd-x64@4.64.5': optional: true - '@rollup/rollup-linux-arm-gnueabihf@4.64.1': + '@rollup/rollup-linux-arm-gnueabihf@4.64.5': optional: true - '@rollup/rollup-linux-arm-musleabihf@4.64.1': + '@rollup/rollup-linux-arm-musleabihf@4.64.5': optional: true - '@rollup/rollup-linux-arm64-gnu@4.64.1': + '@rollup/rollup-linux-arm64-gnu@4.64.5': optional: true - '@rollup/rollup-linux-arm64-musl@4.64.1': + '@rollup/rollup-linux-arm64-musl@4.64.5': optional: true - '@rollup/rollup-linux-loong64-gnu@4.64.1': + '@rollup/rollup-linux-loong64-gnu@4.64.5': optional: true - '@rollup/rollup-linux-loong64-musl@4.64.1': + '@rollup/rollup-linux-loong64-musl@4.64.5': optional: true - '@rollup/rollup-linux-ppc64-gnu@4.64.1': + '@rollup/rollup-linux-ppc64-gnu@4.64.5': optional: true - '@rollup/rollup-linux-ppc64-musl@4.64.1': + '@rollup/rollup-linux-ppc64-musl@4.64.5': optional: true - '@rollup/rollup-linux-riscv64-gnu@4.64.1': + '@rollup/rollup-linux-riscv64-gnu@4.64.5': optional: true - '@rollup/rollup-linux-riscv64-musl@4.64.1': + '@rollup/rollup-linux-riscv64-musl@4.64.5': optional: true - '@rollup/rollup-linux-s390x-gnu@4.64.1': + '@rollup/rollup-linux-s390x-gnu@4.64.5': optional: true - '@rollup/rollup-linux-x64-gnu@4.64.1': + '@rollup/rollup-linux-x64-gnu@4.64.5': optional: true - '@rollup/rollup-linux-x64-musl@4.64.1': + '@rollup/rollup-linux-x64-musl@4.64.5': optional: true - '@rollup/rollup-openbsd-x64@4.64.1': + '@rollup/rollup-openbsd-x64@4.64.5': optional: true - '@rollup/rollup-openharmony-arm64@4.64.1': + '@rollup/rollup-openharmony-arm64@4.64.5': optional: true - '@rollup/rollup-win32-arm64-msvc@4.64.1': + '@rollup/rollup-win32-arm64-msvc@4.64.5': optional: true - '@rollup/rollup-win32-ia32-msvc@4.64.1': + '@rollup/rollup-win32-ia32-msvc@4.64.5': optional: true - '@rollup/rollup-win32-x64-gnu@4.64.1': + '@rollup/rollup-win32-x64-gnu@4.64.5': optional: true - '@rollup/rollup-win32-x64-msvc@4.64.1': + '@rollup/rollup-win32-x64-msvc@4.64.5': optional: true - '@rollup/wasm-node@4.64.1': + '@rollup/wasm-node@4.64.5': dependencies: '@types/estree': 1.0.9 optionalDependencies: @@ -11548,14 +11813,14 @@ snapshots: '@types/yarnpkg__lockfile@1.1.9': {} - '@typescript-eslint/eslint-plugin@8.71.1(@typescript-eslint/parser@8.71.1(eslint@10.12.0(jiti@2.7.0)(supports-color@11.0.0))(supports-color@11.0.0)(typescript@6.0.3))(eslint@10.12.0(jiti@2.7.0)(supports-color@11.0.0))(supports-color@11.0.0)(typescript@6.0.3)': + '@typescript-eslint/eslint-plugin@8.71.2(@typescript-eslint/parser@8.71.2(eslint@10.12.0(jiti@2.7.0)(supports-color@11.0.0))(supports-color@11.0.0)(typescript@6.0.3))(eslint@10.12.0(jiti@2.7.0)(supports-color@11.0.0))(supports-color@11.0.0)(typescript@6.0.3)': dependencies: '@eslint-community/regexpp': 4.12.2 - '@typescript-eslint/parser': 8.71.1(eslint@10.12.0(jiti@2.7.0)(supports-color@11.0.0))(supports-color@11.0.0)(typescript@6.0.3) - '@typescript-eslint/scope-manager': 8.71.1 - '@typescript-eslint/type-utils': 8.71.1(eslint@10.12.0(jiti@2.7.0)(supports-color@11.0.0))(supports-color@11.0.0)(typescript@6.0.3) - '@typescript-eslint/utils': 8.71.1(eslint@10.12.0(jiti@2.7.0)(supports-color@11.0.0))(supports-color@11.0.0)(typescript@6.0.3) - '@typescript-eslint/visitor-keys': 8.71.1 + '@typescript-eslint/parser': 8.71.2(eslint@10.12.0(jiti@2.7.0)(supports-color@11.0.0))(supports-color@11.0.0)(typescript@6.0.3) + '@typescript-eslint/scope-manager': 8.71.2 + '@typescript-eslint/type-utils': 8.71.2(eslint@10.12.0(jiti@2.7.0)(supports-color@11.0.0))(supports-color@11.0.0)(typescript@6.0.3) + '@typescript-eslint/utils': 8.71.2(eslint@10.12.0(jiti@2.7.0)(supports-color@11.0.0))(supports-color@11.0.0)(typescript@6.0.3) + '@typescript-eslint/visitor-keys': 8.71.2 eslint: 10.12.0(jiti@2.7.0)(supports-color@11.0.0) ignore: 7.0.12 natural-compare: 1.4.0 @@ -11564,41 +11829,41 @@ snapshots: transitivePeerDependencies: - supports-color - '@typescript-eslint/parser@8.71.1(eslint@10.12.0(jiti@2.7.0)(supports-color@11.0.0))(supports-color@11.0.0)(typescript@6.0.3)': + '@typescript-eslint/parser@8.71.2(eslint@10.12.0(jiti@2.7.0)(supports-color@11.0.0))(supports-color@11.0.0)(typescript@6.0.3)': dependencies: - '@typescript-eslint/scope-manager': 8.71.1 - '@typescript-eslint/types': 8.71.1 - '@typescript-eslint/typescript-estree': 8.71.1(supports-color@11.0.0)(typescript@6.0.3) - '@typescript-eslint/visitor-keys': 8.71.1 + '@typescript-eslint/scope-manager': 8.71.2 + '@typescript-eslint/types': 8.71.2 + '@typescript-eslint/typescript-estree': 8.71.2(supports-color@11.0.0)(typescript@6.0.3) + '@typescript-eslint/visitor-keys': 8.71.2 debug: 4.4.3(supports-color@11.0.0) eslint: 10.12.0(jiti@2.7.0)(supports-color@11.0.0) typescript: 6.0.3 transitivePeerDependencies: - supports-color - '@typescript-eslint/project-service@8.71.1(supports-color@11.0.0)(typescript@6.0.3)': + '@typescript-eslint/project-service@8.71.2(supports-color@11.0.0)(typescript@6.0.3)': dependencies: - '@typescript-eslint/tsconfig-utils': 8.71.1(typescript@6.0.3) - '@typescript-eslint/types': 8.71.1 + '@typescript-eslint/tsconfig-utils': 8.71.2(typescript@6.0.3) + '@typescript-eslint/types': 8.71.2 debug: 4.4.3(supports-color@11.0.0) typescript: 6.0.3 transitivePeerDependencies: - supports-color - '@typescript-eslint/scope-manager@8.71.1': + '@typescript-eslint/scope-manager@8.71.2': dependencies: - '@typescript-eslint/types': 8.71.1 - '@typescript-eslint/visitor-keys': 8.71.1 + '@typescript-eslint/types': 8.71.2 + '@typescript-eslint/visitor-keys': 8.71.2 - '@typescript-eslint/tsconfig-utils@8.71.1(typescript@6.0.3)': + '@typescript-eslint/tsconfig-utils@8.71.2(typescript@6.0.3)': dependencies: typescript: 6.0.3 - '@typescript-eslint/type-utils@8.71.1(eslint@10.12.0(jiti@2.7.0)(supports-color@11.0.0))(supports-color@11.0.0)(typescript@6.0.3)': + '@typescript-eslint/type-utils@8.71.2(eslint@10.12.0(jiti@2.7.0)(supports-color@11.0.0))(supports-color@11.0.0)(typescript@6.0.3)': dependencies: - '@typescript-eslint/types': 8.71.1 - '@typescript-eslint/typescript-estree': 8.71.1(supports-color@11.0.0)(typescript@6.0.3) - '@typescript-eslint/utils': 8.71.1(eslint@10.12.0(jiti@2.7.0)(supports-color@11.0.0))(supports-color@11.0.0)(typescript@6.0.3) + '@typescript-eslint/types': 8.71.2 + '@typescript-eslint/typescript-estree': 8.71.2(supports-color@11.0.0)(typescript@6.0.3) + '@typescript-eslint/utils': 8.71.2(eslint@10.12.0(jiti@2.7.0)(supports-color@11.0.0))(supports-color@11.0.0)(typescript@6.0.3) debug: 4.4.3(supports-color@11.0.0) eslint: 10.12.0(jiti@2.7.0)(supports-color@11.0.0) ts-api-utils: 2.5.0(typescript@6.0.3) @@ -11608,12 +11873,14 @@ snapshots: '@typescript-eslint/types@8.71.1': {} - '@typescript-eslint/typescript-estree@8.71.1(supports-color@11.0.0)(typescript@6.0.3)': + '@typescript-eslint/types@8.71.2': {} + + '@typescript-eslint/typescript-estree@8.71.2(supports-color@11.0.0)(typescript@6.0.3)': dependencies: - '@typescript-eslint/project-service': 8.71.1(supports-color@11.0.0)(typescript@6.0.3) - '@typescript-eslint/tsconfig-utils': 8.71.1(typescript@6.0.3) - '@typescript-eslint/types': 8.71.1 - '@typescript-eslint/visitor-keys': 8.71.1 + '@typescript-eslint/project-service': 8.71.2(supports-color@11.0.0)(typescript@6.0.3) + '@typescript-eslint/tsconfig-utils': 8.71.2(typescript@6.0.3) + '@typescript-eslint/types': 8.71.2 + '@typescript-eslint/visitor-keys': 8.71.2 debug: 4.4.3(supports-color@11.0.0) minimatch: 10.2.6 semver: 7.8.5 @@ -11623,20 +11890,20 @@ snapshots: transitivePeerDependencies: - supports-color - '@typescript-eslint/utils@8.71.1(eslint@10.12.0(jiti@2.7.0)(supports-color@11.0.0))(supports-color@11.0.0)(typescript@6.0.3)': + '@typescript-eslint/utils@8.71.2(eslint@10.12.0(jiti@2.7.0)(supports-color@11.0.0))(supports-color@11.0.0)(typescript@6.0.3)': dependencies: '@eslint-community/eslint-utils': 4.10.1(eslint@10.12.0(jiti@2.7.0)(supports-color@11.0.0)) - '@typescript-eslint/scope-manager': 8.71.1 - '@typescript-eslint/types': 8.71.1 - '@typescript-eslint/typescript-estree': 8.71.1(supports-color@11.0.0)(typescript@6.0.3) + '@typescript-eslint/scope-manager': 8.71.2 + '@typescript-eslint/types': 8.71.2 + '@typescript-eslint/typescript-estree': 8.71.2(supports-color@11.0.0)(typescript@6.0.3) eslint: 10.12.0(jiti@2.7.0)(supports-color@11.0.0) typescript: 6.0.3 transitivePeerDependencies: - supports-color - '@typescript-eslint/visitor-keys@8.71.1': + '@typescript-eslint/visitor-keys@8.71.2': dependencies: - '@typescript-eslint/types': 8.71.1 + '@typescript-eslint/types': 8.71.2 eslint-visitor-keys: 5.0.1 '@verdaccio/auth@8.1.5(supports-color@11.0.0)': @@ -11807,21 +12074,21 @@ snapshots: transitivePeerDependencies: - supports-color - '@vitejs/plugin-basic-ssl@2.3.0(vite@8.3.3(@types/node@22.20.5)(esbuild@0.28.2)(jiti@2.7.0)(less@4.9.1(supports-color@11.0.0))(sass-embedded@1.105.1)(sass@1.105.1)(terser@5.51.2)(tsx@4.23.15)(yaml@2.9.1))': + '@vitejs/plugin-basic-ssl@2.3.0(vite@8.3.4(@types/node@22.20.5)(esbuild@0.28.2)(jiti@2.7.0)(less@4.9.1(supports-color@11.0.0))(sass-embedded@1.105.1)(sass@1.105.1)(terser@5.51.2)(tsx@4.23.15)(yaml@2.9.1))': dependencies: - vite: 8.3.3(@types/node@22.20.5)(esbuild@0.28.2)(jiti@2.7.0)(less@4.9.1(supports-color@11.0.0))(sass-embedded@1.105.1)(sass@1.105.1)(terser@5.51.2)(tsx@4.23.15)(yaml@2.9.1) + vite: 8.3.4(@types/node@22.20.5)(esbuild@0.28.2)(jiti@2.7.0)(less@4.9.1(supports-color@11.0.0))(sass-embedded@1.105.1)(sass@1.105.1)(terser@5.51.2)(tsx@4.23.15)(yaml@2.9.1) - '@vitest/coverage-v8@5.0.3(vitest@5.0.3)': + '@vitest/coverage-v8@5.0.4(vitest@5.0.4)': dependencies: '@bcoe/v8-coverage': 1.0.2 '@vitest/istanbul-lib-coverage': 1.0.2 '@vitest/istanbul-lib-report': 1.0.2 ast-v8-to-istanbul: 1.0.7 magicast: 0.5.5 - obug: 2.2.1 + obug: 3.0.0 std-env: 4.3.0 tinyrainbow: 3.2.0 - vitest: 5.0.3(@opentelemetry/api@1.9.1)(@types/node@22.20.5)(@vitest/coverage-v8@5.0.3)(jsdom@30.1.2(@noble/hashes@1.8.0))(vite@8.3.3(@types/node@22.20.5)(esbuild@0.28.2)(jiti@2.7.0)(less@4.9.1(supports-color@11.0.0))(sass-embedded@1.105.1)(sass@1.105.1)(terser@5.51.2)(tsx@4.23.15)(yaml@2.9.1)) + vitest: 5.0.4(@opentelemetry/api@1.9.1)(@types/node@22.20.5)(@vitest/coverage-v8@5.0.4)(jsdom@30.1.2(@noble/hashes@1.8.0))(vite@8.3.4(@types/node@22.20.5)(esbuild@0.28.2)(jiti@2.7.0)(less@4.9.1(supports-color@11.0.0))(sass-embedded@1.105.1)(sass@1.105.1)(terser@5.51.2)(tsx@4.23.15)(yaml@2.9.1)) '@vitest/istanbul-lib-coverage@1.0.2': {} @@ -11829,16 +12096,16 @@ snapshots: dependencies: '@vitest/istanbul-lib-coverage': 1.0.2 - '@vitest/mocker@5.0.3(vite@8.3.3(@types/node@22.20.5)(esbuild@0.28.2)(jiti@2.7.0)(less@4.9.1(supports-color@11.0.0))(sass-embedded@1.105.1)(sass@1.105.1)(terser@5.51.2)(tsx@4.23.15)(yaml@2.9.1))': + '@vitest/mocker@5.0.4(vite@8.3.4(@types/node@22.20.5)(esbuild@0.28.2)(jiti@2.7.0)(less@4.9.1(supports-color@11.0.0))(sass-embedded@1.105.1)(sass@1.105.1)(terser@5.51.2)(tsx@4.23.15)(yaml@2.9.1))': dependencies: '@jridgewell/trace-mapping': 0.3.31 - '@vitest/spy': 5.0.3 + '@vitest/spy': 5.0.4 estree-walker: 3.0.3 magic-string: 1.4.3 optionalDependencies: - vite: 8.3.3(@types/node@22.20.5)(esbuild@0.28.2)(jiti@2.7.0)(less@4.9.1(supports-color@11.0.0))(sass-embedded@1.105.1)(sass@1.105.1)(terser@5.51.2)(tsx@4.23.15)(yaml@2.9.1) + vite: 8.3.4(@types/node@22.20.5)(esbuild@0.28.2)(jiti@2.7.0)(less@4.9.1(supports-color@11.0.0))(sass-embedded@1.105.1)(sass@1.105.1)(terser@5.51.2)(tsx@4.23.15)(yaml@2.9.1) - '@vitest/spy@5.0.3': {} + '@vitest/spy@5.0.4': {} '@webassemblyjs/ast@1.14.1': dependencies: @@ -11960,6 +12227,42 @@ snapshots: '@yuku-codegen/binding-win32-x64@0.10.2': optional: true + '@yuku-core/binding-android-arm64@0.19.0': + optional: true + + '@yuku-core/binding-darwin-arm64@0.19.0': + optional: true + + '@yuku-core/binding-darwin-x64@0.19.0': + optional: true + + '@yuku-core/binding-freebsd-x64@0.19.0': + optional: true + + '@yuku-core/binding-linux-arm-gnu@0.19.0': + optional: true + + '@yuku-core/binding-linux-arm-musl@0.19.0': + optional: true + + '@yuku-core/binding-linux-arm64-gnu@0.19.0': + optional: true + + '@yuku-core/binding-linux-arm64-musl@0.19.0': + optional: true + + '@yuku-core/binding-linux-x64-gnu@0.19.0': + optional: true + + '@yuku-core/binding-linux-x64-musl@0.19.0': + optional: true + + '@yuku-core/binding-win32-arm64@0.19.0': + optional: true + + '@yuku-core/binding-win32-x64@0.19.0': + optional: true + '@yuku-parser/binding-android-arm64@0.10.2': optional: true @@ -11998,6 +12301,8 @@ snapshots: '@yuku-toolchain/types@0.10.2': {} + '@yuku-toolchain/types@0.19.0': {} + JSONStream@1.3.5: dependencies: jsonparse: 1.3.1 @@ -12261,7 +12566,7 @@ snapshots: bcryptjs@2.4.3: {} - beasties@0.5.4: + beasties@0.5.5: dependencies: css-select: 7.0.0 css-what: 8.0.0 @@ -12517,11 +12822,11 @@ snapshots: chrome-trace-event@1.0.4: {} - chromium-bidi@17.0.2(devtools-protocol@0.0.1687809): + chromium-bidi@157.0.8090-0(devtools-protocol@0.0.1696802): dependencies: - devtools-protocol: 0.0.1687809 + devtools-protocol: 0.0.1696802 mitt: 3.0.1 - zod: 3.25.76 + zod: 4.6.5 chunk-data@0.1.0: {} @@ -12655,6 +12960,8 @@ snapshots: content-disposition@1.1.0: {} + content-disposition@2.0.1: {} + content-type@1.0.5: {} content-type@2.1.0: {} @@ -12849,7 +13156,7 @@ snapshots: dev-ip@1.0.1: {} - devtools-protocol@0.0.1687809: {} + devtools-protocol@0.0.1696802: {} di@0.0.1: {} @@ -13161,17 +13468,17 @@ snapshots: transitivePeerDependencies: - supports-color - eslint-module-utils@2.14.0(@typescript-eslint/parser@8.71.1(eslint@10.12.0(jiti@2.7.0)(supports-color@11.0.0))(supports-color@11.0.0)(typescript@6.0.3))(eslint-import-resolver-node@0.3.10(supports-color@11.0.0))(eslint@10.12.0(jiti@2.7.0)(supports-color@11.0.0))(supports-color@11.0.0): + eslint-module-utils@2.14.0(@typescript-eslint/parser@8.71.2(eslint@10.12.0(jiti@2.7.0)(supports-color@11.0.0))(supports-color@11.0.0)(typescript@6.0.3))(eslint-import-resolver-node@0.3.10(supports-color@11.0.0))(eslint@10.12.0(jiti@2.7.0)(supports-color@11.0.0))(supports-color@11.0.0): dependencies: debug: 3.2.7(supports-color@11.0.0) optionalDependencies: - '@typescript-eslint/parser': 8.71.1(eslint@10.12.0(jiti@2.7.0)(supports-color@11.0.0))(supports-color@11.0.0)(typescript@6.0.3) + '@typescript-eslint/parser': 8.71.2(eslint@10.12.0(jiti@2.7.0)(supports-color@11.0.0))(supports-color@11.0.0)(typescript@6.0.3) eslint: 10.12.0(jiti@2.7.0)(supports-color@11.0.0) eslint-import-resolver-node: 0.3.10(supports-color@11.0.0) transitivePeerDependencies: - supports-color - eslint-plugin-import@2.32.0(@typescript-eslint/parser@8.71.1(eslint@10.12.0(jiti@2.7.0)(supports-color@11.0.0))(supports-color@11.0.0)(typescript@6.0.3))(eslint@10.12.0(jiti@2.7.0)(supports-color@11.0.0))(supports-color@11.0.0): + eslint-plugin-import@2.32.0(@typescript-eslint/parser@8.71.2(eslint@10.12.0(jiti@2.7.0)(supports-color@11.0.0))(supports-color@11.0.0)(typescript@6.0.3))(eslint@10.12.0(jiti@2.7.0)(supports-color@11.0.0))(supports-color@11.0.0): dependencies: '@rtsao/scc': 1.1.0 array-includes: 3.2.0 @@ -13182,7 +13489,7 @@ snapshots: doctrine: 2.1.0 eslint: 10.12.0(jiti@2.7.0)(supports-color@11.0.0) eslint-import-resolver-node: 0.3.10(supports-color@11.0.0) - eslint-module-utils: 2.14.0(@typescript-eslint/parser@8.71.1(eslint@10.12.0(jiti@2.7.0)(supports-color@11.0.0))(supports-color@11.0.0)(typescript@6.0.3))(eslint-import-resolver-node@0.3.10(supports-color@11.0.0))(eslint@10.12.0(jiti@2.7.0)(supports-color@11.0.0))(supports-color@11.0.0) + eslint-module-utils: 2.14.0(@typescript-eslint/parser@8.71.2(eslint@10.12.0(jiti@2.7.0)(supports-color@11.0.0))(supports-color@11.0.0)(typescript@6.0.3))(eslint-import-resolver-node@0.3.10(supports-color@11.0.0))(eslint@10.12.0(jiti@2.7.0)(supports-color@11.0.0))(supports-color@11.0.0) hasown: 2.0.4 is-core-module: 2.17.0 is-glob: 4.0.3 @@ -13194,7 +13501,7 @@ snapshots: string.prototype.trimend: 1.0.10 tsconfig-paths: 3.15.0 optionalDependencies: - '@typescript-eslint/parser': 8.71.1(eslint@10.12.0(jiti@2.7.0)(supports-color@11.0.0))(supports-color@11.0.0)(typescript@6.0.3) + '@typescript-eslint/parser': 8.71.2(eslint@10.12.0(jiti@2.7.0)(supports-color@11.0.0))(supports-color@11.0.0)(typescript@6.0.3) transitivePeerDependencies: - eslint-import-resolver-typescript - eslint-import-resolver-webpack @@ -13369,6 +13676,39 @@ snapshots: transitivePeerDependencies: - supports-color + express@5.3.0(supports-color@11.0.0): + dependencies: + accepts: 2.0.0 + body-parser: 2.3.0(supports-color@11.0.0) + content-disposition: 2.0.1 + content-type: 2.1.0 + cookie: 0.7.2 + cookie-signature: 1.2.2 + debug: 4.4.3(supports-color@11.0.0) + depd: 2.0.0 + encodeurl: 2.0.0 + escape-html: 1.0.3 + etag: 1.8.1 + finalhandler: 2.1.1(supports-color@11.0.0) + fresh: 2.0.0 + http-errors: 2.0.1 + merge-descriptors: 2.0.0 + mime-types: 3.0.2 + on-finished: 2.4.1 + once: 1.4.0 + parseurl: 1.3.3 + proxy-addr: 2.0.8 + qs: 6.16.0 + range-parser: 1.3.0 + router: 2.2.0(supports-color@11.0.0) + send: 1.2.1(supports-color@11.0.0) + serve-static: 2.2.1(supports-color@11.0.0) + statuses: 2.0.2 + type-is: 2.1.0 + vary: 1.1.2 + transitivePeerDependencies: + - supports-color + extend@3.0.2: {} extsprintf@1.3.0: {} @@ -14573,7 +14913,7 @@ snapshots: lines-and-columns@1.2.4: {} - listr2@11.1.1: + listr2@11.2.0: dependencies: cli-truncate: 6.1.1 log-update: 8.0.0 @@ -15383,13 +15723,13 @@ snapshots: punycode@2.3.1: {} - puppeteer-core@25.12.0(bufferutil@4.1.0)(utf-8-validate@6.0.6): + puppeteer-core@25.13.0(bufferutil@4.1.0)(utf-8-validate@6.0.6): dependencies: - '@puppeteer/browsers': 3.2.3 - chromium-bidi: 17.0.2(devtools-protocol@0.0.1687809) - devtools-protocol: 0.0.1687809 + '@puppeteer/browsers': 3.2.4 + chromium-bidi: 157.0.8090-0(devtools-protocol@0.0.1696802) + devtools-protocol: 0.0.1696802 typed-query-selector: 2.12.3 - webdriver-bidi-protocol: 0.4.3 + webdriver-bidi-protocol: 1.0.1 ws: 8.22.0(bufferutil@4.1.0)(utf-8-validate@6.0.6) transitivePeerDependencies: - bufferutil @@ -15397,13 +15737,13 @@ snapshots: - utf-8-validate - yauzl - puppeteer@25.12.0(bufferutil@4.1.0)(utf-8-validate@6.0.6): + puppeteer@25.13.0(bufferutil@4.1.0)(utf-8-validate@6.0.6): dependencies: - '@puppeteer/browsers': 3.2.3 - chromium-bidi: 17.0.2(devtools-protocol@0.0.1687809) - devtools-protocol: 0.0.1687809 + '@puppeteer/browsers': 3.2.4 + chromium-bidi: 157.0.8090-0(devtools-protocol@0.0.1696802) + devtools-protocol: 0.0.1696802 lilconfig: 3.1.3 - puppeteer-core: 25.12.0(bufferutil@4.1.0)(utf-8-validate@6.0.6) + puppeteer-core: 25.13.0(bufferutil@4.1.0)(utf-8-validate@6.0.6) typed-query-selector: 2.12.3 transitivePeerDependencies: - bufferutil @@ -15644,6 +15984,20 @@ snapshots: transitivePeerDependencies: - oxc-resolver + rolldown-plugin-dts@0.28.8(rolldown@1.2.13)(typescript@6.0.3): + dependencies: + dts-resolver: 3.0.0 + get-tsconfig: 5.0.0-beta.6 + obug: 3.0.0 + rolldown: 1.2.13 + yuku-ast: 0.19.0 + yuku-codegen: 0.19.0 + yuku-parser: 0.19.0 + optionalDependencies: + typescript: 6.0.3 + transitivePeerDependencies: + - oxc-resolver + rolldown@1.2.12: dependencies: '@oxc-project/types': 0.152.0 @@ -15665,54 +16019,75 @@ snapshots: '@rolldown/binding-win32-arm64-msvc': 1.2.12 '@rolldown/binding-win32-x64-msvc': 1.2.12 - rollup-plugin-dts@6.5.1(rollup@4.64.1)(typescript@6.0.3): + rolldown@1.2.13: + dependencies: + '@oxc-project/types': 0.153.0 + '@rolldown/pluginutils': 1.0.1 + optionalDependencies: + '@rolldown/binding-android-arm-eabi': 1.2.13 + '@rolldown/binding-android-arm64': 1.2.13 + '@rolldown/binding-darwin-arm64': 1.2.13 + '@rolldown/binding-darwin-x64': 1.2.13 + '@rolldown/binding-freebsd-x64': 1.2.13 + '@rolldown/binding-linux-arm-gnueabihf': 1.2.13 + '@rolldown/binding-linux-arm64-gnu': 1.2.13 + '@rolldown/binding-linux-arm64-musl': 1.2.13 + '@rolldown/binding-linux-ppc64-gnu': 1.2.13 + '@rolldown/binding-linux-s390x-gnu': 1.2.13 + '@rolldown/binding-linux-x64-gnu': 1.2.13 + '@rolldown/binding-linux-x64-musl': 1.2.13 + '@rolldown/binding-openharmony-arm64': 1.2.13 + '@rolldown/binding-win32-arm64-msvc': 1.2.13 + '@rolldown/binding-win32-x64-msvc': 1.2.13 + + rollup-plugin-dts@6.5.1(rollup@4.64.5)(typescript@6.0.3): dependencies: '@jridgewell/remapping': 2.3.5 '@jridgewell/sourcemap-codec': 1.6.0 convert-source-map: 2.0.0 magic-string: 0.30.21 - rollup: 4.64.1 + rollup: 4.64.5 typescript: 6.0.3 optionalDependencies: '@babel/code-frame': 8.0.6 - rollup-plugin-sourcemaps2@0.5.9(@types/node@22.20.5)(rollup@4.64.1): + rollup-plugin-sourcemaps2@0.5.9(@types/node@22.20.5)(rollup@4.64.5): dependencies: - '@rollup/pluginutils': 5.4.0(rollup@4.64.1) - rollup: 4.64.1 + '@rollup/pluginutils': 5.4.0(rollup@4.64.5) + rollup: 4.64.5 optionalDependencies: '@types/node': 22.20.5 - rollup@4.64.1: + rollup@4.64.5: dependencies: '@types/estree': 1.0.9 optionalDependencies: '@napi-rs/lzma-linux-x64-gnu': 1.5.1 - '@rollup/rollup-android-arm-eabi': 4.64.1 - '@rollup/rollup-android-arm64': 4.64.1 - '@rollup/rollup-darwin-arm64': 4.64.1 - '@rollup/rollup-darwin-x64': 4.64.1 - '@rollup/rollup-freebsd-arm64': 4.64.1 - '@rollup/rollup-freebsd-x64': 4.64.1 - '@rollup/rollup-linux-arm-gnueabihf': 4.64.1 - '@rollup/rollup-linux-arm-musleabihf': 4.64.1 - '@rollup/rollup-linux-arm64-gnu': 4.64.1 - '@rollup/rollup-linux-arm64-musl': 4.64.1 - '@rollup/rollup-linux-loong64-gnu': 4.64.1 - '@rollup/rollup-linux-loong64-musl': 4.64.1 - '@rollup/rollup-linux-ppc64-gnu': 4.64.1 - '@rollup/rollup-linux-ppc64-musl': 4.64.1 - '@rollup/rollup-linux-riscv64-gnu': 4.64.1 - '@rollup/rollup-linux-riscv64-musl': 4.64.1 - '@rollup/rollup-linux-s390x-gnu': 4.64.1 - '@rollup/rollup-linux-x64-gnu': 4.64.1 - '@rollup/rollup-linux-x64-musl': 4.64.1 - '@rollup/rollup-openbsd-x64': 4.64.1 - '@rollup/rollup-openharmony-arm64': 4.64.1 - '@rollup/rollup-win32-arm64-msvc': 4.64.1 - '@rollup/rollup-win32-ia32-msvc': 4.64.1 - '@rollup/rollup-win32-x64-gnu': 4.64.1 - '@rollup/rollup-win32-x64-msvc': 4.64.1 + '@rollup/rollup-android-arm-eabi': 4.64.5 + '@rollup/rollup-android-arm64': 4.64.5 + '@rollup/rollup-darwin-arm64': 4.64.5 + '@rollup/rollup-darwin-x64': 4.64.5 + '@rollup/rollup-freebsd-arm64': 4.64.5 + '@rollup/rollup-freebsd-x64': 4.64.5 + '@rollup/rollup-linux-arm-gnueabihf': 4.64.5 + '@rollup/rollup-linux-arm-musleabihf': 4.64.5 + '@rollup/rollup-linux-arm64-gnu': 4.64.5 + '@rollup/rollup-linux-arm64-musl': 4.64.5 + '@rollup/rollup-linux-loong64-gnu': 4.64.5 + '@rollup/rollup-linux-loong64-musl': 4.64.5 + '@rollup/rollup-linux-ppc64-gnu': 4.64.5 + '@rollup/rollup-linux-ppc64-musl': 4.64.5 + '@rollup/rollup-linux-riscv64-gnu': 4.64.5 + '@rollup/rollup-linux-riscv64-musl': 4.64.5 + '@rollup/rollup-linux-s390x-gnu': 4.64.5 + '@rollup/rollup-linux-x64-gnu': 4.64.5 + '@rollup/rollup-linux-x64-musl': 4.64.5 + '@rollup/rollup-openbsd-x64': 4.64.5 + '@rollup/rollup-openharmony-arm64': 4.64.5 + '@rollup/rollup-win32-arm64-msvc': 4.64.5 + '@rollup/rollup-win32-ia32-msvc': 4.64.5 + '@rollup/rollup-win32-x64-gnu': 4.64.5 + '@rollup/rollup-win32-x64-msvc': 4.64.5 fsevents: 2.3.3 router@2.2.0(supports-color@11.0.0): @@ -16657,7 +17032,7 @@ snapshots: core-util-is: 1.0.2 extsprintf: 1.3.0 - vite@8.3.3(@types/node@22.20.5)(esbuild@0.28.2)(jiti@2.7.0)(less@4.9.1(supports-color@11.0.0))(sass-embedded@1.105.1)(sass@1.105.1)(terser@5.51.2)(tsx@4.23.15)(yaml@2.9.1): + vite@8.3.4(@types/node@22.20.5)(esbuild@0.28.2)(jiti@2.7.0)(less@4.9.1(supports-color@11.0.0))(sass-embedded@1.105.1)(sass@1.105.1)(terser@5.51.2)(tsx@4.23.15)(yaml@2.9.1): dependencies: lightningcss: 1.33.0 picomatch: 4.0.7 @@ -16676,26 +17051,26 @@ snapshots: tsx: 4.23.15 yaml: 2.9.1 - vitest@5.0.3(@opentelemetry/api@1.9.1)(@types/node@22.20.5)(@vitest/coverage-v8@5.0.3)(jsdom@30.1.2(@noble/hashes@1.8.0))(vite@8.3.3(@types/node@22.20.5)(esbuild@0.28.2)(jiti@2.7.0)(less@4.9.1(supports-color@11.0.0))(sass-embedded@1.105.1)(sass@1.105.1)(terser@5.51.2)(tsx@4.23.15)(yaml@2.9.1)): + vitest@5.0.4(@opentelemetry/api@1.9.1)(@types/node@22.20.5)(@vitest/coverage-v8@5.0.4)(jsdom@30.1.2(@noble/hashes@1.8.0))(vite@8.3.4(@types/node@22.20.5)(esbuild@0.28.2)(jiti@2.7.0)(less@4.9.1(supports-color@11.0.0))(sass-embedded@1.105.1)(sass@1.105.1)(terser@5.51.2)(tsx@4.23.15)(yaml@2.9.1)): dependencies: '@types/chai': 5.2.3 - '@vitest/mocker': 5.0.3(vite@8.3.3(@types/node@22.20.5)(esbuild@0.28.2)(jiti@2.7.0)(less@4.9.1(supports-color@11.0.0))(sass-embedded@1.105.1)(sass@1.105.1)(terser@5.51.2)(tsx@4.23.15)(yaml@2.9.1)) + '@vitest/mocker': 5.0.4(vite@8.3.4(@types/node@22.20.5)(esbuild@0.28.2)(jiti@2.7.0)(less@4.9.1(supports-color@11.0.0))(sass-embedded@1.105.1)(sass@1.105.1)(terser@5.51.2)(tsx@4.23.15)(yaml@2.9.1)) chai: 6.3.0 es-module-lexer: 2.3.2 expect-type: 1.4.0 magic-string: 1.4.3 - obug: 2.2.1 + obug: 3.0.0 picomatch: 4.0.7 std-env: 4.3.0 tinybench: 6.2.2 tinyexec: 1.3.1 tinyglobby: 0.2.17 - vite: 8.3.3(@types/node@22.20.5)(esbuild@0.28.2)(jiti@2.7.0)(less@4.9.1(supports-color@11.0.0))(sass-embedded@1.105.1)(sass@1.105.1)(terser@5.51.2)(tsx@4.23.15)(yaml@2.9.1) + vite: 8.3.4(@types/node@22.20.5)(esbuild@0.28.2)(jiti@2.7.0)(less@4.9.1(supports-color@11.0.0))(sass-embedded@1.105.1)(sass@1.105.1)(terser@5.51.2)(tsx@4.23.15)(yaml@2.9.1) why-is-node-running: 3.2.1 optionalDependencies: '@opentelemetry/api': 1.9.1 '@types/node': 22.20.5 - '@vitest/coverage-v8': 5.0.3(vitest@5.0.3) + '@vitest/coverage-v8': 5.0.4(vitest@5.0.4) jsdom: 30.1.2(@noble/hashes@1.8.0) transitivePeerDependencies: - msw @@ -16717,7 +17092,7 @@ snapshots: web-vitals@4.2.4: {} - webdriver-bidi-protocol@0.4.3: {} + webdriver-bidi-protocol@1.0.1: {} webidl-conversions@3.0.1: {} @@ -17002,6 +17377,10 @@ snapshots: dependencies: '@yuku-toolchain/types': 0.10.2 + yuku-ast@0.19.0: + dependencies: + '@yuku-toolchain/types': 0.19.0 + yuku-codegen@0.10.2: dependencies: '@yuku-toolchain/types': 0.10.2 @@ -17019,6 +17398,27 @@ snapshots: '@yuku-codegen/binding-win32-arm64': 0.10.2 '@yuku-codegen/binding-win32-x64': 0.10.2 + yuku-codegen@0.19.0: + dependencies: + '@yuku-toolchain/types': 0.19.0 + + yuku-core@0.19.0: + dependencies: + '@yuku-toolchain/types': 0.19.0 + optionalDependencies: + '@yuku-core/binding-android-arm64': 0.19.0 + '@yuku-core/binding-darwin-arm64': 0.19.0 + '@yuku-core/binding-darwin-x64': 0.19.0 + '@yuku-core/binding-freebsd-x64': 0.19.0 + '@yuku-core/binding-linux-arm-gnu': 0.19.0 + '@yuku-core/binding-linux-arm-musl': 0.19.0 + '@yuku-core/binding-linux-arm64-gnu': 0.19.0 + '@yuku-core/binding-linux-arm64-musl': 0.19.0 + '@yuku-core/binding-linux-x64-gnu': 0.19.0 + '@yuku-core/binding-linux-x64-musl': 0.19.0 + '@yuku-core/binding-win32-arm64': 0.19.0 + '@yuku-core/binding-win32-x64': 0.19.0 + yuku-parser@0.10.2: dependencies: '@yuku-toolchain/types': 0.10.2 @@ -17037,8 +17437,13 @@ snapshots: '@yuku-parser/binding-win32-arm64': 0.10.2 '@yuku-parser/binding-win32-x64': 0.10.2 - zod@3.25.76: {} + yuku-parser@0.19.0: + dependencies: + '@yuku-toolchain/types': 0.19.0 + yuku-core: 0.19.0 zod@4.6.5: {} + zod@4.6.7: {} + zone.js@0.16.3: {} From 1e97effe7bbc73553b1bf35a92e0df7169598ca3 Mon Sep 17 00:00:00 2001 From: Alan Agius <17563226+alan-agius4@users.noreply.github.com> Date: Tue, 13 Oct 2026 14:31:42 +0000 Subject: [PATCH 610/787] refactor(@angular/build): collect and log build errors in library builder Instead of throwing errors inside `buildAction` and `compileLibrary` during progress spinner execution, collect formatted diagnostic errors, warnings, and informational logs into `BuildActionResult` and log them via `context.logger` after `withProgress` completes, matching the behavior of the `application` builder. --- .../build/src/builders/library/builder.ts | 52 +++- .../builders/library/pipeline/build-action.ts | 294 ++++++++++-------- .../builders/library/pipeline/compilation.ts | 54 ++-- .../builders/library/pipeline/entry-points.ts | 65 ++++ .../library/tests/behavior/build_spec.ts | 6 + .../allowed-non-peer-dependencies_spec.ts | 10 +- 6 files changed, 317 insertions(+), 164 deletions(-) diff --git a/packages/angular/build/src/builders/library/builder.ts b/packages/angular/build/src/builders/library/builder.ts index 948f53ae568b..84b933e7ceb6 100644 --- a/packages/angular/build/src/builders/library/builder.ts +++ b/packages/angular/build/src/builders/library/builder.ts @@ -24,6 +24,7 @@ import { getSupportedBrowsers } from '../../utils/supported-browsers'; import { assertCompatibleAngularVersion } from '../../utils/version'; import type { BuildWatcher } from '../../utils/watcher'; import { normalizeLibraryOptions } from './options'; +import type { BuildActionResult } from './pipeline/build-action'; import { updateWatchedEntryPoints } from './pipeline/entry-points'; import type { createComponentStylesheetBundlerForLibrary } from './pipeline/stylesheet-bundler'; import { loadPackageJson } from './pipeline/utils'; @@ -185,6 +186,17 @@ export async function* executeLibraryBuilder( } } +/** + * Executes a single build iteration with progress reporting, logs any resulting + * messages, and registers newly discovered files with the watcher. + * + * @param message Progress spinner message to display while building. + * @param actionContext The build action context and state. + * @param withProgress Progress wrapper function (`withSpinner` or `withNoProgress`). + * @param watcher Optional file watcher for watch mode. + * @param buildAction The library build action function to execute. + * @returns A promise resolving to the Architect `BuilderOutput`. + */ async function executeBuild( message: string, actionContext: import('./pipeline/build-action').BuildActionContext, @@ -196,13 +208,16 @@ async function executeBuild( const { context, watchedCompilationFiles, isWatchMode, options } = actionContext; try { - await withProgress(message, () => buildAction(actionContext)); - logBuildResult(context.logger, startTime, true, options.outputPath); - if (isWatchMode) { + const result = await withProgress(message, () => buildAction(actionContext)); + logMessages(context.logger, result); + + const success = result.errors.length === 0; + logBuildResult(context.logger, startTime, success, options.outputPath); + if (success && isWatchMode) { logCumulativeDurations(); } - return { success: true }; + return { success }; } catch (error) { assertIsError(error); logBuildResult(context.logger, startTime, false); @@ -300,6 +315,7 @@ async function* runWatchLoop( assertIsError(error); await buildState.singleProgramCache?.compilationInstance.update?.(changedFiles); buildState.hasEmittedManifests = false; + yield { success: false, error: `Failed to reload 'package.json': ${error.message}`, @@ -343,8 +359,36 @@ async function* runWatchLoop( } } +/** + * Logs informational, warning, and error messages produced during a build iteration. + * + * @param logger The Architect logger API. + * @param result The build action result containing logs, warnings, and errors. + */ +function logMessages( + logger: logging.LoggerApi, + { logs, warnings, errors }: BuildActionResult, +): void { + if (logs.length) { + logger.info(logs.join('\n')); + } + + if (warnings.length) { + logger.warn(warnings.join('\n')); + } + + if (errors.length) { + logger.error(errors.join('\n')); + } +} + /** * Logs the build completion time and status. + * + * @param logger The Architect logger API. + * @param startTime High-resolution timestamp recorded when the build iteration started. + * @param success Whether the build iteration succeeded without errors. + * @param outputPath Optional output directory path to log on successful builds. */ function logBuildResult( logger: logging.LoggerApi, diff --git a/packages/angular/build/src/builders/library/pipeline/build-action.ts b/packages/angular/build/src/builders/library/pipeline/build-action.ts index a430312ac925..6d40f5fe4383 100644 --- a/packages/angular/build/src/builders/library/pipeline/build-action.ts +++ b/packages/angular/build/src/builders/library/pipeline/build-action.ts @@ -10,14 +10,30 @@ import type { BuilderContext } from '@angular-devkit/architect'; import path from 'node:path'; import type { ComponentStylesheetBundler } from '../../../tools/esbuild/angular/component-stylesheets'; import { emitFilesToDisk } from '../../../utils/emit-files-to-disk'; +import { assertIsError } from '../../../utils/error'; import { toPosixPath } from '../../../utils/path'; import type { NormalizedLibraryOptions, SingleBuildState } from '../types'; import { collectAssetsToEmit } from './assets'; -import { type BundleEntryPointInput, bundleEntryPoints } from './bundler'; -import { compileLibrary } from './compilation'; +import { bundleEntryPoints } from './bundler'; +import { type LibraryCompilationDiagnostics, compileLibrary } from './compilation'; +import { collectEntryPointsToBundle } from './entry-points'; import { generatePackageManifests } from './package-manifests'; import type { DiskOutputFile, OutputFile } from './utils'; +/** + * Result of executing a single library build iteration. + */ +export interface BuildActionResult { + /** Formatted error messages produced during the build. */ + errors: string[]; + + /** Formatted warning messages produced during the build. */ + warnings: string[]; + + /** Informational log messages produced during the build. */ + logs: string[]; +} + /** * Creates a fresh {@link SingleBuildState} instance. */ @@ -76,10 +92,9 @@ export interface BuildActionContext { * * @param actionContext The build action state and configuration. */ -export async function buildAction(actionContext: BuildActionContext): Promise { +export async function buildAction(actionContext: BuildActionContext): Promise { const { options, - context, stylesheetBundler, isWatchMode, watchedCompilationFiles, @@ -87,6 +102,10 @@ export async function buildAction(actionContext: BuildActionContext): Promise 0 || pendingChangedDtsFiles.size > 0 || hasModifiedWatchedFile(modifiedFiles, watchedCompilationFiles, posixPackageJsonPath); - const shouldGenerateManifests = !buildState.hasEmittedManifests; - if (shouldGenerateManifests) { - verifyAllowedDependencies(options); - } + try { + if (!buildState.hasEmittedManifests) { + const dependencyErrors = verifyAllowedDependencies(options); + if (dependencyErrors.length > 0) { + errors.push(...dependencyErrors); - const filesToEmit: OutputFile[] = []; - - if (shouldCompileEntryPoints) { - buildState.hasCompilationError = true; - buildState.hasEntryPointsChanges = false; - - const { - esmFiles, - dtsFiles, - changedEsmFiles, - changedDtsFiles, - referencedFiles, - cache, - diagnosePromise, - declarationMap, - compilationMode, - } = await compileLibrary( - options.entryPoints.values(), - options, - stylesheetBundler, - buildState.singleProgramCache, - modifiedFiles, - ); - buildState.singleProgramCache = cache; - if (buildState.compilationMode !== compilationMode) { - buildState.compilationMode = compilationMode; - buildState.hasEmittedManifests = false; + return { errors, warnings, logs }; + } } - for (const file of referencedFiles) { - watchedCompilationFiles.add(file); - } + const filesToEmit: OutputFile[] = []; - for (const file of changedEsmFiles) { - pendingChangedEsmFiles.add(file); - } - for (const file of changedDtsFiles) { - pendingChangedDtsFiles.add(file); - } + if (shouldCompileEntryPoints) { + buildState.hasCompilationError = true; + buildState.hasEntryPointsChanges = false; - const itemsToBundle: BundleEntryPointInput[] = []; + const { + esmFiles, + dtsFiles, + changedEsmFiles, + changedDtsFiles, + referencedFiles, + cache, + hasStylesheetErrors, + diagnosePromise, + declarationMap, + compilationMode, + } = await compileLibrary( + options.entryPoints.values(), + options, + stylesheetBundler, + buildState.singleProgramCache, + modifiedFiles, + ); + buildState.singleProgramCache = cache; + if (buildState.compilationMode !== compilationMode) { + buildState.compilationMode = compilationMode; + buildState.hasEmittedManifests = false; + } - for (const entryPoint of options.entryPoints.values()) { - const previousBundleResult = buildState.previousBundleResults.get(entryPoint.name); - const hasEsmChanges = - !previousBundleResult || - hasEntryPointChanges(previousBundleResult.esmModuleIds, pendingChangedEsmFiles); - const hasDtsChanges = - !previousBundleResult || - hasEntryPointChanges(previousBundleResult.dtsModuleIds, pendingChangedDtsFiles); - - if (hasEsmChanges || hasDtsChanges) { - context.logger.info(`Compiling ${entryPoint.displayName}...`); - itemsToBundle.push({ - entryPoint, - hasEsmChanges, - hasDtsChanges, - previousBundleResult, - }); + for (const file of referencedFiles) { + watchedCompilationFiles.add(file); + } + for (const file of changedEsmFiles) { + pendingChangedEsmFiles.add(file); + } + for (const file of changedDtsFiles) { + pendingChangedDtsFiles.add(file); } - } - let bundleOutput: Awaited>; - let warnings: string[]; - try { - [bundleOutput, warnings] = await Promise.all([ - bundleEntryPoints(itemsToBundle, esmFiles, dtsFiles, { - ...options, - declarationMap, - compilationMode, - }), - diagnosePromise, - ]); - } catch (error) { - // Prioritize TypeScript/Angular diagnostic errors over secondary bundler failures. - await diagnosePromise; - throw error; - } + const itemsToBundle = collectEntryPointsToBundle(options, buildState, logs); + + let bundleOutput: Awaited> | undefined; + let diagnostics: LibraryCompilationDiagnostics; + if (hasStylesheetErrors) { + diagnostics = await diagnosePromise; + } else { + try { + [bundleOutput, diagnostics] = await Promise.all([ + bundleEntryPoints(itemsToBundle, esmFiles, dtsFiles, { + ...options, + declarationMap, + compilationMode, + }), + diagnosePromise, + ]); + } catch (error) { + assertIsError(error); + // Prioritize TypeScript/Angular diagnostic errors over secondary bundler failures. + diagnostics = await diagnosePromise; + if (diagnostics.errors.length === 0) { + errors.push(error.message); + } + } + } + + warnings.push(...diagnostics.warnings, ...(bundleOutput?.warnings ?? [])); + if (diagnostics.errors.length > 0 || errors.length > 0 || !bundleOutput) { + errors.push(...diagnostics.errors); + + return { errors, warnings, logs }; + } - buildState.hasCompilationError = false; - pendingChangedEsmFiles.clear(); - pendingChangedDtsFiles.clear(); + buildState.hasCompilationError = false; + pendingChangedEsmFiles.clear(); + pendingChangedDtsFiles.clear(); - for (const warning of [...warnings, ...bundleOutput.warnings]) { - context.logger.warn(warning); + filesToEmit.push(...bundleOutput.filesToEmit); + for (const [name, bundleResult] of bundleOutput.bundleResults) { + buildState.previousBundleResults.set(name, bundleResult); + } } - filesToEmit.push(...bundleOutput.filesToEmit); - for (const [name, bundleResult] of bundleOutput.bundleResults) { - buildState.previousBundleResults.set(name, bundleResult); + let hasTslibImport = false; + for (const entryPoint of options.entryPoints.values()) { + if (buildState.previousBundleResults.get(entryPoint.name)?.hasTslibImport) { + hasTslibImport = true; + break; + } } - } - let hasTslibImport = false; - for (const entryPoint of options.entryPoints.values()) { - if (buildState.previousBundleResults.get(entryPoint.name)?.hasTslibImport) { - hasTslibImport = true; - break; + if (!buildState.hasEmittedManifests || buildState.hasEmittedTslib !== hasTslibImport) { + filesToEmit.push( + ...(await generatePackageManifests( + { + ...options, + compilationMode: buildState.compilationMode ?? options.compilationMode ?? 'partial', + }, + isWatchMode, + hasTslibImport, + )), + ); } - } - if (!buildState.hasEmittedManifests || buildState.hasEmittedTslib !== hasTslibImport) { - filesToEmit.push( - ...(await generatePackageManifests( - { - ...options, - compilationMode: buildState.compilationMode ?? options.compilationMode ?? 'partial', - }, - isWatchMode, - hasTslibImport, - )), - ); + const resolvedAssetsToEmit = (actionContext.assetsToEmit ??= await collectAssetsToEmit( + options.assets, + options.workspaceRoot, + buildState.hasEmittedAssets ? modifiedFiles : undefined, + )); + filesToEmit.push(...resolvedAssetsToEmit); + + await emitFilesToDisk(filesToEmit, (file) => path.join(options.outputPath, file.path)); + + buildState.hasEmittedManifests = true; + buildState.hasEmittedTslib = hasTslibImport; + buildState.hasEmittedAssets = true; + } catch (error) { + assertIsError(error); + errors.push(error.message); } - const resolvedAssetsToEmit = (actionContext.assetsToEmit ??= await collectAssetsToEmit( - options.assets, - options.workspaceRoot, - buildState.hasEmittedAssets ? modifiedFiles : undefined, - )); - filesToEmit.push(...resolvedAssetsToEmit); - - await emitFilesToDisk(filesToEmit, (file) => path.join(options.outputPath, file.path)); - - buildState.hasEmittedManifests = true; - buildState.hasEmittedTslib = hasTslibImport; - buildState.hasEmittedAssets = true; + return { errors, warnings, logs }; } +/** + * Checks whether any modified file (excluding `package.json`) is part of the + * tracked compilation file set. + * + * @param modifiedFiles Set of POSIX file paths modified since the last build. + * @param watchedCompilationFiles Set of POSIX file paths tracked for compilation. + * @param posixPackageJsonPath The normalized POSIX path to the library's `package.json`. + * @returns `true` if a watched compilation file was modified; otherwise `false`. + */ export function hasModifiedWatchedFile( modifiedFiles: ReadonlySet, watchedCompilationFiles: ReadonlySet, @@ -250,36 +279,29 @@ export function hasModifiedWatchedFile( return false; } -function hasEntryPointChanges( - moduleIds: ReadonlySet, - changedFiles: ReadonlySet, -): boolean { - if (changedFiles.size === 0) { - return false; - } - - for (const file of changedFiles) { - if (moduleIds.has(file)) { - return true; - } - } - - return false; -} - -function verifyAllowedDependencies(options: NormalizedLibraryOptions): void { +/** + * Validates that all direct and optional dependencies in `package.json` are + * permitted by `allowedNonPeerDependencies`. + * + * @param options The normalized library builder options. + * @returns An array of error messages for any disallowed dependencies. + */ +function verifyAllowedDependencies(options: NormalizedLibraryOptions): string[] { const { packageJson, allowedNonPeerDependencies } = options; const dependencies = { ...(packageJson.dependencies ?? {}), ...(packageJson.optionalDependencies ?? {}), }; + const errors: string[] = []; for (const dep of Object.keys(dependencies)) { if (!allowedNonPeerDependencies.some((regex) => regex.test(dep))) { - throw new Error( + errors.push( `Dependency '${dep}' must be explicitly allowed using the 'allowedNonPeerDependencies' option, ` + `or moved to 'peerDependencies' in 'package.json'.`, ); } } + + return errors; } diff --git a/packages/angular/build/src/builders/library/pipeline/compilation.ts b/packages/angular/build/src/builders/library/pipeline/compilation.ts index 51a8fb0d231e..afc5c319854e 100644 --- a/packages/angular/build/src/builders/library/pipeline/compilation.ts +++ b/packages/angular/build/src/builders/library/pipeline/compilation.ts @@ -20,6 +20,17 @@ import { isDeclarationFile, isDeclarationSourceMapFile } from './utils'; const EMITTED_EXTENSIONS = ['.js', '.mjs', '.cjs', '.d.ts', '.d.mts', '.d.cts']; +/** + * Formatted diagnostic messages produced during library compilation. + */ +export interface LibraryCompilationDiagnostics { + /** Formatted compilation error messages. */ + readonly errors: string[]; + + /** Formatted compilation warning messages. */ + readonly warnings: string[]; +} + /** * Output of the unified library compilation step. */ @@ -42,8 +53,11 @@ export interface LibraryCompilationOutput { /** Cached compilation state for subsequent incremental builds. */ readonly cache: SingleProgramCache; - /** Promise that resolves to formatted compilation warnings or rejects on diagnostic errors. */ - readonly diagnosePromise: Promise; + /** Whether any component stylesheet bundling errors occurred. */ + readonly hasStylesheetErrors: boolean; + + /** Promise that resolves to formatted compilation diagnostic errors and warnings. */ + readonly diagnosePromise: Promise; /** Effective declarationMap setting resolved from builder options and tsconfig. */ readonly declarationMap: boolean; @@ -145,8 +159,8 @@ export async function compileLibrary( 'library', ); - const emittedFiles = - stylesheetErrors.length === 0 ? await compilationInstance.emitAffectedFiles() : []; + const hasStylesheetErrors = stylesheetErrors.length > 0; + const emittedFiles = hasStylesheetErrors ? [] : await compilationInstance.emitAffectedFiles(); const diagnosePromise = runDiagnosticsAndFormat( compilationInstance, stylesheetErrors, @@ -154,9 +168,6 @@ export async function compileLibrary( colors, ); - // Prevent unhandled promise rejection if an error occurs before diagnosePromise is awaited. - diagnosePromise.catch(() => {}); - const esmFiles = cached?.esmFiles ?? new Map(); const dtsFiles = cached?.dtsFiles ?? new Map(); const changedEsmFiles = new Set(); @@ -225,6 +236,7 @@ export async function compileLibrary( dtsFiles, failedFiles: failedFiles.size > 0 ? failedFiles : undefined, }, + hasStylesheetErrors, diagnosePromise, declarationMap: !!compilerOptions.declarationMap, compilationMode: compilerOptions.compilationMode === 'full' ? 'full' : 'partial', @@ -238,34 +250,31 @@ export async function compileLibrary( } /** - * Validates stylesheet bundling results and runs TypeScript/Angular diagnostics. + * Formats stylesheet bundling diagnostics and TypeScript/Angular diagnostics. * * @param compilationInstance The active Angular compilation instance. * @param stylesheetErrors List of stylesheet bundling errors. * @param stylesheetWarnings List of stylesheet bundling warnings. * @param colors Whether diagnostic messages should be formatted with ANSI colors. - * @returns A promise resolving to formatted warning messages. - * @throws If stylesheet bundling errors or compilation errors occur. + * @returns A promise resolving to the formatted diagnostic errors and warnings. */ async function runDiagnosticsAndFormat( compilationInstance: AngularCompilation, stylesheetErrors: PartialMessage[], stylesheetWarnings: PartialMessage[], colors: boolean, -): Promise { - if (stylesheetErrors.length > 0) { - const formatted = await formatMessages(stylesheetErrors, { kind: 'error', color: colors }); - - throw new Error(`Failed to bundle stylesheet:\n${formatted.join('\n')}`); - } - +): Promise { + const errorsOut: string[] = []; const warningsOut: string[] = []; - if (useTypeChecking) { + if (stylesheetErrors.length > 0) { + const formatted = await formatMessages(stylesheetErrors, { kind: 'error', color: colors }); + errorsOut.push(...formatted); + } else if (useTypeChecking) { const { errors, warnings } = await compilationInstance.diagnoseFiles(); if (errors?.length) { - const errorMessages = await formatMessages(errors, { kind: 'error', color: colors }); - throw new Error(`Compilation failed with errors:\n${errorMessages.join('\n')}`); + const formatted = await formatMessages(errors, { kind: 'error', color: colors }); + errorsOut.push(...formatted); } if (warnings?.length) { @@ -282,5 +291,8 @@ async function runDiagnosticsAndFormat( warningsOut.push(...formattedStyleWarnings); } - return warningsOut; + return { + errors: errorsOut, + warnings: warningsOut, + }; } diff --git a/packages/angular/build/src/builders/library/pipeline/entry-points.ts b/packages/angular/build/src/builders/library/pipeline/entry-points.ts index 93a96307d9e4..7797f069fade 100644 --- a/packages/angular/build/src/builders/library/pipeline/entry-points.ts +++ b/packages/angular/build/src/builders/library/pipeline/entry-points.ts @@ -14,6 +14,7 @@ import type { PackageJsonData, SingleBuildState, } from '../types'; +import type { BundleEntryPointInput } from './bundler'; /** * Computes the base bundle file name for an entry point. @@ -270,3 +271,67 @@ export function updateWatchedEntryPoints( buildState.hasEntryPointsChanges = true; } } + +/** + * Determines which entry points have modified JavaScript or declaration files + * and collects them for bundling. + * + * @param options The normalized library builder options. + * @param buildState The state preserved across incremental builds. + * @param logs Array of informational log messages to append to when an entry point is queued. + * @returns The list of entry points that require bundling in the current build iteration. + */ +export function collectEntryPointsToBundle( + options: NormalizedLibraryOptions, + buildState: SingleBuildState, + logs: string[], +): BundleEntryPointInput[] { + const { pendingChangedEsmFiles, pendingChangedDtsFiles, previousBundleResults } = buildState; + const itemsToBundle: BundleEntryPointInput[] = []; + + for (const entryPoint of options.entryPoints.values()) { + const previousBundleResult = previousBundleResults.get(entryPoint.name); + const hasEsmChanges = + !previousBundleResult || + hasEntryPointChanges(previousBundleResult.esmModuleIds, pendingChangedEsmFiles); + const hasDtsChanges = + !previousBundleResult || + hasEntryPointChanges(previousBundleResult.dtsModuleIds, pendingChangedDtsFiles); + + if (hasEsmChanges || hasDtsChanges) { + logs.push(`Compiling ${entryPoint.displayName}...`); + itemsToBundle.push({ + entryPoint, + hasEsmChanges, + hasDtsChanges, + previousBundleResult, + }); + } + } + + return itemsToBundle; +} + +/** + * Checks whether any file in `changedFiles` belongs to the given entry point's `moduleIds`. + * + * @param moduleIds Set of module IDs referenced by the entry point's previous bundle. + * @param changedFiles Set of file paths that changed during compilation. + * @returns `true` if at least one changed file is part of `moduleIds`; otherwise `false`. + */ +function hasEntryPointChanges( + moduleIds: ReadonlySet, + changedFiles: ReadonlySet, +): boolean { + if (changedFiles.size === 0) { + return false; + } + + for (const file of changedFiles) { + if (moduleIds.has(file)) { + return true; + } + } + + return false; +} diff --git a/packages/angular/build/src/builders/library/tests/behavior/build_spec.ts b/packages/angular/build/src/builders/library/tests/behavior/build_spec.ts index e55a414c1ada..4f5c6736c1ff 100644 --- a/packages/angular/build/src/builders/library/tests/behavior/build_spec.ts +++ b/packages/angular/build/src/builders/library/tests/behavior/build_spec.ts @@ -216,6 +216,12 @@ describeLibraryBuilder(executeLibraryBuilder, LIBRARY_BUILDER_INFO, (harness) => const { result, logs } = await harness.executeOnce({ outputLogsOnFailure: false }); expect(result?.success).toBeFalse(); + expect(logs).toContain( + jasmine.objectContaining({ + level: 'error', + message: jasmine.stringContaining('TS2322'), + }), + ); expect(logs).toContain( jasmine.objectContaining({ level: 'error', diff --git a/packages/angular/build/src/builders/library/tests/options/allowed-non-peer-dependencies_spec.ts b/packages/angular/build/src/builders/library/tests/options/allowed-non-peer-dependencies_spec.ts index caca7c594f26..c75699d068a3 100644 --- a/packages/angular/build/src/builders/library/tests/options/allowed-non-peer-dependencies_spec.ts +++ b/packages/angular/build/src/builders/library/tests/options/allowed-non-peer-dependencies_spec.ts @@ -24,10 +24,14 @@ describeLibraryBuilder(executeLibraryBuilder, LIBRARY_BUILDER_INFO, (harness) => ...BASE_OPTIONS, }); - const { result } = await harness.executeOnce(); + const { result, logs } = await harness.executeOnce({ outputLogsOnFailure: false }); expect(result?.success).toBeFalse(); - expect(result?.error).toContain('allowedNonPeerDependencies'); - expect(result?.error).toContain('lodash-es'); + expect(logs).toContain( + jasmine.objectContaining({ + level: 'error', + message: jasmine.stringMatching(/lodash-es.*allowedNonPeerDependencies/), + }), + ); }); it('should succeed build when dependency matches allowedNonPeerDependencies pattern', async () => { From 0b9a52cc9516d28afa0d9ef0d07ec745967faf56 Mon Sep 17 00:00:00 2001 From: Alan Agius <17563226+alan-agius4@users.noreply.github.com> Date: Tue, 13 Oct 2026 07:00:46 +0000 Subject: [PATCH 611/787] fix(@angular/ssr): preserve preload metadata for nested empty-path routes Previously, `handleRoute` yielded a parent route's metadata before appending `loadChildren` preloads or traversing child routes, while `traverseRoutesConfig` appended a trailing slash only to empty-path routes. Under a non-empty parent, the parent ('/pricing') and its empty-path child ('/pricing/') received distinct keys during `getRoutesFromAngularRouterConfig` deduplication (`seenRoutes`) and were only merged later by `RouteTree.insert`. However, when an empty-path route was nested under another empty-path route (such as at the root '/' or under '/es' -> '' -> ''), both the parent and child received the same key, causing `seenRoutes` to keep the outer route's metadata and drop the descendant's accumulated `preload` and redirect metadata. Update `handleRoute` to append `loadChildren` preloads upfront and allow the first matching empty-path child route to override its parent's metadata for the same path, and remove the redundant `addTrailingSlash` keying in `traverseRoutesConfig`. Closes #34320 --- packages/angular/ssr/src/routes/ng-routes.ts | 96 ++++++++++++------- .../angular/ssr/test/routes/ng-routes_spec.ts | 91 ++++++++++++++++++ packages/angular/ssr/test/testing-utils.ts | 5 +- 3 files changed, 156 insertions(+), 36 deletions(-) diff --git a/packages/angular/ssr/src/routes/ng-routes.ts b/packages/angular/ssr/src/routes/ng-routes.ts index 915d7c2b9a47..816155c4df01 100644 --- a/packages/angular/ssr/src/routes/ng-routes.ts +++ b/packages/angular/ssr/src/routes/ng-routes.ts @@ -31,7 +31,7 @@ import { AngularAppManifest, getAngularAppManifest } from '../manifest'; import { AngularBootstrap, isNgModule } from '../utils/ng'; import { promiseWithAbort } from '../utils/promise'; import { VALID_REDIRECT_RESPONSE_CODES, isValidRedirectResponseCode } from '../utils/redirect'; -import { addTrailingSlash, joinUrlParts, stripLeadingSlash } from '../utils/url'; +import { joinUrlParts, stripLeadingSlash } from '../utils/url'; import { PrerenderFallback, RenderMode, @@ -170,12 +170,14 @@ async function* handleRoute(options: { } = options; const { redirectTo, loadChildren, loadComponent, children, ɵentryName } = route; - if (ɵentryName && loadComponent) { + if (ɵentryName && (loadComponent || loadChildren)) { appendPreloadToMetadata(ɵentryName, entryPointToBrowserMapping, metadata); } + const parentRoutes = new Map(); + if (metadata.renderMode === RenderMode.Prerender) { - yield* handleSSGRoute( + for await (const result of handleSSGRoute( serverConfigRouteTree, typeof redirectTo === 'string' ? redirectTo : undefined, parentRoute, @@ -183,7 +185,13 @@ async function* handleRoute(options: { parentInjector, invokeGetPrerenderParams, includePrerenderFallbackRoutes, - ); + )) { + if ('error' in result) { + yield result; + } else { + parentRoutes.set(result.route, result); + } + } } else if (redirectTo !== undefined) { if (metadata.status && !isValidRedirectResponseCode(metadata.status)) { yield { @@ -192,34 +200,23 @@ async function* handleRoute(options: { `Please use one of the following redirect response codes: ${[...VALID_REDIRECT_RESPONSE_CODES.values()].join(', ')}.`, }; } else if (typeof redirectTo === 'string') { - yield { + parentRoutes.set(metadata.route, { ...metadata, redirectTo: resolveRedirectTo(parentRoute, redirectTo), relativeRedirect: redirectTo[0] !== '/' ? true : undefined, - }; + }); } else { - yield metadata; + parentRoutes.set(metadata.route, metadata); } } else { - yield metadata; + parentRoutes.set(metadata.route, metadata); } - // Recursively process child routes - if (children?.length) { - yield* traverseRoutesConfig({ - ...options, - routes: children, - parentRoute: currentRoutePath, - parentPreloads: metadata.preload, - }); - } - - // Load and process lazy-loaded child routes - if (loadChildren) { - if (ɵentryName) { - appendPreloadToMetadata(ɵentryName, entryPointToBrowserMapping, metadata); - } + // Recursively process child and lazy-loaded routes + let childRoutes: Route[] | undefined = children; + let childInjector = parentInjector; + if (!childRoutes?.length && loadChildren) { const routeInjector = route.providers ? createEnvironmentInjector( route.providers, @@ -230,16 +227,48 @@ async function* handleRoute(options: { const loadedChildRoutes = await loadChildrenHelper(route, compiler, routeInjector); if (loadedChildRoutes) { - const { routes: childRoutes, injector = routeInjector } = loadedChildRoutes; - yield* traverseRoutesConfig({ - ...options, - routes: childRoutes, - parentInjector: injector, - parentRoute: currentRoutePath, - parentPreloads: metadata.preload, - }); + childRoutes = loadedChildRoutes.routes; + childInjector = loadedChildRoutes.injector ?? routeInjector; } } + + if (!childRoutes?.length) { + yield* parentRoutes.values(); + + return; + } + + const childResults: (RouteTreeNodeMetadata | { error: string })[] = []; + const overriddenParentRoutes = new Set(); + const traverseChildRoutes = traverseRoutesConfig({ + ...options, + routes: childRoutes, + parentInjector: childInjector, + parentRoute: currentRoutePath, + parentPreloads: metadata.preload, + }); + + for await (const result of traverseChildRoutes) { + if ('error' in result) { + childResults.push(result); + continue; + } + + // If a child route resolves to the exact same path as the parent (i.e., an empty-path child), + // let the first matching child override the parent's metadata so accumulated preloads and + // redirects from the activated descendant chain are preserved. + if (parentRoutes.has(result.route)) { + if (!overriddenParentRoutes.has(result.route)) { + overriddenParentRoutes.add(result.route); + parentRoutes.set(result.route, result); + } + } else { + childResults.push(result); + } + } + + yield* parentRoutes.values(); + yield* childResults; } catch (error) { yield { error: `Error in handleRoute for '${options.currentRoutePath}': ${(error as Error).message}`, @@ -344,10 +373,7 @@ async function* traverseRoutesConfig(options: { renderMode: RenderMode.Prerender, ...matchedMetaData, preload: parentPreloads, - // Match Angular router behavior - // ['one', 'two', ''] -> 'one/two/' - // ['one', 'two', 'three'] -> 'one/two/three' - route: path === '' ? addTrailingSlash(currentRoutePath) : currentRoutePath, + route: currentRoutePath, presentInClientRouter: undefined, }, currentRoutePath, diff --git a/packages/angular/ssr/test/routes/ng-routes_spec.ts b/packages/angular/ssr/test/routes/ng-routes_spec.ts index 1af823f8f2ba..93b8e446ccb4 100644 --- a/packages/angular/ssr/test/routes/ng-routes_spec.ts +++ b/packages/angular/ssr/test/routes/ng-routes_spec.ts @@ -1044,4 +1044,95 @@ describe('extractRoutesAndCreateRouteTree', () => { expect(isDiscoveringRoutes).toBeTrue(); }); + + it('should preserve preload metadata for routes under nested empty-path routes', async () => { + setAngularAppTestingManifest( + [ + { + path: '', + children: [ + { + path: '', + pathMatch: 'full', + loadChildren: () => [ + { + path: '', + loadComponent: () => DummyComponent, + ɵentryName: 'home-page', + } as Route, + ], + ɵentryName: 'home-routes', + } as Route, + { + path: '', + children: [ + { + path: 'pricing', + loadChildren: () => [ + { + path: '', + loadComponent: () => DummyComponent, + ɵentryName: 'pricing-page', + } as Route, + ], + ɵentryName: 'pricing-routes', + } as Route, + ], + }, + ], + }, + { + path: 'es', + children: [ + { + path: '', + pathMatch: 'full', + loadChildren: () => [ + { + path: '', + loadComponent: () => DummyComponent, + ɵentryName: 'home-page', + } as Route, + ], + ɵentryName: 'home-routes', + } as Route, + ], + }, + ], + [{ path: '**', renderMode: RenderMode.Prerender }], + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + { + 'home-routes': ['chunk-home-routes.js'], + 'home-page': ['chunk-home-page.js'], + 'pricing-routes': ['chunk-pricing-routes.js'], + 'pricing-page': ['chunk-pricing-page.js'], + }, + ); + + const { routeTree, errors } = await extractRoutesAndCreateRouteTree({ url }); + expect(errors).toHaveSize(0); + expect(routeTree.toObject()).toEqual([ + { + route: '/', + renderMode: RenderMode.Prerender, + preload: ['chunk-home-routes.js', 'chunk-home-page.js'], + }, + { + route: '/pricing', + renderMode: RenderMode.Prerender, + preload: ['chunk-pricing-routes.js', 'chunk-pricing-page.js'], + }, + { + route: '/es', + renderMode: RenderMode.Prerender, + preload: ['chunk-home-routes.js', 'chunk-home-page.js'], + }, + ]); + }); }); diff --git a/packages/angular/ssr/test/testing-utils.ts b/packages/angular/ssr/test/testing-utils.ts index 6f825507c7a3..dad622d2e802 100644 --- a/packages/angular/ssr/test/testing-utils.ts +++ b/packages/angular/ssr/test/testing-utils.ts @@ -17,7 +17,7 @@ import { bootstrapApplication } from '@angular/platform-browser'; import { RouterOutlet, Routes, provideRouter } from '@angular/router'; import { type CompactPlan, compileSheet, encodePlan } from 'beasties/compiler'; import { destroyAngularServerApp } from '../src/app'; -import { ServerAsset, setAngularAppManifest } from '../src/manifest'; +import { AngularAppManifest, ServerAsset, setAngularAppManifest } from '../src/manifest'; import { ServerRoute, provideServerRendering, withRoutes } from '../src/routes/route-config'; @Component({ @@ -44,6 +44,7 @@ class AppComponent {} * root component and all its children. * @param inlineCriticalCss - An optional record of stylesheet paths to CSS content to be compiled into critical CSS plans. * @param nonce - An optional Content Security Policy (CSP) nonce to be used for inlined critical CSS. + * @param entryPointToBrowserMapping - An optional mapping of entry-point names to their associated browser bundles. */ export function setAngularAppTestingManifest( routes: Routes, @@ -55,6 +56,7 @@ export function setAngularAppTestingManifest( extraProviders: Array = [], inlineCriticalCss?: Record, nonce?: string, + entryPointToBrowserMapping?: AngularAppManifest['entryPointToBrowserMapping'], ): void { destroyAngularServerApp(); @@ -70,6 +72,7 @@ export function setAngularAppTestingManifest( setAngularAppManifest({ criticalCssPlans, nonce, + entryPointToBrowserMapping, baseHref, locale, assets: { From 639d31f11b102a12776ae8dce6369d6edd1b6ff3 Mon Sep 17 00:00:00 2001 From: Alan Agius Date: Wed, 14 Oct 2026 08:38:24 +0200 Subject: [PATCH 612/787] feat(@schematics/angular): add use-library-builder migration to migrate from ng-packagr Adds an optional migration for v22.3.0 to migrate library projects from ng-packagr to the @angular/build:library builder. --- .../migrations/migration-collection.json | 7 + .../use-library-builder/migration.ts | 587 ++++++++++++++++++ .../use-library-builder/migration_spec.ts | 430 +++++++++++++ .../angular/utility/workspace-models.ts | 1 + 4 files changed, 1025 insertions(+) create mode 100644 packages/schematics/angular/migrations/use-library-builder/migration.ts create mode 100644 packages/schematics/angular/migrations/use-library-builder/migration_spec.ts diff --git a/packages/schematics/angular/migrations/migration-collection.json b/packages/schematics/angular/migrations/migration-collection.json index db1b95f987ef..9147e229b97c 100644 --- a/packages/schematics/angular/migrations/migration-collection.json +++ b/packages/schematics/angular/migrations/migration-collection.json @@ -29,6 +29,13 @@ "version": "22.0.0", "factory": "./update-workspace-config/migration", "description": "Update the angular workspace configuration." + }, + "use-library-builder": { + "version": "22.3.0", + "factory": "./use-library-builder/migration", + "description": "Migrate library projects from 'ng-packagr' to the new '@angular/build:library' builder.", + "optional": true, + "recommended": false } } } diff --git a/packages/schematics/angular/migrations/use-library-builder/migration.ts b/packages/schematics/angular/migrations/use-library-builder/migration.ts new file mode 100644 index 000000000000..68f9e8738e25 --- /dev/null +++ b/packages/schematics/angular/migrations/use-library-builder/migration.ts @@ -0,0 +1,587 @@ +/** + * @license + * Copyright Google LLC All Rights Reserved. + * + * Use of this source code is governed by an MIT-style license that can be + * found in the LICENSE file at https://angular.dev/license + */ + +import { type JsonObject, type JsonValue, isJsonObject } from '@angular-devkit/core'; +import { + type Rule, + type SchematicContext, + SchematicsException, + type Tree, + chain, +} from '@angular-devkit/schematics'; +import { dirname, join, normalize, relative } from 'node:path/posix'; +import { + DependencyType, + ExistingBehavior, + addDependency, + removeDependency, +} from '../../utility/dependency'; +import { JSONFile } from '../../utility/json-file'; +import { latestVersions } from '../../utility/latest-versions'; +import { + type TargetDefinition, + allTargetOptions, + allWorkspaceTargets, + updateWorkspace, +} from '../../utility/workspace'; +import { Builders, ProjectType } from '../../utility/workspace-models'; + +/** + * Represents the configuration structure of an `ng-package.json` file or + * the `ngPackage` section within a `package.json` file. + */ +interface NgPackageConfig { + dest?: string; + assets?: (string | { glob: string; input: string; output: string })[]; + allowedNonPeerDependencies?: string[]; + inlineStyleLanguage?: string; + keepLifecycleScripts?: boolean; + deleteDestPath?: boolean; + lib?: { + entryFile?: string; + styleIncludePaths?: string[]; + sass?: { + fatalDeprecations?: string[]; + silenceDeprecations?: string[]; + futureDeprecations?: string[]; + }; + }; +} + +/** + * Metadata describing a discovered secondary entry point in a library project. + */ +interface SecondaryEntryPoint { + subpath: string; + entryPoint: string; + configFile: string; +} + +/** + * Normalizes a workspace-relative POSIX path, converting `'.'` or `'/'` to `''`. + * + * @param path The path string to normalize. + * @returns The normalized workspace-relative path. + */ +function normalizeRelativePath(path: string): string { + const normalized = normalize(path).replace(/^\/+|\/+$/g, ''); + + return normalized === '.' ? '' : normalized; +} + +/** + * Reads and parses an `ng-packagr` configuration from either an `ng-package.json` + * file or the `ngPackage` property of a `package.json` file. + * + * @param tree The virtual file system tree. + * @param filePath The workspace-relative path to the configuration file. + * @returns The parsed `NgPackageConfig`, or `undefined` if the file does not exist or cannot be parsed. + */ +function parseNgPackageFile(tree: Tree, filePath: string): NgPackageConfig | undefined { + if (!tree.exists(filePath)) { + return undefined; + } + + try { + const json = new JSONFile(tree, filePath); + if (filePath.endsWith('/package.json') || filePath === 'package.json') { + const ngPackage = json.get(['ngPackage']) as JsonValue; + + return isJsonObject(ngPackage) ? (ngPackage as NgPackageConfig) : undefined; + } + + const content = json.get([]) as JsonValue; + + return isJsonObject(content) ? (content as NgPackageConfig) : undefined; + } catch { + return undefined; + } +} + +/** + * Resolves the TypeScript entry file path for a library entry point directory. + * Uses the explicitly configured `entryFile` when provided, or checks common + * default locations. + * + * @param tree The virtual file system tree. + * @param dir The directory of the primary or secondary entry point. + * @param configuredEntry The optional `lib.entryFile` path from `ng-package.json`. + * @returns The resolved entry file path relative to `dir`. + */ +function resolveEntryFile(tree: Tree, dir: string, configuredEntry?: string): string { + if (configuredEntry) { + return configuredEntry; + } + + const candidates = [ + 'src/public-api.ts', + 'src/public_api.ts', + 'public-api.ts', + 'public_api.ts', + 'src/index.ts', + 'index.ts', + ]; + + for (const candidate of candidates) { + if (tree.exists(join(dir, candidate))) { + return candidate; + } + } + + throw new SchematicsException( + `Could not find an entry file for library entry point at "${dir || '.'}".`, + ); +} + +/** + * Traverses a library project directory to discover all secondary entry points + * defined by nested `ng-package.json` files or `package.json` files containing an `ngPackage` field. + * + * @param tree The virtual file system tree. + * @param projectRoot The root directory of the library project. + * @param primaryProjectFile The workspace-relative path to the primary `ng-packagr` configuration file. + * @returns An array of discovered secondary entry points. + */ +function findSecondaryEntryPoints( + tree: Tree, + projectRoot: string, + primaryProjectFile: string, +): SecondaryEntryPoint[] { + const secondaryEntryPoints: SecondaryEntryPoint[] = []; + const normalizedRoot = normalizeRelativePath(projectRoot); + const normalizedPrimary = primaryProjectFile ? normalizeRelativePath(primaryProjectFile) : ''; + const rootDir = tree.getDir(normalizedRoot); + const directories = [rootDir]; + + for (const current of directories) { + const currentPath = normalizeRelativePath(current.path); + + if (currentPath !== normalizedRoot) { + const ngPackageJsonPath = join(currentPath, 'ng-package.json'); + const packageJsonPath = join(currentPath, 'package.json'); + + if ( + current.subfiles.some((f) => f === 'ng-package.json') && + ngPackageJsonPath !== normalizedPrimary + ) { + const config = parseNgPackageFile(tree, ngPackageJsonPath); + const subpath = relative(normalizedRoot, currentPath); + const entryFile = resolveEntryFile(tree, currentPath, config?.lib?.entryFile); + secondaryEntryPoints.push({ + subpath, + entryPoint: join(currentPath, entryFile), + configFile: ngPackageJsonPath, + }); + } else if ( + current.subfiles.some((f) => f === 'package.json') && + packageJsonPath !== normalizedPrimary + ) { + const config = parseNgPackageFile(tree, packageJsonPath); + if (config) { + const subpath = relative(normalizedRoot, currentPath); + const entryFile = resolveEntryFile(tree, currentPath, config.lib?.entryFile); + secondaryEntryPoints.push({ + subpath, + entryPoint: join(currentPath, entryFile), + configFile: packageJsonPath, + }); + } + } + } + + for (const subdir of current.subdirs) { + if ( + subdir === 'node_modules' || + subdir === 'dist' || + subdir === 'out-tsc' || + subdir.startsWith('.') + ) { + continue; + } + directories.push(current.dir(subdir)); + } + } + + return secondaryEntryPoints; +} + +/** + * Transfers `ng-packagr` configuration options onto the library's `build` target in `angular.json`. + * + * @param projectRoot The normalized root directory of the library project. + * @param projectDir The directory containing the primary `ng-packagr` configuration file. + * @param buildTarget The library's `build` target definition in `angular.json`. + * @param ngPackageConfig The parsed `NgPackageConfig`, if available. + * @param tree The virtual file system tree. + */ +function migrateTargetOptions( + projectRoot: string, + projectDir: string, + buildTarget: TargetDefinition, + ngPackageConfig: NgPackageConfig | undefined, + tree: Tree, +): void { + buildTarget.builder = Builders.BuildLibrary; + buildTarget.options ??= {}; + + const devTsConfig = buildTarget.configurations?.['development']?.['tsConfig']; + if (typeof buildTarget.options['tsConfig'] !== 'string') { + if (typeof devTsConfig === 'string') { + buildTarget.options['tsConfig'] = devTsConfig; + delete buildTarget.configurations?.['development']?.['tsConfig']; + } else if (tree.exists(join(projectRoot, 'tsconfig.lib.json'))) { + buildTarget.options['tsConfig'] = join(projectRoot, 'tsconfig.lib.json'); + } + } else if (devTsConfig === buildTarget.options['tsConfig']) { + delete buildTarget.configurations?.['development']?.['tsConfig']; + } + + if (ngPackageConfig?.dest && typeof buildTarget.options['outputPath'] !== 'string') { + buildTarget.options['outputPath'] = join(projectDir, ngPackageConfig.dest); + } + + if (ngPackageConfig?.assets?.length) { + const existingAssets = Array.isArray(buildTarget.options['assets']) + ? buildTarget.options['assets'] + : []; + const migratedAssets = ngPackageConfig.assets.map((asset) => { + if (typeof asset === 'string') { + return join(projectDir, asset); + } + if (isJsonObject(asset) && typeof asset['input'] === 'string') { + return { + ...asset, + input: join(projectDir, asset['input']), + }; + } + + return asset; + }); + buildTarget.options['assets'] = [...existingAssets, ...migratedAssets]; + } + + if (ngPackageConfig?.lib?.styleIncludePaths?.length || ngPackageConfig?.lib?.sass) { + const stylePreprocessorOptions = buildTarget.options['stylePreprocessorOptions']; + const existingPreprocessorOptions: JsonObject = + stylePreprocessorOptions && isJsonObject(stylePreprocessorOptions) + ? { ...stylePreprocessorOptions } + : {}; + + if (ngPackageConfig.lib.styleIncludePaths?.length) { + const existingIncludePaths = Array.isArray(existingPreprocessorOptions['includePaths']) + ? (existingPreprocessorOptions['includePaths'] as string[]) + : []; + const migratedIncludePaths = ngPackageConfig.lib.styleIncludePaths.map((p) => + join(projectDir, p), + ); + existingPreprocessorOptions['includePaths'] = [ + ...existingIncludePaths, + ...migratedIncludePaths, + ]; + } + if (ngPackageConfig.lib.sass) { + existingPreprocessorOptions['sass'] = ngPackageConfig.lib.sass; + } + + buildTarget.options['stylePreprocessorOptions'] = existingPreprocessorOptions; + } + + if (ngPackageConfig?.allowedNonPeerDependencies?.length) { + buildTarget.options['allowedNonPeerDependencies'] = ngPackageConfig.allowedNonPeerDependencies; + } + if (ngPackageConfig?.inlineStyleLanguage) { + buildTarget.options['inlineStyleLanguage'] = ngPackageConfig.inlineStyleLanguage; + } + if (ngPackageConfig?.keepLifecycleScripts !== undefined) { + buildTarget.options['keepLifecycleScripts'] = ngPackageConfig.keepLifecycleScripts; + } + if (ngPackageConfig?.deleteDestPath !== undefined) { + buildTarget.options['deleteOutputPath'] = ngPackageConfig.deleteDestPath; + } + + for (const [, options] of allTargetOptions(buildTarget, false)) { + delete options['project']; + } + + // Configure development configuration with full compilation mode unless already specified in tsconfig + buildTarget.configurations ??= {}; + buildTarget.configurations['development'] ??= {}; + + const effectiveDevTsConfig = + typeof buildTarget.configurations['development']['tsConfig'] === 'string' + ? buildTarget.configurations['development']['tsConfig'] + : typeof buildTarget.options['tsConfig'] === 'string' + ? buildTarget.options['tsConfig'] + : undefined; + + let hasDevTsConfigCompilationMode = false; + if (effectiveDevTsConfig && tree.exists(effectiveDevTsConfig)) { + try { + const tsConfigJson = new JSONFile(tree, effectiveDevTsConfig); + hasDevTsConfigCompilationMode = + tsConfigJson.get(['angularCompilerOptions', 'compilationMode']) !== undefined; + } catch { + // Ignore parse errors + } + } + + if (!hasDevTsConfigCompilationMode) { + buildTarget.configurations['development']['compilationMode'] ??= 'full'; + } +} + +/** + * Migrates a single library project's `build` target from `ng-packagr` to `@angular/build:library`, + * transferring configuration options to `angular.json`, writing entry points to `package.json#exports`, + * and cleaning up obsolete `ng-packagr` configuration files. + * + * @param projectRoot The root directory of the library project. + * @param buildTarget The library's `build` target definition in `angular.json`. + * @param tree The virtual file system tree. + * @param context The schematic execution context. + * @returns `true` if the library target was migrated, or `false` if it was skipped. + */ +function updateLibraryTarget( + projectRoot: string, + buildTarget: TargetDefinition, + tree: Tree, + context: SchematicContext, +): boolean { + const normalizedProjectRoot = normalizeRelativePath(projectRoot); + let primaryProjectFile = + typeof buildTarget.options?.['project'] === 'string' + ? normalizeRelativePath(buildTarget.options['project']) + : ''; + if (!primaryProjectFile) { + for (const [, options] of allTargetOptions(buildTarget, true)) { + if (typeof options['project'] === 'string') { + primaryProjectFile = normalizeRelativePath(options['project']); + break; + } + } + } + if (!primaryProjectFile) { + const defaultNgPackageJson = join(normalizedProjectRoot, 'ng-package.json'); + const defaultPackageJson = join(normalizedProjectRoot, 'package.json'); + if (tree.exists(defaultNgPackageJson)) { + primaryProjectFile = defaultNgPackageJson; + } else if (tree.exists(defaultPackageJson)) { + primaryProjectFile = defaultPackageJson; + } + } + + if (/\.[cm]?js$/.test(primaryProjectFile)) { + context.logger.warn( + `Skipping project at "${projectRoot}" because JavaScript ng-packagr ` + + `configuration files ("${primaryProjectFile}") cannot be automatically migrated.`, + ); + + return false; + } + + const ngPackageConfig = primaryProjectFile + ? parseNgPackageFile(tree, primaryProjectFile) + : undefined; + + const projectDir = primaryProjectFile + ? normalizeRelativePath(dirname(primaryProjectFile)) + : normalizedProjectRoot; + const primaryEntryFile = resolveEntryFile(tree, projectDir, ngPackageConfig?.lib?.entryFile); + const primaryEntryFilePath = join(projectDir, primaryEntryFile); + const secondaryEntryPoints = findSecondaryEntryPoints( + tree, + normalizedProjectRoot, + primaryProjectFile, + ); + + const toRelativeExportPath = (filePath: string): string => { + const rel = relative(normalizedProjectRoot, filePath); + + return rel.startsWith('./') || rel.startsWith('../') ? rel : `./${rel}`; + }; + + const entryPointExports: Record = { + '.': toRelativeExportPath(primaryEntryFilePath), + }; + for (const secondary of secondaryEntryPoints) { + const exportKey = + secondary.subpath.startsWith('./') || secondary.subpath.startsWith('../') + ? secondary.subpath + : `./${secondary.subpath}`; + entryPointExports[exportKey] = toRelativeExportPath(secondary.entryPoint); + } + + migrateTargetOptions(normalizedProjectRoot, projectDir, buildTarget, ngPackageConfig, tree); + + const packageJsonPath = join(normalizedProjectRoot, 'package.json'); + + // Delete primary ng-package.json if it exists + if ( + primaryProjectFile && + primaryProjectFile.endsWith('ng-package.json') && + tree.exists(primaryProjectFile) + ) { + tree.delete(primaryProjectFile); + } else if ( + primaryProjectFile && + primaryProjectFile !== packageJsonPath && + (primaryProjectFile.endsWith('/package.json') || primaryProjectFile === 'package.json') && + tree.exists(primaryProjectFile) + ) { + const json = new JSONFile(tree, primaryProjectFile); + json.remove(['ngPackage']); + } + + // Update library package.json with exports and remove ngPackage + if (tree.exists(packageJsonPath)) { + updateLibraryPackageJson(tree, packageJsonPath, entryPointExports); + } + + // Delete secondary configuration files + for (const secondary of secondaryEntryPoints) { + if (secondary.configFile.endsWith('ng-package.json') && tree.exists(secondary.configFile)) { + tree.delete(secondary.configFile); + } else if ( + (secondary.configFile.endsWith('/package.json') || secondary.configFile === 'package.json') && + tree.exists(secondary.configFile) + ) { + const json = new JSONFile(tree, secondary.configFile); + json.remove(['ngPackage']); + const remaining = json.get([]) as JsonValue; + if ( + isJsonObject(remaining) && + Object.keys(remaining).filter((k) => k !== '$schema').length === 0 + ) { + tree.delete(secondary.configFile); + } + } + } + + context.logger.info( + `Updated project at "${projectRoot}" to use the new '@angular/build:library' builder with ${ + Object.keys(entryPointExports).length + } entry point(s).`, + ); + + return true; +} + +/** + * Updates the library's `package.json` file by removing the legacy `ngPackage` configuration + * and `tslib` dependency, and merging the discovered entry points into the `exports` map. + * + * @param tree The virtual file system tree. + * @param packageJsonPath The workspace-relative path to the library's `package.json`. + * @param entryPointExports Map of export subpaths to relative entry file paths. + */ +function updateLibraryPackageJson( + tree: Tree, + packageJsonPath: string, + entryPointExports: Record, +): void { + const json = new JSONFile(tree, packageJsonPath); + json.remove(['ngPackage']); + + for (const depType of [ + 'dependencies', + 'peerDependencies', + 'devDependencies', + 'optionalDependencies', + ]) { + json.remove([depType, 'tslib']); + const deps = json.get([depType]) as JsonValue; + if (isJsonObject(deps) && Object.keys(deps).length === 0) { + json.remove([depType]); + } + } + + const existingExports = json.get(['exports']) as JsonValue; + let existingExportsObj: Record = {}; + if (isJsonObject(existingExports)) { + const keys = Object.keys(existingExports); + if (keys.some((k) => k.startsWith('.'))) { + existingExportsObj = existingExports; + } else if (keys.length > 0) { + existingExportsObj = { '.': existingExports }; + } + } + + const updatedExports: Record = { + ...existingExportsObj, + }; + + for (const [subpath, targetPath] of Object.entries(entryPointExports)) { + const current = updatedExports[subpath]; + if (current && isJsonObject(current)) { + updatedExports[subpath] = { + ...current, + default: targetPath, + }; + } else { + updatedExports[subpath] = targetPath; + } + } + + json.modify(['exports'], updatedExports); +} + +/** + * Migration main entrypoint for use-library-builder. + */ +export default function (): Rule { + return (tree, context) => + updateWorkspace((workspace) => { + let hasMigratedLibrary = false; + + for (const [, project] of workspace.projects) { + if (project.extensions.projectType !== ProjectType.Library) { + continue; + } + + const buildTarget = project.targets.get('build'); + if ( + !buildTarget || + buildTarget.builder === Builders.BuildLibrary || + (buildTarget.builder !== Builders.NgPackagr && + buildTarget.builder !== Builders.BuildNgPackagr) + ) { + continue; + } + + if (updateLibraryTarget(project.root, buildTarget, tree, context)) { + hasMigratedLibrary = true; + } + } + + if (!hasMigratedLibrary) { + return; + } + + const rules: Rule[] = [ + addDependency('@angular/build', latestVersions.AngularBuild, { + type: DependencyType.Dev, + existing: ExistingBehavior.Skip, + }), + ]; + + // Check if any targets still use ng-packagr across the workspace + let hasNgPackagrUsage = false; + for (const [, target] of allWorkspaceTargets(workspace)) { + if (target.builder === Builders.NgPackagr || target.builder === Builders.BuildNgPackagr) { + hasNgPackagrUsage = true; + break; + } + } + + if (!hasNgPackagrUsage) { + rules.push(removeDependency('ng-packagr')); + } + + return chain(rules); + }); +} diff --git a/packages/schematics/angular/migrations/use-library-builder/migration_spec.ts b/packages/schematics/angular/migrations/use-library-builder/migration_spec.ts new file mode 100644 index 000000000000..11192f8e5897 --- /dev/null +++ b/packages/schematics/angular/migrations/use-library-builder/migration_spec.ts @@ -0,0 +1,430 @@ +/** + * @license + * Copyright Google LLC All Rights Reserved. + * + * Use of this source code is governed by an MIT-style license that can be + * found in the LICENSE file at https://angular.dev/license + */ + +import { EmptyTree } from '@angular-devkit/schematics'; +import { SchematicTestRunner, UnitTestTree } from '@angular-devkit/schematics/testing'; +import { Builders, ProjectType, type WorkspaceSchema } from '../../utility/workspace-models'; + +function createWorkspaceConfig(tree: UnitTestTree) { + const angularConfig: WorkspaceSchema = { + version: 1, + projects: { + 'my-lib': { + root: 'projects/my-lib', + sourceRoot: 'projects/my-lib/src', + projectType: ProjectType.Library, + prefix: 'lib', + architect: { + build: { + builder: Builders.NgPackagr, + options: { + project: 'projects/my-lib/ng-package.json', + tsConfig: 'projects/my-lib/tsconfig.lib.json', + }, + configurations: { + production: { + tsConfig: 'projects/my-lib/tsconfig.lib.prod.json', + }, + }, + }, + }, + }, + }, + }; + + tree.create('/angular.json', JSON.stringify(angularConfig, undefined, 2)); + tree.create( + '/package.json', + JSON.stringify( + { + devDependencies: { + 'ng-packagr': '^18.0.0', + }, + }, + undefined, + 2, + ), + ); + tree.create( + '/projects/my-lib/package.json', + JSON.stringify( + { + name: 'my-lib', + version: '0.0.1', + dependencies: { + tslib: '^2.3.0', + }, + }, + undefined, + 2, + ), + ); + tree.create( + '/projects/my-lib/ng-package.json', + JSON.stringify( + { + dest: '../../dist/my-lib', + lib: { + entryFile: 'src/public-api.ts', + }, + }, + undefined, + 2, + ), + ); +} + +describe('Migration to use the library builder', () => { + const schematicName = 'use-library-builder'; + const schematicRunner = new SchematicTestRunner( + 'migrations', + require.resolve('../migration-collection.json'), + ); + + let tree: UnitTestTree; + beforeEach(() => { + tree = new UnitTestTree(new EmptyTree()); + createWorkspaceConfig(tree); + }); + + it('should migrate library project using ng-packagr to @angular/build:library', async () => { + const newTree = await schematicRunner.runSchematic(schematicName, {}, tree); + const { + projects: { 'my-lib': lib }, + // eslint-disable-next-line @typescript-eslint/no-explicit-any + } = newTree.readJson('/angular.json') as any; + + const { builder, options, configurations } = lib.architect['build']; + expect(builder).toBe(Builders.BuildLibrary); + expect(options.project).toBeUndefined(); + expect(options.entryPoints).toBeUndefined(); + expect(options.tsConfig).toBe('projects/my-lib/tsconfig.lib.json'); + expect(options.outputPath).toBe('dist/my-lib'); + expect(configurations.development).toEqual({ + compilationMode: 'full', + }); + + const libPkg = newTree.readJson('/projects/my-lib/package.json') as { + dependencies: unknown; + exports: unknown; + }; + expect(libPkg.dependencies).toBeUndefined(); + expect(libPkg.exports).toEqual({ + '.': './src/public-api.ts', + }); + + expect(newTree.exists('/projects/my-lib/ng-package.json')).toBe(false); + }); + + it('should migrate @angular/build:ng-packagr and promote tsConfig from development configuration', async () => { + const angularJson = JSON.parse(tree.readContent('/angular.json')); + angularJson.projects['my-lib'].architect.build = { + builder: Builders.BuildNgPackagr, + configurations: { + production: { + tsConfig: 'projects/my-lib/tsconfig.lib.prod.json', + }, + development: { + tsConfig: 'projects/my-lib/tsconfig.lib.json', + }, + }, + }; + tree.overwrite('/angular.json', JSON.stringify(angularJson, undefined, 2)); + + const newTree = await schematicRunner.runSchematic(schematicName, {}, tree); + const { + projects: { 'my-lib': lib }, + // eslint-disable-next-line @typescript-eslint/no-explicit-any + } = newTree.readJson('/angular.json') as any; + + const { builder, options, configurations } = lib.architect['build']; + expect(builder).toBe(Builders.BuildLibrary); + expect(options.tsConfig).toBe('projects/my-lib/tsconfig.lib.json'); + expect(configurations.development).toEqual({ + compilationMode: 'full', + }); + }); + + it('should not set compilationMode in development configuration if already defined in tsconfig.lib.json', async () => { + tree.create( + '/projects/my-lib/tsconfig.lib.json', + JSON.stringify( + { + compilerOptions: { + declaration: true, + declarationMap: true, + }, + angularCompilerOptions: { + compilationMode: 'partial', + }, + }, + undefined, + 2, + ), + ); + + const newTree = await schematicRunner.runSchematic(schematicName, {}, tree); + const { + projects: { 'my-lib': lib }, + // eslint-disable-next-line @typescript-eslint/no-explicit-any + } = newTree.readJson('/angular.json') as any; + + const { configurations } = lib.architect['build']; + expect(configurations.development).toEqual({}); + }); + + it('should discover and migrate secondary entry points into package.json exports', async () => { + tree.create( + '/projects/my-lib/testing/ng-package.json', + JSON.stringify( + { + lib: { + entryFile: 'src/public-api.ts', + }, + }, + undefined, + 2, + ), + ); + tree.create( + '/projects/my-lib/schematics/package.json', + JSON.stringify( + { + ngPackage: { + lib: { + entryFile: 'index.ts', + }, + }, + }, + undefined, + 2, + ), + ); + + const newTree = await schematicRunner.runSchematic(schematicName, {}, tree); + const { + projects: { 'my-lib': lib }, + // eslint-disable-next-line @typescript-eslint/no-explicit-any + } = newTree.readJson('/angular.json') as any; + + const { options } = lib.architect['build']; + expect(options.entryPoints).toBeUndefined(); + + const libPkg = newTree.readJson('/projects/my-lib/package.json') as { exports: unknown }; + expect(libPkg.exports).toEqual({ + '.': './src/public-api.ts', + './schematics': './schematics/index.ts', + './testing': './testing/src/public-api.ts', + }); + + expect(newTree.exists('/projects/my-lib/testing/ng-package.json')).toBe(false); + expect(newTree.exists('/projects/my-lib/schematics/package.json')).toBe(false); + }); + + it('should preserve existing custom exports in package.json when adding entry points', async () => { + tree.overwrite( + '/projects/my-lib/package.json', + JSON.stringify( + { + name: 'my-lib', + version: '0.0.1', + exports: { + './theming': { + sass: './src/_theming.scss', + }, + }, + }, + undefined, + 2, + ), + ); + + const newTree = await schematicRunner.runSchematic(schematicName, {}, tree); + const libPkg = newTree.readJson('/projects/my-lib/package.json') as { exports: unknown }; + expect(libPkg.exports).toEqual({ + './theming': { + sass: './src/_theming.scss', + }, + '.': './src/public-api.ts', + }); + }); + + it('should preserve root condition-only exports in package.json', async () => { + tree.overwrite( + '/projects/my-lib/package.json', + JSON.stringify( + { + name: 'my-lib', + version: '0.0.1', + exports: { + sass: './src/_index.scss', + }, + }, + undefined, + 2, + ), + ); + + const newTree = await schematicRunner.runSchematic(schematicName, {}, tree); + const libPkg = newTree.readJson('/projects/my-lib/package.json') as { exports: unknown }; + expect(libPkg.exports).toEqual({ + '.': { + sass: './src/_index.scss', + default: './src/public-api.ts', + }, + }); + }); + + it('should migrate assets, styleIncludePaths, and sass options from ng-package.json', async () => { + tree.overwrite( + '/projects/my-lib/ng-package.json', + JSON.stringify( + { + dest: '../../dist/my-lib', + assets: ['CHANGELOG.md'], + allowedNonPeerDependencies: ['lodash-es'], + inlineStyleLanguage: 'scss', + keepLifecycleScripts: true, + deleteDestPath: false, + lib: { + entryFile: 'src/public-api.ts', + styleIncludePaths: ['../theme'], + sass: { + silenceDeprecations: ['import'], + }, + }, + }, + undefined, + 2, + ), + ); + + const newTree = await schematicRunner.runSchematic(schematicName, {}, tree); + const { + projects: { 'my-lib': lib }, + // eslint-disable-next-line @typescript-eslint/no-explicit-any + } = newTree.readJson('/angular.json') as any; + + const { options } = lib.architect['build']; + expect(options.assets).toEqual(['projects/my-lib/CHANGELOG.md']); + expect(options.allowedNonPeerDependencies).toEqual(['lodash-es']); + expect(options.inlineStyleLanguage).toBe('scss'); + expect(options.keepLifecycleScripts).toBe(true); + expect(options.deleteOutputPath).toBe(false); + expect(options.stylePreprocessorOptions).toEqual({ + includePaths: ['projects/theme'], + sass: { + silenceDeprecations: ['import'], + }, + }); + }); + + it('should preserve existing stylePreprocessorOptions.includePaths when migrating styleIncludePaths', async () => { + const angularJson = JSON.parse(tree.readContent('/angular.json')); + angularJson.projects['my-lib'].architect.build.options.stylePreprocessorOptions = { + includePaths: ['existing/styles'], + }; + tree.overwrite('/angular.json', JSON.stringify(angularJson, undefined, 2)); + + tree.overwrite( + '/projects/my-lib/ng-package.json', + JSON.stringify( + { + lib: { + entryFile: 'src/public-api.ts', + styleIncludePaths: ['../theme'], + }, + }, + undefined, + 2, + ), + ); + + const newTree = await schematicRunner.runSchematic(schematicName, {}, tree); + const { + projects: { 'my-lib': lib }, + // eslint-disable-next-line @typescript-eslint/no-explicit-any + } = newTree.readJson('/angular.json') as any; + + expect(lib.architect['build'].options.stylePreprocessorOptions).toEqual({ + includePaths: ['existing/styles', 'projects/theme'], + }); + }); + + it('should throw an error when entry file is not configured and no default candidate exists', async () => { + tree.overwrite('/projects/my-lib/ng-package.json', JSON.stringify({}, undefined, 2)); + + await expectAsync(schematicRunner.runSchematic(schematicName, {}, tree)).toBeRejectedWithError( + 'Could not find an entry file for library entry point at "projects/my-lib".', + ); + }); + + it('should migrate package.json with ngPackage configuration', async () => { + tree.overwrite( + '/projects/my-lib/package.json', + JSON.stringify( + { + name: 'my-lib', + ngPackage: { + lib: { + entryFile: 'src/public-api.ts', + }, + }, + }, + undefined, + 2, + ), + ); + + // Point angular.json to package.json + const angularJson = JSON.parse(tree.readContent('/angular.json')); + angularJson.projects['my-lib'].architect.build.options.project = 'projects/my-lib/package.json'; + tree.overwrite('/angular.json', JSON.stringify(angularJson, undefined, 2)); + + const newTree = await schematicRunner.runSchematic(schematicName, {}, tree); + const libPkg = newTree.readJson('/projects/my-lib/package.json') as { + ngPackage?: unknown; + name: string; + exports: unknown; + }; + expect(libPkg.ngPackage).toBeUndefined(); + expect(libPkg.name).toBe('my-lib'); + expect(libPkg.exports).toEqual({ + '.': './src/public-api.ts', + }); + }); + + it('should skip libraries with JavaScript ng-packagr config files and retain ng-packagr dependency', async () => { + const angularJson = JSON.parse(tree.readContent('/angular.json')); + angularJson.projects['my-lib'].architect.build.options.project = + 'projects/my-lib/ng-package.cjs'; + tree.overwrite('/angular.json', JSON.stringify(angularJson, undefined, 2)); + + const newTree = await schematicRunner.runSchematic(schematicName, {}, tree); + const { + projects: { 'my-lib': lib }, + // eslint-disable-next-line @typescript-eslint/no-explicit-any + } = newTree.readJson('/angular.json') as any; + + expect(lib.architect['build'].builder).toBe(Builders.NgPackagr); + + // eslint-disable-next-line @typescript-eslint/no-explicit-any + const rootPkg = newTree.readJson('/package.json') as any; + expect(rootPkg.devDependencies['ng-packagr']).toBeDefined(); + expect(rootPkg.devDependencies['@angular/build']).toBeUndefined(); + }); + + it('should remove ng-packagr and add @angular/build when no library uses ng-packagr', async () => { + const newTree = await schematicRunner.runSchematic(schematicName, {}, tree); + // eslint-disable-next-line @typescript-eslint/no-explicit-any + const rootPkg = newTree.readJson('/package.json') as any; + + expect(rootPkg.devDependencies['ng-packagr']).toBeUndefined(); + expect(rootPkg.devDependencies['@angular/build']).toBeDefined(); + }); +}); diff --git a/packages/schematics/angular/utility/workspace-models.ts b/packages/schematics/angular/utility/workspace-models.ts index d1ae1b146835..51c9c9dbdc9f 100644 --- a/packages/schematics/angular/utility/workspace-models.ts +++ b/packages/schematics/angular/utility/workspace-models.ts @@ -36,6 +36,7 @@ export enum Builders { ExtractI18n = '@angular-devkit/build-angular:extract-i18n', BuildExtractI18n = '@angular/build:extract-i18n', BuildApplication = '@angular/build:application', + BuildLibrary = '@angular/build:library', } export interface FileReplacements { From 6b94a2c904c647dcbdfab5a218aaf08e7eec7cf4 Mon Sep 17 00:00:00 2001 From: Alan Agius <17563226+alan-agius4@users.noreply.github.com> Date: Wed, 14 Oct 2026 09:36:09 +0000 Subject: [PATCH 613/787] refactor(@angular/build): add deleteFilesFromDisk utility and rename emit-files-to-disk Rename 'emit-files-to-disk.ts' to 'disk-files.ts' and introduce 'deleteFilesFromDisk' to delete removed output files with bounded concurrency. --- .../build/src/builders/application/index.ts | 12 +-- .../builders/library/pipeline/build-action.ts | 2 +- packages/angular/build/src/private.ts | 2 +- .../{emit-files-to-disk.ts => disk-files.ts} | 18 ++++- .../build/src/utils/disk-files_spec.ts | 75 +++++++++++++++++++ .../src/utils/emit-files-to-disk_spec.ts | 53 ------------- .../angular/build/src/utils/test-files.ts | 2 +- 7 files changed, 97 insertions(+), 67 deletions(-) rename packages/angular/build/src/utils/{emit-files-to-disk.ts => disk-files.ts} (79%) create mode 100644 packages/angular/build/src/utils/disk-files_spec.ts delete mode 100644 packages/angular/build/src/utils/emit-files-to-disk_spec.ts diff --git a/packages/angular/build/src/builders/application/index.ts b/packages/angular/build/src/builders/application/index.ts index f1b16a27e394..db2cee237896 100644 --- a/packages/angular/build/src/builders/application/index.ts +++ b/packages/angular/build/src/builders/application/index.ts @@ -8,13 +8,12 @@ import { Builder, BuilderContext, BuilderOutput, createBuilder } from '@angular-devkit/architect'; import assert from 'node:assert'; -import fs from 'node:fs/promises'; import path from 'node:path'; import { BuildOutputFileType } from '../../tools/esbuild/bundler-files'; import { createJsonBuildManifest } from '../../tools/esbuild/utils'; import { colors as ansiColors } from '../../utils/color'; import { deleteOutputDir } from '../../utils/delete-output-dir'; -import { emitFilesToDisk } from '../../utils/emit-files-to-disk'; +import { deleteFilesFromDisk, emitFilesToDisk } from '../../utils/disk-files'; import { bazelEsbuildPluginPath, useJSONBuildLogs } from '../../utils/environment-options'; import { isSubDirectory } from '../../utils/path'; import { purgeStaleBuildCache } from '../../utils/purge-cache'; @@ -215,13 +214,10 @@ export async function* buildApplication( // Delete any removed files if incremental if (result.kind === ResultKind.Incremental && result.removed?.length) { try { - await Promise.all( - result.removed.map((file) => { - const fullFilePath = generateFullPath(file.path, file.type, outputOptions); - - return fs.rm(fullFilePath, { force: true, maxRetries: 3 }); - }), + const filesToDelete = result.removed.map((file) => + generateFullPath(file.path, file.type, outputOptions), ); + await deleteFilesFromDisk(filesToDelete); } catch (error) { context.logger.error(error instanceof Error ? error.message : String(error)); yield { success: false }; diff --git a/packages/angular/build/src/builders/library/pipeline/build-action.ts b/packages/angular/build/src/builders/library/pipeline/build-action.ts index 6d40f5fe4383..acdc69c61bff 100644 --- a/packages/angular/build/src/builders/library/pipeline/build-action.ts +++ b/packages/angular/build/src/builders/library/pipeline/build-action.ts @@ -9,7 +9,7 @@ import type { BuilderContext } from '@angular-devkit/architect'; import path from 'node:path'; import type { ComponentStylesheetBundler } from '../../../tools/esbuild/angular/component-stylesheets'; -import { emitFilesToDisk } from '../../../utils/emit-files-to-disk'; +import { emitFilesToDisk } from '../../../utils/disk-files'; import { assertIsError } from '../../../utils/error'; import { toPosixPath } from '../../../utils/path'; import type { NormalizedLibraryOptions, SingleBuildState } from '../types'; diff --git a/packages/angular/build/src/private.ts b/packages/angular/build/src/private.ts index 6f98e4f8f0e9..e95ad26af3fc 100644 --- a/packages/angular/build/src/private.ts +++ b/packages/angular/build/src/private.ts @@ -72,7 +72,7 @@ export { ComponentStylesheetBundler } from './tools/esbuild/angular/component-st export * from './utils/bundle-calculator'; export { checkPort } from './utils/check-port'; export { deleteOutputDir } from './utils/delete-output-dir'; -export { emitFilesToDisk } from './utils/emit-files-to-disk'; +export { emitFilesToDisk } from './utils/disk-files'; export { type I18nOptions, createI18nOptions, loadTranslations } from './utils/i18n-options'; export { IndexHtmlGenerator, diff --git a/packages/angular/build/src/utils/emit-files-to-disk.ts b/packages/angular/build/src/utils/disk-files.ts similarity index 79% rename from packages/angular/build/src/utils/emit-files-to-disk.ts rename to packages/angular/build/src/utils/disk-files.ts index b6df74088451..dbbe34ee919e 100644 --- a/packages/angular/build/src/utils/emit-files-to-disk.ts +++ b/packages/angular/build/src/utils/disk-files.ts @@ -6,14 +6,14 @@ * found in the LICENSE file at https://angular.dev/license */ -import { constants, cp, mkdir, writeFile } from 'node:fs/promises'; +import { constants, cp, mkdir, rm, writeFile } from 'node:fs/promises'; import { dirname } from 'node:path'; import { runConcurrent } from './concurrency'; /** * Maximum number of concurrent file system write/copy operations to avoid open file descriptor exhaustion. */ -const MAX_CONCURRENT_WRITES = 64; +const MAX_CONCURRENT_OPS = 64; /** * Represents a file that can be emitted to disk from memory or copied from an existing path on disk. @@ -38,7 +38,7 @@ export async function emitFilesToDisk( const directoryCreationPromises = new Map>(); - await runConcurrent(files, MAX_CONCURRENT_WRITES, async (file) => { + await runConcurrent(files, MAX_CONCURRENT_OPS, async (file) => { const fullFilePath = resolveDestinationPath(file); if (!fullFilePath) { return; @@ -69,3 +69,15 @@ export async function emitFilesToDisk( }); }); } + +/** + * Deletes a collection of files from disk with bounded concurrency. + * @param files The collection of files to delete. + */ +export async function deleteFilesFromDisk(files: readonly string[]): Promise { + if (files.length === 0) { + return; + } + + await runConcurrent(files, MAX_CONCURRENT_OPS, (file) => rm(file, { force: true })); +} diff --git a/packages/angular/build/src/utils/disk-files_spec.ts b/packages/angular/build/src/utils/disk-files_spec.ts new file mode 100644 index 000000000000..4a9422bd4373 --- /dev/null +++ b/packages/angular/build/src/utils/disk-files_spec.ts @@ -0,0 +1,75 @@ +/** + * @license + * Copyright Google LLC All Rights Reserved. + * + * Use of this source code is governed by an MIT-style license that can be + * found in the LICENSE file at https://angular.dev/license + */ + +import assert from 'node:assert'; +import { existsSync } from 'node:fs'; +import { mkdtemp, readFile, rm, writeFile } from 'node:fs/promises'; +import { join } from 'node:path'; +import { type EmittableFile, deleteFilesFromDisk, emitFilesToDisk } from './disk-files'; + +describe('disk-files', () => { + let tempRoot: string; + + beforeEach(async () => { + const baseTmpDir = process.env['TEST_TMPDIR']; + assert(baseTmpDir, 'TEST_TMPDIR is not set'); + tempRoot = await mkdtemp(join(baseTmpDir, 'angular-cli-disk-files-test-')); + }); + + afterEach(async () => { + if (tempRoot) { + await rm(tempRoot, { recursive: true, force: true }); + } + }); + + describe('emitFilesToDisk', () => { + it('should write memory files and copy disk files while creating nested directories', async () => { + const sourceFile = join(tempRoot, 'source-asset.txt'); + await writeFile(sourceFile, 'from-disk'); + + const files: (EmittableFile & { path: string })[] = [ + { + origin: 'memory', + path: 'nested/a/mem1.txt', + contents: new TextEncoder().encode('mem-1'), + }, + { origin: 'memory', path: 'nested/a/mem2.txt', contents: 'mem-2' }, + { origin: 'disk', path: 'nested/b/disk1.txt', source: sourceFile }, + { origin: 'disk', path: 'nested/c/disk2.txt', source: sourceFile }, + { origin: 'memory', path: 'skipped/file.txt', contents: 'should-not-exist' }, + ]; + + const outDir = join(tempRoot, 'out'); + await emitFilesToDisk(files, (file) => + file.path.startsWith('skipped/') ? undefined : join(outDir, file.path), + ); + + expect(await readFile(join(outDir, 'nested/a/mem1.txt'), 'utf-8')).toBe('mem-1'); + expect(await readFile(join(outDir, 'nested/a/mem2.txt'), 'utf-8')).toBe('mem-2'); + expect(await readFile(join(outDir, 'nested/b/disk1.txt'), 'utf-8')).toBe('from-disk'); + expect(await readFile(join(outDir, 'nested/c/disk2.txt'), 'utf-8')).toBe('from-disk'); + expect(existsSync(join(outDir, 'skipped/file.txt'))).toBeFalse(); + }); + }); + + describe('deleteFilesFromDisk', () => { + it('should delete existing files and ignore non-existent files', async () => { + const fileA = join(tempRoot, 'a.txt'); + const fileB = join(tempRoot, 'b.txt'); + const nonExistent = join(tempRoot, 'missing.txt'); + + await writeFile(fileA, 'a'); + await writeFile(fileB, 'b'); + + await deleteFilesFromDisk([fileA, nonExistent]); + + expect(existsSync(fileA)).toBeFalse(); + expect(existsSync(fileB)).toBeTrue(); + }); + }); +}); diff --git a/packages/angular/build/src/utils/emit-files-to-disk_spec.ts b/packages/angular/build/src/utils/emit-files-to-disk_spec.ts deleted file mode 100644 index 028653028b43..000000000000 --- a/packages/angular/build/src/utils/emit-files-to-disk_spec.ts +++ /dev/null @@ -1,53 +0,0 @@ -/** - * @license - * Copyright Google LLC All Rights Reserved. - * - * Use of this source code is governed by an MIT-style license that can be - * found in the LICENSE file at https://angular.dev/license - */ - -import assert from 'node:assert'; -import { existsSync } from 'node:fs'; -import { mkdtemp, readFile, rm, writeFile } from 'node:fs/promises'; -import { join } from 'node:path'; -import { type EmittableFile, emitFilesToDisk } from './emit-files-to-disk'; - -describe('emitFilesToDisk', () => { - let tempRoot: string; - - beforeEach(async () => { - const baseTmpDir = process.env['TEST_TMPDIR']; - assert(baseTmpDir, 'TEST_TMPDIR is not set'); - tempRoot = await mkdtemp(join(baseTmpDir, 'angular-cli-emit-files-test-')); - }); - - afterEach(async () => { - if (tempRoot) { - await rm(tempRoot, { recursive: true, force: true }); - } - }); - - it('should write memory files and copy disk files while creating nested directories', async () => { - const sourceFile = join(tempRoot, 'source-asset.txt'); - await writeFile(sourceFile, 'from-disk'); - - const files: (EmittableFile & { path: string })[] = [ - { origin: 'memory', path: 'nested/a/mem1.txt', contents: new TextEncoder().encode('mem-1') }, - { origin: 'memory', path: 'nested/a/mem2.txt', contents: 'mem-2' }, - { origin: 'disk', path: 'nested/b/disk1.txt', source: sourceFile }, - { origin: 'disk', path: 'nested/c/disk2.txt', source: sourceFile }, - { origin: 'memory', path: 'skipped/file.txt', contents: 'should-not-exist' }, - ]; - - const outDir = join(tempRoot, 'out'); - await emitFilesToDisk(files, (file) => - file.path.startsWith('skipped/') ? undefined : join(outDir, file.path), - ); - - expect(await readFile(join(outDir, 'nested/a/mem1.txt'), 'utf-8')).toBe('mem-1'); - expect(await readFile(join(outDir, 'nested/a/mem2.txt'), 'utf-8')).toBe('mem-2'); - expect(await readFile(join(outDir, 'nested/b/disk1.txt'), 'utf-8')).toBe('from-disk'); - expect(await readFile(join(outDir, 'nested/c/disk2.txt'), 'utf-8')).toBe('from-disk'); - expect(existsSync(join(outDir, 'skipped/file.txt'))).toBeFalse(); - }); -}); diff --git a/packages/angular/build/src/utils/test-files.ts b/packages/angular/build/src/utils/test-files.ts index db480686b66a..763c762ac19f 100644 --- a/packages/angular/build/src/utils/test-files.ts +++ b/packages/angular/build/src/utils/test-files.ts @@ -9,7 +9,7 @@ import path from 'node:path'; import { ResultFile } from '../builders/application/results'; import { BuildOutputFileType } from '../tools/esbuild/bundler-files'; -import { emitFilesToDisk } from './emit-files-to-disk'; +import { emitFilesToDisk } from './disk-files'; /** * Writes a collection of build result files to a specified directory. From 01afbf418cf6a7688f3f131988eeba3cdac2bde4 Mon Sep 17 00:00:00 2001 From: Julien Venet Date: Tue, 13 Oct 2026 13:22:08 -0400 Subject: [PATCH 614/787] fix(@angular/build): sort discovered unit-test files for deterministic builds --- .../src/builders/unit-test/test-discovery.ts | 6 ++-- .../builders/unit-test/test-discovery_spec.ts | 34 ++++++++++++++++++- 2 files changed, 37 insertions(+), 3 deletions(-) diff --git a/packages/angular/build/src/builders/unit-test/test-discovery.ts b/packages/angular/build/src/builders/unit-test/test-discovery.ts index f2fc8c221646..2452675a9abf 100644 --- a/packages/angular/build/src/builders/unit-test/test-discovery.ts +++ b/packages/angular/build/src/builders/unit-test/test-discovery.ts @@ -74,8 +74,10 @@ export async function findTests( } } - // 3. Combine and de-duplicate results - return [...resolvedTestFiles]; + // 3. Combine, de-duplicate and sort the results. The glob crawls directories asynchronously and + // returns matches in a varying order; the order feeds the build entry points, so an unsorted list + // makes the output (chunk contents and names) differ between two builds of the same sources. + return [...resolvedTestFiles].sort(); } interface TestEntrypointsOptions { diff --git a/packages/angular/build/src/builders/unit-test/test-discovery_spec.ts b/packages/angular/build/src/builders/unit-test/test-discovery_spec.ts index 764924d9552b..91c33fd0120a 100644 --- a/packages/angular/build/src/builders/unit-test/test-discovery_spec.ts +++ b/packages/angular/build/src/builders/unit-test/test-discovery_spec.ts @@ -6,8 +6,40 @@ * found in the LICENSE file at https://angular.dev/license */ +import assert from 'node:assert'; +import { promises as fs } from 'node:fs'; +import { join } from 'node:path'; import { initializeHash } from '../../utils/hash'; -import { generateNameFromPath, getTestEntrypoints } from './test-discovery'; +import { toPosixPath } from '../../utils/path'; +import { findTests, generateNameFromPath, getTestEntrypoints } from './test-discovery'; + +describe('findTests', () => { + let projectSourceRoot: string; + + beforeEach(async () => { + const baseTmpDir = process.env['TEST_TMPDIR']; + assert(baseTmpDir, 'TEST_TMPDIR is not set'); + projectSourceRoot = await fs.mkdtemp(join(baseTmpDir, 'angular-find-tests-')); + }); + + afterEach(async () => { + await fs.rm(projectSourceRoot, { recursive: true, force: true }); + }); + + it('should return the test files sorted, regardless of the crawl order', async () => { + const files = ['z/z.spec.ts', 'a/b/c.spec.ts', 'm.spec.ts', 'a/a.spec.ts', 'b/x/y.spec.ts']; + for (const file of files) { + const path = join(projectSourceRoot, file); + await fs.mkdir(join(path, '..'), { recursive: true }); + await fs.writeFile(path, ''); + } + + const result = await findTests(['**/*.spec.ts'], [], projectSourceRoot, projectSourceRoot); + + const expected = files.map((file) => toPosixPath(join(projectSourceRoot, file))).sort(); + expect(result).toEqual(expected); + }); +}); describe('getTestEntrypoints', () => { beforeAll(async () => { From b39a5fcdac288e317f3b00468c09173a1d306f98 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Adrian=20Turbi=C5=84ski?= Date: Tue, 13 Oct 2026 20:01:06 +0000 Subject: [PATCH 615/787] fix(@angular-devkit/schematics): avoid stack overflow when chaining many rules The chain rule nested one observable per rule, so subscribing to a chain of a few thousand rules exceeded the call stack and the result never settled. Each rule result is now awaited before the next rule runs. --- .../angular_devkit/schematics/src/rules/base.ts | 10 +++++----- .../schematics/src/rules/base_spec.ts | 13 +++++++++++++ 2 files changed, 18 insertions(+), 5 deletions(-) diff --git a/packages/angular_devkit/schematics/src/rules/base.ts b/packages/angular_devkit/schematics/src/rules/base.ts index ec380f2aeb0d..1f5d3023c28e 100644 --- a/packages/angular_devkit/schematics/src/rules/base.ts +++ b/packages/angular_devkit/schematics/src/rules/base.ts @@ -6,7 +6,7 @@ * found in the LICENSE file at https://angular.dev/license */ -import { Observable, concat, map, mapTo, toArray } from 'rxjs'; +import { concat, lastValueFrom, map, mapTo, toArray } from 'rxjs'; import { FileOperator, Rule, Source } from '../engine/interface'; import { SchematicsException } from '../exception/exception'; import { FilterHostTree, HostTree } from '../tree/host-tree'; @@ -34,18 +34,18 @@ export function empty(): Source { */ export function chain(rules: Iterable | AsyncIterable): Rule { return async (initialTree, context) => { - let intermediateTree: Observable | undefined; + let intermediateTree = initialTree; if (Symbol.asyncIterator in rules) { for await (const rule of rules) { - intermediateTree = callRule(rule, intermediateTree ?? initialTree, context); + intermediateTree = await lastValueFrom(callRule(rule, intermediateTree, context)); } } else { for (const rule of rules) { - intermediateTree = callRule(rule, intermediateTree ?? initialTree, context); + intermediateTree = await lastValueFrom(callRule(rule, intermediateTree, context)); } } - return () => intermediateTree; + return intermediateTree; }; } diff --git a/packages/angular_devkit/schematics/src/rules/base_spec.ts b/packages/angular_devkit/schematics/src/rules/base_spec.ts index b3578ca8c00a..6eb299ef9890 100644 --- a/packages/angular_devkit/schematics/src/rules/base_spec.ts +++ b/packages/angular_devkit/schematics/src/rules/base_spec.ts @@ -140,6 +140,19 @@ describe('chain', () => { expect(rulesCalled[2]).toBe(tree2); expect(result).toBe(tree3); }); + + it('works with a large number of rules', async () => { + const tree0 = empty(); + let callCount = 0; + const rules: Rule[] = Array.from({ length: 20_000 }, () => () => { + callCount++; + }); + + const result = await lastValueFrom(callRule(chain(rules), tree0, context)); + + expect(result).toBe(tree0); + expect(callCount).toBe(20_000); + }); }); describe('apply', () => { From 7714a8537589afc6180443cc36acd5149a459c57 Mon Sep 17 00:00:00 2001 From: Charles Lyding <19598772+clydin@users.noreply.github.com> Date: Tue, 13 Oct 2026 09:44:41 -0400 Subject: [PATCH 616/787] fix(@angular/build): resolve unimported NgModule scopes when filtering unit-test files When `rootFiles` overrides are provided (such as during `unit-test` runs), the initial TypeScript program is restricted to those entry points and their transitive imports. If a test imports a non-standalone `@Component` directly without importing its declaring `@NgModule`, the `NgModule` may be omitted from the program and leave the component without its compilation scope. Preserve the full `tsconfig` root file set as `fallbackRootNames` for application builds when `rootFiles` is a subset of the `tsconfig` files. If AOT analysis detects a non-standalone component lacking an owning `NgModule` scope (`getOwningNgModule(component) === null`) and additional uncompiled `tsconfig` files exist, recreate and re-analyze the Angular program with the full root file set so all `NgModule` declarations can be discovered. --- .../unit-test/tests/options/include_spec.ts | 167 ++++++++++++++++++ .../compilation/angular-compilation_spec.ts | 79 ++++++++- .../angular/compilation/aot-compilation.ts | 102 ++++++++++- .../compilation/typescript-compilation.ts | 25 ++- 4 files changed, 364 insertions(+), 9 deletions(-) diff --git a/packages/angular/build/src/builders/unit-test/tests/options/include_spec.ts b/packages/angular/build/src/builders/unit-test/tests/options/include_spec.ts index d3d4e19a30f9..4ba7c9eaa051 100644 --- a/packages/angular/build/src/builders/unit-test/tests/options/include_spec.ts +++ b/packages/angular/build/src/builders/unit-test/tests/options/include_spec.ts @@ -110,5 +110,172 @@ describeBuilder(execute, UNIT_TEST_BUILDER_INFO, (harness) => { const { result } = await harness.executeOnce(); expect(result?.success).toBeTrue(); }); + + it('should not compile unimported application files when testing standalone code', async () => { + await harness.writeFiles({ + 'src/tsconfig.spec.json': JSON.stringify({ + extends: '../tsconfig.json', + compilerOptions: { + outDir: '../out-tsc/spec', + types: ['jasmine', '@angular/localize'], + }, + files: ['polyfills.ts'], + include: ['**/*.ts', '**/*.d.ts'], + }), + 'src/app/services/test.service.spec.ts': ` + describe('TestService', () => { + it('should succeed', () => { + expect(true).toBe(true); + }); + });`, + 'src/app/unused-broken.ts': ` + // This unimported file has a TypeScript error and should not be compiled for standalone tests + export const invalidNumber: number = 'not a number'; + `, + }); + + harness.useTarget('test', { + ...BASE_OPTIONS, + include: ['src/app/services/test.service.spec.ts'], + }); + + const { result } = await harness.executeOnce(); + expect(result?.success).toBeTrue(); + }); + + it('should resolve NgModule scope when testing a non-standalone component without importing the NgModule', async () => { + await harness.writeFiles({ + 'src/tsconfig.spec.json': JSON.stringify({ + extends: '../tsconfig.json', + compilerOptions: { + outDir: '../out-tsc/spec', + types: ['jasmine', '@angular/localize'], + }, + files: ['polyfills.ts'], + include: ['**/*.ts', '**/*.d.ts'], + }), + 'src/app/app.ts': ` + import { Component } from '@angular/core'; + + @Component({ + selector: 'app-root', + template: '

Hello, {{ title }}

', + standalone: false, + }) + export class App { + title = 'test'; + } + `, + 'src/app/app-module.ts': ` + import { NgModule } from '@angular/core'; + import { BrowserModule } from '@angular/platform-browser'; + import { RouterModule } from '@angular/router'; + import { App } from './app'; + + @NgModule({ + declarations: [App], + imports: [BrowserModule, RouterModule.forRoot([])], + bootstrap: [App], + }) + export class AppModule {} + `, + 'src/app/app.spec.ts': ` + import { TestBed } from '@angular/core/testing'; + import { RouterModule } from '@angular/router'; + import { App } from './app'; + + describe('App', () => { + beforeEach(async () => { + await TestBed.configureTestingModule({ + imports: [RouterModule.forRoot([])], + declarations: [App], + }).compileComponents(); + }); + + it('should create the app', () => { + const fixture = TestBed.createComponent(App); + expect(fixture.componentInstance).toBeTruthy(); + }); + }); + `, + }); + + harness.useTarget('test', { + ...BASE_OPTIONS, + include: ['src/app/app.spec.ts'], + }); + + const { result } = await harness.executeOnce(); + expect(result?.success).toBeTrue(); + }); + + it('should not compile unimported files when a non-standalone component NgModule is imported by the test', async () => { + await harness.writeFiles({ + 'src/tsconfig.spec.json': JSON.stringify({ + extends: '../tsconfig.json', + compilerOptions: { + outDir: '../out-tsc/spec', + types: ['jasmine', '@angular/localize'], + }, + files: ['polyfills.ts'], + include: ['**/*.ts', '**/*.d.ts'], + }), + 'src/app/app.ts': ` + import { Component } from '@angular/core'; + + @Component({ + selector: 'app-root', + template: '

Hello, {{ title }}

', + standalone: false, + }) + export class App { + title = 'test'; + } + `, + 'src/app/app-module.ts': ` + import { NgModule } from '@angular/core'; + import { BrowserModule } from '@angular/platform-browser'; + import { RouterModule } from '@angular/router'; + import { App } from './app'; + + @NgModule({ + declarations: [App], + imports: [BrowserModule, RouterModule.forRoot([])], + bootstrap: [App], + }) + export class AppModule {} + `, + 'src/app/app.spec.ts': ` + import { TestBed } from '@angular/core/testing'; + import { App } from './app'; + import { AppModule } from './app-module'; + + describe('App', () => { + beforeEach(async () => { + await TestBed.configureTestingModule({ + imports: [AppModule], + }).compileComponents(); + }); + + it('should create the app', () => { + const fixture = TestBed.createComponent(App); + expect(fixture.componentInstance).toBeTruthy(); + }); + }); + `, + 'src/app/unused-broken.ts': ` + // This unimported file has a TypeScript error and should not be compiled when AppModule is already imported + export const invalidNumber: number = 'not a number'; + `, + }); + + harness.useTarget('test', { + ...BASE_OPTIONS, + include: ['src/app/app.spec.ts'], + }); + + const { result } = await harness.executeOnce(); + expect(result?.success).toBeTrue(); + }); }); }); diff --git a/packages/angular/build/src/tools/angular/compilation/angular-compilation_spec.ts b/packages/angular/build/src/tools/angular/compilation/angular-compilation_spec.ts index 2d001dfeff7c..3c09b87f69d7 100644 --- a/packages/angular/build/src/tools/angular/compilation/angular-compilation_spec.ts +++ b/packages/angular/build/src/tools/angular/compilation/angular-compilation_spec.ts @@ -91,8 +91,12 @@ describe('AngularCompilation', () => { return this.sourceFiles; } - public async testLoadConfiguration(tsconfig: string, overrides?: CompilerOptionOverrides) { - return this.loadConfiguration(tsconfig, overrides); + public async testLoadConfiguration( + tsconfig: string, + overrides?: CompilerOptionOverrides, + buildType?: 'application' | 'library', + ) { + return this.loadConfiguration(tsconfig, overrides, buildType); } } @@ -162,12 +166,83 @@ describe('AngularCompilation', () => { jasmine.any(Map), ); expect(result.rootNames).toEqual(['/src/main.ts']); + expect(result.fallbackRootNames).toBeUndefined(); expect(result.compilerOptions.target).toBe(ts.ScriptTarget.ES2022); expect(result.compilerOptions.inlineSources).toBe(true); expect(result.warnings.length).toBeGreaterThan(0); expect(result.tsConfigFiles).toEqual(['tsconfig.json']); }); + it('filters rootNames to rootFiles while retaining ambient declaration files and setting fallbackRootNames', async () => { + const compilation = new MockTypeScriptCompilation(); + const mockReadConfig = jasmine.createSpy('readConfiguration').and.returnValue({ + options: { target: ts.ScriptTarget.ES2022 }, + rootNames: [ + '/src/app/included.spec.ts', + '/src/app/excluded.spec.ts', + '/src/app/app-module.ts', + '/src/env.d.ts', + '/src/types.d.mts', + '/src/legacy.d.cts', + ], + errors: [], + }); + spyOn(TypeScriptCompilation, 'loadCompilerCli').and.resolveTo({ + readConfiguration: mockReadConfig, + } as unknown as typeof import('@angular/compiler-cli')); + + const result = await compilation.testLoadConfiguration('tsconfig.spec.json', { + rootFiles: ['/src/app/included.spec.ts'], + }); + + expect(result.rootNames).toEqual([ + '/src/app/included.spec.ts', + '/src/env.d.ts', + '/src/types.d.mts', + '/src/legacy.d.cts', + ]); + expect(result.fallbackRootNames).toEqual([ + '/src/app/included.spec.ts', + '/src/app/excluded.spec.ts', + '/src/app/app-module.ts', + '/src/env.d.ts', + '/src/types.d.mts', + '/src/legacy.d.cts', + ]); + }); + + it('omits fallbackRootNames when buildType is "library" or when rootFiles covers all tsconfig files', async () => { + const compilation = new MockTypeScriptCompilation(); + const mockReadConfig = jasmine.createSpy('readConfiguration').and.returnValue({ + options: { target: ts.ScriptTarget.ES2022 }, + rootNames: ['/src/public-api.ts', '/src/internal.ts', '/src/env.d.ts'], + errors: [], + }); + spyOn(TypeScriptCompilation, 'loadCompilerCli').and.resolveTo({ + readConfiguration: mockReadConfig, + } as unknown as typeof import('@angular/compiler-cli')); + + const libraryResult = await compilation.testLoadConfiguration( + 'tsconfig.lib.json', + { rootFiles: ['/src/public-api.ts'] }, + 'library', + ); + expect(libraryResult.rootNames).toEqual(['/src/public-api.ts', '/src/env.d.ts']); + expect(libraryResult.fallbackRootNames).toBeUndefined(); + + const fullSetResult = await compilation.testLoadConfiguration( + 'tsconfig.app.json', + { rootFiles: ['/src/public-api.ts', '/src/internal.ts'] }, + 'application', + ); + expect(fullSetResult.rootNames).toEqual([ + '/src/public-api.ts', + '/src/internal.ts', + '/src/env.d.ts', + ]); + expect(fullSetResult.fallbackRootNames).toBeUndefined(); + }); + it('passes extendedConfigCache to readConfiguration and invalidates entries on config change', async () => { const compilation = new MockTypeScriptCompilation(); let passedCache: Map | undefined; diff --git a/packages/angular/build/src/tools/angular/compilation/aot-compilation.ts b/packages/angular/build/src/tools/angular/compilation/aot-compilation.ts index 749962e3def6..4ca1480f646c 100644 --- a/packages/angular/build/src/tools/angular/compilation/aot-compilation.ts +++ b/packages/angular/build/src/tools/angular/compilation/aot-compilation.ts @@ -72,6 +72,7 @@ class AngularCompilationState { public readonly useTypeScriptTranspilation: boolean, public readonly diagnosticCache = new WeakMap(), public readonly filesWithoutDtsSignature = new Set(), + public readonly useFallbackRootNames = false, ) {} get angularCompiler() { @@ -100,6 +101,7 @@ export class AotCompilation extends TypeScriptCompilation { const { compilerOptions, rootNames, + fallbackRootNames, errors: configurationDiagnostics, warnings, tsConfigFiles, @@ -165,13 +167,48 @@ export class AotCompilation extends TypeScriptCompilation { this.sourceFiles, ); + // If a previous watch rebuild already fell back to the full tsconfig root file set, + // start directly with fallbackRootNames to avoid repeating the two-step check. + let useFallbackRootNames = this.#state?.useFallbackRootNames ?? false; + // Create the Angular specific program that contains the Angular compiler - const angularProgram = profileSync( + let angularProgram = profileSync( 'NG_CREATE_PROGRAM', - () => new NgtscProgram(rootNames, compilerOptions, host, this.#state?.angularProgram), + () => + new NgtscProgram( + (useFallbackRootNames && fallbackRootNames) || rootNames, + compilerOptions, + host, + this.#state?.angularProgram, + ), ); - const angularCompiler = angularProgram.compiler; - const angularTypeScriptProgram = angularProgram.getTsProgram(); + let angularCompiler = angularProgram.compiler; + + await profileAsync('NG_ANALYZE_PROGRAM', () => angularCompiler.analyzeAsync()); + + let angularTypeScriptProgram = angularProgram.getTsProgram(); + + // When rootFiles filtering is active and a non-standalone component without a resolved + // NgModule scope is encountered, its declaring NgModule may not be directly imported by + // the test entry points. Fall back to the full tsconfig root file set if it contains + // additional uncompiled files so the Angular compiler can discover all NgModules and + // resolve component compilation scopes. + if ( + !useFallbackRootNames && + fallbackRootNames?.some((file) => !angularTypeScriptProgram.getSourceFile(file)) && + hasUnscopedComponent(angularCompiler) + ) { + useFallbackRootNames = true; + angularProgram = profileSync( + 'NG_CREATE_PROGRAM_FALLBACK', + () => new NgtscProgram(fallbackRootNames, compilerOptions, host, angularProgram), + ); + angularCompiler = angularProgram.compiler; + + await profileAsync('NG_ANALYZE_PROGRAM_FALLBACK', () => angularCompiler.analyzeAsync()); + angularTypeScriptProgram = angularProgram.getTsProgram(); + } + ensureSourceFileVersions(angularTypeScriptProgram); let oldProgram = this.#state?.typeScriptProgram; @@ -200,8 +237,6 @@ export class AotCompilation extends TypeScriptCompilation { } } - await profileAsync('NG_ANALYZE_PROGRAM', () => angularCompiler.analyzeAsync()); - let templateUpdates; if (useHmr && hostOptions.modifiedFiles && this.#state) { const componentNodes = collectHmrCandidates( @@ -315,6 +350,7 @@ export class AotCompilation extends TypeScriptCompilation { useTypeScriptTranspilation, this.#state?.diagnosticCache, filesWithoutDtsSignature, + useFallbackRootNames, ); return { @@ -810,3 +846,57 @@ function populatePreviousDtsSignatures( compilerOptions.noEmitOnError = prevNoEmitOnError; } } + +/** + * Checks whether the analyzed Angular program contains any non-standalone `@Component` + * declarations in user source files that lack an owning `NgModule` scope. + */ +function hasUnscopedComponent(angularCompiler: ng.NgCompiler): boolean { + // `incrementalCompilation.state` is typed as the `IncrementalState` union + // (`AnalyzedIncrementalState | DeltaIncrementalState | FreshIncrementalState`), where only + // `AnalyzedIncrementalState` (populated once `analyzeAsync()` completes) contains + // `priorAnalysis`. Because the `IncrementalStateKind` discriminant enum is not re-exported + // from `@angular/compiler-cli`, narrow the union via `'priorAnalysis' in state`. + const state = angularCompiler.incrementalCompilation.state; + if (!('priorAnalysis' in state)) { + return false; + } + + let templateTypeChecker: ReturnType | undefined; + + for (const [sourceFile, records] of state.priorAnalysis) { + if (records.length === 0 || angularCompiler.ignoreForEmit.has(sourceFile)) { + continue; + } + + for (const { node } of records) { + if (!ts.isClassDeclaration(node)) { + continue; + } + + const meta = angularCompiler.getMeta(node); + if (meta && 'isComponent' in meta && meta.isComponent && !meta.isStandalone) { + if (!templateTypeChecker) { + // `NgtscProgram` initializes `NgCompiler` with `enableTemplateTypeChecker = false`, which + // guards the public `getTemplateTypeChecker()` getter. Temporarily enable the flag after + // `analyzeAsync()` has already constructed `TemplateTypeCheckerImpl` so we can query + // `getOwningNgModule()` without altering `typeCheckingConfig.enableTemplateTypeChecker`. + const compiler = angularCompiler as { enableTemplateTypeChecker: boolean }; + const previous = compiler.enableTemplateTypeChecker; + try { + compiler.enableTemplateTypeChecker = true; + templateTypeChecker = angularCompiler.getTemplateTypeChecker(); + } finally { + compiler.enableTemplateTypeChecker = previous; + } + } + + if (templateTypeChecker.getOwningNgModule(node) === null) { + return true; + } + } + } + } + + return false; +} diff --git a/packages/angular/build/src/tools/angular/compilation/typescript-compilation.ts b/packages/angular/build/src/tools/angular/compilation/typescript-compilation.ts index eba7a10a5cb4..6601500fbcc9 100644 --- a/packages/angular/build/src/tools/angular/compilation/typescript-compilation.ts +++ b/packages/angular/build/src/tools/angular/compilation/typescript-compilation.ts @@ -18,6 +18,7 @@ import { convertTypeScriptDiagnostic } from './diagnostics'; export interface TransformedConfiguration { compilerOptions: ng.CompilerOptions; rootNames: string[]; + fallbackRootNames?: string[]; errors: ts.Diagnostic[]; warnings: PartialMessage[]; tsConfigFiles: readonly string[]; @@ -75,16 +76,37 @@ export abstract class TypeScriptCompilation extends AngularCompilation { const tsConfigFiles = [toPosixPath(tsconfig), ...this.#extendedConfigCache.keys()]; let rootNames = originalRootNames; + let fallbackRootNames: string[] | undefined; if (compilerOptionOverrides?.rootFiles?.length) { + // When explicit rootFiles are provided (e.g., filtered unit test entry points), restrict + // the initial program to only those entry points so TypeScript resolves only their + // transitive imports and skips unrelated or non-included test/application files. const rootFilesSet = new Set( compilerOptionOverrides.rootFiles.map((file) => canonicalizePath(toPosixPath(file))), ); + const fallbackFilesSet = new Set(rootFilesSet); for (const file of originalRootNames) { + const canonicalFile = canonicalizePath(toPosixPath(file)); + // Ambient declaration files (.d.ts) are not imported directly, so they must always be + // retained from the tsconfig to preserve global type definitions. if (/\.d\.[cm]?ts$/i.test(file)) { - rootFilesSet.add(canonicalizePath(toPosixPath(file))); + rootFilesSet.add(canonicalFile); } + fallbackFilesSet.add(canonicalFile); } rootNames = [...rootFilesSet]; + // For application builds (including unit tests), preserve the full set of tsconfig root + // files as a fallback in case the AOT compilation encounters a non-standalone component + // whose declaring NgModule is not directly imported by the entry points. Note that when a + // test tsconfig uses broad globs (e.g., `src/**/*.ts`), this fallback set will also include + // non-included spec files; this is an acceptable trade-off to keep compilation agnostic of + // test-file naming conventions and only occurs for legacy non-standalone components lacking + // explicit NgModule imports. Library builds are excluded because all public NgModules must + // be reachable from the library entry points and should never resolve compilation scope from + // unexported tsconfig files. + if (buildType === 'application' && fallbackFilesSet.size > rootFilesSet.size) { + fallbackRootNames = [...fallbackFilesSet]; + } } const { compilerOptions, warnings } = transformCompilerOptions( @@ -98,6 +120,7 @@ export abstract class TypeScriptCompilation extends AngularCompilation { return { compilerOptions, rootNames, + fallbackRootNames, errors, warnings, tsConfigFiles, From f479c11d4deda6b5aad1c9adaa89fb6a547ebc12 Mon Sep 17 00:00:00 2001 From: Angular Robot Date: Wed, 14 Oct 2026 15:55:57 +0000 Subject: [PATCH 617/787] build: update cross-repo angular dependencies See associated pull request for more information. --- package.json | 4 ++-- pnpm-lock.yaml | 24 +++++++++++----------- tests/e2e/ng-snapshot/package.json | 32 +++++++++++++++--------------- 3 files changed, 30 insertions(+), 30 deletions(-) diff --git a/package.json b/package.json index c2efa7133c4f..6a7407853c21 100644 --- a/package.json +++ b/package.json @@ -48,13 +48,13 @@ }, "devDependencies": { "@angular/animations": "22.3.0-next.1", - "@angular/cdk": "22.3.0-next.1", + "@angular/cdk": "22.3.0-next.2", "@angular/common": "22.3.0-next.1", "@angular/compiler": "22.3.0-next.1", "@angular/core": "22.3.0-next.1", "@angular/forms": "22.3.0-next.1", "@angular/localize": "22.3.0-next.1", - "@angular/material": "22.3.0-next.1", + "@angular/material": "22.3.0-next.2", "@angular/ng-dev": "https://github.com/angular/dev-infra-private-ng-dev-builds.git#fa4308affb4a0dde34ebc95196b58550752485a2", "@angular/platform-browser": "22.3.0-next.1", "@angular/platform-server": "22.3.0-next.1", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index b2b2fdfdffd9..e38b036ee3d9 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -187,8 +187,8 @@ importers: specifier: 22.3.0-next.1 version: 22.3.0-next.1(@angular/core@22.3.0-next.1(@angular/compiler@22.3.0-next.1)(rxjs@7.8.2)(zone.js@0.16.3)) '@angular/cdk': - specifier: 22.3.0-next.1 - version: 22.3.0-next.1(1e228ab395252fe57958c1335d3a301f) + specifier: 22.3.0-next.2 + version: 22.3.0-next.2(1e228ab395252fe57958c1335d3a301f) '@angular/common': specifier: 22.3.0-next.1 version: 22.3.0-next.1(@angular/core@22.3.0-next.1(@angular/compiler@22.3.0-next.1)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2) @@ -205,8 +205,8 @@ importers: specifier: 22.3.0-next.1 version: 22.3.0-next.1(@angular/compiler-cli@22.3.0-next.1(@angular/compiler@22.3.0-next.1)(typescript@6.0.3))(@angular/compiler@22.3.0-next.1) '@angular/material': - specifier: 22.3.0-next.1 - version: 22.3.0-next.1(837417520965053888cf2615dc986a27) + specifier: 22.3.0-next.2 + version: 22.3.0-next.2(1acbd77e3019024ea0df0dc9f59ed8c0) '@angular/ng-dev': specifier: https://github.com/angular/dev-infra-private-ng-dev-builds.git#fa4308affb4a0dde34ebc95196b58550752485a2 version: https://codeload.github.com/angular/dev-infra-private-ng-dev-builds/tar.gz/fa4308affb4a0dde34ebc95196b58550752485a2 @@ -1035,8 +1035,8 @@ packages: peerDependencies: '@angular/core': 22.3.0-next.1 - '@angular/cdk@22.3.0-next.1': - resolution: {integrity: sha512-WAOIXq+8KtLn59xdt7rRKgdxO3VUCGSlSzoUJQez4EM+/MFa8GPMTHZ392ewBA3R2XpEJNFbSIH61A0+yfNBMg==} + '@angular/cdk@22.3.0-next.2': + resolution: {integrity: sha512-UlleZDkYVds93nKOJ32g393Ca7XyrG+c8r5XoQG3aQHKe5L+lc5HjmPGAJ1Y80iotUQG3NFsgwLnweCGV12yWw==} peerDependencies: '@angular/common': ^22.0.0-0 || ^22.1.0-0 || ^22.2.0-0 || ^22.3.0-0 || ^23.0.0-0 '@angular/core': ^22.0.0-0 || ^22.1.0-0 || ^22.2.0-0 || ^22.3.0-0 || ^23.0.0-0 @@ -1096,10 +1096,10 @@ packages: '@angular/compiler': 22.3.0-next.1 '@angular/compiler-cli': 22.3.0-next.1 - '@angular/material@22.3.0-next.1': - resolution: {integrity: sha512-iQrlvYiHEwY9p7c8CIa9pPXfWDuE+4cU3c64X3w8i7ChDBSj/dzsGK31X4EstZ+PXozDzcLH+JXuHkWPg81CVQ==} + '@angular/material@22.3.0-next.2': + resolution: {integrity: sha512-4l6+DzUtwIH+SYrZdT54Lg7sNvFu6+MmLxlQQB8TtC5V5EijqOv1rjLmp+mFFgpVFmwlZwdGS8vJfRvkzKLY2w==} peerDependencies: - '@angular/cdk': 22.3.0-next.1 + '@angular/cdk': 22.3.0-next.2 '@angular/common': ^22.0.0-0 || ^22.1.0-0 || ^22.2.0-0 || ^22.3.0-0 || ^23.0.0-0 '@angular/core': ^22.0.0-0 || ^22.1.0-0 || ^22.2.0-0 || ^22.3.0-0 || ^23.0.0-0 '@angular/forms': ^22.0.0-0 || ^22.1.0-0 || ^22.2.0-0 || ^22.3.0-0 || ^23.0.0-0 @@ -8870,7 +8870,7 @@ snapshots: '@angular/core': 22.3.0-next.1(@angular/compiler@22.3.0-next.1)(rxjs@7.8.2)(zone.js@0.16.3) tslib: 2.8.1 - '@angular/cdk@22.3.0-next.1(1e228ab395252fe57958c1335d3a301f)': + '@angular/cdk@22.3.0-next.2(1e228ab395252fe57958c1335d3a301f)': dependencies: '@angular/common': 22.3.0-next.1(@angular/core@22.3.0-next.1(@angular/compiler@22.3.0-next.1)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2) '@angular/core': 22.3.0-next.1(@angular/compiler@22.3.0-next.1)(rxjs@7.8.2)(zone.js@0.16.3) @@ -8930,9 +8930,9 @@ snapshots: tinyglobby: 0.2.17 yargs: 18.2.0 - '@angular/material@22.3.0-next.1(837417520965053888cf2615dc986a27)': + '@angular/material@22.3.0-next.2(1acbd77e3019024ea0df0dc9f59ed8c0)': dependencies: - '@angular/cdk': 22.3.0-next.1(1e228ab395252fe57958c1335d3a301f) + '@angular/cdk': 22.3.0-next.2(1e228ab395252fe57958c1335d3a301f) '@angular/common': 22.3.0-next.1(@angular/core@22.3.0-next.1(@angular/compiler@22.3.0-next.1)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2) '@angular/core': 22.3.0-next.1(@angular/compiler@22.3.0-next.1)(rxjs@7.8.2)(zone.js@0.16.3) '@angular/forms': 22.3.0-next.1(@angular/common@22.3.0-next.1(@angular/core@22.3.0-next.1(@angular/compiler@22.3.0-next.1)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2))(@angular/core@22.3.0-next.1(@angular/compiler@22.3.0-next.1)(rxjs@7.8.2)(zone.js@0.16.3))(@angular/platform-browser@22.3.0-next.1(@angular/animations@22.3.0-next.1(@angular/core@22.3.0-next.1(@angular/compiler@22.3.0-next.1)(rxjs@7.8.2)(zone.js@0.16.3)))(@angular/common@22.3.0-next.1(@angular/core@22.3.0-next.1(@angular/compiler@22.3.0-next.1)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2))(@angular/core@22.3.0-next.1(@angular/compiler@22.3.0-next.1)(rxjs@7.8.2)(zone.js@0.16.3)))(rxjs@7.8.2) diff --git a/tests/e2e/ng-snapshot/package.json b/tests/e2e/ng-snapshot/package.json index 0618eb046f57..8550a3c4bb4c 100644 --- a/tests/e2e/ng-snapshot/package.json +++ b/tests/e2e/ng-snapshot/package.json @@ -2,21 +2,21 @@ "description": "snapshot versions of Angular for e2e testing", "private": true, "dependencies": { - "@angular/animations": "github:angular/animations-builds#7ef64e48fbd50c668e386243a1d4c2f1ef84675b", - "@angular/cdk": "github:angular/cdk-builds#8aa05501715c9b9b0fc95625f52b3b536c35cc4a", - "@angular/common": "github:angular/common-builds#96bb8a452e96a75e2130519f1301b25a08e408ec", - "@angular/compiler": "github:angular/compiler-builds#c94e6865d332afa0694d24049624ef23d1923089", - "@angular/compiler-cli": "github:angular/compiler-cli-builds#2d4f2f5eede86c9f3fa7ec4e8ce4cf03fc502d54", - "@angular/core": "github:angular/core-builds#f43cfb919a0da367f40da1bd07e67cd1845388c2", - "@angular/forms": "github:angular/forms-builds#a181c75be824e20dcc653e7e029217014aaae777", - "@angular/language-service": "github:angular/language-service-builds#3224af77e1a302a3ba6a5620fce41879c8c8158e", - "@angular/localize": "github:angular/localize-builds#b1148951f8251042228b544facb01d24f40d7380", - "@angular/material": "github:angular/material-builds#5f4d7a4724a306e1e24d55f53564eebfa22dbdd4", - "@angular/material-moment-adapter": "github:angular/material-moment-adapter-builds#a600a485f5c91b376684763cbf00b158f85502f0", - "@angular/platform-browser": "github:angular/platform-browser-builds#b8cd3c70f3e83ccc2675345dbaef19406c274814", - "@angular/platform-browser-dynamic": "github:angular/platform-browser-dynamic-builds#81f80d43de410f7d4a2f0da625ca5882b7c3f71a", - "@angular/platform-server": "github:angular/platform-server-builds#b94ffc850d236d03d53460c6bb72b23eb7e21920", - "@angular/router": "github:angular/router-builds#cbe6196b50ea6948bb8ade7ac32f26029d37ca45", - "@angular/service-worker": "github:angular/service-worker-builds#5bb5c383c8e2323d28a2347a784327e031a4b101" + "@angular/animations": "github:angular/animations-builds#f2f4920079874bc3ff7233cae1bfc044f540aaea", + "@angular/cdk": "github:angular/cdk-builds#47633891913bba784f30c7e96a832ce5aee6b5ca", + "@angular/common": "github:angular/common-builds#50cb684a62ab0a76b5cac1f43e419dcef95695c5", + "@angular/compiler": "github:angular/compiler-builds#121ce74dc256084d4df6189faec0897906c81e7f", + "@angular/compiler-cli": "github:angular/compiler-cli-builds#13f5a3741ae88163e4830805d5fdb3be10975600", + "@angular/core": "github:angular/core-builds#803e8bc85644b8ae2f7626a2128b2597bad464f5", + "@angular/forms": "github:angular/forms-builds#dfc8f809fc98e7350bfb3c0cc4ed76c2f898e8a2", + "@angular/language-service": "github:angular/language-service-builds#26e3a3900301c3d6a9ab6a25567c1038e7a8556d", + "@angular/localize": "github:angular/localize-builds#152ad1e6420c1f2f6592f920c81e39dbcb5f5493", + "@angular/material": "github:angular/material-builds#e39e747aad22eb1ee2981f8f7b39a3b8ec788381", + "@angular/material-moment-adapter": "github:angular/material-moment-adapter-builds#f0e6679098e0bfdb8f98b2c7a2c271ec2d128994", + "@angular/platform-browser": "github:angular/platform-browser-builds#c87936c6c5381b369a60bcd311836c711b68d498", + "@angular/platform-browser-dynamic": "github:angular/platform-browser-dynamic-builds#abdac4b65aa34f8a1c9580631d22ae478579e111", + "@angular/platform-server": "github:angular/platform-server-builds#11bfbc1463ebaff83489b1b560ff49e9fb281fb1", + "@angular/router": "github:angular/router-builds#5457840c68f0afb075100b2d923de1219b450838", + "@angular/service-worker": "github:angular/service-worker-builds#94c8e94f4903c4271b9da3eedea9402e3af87043" } } From a3b6d48f477626c8eaed4a689551fb6f7c285a7d Mon Sep 17 00:00:00 2001 From: Alan Agius Date: Wed, 14 Oct 2026 18:57:25 +0200 Subject: [PATCH 618/787] refactor(@angular/build): normalize library builder paths to POSIX format Normalize paths at option and compilation boundaries in the library builder to POSIX format and update TSDoc comments across the library builder pipeline. --- .../build/src/builders/library/builder.ts | 27 +++++++----- .../build/src/builders/library/options.ts | 34 +++++++++++---- .../src/builders/library/pipeline/assets.ts | 29 ++++++------- .../builders/library/pipeline/build-action.ts | 25 ++++++----- .../src/builders/library/pipeline/bundler.ts | 43 ++++++++----------- .../builders/library/pipeline/compilation.ts | 21 +++++---- .../builders/library/pipeline/entry-points.ts | 30 ++++++++----- .../library/pipeline/package-manifests.ts | 2 +- .../library/pipeline/stylesheet-bundler.ts | 5 ++- .../src/builders/library/pipeline/utils.ts | 25 +++++------ .../build/src/builders/library/types.ts | 35 +++++++++++---- .../build/src/utils/delete-output-dir.ts | 5 ++- .../src/utils/normalize-asset-patterns.ts | 15 ++++--- 13 files changed, 171 insertions(+), 125 deletions(-) diff --git a/packages/angular/build/src/builders/library/builder.ts b/packages/angular/build/src/builders/library/builder.ts index 84b933e7ceb6..c3c2149adf5b 100644 --- a/packages/angular/build/src/builders/library/builder.ts +++ b/packages/angular/build/src/builders/library/builder.ts @@ -111,13 +111,10 @@ export async function* executeLibraryBuilder( ); // Track all referenced compilation files for watch mode - const watchedCompilationFiles = new Set([ - toPosixPath(tsConfigPath), - toPosixPath(packageJsonPath), - ]); + const watchedCompilationFiles = new Set([tsConfigPath, packageJsonPath]); for (const entryPoint of normalizedOptions.entryPoints.values()) { - watchedCompilationFiles.add(toPosixPath(entryPoint.entryFilePath)); + watchedCompilationFiles.add(entryPoint.entryFilePath); } if (isWatchMode) { @@ -237,6 +234,17 @@ async function executeBuild( /** * Runs the watch loop, rebuilding the library as watched files are modified. + * + * @param watcher The file watcher instance. + * @param options The normalized library builder options with POSIX paths. + * @param stylesheetBundler The component stylesheet bundler instance. + * @param watchedCompilationFiles Set of POSIX file paths tracked for compilation. + * @param context The Architect builder context. + * @param withProgress Progress wrapper function (`withSpinner` or `withNoProgress`). + * @param buildState The state preserved across incremental builds. + * @param buildAction The library build action function to execute. + * @param hasModifiedWatchedFile Helper to check whether watched compilation files changed. + * @param signal Optional abort signal to terminate the watch loop. */ async function* runWatchLoop( watcher: BuildWatcher, @@ -253,7 +261,6 @@ async function* runWatchLoop( const { collectAssetsToEmit } = await import('./pipeline/assets'); const { workspaceRoot, packageJsonPath, assets, clearScreen } = options; - const posixPackageJsonPath = toPosixPath(packageJsonPath); for await (const changes of watcher) { if (signal?.aborted) { @@ -293,13 +300,13 @@ async function* runWatchLoop( // Check if package.json was modified let hasPackageJsonChanges = false; - if (changedFiles.has(posixPackageJsonPath)) { + if (changedFiles.has(packageJsonPath)) { try { const packageJson = await loadPackageJson(packageJsonPath); - options.packageJson = packageJson; if (!packageJson.name) { throw new Error(`The package.json at '${packageJsonPath}' must contain a 'name'.`); } + options.packageJson = packageJson; options.packageName = packageJson.name; updateWatchedEntryPoints( @@ -328,7 +335,7 @@ async function* runWatchLoop( !buildState.singleProgramCache || buildState.hasCompilationError || buildState.hasEntryPointsChanges || - hasModifiedWatchedFile(changedFiles, watchedCompilationFiles, posixPackageJsonPath); + hasModifiedWatchedFile(changedFiles, watchedCompilationFiles, packageJsonPath); const assetsToEmit = await collectAssetsToEmit( assets, @@ -388,7 +395,7 @@ function logMessages( * @param logger The Architect logger API. * @param startTime High-resolution timestamp recorded when the build iteration started. * @param success Whether the build iteration succeeded without errors. - * @param outputPath Optional output directory path to log on successful builds. + * @param outputPath Optional POSIX output directory path to log on successful builds. */ function logBuildResult( logger: logging.LoggerApi, diff --git a/packages/angular/build/src/builders/library/options.ts b/packages/angular/build/src/builders/library/options.ts index b7747fb6db27..14bc4514027d 100644 --- a/packages/angular/build/src/builders/library/options.ts +++ b/packages/angular/build/src/builders/library/options.ts @@ -13,6 +13,7 @@ import { normalizeAssetPatterns } from '../../utils'; import { supportColor } from '../../utils/color'; import { assertIsError } from '../../utils/error'; import { normalizeCacheOptions } from '../../utils/normalize-cache'; +import { toPosixPath } from '../../utils/path'; import { generateSearchDirectories, getTailwindConfig, @@ -24,14 +25,25 @@ import { loadPackageJson } from './pipeline/utils'; import type { Schema as LibraryBuilderOptions } from './schema'; import type { NormalizedLibraryOptions, PackageJsonData } from './types'; +/** + * Normalizes raw library builder options into {@link NormalizedLibraryOptions} with all + * file and directory paths normalized to POSIX format. + * + * @param context The Architect builder context. + * @param projectName The name of the library project. + * @param options The raw library builder schema options. + * @returns A promise resolving to the normalized library options. + */ export async function normalizeLibraryOptions( context: BuilderContext, projectName: string, options: LibraryBuilderOptions, ): Promise { - const { workspaceRoot } = context; + const workspaceRoot = toPosixPath(context.workspaceRoot); const projectMetadata = await context.getProjectMetadata(projectName); - const { projectRoot, projectSourceRoot } = getProjectRootPaths(workspaceRoot, projectMetadata); + const projectRootPaths = getProjectRootPaths(workspaceRoot, projectMetadata); + const projectRoot = toPosixPath(projectRootPaths.projectRoot); + const projectSourceRoot = toPosixPath(projectRootPaths.projectSourceRoot); const { tsConfig, @@ -50,8 +62,8 @@ export async function normalizeLibraryOptions( clearScreen, } = options; - const resolvedTsConfigPath = path.resolve(workspaceRoot, tsConfig); - const packageJsonPath = path.join(projectRoot, 'package.json'); + const resolvedTsConfigPath = toPosixPath(path.resolve(workspaceRoot, tsConfig)); + const packageJsonPath = path.posix.join(projectRoot, 'package.json'); let packageJson: PackageJsonData; try { @@ -99,7 +111,7 @@ export async function normalizeLibraryOptions( } defaultAssets.push({ glob: 'README.md', - input: path.dirname(entryPoint.entryFilePath), + input: path.posix.dirname(entryPoint.entryFilePath), output: entryPoint.name, }); } @@ -109,7 +121,11 @@ export async function normalizeLibraryOptions( workspaceRoot, projectRoot, projectSourceRoot, - ); + ).map((asset) => ({ + ...asset, + input: toPosixPath(path.resolve(workspaceRoot, asset.input)), + output: toPosixPath(asset.output), + })); const cacheOptions = normalizeCacheOptions( projectMetadata, @@ -119,7 +135,7 @@ export async function normalizeLibraryOptions( ); const styleIncludePaths = (stylePreprocessorOptions?.includePaths ?? []).map((p: string) => - path.resolve(workspaceRoot, p), + toPosixPath(path.resolve(workspaceRoot, p)), ); const searchDirectories = await generateSearchDirectories([projectRoot, workspaceRoot]); @@ -133,7 +149,9 @@ export async function normalizeLibraryOptions( projectRoot, packageName, packageJson, - outputPath: path.resolve(workspaceRoot, options.outputPath ?? path.join('dist', projectName)), + outputPath: toPosixPath( + path.resolve(workspaceRoot, options.outputPath ?? path.posix.join('dist', projectName)), + ), deleteOutputPath, packageJsonPath, tsConfigPath: resolvedTsConfigPath, diff --git a/packages/angular/build/src/builders/library/pipeline/assets.ts b/packages/angular/build/src/builders/library/pipeline/assets.ts index e1e46f4b9f08..7b8329a7865a 100644 --- a/packages/angular/build/src/builders/library/pipeline/assets.ts +++ b/packages/angular/build/src/builders/library/pipeline/assets.ts @@ -9,7 +9,6 @@ import { statSync } from 'node:fs'; import path from 'node:path'; import picomatch from 'picomatch'; -import { toPosixPath } from '../../../utils/path'; import { DEFAULT_ASSET_IGNORE, resolveAssets } from '../../../utils/resolve-assets'; import type { NormalizedLibraryOptions } from '../types'; import { type DiskOutputFile, createDiskOutputFile } from './utils'; @@ -17,9 +16,9 @@ import { type DiskOutputFile, createDiskOutputFile } from './utils'; /** * Resolves and collects configured library assets to be emitted to disk. * - * @param assets The normalized asset patterns. - * @param workspaceRoot The workspace root directory path. - * @param modifiedFiles Optional set of modified file paths for incremental copying in watch mode. + * @param assets The normalized asset patterns with POSIX paths. + * @param workspaceRoot The normalized POSIX workspace root directory path. + * @param modifiedFiles Optional set of modified POSIX file paths for incremental copying in watch mode. * @returns An array of disk file emission descriptors. */ export async function collectAssetsToEmit( @@ -32,25 +31,22 @@ export async function collectAssetsToEmit( } if (modifiedFiles) { - const matchers = createAssetMatchers(assets, workspaceRoot); + const matchers = createAssetMatchers(assets); const filesToEmit: DiskOutputFile[] = []; for (const file of modifiedFiles) { - const resolvedFile = path.isAbsolute(file) ? file : path.resolve(workspaceRoot, file); - const posixFile = toPosixPath(resolvedFile); - - for (const { asset, posixInputPrefix, isMatch } of matchers) { - if (!posixFile.startsWith(posixInputPrefix)) { + for (const { asset, prefix, isMatch } of matchers) { + if (!file.startsWith(prefix)) { continue; } - const relative = posixFile.slice(posixInputPrefix.length); + const relative = file.slice(prefix.length); if (!isMatch(relative)) { continue; } - if (statSync(resolvedFile, { throwIfNoEntry: false })?.isFile()) { - filesToEmit.push(createDiskOutputFile(resolvedFile, path.join(asset.output, relative))); + if (statSync(file, { throwIfNoEntry: false })?.isFile()) { + filesToEmit.push(createDiskOutputFile(file, path.posix.join(asset.output, relative))); } } } @@ -63,15 +59,14 @@ export async function collectAssetsToEmit( return resolvedAssets.map(({ source, destination }) => createDiskOutputFile(source, destination)); } -function createAssetMatchers(assets: NormalizedLibraryOptions['assets'], workspaceRoot: string) { +function createAssetMatchers(assets: NormalizedLibraryOptions['assets']) { return assets.map((asset) => { - const absInput = path.resolve(workspaceRoot, asset.input); - const posixInput = toPosixPath(absInput).replace(/\/+$/, ''); const isMatch = picomatch(asset.glob, { dot: true, ignore: [...DEFAULT_ASSET_IGNORE, ...(asset.ignore ?? [])], }); + const prefix = asset.input.endsWith('/') ? asset.input : `${asset.input}/`; - return { asset, posixInputPrefix: `${posixInput}/`, isMatch }; + return { asset, prefix, isMatch }; }); } diff --git a/packages/angular/build/src/builders/library/pipeline/build-action.ts b/packages/angular/build/src/builders/library/pipeline/build-action.ts index acdc69c61bff..f121048b1fc7 100644 --- a/packages/angular/build/src/builders/library/pipeline/build-action.ts +++ b/packages/angular/build/src/builders/library/pipeline/build-action.ts @@ -11,7 +11,6 @@ import path from 'node:path'; import type { ComponentStylesheetBundler } from '../../../tools/esbuild/angular/component-stylesheets'; import { emitFilesToDisk } from '../../../utils/disk-files'; import { assertIsError } from '../../../utils/error'; -import { toPosixPath } from '../../../utils/path'; import type { NormalizedLibraryOptions, SingleBuildState } from '../types'; import { collectAssetsToEmit } from './assets'; import { bundleEntryPoints } from './bundler'; @@ -49,7 +48,7 @@ export function createSingleBuildState(): SingleBuildState { * Context required to execute a single library build iteration. */ export interface BuildActionContext { - /** Normalized options for the library build. */ + /** Normalized options for the library build with POSIX paths. */ options: NormalizedLibraryOptions; /** The Architect builder context. */ @@ -62,7 +61,7 @@ export interface BuildActionContext { isWatchMode: boolean; /** - * Set of file paths tracked for compilation and configuration + * Set of POSIX file paths tracked for compilation and configuration * (including `tsconfig.json`, `package.json`, entry points, and referenced source, * template, and stylesheet files). Updated during compilation and used to determine * whether file changes require recompiling entry points, excluding asset files so @@ -73,7 +72,7 @@ export interface BuildActionContext { /** State preserved across incremental builds in watch mode. */ buildState: SingleBuildState; - /** Set of file paths modified since the last build iteration. */ + /** Set of POSIX file paths modified since the last build iteration. */ modifiedFiles?: Set; /** @@ -91,6 +90,7 @@ export interface BuildActionContext { * manifest generation, and asset copying. * * @param actionContext The build action state and configuration. + * @returns A promise resolving to the build action result containing errors, warnings, and logs. */ export async function buildAction(actionContext: BuildActionContext): Promise { const { @@ -106,10 +106,10 @@ export async function buildAction(actionContext: BuildActionContext): Promise 0 || pendingChangedDtsFiles.size > 0 || - hasModifiedWatchedFile(modifiedFiles, watchedCompilationFiles, posixPackageJsonPath); + hasModifiedWatchedFile(modifiedFiles, watchedCompilationFiles, packageJsonPath); try { if (!buildState.hasEmittedManifests) { @@ -172,13 +172,12 @@ export async function buildAction(actionContext: BuildActionContext): Promise> | undefined; let diagnostics: LibraryCompilationDiagnostics; if (hasStylesheetErrors) { diagnostics = await diagnosePromise; } else { + const itemsToBundle = collectEntryPointsToBundle(options, buildState, logs); try { [bundleOutput, diagnostics] = await Promise.all([ bundleEntryPoints(itemsToBundle, esmFiles, dtsFiles, { @@ -243,7 +242,7 @@ export async function buildAction(actionContext: BuildActionContext): Promise path.join(options.outputPath, file.path)); + await emitFilesToDisk(filesToEmit, (file) => path.posix.join(options.outputPath, file.path)); buildState.hasEmittedManifests = true; buildState.hasEmittedTslib = hasTslibImport; @@ -262,16 +261,16 @@ export async function buildAction(actionContext: BuildActionContext): Promise, watchedCompilationFiles: ReadonlySet, - posixPackageJsonPath: string, + packageJsonPath: string, ): boolean { for (const file of modifiedFiles) { - if (file !== posixPackageJsonPath && watchedCompilationFiles.has(file)) { + if (file !== packageJsonPath && watchedCompilationFiles.has(file)) { return true; } } diff --git a/packages/angular/build/src/builders/library/pipeline/bundler.ts b/packages/angular/build/src/builders/library/pipeline/bundler.ts index 5cd89a4b110d..c48942885083 100644 --- a/packages/angular/build/src/builders/library/pipeline/bundler.ts +++ b/packages/angular/build/src/builders/library/pipeline/bundler.ts @@ -60,7 +60,7 @@ interface MultiBundleOutput { /** In-memory files generated by the bundle invocation. */ filesToEmit: MemoryOutputFile[]; - /** Map of bundle entry names to the set of virtual module IDs included in the bundle. */ + /** Map of bundle entry names to the set of virtual POSIX module IDs included in the bundle. */ moduleIdsByBundle: Map>; /** Set of bundle entry names that import 'tslib'. */ @@ -75,9 +75,9 @@ interface MultiBundleOutput { * using at most 2 Rolldown instances total (1 for all .mjs bundles, 1 for all .d.ts bundles). * * @param items The collection of entry point inputs with change statuses. - * @param esmFiles Map of virtual ESM output file paths to their content. - * @param dtsFiles Map of virtual TypeScript declaration file paths to their content. - * @param options The normalized library builder options. + * @param esmFiles Map of virtual POSIX ESM output file paths to their content. + * @param dtsFiles Map of virtual POSIX TypeScript declaration file paths to their content. + * @param options The normalized library builder options with POSIX paths. * @returns A promise resolving to the bundled output files and bundle cache results. */ export async function bundleEntryPoints( @@ -135,7 +135,7 @@ export async function bundleEntryPoints( * * @param entryPoints The entry points to include in the bundle input map. * @param dtsMode Whether the input map is for declaration files (.d.ts) rather than ESM files (.js). - * @returns A record mapping bundle names to virtual entry file paths. + * @returns A record mapping bundle names to virtual POSIX entry file paths. */ function resolveEntryInputMap( entryPoints: readonly NormalizedEntryPoint[], @@ -143,20 +143,18 @@ function resolveEntryInputMap( ): Record { const input: Record = {}; for (const { bundleName, entryFilePath } of entryPoints) { - const posixPath = toPosixPath(entryFilePath); input[bundleName] = dtsMode - ? posixPath.replace(/\.([cm]?ts)$/, '.d.$1') - : posixPath.replace(/\.([cm]?)ts$/, '.$1js'); + ? entryFilePath.replace(/\.([cm]?ts)$/, '.d.$1') + : entryFilePath.replace(/\.([cm]?)ts$/, '.$1js'); } return input; } /** - * Creates a Rolldown plugin that loads modules from an in-memory file map - * and prevents illegal cross-entry-point sibling imports. + * Creates a Rolldown plugin that resolves and loads modules from an in-memory file map. * - * @param files Map of virtual file paths to their content. + * @param files Map of virtual POSIX file paths to their content. * @param extensions Candidate extensions to probe when resolving extensionless module specifiers. * @param includeMap Whether source map files should also be loaded from the memory map. * @returns A Rolldown plugin instance. @@ -183,12 +181,7 @@ function createMemoryFileLoaderPlugin( return { id, external: true }; } - const posixId = toPosixPath(id); - const importerPosix = toPosixPath(importer); - const resolved = - posixId[0] === '.' - ? path.posix.join(path.posix.dirname(importerPosix), posixId) - : posixId; + const resolved = id[0] === '.' ? path.posix.join(path.posix.dirname(importer), id) : id; let resolvedCandidate: string | undefined; if (files.has(resolved)) { @@ -230,7 +223,7 @@ function createMemoryFileLoaderPlugin( * the transitive set of module IDs belonging to each entry point bundle. * * @param output The array of output chunks and assets from Rolldown. - * @param dir The destination output directory prefix. + * @param dir The destination POSIX output directory prefix. * @returns The processed multi-bundle output. */ function processRolldownOutput( @@ -312,10 +305,10 @@ const IGNORED_ROLLDOWN_WARNING_CODES: ReadonlySet = new Set([ /** * Executes a Rolldown bundle build across all provided entry inputs. * - * @param input Map of bundle names to virtual entry file paths. + * @param input Map of bundle names to virtual POSIX entry file paths. * @param plugins Rolldown plugins to use during bundling. * @param extension Output file extension ('mjs' or 'd.ts'). - * @param options The normalized library options. + * @param options The normalized library options with POSIX paths. * @returns A promise resolving to the multi-bundle output. */ async function executeMultiBundle( @@ -367,7 +360,7 @@ async function executeMultiBundle( try { const { output } = await bundle.generate({ format: 'es', - dir: path.join(outputPath, dir), + dir: path.posix.join(outputPath, dir), entryFileNames: `[name].${extension}`, chunkFileNames: `[name]-[hash].${extension}`, sourcemap, @@ -388,8 +381,8 @@ async function executeMultiBundle( * Bundles JavaScript ESM output files for all provided entry points. * * @param entryPoints The entry points to bundle. - * @param esmFiles Map of virtual ESM output file paths to contents. - * @param options The normalized library options. + * @param esmFiles Map of virtual POSIX ESM output file paths to contents. + * @param options The normalized library options with POSIX paths. * @returns A promise resolving to the multi-bundle output. */ async function bundleAllEsm( @@ -418,8 +411,8 @@ async function bundleAllEsm( * Bundles TypeScript declaration (.d.ts) output files for all provided entry points. * * @param entryPoints The entry points to bundle. - * @param dtsFiles Map of virtual declaration output file paths to contents. - * @param options The normalized library options. + * @param dtsFiles Map of virtual POSIX declaration output file paths to contents. + * @param options The normalized library options with POSIX paths. * @returns A promise resolving to the multi-bundle output. */ async function bundleAllDts( diff --git a/packages/angular/build/src/builders/library/pipeline/compilation.ts b/packages/angular/build/src/builders/library/pipeline/compilation.ts index afc5c319854e..5a795b463bae 100644 --- a/packages/angular/build/src/builders/library/pipeline/compilation.ts +++ b/packages/angular/build/src/builders/library/pipeline/compilation.ts @@ -35,19 +35,19 @@ export interface LibraryCompilationDiagnostics { * Output of the unified library compilation step. */ export interface LibraryCompilationOutput { - /** Read-only map of emitted JavaScript files. */ + /** Read-only map of emitted JavaScript files keyed by POSIX path. */ readonly esmFiles: ReadonlyMap; - /** Read-only map of emitted TypeScript declaration files. */ + /** Read-only map of emitted TypeScript declaration files keyed by POSIX path. */ readonly dtsFiles: ReadonlyMap; - /** Set of JavaScript file paths that were modified or newly emitted in this iteration. */ + /** Set of POSIX JavaScript file paths that were modified or newly emitted in this iteration. */ readonly changedEsmFiles: ReadonlySet; - /** Set of declaration file paths that were modified or newly emitted in this iteration. */ + /** Set of POSIX declaration file paths that were modified or newly emitted in this iteration. */ readonly changedDtsFiles: ReadonlySet; - /** Set of all source and dependency file paths referenced during compilation. */ + /** Set of all POSIX source and dependency file paths referenced during compilation. */ readonly referencedFiles: ReadonlySet; /** Cached compilation state for subsequent incremental builds. */ @@ -70,10 +70,10 @@ export interface LibraryCompilationOutput { * Compiles all library entry points in a single TypeScript and Angular compilation pass. * * @param entryPoints The collection of normalized library entry points to compile. - * @param options The normalized library builder options. + * @param options The normalized library builder options with POSIX paths. * @param stylesheetBundler The component stylesheet bundler instance. * @param cached Optional cached compilation state from a previous build iteration. - * @param modifiedFiles Optional set of modified file paths for incremental compilation. + * @param modifiedFiles Optional set of modified POSIX file paths for incremental compilation. * @returns A promise resolving to the compilation output containing emitted files and diagnostics. */ export async function compileLibrary( @@ -179,13 +179,12 @@ export async function compileLibrary( if (effectiveModifiedFiles) { for (const modifiedFile of effectiveModifiedFiles) { - const posixModified = toPosixPath(modifiedFile); - if (allReferencedFiles.has(posixModified)) { + if (allReferencedFiles.has(modifiedFile)) { continue; } - const basePathWithoutExt = posixModified.replace(/(?:\.d\.[cm]?ts|\.[cm]?[jt]sx?)$/i, ''); - if (basePathWithoutExt === posixModified || existsSync(posixModified)) { + const basePathWithoutExt = modifiedFile.replace(/(?:\.d\.[cm]?ts|\.[cm]?[jt]sx?)$/i, ''); + if (basePathWithoutExt === modifiedFile || existsSync(modifiedFile)) { continue; } diff --git a/packages/angular/build/src/builders/library/pipeline/entry-points.ts b/packages/angular/build/src/builders/library/pipeline/entry-points.ts index 7797f069fade..5cff4ca82136 100644 --- a/packages/angular/build/src/builders/library/pipeline/entry-points.ts +++ b/packages/angular/build/src/builders/library/pipeline/entry-points.ts @@ -38,9 +38,9 @@ export function getEntryPointBundleName(packageName: string, entryPointName = '. * @param posixKey Normalized POSIX key without trailing slashes. * @param isPrimary Whether this is the primary entry point. * @param targetPath The relative file path string from exports. - * @param projectRoot The library project root directory. + * @param projectRoot The library project root POSIX directory path. * @param packageName The root package name (e.g. `@my/lib`). - * @returns The normalized entry point descriptor. + * @returns The normalized entry point descriptor with POSIX paths. */ function normalizeEntryPoint( key: string, @@ -65,7 +65,7 @@ function normalizeEntryPoint( const subpath = isPrimary ? '.' : `./${name}`; const displayName = (isPrimary ? packageName : `${packageName}/${name}`).toLowerCase(); const bundleName = getEntryPointBundleName(packageName, name); - const entryFilePath = path.resolve(projectRoot, targetPath); + const entryFilePath = toPosixPath(path.resolve(projectRoot, targetPath)); if (!/(?, @@ -234,6 +238,12 @@ export function haveEntryPointsChanged( /** * Updates watched files, entry points in options, and cached bundle results when package.json entry points change. + * + * @param packageJson The reloaded `package.json` data. + * @param options The normalized library builder options. + * @param buildState The state preserved across incremental builds. + * @param watchedCompilationFiles Set of POSIX file paths tracked for compilation. + * @param packageJsonPath Normalized POSIX path to `package.json`. */ export function updateWatchedEntryPoints( packageJson: PackageJsonData, @@ -251,7 +261,7 @@ export function updateWatchedEntryPoints( if (haveEntryPointsChanged(options.entryPoints, newEntryPoints)) { for (const entryPoint of newEntryPoints.values()) { - watchedCompilationFiles.add(toPosixPath(entryPoint.entryFilePath)); + watchedCompilationFiles.add(entryPoint.entryFilePath); } for (const name of buildState.previousBundleResults.keys()) { @@ -315,8 +325,8 @@ export function collectEntryPointsToBundle( /** * Checks whether any file in `changedFiles` belongs to the given entry point's `moduleIds`. * - * @param moduleIds Set of module IDs referenced by the entry point's previous bundle. - * @param changedFiles Set of file paths that changed during compilation. + * @param moduleIds Set of virtual POSIX module IDs referenced by the entry point's previous bundle. + * @param changedFiles Set of POSIX file paths that changed during compilation. * @returns `true` if at least one changed file is part of `moduleIds`; otherwise `false`. */ function hasEntryPointChanges( diff --git a/packages/angular/build/src/builders/library/pipeline/package-manifests.ts b/packages/angular/build/src/builders/library/pipeline/package-manifests.ts index 90e5d5bbd94a..98ed88a506e6 100644 --- a/packages/angular/build/src/builders/library/pipeline/package-manifests.ts +++ b/packages/angular/build/src/builders/library/pipeline/package-manifests.ts @@ -188,7 +188,7 @@ let cachedTslibRange: string | undefined; /** * Get the tslib range used by the Angular compiler. - * @param workspaceRoot path to the workspace root + * @param workspaceRoot path to the workspace root. * @returns tslib range */ async function getAngularTslibRange(workspaceRoot: string): Promise { diff --git a/packages/angular/build/src/builders/library/pipeline/stylesheet-bundler.ts b/packages/angular/build/src/builders/library/pipeline/stylesheet-bundler.ts index 74c44f3a1491..971741d7a2e2 100644 --- a/packages/angular/build/src/builders/library/pipeline/stylesheet-bundler.ts +++ b/packages/angular/build/src/builders/library/pipeline/stylesheet-bundler.ts @@ -10,6 +10,9 @@ import { ComponentStylesheetBundler } from '../../../tools/esbuild/angular/compo import type { BundleStylesheetOptions } from '../../../tools/esbuild/stylesheets/bundle-options'; import type { NormalizedLibraryOptions } from '../types'; +/** + * Subset of normalized library options required to configure the component stylesheet bundler. + */ export type LibraryStylesheetBundlerOptions = Pick< NormalizedLibraryOptions, | 'workspaceRoot' @@ -25,7 +28,7 @@ export type LibraryStylesheetBundlerOptions = Pick< /** * Creates a stylesheet bundler instance configured for library compilation. * - * @param options The normalized library builder options. + * @param options The normalized library builder options with POSIX paths. * @param incremental Whether incremental watch mode is enabled. * @param target The esbuild target environments derived from browserslist. * @returns A new ComponentStylesheetBundler instance. diff --git a/packages/angular/build/src/builders/library/pipeline/utils.ts b/packages/angular/build/src/builders/library/pipeline/utils.ts index 9092a73005ef..8ef8cf7fe9f3 100644 --- a/packages/angular/build/src/builders/library/pipeline/utils.ts +++ b/packages/angular/build/src/builders/library/pipeline/utils.ts @@ -7,6 +7,7 @@ */ import fs from 'node:fs/promises'; +import { toPosixPath } from '../../../utils/path'; import type { PackageJsonData } from '../types'; const IS_DTS_FILE_REGEXP = /\.d\.[cm]?ts$/i; @@ -28,7 +29,7 @@ export const TYPES_OUTPUT_DIR = 'types'; export interface MemoryOutputFile { origin: 'memory'; - /** The destination path where the file should be written. */ + /** The relative POSIX destination path where the file should be written. */ path: string; /** The contents of the file as either a string or byte array. */ @@ -41,10 +42,10 @@ export interface MemoryOutputFile { export interface DiskOutputFile { origin: 'disk'; - /** The path to the source file on disk. */ + /** The POSIX path to the source file on disk. */ source: string; - /** The destination path where the file should be copied. */ + /** The relative POSIX destination path where the file should be copied. */ path: string; } @@ -54,26 +55,26 @@ export interface DiskOutputFile { export type OutputFile = MemoryOutputFile | DiskOutputFile; /** - * Creates an output file descriptor for an existing file on disk. + * Creates an output file descriptor for an existing file on disk with POSIX paths. * * @param source The path to the source file on disk. - * @param path The destination path where the file should be copied. - * @returns A {@link DiskOutputFile} descriptor. + * @param path The relative destination path where the file should be copied. + * @returns A {@link DiskOutputFile} descriptor with POSIX `source` and `path`. */ export function createDiskOutputFile(source: string, path: string): DiskOutputFile { return { origin: 'disk', - source, - path, + source: toPosixPath(source), + path: toPosixPath(path), }; } /** - * Creates an output file descriptor for an in-memory file. + * Creates an output file descriptor for an in-memory file with a POSIX destination path. * - * @param path The destination path where the file should be written. + * @param path The relative destination path where the file should be written. * @param contents The contents of the file as either a string, byte array, or JSON object. - * @returns A {@link MemoryOutputFile} descriptor. + * @returns A {@link MemoryOutputFile} descriptor with a POSIX `path`. */ export function createMemoryOutputFile( path: string, @@ -81,7 +82,7 @@ export function createMemoryOutputFile( ): MemoryOutputFile { return { origin: 'memory', - path, + path: toPosixPath(path), contents: typeof contents === 'string' || contents instanceof Uint8Array ? contents diff --git a/packages/angular/build/src/builders/library/types.ts b/packages/angular/build/src/builders/library/types.ts index d360cfe2c868..2deeddf589e5 100644 --- a/packages/angular/build/src/builders/library/types.ts +++ b/packages/angular/build/src/builders/library/types.ts @@ -28,7 +28,7 @@ export interface NormalizedEntryPoint { /** Base name of the output bundle (e.g. 'my-lib' or 'my-lib-testing'). */ bundleName: string; - /** Absolute path to entry file. */ + /** Absolute POSIX path to the entry file. */ entryFilePath: string; /** Is this the primary entry point ('.')? */ @@ -59,21 +59,40 @@ export interface PackageJsonData { /** * Normalized options for the library builder. + * All file and directory paths are normalized to POSIX format. */ export interface NormalizedLibraryOptions { + /** Absolute POSIX path to the workspace root directory. */ workspaceRoot: string; + + /** Absolute POSIX path to the library project root directory. */ projectRoot: string; + packageName: string; packageJson: PackageJsonData; + + /** Absolute POSIX path to the build output directory. */ outputPath: string; + deleteOutputPath: boolean; + + /** Absolute POSIX path to the library's `package.json`. */ packageJsonPath: string; + + /** Absolute POSIX path to the TypeScript configuration file. */ tsConfigPath: string; + entryPoints: Map; inlineStyleLanguage: 'css' | 'less' | 'sass' | 'scss'; + + /** Absolute POSIX paths to style preprocessor include directories. */ styleIncludePaths: string[]; + sass?: StylesheetPluginsass; + + /** Normalized asset patterns with POSIX `input` and `output` paths. */ assets: ReturnType; + compilationMode?: 'partial' | 'full'; declarationMap?: boolean; allowedNonPeerDependencies: RegExp[]; @@ -93,10 +112,10 @@ export interface NormalizedLibraryOptions { * Cached module ID sets for a bundled entry point. */ export interface BundleResult { - /** Exact set of virtual ESM module IDs bundled into this entry point. */ + /** Exact set of virtual POSIX ESM module IDs bundled into this entry point. */ esmModuleIds: ReadonlySet; - /** Exact set of virtual DTS module IDs bundled into this entry point. */ + /** Exact set of virtual POSIX DTS module IDs bundled into this entry point. */ dtsModuleIds: ReadonlySet; /** Whether this entry point bundle imports 'tslib'. */ @@ -110,13 +129,13 @@ export interface SingleProgramCache { /** The active Angular compilation instance. */ readonly compilationInstance: AngularCompilation; - /** In-memory map of emitted JavaScript files keyed by relative output path. */ + /** In-memory map of emitted JavaScript files keyed by POSIX path. */ readonly esmFiles: Map; - /** In-memory map of emitted TypeScript declaration files keyed by relative output path. */ + /** In-memory map of emitted TypeScript declaration files keyed by POSIX path. */ readonly dtsFiles: Map; - /** Set of file paths that failed during stylesheet bundling or compilation. */ + /** Set of POSIX file paths that failed during stylesheet bundling or compilation. */ readonly failedFiles?: ReadonlySet; } @@ -133,10 +152,10 @@ export interface SingleBuildState { /** Map of entry point names to their previous bundle results. */ previousBundleResults: Map; - /** Set of changed ESM file paths pending bundling. */ + /** Set of changed POSIX ESM file paths pending bundling. */ pendingChangedEsmFiles: Set; - /** Set of changed TypeScript declaration file paths pending bundling. */ + /** Set of changed POSIX TypeScript declaration file paths pending bundling. */ pendingChangedDtsFiles: Set; /** Whether the previous build iteration encountered a compilation or diagnostic error. */ diff --git a/packages/angular/build/src/utils/delete-output-dir.ts b/packages/angular/build/src/utils/delete-output-dir.ts index 45084760793d..1f676e77b759 100644 --- a/packages/angular/build/src/utils/delete-output-dir.ts +++ b/packages/angular/build/src/utils/delete-output-dir.ts @@ -17,8 +17,9 @@ export async function deleteOutputDir( outputPath: string, emptyOnlyDirectories?: string[], ): Promise { - const resolvedOutputPath = resolve(root, outputPath); - if (resolvedOutputPath === root) { + const resolvedRoot = resolve(root); + const resolvedOutputPath = resolve(resolvedRoot, outputPath); + if (resolvedOutputPath === resolvedRoot) { throw new Error('Output path MUST not be project root directory!'); } diff --git a/packages/angular/build/src/utils/normalize-asset-patterns.ts b/packages/angular/build/src/utils/normalize-asset-patterns.ts index d97b6e605fa4..66365e10df22 100644 --- a/packages/angular/build/src/utils/normalize-asset-patterns.ts +++ b/packages/angular/build/src/utils/normalize-asset-patterns.ts @@ -24,14 +24,15 @@ export function normalizeAssetPatterns( // When sourceRoot is not available, we default to ${projectRoot}/src. const sourceRoot = projectSourceRoot || path.join(projectRoot, 'src'); - const resolvedSourceRoot = path.resolve(workspaceRoot, sourceRoot); - const resolvedProjectRoot = path.resolve(workspaceRoot, projectRoot); + const resolvedWorkspaceRoot = path.resolve(workspaceRoot); + const resolvedSourceRoot = path.resolve(resolvedWorkspaceRoot, sourceRoot); + const resolvedProjectRoot = path.resolve(resolvedWorkspaceRoot, projectRoot); return assetPatterns.map((assetPattern) => { // Normalize string asset patterns to objects. if (typeof assetPattern === 'string') { const assetPath = path.normalize(assetPattern); - const resolvedAssetPath = path.resolve(workspaceRoot, assetPath); + const resolvedAssetPath = path.resolve(resolvedWorkspaceRoot, assetPath); let root: string; // Check if the string asset is within sourceRoot. @@ -39,8 +40,8 @@ export function normalizeAssetPatterns( root = resolvedSourceRoot; } else if (resolvedAssetPath.startsWith(resolvedProjectRoot)) { root = resolvedProjectRoot; - } else if (resolvedAssetPath.startsWith(workspaceRoot)) { - root = workspaceRoot; + } else if (resolvedAssetPath.startsWith(resolvedWorkspaceRoot)) { + root = resolvedWorkspaceRoot; } else { throw new Error(`The ${assetPattern} asset path must be within the workspace root.`); } @@ -67,11 +68,11 @@ export function normalizeAssetPatterns( } // Output directory for both is the relative path from the root to input. - const output = path.relative(root, path.resolve(workspaceRoot, input)); + const output = path.relative(root, path.resolve(resolvedWorkspaceRoot, input)); assetPattern = { glob, input, output }; } else { - if (!isSubDirectory(workspaceRoot, assetPattern.input)) { + if (!isSubDirectory(resolvedWorkspaceRoot, assetPattern.input)) { throw new Error(`The ${assetPattern.input} asset path must be within the workspace root.`); } From 3dd880525c979ff130fbaf24da662a1d6eb368c2 Mon Sep 17 00:00:00 2001 From: Doug Parker Date: Wed, 14 Oct 2026 15:33:16 -0700 Subject: [PATCH 619/787] docs: release notes for the v20.3.40 release --- CHANGELOG.md | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1922874a08d9..58a5466b6649 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,15 @@ + + +# 20.3.40 (2026-10-14) + +### @angular/cli + +| Commit | Type | Description | +| --------------------------------------------------------------------------------------------------- | ---- | ------------------- | +| [bfe1908f4](https://github.com/angular/angular-cli/commit/bfe1908f46f5799e839dcf0f162955df59a94cb0) | fix | update zod to 4.6.6 | + + + # 22.3.0-next.1 (2026-10-07) From 3515b05c715919b7ae36225fa21475c7a64738d0 Mon Sep 17 00:00:00 2001 From: Doug Parker Date: Wed, 14 Oct 2026 19:51:23 -0700 Subject: [PATCH 620/787] docs: release notes for the v21.2.27 release --- CHANGELOG.md | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 58a5466b6649..ce91a1e74158 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,15 @@ + + +# 21.2.27 (2026-10-14) + +### @angular/cli + +| Commit | Type | Description | +| --------------------------------------------------------------------------------------------------- | ---- | ------------------- | +| [2e1742adf](https://github.com/angular/angular-cli/commit/2e1742adf28645635bb6cff3cc08ad9c94c7d085) | fix | update zod to 4.6.6 | + + + # 20.3.40 (2026-10-14) From 2b5a9a620495b4c85bf5cfa3db39b632d88e6ca5 Mon Sep 17 00:00:00 2001 From: Alan Agius <17563226+alan-agius4@users.noreply.github.com> Date: Mon, 12 Oct 2026 13:15:29 +0000 Subject: [PATCH 621/787] perf(@angular/build): enable TypeScript incremental build cache in library builder Pass the normalized `cacheOptions.path` to `compilationInstance.initialize` when persistent disk caching is enabled so TypeScript writes and reuses `.tsbuildinfo` across builds. --- .../builders/library/pipeline/compilation.ts | 4 +- .../library/tests/behavior/build_spec.ts | 42 +++++++++++++++++++ 2 files changed, 45 insertions(+), 1 deletion(-) diff --git a/packages/angular/build/src/builders/library/pipeline/compilation.ts b/packages/angular/build/src/builders/library/pipeline/compilation.ts index 5a795b463bae..367777667fe3 100644 --- a/packages/angular/build/src/builders/library/pipeline/compilation.ts +++ b/packages/angular/build/src/builders/library/pipeline/compilation.ts @@ -83,7 +83,8 @@ export async function compileLibrary( cached?: SingleProgramCache, modifiedFiles?: Set, ): Promise { - const { tsConfigPath, compilationMode, preserveSymlinks, colors, declarationMap } = options; + const { tsConfigPath, compilationMode, preserveSymlinks, colors, declarationMap, cacheOptions } = + options; const entryPathsMap: Record = {}; const rootFiles: string[] = []; @@ -155,6 +156,7 @@ export async function compileLibrary( declarationMap, compilationMode, paths: entryPathsMap, + cachePath: cacheOptions.enabled ? cacheOptions.path : undefined, }, 'library', ); diff --git a/packages/angular/build/src/builders/library/tests/behavior/build_spec.ts b/packages/angular/build/src/builders/library/tests/behavior/build_spec.ts index 4f5c6736c1ff..0b6de2a26c7f 100644 --- a/packages/angular/build/src/builders/library/tests/behavior/build_spec.ts +++ b/packages/angular/build/src/builders/library/tests/behavior/build_spec.ts @@ -236,5 +236,47 @@ describeLibraryBuilder(executeLibraryBuilder, LIBRARY_BUILDER_INFO, (harness) => }), ); }); + + it('should write and reuse .tsbuildinfo in the persistent cache directory when cache is enabled', async () => { + harness.useProject('lib', { + root: 'projects/lib', + sourceRoot: 'projects/lib/src', + cli: { + cache: { + enabled: true, + environment: 'all', + path: '.angular/cache', + }, + }, + }); + + harness.useTarget('build', { + ...BASE_OPTIONS, + }); + + const firstBuild = await harness.executeOnce(); + expect(firstBuild.result?.success).toBeTrue(); + harness + .expectFile('.angular/cache/0.0.0-PLACEHOLDER/lib/angular-build-library/.tsbuildinfo') + .toExist(); + + await harness.writeFile( + 'projects/lib/src/public-api.ts', + ` + export * from './lib/lib.service'; + export * from './lib/lib.component'; + export const CACHED_BUILD = true; + `, + ); + + const secondBuild = await harness.executeOnce(); + expect(secondBuild.result?.success).toBeTrue(); + const fesmContent = harness.readFile('dist/lib/fesm2022/lib.mjs'); + expect(fesmContent).toContain('LibComponent'); + expect(fesmContent).toContain('CACHED_BUILD'); + const dtsContent = harness.readFile('dist/lib/types/lib.d.ts'); + expect(dtsContent).toContain('LibComponent'); + expect(dtsContent).toContain('CACHED_BUILD'); + }); }); }); From b640b32e148ab68f820b390b1d9f03ae9a809266 Mon Sep 17 00:00:00 2001 From: Alan Agius <17563226+alan-agius4@users.noreply.github.com> Date: Thu, 15 Oct 2026 12:26:33 +0000 Subject: [PATCH 622/787] fix(@angular/build): use module.registerHooks() for in-memory ESM loader Node.js 26 runtime-deprecates `module.register()` (`DEP0205`) in favor of synchronous `module.registerHooks()`. Update the server-rendering in-memory ESM loader hooks to make `load` synchronous using `readFileSync` and register the hooks directly via `registerHooks({ resolve, load })`. Closes #34358 --- .../esm-in-memory-loader/loader-hooks.ts | 6 +- .../esm-in-memory-loader/loader-hooks_spec.ts | 69 +++++++++++++------ .../esm-in-memory-loader/register-hooks.ts | 7 +- 3 files changed, 56 insertions(+), 26 deletions(-) diff --git a/packages/angular/build/src/utils/server-rendering/esm-in-memory-loader/loader-hooks.ts b/packages/angular/build/src/utils/server-rendering/esm-in-memory-loader/loader-hooks.ts index 6f21bfbc739b..6ff4c8f8191c 100644 --- a/packages/angular/build/src/utils/server-rendering/esm-in-memory-loader/loader-hooks.ts +++ b/packages/angular/build/src/utils/server-rendering/esm-in-memory-loader/loader-hooks.ts @@ -8,7 +8,7 @@ import assert from 'node:assert'; import { randomUUID } from 'node:crypto'; -import { readFile } from 'node:fs/promises'; +import { readFileSync } from 'node:fs'; import { join } from 'node:path'; import { fileURLToPath, pathToFileURL } from 'node:url'; @@ -110,7 +110,7 @@ export function resolve( }); } -export async function load(url: string, context: { format?: string | null }, nextLoad: Function) { +export function load(url: string, context: { format?: string | null }, nextLoad: Function) { const { format } = context; // Load the file from memory if the URL is based in the virtual root @@ -137,7 +137,7 @@ export async function load(url: string, context: { format?: string | null }, nex } const filePath = fileURLToPath(url); - const fileBytes = await readFile(filePath); + const fileBytes = readFileSync(filePath); const source = Buffer.concat([NG_SERVER_MODE_INIT_BYTES, fileBytes]); return { diff --git a/packages/angular/build/src/utils/server-rendering/esm-in-memory-loader/loader-hooks_spec.ts b/packages/angular/build/src/utils/server-rendering/esm-in-memory-loader/loader-hooks_spec.ts index 2b7622145378..0b32c2248b10 100644 --- a/packages/angular/build/src/utils/server-rendering/esm-in-memory-loader/loader-hooks_spec.ts +++ b/packages/angular/build/src/utils/server-rendering/esm-in-memory-loader/loader-hooks_spec.ts @@ -6,6 +6,10 @@ * found in the LICENSE file at https://angular.dev/license */ +import assert from 'node:assert'; +import { mkdir, mkdtemp, rm, writeFile } from 'node:fs/promises'; +import { join } from 'node:path'; +import { pathToFileURL } from 'node:url'; import { initialize, load, resolve } from './loader-hooks'; import { createSharedServerFiles } from './utils'; @@ -124,12 +128,12 @@ describe('esm-in-memory-loader loader-hooks', () => { }); describe('load', () => { - it('should load in-memory file source from SharedArrayBuffer backed Uint8Array', async () => { + it('should load in-memory file source from SharedArrayBuffer backed Uint8Array', () => { const memoryUrl = new URL('./main.server.mjs', 'memory://').href; const rootResolve = resolve(memoryUrl, { parentURL: undefined }, () => {}); const nextLoad = jasmine.createSpy('nextLoad'); - const result = await load(rootResolve.url, { format: 'module' }, nextLoad); + const result = load(rootResolve.url, { format: 'module' }, nextLoad); expect(nextLoad).not.toHaveBeenCalled(); expect(result.format).toBe('module'); @@ -137,12 +141,12 @@ describe('esm-in-memory-loader loader-hooks', () => { expect(result.source).toBe('export const main = true;'); }); - it('should load in-memory file with multi-byte UTF-8 characters', async () => { + it('should load in-memory file with multi-byte UTF-8 characters', () => { const memoryUrl = new URL('./utf8.mjs', 'memory://').href; const rootResolve = resolve(memoryUrl, { parentURL: undefined }, () => {}); const nextLoad = jasmine.createSpy('nextLoad'); - const result = await load(rootResolve.url, { format: 'module' }, nextLoad); + const result = load(rootResolve.url, { format: 'module' }, nextLoad); expect(nextLoad).not.toHaveBeenCalled(); expect(result.format).toBe('module'); @@ -150,12 +154,12 @@ describe('esm-in-memory-loader loader-hooks', () => { expect(result.source).toBe('export const text = "🔥 UTF-8 🚀";'); }); - it('should load in-memory file with empty content', async () => { + it('should load in-memory file with empty content', () => { const memoryUrl = new URL('./empty.mjs', 'memory://').href; const rootResolve = resolve(memoryUrl, { parentURL: undefined }, () => {}); const nextLoad = jasmine.createSpy('nextLoad'); - const result = await load(rootResolve.url, { format: 'module' }, nextLoad); + const result = load(rootResolve.url, { format: 'module' }, nextLoad); expect(nextLoad).not.toHaveBeenCalled(); expect(result.format).toBe('module'); @@ -163,7 +167,7 @@ describe('esm-in-memory-loader loader-hooks', () => { expect(result.source).toBe(''); }); - it('should load in-memory file source with non-zero byteOffset in Uint8Array', async () => { + it('should load in-memory file source with non-zero byteOffset in Uint8Array', () => { const target = 'export const sliced = 42;'; const fullBuffer = Buffer.from(`__PADDING__${target}__MORE__`); const offset = Buffer.byteLength('__PADDING__', 'utf-8'); @@ -181,7 +185,7 @@ describe('esm-in-memory-loader loader-hooks', () => { const rootResolve = resolve(memoryUrl, { parentURL: undefined }, () => {}); const nextLoad = jasmine.createSpy('nextLoad'); - const result = await load(rootResolve.url, { format: 'module' }, nextLoad); + const result = load(rootResolve.url, { format: 'module' }, nextLoad); expect(nextLoad).not.toHaveBeenCalled(); expect(result.format).toBe('module'); @@ -189,7 +193,7 @@ describe('esm-in-memory-loader loader-hooks', () => { expect(result.source).toBe(target); }); - it('should load in-memory file source when outputFiles contain string values', async () => { + it('should load in-memory file source when outputFiles contain string values', () => { initialize({ workspaceRoot, outputFiles: { @@ -201,7 +205,7 @@ describe('esm-in-memory-loader loader-hooks', () => { const rootResolve = resolve(memoryUrl, { parentURL: undefined }, () => {}); const nextLoad = jasmine.createSpy('nextLoad'); - const result = await load(rootResolve.url, { format: 'module' }, nextLoad); + const result = load(rootResolve.url, { format: 'module' }, nextLoad); expect(nextLoad).not.toHaveBeenCalled(); expect(result.format).toBe('module'); @@ -209,21 +213,46 @@ describe('esm-in-memory-loader loader-hooks', () => { expect(result.source).toBe('export const fromString = 1;'); }); - it('should reject when in-memory file does not exist in outputFiles', async () => { + it('should throw when in-memory file does not exist in outputFiles', () => { const memoryUrl = new URL('./main.server.mjs', 'memory://').href; const rootResolve = resolve(memoryUrl, { parentURL: undefined }, () => {}); const nonExistentVirtualUrl = rootResolve.url.replace('main.server.mjs', 'missing.mjs'); const nextLoad = jasmine.createSpy('nextLoad'); - await expectAsync( - load(nonExistentVirtualUrl, { format: 'module' }, nextLoad), - ).toBeRejectedWithError(/Resolved in-memory ESM file should always exist/); + expect(() => load(nonExistentVirtualUrl, { format: 'module' }, nextLoad)).toThrowError( + /Resolved in-memory ESM file should always exist/, + ); expect(nextLoad).not.toHaveBeenCalled(); }); - it('should delegate to nextLoad for non-angular file URLs', async () => { - const nextLoad = jasmine.createSpy('nextLoad').and.resolveTo({ format: 'module' }); - const result = await load( + it('should prepend ngServerMode initialization for @angular/ file URLs', async () => { + const baseTmpDir = process.env['TEST_TMPDIR']; + assert(baseTmpDir, 'TEST_TMPDIR is not set'); + const tmpDir = await mkdtemp(join(baseTmpDir, 'loader-hooks-test-')); + + try { + const angularDir = join(tmpDir, '@angular/core'); + await mkdir(angularDir, { recursive: true }); + const filePath = join(angularDir, 'index.mjs'); + await writeFile(filePath, 'export const VERSION = "1.0.0";'); + + const nextLoad = jasmine.createSpy('nextLoad'); + const result = load(pathToFileURL(filePath).href, { format: 'module' }, nextLoad); + + expect(nextLoad).not.toHaveBeenCalled(); + expect(result.format).toBe('module'); + expect(result.shortCircuit).toBeTrue(); + expect(new TextDecoder().decode(result.source)).toBe( + 'var ngServerMode=true;export const VERSION = "1.0.0";', + ); + } finally { + await rm(tmpDir, { recursive: true, force: true }); + } + }); + + it('should delegate to nextLoad for non-angular file URLs', () => { + const nextLoad = jasmine.createSpy('nextLoad').and.returnValue({ format: 'module' }); + const result = load( 'file:///workspace/node_modules/rxjs/index.js', { format: 'module' }, nextLoad, @@ -235,9 +264,9 @@ describe('esm-in-memory-loader loader-hooks', () => { expect(result.format).toBe('module'); }); - it('should delegate to nextLoad for non-memory non-file URLs', async () => { - const nextLoad = jasmine.createSpy('nextLoad').and.resolveTo({ format: 'builtin' }); - const result = await load('node:fs', { format: 'builtin' }, nextLoad); + it('should delegate to nextLoad for non-memory non-file URLs', () => { + const nextLoad = jasmine.createSpy('nextLoad').and.returnValue({ format: 'builtin' }); + const result = load('node:fs', { format: 'builtin' }, nextLoad); expect(nextLoad).toHaveBeenCalledWith('node:fs'); expect(result.format).toBe('builtin'); diff --git a/packages/angular/build/src/utils/server-rendering/esm-in-memory-loader/register-hooks.ts b/packages/angular/build/src/utils/server-rendering/esm-in-memory-loader/register-hooks.ts index b23fe297bc19..56747e17bd03 100644 --- a/packages/angular/build/src/utils/server-rendering/esm-in-memory-loader/register-hooks.ts +++ b/packages/angular/build/src/utils/server-rendering/esm-in-memory-loader/register-hooks.ts @@ -6,8 +6,9 @@ * found in the LICENSE file at https://angular.dev/license */ -import { register } from 'node:module'; -import { pathToFileURL } from 'node:url'; +import { registerHooks } from 'node:module'; import { workerData } from 'node:worker_threads'; +import { initialize, load, resolve } from './loader-hooks'; -register('./loader-hooks.js', { parentURL: pathToFileURL(__filename), data: workerData }); +initialize(workerData); +registerHooks({ resolve, load }); From c042a66fed76f8190f6dc739865af1144f9bf854 Mon Sep 17 00:00:00 2001 From: Alan Agius <17563226+alan-agius4@users.noreply.github.com> Date: Thu, 15 Oct 2026 10:50:57 +0000 Subject: [PATCH 623/787] refactor(@angular/build): export NormalizedAssetsPattern and avoid mutating input patterns Export the `NormalizedAssetsPattern` interface from `normalize-asset-patterns.ts`, avoid mutating input `AssetPatternClass` objects in place, and simplify directory detection using `statSync(..., { throwIfNoEntry: false })`. Also import `normalizeAssetPatterns` directly in `library/options.ts` and add test coverage for asset `ignore` patterns. --- .../build/src/builders/library/options.ts | 2 +- .../library/tests/options/assets_spec.ts | 3 + .../src/utils/normalize-asset-patterns.ts | 64 ++++++++++--------- 3 files changed, 39 insertions(+), 30 deletions(-) diff --git a/packages/angular/build/src/builders/library/options.ts b/packages/angular/build/src/builders/library/options.ts index 14bc4514027d..23d18d6f4d8e 100644 --- a/packages/angular/build/src/builders/library/options.ts +++ b/packages/angular/build/src/builders/library/options.ts @@ -9,9 +9,9 @@ import type { BuilderContext } from '@angular-devkit/architect'; import path from 'node:path'; import type { StylesheetPluginsass } from '../../tools/esbuild/stylesheets/stylesheet-plugin-factory'; -import { normalizeAssetPatterns } from '../../utils'; import { supportColor } from '../../utils/color'; import { assertIsError } from '../../utils/error'; +import { normalizeAssetPatterns } from '../../utils/normalize-asset-patterns'; import { normalizeCacheOptions } from '../../utils/normalize-cache'; import { toPosixPath } from '../../utils/path'; import { diff --git a/packages/angular/build/src/builders/library/tests/options/assets_spec.ts b/packages/angular/build/src/builders/library/tests/options/assets_spec.ts index ded7743675ff..a596cbfe4e62 100644 --- a/packages/angular/build/src/builders/library/tests/options/assets_spec.ts +++ b/packages/angular/build/src/builders/library/tests/options/assets_spec.ts @@ -15,6 +15,7 @@ describeLibraryBuilder(executeLibraryBuilder, LIBRARY_BUILDER_INFO, (harness) => await harness.writeFiles({ 'projects/lib/assets-dir/file-a.png': 'PNG_A', 'projects/lib/assets-dir/file-b.png': 'PNG_B', + 'projects/lib/assets-dir/ignored.png': 'PNG_IGNORED', 'projects/lib/assets-dir/file-c.svg': 'SVG_C', }); @@ -25,6 +26,7 @@ describeLibraryBuilder(executeLibraryBuilder, LIBRARY_BUILDER_INFO, (harness) => glob: '**/*.png', input: 'projects/lib/assets-dir', output: 'assets', + ignore: ['ignored.png'], }, ], }); @@ -34,6 +36,7 @@ describeLibraryBuilder(executeLibraryBuilder, LIBRARY_BUILDER_INFO, (harness) => expect(harness.readFile('dist/lib/assets/file-a.png')).toBe('PNG_A'); expect(harness.readFile('dist/lib/assets/file-b.png')).toBe('PNG_B'); + expect(harness.hasFile('dist/lib/assets/ignored.png')).toBeFalse(); expect(harness.hasFile('dist/lib/assets/file-c.svg')).toBeFalse(); }); diff --git a/packages/angular/build/src/utils/normalize-asset-patterns.ts b/packages/angular/build/src/utils/normalize-asset-patterns.ts index 66365e10df22..defa6511172f 100644 --- a/packages/angular/build/src/utils/normalize-asset-patterns.ts +++ b/packages/angular/build/src/utils/normalize-asset-patterns.ts @@ -6,18 +6,35 @@ * found in the LICENSE file at https://angular.dev/license */ -import assert from 'node:assert'; import { statSync } from 'node:fs'; -import * as path from 'node:path'; -import { AssetPattern, AssetPatternClass } from '../builders/application/schema'; +import path from 'node:path'; +import type { AssetPattern, AssetPatternClass } from '../builders/application/schema'; import { isSubDirectory } from './path'; +/** + * Asset pattern configuration normalized into its object form with a resolved `output` directory. + */ +export interface NormalizedAssetsPattern extends AssetPatternClass { + /** Relative output directory within the build output path. */ + output: string; +} + +/** + * Normalizes raw string and object asset patterns into {@link NormalizedAssetsPattern} objects + * and validates that all asset inputs and outputs stay within the workspace and output directories. + * + * @param assetPatterns Raw string or object asset patterns from builder options. + * @param workspaceRoot Workspace root directory path. + * @param projectRoot Project root directory path. + * @param projectSourceRoot Optional project source root directory path. + * @returns An array of normalized asset pattern configurations. + */ export function normalizeAssetPatterns( assetPatterns: AssetPattern[], workspaceRoot: string, projectRoot: string, projectSourceRoot: string | undefined, -): (AssetPatternClass & { output: string })[] { +): NormalizedAssetsPattern[] { if (assetPatterns.length === 0) { return []; } @@ -29,6 +46,8 @@ export function normalizeAssetPatterns( const resolvedProjectRoot = path.resolve(resolvedWorkspaceRoot, projectRoot); return assetPatterns.map((assetPattern) => { + let normalized: NormalizedAssetsPattern; + // Normalize string asset patterns to objects. if (typeof assetPattern === 'string') { const assetPath = path.normalize(assetPattern); @@ -46,45 +65,32 @@ export function normalizeAssetPatterns( throw new Error(`The ${assetPattern} asset path must be within the workspace root.`); } - let glob: string, input: string; - let isDirectory: boolean; - + let isDirectory = true; try { - isDirectory = statSync(resolvedAssetPath).isDirectory(); - } catch { - isDirectory = true; - } - - if (isDirectory) { - // Folders get a recursive star glob. - glob = '**/*'; - // Input directory is their original path. - input = assetPath; - } else { - // Files are their own glob. - glob = path.basename(assetPath); - // Input directory is their original dirname. - input = path.dirname(assetPath); - } + isDirectory = statSync(resolvedAssetPath, { throwIfNoEntry: false })?.isDirectory() ?? true; + } catch {} + const glob = isDirectory ? '**/*' : path.basename(assetPath); + const input = isDirectory ? assetPath : path.dirname(assetPath); // Output directory for both is the relative path from the root to input. const output = path.relative(root, path.resolve(resolvedWorkspaceRoot, input)); - assetPattern = { glob, input, output }; + normalized = { glob, input, output }; } else { if (!isSubDirectory(resolvedWorkspaceRoot, assetPattern.input)) { throw new Error(`The ${assetPattern.input} asset path must be within the workspace root.`); } - assetPattern.output = path.join('.', assetPattern.output ?? ''); + normalized = { + ...assetPattern, + output: path.join('.', assetPattern.output ?? ''), + }; } - assert(assetPattern.output !== undefined); - - if (assetPattern.output.startsWith('..')) { + if (normalized.output.startsWith('..')) { throw new Error('An asset cannot be written to a location outside of the output path.'); } - return assetPattern as AssetPatternClass & { output: string }; + return normalized; }); } From d02d39caa64b610d7ee849d9a98d4a2109e29e70 Mon Sep 17 00:00:00 2001 From: Alan Agius <17563226+alan-agius4@users.noreply.github.com> Date: Thu, 15 Oct 2026 10:55:57 +0000 Subject: [PATCH 624/787] refactor(@angular/build): encapsulate library build state in BuilderState and ExecutionResult Introduce `BuilderState` and `ExecutionResult` to replace `SingleBuildState`, `BuildActionResult`, `LibraryCompilationDiagnostics`, and manual `watchedCompilationFiles` parameter threading across the library builder pipeline. `BuilderState` manages incremental compilation state, watched compilation files, pending compilation modifications across aborted watch iterations, and `ExecutionResult` diagnostic collection. --- .../src/builders/library/builder-state.ts | 240 +++++++++++++++++ .../builders/library/builder-state_spec.ts | 155 +++++++++++ .../build/src/builders/library/builder.ts | 122 ++++----- .../src/builders/library/execution-result.ts | 75 ++++++ .../build/src/builders/library/index.ts | 2 +- .../builders/library/pipeline/build-action.ts | 244 +++++------------- .../builders/library/pipeline/compilation.ts | 157 ++++------- .../builders/library/pipeline/entry-points.ts | 61 +++-- .../library/pipeline/entry-points_spec.ts | 220 ++++++++++------ .../library/pipeline/package-manifests.ts | 16 +- .../build/src/builders/library/types.ts | 85 ++++-- 11 files changed, 883 insertions(+), 494 deletions(-) create mode 100644 packages/angular/build/src/builders/library/builder-state.ts create mode 100644 packages/angular/build/src/builders/library/builder-state_spec.ts create mode 100644 packages/angular/build/src/builders/library/execution-result.ts diff --git a/packages/angular/build/src/builders/library/builder-state.ts b/packages/angular/build/src/builders/library/builder-state.ts new file mode 100644 index 000000000000..c20ef26ea7c5 --- /dev/null +++ b/packages/angular/build/src/builders/library/builder-state.ts @@ -0,0 +1,240 @@ +/** + * @license + * Copyright Google LLC All Rights Reserved. + * + * Use of this source code is governed by an MIT-style license that can be + * found in the LICENSE file at https://angular.dev/license + */ + +import { ExecutionResult } from './execution-result'; +import type { + BundleResult, + LibraryCompilationOutput, + NormalizedLibraryOptions, + SingleProgramCache, +} from './types'; + +/** + * Encapsulates incremental compilation state, watched compilation file tracking, + * and execution results across watch-mode rebuilds. + */ +export class BuilderState { + readonly #watchedCompilationFiles = new Set(); + readonly #pendingCompilationFiles = new Set(); + + #executionResult = new ExecutionResult(); + #singleProgramCache?: SingleProgramCache; + #compilationMode?: 'partial' | 'full'; + + /** Map of entry point names to their previous bundle results. */ + readonly previousBundleResults = new Map(); + + /** Set of changed POSIX ESM file paths pending bundling. */ + readonly pendingChangedEsmFiles = new Set(); + + /** Set of changed POSIX TypeScript declaration file paths pending bundling. */ + readonly pendingChangedDtsFiles = new Set(); + + /** Whether the previous build iteration encountered a compilation or diagnostic error. */ + hasCompilationError = false; + + /** Whether package.json and secondary entry point manifests have been emitted. */ + hasEmittedManifests = false; + + /** Whether the last emitted root package.json included a tslib dependency. */ + hasEmittedTslib = false; + + /** Whether static assets have been emitted in a prior iteration. */ + hasEmittedAssets = false; + + /** Whether entry points in package.json changed since the last compilation. */ + hasEntryPointsChanges = false; + + constructor( + options?: Partial< + Pick + >, + ) { + if (options?.tsConfigPath) { + this.#watchedCompilationFiles.add(options.tsConfigPath); + } + if (options?.packageJsonPath) { + this.#watchedCompilationFiles.add(options.packageJsonPath); + } + if (options?.entryPoints) { + for (const entryPoint of options.entryPoints.values()) { + this.#watchedCompilationFiles.add(entryPoint.entryFilePath); + } + } + } + + /** Cached unified TypeScript and Angular compilation state. */ + get singleProgramCache(): SingleProgramCache | undefined { + return this.#singleProgramCache; + } + + /** Effective compilation mode resolved from builder options and tsconfig. */ + get compilationMode(): 'partial' | 'full' | undefined { + return this.#compilationMode; + } + + /** Whether any active entry point bundle imports `tslib`. */ + get hasTslibImport(): boolean { + for (const result of this.previousBundleResults.values()) { + if (result.hasTslibImport) { + return true; + } + } + + return false; + } + + /** + * Set of POSIX file paths tracked for compilation and configuration + * (including `tsconfig.json`, `package.json`, entry points, and referenced source, + * template, and stylesheet files). + */ + get watchedCompilationFiles(): Set { + return this.#watchedCompilationFiles; + } + + /** + * Execution result holding errors, warnings, and logs for the current build iteration. + */ + get executionResult(): ExecutionResult { + return this.#executionResult; + } + + /** + * Resets the execution result for a new build iteration. + * + * @returns The fresh `ExecutionResult` instance for the current build iteration. + */ + resetExecutionResult(): ExecutionResult { + this.#executionResult = new ExecutionResult(); + + return this.#executionResult; + } + + /** + * Determines whether compilation and bundling need to run for the current build iteration. + * Also records incoming modified files so they are retained if the iteration aborts early. + * + * @param packageJsonPath Normalized POSIX path to the library's `package.json`. + * @param modifiedFiles Optional set of modified POSIX file paths in watch mode. + * @returns `true` if entry points should be compiled; otherwise `false`. + */ + shouldCompileEntryPoints(packageJsonPath: string, modifiedFiles?: ReadonlySet): boolean { + if (modifiedFiles) { + for (const file of modifiedFiles) { + if (file !== packageJsonPath) { + this.#pendingCompilationFiles.add(file); + } + } + } + + if ( + !modifiedFiles || + !this.#singleProgramCache || + this.hasCompilationError || + this.hasEntryPointsChanges || + this.pendingChangedEsmFiles.size > 0 || + this.pendingChangedDtsFiles.size > 0 + ) { + return true; + } + + for (const file of this.#pendingCompilationFiles) { + if (this.#watchedCompilationFiles.has(file)) { + return true; + } + } + + this.#pendingCompilationFiles.clear(); + + return false; + } + + /** + * Returns the effective set of modified POSIX file paths for compilation, + * merging any pending compilation files from earlier aborted iterations. + * + * @param modifiedFiles Optional set of modified POSIX file paths from the current iteration. + * @returns Merged set of modified POSIX file paths, or `undefined` for a full compilation. + */ + getCompilationModifiedFiles(modifiedFiles?: ReadonlySet): Set | undefined { + if (!modifiedFiles) { + this.#pendingCompilationFiles.clear(); + + return undefined; + } + + const files = new Set(modifiedFiles); + for (const file of this.#pendingCompilationFiles) { + files.add(file); + } + + return files; + } + + /** + * Records compilation output into the build state, updating the program cache, + * watched compilation files, and pending changed ESM/DTS file sets. + * + * @param output The compilation output produced by `compileLibrary`. + */ + recordCompilationOutput(output: LibraryCompilationOutput): void { + this.#pendingCompilationFiles.clear(); + this.#singleProgramCache = output.cache; + if (this.#compilationMode !== output.compilationMode) { + this.#compilationMode = output.compilationMode; + this.hasEmittedManifests = false; + } + + for (const file of output.referencedFiles) { + this.#watchedCompilationFiles.add(file); + } + for (const file of output.changedEsmFiles) { + this.pendingChangedEsmFiles.add(file); + } + for (const file of output.changedDtsFiles) { + this.pendingChangedDtsFiles.add(file); + } + } + + /** + * Records active bundle results across entry points after compilation and bundling succeed, + * clearing pending compilation/bundle flags. + * + * @param bundleResults Newly bundled results keyed by entry point name. + */ + recordBundleOutput(bundleResults: ReadonlyMap): void { + this.hasCompilationError = false; + this.hasEntryPointsChanges = false; + this.pendingChangedEsmFiles.clear(); + this.pendingChangedDtsFiles.clear(); + + for (const [name, bundleResult] of bundleResults) { + this.previousBundleResults.set(name, bundleResult); + } + } + + /** + * Disposes active compilation resources and clears cached state. + */ + async dispose(): Promise { + await this.#singleProgramCache?.compilationInstance.close?.(); + this.#singleProgramCache = undefined; + this.#compilationMode = undefined; + this.hasEmittedTslib = false; + this.hasEmittedAssets = false; + this.hasCompilationError = false; + this.hasEmittedManifests = false; + this.hasEntryPointsChanges = false; + this.previousBundleResults.clear(); + this.pendingChangedEsmFiles.clear(); + this.pendingChangedDtsFiles.clear(); + this.#pendingCompilationFiles.clear(); + this.#watchedCompilationFiles.clear(); + } +} diff --git a/packages/angular/build/src/builders/library/builder-state_spec.ts b/packages/angular/build/src/builders/library/builder-state_spec.ts new file mode 100644 index 000000000000..9cf744d288bc --- /dev/null +++ b/packages/angular/build/src/builders/library/builder-state_spec.ts @@ -0,0 +1,155 @@ +/** + * @license + * Copyright Google LLC All Rights Reserved. + * + * Use of this source code is governed by an MIT-style license that can be + * found in the LICENSE file at https://angular.dev/license + */ + +import { BuilderState } from './builder-state'; +import type { LibraryCompilationOutput, SingleProgramCache } from './types'; + +describe('BuilderState', () => { + const packageJsonPath = '/workspace/projects/my-lib/package.json'; + const tsConfigPath = '/workspace/projects/my-lib/tsconfig.lib.json'; + const entryFilePath = '/workspace/projects/my-lib/src/public-api.ts'; + + function createMockCache(closeSpy?: jasmine.Spy): SingleProgramCache { + return { + compilationInstance: { + close: closeSpy, + } as unknown as SingleProgramCache['compilationInstance'], + esmFiles: new Map(), + dtsFiles: new Map(), + failedFiles: new Set(), + }; + } + + function createMockCompilationOutput( + overrides: Partial = {}, + ): LibraryCompilationOutput { + return { + esmFiles: new Map(), + dtsFiles: new Map(), + changedEsmFiles: new Set(), + changedDtsFiles: new Set(), + referencedFiles: new Set(), + cache: createMockCache(), + hasStylesheetErrors: false, + diagnosePromise: Promise.resolve(), + declarationMap: false, + compilationMode: 'partial', + ...overrides, + }; + } + + describe('ExecutionResult', () => { + it('should track logs, warnings, and errors and reset per iteration', () => { + const state = new BuilderState(); + expect(state.executionResult.hasErrors).toBeFalse(); + expect(state.executionResult.output).toEqual({ success: true }); + + state.executionResult.addLog('Bundling my-lib'); + state.executionResult.addWarning('Unused import'); + state.executionResult.addWarnings(['Deprecated API']); + state.executionResult.addError('Type error'); + state.executionResult.addErrors(['Syntax error']); + + expect(state.executionResult.logs).toEqual(['Bundling my-lib']); + expect(state.executionResult.warnings).toEqual(['Unused import', 'Deprecated API']); + expect(state.executionResult.errors).toEqual(['Type error', 'Syntax error']); + expect(state.executionResult.hasErrors).toBeTrue(); + expect(state.executionResult.output).toEqual({ success: false }); + + const freshResult = state.resetExecutionResult(); + expect(freshResult).toBe(state.executionResult); + expect(freshResult.hasErrors).toBeFalse(); + expect(freshResult.logs).toEqual([]); + expect(freshResult.warnings).toEqual([]); + expect(freshResult.errors).toEqual([]); + }); + }); + + describe('shouldCompileEntryPoints & getCompilationModifiedFiles', () => { + it('should preserve pending compilation files across aborted iterations', () => { + const state = new BuilderState({ + packageJsonPath, + tsConfigPath, + entryPoints: new Map([ + [ + '.', + { + subpath: '.', + name: '.', + displayName: 'my-lib', + bundleName: 'my-lib', + entryFilePath, + isPrimary: true, + }, + ], + ]), + }); + + state.recordCompilationOutput( + createMockCompilationOutput({ + referencedFiles: new Set([entryFilePath]), + }), + ); + + // Iteration 1: entryFilePath changes, but build aborts before recordCompilationOutput + expect( + state.shouldCompileEntryPoints(packageJsonPath, new Set([entryFilePath, packageJsonPath])), + ).toBeTrue(); + + // Iteration 2: only package.json changes on recovery + expect( + state.shouldCompileEntryPoints(packageJsonPath, new Set([packageJsonPath])), + ).toBeTrue(); + expect(state.getCompilationModifiedFiles(new Set([packageJsonPath]))).toEqual( + new Set([packageJsonPath, entryFilePath]), + ); + + // Once compilation output is recorded, pending compilation files are cleared + state.recordCompilationOutput(createMockCompilationOutput()); + expect( + state.shouldCompileEntryPoints(packageJsonPath, new Set([packageJsonPath])), + ).toBeFalse(); + }); + + it('should invalidate hasEmittedManifests when compilationMode changes', () => { + const state = new BuilderState(); + state.hasEmittedManifests = true; + state.recordCompilationOutput(createMockCompilationOutput({ compilationMode: 'partial' })); + expect(state.hasEmittedManifests).toBeFalse(); + + state.hasEmittedManifests = true; + state.recordCompilationOutput(createMockCompilationOutput({ compilationMode: 'partial' })); + expect(state.hasEmittedManifests).toBeTrue(); + + state.recordCompilationOutput(createMockCompilationOutput({ compilationMode: 'full' })); + expect(state.hasEmittedManifests).toBeFalse(); + }); + }); + + describe('dispose', () => { + it('should close compilationInstance and clear cached state on dispose', async () => { + const closeSpy = jasmine.createSpy('close').and.resolveTo(); + const state = new BuilderState({ packageJsonPath }); + state.recordCompilationOutput( + createMockCompilationOutput({ + cache: createMockCache(closeSpy), + changedEsmFiles: new Set(['/a.js']), + changedDtsFiles: new Set(['/a.d.ts']), + }), + ); + + await state.dispose(); + + expect(closeSpy).toHaveBeenCalledTimes(1); + expect(state.singleProgramCache).toBeUndefined(); + expect(state.pendingChangedEsmFiles).toHaveSize(0); + expect(state.pendingChangedDtsFiles).toHaveSize(0); + expect(state.watchedCompilationFiles).toHaveSize(0); + }); + }); +}); diff --git a/packages/angular/build/src/builders/library/builder.ts b/packages/angular/build/src/builders/library/builder.ts index c3c2149adf5b..fa8e717c9776 100644 --- a/packages/angular/build/src/builders/library/builder.ts +++ b/packages/angular/build/src/builders/library/builder.ts @@ -8,6 +8,7 @@ import type { BuilderContext, BuilderOutput } from '@angular-devkit/architect'; import type { logging } from '@angular-devkit/core'; +import type { ComponentStylesheetBundler } from '../../tools/esbuild/angular/component-stylesheets'; import { resetSassWorkerPoolCaches, shutdownSassWorkerPool, @@ -23,13 +24,14 @@ import { purgeStaleBuildCache } from '../../utils/purge-cache'; import { getSupportedBrowsers } from '../../utils/supported-browsers'; import { assertCompatibleAngularVersion } from '../../utils/version'; import type { BuildWatcher } from '../../utils/watcher'; +import { BuilderState } from './builder-state'; +import type { ExecutionResult } from './execution-result'; import { normalizeLibraryOptions } from './options'; -import type { BuildActionResult } from './pipeline/build-action'; +import type { BuildActionContext } from './pipeline/build-action'; import { updateWatchedEntryPoints } from './pipeline/entry-points'; -import type { createComponentStylesheetBundlerForLibrary } from './pipeline/stylesheet-bundler'; import { loadPackageJson } from './pipeline/utils'; import type { Schema as LibraryBuilderOptions } from './schema'; -import type { NormalizedLibraryOptions, SingleBuildState } from './types'; +import type { NormalizedLibraryOptions } from './types'; /** * Executes the library builder to compile, bundle, and package an Angular library into the Angular Package Format (APF). @@ -63,8 +65,6 @@ export async function* executeLibraryBuilder( projectRoot, outputPath, deleteOutputPath, - packageJsonPath, - tsConfigPath, watch: isWatchMode, poll, cacheOptions, @@ -89,17 +89,14 @@ export async function* executeLibraryBuilder( } // Dynamically lazy-loaded to prevent importing dependencies at the top level. - const [ - { buildAction, createSingleBuildState, hasModifiedWatchedFile }, - { createComponentStylesheetBundlerForLibrary }, - ] = await Promise.all([ + const [{ buildAction }, { createComponentStylesheetBundlerForLibrary }] = await Promise.all([ import('./pipeline/build-action'), import('./pipeline/stylesheet-bundler'), ]); - let stylesheetBundler: ReturnType | undefined; + let stylesheetBundler: ComponentStylesheetBundler | undefined; let watcher: BuildWatcher | undefined; - const buildState = createSingleBuildState(); + const buildState = new BuilderState(normalizedOptions); try { const browsers = getSupportedBrowsers(projectRoot, logger); @@ -110,13 +107,6 @@ export async function* executeLibraryBuilder( target, ); - // Track all referenced compilation files for watch mode - const watchedCompilationFiles = new Set([tsConfigPath, packageJsonPath]); - - for (const entryPoint of normalizedOptions.entryPoints.values()) { - watchedCompilationFiles.add(entryPoint.entryFilePath); - } - if (isWatchMode) { const { setupWatcher } = await import('../../utils/watcher'); watcher = await setupWatcher({ @@ -127,7 +117,10 @@ export async function* executeLibraryBuilder( poll, preserveSymlinks, signal, - watchFiles: watchedCompilationFiles, + watchFiles: [ + ...buildState.watchedCompilationFiles, + ...normalizedOptions.assets.map((asset) => asset.input), + ], }); context.addTeardown?.(() => void watcher?.close()); @@ -139,11 +132,10 @@ export async function* executeLibraryBuilder( { options: normalizedOptions, stylesheetBundler, - watchedCompilationFiles, isWatchMode, - context, buildState, }, + logger, withProgress, watcher, buildAction, @@ -163,12 +155,10 @@ export async function* executeLibraryBuilder( watcher, normalizedOptions, stylesheetBundler, - watchedCompilationFiles, - context, + logger, withProgress, buildState, buildAction, - hasModifiedWatchedFile, signal, ); } finally { @@ -178,7 +168,7 @@ export async function* executeLibraryBuilder( await Promise.allSettled([ watcher?.close(), stylesheetBundler?.dispose(), - buildState.singleProgramCache?.compilationInstance.close?.(), + buildState.dispose(), ]); } } @@ -189,6 +179,7 @@ export async function* executeLibraryBuilder( * * @param message Progress spinner message to display while building. * @param actionContext The build action context and state. + * @param logger The Architect logger API. * @param withProgress Progress wrapper function (`withSpinner` or `withNoProgress`). * @param watcher Optional file watcher for watch mode. * @param buildAction The library build action function to execute. @@ -196,33 +187,34 @@ export async function* executeLibraryBuilder( */ async function executeBuild( message: string, - actionContext: import('./pipeline/build-action').BuildActionContext, + actionContext: BuildActionContext, + logger: logging.LoggerApi, withProgress: typeof withSpinner, watcher: BuildWatcher | undefined, buildAction: typeof import('./pipeline/build-action').buildAction, ): Promise { const startTime = process.hrtime.bigint(); - const { context, watchedCompilationFiles, isWatchMode, options } = actionContext; + const { buildState, isWatchMode, options } = actionContext; try { const result = await withProgress(message, () => buildAction(actionContext)); - logMessages(context.logger, result); + logMessages(logger, result); - const success = result.errors.length === 0; - logBuildResult(context.logger, startTime, success, options.outputPath); - if (success && isWatchMode) { + const { output } = result; + logBuildResult(logger, startTime, output.success, options.outputPath); + if (output.success && isWatchMode) { logCumulativeDurations(); } - return { success }; + return output; } catch (error) { assertIsError(error); - logBuildResult(context.logger, startTime, false); + logBuildResult(logger, startTime, false); return { success: false, error: error.message }; } finally { if (watcher) { - watcher.add(Array.from(watchedCompilationFiles)); + watcher.add(Array.from(buildState.watchedCompilationFiles)); const { assetsToEmit } = actionContext; if (assetsToEmit?.length) { @@ -238,32 +230,29 @@ async function executeBuild( * @param watcher The file watcher instance. * @param options The normalized library builder options with POSIX paths. * @param stylesheetBundler The component stylesheet bundler instance. - * @param watchedCompilationFiles Set of POSIX file paths tracked for compilation. - * @param context The Architect builder context. + * @param logger The Architect logger API. * @param withProgress Progress wrapper function (`withSpinner` or `withNoProgress`). * @param buildState The state preserved across incremental builds. * @param buildAction The library build action function to execute. - * @param hasModifiedWatchedFile Helper to check whether watched compilation files changed. - * @param signal Optional abort signal to terminate the watch loop. + * @param signal Abort signal to terminate the watch loop. + * @returns An async iterator yielding builder output results. */ async function* runWatchLoop( watcher: BuildWatcher, options: NormalizedLibraryOptions, - stylesheetBundler: ReturnType, - watchedCompilationFiles: Set, - context: BuilderContext, + stylesheetBundler: ComponentStylesheetBundler, + logger: logging.LoggerApi, withProgress: typeof withSpinner, - buildState: SingleBuildState, + buildState: BuilderState, buildAction: typeof import('./pipeline/build-action').buildAction, - hasModifiedWatchedFile: typeof import('./pipeline/build-action').hasModifiedWatchedFile, - signal?: AbortSignal, + signal: AbortSignal, ): AsyncIterableIterator { const { collectAssetsToEmit } = await import('./pipeline/assets'); const { workspaceRoot, packageJsonPath, assets, clearScreen } = options; for await (const changes of watcher) { - if (signal?.aborted) { + if (signal.aborted) { break; } @@ -299,29 +288,17 @@ async function* runWatchLoop( } // Check if package.json was modified - let hasPackageJsonChanges = false; if (changedFiles.has(packageJsonPath)) { + buildState.hasEmittedManifests = false; try { const packageJson = await loadPackageJson(packageJsonPath); - if (!packageJson.name) { - throw new Error(`The package.json at '${packageJsonPath}' must contain a 'name'.`); - } - options.packageJson = packageJson; - options.packageName = packageJson.name; - - updateWatchedEntryPoints( - packageJson, - options, - buildState, - watchedCompilationFiles, - packageJsonPath, - ); - - hasPackageJsonChanges = true; + updateWatchedEntryPoints(packageJson, options, buildState); } catch (error) { assertIsError(error); await buildState.singleProgramCache?.compilationInstance.update?.(changedFiles); - buildState.hasEmittedManifests = false; + if (buildState.shouldCompileEntryPoints(packageJsonPath, changedFiles)) { + buildState.hasCompilationError = true; + } yield { success: false, @@ -331,11 +308,10 @@ async function* runWatchLoop( } } - const hasSourceChanges = - !buildState.singleProgramCache || - buildState.hasCompilationError || - buildState.hasEntryPointsChanges || - hasModifiedWatchedFile(changedFiles, watchedCompilationFiles, packageJsonPath); + const hasSourceChanges = buildState.shouldCompileEntryPoints(packageJsonPath, changedFiles); + if (!hasSourceChanges) { + await buildState.singleProgramCache?.compilationInstance.update?.(changedFiles); + } const assetsToEmit = await collectAssetsToEmit( assets, @@ -343,7 +319,7 @@ async function* runWatchLoop( buildState.hasEmittedAssets ? changedFiles : undefined, ); - if (!hasSourceChanges && !hasPackageJsonChanges && assetsToEmit.length === 0) { + if (!hasSourceChanges && buildState.hasEmittedManifests && assetsToEmit.length === 0) { continue; } @@ -352,13 +328,12 @@ async function* runWatchLoop( { options, stylesheetBundler, - watchedCompilationFiles, isWatchMode: true, - context, buildState, modifiedFiles: changedFiles, assetsToEmit, }, + logger, withProgress, watcher, buildAction, @@ -370,12 +345,9 @@ async function* runWatchLoop( * Logs informational, warning, and error messages produced during a build iteration. * * @param logger The Architect logger API. - * @param result The build action result containing logs, warnings, and errors. + * @param result The build execution result containing logs, warnings, and errors. */ -function logMessages( - logger: logging.LoggerApi, - { logs, warnings, errors }: BuildActionResult, -): void { +function logMessages(logger: logging.LoggerApi, { logs, warnings, errors }: ExecutionResult): void { if (logs.length) { logger.info(logs.join('\n')); } diff --git a/packages/angular/build/src/builders/library/execution-result.ts b/packages/angular/build/src/builders/library/execution-result.ts new file mode 100644 index 000000000000..4f9826360503 --- /dev/null +++ b/packages/angular/build/src/builders/library/execution-result.ts @@ -0,0 +1,75 @@ +/** + * @license + * Copyright Google LLC All Rights Reserved. + * + * Use of this source code is governed by an MIT-style license that can be + * found in the LICENSE file at https://angular.dev/license + */ + +import type { BuilderOutput } from '@angular-devkit/architect'; + +/** + * Encapsulates the diagnostic messages (`errors`, `warnings`, and `logs`) and + * builder output status for a single library build iteration. + */ +export class ExecutionResult { + readonly #errors: string[] = []; + readonly #warnings: string[] = []; + readonly #logs: string[] = []; + + /** Formatted error messages produced during the build iteration. */ + get errors(): readonly string[] { + return this.#errors; + } + + /** Formatted warning messages produced during the build iteration. */ + get warnings(): readonly string[] { + return this.#warnings; + } + + /** Informational log messages produced during the build iteration. */ + get logs(): readonly string[] { + return this.#logs; + } + + /** Whether any errors have been recorded in the build iteration. */ + get hasErrors(): boolean { + return this.#errors.length > 0; + } + + /** Architect builder output status for the build iteration. */ + get output(): BuilderOutput { + return { + success: !this.hasErrors, + }; + } + + /** Records an informational log message. */ + addLog(value: string): void { + this.#logs.push(value); + } + + /** Records a formatted error message. */ + addError(error: string): void { + this.#errors.push(error); + } + + /** Records multiple formatted error messages. */ + addErrors(errors: Iterable): void { + for (const error of errors) { + this.#errors.push(error); + } + } + + /** Records a formatted warning message. */ + addWarning(warning: string): void { + this.#warnings.push(warning); + } + + /** Records multiple formatted warning messages. */ + addWarnings(warnings: Iterable): void { + for (const warning of warnings) { + this.#warnings.push(warning); + } + } +} diff --git a/packages/angular/build/src/builders/library/index.ts b/packages/angular/build/src/builders/library/index.ts index 6a6ddf7a1ce7..da1f5d9385a3 100644 --- a/packages/angular/build/src/builders/library/index.ts +++ b/packages/angular/build/src/builders/library/index.ts @@ -6,7 +6,7 @@ * found in the LICENSE file at https://angular.dev/license */ -import { Builder, createBuilder } from '@angular-devkit/architect'; +import { type Builder, createBuilder } from '@angular-devkit/architect'; import { executeLibraryBuilder } from './builder'; import type { Schema as LibraryBuilderOptions } from './schema'; diff --git a/packages/angular/build/src/builders/library/pipeline/build-action.ts b/packages/angular/build/src/builders/library/pipeline/build-action.ts index f121048b1fc7..734ea23c544e 100644 --- a/packages/angular/build/src/builders/library/pipeline/build-action.ts +++ b/packages/angular/build/src/builders/library/pipeline/build-action.ts @@ -6,44 +6,20 @@ * found in the LICENSE file at https://angular.dev/license */ -import type { BuilderContext } from '@angular-devkit/architect'; import path from 'node:path'; import type { ComponentStylesheetBundler } from '../../../tools/esbuild/angular/component-stylesheets'; import { emitFilesToDisk } from '../../../utils/disk-files'; import { assertIsError } from '../../../utils/error'; -import type { NormalizedLibraryOptions, SingleBuildState } from '../types'; +import type { BuilderState } from '../builder-state'; +import type { ExecutionResult } from '../execution-result'; +import type { NormalizedLibraryOptions } from '../types'; import { collectAssetsToEmit } from './assets'; -import { bundleEntryPoints } from './bundler'; -import { type LibraryCompilationDiagnostics, compileLibrary } from './compilation'; +import { type BundleEntryPointsOutput, bundleEntryPoints } from './bundler'; +import { compileLibrary } from './compilation'; import { collectEntryPointsToBundle } from './entry-points'; import { generatePackageManifests } from './package-manifests'; import type { DiskOutputFile, OutputFile } from './utils'; -/** - * Result of executing a single library build iteration. - */ -export interface BuildActionResult { - /** Formatted error messages produced during the build. */ - errors: string[]; - - /** Formatted warning messages produced during the build. */ - warnings: string[]; - - /** Informational log messages produced during the build. */ - logs: string[]; -} - -/** - * Creates a fresh {@link SingleBuildState} instance. - */ -export function createSingleBuildState(): SingleBuildState { - return { - previousBundleResults: new Map(), - pendingChangedEsmFiles: new Set(), - pendingChangedDtsFiles: new Set(), - }; -} - /** * Context required to execute a single library build iteration. */ @@ -51,35 +27,23 @@ export interface BuildActionContext { /** Normalized options for the library build with POSIX paths. */ options: NormalizedLibraryOptions; - /** The Architect builder context. */ - context: BuilderContext; - /** Bundler instance used to process component stylesheets. */ stylesheetBundler: ComponentStylesheetBundler; /** Whether the builder is running in watch mode. */ isWatchMode: boolean; - /** - * Set of POSIX file paths tracked for compilation and configuration - * (including `tsconfig.json`, `package.json`, entry points, and referenced source, - * template, and stylesheet files). Updated during compilation and used to determine - * whether file changes require recompiling entry points, excluding asset files so - * asset-only changes do not trigger code compilation. - */ - watchedCompilationFiles: Set; - - /** State preserved across incremental builds in watch mode. */ - buildState: SingleBuildState; + /** Build state tracking compilation caches and emitted outputs. */ + buildState: BuilderState; /** Set of POSIX file paths modified since the last build iteration. */ modifiedFiles?: Set; /** - * Asset files to emit to disk for the current build iteration. + * Asset files to emit for the current build iteration. * Pre-collected in the watch loop to avoid redundant asset matching, or resolved and * populated by `buildAction` when omitted (such as during the initial build) so the - * caller can register their source paths with the file watcher. + * caller can register their POSIX source paths with the file watcher. */ assetsToEmit?: DiskOutputFile[]; } @@ -90,138 +54,84 @@ export interface BuildActionContext { * manifest generation, and asset copying. * * @param actionContext The build action state and configuration. - * @returns A promise resolving to the build action result containing errors, warnings, and logs. + * @returns A promise resolving to the build iteration's `ExecutionResult`. */ -export async function buildAction(actionContext: BuildActionContext): Promise { - const { - options, - stylesheetBundler, - isWatchMode, - watchedCompilationFiles, - buildState, - modifiedFiles, - } = actionContext; - - const errors: string[] = []; - const warnings: string[] = []; - const logs: string[] = []; +export async function buildAction(actionContext: BuildActionContext): Promise { + const { options, stylesheetBundler, isWatchMode, buildState, modifiedFiles } = actionContext; + const result = buildState.resetExecutionResult(); const { packageJsonPath } = options; - const { pendingChangedEsmFiles, pendingChangedDtsFiles } = buildState; - if (!modifiedFiles || modifiedFiles.has(packageJsonPath)) { - buildState.hasEmittedManifests = false; - } - - const shouldCompileEntryPoints = - !modifiedFiles || - !buildState.singleProgramCache || - buildState.hasCompilationError || - buildState.hasEntryPointsChanges || - pendingChangedEsmFiles.size > 0 || - pendingChangedDtsFiles.size > 0 || - hasModifiedWatchedFile(modifiedFiles, watchedCompilationFiles, packageJsonPath); + const shouldCompileEntryPoints = buildState.shouldCompileEntryPoints( + packageJsonPath, + modifiedFiles, + ); try { - if (!buildState.hasEmittedManifests) { - const dependencyErrors = verifyAllowedDependencies(options); - if (dependencyErrors.length > 0) { - errors.push(...dependencyErrors); - - return { errors, warnings, logs }; - } + if (!buildState.hasEmittedManifests && !verifyAllowedDependencies(options, result)) { + return result; } const filesToEmit: OutputFile[] = []; if (shouldCompileEntryPoints) { buildState.hasCompilationError = true; - buildState.hasEntryPointsChanges = false; + + const compilationOutput = await compileLibrary( + options, + stylesheetBundler, + buildState, + buildState.getCompilationModifiedFiles(modifiedFiles), + ); + buildState.recordCompilationOutput(compilationOutput); const { esmFiles, dtsFiles, - changedEsmFiles, - changedDtsFiles, - referencedFiles, - cache, hasStylesheetErrors, diagnosePromise, declarationMap, compilationMode, - } = await compileLibrary( - options.entryPoints.values(), - options, - stylesheetBundler, - buildState.singleProgramCache, - modifiedFiles, - ); - buildState.singleProgramCache = cache; - if (buildState.compilationMode !== compilationMode) { - buildState.compilationMode = compilationMode; - buildState.hasEmittedManifests = false; - } - - for (const file of referencedFiles) { - watchedCompilationFiles.add(file); - } - for (const file of changedEsmFiles) { - pendingChangedEsmFiles.add(file); - } - for (const file of changedDtsFiles) { - pendingChangedDtsFiles.add(file); - } + } = compilationOutput; - let bundleOutput: Awaited> | undefined; - let diagnostics: LibraryCompilationDiagnostics; if (hasStylesheetErrors) { - diagnostics = await diagnosePromise; - } else { - const itemsToBundle = collectEntryPointsToBundle(options, buildState, logs); - try { - [bundleOutput, diagnostics] = await Promise.all([ - bundleEntryPoints(itemsToBundle, esmFiles, dtsFiles, { - ...options, - declarationMap, - compilationMode, - }), - diagnosePromise, - ]); - } catch (error) { - assertIsError(error); - // Prioritize TypeScript/Angular diagnostic errors over secondary bundler failures. - diagnostics = await diagnosePromise; - if (diagnostics.errors.length === 0) { - errors.push(error.message); - } - } - } - - warnings.push(...diagnostics.warnings, ...(bundleOutput?.warnings ?? [])); - if (diagnostics.errors.length > 0 || errors.length > 0 || !bundleOutput) { - errors.push(...diagnostics.errors); + await diagnosePromise; - return { errors, warnings, logs }; + return result; } - buildState.hasCompilationError = false; - pendingChangedEsmFiles.clear(); - pendingChangedDtsFiles.clear(); + const itemsToBundle = collectEntryPointsToBundle(options, buildState); + let bundleOutput: BundleEntryPointsOutput; + try { + [bundleOutput] = await Promise.all([ + bundleEntryPoints(itemsToBundle, esmFiles, dtsFiles, { + ...options, + declarationMap, + compilationMode, + }), + diagnosePromise, + ]); + } catch (error) { + assertIsError(error); + // Prioritize TypeScript/Angular diagnostic errors over secondary bundler failures. + await diagnosePromise; + if (!result.hasErrors) { + result.addError(error.message); + } - filesToEmit.push(...bundleOutput.filesToEmit); - for (const [name, bundleResult] of bundleOutput.bundleResults) { - buildState.previousBundleResults.set(name, bundleResult); + return result; } - } - let hasTslibImport = false; - for (const entryPoint of options.entryPoints.values()) { - if (buildState.previousBundleResults.get(entryPoint.name)?.hasTslibImport) { - hasTslibImport = true; - break; + result.addWarnings(bundleOutput.warnings); + if (result.hasErrors) { + return result; } + + filesToEmit.push(...bundleOutput.filesToEmit); + buildState.recordBundleOutput(bundleOutput.bundleResults); } + const { hasTslibImport } = buildState; if (!buildState.hasEmittedManifests || buildState.hasEmittedTslib !== hasTslibImport) { filesToEmit.push( ...(await generatePackageManifests( @@ -249,33 +159,10 @@ export async function buildAction(actionContext: BuildActionContext): Promise, - watchedCompilationFiles: ReadonlySet, - packageJsonPath: string, -): boolean { - for (const file of modifiedFiles) { - if (file !== packageJsonPath && watchedCompilationFiles.has(file)) { - return true; - } - } - - return false; + return result; } /** @@ -283,24 +170,29 @@ export function hasModifiedWatchedFile( * permitted by `allowedNonPeerDependencies`. * * @param options The normalized library builder options. - * @returns An array of error messages for any disallowed dependencies. + * @param result The execution result to record any disallowed dependency errors into. + * @returns `true` if all dependencies are allowed; otherwise `false`. */ -function verifyAllowedDependencies(options: NormalizedLibraryOptions): string[] { +function verifyAllowedDependencies( + options: NormalizedLibraryOptions, + result: ExecutionResult, +): boolean { const { packageJson, allowedNonPeerDependencies } = options; const dependencies = { ...(packageJson.dependencies ?? {}), ...(packageJson.optionalDependencies ?? {}), }; - const errors: string[] = []; + let isValid = true; for (const dep of Object.keys(dependencies)) { if (!allowedNonPeerDependencies.some((regex) => regex.test(dep))) { - errors.push( + result.addError( `Dependency '${dep}' must be explicitly allowed using the 'allowedNonPeerDependencies' option, ` + `or moved to 'peerDependencies' in 'package.json'.`, ); + isValid = false; } } - return errors; + return isValid; } diff --git a/packages/angular/build/src/builders/library/pipeline/compilation.ts b/packages/angular/build/src/builders/library/pipeline/compilation.ts index 367777667fe3..38b28f442df6 100644 --- a/packages/angular/build/src/builders/library/pipeline/compilation.ts +++ b/packages/angular/build/src/builders/library/pipeline/compilation.ts @@ -15,80 +15,41 @@ import { import type { ComponentStylesheetBundler } from '../../../tools/esbuild/angular/component-stylesheets'; import { useTypeChecking } from '../../../utils/environment-options'; import { toPosixPath } from '../../../utils/path'; -import type { NormalizedEntryPoint, NormalizedLibraryOptions, SingleProgramCache } from '../types'; +import type { BuilderState } from '../builder-state'; +import type { LibraryCompilationOutput, NormalizedLibraryOptions } from '../types'; import { isDeclarationFile, isDeclarationSourceMapFile } from './utils'; const EMITTED_EXTENSIONS = ['.js', '.mjs', '.cjs', '.d.ts', '.d.mts', '.d.cts']; -/** - * Formatted diagnostic messages produced during library compilation. - */ -export interface LibraryCompilationDiagnostics { - /** Formatted compilation error messages. */ - readonly errors: string[]; - - /** Formatted compilation warning messages. */ - readonly warnings: string[]; -} - -/** - * Output of the unified library compilation step. - */ -export interface LibraryCompilationOutput { - /** Read-only map of emitted JavaScript files keyed by POSIX path. */ - readonly esmFiles: ReadonlyMap; - - /** Read-only map of emitted TypeScript declaration files keyed by POSIX path. */ - readonly dtsFiles: ReadonlyMap; - - /** Set of POSIX JavaScript file paths that were modified or newly emitted in this iteration. */ - readonly changedEsmFiles: ReadonlySet; - - /** Set of POSIX declaration file paths that were modified or newly emitted in this iteration. */ - readonly changedDtsFiles: ReadonlySet; - - /** Set of all POSIX source and dependency file paths referenced during compilation. */ - readonly referencedFiles: ReadonlySet; - - /** Cached compilation state for subsequent incremental builds. */ - readonly cache: SingleProgramCache; - - /** Whether any component stylesheet bundling errors occurred. */ - readonly hasStylesheetErrors: boolean; - - /** Promise that resolves to formatted compilation diagnostic errors and warnings. */ - readonly diagnosePromise: Promise; - - /** Effective declarationMap setting resolved from builder options and tsconfig. */ - readonly declarationMap: boolean; - - /** Effective compilationMode setting resolved from builder options and tsconfig. */ - readonly compilationMode: 'partial' | 'full'; -} - /** * Compiles all library entry points in a single TypeScript and Angular compilation pass. * - * @param entryPoints The collection of normalized library entry points to compile. * @param options The normalized library builder options with POSIX paths. * @param stylesheetBundler The component stylesheet bundler instance. - * @param cached Optional cached compilation state from a previous build iteration. + * @param buildState The build state tracking compilation caches and diagnostics. * @param modifiedFiles Optional set of modified POSIX file paths for incremental compilation. - * @returns A promise resolving to the compilation output containing emitted files and diagnostics. + * @returns A promise resolving to the compilation output containing emitted files and cache state. */ export async function compileLibrary( - entryPoints: Iterable, options: NormalizedLibraryOptions, stylesheetBundler: ComponentStylesheetBundler, - cached?: SingleProgramCache, + buildState: BuilderState, modifiedFiles?: Set, ): Promise { - const { tsConfigPath, compilationMode, preserveSymlinks, colors, declarationMap, cacheOptions } = - options; + const { + tsConfigPath, + entryPoints, + compilationMode, + preserveSymlinks, + colors, + declarationMap, + cacheOptions, + } = options; + const cached = buildState.singleProgramCache; const entryPathsMap: Record = {}; const rootFiles: string[] = []; - for (const ep of entryPoints) { + for (const ep of entryPoints.values()) { entryPathsMap[ep.displayName] = [ep.entryFilePath]; rootFiles.push(ep.entryFilePath); } @@ -98,12 +59,13 @@ export async function compileLibrary( try { let effectiveModifiedFiles = modifiedFiles; - if (cached?.failedFiles?.size) { + if (cached && cached.failedFiles.size > 0) { stylesheetBundler.invalidate(cached.failedFiles); - effectiveModifiedFiles = new Set(modifiedFiles); + const merged = new Set(modifiedFiles); for (const file of cached.failedFiles) { - effectiveModifiedFiles.add(file); + merged.add(file); } + effectiveModifiedFiles = merged; } if (effectiveModifiedFiles && effectiveModifiedFiles.size > 0) { @@ -168,6 +130,7 @@ export async function compileLibrary( stylesheetErrors, stylesheetWarnings, colors, + buildState, ); const esmFiles = cached?.esmFiles ?? new Map(); @@ -179,7 +142,7 @@ export async function compileLibrary( allReferencedFiles.add(toPosixPath(ref)); } - if (effectiveModifiedFiles) { + if (cached && effectiveModifiedFiles) { for (const modifiedFile of effectiveModifiedFiles) { if (allReferencedFiles.has(modifiedFile)) { continue; @@ -207,21 +170,15 @@ export async function compileLibrary( for (const { filename, contents } of emittedFiles) { const normalized = toPosixPath(filename); - if (normalized.endsWith('.map')) { - const isDtsMap = isDeclarationSourceMapFile(normalized); - const targetMap = isDtsMap ? dtsFiles : esmFiles; - if (targetMap.get(normalized) !== contents) { - targetMap.set(normalized, contents); - (isDtsMap ? changedDtsFiles : changedEsmFiles).add(normalized.slice(0, -4)); - } - } else if (isDeclarationFile(normalized)) { - if (dtsFiles.get(normalized) !== contents) { - changedDtsFiles.add(normalized); - dtsFiles.set(normalized, contents); - } - } else if (esmFiles.get(normalized) !== contents) { - changedEsmFiles.add(normalized); - esmFiles.set(normalized, contents); + const isMap = normalized.endsWith('.map'); + const isDts = isMap ? isDeclarationSourceMapFile(normalized) : isDeclarationFile(normalized); + const targetFiles = isDts ? dtsFiles : esmFiles; + + if (targetFiles.get(normalized) !== contents) { + targetFiles.set(normalized, contents); + (isDts ? changedDtsFiles : changedEsmFiles).add( + isMap ? normalized.slice(0, -4) : normalized, + ); } } @@ -235,7 +192,7 @@ export async function compileLibrary( compilationInstance, esmFiles, dtsFiles, - failedFiles: failedFiles.size > 0 ? failedFiles : undefined, + failedFiles, }, hasStylesheetErrors, diagnosePromise, @@ -251,49 +208,43 @@ export async function compileLibrary( } /** - * Formats stylesheet bundling diagnostics and TypeScript/Angular diagnostics. + * Formats stylesheet bundling diagnostics and TypeScript/Angular diagnostics + * and records them on the build state's execution result. * * @param compilationInstance The active Angular compilation instance. * @param stylesheetErrors List of stylesheet bundling errors. * @param stylesheetWarnings List of stylesheet bundling warnings. * @param colors Whether diagnostic messages should be formatted with ANSI colors. - * @returns A promise resolving to the formatted diagnostic errors and warnings. + * @param buildState The build state whose execution result receives the formatted diagnostics. */ async function runDiagnosticsAndFormat( compilationInstance: AngularCompilation, stylesheetErrors: PartialMessage[], stylesheetWarnings: PartialMessage[], colors: boolean, -): Promise { - const errorsOut: string[] = []; - const warningsOut: string[] = []; - - if (stylesheetErrors.length > 0) { - const formatted = await formatMessages(stylesheetErrors, { kind: 'error', color: colors }); - errorsOut.push(...formatted); - } else if (useTypeChecking) { - const { errors, warnings } = await compilationInstance.diagnoseFiles(); - if (errors?.length) { - const formatted = await formatMessages(errors, { kind: 'error', color: colors }); - errorsOut.push(...formatted); + buildState: BuilderState, +): Promise { + const { executionResult } = buildState; + const errors = [...stylesheetErrors]; + const warnings: PartialMessage[] = []; + + if (errors.length === 0 && useTypeChecking) { + const diagnostics = await compilationInstance.diagnoseFiles(); + if (diagnostics.errors?.length) { + errors.push(...diagnostics.errors); } - - if (warnings?.length) { - const formatted = await formatMessages(warnings, { kind: 'warning', color: colors }); - warningsOut.push(...formatted); + if (diagnostics.warnings?.length) { + warnings.push(...diagnostics.warnings); } } - if (stylesheetWarnings.length > 0) { - const formattedStyleWarnings = await formatMessages(stylesheetWarnings, { - kind: 'warning', - color: colors, - }); - warningsOut.push(...formattedStyleWarnings); + warnings.push(...stylesheetWarnings); + + if (errors.length > 0) { + executionResult.addErrors(await formatMessages(errors, { kind: 'error', color: colors })); } - return { - errors: errorsOut, - warnings: warningsOut, - }; + if (warnings.length > 0) { + executionResult.addWarnings(await formatMessages(warnings, { kind: 'warning', color: colors })); + } } diff --git a/packages/angular/build/src/builders/library/pipeline/entry-points.ts b/packages/angular/build/src/builders/library/pipeline/entry-points.ts index 5cff4ca82136..f50824c5d9f3 100644 --- a/packages/angular/build/src/builders/library/pipeline/entry-points.ts +++ b/packages/angular/build/src/builders/library/pipeline/entry-points.ts @@ -8,12 +8,8 @@ import path from 'node:path'; import { toPosixPath } from '../../../utils/path'; -import type { - NormalizedEntryPoint, - NormalizedLibraryOptions, - PackageJsonData, - SingleBuildState, -} from '../types'; +import type { BuilderState } from '../builder-state'; +import type { NormalizedEntryPoint, NormalizedLibraryOptions, PackageJsonData } from '../types'; import type { BundleEntryPointInput } from './bundler'; /** @@ -24,7 +20,7 @@ import type { BundleEntryPointInput } from './bundler'; * @returns The sanitized bundle base name. */ export function getEntryPointBundleName(packageName: string, entryPointName = '.'): string { - const isPrimary = !entryPointName || entryPointName === '.'; + const isPrimary = entryPointName === '.'; const pkgName = packageName[0] === '@' ? packageName.slice(1) : packageName; const epName = isPrimary ? pkgName : `${pkgName}-${entryPointName}`; @@ -50,11 +46,7 @@ function normalizeEntryPoint( projectRoot: string, packageName: string, ): NormalizedEntryPoint { - const name = isPrimary - ? '.' - : posixKey[0] === '.' && posixKey[1] === '/' - ? posixKey.slice(2) - : posixKey; + const name = isPrimary ? '.' : posixKey.startsWith('./') ? posixKey.slice(2) : posixKey; if (name !== '.' && (path.posix.isAbsolute(name) || name.includes('..'))) { throw new Error( @@ -139,7 +131,7 @@ export function normalizeEntryPoints( exportsRecord = { '.': rawExports }; } else { // If an object has no keys starting with '.', Node.js treats the entire object as the '.' entry point. - const hasSubpathKeys = Object.keys(rawExports as object).some((k) => k.startsWith('.')); + const hasSubpathKeys = Object.keys(rawExports).some((k) => k.startsWith('.')); exportsRecord = hasSubpathKeys ? (rawExports as Record) : { '.': rawExports }; } @@ -190,10 +182,7 @@ export function normalizeEntryPoints( usedBundleNames.set(entryPoint.bundleName, key); entryPoints.set(entryPoint.name, entryPoint); - - if (entryPoint.isPrimary) { - hasPrimary = true; - } + hasPrimary ||= isPrimary; } if (!hasPrimary) { @@ -206,7 +195,8 @@ export function normalizeEntryPoints( } /** - * Determines whether two sets of normalized entry points differ in keys, POSIX entry paths, or subpaths. + * Determines whether two sets of normalized entry points differ in keys, POSIX entry paths, + * subpaths, bundle names, or display names. * * @param oldEntryPoints The previous map of normalized entry points. * @param newEntryPoints The new map of normalized entry points. @@ -242,29 +232,36 @@ export function haveEntryPointsChanged( * @param packageJson The reloaded `package.json` data. * @param options The normalized library builder options. * @param buildState The state preserved across incremental builds. - * @param watchedCompilationFiles Set of POSIX file paths tracked for compilation. - * @param packageJsonPath Normalized POSIX path to `package.json`. */ export function updateWatchedEntryPoints( packageJson: PackageJsonData, options: NormalizedLibraryOptions, - buildState: SingleBuildState, - watchedCompilationFiles: Set, - packageJsonPath: string, + buildState: BuilderState, ): void { + const { packageJsonPath } = options; + if (!packageJson.name) { + throw new Error(`The package.json at '${packageJsonPath}' must contain a 'name'.`); + } + const newEntryPoints = normalizeEntryPoints( packageJson.exports, options.projectRoot, packageJsonPath, - options.packageName, + packageJson.name, ); + const { watchedCompilationFiles, previousBundleResults } = buildState; + if (haveEntryPointsChanged(options.entryPoints, newEntryPoints)) { + for (const oldEntryPoint of options.entryPoints.values()) { + watchedCompilationFiles.delete(oldEntryPoint.entryFilePath); + } + for (const entryPoint of newEntryPoints.values()) { watchedCompilationFiles.add(entryPoint.entryFilePath); } - for (const name of buildState.previousBundleResults.keys()) { + for (const name of previousBundleResults.keys()) { const oldEp = options.entryPoints.get(name); const newEp = newEntryPoints.get(name); if ( @@ -273,13 +270,16 @@ export function updateWatchedEntryPoints( newEp.entryFilePath !== oldEp.entryFilePath || newEp.bundleName !== oldEp.bundleName ) { - buildState.previousBundleResults.delete(name); + previousBundleResults.delete(name); } } options.entryPoints = newEntryPoints; buildState.hasEntryPointsChanges = true; } + + options.packageJson = packageJson; + options.packageName = packageJson.name; } /** @@ -288,15 +288,14 @@ export function updateWatchedEntryPoints( * * @param options The normalized library builder options. * @param buildState The state preserved across incremental builds. - * @param logs Array of informational log messages to append to when an entry point is queued. * @returns The list of entry points that require bundling in the current build iteration. */ export function collectEntryPointsToBundle( options: NormalizedLibraryOptions, - buildState: SingleBuildState, - logs: string[], + buildState: BuilderState, ): BundleEntryPointInput[] { - const { pendingChangedEsmFiles, pendingChangedDtsFiles, previousBundleResults } = buildState; + const { pendingChangedEsmFiles, pendingChangedDtsFiles, previousBundleResults, executionResult } = + buildState; const itemsToBundle: BundleEntryPointInput[] = []; for (const entryPoint of options.entryPoints.values()) { @@ -309,7 +308,7 @@ export function collectEntryPointsToBundle( hasEntryPointChanges(previousBundleResult.dtsModuleIds, pendingChangedDtsFiles); if (hasEsmChanges || hasDtsChanges) { - logs.push(`Compiling ${entryPoint.displayName}...`); + executionResult.addLog(`Compiling ${entryPoint.displayName}...`); itemsToBundle.push({ entryPoint, hasEsmChanges, diff --git a/packages/angular/build/src/builders/library/pipeline/entry-points_spec.ts b/packages/angular/build/src/builders/library/pipeline/entry-points_spec.ts index 834b7aec6835..e4653ef56e2b 100644 --- a/packages/angular/build/src/builders/library/pipeline/entry-points_spec.ts +++ b/packages/angular/build/src/builders/library/pipeline/entry-points_spec.ts @@ -6,16 +6,16 @@ * found in the LICENSE file at https://angular.dev/license */ -import { join, resolve } from 'node:path'; -import { toPosixPath } from '../../../utils/path'; +import { join } from 'node:path'; +import { BuilderState } from '../builder-state'; import type { BundleResult, NormalizedEntryPoint, NormalizedLibraryOptions, PackageJsonData, - SingleBuildState, } from '../types'; import { + collectEntryPointsToBundle, getEntryPointBundleName, haveEntryPointsChanged, normalizeEntryPoints, @@ -23,10 +23,19 @@ import { } from './entry-points'; describe('entry-points pipeline', () => { - const projectRoot = resolve('/workspace/projects/my-lib'); + const projectRoot = '/workspace/projects/my-lib'; const packageJsonPath = join(projectRoot, 'package.json'); const packageName = '@my-scope/my-lib'; + function createBundleResult(overrides: Partial = {}): BundleResult { + return { + esmModuleIds: new Set(), + dtsModuleIds: new Set(), + hasTslibImport: false, + ...overrides, + }; + } + describe('getEntryPointBundleName', () => { it('should compute bundle name for primary entry point without scope', () => { expect(getEntryPointBundleName('my-lib')).toBe('my-lib'); @@ -505,6 +514,8 @@ describe('entry-points pipeline', () => { }); describe('updateWatchedEntryPoints', () => { + const tsConfigPath = join(projectRoot, 'tsconfig.lib.json'); + it('should update options, watched files, build state, and prune removed bundles when entry points change', () => { const initialEntryPoints = normalizeEntryPoints( { @@ -520,17 +531,14 @@ describe('entry-points pipeline', () => { entryPoints: initialEntryPoints, projectRoot, packageName, + packageJsonPath, + tsConfigPath, + assets: [], } as unknown as NormalizedLibraryOptions; - const buildState = { - previousBundleResults: new Map([ - ['.', { esmModuleIds: new Set(), dtsModuleIds: new Set() }], - ['old-feature', { esmModuleIds: new Set(), dtsModuleIds: new Set() }], - ]), - hasEntryPointsChanges: false, - } as unknown as SingleBuildState; - - const watchedCompilationFiles = new Set(); + const buildState = new BuilderState(options); + buildState.previousBundleResults.set('.', createBundleResult()); + buildState.previousBundleResults.set('old-feature', createBundleResult()); const newPackageJson: PackageJsonData = { name: packageName, @@ -540,13 +548,7 @@ describe('entry-points pipeline', () => { }, }; - updateWatchedEntryPoints( - newPackageJson, - options, - buildState, - watchedCompilationFiles, - packageJsonPath, - ); + updateWatchedEntryPoints(newPackageJson, options, buildState); expect(buildState.hasEntryPointsChanges).toBeTrue(); expect(options.entryPoints.has('new-feature')).toBeTrue(); @@ -554,16 +556,17 @@ describe('entry-points pipeline', () => { expect(buildState.previousBundleResults.has('old-feature')).toBeFalse(); expect(buildState.previousBundleResults.has('.')).toBeTrue(); expect( - watchedCompilationFiles.has(toPosixPath(join(projectRoot, 'src/public-api.ts'))), + buildState.watchedCompilationFiles.has(join(projectRoot, 'src/public-api.ts')), ).toBeTrue(); expect( - watchedCompilationFiles.has( - toPosixPath(join(projectRoot, 'new-feature/src/public-api.ts')), - ), + buildState.watchedCompilationFiles.has(join(projectRoot, 'old-feature/src/public-api.ts')), + ).toBeFalse(); + expect( + buildState.watchedCompilationFiles.has(join(projectRoot, 'new-feature/src/public-api.ts')), ).toBeTrue(); }); - it('should not mutate buildState or options when entry points do not change', () => { + it('should not mutate buildState or options.entryPoints when entry points do not change', () => { const initialEntryPoints = normalizeEntryPoints( { '.': './src/public-api.ts', @@ -578,17 +581,14 @@ describe('entry-points pipeline', () => { entryPoints: initialEntryPoints, projectRoot, packageName, + packageJsonPath, + tsConfigPath, + assets: [], } as unknown as NormalizedLibraryOptions; - const buildState = { - previousBundleResults: new Map([ - ['.', { esmModuleIds: new Set(), dtsModuleIds: new Set() }], - ['feature', { esmModuleIds: new Set(), dtsModuleIds: new Set() }], - ]), - hasEntryPointsChanges: false, - } as unknown as SingleBuildState; - - const watchedCompilationFiles = new Set(); + const buildState = new BuilderState(options); + buildState.previousBundleResults.set('.', createBundleResult()); + buildState.previousBundleResults.set('feature', createBundleResult()); const samePackageJson: PackageJsonData = { name: packageName, @@ -598,17 +598,10 @@ describe('entry-points pipeline', () => { }, }; - updateWatchedEntryPoints( - samePackageJson, - options, - buildState, - watchedCompilationFiles, - packageJsonPath, - ); + updateWatchedEntryPoints(samePackageJson, options, buildState); expect(buildState.hasEntryPointsChanges).toBeFalse(); expect(options.entryPoints).toBe(initialEntryPoints); - expect(watchedCompilationFiles).toHaveSize(0); expect(buildState.previousBundleResults).toHaveSize(2); }); @@ -626,16 +619,13 @@ describe('entry-points pipeline', () => { entryPoints: initialEntryPoints, projectRoot, packageName, + packageJsonPath, + tsConfigPath, + assets: [], } as unknown as NormalizedLibraryOptions; - const buildState = { - previousBundleResults: new Map([ - ['.', { esmModuleIds: new Set(), dtsModuleIds: new Set() }], - ]), - hasEntryPointsChanges: false, - } as unknown as SingleBuildState; - - const watchedCompilationFiles = new Set(); + const buildState = new BuilderState(options); + buildState.previousBundleResults.set('.', createBundleResult()); const updatedPackageJson: PackageJsonData = { name: packageName, @@ -644,13 +634,7 @@ describe('entry-points pipeline', () => { }, }; - updateWatchedEntryPoints( - updatedPackageJson, - options, - buildState, - watchedCompilationFiles, - packageJsonPath, - ); + updateWatchedEntryPoints(updatedPackageJson, options, buildState); expect(buildState.hasEntryPointsChanges).toBeTrue(); expect(buildState.previousBundleResults.has('.')).toBeFalse(); @@ -658,7 +642,7 @@ describe('entry-points pipeline', () => { join(projectRoot, 'src/other-api.ts'), ); expect( - watchedCompilationFiles.has(toPosixPath(join(projectRoot, 'src/other-api.ts'))), + buildState.watchedCompilationFiles.has(join(projectRoot, 'src/other-api.ts')), ).toBeTrue(); }); @@ -676,16 +660,13 @@ describe('entry-points pipeline', () => { entryPoints: initialEntryPoints, projectRoot, packageName, + packageJsonPath, + tsConfigPath, + assets: [], } as unknown as NormalizedLibraryOptions; - const buildState = { - previousBundleResults: new Map([ - ['.', { esmModuleIds: new Set(), dtsModuleIds: new Set() }], - ]), - hasEntryPointsChanges: false, - } as unknown as SingleBuildState; - - const watchedCompilationFiles = new Set(); + const buildState = new BuilderState(options); + buildState.previousBundleResults.set('.', createBundleResult()); const updatedPackageJson: PackageJsonData = { name: '@renamed-scope/my-lib', @@ -694,19 +675,108 @@ describe('entry-points pipeline', () => { }, }; - options.packageName = updatedPackageJson.name; - - updateWatchedEntryPoints( - updatedPackageJson, - options, - buildState, - watchedCompilationFiles, - packageJsonPath, - ); + updateWatchedEntryPoints(updatedPackageJson, options, buildState); expect(buildState.hasEntryPointsChanges).toBeTrue(); expect(buildState.previousBundleResults.has('.')).toBeFalse(); + expect(options.packageName).toBe('@renamed-scope/my-lib'); expect(options.entryPoints.get('.')?.bundleName).toBe('renamed-scope-my-lib'); }); + + it('should throw when updated packageJson is missing a name field', () => { + const options = { + entryPoints: new Map(), + projectRoot, + packageName, + packageJsonPath, + assets: [], + } as unknown as NormalizedLibraryOptions; + const buildState = new BuilderState(options); + + expect(() => + updateWatchedEntryPoints({} as PackageJsonData, options, buildState), + ).toThrowError(/must contain a 'name'/); + }); + }); + + describe('collectEntryPointsToBundle', () => { + it('should return all entry points with ESM and DTS changes on initial build', () => { + const entryPoints = normalizeEntryPoints( + { + '.': './src/public-api.ts', + './testing': './testing/src/public-api.ts', + }, + projectRoot, + packageJsonPath, + packageName, + ); + const options = { entryPoints } as unknown as NormalizedLibraryOptions; + const buildState = new BuilderState(options); + + const items = collectEntryPointsToBundle(options, buildState); + + expect(items).toHaveSize(2); + expect(items[0]).toEqual({ + entryPoint: jasmine.objectContaining({ name: '.' }), + previousBundleResult: undefined, + hasEsmChanges: true, + hasDtsChanges: true, + }); + expect(items[1]).toEqual({ + entryPoint: jasmine.objectContaining({ name: 'testing' }), + previousBundleResult: undefined, + hasEsmChanges: true, + hasDtsChanges: true, + }); + expect(buildState.executionResult.logs).toEqual([ + 'Compiling @my-scope/my-lib...', + 'Compiling @my-scope/my-lib/testing...', + ]); + }); + + it('should only return entry points whose ESM or DTS module IDs intersect pending changes', () => { + const entryPoints = normalizeEntryPoints( + { + '.': './src/public-api.ts', + './testing': './testing/src/public-api.ts', + }, + projectRoot, + packageJsonPath, + packageName, + ); + const options = { entryPoints } as unknown as NormalizedLibraryOptions; + const buildState = new BuilderState(options); + + const primaryEntryJs = join(projectRoot, 'src/public-api.js'); + const primaryEntryDts = join(projectRoot, 'src/public-api.d.ts'); + const testingEntryJs = join(projectRoot, 'testing/src/public-api.js'); + const testingEntryDts = join(projectRoot, 'testing/src/public-api.d.ts'); + + buildState.previousBundleResults.set( + '.', + createBundleResult({ + esmModuleIds: new Set([primaryEntryJs]), + dtsModuleIds: new Set([primaryEntryDts]), + }), + ); + buildState.previousBundleResults.set( + 'testing', + createBundleResult({ + esmModuleIds: new Set([testingEntryJs]), + dtsModuleIds: new Set([testingEntryDts]), + }), + ); + + buildState.pendingChangedEsmFiles.add(testingEntryJs); + + const items = collectEntryPointsToBundle(options, buildState); + + expect(items).toHaveSize(1); + expect(items[0]?.entryPoint.name).toBe('testing'); + expect(items[0]?.hasEsmChanges).toBeTrue(); + expect(items[0]?.hasDtsChanges).toBeFalse(); + expect(items[0]?.previousBundleResult).toBe(buildState.previousBundleResults.get('testing')); + expect(buildState.executionResult.logs).toEqual(['Compiling @my-scope/my-lib/testing...']); + }); }); }); diff --git a/packages/angular/build/src/builders/library/pipeline/package-manifests.ts b/packages/angular/build/src/builders/library/pipeline/package-manifests.ts index 98ed88a506e6..5238ccca76c2 100644 --- a/packages/angular/build/src/builders/library/pipeline/package-manifests.ts +++ b/packages/angular/build/src/builders/library/pipeline/package-manifests.ts @@ -78,13 +78,10 @@ export async function generatePackageManifests( }; if (hasTslibImport && !rawPackageJson.dependencies?.['tslib']) { - const tslibVersion = await getAngularTslibRange(options.workspaceRoot); - if (tslibVersion) { - distPackageJson.dependencies = { - ...rawPackageJson.dependencies, - tslib: tslibVersion, - }; - } + distPackageJson.dependencies = { + ...rawPackageJson.dependencies, + tslib: await getAngularTslibRange(options.workspaceRoot), + }; } // Retain scripts if keepLifecycleScripts is set @@ -159,6 +156,11 @@ export async function generatePackageManifests( /** * Creates or updates export conditions for an entry point, preserving custom user-defined conditions. + * + * @param existingConditions Existing export conditions from the user's `package.json`. + * @param dtsPath Relative POSIX path to the bundled `.d.ts` file. + * @param fesmPath Relative POSIX path to the bundled FESM `.mjs` file. + * @returns The merged export conditions object. */ function createExportConditions( existingConditions: unknown, diff --git a/packages/angular/build/src/builders/library/types.ts b/packages/angular/build/src/builders/library/types.ts index 2deeddf589e5..2d2d9f61891d 100644 --- a/packages/angular/build/src/builders/library/types.ts +++ b/packages/angular/build/src/builders/library/types.ts @@ -9,7 +9,7 @@ import type { AngularCompilation } from '../../tools/angular/compilation'; import type { StylesheetPluginsass } from '../../tools/esbuild/stylesheets/stylesheet-plugin-factory'; import type { normalizeAssetPatterns } from '../../utils'; -import type { normalizeCacheOptions } from '../../utils/normalize-cache'; +import type { NormalizedCachedOptions } from '../../utils/normalize-cache'; import type { PostcssConfiguration } from '../../utils/postcss-configuration'; /** @@ -68,12 +68,16 @@ export interface NormalizedLibraryOptions { /** Absolute POSIX path to the library project root directory. */ projectRoot: string; + /** Name of the npm package from the library's `package.json`. */ packageName: string; + + /** Parsed contents of the library's `package.json`. */ packageJson: PackageJsonData; /** Absolute POSIX path to the build output directory. */ outputPath: string; + /** Whether to delete the output directory before building. */ deleteOutputPath: boolean; /** Absolute POSIX path to the library's `package.json`. */ @@ -82,29 +86,58 @@ export interface NormalizedLibraryOptions { /** Absolute POSIX path to the TypeScript configuration file. */ tsConfigPath: string; + /** Map of normalized entry points keyed by entry point name. */ entryPoints: Map; + + /** Default stylesheet language for inline component styles. */ inlineStyleLanguage: 'css' | 'less' | 'sass' | 'scss'; /** Absolute POSIX paths to style preprocessor include directories. */ styleIncludePaths: string[]; + /** Optional Sass preprocessor configuration. */ sass?: StylesheetPluginsass; /** Normalized asset patterns with POSIX `input` and `output` paths. */ assets: ReturnType; + /** Angular compilation mode (`'partial'` or `'full'`). */ compilationMode?: 'partial' | 'full'; + + /** Whether to generate source maps for TypeScript declaration files. */ declarationMap?: boolean; + + /** Regular expressions matching allowed non-peer dependencies. */ allowedNonPeerDependencies: RegExp[]; + + /** Whether to preserve lifecycle scripts in the emitted `package.json`. */ keepLifecycleScripts: boolean; + + /** Whether to run the build in watch mode. */ watch: boolean; + + /** Optional file watching polling interval in milliseconds. */ poll?: number; + + /** Whether to preserve symbolic links during resolution and bundling. */ preserveSymlinks: boolean; + + /** Whether to display build progress in the terminal. */ progress: boolean; + + /** Whether to clear the terminal screen before watch rebuilds. */ clearScreen?: boolean; - cacheOptions: ReturnType; + + /** Normalized build cache configuration. */ + cacheOptions: NormalizedCachedOptions; + + /** Resolved PostCSS configuration, if present in the workspace. */ postcssConfiguration?: { config: PostcssConfiguration; configPath: string }; + + /** Resolved Tailwind CSS configuration, if applicable. */ tailwindConfiguration?: { file: string; package: string }; + + /** Whether terminal color output is enabled. */ colors: boolean; } @@ -135,41 +168,41 @@ export interface SingleProgramCache { /** In-memory map of emitted TypeScript declaration files keyed by POSIX path. */ readonly dtsFiles: Map; - /** Set of POSIX file paths that failed during stylesheet bundling or compilation. */ - readonly failedFiles?: ReadonlySet; + /** Set of POSIX file paths that failed during stylesheet bundling. */ + readonly failedFiles: ReadonlySet; } /** - * State preserved across incremental builds in watch mode. + * Output of the unified library compilation step. */ -export interface SingleBuildState { - /** Cached unified TypeScript and Angular compilation state. */ - singleProgramCache?: SingleProgramCache; +export interface LibraryCompilationOutput { + /** Read-only map of emitted JavaScript files keyed by POSIX path. */ + readonly esmFiles: ReadonlyMap; - /** Effective compilation mode resolved from builder options and tsconfig. */ - compilationMode?: 'partial' | 'full'; + /** Read-only map of emitted TypeScript declaration files keyed by POSIX path. */ + readonly dtsFiles: ReadonlyMap; - /** Map of entry point names to their previous bundle results. */ - previousBundleResults: Map; + /** Set of POSIX JavaScript file paths that were added, modified, or deleted in this iteration. */ + readonly changedEsmFiles: ReadonlySet; - /** Set of changed POSIX ESM file paths pending bundling. */ - pendingChangedEsmFiles: Set; + /** Set of POSIX declaration file paths that were added, modified, or deleted in this iteration. */ + readonly changedDtsFiles: ReadonlySet; - /** Set of changed POSIX TypeScript declaration file paths pending bundling. */ - pendingChangedDtsFiles: Set; + /** Set of all POSIX source and dependency file paths referenced during compilation. */ + readonly referencedFiles: ReadonlySet; - /** Whether the previous build iteration encountered a compilation or diagnostic error. */ - hasCompilationError?: boolean; + /** Cached compilation state for subsequent incremental builds. */ + readonly cache: SingleProgramCache; - /** Whether package.json and secondary entry point manifests have been emitted. */ - hasEmittedManifests?: boolean; + /** Whether any component stylesheet bundling errors occurred. */ + readonly hasStylesheetErrors: boolean; - /** Whether the last emitted root package.json included a tslib dependency. */ - hasEmittedTslib?: boolean; + /** Promise that resolves when compilation diagnostics have been formatted and recorded. */ + readonly diagnosePromise: Promise; - /** Whether static assets have been emitted in a prior iteration. */ - hasEmittedAssets?: boolean; + /** Effective declarationMap setting resolved from builder options and tsconfig. */ + readonly declarationMap: boolean; - /** Whether entry points in package.json changed since the last compilation. */ - hasEntryPointsChanges?: boolean; + /** Effective compilationMode setting resolved from builder options and tsconfig. */ + readonly compilationMode: 'partial' | 'full'; } From d2233e225aa5fd507e3ce7bfd35ae2268c036aa4 Mon Sep 17 00:00:00 2001 From: Charles Lyding <19598772+clydin@users.noreply.github.com> Date: Wed, 14 Oct 2026 16:54:52 -0400 Subject: [PATCH 625/787] fix(@angular/build): coalesce external watcher directories to avoid macOS FSEvents limit Previously, `ParcelExternalManager` immediately created a separate `@parcel/watcher` subscription for the parent directory of every watched file outside the workspace root. In monorepo setups where an application imports from hundreds of external library directories and hoisted `node_modules` packages, this exceeded macOS's ~512 per-process `FSEvents` stream limit, causing subsequent subscriptions to silently fail and miss file changes. To prevent exhausting native watcher streams, `ParcelExternalManager` now normalizes external `node_modules` file paths to their package root directory and batches synchronous file additions and removals within a microtask so nested child directories are subsumed before subscribing. When the number of external target directories exceeds the subscription budget of 256, a prefix tree is used to iteratively collapse the deepest branching subdirectories into common ancestors while preferring directories that do not contain `workspaceRoot`. Additionally, if `parcelWatcher.subscribe()` rejects for an existing directory on disk, the manager dynamically lowers its subscription budget and re-reconciles into higher-level ancestor directories. Closes #34246 --- packages/angular/build/BUILD.bazel | 1 + packages/angular/build/src/utils/watcher.ts | 582 +++++++++++++++--- .../angular/build/src/utils/watcher_spec.ts | 361 +++++++++++ 3 files changed, 866 insertions(+), 78 deletions(-) diff --git a/packages/angular/build/BUILD.bazel b/packages/angular/build/BUILD.bazel index bf6c034292df..d0ab55750e98 100644 --- a/packages/angular/build/BUILD.bazel +++ b/packages/angular/build/BUILD.bazel @@ -153,6 +153,7 @@ ts_project( ":build", ":node_modules/@angular-devkit/core", ":node_modules/@babel/core", + ":node_modules/@parcel/watcher", ":node_modules/oxc-parser", "//:node_modules/@angular/compiler-cli", "//:node_modules/@angular/router", diff --git a/packages/angular/build/src/utils/watcher.ts b/packages/angular/build/src/utils/watcher.ts index 610051c5dcc7..ca0e86f987ff 100644 --- a/packages/angular/build/src/utils/watcher.ts +++ b/packages/angular/build/src/utils/watcher.ts @@ -419,89 +419,364 @@ export function extractNodeModulesPackageDir(posixPath: string): string | undefi return `${nodeModulesPath}/${segments[0]}`; } -class ParcelExternalManager { - private readonly extraSubscriptions = new Map(); - private readonly pendingSubscriptions = new Map< - string, - Promise - >(); - private readonly externalDirFiles = new Map }>(); +/** + * Maximum number of concurrent external directory subscriptions before coalescing + * sibling/cousin directories into common ancestor directories. + * Kept well below macOS's ~512 per-process FSEvents stream limit. + */ +const DEFAULT_MAX_EXTERNAL_SUBSCRIPTIONS = 256; + +/** + * Node in a directory prefix tree used to subsume nested directories + * and coalesce sibling/cousin directories into common ancestors. + */ +interface DirTrieNode { + /** Case-normalized POSIX path key for set/map lookups. */ + dirKey: string; + + /** Original-case POSIX directory path passed to `@parcel/watcher`. */ + dirPath: string; + + /** Depth of this directory node from the filesystem root (0 at root). */ + depth: number; + + /** Parent directory node, or `undefined` if this node is a filesystem root. */ + parent: DirTrieNode | undefined; + + /** Child directory nodes keyed by their `dirKey`. */ + children: Map; + + /** Whether this directory is selected as an active subscription target. */ + isTarget: boolean; + + /** Number of active target leaf directories within this node's subtree. */ + leafCount: number; +} + +/** + * Checks whether any strict ancestor of the given trie node is already marked as a target. + */ +function hasTargetAncestor(node: DirTrieNode): boolean { + let current = node.parent; + while (current) { + if (current.isTarget) { + return true; + } + current = current.parent; + } + + return false; +} + +/** + * Manages `@parcel/watcher` directory subscriptions for watched files located outside the + * primary `workspaceRoot`. + * + * Because `@parcel/watcher` watches directories recursively and macOS limits each process to + * ~512 concurrent `FSEvents` streams, this manager: + * - Normalizes external `node_modules` file paths to their package root directory. + * - Batches synchronous `watchFile` and `removeFile` calls within a microtask before subscribing. + * - Uses a directory prefix tree to subsume nested child directories and iteratively coalesce + * deepest branching subdirectories into common ancestors when the subscription budget is exceeded. + * - Dynamically lowers its subscription budget and coalesces further if `subscribe()` fails on + * an existing directory due to OS stream limits. + */ +export class ParcelExternalManager { + /** Active `@parcel/watcher` subscriptions keyed by subscribed directory lookup key. */ + readonly #extraSubscriptions = new Map(); + + /** Reference-counted watched files grouped by their target external directory lookup key. */ + readonly #externalDirFiles = new Map }>(); + + /** Reverse lookup mapping each watched file lookup key to its target directory lookup key. */ + readonly #fileToDirKey = new Map(); + + /** The `@parcel/watcher` module instance. */ + readonly #parcelWatcher: typeof ParcelWatcher; + + /** Watcher configuration options including ignore patterns. */ + readonly #options: WatcherOptions | undefined; + + /** Normalized POSIX path of the primary watched workspace root. */ + readonly #rootDirPosix: string; + + /** Case-normalized lookup key of the primary watched workspace root. */ + readonly #rootDirLookupKey: string; + + /** Whether the underlying filesystem is case-sensitive. */ + readonly #isCaseSensitive: boolean; + + /** Callback invoked when `@parcel/watcher` emits filesystem events. */ + readonly #handleEvents: (events: ParcelWatcher.Event[]) => void; + + /** Current maximum number of concurrent external directory subscriptions allowed before coalescing. */ + #maxSubscriptions: number; + + /** Whether external directory state has changed and requires a reconciliation pass. */ + #needsReconcile = false; + + /** Whether obsolete subscriptions should be unsubscribed before creating new ones (used after stream limit errors). */ + #shrinkBeforeSubscribe = false; + /** In-flight promise for the currently scheduled or running reconciliation loop. */ + #reconcilePromise: Promise | undefined; + + /** Whether this manager has been closed. */ + #isClosed = false; + + /** + * Creates a new external directory subscription manager for `@parcel/watcher`. + * + * @param parcelWatcher The `@parcel/watcher` module. + * @param options Watcher configuration options. + * @param rootDirPosix Normalized POSIX path of the primary workspace root. + * @param rootDirLookupKey Case-normalized lookup key of the primary workspace root. + * @param isCaseSensitive Whether the filesystem at the workspace root is case-sensitive. + * @param handleEvents Callback to process incoming `@parcel/watcher` events. + * @param maxSubscriptions Maximum number of concurrent external directory subscriptions before coalescing. + */ constructor( - private readonly parcelWatcher: typeof ParcelWatcher, - private readonly options: WatcherOptions | undefined, - private readonly rootDirLookupKey: string, - private readonly handleEvents: (events: ParcelWatcher.Event[]) => void, - ) {} + parcelWatcher: typeof ParcelWatcher, + options: WatcherOptions | undefined, + rootDirPosix: string, + rootDirLookupKey: string, + isCaseSensitive: boolean, + handleEvents: (events: ParcelWatcher.Event[]) => void, + maxSubscriptions = DEFAULT_MAX_EXTERNAL_SUBSCRIPTIONS, + ) { + this.#parcelWatcher = parcelWatcher; + this.#options = options; + this.#rootDirPosix = rootDirPosix; + this.#rootDirLookupKey = rootDirLookupKey; + this.#isCaseSensitive = isCaseSensitive; + this.#handleEvents = handleEvents; + this.#maxSubscriptions = Math.max(1, maxSubscriptions); + } - async ensureWatched(posixPath: string, lookupKey: string): Promise { - if (isPathInside(lookupKey, this.rootDirLookupKey) || lookupKey === this.rootDirLookupKey) { + /** + * Registers a file path to be watched if it resides outside the primary workspace root, + * and schedules an asynchronous subscription reconciliation pass if needed. + * + * @param posixPath Normalized POSIX file path preserving original casing. + * @param lookupKey Case-normalized lookup key for the file path. + */ + watchFile(posixPath: string, lookupKey: string): void { + if ( + this.#isClosed || + isPathInside(lookupKey, this.#rootDirLookupKey) || + lookupKey === this.#rootDirLookupKey + ) { return; } - const dirPath = getDirectoryPath(posixPath); - const dirKey = getDirectoryPath(lookupKey); - let dirEntry = this.externalDirFiles.get(dirKey); + const pkgDir = extractNodeModulesPackageDir(posixPath); + const dirPath = pkgDir ?? getDirectoryPath(posixPath); + const dirKey = pkgDir + ? toLookupKey(pkgDir, this.#isCaseSensitive) + : getDirectoryPath(lookupKey); + + this.#fileToDirKey.set(lookupKey, dirKey); + + let dirEntry = this.#externalDirFiles.get(dirKey); + const isNewDir = !dirEntry; if (!dirEntry) { dirEntry = { dirPath, files: new Set() }; - this.externalDirFiles.set(dirKey, dirEntry); + this.#externalDirFiles.set(dirKey, dirEntry); } dirEntry.files.add(lookupKey); - await this.ensureDirWatched(dirPath, dirKey); + if (isNewDir || !this.#isCoveredByActiveSubscription(dirKey)) { + this.#scheduleReconcile(); + } } + /** + * Unregisters a previously watched external file and schedules a reconciliation pass + * if it was the last watched file in its target directory. + * + * @param lookupKey Case-normalized lookup key for the file path to remove. + */ removeFile(lookupKey: string): void { - if (isPathInside(lookupKey, this.rootDirLookupKey) || lookupKey === this.rootDirLookupKey) { + const dirKey = this.#fileToDirKey.get(lookupKey); + if (!dirKey) { return; } - const dirKey = getDirectoryPath(lookupKey); - const dirEntry = this.externalDirFiles.get(dirKey); + this.#fileToDirKey.delete(lookupKey); + const dirEntry = this.#externalDirFiles.get(dirKey); if (dirEntry) { dirEntry.files.delete(lookupKey); if (dirEntry.files.size === 0) { - this.externalDirFiles.delete(dirKey); - const sub = this.extraSubscriptions.get(dirKey); - if (sub) { - this.extraSubscriptions.delete(dirKey); - sub.unsubscribe().catch(() => {}); - - for (const [remainingDirKey, remainingDirEntry] of this.externalDirFiles.entries()) { - if (!this.isCoveredByExistingExternal(remainingDirKey)) { - this.ensureDirWatched(remainingDirEntry.dirPath, remainingDirKey).catch(() => {}); - } - } - } + this.#externalDirFiles.delete(dirKey); + this.#scheduleReconcile(); } } } + /** + * Waits for any scheduled or in-progress subscription reconciliation pass to complete. + */ + async flush(): Promise { + if (this.#reconcilePromise) { + await this.#reconcilePromise; + } + } + + /** + * Closes the manager, awaiting any pending reconciliation and unsubscribing all active + * external directory subscriptions. + */ async close(): Promise { + this.#isClosed = true; + this.#needsReconcile = false; try { - if (this.pendingSubscriptions.size > 0) { - await Promise.allSettled(Array.from(this.pendingSubscriptions.values())); + if (this.#reconcilePromise) { + await this.#reconcilePromise.catch(() => {}); } - if (this.extraSubscriptions.size > 0) { + if (this.#extraSubscriptions.size > 0) { await Promise.allSettled( - Array.from(this.extraSubscriptions.values()).map((sub) => sub.unsubscribe()), + Array.from(this.#extraSubscriptions.values(), (sub) => sub.unsubscribe()), ); } } finally { - this.extraSubscriptions.clear(); - this.pendingSubscriptions.clear(); - this.externalDirFiles.clear(); + this.#extraSubscriptions.clear(); + this.#externalDirFiles.clear(); + this.#fileToDirKey.clear(); } } - private isCoveredByExistingExternal(dirLookupKey: string): boolean { - for (const existingDir of this.extraSubscriptions.keys()) { - if (dirLookupKey === existingDir || isPathInside(dirLookupKey, existingDir)) { - return true; + /** + * Schedules a microtask to reconcile active `@parcel/watcher` subscriptions with the + * current set of external directories. + */ + #scheduleReconcile(): void { + if (this.#isClosed) { + return; + } + + this.#needsReconcile = true; + this.#reconcilePromise ??= Promise.resolve() + .then(() => this.#runReconcileLoop()) + .finally(() => { + this.#reconcilePromise = undefined; + }); + } + + /** + * Continuously executes reconciliation passes until no further changes are pending. + */ + async #runReconcileLoop(): Promise { + while (this.#needsReconcile && !this.#isClosed) { + this.#needsReconcile = false; + await this.#reconcileOnce(); + } + } + + /** + * Performs a single reconciliation pass: computes the desired coalesced directory set, + * subscribes to newly required directories, unsubscribes obsolete directories, and + * triggers fallback coalescing if OS stream limits are encountered. + */ + async #reconcileOnce(): Promise { + const desiredDirs = this.#computeDesiredDirectories(); + + if (this.#shrinkBeforeSubscribe) { + this.#shrinkBeforeSubscribe = false; + const toUnsubscribe: Promise[] = []; + for (const [existingKey, sub] of this.#extraSubscriptions.entries()) { + if (!desiredDirs.has(existingKey)) { + this.#extraSubscriptions.delete(existingKey); + toUnsubscribe.push(sub.unsubscribe().catch(() => {})); + } + } + if (toUnsubscribe.length > 0) { + await Promise.allSettled(toUnsubscribe); } } - for (const pendingDir of this.pendingSubscriptions.keys()) { - if (dirLookupKey === pendingDir || isPathInside(dirLookupKey, pendingDir)) { + + if (this.#isClosed) { + return; + } + + const toSubscribe: [string, string][] = []; + for (const [dirKey, dirPath] of desiredDirs.entries()) { + if (!this.#extraSubscriptions.has(dirKey)) { + toSubscribe.push([dirKey, dirPath]); + } + } + + let hadExistingDirFailure = false; + if (toSubscribe.length > 0) { + await Promise.allSettled( + toSubscribe.map(async ([dirKey, dirPath]) => { + const ignore = isPathInside(this.#rootDirLookupKey, dirKey) + ? [...(this.#options?.ignored ?? []), this.#rootDirPosix, `${this.#rootDirPosix}/**`] + : this.#options?.ignored; + + try { + const sub = await this.#parcelWatcher.subscribe( + dirPath, + (err, events) => { + if (!err) { + this.#handleEvents(events); + } + }, + { ignore }, + ); + + if (this.#isClosed) { + await sub.unsubscribe().catch(() => {}); + + return; + } + + this.#extraSubscriptions.set(dirKey, sub); + } catch { + // Ignore errors for missing directories; if the directory exists on disk, + // mark failure so the manager can coalesce further if over OS stream limits. + if (!this.#isClosed && fs.existsSync(dirPath)) { + hadExistingDirFailure = true; + } + } + }), + ); + } + + if (this.#isClosed) { + return; + } + + // Unsubscribe any previous subscriptions that are no longer desired and whose + // remaining watched files (if any) are now covered by another active subscription. + for (const [existingKey, sub] of this.#extraSubscriptions.entries()) { + if (!desiredDirs.has(existingKey) && this.#canRemoveSubscription(existingKey)) { + this.#extraSubscriptions.delete(existingKey); + sub.unsubscribe().catch(() => {}); + } + } + + // If subscribing to an existing directory failed (e.g. macOS FSEvents per-process limit), + // dynamically lower the subscription budget and re-reconcile to coalesce into ancestors. + if (hadExistingDirFailure && desiredDirs.size > 1 && this.#maxSubscriptions > 1) { + const nextMax = + this.#extraSubscriptions.size > 0 + ? Math.max(1, Math.floor(this.#extraSubscriptions.size / 2)) + : Math.max(1, Math.floor(Math.min(this.#maxSubscriptions, desiredDirs.size) / 2)); + + if (nextMax < desiredDirs.size && nextMax < this.#maxSubscriptions) { + this.#maxSubscriptions = nextMax; + this.#shrinkBeforeSubscribe = true; + this.#needsReconcile = true; + } + } + } + + /** + * Checks whether a directory lookup key is already covered by an active subscription. + */ + #isCoveredByActiveSubscription(dirLookupKey: string): boolean { + for (const existingDir of this.#extraSubscriptions.keys()) { + if (dirLookupKey === existingDir || isPathInside(dirLookupKey, existingDir)) { return true; } } @@ -509,47 +784,196 @@ class ParcelExternalManager { return false; } - private async ensureDirWatched(dirPath: string, dirKey: string): Promise { - if (this.isCoveredByExistingExternal(dirKey)) { - return; + /** + * Determines whether an existing subscription can be safely removed without leaving + * any remaining watched target directories uncovered. + */ + #canRemoveSubscription(subKey: string): boolean { + for (const targetDirKey of this.#externalDirFiles.keys()) { + if (targetDirKey === subKey || isPathInside(targetDirKey, subKey)) { + let coveredByOther = false; + for (const otherSubKey of this.#extraSubscriptions.keys()) { + if ( + otherSubKey !== subKey && + (targetDirKey === otherSubKey || isPathInside(targetDirKey, otherSubKey)) + ) { + coveredByOther = true; + break; + } + } + if (!coveredByOther) { + return false; + } + } + } + + return true; + } + + /** + * Computes the minimal set of external directories to subscribe to (mapped from `dirKey` to `dirPath`), + * subsuming nested directories and coalescing branching ancestors to stay within `#maxSubscriptions`. + */ + #computeDesiredDirectories(): Map { + if (this.#externalDirFiles.size === 0) { + return new Map(); } - const subPromise = this.parcelWatcher.subscribe( - dirPath, - (err, events) => { - if (!err) { - this.handleEvents(events); + const nodesByKey = new Map(); + const roots: DirTrieNode[] = []; + + for (const [dirKey, { dirPath }] of this.#externalDirFiles.entries()) { + const chain: { dirKey: string; dirPath: string }[] = []; + let currentKey = dirKey; + let currentPath = dirPath; + while (true) { + chain.push({ dirKey: currentKey, dirPath: currentPath }); + const parentKey = getDirectoryPath(currentKey); + if (parentKey === currentKey) { + break; } - }, - { - ignore: this.options?.ignored, - }, - ); + currentKey = parentKey; + currentPath = getDirectoryPath(currentPath); + } - this.pendingSubscriptions.set(dirKey, subPromise); + let parentNode: DirTrieNode | undefined; + for (let i = chain.length - 1; i >= 0; i--) { + const { dirKey: nodeKey, dirPath: nodePath } = chain[i]; + const depth = chain.length - 1 - i; + let node = nodesByKey.get(nodeKey); + if (!node) { + node = { + dirKey: nodeKey, + dirPath: nodePath, + depth, + parent: parentNode, + children: new Map(), + isTarget: false, + leafCount: 0, + }; + nodesByKey.set(nodeKey, node); + if (parentNode) { + parentNode.children.set(nodeKey, node); + } else { + roots.push(node); + } + } + parentNode = node; + } - try { - const sub = await subPromise; - this.pendingSubscriptions.delete(dirKey); + if (parentNode) { + parentNode.isTarget = true; + } + } - if (this.externalDirFiles.has(dirKey) && !this.isCoveredByExistingExternal(dirKey)) { - this.extraSubscriptions.set(dirKey, sub); + const initSubtree = (node: DirTrieNode): number => { + if (node.isTarget) { + node.children.clear(); + node.leafCount = 1; - // Subsume any nested child subscriptions that are now covered by this parent subscription - for (const [childDir, childSub] of this.extraSubscriptions.entries()) { - if (childDir !== dirKey && isPathInside(childDir, dirKey)) { - this.extraSubscriptions.delete(childDir); - childSub.unsubscribe().catch(() => {}); + return 1; + } + + let count = 0; + for (const child of node.children.values()) { + count += initSubtree(child); + } + node.leafCount = count; + + return count; + }; + + let totalLeaves = 0; + for (const root of roots) { + totalLeaves += initSubtree(root); + } + + if (totalLeaves > this.#maxSubscriptions) { + // Tier 1: non-ancestors of workspaceRoot (e.g., /libs, /node_modules) + // Tier 2: ancestors of workspaceRoot (e.g., when sibling apps/libs are directly under it) + const tier1ByDepth = new Map(); + const tier2ByDepth = new Map(); + + const collectInternalNodes = (node: DirTrieNode) => { + if (node.isTarget) { + return; + } + if (node.parent !== undefined && node.leafCount > 1) { + const isWorkspaceAncestor = isPathInside(this.#rootDirLookupKey, node.dirKey); + const bucketMap = isWorkspaceAncestor ? tier2ByDepth : tier1ByDepth; + let bucket = bucketMap.get(node.depth); + if (!bucket) { + bucket = []; + bucketMap.set(node.depth, bucket); } + bucket.push(node); } - } else { - sub.unsubscribe().catch(() => {}); + for (const child of node.children.values()) { + collectInternalNodes(child); + } + }; + + for (const root of roots) { + collectInternalNodes(root); + } + + const collapseTier = (byDepth: Map) => { + const sortedLevels = Array.from(byDepth.entries()).sort(([a], [b]) => b - a); + for (const [, nodes] of sortedLevels) { + if (totalLeaves <= this.#maxSubscriptions) { + return; + } + + const candidates = nodes + .filter((n) => n.leafCount > 1 && !hasTargetAncestor(n)) + .sort((a, b) => b.leafCount - a.leafCount || a.dirKey.localeCompare(b.dirKey)); + + for (const candidate of candidates) { + if (totalLeaves <= this.#maxSubscriptions) { + return; + } + if (candidate.leafCount <= 1 || hasTargetAncestor(candidate)) { + continue; + } + + const reduction = candidate.leafCount - 1; + candidate.isTarget = true; + candidate.children.clear(); + candidate.leafCount = 1; + totalLeaves -= reduction; + + let ancestor = candidate.parent; + while (ancestor) { + ancestor.leafCount -= reduction; + ancestor = ancestor.parent; + } + } + } + }; + + collapseTier(tier1ByDepth); + if (totalLeaves > this.#maxSubscriptions) { + collapseTier(tier2ByDepth); } - } catch { - // Ignore subscription errors for missing or restricted external directories - } finally { - this.pendingSubscriptions.delete(dirKey); } + + const desired = new Map(); + const collectTargets = (node: DirTrieNode) => { + if (node.isTarget) { + desired.set(node.dirKey, node.dirPath); + + return; + } + for (const child of node.children.values()) { + collectTargets(child); + } + }; + + for (const root of roots) { + collectTargets(root); + } + + return desired; } } @@ -609,7 +1033,9 @@ async function createParcelWatcher( const externalManager = new ParcelExternalManager( parcelWatcher, options, + rootDirPosix, rootDirLookupKey, + isCaseSensitive, handleEvents, ); @@ -629,7 +1055,7 @@ async function createParcelWatcher( const lookupKey = toLookupKey(posixPath, isCaseSensitive); if (!watchedFiles.has(lookupKey)) { watchedFiles.add(lookupKey); - void externalManager.ensureWatched(posixPath, lookupKey); + externalManager.watchFile(posixPath, lookupKey); } } }, diff --git a/packages/angular/build/src/utils/watcher_spec.ts b/packages/angular/build/src/utils/watcher_spec.ts index 547ad2695f90..3703eb9f4ce1 100644 --- a/packages/angular/build/src/utils/watcher_spec.ts +++ b/packages/angular/build/src/utils/watcher_spec.ts @@ -6,6 +6,7 @@ * found in the LICENSE file at https://angular.dev/license */ +import type * as ParcelWatcher from '@parcel/watcher'; import assert from 'node:assert'; import * as fs from 'node:fs'; import * as path from 'node:path'; @@ -13,6 +14,7 @@ import { setTimeout } from 'node:timers/promises'; import { type BuildWatcher, ChangedFiles, + ParcelExternalManager, createWatcher, extractNodeModulesPackageDir, getDirectoryPath, @@ -829,5 +831,364 @@ describe('Watcher', () => { fs.rmSync(externalDir, { recursive: true, force: true }); } }, 10000); + + it('should detect changes across multiple external directories when using @parcel/watcher', async () => { + const externalRoot = fs.mkdtempSync(path.join(TMP_DIR, 'parcel-external-spec-')); + let watcher: BuildWatcher | undefined; + + try { + const lib1Dir = path.join(externalRoot, 'libs', 'lib-1', 'src'); + const lib2Dir = path.join(externalRoot, 'libs', 'lib-2', 'src'); + fs.mkdirSync(lib1Dir, { recursive: true }); + fs.mkdirSync(lib2Dir, { recursive: true }); + + const file1 = path.join(lib1Dir, 'index.ts'); + const file2 = path.join(lib2Dir, 'index.ts'); + fs.writeFileSync(file1, 'export const a = 1;'); + fs.writeFileSync(file2, 'export const b = 1;'); + + // Backdate initial file timestamps to earlier than `initTime - 1000` so that any + // delayed initial FSEvents replay from file creation is ignored by the watcher. + const pastTime = new Date(Date.now() - 5000); + fs.utimesSync(file1, pastTime, pastTime); + fs.utimesSync(file2, pastTime, pastTime); + + watcher = await createWatcher({ cwd: tempDir }); + watcher.add([file1, file2]); + + await setTimeout(150); + + const iterator = watcher[Symbol.asyncIterator](); + + let nextPromise = iterator.next(); + fs.writeFileSync(file1, 'export const a = 2;'); + let result = await nextPromise; + expect(result.done).toBeFalsy(); + expect(result.value?.all.some((f: string) => f.includes('lib-1'))).toBeTrue(); + + nextPromise = iterator.next(); + fs.writeFileSync(file2, 'export const b = 2;'); + result = await nextPromise; + expect(result.done).toBeFalsy(); + expect(result.value?.all.some((f: string) => f.includes('lib-2'))).toBeTrue(); + } finally { + await watcher?.close(); + fs.rmSync(externalRoot, { recursive: true, force: true }); + } + }, 10000); + }); + + describe('ParcelExternalManager', () => { + function createMockParcelWatcher(options?: { + failAfter?: number; + onSubscribe?: (dir: string, opts?: ParcelWatcher.Options) => void; + }) { + const activeDirs = new Set(); + const subscribeHistory: { dir: string; options?: ParcelWatcher.Options }[] = []; + let totalCalls = 0; + + const mockWatcher = { + subscribe: jasmine + .createSpy('subscribe') + .and.callFake( + async ( + dir: string, + _cb: ParcelWatcher.SubscribeCallback, + opts?: ParcelWatcher.Options, + ): Promise => { + totalCalls++; + options?.onSubscribe?.(dir, opts); + if (options?.failAfter !== undefined && activeDirs.size >= options.failAfter) { + throw new Error('Error starting FSEvents stream'); + } + activeDirs.add(dir); + subscribeHistory.push({ dir, options: opts }); + + return { + unsubscribe: async () => { + activeDirs.delete(dir); + }, + }; + }, + ), + } as unknown as typeof ParcelWatcher; + + return { + mockWatcher, + activeDirs, + subscribeHistory, + getTotalCalls: () => totalCalls, + }; + } + + it('should batch synchronous watchFile calls and subsume child directories added before parent', async () => { + const { mockWatcher, activeDirs, getTotalCalls } = createMockParcelWatcher(); + const manager = new ParcelExternalManager( + mockWatcher, + undefined, + '/monorepo/apps/app', + '/monorepo/apps/app', + true, + () => {}, + ); + + // Add deeper child directories first, then their parent directory in the same synchronous turn + manager.watchFile( + '/monorepo/libs/lib-1/src/components/button/button.ts', + '/monorepo/libs/lib-1/src/components/button/button.ts', + ); + manager.watchFile( + '/monorepo/libs/lib-1/src/components/card/card.ts', + '/monorepo/libs/lib-1/src/components/card/card.ts', + ); + manager.watchFile('/monorepo/libs/lib-1/src/index.ts', '/monorepo/libs/lib-1/src/index.ts'); + + await manager.flush(); + + // Should only ever have subscribed once to the parent '/monorepo/libs/lib-1/src' + expect(getTotalCalls()).toBe(1); + expect(Array.from(activeDirs)).toEqual(['/monorepo/libs/lib-1/src']); + + await manager.close(); + }); + + it('should normalize external node_modules paths to their package root directory', async () => { + const { mockWatcher, activeDirs, getTotalCalls } = createMockParcelWatcher(); + const manager = new ParcelExternalManager( + mockWatcher, + undefined, + '/monorepo/apps/app', + '/monorepo/apps/app', + true, + () => {}, + ); + + manager.watchFile( + '/monorepo/node_modules/my-pkg/fesm2022/my-pkg.mjs', + '/monorepo/node_modules/my-pkg/fesm2022/my-pkg.mjs', + ); + manager.watchFile( + '/monorepo/node_modules/my-pkg/esm2022/sub/helper.mjs', + '/monorepo/node_modules/my-pkg/esm2022/sub/helper.mjs', + ); + manager.watchFile( + '/monorepo/node_modules/@scope/scoped-pkg/fesm2022/index.mjs', + '/monorepo/node_modules/@scope/scoped-pkg/fesm2022/index.mjs', + ); + manager.watchFile( + '/monorepo/node_modules/@scope/scoped-pkg/package.json', + '/monorepo/node_modules/@scope/scoped-pkg/package.json', + ); + + await manager.flush(); + + expect(getTotalCalls()).toBe(2); + expect(Array.from(activeDirs).sort()).toEqual([ + '/monorepo/node_modules/@scope/scoped-pkg', + '/monorepo/node_modules/my-pkg', + ]); + + // Removing one file from my-pkg should keep the package subscription active + manager.removeFile('/monorepo/node_modules/my-pkg/fesm2022/my-pkg.mjs'); + await manager.flush(); + expect(activeDirs.has('/monorepo/node_modules/my-pkg')).toBeTrue(); + + // Removing the last file from my-pkg should unsubscribe the package directory + manager.removeFile('/monorepo/node_modules/my-pkg/esm2022/sub/helper.mjs'); + await manager.flush(); + expect(activeDirs.has('/monorepo/node_modules/my-pkg')).toBeFalse(); + expect(Array.from(activeDirs)).toEqual(['/monorepo/node_modules/@scope/scoped-pkg']); + + await manager.close(); + }); + + it('should coalesce large numbers of external library and node_modules directories into common ancestors within budget', async () => { + const { mockWatcher, activeDirs, getTotalCalls } = createMockParcelWatcher(); + const manager = new ParcelExternalManager( + mockWatcher, + undefined, + '/monorepo/apps/app', + '/monorepo/apps/app', + true, + () => {}, + 64, + ); + + // Simulate 600 sibling libraries and 200 hoisted node_modules packages (800 external dirs) + for (let i = 0; i < 600; i++) { + const file = `/monorepo/libs/lib-${i}/src/index.ts`; + manager.watchFile(file, file); + } + for (let i = 0; i < 200; i++) { + const file = `/monorepo/node_modules/pkg-${i}/dist/index.mjs`; + manager.watchFile(file, file); + } + + await manager.flush(); + + // All 600 libs coalesce into '/monorepo/libs' and all 200 packages coalesce into '/monorepo/node_modules' + expect(getTotalCalls()).toBe(2); + expect(Array.from(activeDirs).sort()).toEqual(['/monorepo/libs', '/monorepo/node_modules']); + + await manager.close(); + }); + + it('should prioritize collapsing deeper branching subdirectories before broader ancestor directories', async () => { + const { mockWatcher, activeDirs } = createMockParcelWatcher(); + const manager = new ParcelExternalManager( + mockWatcher, + undefined, + '/monorepo/apps/app', + '/monorepo/apps/app', + true, + () => {}, + 3, // Budget of 3 subscriptions + ); + + // lib-1 has 4 component subdirectories, lib-2 and lib-3 have 1 each (total = 6 leaf dirs) + for (let c = 1; c <= 4; c++) { + const file = `/monorepo/libs/lib-1/src/comp-${c}/comp.ts`; + manager.watchFile(file, file); + } + manager.watchFile('/monorepo/libs/lib-2/src/index.ts', '/monorepo/libs/lib-2/src/index.ts'); + manager.watchFile('/monorepo/libs/lib-3/src/index.ts', '/monorepo/libs/lib-3/src/index.ts'); + + await manager.flush(); + + // Collapsing lib-1/src reduces total leaves from 6 to 3, meeting the budget of 3 + // without needing to collapse all of '/monorepo/libs' + expect(Array.from(activeDirs).sort()).toEqual([ + '/monorepo/libs/lib-1/src', + '/monorepo/libs/lib-2/src', + '/monorepo/libs/lib-3/src', + ]); + + await manager.close(); + }); + + it('should ignore workspaceRoot when coalescing into an ancestor of workspaceRoot (Tier 2)', async () => { + const { mockWatcher, activeDirs, subscribeHistory } = createMockParcelWatcher(); + const manager = new ParcelExternalManager( + mockWatcher, + { ignored: ['/monorepo/apps/app/dist'] }, + '/monorepo/apps/app', + '/monorepo/apps/app', + true, + () => {}, + 2, // Budget of 2 subscriptions + ); + + // Sibling apps/packages directly under /monorepo/apps (which is an ancestor of /monorepo/apps/app) + manager.watchFile( + '/monorepo/apps/shared-1/src/index.ts', + '/monorepo/apps/shared-1/src/index.ts', + ); + manager.watchFile( + '/monorepo/apps/shared-2/src/index.ts', + '/monorepo/apps/shared-2/src/index.ts', + ); + manager.watchFile( + '/monorepo/apps/shared-3/src/index.ts', + '/monorepo/apps/shared-3/src/index.ts', + ); + + await manager.flush(); + + expect(Array.from(activeDirs)).toEqual(['/monorepo/apps']); + expect(subscribeHistory.length).toBe(1); + expect(subscribeHistory[0].options?.ignore).toEqual([ + '/monorepo/apps/app/dist', + '/monorepo/apps/app', + '/monorepo/apps/app/**', + ]); + + await manager.close(); + }); + + it('should dynamically lower budget and coalesce into ancestor when subscribe fails with FSEvents stream limit error', async () => { + const externalRoot = fs.mkdtempSync(path.join(TMP_DIR, 'parcel-fallback-spec-')); + + try { + const rootPosix = toPosixPathNormalized(path.join(externalRoot, 'apps', 'app')); + const libFiles: string[] = []; + for (let i = 0; i < 6; i++) { + const libDir = path.join(externalRoot, 'libs', `lib-${i}`, 'src'); + fs.mkdirSync(libDir, { recursive: true }); + const file = toPosixPathNormalized(path.join(libDir, 'index.ts')); + fs.writeFileSync(file, 'export const x = 1;'); + libFiles.push(file); + } + + // Allow at most 2 active FSEvents streams even though manager budget starts at 64 + const { mockWatcher, activeDirs } = createMockParcelWatcher({ failAfter: 2 }); + const manager = new ParcelExternalManager( + mockWatcher, + undefined, + rootPosix, + rootPosix, + true, + () => {}, + 64, + ); + + for (const file of libFiles) { + manager.watchFile(file, file); + } + + await manager.flush(); + + // Should have shrunk and coalesced the 6 libraries into the single '/libs' ancestor directory + const expectedLibsDir = toPosixPathNormalized(path.join(externalRoot, 'libs')); + expect(Array.from(activeDirs)).toEqual([expectedLibsDir]); + + await manager.close(); + } finally { + fs.rmSync(externalRoot, { recursive: true, force: true }); + } + }); + + it('should uncoalesce and subscribe to remaining leaf directories when removals bring count back within budget', async () => { + const { mockWatcher, activeDirs } = createMockParcelWatcher(); + const manager = new ParcelExternalManager( + mockWatcher, + undefined, + '/monorepo/apps/app', + '/monorepo/apps/app', + true, + () => {}, + 2, // Budget of 2 subscriptions + ); + + const file1 = '/monorepo/libs/lib-1/src/index.ts'; + const file2 = '/monorepo/libs/lib-2/src/index.ts'; + const file3 = '/monorepo/libs/lib-3/src/index.ts'; + + manager.watchFile(file1, file1); + manager.watchFile(file2, file2); + manager.watchFile(file3, file3); + + await manager.flush(); + + // 3 directories exceed budget of 2, so they coalesce into '/monorepo/libs' + expect(Array.from(activeDirs)).toEqual(['/monorepo/libs']); + + // Removing file3 brings remaining directories to 2, which fits within budget + manager.removeFile(file3); + await manager.flush(); + + expect(Array.from(activeDirs).sort()).toEqual([ + '/monorepo/libs/lib-1/src', + '/monorepo/libs/lib-2/src', + ]); + + // Removing the remaining files unsubscribes everything + manager.removeFile(file1); + manager.removeFile(file2); + await manager.flush(); + + expect(activeDirs.size).toBe(0); + + await manager.close(); + }); }); }); From 14cded63307cf76ad4278d2520ff351131622d01 Mon Sep 17 00:00:00 2001 From: Angular Robot Date: Thu, 15 Oct 2026 13:02:11 +0000 Subject: [PATCH 626/787] build: update cross-repo angular dependencies See associated pull request for more information. --- .../assistant-to-the-branch-manager.yml | 2 +- .github/workflows/ci.yml | 52 +- .github/workflows/dev-infra.yml | 6 +- .github/workflows/perf.yml | 6 +- .github/workflows/pr.yml | 44 +- MODULE.bazel | 6 +- MODULE.bazel.lock | 50 +- package.json | 24 +- packages/angular/ssr/package.json | 12 +- packages/ngtools/webpack/package.json | 4 +- pnpm-lock.yaml | 456 ++++++++---------- tests/e2e/ng-snapshot/package.json | 32 +- 12 files changed, 330 insertions(+), 364 deletions(-) diff --git a/.github/workflows/assistant-to-the-branch-manager.yml b/.github/workflows/assistant-to-the-branch-manager.yml index 8c6035d666dc..f50263aad6ab 100644 --- a/.github/workflows/assistant-to-the-branch-manager.yml +++ b/.github/workflows/assistant-to-the-branch-manager.yml @@ -18,6 +18,6 @@ jobs: - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: persist-credentials: false - - uses: angular/dev-infra/github-actions/branch-manager@28ae58d2ad683fb3991006c23a9829c08b65aaec # main + - uses: angular/dev-infra/github-actions/branch-manager@c09a8058c7eee99ed9cec6213ff967bad6d6b73c # main with: angular-robot-key: ${{ secrets.ANGULAR_ROBOT_PRIVATE_KEY }} diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 56dde16b608c..6397ee443590 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -21,9 +21,9 @@ jobs: runs-on: ubuntu-latest steps: - name: Initialize environment - uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@28ae58d2ad683fb3991006c23a9829c08b65aaec # main + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@c09a8058c7eee99ed9cec6213ff967bad6d6b73c # main - name: Setup Bazel - uses: angular/dev-infra/github-actions/bazel/setup@28ae58d2ad683fb3991006c23a9829c08b65aaec # main + uses: angular/dev-infra/github-actions/bazel/setup@c09a8058c7eee99ed9cec6213ff967bad6d6b73c # main - name: Install node modules run: pnpm install --frozen-lockfile - name: Generate JSON schema types @@ -44,11 +44,11 @@ jobs: runs-on: ubuntu-latest steps: - name: Initialize environment - uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@28ae58d2ad683fb3991006c23a9829c08b65aaec # main + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@c09a8058c7eee99ed9cec6213ff967bad6d6b73c # main - name: Setup Bazel - uses: angular/dev-infra/github-actions/bazel/setup@28ae58d2ad683fb3991006c23a9829c08b65aaec # main + uses: angular/dev-infra/github-actions/bazel/setup@c09a8058c7eee99ed9cec6213ff967bad6d6b73c # main - name: Setup Bazel RBE - uses: angular/dev-infra/github-actions/bazel/configure-remote@28ae58d2ad683fb3991006c23a9829c08b65aaec # main + uses: angular/dev-infra/github-actions/bazel/configure-remote@c09a8058c7eee99ed9cec6213ff967bad6d6b73c # main with: google_credential: ${{ secrets.RBE_TRUSTED_BUILDS_USER }} - name: Install node modules @@ -61,11 +61,11 @@ jobs: runs-on: ubuntu-latest steps: - name: Initialize environment - uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@28ae58d2ad683fb3991006c23a9829c08b65aaec # main + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@c09a8058c7eee99ed9cec6213ff967bad6d6b73c # main - name: Setup Bazel - uses: angular/dev-infra/github-actions/bazel/setup@28ae58d2ad683fb3991006c23a9829c08b65aaec # main + uses: angular/dev-infra/github-actions/bazel/setup@c09a8058c7eee99ed9cec6213ff967bad6d6b73c # main - name: Setup Bazel RBE - uses: angular/dev-infra/github-actions/bazel/configure-remote@28ae58d2ad683fb3991006c23a9829c08b65aaec # main + uses: angular/dev-infra/github-actions/bazel/configure-remote@c09a8058c7eee99ed9cec6213ff967bad6d6b73c # main with: google_credential: ${{ secrets.RBE_TRUSTED_BUILDS_USER }} - name: Install node modules @@ -84,13 +84,13 @@ jobs: runs-on: ubuntu-latest steps: - name: Initialize environment - uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@28ae58d2ad683fb3991006c23a9829c08b65aaec # main + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@c09a8058c7eee99ed9cec6213ff967bad6d6b73c # main - name: Install node modules run: pnpm install --frozen-lockfile - name: Setup Bazel - uses: angular/dev-infra/github-actions/bazel/setup@28ae58d2ad683fb3991006c23a9829c08b65aaec # main + uses: angular/dev-infra/github-actions/bazel/setup@c09a8058c7eee99ed9cec6213ff967bad6d6b73c # main - name: Setup Bazel RBE - uses: angular/dev-infra/github-actions/bazel/configure-remote@28ae58d2ad683fb3991006c23a9829c08b65aaec # main + uses: angular/dev-infra/github-actions/bazel/configure-remote@c09a8058c7eee99ed9cec6213ff967bad6d6b73c # main with: google_credential: ${{ secrets.RBE_TRUSTED_BUILDS_USER }} - name: Run CLI E2E tests @@ -100,11 +100,11 @@ jobs: runs-on: ubuntu-latest steps: - name: Initialize environment - uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@28ae58d2ad683fb3991006c23a9829c08b65aaec # main + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@c09a8058c7eee99ed9cec6213ff967bad6d6b73c # main - name: Setup Bazel - uses: angular/dev-infra/github-actions/bazel/setup@28ae58d2ad683fb3991006c23a9829c08b65aaec # main + uses: angular/dev-infra/github-actions/bazel/setup@c09a8058c7eee99ed9cec6213ff967bad6d6b73c # main - name: Setup Bazel RBE - uses: angular/dev-infra/github-actions/bazel/configure-remote@28ae58d2ad683fb3991006c23a9829c08b65aaec # main + uses: angular/dev-infra/github-actions/bazel/configure-remote@c09a8058c7eee99ed9cec6213ff967bad6d6b73c # main with: google_credential: ${{ secrets.RBE_TRUSTED_BUILDS_USER }} - name: Install node modules @@ -137,7 +137,7 @@ jobs: runs-on: windows-2025 steps: - name: Initialize environment - uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@28ae58d2ad683fb3991006c23a9829c08b65aaec # main + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@c09a8058c7eee99ed9cec6213ff967bad6d6b73c # main - name: Install node modules run: pnpm install --frozen-lockfile - name: Download built Windows E2E tests @@ -164,13 +164,13 @@ jobs: runs-on: ubuntu-latest steps: - name: Initialize environment - uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@28ae58d2ad683fb3991006c23a9829c08b65aaec # main + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@c09a8058c7eee99ed9cec6213ff967bad6d6b73c # main - name: Install node modules run: pnpm install --frozen-lockfile - name: Setup Bazel - uses: angular/dev-infra/github-actions/bazel/setup@28ae58d2ad683fb3991006c23a9829c08b65aaec # main + uses: angular/dev-infra/github-actions/bazel/setup@c09a8058c7eee99ed9cec6213ff967bad6d6b73c # main - name: Setup Bazel RBE - uses: angular/dev-infra/github-actions/bazel/configure-remote@28ae58d2ad683fb3991006c23a9829c08b65aaec # main + uses: angular/dev-infra/github-actions/bazel/configure-remote@c09a8058c7eee99ed9cec6213ff967bad6d6b73c # main with: google_credential: ${{ secrets.RBE_TRUSTED_BUILDS_USER }} - name: Run CLI E2E tests @@ -188,13 +188,13 @@ jobs: runs-on: ubuntu-latest steps: - name: Initialize environment - uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@28ae58d2ad683fb3991006c23a9829c08b65aaec # main + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@c09a8058c7eee99ed9cec6213ff967bad6d6b73c # main - name: Install node modules run: pnpm install --frozen-lockfile - name: Setup Bazel - uses: angular/dev-infra/github-actions/bazel/setup@28ae58d2ad683fb3991006c23a9829c08b65aaec # main + uses: angular/dev-infra/github-actions/bazel/setup@c09a8058c7eee99ed9cec6213ff967bad6d6b73c # main - name: Setup Bazel RBE - uses: angular/dev-infra/github-actions/bazel/configure-remote@28ae58d2ad683fb3991006c23a9829c08b65aaec # main + uses: angular/dev-infra/github-actions/bazel/configure-remote@c09a8058c7eee99ed9cec6213ff967bad6d6b73c # main with: google_credential: ${{ secrets.RBE_TRUSTED_BUILDS_USER }} - name: Run CLI E2E tests @@ -208,13 +208,13 @@ jobs: SAUCE_TUNNEL_IDENTIFIER: angular-cli-${{ github.workflow }}-${{ github.run_number }} steps: - name: Initialize environment - uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@28ae58d2ad683fb3991006c23a9829c08b65aaec # main + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@c09a8058c7eee99ed9cec6213ff967bad6d6b73c # main - name: Install node modules run: pnpm install --frozen-lockfile - name: Setup Bazel - uses: angular/dev-infra/github-actions/bazel/setup@28ae58d2ad683fb3991006c23a9829c08b65aaec # main + uses: angular/dev-infra/github-actions/bazel/setup@c09a8058c7eee99ed9cec6213ff967bad6d6b73c # main - name: Setup Bazel RBE - uses: angular/dev-infra/github-actions/bazel/configure-remote@28ae58d2ad683fb3991006c23a9829c08b65aaec # main + uses: angular/dev-infra/github-actions/bazel/configure-remote@c09a8058c7eee99ed9cec6213ff967bad6d6b73c # main with: google_credential: ${{ secrets.RBE_TRUSTED_BUILDS_USER }} - name: Start Sauce Connect @@ -245,11 +245,11 @@ jobs: CIRCLE_BRANCH: ${{ github.ref_name }} steps: - name: Initialize environment - uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@28ae58d2ad683fb3991006c23a9829c08b65aaec # main + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@c09a8058c7eee99ed9cec6213ff967bad6d6b73c # main - name: Install node modules run: pnpm install --frozen-lockfile - name: Setup Bazel - uses: angular/dev-infra/github-actions/bazel/setup@28ae58d2ad683fb3991006c23a9829c08b65aaec # main + uses: angular/dev-infra/github-actions/bazel/setup@c09a8058c7eee99ed9cec6213ff967bad6d6b73c # main - run: pnpm admin snapshots --verbose env: SNAPSHOT_BUILDS_GITHUB_TOKEN: ${{ secrets.SNAPSHOT_BUILDS_GITHUB_TOKEN }} diff --git a/.github/workflows/dev-infra.yml b/.github/workflows/dev-infra.yml index f508452e9456..b85b240f82dc 100644 --- a/.github/workflows/dev-infra.yml +++ b/.github/workflows/dev-infra.yml @@ -16,21 +16,21 @@ jobs: if: github.event_name == 'pull_request_target' runs-on: ubuntu-latest steps: - - uses: angular/dev-infra/github-actions/labeling/pull-request@28ae58d2ad683fb3991006c23a9829c08b65aaec # main + - uses: angular/dev-infra/github-actions/labeling/pull-request@c09a8058c7eee99ed9cec6213ff967bad6d6b73c # main with: angular-robot-key: ${{ secrets.ANGULAR_ROBOT_PRIVATE_KEY }} post_approval_changes: if: github.event_name == 'pull_request_target' runs-on: ubuntu-latest steps: - - uses: angular/dev-infra/github-actions/post-approval-changes@28ae58d2ad683fb3991006c23a9829c08b65aaec # main + - uses: angular/dev-infra/github-actions/post-approval-changes@c09a8058c7eee99ed9cec6213ff967bad6d6b73c # main with: angular-robot-key: ${{ secrets.ANGULAR_ROBOT_PRIVATE_KEY }} issue_labels: if: github.event_name == 'issues' runs-on: ubuntu-latest steps: - - uses: angular/dev-infra/github-actions/labeling/issue@28ae58d2ad683fb3991006c23a9829c08b65aaec # main + - uses: angular/dev-infra/github-actions/labeling/issue@c09a8058c7eee99ed9cec6213ff967bad6d6b73c # main with: angular-robot-key: ${{ secrets.ANGULAR_ROBOT_PRIVATE_KEY }} google-generative-ai-key: ${{ secrets.GOOGLE_GENERATIVE_AI_KEY }} diff --git a/.github/workflows/perf.yml b/.github/workflows/perf.yml index 1c275f2d1a0d..21a061c26de5 100644 --- a/.github/workflows/perf.yml +++ b/.github/workflows/perf.yml @@ -22,7 +22,7 @@ jobs: workflows: ${{ steps.workflows.outputs.workflows }} steps: - name: Initialize environment - uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@28ae58d2ad683fb3991006c23a9829c08b65aaec # main + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@c09a8058c7eee99ed9cec6213ff967bad6d6b73c # main - name: Install node modules run: pnpm install --frozen-lockfile - id: workflows @@ -40,9 +40,9 @@ jobs: workflow: ${{ fromJSON(needs.list.outputs.workflows) }} steps: - name: Initialize environment - uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@28ae58d2ad683fb3991006c23a9829c08b65aaec # main + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@c09a8058c7eee99ed9cec6213ff967bad6d6b73c # main - name: Setup Bazel - uses: angular/dev-infra/github-actions/bazel/setup@28ae58d2ad683fb3991006c23a9829c08b65aaec # main + uses: angular/dev-infra/github-actions/bazel/setup@c09a8058c7eee99ed9cec6213ff967bad6d6b73c # main - name: Install node modules run: pnpm install --frozen-lockfile # We utilize the google-github-actions/auth action to allow us to get an active credential using workflow diff --git a/.github/workflows/pr.yml b/.github/workflows/pr.yml index d9195bdf9f8c..f0eb6e091f47 100644 --- a/.github/workflows/pr.yml +++ b/.github/workflows/pr.yml @@ -34,9 +34,9 @@ jobs: runs-on: ubuntu-latest steps: - name: Initialize environment - uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@28ae58d2ad683fb3991006c23a9829c08b65aaec # main + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@c09a8058c7eee99ed9cec6213ff967bad6d6b73c # main - name: Setup Bazel - uses: angular/dev-infra/github-actions/bazel/setup@28ae58d2ad683fb3991006c23a9829c08b65aaec # main + uses: angular/dev-infra/github-actions/bazel/setup@c09a8058c7eee99ed9cec6213ff967bad6d6b73c # main - name: Setup ESLint Caching uses: actions/cache@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0 with: @@ -66,17 +66,17 @@ jobs: # it has been merged. run: pnpm ng-dev format changed --check ${{ github.event.pull_request.base.sha }} - name: Check Package Licenses - uses: angular/dev-infra/github-actions/linting/licenses@28ae58d2ad683fb3991006c23a9829c08b65aaec # main + uses: angular/dev-infra/github-actions/linting/licenses@c09a8058c7eee99ed9cec6213ff967bad6d6b73c # main build: runs-on: ubuntu-latest steps: - name: Initialize environment - uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@28ae58d2ad683fb3991006c23a9829c08b65aaec # main + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@c09a8058c7eee99ed9cec6213ff967bad6d6b73c # main - name: Setup Bazel - uses: angular/dev-infra/github-actions/bazel/setup@28ae58d2ad683fb3991006c23a9829c08b65aaec # main + uses: angular/dev-infra/github-actions/bazel/setup@c09a8058c7eee99ed9cec6213ff967bad6d6b73c # main - name: Setup Bazel RBE - uses: angular/dev-infra/github-actions/bazel/configure-remote@28ae58d2ad683fb3991006c23a9829c08b65aaec # main + uses: angular/dev-infra/github-actions/bazel/configure-remote@c09a8058c7eee99ed9cec6213ff967bad6d6b73c # main - name: Install node modules run: pnpm install --frozen-lockfile - name: Build release targets @@ -93,11 +93,11 @@ jobs: runs-on: ubuntu-latest steps: - name: Initialize environment - uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@28ae58d2ad683fb3991006c23a9829c08b65aaec # main + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@c09a8058c7eee99ed9cec6213ff967bad6d6b73c # main - name: Setup Bazel - uses: angular/dev-infra/github-actions/bazel/setup@28ae58d2ad683fb3991006c23a9829c08b65aaec # main + uses: angular/dev-infra/github-actions/bazel/setup@c09a8058c7eee99ed9cec6213ff967bad6d6b73c # main - name: Setup Bazel RBE - uses: angular/dev-infra/github-actions/bazel/configure-remote@28ae58d2ad683fb3991006c23a9829c08b65aaec # main + uses: angular/dev-infra/github-actions/bazel/configure-remote@c09a8058c7eee99ed9cec6213ff967bad6d6b73c # main - name: Install node modules run: pnpm install --frozen-lockfile - name: Run module and package tests @@ -114,13 +114,13 @@ jobs: runs-on: ubuntu-latest steps: - name: Initialize environment - uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@28ae58d2ad683fb3991006c23a9829c08b65aaec # main + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@c09a8058c7eee99ed9cec6213ff967bad6d6b73c # main - name: Install node modules run: pnpm install --frozen-lockfile - name: Setup Bazel - uses: angular/dev-infra/github-actions/bazel/setup@28ae58d2ad683fb3991006c23a9829c08b65aaec # main + uses: angular/dev-infra/github-actions/bazel/setup@c09a8058c7eee99ed9cec6213ff967bad6d6b73c # main - name: Setup Bazel RBE - uses: angular/dev-infra/github-actions/bazel/configure-remote@28ae58d2ad683fb3991006c23a9829c08b65aaec # main + uses: angular/dev-infra/github-actions/bazel/configure-remote@c09a8058c7eee99ed9cec6213ff967bad6d6b73c # main - name: Run CLI E2E tests run: pnpm bazel test --test_env=E2E_SHARD_TOTAL=6 --test_env=E2E_SHARD_INDEX=${{ matrix.shard }} --config=e2e //tests:e2e.${{ matrix.subset }}_node${{ matrix.node }} @@ -128,11 +128,11 @@ jobs: runs-on: ubuntu-latest steps: - name: Initialize environment - uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@28ae58d2ad683fb3991006c23a9829c08b65aaec # main + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@c09a8058c7eee99ed9cec6213ff967bad6d6b73c # main - name: Setup Bazel - uses: angular/dev-infra/github-actions/bazel/setup@28ae58d2ad683fb3991006c23a9829c08b65aaec # main + uses: angular/dev-infra/github-actions/bazel/setup@c09a8058c7eee99ed9cec6213ff967bad6d6b73c # main - name: Setup Bazel RBE - uses: angular/dev-infra/github-actions/bazel/configure-remote@28ae58d2ad683fb3991006c23a9829c08b65aaec # main + uses: angular/dev-infra/github-actions/bazel/configure-remote@c09a8058c7eee99ed9cec6213ff967bad6d6b73c # main - name: Install node modules run: pnpm install --frozen-lockfile - name: Build E2E tests for Windows on Linux @@ -156,7 +156,7 @@ jobs: runs-on: windows-2025 steps: - name: Initialize environment - uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@28ae58d2ad683fb3991006c23a9829c08b65aaec # main + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@c09a8058c7eee99ed9cec6213ff967bad6d6b73c # main - name: Install node modules run: pnpm install --frozen-lockfile - name: Download built Windows E2E tests @@ -183,13 +183,13 @@ jobs: runs-on: ubuntu-latest steps: - name: Initialize environment - uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@28ae58d2ad683fb3991006c23a9829c08b65aaec # main + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@c09a8058c7eee99ed9cec6213ff967bad6d6b73c # main - name: Install node modules run: pnpm install --frozen-lockfile - name: Setup Bazel - uses: angular/dev-infra/github-actions/bazel/setup@28ae58d2ad683fb3991006c23a9829c08b65aaec # main + uses: angular/dev-infra/github-actions/bazel/setup@c09a8058c7eee99ed9cec6213ff967bad6d6b73c # main - name: Setup Bazel RBE - uses: angular/dev-infra/github-actions/bazel/configure-remote@28ae58d2ad683fb3991006c23a9829c08b65aaec # main + uses: angular/dev-infra/github-actions/bazel/configure-remote@c09a8058c7eee99ed9cec6213ff967bad6d6b73c # main - name: Run CLI E2E tests run: pnpm bazel test --test_env=E2E_SHARD_TOTAL=3 --test_env=E2E_SHARD_INDEX=${{ matrix.shard }} --config=e2e //tests:e2e.${{ matrix.subset }}_node${{ matrix.node }} @@ -205,12 +205,12 @@ jobs: runs-on: ubuntu-latest steps: - name: Initialize environment - uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@28ae58d2ad683fb3991006c23a9829c08b65aaec # main + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@c09a8058c7eee99ed9cec6213ff967bad6d6b73c # main - name: Install node modules run: pnpm install --frozen-lockfile - name: Setup Bazel - uses: angular/dev-infra/github-actions/bazel/setup@28ae58d2ad683fb3991006c23a9829c08b65aaec # main + uses: angular/dev-infra/github-actions/bazel/setup@c09a8058c7eee99ed9cec6213ff967bad6d6b73c # main - name: Setup Bazel RBE - uses: angular/dev-infra/github-actions/bazel/configure-remote@28ae58d2ad683fb3991006c23a9829c08b65aaec # main + uses: angular/dev-infra/github-actions/bazel/configure-remote@c09a8058c7eee99ed9cec6213ff967bad6d6b73c # main - name: Run CLI E2E tests run: pnpm bazel test --test_env=E2E_SHARD_TOTAL=6 --test_env=E2E_SHARD_INDEX=${{ matrix.shard }} --config=e2e //tests:e2e.snapshots.${{ matrix.subset }}_node${{ matrix.node }} diff --git a/MODULE.bazel b/MODULE.bazel index a4caf9a9bc97..f81a41dd6522 100644 --- a/MODULE.bazel +++ b/MODULE.bazel @@ -19,21 +19,21 @@ bazel_dep(name = "aspect_rules_jasmine", version = "2.0.4") bazel_dep(name = "rules_angular") git_override( module_name = "rules_angular", - commit = "b5869cff3db5d2217b8896d483e75af8a1d26712", + commit = "bfe6e98434982bad38c393f1bd472ec33f16cd32", remote = "https://github.com/angular/rules_angular.git", ) bazel_dep(name = "devinfra") git_override( module_name = "devinfra", - commit = "28ae58d2ad683fb3991006c23a9829c08b65aaec", + commit = "c09a8058c7eee99ed9cec6213ff967bad6d6b73c", remote = "https://github.com/angular/dev-infra.git", ) bazel_dep(name = "rules_browsers") git_override( module_name = "rules_browsers", - commit = "4b53d68eed02bbb0901b21fb02b8cf99f4f59a52", + commit = "48a956da3908e5c923f21e6ffd1c72c5605d61fe", remote = "https://github.com/angular/rules_browsers.git", ) diff --git a/MODULE.bazel.lock b/MODULE.bazel.lock index 5f2282f7683b..4cb3f4cc542f 100644 --- a/MODULE.bazel.lock +++ b/MODULE.bazel.lock @@ -445,16 +445,16 @@ }, "@@rules_browsers+//browsers:extensions.bzl%browsers": { "general": { - "bzlTransitiveDigest": "/FonktAou7w4aKjGZUZDFFOlASeGnKNw0QALxUIdtuE=", + "bzlTransitiveDigest": "OZ8V6/fUTaz9GXcrxaCB7fqf29DyphGiugzTRl7yPR8=", "usagesDigest": "FmXYJVoVJlnfUU8x8gObSvu4qWcco/9Faw61aC/wBF0=", "recordedInputs": [], "generatedRepoSpecs": { "rules_browsers_chrome_linux": { "repoRuleId": "@@rules_browsers+//browsers/private:browser_repo.bzl%browser_repo", "attributes": { - "sha256": "9541eafbc02f85e3ec0c24b05f8bbffe88094389949860681bf6055aef668d7b", + "sha256": "e3f19706550899e76efdadb1ad172c3af2bb89c137a1350fe7f72333d2a4d0a4", "urls": [ - "https://storage.googleapis.com/chrome-for-testing-public/157.0.8099.0/linux64/chrome-headless-shell-linux64.zip" + "https://storage.googleapis.com/chrome-for-testing-public/158.0.8106.0/linux64/chrome-headless-shell-linux64.zip" ], "named_files": { "CHROME-HEADLESS-SHELL": "chrome-headless-shell-linux64/chrome-headless-shell" @@ -470,9 +470,9 @@ "rules_browsers_chrome_mac": { "repoRuleId": "@@rules_browsers+//browsers/private:browser_repo.bzl%browser_repo", "attributes": { - "sha256": "358f032d48a0b825b0601b89b970da5a7c245344ed7a557a3ef8613c342521b0", + "sha256": "1f98187b068d2c631d4465a437ce7c4d83f7bde9b6a0e19faae1c9de04eb4a4d", "urls": [ - "https://storage.googleapis.com/chrome-for-testing-public/157.0.8099.0/mac-x64/chrome-headless-shell-mac-x64.zip" + "https://storage.googleapis.com/chrome-for-testing-public/158.0.8106.0/mac-x64/chrome-headless-shell-mac-x64.zip" ], "named_files": { "CHROME-HEADLESS-SHELL": "chrome-headless-shell-mac-x64/chrome-headless-shell" @@ -488,9 +488,9 @@ "rules_browsers_chrome_mac_arm": { "repoRuleId": "@@rules_browsers+//browsers/private:browser_repo.bzl%browser_repo", "attributes": { - "sha256": "c3de600edda5e11aa40918f123781040cd6e9c2509a2acfc466b773bf7c9b326", + "sha256": "a564d6b8c498a1c8624e9e14f83ece2d9903db1ec2b491e9fa8fdc7805187dce", "urls": [ - "https://storage.googleapis.com/chrome-for-testing-public/157.0.8099.0/mac-arm64/chrome-headless-shell-mac-arm64.zip" + "https://storage.googleapis.com/chrome-for-testing-public/158.0.8106.0/mac-arm64/chrome-headless-shell-mac-arm64.zip" ], "named_files": { "CHROME-HEADLESS-SHELL": "chrome-headless-shell-mac-arm64/chrome-headless-shell" @@ -506,9 +506,9 @@ "rules_browsers_chrome_win64": { "repoRuleId": "@@rules_browsers+//browsers/private:browser_repo.bzl%browser_repo", "attributes": { - "sha256": "b2e81e06ac46d3355bc6428b3abe97308d34e810d4404427bbd14665111e67a1", + "sha256": "3a874f0d0d36a84a89c4fedf7e0dfdcad7e4818bbaf22842ac06762305256b87", "urls": [ - "https://storage.googleapis.com/chrome-for-testing-public/157.0.8099.0/win64/chrome-headless-shell-win64.zip" + "https://storage.googleapis.com/chrome-for-testing-public/158.0.8106.0/win64/chrome-headless-shell-win64.zip" ], "named_files": { "CHROME-HEADLESS-SHELL": "chrome-headless-shell-win64/chrome-headless-shell.exe" @@ -524,9 +524,9 @@ "rules_browsers_chromedriver_linux": { "repoRuleId": "@@rules_browsers+//browsers/private:browser_repo.bzl%browser_repo", "attributes": { - "sha256": "cf16fed1899de0f0b8999389779cefbb6696c5fd44ad9718ce2195a3ff5ca029", + "sha256": "51b3afc67a5765403601420074ad7091e083133ca8f82e878a49b783614256df", "urls": [ - "https://storage.googleapis.com/chrome-for-testing-public/157.0.8099.0/linux64/chromedriver-linux64.zip" + "https://storage.googleapis.com/chrome-for-testing-public/158.0.8106.0/linux64/chromedriver-linux64.zip" ], "named_files": { "CHROMEDRIVER": "chromedriver-linux64/chromedriver" @@ -540,9 +540,9 @@ "rules_browsers_chromedriver_mac": { "repoRuleId": "@@rules_browsers+//browsers/private:browser_repo.bzl%browser_repo", "attributes": { - "sha256": "ba472bdd32ee62a98f04fcca364015a0df241fdf85ee7d834a048b5fdfd90fd3", + "sha256": "944924ff8ba2ca15407e788f1d36918e4979f9f5329d0bdf8689c9a96c1818fc", "urls": [ - "https://storage.googleapis.com/chrome-for-testing-public/157.0.8099.0/mac-x64/chromedriver-mac-x64.zip" + "https://storage.googleapis.com/chrome-for-testing-public/158.0.8106.0/mac-x64/chromedriver-mac-x64.zip" ], "named_files": { "CHROMEDRIVER": "chromedriver-mac-x64/chromedriver" @@ -556,9 +556,9 @@ "rules_browsers_chromedriver_mac_arm": { "repoRuleId": "@@rules_browsers+//browsers/private:browser_repo.bzl%browser_repo", "attributes": { - "sha256": "8fe44ebac5303278a5d533c114ad0dbed0df9c218bce5b80d606078472ea95bd", + "sha256": "2b46fd5f3838e6a2ea73e29e67537c97f43a23eeddbf5522ac15cd27f05a4987", "urls": [ - "https://storage.googleapis.com/chrome-for-testing-public/157.0.8099.0/mac-arm64/chromedriver-mac-arm64.zip" + "https://storage.googleapis.com/chrome-for-testing-public/158.0.8106.0/mac-arm64/chromedriver-mac-arm64.zip" ], "named_files": { "CHROMEDRIVER": "chromedriver-mac-arm64/chromedriver" @@ -572,9 +572,9 @@ "rules_browsers_chromedriver_win64": { "repoRuleId": "@@rules_browsers+//browsers/private:browser_repo.bzl%browser_repo", "attributes": { - "sha256": "1fadd71af32db4e3497ce4faac3f07503f4c4cdad8747e71ff62c5c9c3dd05e1", + "sha256": "5c38e2e1d06b51e34885fb0474bf74a5bb36e4a6a517327df8d74f49d7cf9dd8", "urls": [ - "https://storage.googleapis.com/chrome-for-testing-public/157.0.8099.0/win64/chromedriver-win64.zip" + "https://storage.googleapis.com/chrome-for-testing-public/158.0.8106.0/win64/chromedriver-win64.zip" ], "named_files": { "CHROMEDRIVER": "chromedriver-win64/chromedriver.exe" @@ -588,9 +588,9 @@ "rules_browsers_firefox_linux": { "repoRuleId": "@@rules_browsers+//browsers/private:browser_repo.bzl%browser_repo", "attributes": { - "sha256": "42f2c62a562316982ef5a796738c57602bf84a984f5c616e80bcff4627f78fff", + "sha256": "9549b054ec4cf85f50f6a19d8c6fb79580312e71ebc4ec2cb217ec9af09dc12a", "urls": [ - "https://archive.mozilla.org/pub/firefox/releases/157.0/linux-x86_64/en-US/firefox-157.0.tar.xz" + "https://archive.mozilla.org/pub/firefox/releases/158.0/linux-x86_64/en-US/firefox-158.0.tar.xz" ], "named_files": { "FIREFOX": "firefox/firefox" @@ -604,9 +604,9 @@ "rules_browsers_firefox_mac": { "repoRuleId": "@@rules_browsers+//browsers/private:browser_repo.bzl%browser_repo", "attributes": { - "sha256": "df6d8c79b6126bcf24cb70ebab9371916a662028e2d706e462d432e78fdf396c", + "sha256": "dfe8508ee8880cec1578253eb02b9154b5971a55e832d97396f463cd07b5ef67", "urls": [ - "https://archive.mozilla.org/pub/firefox/releases/157.0/mac/en-US/Firefox%20157.0.dmg" + "https://archive.mozilla.org/pub/firefox/releases/158.0/mac/en-US/Firefox%20158.0.dmg" ], "named_files": { "FIREFOX": "Firefox.app/Contents/MacOS/firefox" @@ -620,9 +620,9 @@ "rules_browsers_firefox_mac_arm": { "repoRuleId": "@@rules_browsers+//browsers/private:browser_repo.bzl%browser_repo", "attributes": { - "sha256": "df6d8c79b6126bcf24cb70ebab9371916a662028e2d706e462d432e78fdf396c", + "sha256": "dfe8508ee8880cec1578253eb02b9154b5971a55e832d97396f463cd07b5ef67", "urls": [ - "https://archive.mozilla.org/pub/firefox/releases/157.0/mac/en-US/Firefox%20157.0.dmg" + "https://archive.mozilla.org/pub/firefox/releases/158.0/mac/en-US/Firefox%20158.0.dmg" ], "named_files": { "FIREFOX": "Firefox.app/Contents/MacOS/firefox" @@ -636,9 +636,9 @@ "rules_browsers_firefox_win64": { "repoRuleId": "@@rules_browsers+//browsers/private:browser_repo.bzl%browser_repo", "attributes": { - "sha256": "58c90afab6e4b9a6b34d2958fe06d1a143dd9226ea8834377e5cd45e815936d7", + "sha256": "450ab1c772e02f0c9ef02f489b153d86c45bd9311b202d10dc233f3c0206f8d1", "urls": [ - "https://archive.mozilla.org/pub/firefox/releases/157.0/win64/en-US/Firefox%20Setup%20157.0.exe" + "https://archive.mozilla.org/pub/firefox/releases/158.0/win64/en-US/Firefox%20Setup%20158.0.exe" ], "named_files": { "FIREFOX": "core/firefox.exe" diff --git a/package.json b/package.json index 6a7407853c21..6e4cab8c46dc 100644 --- a/package.json +++ b/package.json @@ -43,23 +43,23 @@ }, "homepage": "https://github.com/angular/angular-cli", "dependencies": { - "@angular/compiler-cli": "22.3.0-next.1", + "@angular/compiler-cli": "22.3.0-next.2", "typescript": "6.0.3" }, "devDependencies": { - "@angular/animations": "22.3.0-next.1", + "@angular/animations": "22.3.0-next.2", "@angular/cdk": "22.3.0-next.2", - "@angular/common": "22.3.0-next.1", - "@angular/compiler": "22.3.0-next.1", - "@angular/core": "22.3.0-next.1", - "@angular/forms": "22.3.0-next.1", - "@angular/localize": "22.3.0-next.1", + "@angular/common": "22.3.0-next.2", + "@angular/compiler": "22.3.0-next.2", + "@angular/core": "22.3.0-next.2", + "@angular/forms": "22.3.0-next.2", + "@angular/localize": "22.3.0-next.2", "@angular/material": "22.3.0-next.2", - "@angular/ng-dev": "https://github.com/angular/dev-infra-private-ng-dev-builds.git#fa4308affb4a0dde34ebc95196b58550752485a2", - "@angular/platform-browser": "22.3.0-next.1", - "@angular/platform-server": "22.3.0-next.1", - "@angular/router": "22.3.0-next.1", - "@angular/service-worker": "22.3.0-next.1", + "@angular/ng-dev": "https://github.com/angular/dev-infra-private-ng-dev-builds.git#940c0beef0de4cb128e90962d47ff80e352a1cd8", + "@angular/platform-browser": "22.3.0-next.2", + "@angular/platform-server": "22.3.0-next.2", + "@angular/router": "22.3.0-next.2", + "@angular/service-worker": "22.3.0-next.2", "@babel/core": "8.0.7", "@bazel/bazelisk": "1.28.1", "@bazel/buildifier": "8.2.1", diff --git a/packages/angular/ssr/package.json b/packages/angular/ssr/package.json index 9d86125f4aad..a3049daf662d 100644 --- a/packages/angular/ssr/package.json +++ b/packages/angular/ssr/package.json @@ -38,12 +38,12 @@ }, "devDependencies": { "@angular-devkit/schematics": "workspace:*", - "@angular/common": "22.3.0-next.1", - "@angular/compiler": "22.3.0-next.1", - "@angular/core": "22.3.0-next.1", - "@angular/platform-browser": "22.3.0-next.1", - "@angular/platform-server": "22.3.0-next.1", - "@angular/router": "22.3.0-next.1", + "@angular/common": "22.3.0-next.2", + "@angular/compiler": "22.3.0-next.2", + "@angular/core": "22.3.0-next.2", + "@angular/platform-browser": "22.3.0-next.2", + "@angular/platform-server": "22.3.0-next.2", + "@angular/router": "22.3.0-next.2", "@schematics/angular": "workspace:*" }, "sideEffects": false, diff --git a/packages/ngtools/webpack/package.json b/packages/ngtools/webpack/package.json index a7488b0d9316..13cea96fc202 100644 --- a/packages/ngtools/webpack/package.json +++ b/packages/ngtools/webpack/package.json @@ -17,8 +17,8 @@ }, "devDependencies": { "@angular-devkit/core": "workspace:0.0.0-PLACEHOLDER", - "@angular/compiler": "22.3.0-next.1", - "@angular/compiler-cli": "22.3.0-next.1", + "@angular/compiler": "22.3.0-next.2", + "@angular/compiler-cli": "22.3.0-next.2", "typescript": "6.0.3", "webpack": "5.111.1" } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index e38b036ee3d9..ff51f38b4f6c 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -172,8 +172,8 @@ importers: .: dependencies: '@angular/compiler-cli': - specifier: 22.3.0-next.1 - version: 22.3.0-next.1(@angular/compiler@22.3.0-next.1)(typescript@6.0.3) + specifier: 22.3.0-next.2 + version: 22.3.0-next.2(@angular/compiler@22.3.0-next.2)(typescript@6.0.3) typescript: specifier: 6.0.3 version: 6.0.3 @@ -184,44 +184,44 @@ importers: built: true devDependencies: '@angular/animations': - specifier: 22.3.0-next.1 - version: 22.3.0-next.1(@angular/core@22.3.0-next.1(@angular/compiler@22.3.0-next.1)(rxjs@7.8.2)(zone.js@0.16.3)) + specifier: 22.3.0-next.2 + version: 22.3.0-next.2(@angular/core@22.3.0-next.2(@angular/compiler@22.3.0-next.2)(rxjs@7.8.2)(zone.js@0.16.3)) '@angular/cdk': specifier: 22.3.0-next.2 - version: 22.3.0-next.2(1e228ab395252fe57958c1335d3a301f) + version: 22.3.0-next.2(e02572097466d520d7eb144e95d6bbd2) '@angular/common': - specifier: 22.3.0-next.1 - version: 22.3.0-next.1(@angular/core@22.3.0-next.1(@angular/compiler@22.3.0-next.1)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2) + specifier: 22.3.0-next.2 + version: 22.3.0-next.2(@angular/core@22.3.0-next.2(@angular/compiler@22.3.0-next.2)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2) '@angular/compiler': - specifier: 22.3.0-next.1 - version: 22.3.0-next.1 + specifier: 22.3.0-next.2 + version: 22.3.0-next.2 '@angular/core': - specifier: 22.3.0-next.1 - version: 22.3.0-next.1(@angular/compiler@22.3.0-next.1)(rxjs@7.8.2)(zone.js@0.16.3) + specifier: 22.3.0-next.2 + version: 22.3.0-next.2(@angular/compiler@22.3.0-next.2)(rxjs@7.8.2)(zone.js@0.16.3) '@angular/forms': - specifier: 22.3.0-next.1 - version: 22.3.0-next.1(@angular/common@22.3.0-next.1(@angular/core@22.3.0-next.1(@angular/compiler@22.3.0-next.1)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2))(@angular/core@22.3.0-next.1(@angular/compiler@22.3.0-next.1)(rxjs@7.8.2)(zone.js@0.16.3))(@angular/platform-browser@22.3.0-next.1(@angular/animations@22.3.0-next.1(@angular/core@22.3.0-next.1(@angular/compiler@22.3.0-next.1)(rxjs@7.8.2)(zone.js@0.16.3)))(@angular/common@22.3.0-next.1(@angular/core@22.3.0-next.1(@angular/compiler@22.3.0-next.1)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2))(@angular/core@22.3.0-next.1(@angular/compiler@22.3.0-next.1)(rxjs@7.8.2)(zone.js@0.16.3)))(rxjs@7.8.2) + specifier: 22.3.0-next.2 + version: 22.3.0-next.2(@angular/common@22.3.0-next.2(@angular/core@22.3.0-next.2(@angular/compiler@22.3.0-next.2)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2))(@angular/core@22.3.0-next.2(@angular/compiler@22.3.0-next.2)(rxjs@7.8.2)(zone.js@0.16.3))(@angular/platform-browser@22.3.0-next.2(@angular/animations@22.3.0-next.2(@angular/core@22.3.0-next.2(@angular/compiler@22.3.0-next.2)(rxjs@7.8.2)(zone.js@0.16.3)))(@angular/common@22.3.0-next.2(@angular/core@22.3.0-next.2(@angular/compiler@22.3.0-next.2)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2))(@angular/core@22.3.0-next.2(@angular/compiler@22.3.0-next.2)(rxjs@7.8.2)(zone.js@0.16.3)))(rxjs@7.8.2) '@angular/localize': - specifier: 22.3.0-next.1 - version: 22.3.0-next.1(@angular/compiler-cli@22.3.0-next.1(@angular/compiler@22.3.0-next.1)(typescript@6.0.3))(@angular/compiler@22.3.0-next.1) + specifier: 22.3.0-next.2 + version: 22.3.0-next.2(@angular/compiler-cli@22.3.0-next.2(@angular/compiler@22.3.0-next.2)(typescript@6.0.3))(@angular/compiler@22.3.0-next.2) '@angular/material': specifier: 22.3.0-next.2 - version: 22.3.0-next.2(1acbd77e3019024ea0df0dc9f59ed8c0) + version: 22.3.0-next.2(4016851894464b4783f4f873310c276b) '@angular/ng-dev': - specifier: https://github.com/angular/dev-infra-private-ng-dev-builds.git#fa4308affb4a0dde34ebc95196b58550752485a2 - version: https://codeload.github.com/angular/dev-infra-private-ng-dev-builds/tar.gz/fa4308affb4a0dde34ebc95196b58550752485a2 + specifier: https://github.com/angular/dev-infra-private-ng-dev-builds.git#940c0beef0de4cb128e90962d47ff80e352a1cd8 + version: https://codeload.github.com/angular/dev-infra-private-ng-dev-builds/tar.gz/940c0beef0de4cb128e90962d47ff80e352a1cd8 '@angular/platform-browser': - specifier: 22.3.0-next.1 - version: 22.3.0-next.1(@angular/animations@22.3.0-next.1(@angular/core@22.3.0-next.1(@angular/compiler@22.3.0-next.1)(rxjs@7.8.2)(zone.js@0.16.3)))(@angular/common@22.3.0-next.1(@angular/core@22.3.0-next.1(@angular/compiler@22.3.0-next.1)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2))(@angular/core@22.3.0-next.1(@angular/compiler@22.3.0-next.1)(rxjs@7.8.2)(zone.js@0.16.3)) + specifier: 22.3.0-next.2 + version: 22.3.0-next.2(@angular/animations@22.3.0-next.2(@angular/core@22.3.0-next.2(@angular/compiler@22.3.0-next.2)(rxjs@7.8.2)(zone.js@0.16.3)))(@angular/common@22.3.0-next.2(@angular/core@22.3.0-next.2(@angular/compiler@22.3.0-next.2)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2))(@angular/core@22.3.0-next.2(@angular/compiler@22.3.0-next.2)(rxjs@7.8.2)(zone.js@0.16.3)) '@angular/platform-server': - specifier: 22.3.0-next.1 - version: 22.3.0-next.1(@angular/common@22.3.0-next.1(@angular/core@22.3.0-next.1(@angular/compiler@22.3.0-next.1)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2))(@angular/compiler@22.3.0-next.1)(@angular/core@22.3.0-next.1(@angular/compiler@22.3.0-next.1)(rxjs@7.8.2)(zone.js@0.16.3))(@angular/platform-browser@22.3.0-next.1(@angular/animations@22.3.0-next.1(@angular/core@22.3.0-next.1(@angular/compiler@22.3.0-next.1)(rxjs@7.8.2)(zone.js@0.16.3)))(@angular/common@22.3.0-next.1(@angular/core@22.3.0-next.1(@angular/compiler@22.3.0-next.1)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2))(@angular/core@22.3.0-next.1(@angular/compiler@22.3.0-next.1)(rxjs@7.8.2)(zone.js@0.16.3)))(rxjs@7.8.2) + specifier: 22.3.0-next.2 + version: 22.3.0-next.2(@angular/common@22.3.0-next.2(@angular/core@22.3.0-next.2(@angular/compiler@22.3.0-next.2)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2))(@angular/compiler@22.3.0-next.2)(@angular/core@22.3.0-next.2(@angular/compiler@22.3.0-next.2)(rxjs@7.8.2)(zone.js@0.16.3))(@angular/platform-browser@22.3.0-next.2(@angular/animations@22.3.0-next.2(@angular/core@22.3.0-next.2(@angular/compiler@22.3.0-next.2)(rxjs@7.8.2)(zone.js@0.16.3)))(@angular/common@22.3.0-next.2(@angular/core@22.3.0-next.2(@angular/compiler@22.3.0-next.2)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2))(@angular/core@22.3.0-next.2(@angular/compiler@22.3.0-next.2)(rxjs@7.8.2)(zone.js@0.16.3)))(rxjs@7.8.2) '@angular/router': - specifier: 22.3.0-next.1 - version: 22.3.0-next.1(@angular/common@22.3.0-next.1(@angular/core@22.3.0-next.1(@angular/compiler@22.3.0-next.1)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2))(@angular/core@22.3.0-next.1(@angular/compiler@22.3.0-next.1)(rxjs@7.8.2)(zone.js@0.16.3))(@angular/platform-browser@22.3.0-next.1(@angular/animations@22.3.0-next.1(@angular/core@22.3.0-next.1(@angular/compiler@22.3.0-next.1)(rxjs@7.8.2)(zone.js@0.16.3)))(@angular/common@22.3.0-next.1(@angular/core@22.3.0-next.1(@angular/compiler@22.3.0-next.1)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2))(@angular/core@22.3.0-next.1(@angular/compiler@22.3.0-next.1)(rxjs@7.8.2)(zone.js@0.16.3)))(rxjs@7.8.2) + specifier: 22.3.0-next.2 + version: 22.3.0-next.2(@angular/common@22.3.0-next.2(@angular/core@22.3.0-next.2(@angular/compiler@22.3.0-next.2)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2))(@angular/core@22.3.0-next.2(@angular/compiler@22.3.0-next.2)(rxjs@7.8.2)(zone.js@0.16.3))(@angular/platform-browser@22.3.0-next.2(@angular/animations@22.3.0-next.2(@angular/core@22.3.0-next.2(@angular/compiler@22.3.0-next.2)(rxjs@7.8.2)(zone.js@0.16.3)))(@angular/common@22.3.0-next.2(@angular/core@22.3.0-next.2(@angular/compiler@22.3.0-next.2)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2))(@angular/core@22.3.0-next.2(@angular/compiler@22.3.0-next.2)(rxjs@7.8.2)(zone.js@0.16.3)))(rxjs@7.8.2) '@angular/service-worker': - specifier: 22.3.0-next.1 - version: 22.3.0-next.1(@angular/core@22.3.0-next.1(@angular/compiler@22.3.0-next.1)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2) + specifier: 22.3.0-next.2 + version: 22.3.0-next.2(@angular/core@22.3.0-next.2(@angular/compiler@22.3.0-next.2)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2) '@babel/core': specifier: 8.0.7 version: 8.0.7 @@ -464,7 +464,7 @@ importers: version: 30.1.2(@noble/hashes@1.8.0) ng-packagr: specifier: 22.3.0-next.2 - version: 22.3.0-next.2(@angular/compiler-cli@22.3.0-next.1(@angular/compiler@22.3.0-next.1)(typescript@6.0.3))(supports-color@11.0.0)(tslib@2.8.1)(typescript@6.0.3) + version: 22.3.0-next.2(@angular/compiler-cli@22.3.0-next.2(@angular/compiler@22.3.0-next.2)(typescript@6.0.3))(supports-color@11.0.0)(tslib@2.8.1)(typescript@6.0.3) rxjs: specifier: 7.8.2 version: 7.8.2 @@ -582,7 +582,7 @@ importers: version: 4.9.1(supports-color@11.0.0) ng-packagr: specifier: 22.3.0-next.2 - version: 22.3.0-next.2(@angular/compiler-cli@22.3.0-next.1(@angular/compiler@22.3.0-next.1)(typescript@6.0.3))(supports-color@11.0.0)(tslib@2.8.1)(typescript@6.0.3) + version: 22.3.0-next.2(@angular/compiler-cli@22.3.0-next.2(@angular/compiler@22.3.0-next.2)(typescript@6.0.3))(supports-color@11.0.0)(tslib@2.8.1)(typescript@6.0.3) postcss: specifier: 8.5.29 version: 8.5.29 @@ -670,23 +670,23 @@ importers: specifier: workspace:* version: link:../../angular_devkit/schematics '@angular/common': - specifier: 22.3.0-next.1 - version: 22.3.0-next.1(@angular/core@22.3.0-next.1(@angular/compiler@22.3.0-next.1)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2) + specifier: 22.3.0-next.2 + version: 22.3.0-next.2(@angular/core@22.3.0-next.2(@angular/compiler@22.3.0-next.2)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2) '@angular/compiler': - specifier: 22.3.0-next.1 - version: 22.3.0-next.1 + specifier: 22.3.0-next.2 + version: 22.3.0-next.2 '@angular/core': - specifier: 22.3.0-next.1 - version: 22.3.0-next.1(@angular/compiler@22.3.0-next.1)(rxjs@7.8.2)(zone.js@0.16.3) + specifier: 22.3.0-next.2 + version: 22.3.0-next.2(@angular/compiler@22.3.0-next.2)(rxjs@7.8.2)(zone.js@0.16.3) '@angular/platform-browser': - specifier: 22.3.0-next.1 - version: 22.3.0-next.1(@angular/animations@22.3.0-next.1(@angular/core@22.3.0-next.1(@angular/compiler@22.3.0-next.1)(rxjs@7.8.2)(zone.js@0.16.3)))(@angular/common@22.3.0-next.1(@angular/core@22.3.0-next.1(@angular/compiler@22.3.0-next.1)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2))(@angular/core@22.3.0-next.1(@angular/compiler@22.3.0-next.1)(rxjs@7.8.2)(zone.js@0.16.3)) + specifier: 22.3.0-next.2 + version: 22.3.0-next.2(@angular/animations@22.3.0-next.2(@angular/core@22.3.0-next.2(@angular/compiler@22.3.0-next.2)(rxjs@7.8.2)(zone.js@0.16.3)))(@angular/common@22.3.0-next.2(@angular/core@22.3.0-next.2(@angular/compiler@22.3.0-next.2)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2))(@angular/core@22.3.0-next.2(@angular/compiler@22.3.0-next.2)(rxjs@7.8.2)(zone.js@0.16.3)) '@angular/platform-server': - specifier: 22.3.0-next.1 - version: 22.3.0-next.1(@angular/common@22.3.0-next.1(@angular/core@22.3.0-next.1(@angular/compiler@22.3.0-next.1)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2))(@angular/compiler@22.3.0-next.1)(@angular/core@22.3.0-next.1(@angular/compiler@22.3.0-next.1)(rxjs@7.8.2)(zone.js@0.16.3))(@angular/platform-browser@22.3.0-next.1(@angular/animations@22.3.0-next.1(@angular/core@22.3.0-next.1(@angular/compiler@22.3.0-next.1)(rxjs@7.8.2)(zone.js@0.16.3)))(@angular/common@22.3.0-next.1(@angular/core@22.3.0-next.1(@angular/compiler@22.3.0-next.1)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2))(@angular/core@22.3.0-next.1(@angular/compiler@22.3.0-next.1)(rxjs@7.8.2)(zone.js@0.16.3)))(rxjs@7.8.2) + specifier: 22.3.0-next.2 + version: 22.3.0-next.2(@angular/common@22.3.0-next.2(@angular/core@22.3.0-next.2(@angular/compiler@22.3.0-next.2)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2))(@angular/compiler@22.3.0-next.2)(@angular/core@22.3.0-next.2(@angular/compiler@22.3.0-next.2)(rxjs@7.8.2)(zone.js@0.16.3))(@angular/platform-browser@22.3.0-next.2(@angular/animations@22.3.0-next.2(@angular/core@22.3.0-next.2(@angular/compiler@22.3.0-next.2)(rxjs@7.8.2)(zone.js@0.16.3)))(@angular/common@22.3.0-next.2(@angular/core@22.3.0-next.2(@angular/compiler@22.3.0-next.2)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2))(@angular/core@22.3.0-next.2(@angular/compiler@22.3.0-next.2)(rxjs@7.8.2)(zone.js@0.16.3)))(rxjs@7.8.2) '@angular/router': - specifier: 22.3.0-next.1 - version: 22.3.0-next.1(@angular/common@22.3.0-next.1(@angular/core@22.3.0-next.1(@angular/compiler@22.3.0-next.1)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2))(@angular/core@22.3.0-next.1(@angular/compiler@22.3.0-next.1)(rxjs@7.8.2)(zone.js@0.16.3))(@angular/platform-browser@22.3.0-next.1(@angular/animations@22.3.0-next.1(@angular/core@22.3.0-next.1(@angular/compiler@22.3.0-next.1)(rxjs@7.8.2)(zone.js@0.16.3)))(@angular/common@22.3.0-next.1(@angular/core@22.3.0-next.1(@angular/compiler@22.3.0-next.1)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2))(@angular/core@22.3.0-next.1(@angular/compiler@22.3.0-next.1)(rxjs@7.8.2)(zone.js@0.16.3)))(rxjs@7.8.2) + specifier: 22.3.0-next.2 + version: 22.3.0-next.2(@angular/common@22.3.0-next.2(@angular/core@22.3.0-next.2(@angular/compiler@22.3.0-next.2)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2))(@angular/core@22.3.0-next.2(@angular/compiler@22.3.0-next.2)(rxjs@7.8.2)(zone.js@0.16.3))(@angular/platform-browser@22.3.0-next.2(@angular/animations@22.3.0-next.2(@angular/core@22.3.0-next.2(@angular/compiler@22.3.0-next.2)(rxjs@7.8.2)(zone.js@0.16.3)))(@angular/common@22.3.0-next.2(@angular/core@22.3.0-next.2(@angular/compiler@22.3.0-next.2)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2))(@angular/core@22.3.0-next.2(@angular/compiler@22.3.0-next.2)(rxjs@7.8.2)(zone.js@0.16.3)))(rxjs@7.8.2) '@schematics/angular': specifier: workspace:* version: link:../../schematics/angular @@ -870,7 +870,7 @@ importers: version: 3.0.4(bufferutil@4.1.0)(debug@4.4.3(supports-color@11.0.0))(supports-color@11.0.0)(utf-8-validate@6.0.6) ng-packagr: specifier: 22.3.0-next.2 - version: 22.3.0-next.2(@angular/compiler-cli@22.3.0-next.1(@angular/compiler@22.3.0-next.1)(typescript@6.0.3))(supports-color@11.0.0)(tslib@2.8.1)(typescript@6.0.3) + version: 22.3.0-next.2(@angular/compiler-cli@22.3.0-next.2(@angular/compiler@22.3.0-next.2)(typescript@6.0.3))(supports-color@11.0.0)(tslib@2.8.1)(typescript@6.0.3) sass: specifier: 1.105.1 version: 1.105.1 @@ -965,11 +965,11 @@ importers: specifier: workspace:0.0.0-PLACEHOLDER version: link:../../angular_devkit/core '@angular/compiler': - specifier: 22.3.0-next.1 - version: 22.3.0-next.1 + specifier: 22.3.0-next.2 + version: 22.3.0-next.2 '@angular/compiler-cli': - specifier: 22.3.0-next.1 - version: 22.3.0-next.1(@angular/compiler@22.3.0-next.1)(typescript@6.0.3) + specifier: 22.3.0-next.2 + version: 22.3.0-next.2(@angular/compiler@22.3.0-next.2)(typescript@6.0.3) typescript: specifier: 6.0.3 version: 6.0.3 @@ -1029,11 +1029,12 @@ packages: resolution: {integrity: sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==} engines: {node: '>=6.0.0'} - '@angular/animations@22.3.0-next.1': - resolution: {integrity: sha512-YdJE9xE7EO9xJtXNcWFXCatofYRXmkZm5oPOaKBCTHvX12Iw3SQsybxXr23Lq1gHscAZnqffEfhQ78TdnSl5wA==} + '@angular/animations@22.3.0-next.2': + resolution: {integrity: sha512-YJCMY2lUtiIQNfqTXnwbKjePHAEq4sION4i+66eH7Fhog55eust9BQ7zVCp8CtfPUF2kNwhiMyU6DbZQCxmN1w==} engines: {node: ^22.22.3 || ^24.15.0 || >=26.0.0} + deprecated: '@angular/animations is deprecated. Use `animate.enter` and `animate.leave` instead. For more information see: https://v22.angular.dev/guide/animations.' peerDependencies: - '@angular/core': 22.3.0-next.1 + '@angular/core': 22.3.0-next.2 '@angular/cdk@22.3.0-next.2': resolution: {integrity: sha512-UlleZDkYVds93nKOJ32g393Ca7XyrG+c8r5XoQG3aQHKe5L+lc5HjmPGAJ1Y80iotUQG3NFsgwLnweCGV12yWw==} @@ -1044,33 +1045,33 @@ packages: '@angular/platform-browser': ^22.0.0-0 || ^22.1.0-0 || ^22.2.0-0 || ^22.3.0-0 || ^23.0.0-0 rxjs: ^6.5.3 || ^7.4.0 - '@angular/common@22.3.0-next.1': - resolution: {integrity: sha512-vJ4X+f43MIfOMKJc53ttkwxKSP6pfOFgfZ1m+W6fAIF5Ydy49/GnXIUbM2rtcbhsSYgh+95YMs3lhUrgyMXEUw==} + '@angular/common@22.3.0-next.2': + resolution: {integrity: sha512-w4oG/QGNTC5oY+vBf4WnODDr56vvPt8Y0TgLpDy6mW6ephWaIx8dAgvFdlpohU5R1cOYAABeLboQHtS6pdP8Fg==} engines: {node: ^22.22.3 || ^24.15.0 || >=26.0.0} peerDependencies: - '@angular/core': 22.3.0-next.1 + '@angular/core': 22.3.0-next.2 rxjs: ^6.5.3 || ^7.4.0 - '@angular/compiler-cli@22.3.0-next.1': - resolution: {integrity: sha512-yfJ4jfjdTjTJYhWT3A8aEWZsk4xwTTB/S0oVi9VWm7HAb2trn5c3F5B/nWUJSSX5CXQ8TAnzN27mca2ZhyUPLw==} + '@angular/compiler-cli@22.3.0-next.2': + resolution: {integrity: sha512-r0Cq0n88GBn/iOFAL/oLGC3uBAGMINAYtZDA0gvIG+WZPuyo0CPeUEmAndAFDzuiAPegfXVi8yPlfzLS6uP5mw==} engines: {node: ^22.22.3 || ^24.15.0 || >=26.0.0} hasBin: true peerDependencies: - '@angular/compiler': 22.3.0-next.1 + '@angular/compiler': 22.3.0-next.2 typescript: '>=6.0 <6.1' peerDependenciesMeta: typescript: optional: true - '@angular/compiler@22.3.0-next.1': - resolution: {integrity: sha512-58W3f6lwfMwAlmoKfK4qigYuRQkRF0ZGZiSjAEXFhU1sV48pgQaADiz/2cfNGD3pEcb99sW9853XzDA9zzcbqA==} + '@angular/compiler@22.3.0-next.2': + resolution: {integrity: sha512-ayaEJt1ZDS9qKmAvQHq47m3FSMt2Au95KL+ucElgBHGV0TIuXjLdc25smiRj6Jr47U9D1zbEnFoVgWhKBuCl7g==} engines: {node: ^22.22.3 || ^24.15.0 || >=26.0.0} - '@angular/core@22.3.0-next.1': - resolution: {integrity: sha512-6Y4bgGkZmje+7Ct8L3PARXfpm5ZrUYuWYKNz4Xtlr08Fsx1Fp2oroUQ8BsPgZGgfzmHaWyTBE/fvK7ZbybKcjw==} + '@angular/core@22.3.0-next.2': + resolution: {integrity: sha512-9onGgNA0v0q9UI31uVAk3K5Q2r/ye82qwKsQv5FesyZ1hnEyrMMc0kdTzHkgDDRS2xpwVHchZH8BTgJA6A+SGQ==} engines: {node: ^22.22.3 || ^24.15.0 || >=26.0.0} peerDependencies: - '@angular/compiler': 22.3.0-next.1 + '@angular/compiler': 22.3.0-next.2 rxjs: ^6.5.3 || ^7.4.0 zone.js: ~0.15.0 || ~0.16.0 peerDependenciesMeta: @@ -1079,22 +1080,22 @@ packages: zone.js: optional: true - '@angular/forms@22.3.0-next.1': - resolution: {integrity: sha512-dssi5/s/DekmNKDA8zFDgfDVLrK2akZxg0lFO+e/pDeSYBKoalbljtAssPFEdGCiDdfmz6pFasvRw50TYI1ErQ==} + '@angular/forms@22.3.0-next.2': + resolution: {integrity: sha512-1NF2giTkXbULCVTNV8fPooKa8HKYEozWdgzZdCHvtrgIF6C2aW+PN/4ZJTddQjFBjH/4XnQ2xfM7nFCm/SQJuw==} engines: {node: ^22.22.3 || ^24.15.0 || >=26.0.0} peerDependencies: - '@angular/common': 22.3.0-next.1 - '@angular/core': 22.3.0-next.1 - '@angular/platform-browser': 22.3.0-next.1 + '@angular/common': 22.3.0-next.2 + '@angular/core': 22.3.0-next.2 + '@angular/platform-browser': 22.3.0-next.2 rxjs: ^6.5.3 || ^7.4.0 - '@angular/localize@22.3.0-next.1': - resolution: {integrity: sha512-KPZuMWghal8+ZQn3N8s6shDZTyKTFSyw55ooxxhJNt+bOQ++mmjPJ7JCen39qAAILYpgI3IriLnswsbhGnGDNQ==} + '@angular/localize@22.3.0-next.2': + resolution: {integrity: sha512-Q0+i9GURr6A6jUIi5N4b/2ev8ZKDKfcZ1e1B9u6jT+wb1/mryB+8sJnFD3sT7a+E/2wRkNk5GCQuT+HjYzi+HQ==} engines: {node: ^22.22.3 || ^24.15.0 || >=26.0.0} hasBin: true peerDependencies: - '@angular/compiler': 22.3.0-next.1 - '@angular/compiler-cli': 22.3.0-next.1 + '@angular/compiler': 22.3.0-next.2 + '@angular/compiler-cli': 22.3.0-next.2 '@angular/material@22.3.0-next.2': resolution: {integrity: sha512-4l6+DzUtwIH+SYrZdT54Lg7sNvFu6+MmLxlQQB8TtC5V5EijqOv1rjLmp+mFFgpVFmwlZwdGS8vJfRvkzKLY2w==} @@ -1106,47 +1107,47 @@ packages: '@angular/platform-browser': ^22.0.0-0 || ^22.1.0-0 || ^22.2.0-0 || ^22.3.0-0 || ^23.0.0-0 rxjs: ^6.5.3 || ^7.4.0 - '@angular/ng-dev@https://codeload.github.com/angular/dev-infra-private-ng-dev-builds/tar.gz/fa4308affb4a0dde34ebc95196b58550752485a2': - resolution: {gitHosted: true, integrity: sha512-zq1Lg7edQb2cf9QrSiQEU/+LwY4e/af9tN9W3hO5jDdYK+gp+sYZbBbuzounSWkmK+j+oG0K5CA9/kmyHAimZg==, tarball: https://codeload.github.com/angular/dev-infra-private-ng-dev-builds/tar.gz/fa4308affb4a0dde34ebc95196b58550752485a2} - version: 0.0.0-f28485704b2d1f81ae380a8296a4f14d9852c248 + '@angular/ng-dev@https://codeload.github.com/angular/dev-infra-private-ng-dev-builds/tar.gz/940c0beef0de4cb128e90962d47ff80e352a1cd8': + resolution: {gitHosted: true, integrity: sha512-6d8sBwbru5J4TsfMlHneqn1PD+K2p5l5HGKOba3Y/Ygl+bUEtxIJyM8aRgX88WWgVwjcaKSByQ6gClVxjqNznw==, tarball: https://codeload.github.com/angular/dev-infra-private-ng-dev-builds/tar.gz/940c0beef0de4cb128e90962d47ff80e352a1cd8} + version: 0.0.0-f8062d1d0f50e59fcb36a9375a596f416204ee28 hasBin: true - '@angular/platform-browser@22.3.0-next.1': - resolution: {integrity: sha512-2mhIqbG0U75M3m2zICdF1qInDsuwiS+asx/xHWXPNAC1Igsiiq2DrCo9lGfKAuYpORvRWJfppXSD88atBeiDJw==} + '@angular/platform-browser@22.3.0-next.2': + resolution: {integrity: sha512-/KrZjns+lbZx9pMpWLI1E7C5y8B5veA8D/5dWJnNuiUmbAWevaEGpsMl1xGnopuE8JrJvUEOI2aSU4oT729FIQ==} engines: {node: ^22.22.3 || ^24.15.0 || >=26.0.0} peerDependencies: - '@angular/animations': 22.3.0-next.1 - '@angular/common': 22.3.0-next.1 - '@angular/core': 22.3.0-next.1 + '@angular/animations': 22.3.0-next.2 + '@angular/common': 22.3.0-next.2 + '@angular/core': 22.3.0-next.2 peerDependenciesMeta: '@angular/animations': optional: true - '@angular/platform-server@22.3.0-next.1': - resolution: {integrity: sha512-sGX0TGZMoN2c5j3kC6egIoTaD8lNurzIlRbbOAlFhkv6I8NJuyStk74pXn9yTsi2co+i/b8eAQe7Jw0mRXa6gA==} + '@angular/platform-server@22.3.0-next.2': + resolution: {integrity: sha512-AyegJGA+qdjqUJGPX8IysYKqt5XUoLYnjmVzzBV3bYrN0kt0g9SRirm4QCExQB30v/g+AKiVI9Fib50VyU/O9Q==} engines: {node: ^22.22.3 || ^24.15.0 || >=26.0.0} peerDependencies: - '@angular/common': 22.3.0-next.1 - '@angular/compiler': 22.3.0-next.1 - '@angular/core': 22.3.0-next.1 - '@angular/platform-browser': 22.3.0-next.1 + '@angular/common': 22.3.0-next.2 + '@angular/compiler': 22.3.0-next.2 + '@angular/core': 22.3.0-next.2 + '@angular/platform-browser': 22.3.0-next.2 rxjs: ^6.5.3 || ^7.4.0 - '@angular/router@22.3.0-next.1': - resolution: {integrity: sha512-Syu0u+mWinMzwLYidzi1yy2wbXmljRucsLE1jwaaf97rZ6Lqqc8cgnfWBSwxVdZ1r8qhR5zlauvAN/+cbiMF3g==} + '@angular/router@22.3.0-next.2': + resolution: {integrity: sha512-b5Sn7sokZxL5rdN0M8Hf0FYexYo+l5vA7gcxpoJld00QPtv6Uq75mqjhp6MFIk8pWhANY3RoKEjHMdUoNgO4kA==} engines: {node: ^22.22.3 || ^24.15.0 || >=26.0.0} peerDependencies: - '@angular/common': 22.3.0-next.1 - '@angular/core': 22.3.0-next.1 - '@angular/platform-browser': 22.3.0-next.1 + '@angular/common': 22.3.0-next.2 + '@angular/core': 22.3.0-next.2 + '@angular/platform-browser': 22.3.0-next.2 rxjs: ^6.5.3 || ^7.4.0 - '@angular/service-worker@22.3.0-next.1': - resolution: {integrity: sha512-KStwvrt0vE8UAfXEE1GtIJm1b/oKu5XNSzCMqF/xE+VjSTrhnwNaKfyqXbK+7dVwr42AcUifTkOKJLq8zlz8fQ==} + '@angular/service-worker@22.3.0-next.2': + resolution: {integrity: sha512-L4a2at4NHToTNHwD03ir3w1ZXSrM/aARE2j4y7tcYBQXPQlSqwC7Bg4QHQecZ8Ua+eh8ssdVdpb8kPL4A+85pQ==} engines: {node: ^22.22.3 || ^24.15.0 || >=26.0.0} hasBin: true peerDependencies: - '@angular/core': 22.3.0-next.1 + '@angular/core': 22.3.0-next.2 rxjs: ^6.5.3 || ^7.4.0 '@asamuzakjp/css-color@7.1.5': @@ -1177,10 +1178,6 @@ packages: resolution: {integrity: sha512-RgHBCvtjbOK2gXSNBNIkNoEc9qoVEtau3hj8gEqKQuL3HZAibKarWFEI3Lfm6EYKkLalOh8eSrj9b+ch9H/VBA==} engines: {node: '>=6.9.0'} - '@babel/core@8.0.6': - resolution: {integrity: sha512-5zwYt1V4ji3mXKKRIAkohSJ29WepxNwxQi+7y7P5AcVPh1dcxnZBU2cfxHnPwS+u9+lZnXPsv30TQaF2xg+Tfg==} - engines: {node: ^22.18.0 || >=24.11.0} - '@babel/core@8.0.7': resolution: {integrity: sha512-ZIsZWBG6Y1oa+8fkQVp0xeCdjCHBkXFCCIWrmg9SvejVvfcVQgKKRmGrBDWfM7rilhvnRoEuaqa5dkK7KB3pHA==} engines: {node: ^22.18.0 || >=24.11.0} @@ -2282,8 +2279,8 @@ packages: resolution: {integrity: sha512-IJn+8A3QZJfe7FUtWqHVNo3xJs7KFpurCWGWCiCz3oEh+BkRymKZ1QxfAbU2yGMDzTytLGQ2IV6T2r3cuo75/w==} engines: {node: '>=18'} - '@google/genai@2.28.0': - resolution: {integrity: sha512-hyNAJj+ywu3L46qlZod6KO/JvcT3QONz6VCiPevC/FWOjAD+LQb7DMLUoV8vzoLpt61Q0ruQX99iqbxEjPJWmw==} + '@google/genai@2.29.1': + resolution: {integrity: sha512-keU+JsY11fT4ykdFA6Q8iQHBgOAAVssFLxPtXRjCIEr5Zt2GzE75c22bBmq87XbhgtpuKaObnSgsrG60rj0ZMA==} engines: {node: '>=20.0.0'} peerDependencies: '@modelcontextprotocol/sdk': ^1.25.2 @@ -3804,8 +3801,8 @@ packages: '@types/node@22.20.5': resolution: {integrity: sha512-U2+DNr+wSjpsTS/wZGYHq7GcwfuSmKiKvoPvK22zwTlRhU91yOniN4qRR5KhIjvif7ysw/dz/hKmfDH0Ris4aA==} - '@types/node@24.19.1': - resolution: {integrity: sha512-aS3/DG0oM05K0RIXXP+hKjinGG5IgSSVGzswZxW3O0sS3pH4/fycXundUC9XsszgKCk4gHXylTEK6hyFxVxnoQ==} + '@types/node@24.19.2': + resolution: {integrity: sha512-93d49wCWJkCyN87MxLpNN6KXPCwFw7bVUg79mGUV1OS40JGWwVCr8n61DXCSqz7CV6/VfPkb7xec7uP2M+QHWQ==} '@types/npm-package-arg@6.1.4': resolution: {integrity: sha512-vDgdbMy2QXHnAruzlv68pUtXCjmqUk3WrBAsRboRovsOmxbfn/WiYCjmecyKjGztnMps5dWp4Uq2prp+Ilo17Q==} @@ -7020,10 +7017,6 @@ packages: resolution: {integrity: sha512-gXah6aZrcUxjWg2zR2MwouP2eHlCBzdV4pygudehaKXSGW4v2AsRQUK+lwwXhii6KFZcunEnmSUoYp5CXibxtA==} engines: {node: '>= 0.4'} - obug@2.2.1: - resolution: {integrity: sha512-XrsrhT5sybtKI6wakr2SPOlGZWWYbUXZ7a0jT8/QOeAPau+1X/bSegNe5YR75oJmEZQbKningirmGOEJCIk61Q==} - engines: {node: '>=12.20.0'} - obug@3.0.0: resolution: {integrity: sha512-5vvB5+W7ePv+p3uqxi+RcW1XAzLW0/hxt3/4X4Lc4qHudzOhmBiBwOY6DRob4WnanAEGvNcLjF+KNOufrUoEQw==} engines: {node: '>=12.20.0'} @@ -8454,10 +8447,6 @@ packages: engines: {node: '>=22'} hasBin: true - verkit@0.3.2: - resolution: {integrity: sha512-zj/ob3UsvJGN0whEAKFp53REA5X66hvffVqoCtVQAakJKnKlH+/PcOfMoFwIG/o4rElqLv/ycAFlx8ZlXUorCg==} - engines: {node: '>=18.12.0'} - verkit@0.5.0: resolution: {integrity: sha512-u4J1hr6Y+C/hit34GwL3eIcUf3wngT8TlYUjK7tk0jxydKLAq3sYvifjdTDA6U3KCKRcQCQDGf/srjxfZF3l7g==} engines: {node: '>=18.12.0'} @@ -8865,31 +8854,31 @@ snapshots: '@jridgewell/gen-mapping': 0.3.13 '@jridgewell/trace-mapping': 0.3.31 - '@angular/animations@22.3.0-next.1(@angular/core@22.3.0-next.1(@angular/compiler@22.3.0-next.1)(rxjs@7.8.2)(zone.js@0.16.3))': + '@angular/animations@22.3.0-next.2(@angular/core@22.3.0-next.2(@angular/compiler@22.3.0-next.2)(rxjs@7.8.2)(zone.js@0.16.3))': dependencies: - '@angular/core': 22.3.0-next.1(@angular/compiler@22.3.0-next.1)(rxjs@7.8.2)(zone.js@0.16.3) + '@angular/core': 22.3.0-next.2(@angular/compiler@22.3.0-next.2)(rxjs@7.8.2)(zone.js@0.16.3) tslib: 2.8.1 - '@angular/cdk@22.3.0-next.2(1e228ab395252fe57958c1335d3a301f)': + '@angular/cdk@22.3.0-next.2(e02572097466d520d7eb144e95d6bbd2)': dependencies: - '@angular/common': 22.3.0-next.1(@angular/core@22.3.0-next.1(@angular/compiler@22.3.0-next.1)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2) - '@angular/core': 22.3.0-next.1(@angular/compiler@22.3.0-next.1)(rxjs@7.8.2)(zone.js@0.16.3) - '@angular/forms': 22.3.0-next.1(@angular/common@22.3.0-next.1(@angular/core@22.3.0-next.1(@angular/compiler@22.3.0-next.1)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2))(@angular/core@22.3.0-next.1(@angular/compiler@22.3.0-next.1)(rxjs@7.8.2)(zone.js@0.16.3))(@angular/platform-browser@22.3.0-next.1(@angular/animations@22.3.0-next.1(@angular/core@22.3.0-next.1(@angular/compiler@22.3.0-next.1)(rxjs@7.8.2)(zone.js@0.16.3)))(@angular/common@22.3.0-next.1(@angular/core@22.3.0-next.1(@angular/compiler@22.3.0-next.1)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2))(@angular/core@22.3.0-next.1(@angular/compiler@22.3.0-next.1)(rxjs@7.8.2)(zone.js@0.16.3)))(rxjs@7.8.2) - '@angular/platform-browser': 22.3.0-next.1(@angular/animations@22.3.0-next.1(@angular/core@22.3.0-next.1(@angular/compiler@22.3.0-next.1)(rxjs@7.8.2)(zone.js@0.16.3)))(@angular/common@22.3.0-next.1(@angular/core@22.3.0-next.1(@angular/compiler@22.3.0-next.1)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2))(@angular/core@22.3.0-next.1(@angular/compiler@22.3.0-next.1)(rxjs@7.8.2)(zone.js@0.16.3)) + '@angular/common': 22.3.0-next.2(@angular/core@22.3.0-next.2(@angular/compiler@22.3.0-next.2)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2) + '@angular/core': 22.3.0-next.2(@angular/compiler@22.3.0-next.2)(rxjs@7.8.2)(zone.js@0.16.3) + '@angular/forms': 22.3.0-next.2(@angular/common@22.3.0-next.2(@angular/core@22.3.0-next.2(@angular/compiler@22.3.0-next.2)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2))(@angular/core@22.3.0-next.2(@angular/compiler@22.3.0-next.2)(rxjs@7.8.2)(zone.js@0.16.3))(@angular/platform-browser@22.3.0-next.2(@angular/animations@22.3.0-next.2(@angular/core@22.3.0-next.2(@angular/compiler@22.3.0-next.2)(rxjs@7.8.2)(zone.js@0.16.3)))(@angular/common@22.3.0-next.2(@angular/core@22.3.0-next.2(@angular/compiler@22.3.0-next.2)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2))(@angular/core@22.3.0-next.2(@angular/compiler@22.3.0-next.2)(rxjs@7.8.2)(zone.js@0.16.3)))(rxjs@7.8.2) + '@angular/platform-browser': 22.3.0-next.2(@angular/animations@22.3.0-next.2(@angular/core@22.3.0-next.2(@angular/compiler@22.3.0-next.2)(rxjs@7.8.2)(zone.js@0.16.3)))(@angular/common@22.3.0-next.2(@angular/core@22.3.0-next.2(@angular/compiler@22.3.0-next.2)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2))(@angular/core@22.3.0-next.2(@angular/compiler@22.3.0-next.2)(rxjs@7.8.2)(zone.js@0.16.3)) parse5: 8.0.1 rxjs: 7.8.2 tslib: 2.8.1 - '@angular/common@22.3.0-next.1(@angular/core@22.3.0-next.1(@angular/compiler@22.3.0-next.1)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2)': + '@angular/common@22.3.0-next.2(@angular/core@22.3.0-next.2(@angular/compiler@22.3.0-next.2)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2)': dependencies: - '@angular/core': 22.3.0-next.1(@angular/compiler@22.3.0-next.1)(rxjs@7.8.2)(zone.js@0.16.3) + '@angular/core': 22.3.0-next.2(@angular/compiler@22.3.0-next.2)(rxjs@7.8.2)(zone.js@0.16.3) rxjs: 7.8.2 tslib: 2.8.1 - '@angular/compiler-cli@22.3.0-next.1(@angular/compiler@22.3.0-next.1)(typescript@6.0.3)': + '@angular/compiler-cli@22.3.0-next.2(@angular/compiler@22.3.0-next.2)(typescript@6.0.3)': dependencies: - '@angular/compiler': 22.3.0-next.1 - '@babel/core': 8.0.6 + '@angular/compiler': 22.3.0-next.2 + '@babel/core': 8.0.7 '@jridgewell/sourcemap-codec': 1.6.0 chokidar: 5.0.0 convert-source-map: 1.9.0 @@ -8900,54 +8889,54 @@ snapshots: optionalDependencies: typescript: 6.0.3 - '@angular/compiler@22.3.0-next.1': + '@angular/compiler@22.3.0-next.2': dependencies: tslib: 2.8.1 - '@angular/core@22.3.0-next.1(@angular/compiler@22.3.0-next.1)(rxjs@7.8.2)(zone.js@0.16.3)': + '@angular/core@22.3.0-next.2(@angular/compiler@22.3.0-next.2)(rxjs@7.8.2)(zone.js@0.16.3)': dependencies: rxjs: 7.8.2 tslib: 2.8.1 optionalDependencies: - '@angular/compiler': 22.3.0-next.1 + '@angular/compiler': 22.3.0-next.2 zone.js: 0.16.3 - '@angular/forms@22.3.0-next.1(@angular/common@22.3.0-next.1(@angular/core@22.3.0-next.1(@angular/compiler@22.3.0-next.1)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2))(@angular/core@22.3.0-next.1(@angular/compiler@22.3.0-next.1)(rxjs@7.8.2)(zone.js@0.16.3))(@angular/platform-browser@22.3.0-next.1(@angular/animations@22.3.0-next.1(@angular/core@22.3.0-next.1(@angular/compiler@22.3.0-next.1)(rxjs@7.8.2)(zone.js@0.16.3)))(@angular/common@22.3.0-next.1(@angular/core@22.3.0-next.1(@angular/compiler@22.3.0-next.1)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2))(@angular/core@22.3.0-next.1(@angular/compiler@22.3.0-next.1)(rxjs@7.8.2)(zone.js@0.16.3)))(rxjs@7.8.2)': + '@angular/forms@22.3.0-next.2(@angular/common@22.3.0-next.2(@angular/core@22.3.0-next.2(@angular/compiler@22.3.0-next.2)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2))(@angular/core@22.3.0-next.2(@angular/compiler@22.3.0-next.2)(rxjs@7.8.2)(zone.js@0.16.3))(@angular/platform-browser@22.3.0-next.2(@angular/animations@22.3.0-next.2(@angular/core@22.3.0-next.2(@angular/compiler@22.3.0-next.2)(rxjs@7.8.2)(zone.js@0.16.3)))(@angular/common@22.3.0-next.2(@angular/core@22.3.0-next.2(@angular/compiler@22.3.0-next.2)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2))(@angular/core@22.3.0-next.2(@angular/compiler@22.3.0-next.2)(rxjs@7.8.2)(zone.js@0.16.3)))(rxjs@7.8.2)': dependencies: - '@angular/common': 22.3.0-next.1(@angular/core@22.3.0-next.1(@angular/compiler@22.3.0-next.1)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2) - '@angular/core': 22.3.0-next.1(@angular/compiler@22.3.0-next.1)(rxjs@7.8.2)(zone.js@0.16.3) - '@angular/platform-browser': 22.3.0-next.1(@angular/animations@22.3.0-next.1(@angular/core@22.3.0-next.1(@angular/compiler@22.3.0-next.1)(rxjs@7.8.2)(zone.js@0.16.3)))(@angular/common@22.3.0-next.1(@angular/core@22.3.0-next.1(@angular/compiler@22.3.0-next.1)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2))(@angular/core@22.3.0-next.1(@angular/compiler@22.3.0-next.1)(rxjs@7.8.2)(zone.js@0.16.3)) + '@angular/common': 22.3.0-next.2(@angular/core@22.3.0-next.2(@angular/compiler@22.3.0-next.2)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2) + '@angular/core': 22.3.0-next.2(@angular/compiler@22.3.0-next.2)(rxjs@7.8.2)(zone.js@0.16.3) + '@angular/platform-browser': 22.3.0-next.2(@angular/animations@22.3.0-next.2(@angular/core@22.3.0-next.2(@angular/compiler@22.3.0-next.2)(rxjs@7.8.2)(zone.js@0.16.3)))(@angular/common@22.3.0-next.2(@angular/core@22.3.0-next.2(@angular/compiler@22.3.0-next.2)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2))(@angular/core@22.3.0-next.2(@angular/compiler@22.3.0-next.2)(rxjs@7.8.2)(zone.js@0.16.3)) '@standard-schema/spec': 1.1.0 rxjs: 7.8.2 tslib: 2.8.1 - zod: 4.6.5 + zod: 4.6.7 - '@angular/localize@22.3.0-next.1(@angular/compiler-cli@22.3.0-next.1(@angular/compiler@22.3.0-next.1)(typescript@6.0.3))(@angular/compiler@22.3.0-next.1)': + '@angular/localize@22.3.0-next.2(@angular/compiler-cli@22.3.0-next.2(@angular/compiler@22.3.0-next.2)(typescript@6.0.3))(@angular/compiler@22.3.0-next.2)': dependencies: - '@angular/compiler': 22.3.0-next.1 - '@angular/compiler-cli': 22.3.0-next.1(@angular/compiler@22.3.0-next.1)(typescript@6.0.3) - '@babel/core': 8.0.6 + '@angular/compiler': 22.3.0-next.2 + '@angular/compiler-cli': 22.3.0-next.2(@angular/compiler@22.3.0-next.2)(typescript@6.0.3) + '@babel/core': 8.0.7 tinyglobby: 0.2.17 yargs: 18.2.0 - '@angular/material@22.3.0-next.2(1acbd77e3019024ea0df0dc9f59ed8c0)': + '@angular/material@22.3.0-next.2(4016851894464b4783f4f873310c276b)': dependencies: - '@angular/cdk': 22.3.0-next.2(1e228ab395252fe57958c1335d3a301f) - '@angular/common': 22.3.0-next.1(@angular/core@22.3.0-next.1(@angular/compiler@22.3.0-next.1)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2) - '@angular/core': 22.3.0-next.1(@angular/compiler@22.3.0-next.1)(rxjs@7.8.2)(zone.js@0.16.3) - '@angular/forms': 22.3.0-next.1(@angular/common@22.3.0-next.1(@angular/core@22.3.0-next.1(@angular/compiler@22.3.0-next.1)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2))(@angular/core@22.3.0-next.1(@angular/compiler@22.3.0-next.1)(rxjs@7.8.2)(zone.js@0.16.3))(@angular/platform-browser@22.3.0-next.1(@angular/animations@22.3.0-next.1(@angular/core@22.3.0-next.1(@angular/compiler@22.3.0-next.1)(rxjs@7.8.2)(zone.js@0.16.3)))(@angular/common@22.3.0-next.1(@angular/core@22.3.0-next.1(@angular/compiler@22.3.0-next.1)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2))(@angular/core@22.3.0-next.1(@angular/compiler@22.3.0-next.1)(rxjs@7.8.2)(zone.js@0.16.3)))(rxjs@7.8.2) - '@angular/platform-browser': 22.3.0-next.1(@angular/animations@22.3.0-next.1(@angular/core@22.3.0-next.1(@angular/compiler@22.3.0-next.1)(rxjs@7.8.2)(zone.js@0.16.3)))(@angular/common@22.3.0-next.1(@angular/core@22.3.0-next.1(@angular/compiler@22.3.0-next.1)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2))(@angular/core@22.3.0-next.1(@angular/compiler@22.3.0-next.1)(rxjs@7.8.2)(zone.js@0.16.3)) + '@angular/cdk': 22.3.0-next.2(e02572097466d520d7eb144e95d6bbd2) + '@angular/common': 22.3.0-next.2(@angular/core@22.3.0-next.2(@angular/compiler@22.3.0-next.2)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2) + '@angular/core': 22.3.0-next.2(@angular/compiler@22.3.0-next.2)(rxjs@7.8.2)(zone.js@0.16.3) + '@angular/forms': 22.3.0-next.2(@angular/common@22.3.0-next.2(@angular/core@22.3.0-next.2(@angular/compiler@22.3.0-next.2)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2))(@angular/core@22.3.0-next.2(@angular/compiler@22.3.0-next.2)(rxjs@7.8.2)(zone.js@0.16.3))(@angular/platform-browser@22.3.0-next.2(@angular/animations@22.3.0-next.2(@angular/core@22.3.0-next.2(@angular/compiler@22.3.0-next.2)(rxjs@7.8.2)(zone.js@0.16.3)))(@angular/common@22.3.0-next.2(@angular/core@22.3.0-next.2(@angular/compiler@22.3.0-next.2)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2))(@angular/core@22.3.0-next.2(@angular/compiler@22.3.0-next.2)(rxjs@7.8.2)(zone.js@0.16.3)))(rxjs@7.8.2) + '@angular/platform-browser': 22.3.0-next.2(@angular/animations@22.3.0-next.2(@angular/core@22.3.0-next.2(@angular/compiler@22.3.0-next.2)(rxjs@7.8.2)(zone.js@0.16.3)))(@angular/common@22.3.0-next.2(@angular/core@22.3.0-next.2(@angular/compiler@22.3.0-next.2)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2))(@angular/core@22.3.0-next.2(@angular/compiler@22.3.0-next.2)(rxjs@7.8.2)(zone.js@0.16.3)) rxjs: 7.8.2 tslib: 2.8.1 - '@angular/ng-dev@https://codeload.github.com/angular/dev-infra-private-ng-dev-builds/tar.gz/fa4308affb4a0dde34ebc95196b58550752485a2': + '@angular/ng-dev@https://codeload.github.com/angular/dev-infra-private-ng-dev-builds/tar.gz/940c0beef0de4cb128e90962d47ff80e352a1cd8': dependencies: '@actions/core': 3.0.1 '@conventional-changelog/git-client': 3.2.0(conventional-commits-filter@6.0.1)(conventional-commits-parser@7.1.3) '@google-cloud/spanner': 8.0.0(supports-color@11.0.0) - '@google/genai': 2.28.0(bufferutil@4.1.0)(supports-color@11.0.0)(utf-8-validate@6.0.6) - '@inquirer/prompts': 8.7.3(@types/node@24.19.1) - '@inquirer/type': 4.2.0(@types/node@24.19.1) + '@google/genai': 2.29.1(bufferutil@4.1.0)(supports-color@11.0.0)(utf-8-validate@6.0.6) + '@inquirer/prompts': 8.7.3(@types/node@24.19.2) + '@inquirer/type': 4.2.0(@types/node@24.19.2) '@octokit/auth-app': 8.3.1 '@octokit/core': 7.0.8 '@octokit/graphql': 9.0.5 @@ -8961,7 +8950,7 @@ snapshots: '@types/events': 3.0.3 '@types/folder-hash': 4.0.4 '@types/jasmine': 6.0.0 - '@types/node': 24.19.1 + '@types/node': 24.19.2 '@types/semver': 7.8.0 '@types/which': 3.0.4 '@types/yargs': 17.0.35 @@ -8992,40 +8981,40 @@ snapshots: which: 7.0.0 yaml: 2.9.1 yargs: 18.2.0 - zod: 4.6.5 + zod: 4.6.7 transitivePeerDependencies: - '@modelcontextprotocol/sdk' - '@react-native-async-storage/async-storage' - '@angular/platform-browser@22.3.0-next.1(@angular/animations@22.3.0-next.1(@angular/core@22.3.0-next.1(@angular/compiler@22.3.0-next.1)(rxjs@7.8.2)(zone.js@0.16.3)))(@angular/common@22.3.0-next.1(@angular/core@22.3.0-next.1(@angular/compiler@22.3.0-next.1)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2))(@angular/core@22.3.0-next.1(@angular/compiler@22.3.0-next.1)(rxjs@7.8.2)(zone.js@0.16.3))': + '@angular/platform-browser@22.3.0-next.2(@angular/animations@22.3.0-next.2(@angular/core@22.3.0-next.2(@angular/compiler@22.3.0-next.2)(rxjs@7.8.2)(zone.js@0.16.3)))(@angular/common@22.3.0-next.2(@angular/core@22.3.0-next.2(@angular/compiler@22.3.0-next.2)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2))(@angular/core@22.3.0-next.2(@angular/compiler@22.3.0-next.2)(rxjs@7.8.2)(zone.js@0.16.3))': dependencies: - '@angular/common': 22.3.0-next.1(@angular/core@22.3.0-next.1(@angular/compiler@22.3.0-next.1)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2) - '@angular/core': 22.3.0-next.1(@angular/compiler@22.3.0-next.1)(rxjs@7.8.2)(zone.js@0.16.3) + '@angular/common': 22.3.0-next.2(@angular/core@22.3.0-next.2(@angular/compiler@22.3.0-next.2)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2) + '@angular/core': 22.3.0-next.2(@angular/compiler@22.3.0-next.2)(rxjs@7.8.2)(zone.js@0.16.3) tslib: 2.8.1 optionalDependencies: - '@angular/animations': 22.3.0-next.1(@angular/core@22.3.0-next.1(@angular/compiler@22.3.0-next.1)(rxjs@7.8.2)(zone.js@0.16.3)) + '@angular/animations': 22.3.0-next.2(@angular/core@22.3.0-next.2(@angular/compiler@22.3.0-next.2)(rxjs@7.8.2)(zone.js@0.16.3)) - '@angular/platform-server@22.3.0-next.1(@angular/common@22.3.0-next.1(@angular/core@22.3.0-next.1(@angular/compiler@22.3.0-next.1)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2))(@angular/compiler@22.3.0-next.1)(@angular/core@22.3.0-next.1(@angular/compiler@22.3.0-next.1)(rxjs@7.8.2)(zone.js@0.16.3))(@angular/platform-browser@22.3.0-next.1(@angular/animations@22.3.0-next.1(@angular/core@22.3.0-next.1(@angular/compiler@22.3.0-next.1)(rxjs@7.8.2)(zone.js@0.16.3)))(@angular/common@22.3.0-next.1(@angular/core@22.3.0-next.1(@angular/compiler@22.3.0-next.1)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2))(@angular/core@22.3.0-next.1(@angular/compiler@22.3.0-next.1)(rxjs@7.8.2)(zone.js@0.16.3)))(rxjs@7.8.2)': + '@angular/platform-server@22.3.0-next.2(@angular/common@22.3.0-next.2(@angular/core@22.3.0-next.2(@angular/compiler@22.3.0-next.2)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2))(@angular/compiler@22.3.0-next.2)(@angular/core@22.3.0-next.2(@angular/compiler@22.3.0-next.2)(rxjs@7.8.2)(zone.js@0.16.3))(@angular/platform-browser@22.3.0-next.2(@angular/animations@22.3.0-next.2(@angular/core@22.3.0-next.2(@angular/compiler@22.3.0-next.2)(rxjs@7.8.2)(zone.js@0.16.3)))(@angular/common@22.3.0-next.2(@angular/core@22.3.0-next.2(@angular/compiler@22.3.0-next.2)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2))(@angular/core@22.3.0-next.2(@angular/compiler@22.3.0-next.2)(rxjs@7.8.2)(zone.js@0.16.3)))(rxjs@7.8.2)': dependencies: - '@angular/common': 22.3.0-next.1(@angular/core@22.3.0-next.1(@angular/compiler@22.3.0-next.1)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2) - '@angular/compiler': 22.3.0-next.1 - '@angular/core': 22.3.0-next.1(@angular/compiler@22.3.0-next.1)(rxjs@7.8.2)(zone.js@0.16.3) - '@angular/platform-browser': 22.3.0-next.1(@angular/animations@22.3.0-next.1(@angular/core@22.3.0-next.1(@angular/compiler@22.3.0-next.1)(rxjs@7.8.2)(zone.js@0.16.3)))(@angular/common@22.3.0-next.1(@angular/core@22.3.0-next.1(@angular/compiler@22.3.0-next.1)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2))(@angular/core@22.3.0-next.1(@angular/compiler@22.3.0-next.1)(rxjs@7.8.2)(zone.js@0.16.3)) + '@angular/common': 22.3.0-next.2(@angular/core@22.3.0-next.2(@angular/compiler@22.3.0-next.2)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2) + '@angular/compiler': 22.3.0-next.2 + '@angular/core': 22.3.0-next.2(@angular/compiler@22.3.0-next.2)(rxjs@7.8.2)(zone.js@0.16.3) + '@angular/platform-browser': 22.3.0-next.2(@angular/animations@22.3.0-next.2(@angular/core@22.3.0-next.2(@angular/compiler@22.3.0-next.2)(rxjs@7.8.2)(zone.js@0.16.3)))(@angular/common@22.3.0-next.2(@angular/core@22.3.0-next.2(@angular/compiler@22.3.0-next.2)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2))(@angular/core@22.3.0-next.2(@angular/compiler@22.3.0-next.2)(rxjs@7.8.2)(zone.js@0.16.3)) rxjs: 7.8.2 tslib: 2.8.1 xhr2: 0.2.1 - '@angular/router@22.3.0-next.1(@angular/common@22.3.0-next.1(@angular/core@22.3.0-next.1(@angular/compiler@22.3.0-next.1)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2))(@angular/core@22.3.0-next.1(@angular/compiler@22.3.0-next.1)(rxjs@7.8.2)(zone.js@0.16.3))(@angular/platform-browser@22.3.0-next.1(@angular/animations@22.3.0-next.1(@angular/core@22.3.0-next.1(@angular/compiler@22.3.0-next.1)(rxjs@7.8.2)(zone.js@0.16.3)))(@angular/common@22.3.0-next.1(@angular/core@22.3.0-next.1(@angular/compiler@22.3.0-next.1)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2))(@angular/core@22.3.0-next.1(@angular/compiler@22.3.0-next.1)(rxjs@7.8.2)(zone.js@0.16.3)))(rxjs@7.8.2)': + '@angular/router@22.3.0-next.2(@angular/common@22.3.0-next.2(@angular/core@22.3.0-next.2(@angular/compiler@22.3.0-next.2)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2))(@angular/core@22.3.0-next.2(@angular/compiler@22.3.0-next.2)(rxjs@7.8.2)(zone.js@0.16.3))(@angular/platform-browser@22.3.0-next.2(@angular/animations@22.3.0-next.2(@angular/core@22.3.0-next.2(@angular/compiler@22.3.0-next.2)(rxjs@7.8.2)(zone.js@0.16.3)))(@angular/common@22.3.0-next.2(@angular/core@22.3.0-next.2(@angular/compiler@22.3.0-next.2)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2))(@angular/core@22.3.0-next.2(@angular/compiler@22.3.0-next.2)(rxjs@7.8.2)(zone.js@0.16.3)))(rxjs@7.8.2)': dependencies: - '@angular/common': 22.3.0-next.1(@angular/core@22.3.0-next.1(@angular/compiler@22.3.0-next.1)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2) - '@angular/core': 22.3.0-next.1(@angular/compiler@22.3.0-next.1)(rxjs@7.8.2)(zone.js@0.16.3) - '@angular/platform-browser': 22.3.0-next.1(@angular/animations@22.3.0-next.1(@angular/core@22.3.0-next.1(@angular/compiler@22.3.0-next.1)(rxjs@7.8.2)(zone.js@0.16.3)))(@angular/common@22.3.0-next.1(@angular/core@22.3.0-next.1(@angular/compiler@22.3.0-next.1)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2))(@angular/core@22.3.0-next.1(@angular/compiler@22.3.0-next.1)(rxjs@7.8.2)(zone.js@0.16.3)) + '@angular/common': 22.3.0-next.2(@angular/core@22.3.0-next.2(@angular/compiler@22.3.0-next.2)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2) + '@angular/core': 22.3.0-next.2(@angular/compiler@22.3.0-next.2)(rxjs@7.8.2)(zone.js@0.16.3) + '@angular/platform-browser': 22.3.0-next.2(@angular/animations@22.3.0-next.2(@angular/core@22.3.0-next.2(@angular/compiler@22.3.0-next.2)(rxjs@7.8.2)(zone.js@0.16.3)))(@angular/common@22.3.0-next.2(@angular/core@22.3.0-next.2(@angular/compiler@22.3.0-next.2)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2))(@angular/core@22.3.0-next.2(@angular/compiler@22.3.0-next.2)(rxjs@7.8.2)(zone.js@0.16.3)) rxjs: 7.8.2 tslib: 2.8.1 - '@angular/service-worker@22.3.0-next.1(@angular/core@22.3.0-next.1(@angular/compiler@22.3.0-next.1)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2)': + '@angular/service-worker@22.3.0-next.2(@angular/core@22.3.0-next.2(@angular/compiler@22.3.0-next.2)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2)': dependencies: - '@angular/core': 22.3.0-next.1(@angular/compiler@22.3.0-next.1)(rxjs@7.8.2)(zone.js@0.16.3) + '@angular/core': 22.3.0-next.2(@angular/compiler@22.3.0-next.2)(rxjs@7.8.2)(zone.js@0.16.3) rxjs: 7.8.2 tslib: 2.8.1 @@ -9079,25 +9068,6 @@ snapshots: transitivePeerDependencies: - supports-color - '@babel/core@8.0.6': - dependencies: - '@babel/code-frame': 8.0.6 - '@babel/generator': 8.0.6 - '@babel/helper-compilation-targets': 8.0.7 - '@babel/helpers': 8.0.7 - '@babel/parser': 8.0.7 - '@babel/template': 8.0.0 - '@babel/traverse': 8.0.7 - '@babel/types': 8.0.6 - '@types/gensync': 1.0.5 - convert-source-map: 2.0.0 - empathic: 2.1.0 - gensync: 1.0.0-beta.2 - import-meta-resolve: 4.2.0 - json5: 2.2.3 - obug: 2.2.1 - verkit: 0.3.2 - '@babel/core@8.0.7': dependencies: '@babel/code-frame': 8.0.6 @@ -10334,7 +10304,7 @@ snapshots: transitivePeerDependencies: - supports-color - '@google/genai@2.28.0(bufferutil@4.1.0)(supports-color@11.0.0)(utf-8-validate@6.0.6)': + '@google/genai@2.29.1(bufferutil@4.1.0)(supports-color@11.0.0)(utf-8-validate@6.0.6)': dependencies: google-auth-library: 10.9.1(supports-color@11.0.0) p-retry: 4.6.2 @@ -10399,14 +10369,14 @@ snapshots: optionalDependencies: '@types/node': 22.20.5 - '@inquirer/checkbox@5.2.6(@types/node@24.19.1)': + '@inquirer/checkbox@5.2.6(@types/node@24.19.2)': dependencies: '@inquirer/ansi': 2.0.9 - '@inquirer/core': 12.0.4(@types/node@24.19.1) + '@inquirer/core': 12.0.4(@types/node@24.19.2) '@inquirer/figures': 2.0.9 - '@inquirer/type': 4.2.0(@types/node@24.19.1) + '@inquirer/type': 4.2.0(@types/node@24.19.2) optionalDependencies: - '@types/node': 24.19.1 + '@types/node': 24.19.2 '@inquirer/confirm@6.3.3(@types/node@22.20.5)': dependencies: @@ -10415,12 +10385,12 @@ snapshots: optionalDependencies: '@types/node': 22.20.5 - '@inquirer/confirm@6.3.3(@types/node@24.19.1)': + '@inquirer/confirm@6.3.3(@types/node@24.19.2)': dependencies: - '@inquirer/core': 12.0.4(@types/node@24.19.1) - '@inquirer/type': 4.2.0(@types/node@24.19.1) + '@inquirer/core': 12.0.4(@types/node@24.19.2) + '@inquirer/type': 4.2.0(@types/node@24.19.2) optionalDependencies: - '@types/node': 24.19.1 + '@types/node': 24.19.2 '@inquirer/core@12.0.4(@types/node@22.20.5)': dependencies: @@ -10434,17 +10404,17 @@ snapshots: optionalDependencies: '@types/node': 22.20.5 - '@inquirer/core@12.0.4(@types/node@24.19.1)': + '@inquirer/core@12.0.4(@types/node@24.19.2)': dependencies: '@inquirer/ansi': 2.0.9 '@inquirer/figures': 2.0.9 - '@inquirer/type': 4.2.0(@types/node@24.19.1) + '@inquirer/type': 4.2.0(@types/node@24.19.2) cli-width: 4.1.0 fast-wrap-ansi: 0.2.2 mute-stream: 3.0.0 signal-exit: 4.1.0 optionalDependencies: - '@types/node': 24.19.1 + '@types/node': 24.19.2 '@inquirer/editor@5.3.4(@types/node@22.20.5)': dependencies: @@ -10454,13 +10424,13 @@ snapshots: optionalDependencies: '@types/node': 22.20.5 - '@inquirer/editor@5.3.4(@types/node@24.19.1)': + '@inquirer/editor@5.3.4(@types/node@24.19.2)': dependencies: - '@inquirer/core': 12.0.4(@types/node@24.19.1) - '@inquirer/external-editor': 3.0.6(@types/node@24.19.1) - '@inquirer/type': 4.2.0(@types/node@24.19.1) + '@inquirer/core': 12.0.4(@types/node@24.19.2) + '@inquirer/external-editor': 3.0.6(@types/node@24.19.2) + '@inquirer/type': 4.2.0(@types/node@24.19.2) optionalDependencies: - '@types/node': 24.19.1 + '@types/node': 24.19.2 '@inquirer/expand@5.1.6(@types/node@22.20.5)': dependencies: @@ -10469,12 +10439,12 @@ snapshots: optionalDependencies: '@types/node': 22.20.5 - '@inquirer/expand@5.1.6(@types/node@24.19.1)': + '@inquirer/expand@5.1.6(@types/node@24.19.2)': dependencies: - '@inquirer/core': 12.0.4(@types/node@24.19.1) - '@inquirer/type': 4.2.0(@types/node@24.19.1) + '@inquirer/core': 12.0.4(@types/node@24.19.2) + '@inquirer/type': 4.2.0(@types/node@24.19.2) optionalDependencies: - '@types/node': 24.19.1 + '@types/node': 24.19.2 '@inquirer/external-editor@3.0.6(@types/node@22.20.5)': dependencies: @@ -10483,12 +10453,12 @@ snapshots: optionalDependencies: '@types/node': 22.20.5 - '@inquirer/external-editor@3.0.6(@types/node@24.19.1)': + '@inquirer/external-editor@3.0.6(@types/node@24.19.2)': dependencies: chardet: 2.2.0 iconv-lite: 0.7.3 optionalDependencies: - '@types/node': 24.19.1 + '@types/node': 24.19.2 '@inquirer/figures@2.0.9': {} @@ -10499,12 +10469,12 @@ snapshots: optionalDependencies: '@types/node': 22.20.5 - '@inquirer/input@5.1.7(@types/node@24.19.1)': + '@inquirer/input@5.1.7(@types/node@24.19.2)': dependencies: - '@inquirer/core': 12.0.4(@types/node@24.19.1) - '@inquirer/type': 4.2.0(@types/node@24.19.1) + '@inquirer/core': 12.0.4(@types/node@24.19.2) + '@inquirer/type': 4.2.0(@types/node@24.19.2) optionalDependencies: - '@types/node': 24.19.1 + '@types/node': 24.19.2 '@inquirer/number@4.2.4(@types/node@22.20.5)': dependencies: @@ -10513,12 +10483,12 @@ snapshots: optionalDependencies: '@types/node': 22.20.5 - '@inquirer/number@4.2.4(@types/node@24.19.1)': + '@inquirer/number@4.2.4(@types/node@24.19.2)': dependencies: - '@inquirer/core': 12.0.4(@types/node@24.19.1) - '@inquirer/type': 4.2.0(@types/node@24.19.1) + '@inquirer/core': 12.0.4(@types/node@24.19.2) + '@inquirer/type': 4.2.0(@types/node@24.19.2) optionalDependencies: - '@types/node': 24.19.1 + '@types/node': 24.19.2 '@inquirer/password@5.2.3(@types/node@22.20.5)': dependencies: @@ -10528,13 +10498,13 @@ snapshots: optionalDependencies: '@types/node': 22.20.5 - '@inquirer/password@5.2.3(@types/node@24.19.1)': + '@inquirer/password@5.2.3(@types/node@24.19.2)': dependencies: '@inquirer/ansi': 2.0.9 - '@inquirer/core': 12.0.4(@types/node@24.19.1) - '@inquirer/type': 4.2.0(@types/node@24.19.1) + '@inquirer/core': 12.0.4(@types/node@24.19.2) + '@inquirer/type': 4.2.0(@types/node@24.19.2) optionalDependencies: - '@types/node': 24.19.1 + '@types/node': 24.19.2 '@inquirer/prompts@8.7.3(@types/node@22.20.5)': dependencies: @@ -10551,20 +10521,20 @@ snapshots: optionalDependencies: '@types/node': 22.20.5 - '@inquirer/prompts@8.7.3(@types/node@24.19.1)': - dependencies: - '@inquirer/checkbox': 5.2.6(@types/node@24.19.1) - '@inquirer/confirm': 6.3.3(@types/node@24.19.1) - '@inquirer/editor': 5.3.4(@types/node@24.19.1) - '@inquirer/expand': 5.1.6(@types/node@24.19.1) - '@inquirer/input': 5.1.7(@types/node@24.19.1) - '@inquirer/number': 4.2.4(@types/node@24.19.1) - '@inquirer/password': 5.2.3(@types/node@24.19.1) - '@inquirer/rawlist': 5.3.6(@types/node@24.19.1) - '@inquirer/search': 4.3.4(@types/node@24.19.1) - '@inquirer/select': 5.2.6(@types/node@24.19.1) + '@inquirer/prompts@8.7.3(@types/node@24.19.2)': + dependencies: + '@inquirer/checkbox': 5.2.6(@types/node@24.19.2) + '@inquirer/confirm': 6.3.3(@types/node@24.19.2) + '@inquirer/editor': 5.3.4(@types/node@24.19.2) + '@inquirer/expand': 5.1.6(@types/node@24.19.2) + '@inquirer/input': 5.1.7(@types/node@24.19.2) + '@inquirer/number': 4.2.4(@types/node@24.19.2) + '@inquirer/password': 5.2.3(@types/node@24.19.2) + '@inquirer/rawlist': 5.3.6(@types/node@24.19.2) + '@inquirer/search': 4.3.4(@types/node@24.19.2) + '@inquirer/select': 5.2.6(@types/node@24.19.2) optionalDependencies: - '@types/node': 24.19.1 + '@types/node': 24.19.2 '@inquirer/rawlist@5.3.6(@types/node@22.20.5)': dependencies: @@ -10573,12 +10543,12 @@ snapshots: optionalDependencies: '@types/node': 22.20.5 - '@inquirer/rawlist@5.3.6(@types/node@24.19.1)': + '@inquirer/rawlist@5.3.6(@types/node@24.19.2)': dependencies: - '@inquirer/core': 12.0.4(@types/node@24.19.1) - '@inquirer/type': 4.2.0(@types/node@24.19.1) + '@inquirer/core': 12.0.4(@types/node@24.19.2) + '@inquirer/type': 4.2.0(@types/node@24.19.2) optionalDependencies: - '@types/node': 24.19.1 + '@types/node': 24.19.2 '@inquirer/search@4.3.4(@types/node@22.20.5)': dependencies: @@ -10588,13 +10558,13 @@ snapshots: optionalDependencies: '@types/node': 22.20.5 - '@inquirer/search@4.3.4(@types/node@24.19.1)': + '@inquirer/search@4.3.4(@types/node@24.19.2)': dependencies: - '@inquirer/core': 12.0.4(@types/node@24.19.1) + '@inquirer/core': 12.0.4(@types/node@24.19.2) '@inquirer/figures': 2.0.9 - '@inquirer/type': 4.2.0(@types/node@24.19.1) + '@inquirer/type': 4.2.0(@types/node@24.19.2) optionalDependencies: - '@types/node': 24.19.1 + '@types/node': 24.19.2 '@inquirer/select@5.2.6(@types/node@22.20.5)': dependencies: @@ -10605,22 +10575,22 @@ snapshots: optionalDependencies: '@types/node': 22.20.5 - '@inquirer/select@5.2.6(@types/node@24.19.1)': + '@inquirer/select@5.2.6(@types/node@24.19.2)': dependencies: '@inquirer/ansi': 2.0.9 - '@inquirer/core': 12.0.4(@types/node@24.19.1) + '@inquirer/core': 12.0.4(@types/node@24.19.2) '@inquirer/figures': 2.0.9 - '@inquirer/type': 4.2.0(@types/node@24.19.1) + '@inquirer/type': 4.2.0(@types/node@24.19.2) optionalDependencies: - '@types/node': 24.19.1 + '@types/node': 24.19.2 '@inquirer/type@4.2.0(@types/node@22.20.5)': optionalDependencies: '@types/node': 22.20.5 - '@inquirer/type@4.2.0(@types/node@24.19.1)': + '@inquirer/type@4.2.0(@types/node@24.19.2)': optionalDependencies: - '@types/node': 24.19.1 + '@types/node': 24.19.2 '@isaacs/cliui@8.0.2': dependencies: @@ -11744,7 +11714,7 @@ snapshots: dependencies: undici-types: 6.21.0 - '@types/node@24.19.1': + '@types/node@24.19.2': dependencies: undici-types: 7.24.6 @@ -15227,10 +15197,10 @@ snapshots: neo-async@2.6.2: {} - ng-packagr@22.3.0-next.2(@angular/compiler-cli@22.3.0-next.1(@angular/compiler@22.3.0-next.1)(typescript@6.0.3))(supports-color@11.0.0)(tslib@2.8.1)(typescript@6.0.3): + ng-packagr@22.3.0-next.2(@angular/compiler-cli@22.3.0-next.2(@angular/compiler@22.3.0-next.2)(typescript@6.0.3))(supports-color@11.0.0)(tslib@2.8.1)(typescript@6.0.3): dependencies: '@ampproject/remapping': 2.3.0 - '@angular/compiler-cli': 22.3.0-next.1(@angular/compiler@22.3.0-next.1)(typescript@6.0.3) + '@angular/compiler-cli': 22.3.0-next.2(@angular/compiler@22.3.0-next.2)(typescript@6.0.3) ajv: 8.20.0 browserslist: 4.29.3 chokidar: 5.0.0 @@ -15359,8 +15329,6 @@ snapshots: define-properties: 1.2.1 es-object-atoms: 1.1.2 - obug@2.2.1: {} - obug@3.0.0: {} on-exit-leak-free@2.1.2: {} @@ -17022,8 +16990,6 @@ snapshots: - react-native-b4a - supports-color - verkit@0.3.2: {} - verkit@0.5.0: {} verror@1.10.0: diff --git a/tests/e2e/ng-snapshot/package.json b/tests/e2e/ng-snapshot/package.json index 8550a3c4bb4c..e02c1dcd10e4 100644 --- a/tests/e2e/ng-snapshot/package.json +++ b/tests/e2e/ng-snapshot/package.json @@ -2,21 +2,21 @@ "description": "snapshot versions of Angular for e2e testing", "private": true, "dependencies": { - "@angular/animations": "github:angular/animations-builds#f2f4920079874bc3ff7233cae1bfc044f540aaea", - "@angular/cdk": "github:angular/cdk-builds#47633891913bba784f30c7e96a832ce5aee6b5ca", - "@angular/common": "github:angular/common-builds#50cb684a62ab0a76b5cac1f43e419dcef95695c5", - "@angular/compiler": "github:angular/compiler-builds#121ce74dc256084d4df6189faec0897906c81e7f", - "@angular/compiler-cli": "github:angular/compiler-cli-builds#13f5a3741ae88163e4830805d5fdb3be10975600", - "@angular/core": "github:angular/core-builds#803e8bc85644b8ae2f7626a2128b2597bad464f5", - "@angular/forms": "github:angular/forms-builds#dfc8f809fc98e7350bfb3c0cc4ed76c2f898e8a2", - "@angular/language-service": "github:angular/language-service-builds#26e3a3900301c3d6a9ab6a25567c1038e7a8556d", - "@angular/localize": "github:angular/localize-builds#152ad1e6420c1f2f6592f920c81e39dbcb5f5493", - "@angular/material": "github:angular/material-builds#e39e747aad22eb1ee2981f8f7b39a3b8ec788381", - "@angular/material-moment-adapter": "github:angular/material-moment-adapter-builds#f0e6679098e0bfdb8f98b2c7a2c271ec2d128994", - "@angular/platform-browser": "github:angular/platform-browser-builds#c87936c6c5381b369a60bcd311836c711b68d498", - "@angular/platform-browser-dynamic": "github:angular/platform-browser-dynamic-builds#abdac4b65aa34f8a1c9580631d22ae478579e111", - "@angular/platform-server": "github:angular/platform-server-builds#11bfbc1463ebaff83489b1b560ff49e9fb281fb1", - "@angular/router": "github:angular/router-builds#5457840c68f0afb075100b2d923de1219b450838", - "@angular/service-worker": "github:angular/service-worker-builds#94c8e94f4903c4271b9da3eedea9402e3af87043" + "@angular/animations": "github:angular/animations-builds#43efef5cbf38f5261191e5c11d7f49c276428137", + "@angular/cdk": "github:angular/cdk-builds#43c02174c1dc0f4b74a85342bbd9f43d040bf1ae", + "@angular/common": "github:angular/common-builds#89d9b5d43c81051c59a33d24ccccd75b51f6dc48", + "@angular/compiler": "github:angular/compiler-builds#e91181d83e7086debe8f32f21bfa434c4bd94afd", + "@angular/compiler-cli": "github:angular/compiler-cli-builds#bfd2191e1955c38a1ce52aa467508702d132e7ba", + "@angular/core": "github:angular/core-builds#31cf6f74f000a8499b3ce204ad9b339e830dcc39", + "@angular/forms": "github:angular/forms-builds#1dbb38cca305af00e3362cb59c5293b44a7ae7f1", + "@angular/language-service": "github:angular/language-service-builds#54ce2dee3572da8657674dc965d010fd37b6d15b", + "@angular/localize": "github:angular/localize-builds#bcdfcaf668fd983db3496cdb696ca8b3aa2f68aa", + "@angular/material": "github:angular/material-builds#2c82c94514f7cb2bc3dafd3b5db2160aa9c01517", + "@angular/material-moment-adapter": "github:angular/material-moment-adapter-builds#728a7be6d90391791e0967357a07959d2a4fa3d3", + "@angular/platform-browser": "github:angular/platform-browser-builds#a1b99915c2e91ab779ee0443904bd0194b8e2fb0", + "@angular/platform-browser-dynamic": "github:angular/platform-browser-dynamic-builds#cdfb691b31a234662977f12f0982b880035bb72e", + "@angular/platform-server": "github:angular/platform-server-builds#9e3f315c175ed493a83d91b2d1743582e4934ab3", + "@angular/router": "github:angular/router-builds#972a0d117fd048a478e2cb035ef5b442e8cc5ceb", + "@angular/service-worker": "github:angular/service-worker-builds#f3e0f7d39cadb10a0257cf826cc0519e7809e8e2" } } From d542827facd6e785ae6f7553624a22be5b577026 Mon Sep 17 00:00:00 2001 From: Angular Robot Date: Thu, 15 Oct 2026 16:34:00 +0000 Subject: [PATCH 627/787] build: update all non-major dependencies See associated pull request for more information. --- package.json | 8 +- packages/angular/build/package.json | 10 +- .../angular_devkit/build_angular/package.json | 4 +- packages/schematics/angular/package.json | 4 +- pnpm-lock.yaml | 870 ++++++++++-------- 5 files changed, 503 insertions(+), 393 deletions(-) diff --git a/package.json b/package.json index 6e4cab8c46dc..9bc88e433859 100644 --- a/package.json +++ b/package.json @@ -70,7 +70,7 @@ "@rollup/plugin-commonjs": "^29.0.0", "@rollup/plugin-json": "^6.1.0", "@rollup/plugin-node-resolve": "16.0.3", - "@rollup/wasm-node": "4.64.5", + "@rollup/wasm-node": "4.64.6", "@stylistic/eslint-plugin": "^5.0.0", "@tony.ganchev/eslint-plugin-header": "~3.4.0", "@types/babel__core": "7.20.5", @@ -119,15 +119,15 @@ "lodash": "^4.17.21", "magic-string": "1.4.3", "prettier": "^3.0.0", - "puppeteer": "25.13.0", + "puppeteer": "25.14.0", "quicktype-core": "26.0.0", - "rollup": "4.64.5", + "rollup": "4.64.6", "rollup-plugin-dts": "6.5.1", "rollup-plugin-sourcemaps2": "0.5.9", "semver": "7.8.5", "source-map-support": "0.5.21", "tslib": "2.8.1", - "undici": "8.11.2", + "undici": "8.12.1", "verdaccio": "6.10.5", "verdaccio-auth-memory": "^13.0.0", "zone.js": "^0.16.0" diff --git a/packages/angular/build/package.json b/packages/angular/build/package.json index a5227c45c526..711ab5893f75 100644 --- a/packages/angular/build/package.json +++ b/packages/angular/build/package.json @@ -33,11 +33,11 @@ "listr2": "11.2.0", "magic-string": "1.4.3", "mrmime": "2.0.1", - "oxc-parser": "0.153.0", + "oxc-parser": "0.154.0", "parse5-html-rewriting-stream": "8.0.1", "picomatch": "4.0.7", "piscina": "5.3.2", - "rolldown": "1.2.13", + "rolldown": "1.2.14", "rolldown-plugin-dts": "0.28.8", "sass": "1.105.1", "sass-embedded": "1.105.1", @@ -53,14 +53,14 @@ "devDependencies": { "@angular-devkit/core": "workspace:*", "@angular/ssr": "workspace:*", - "@oxc-project/types": "0.153.0", + "@oxc-project/types": "0.154.0", "@vitest/coverage-v8": "5.0.4", "istanbul-lib-instrument": "6.0.3", "jsdom": "30.1.2", "less": "4.9.1", "ng-packagr": "22.3.0-next.2", - "postcss": "8.5.29", - "rollup": "4.64.5", + "postcss": "8.5.30", + "rollup": "4.64.6", "rxjs": "7.8.2", "vitest": "5.0.4" }, diff --git a/packages/angular_devkit/build_angular/package.json b/packages/angular_devkit/build_angular/package.json index 502d27aa5975..54a44f134b16 100644 --- a/packages/angular_devkit/build_angular/package.json +++ b/packages/angular_devkit/build_angular/package.json @@ -43,7 +43,7 @@ "ora": "9.4.1", "picomatch": "4.0.7", "piscina": "5.3.2", - "postcss": "8.5.29", + "postcss": "8.5.30", "postcss-loader": "8.2.1", "resolve-url-loader": "5.0.0", "rxjs": "7.8.2", @@ -68,7 +68,7 @@ "browser-sync": "3.0.4", "ng-packagr": "22.3.0-next.2", "sass": "1.105.1", - "undici": "8.11.2" + "undici": "8.12.1" }, "peerDependencies": { "@angular/compiler-cli": "0.0.0-ANGULAR-FW-PEER-DEP", diff --git a/packages/schematics/angular/package.json b/packages/schematics/angular/package.json index 5d0cc7efef53..6025fad3bd99 100644 --- a/packages/schematics/angular/package.json +++ b/packages/schematics/angular/package.json @@ -20,10 +20,10 @@ "@angular-devkit/core": "workspace:0.0.0-PLACEHOLDER", "@angular-devkit/schematics": "workspace:0.0.0-PLACEHOLDER", "jsonc-parser": "3.3.1", - "oxc-parser": "0.153.0", + "oxc-parser": "0.154.0", "typescript": "6.0.3" }, "devDependencies": { - "@oxc-project/types": "0.153.0" + "@oxc-project/types": "0.154.0" } } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index ff51f38b4f6c..81cbdf51aeb5 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -245,16 +245,16 @@ importers: version: 10.0.1(eslint@10.12.0(jiti@2.7.0)(supports-color@11.0.0)) '@rollup/plugin-commonjs': specifier: ^29.0.0 - version: 29.0.3(rollup@4.64.5) + version: 29.0.3(rollup@4.64.6) '@rollup/plugin-json': specifier: ^6.1.0 - version: 6.1.0(rollup@4.64.5) + version: 6.1.0(rollup@4.64.6) '@rollup/plugin-node-resolve': specifier: 16.0.3 - version: 16.0.3(rollup@4.64.5) + version: 16.0.3(rollup@4.64.6) '@rollup/wasm-node': - specifier: 4.64.5 - version: 4.64.5 + specifier: 4.64.6 + version: 4.64.6 '@stylistic/eslint-plugin': specifier: ^5.0.0 version: 5.10.0(eslint@10.12.0(jiti@2.7.0)(supports-color@11.0.0)) @@ -400,20 +400,20 @@ importers: specifier: ^3.0.0 version: 3.9.10 puppeteer: - specifier: 25.13.0 - version: 25.13.0(bufferutil@4.1.0)(utf-8-validate@6.0.6) + specifier: 25.14.0 + version: 25.14.0(bufferutil@4.1.0)(utf-8-validate@6.0.6) quicktype-core: specifier: 26.0.0 version: 26.0.0 rollup: - specifier: 4.64.5 - version: 4.64.5 + specifier: 4.64.6 + version: 4.64.6 rollup-plugin-dts: specifier: 6.5.1 - version: 6.5.1(rollup@4.64.5)(typescript@6.0.3) + version: 6.5.1(rollup@4.64.6)(typescript@6.0.3) rollup-plugin-sourcemaps2: specifier: 0.5.9 - version: 0.5.9(@types/node@22.20.5)(rollup@4.64.5) + version: 0.5.9(@types/node@22.20.5)(rollup@4.64.6) semver: specifier: 7.8.5 version: 7.8.5 @@ -424,8 +424,8 @@ importers: specifier: 2.8.1 version: 2.8.1 undici: - specifier: 8.11.2 - version: 8.11.2 + specifier: 8.12.1 + version: 8.12.1 verdaccio: specifier: 6.10.5 version: 6.10.5(encoding@0.1.13)(supports-color@11.0.0) @@ -520,8 +520,8 @@ importers: specifier: 2.0.1 version: 2.0.1 oxc-parser: - specifier: 0.153.0 - version: 0.153.0 + specifier: 0.154.0 + version: 0.154.0 parse5-html-rewriting-stream: specifier: 8.0.1 version: 8.0.1 @@ -532,11 +532,11 @@ importers: specifier: 5.3.2 version: 5.3.2 rolldown: - specifier: 1.2.13 - version: 1.2.13 + specifier: 1.2.14 + version: 1.2.14 rolldown-plugin-dts: specifier: 0.28.8 - version: 0.28.8(rolldown@1.2.13)(typescript@6.0.3) + version: 0.28.8(rolldown@1.2.14)(typescript@6.0.3) sass: specifier: 1.105.1 version: 1.105.1 @@ -566,8 +566,8 @@ importers: specifier: workspace:* version: link:../ssr '@oxc-project/types': - specifier: 0.153.0 - version: 0.153.0 + specifier: 0.154.0 + version: 0.154.0 '@vitest/coverage-v8': specifier: 5.0.4 version: 5.0.4(vitest@5.0.4) @@ -584,11 +584,11 @@ importers: specifier: 22.3.0-next.2 version: 22.3.0-next.2(@angular/compiler-cli@22.3.0-next.2(@angular/compiler@22.3.0-next.2)(typescript@6.0.3))(supports-color@11.0.0)(tslib@2.8.1)(typescript@6.0.3) postcss: - specifier: 8.5.29 - version: 8.5.29 + specifier: 8.5.30 + version: 8.5.30 rollup: - specifier: 4.64.5 - version: 4.64.5 + specifier: 4.64.6 + version: 4.64.6 rxjs: specifier: 7.8.2 version: 7.8.2 @@ -755,10 +755,10 @@ importers: version: 4.1.3 autoprefixer: specifier: 10.6.1 - version: 10.6.1(postcss@8.5.29) + version: 10.6.1(postcss@8.5.30) babel-loader: specifier: 10.1.1 - version: 10.1.1(@babel/core@8.0.7)(webpack@5.111.1(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.29)(uglify-js@3.19.3)) + version: 10.1.1(@babel/core@8.0.7)(webpack@5.111.1(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.30)(uglify-js@3.19.3)) beasties: specifier: 0.5.5 version: 0.5.5 @@ -767,10 +767,10 @@ importers: version: 4.29.3 copy-webpack-plugin: specifier: 14.0.0 - version: 14.0.0(webpack@5.111.1(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.29)(uglify-js@3.19.3)) + version: 14.0.0(webpack@5.111.1(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.30)(uglify-js@3.19.3)) css-loader: specifier: 7.1.5 - version: 7.1.5(webpack@5.111.1(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.29)(uglify-js@3.19.3)) + version: 7.1.5(webpack@5.111.1(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.30)(uglify-js@3.19.3)) esbuild-wasm: specifier: 0.28.2 version: 0.28.2 @@ -791,16 +791,16 @@ importers: version: 4.9.1(supports-color@11.0.0) less-loader: specifier: 13.0.0 - version: 13.0.0(less@4.9.1(supports-color@11.0.0))(webpack@5.111.1(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.29)(uglify-js@3.19.3)) + version: 13.0.0(less@4.9.1(supports-color@11.0.0))(webpack@5.111.1(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.30)(uglify-js@3.19.3)) license-webpack-plugin: specifier: 4.0.2 - version: 4.0.2(webpack@5.111.1(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.29)(uglify-js@3.19.3)) + version: 4.0.2(webpack@5.111.1(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.30)(uglify-js@3.19.3)) loader-utils: specifier: 3.3.1 version: 3.3.1 mini-css-extract-plugin: specifier: 2.10.2 - version: 2.10.2(webpack@5.111.1(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.29)(uglify-js@3.19.3)) + version: 2.10.2(webpack@5.111.1(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.30)(uglify-js@3.19.3)) open: specifier: 11.0.4 version: 11.0.4 @@ -814,11 +814,11 @@ importers: specifier: 5.3.2 version: 5.3.2 postcss: - specifier: 8.5.29 - version: 8.5.29 + specifier: 8.5.30 + version: 8.5.30 postcss-loader: specifier: 8.2.1 - version: 8.2.1(postcss@8.5.29)(typescript@6.0.3)(webpack@5.111.1(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.29)(uglify-js@3.19.3)) + version: 8.2.1(postcss@8.5.30)(typescript@6.0.3)(webpack@5.111.1(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.30)(uglify-js@3.19.3)) resolve-url-loader: specifier: 5.0.0 version: 5.0.0 @@ -827,13 +827,13 @@ importers: version: 7.8.2 sass-loader: specifier: 17.0.1 - version: 17.0.1(sass-embedded@1.105.1)(sass@1.105.1)(webpack@5.111.1(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.29)(uglify-js@3.19.3)) + version: 17.0.1(sass-embedded@1.105.1)(sass@1.105.1)(webpack@5.111.1(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.30)(uglify-js@3.19.3)) semver: specifier: 7.8.5 version: 7.8.5 source-map-loader: specifier: 5.0.0 - version: 5.0.0(webpack@5.111.1(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.29)(uglify-js@3.19.3)) + version: 5.0.0(webpack@5.111.1(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.30)(uglify-js@3.19.3)) source-map-support: specifier: 0.5.21 version: 0.5.21 @@ -848,19 +848,19 @@ importers: version: 2.8.1 webpack: specifier: 5.111.1 - version: 5.111.1(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.29)(uglify-js@3.19.3) + version: 5.111.1(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.30)(uglify-js@3.19.3) webpack-dev-middleware: specifier: 8.3.0 - version: 8.3.0(webpack@5.111.1(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.29)(uglify-js@3.19.3)) + version: 8.3.0(webpack@5.111.1(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.30)(uglify-js@3.19.3)) webpack-dev-server: specifier: 6.0.0 - version: 6.0.0(bufferutil@4.1.0)(supports-color@11.0.0)(utf-8-validate@6.0.6)(webpack@5.111.1(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.29)(uglify-js@3.19.3)) + version: 6.0.0(bufferutil@4.1.0)(supports-color@11.0.0)(utf-8-validate@6.0.6)(webpack@5.111.1(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.30)(uglify-js@3.19.3)) webpack-merge: specifier: 6.0.1 version: 6.0.1 webpack-subresource-integrity: specifier: 5.1.0 - version: 5.1.0(webpack@5.111.1(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.29)(uglify-js@3.19.3)) + version: 5.1.0(webpack@5.111.1(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.30)(uglify-js@3.19.3)) devDependencies: '@angular/ssr': specifier: workspace:* @@ -875,8 +875,8 @@ importers: specifier: 1.105.1 version: 1.105.1 undici: - specifier: 8.11.2 - version: 8.11.2 + specifier: 8.12.1 + version: 8.12.1 optionalDependencies: esbuild: specifier: 0.28.2 @@ -989,15 +989,15 @@ importers: specifier: 3.3.1 version: 3.3.1 oxc-parser: - specifier: 0.153.0 - version: 0.153.0 + specifier: 0.154.0 + version: 0.154.0 typescript: specifier: 6.0.3 version: 6.0.3 devDependencies: '@oxc-project/types': - specifier: 0.153.0 - version: 0.153.0 + specifier: 0.154.0 + version: 0.154.0 tests: devDependencies: @@ -2971,124 +2971,124 @@ packages: resolution: {integrity: sha512-eSYWTm620tTk45EKSedaUL8MFYI8hW164hIXsgIHyxu3VobUB3fFCu5t0hQby6OoWRPsG1KkKUG2M5UadiLiVg==} engines: {node: '>=14'} - '@oxc-parser/binding-android-arm-eabi@0.153.0': - resolution: {integrity: sha512-BcWu25dMwMjHpaDCEidmpAi7rGg1qZoihJeUUH9bD55pVZ0z4Wa5CQgqSTo0R41H81oozisQKW3WqvAN2m77IQ==} + '@oxc-parser/binding-android-arm-eabi@0.154.0': + resolution: {integrity: sha512-sDdEtDl7vKdCvf54j72RJbowE3jCmyRz/+oOB6IAwQxAHZ0eI+Dcj4hvVnm0b9Dy31plUkdmfds9C+/Zt895Tg==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm] os: [android] - '@oxc-parser/binding-android-arm64@0.153.0': - resolution: {integrity: sha512-9l5rdp2DhRqVriBHsNpu5cEf+hizZ4B58rt93HzyQEBUgZiC6qe2oFpaAAnXGCxHGnQExI1s7S2G0QhFacUZ6w==} + '@oxc-parser/binding-android-arm64@0.154.0': + resolution: {integrity: sha512-UHrDPELzvWZoVkIDdSycj4bzcTMCJG3IbN++mSUgVBaUtNtWHjQ98U6Vz5bpF/1Ic3FYJyYhMr74huO5tVvpZw==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [android] - '@oxc-parser/binding-darwin-arm64@0.153.0': - resolution: {integrity: sha512-EcpsyRXHhENDpekpG4QNaSZj2F/BAz4Gh4o89zZwNss86R8KyRSQ6sXbAj74Xyeb4z3j/yBZZ6joQZhraIWyfw==} + '@oxc-parser/binding-darwin-arm64@0.154.0': + resolution: {integrity: sha512-mokYzajOSXxtSRDWCdHARGdntrKH+rZZ24Jzo8AtafyNzz0NARmpMm26Tc5B6qiGrr6UliWibHCOif1qRN2vaA==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [darwin] - '@oxc-parser/binding-darwin-x64@0.153.0': - resolution: {integrity: sha512-hlj80HUQy07/2lYp6rmxH+3u+H2ik3rjLR52CUdPApxmZCNxASDUf/+ykTzAHS/fehftmVMATKvPaWmuLHuasg==} + '@oxc-parser/binding-darwin-x64@0.154.0': + resolution: {integrity: sha512-WbtUBrclOVItWfLRSvs+Z/WLtXxJ2Ctv50PyuX894HzDN5/e0qzxVpTNPIVMzOerBhgKtFsSMcfxlYIAbvdVgg==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [darwin] - '@oxc-parser/binding-freebsd-x64@0.153.0': - resolution: {integrity: sha512-fWRcv2pMSh1qtez46MOu8vuUJ5fiaQZPHSphbWulbL7SHBMKfRgZl2PzjXZYQJbq7NEXyXbgIuIuUm+/Rmkv8w==} + '@oxc-parser/binding-freebsd-x64@0.154.0': + resolution: {integrity: sha512-YooHZSLawOe2fqm+lDdG8oAaQh2NYV/RMYTYzWRLy72stm2BgE9O/8Al6kFENjkmzyyBccDLLBirGxVtpzQfrw==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [freebsd] - '@oxc-parser/binding-linux-arm-gnueabihf@0.153.0': - resolution: {integrity: sha512-paZeUK1GXShl/bOJQET1/8AQxayFeuN4SIWAkgTRxE7ZQwv9uYSB2n0648smygP22N7jcI3zxAm0Z+ALNiIKxg==} + '@oxc-parser/binding-linux-arm-gnueabihf@0.154.0': + resolution: {integrity: sha512-hKOwhZbrXdTwc4bGVfbLCXl9f2swl6zWdISocLQSNX9MgPmwHE3qGzOUkCrkuGpwdCVHPnkfOwsqTuYsrP5uNg==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm] os: [linux] - '@oxc-parser/binding-linux-arm-musleabihf@0.153.0': - resolution: {integrity: sha512-qFPp5NwMf4K1C0O+DCVGmcbOaYyYAq98Rvv9p4VSfb777iUwlJCqMUxf6QG9N5f5ls4TEX6LitOZHi+6GL6rYQ==} + '@oxc-parser/binding-linux-arm-musleabihf@0.154.0': + resolution: {integrity: sha512-tnjiooXEU013349O/yxKbF5Cusp1CfHWQ8kYR8tGeRzR/P4sOpQGQo21fsS71M0fMD6ESLq+lbvXFWi43PuKeQ==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm] os: [linux] - '@oxc-parser/binding-linux-arm64-gnu@0.153.0': - resolution: {integrity: sha512-oufEhZCX7saeo27Logra8cvBR1jQ/yw2zUI2hHmWw3qA/XYqEW31FOvLQBv7DWN32NjVdlcaP11WBBZTJo4k9g==} + '@oxc-parser/binding-linux-arm64-gnu@0.154.0': + resolution: {integrity: sha512-Cao2kj+8d7BT6XJU1gV9eVQjV+Cr+e8vQm3tddDRZiM2hHrMDxwy3j6t+ofaSl0idyuPPCZ4AlpmQoj8yOT1QA==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [linux] libc: [glibc] - '@oxc-parser/binding-linux-arm64-musl@0.153.0': - resolution: {integrity: sha512-zXYzuAqng85h6+LI3iRm0zeMLX1/K2z41ZAMWxVRgt0D10VvZUaV5q+TEB46KDhoKBpdexoTLC6QoB/EiP2oqQ==} + '@oxc-parser/binding-linux-arm64-musl@0.154.0': + resolution: {integrity: sha512-uiwA0V3q8llWA7/8r+a9BBjk4j5YMDmi6wfOsyQfGOJMQSLHEiZ3HI8ulea766ykUa9wJFWk9XWEl4uJrZLQqw==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [linux] libc: [musl] - '@oxc-parser/binding-linux-ppc64-gnu@0.153.0': - resolution: {integrity: sha512-J7+NLwLEzdkKM9cKyPHH/AjXXstWOs98KYgLrPPnO4N9MO8EZRBfPNnBcS3S67uMOBkRpUmCl2FhRnWdQ5CbBA==} + '@oxc-parser/binding-linux-ppc64-gnu@0.154.0': + resolution: {integrity: sha512-LICfN0Xs4Zdko+bJy6eOAEQojDuIR26suF2JtOsMaXjgbCrpRSH7/NCvJhY13YvYBx12V6hnwrL8n0lk0rbNJQ==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [ppc64] os: [linux] libc: [glibc] - '@oxc-parser/binding-linux-riscv64-gnu@0.153.0': - resolution: {integrity: sha512-sD0K11GQTLWylln54nPMMTtgmBbQrR5It/vMpZpy/fogiw8O2AvIE+9LuWUXddrWk9zvFIHGRcSgFn4IHOfoYg==} + '@oxc-parser/binding-linux-riscv64-gnu@0.154.0': + resolution: {integrity: sha512-gbbSYxLF8ssRbQ2qQPy+2EhGNwNH1bAoRdkk6cnWaKHqmCikpSIPtpXjFbCCtjTi0uojqOM3ghFQwQPbDQsU0Q==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [riscv64] os: [linux] libc: [glibc] - '@oxc-parser/binding-linux-riscv64-musl@0.153.0': - resolution: {integrity: sha512-7L66uql2BhvSz51LwfExjOdn6et/ydTiQxl23VApdKzJhTc3TczA1Qt6VR/UcvlQrL2ZbytIJb447vh7p5wmUw==} + '@oxc-parser/binding-linux-riscv64-musl@0.154.0': + resolution: {integrity: sha512-nSnRYYDLCcRVjSQzF3g6rKqCNYwo5o+aQgnn8BBXfe+ofCgMGlGqkfRyvXm6ptZvoxNkkWtLlqM8W7Xc3j6ZnQ==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [riscv64] os: [linux] libc: [musl] - '@oxc-parser/binding-linux-s390x-gnu@0.153.0': - resolution: {integrity: sha512-hXV3T7mNyrPR19rbPYkglkQJtoM/UNo/xwbZeeqdAxEg8PXgb4LXXuxPpGgI4bzRRCWwLUxdDSS58xIyC2u1TA==} + '@oxc-parser/binding-linux-s390x-gnu@0.154.0': + resolution: {integrity: sha512-BxBQoJKtzRQgZEKQIt6CDUm8RGKC5T8Qo4576yDa5/xgc10X3fBDItMbRabzLtbUBfTqKLl+8AVr/H6CF7W22g==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [s390x] os: [linux] libc: [glibc] - '@oxc-parser/binding-linux-x64-gnu@0.153.0': - resolution: {integrity: sha512-Da8Vqs1xdtoDYtEjmozD7wGgJeLBQkMbR0WUBECOSxodyX5DXy8ySlvJWbukyO2Q0+TM9EK+4LT6tbq0jCg4hQ==} + '@oxc-parser/binding-linux-x64-gnu@0.154.0': + resolution: {integrity: sha512-/whkust2vYy+GjRUVL5cWaJmEu6jkdFfo5mkxgckyeOX61eMwo4iBoiwzeJZeMWAdzb/XOtQyLApHhFht3sOWA==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [linux] libc: [glibc] - '@oxc-parser/binding-linux-x64-musl@0.153.0': - resolution: {integrity: sha512-zGAPxNTIIw6X5WyTRscIFE/oDjpdNtrrl32ing6NOXdGjzRucadnxBilexLdeYQ9YxixF93GujpXyQ0jw7ddSg==} + '@oxc-parser/binding-linux-x64-musl@0.154.0': + resolution: {integrity: sha512-EXURTyW9riw4B/kZnnE+58emAtw6+3VEszQfXUZkRqGaKIcmWDYkZtKB+xY/blHvuZ+Qy/fDclc31nmUCgtkSA==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [linux] libc: [musl] - '@oxc-parser/binding-openharmony-arm64@0.153.0': - resolution: {integrity: sha512-GoHzpqP5XyPIp9DHokoEdCp+K4UPl/h1neFj1uXnUB3pJYyOQ7NOhFVOttNUgCGcj2eywAvu5cRivTOSq4S10g==} + '@oxc-parser/binding-openharmony-arm64@0.154.0': + resolution: {integrity: sha512-ZRFooyH3qsR6vuR4jFGlG3XM36490SvvXtNaUahBK4zHpooMdTHNaOMtGGJI0EW38m5hi4rOco9kw7ZwCIp28w==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [openharmony] - '@oxc-parser/binding-win32-arm64-msvc@0.153.0': - resolution: {integrity: sha512-xGcy12tO9k7zFbeyQzEuilfWfQpyRq23/fLPfN3wjSWuWv58k46fQT1hsO1KFNykZuVGW9xSJE/z592TmAoSDA==} + '@oxc-parser/binding-win32-arm64-msvc@0.154.0': + resolution: {integrity: sha512-U0Vp+4lvwUa/PnOCJTZOjydj1rX2+VLHz4Y2vSFqlN8/7LTiURgD7z4uQ9yNv9O/NlU3mELBnPDlu7aaSYG1zQ==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [win32] - '@oxc-parser/binding-win32-ia32-msvc@0.153.0': - resolution: {integrity: sha512-o1ykUjWncvXX6N5a4KebgLjtD8zRui+f1llMhSGoSC9oP2KOqapRpdwmZ3NcNG0axFouwVKmhGBjd+IhA8BksA==} + '@oxc-parser/binding-win32-ia32-msvc@0.154.0': + resolution: {integrity: sha512-Hc8QgsFY5eUUP25we8TISUruibG2cDt0H4IcPG9RKdabb6odkCzIqjV6Gk9beGWGuOwMVCr81H/Su1q363LCCg==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [ia32] os: [win32] - '@oxc-parser/binding-win32-x64-msvc@0.153.0': - resolution: {integrity: sha512-gxQz7G96Up136fd+2zWrP+o6FYGs9NO4Dyv55IoeJFJUDwLFHcLYY11hhA5wQKs0HoM57Q8esQ3nEVhnCdsjAQ==} + '@oxc-parser/binding-win32-x64-msvc@0.154.0': + resolution: {integrity: sha512-hD7judkUMA/hZPoamvKADs6+an1smp8UTK0aMYRijkvi00K/1vl7vEtmyn2JyQ9S+vibtnfcNzxqTLGyJUZCRQ==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [win32] @@ -3096,8 +3096,8 @@ packages: '@oxc-project/types@0.152.0': resolution: {integrity: sha512-oM/5rLBm2tPkg0iBgkH/FOeR3PCDpY19GTgAZjMFM8h9WI9VW7cLgzp6nwtarYKmovavIQZ+Fe/RKX/8C8O/Rw==} - '@oxc-project/types@0.153.0': - resolution: {integrity: sha512-jSNrRIyvPVLL5E1z/tS5zLAprosGz/FuI1PWwEOz59j3E4TTTzSpqKb/RDGqJhhW0QHYISGXxq582wGx6T11Tw==} + '@oxc-project/types@0.154.0': + resolution: {integrity: sha512-KYOUGQFlLWR+s4QMV2Q9ko38TZm7EdO87Qm7rvZLqk/webse/cDjtyxKhg/47l0byCbs/k46LT8qc4PKjAikzA==} '@parcel/watcher-android-arm64@2.6.0': resolution: {integrity: sha512-trgpLSCKRC/huFjXX/Smh+0sWe4+YtKfktIToiMl59ghz7z+qkH6kMvNnUbLyRs9N11t8l4svSCs1+5B3rOAhA==} @@ -3262,8 +3262,8 @@ packages: '@protobufjs/utf8@1.1.2': resolution: {integrity: sha512-b1UQwcEZ4yCnMCD8DAL1VlbvBJE9/IX4FTIp7BG1xYpf29SLazLSrqUkj4w7Y5y7cCVP6E5tcqqcI0xemPkHug==} - '@puppeteer/browsers@3.2.4': - resolution: {integrity: sha512-okJ6yQMc0SBexOKxMi966omwAV1uAPwgF/YMZdb04gZQPXVjWHl9bmXjZYtIcsN1+PN3Bz4iFfGK3g+c6lZJ0Q==} + '@puppeteer/browsers@3.2.5': + resolution: {integrity: sha512-UoCo3Pynbm37aLEEoydSiG+t24ui7sLD40+07CKxzxNy4PpSowJMkvlLIiV67XjP1lMVynhQVnuwlTABqBH8LQ==} engines: {node: '>=22.12.0'} hasBin: true peerDependencies: @@ -3281,8 +3281,8 @@ packages: cpu: [arm] os: [android] - '@rolldown/binding-android-arm-eabi@1.2.13': - resolution: {integrity: sha512-Vu/NICrgdRvUOeaJZIyB2FP63s6fO/4ud5l8dXmxDx9yDyn+mN0y+gsvsVviSli+T361Aqo0h46EuMoobrwawA==} + '@rolldown/binding-android-arm-eabi@1.2.14': + resolution: {integrity: sha512-aWR+XKH9+rW7m5fWq/5360J3mHycrx/o6xZM2DQFdJnTMdyP7/WzxPjhtLbVWdKo2y612/4U1bWqb3HQhiF7vg==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm] os: [android] @@ -3293,8 +3293,8 @@ packages: cpu: [arm64] os: [android] - '@rolldown/binding-android-arm64@1.2.13': - resolution: {integrity: sha512-6LEoIrGy5vvCd2boNnv2soPSUZj/PRvhp8R/t9KlX+mIZxThIE/ZqxrGXxmuNX0FuvQFvLdZr7S4HrYpYBVhEQ==} + '@rolldown/binding-android-arm64@1.2.14': + resolution: {integrity: sha512-QiVxHofl6A8lQU7WAtOUY4QMVZXohxwz7WJJoeh8NBEUyKfIkMRKhYyq8az/1RypNiIXzNTtiS6KwHz0erxYRQ==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [android] @@ -3305,8 +3305,8 @@ packages: cpu: [arm64] os: [darwin] - '@rolldown/binding-darwin-arm64@1.2.13': - resolution: {integrity: sha512-CaJSRzlQ6Q+zkDMVA9OkVxBjVoPRCDEE3v0FSJ9kIQBgRjFApA3Si4ijhbNVUji7ZJt+PfO0e46qy4nPInHUPA==} + '@rolldown/binding-darwin-arm64@1.2.14': + resolution: {integrity: sha512-lTQOzHuBIooh3jIr5XINQkjPGEuGy+Dsy0meXDr6Sjty0b99kYgGh4uBC/8mJX1T0kC8d6S0aPP1Y+bHkh6aBw==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [darwin] @@ -3317,8 +3317,8 @@ packages: cpu: [x64] os: [darwin] - '@rolldown/binding-darwin-x64@1.2.13': - resolution: {integrity: sha512-e4r340I5hxSzJkD3YJBxgzq/rJ3wwxwdLLb2FPt1Zpyem20nrQPT11DDEEkazwxaHumH8wpglsp/Ozgj/wT6mw==} + '@rolldown/binding-darwin-x64@1.2.14': + resolution: {integrity: sha512-hyMKEGatjmBYCs/Q4sbIcL/GqpFEqsX3wc+HYVQ/85A4rxc1o7rPm4DUI4GV4k/h0ITddwFSGpqQunI14GXjTA==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [darwin] @@ -3329,8 +3329,8 @@ packages: cpu: [x64] os: [freebsd] - '@rolldown/binding-freebsd-x64@1.2.13': - resolution: {integrity: sha512-hoBWDZ4/K/mJKVMbsgUd1jfpA2DiOrJ54mpegObU9TBHBBrtX4FLIXJJQRDPZ/2Dn91GvPob+Z2hwKJzf4E5SQ==} + '@rolldown/binding-freebsd-x64@1.2.14': + resolution: {integrity: sha512-u371GbXoVXrEgP20PwzoGNOdAOqAMhzo19JzzY+V4YmmnC+DTOoqdbMu+O+54emM59Mik/UdrtWgcuEDKWRPKA==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [freebsd] @@ -3341,8 +3341,8 @@ packages: cpu: [arm] os: [linux] - '@rolldown/binding-linux-arm-gnueabihf@1.2.13': - resolution: {integrity: sha512-oF9fZu3vTWnTiVAkDFxU9PJLt1nh20K9RRpuHsR7ZnE2L7XookBbDBVLojCVSLGbvtSlxeUNnjAj6DbNsKyzbg==} + '@rolldown/binding-linux-arm-gnueabihf@1.2.14': + resolution: {integrity: sha512-BqwKsdZQf6EqVWr8fv2MrDYzAvOZ7+NYFSJESRGs87fkseEhs0TU9TXgRJTkZoRRkxTizyEg1LKUXfU3/78uqg==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm] os: [linux] @@ -3354,8 +3354,8 @@ packages: os: [linux] libc: [glibc] - '@rolldown/binding-linux-arm64-gnu@1.2.13': - resolution: {integrity: sha512-DTpb/+jMiqWMPgphn4ksW1zW+XLJ6dJJ9FMvnIk9I291LhCctMPhMYJrP5t9p6C9qa3KXadDdUEZHBaPh3kNxQ==} + '@rolldown/binding-linux-arm64-gnu@1.2.14': + resolution: {integrity: sha512-SD9kY8M009x/7s57Z1dgUVlP5+uYBgKQK0Tkr1WIWngrtUJmRCW1RJFMY7QDla2khXhmg2i5Io7MUjcmZNZ/KQ==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [linux] @@ -3368,8 +3368,8 @@ packages: os: [linux] libc: [musl] - '@rolldown/binding-linux-arm64-musl@1.2.13': - resolution: {integrity: sha512-xU+Kvv9N2A3SY35zFh1FWWNjxbadE/BKeqnkXe7vScU4GZsw757BlVmDLITZEq8DPpk6m7uoDYkK7P+x/uU5Ow==} + '@rolldown/binding-linux-arm64-musl@1.2.14': + resolution: {integrity: sha512-BJ2CL19M6uuWesMgnqJzgxoI+N+eV7b0A9O9vLV42y+gitC41fNa8KElau1tHVzuLWX5GzEuxMPhAO0tQXQMkg==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [linux] @@ -3382,8 +3382,8 @@ packages: os: [linux] libc: [glibc] - '@rolldown/binding-linux-ppc64-gnu@1.2.13': - resolution: {integrity: sha512-XMk/hnhh25oQ756Lclb1Q11h4ll0xC0Esa5w4Vzp+mAE2S3AGJgeM0SonrIgY8fHhjarb6hcoTuwoFG0VVP2ig==} + '@rolldown/binding-linux-ppc64-gnu@1.2.14': + resolution: {integrity: sha512-4+Kl8daPV8NDHaD7mfCcc1pRM+Qg7ab8DyMm5FG5WoZgv4h2i3KFN1CybYBNbQqmuYm7ftJLvmMI1eHYJ22S/Q==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [ppc64] os: [linux] @@ -3396,8 +3396,8 @@ packages: os: [linux] libc: [glibc] - '@rolldown/binding-linux-s390x-gnu@1.2.13': - resolution: {integrity: sha512-U1BoTHYmlywE2n3HUWjzZ+8EQsKr+OwpxYuDWaubx42tUL8QSL7nOqRz/NVHanibbFP3M1Rxuprz/wNcbMKjqw==} + '@rolldown/binding-linux-s390x-gnu@1.2.14': + resolution: {integrity: sha512-V/h8ePq1fKDrmtFMz6xcCN3DKvuvMRrwwD1q0PkBeeo4DpK64biaKvqWGVxqCeYKqeRk7gE7/iKPxLCn08O97A==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [s390x] os: [linux] @@ -3410,8 +3410,8 @@ packages: os: [linux] libc: [glibc] - '@rolldown/binding-linux-x64-gnu@1.2.13': - resolution: {integrity: sha512-J4cm80Pc6wEwV5AZ42o62sIQgDk+Y7R2s646jIwuvO+4V46QB58N4vVuMPWCBaNgursXLpmUWJV//WQAkPvHBQ==} + '@rolldown/binding-linux-x64-gnu@1.2.14': + resolution: {integrity: sha512-WxalXzgrLVpKC93xfpaJ3gCXUWzeCr+FRCbDVD2mUAy4L6Vo3lNVz0epUEUpxPWJkLNYUwM4OSIikv36OJ9mLg==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [linux] @@ -3424,8 +3424,8 @@ packages: os: [linux] libc: [musl] - '@rolldown/binding-linux-x64-musl@1.2.13': - resolution: {integrity: sha512-W0euZS40U4V6JkmEnVCIX9mcsL6cbXQ4X8c2w+MMOIjFg68TXUW+u3RT+2e1t1pv9mg/EP3pDtK3POXdQ7Rxyw==} + '@rolldown/binding-linux-x64-musl@1.2.14': + resolution: {integrity: sha512-3G3tnAmTpdk9jO3GQtyHXqeFD2SlecfTws/Y3M2mmj9nMBwwuLT4kur8sZKeu7ENUHSpVO3cIsm5A52LEWWwlg==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [linux] @@ -3437,8 +3437,8 @@ packages: cpu: [arm64] os: [openharmony] - '@rolldown/binding-openharmony-arm64@1.2.13': - resolution: {integrity: sha512-do/AF/4n9MRshia3a5aXoy8xM2c6mgfT6D7H/dY6my5z+hfCIR4ab7mk4IRj++nsEQpKy39kd0DQnDq+r692tw==} + '@rolldown/binding-openharmony-arm64@1.2.14': + resolution: {integrity: sha512-qyr5XiNGxm2ytx17vvtcJ9nXn6v1gENETi503bJx3OGwZ1tSonj7BosxbMa/xeAfSl5iS9X6KjEWYXLu6v1L7Q==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [openharmony] @@ -3449,8 +3449,8 @@ packages: cpu: [arm64] os: [win32] - '@rolldown/binding-win32-arm64-msvc@1.2.13': - resolution: {integrity: sha512-6FtUf2cJZobutJdxnGYX8z0vtbgqU0b2v8vfBhkXb9wp2MppMFtkunE+IaOntyi01rkIQoPW2GHABtfzsC0BRQ==} + '@rolldown/binding-win32-arm64-msvc@1.2.14': + resolution: {integrity: sha512-oA4o5o0S2yB199YyYXDzKUv1Z56Rc+mgOjwm7Z/vJ9Z8igiDPYvoOuDyo6g7AK/ZaF09nPhDKVnGBcYHO11GXA==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [win32] @@ -3461,8 +3461,8 @@ packages: cpu: [x64] os: [win32] - '@rolldown/binding-win32-x64-msvc@1.2.13': - resolution: {integrity: sha512-UKhFaZTeTcbKrb3iU82m17jVcPEAoqDkCN5MBqgPyZSwp/cQmib21crTS0DdH7T1B7wZRWEI89YQAOJMet5yhg==} + '@rolldown/binding-win32-x64-msvc@1.2.14': + resolution: {integrity: sha512-9mE94bf2GZUaR/fUSXCMpBoWkctu421Mi0ORpm4zqfbkjKep7RxzPFa5etcGs5h+2KApoWBOA/hAJa/7saGgEQ==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [win32] @@ -3506,146 +3506,146 @@ packages: rollup: optional: true - '@rollup/rollup-android-arm-eabi@4.64.5': - resolution: {integrity: sha512-MrfgRQSpD5hkkRg6XI16B6EDLb+6+xp8xje6bpdSwkYw+qxrBKbUVrRAQu9h82UT+QumSIVQ8HXsXjPd2dlhqw==} + '@rollup/rollup-android-arm-eabi@4.64.6': + resolution: {integrity: sha512-FkO19Fowv/OQeJZPVfdetJaI3/VpbZmBsnmAlR/rQ+b3QwfiGQiOpVegpSRH331kelvHTVw9hXYG3DwjAaRzyQ==} cpu: [arm] os: [android] - '@rollup/rollup-android-arm64@4.64.5': - resolution: {integrity: sha512-+uu2p/R9Tzn8GpoQyX1pAo5dmKT1DhXevfaCzqzmPFhnLjHLWw7uWkaVGlxmhwYoRiYYhsGfRcD5cTBpL7rgSw==} + '@rollup/rollup-android-arm64@4.64.6': + resolution: {integrity: sha512-si5/Etm6MphPc2xYHnk455Shls/hoMjTy3mhXge4OPmvCw7TwC4KP4fKokAlKLV4XaQvLvgSHfafPcblLMYYdQ==} cpu: [arm64] os: [android] - '@rollup/rollup-darwin-arm64@4.64.5': - resolution: {integrity: sha512-17dys+YEmzwzzFVHQAVDONg5FALXY9kd99HFEpfk4gJVHYxoh5bGea3D4t1fXXnwkTcOe25wPyd6nWS0I8IdLQ==} + '@rollup/rollup-darwin-arm64@4.64.6': + resolution: {integrity: sha512-PQCl3q7b0BgvVt72i2xrWM6I5KliwwVe4GpWW5QDGyUQawDS9aPZss/aGyFqBmxdRxlE8wDc9CaxiQ5DHRSp/Q==} cpu: [arm64] os: [darwin] - '@rollup/rollup-darwin-x64@4.64.5': - resolution: {integrity: sha512-wg0zQEKkEvFZf1UaaX1UELOoPs//OSKUG7D+yITuqOsAvza7LvHTv5Wu4nmMfzNG7EYI2jp2PJC7Id6OETmsYQ==} + '@rollup/rollup-darwin-x64@4.64.6': + resolution: {integrity: sha512-l9DFl1Itb1YYdSrP1K3U8ih44AOHa/p+Q4WMMDfGvH5qVWp+ajfgS1DlYo4yCRh8wJ2ZJv0Fqccf+ULAmMFjmg==} cpu: [x64] os: [darwin] - '@rollup/rollup-freebsd-arm64@4.64.5': - resolution: {integrity: sha512-CoJmWcpEMuwin+TZ/ev/H9uDyF/uxUKQSWXdmIPn/UBx/uGV9+4ebMp0FwnlhWR9PE1AdzYsKf3bZevhif38+A==} + '@rollup/rollup-freebsd-arm64@4.64.6': + resolution: {integrity: sha512-bR4GR3205N9+od0+l5Dd9/iZTDpJkIe6d6Ydp2qbcQZJLmKBdYQQRp8gbWpbMt92twKJY66o1vK4NkoKQODIrA==} cpu: [arm64] os: [freebsd] - '@rollup/rollup-freebsd-x64@4.64.5': - resolution: {integrity: sha512-PxZnLAaTUAL5xG0W2BXLeYPKrK2b3LIASV2/e/Kf7PZvSLI1iAQIm9B9aJD+YyFIT7hc6qaMV3+OOO35R28LfA==} + '@rollup/rollup-freebsd-x64@4.64.6': + resolution: {integrity: sha512-XTVNaDzcFl2TeBglvxdGgsCv9JGtAGRAoJENmGBR/XvDH2mA2K0IXc2aMfP0dR8mexSXSKifJ85FixoXX1wfTw==} cpu: [x64] os: [freebsd] - '@rollup/rollup-linux-arm-gnueabihf@4.64.5': - resolution: {integrity: sha512-uPo3IvnONjhbFXwWgroBeFwOicuhT7ZwQrnzkzmOtBJzeQbkUJUE1SJDfDI31ijQ5+ZUIA6sPrdUMxTSnxUWAg==} + '@rollup/rollup-linux-arm-gnueabihf@4.64.6': + resolution: {integrity: sha512-qWc6qbc+25ugG9vqPR9P422KJBbVfZ05mjcMggoq8tsfWP+eRfC+/tiDdIlRF5VL2pDVZWN9zAhWsmu7R1+7Dw==} cpu: [arm] os: [linux] libc: [glibc] - '@rollup/rollup-linux-arm-musleabihf@4.64.5': - resolution: {integrity: sha512-ywI8Jyuc4LyHYTjC0mw4yA1ulvZBkHusdpWnoiEBsmBuHvSnt90btTBGCZ+s/2y+YNNfVAEKy33nPo5UI9zTmg==} + '@rollup/rollup-linux-arm-musleabihf@4.64.6': + resolution: {integrity: sha512-V4Nwkp8844X/Xnww3PI1LYS0YPei8XQEVG70R+5MPZGO7AhYoun4hCN7Svs4U3wbQLZbwiz+9xRFhUZZdRl8Ww==} cpu: [arm] os: [linux] libc: [musl] - '@rollup/rollup-linux-arm64-gnu@4.64.5': - resolution: {integrity: sha512-tmuXJoQ/3ovSr637aykZMdQteU/CB2APAz2CrvsbibuoHZi1BS1Db13cVViBdEARGwXCLn1DSJ8wsjoThLJPGA==} + '@rollup/rollup-linux-arm64-gnu@4.64.6': + resolution: {integrity: sha512-xb72A1aPaaIsp+a88VtRae/ovIEXislbUMyp7b9AQQU7ZkP2m/+ik6DW9TQcJyw5R8/RIailF9zExYwkjR++UA==} cpu: [arm64] os: [linux] libc: [glibc] - '@rollup/rollup-linux-arm64-musl@4.64.5': - resolution: {integrity: sha512-5FMjSYNcUOHx7oW8Qu9KB6jGPpvF/8sG7+BDHwU/Ihh1/6FMJ9ySmsFG4tJ1qbNRuP8OLzCBDso4sF0mQaLuFQ==} + '@rollup/rollup-linux-arm64-musl@4.64.6': + resolution: {integrity: sha512-pbcs1BVBwC43hZkjhjlF8Rx8m5G0KnhLZs9Azy/gqccP6UsNSzJr0hKGIAVPqzAH1O/NdPxxC9GVGb4msQg/aw==} cpu: [arm64] os: [linux] libc: [musl] - '@rollup/rollup-linux-loong64-gnu@4.64.5': - resolution: {integrity: sha512-K8ZJ+neLDbUkIrL8dqF/5LtuVCrKwo27kREgOlxjBEjlOXwHvDnHLU8Z/UKv/B49qi7e8hsSDOyoJwhwqhvX4w==} + '@rollup/rollup-linux-loong64-gnu@4.64.6': + resolution: {integrity: sha512-EKOC8os6Vsg487ZLKUqzLF99Jsmnq6tu7O7mAELakNpcA+8KadktFf/JYdRuHe/DzCUXmN38pUKu4XBcKlqGbQ==} cpu: [loong64] os: [linux] libc: [glibc] - '@rollup/rollup-linux-loong64-musl@4.64.5': - resolution: {integrity: sha512-NlVxsq7PFPv0DBKGuNWRDKixQYQCjM53zl04mxEcKMBmJbCBIUm1JdPfIWDRHyOOFzzYPmLQzfeEwh4716ayQg==} + '@rollup/rollup-linux-loong64-musl@4.64.6': + resolution: {integrity: sha512-v/SQ68GnSlr/HyjB79sNXesGDwkOPu9JjbHfmWaymCiM+nZsQ9TstG1KfA4MuEvTr2d3PoY8PhFxj9bt0e32JA==} cpu: [loong64] os: [linux] libc: [musl] - '@rollup/rollup-linux-ppc64-gnu@4.64.5': - resolution: {integrity: sha512-ARhRHJYs5eCFet5azfrHD97vOkD8OzNW2RSMlvo5CcBqXaTOLfp0OHDtUQh7/K5AL5fUYoFp2fgC9KDg4vVYMQ==} + '@rollup/rollup-linux-ppc64-gnu@4.64.6': + resolution: {integrity: sha512-G3pmliMQ7r15zFFNwBlaT/xTdSLi4lfgI7CUrQueyKYheNVhrd8JrWCE6Ll8xf4AA1RZFqq+mNJYntiElsVOyA==} cpu: [ppc64] os: [linux] libc: [glibc] - '@rollup/rollup-linux-ppc64-musl@4.64.5': - resolution: {integrity: sha512-atSgreM5C7jpxd9aEXN+6vJ5wTd05iYw+S3FiQpw7VsoEl8B90llbq35ARON+GOHj5QlVQEq2vOKWCHTob/BSQ==} + '@rollup/rollup-linux-ppc64-musl@4.64.6': + resolution: {integrity: sha512-XQTB/IPoB/wG6x/wu9uomAt8YH61IAr5iZTubMiad/lu88sotq2ocz9hJd556+Jz2kIkF7ZQZIsUuWE3OWqtcA==} cpu: [ppc64] os: [linux] libc: [musl] - '@rollup/rollup-linux-riscv64-gnu@4.64.5': - resolution: {integrity: sha512-vmlmwBFGnjVWxSRoVabNkyYuscSmg52Pd0fM8jEbNT3Jmka4A6HcB84x4uAmuumznWfBVaxKOqU6jbEgomWKCA==} + '@rollup/rollup-linux-riscv64-gnu@4.64.6': + resolution: {integrity: sha512-O5mpokth6+ydMuwiGtY8fIjvOBfH7u6SzmDNmZ3k6GK5C6iEAC2q2ZN/T5L9jYILx0IcCT0KnfMDihQ5yQFSBw==} cpu: [riscv64] os: [linux] libc: [glibc] - '@rollup/rollup-linux-riscv64-musl@4.64.5': - resolution: {integrity: sha512-hhJrP6S9WkbsbcHgUkvCBS5Cn8IdsG8XjlLZyxjnv9+NdoYfbbZE4TWJYr8apdaj1M5t5Y1id2StnEslxpNFyA==} + '@rollup/rollup-linux-riscv64-musl@4.64.6': + resolution: {integrity: sha512-aIFxbAD9v3TvIaEDsKmukjcDg1JS4/tFXw8SHyQQgzOwzWCQ4cyDK7Ju1pQKqUXDFkEu/BZCFDCDATsKhQcB/Q==} cpu: [riscv64] os: [linux] libc: [musl] - '@rollup/rollup-linux-s390x-gnu@4.64.5': - resolution: {integrity: sha512-NNVCyN9pGrwFmQa4bf+Cnf5aVH3g6ZpnlOg1Cs/H9swIHT9bRixijfzUqyEIWm1WtiAuR1LJ+rJH6zpBm8kgQA==} + '@rollup/rollup-linux-s390x-gnu@4.64.6': + resolution: {integrity: sha512-fuNo1UwBc6BxnHDOxxguQL/InhheMN3RJcJMb0b4xP8r5Q3CNCrJbVg0eCIFuJ4e/zAfjR2gYbOfbzO/G7CIyw==} cpu: [s390x] os: [linux] libc: [glibc] - '@rollup/rollup-linux-x64-gnu@4.64.5': - resolution: {integrity: sha512-dR9nd6OKnvSS60Ifz/L7Mj5zzYyoqyRn2NwTuaOONKaa3xsVGXyp8YusMbvFyEOR94DxnwgcbgsFqkHd29ZSzQ==} + '@rollup/rollup-linux-x64-gnu@4.64.6': + resolution: {integrity: sha512-05v6wFKDKJPZs9xlytVrrRu6IbRuoSvlH9xNwEOafXsKyjBFZPvAcZz2VIAB/M+lblYeKa9iOYC4RDVdfcAAaw==} cpu: [x64] os: [linux] libc: [glibc] - '@rollup/rollup-linux-x64-musl@4.64.5': - resolution: {integrity: sha512-1tzsMjaqhsh3bAO6SJiJqh8hIr9sSPRd+i2vPPxJHod8/XYnf9TEnK0z/u3r1z1AkI347X0KbRSg9dWcxeGahw==} + '@rollup/rollup-linux-x64-musl@4.64.6': + resolution: {integrity: sha512-wJXKcdMjvkc/FaavZXNP1yW4i0pfOmhZAIWRSLG2yJ0PB0TWi7dkLErhX0u0vptDcXKKO/m1Y/YTeuyvb2MXwg==} cpu: [x64] os: [linux] libc: [musl] - '@rollup/rollup-openbsd-x64@4.64.5': - resolution: {integrity: sha512-01mWMQblKoXXsmk28KXtpbA96w7g/aOWUoV3AC16fdHdqkykGalqyyM+5u8M7uP5/MEMiiPv69Hv7iv/hEH/dA==} + '@rollup/rollup-openbsd-x64@4.64.6': + resolution: {integrity: sha512-cwg7/h0ThvJwy8CBkmACdiHAxRWpbsCmIsjOt+Zzx0hTnIcSUmKYEV03bGg+hD827OnwUsbKh1ZZDW754xWyBA==} cpu: [x64] os: [openbsd] - '@rollup/rollup-openharmony-arm64@4.64.5': - resolution: {integrity: sha512-trdnMPb/DNm4V/CgsaoGgr90HfQQ071wfK0KoIs4YpLvjBgVQGXhGabg2Z6nK4EcYNilrb9ZZPcsP6+zpJIdxQ==} + '@rollup/rollup-openharmony-arm64@4.64.6': + resolution: {integrity: sha512-T0RkYIJbdYXJEQFw+tMBO09KDFdgmNxkHsof3wWAABrvnx15Yh8RytmrgYy9+q9cBeBNZF66MMQZC+5nzEz6vg==} cpu: [arm64] os: [openharmony] - '@rollup/rollup-win32-arm64-msvc@4.64.5': - resolution: {integrity: sha512-x2LxZlfdfsw99T6/qb9EqE/Qi84JWzibjyOJyhJsgFJy6CafaTiqIXCCnslCGrV5XWNh7fwrS3FbRENcuKnooA==} + '@rollup/rollup-win32-arm64-msvc@4.64.6': + resolution: {integrity: sha512-KlfpmF1AAIdAWxt8QQNClbpLFlAUfYOzqIuJ7IXEStMHpFRuH78RG6FjqPb3Rqhh0K89F5npvG+/i3Fjl6IveQ==} cpu: [arm64] os: [win32] - '@rollup/rollup-win32-ia32-msvc@4.64.5': - resolution: {integrity: sha512-/Qd/9aDQIo0+jmItgBmPIs8195YVbDxRRApn47GyufgbutCDOh7eP5vSKKlI4QNFeaI+wKQAkSMsPnF3EuMpaA==} + '@rollup/rollup-win32-ia32-msvc@4.64.6': + resolution: {integrity: sha512-MrTLjd7Jlt9/ZavJZYG61KQv9Iy9bzbY+yXy73Xvwoa2uP66wvDShkyBr5Chz/yrE6lbD/zHMuTmKQVNQqBApg==} cpu: [ia32] os: [win32] - '@rollup/rollup-win32-x64-gnu@4.64.5': - resolution: {integrity: sha512-ngUJ/XvOWrqbd2IMsfXfh2xXFLTP3sY7sCKvxbGvYdBZ1KmXFd3ewDZ9n3/GNzAUgzRuhLT/UvJRivbNoAQRBw==} + '@rollup/rollup-win32-x64-gnu@4.64.6': + resolution: {integrity: sha512-8fWDH1CkPI8GdBKAxzHDza7UmgficsKo2+MVbvUgOGhB0629w5sHMg3Qu5y7TZsrYKHHWpz8fla4KvoT7WsO3Q==} cpu: [x64] os: [win32] - '@rollup/rollup-win32-x64-msvc@4.64.5': - resolution: {integrity: sha512-IhV6ew/DuzUWwHaYmlh7MrPCV3lKFUq/amTEwysi4r/mwNPAEfAMh5dYWeTSPTeMy2pFHGMEWYtPkHzfX3tG5A==} + '@rollup/rollup-win32-x64-msvc@4.64.6': + resolution: {integrity: sha512-9/c9PWdr5GCIHkkxiHM1HjNBQMVdftP4O8QTcoUAaRza2FSqJ4axbf8QAnBuE6BIGQDl71SaRPeDdDYid5ecTw==} cpu: [x64] os: [win32] - '@rollup/wasm-node@4.64.5': - resolution: {integrity: sha512-kN33cPixKuDMgrYkRnkAW7iwiDWzRhNUgVY+IpcniQNXuIvDAAv0cFgZsaLEFP1z8eqVGhKG13dy5hFN3yBy+g==} + '@rollup/wasm-node@4.64.6': + resolution: {integrity: sha512-ufelhiGxNl8RuflC/Tie5ZVcI3MJUtd27nJ0jC2I4LroyZb7n4iwmajEmXXeTLxJtDiiWUwU8v2UjkACBHqQvw==} engines: {node: '>=18.0.0', npm: '>=8.0.0'} hasBin: true @@ -7070,8 +7070,8 @@ packages: resolution: {integrity: sha512-19YVAg7T+WTrxggPukVq7DjTv6+PJ867TmhCvBsYwmbFCsZd344rq2Ld1p0wo8f8Qrrhgp82c6FJRqdXWtSEhg==} engines: {node: '>= 0.4'} - oxc-parser@0.153.0: - resolution: {integrity: sha512-cEnpyyV1OJRXv++SFNw0z8i+2o/cr88rVLaOYJafELDoHM5yHvCAbwGRLvxuany6SNLcbblSMUyZaGzH+quSYg==} + oxc-parser@0.154.0: + resolution: {integrity: sha512-Gr/6fkjZwi937c4Tsz8y0iO4U0FLPkZI6JSVucLAIvQyqh379px7RS8ORIc0HOORbFjXZ6zyqWLl53qxhSeofw==} engines: {node: ^20.19.0 || >=22.12.0} p-finally@1.0.0: @@ -7281,6 +7281,10 @@ packages: resolution: {integrity: sha512-49cGhUbXj8Qenv0iTMxA1cFBzxXoctpC9Ujd77t1WcbJIr6nF/eI7g/8MgxrYldFRuAXvja7xQRwavoW7kgrxQ==} engines: {node: ^10 || ^12 || >=14} + postcss@8.5.30: + resolution: {integrity: sha512-zkd+e9S1AQHhmaBKye9zlFHWjOwVgqXl1q3ECYy8561K7qxR2cREf/STLskulBFd78k6AOFeA+ff1TtEzk9bAA==} + engines: {node: ^10 || ^12 || >=14} + powershell-utils@0.2.1: resolution: {integrity: sha512-C+y9x90UElAddDZmV4qOx9W53B61PO7cIqWz2dQsWlwswuq4mr8NEwytdGKboYbQlGZ3awrkTeNvcZiZNHnQ8A==} engines: {node: '>=20'} @@ -7351,12 +7355,12 @@ packages: resolution: {integrity: sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==} engines: {node: '>=6'} - puppeteer-core@25.13.0: - resolution: {integrity: sha512-cyBS0OEx3e9NS53B5F6+UazXtR7f9Tw0cR1/FbPW59/hV6JPZbkIiMnxK2543IkFp3rsGlLn1iPDLF77TJsJsA==} + puppeteer-core@25.14.0: + resolution: {integrity: sha512-LQitnes3tBeVbdZ7V/4iwJPLZGgkl9uBVK0W7YYMh68j/3Y9eNuvj4yl+Fdo7zN0SuajOMrhd7aPj3DifK8k6A==} engines: {node: '>=22.12.0'} - puppeteer@25.13.0: - resolution: {integrity: sha512-vB4KLXTT5QqlikcOQ/xV0RY18bBVtNyLUTfqJ9mW+penHyoM+5DmANYuDCI4jgBtiL0eD9I5ZFSafW6/a6Trpg==} + puppeteer@25.14.0: + resolution: {integrity: sha512-+s1Iqbl9DsGLOaQdgCQyhtgHZsF9hi4Iu8iuBqxzraxUXoRG1QkYQI0CA1/VsNK1gZWJfs50BL/oOb1L+Yz8Yg==} engines: {node: '>=22.12.0'} hasBin: true @@ -7595,8 +7599,8 @@ packages: engines: {node: ^20.19.0 || >=22.12.0} hasBin: true - rolldown@1.2.13: - resolution: {integrity: sha512-/5apOkwWxtACcQtZ5WlrAsKS4JwXVThQPJZ3RqIruRY9UG9M8e0VlXN068xum/JRKA4aIUoJ13ghe/kGCvidiQ==} + rolldown@1.2.14: + resolution: {integrity: sha512-eTBTTqMR6uHKLgcUqpJP8ntzDI6V4LYA8negAMBEI7gkgVvOdrx6VsvS2Ym+83KhOPdLCHWJu0w7UQFJZhHKNw==} engines: {node: ^20.19.0 || >=22.12.0} hasBin: true @@ -7621,8 +7625,8 @@ packages: '@types/node': optional: true - rollup@4.64.5: - resolution: {integrity: sha512-EAP5ZHcz2ijbgCWwPkpI7zh6bfsri2Ez5FtCy2dCp1k62duXzfG7DLGGh7RU2QQXWwavT+u4qpvDF/TWOiiGTw==} + rollup@4.64.6: + resolution: {integrity: sha512-fX1Vy+UNKdXn+xKDnu/HBXbHVr1AY8cSdQj9BU4kLv5aFCMqGpvrVbyUMmjN3DdzWhSAuTbcX8PCNEVaumthYA==} engines: {node: '>=18.0.0', npm: '>=8.0.0'} hasBin: true @@ -8350,6 +8354,10 @@ packages: resolution: {integrity: sha512-u4UB2/IrKdU6lFxumHmmo1a3fCQO5tzQllRorfoRS63txhrB7xTpSn1PftwC4qEHkOaqP95fCWW4lJzwErwzhQ==} engines: {node: '>=22.19.0'} + undici@8.12.1: + resolution: {integrity: sha512-usz3OVQBeh1LxNn0DzU0voLXMgn5CU/WUdpBsY6Ti5afNao+vTkmn4H/NxoXolc10cOqe2+YIG0Hspq2rsl64w==} + engines: {node: '>=22.19.0'} + unicode-canonical-property-names-ecmascript@2.0.1: resolution: {integrity: sha512-dA8WbNeb2a6oQzAQ55YlT5vQAWGV9WXOsi3SskE3bcCdM0P4SDd+24zS/OCacdRq5BkdsRj9q3Pg6YyQoxIGqg==} engines: {node: '>=4'} @@ -11073,66 +11081,66 @@ snapshots: '@opentelemetry/semantic-conventions@1.43.0': {} - '@oxc-parser/binding-android-arm-eabi@0.153.0': + '@oxc-parser/binding-android-arm-eabi@0.154.0': optional: true - '@oxc-parser/binding-android-arm64@0.153.0': + '@oxc-parser/binding-android-arm64@0.154.0': optional: true - '@oxc-parser/binding-darwin-arm64@0.153.0': + '@oxc-parser/binding-darwin-arm64@0.154.0': optional: true - '@oxc-parser/binding-darwin-x64@0.153.0': + '@oxc-parser/binding-darwin-x64@0.154.0': optional: true - '@oxc-parser/binding-freebsd-x64@0.153.0': + '@oxc-parser/binding-freebsd-x64@0.154.0': optional: true - '@oxc-parser/binding-linux-arm-gnueabihf@0.153.0': + '@oxc-parser/binding-linux-arm-gnueabihf@0.154.0': optional: true - '@oxc-parser/binding-linux-arm-musleabihf@0.153.0': + '@oxc-parser/binding-linux-arm-musleabihf@0.154.0': optional: true - '@oxc-parser/binding-linux-arm64-gnu@0.153.0': + '@oxc-parser/binding-linux-arm64-gnu@0.154.0': optional: true - '@oxc-parser/binding-linux-arm64-musl@0.153.0': + '@oxc-parser/binding-linux-arm64-musl@0.154.0': optional: true - '@oxc-parser/binding-linux-ppc64-gnu@0.153.0': + '@oxc-parser/binding-linux-ppc64-gnu@0.154.0': optional: true - '@oxc-parser/binding-linux-riscv64-gnu@0.153.0': + '@oxc-parser/binding-linux-riscv64-gnu@0.154.0': optional: true - '@oxc-parser/binding-linux-riscv64-musl@0.153.0': + '@oxc-parser/binding-linux-riscv64-musl@0.154.0': optional: true - '@oxc-parser/binding-linux-s390x-gnu@0.153.0': + '@oxc-parser/binding-linux-s390x-gnu@0.154.0': optional: true - '@oxc-parser/binding-linux-x64-gnu@0.153.0': + '@oxc-parser/binding-linux-x64-gnu@0.154.0': optional: true - '@oxc-parser/binding-linux-x64-musl@0.153.0': + '@oxc-parser/binding-linux-x64-musl@0.154.0': optional: true - '@oxc-parser/binding-openharmony-arm64@0.153.0': + '@oxc-parser/binding-openharmony-arm64@0.154.0': optional: true - '@oxc-parser/binding-win32-arm64-msvc@0.153.0': + '@oxc-parser/binding-win32-arm64-msvc@0.154.0': optional: true - '@oxc-parser/binding-win32-ia32-msvc@0.153.0': + '@oxc-parser/binding-win32-ia32-msvc@0.154.0': optional: true - '@oxc-parser/binding-win32-x64-msvc@0.153.0': + '@oxc-parser/binding-win32-x64-msvc@0.154.0': optional: true '@oxc-project/types@0.152.0': {} - '@oxc-project/types@0.153.0': {} + '@oxc-project/types@0.154.0': {} '@parcel/watcher-android-arm64@2.6.0': optional: true @@ -11309,7 +11317,7 @@ snapshots: '@protobufjs/utf8@1.1.2': {} - '@puppeteer/browsers@3.2.4': + '@puppeteer/browsers@3.2.5': dependencies: modern-tar: 0.8.5 yargs: 18.2.0 @@ -11317,98 +11325,98 @@ snapshots: '@rolldown/binding-android-arm-eabi@1.2.12': optional: true - '@rolldown/binding-android-arm-eabi@1.2.13': + '@rolldown/binding-android-arm-eabi@1.2.14': optional: true '@rolldown/binding-android-arm64@1.2.12': optional: true - '@rolldown/binding-android-arm64@1.2.13': + '@rolldown/binding-android-arm64@1.2.14': optional: true '@rolldown/binding-darwin-arm64@1.2.12': optional: true - '@rolldown/binding-darwin-arm64@1.2.13': + '@rolldown/binding-darwin-arm64@1.2.14': optional: true '@rolldown/binding-darwin-x64@1.2.12': optional: true - '@rolldown/binding-darwin-x64@1.2.13': + '@rolldown/binding-darwin-x64@1.2.14': optional: true '@rolldown/binding-freebsd-x64@1.2.12': optional: true - '@rolldown/binding-freebsd-x64@1.2.13': + '@rolldown/binding-freebsd-x64@1.2.14': optional: true '@rolldown/binding-linux-arm-gnueabihf@1.2.12': optional: true - '@rolldown/binding-linux-arm-gnueabihf@1.2.13': + '@rolldown/binding-linux-arm-gnueabihf@1.2.14': optional: true '@rolldown/binding-linux-arm64-gnu@1.2.12': optional: true - '@rolldown/binding-linux-arm64-gnu@1.2.13': + '@rolldown/binding-linux-arm64-gnu@1.2.14': optional: true '@rolldown/binding-linux-arm64-musl@1.2.12': optional: true - '@rolldown/binding-linux-arm64-musl@1.2.13': + '@rolldown/binding-linux-arm64-musl@1.2.14': optional: true '@rolldown/binding-linux-ppc64-gnu@1.2.12': optional: true - '@rolldown/binding-linux-ppc64-gnu@1.2.13': + '@rolldown/binding-linux-ppc64-gnu@1.2.14': optional: true '@rolldown/binding-linux-s390x-gnu@1.2.12': optional: true - '@rolldown/binding-linux-s390x-gnu@1.2.13': + '@rolldown/binding-linux-s390x-gnu@1.2.14': optional: true '@rolldown/binding-linux-x64-gnu@1.2.12': optional: true - '@rolldown/binding-linux-x64-gnu@1.2.13': + '@rolldown/binding-linux-x64-gnu@1.2.14': optional: true '@rolldown/binding-linux-x64-musl@1.2.12': optional: true - '@rolldown/binding-linux-x64-musl@1.2.13': + '@rolldown/binding-linux-x64-musl@1.2.14': optional: true '@rolldown/binding-openharmony-arm64@1.2.12': optional: true - '@rolldown/binding-openharmony-arm64@1.2.13': + '@rolldown/binding-openharmony-arm64@1.2.14': optional: true '@rolldown/binding-win32-arm64-msvc@1.2.12': optional: true - '@rolldown/binding-win32-arm64-msvc@1.2.13': + '@rolldown/binding-win32-arm64-msvc@1.2.14': optional: true '@rolldown/binding-win32-x64-msvc@1.2.12': optional: true - '@rolldown/binding-win32-x64-msvc@1.2.13': + '@rolldown/binding-win32-x64-msvc@1.2.14': optional: true '@rolldown/pluginutils@1.0.1': {} - '@rollup/plugin-commonjs@29.0.3(rollup@4.64.5)': + '@rollup/plugin-commonjs@29.0.3(rollup@4.64.6)': dependencies: - '@rollup/pluginutils': 5.4.0(rollup@4.64.5) + '@rollup/pluginutils': 5.4.0(rollup@4.64.6) commondir: 1.0.1 estree-walker: 2.0.2 fdir: 6.5.0(picomatch@4.0.7) @@ -11416,108 +11424,108 @@ snapshots: magic-string: 0.30.21 picomatch: 4.0.7 optionalDependencies: - rollup: 4.64.5 + rollup: 4.64.6 - '@rollup/plugin-json@6.1.0(rollup@4.64.5)': + '@rollup/plugin-json@6.1.0(rollup@4.64.6)': dependencies: - '@rollup/pluginutils': 5.4.0(rollup@4.64.5) + '@rollup/pluginutils': 5.4.0(rollup@4.64.6) optionalDependencies: - rollup: 4.64.5 + rollup: 4.64.6 - '@rollup/plugin-node-resolve@16.0.3(rollup@4.64.5)': + '@rollup/plugin-node-resolve@16.0.3(rollup@4.64.6)': dependencies: - '@rollup/pluginutils': 5.4.0(rollup@4.64.5) + '@rollup/pluginutils': 5.4.0(rollup@4.64.6) '@types/resolve': 1.20.2 deepmerge: 4.3.1 is-module: 1.0.0 resolve: 1.22.13 optionalDependencies: - rollup: 4.64.5 + rollup: 4.64.6 - '@rollup/pluginutils@5.4.0(rollup@4.64.5)': + '@rollup/pluginutils@5.4.0(rollup@4.64.6)': dependencies: '@types/estree': 1.0.9 estree-walker: 2.0.2 picomatch: 4.0.7 optionalDependencies: - rollup: 4.64.5 + rollup: 4.64.6 - '@rollup/rollup-android-arm-eabi@4.64.5': + '@rollup/rollup-android-arm-eabi@4.64.6': optional: true - '@rollup/rollup-android-arm64@4.64.5': + '@rollup/rollup-android-arm64@4.64.6': optional: true - '@rollup/rollup-darwin-arm64@4.64.5': + '@rollup/rollup-darwin-arm64@4.64.6': optional: true - '@rollup/rollup-darwin-x64@4.64.5': + '@rollup/rollup-darwin-x64@4.64.6': optional: true - '@rollup/rollup-freebsd-arm64@4.64.5': + '@rollup/rollup-freebsd-arm64@4.64.6': optional: true - '@rollup/rollup-freebsd-x64@4.64.5': + '@rollup/rollup-freebsd-x64@4.64.6': optional: true - '@rollup/rollup-linux-arm-gnueabihf@4.64.5': + '@rollup/rollup-linux-arm-gnueabihf@4.64.6': optional: true - '@rollup/rollup-linux-arm-musleabihf@4.64.5': + '@rollup/rollup-linux-arm-musleabihf@4.64.6': optional: true - '@rollup/rollup-linux-arm64-gnu@4.64.5': + '@rollup/rollup-linux-arm64-gnu@4.64.6': optional: true - '@rollup/rollup-linux-arm64-musl@4.64.5': + '@rollup/rollup-linux-arm64-musl@4.64.6': optional: true - '@rollup/rollup-linux-loong64-gnu@4.64.5': + '@rollup/rollup-linux-loong64-gnu@4.64.6': optional: true - '@rollup/rollup-linux-loong64-musl@4.64.5': + '@rollup/rollup-linux-loong64-musl@4.64.6': optional: true - '@rollup/rollup-linux-ppc64-gnu@4.64.5': + '@rollup/rollup-linux-ppc64-gnu@4.64.6': optional: true - '@rollup/rollup-linux-ppc64-musl@4.64.5': + '@rollup/rollup-linux-ppc64-musl@4.64.6': optional: true - '@rollup/rollup-linux-riscv64-gnu@4.64.5': + '@rollup/rollup-linux-riscv64-gnu@4.64.6': optional: true - '@rollup/rollup-linux-riscv64-musl@4.64.5': + '@rollup/rollup-linux-riscv64-musl@4.64.6': optional: true - '@rollup/rollup-linux-s390x-gnu@4.64.5': + '@rollup/rollup-linux-s390x-gnu@4.64.6': optional: true - '@rollup/rollup-linux-x64-gnu@4.64.5': + '@rollup/rollup-linux-x64-gnu@4.64.6': optional: true - '@rollup/rollup-linux-x64-musl@4.64.5': + '@rollup/rollup-linux-x64-musl@4.64.6': optional: true - '@rollup/rollup-openbsd-x64@4.64.5': + '@rollup/rollup-openbsd-x64@4.64.6': optional: true - '@rollup/rollup-openharmony-arm64@4.64.5': + '@rollup/rollup-openharmony-arm64@4.64.6': optional: true - '@rollup/rollup-win32-arm64-msvc@4.64.5': + '@rollup/rollup-win32-arm64-msvc@4.64.6': optional: true - '@rollup/rollup-win32-ia32-msvc@4.64.5': + '@rollup/rollup-win32-ia32-msvc@4.64.6': optional: true - '@rollup/rollup-win32-x64-gnu@4.64.5': + '@rollup/rollup-win32-x64-gnu@4.64.6': optional: true - '@rollup/rollup-win32-x64-msvc@4.64.5': + '@rollup/rollup-win32-x64-msvc@4.64.6': optional: true - '@rollup/wasm-node@4.64.5': + '@rollup/wasm-node@4.64.6': dependencies: '@types/estree': 1.0.9 optionalDependencies: @@ -11682,7 +11690,7 @@ snapshots: '@types/loader-utils@3.0.0(esbuild@0.28.2)(lightningcss@1.33.0)(uglify-js@3.19.3)': dependencies: '@types/node': 22.20.5 - webpack: 5.111.1(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.29)(uglify-js@3.19.3) + webpack: 5.111.1(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.30)(uglify-js@3.19.3) transitivePeerDependencies: - '@minify-html/node' - '@napi-rs/image' @@ -12459,13 +12467,13 @@ snapshots: atomic-sleep@1.0.0: {} - autoprefixer@10.6.1(postcss@8.5.29): + autoprefixer@10.6.1(postcss@8.5.30): dependencies: browserslist: 4.29.3 caniuse-lite: 1.0.30001815 fraction.js: 5.3.4 picocolors: 1.1.1 - postcss: 8.5.29 + postcss: 8.5.30 postcss-value-parser: 4.2.0 available-typed-arrays@1.0.7: @@ -12478,12 +12486,12 @@ snapshots: b4a@1.9.0: {} - babel-loader@10.1.1(@babel/core@8.0.7)(webpack@5.111.1(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.29)(uglify-js@3.19.3)): + babel-loader@10.1.1(@babel/core@8.0.7)(webpack@5.111.1(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.30)(uglify-js@3.19.3)): dependencies: '@babel/core': 8.0.7 find-up: 5.0.0 optionalDependencies: - webpack: 5.111.1(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.29)(uglify-js@3.19.3) + webpack: 5.111.1(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.30)(uglify-js@3.19.3) babel-plugin-polyfill-corejs3@1.0.0(@babel/core@8.0.7): dependencies: @@ -12544,9 +12552,9 @@ snapshots: domhandler: 6.0.1 htmlparser2: 12.0.0 picocolors: 1.1.1 - postcss: 8.5.29 + postcss: 8.5.30 postcss-media-query-parser: 0.2.3 - postcss-safe-parser: 7.1.0(postcss@8.5.29) + postcss-safe-parser: 7.1.0(postcss@8.5.30) before-after-hook@4.0.0: {} @@ -12796,7 +12804,7 @@ snapshots: dependencies: devtools-protocol: 0.0.1696802 mitt: 3.0.1 - zod: 4.6.5 + zod: 4.6.7 chunk-data@0.1.0: {} @@ -12959,14 +12967,14 @@ snapshots: dependencies: is-what: 4.1.16 - copy-webpack-plugin@14.0.0(webpack@5.111.1(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.29)(uglify-js@3.19.3)): + copy-webpack-plugin@14.0.0(webpack@5.111.1(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.30)(uglify-js@3.19.3)): dependencies: glob-parent: 6.0.2 normalize-path: 3.0.0 schema-utils: 4.5.0 serialize-javascript: 7.1.2 tinyglobby: 0.2.17 - webpack: 5.111.1(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.29)(uglify-js@3.19.3) + webpack: 5.111.1(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.30)(uglify-js@3.19.3) core-js-compat@3.50.0: dependencies: @@ -12996,18 +13004,18 @@ snapshots: shebang-command: 2.0.0 which: 2.0.2 - css-loader@7.1.5(webpack@5.111.1(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.29)(uglify-js@3.19.3)): + css-loader@7.1.5(webpack@5.111.1(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.30)(uglify-js@3.19.3)): dependencies: - icss-utils: 5.1.0(postcss@8.5.29) - postcss: 8.5.29 - postcss-modules-extract-imports: 3.1.0(postcss@8.5.29) - postcss-modules-local-by-default: 4.2.0(postcss@8.5.29) - postcss-modules-scope: 3.2.1(postcss@8.5.29) - postcss-modules-values: 4.0.0(postcss@8.5.29) + icss-utils: 5.1.0(postcss@8.5.30) + postcss: 8.5.30 + postcss-modules-extract-imports: 3.1.0(postcss@8.5.30) + postcss-modules-local-by-default: 4.2.0(postcss@8.5.30) + postcss-modules-scope: 3.2.1(postcss@8.5.30) + postcss-modules-values: 4.0.0(postcss@8.5.30) postcss-value-parser: 4.2.0 semver: 7.8.5 optionalDependencies: - webpack: 5.111.1(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.29)(uglify-js@3.19.3) + webpack: 5.111.1(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.30)(uglify-js@3.19.3) css-select@7.0.0: dependencies: @@ -14296,9 +14304,9 @@ snapshots: dependencies: safer-buffer: 2.1.2 - icss-utils@5.1.0(postcss@8.5.29): + icss-utils@5.1.0(postcss@8.5.30): dependencies: - postcss: 8.5.29 + postcss: 8.5.30 idb@7.1.1: {} @@ -14795,12 +14803,12 @@ snapshots: picocolors: 1.1.1 shell-quote: 1.12.0 - less-loader@13.0.0(less@4.9.1(supports-color@11.0.0))(webpack@5.111.1(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.29)(uglify-js@3.19.3)): + less-loader@13.0.0(less@4.9.1(supports-color@11.0.0))(webpack@5.111.1(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.30)(uglify-js@3.19.3)): dependencies: '@types/less': 3.0.8 less: 4.9.1(supports-color@11.0.0) optionalDependencies: - webpack: 5.111.1(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.29)(uglify-js@3.19.3) + webpack: 5.111.1(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.30)(uglify-js@3.19.3) less@4.9.1(supports-color@11.0.0): dependencies: @@ -14822,11 +14830,11 @@ snapshots: prelude-ls: 1.2.1 type-check: 0.4.0 - license-webpack-plugin@4.0.2(webpack@5.111.1(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.29)(uglify-js@3.19.3)): + license-webpack-plugin@4.0.2(webpack@5.111.1(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.30)(uglify-js@3.19.3)): dependencies: webpack-sources: 3.6.0 optionalDependencies: - webpack: 5.111.1(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.29)(uglify-js@3.19.3) + webpack: 5.111.1(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.30)(uglify-js@3.19.3) lightningcss-android-arm64@1.33.0: optional: true @@ -15081,11 +15089,11 @@ snapshots: mimic-response@4.0.0: {} - mini-css-extract-plugin@2.10.2(webpack@5.111.1(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.29)(uglify-js@3.19.3)): + mini-css-extract-plugin@2.10.2(webpack@5.111.1(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.30)(uglify-js@3.19.3)): dependencies: schema-utils: 4.5.0 tapable: 2.3.3 - webpack: 5.111.1(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.29)(uglify-js@3.19.3) + webpack: 5.111.1(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.30)(uglify-js@3.19.3) minimatch@10.2.6: dependencies: @@ -15118,6 +15126,19 @@ snapshots: postcss: 8.5.29 uglify-js: 3.19.3 + minimizer-webpack-plugin@5.13.0(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.30)(uglify-js@3.19.3)(webpack@5.111.1(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.30)(uglify-js@3.19.3)): + dependencies: + '@jridgewell/trace-mapping': 0.3.31 + jest-worker: 27.5.1 + schema-utils: 4.5.0 + terser: 5.51.2 + webpack: 5.111.1(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.30)(uglify-js@3.19.3) + optionalDependencies: + esbuild: 0.28.2 + lightningcss: 1.33.0 + postcss: 8.5.30 + uglify-js: 3.19.3 + minipass@7.1.3: {} mitt@1.2.0: {} @@ -15396,29 +15417,29 @@ snapshots: object-keys: 1.1.1 safe-push-apply: 1.0.0 - oxc-parser@0.153.0: + oxc-parser@0.154.0: dependencies: - '@oxc-project/types': 0.153.0 + '@oxc-project/types': 0.154.0 optionalDependencies: - '@oxc-parser/binding-android-arm-eabi': 0.153.0 - '@oxc-parser/binding-android-arm64': 0.153.0 - '@oxc-parser/binding-darwin-arm64': 0.153.0 - '@oxc-parser/binding-darwin-x64': 0.153.0 - '@oxc-parser/binding-freebsd-x64': 0.153.0 - '@oxc-parser/binding-linux-arm-gnueabihf': 0.153.0 - '@oxc-parser/binding-linux-arm-musleabihf': 0.153.0 - '@oxc-parser/binding-linux-arm64-gnu': 0.153.0 - '@oxc-parser/binding-linux-arm64-musl': 0.153.0 - '@oxc-parser/binding-linux-ppc64-gnu': 0.153.0 - '@oxc-parser/binding-linux-riscv64-gnu': 0.153.0 - '@oxc-parser/binding-linux-riscv64-musl': 0.153.0 - '@oxc-parser/binding-linux-s390x-gnu': 0.153.0 - '@oxc-parser/binding-linux-x64-gnu': 0.153.0 - '@oxc-parser/binding-linux-x64-musl': 0.153.0 - '@oxc-parser/binding-openharmony-arm64': 0.153.0 - '@oxc-parser/binding-win32-arm64-msvc': 0.153.0 - '@oxc-parser/binding-win32-ia32-msvc': 0.153.0 - '@oxc-parser/binding-win32-x64-msvc': 0.153.0 + '@oxc-parser/binding-android-arm-eabi': 0.154.0 + '@oxc-parser/binding-android-arm64': 0.154.0 + '@oxc-parser/binding-darwin-arm64': 0.154.0 + '@oxc-parser/binding-darwin-x64': 0.154.0 + '@oxc-parser/binding-freebsd-x64': 0.154.0 + '@oxc-parser/binding-linux-arm-gnueabihf': 0.154.0 + '@oxc-parser/binding-linux-arm-musleabihf': 0.154.0 + '@oxc-parser/binding-linux-arm64-gnu': 0.154.0 + '@oxc-parser/binding-linux-arm64-musl': 0.154.0 + '@oxc-parser/binding-linux-ppc64-gnu': 0.154.0 + '@oxc-parser/binding-linux-riscv64-gnu': 0.154.0 + '@oxc-parser/binding-linux-riscv64-musl': 0.154.0 + '@oxc-parser/binding-linux-s390x-gnu': 0.154.0 + '@oxc-parser/binding-linux-x64-gnu': 0.154.0 + '@oxc-parser/binding-linux-x64-musl': 0.154.0 + '@oxc-parser/binding-openharmony-arm64': 0.154.0 + '@oxc-parser/binding-win32-arm64-msvc': 0.154.0 + '@oxc-parser/binding-win32-ia32-msvc': 0.154.0 + '@oxc-parser/binding-win32-x64-msvc': 0.154.0 p-finally@1.0.0: {} @@ -15572,43 +15593,43 @@ snapshots: possible-typed-array-names@1.1.0: {} - postcss-loader@8.2.1(postcss@8.5.29)(typescript@6.0.3)(webpack@5.111.1(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.29)(uglify-js@3.19.3)): + postcss-loader@8.2.1(postcss@8.5.30)(typescript@6.0.3)(webpack@5.111.1(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.30)(uglify-js@3.19.3)): dependencies: cosmiconfig: 9.0.2(typescript@6.0.3) jiti: 2.7.0 - postcss: 8.5.29 + postcss: 8.5.30 semver: 7.8.5 optionalDependencies: - webpack: 5.111.1(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.29)(uglify-js@3.19.3) + webpack: 5.111.1(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.30)(uglify-js@3.19.3) transitivePeerDependencies: - typescript postcss-media-query-parser@0.2.3: {} - postcss-modules-extract-imports@3.1.0(postcss@8.5.29): + postcss-modules-extract-imports@3.1.0(postcss@8.5.30): dependencies: - postcss: 8.5.29 + postcss: 8.5.30 - postcss-modules-local-by-default@4.2.0(postcss@8.5.29): + postcss-modules-local-by-default@4.2.0(postcss@8.5.30): dependencies: - icss-utils: 5.1.0(postcss@8.5.29) - postcss: 8.5.29 + icss-utils: 5.1.0(postcss@8.5.30) + postcss: 8.5.30 postcss-selector-parser: 7.1.6 postcss-value-parser: 4.2.0 - postcss-modules-scope@3.2.1(postcss@8.5.29): + postcss-modules-scope@3.2.1(postcss@8.5.30): dependencies: - postcss: 8.5.29 + postcss: 8.5.30 postcss-selector-parser: 7.1.6 - postcss-modules-values@4.0.0(postcss@8.5.29): + postcss-modules-values@4.0.0(postcss@8.5.30): dependencies: - icss-utils: 5.1.0(postcss@8.5.29) - postcss: 8.5.29 + icss-utils: 5.1.0(postcss@8.5.30) + postcss: 8.5.30 - postcss-safe-parser@7.1.0(postcss@8.5.29): + postcss-safe-parser@7.1.0(postcss@8.5.30): dependencies: - postcss: 8.5.29 + postcss: 8.5.30 postcss-selector-parser@7.1.6: dependencies: @@ -15623,6 +15644,12 @@ snapshots: picocolors: 1.1.1 source-map-js: 1.2.2 + postcss@8.5.30: + dependencies: + nanoid: 3.3.20 + picocolors: 1.1.1 + source-map-js: 1.2.2 + powershell-utils@0.2.1: {} prelude-ls@1.2.1: {} @@ -15691,9 +15718,9 @@ snapshots: punycode@2.3.1: {} - puppeteer-core@25.13.0(bufferutil@4.1.0)(utf-8-validate@6.0.6): + puppeteer-core@25.14.0(bufferutil@4.1.0)(utf-8-validate@6.0.6): dependencies: - '@puppeteer/browsers': 3.2.4 + '@puppeteer/browsers': 3.2.5 chromium-bidi: 157.0.8090-0(devtools-protocol@0.0.1696802) devtools-protocol: 0.0.1696802 typed-query-selector: 2.12.3 @@ -15705,13 +15732,13 @@ snapshots: - utf-8-validate - yauzl - puppeteer@25.13.0(bufferutil@4.1.0)(utf-8-validate@6.0.6): + puppeteer@25.14.0(bufferutil@4.1.0)(utf-8-validate@6.0.6): dependencies: - '@puppeteer/browsers': 3.2.4 + '@puppeteer/browsers': 3.2.5 chromium-bidi: 157.0.8090-0(devtools-protocol@0.0.1696802) devtools-protocol: 0.0.1696802 lilconfig: 3.1.3 - puppeteer-core: 25.13.0(bufferutil@4.1.0)(utf-8-validate@6.0.6) + puppeteer-core: 25.14.0(bufferutil@4.1.0)(utf-8-validate@6.0.6) typed-query-selector: 2.12.3 transitivePeerDependencies: - bufferutil @@ -15880,7 +15907,7 @@ snapshots: adjust-sourcemap-loader: 4.0.0 convert-source-map: 1.9.0 loader-utils: 2.0.4 - postcss: 8.5.29 + postcss: 8.5.30 source-map: 0.6.1 resolve@1.22.13: @@ -15952,12 +15979,12 @@ snapshots: transitivePeerDependencies: - oxc-resolver - rolldown-plugin-dts@0.28.8(rolldown@1.2.13)(typescript@6.0.3): + rolldown-plugin-dts@0.28.8(rolldown@1.2.14)(typescript@6.0.3): dependencies: dts-resolver: 3.0.0 get-tsconfig: 5.0.0-beta.6 obug: 3.0.0 - rolldown: 1.2.13 + rolldown: 1.2.14 yuku-ast: 0.19.0 yuku-codegen: 0.19.0 yuku-parser: 0.19.0 @@ -15987,75 +16014,75 @@ snapshots: '@rolldown/binding-win32-arm64-msvc': 1.2.12 '@rolldown/binding-win32-x64-msvc': 1.2.12 - rolldown@1.2.13: + rolldown@1.2.14: dependencies: - '@oxc-project/types': 0.153.0 + '@oxc-project/types': 0.154.0 '@rolldown/pluginutils': 1.0.1 optionalDependencies: - '@rolldown/binding-android-arm-eabi': 1.2.13 - '@rolldown/binding-android-arm64': 1.2.13 - '@rolldown/binding-darwin-arm64': 1.2.13 - '@rolldown/binding-darwin-x64': 1.2.13 - '@rolldown/binding-freebsd-x64': 1.2.13 - '@rolldown/binding-linux-arm-gnueabihf': 1.2.13 - '@rolldown/binding-linux-arm64-gnu': 1.2.13 - '@rolldown/binding-linux-arm64-musl': 1.2.13 - '@rolldown/binding-linux-ppc64-gnu': 1.2.13 - '@rolldown/binding-linux-s390x-gnu': 1.2.13 - '@rolldown/binding-linux-x64-gnu': 1.2.13 - '@rolldown/binding-linux-x64-musl': 1.2.13 - '@rolldown/binding-openharmony-arm64': 1.2.13 - '@rolldown/binding-win32-arm64-msvc': 1.2.13 - '@rolldown/binding-win32-x64-msvc': 1.2.13 - - rollup-plugin-dts@6.5.1(rollup@4.64.5)(typescript@6.0.3): + '@rolldown/binding-android-arm-eabi': 1.2.14 + '@rolldown/binding-android-arm64': 1.2.14 + '@rolldown/binding-darwin-arm64': 1.2.14 + '@rolldown/binding-darwin-x64': 1.2.14 + '@rolldown/binding-freebsd-x64': 1.2.14 + '@rolldown/binding-linux-arm-gnueabihf': 1.2.14 + '@rolldown/binding-linux-arm64-gnu': 1.2.14 + '@rolldown/binding-linux-arm64-musl': 1.2.14 + '@rolldown/binding-linux-ppc64-gnu': 1.2.14 + '@rolldown/binding-linux-s390x-gnu': 1.2.14 + '@rolldown/binding-linux-x64-gnu': 1.2.14 + '@rolldown/binding-linux-x64-musl': 1.2.14 + '@rolldown/binding-openharmony-arm64': 1.2.14 + '@rolldown/binding-win32-arm64-msvc': 1.2.14 + '@rolldown/binding-win32-x64-msvc': 1.2.14 + + rollup-plugin-dts@6.5.1(rollup@4.64.6)(typescript@6.0.3): dependencies: '@jridgewell/remapping': 2.3.5 '@jridgewell/sourcemap-codec': 1.6.0 convert-source-map: 2.0.0 magic-string: 0.30.21 - rollup: 4.64.5 + rollup: 4.64.6 typescript: 6.0.3 optionalDependencies: '@babel/code-frame': 8.0.6 - rollup-plugin-sourcemaps2@0.5.9(@types/node@22.20.5)(rollup@4.64.5): + rollup-plugin-sourcemaps2@0.5.9(@types/node@22.20.5)(rollup@4.64.6): dependencies: - '@rollup/pluginutils': 5.4.0(rollup@4.64.5) - rollup: 4.64.5 + '@rollup/pluginutils': 5.4.0(rollup@4.64.6) + rollup: 4.64.6 optionalDependencies: '@types/node': 22.20.5 - rollup@4.64.5: + rollup@4.64.6: dependencies: '@types/estree': 1.0.9 optionalDependencies: '@napi-rs/lzma-linux-x64-gnu': 1.5.1 - '@rollup/rollup-android-arm-eabi': 4.64.5 - '@rollup/rollup-android-arm64': 4.64.5 - '@rollup/rollup-darwin-arm64': 4.64.5 - '@rollup/rollup-darwin-x64': 4.64.5 - '@rollup/rollup-freebsd-arm64': 4.64.5 - '@rollup/rollup-freebsd-x64': 4.64.5 - '@rollup/rollup-linux-arm-gnueabihf': 4.64.5 - '@rollup/rollup-linux-arm-musleabihf': 4.64.5 - '@rollup/rollup-linux-arm64-gnu': 4.64.5 - '@rollup/rollup-linux-arm64-musl': 4.64.5 - '@rollup/rollup-linux-loong64-gnu': 4.64.5 - '@rollup/rollup-linux-loong64-musl': 4.64.5 - '@rollup/rollup-linux-ppc64-gnu': 4.64.5 - '@rollup/rollup-linux-ppc64-musl': 4.64.5 - '@rollup/rollup-linux-riscv64-gnu': 4.64.5 - '@rollup/rollup-linux-riscv64-musl': 4.64.5 - '@rollup/rollup-linux-s390x-gnu': 4.64.5 - '@rollup/rollup-linux-x64-gnu': 4.64.5 - '@rollup/rollup-linux-x64-musl': 4.64.5 - '@rollup/rollup-openbsd-x64': 4.64.5 - '@rollup/rollup-openharmony-arm64': 4.64.5 - '@rollup/rollup-win32-arm64-msvc': 4.64.5 - '@rollup/rollup-win32-ia32-msvc': 4.64.5 - '@rollup/rollup-win32-x64-gnu': 4.64.5 - '@rollup/rollup-win32-x64-msvc': 4.64.5 + '@rollup/rollup-android-arm-eabi': 4.64.6 + '@rollup/rollup-android-arm64': 4.64.6 + '@rollup/rollup-darwin-arm64': 4.64.6 + '@rollup/rollup-darwin-x64': 4.64.6 + '@rollup/rollup-freebsd-arm64': 4.64.6 + '@rollup/rollup-freebsd-x64': 4.64.6 + '@rollup/rollup-linux-arm-gnueabihf': 4.64.6 + '@rollup/rollup-linux-arm-musleabihf': 4.64.6 + '@rollup/rollup-linux-arm64-gnu': 4.64.6 + '@rollup/rollup-linux-arm64-musl': 4.64.6 + '@rollup/rollup-linux-loong64-gnu': 4.64.6 + '@rollup/rollup-linux-loong64-musl': 4.64.6 + '@rollup/rollup-linux-ppc64-gnu': 4.64.6 + '@rollup/rollup-linux-ppc64-musl': 4.64.6 + '@rollup/rollup-linux-riscv64-gnu': 4.64.6 + '@rollup/rollup-linux-riscv64-musl': 4.64.6 + '@rollup/rollup-linux-s390x-gnu': 4.64.6 + '@rollup/rollup-linux-x64-gnu': 4.64.6 + '@rollup/rollup-linux-x64-musl': 4.64.6 + '@rollup/rollup-openbsd-x64': 4.64.6 + '@rollup/rollup-openharmony-arm64': 4.64.6 + '@rollup/rollup-win32-arm64-msvc': 4.64.6 + '@rollup/rollup-win32-ia32-msvc': 4.64.6 + '@rollup/rollup-win32-x64-gnu': 4.64.6 + '@rollup/rollup-win32-x64-msvc': 4.64.6 fsevents: 2.3.3 router@2.2.0(supports-color@11.0.0): @@ -16198,11 +16225,11 @@ snapshots: sass-embedded-win32-arm64: 1.105.1 sass-embedded-win32-x64: 1.105.1 - sass-loader@17.0.1(sass-embedded@1.105.1)(sass@1.105.1)(webpack@5.111.1(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.29)(uglify-js@3.19.3)): + sass-loader@17.0.1(sass-embedded@1.105.1)(sass@1.105.1)(webpack@5.111.1(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.30)(uglify-js@3.19.3)): optionalDependencies: sass: 1.105.1 sass-embedded: 1.105.1 - webpack: 5.111.1(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.29)(uglify-js@3.19.3) + webpack: 5.111.1(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.30)(uglify-js@3.19.3) sass@1.105.1: dependencies: @@ -16428,11 +16455,11 @@ snapshots: source-map-js@1.2.2: {} - source-map-loader@5.0.0(webpack@5.111.1(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.29)(uglify-js@3.19.3)): + source-map-loader@5.0.0(webpack@5.111.1(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.30)(uglify-js@3.19.3)): dependencies: iconv-lite: 0.6.3 source-map-js: 1.2.2 - webpack: 5.111.1(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.29)(uglify-js@3.19.3) + webpack: 5.111.1(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.30)(uglify-js@3.19.3) source-map-support@0.5.21: dependencies: @@ -16860,6 +16887,8 @@ snapshots: undici@8.11.2: {} + undici@8.12.1: {} + unicode-canonical-property-names-ecmascript@2.0.1: {} unicode-match-property-ecmascript@2.0.0: @@ -17002,8 +17031,8 @@ snapshots: dependencies: lightningcss: 1.33.0 picomatch: 4.0.7 - postcss: 8.5.29 - rolldown: 1.2.12 + postcss: 8.5.30 + rolldown: 1.2.14 tinyglobby: 0.2.17 optionalDependencies: '@types/node': 22.20.5 @@ -17074,6 +17103,16 @@ snapshots: optionalDependencies: webpack: 5.111.1(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.29)(uglify-js@3.19.3) + webpack-dev-middleware@8.3.0(webpack@5.111.1(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.30)(uglify-js@3.19.3)): + dependencies: + ansi-html-community: 0.0.8 + memfs: 4.80.0 + mime-types: 3.0.2 + range-parser: 1.3.0 + schema-utils: 4.5.0 + optionalDependencies: + webpack: 5.111.1(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.30)(uglify-js@3.19.3) + webpack-dev-server@6.0.0(bufferutil@4.1.0)(supports-color@11.0.0)(utf-8-validate@6.0.6)(webpack@5.111.1(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.29)(uglify-js@3.19.3)): dependencies: '@types/bonjour': 3.5.13 @@ -17108,6 +17147,40 @@ snapshots: - supports-color - utf-8-validate + webpack-dev-server@6.0.0(bufferutil@4.1.0)(supports-color@11.0.0)(utf-8-validate@6.0.6)(webpack@5.111.1(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.30)(uglify-js@3.19.3)): + dependencies: + '@types/bonjour': 3.5.13 + '@types/connect-history-api-fallback': 1.5.4 + '@types/express': 5.0.6 + '@types/express-serve-static-core': 5.1.3 + '@types/serve-index': 1.9.4 + '@types/serve-static': 2.2.0 + '@types/ws': 8.18.2 + ansi-html-community: 0.0.8 + bonjour-service: 1.4.4 + chokidar: 5.0.0 + compression: 1.8.2(supports-color@11.0.0) + connect-history-api-fallback: 2.0.0 + express: 5.2.1(supports-color@11.0.0) + graceful-fs: 4.2.11 + http-proxy-middleware: 4.2.0(supports-color@11.0.0) + ipaddr.js: 2.5.0 + launch-editor: 2.14.2 + open: 11.0.4 + p-retry: 8.0.1 + schema-utils: 4.5.0 + selfsigned: 5.5.0 + serve-index: 1.9.2(supports-color@11.0.0) + tinyglobby: 0.2.17 + webpack-dev-middleware: 8.3.0(webpack@5.111.1(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.30)(uglify-js@3.19.3)) + ws: 8.22.0(bufferutil@4.1.0)(utf-8-validate@6.0.6) + optionalDependencies: + webpack: 5.111.1(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.30)(uglify-js@3.19.3) + transitivePeerDependencies: + - bufferutil + - supports-color + - utf-8-validate + webpack-merge@6.0.1: dependencies: clone-deep: 4.0.1 @@ -17116,10 +17189,10 @@ snapshots: webpack-sources@3.6.0: {} - webpack-subresource-integrity@5.1.0(webpack@5.111.1(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.29)(uglify-js@3.19.3)): + webpack-subresource-integrity@5.1.0(webpack@5.111.1(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.30)(uglify-js@3.19.3)): dependencies: typed-assert: 1.0.9 - webpack: 5.111.1(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.29)(uglify-js@3.19.3) + webpack: 5.111.1(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.30)(uglify-js@3.19.3) webpack@5.111.1(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.29)(uglify-js@3.19.3): dependencies: @@ -17158,6 +17231,43 @@ snapshots: - svgo - uglify-js + webpack@5.111.1(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.30)(uglify-js@3.19.3): + dependencies: + '@types/estree': 1.0.9 + '@types/json-schema': 7.0.15 + '@webassemblyjs/ast': 1.14.1 + '@webassemblyjs/wasm-edit': 1.14.1 + '@webassemblyjs/wasm-parser': 1.14.1 + browserslist: 4.29.3 + chrome-trace-event: 1.0.4 + enhanced-resolve: 5.26.0 + es-module-lexer: 2.3.2 + events: 3.3.0 + graceful-fs: 4.2.11 + mime-db: 1.54.0 + minimizer-webpack-plugin: 5.13.0(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.30)(uglify-js@3.19.3)(webpack@5.111.1(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.30)(uglify-js@3.19.3)) + schema-utils: 4.5.0 + tapable: 2.3.3 + watchpack: 2.5.2 + webpack-sources: 3.6.0 + transitivePeerDependencies: + - '@minify-html/node' + - '@napi-rs/image' + - '@swc/core' + - '@swc/css' + - '@swc/html' + - clean-css + - cssnano + - csso + - esbuild + - html-minifier-terser + - imagemin + - lightningcss + - postcss + - sharp + - svgo + - uglify-js + websocket-driver@0.7.5: dependencies: http-parser-js: 0.5.10 From 93f238c9781897997b1c64d607f3bb3c91ba1fd1 Mon Sep 17 00:00:00 2001 From: Alan Agius <17563226+alan-agius4@users.noreply.github.com> Date: Thu, 15 Oct 2026 10:58:56 +0000 Subject: [PATCH 628/787] fix(@angular/build): rebuild library when transitive stylesheet dependencies change in watch mode Track transitive stylesheet resource references per containing component and stylesheet file in `BuilderState.addFileReferences`, and resolve affected files via `BuilderState.getAffectedFiles` during watch mode rebuilds. Previously, modifying a Sass partial imported by an inline component stylesheet did not invalidate the containing component file or reset the Sass worker pool cache. --- .../src/builders/library/builder-state.ts | 97 ++++++++++++++++++- .../builders/library/builder-state_spec.ts | 52 ++++++++++ .../build/src/builders/library/builder.ts | 27 ++---- .../builders/library/pipeline/compilation.ts | 21 ++-- .../library/tests/behavior/watch_spec.ts | 48 +++++++++ 5 files changed, 213 insertions(+), 32 deletions(-) diff --git a/packages/angular/build/src/builders/library/builder-state.ts b/packages/angular/build/src/builders/library/builder-state.ts index c20ef26ea7c5..81b4e21e778d 100644 --- a/packages/angular/build/src/builders/library/builder-state.ts +++ b/packages/angular/build/src/builders/library/builder-state.ts @@ -6,6 +6,7 @@ * found in the LICENSE file at https://angular.dev/license */ +import { toPosixPath } from '../../utils/path'; import { ExecutionResult } from './execution-result'; import type { BundleResult, @@ -15,10 +16,12 @@ import type { } from './types'; /** - * Encapsulates incremental compilation state, watched compilation file tracking, - * and execution results across watch-mode rebuilds. + * Encapsulates incremental compilation state, transitive resource reference tracking, + * watched compilation file tracking, and execution results across watch-mode rebuilds. */ export class BuilderState { + readonly #referencingFiles = new Map>(); + readonly #referencedByFile = new Map>(); readonly #watchedCompilationFiles = new Set(); readonly #pendingCompilationFiles = new Set(); @@ -116,6 +119,94 @@ export class BuilderState { return this.#executionResult; } + /** + * Records transitive resource dependencies (such as Sass partials) for a containing + * component or stylesheet file and registers them in `watchedCompilationFiles`. + * Multiple calls for the same containing file accumulate references additively. + * + * @param containingFile Path of the referencing component or stylesheet file. + * @param referencedFiles Paths of the referenced files. + */ + addFileReferences(containingFile: string, referencedFiles: Iterable): void { + const posixContainingFile = toPosixPath(containingFile); + let forwardReferences = this.#referencedByFile.get(posixContainingFile); + + for (const file of referencedFiles) { + const posixFile = toPosixPath(file); + this.#watchedCompilationFiles.add(posixFile); + if (posixFile === posixContainingFile) { + continue; + } + + if (!forwardReferences) { + forwardReferences = new Set(); + this.#referencedByFile.set(posixContainingFile, forwardReferences); + } + forwardReferences.add(posixFile); + + let referencing = this.#referencingFiles.get(posixFile); + if (!referencing) { + referencing = new Set(); + this.#referencingFiles.set(posixFile, referencing); + } + referencing.add(posixContainingFile); + } + } + + /** + * Clears previously recorded outgoing resource references for the given containing files + * before they are recompiled. + * + * @param containingFiles Paths of the containing or stylesheet files being recompiled. + */ + clearFileReferences(containingFiles: Iterable): void { + for (const containingFile of containingFiles) { + const posixContainingFile = toPosixPath(containingFile); + const forwardReferences = this.#referencedByFile.get(posixContainingFile); + if (!forwardReferences) { + continue; + } + + for (const prevRef of forwardReferences) { + const referencing = this.#referencingFiles.get(prevRef); + if (referencing) { + referencing.delete(posixContainingFile); + if (referencing.size === 0) { + this.#referencingFiles.delete(prevRef); + } + } + } + + this.#referencedByFile.delete(posixContainingFile); + } + } + + /** + * Returns the set of all files affected by the given changed files, including the + * changed files themselves and all transitively referencing files + * (e.g., partial `.scss` -> component `.scss` -> component `.ts`). + * + * @param files Initial changed file paths. + * @returns Set of POSIX paths including all transitively referencing files. + */ + getAffectedFiles(files: Iterable): Set { + const affected = new Set(); + for (const file of files) { + affected.add(toPosixPath(file)); + } + + for (const file of affected) { + const referencing = this.#referencingFiles.get(file); + if (referencing) { + for (const refFile of referencing) { + affected.add(refFile); + } + } + } + + return affected; + } + /** * Determines whether compilation and bundling need to run for the current build iteration. * Also records incoming modified files so they are retained if the iteration aborts early. @@ -235,6 +326,8 @@ export class BuilderState { this.pendingChangedEsmFiles.clear(); this.pendingChangedDtsFiles.clear(); this.#pendingCompilationFiles.clear(); + this.#referencingFiles.clear(); + this.#referencedByFile.clear(); this.#watchedCompilationFiles.clear(); } } diff --git a/packages/angular/build/src/builders/library/builder-state_spec.ts b/packages/angular/build/src/builders/library/builder-state_spec.ts index 9cf744d288bc..ae84bbaa7331 100644 --- a/packages/angular/build/src/builders/library/builder-state_spec.ts +++ b/packages/angular/build/src/builders/library/builder-state_spec.ts @@ -70,6 +70,58 @@ describe('BuilderState', () => { }); }); + describe('file reference tracking', () => { + it('should expand transitive multi-hop references and ignore self-references', () => { + const state = new BuilderState(); + const compTs = '/workspace/projects/my-lib/src/lib/comp.ts'; + const compScss = '/workspace/projects/my-lib/src/lib/comp.scss'; + const varsScss = '/workspace/projects/my-lib/src/lib/_vars.scss'; + + state.addFileReferences(compTs, [compTs, compScss, varsScss]); + state.addFileReferences(compScss, [compScss, varsScss]); + + expect(state.watchedCompilationFiles.has(compTs)).toBeTrue(); + expect(state.watchedCompilationFiles.has(compScss)).toBeTrue(); + expect(state.watchedCompilationFiles.has(varsScss)).toBeTrue(); + + const affected = state.getAffectedFiles([varsScss]); + expect(affected).toEqual(new Set([varsScss, compTs, compScss])); + + // Subsequent getAffectedFiles calls preserve mappings when not yet overwritten + const affectedAgain = state.getAffectedFiles([varsScss]); + expect(affectedAgain).toEqual(new Set([varsScss, compTs, compScss])); + }); + + it('should accumulate references across multiple stylesheets for the same containing file', () => { + const state = new BuilderState(); + const compTs = '/workspace/projects/my-lib/src/lib/comp.ts'; + const firstPartial = '/workspace/projects/my-lib/src/lib/_first.scss'; + const secondPartial = '/workspace/projects/my-lib/src/lib/_second.scss'; + + state.addFileReferences(compTs, [compTs, firstPartial]); + state.addFileReferences(compTs, [compTs, secondPartial]); + + expect(state.getAffectedFiles([firstPartial])).toEqual(new Set([firstPartial, compTs])); + expect(state.getAffectedFiles([secondPartial])).toEqual(new Set([secondPartial, compTs])); + }); + + it('should prune stale references when a containing file is cleared and re-recorded', () => { + const state = new BuilderState(); + const compTs = '/workspace/projects/my-lib/src/lib/comp.ts'; + const oldPartial = '/workspace/projects/my-lib/src/lib/_old.scss'; + const newPartial = '/workspace/projects/my-lib/src/lib/_new.scss'; + + state.addFileReferences(compTs, [compTs, oldPartial]); + expect(state.getAffectedFiles([oldPartial])).toEqual(new Set([oldPartial, compTs])); + + // Clear and re-record references for compTs without oldPartial + state.clearFileReferences([compTs]); + state.addFileReferences(compTs, [compTs, newPartial]); + expect(state.getAffectedFiles([oldPartial])).toEqual(new Set([oldPartial])); + expect(state.getAffectedFiles([newPartial])).toEqual(new Set([newPartial, compTs])); + }); + }); + describe('shouldCompileEntryPoints & getCompilationModifiedFiles', () => { it('should preserve pending compilation files across aborted iterations', () => { const state = new BuilderState({ diff --git a/packages/angular/build/src/builders/library/builder.ts b/packages/angular/build/src/builders/library/builder.ts index fa8e717c9776..42be7f99b211 100644 --- a/packages/angular/build/src/builders/library/builder.ts +++ b/packages/angular/build/src/builders/library/builder.ts @@ -261,29 +261,14 @@ async function* runWatchLoop( console.clear(); } - const changedFiles = new Set(); - let hasStyleChanges = false; - let hasSassChanges = false; - for (const file of changes.all) { - const posixFile = toPosixPath(file); - changedFiles.add(posixFile); - if (/\.(?:scss|sass)$/i.test(posixFile)) { - hasStyleChanges = true; - hasSassChanges = true; - } else if (/\.(?:less|css)$/i.test(posixFile)) { - hasStyleChanges = true; - } - } + const rawChangedFiles = changes.all.map(toPosixPath); + stylesheetBundler.invalidate(rawChangedFiles); + const changedFiles = buildState.getAffectedFiles(rawChangedFiles); - if (hasStyleChanges) { - if (hasSassChanges) { + for (const posixFile of changedFiles) { + if (/\.(?:scss|sass)$/i.test(posixFile)) { resetSassWorkerPoolCaches(); - } - const invalidatedStyles = stylesheetBundler.invalidate(changedFiles); - if (invalidatedStyles) { - for (const styleFile of invalidatedStyles) { - changedFiles.add(toPosixPath(styleFile)); - } + break; } } diff --git a/packages/angular/build/src/builders/library/pipeline/compilation.ts b/packages/angular/build/src/builders/library/pipeline/compilation.ts index 38b28f442df6..1c026c5e9fec 100644 --- a/packages/angular/build/src/builders/library/pipeline/compilation.ts +++ b/packages/angular/build/src/builders/library/pipeline/compilation.ts @@ -26,7 +26,7 @@ const EMITTED_EXTENSIONS = ['.js', '.mjs', '.cjs', '.d.ts', '.d.mts', '.d.cts']; * * @param options The normalized library builder options with POSIX paths. * @param stylesheetBundler The component stylesheet bundler instance. - * @param buildState The build state tracking compilation caches and diagnostics. + * @param buildState The build state tracking compilation caches, file references, and diagnostics. * @param modifiedFiles Optional set of modified POSIX file paths for incremental compilation. * @returns A promise resolving to the compilation output containing emitted files and cache state. */ @@ -70,9 +70,9 @@ export async function compileLibrary( if (effectiveModifiedFiles && effectiveModifiedFiles.size > 0) { await compilationInstance.update?.(effectiveModifiedFiles); + buildState.clearFileReferences(effectiveModifiedFiles); } - const allReferencedFiles = new Set(); const stylesheetWarnings: PartialMessage[] = []; const stylesheetErrors: PartialMessage[] = []; const failedFiles = new Set(); @@ -88,7 +88,13 @@ export async function compileLibrary( ? await stylesheetBundler.bundleFile(stylesheetFile) : await stylesheetBundler.bundleInline(data, containingFile); - result.referencedFiles?.forEach((f) => allReferencedFiles.add(toPosixPath(f))); + if (result.referencedFiles) { + buildState.addFileReferences(containingFile, result.referencedFiles); + if (stylesheetFile) { + buildState.addFileReferences(stylesheetFile, result.referencedFiles); + } + } + if (result.warnings.length > 0) { stylesheetWarnings.push(...result.warnings); } @@ -137,14 +143,11 @@ export async function compileLibrary( const dtsFiles = cached?.dtsFiles ?? new Map(); const changedEsmFiles = new Set(); const changedDtsFiles = new Set(); - - for (const ref of referencedFiles) { - allReferencedFiles.add(toPosixPath(ref)); - } + const posixReferencedFiles = new Set(referencedFiles.map(toPosixPath)); if (cached && effectiveModifiedFiles) { for (const modifiedFile of effectiveModifiedFiles) { - if (allReferencedFiles.has(modifiedFile)) { + if (posixReferencedFiles.has(modifiedFile)) { continue; } @@ -187,7 +190,7 @@ export async function compileLibrary( dtsFiles, changedEsmFiles, changedDtsFiles, - referencedFiles: allReferencedFiles, + referencedFiles: posixReferencedFiles, cache: { compilationInstance, esmFiles, diff --git a/packages/angular/build/src/builders/library/tests/behavior/watch_spec.ts b/packages/angular/build/src/builders/library/tests/behavior/watch_spec.ts index 415f24d269c0..e9b7e57ddd9f 100644 --- a/packages/angular/build/src/builders/library/tests/behavior/watch_spec.ts +++ b/packages/angular/build/src/builders/library/tests/behavior/watch_spec.ts @@ -8,6 +8,7 @@ import { rm } from 'node:fs/promises'; import { executeLibraryBuilder } from '../../builder'; +import { InlineStyleLanguage } from '../../schema'; import { BASE_OPTIONS, LIBRARY_BUILDER_INFO, describeLibraryBuilder } from '../setup'; describeLibraryBuilder(executeLibraryBuilder, LIBRARY_BUILDER_INFO, (harness) => { @@ -601,5 +602,52 @@ describeLibraryBuilder(executeLibraryBuilder, LIBRARY_BUILDER_INFO, (harness) => }, ]); }); + + it('should rebuild when a Sass partial imported by an inline component stylesheet is modified in watch mode', async () => { + await harness.writeFiles({ + 'projects/lib/src/lib/_vars.scss': '$primary-color: rgb(10, 20, 30);', + 'projects/lib/src/lib/_spacing.scss': '$pad: 12px;', + 'projects/lib/src/lib/lib.component.ts': ` + import { Component } from '@angular/core'; + + @Component({ + selector: 'lib-inline-sass', + template: 'Inline Sass', + styles: [ + '@use "./vars"; :host { color: vars.$primary-color; }', + '@use "./spacing"; :host { padding: spacing.$pad; }', + ], + }) + export class LibComponent {} + `, + }); + + harness.useTarget('build', { + ...BASE_OPTIONS, + inlineStyleLanguage: InlineStyleLanguage.Scss, + watch: true, + }); + + await harness.executeWithCases([ + async ({ result }) => { + expect(result?.success).toBeTrue(); + const content = harness.readFile('dist/lib/fesm2022/lib.mjs'); + expect(content).toMatch(/color:\s*(?:#0a141e|rgb\(10,\s*20,\s*30\))/); + expect(content).toMatch(/padding:\s*12px/); + + // Modify the Sass partial referenced by the first inline component style + await harness.writeFile( + 'projects/lib/src/lib/_vars.scss', + '$primary-color: rgb(200, 100, 50);', + ); + }, + ({ result }) => { + expect(result?.success).toBeTrue(); + const content = harness.readFile('dist/lib/fesm2022/lib.mjs'); + expect(content).toMatch(/color:\s*(?:#c86432|rgb\(200,\s*100,\s*50\))/); + expect(content).toMatch(/padding:\s*12px/); + }, + ]); + }); }); }); From 554c1eb801ca9b83877eaf03cba9f2a0e5ffe178 Mon Sep 17 00:00:00 2001 From: Doug Parker Date: Thu, 15 Oct 2026 11:33:25 -0700 Subject: [PATCH 629/787] docs: release notes for the v22.2.3 release --- CHANGELOG.md | 49 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 49 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index ce91a1e74158..367c576b8b99 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,52 @@ + + +# 22.2.3 (2026-10-15) + +### @angular/cli + +| Commit | Type | Description | +| --------------------------------------------------------------------------------------------------- | ---- | ----------------------------------------------------------------- | +| [3158e865f](https://github.com/angular/angular-cli/commit/3158e865ffdd828711d645dff16cc17fd26bb58e) | fix | accept multi-digit array indices in ng config | +| [bcff0e76a](https://github.com/angular/angular-cli/commit/bcff0e76adf73cfa32b02c5256490189675cb132) | fix | keep ng version working when the package manager is not installed | +| [5570c91d2](https://github.com/angular/angular-cli/commit/5570c91d2f38764cd841fcce146f1d13fef49b0c) | fix | resolve package name in npm workspace members | + +### @schematics/angular + +| Commit | Type | Description | +| --------------------------------------------------------------------------------------------------- | ---- | ------------------------------------------------------------------------- | +| [881865f36](https://github.com/angular/angular-cli/commit/881865f364b33b36630aa6ab7a129f7ed665cfa7) | fix | keep the workspace build version in the use-application-builder migration | + +### @angular-devkit/schematics + +| Commit | Type | Description | +| --------------------------------------------------------------------------------------------------- | ---- | --------------------------------------------- | +| [cf1f3b9d4](https://github.com/angular/angular-cli/commit/cf1f3b9d43177e15cf9a00973e6da3baeaf4b2dd) | fix | avoid stack overflow when chaining many rules | + +### @angular/build + +| Commit | Type | Description | +| --------------------------------------------------------------------------------------------------- | ---- | ------------------------------------------------------------------- | +| [1d477d6bc](https://github.com/angular/angular-cli/commit/1d477d6bc27159cb0c78288e047fcadfe6fc31d4) | fix | add CSP nonce to stylesheet and modulepreload link elements | +| [fbe208f83](https://github.com/angular/angular-cli/commit/fbe208f8392ec0ce82d597e8b690f146370bdc81) | fix | always use AOT when extracting i18n messages | +| [c1c4216a6](https://github.com/angular/angular-cli/commit/c1c4216a680891b80670660a621d6736c4aecaf0) | fix | coalesce external watcher directories to avoid macOS FSEvents limit | +| [792990bc2](https://github.com/angular/angular-cli/commit/792990bc2eacdcc8ed4de6ef46e58ceeb5fe8741) | fix | disable Vitest fsModuleCache in unit-test builder | +| [82439399c](https://github.com/angular/angular-cli/commit/82439399cbfb4c1d21d1c80d976021efa9e4a39a) | fix | ensure Sass importers return global Promise instances | +| [a818de415](https://github.com/angular/angular-cli/commit/a818de415e933819e7a2e3e679cd0b2d2be734de) | fix | keep Vite server file watcher disabled in Vitest watch mode | +| [91bad469e](https://github.com/angular/angular-cli/commit/91bad469ec5ce7b2dfd07e394b482d2cef411407) | fix | sort discovered unit-test files for deterministic builds | +| [e84db4af7](https://github.com/angular/angular-cli/commit/e84db4af70ca9be490b462e6d8112524dc8eb6d4) | fix | use module.registerHooks() for in-memory ESM loader | +| [a428021b7](https://github.com/angular/angular-cli/commit/a428021b77dbccf404f39712f1c88bed9b8e4272) | perf | avoid invalidating Angular diagnostic cache on stylesheet change | +| [b0ac394a0](https://github.com/angular/angular-cli/commit/b0ac394a063f084d885df67660224b6a25e2c614) | perf | resolve asset patterns concurrently with bounded concurrency | + +### @angular/ssr + +| Commit | Type | Description | +| --------------------------------------------------------------------------------------------------- | ---- | ------------------------------------------------------ | +| [bd09b98fc](https://github.com/angular/angular-cli/commit/bd09b98fcaff4b76c7fd65999b51bfaa942d1858) | fix | preserve preload metadata for nested empty-path routes | +| [a92546892](https://github.com/angular/angular-cli/commit/a925468929c74c30a3e64b361a6dc5d6fdc1006a) | fix | preserve query parameters on relative route redirects | +| [a2b86cc94](https://github.com/angular/angular-cli/commit/a2b86cc94d408ba4c3d422224b58e26b7a68f692) | fix | resolve relative redirects against the parent route | + + + # 21.2.27 (2026-10-14) From 00c25090960adfea437997a8e3cdec17634bf9eb Mon Sep 17 00:00:00 2001 From: Doug Parker Date: Thu, 15 Oct 2026 12:01:18 -0700 Subject: [PATCH 630/787] release: cut the v22.3.0-next.2 release --- CHANGELOG.md | 59 ++++++++++++++++++++++++++++++++++++++++++++++++++++ package.json | 2 +- 2 files changed, 60 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 367c576b8b99..a3c4fa9dd66e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,62 @@ + + +# 22.3.0-next.2 (2026-10-15) + +### @angular/cli + +| Commit | Type | Description | +| --------------------------------------------------------------------------------------------------- | ---- | ----------------------------------------------------------------- | +| [5c656152e](https://github.com/angular/angular-cli/commit/5c656152ef91e2731155f6027a845d8014b53e4f) | fix | accept multi-digit array indices in ng config | +| [2e0f48e3f](https://github.com/angular/angular-cli/commit/2e0f48e3ff40289725d3590fa8e1fc059fbaeb88) | fix | keep ng version working when the package manager is not installed | +| [a1cf33bc4](https://github.com/angular/angular-cli/commit/a1cf33bc45882fb74578cc7d1faeba8cecec7b73) | fix | resolve package name in npm workspace members | + +### @schematics/angular + +| Commit | Type | Description | +| --------------------------------------------------------------------------------------------------- | ---- | ------------------------------------------------------------------------- | +| [639d31f11](https://github.com/angular/angular-cli/commit/639d31f11b102a12776ae8dce6369d6edd1b6ff3) | feat | add use-library-builder migration to migrate from ng-packagr | +| [445cc767e](https://github.com/angular/angular-cli/commit/445cc767e62b72631dd53c0c5324b458fee76608) | fix | keep the workspace build version in the use-application-builder migration | + +### @angular-devkit/schematics + +| Commit | Type | Description | +| --------------------------------------------------------------------------------------------------- | ---- | --------------------------------------------- | +| [b39a5fcda](https://github.com/angular/angular-cli/commit/b39a5fcdac288e317f3b00468c09173a1d306f98) | fix | avoid stack overflow when chaining many rules | + +### @angular/build + +| Commit | Type | Description | +| --------------------------------------------------------------------------------------------------- | ---- | --------------------------------------------------------------------------------- | +| [b975da4b0](https://github.com/angular/angular-cli/commit/b975da4b016eaa107acc259eb8205135d9396f95) | fix | add CSP nonce to stylesheet and modulepreload link elements | +| [13923047f](https://github.com/angular/angular-cli/commit/13923047f64b6e1063f7f07029c70295b5c99d69) | fix | always use AOT when extracting i18n messages | +| [d2233e225](https://github.com/angular/angular-cli/commit/d2233e225aa5fd507e3ce7bfd35ae2268c036aa4) | fix | coalesce external watcher directories to avoid macOS FSEvents limit | +| [23d42fc80](https://github.com/angular/angular-cli/commit/23d42fc806f174c7da961c35e07a42aa1e00d1e7) | fix | conditionally declare tslib in built library package | +| [f0a74e8f0](https://github.com/angular/angular-cli/commit/f0a74e8f0ea04fd3f839be0120346067440b1350) | fix | disable Vitest fsModuleCache in unit-test builder | +| [2c518a6db](https://github.com/angular/angular-cli/commit/2c518a6dbe8734d247dfe4eb2c1c4af5e169fa94) | fix | enhance build logs and output location for library builder | +| [47c328d3e](https://github.com/angular/angular-cli/commit/47c328d3ef7b409af02f270a48f5e99a520fbe14) | fix | ensure Sass importers return global Promise instances | +| [432aea016](https://github.com/angular/angular-cli/commit/432aea0161840bc135704c040108e46092e61c27) | fix | filter Rolldown warnings and disable .d.ts annotation comments in library builder | +| [39d230e18](https://github.com/angular/angular-cli/commit/39d230e1862f2f626d3fba03bbf51873f3578153) | fix | keep Vite server file watcher disabled in Vitest watch mode | +| [93f238c97](https://github.com/angular/angular-cli/commit/93f238c9781897997b1c64d607f3bb3c91ba1fd1) | fix | rebuild library when transitive stylesheet dependencies change in watch mode | +| [7714a8537](https://github.com/angular/angular-cli/commit/7714a8537589afc6180443cc36acd5149a459c57) | fix | resolve unimported NgModule scopes when filtering unit-test files | +| [ad4845583](https://github.com/angular/angular-cli/commit/ad4845583b8d1b8de26ccc0e45b4e6e58d95b362) | fix | respect tsconfig declarationMap and compilationMode in library builder | +| [01afbf418](https://github.com/angular/angular-cli/commit/01afbf418cf6a7688f3f131988eeba3cdac2bde4) | fix | sort discovered unit-test files for deterministic builds | +| [b640b32e1](https://github.com/angular/angular-cli/commit/b640b32e148ab68f820b390b1d9f03ae9a809266) | fix | use module.registerHooks() for in-memory ESM loader | +| [0a077eeed](https://github.com/angular/angular-cli/commit/0a077eeed92b43fa195bf10f479d39a7aca2d3f7) | perf | avoid invalidating Angular diagnostic cache on stylesheet change | +| [2b5a9a620](https://github.com/angular/angular-cli/commit/2b5a9a620495b4c85bf5cfa3db39b632d88e6ca5) | perf | enable TypeScript incremental build cache in library builder | +| [07845f019](https://github.com/angular/angular-cli/commit/07845f019cf7d70c17f037d711b430a776f96031) | perf | optimize incremental watch rebuilds in AOT compilation | +| [fb7efc862](https://github.com/angular/angular-cli/commit/fb7efc86228164330f68ed86801f9d5bbe9ad5b0) | perf | resolve asset patterns concurrently with bounded concurrency | +| [dcf906a62](https://github.com/angular/angular-cli/commit/dcf906a6261a00f95cfbdb18cf9065e1c966e182) | perf | reuse extendedConfigCache in TypeScript compilation | + +### @angular/ssr + +| Commit | Type | Description | +| --------------------------------------------------------------------------------------------------- | ---- | ------------------------------------------------------ | +| [0b9a52cc9](https://github.com/angular/angular-cli/commit/0b9a52cc9516d28afa0d9ef0d07ec745967faf56) | fix | preserve preload metadata for nested empty-path routes | +| [f2cd8c8cf](https://github.com/angular/angular-cli/commit/f2cd8c8cf7c5aa7e7076c87e9c0c55b3bf880f4b) | fix | preserve query parameters on relative route redirects | +| [b3bbada1e](https://github.com/angular/angular-cli/commit/b3bbada1efd0d3a414cce8843b7284e9560f66fc) | fix | resolve relative redirects against the parent route | + + + # 22.2.3 (2026-10-15) diff --git a/package.json b/package.json index 9bc88e433859..911eea20e9f6 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@angular/devkit-repo", - "version": "22.3.0-next.1", + "version": "22.3.0-next.2", "private": true, "description": "Software Development Kit for Angular", "keywords": [ From 972302ac3dc7b675e4b36dac465b876014a02b1e Mon Sep 17 00:00:00 2001 From: Charles Lyding <19598772+clydin@users.noreply.github.com> Date: Thu, 15 Oct 2026 12:05:58 -0400 Subject: [PATCH 631/787] fix(@angular/build): watch only explicitly added paths in chokidar watcher When preserveSymlinks or polling is enabled, the build watcher falls back to Chokidar. Previously, createChokidarWatcher initialized Chokidar on the entire workspace root directory and expanded any watched file inside node_modules to its full package root directory via ChokidarNodeModulesManager. Because Chokidar v5 recursively walks watched directories and attaches individual fs.watch handles to every subdirectory and file, projects with many workspace subdirectories or large imported packages could exceed the macOS per-process directory watch limit and crash with an unhandled EMFILE error. This change initializes Chokidar with an empty watch set and registers only the specific paths passed to add() and remove(), eliminating recursive directory scans across the workspace root and node_modules packages. When a directory is explicitly watched (such as when NG_BUILD_WATCH_ROOT is enabled), node_modules subdirectories are pruned unless directly added to the watch set. An error listener is also attached to prevent unhandled watcher errors from terminating the process, and removed files that remain in the watch set are re-registered so subsequent file recreation is detected across multiple watched directories. Closes #34312 --- packages/angular/build/src/utils/watcher.ts | 299 +++++++++--------- .../angular/build/src/utils/watcher_spec.ts | 96 +++++- 2 files changed, 242 insertions(+), 153 deletions(-) diff --git a/packages/angular/build/src/utils/watcher.ts b/packages/angular/build/src/utils/watcher.ts index ca0e86f987ff..fd865ee80b56 100644 --- a/packages/angular/build/src/utils/watcher.ts +++ b/packages/angular/build/src/utils/watcher.ts @@ -8,7 +8,6 @@ import type * as ParcelWatcher from '@parcel/watcher'; import type * as Chokidar from 'chokidar'; -import { once } from 'node:events'; import * as fs from 'node:fs'; import * as path from 'node:path'; import picomatch from 'picomatch'; @@ -1086,92 +1085,94 @@ async function createParcelWatcher( return buildWatcher; } -/** - * Manages selective node_modules watching for Chokidar. - * - * During Chokidar's initial scan, the allowed packages set is empty, causing Chokidar to prune the entire - * node_modules directory immediately and avoid blocking the 'ready' event for minutes. - * Packages are dynamically allowed and watched at the package root level as files are added via `watcher.add`. - * Tracking files per package allows reference-counting so that package directories are unwatched when no - * longer needed. - */ -class ChokidarNodeModulesManager { - private readonly allowedPackages = new Map>(); - - constructor(private readonly isCaseSensitive: boolean) {} - - registerPackage( - posixPath: string, - lookupKey: string, - ): { isPackage: boolean; newPkgDir?: string } { - const packageDir = extractNodeModulesPackageDir(posixPath); - if (!packageDir) { - return { isPackage: false }; - } - - const packageKey = toLookupKey(packageDir, this.isCaseSensitive); - let watchedInPkg = this.allowedPackages.get(packageKey); - if (!watchedInPkg) { - watchedInPkg = new Set(); - this.allowedPackages.set(packageKey, watchedInPkg); - watchedInPkg.add(lookupKey); - - return { isPackage: true, newPkgDir: packageDir }; - } - - watchedInPkg.add(lookupKey); +function createChokidarIgnored( + ignoredPatterns: string[] | undefined, + isCaseSensitive: boolean, + watchedFiles: ReadonlySet, +): Chokidar.Matcher[] { + // Strip static node_modules ignore patterns (e.g. `**/node_modules/**` from setupWatcher). + // If left in place, picomatch would unconditionally ignore all node_modules files and prevent + // watching explicitly added files inside node_modules. + const customIgnored = + ignoredPatterns + ?.filter((pattern) => { + const base = toPosixPathNormalized(pattern).replace(/\/\*\*$/, ''); - return { isPackage: true }; - } + return base !== NODE_MODULES && !base.endsWith(`/${NODE_MODULES}`); + }) + .map((pattern) => { + if (/[*?[\]{}()]/.test(pattern)) { + const isMatch = picomatch(pattern, { dot: true }); - removePackageFile( - posixPath: string, - lookupKey: string, - ): { isPackage: boolean; unwatchPkgDir?: string } { - const packageDir = extractNodeModulesPackageDir(posixPath); - if (!packageDir) { - return { isPackage: false }; - } + return (filePath: string) => isMatch(toPosixPathNormalized(filePath)); + } - const packageKey = toLookupKey(packageDir, this.isCaseSensitive); - const watchedInPkg = this.allowedPackages.get(packageKey); - if (watchedInPkg) { - watchedInPkg.delete(lookupKey); - if (watchedInPkg.size === 0) { - this.allowedPackages.delete(packageKey); + return { path: toPosixPathNormalized(pattern), recursive: true }; + }) ?? []; - return { isPackage: true, unwatchPkgDir: packageDir }; + // When watching a directory (e.g. projectRoot via NG_BUILD_WATCH_ROOT), prune `node_modules` + // directories unless explicitly added to `watchedFiles`. Explicitly added files inside + // `node_modules` do not end with `/node_modules` and remain watchable. + return [ + ...customIgnored, + (filePath: string) => { + if (!filePath.includes(NODE_MODULES)) { + return false; } - } - - return { isPackage: true }; - } - - isIgnored(filePath: string): boolean { - // Fast path: avoid expensive normalization for non-node_modules files - if (!filePath.includes(NODE_MODULES)) { - return false; - } - const posixPath = toPosixPathNormalized(filePath); - const lookupKey = toLookupKey(posixPath, this.isCaseSensitive); + const posixPath = toPosixPathNormalized(filePath); + const lookupKey = toLookupKey(posixPath, isCaseSensitive); - if (!`${lookupKey}/`.includes(NODE_MODULES_SEGMENT)) { - return false; - } + return ( + (lookupKey === NODE_MODULES || lookupKey.endsWith(`/${NODE_MODULES}`)) && + !watchedFiles.has(lookupKey) + ); + }, + ]; +} - if (this.allowedPackages.has(lookupKey)) { - return false; - } +interface ChokidarBaselineEntry { + posixPath: string; + mtimeMs?: number; + size?: number; +} - for (const pkg of this.allowedPackages.keys()) { - if (isPathInside(lookupKey, pkg)) { - return false; +// Chokidar initializes file watchers asynchronously (`await stat(path)` followed by +// `fs.watch` or `fs.watchFile`). If a file is modified or recreated immediately after +// `watcher.add()` is called, Chokidar may capture the post-modification state as its initial +// baseline (or suppress the initial `'add'` event due to `ignoreInitial: true`) and miss the +// change. Re-statting after a short delay catches any modifications or recreations that occurred +// during asynchronous watcher registration, while `fileStats` deduplicates if Chokidar also fired. +async function checkChokidarBaselines( + baselineStats: ReadonlyMap, + watchedFiles: ReadonlySet, + fileStats: ReadonlyMap, + watcher: Chokidar.FSWatcher, + handleEvent: (type: 'added' | 'modified' | 'removed', rawPath: string) => void, +): Promise { + await Promise.all( + Array.from(baselineStats, async ([lookupKey, baseline]) => { + if (!watchedFiles.has(lookupKey)) { + return; + } + const currentStat = await fs.promises.stat(baseline.posixPath).catch(() => null); + if (!watchedFiles.has(lookupKey) || !currentStat?.isFile()) { + return; } - } - return true; - } + if (baseline.mtimeMs === undefined || baseline.size === undefined) { + const recorded = fileStats.get(lookupKey); + if (!recorded) { + watcher.add(baseline.posixPath); + handleEvent('added', path.normalize(baseline.posixPath)); + } else if (currentStat.mtimeMs !== recorded.mtimeMs || currentStat.size !== recorded.size) { + handleEvent('modified', path.normalize(baseline.posixPath)); + } + } else if (currentStat.mtimeMs !== baseline.mtimeMs || currentStat.size !== baseline.size) { + handleEvent('modified', path.normalize(baseline.posixPath)); + } + }), + ); } async function createChokidarWatcher( @@ -1181,43 +1182,19 @@ async function createChokidarWatcher( const chokidar = chokidarModule ?? (await import('chokidar')); const watchedFiles = new Set(); const fileStats = new Map(); + const pendingTimers = new Set>(); - let queue: WatcherQueue; - if (options?.polling) { - const pollingInterval = options.interval ?? 100; - const debounceMs = Math.min(250, Math.max(100, Math.ceil(pollingInterval * 1.5))); - const maxWaitMs = Math.max(500, debounceMs * 3); - queue = new WatcherQueue(debounceMs, maxWaitMs); - } else { - queue = new WatcherQueue(); - } + const pollingInterval = options?.interval ?? 100; + const debounceMs = Math.min(250, Math.max(100, Math.ceil(pollingInterval * 1.5))); + const queue = options?.polling + ? new WatcherQueue(debounceMs, Math.max(500, debounceMs * 3)) + : new WatcherQueue(); const rootDir = options?.cwd ?? process.cwd(); const isCaseSensitive = isFileSystemCaseSensitive(rootDir); - const rootDirPosix = toPosixPathNormalized(rootDir); - const rootDirLookupKey = toLookupKey(rootDirPosix, isCaseSensitive); - - const nodeModulesManager = new ChokidarNodeModulesManager(isCaseSensitive); + const ignored = createChokidarIgnored(options?.ignored, isCaseSensitive, watchedFiles); - // Strip static node_modules ignore patterns (e.g. `**/node_modules/**` from setupWatcher). - // If left in place, picomatch would unconditionally ignore all node_modules files and override - // our dynamic package allowlist above. - const customIgnored = - options?.ignored - ?.filter((pattern) => !pattern.includes(NODE_MODULES)) - .map((pattern) => { - if (/[*?[\]{}()]/.test(pattern)) { - const isMatch = picomatch(pattern, { dot: true }); - - return (filePath: string) => isMatch(toPosixPathNormalized(filePath)); - } - - return { path: toPosixPathNormalized(pattern), recursive: true }; - }) ?? []; - - const ignored = [...customIgnored, (filePath: string) => nodeModulesManager.isIgnored(filePath)]; - - const watcher = chokidar.watch(rootDir, { + const watcher = chokidar.watch([], { ignoreInitial: true, ignored, followSymlinks: options?.followSymlinks, @@ -1225,13 +1202,10 @@ async function createChokidarWatcher( interval: options?.interval, }); - const initTime = Date.now(); + // Prevent unhandled watcher errors (such as EMFILE or EACCES) from crashing the process. + watcher.on('error', () => {}); - // Wait for the watcher to complete its initial filesystem scan before returning. - // With `ignoreInitial: true`, any file visited during the initial scan is treated as the initial baseline - // and will not emit 'add' or 'change' events. Awaiting 'ready' ensures that rapid file modifications - // made right after watcher setup (e.g. in rebuild tests) are not swallowed as initial files. - await once(watcher, 'ready'); + const initTime = Date.now(); const handleEvent = (type: 'added' | 'modified' | 'removed', rawPath: string) => { const posixPath = toPosixPathNormalized(rawPath); @@ -1248,14 +1222,10 @@ async function createChokidarWatcher( } const stat = fs.statSync(rawPath, { throwIfNoEntry: false }); - if (!stat) { - return; - } - // Ignore historical events from before watcher initialization, but allow a 1000 ms window // to account for coarse filesystem timestamp resolution (e.g., ext4/overlayfs integer second // mtime truncation on Linux) where files modified during startup may have truncated .000 ms mtimes. - if (stat.mtimeMs < initTime - 1000) { + if (!stat || stat.mtimeMs < initTime - 1000) { return; } @@ -1273,11 +1243,55 @@ async function createChokidarWatcher( queue.addChange(type, rawPath); }; + const scheduleBaselineCheck = (baselineStats: ReadonlyMap) => { + if (baselineStats.size === 0) { + return; + } + + const timer = setTimeout(() => { + pendingTimers.delete(timer); + void checkChokidarBaselines(baselineStats, watchedFiles, fileStats, watcher, handleEvent); + }, 50); + timer.unref(); + pendingTimers.add(timer); + }; + watcher.on('add', (path) => handleEvent('added', path)); watcher.on('change', (path) => handleEvent('modified', path)); - watcher.on('unlink', (path) => handleEvent('removed', path)); + watcher.on('unlink', (rawPath) => { + const posixPath = toPosixPathNormalized(rawPath); + const lookupKey = toLookupKey(posixPath, isCaseSensitive); + if (!isPathWatched(lookupKey, watchedFiles)) { + return; + } - const buildWatcher: BuildWatcher = { + // When Chokidar processes a file removal, it closes the underlying file watcher unless only a + // single directory is tracked (`_watched.size === 1`). Re-adding a directly watched path + // ensures Chokidar continues watching either the recreated file (if replaced within the atomic + // window) or its parent directory for future recreation. + if (watchedFiles.has(lookupKey)) { + fileStats.delete(lookupKey); + watcher.add(posixPath); + const stat = fs.statSync(rawPath, { throwIfNoEntry: false }); + if (stat?.isFile()) { + handleEvent('modified', rawPath); + scheduleBaselineCheck( + new Map([[lookupKey, { posixPath, mtimeMs: stat.mtimeMs, size: stat.size }]]), + ); + + return; + } + + handleEvent('removed', rawPath); + scheduleBaselineCheck(new Map([[lookupKey, { posixPath }]])); + + return; + } + + handleEvent('removed', rawPath); + }); + + return { [Symbol.asyncIterator]() { return this; }, @@ -1304,28 +1318,23 @@ async function createChokidarWatcher( add(paths) { const targets = typeof paths === 'string' ? [paths] : paths; const newPaths: string[] = []; + const baselineStats = new Map(); + for (const p of targets) { const posixPath = toPosixPathNormalized(p); const lookupKey = toLookupKey(posixPath, isCaseSensitive); if (!watchedFiles.has(lookupKey)) { watchedFiles.add(lookupKey); - - // For files inside node_modules, register their package directory. Only newly encountered - // package directories need to be added to Chokidar. - const { isPackage, newPkgDir } = nodeModulesManager.registerPackage(posixPath, lookupKey); - if (newPkgDir) { - newPaths.push(newPkgDir); - } else if ( - !isPackage && - !isPathInside(lookupKey, rootDirLookupKey) && - lookupKey !== rootDirLookupKey - ) { - newPaths.push(posixPath); + newPaths.push(posixPath); + const stat = fs.statSync(posixPath, { throwIfNoEntry: false }); + if (stat?.isFile()) { + baselineStats.set(lookupKey, { posixPath, mtimeMs: stat.mtimeMs, size: stat.size }); } } } if (newPaths.length > 0) { watcher.add(newPaths); + scheduleBaselineCheck(baselineStats); } }, @@ -1338,21 +1347,7 @@ async function createChokidarWatcher( if (watchedFiles.has(lookupKey)) { watchedFiles.delete(lookupKey); fileStats.delete(lookupKey); - - // When the last watched file in a package is removed, unwatch the package directory. - const { isPackage, unwatchPkgDir } = nodeModulesManager.removePackageFile( - posixPath, - lookupKey, - ); - if (unwatchPkgDir) { - removePaths.push(unwatchPkgDir); - } else if ( - !isPackage && - !isPathInside(lookupKey, rootDirLookupKey) && - lookupKey !== rootDirLookupKey - ) { - removePaths.push(posixPath); - } + removePaths.push(posixPath); } } if (removePaths.length > 0) { @@ -1361,13 +1356,15 @@ async function createChokidarWatcher( }, async close() { + for (const timer of pendingTimers) { + clearTimeout(timer); + } + pendingTimers.clear(); try { await watcher.close(); } finally { queue.close(); } }, - }; - - return buildWatcher; + } satisfies BuildWatcher; } diff --git a/packages/angular/build/src/utils/watcher_spec.ts b/packages/angular/build/src/utils/watcher_spec.ts index 3703eb9f4ce1..ef7a14d831d2 100644 --- a/packages/angular/build/src/utils/watcher_spec.ts +++ b/packages/angular/build/src/utils/watcher_spec.ts @@ -775,7 +775,7 @@ describe('Watcher', () => { } }, 10000); - it('should unwatch linked package directory when all its files are removed via watcher.remove', async () => { + it('should unwatch linked package file when removed via watcher.remove', async () => { const externalDir = fs.mkdtempSync(path.join(TMP_DIR, 'watcher-remove-npm-link-')); let watcher: BuildWatcher | undefined; @@ -813,7 +813,7 @@ describe('Watcher', () => { // Remove the linked file from the watcher watcher.remove(linkedFile); - // Allow a brief moment for Chokidar to asynchronously complete unwatching the package directory + // Allow a brief moment for Chokidar to asynchronously complete unwatching the file await setTimeout(250); // Modify both the removed linked file and the regular file @@ -876,6 +876,98 @@ describe('Watcher', () => { fs.rmSync(externalRoot, { recursive: true, force: true }); } }, 10000); + + it('should detect file deletion and recreation when watching multiple files with followSymlinks: true', async () => { + const subDirA = path.join(tempDir, 'dir-a'); + const subDirB = path.join(tempDir, 'dir-b'); + fs.mkdirSync(subDirA); + fs.mkdirSync(subDirB); + + const fileA = path.join(subDirA, 'a.ts'); + const fileB = path.join(subDirB, 'b.ts'); + fs.writeFileSync(fileA, 'export const a = 1;'); + fs.writeFileSync(fileB, 'export const b = 1;'); + + const watcher = await createWatcher({ + followSymlinks: true, + cwd: tempDir, + }); + + try { + watcher.add([fileA, fileB]); + await setTimeout(250); + + const iterator = watcher[Symbol.asyncIterator](); + + // Delete fileA and wait past Chokidar's atomic write window + fs.rmSync(fileA); + let result = await iterator.next(); + expect(result.done).toBeFalsy(); + expect(result.value?.removed.size).toBeGreaterThan(0); + + await setTimeout(150); + + // Recreate fileA and verify the watcher still detects it + fs.writeFileSync(fileA, 'export const a = 2;'); + result = await iterator.next(); + expect(result.done).toBeFalsy(); + expect(result.value?.all.some((f: string) => f.includes('a.ts'))).toBeTrue(); + + // Modify recreated fileA again to ensure ongoing changes are tracked + await setTimeout(150); + fs.writeFileSync(fileA, 'export const a = 3;'); + result = await iterator.next(); + expect(result.done).toBeFalsy(); + expect(result.value?.all.some((f: string) => f.includes('a.ts'))).toBeTrue(); + } finally { + await watcher.close(); + } + }, 10000); + + it('should prune node_modules when watching root directory while watching added package files', async () => { + const nodeModulesDir = path.join(tempDir, 'node_modules'); + const pkgDir = path.join(nodeModulesDir, 'some-pkg'); + fs.mkdirSync(pkgDir, { recursive: true }); + + const watchedPkgFile = path.join(pkgDir, 'index.js'); + const unwatchedPkgFile = path.join(pkgDir, 'other.js'); + const rootFile = path.join(tempDir, 'main.ts'); + fs.writeFileSync(watchedPkgFile, 'export const idx = 1;'); + fs.writeFileSync(unwatchedPkgFile, 'export const other = 1;'); + fs.writeFileSync(rootFile, 'export const main = 1;'); + + const pastTime = new Date(Date.now() - 5000); + fs.utimesSync(watchedPkgFile, pastTime, pastTime); + fs.utimesSync(unwatchedPkgFile, pastTime, pastTime); + fs.utimesSync(rootFile, pastTime, pastTime); + + const watcher = await createWatcher({ + followSymlinks: true, + cwd: tempDir, + }); + + try { + // Watch both the root directory and a specific file in node_modules + watcher.add([tempDir, watchedPkgFile]); + await setTimeout(250); + + const iterator = watcher[Symbol.asyncIterator](); + const nextPromise = iterator.next(); + + // Modify unwatched file in node_modules (should be ignored even though tempDir is watched) + // and watched file in node_modules + fs.writeFileSync(unwatchedPkgFile, 'export const other = 2;'); + fs.writeFileSync(watchedPkgFile, 'export const idx = 2;'); + + const result = await nextPromise; + expect(result.done).toBeFalsy(); + const changed = result.value?.all ?? []; + expect(changed.some((f: string) => f.includes('index.js'))).toBeTrue(); + expect(changed.some((f: string) => f.includes('other.js'))).toBeFalse(); + } finally { + await watcher.close(); + } + }, 10000); }); describe('ParcelExternalManager', () => { From 0608ebf8992bc11b43dfb8b042e9322f8b6bdd87 Mon Sep 17 00:00:00 2001 From: Shuaib Hasan Akib <48770016+MeAkib@users.noreply.github.com> Date: Fri, 16 Oct 2026 22:25:25 +0600 Subject: [PATCH 632/787] docs(@schematics/angular): correct `directory` and `entryFile` option descriptions The `ng new` `directory` option claimed the workspace is created in the current directory when the option is omitted, but a new directory named after the workspace is created instead. The library `entryFile` option described a path relative to the workspace root, but the value is a file name without the `.ts` extension that is placed in the library's `src` directory. --- packages/schematics/angular/library/schema.json | 2 +- packages/schematics/angular/ng-new/schema.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/schematics/angular/library/schema.json b/packages/schematics/angular/library/schema.json index bb3d227e5245..02c6c6f8acaa 100644 --- a/packages/schematics/angular/library/schema.json +++ b/packages/schematics/angular/library/schema.json @@ -19,7 +19,7 @@ "entryFile": { "type": "string", "format": "path", - "description": "The path to the library's public API file, relative to the workspace root. This file defines what parts of the library are accessible to applications that import it.", + "description": "The name of the library's public API file, without the `.ts` extension, created in the library's `src` directory. This file defines what parts of the library are accessible to applications that import it.", "default": "public-api" }, "prefix": { diff --git a/packages/schematics/angular/ng-new/schema.json b/packages/schematics/angular/ng-new/schema.json index 257628fcda9e..2c69fa84aaad 100644 --- a/packages/schematics/angular/ng-new/schema.json +++ b/packages/schematics/angular/ng-new/schema.json @@ -8,7 +8,7 @@ "properties": { "directory": { "type": "string", - "description": "The directory where the new workspace and project should be created. If not specified, the workspace will be created in the current directory." + "description": "The directory where the new workspace and project should be created. If not specified, the workspace will be created in a subfolder within the current directory, using the workspace's name." }, "name": { "description": "The name for the new workspace and the initial project. This name will be used for the root directory and various identifiers throughout the project.", From 490a6fe2f1938ea3da5299dabf3a41dec4ef8399 Mon Sep 17 00:00:00 2001 From: MeAkib Date: Fri, 16 Oct 2026 00:09:22 +0600 Subject: [PATCH 633/787] fix(@schematics/angular): show routing module suffixes in `findModule` error When only routing modules are found, the error message printed the optional `routingModuleExt` parameter, which no schematic passes, so users saw "Modules with suffix 'undefined' are strictly reserved for routing.". Since 0b7d48c7ca the lookup checks both `-routing-module.ts` and `-routing.module.ts`, so list the suffixes that are actually used. --- packages/schematics/angular/utility/find-module.ts | 2 +- packages/schematics/angular/utility/find-module_spec.ts | 3 +++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/packages/schematics/angular/utility/find-module.ts b/packages/schematics/angular/utility/find-module.ts index c98b52a0cbe2..e6ad0c5620e6 100644 --- a/packages/schematics/angular/utility/find-module.ts +++ b/packages/schematics/angular/utility/find-module.ts @@ -117,7 +117,7 @@ export function findModule( const errorMsg = foundRoutingModule ? 'Could not find a non Routing NgModule.' + - `\nModules with suffix '${routingModuleExt}' are strictly reserved for routing.` + + `\nModules with suffix '${routingModuleExtensions.join("' or '")}' are strictly reserved for routing.` + `\nUse the '--skip-import' option to skip importing in NgModule.` : `Could not find an NgModule. Use the '--skip-import' option to skip importing in NgModule.`; diff --git a/packages/schematics/angular/utility/find-module_spec.ts b/packages/schematics/angular/utility/find-module_spec.ts index 0db295ae384f..dcc8a7df057e 100644 --- a/packages/schematics/angular/utility/find-module_spec.ts +++ b/packages/schematics/angular/utility/find-module_spec.ts @@ -56,6 +56,9 @@ describe('find-module', () => { expect(() => findModule(host, 'foo/src/app/anything-routing')).toThrowError( /Could not find a non Routing NgModule/, ); + expect(() => findModule(host, 'foo/src/app/anything-routing')).toThrowError( + /Modules with suffix '-routing-module\.ts' or '-routing\.module\.ts' are strictly reserved/, + ); }); it('should throw if two modules found', () => { From c1cfe8f48059e2d48731cf933f8f407e65466428 Mon Sep 17 00:00:00 2001 From: MeAkib Date: Fri, 16 Oct 2026 00:11:22 +0600 Subject: [PATCH 634/787] docs(@angular/build): include component templates in dev-server `hmr` description The `hmr` option description stated that only global and component stylesheets are supported. Component template hot replacement is also enabled by default when HMR is active, so list templates alongside the supported stylesheets. --- packages/angular/build/src/builders/dev-server/schema.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/angular/build/src/builders/dev-server/schema.json b/packages/angular/build/src/builders/dev-server/schema.json index 023478ff7e52..3517d3098887 100644 --- a/packages/angular/build/src/builders/dev-server/schema.json +++ b/packages/angular/build/src/builders/dev-server/schema.json @@ -91,7 +91,7 @@ }, "hmr": { "type": "boolean", - "description": "Enable hot module replacement. Defaults to the value of 'liveReload'. Currently, only global and component stylesheets are supported." + "description": "Enable hot module replacement. Defaults to the value of 'liveReload'. Currently, global stylesheets, component stylesheets, and component templates are supported." }, "watch": { "type": "boolean", From 9469dcddedb931251a9883d9f82142c8fffc56f2 Mon Sep 17 00:00:00 2001 From: Angular Robot Date: Fri, 16 Oct 2026 06:47:17 +0000 Subject: [PATCH 635/787] build: update dependency node to v24.22.0 See associated pull request for more information. --- .nvmrc | 2 +- MODULE.bazel | 20 ++++++++++---------- MODULE.bazel.lock | 3 +++ 3 files changed, 14 insertions(+), 11 deletions(-) diff --git a/.nvmrc b/.nvmrc index df6ae3370f9f..a43a5b943d99 100644 --- a/.nvmrc +++ b/.nvmrc @@ -1 +1 @@ -24.21.0 +24.22.0 diff --git a/MODULE.bazel b/MODULE.bazel index f81a41dd6522..69ddf30cdb73 100644 --- a/MODULE.bazel +++ b/MODULE.bazel @@ -40,15 +40,15 @@ git_override( node = use_extension("@rules_nodejs//nodejs:extensions.bzl", "node") node.toolchain( node_repositories = { - "24.21.0-darwin_arm64": ("node-v24.21.0-darwin-arm64.tar.gz", "node-v24.21.0-darwin-arm64", "bed7eea5325e1108f32ce5228ddd6a5f0f08a499ee42aa7442aea583702f6057"), - "24.21.0-darwin_amd64": ("node-v24.21.0-darwin-x64.tar.gz", "node-v24.21.0-darwin-x64", "1462cb3b3046b815cf8ea436d3da450ec1a9f11dac7e5a46b0ada5305d7e8097"), - "24.21.0-linux_arm64": ("node-v24.21.0-linux-arm64.tar.xz", "node-v24.21.0-linux-arm64", "6ad1325edbdb5649c379b75a237147a666c95d4f9ae8d340fef2d1575d289ad2"), - "24.21.0-linux_ppc64le": ("node-v24.21.0-linux-ppc64le.tar.xz", "node-v24.21.0-linux-ppc64le", "1936fd64623a2f98d1fb31b456686d10c30e92639899cfefdefa8835d22adccd"), - "24.21.0-linux_s390x": ("node-v24.21.0-linux-s390x.tar.xz", "node-v24.21.0-linux-s390x", "2ef7e2ecbf7a6c2f3d08d106f6b2f279419c6dac89fe91b8cad193af7890082c"), - "24.21.0-linux_amd64": ("node-v24.21.0-linux-x64.tar.xz", "node-v24.21.0-linux-x64", "fd8e59d5a511510f6a298afb548f18c7d2b1be404d8b4a27d94fbe49f56cb2d6"), - "24.21.0-windows_amd64": ("node-v24.21.0-win-x64.zip", "node-v24.21.0-win-x64", "158f7685b44de51f6c0df1d153526cbcd3e1bc739a8dfc607721cef75de9e541"), + "24.22.0-darwin_arm64": ("node-v24.22.0-darwin-arm64.tar.gz", "node-v24.22.0-darwin-arm64", "6a9724d9b50a5f22b4816cded441b5a8d9ddae546191a5e5b7efa5a5e2ee26d5"), + "24.22.0-darwin_amd64": ("node-v24.22.0-darwin-x64.tar.gz", "node-v24.22.0-darwin-x64", "495e3f273c645f3c4677d438304cdfc701729ea5dec5728f5c8e76a2dece4b91"), + "24.22.0-linux_arm64": ("node-v24.22.0-linux-arm64.tar.xz", "node-v24.22.0-linux-arm64", "fef00bb4d36e1c50104a9775a10359beee98f162b4104dd12472c75065c6a143"), + "24.22.0-linux_ppc64le": ("node-v24.22.0-linux-ppc64le.tar.xz", "node-v24.22.0-linux-ppc64le", "edfc950d84a74b4fb4fedc8d2a569976682f6bbbf182961a4e916b7aad856013"), + "24.22.0-linux_s390x": ("node-v24.22.0-linux-s390x.tar.xz", "node-v24.22.0-linux-s390x", "ee3a16f7700188d62cd87b50fde39f8cbd8ab82f25611114e5ed6ef00d914431"), + "24.22.0-linux_amd64": ("node-v24.22.0-linux-x64.tar.xz", "node-v24.22.0-linux-x64", "cc2f601cee82d9a5a233302fe307abc600727035fd7d2c3a3571755989e95008"), + "24.22.0-windows_amd64": ("node-v24.22.0-win-x64.zip", "node-v24.22.0-win-x64", "f9683a19877e12a9b167305c8db71040d812876359de21f0d2e97c3f321f80c3"), }, - node_version = "24.21.0", + node_version = "24.22.0", ) use_repo( node, @@ -131,8 +131,8 @@ use_repo( pnpm = use_extension("@aspect_rules_js//npm:extensions.bzl", "pnpm") pnpm.pnpm( name = "pnpm", - pnpm_version = "12.3.4", - pnpm_version_integrity = "sha512-lhqkH7B32joEpEHZ+OFevAyW2o73ELLrZ7+e58sGEOq9SPH9hfUc/+c4RnhfoPh8VqOocqHYk/hEZ0G1zORUVw==", + pnpm_version = "12.11.2", + pnpm_version_integrity = "sha512-JaUWUqGWeFr18ovabf6NxYLr76SsHRgCIc4TkCMcX7dmN4IupLbkYzznSs3LCnf3Ja8RutOBd/3t2u6BipVcuQ==", ) use_repo(pnpm, "pnpm") diff --git a/MODULE.bazel.lock b/MODULE.bazel.lock index 4cb3f4cc542f..ec705b4eb497 100644 --- a/MODULE.bazel.lock +++ b/MODULE.bazel.lock @@ -1069,6 +1069,9 @@ } }, "facts": { + "@@aspect_rules_js+//npm:extensions.bzl%pnpm": { + "exe:12.11.2": "{\"darwin-arm64\":\"sha512-n9M4On66y8FDxUAKgMO1FXt0qihyG4e+56p3/F0uo8Bx9KplW8BwKVnXigzCJ8aNM6sVVPkOE6M9XXbeVIxnZA==\",\"darwin-x64\":\"sha512-oSW7n3sBT0c0cyk4kj10T2Y6Mpm+OFEiCAWozgX039tdoI6yqJF1uaFD3sw7ugLdu6VV3+uY0pa1TUZIPdxDWA==\",\"linux-arm64\":\"sha512-6e8ZAQUwFXAWHHHv5FesWqf/kEK04wuitBv5f/gxzkC0DiBfaixr+f+6JQede8SF4Ji5LcMwVFJbzAtffpWxEg==\",\"linux-arm64-musl\":\"sha512-uMEYDwKRktGwANubQ+kYCwmhNwg3Ik6qK89ahsbQ5cP30R/5FVJb/T99vr9XRUBC/A7mZI6eeT92oyVas9ACyg==\",\"linux-x64\":\"sha512-FK7QKe24AYgppJwO3mpooYptduuvIGqKJPi5ac7MdnWkjUy46JBfYhCW0grnkWKC8YOf0x+vGviuQqJEj3SpQQ==\",\"linux-x64-musl\":\"sha512-7eIxQR05fvJxCujUSKp5KTtehJ7QqrgqP/HD1+BcB/SaV2Be4XI1PEHiOgA1zxsiMIeMvTF6E4G4dYHrFjeXRg==\",\"win32-arm64\":\"sha512-PCTjVDdJb6VvraZxrEeFv6EqEA0hhIsAySx28e95J2Tqpi88hLpgOXgNqV0vpxq9A+b8GLQfyk/D+1UlJPv/YQ==\",\"win32-x64\":\"sha512-8sgX86OvRjJ3yZs/TvGR2L31wH9ScPZ+f+geKI3ikuB0RRiK3i4LlTRO8OXN6pdRqj8epMde4312MCjj7JsJdA==\"}" + }, "@@aspect_tools_telemetry+//:extension.bzl%telemetry": { "notice_version": "3" } From 137351b7de55c899cea9108554777e020de52851 Mon Sep 17 00:00:00 2001 From: Alan Agius <17563226+alan-agius4@users.noreply.github.com> Date: Thu, 15 Oct 2026 18:08:07 +0000 Subject: [PATCH 636/787] fix(@angular/build): preserve incremental .d.ts signatures and emit state in watch mode - Drain newly created .ngtypecheck.ts shims after collectDiagnostics() using emitNextAffectedFile with isolatedModules and assumeChangesOnlyAffectDirectDependencies enabled so TypeScript does not reset .d.ts shape signatures or queue component files into affectedFilesPendingEmit for the next rebuild. - Ensure before transformers run prior to afterDeclarations during .d.ts-only emits so Angular's declarationTransformFactory always has populated dtsTransforms. - Only record source files as emitted when JS output is produced (not on .d.ts-only checks), and pass ts.EmitOnly.Js in the fallback loop when .d.ts was already emitted. - Track transitive importers whose BuilderProgram signatures are reset to sourceFile.version by handleDtsMayChangeOf so populatePreviousDtsSignatures restores their .d.ts signatures on subsequent edits. --- .../library/tests/behavior/watch_spec.ts | 200 +++++++++++++++++- .../angular/compilation/aot-compilation.ts | 156 +++++++++++--- 2 files changed, 329 insertions(+), 27 deletions(-) diff --git a/packages/angular/build/src/builders/library/tests/behavior/watch_spec.ts b/packages/angular/build/src/builders/library/tests/behavior/watch_spec.ts index e9b7e57ddd9f..add8b5151d81 100644 --- a/packages/angular/build/src/builders/library/tests/behavior/watch_spec.ts +++ b/packages/angular/build/src/builders/library/tests/behavior/watch_spec.ts @@ -8,7 +8,7 @@ import { rm } from 'node:fs/promises'; import { executeLibraryBuilder } from '../../builder'; -import { InlineStyleLanguage } from '../../schema'; +import { CompilationMode, InlineStyleLanguage } from '../../schema'; import { BASE_OPTIONS, LIBRARY_BUILDER_INFO, describeLibraryBuilder } from '../setup'; describeLibraryBuilder(executeLibraryBuilder, LIBRARY_BUILDER_INFO, (harness) => { @@ -649,5 +649,203 @@ describeLibraryBuilder(executeLibraryBuilder, LIBRARY_BUILDER_INFO, (harness) => }, ]); }); + + it('should only rebuild affected entry point when an external template is modified with isolatedModules enabled', async () => { + await harness.writeFiles({ + 'projects/lib/src/lib/lib.component.html': '

Primary Initial

', + 'projects/lib/src/lib/lib.component.ts': ` + import { Component } from '@angular/core'; + + @Component({ + selector: 'lib-primary', + templateUrl: './lib.component.html', + }) + export class LibComponent {} + `, + 'projects/lib/secondary/src/secondary.component.html': '

Secondary Initial

', + 'projects/lib/secondary/src/secondary.component.ts': ` + import { Component } from '@angular/core'; + + @Component({ + selector: 'lib-secondary', + templateUrl: './secondary.component.html', + }) + export class SecondaryComponent {} + `, + 'projects/lib/secondary/src/public-api.ts': ` + export { SecondaryComponent } from './secondary.component'; + `, + }); + + await harness.modifyFile('projects/lib/tsconfig.lib.json', (content) => { + const tsconfig = JSON.parse(content); + tsconfig.compilerOptions.isolatedModules = true; + + return JSON.stringify(tsconfig, null, 2); + }); + + await harness.modifyFile('projects/lib/package.json', (content) => { + const pkg = JSON.parse(content); + pkg.exports = { + '.': './src/public-api.ts', + './secondary': './secondary/src/public-api.ts', + }; + + return JSON.stringify(pkg, null, 2); + }); + + harness.useTarget('build', { + ...BASE_OPTIONS, + watch: true, + }); + + await harness.executeWithCases([ + async ({ result }) => { + expect(result?.success).toBeTrue(); + expect(harness.readFile('dist/lib/fesm2022/lib-secondary.mjs')).toContain( + 'Secondary Initial', + ); + expect(harness.readFile('dist/lib/types/lib.d.ts')).toContain('ɵcmp'); + expect(harness.readFile('dist/lib/types/lib-secondary.d.ts')).toContain('ɵcmp'); + + await harness.writeFile( + 'projects/lib/secondary/src/secondary.component.html', + '

Secondary Updated

', + ); + }, + ({ result, logs }) => { + expect(result?.success).toBeTrue(); + expect(harness.readFile('dist/lib/fesm2022/lib-secondary.mjs')).toContain( + 'Secondary Updated', + ); + expect(harness.readFile('dist/lib/types/lib.d.ts')).toContain('ɵcmp'); + expect(harness.readFile('dist/lib/types/lib-secondary.d.ts')).toContain('ɵcmp'); + + expect(logs).toContain( + jasmine.objectContaining({ + message: jasmine.stringContaining('Compiling lib/secondary...'), + }), + ); + expect(logs).not.toContain( + jasmine.objectContaining({ + message: jasmine.stringContaining('Compiling lib...'), + }), + ); + }, + ]); + }); + + it('should rebuild dependent entry point when a shared component input is added in watch mode', async () => { + await harness.writeFiles({ + 'projects/lib/shared/src/public-api.ts': ` + import { Component } from '@angular/core'; + + @Component({ + selector: 'lib-shared-icon', + template: 'icon', + }) + export class SharedIconComponent {} + `, + 'projects/lib/src/lib/lib.component.ts': ` + import { Component } from '@angular/core'; + import { SharedIconComponent } from 'lib/shared'; + + @Component({ + selector: 'lib-primary', + imports: [SharedIconComponent], + template: '', + }) + export class LibComponent {} + `, + }); + + await harness.modifyFile('projects/lib/tsconfig.lib.json', (content) => { + const tsconfig = JSON.parse(content); + tsconfig.compilerOptions.isolatedModules = true; + + return JSON.stringify(tsconfig, null, 2); + }); + + await harness.modifyFile('projects/lib/package.json', (content) => { + const pkg = JSON.parse(content); + pkg.exports = { + '.': './src/public-api.ts', + './shared': './shared/src/public-api.ts', + }; + + return JSON.stringify(pkg, null, 2); + }); + + harness.useTarget('build', { + ...BASE_OPTIONS, + compilationMode: CompilationMode.Partial, + watch: true, + }); + + await harness.executeWithCases([ + async ({ result }) => { + expect(result?.success).toBeTrue(); + + // Trigger a rebuild of `lib` first so `lib/shared` undergoes a `.d.ts`-only check + await harness.writeFile( + 'projects/lib/src/lib/lib.component.ts', + ` + import { Component } from '@angular/core'; + import { SharedIconComponent } from 'lib/shared'; + + @Component({ + selector: 'lib-primary', + imports: [SharedIconComponent], + template: '', + }) + export class LibComponent {} + `, + ); + }, + async ({ result, logs }) => { + expect(result?.success).toBeTrue(); + expect(logs).toContain( + jasmine.objectContaining({ + message: jasmine.stringContaining('Compiling lib...'), + }), + ); + expect(logs).not.toContain( + jasmine.objectContaining({ + message: jasmine.stringContaining('Compiling lib/shared...'), + }), + ); + + // Add a new @Input() to SharedIconComponent + await harness.writeFile( + 'projects/lib/shared/src/public-api.ts', + ` + import { Component, Input } from '@angular/core'; + + @Component({ + selector: 'lib-shared-icon', + template: '{{ name }}', + }) + export class SharedIconComponent { + @Input() name = 'default'; + } + `, + ); + }, + ({ result, logs }) => { + expect(result?.success).toBeTrue(); + expect(logs).toContain( + jasmine.objectContaining({ + message: jasmine.stringContaining('Compiling lib/shared...'), + }), + ); + expect(logs).toContain( + jasmine.objectContaining({ + message: jasmine.stringContaining('Compiling lib...'), + }), + ); + expect(harness.readFile('dist/lib/fesm2022/lib.mjs')).toContain('"name"'); + }, + ]); + }); }); }); diff --git a/packages/angular/build/src/tools/angular/compilation/aot-compilation.ts b/packages/angular/build/src/tools/angular/compilation/aot-compilation.ts index 4ca1480f646c..88171a44fc69 100644 --- a/packages/angular/build/src/tools/angular/compilation/aot-compilation.ts +++ b/packages/angular/build/src/tools/angular/compilation/aot-compilation.ts @@ -47,6 +47,15 @@ const TTC_EXTENSION = '.ngtypecheck.ts'; */ const TTC_EXTENSION_LENGTH = TTC_EXTENSION.length; +/** + * Internal TypeScript `ts.EmitOnly` enum values used by `Program.emit`. + */ +enum EmitOnly { + Js = 0, + Dts = 1, + BuilderSignature = 2, +} + /** * Checks if a file is an Angular type-checking shim file. */ @@ -226,7 +235,7 @@ export class AotCompilation extends TypeScriptCompilation { ); const filesWithoutDtsSignature = this.#state?.filesWithoutDtsSignature ?? new Set(); - if (!this.#state) { + if (!this.#state && !usingBuildInfo && (useTypeChecking || useTypeScriptTranspilation)) { for (const sourceFile of typeScriptProgram.getSourceFiles()) { if ( !sourceFile.isDeclarationFile && @@ -449,19 +458,30 @@ export class AotCompilation extends TypeScriptCompilation { typeScriptProgram, ); + // Temporarily enable `isolatedModules` and `assumeChangesOnlyAffectDirectDependencies` while + // draining the newly created `.ngtypecheck.ts` files. Because each component `.ts` file + // references its `.ngtypecheck.ts` shim via `sourceFile.referencedFiles`, TypeScript's + // `referencedMap` treats the component `.ts` file as depending on its `.ngtypecheck.ts` shim. + // Without both flags (whether `isolatedModules` is enabled or disabled in `tsconfig`), + // TypeScript would walk from `.ngtypecheck.ts` to the component `.ts` file and its transitive + // importers, resetting their `.d.ts` shape signatures and queueing them into + // `affectedFilesPendingEmit` for the next incremental rebuild. + const compilerOptions = currentTsProgram.getCompilerOptions(); + const prevIsolatedModules = compilerOptions.isolatedModules; + const prevAssumeDirect = compilerOptions.assumeChangesOnlyAffectDirectDependencies; + compilerOptions.isolatedModules = true; + compilerOptions.assumeChangesOnlyAffectDirectDependencies = true; + const baseEmit = currentTsProgram.emit; currentTsProgram.emit = () => ({ emitSkipped: true, diagnostics: [] }); try { - while ( - this.#state.typeScriptProgram.getSemanticDiagnosticsOfNextAffectedFile( - undefined, - () => true, - ) - ) { + while (this.#state.typeScriptProgram.emitNextAffectedFile(() => {})) { /* empty */ } } finally { currentTsProgram.emit = baseEmit; + compilerOptions.isolatedModules = prevIsolatedModules; + compilerOptions.assumeChangesOnlyAffectDirectDependencies = prevAssumeDirect; } } } @@ -478,11 +498,12 @@ export class AotCompilation extends TypeScriptCompilation { useTypeScriptTranspilation, } = this.#state; const compilerOptions = typeScriptProgram.getCompilerOptions(); - const isLibraryEmit = !!compilerOptions.declaration; + const emitDeclarations = !!compilerOptions.declaration; const buildInfoFilename = compilerOptions.tsBuildInfoFile ?? '.tsbuildinfo'; const emittedFiles = new Map(); const emittedSourceFiles = new Set(); + const emittedDtsSourceFiles = new Set(); const writeFileCallback: ts.WriteFileCallback = (filename, contents, _a, _b, sourceFiles) => { if (!sourceFiles?.length && filename.endsWith(buildInfoFilename)) { // Save builder info contents to specified location @@ -497,13 +518,20 @@ export class AotCompilation extends TypeScriptCompilation { return; } - angularCompiler.incrementalCompilation.recordSuccessfulEmit(sourceFile); - emittedSourceFiles.add(sourceFile); - const targetFilename = isLibraryEmit ? filename : sourceFile.fileName; + const isMap = filename.endsWith('.map'); + const isDts = !isMap && /\.d\.[cm]?ts$/i.test(filename); + if (!emitDeclarations || (!isMap && !isDts)) { + angularCompiler.incrementalCompilation.recordSuccessfulEmit(sourceFile); + emittedSourceFiles.add(sourceFile); + } else if (isDts) { + emittedDtsSourceFiles.add(sourceFile); + } + + const targetFilename = emitDeclarations ? filename : sourceFile.fileName; emittedFiles.set(targetFilename, { filename: targetFilename, contents }); }; const transformers = angularCompiler.prepareEmit().transformers; - if (!isLibraryEmit) { + if (!emitDeclarations) { transformers.before ??= []; transformers.before.push( replaceBootstrap(() => typeScriptProgram.getProgram().getTypeChecker()), @@ -513,6 +541,8 @@ export class AotCompilation extends TypeScriptCompilation { if (!this.browserOnlyBuild) { transformers.before.push(lazyRoutesTransformer(compilerOptions, compilerHost)); } + } else if (transformers.before?.length && transformers.afterDeclarations?.length) { + ensurePreDeclarationTransformers(transformers); } // Emit is handled in write file callback when using TypeScript @@ -554,15 +584,14 @@ export class AotCompilation extends TypeScriptCompilation { continue; } - if ( - angularCompiler.incrementalCompilation.safeToSkipEmit(sourceFile) && - (!useTypeScriptTranspilation || !affectedFiles.has(sourceFile)) - ) { + if (angularCompiler.incrementalCompilation.safeToSkipEmit(sourceFile)) { continue; } if (useTypeScriptTranspilation) { - const emitOnly = affectedFiles.has(sourceFile) ? undefined : false; + const emitOnly = emittedDtsSourceFiles.has(sourceFile) + ? (EmitOnly.Js as unknown as boolean) + : undefined; typeScriptProgram.emit(sourceFile, writeFileCallback, undefined, emitOnly, transformers); continue; } @@ -618,6 +647,60 @@ export class AotCompilation extends TypeScriptCompilation { } } +/** + * When TypeScript's `BuilderProgram.emitNextAffectedFile` emits `.d.ts`-only (`emitOnly = Dts`) + * for a transitive importer, TypeScript skips `transformers.before`. However, Angular's + * `declarationTransformFactory` in `afterDeclarations` relies on `ivyTransformFactory` in + * `before` having compiled the file's classes to populate `dtsTransforms`. + * + * This helper ensures `before` transformers have executed on the original `SourceFile` prior to + * `afterDeclarations`, and caches the transformed `SourceFile` so a subsequent `.js` emit for the + * same file does not re-execute `before` transformers. + */ +function ensurePreDeclarationTransformers(transformers: ts.CustomTransformers): void { + if (!transformers.before?.length || !transformers.afterDeclarations?.length) { + return; + } + + const beforeTransformers = transformers.before as ts.TransformerFactory[]; + const transformedSourceFiles = new Set(); + transformers.before = beforeTransformers.map((factory, index) => + index === 0 + ? (context) => { + const transform = factory(context); + + return (sourceFile) => { + transformedSourceFiles.add(ts.getOriginalNode(sourceFile, ts.isSourceFile)); + + return transform(sourceFile); + }; + } + : factory, + ); + transformers.afterDeclarations = [ + (context) => { + let beforeTransforms: ts.Transformer[] | undefined; + + return (fileOrBundle) => { + if (!ts.isBundle(fileOrBundle)) { + const originalSourceFile = ts.getOriginalNode(fileOrBundle, ts.isSourceFile); + if (!transformedSourceFiles.has(originalSourceFile)) { + transformedSourceFiles.add(originalSourceFile); + beforeTransforms ??= beforeTransformers.map((factory) => factory(context)); + let current = originalSourceFile; + for (const transform of beforeTransforms) { + current = transform(current); + } + } + } + + return fileOrBundle; + }; + }, + ...transformers.afterDeclarations, + ]; +} + function findAffectedFiles( builder: ts.EmitAndSemanticDiagnosticsBuilderProgram, { ignoreForDiagnostics, incrementalCompilation }: ng.NgtscProgram['compiler'], @@ -627,10 +710,15 @@ function findAffectedFiles( ): Set { const affectedFiles = new Set(); - // Temporarily disable `isolatedModules` and `verbatimModuleSyntax` while walking affected - // files so TypeScript's `getFilesAffectedByUpdatedShapeWhenModuleEmit` yields dependent - // `.ngtypecheck.ts` shims to the `ignoreSourceFile` callback when a file's `.d.ts` shape - // changes, instead of returning only the modified file itself. + // Temporarily disable `isolatedModules` and `verbatimModuleSyntax` while walking affected files. + // In TypeScript, `getIsolatedModules(options)` is true when either `isolatedModules` or + // `verbatimModuleSyntax` is enabled, which causes `getFilesAffectedByUpdatedShapeWhenModuleEmit` + // to short-circuit and return only `[sourceFileWithUpdatedShape]` instead of walking + // `referencedMap` during `getSemanticDiagnosticsOfNextAffectedFile`. + // Disabling both flags forces TypeScript to traverse `referencedMap` when a file's `.d.ts` shape + // signature changes so that dependent files—especially `.ngtypecheck.ts` shims that reference + // directives or pipes used in templates—are visited by the `ignoreSourceFile` callback and have + // their own `.d.ts` shape signatures updated along the dependency chain. const compilerOptions = builder.getCompilerOptions(); const prevIsolatedModules = compilerOptions.isolatedModules; const prevVerbatimModuleSyntax = compilerOptions.verbatimModuleSyntax; @@ -640,6 +728,8 @@ function findAffectedFiles( const program = builder.getProgram(); const baseEmit = program.emit; const oldProgram = oldBuilder?.getProgram(); + const hadDtsSignatureComputed = new Set(); + const tsAffectedFiles: ts.SourceFile[] = []; program.emit = ( targetSourceFile, writeFile, @@ -677,8 +767,9 @@ function findAffectedFiles( (fileName, text, writeByteOrderMark, onError, sourceFiles, data) => { const newHasDiagnostics = !!(data as { diagnostics?: unknown[] } | undefined) ?.diagnostics?.length; - if (text !== oldDtsText || newHasDiagnostics !== oldHasDiagnostics) { + if (text !== oldDtsText || oldHasDiagnostics || newHasDiagnostics) { filesWithoutDtsSignature.delete(targetSourceFile.fileName); + hadDtsSignatureComputed.add(targetSourceFile.fileName); writeFile?.(fileName, text, writeByteOrderMark, onError, sourceFiles, data); } }, @@ -691,6 +782,8 @@ function findAffectedFiles( filesWithoutDtsSignature.delete(targetSourceFile.fileName); } + + hadDtsSignatureComputed.add(targetSourceFile.fileName); } return baseEmit.call( @@ -716,7 +809,7 @@ function findAffectedFiles( // A TTC shim is a file that has been ignored for diagnostics and has a filename ending in `.ngtypecheck.ts`. if (isNgTypeCheckFile(sourceFile.fileName)) { // This file name conversion relies on internal compiler logic and should be converted - // to an official method when available. 15 is length of `.ngtypecheck.ts` + // to an official method when available. const originalFilename = getOriginalFilename(sourceFile.fileName); const originalSourceFile = builder.getSourceFile(originalFilename); if (originalSourceFile) { @@ -725,6 +818,7 @@ function findAffectedFiles( } } else { affectedFiles.add(sourceFile); + tsAffectedFiles.push(sourceFile); } return true; @@ -738,6 +832,16 @@ function findAffectedFiles( compilerOptions.verbatimModuleSyntax = prevVerbatimModuleSyntax; } + // Transitive importers visited by `getSemanticDiagnosticsOfNextAffectedFile` via + // `handleDtsMayChangeOf` do not have a `.d.ts` signature computed via `program.emit` and + // instead have their BuilderProgram signature reset to `sourceFile.version`. Track them so + // `populatePreviousDtsSignatures` restores their `.d.ts` signature if they are modified later. + for (const sourceFile of tsAffectedFiles) { + if (!sourceFile.isDeclarationFile && !hadDtsSignatureComputed.has(sourceFile.fileName)) { + filesWithoutDtsSignature.add(sourceFile.fileName); + } + } + // Also include files identified by Angular's incremental compilation graph as needing // re-emission or template re-typechecking (such as selector renames or required input changes // that only affect Angular metadata without altering standard TypeScript `.d.ts` signatures). @@ -762,7 +866,7 @@ function findAffectedFiles( for (const sourceFile of builder.getSourceFiles()) { if (ignoreForDiagnostics.has(sourceFile) && isNgTypeCheckFile(sourceFile.fileName)) { // This file name conversion relies on internal compiler logic and should be converted - // to an official method when available. 15 is length of `.ngtypecheck.ts` + // to an official method when available. const originalFilename = getOriginalFilename(sourceFile.fileName); const originalSourceFile = builder.getSourceFile(originalFilename); if (originalSourceFile) { @@ -819,7 +923,7 @@ function populatePreviousDtsSignatures( targetSourceFile?: ts.SourceFile, writeFile?: ts.WriteFileCallback, cancellationToken?: ts.CancellationToken, - emitOnlyDtsFiles?: boolean | number, + emitOnlyDtsFiles?: boolean | EmitOnly, customTransformers?: ts.CustomTransformers, forceDtsEmit?: boolean, ) => ts.EmitResult; @@ -829,7 +933,7 @@ function populatePreviousDtsSignatures( targetSourceFile, writeFile, cancellationToken, - 2, // ts.EmitOnly.BuilderSignature + EmitOnly.BuilderSignature, undefined, true, // forceDtsEmit ); From 1b893ed95ba3bfe0690274682c6473489003dbe8 Mon Sep 17 00:00:00 2001 From: Alan Agius Date: Mon, 19 Oct 2026 09:35:16 +0200 Subject: [PATCH 637/787] fix(@angular/build): align lazy route entry names with workspace root for SSR modulepreload MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Override `compilerOptions.basePath` with `build.initialOptions.absWorkingDir` when initializing the Angular compilation so `lazyRoutesTransformer` computes `ɵentryName` relative to the workspace root rather than the tsconfig directory. This matches the workspace-relative keys in `entryPointToBrowserMapping` used for SSR `modulepreload` link generation when the application's `tsconfig` is not located at the workspace root. --- .../behavior/chunk-optimization-server_spec.ts | 16 ++++++++++------ .../compilation/angular-compilation_spec.ts | 8 +++++++- .../angular/compilation/compiler-options.ts | 3 +++ .../src/tools/esbuild/angular/compiler-plugin.ts | 1 + 4 files changed, 21 insertions(+), 7 deletions(-) diff --git a/packages/angular/build/src/builders/application/tests/behavior/chunk-optimization-server_spec.ts b/packages/angular/build/src/builders/application/tests/behavior/chunk-optimization-server_spec.ts index 76ecbbc4329e..18b92e7690a0 100644 --- a/packages/angular/build/src/builders/application/tests/behavior/chunk-optimization-server_spec.ts +++ b/packages/angular/build/src/builders/application/tests/behavior/chunk-optimization-server_spec.ts @@ -151,15 +151,19 @@ describeBuilder(buildApplication, APPLICATION_BUILDER_INFO, (harness) => { .not.toBeNull(); const mapping = JSON.parse(mappingSource![1]) as Record; + const mainServerContent = harness.readFile('dist/server/main.server.mjs'); - // Every lazy route entry point must retain a mapping entry after optimization. + // Every lazy route entry point must retain a mapping entry after optimization + // that matches the ɵentryName emitted into the server bundle. for (const name of LAZY_ROUTE_NAMES) { - const key = Object.keys(mapping).find((entryPoint) => - entryPoint.endsWith(`${name}.component.ts`), - ); - expect(key) - .withContext(`mapping entry for lazy route '${name}' should exist`) + const expectedEntryPoint = `src/app/${name}.component.ts`; + expect(mapping[expectedEntryPoint]) + .withContext(`mapping entry for '${expectedEntryPoint}' should exist`) .toBeDefined(); + + expect(mainServerContent) + .withContext(`main.server.mjs should contain ɵentryName '${expectedEntryPoint}'`) + .toContain(expectedEntryPoint); } // Every browser file referenced by the mapping must exist on disk. diff --git a/packages/angular/build/src/tools/angular/compilation/angular-compilation_spec.ts b/packages/angular/build/src/tools/angular/compilation/angular-compilation_spec.ts index 3c09b87f69d7..58c492ac5214 100644 --- a/packages/angular/build/src/tools/angular/compilation/angular-compilation_spec.ts +++ b/packages/angular/build/src/tools/angular/compilation/angular-compilation_spec.ts @@ -451,7 +451,11 @@ describe('AngularCompilation', () => { it('applies override options correctly', () => { const { compilerOptions } = transformCompilerOptions( ts, - { target: ts.ScriptTarget.ES2022, isolatedModules: true }, + { + target: ts.ScriptTarget.ES2022, + isolatedModules: true, + basePath: '/workspace/projects/app', + }, { sourcemap: true, preserveSymlinks: true, @@ -459,9 +463,11 @@ describe('AngularCompilation', () => { enableHmr: true, instrumentForCoverage: true, includeTestMetadata: true, + basePath: '/workspace', }, ); + expect(compilerOptions.basePath).toBe('/workspace'); expect(compilerOptions.inlineSources).toBe(true); expect(compilerOptions.inlineSourceMap).toBe(true); expect(compilerOptions.preserveSymlinks).toBe(true); diff --git a/packages/angular/build/src/tools/angular/compilation/compiler-options.ts b/packages/angular/build/src/tools/angular/compilation/compiler-options.ts index b2c83d616f08..77bfdfde2f90 100644 --- a/packages/angular/build/src/tools/angular/compilation/compiler-options.ts +++ b/packages/angular/build/src/tools/angular/compilation/compiler-options.ts @@ -10,6 +10,7 @@ import type * as ng from '@angular/compiler-cli'; import type { PartialMessage } from 'esbuild'; import * as path from 'node:path'; import type ts from 'typescript'; +import { toPosixPath } from '../../../utils/path'; export interface CompilerOptionOverrides { sourcemap?: boolean; @@ -24,6 +25,7 @@ export interface CompilerOptionOverrides { declarationMap?: boolean; compilationMode?: 'full' | 'partial'; paths?: Record; + basePath?: string; } export function transformCompilerOptions( @@ -134,6 +136,7 @@ export function transformCompilerOptions( return { compilerOptions: { ...compilerOptions, + basePath: overrides?.basePath ? toPosixPath(overrides.basePath) : compilerOptions.basePath, noEmitOnError: false, composite: false, inlineSources: !!overrides?.sourcemap, diff --git a/packages/angular/build/src/tools/esbuild/angular/compiler-plugin.ts b/packages/angular/build/src/tools/esbuild/angular/compiler-plugin.ts index 9a36eea56d61..cd53d6085e65 100644 --- a/packages/angular/build/src/tools/esbuild/angular/compiler-plugin.ts +++ b/packages/angular/build/src/tools/esbuild/angular/compiler-plugin.ts @@ -331,6 +331,7 @@ export function createCompilerPlugin( includeTestMetadata: !!pluginOptions.includeTestMetadata, customConditions: build.initialOptions.conditions, rootFiles: pluginOptions.rootFiles, + basePath: build.initialOptions.absWorkingDir, }, ); From 96046878ad238dd3acf1c27adc60d9d8a6acac5b Mon Sep 17 00:00:00 2001 From: Angular Robot Date: Mon, 19 Oct 2026 07:33:20 +0000 Subject: [PATCH 638/787] build: update all non-major dependencies See associated pull request for more information. --- modules/testing/builder/package.json | 6 +- package.json | 12 +- packages/angular/build/package.json | 14 +- packages/angular/cli/package.json | 4 +- .../angular_devkit/build_angular/package.json | 8 +- .../angular_devkit/build_webpack/package.json | 2 +- packages/ngtools/webpack/package.json | 2 +- pnpm-lock.yaml | 1116 +++++++++++------ 8 files changed, 751 insertions(+), 413 deletions(-) diff --git a/modules/testing/builder/package.json b/modules/testing/builder/package.json index 398a200cdf8a..149a97369205 100644 --- a/modules/testing/builder/package.json +++ b/modules/testing/builder/package.json @@ -4,12 +4,12 @@ "@angular-devkit/build-angular": "workspace:*", "@angular-devkit/core": "workspace:*", "@angular/ssr": "workspace:*", - "@vitest/coverage-v8": "5.0.4", + "@vitest/coverage-v8": "5.0.5", "browser-sync": "3.0.4", "istanbul-lib-instrument": "6.0.3", - "jsdom": "30.1.2", + "jsdom": "30.1.3", "ng-packagr": "22.3.0-next.2", "rxjs": "7.8.2", - "vitest": "5.0.4" + "vitest": "5.0.5" } } diff --git a/package.json b/package.json index 911eea20e9f6..e1fd9d31b31f 100644 --- a/package.json +++ b/package.json @@ -29,12 +29,12 @@ "type": "git", "url": "git+https://github.com/angular/angular-cli.git" }, - "packageManager": "pnpm@12.11.2", + "packageManager": "pnpm@12.14.0", "engines": { "node": "^22.22.3 || ^24.15.0 || >=26.0.0", "npm": "Please use pnpm instead of NPM to install dependencies", "yarn": "Please use pnpm instead of Yarn to install dependencies", - "pnpm": "12.11.2" + "pnpm": "12.14.0" }, "author": "Angular Authors", "license": "MIT", @@ -70,7 +70,7 @@ "@rollup/plugin-commonjs": "^29.0.0", "@rollup/plugin-json": "^6.1.0", "@rollup/plugin-node-resolve": "16.0.3", - "@rollup/wasm-node": "4.64.6", + "@rollup/wasm-node": "4.64.9", "@stylistic/eslint-plugin": "^5.0.0", "@tony.ganchev/eslint-plugin-header": "~3.4.0", "@types/babel__core": "7.20.5", @@ -97,7 +97,7 @@ "buffer": "6.0.3", "esbuild": "0.28.2", "esbuild-wasm": "0.28.2", - "eslint": "10.12.0", + "eslint": "10.13.0", "eslint-config-prettier": "10.1.8", "eslint-plugin-import": "2.32.0", "express": "5.3.0", @@ -121,13 +121,13 @@ "prettier": "^3.0.0", "puppeteer": "25.14.0", "quicktype-core": "26.0.0", - "rollup": "4.64.6", + "rollup": "4.64.9", "rollup-plugin-dts": "6.5.1", "rollup-plugin-sourcemaps2": "0.5.9", "semver": "7.8.5", "source-map-support": "0.5.21", "tslib": "2.8.1", - "undici": "8.12.1", + "undici": "8.12.2", "verdaccio": "6.10.5", "verdaccio-auth-memory": "^13.0.0", "zone.js": "^0.16.0" diff --git a/packages/angular/build/package.json b/packages/angular/build/package.json index 711ab5893f75..49cb93d743ac 100644 --- a/packages/angular/build/package.json +++ b/packages/angular/build/package.json @@ -30,7 +30,7 @@ "esbuild": "0.28.2", "https-proxy-agent": "9.1.0", "jsonc-parser": "3.3.1", - "listr2": "11.2.0", + "listr2": "11.4.0", "magic-string": "1.4.3", "mrmime": "2.0.1", "oxc-parser": "0.154.0", @@ -39,8 +39,8 @@ "piscina": "5.3.2", "rolldown": "1.2.14", "rolldown-plugin-dts": "0.28.8", - "sass": "1.105.1", - "sass-embedded": "1.105.1", + "sass": "1.105.2", + "sass-embedded": "1.105.2", "semver": "7.8.5", "source-map-support": "0.5.21", "tinyglobby": "0.2.17", @@ -54,15 +54,15 @@ "@angular-devkit/core": "workspace:*", "@angular/ssr": "workspace:*", "@oxc-project/types": "0.154.0", - "@vitest/coverage-v8": "5.0.4", + "@vitest/coverage-v8": "5.0.5", "istanbul-lib-instrument": "6.0.3", - "jsdom": "30.1.2", + "jsdom": "30.1.3", "less": "4.9.1", "ng-packagr": "22.3.0-next.2", "postcss": "8.5.30", - "rollup": "4.64.6", + "rollup": "4.64.9", "rxjs": "7.8.2", - "vitest": "5.0.4" + "vitest": "5.0.5" }, "peerDependencies": { "@angular/compiler": "0.0.0-ANGULAR-FW-PEER-DEP", diff --git a/packages/angular/cli/package.json b/packages/angular/cli/package.json index f558e7a6293d..780a6660a158 100644 --- a/packages/angular/cli/package.json +++ b/packages/angular/cli/package.json @@ -21,11 +21,11 @@ "@angular-devkit/core": "workspace:0.0.0-PLACEHOLDER", "@angular-devkit/schematics": "workspace:0.0.0-PLACEHOLDER", "@inquirer/prompts": "8.7.3", - "@listr2/prompt-adapter-inquirer": "4.3.1", + "@listr2/prompt-adapter-inquirer": "4.3.3", "@modelcontextprotocol/server": "2.3.1", "@schematics/angular": "workspace:0.0.0-PLACEHOLDER", "jsonc-parser": "3.3.1", - "listr2": "11.2.0", + "listr2": "11.4.0", "npm-package-arg": "14.0.0", "parse5-html-rewriting-stream": "8.0.1", "semver": "7.8.5", diff --git a/packages/angular_devkit/build_angular/package.json b/packages/angular_devkit/build_angular/package.json index 54a44f134b16..2a584459d6c9 100644 --- a/packages/angular_devkit/build_angular/package.json +++ b/packages/angular_devkit/build_angular/package.json @@ -54,8 +54,8 @@ "terser": "5.51.2", "tinyglobby": "0.2.17", "tslib": "2.8.1", - "webpack": "5.111.1", - "webpack-dev-middleware": "8.3.0", + "webpack": "5.112.0", + "webpack-dev-middleware": "8.4.0", "webpack-dev-server": "6.0.0", "webpack-merge": "6.0.1", "webpack-subresource-integrity": "5.1.0" @@ -67,8 +67,8 @@ "@angular/ssr": "workspace:*", "browser-sync": "3.0.4", "ng-packagr": "22.3.0-next.2", - "sass": "1.105.1", - "undici": "8.12.1" + "sass": "1.105.2", + "undici": "8.12.2" }, "peerDependencies": { "@angular/compiler-cli": "0.0.0-ANGULAR-FW-PEER-DEP", diff --git a/packages/angular_devkit/build_webpack/package.json b/packages/angular_devkit/build_webpack/package.json index 3c23e6109fef..a00b76bb9640 100644 --- a/packages/angular_devkit/build_webpack/package.json +++ b/packages/angular_devkit/build_webpack/package.json @@ -22,7 +22,7 @@ "devDependencies": { "@angular-devkit/core": "workspace:0.0.0-PLACEHOLDER", "@ngtools/webpack": "workspace:0.0.0-PLACEHOLDER", - "webpack": "5.111.1", + "webpack": "5.112.0", "webpack-dev-server": "6.0.0" }, "peerDependencies": { diff --git a/packages/ngtools/webpack/package.json b/packages/ngtools/webpack/package.json index 13cea96fc202..97cdf5645198 100644 --- a/packages/ngtools/webpack/package.json +++ b/packages/ngtools/webpack/package.json @@ -20,6 +20,6 @@ "@angular/compiler": "22.3.0-next.2", "@angular/compiler-cli": "22.3.0-next.2", "typescript": "6.0.3", - "webpack": "5.111.1" + "webpack": "5.112.0" } } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 81cbdf51aeb5..206638bf5095 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -7,153 +7,153 @@ importers: configDependencies: {} packageManagerDependencies: pnpm: - specifier: 12.11.2 - version: 12.11.2 + specifier: 12.14.0 + version: 12.14.0 packages: - '@pnpm/exe.android-arm64@12.11.2': - resolution: {integrity: sha512-owLw13OfPkEoY+hLBNeeG+dCFhywr7q2d/EHPz4mNL2RhKnv8gNwMARkjkiDQu234aItVwFNDeGnmQXm+ikkAg==} + '@pnpm/exe.android-arm64@12.14.0': + resolution: {integrity: sha512-+iSh7x21C3A2hqc+Z0ZmbKTcn6YNlzrXM142PsnQH/dLj0DYxFzoBvc6XAnL/yfQ5nnH2ebBiRj/zVxr61fZbQ==} cpu: [arm64] os: [android] - '@pnpm/exe.android-x64@12.11.2': - resolution: {integrity: sha512-GYPkVebl4iokOA/4MPSpGoUVfFlsth7uqOCe1XiaiM23LAdvUOMJBObqHJijr89ZqjwHm9pO6vO45GRwJ2U2qA==} + '@pnpm/exe.android-x64@12.14.0': + resolution: {integrity: sha512-qT+0LqEr2wBVaxcG2T8cX/R8SSRz2Rvpp8nRR4fh8tnGUZRch87gFmsHUAoSQh7w6j1h0qTjrA384j4xi8frvw==} cpu: [x64] os: [android] - '@pnpm/exe.darwin-arm64@12.11.2': - resolution: {integrity: sha512-n9M4On66y8FDxUAKgMO1FXt0qihyG4e+56p3/F0uo8Bx9KplW8BwKVnXigzCJ8aNM6sVVPkOE6M9XXbeVIxnZA==} + '@pnpm/exe.darwin-arm64@12.14.0': + resolution: {integrity: sha512-tnrdUB8ecJoehuKKqi1YHCBVl61xtJ9XVGcx5EviC6fWO4DeGI8GtXrjvJxDBM3nuVjJeWistgsUp/N142x4sw==} cpu: [arm64] os: [darwin] - '@pnpm/exe.darwin-x64@12.11.2': - resolution: {integrity: sha512-oSW7n3sBT0c0cyk4kj10T2Y6Mpm+OFEiCAWozgX039tdoI6yqJF1uaFD3sw7ugLdu6VV3+uY0pa1TUZIPdxDWA==} + '@pnpm/exe.darwin-x64@12.14.0': + resolution: {integrity: sha512-vlBfGkruqQRsEHTW43cPwpYd7QlbIJ//cvpAdb3bVXkI8SgTPoXhCnc05m+ZNiPrrEkBsX/t7KHw9aXpkzPm3Q==} cpu: [x64] os: [darwin] - '@pnpm/exe.freebsd-x64@12.11.2': - resolution: {integrity: sha512-qbzc3KoDpa/Lkf8vs3jnDe6dUUbso+6eLIyssYFMiliLpYNxn8dirk11YoNnOQcdHVB50v5RFls1Yid6ttT5pg==} + '@pnpm/exe.freebsd-x64@12.14.0': + resolution: {integrity: sha512-Qg5rxBrGYl6Tfso+EyygPf84fY1Fzy55E/0or+iuYKtnf0vc0MlHJfVIlT7pBukMRntQHRik7hUi0Z4s7AlJsw==} cpu: [x64] os: [freebsd] - '@pnpm/exe.linux-arm64-musl@12.11.2': - resolution: {integrity: sha512-uMEYDwKRktGwANubQ+kYCwmhNwg3Ik6qK89ahsbQ5cP30R/5FVJb/T99vr9XRUBC/A7mZI6eeT92oyVas9ACyg==} + '@pnpm/exe.linux-arm64-musl@12.14.0': + resolution: {integrity: sha512-DRIe4yQkXBGA/PhVJdzlbnllxBdAtnMMvTVLLcGpsK5FvJz9kxD2Hyxtn68ovmNkVX06f6p45cQwfm3wx2jn1A==} cpu: [arm64] os: [linux] libc: [musl] - '@pnpm/exe.linux-arm64@12.11.2': - resolution: {integrity: sha512-6e8ZAQUwFXAWHHHv5FesWqf/kEK04wuitBv5f/gxzkC0DiBfaixr+f+6JQede8SF4Ji5LcMwVFJbzAtffpWxEg==} + '@pnpm/exe.linux-arm64@12.14.0': + resolution: {integrity: sha512-7joGShZ44Nk3WpNU+60JoOPjCXlgxhJAq11S2UiVtwCUDgTer1yTPPfxGW8pxaD6046actYLIYDbZNlubHWs0A==} cpu: [arm64] os: [linux] libc: [glibc] - '@pnpm/exe.linux-ppc64@12.11.2': - resolution: {integrity: sha512-Ui8A4nepkVupx2VpuFfysEluMvWK6gTB5rgVts7Ss/+8dj0RD28x3F/seNeH/zSypgC6yKdV6qsKVQh/uffTuQ==} + '@pnpm/exe.linux-ppc64@12.14.0': + resolution: {integrity: sha512-gSoryn7ySdXd//gjgf3MvvA8ZerJayaSbuMZMtAWq4vb2/wlVEgpl0Kvqt54y58TRj533Qjq2txKgnxd4JyoAQ==} cpu: [ppc64] os: [linux] libc: [glibc] - '@pnpm/exe.linux-riscv64@12.11.2': - resolution: {integrity: sha512-i1yLdQ5bu+wjQ+srtFoJAaY2gN/+oXHFdjul4llCeoDxHE0rTIG3R41NhHfCjyFPW4+CpbBT58933CL9sMOCnA==} + '@pnpm/exe.linux-riscv64@12.14.0': + resolution: {integrity: sha512-EMjew1H9WqQ7pL+tYqCPwiuB+0PeCiJRV7fyWeuFw0wwYUajFBjcaPO3IGAVu9sdmJDU+e+HYv/Zey6aKae0Vw==} cpu: [riscv64] os: [linux] libc: [glibc] - '@pnpm/exe.linux-s390x@12.11.2': - resolution: {integrity: sha512-YS1/lhPjjTsN4QL50VaFZKRa3Uc/bDnhE8eKbJMFvuX06UuFS5YaiDg04APoZdfVSGqTfX27QAg7rfLMSWaqxA==} + '@pnpm/exe.linux-s390x@12.14.0': + resolution: {integrity: sha512-shYOj/SFoXD35fHe0pWr2JofwSXulC0BnEIXLj2QokDi0EF//AfKsui35yKIkTEl+s2VJybc3PO4iJNhKIj5Qw==} cpu: [s390x] os: [linux] libc: [glibc] - '@pnpm/exe.linux-x64-musl@12.11.2': - resolution: {integrity: sha512-7eIxQR05fvJxCujUSKp5KTtehJ7QqrgqP/HD1+BcB/SaV2Be4XI1PEHiOgA1zxsiMIeMvTF6E4G4dYHrFjeXRg==} + '@pnpm/exe.linux-x64-musl@12.14.0': + resolution: {integrity: sha512-btZiZ2Ot0llKK1ndSfA5i3IRX7/S0VrmzseNH/BJ4c+Cady+S81H6vvU1zByggHMyqQhC8OgxO5PiIY7D9bH0Q==} cpu: [x64] os: [linux] libc: [musl] - '@pnpm/exe.linux-x64@12.11.2': - resolution: {integrity: sha512-FK7QKe24AYgppJwO3mpooYptduuvIGqKJPi5ac7MdnWkjUy46JBfYhCW0grnkWKC8YOf0x+vGviuQqJEj3SpQQ==} + '@pnpm/exe.linux-x64@12.14.0': + resolution: {integrity: sha512-F6K8e/jWxiuEYJaQtRRUG9ynBSTEHa+t7Lf86MKuOO5UA7WVVMbi+oB8nY6iKW++ncWS2yG6T9faXZGxqNsfoQ==} cpu: [x64] os: [linux] libc: [glibc] - '@pnpm/exe.win32-arm64@12.11.2': - resolution: {integrity: sha512-PCTjVDdJb6VvraZxrEeFv6EqEA0hhIsAySx28e95J2Tqpi88hLpgOXgNqV0vpxq9A+b8GLQfyk/D+1UlJPv/YQ==} + '@pnpm/exe.win32-arm64@12.14.0': + resolution: {integrity: sha512-DOjlkVB6TtTKeAAe0hNZXn5S7YqESmo1Z6SGbR4BZNQ4isRg31XVHjX2RFTbY8gnZq68IwzyLmPqlEjMmYxofg==} cpu: [arm64] os: [win32] - '@pnpm/exe.win32-x64@12.11.2': - resolution: {integrity: sha512-8sgX86OvRjJ3yZs/TvGR2L31wH9ScPZ+f+geKI3ikuB0RRiK3i4LlTRO8OXN6pdRqj8epMde4312MCjj7JsJdA==} + '@pnpm/exe.win32-x64@12.14.0': + resolution: {integrity: sha512-/LSX6mew/sLf08XqcjemuklNKf1K/Ftpgj4//hK/HKzI2dKbmxDB27a/2OaQ5a0O3/3OFzlssXDziZsi+yVBwQ==} cpu: [x64] os: [win32] - pnpm@12.11.2: - resolution: {integrity: sha512-JaUWUqGWeFr18ovabf6NxYLr76SsHRgCIc4TkCMcX7dmN4IupLbkYzznSs3LCnf3Ja8RutOBd/3t2u6BipVcuQ==} + pnpm@12.14.0: + resolution: {integrity: sha512-wYum2HmT09Fky16JSPMrLAbuhUSH4GzY2GeBNC+z5btGNDZwNHEehoArqpw3vqkGzhkprQjXCITJfYAd8TOJpg==} engines: {node: '>=18.*'} hasBin: true snapshots: - '@pnpm/exe.android-arm64@12.11.2': + '@pnpm/exe.android-arm64@12.14.0': optional: true - '@pnpm/exe.android-x64@12.11.2': + '@pnpm/exe.android-x64@12.14.0': optional: true - '@pnpm/exe.darwin-arm64@12.11.2': + '@pnpm/exe.darwin-arm64@12.14.0': optional: true - '@pnpm/exe.darwin-x64@12.11.2': + '@pnpm/exe.darwin-x64@12.14.0': optional: true - '@pnpm/exe.freebsd-x64@12.11.2': + '@pnpm/exe.freebsd-x64@12.14.0': optional: true - '@pnpm/exe.linux-arm64-musl@12.11.2': + '@pnpm/exe.linux-arm64-musl@12.14.0': optional: true - '@pnpm/exe.linux-arm64@12.11.2': + '@pnpm/exe.linux-arm64@12.14.0': optional: true - '@pnpm/exe.linux-ppc64@12.11.2': + '@pnpm/exe.linux-ppc64@12.14.0': optional: true - '@pnpm/exe.linux-riscv64@12.11.2': + '@pnpm/exe.linux-riscv64@12.14.0': optional: true - '@pnpm/exe.linux-s390x@12.11.2': + '@pnpm/exe.linux-s390x@12.14.0': optional: true - '@pnpm/exe.linux-x64-musl@12.11.2': + '@pnpm/exe.linux-x64-musl@12.14.0': optional: true - '@pnpm/exe.linux-x64@12.11.2': + '@pnpm/exe.linux-x64@12.14.0': optional: true - '@pnpm/exe.win32-arm64@12.11.2': + '@pnpm/exe.win32-arm64@12.14.0': optional: true - '@pnpm/exe.win32-x64@12.11.2': + '@pnpm/exe.win32-x64@12.14.0': optional: true - pnpm@12.11.2: + pnpm@12.14.0: optionalDependencies: - '@pnpm/exe.android-arm64': 12.11.2 - '@pnpm/exe.android-x64': 12.11.2 - '@pnpm/exe.darwin-arm64': 12.11.2 - '@pnpm/exe.darwin-x64': 12.11.2 - '@pnpm/exe.freebsd-x64': 12.11.2 - '@pnpm/exe.linux-arm64': 12.11.2 - '@pnpm/exe.linux-arm64-musl': 12.11.2 - '@pnpm/exe.linux-ppc64': 12.11.2 - '@pnpm/exe.linux-riscv64': 12.11.2 - '@pnpm/exe.linux-s390x': 12.11.2 - '@pnpm/exe.linux-x64': 12.11.2 - '@pnpm/exe.linux-x64-musl': 12.11.2 - '@pnpm/exe.win32-arm64': 12.11.2 - '@pnpm/exe.win32-x64': 12.11.2 + '@pnpm/exe.android-arm64': 12.14.0 + '@pnpm/exe.android-x64': 12.14.0 + '@pnpm/exe.darwin-arm64': 12.14.0 + '@pnpm/exe.darwin-x64': 12.14.0 + '@pnpm/exe.freebsd-x64': 12.14.0 + '@pnpm/exe.linux-arm64': 12.14.0 + '@pnpm/exe.linux-arm64-musl': 12.14.0 + '@pnpm/exe.linux-ppc64': 12.14.0 + '@pnpm/exe.linux-riscv64': 12.14.0 + '@pnpm/exe.linux-s390x': 12.14.0 + '@pnpm/exe.linux-x64': 12.14.0 + '@pnpm/exe.linux-x64-musl': 12.14.0 + '@pnpm/exe.win32-arm64': 12.14.0 + '@pnpm/exe.win32-x64': 12.14.0 --- lockfileVersion: '9.0' @@ -236,31 +236,31 @@ importers: version: 0.28.0 '@eslint/compat': specifier: 2.1.1 - version: 2.1.1(eslint@10.12.0(jiti@2.7.0)(supports-color@11.0.0)) + version: 2.1.1(eslint@10.13.0(jiti@2.7.0)(supports-color@11.0.0)) '@eslint/eslintrc': specifier: 3.3.7 version: 3.3.7(supports-color@11.0.0) '@eslint/js': specifier: 10.0.1 - version: 10.0.1(eslint@10.12.0(jiti@2.7.0)(supports-color@11.0.0)) + version: 10.0.1(eslint@10.13.0(jiti@2.7.0)(supports-color@11.0.0)) '@rollup/plugin-commonjs': specifier: ^29.0.0 - version: 29.0.3(rollup@4.64.6) + version: 29.0.3(rollup@4.64.9) '@rollup/plugin-json': specifier: ^6.1.0 - version: 6.1.0(rollup@4.64.6) + version: 6.1.0(rollup@4.64.9) '@rollup/plugin-node-resolve': specifier: 16.0.3 - version: 16.0.3(rollup@4.64.6) + version: 16.0.3(rollup@4.64.9) '@rollup/wasm-node': - specifier: 4.64.6 - version: 4.64.6 + specifier: 4.64.9 + version: 4.64.9 '@stylistic/eslint-plugin': specifier: ^5.0.0 - version: 5.10.0(eslint@10.12.0(jiti@2.7.0)(supports-color@11.0.0)) + version: 5.10.0(eslint@10.13.0(jiti@2.7.0)(supports-color@11.0.0)) '@tony.ganchev/eslint-plugin-header': specifier: ~3.4.0 - version: 3.4.4(eslint@10.12.0(jiti@2.7.0)(supports-color@11.0.0)) + version: 3.4.4(eslint@10.13.0(jiti@2.7.0)(supports-color@11.0.0)) '@types/babel__core': specifier: 7.20.5 version: 7.20.5 @@ -290,7 +290,7 @@ importers: version: 3.0.8 '@types/loader-utils': specifier: ^3.0.0 - version: 3.0.0(esbuild@0.28.2)(lightningcss@1.33.0)(uglify-js@3.19.3) + version: 3.0.0(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.30)(uglify-js@3.19.3) '@types/lodash': specifier: ^4.17.0 version: 4.17.26 @@ -317,10 +317,10 @@ importers: version: 21.0.3 '@typescript-eslint/eslint-plugin': specifier: 8.71.2 - version: 8.71.2(@typescript-eslint/parser@8.71.2(eslint@10.12.0(jiti@2.7.0)(supports-color@11.0.0))(supports-color@11.0.0)(typescript@6.0.3))(eslint@10.12.0(jiti@2.7.0)(supports-color@11.0.0))(supports-color@11.0.0)(typescript@6.0.3) + version: 8.71.2(@typescript-eslint/parser@8.71.2(eslint@10.13.0(jiti@2.7.0)(supports-color@11.0.0))(supports-color@11.0.0)(typescript@6.0.3))(eslint@10.13.0(jiti@2.7.0)(supports-color@11.0.0))(supports-color@11.0.0)(typescript@6.0.3) '@typescript-eslint/parser': specifier: 8.71.2 - version: 8.71.2(eslint@10.12.0(jiti@2.7.0)(supports-color@11.0.0))(supports-color@11.0.0)(typescript@6.0.3) + version: 8.71.2(eslint@10.13.0(jiti@2.7.0)(supports-color@11.0.0))(supports-color@11.0.0)(typescript@6.0.3) ajv: specifier: 8.20.0 version: 8.20.0 @@ -334,14 +334,14 @@ importers: specifier: 0.28.2 version: 0.28.2 eslint: - specifier: 10.12.0 - version: 10.12.0(jiti@2.7.0)(supports-color@11.0.0) + specifier: 10.13.0 + version: 10.13.0(jiti@2.7.0)(supports-color@11.0.0) eslint-config-prettier: specifier: 10.1.8 - version: 10.1.8(eslint@10.12.0(jiti@2.7.0)(supports-color@11.0.0)) + version: 10.1.8(eslint@10.13.0(jiti@2.7.0)(supports-color@11.0.0)) eslint-plugin-import: specifier: 2.32.0 - version: 2.32.0(@typescript-eslint/parser@8.71.2(eslint@10.12.0(jiti@2.7.0)(supports-color@11.0.0))(supports-color@11.0.0)(typescript@6.0.3))(eslint@10.12.0(jiti@2.7.0)(supports-color@11.0.0))(supports-color@11.0.0) + version: 2.32.0(@typescript-eslint/parser@8.71.2(eslint@10.13.0(jiti@2.7.0)(supports-color@11.0.0))(supports-color@11.0.0)(typescript@6.0.3))(eslint@10.13.0(jiti@2.7.0)(supports-color@11.0.0))(supports-color@11.0.0) express: specifier: 5.3.0 version: 5.3.0(supports-color@11.0.0) @@ -406,14 +406,14 @@ importers: specifier: 26.0.0 version: 26.0.0 rollup: - specifier: 4.64.6 - version: 4.64.6 + specifier: 4.64.9 + version: 4.64.9 rollup-plugin-dts: specifier: 6.5.1 - version: 6.5.1(rollup@4.64.6)(typescript@6.0.3) + version: 6.5.1(rollup@4.64.9)(typescript@6.0.3) rollup-plugin-sourcemaps2: specifier: 0.5.9 - version: 0.5.9(@types/node@22.20.5)(rollup@4.64.6) + version: 0.5.9(@types/node@22.20.5)(rollup@4.64.9) semver: specifier: 7.8.5 version: 7.8.5 @@ -424,8 +424,8 @@ importers: specifier: 2.8.1 version: 2.8.1 undici: - specifier: 8.12.1 - version: 8.12.1 + specifier: 8.12.2 + version: 8.12.2 verdaccio: specifier: 6.10.5 version: 6.10.5(encoding@0.1.13)(supports-color@11.0.0) @@ -451,8 +451,8 @@ importers: specifier: workspace:* version: link:../../../packages/angular/ssr '@vitest/coverage-v8': - specifier: 5.0.4 - version: 5.0.4(vitest@5.0.4) + specifier: 5.0.5 + version: 5.0.5(vitest@5.0.5) browser-sync: specifier: 3.0.4 version: 3.0.4(bufferutil@4.1.0)(debug@4.4.3(supports-color@11.0.0))(supports-color@11.0.0)(utf-8-validate@6.0.6) @@ -460,8 +460,8 @@ importers: specifier: 6.0.3 version: 6.0.3(supports-color@11.0.0) jsdom: - specifier: 30.1.2 - version: 30.1.2(@noble/hashes@1.8.0) + specifier: 30.1.3 + version: 30.1.3(@noble/hashes@1.8.0) ng-packagr: specifier: 22.3.0-next.2 version: 22.3.0-next.2(@angular/compiler-cli@22.3.0-next.2(@angular/compiler@22.3.0-next.2)(typescript@6.0.3))(supports-color@11.0.0)(tslib@2.8.1)(typescript@6.0.3) @@ -469,8 +469,8 @@ importers: specifier: 7.8.2 version: 7.8.2 vitest: - specifier: 5.0.4 - version: 5.0.4(@opentelemetry/api@1.9.1)(@types/node@22.20.5)(@vitest/coverage-v8@5.0.4)(jsdom@30.1.2(@noble/hashes@1.8.0))(vite@8.3.4(@types/node@22.20.5)(esbuild@0.28.2)(jiti@2.7.0)(less@4.9.1(supports-color@11.0.0))(sass-embedded@1.105.1)(sass@1.105.1)(terser@5.51.2)(tsx@4.23.15)(yaml@2.9.1)) + specifier: 5.0.5 + version: 5.0.5(@opentelemetry/api@1.9.1)(@types/node@22.20.5)(@vitest/coverage-v8@5.0.5)(jsdom@30.1.3(@noble/hashes@1.8.0))(vite@8.3.4(@types/node@22.20.5)(esbuild@0.28.2)(jiti@2.7.0)(less@4.9.1(supports-color@11.0.0))(sass-embedded@1.105.1)(sass@1.105.1)(terser@5.51.2)(tsx@4.23.15)(yaml@2.9.1)) packages/angular/build: dependencies: @@ -491,7 +491,7 @@ importers: version: 2.6.0 '@vitejs/plugin-basic-ssl': specifier: 2.3.0 - version: 2.3.0(vite@8.3.4(@types/node@22.20.5)(esbuild@0.28.2)(jiti@2.7.0)(less@4.9.1(supports-color@11.0.0))(sass-embedded@1.105.1)(sass@1.105.1)(terser@5.51.2)(tsx@4.23.15)(yaml@2.9.1)) + version: 2.3.0(vite@8.3.4(@types/node@22.20.5)(esbuild@0.28.2)(jiti@2.7.0)(less@4.9.1(supports-color@11.0.0))(sass-embedded@1.105.2)(sass@1.105.2)(terser@5.51.2)(tsx@4.23.15)(yaml@2.9.1)) beasties: specifier: 0.5.5 version: 0.5.5 @@ -511,8 +511,8 @@ importers: specifier: 3.3.1 version: 3.3.1 listr2: - specifier: 11.2.0 - version: 11.2.0 + specifier: 11.4.0 + version: 11.4.0 magic-string: specifier: 1.4.3 version: 1.4.3 @@ -538,11 +538,11 @@ importers: specifier: 0.28.8 version: 0.28.8(rolldown@1.2.14)(typescript@6.0.3) sass: - specifier: 1.105.1 - version: 1.105.1 + specifier: 1.105.2 + version: 1.105.2 sass-embedded: - specifier: 1.105.1 - version: 1.105.1 + specifier: 1.105.2 + version: 1.105.2 semver: specifier: 7.8.5 version: 7.8.5 @@ -554,7 +554,7 @@ importers: version: 0.2.17 vite: specifier: 8.3.4 - version: 8.3.4(@types/node@22.20.5)(esbuild@0.28.2)(jiti@2.7.0)(less@4.9.1(supports-color@11.0.0))(sass-embedded@1.105.1)(sass@1.105.1)(terser@5.51.2)(tsx@4.23.15)(yaml@2.9.1) + version: 8.3.4(@types/node@22.20.5)(esbuild@0.28.2)(jiti@2.7.0)(less@4.9.1(supports-color@11.0.0))(sass-embedded@1.105.2)(sass@1.105.2)(terser@5.51.2)(tsx@4.23.15)(yaml@2.9.1) xxhash-wasm: specifier: 1.1.0 version: 1.1.0 @@ -569,14 +569,14 @@ importers: specifier: 0.154.0 version: 0.154.0 '@vitest/coverage-v8': - specifier: 5.0.4 - version: 5.0.4(vitest@5.0.4) + specifier: 5.0.5 + version: 5.0.5(vitest@5.0.5) istanbul-lib-instrument: specifier: 6.0.3 version: 6.0.3(supports-color@11.0.0) jsdom: - specifier: 30.1.2 - version: 30.1.2(@noble/hashes@1.8.0) + specifier: 30.1.3 + version: 30.1.3(@noble/hashes@1.8.0) less: specifier: 4.9.1 version: 4.9.1(supports-color@11.0.0) @@ -587,14 +587,14 @@ importers: specifier: 8.5.30 version: 8.5.30 rollup: - specifier: 4.64.6 - version: 4.64.6 + specifier: 4.64.9 + version: 4.64.9 rxjs: specifier: 7.8.2 version: 7.8.2 vitest: - specifier: 5.0.4 - version: 5.0.4(@opentelemetry/api@1.9.1)(@types/node@22.20.5)(@vitest/coverage-v8@5.0.4)(jsdom@30.1.2(@noble/hashes@1.8.0))(vite@8.3.4(@types/node@22.20.5)(esbuild@0.28.2)(jiti@2.7.0)(less@4.9.1(supports-color@11.0.0))(sass-embedded@1.105.1)(sass@1.105.1)(terser@5.51.2)(tsx@4.23.15)(yaml@2.9.1)) + specifier: 5.0.5 + version: 5.0.5(@opentelemetry/api@1.9.1)(@types/node@22.20.5)(@vitest/coverage-v8@5.0.5)(jsdom@30.1.3(@noble/hashes@1.8.0))(vite@8.3.4(@types/node@22.20.5)(esbuild@0.28.2)(jiti@2.7.0)(less@4.9.1(supports-color@11.0.0))(sass-embedded@1.105.2)(sass@1.105.2)(terser@5.51.2)(tsx@4.23.15)(yaml@2.9.1)) optionalDependencies: lmdb: specifier: 3.5.7 @@ -615,8 +615,8 @@ importers: specifier: 8.7.3 version: 8.7.3(@types/node@22.20.5) '@listr2/prompt-adapter-inquirer': - specifier: 4.3.1 - version: 4.3.1(@inquirer/prompts@8.7.3(@types/node@22.20.5))(@types/node@22.20.5)(listr2@11.2.0) + specifier: 4.3.3 + version: 4.3.3(@inquirer/prompts@8.7.3(@types/node@22.20.5))(@types/node@22.20.5)(listr2@11.4.0) '@modelcontextprotocol/server': specifier: 2.3.1 version: 2.3.1 @@ -627,8 +627,8 @@ importers: specifier: 3.3.1 version: 3.3.1 listr2: - specifier: 11.2.0 - version: 11.2.0 + specifier: 11.4.0 + version: 11.4.0 npm-package-arg: specifier: 14.0.0 version: 14.0.0 @@ -758,7 +758,7 @@ importers: version: 10.6.1(postcss@8.5.30) babel-loader: specifier: 10.1.1 - version: 10.1.1(@babel/core@8.0.7)(webpack@5.111.1(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.30)(uglify-js@3.19.3)) + version: 10.1.1(@babel/core@8.0.7)(webpack@5.112.0(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.30)(uglify-js@3.19.3)) beasties: specifier: 0.5.5 version: 0.5.5 @@ -767,10 +767,10 @@ importers: version: 4.29.3 copy-webpack-plugin: specifier: 14.0.0 - version: 14.0.0(webpack@5.111.1(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.30)(uglify-js@3.19.3)) + version: 14.0.0(webpack@5.112.0(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.30)(uglify-js@3.19.3)) css-loader: specifier: 7.1.5 - version: 7.1.5(webpack@5.111.1(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.30)(uglify-js@3.19.3)) + version: 7.1.5(webpack@5.112.0(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.30)(uglify-js@3.19.3)) esbuild-wasm: specifier: 0.28.2 version: 0.28.2 @@ -791,16 +791,16 @@ importers: version: 4.9.1(supports-color@11.0.0) less-loader: specifier: 13.0.0 - version: 13.0.0(less@4.9.1(supports-color@11.0.0))(webpack@5.111.1(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.30)(uglify-js@3.19.3)) + version: 13.0.0(less@4.9.1(supports-color@11.0.0))(webpack@5.112.0(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.30)(uglify-js@3.19.3)) license-webpack-plugin: specifier: 4.0.2 - version: 4.0.2(webpack@5.111.1(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.30)(uglify-js@3.19.3)) + version: 4.0.2(webpack@5.112.0(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.30)(uglify-js@3.19.3)) loader-utils: specifier: 3.3.1 version: 3.3.1 mini-css-extract-plugin: specifier: 2.10.2 - version: 2.10.2(webpack@5.111.1(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.30)(uglify-js@3.19.3)) + version: 2.10.2(webpack@5.112.0(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.30)(uglify-js@3.19.3)) open: specifier: 11.0.4 version: 11.0.4 @@ -818,7 +818,7 @@ importers: version: 8.5.30 postcss-loader: specifier: 8.2.1 - version: 8.2.1(postcss@8.5.30)(typescript@6.0.3)(webpack@5.111.1(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.30)(uglify-js@3.19.3)) + version: 8.2.1(postcss@8.5.30)(typescript@6.0.3)(webpack@5.112.0(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.30)(uglify-js@3.19.3)) resolve-url-loader: specifier: 5.0.0 version: 5.0.0 @@ -827,13 +827,13 @@ importers: version: 7.8.2 sass-loader: specifier: 17.0.1 - version: 17.0.1(sass-embedded@1.105.1)(sass@1.105.1)(webpack@5.111.1(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.30)(uglify-js@3.19.3)) + version: 17.0.1(sass-embedded@1.105.1)(sass@1.105.2)(webpack@5.112.0(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.30)(uglify-js@3.19.3)) semver: specifier: 7.8.5 version: 7.8.5 source-map-loader: specifier: 5.0.0 - version: 5.0.0(webpack@5.111.1(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.30)(uglify-js@3.19.3)) + version: 5.0.0(webpack@5.112.0(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.30)(uglify-js@3.19.3)) source-map-support: specifier: 0.5.21 version: 0.5.21 @@ -847,20 +847,20 @@ importers: specifier: 2.8.1 version: 2.8.1 webpack: - specifier: 5.111.1 - version: 5.111.1(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.30)(uglify-js@3.19.3) + specifier: 5.112.0 + version: 5.112.0(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.30)(uglify-js@3.19.3) webpack-dev-middleware: - specifier: 8.3.0 - version: 8.3.0(webpack@5.111.1(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.30)(uglify-js@3.19.3)) + specifier: 8.4.0 + version: 8.4.0(bufferutil@4.1.0)(utf-8-validate@6.0.6)(webpack@5.112.0(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.30)(uglify-js@3.19.3)) webpack-dev-server: specifier: 6.0.0 - version: 6.0.0(bufferutil@4.1.0)(supports-color@11.0.0)(utf-8-validate@6.0.6)(webpack@5.111.1(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.30)(uglify-js@3.19.3)) + version: 6.0.0(bufferutil@4.1.0)(supports-color@11.0.0)(utf-8-validate@6.0.6)(webpack@5.112.0(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.30)(uglify-js@3.19.3)) webpack-merge: specifier: 6.0.1 version: 6.0.1 webpack-subresource-integrity: specifier: 5.1.0 - version: 5.1.0(webpack@5.111.1(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.30)(uglify-js@3.19.3)) + version: 5.1.0(webpack@5.112.0(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.30)(uglify-js@3.19.3)) devDependencies: '@angular/ssr': specifier: workspace:* @@ -872,11 +872,11 @@ importers: specifier: 22.3.0-next.2 version: 22.3.0-next.2(@angular/compiler-cli@22.3.0-next.2(@angular/compiler@22.3.0-next.2)(typescript@6.0.3))(supports-color@11.0.0)(tslib@2.8.1)(typescript@6.0.3) sass: - specifier: 1.105.1 - version: 1.105.1 + specifier: 1.105.2 + version: 1.105.2 undici: - specifier: 8.12.1 - version: 8.12.1 + specifier: 8.12.2 + version: 8.12.2 optionalDependencies: esbuild: specifier: 0.28.2 @@ -898,11 +898,11 @@ importers: specifier: workspace:0.0.0-PLACEHOLDER version: link:../../ngtools/webpack webpack: - specifier: 5.111.1 - version: 5.111.1(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.29)(uglify-js@3.19.3) + specifier: 5.112.0 + version: 5.112.0(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.29)(uglify-js@3.19.3) webpack-dev-server: specifier: 6.0.0 - version: 6.0.0(bufferutil@4.1.0)(supports-color@11.0.0)(utf-8-validate@6.0.6)(webpack@5.111.1(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.29)(uglify-js@3.19.3)) + version: 6.0.0(bufferutil@4.1.0)(supports-color@11.0.0)(utf-8-validate@6.0.6)(webpack@5.112.0(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.29)(uglify-js@3.19.3)) packages/angular_devkit/core: dependencies: @@ -974,8 +974,8 @@ importers: specifier: 6.0.3 version: 6.0.3 webpack: - specifier: 5.111.1 - version: 5.111.1(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.29)(uglify-js@3.19.3) + specifier: 5.112.0 + version: 5.112.0(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.29)(uglify-js@3.19.3) packages/schematics/angular: dependencies: @@ -1154,8 +1154,8 @@ packages: resolution: {integrity: sha512-jCpAvj8apa7SKHZYogk0rbXB3Kb0hLFrpkWF+Ap+vBA5rirItnpv9NKyAyEuDuFizvl0qwnj6JWR70RGJ0rOlw==} engines: {node: ^22.22.2 || ^24.15.0 || >=26.0.0} - '@asamuzakjp/dom-selector@9.2.4': - resolution: {integrity: sha512-YnVzxDxLaqL0t7Q4wfcgHZjg55Wm6y5EaO7Bhu3q9J7wq/8iw3PhsnWiOQhYekx4VexnbkgWpTT6n+QIV7kczw==} + '@asamuzakjp/dom-selector@10.0.4': + resolution: {integrity: sha512-A6f1nKy99I6tyoK82U6kBHvQQZmdHmTmPzJYPY/0eaOW0r8/qPmEOwjGHs+hL/vCgOwQTupu4LT1XtXNUuDruA==} engines: {node: ^22.22.2 || ^24.15.0 || >=26.0.0} '@babel/code-frame@7.29.7': @@ -2631,8 +2631,8 @@ packages: '@leichtgewicht/ip-codec@2.0.5': resolution: {integrity: sha512-Vo+PSpZG2/fmgmiNzYK9qWRh8h/CHrwD0mo1h1DzL4yzHNSfWYujGTYsWGreD000gcgmZ7K4Ys6Tx9TxtsKdDw==} - '@listr2/prompt-adapter-inquirer@4.3.1': - resolution: {integrity: sha512-NnKK9IrkBPr3v9DxXz/MTxQ989bJEfH1Q6Qr+MA9XU0QRXEgAQJO4XjFs8OzPQI5WYScz0kXi9WNDkANr2bRVw==} + '@listr2/prompt-adapter-inquirer@4.3.3': + resolution: {integrity: sha512-E2VRgMneFxQB1+4yeBJjAvlicWfss/U2ZXtEhUKvBVgo8zCYvXINeAK+Go2J7jB1EkOlENYVoaMxBmmhsEpB0g==} engines: {node: '>=22.13.0'} peerDependencies: '@inquirer/prompts': '>= 3 < 9' @@ -3506,146 +3506,146 @@ packages: rollup: optional: true - '@rollup/rollup-android-arm-eabi@4.64.6': - resolution: {integrity: sha512-FkO19Fowv/OQeJZPVfdetJaI3/VpbZmBsnmAlR/rQ+b3QwfiGQiOpVegpSRH331kelvHTVw9hXYG3DwjAaRzyQ==} + '@rollup/rollup-android-arm-eabi@4.64.9': + resolution: {integrity: sha512-qJmhckvOleXp8R+BaXiVW/S34/3M7pvN17/QcG90A74BDaSvKv8ffY+GYG+a/xU0vEoITzdMSiM7o9HZSQWbfA==} cpu: [arm] os: [android] - '@rollup/rollup-android-arm64@4.64.6': - resolution: {integrity: sha512-si5/Etm6MphPc2xYHnk455Shls/hoMjTy3mhXge4OPmvCw7TwC4KP4fKokAlKLV4XaQvLvgSHfafPcblLMYYdQ==} + '@rollup/rollup-android-arm64@4.64.9': + resolution: {integrity: sha512-dqQgds39BNWGB2ughJ6n2LTQFXk8RAOwnXj6m387OHpygfD93QRS1ODIfpiWyAa9gsFB9l34pSqeLmA0Xk/VBw==} cpu: [arm64] os: [android] - '@rollup/rollup-darwin-arm64@4.64.6': - resolution: {integrity: sha512-PQCl3q7b0BgvVt72i2xrWM6I5KliwwVe4GpWW5QDGyUQawDS9aPZss/aGyFqBmxdRxlE8wDc9CaxiQ5DHRSp/Q==} + '@rollup/rollup-darwin-arm64@4.64.9': + resolution: {integrity: sha512-scrMx4SGikOSbWknLmPD0v6OeJ1Wih3kyRLdNZnlVbBeKVWp1nRTVcpM0IxDJdc3u8UjesPHTmnX649u8cQpBw==} cpu: [arm64] os: [darwin] - '@rollup/rollup-darwin-x64@4.64.6': - resolution: {integrity: sha512-l9DFl1Itb1YYdSrP1K3U8ih44AOHa/p+Q4WMMDfGvH5qVWp+ajfgS1DlYo4yCRh8wJ2ZJv0Fqccf+ULAmMFjmg==} + '@rollup/rollup-darwin-x64@4.64.9': + resolution: {integrity: sha512-fkwi2OQR+QWoViRFt08Bsca6G0e9pk/4z+JgmqHq6jSRTT0LtI27KRVK8bu++6L/CBtQ3OZePbqC3bcrwGzTqQ==} cpu: [x64] os: [darwin] - '@rollup/rollup-freebsd-arm64@4.64.6': - resolution: {integrity: sha512-bR4GR3205N9+od0+l5Dd9/iZTDpJkIe6d6Ydp2qbcQZJLmKBdYQQRp8gbWpbMt92twKJY66o1vK4NkoKQODIrA==} + '@rollup/rollup-freebsd-arm64@4.64.9': + resolution: {integrity: sha512-8Apr0Khn0r2MUsDtcOMbp85fDdXsX/E+iLhO17WUjG24m3O8ChArqI0isI7CAdj9Ouq177PHtVtEUpMNE1C4Gw==} cpu: [arm64] os: [freebsd] - '@rollup/rollup-freebsd-x64@4.64.6': - resolution: {integrity: sha512-XTVNaDzcFl2TeBglvxdGgsCv9JGtAGRAoJENmGBR/XvDH2mA2K0IXc2aMfP0dR8mexSXSKifJ85FixoXX1wfTw==} + '@rollup/rollup-freebsd-x64@4.64.9': + resolution: {integrity: sha512-H+upy4DhBcBZlUsCAMyr8wR0Dg9kj8sGloVZdZ7va2heJM/5jnROxI47dtXseJjlD/VoQe6MrXhY3b5ikOq/Vw==} cpu: [x64] os: [freebsd] - '@rollup/rollup-linux-arm-gnueabihf@4.64.6': - resolution: {integrity: sha512-qWc6qbc+25ugG9vqPR9P422KJBbVfZ05mjcMggoq8tsfWP+eRfC+/tiDdIlRF5VL2pDVZWN9zAhWsmu7R1+7Dw==} + '@rollup/rollup-linux-arm-gnueabihf@4.64.9': + resolution: {integrity: sha512-b50NS9TbAEK/b16vBoKrkeNwy+HvGBXmtBbzX4wcodWOh9dQZvRTN9rUyElIXa36QnwXhU9PAVVkZpqRzSi2Tg==} cpu: [arm] os: [linux] libc: [glibc] - '@rollup/rollup-linux-arm-musleabihf@4.64.6': - resolution: {integrity: sha512-V4Nwkp8844X/Xnww3PI1LYS0YPei8XQEVG70R+5MPZGO7AhYoun4hCN7Svs4U3wbQLZbwiz+9xRFhUZZdRl8Ww==} + '@rollup/rollup-linux-arm-musleabihf@4.64.9': + resolution: {integrity: sha512-SdqcudB/FzjLESsRMgXhV+FXGtf6usxXwlMoRW7D/XS3f9CZ4T4wycRBu2h9bVl2AOaPpunoA8ftAM/MF4altQ==} cpu: [arm] os: [linux] libc: [musl] - '@rollup/rollup-linux-arm64-gnu@4.64.6': - resolution: {integrity: sha512-xb72A1aPaaIsp+a88VtRae/ovIEXislbUMyp7b9AQQU7ZkP2m/+ik6DW9TQcJyw5R8/RIailF9zExYwkjR++UA==} + '@rollup/rollup-linux-arm64-gnu@4.64.9': + resolution: {integrity: sha512-dg19FFRoovN+KZ+gMHBAq4Do8PgQmBcxpuhux57OuiR0QLavfn8uPBY8CP+UO50bO+xf0tK0GlqI/jld++5E6g==} cpu: [arm64] os: [linux] libc: [glibc] - '@rollup/rollup-linux-arm64-musl@4.64.6': - resolution: {integrity: sha512-pbcs1BVBwC43hZkjhjlF8Rx8m5G0KnhLZs9Azy/gqccP6UsNSzJr0hKGIAVPqzAH1O/NdPxxC9GVGb4msQg/aw==} + '@rollup/rollup-linux-arm64-musl@4.64.9': + resolution: {integrity: sha512-+jyv5ofGmpAvtrzLjSr/e4syskeikEp5L82bUzB76auwOgK1VNVwZV/F2g1Pes9bhTznbejOefAqPglHSKYmTA==} cpu: [arm64] os: [linux] libc: [musl] - '@rollup/rollup-linux-loong64-gnu@4.64.6': - resolution: {integrity: sha512-EKOC8os6Vsg487ZLKUqzLF99Jsmnq6tu7O7mAELakNpcA+8KadktFf/JYdRuHe/DzCUXmN38pUKu4XBcKlqGbQ==} + '@rollup/rollup-linux-loong64-gnu@4.64.9': + resolution: {integrity: sha512-MKFXxqmkzCbtNvx/vjiJdss44eRtVabhCtDWcCFD9NHGwP+YkqnM/slnEsv/3fsoq9ukTtudraAjGhptrUPCVg==} cpu: [loong64] os: [linux] libc: [glibc] - '@rollup/rollup-linux-loong64-musl@4.64.6': - resolution: {integrity: sha512-v/SQ68GnSlr/HyjB79sNXesGDwkOPu9JjbHfmWaymCiM+nZsQ9TstG1KfA4MuEvTr2d3PoY8PhFxj9bt0e32JA==} + '@rollup/rollup-linux-loong64-musl@4.64.9': + resolution: {integrity: sha512-lhARcOT6n7Ni9hpQRq8LZjbuoW+G/GXaW4Jfhx2MbmjnCj9XxLMRTceJIMpiMLQVWm+qxe7oq1sYvlIGOAW34Q==} cpu: [loong64] os: [linux] libc: [musl] - '@rollup/rollup-linux-ppc64-gnu@4.64.6': - resolution: {integrity: sha512-G3pmliMQ7r15zFFNwBlaT/xTdSLi4lfgI7CUrQueyKYheNVhrd8JrWCE6Ll8xf4AA1RZFqq+mNJYntiElsVOyA==} + '@rollup/rollup-linux-ppc64-gnu@4.64.9': + resolution: {integrity: sha512-oORQzGxZ1oHghJwLdwc8Ni0SY9otILAeXsWdiImTF4F5HkWJUwh5s/269PF5tYILNC1z/3RwFsrgcHPguBcb0g==} cpu: [ppc64] os: [linux] libc: [glibc] - '@rollup/rollup-linux-ppc64-musl@4.64.6': - resolution: {integrity: sha512-XQTB/IPoB/wG6x/wu9uomAt8YH61IAr5iZTubMiad/lu88sotq2ocz9hJd556+Jz2kIkF7ZQZIsUuWE3OWqtcA==} + '@rollup/rollup-linux-ppc64-musl@4.64.9': + resolution: {integrity: sha512-J2JQHQt7oR1uutd2OSwbV2Qpb2LI5gggPolbkUwDe7vn/0dnduZ0w6EIbGnZUAw7uIKaMgfVylcH6V+Aov8kRA==} cpu: [ppc64] os: [linux] libc: [musl] - '@rollup/rollup-linux-riscv64-gnu@4.64.6': - resolution: {integrity: sha512-O5mpokth6+ydMuwiGtY8fIjvOBfH7u6SzmDNmZ3k6GK5C6iEAC2q2ZN/T5L9jYILx0IcCT0KnfMDihQ5yQFSBw==} + '@rollup/rollup-linux-riscv64-gnu@4.64.9': + resolution: {integrity: sha512-bWaKLrfzeQ9mOzJJxXbPgw2RH6VAaTJrb/60Tqf7YSMxubG8780Hzm7Us+D6qVW8QRGJYl4VUvVXxnRB0o9zvQ==} cpu: [riscv64] os: [linux] libc: [glibc] - '@rollup/rollup-linux-riscv64-musl@4.64.6': - resolution: {integrity: sha512-aIFxbAD9v3TvIaEDsKmukjcDg1JS4/tFXw8SHyQQgzOwzWCQ4cyDK7Ju1pQKqUXDFkEu/BZCFDCDATsKhQcB/Q==} + '@rollup/rollup-linux-riscv64-musl@4.64.9': + resolution: {integrity: sha512-TFJyaCB9NsvSyvVGQgTSRD9XgxsAq99ivDDkt9KAySlrNW5Obsd1kQpvoCvBCOLq+JlJTjmtroLH0wp8M8mEsA==} cpu: [riscv64] os: [linux] libc: [musl] - '@rollup/rollup-linux-s390x-gnu@4.64.6': - resolution: {integrity: sha512-fuNo1UwBc6BxnHDOxxguQL/InhheMN3RJcJMb0b4xP8r5Q3CNCrJbVg0eCIFuJ4e/zAfjR2gYbOfbzO/G7CIyw==} + '@rollup/rollup-linux-s390x-gnu@4.64.9': + resolution: {integrity: sha512-DvmOM5xz/wDnUJFVjqP32ahalxn7BDuvO25bpuFOrb50AIFCCcFPN4lWWUDD1c8Ddv9sMO9SXyqtOet8G8u9cQ==} cpu: [s390x] os: [linux] libc: [glibc] - '@rollup/rollup-linux-x64-gnu@4.64.6': - resolution: {integrity: sha512-05v6wFKDKJPZs9xlytVrrRu6IbRuoSvlH9xNwEOafXsKyjBFZPvAcZz2VIAB/M+lblYeKa9iOYC4RDVdfcAAaw==} + '@rollup/rollup-linux-x64-gnu@4.64.9': + resolution: {integrity: sha512-aFzokHK3yE00mzAvKm/PY76OsOOTjvoTGE82Vp89iBDyD2wUBlV4ZsR2tWkRECTEFk6TC4Yc3zaEWjPqq1vstQ==} cpu: [x64] os: [linux] libc: [glibc] - '@rollup/rollup-linux-x64-musl@4.64.6': - resolution: {integrity: sha512-wJXKcdMjvkc/FaavZXNP1yW4i0pfOmhZAIWRSLG2yJ0PB0TWi7dkLErhX0u0vptDcXKKO/m1Y/YTeuyvb2MXwg==} + '@rollup/rollup-linux-x64-musl@4.64.9': + resolution: {integrity: sha512-t/yMdeaaQUuNNpmT7taBmH2VvHzgT4YA/IaKVE3qVr4PYQemn/kmJkL4uG4UvTLcWXQd0MSoOa/3URYSWGmUEg==} cpu: [x64] os: [linux] libc: [musl] - '@rollup/rollup-openbsd-x64@4.64.6': - resolution: {integrity: sha512-cwg7/h0ThvJwy8CBkmACdiHAxRWpbsCmIsjOt+Zzx0hTnIcSUmKYEV03bGg+hD827OnwUsbKh1ZZDW754xWyBA==} + '@rollup/rollup-openbsd-x64@4.64.9': + resolution: {integrity: sha512-4dnxKQ8GHARyjqAU87q5UWhywZTpIbR2VWhtACdC37GD1SGszmvb3TaBFVA4n+fnDHSKMut4ZJ63hVFwgnxVtg==} cpu: [x64] os: [openbsd] - '@rollup/rollup-openharmony-arm64@4.64.6': - resolution: {integrity: sha512-T0RkYIJbdYXJEQFw+tMBO09KDFdgmNxkHsof3wWAABrvnx15Yh8RytmrgYy9+q9cBeBNZF66MMQZC+5nzEz6vg==} + '@rollup/rollup-openharmony-arm64@4.64.9': + resolution: {integrity: sha512-1qdQj6IrNoR0xFvrCQHmhBXe9HMbBGNTFi+3n4jKMt2rTx4k0aeAdraZU4WDOMfL9tAwS8/TRSuquvNuPQ+Gpw==} cpu: [arm64] os: [openharmony] - '@rollup/rollup-win32-arm64-msvc@4.64.6': - resolution: {integrity: sha512-KlfpmF1AAIdAWxt8QQNClbpLFlAUfYOzqIuJ7IXEStMHpFRuH78RG6FjqPb3Rqhh0K89F5npvG+/i3Fjl6IveQ==} + '@rollup/rollup-win32-arm64-msvc@4.64.9': + resolution: {integrity: sha512-yc1GSEHIYhKGN5WSaJc+eMy8bZvzcvAmflEgFh8L3xcy8dYxGmfrudyBnBFde9f6JzOa1kFqocF8BHaWybjQoA==} cpu: [arm64] os: [win32] - '@rollup/rollup-win32-ia32-msvc@4.64.6': - resolution: {integrity: sha512-MrTLjd7Jlt9/ZavJZYG61KQv9Iy9bzbY+yXy73Xvwoa2uP66wvDShkyBr5Chz/yrE6lbD/zHMuTmKQVNQqBApg==} + '@rollup/rollup-win32-ia32-msvc@4.64.9': + resolution: {integrity: sha512-VzHGvosAkLIzrwqvSgJBPDmGFTF/yE8OtMT4H5z8pM1NA0NiPpvTYnUh+9xPd+d5oy/wqF317FmJ1I8Kk8pp0Q==} cpu: [ia32] os: [win32] - '@rollup/rollup-win32-x64-gnu@4.64.6': - resolution: {integrity: sha512-8fWDH1CkPI8GdBKAxzHDza7UmgficsKo2+MVbvUgOGhB0629w5sHMg3Qu5y7TZsrYKHHWpz8fla4KvoT7WsO3Q==} + '@rollup/rollup-win32-x64-gnu@4.64.9': + resolution: {integrity: sha512-FB77txy1PiAcJgG72nOLA6R0S3PRZahs8Spx0z2yseDUkoMmJcrQghiebJ2JHZ74cCOVlX/MYd4dUbJtJJ8fow==} cpu: [x64] os: [win32] - '@rollup/rollup-win32-x64-msvc@4.64.6': - resolution: {integrity: sha512-9/c9PWdr5GCIHkkxiHM1HjNBQMVdftP4O8QTcoUAaRza2FSqJ4axbf8QAnBuE6BIGQDl71SaRPeDdDYid5ecTw==} + '@rollup/rollup-win32-x64-msvc@4.64.9': + resolution: {integrity: sha512-IoIgQLpK1DbOcQf1vX+i5oe5LXypsCVb1j/mU6BLAbOGmXH4E+j4kMfgZRwPYUohVBurNyVMgIKVM5dR6xA0kA==} cpu: [x64] os: [win32] - '@rollup/wasm-node@4.64.6': - resolution: {integrity: sha512-ufelhiGxNl8RuflC/Tie5ZVcI3MJUtd27nJ0jC2I4LroyZb7n4iwmajEmXXeTLxJtDiiWUwU8v2UjkACBHqQvw==} + '@rollup/wasm-node@4.64.9': + resolution: {integrity: sha512-CNks3vhhgXJ/HXuOOvXEY8jyovEJQ0yCnCYeBwA/rsjeASKrr+wSbMZi+AtuDoAWQ/8oQFkSiOFzt/FP3H0D8g==} engines: {node: '>=18.0.0', npm: '>=8.0.0'} hasBin: true @@ -4014,11 +4014,11 @@ packages: peerDependencies: vite: ^6.0.0 || ^7.0.0 || ^8.0.0 - '@vitest/coverage-v8@5.0.4': - resolution: {integrity: sha512-P5YcQY8Y6RmoE9xRXI38rT8pssbcubEzqtYTM2XQoxOXMDn04nRaTI1SM8qCl9/NfW3ag9GlzdSXu7IwO5Ft8A==} + '@vitest/coverage-v8@5.0.5': + resolution: {integrity: sha512-4KpkGdIrSqBihx/JyP/e+S+IKB98etg1XDQiLAxksLfcShnwi1VReGeOT9NI43hLHbknosKp/1CCLn9Zgcs8mg==} peerDependencies: - '@vitest/browser': 5.0.4 - vitest: 5.0.4 + '@vitest/browser': 5.0.5 + vitest: 5.0.5 peerDependenciesMeta: '@vitest/browser': optional: true @@ -4031,8 +4031,8 @@ packages: resolution: {integrity: sha512-gUsfXZJbzPamoIY5TvHFiMMoXESBrUMo+xqaj+rYrWI69+EnvRlYBlP96ZnHPY4vX8kyUpgAnFUCg5wZG/HkDQ==} engines: {node: '>=22'} - '@vitest/mocker@5.0.4': - resolution: {integrity: sha512-tqAlrYWce4iUxhr3ncNohejtCTOcHeE8XWrSNZY3OhPoDn01yeGv+gnaBy64ATp7o6pb03eIbBAjzmibpc9vIQ==} + '@vitest/mocker@5.0.5': + resolution: {integrity: sha512-xLL3lkDegJZw+MGoGaCCsFayDZthGgpAtr3Vziyfc4p7xH89K7KRPcRBBh/kEYm0Aqkt5DtTmkYpBtRV/FrHZg==} peerDependencies: msw: ^2.4.9 || ^3.0.0 vite: ^6.0.0 || ^7.0.0 || ^8.0.0 @@ -4042,8 +4042,8 @@ packages: vite: optional: true - '@vitest/spy@5.0.4': - resolution: {integrity: sha512-MZKk/gSkm2q+ICobMxCpH1mA+cCAWm8WV7UhxlqGjq/sJ3AGc1BqFOs5CRVXxH78wQtme9q/NAAgBquj4AcyMw==} + '@vitest/spy@5.0.5': + resolution: {integrity: sha512-lwJRExuH417257Q5wv9QYugN9IMJkoxcrKrYxGPQkBzl7wlNpTUxD/5yNX4ESKVUIShKPgkGchYPFMWOOk0wzw==} '@webassemblyjs/ast@1.14.1': resolution: {integrity: sha512-nuBEDgQfm1ccRp/8bCQrx1frohyufl4JlbMMZ4P1wpeOfDhF6FQkxZJ1b/e+PLwr6X1Nhw6OLme5usuBWYBvuQ==} @@ -5416,8 +5416,8 @@ packages: resolution: {integrity: sha512-tD40eHxA35h0PEIZNeIjkHoDR4YjjJp34biM0mDvplBe//mB+IHCqHDGV7pxF+7MklTvighcCPPZC7ynWyjdTA==} engines: {node: ^20.19.0 || ^22.13.0 || >=24} - eslint@10.12.0: - resolution: {integrity: sha512-npHjrHb2o4ehH3mE+YuxABR+0gyb0aVWCIolgJDArwCiHEIsonBm3ZKjel5b0U5+a+MbEvIyRCGCzD3eKKK2NA==} + eslint@10.13.0: + resolution: {integrity: sha512-UohDjD4zSzEwhf58M3O7vc/ycc8O1I7dNlhtD0WxE8Px8EHNJKtUwzBqrzeGhisRuv2ag4sAYswszCJRgKXYUg==} engines: {node: ^20.19.0 || ^22.13.0 || >=24} hasBin: true peerDependencies: @@ -6321,8 +6321,8 @@ packages: jsbn@0.1.1: resolution: {integrity: sha512-UVU9dibq2JcFWxQPA6KCqj5O42VOmAY3zQUfEKxU0KpTGXwNoCjkX1e13eHNvw/xPynt6pU0rZ1htjWTNTSXsg==} - jsdom@30.1.2: - resolution: {integrity: sha512-0FFE/jE1rppmVfUrJUgxqXjcwolZYIGtAgj1pTussMhNZxIxi7W/PvfWaMNroGi2B36X1IKHbexpZ9DhkoOPiQ==} + jsdom@30.1.3: + resolution: {integrity: sha512-hQMUPvRgN7KxsfIytDQji7bimuJeRQa6Qo5+iuiZQk5CafeRxLIA10/cG5YCBFNpD9RO3oqIiN4CO1Y44kxqXg==} engines: {node: ^22.22.2 || ^24.15.0 || >=26.0.0} peerDependencies: canvas: ^3.2.3 @@ -6545,8 +6545,8 @@ packages: lines-and-columns@1.2.4: resolution: {integrity: sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==} - listr2@11.2.0: - resolution: {integrity: sha512-+H/hEo9EA7tyLY0ZihpDg76jHWolc0nCjbjnXFguSm4Epk+WYtL1w1tYs1kjEo229NmhgLmUrncyn81K1vBoRw==} + listr2@11.4.0: + resolution: {integrity: sha512-N6jpS9lEmqGcWqJqryuOfjPUTn7mcDvG5ndsTlZk4Aohwfywc7deqjscI9lm7K+FHS6anZmazE8/IQxQfVTHZg==} engines: {node: '>=22.13.0'} lmdb@3.5.7: @@ -7625,8 +7625,8 @@ packages: '@types/node': optional: true - rollup@4.64.6: - resolution: {integrity: sha512-fX1Vy+UNKdXn+xKDnu/HBXbHVr1AY8cSdQj9BU4kLv5aFCMqGpvrVbyUMmjN3DdzWhSAuTbcX8PCNEVaumthYA==} + rollup@4.64.9: + resolution: {integrity: sha512-mnPSQINChN7PpT+a5CI0/+87hm/+6zxSKBK1XonrzQ0zFnglaTjhkTP2Br4yNCTcLHUEvrAfZffH57jGf+8xBQ==} engines: {node: '>=18.0.0', npm: '>=8.0.0'} hasBin: true @@ -7679,42 +7679,82 @@ packages: resolution: {integrity: sha512-kN0G03K9KoUbSf72t7ZvxAudcB4Wbf0M0XFaPc1gaF94jEPUb0xLCQUIPIDPH2Kx8vpYZ/GzzgF7USsB6rUYfw==} cpu: ['!arm', '!arm64', '!riscv64', '!x64'] + sass-embedded-all-unknown@1.105.2: + resolution: {integrity: sha512-GqjZMao18JekkkSWIoKOsmxJRGPF1c7fPXK8bn1AP0nrtYzCX7pvid0rmHcCi1Ww6DfDVbjkif52PCCupuPIOQ==} + cpu: ['!arm', '!arm64', '!riscv64', '!x64'] + sass-embedded-android-arm64@1.105.1: resolution: {integrity: sha512-lWnIFmW3gL4ZDfZgjeUfxazmA0zlwSS/ADe2q9XmP0W2UfM9kuvrXdWvp6KjZOCv0CrTYVQMrIUj8Of1L2M24Q==} engines: {node: '>=14.0.0'} cpu: [arm64] os: [android] + sass-embedded-android-arm64@1.105.2: + resolution: {integrity: sha512-9v5TtqYzpjw0cEqojXPzHrOGqgEOLNbmV8iPEL9RU+dDBoCW6fKfZqYLtbwaB/1fcZMGTZYxiLd8wDLi66IlIw==} + engines: {node: '>=14.0.0'} + cpu: [arm64] + os: [android] + sass-embedded-android-arm@1.105.1: resolution: {integrity: sha512-WYltUXkUP9jDaUq4uUiLgZXyYO5c72sa/TvpO4E2MMRdS+WJWgrPUDyvO+DpMR9gKWIm0QQ5cCEYnPDgovjVJw==} engines: {node: '>=14.0.0'} cpu: [arm] os: [android] + sass-embedded-android-arm@1.105.2: + resolution: {integrity: sha512-BCFgxtW2HvWjedNTRA6dVo8EXxeQzk4dUymfr9A6SO4ReZKS6XkQrFsTEEdmYa7KTtZg9iOunCS6asSk4cmHNw==} + engines: {node: '>=14.0.0'} + cpu: [arm] + os: [android] + sass-embedded-android-riscv64@1.105.1: resolution: {integrity: sha512-lWity0qhyQyPgkHUfZz+4IeD0r6mcAqG9KzOwVSjUrcSR9xAfWFKYAtHTA05R28ymyXf2Sf2+XfNV7YkxLgkUQ==} engines: {node: '>=14.0.0'} cpu: [riscv64] os: [android] + sass-embedded-android-riscv64@1.105.2: + resolution: {integrity: sha512-+1dNjHu0N8GlLTawCHU8zrqLQms52aof6WYoExGp1BO3xHH7eCnxyIxd2FWOj2ttDhUyEpK8Odp+gYaxhpNMIw==} + engines: {node: '>=14.0.0'} + cpu: [riscv64] + os: [android] + sass-embedded-android-x64@1.105.1: resolution: {integrity: sha512-FRGZuIZ9eS3qutYPFqz8u12Ti9ccyWKWb7F7rKRI1BkIEmLZV1rC862dUGnTV2d9Tk9qbSAXL71t8alUR+fzIA==} engines: {node: '>=14.0.0'} cpu: [x64] os: [android] + sass-embedded-android-x64@1.105.2: + resolution: {integrity: sha512-+4Ga77s76LSCml6n2kJ8tDtRuwS/T83OCEvsGp0BCz8HX3L9edFGmHO3ryYcQEbmxiNlhc3tzuVW/enfhiefqw==} + engines: {node: '>=14.0.0'} + cpu: [x64] + os: [android] + sass-embedded-darwin-arm64@1.105.1: resolution: {integrity: sha512-75qVpHj0qwJKWOo+ZA5NPVFnOGfRrUiBdnLR0dPqsvzp3acvb5gBevptqTtJjVWubpYRIjcRdDDjmeWoXnfacQ==} engines: {node: '>=14.0.0'} cpu: [arm64] os: [darwin] + sass-embedded-darwin-arm64@1.105.2: + resolution: {integrity: sha512-aVRTgD8yisk6q3SWnI0CquIU5OiWtCBBmZHEoQMQdlqMBJLmO8+gSQ5qNfBkn4shkiY93dEDpK7xP3vsQzicXA==} + engines: {node: '>=14.0.0'} + cpu: [arm64] + os: [darwin] + sass-embedded-darwin-x64@1.105.1: resolution: {integrity: sha512-5TV8xyZrOO89ky752favkTuyz9O2hOB2aMoiUpMTk0rFr+UVANcXdIrEvJ9WKoqTHaszim7un3jADumunpW7zQ==} engines: {node: '>=14.0.0'} cpu: [x64] os: [darwin] + sass-embedded-darwin-x64@1.105.2: + resolution: {integrity: sha512-Bsfijwi4VkB2Uva6LEbA9AGeGd56HmnN36hjsfa9ibsQdLy3ZPwjFMujQCkYrrA4ISxxymMX3vMmDO8RB/F0qg==} + engines: {node: '>=14.0.0'} + cpu: [x64] + os: [darwin] + sass-embedded-linux-arm64@1.105.1: resolution: {integrity: sha512-arALlVQkXjxN1RPaQR41vbDYXrTIdXwPtEzBWRkOg7FdIN/dSohY8ik96M6M3MSc+niV/UIC7BO47PcspzJGpw==} engines: {node: '>=14.0.0'} @@ -7722,6 +7762,13 @@ packages: os: [linux] libc: glibc + sass-embedded-linux-arm64@1.105.2: + resolution: {integrity: sha512-brEilUD9qlnzau/FiYc2k6h1+6WpByktuj/mAPEFftvLEXtes+e3/TTdTMUlS2RFkdeM0FDhIwjrkMSpYqEmow==} + engines: {node: '>=14.0.0'} + cpu: [arm64] + os: [linux] + libc: glibc + sass-embedded-linux-arm@1.105.1: resolution: {integrity: sha512-Ng9GWIF6heTrwc9r/FFY9oUSoaylV2zcS296Qo2re3tJfLMWR37O2JUMyzPT+vtkRs8k3JOE6jTFVlXYnz4EAA==} engines: {node: '>=14.0.0'} @@ -7729,6 +7776,13 @@ packages: os: [linux] libc: glibc + sass-embedded-linux-arm@1.105.2: + resolution: {integrity: sha512-JJ4UYZweLZTU2f5lbjJ8Z/L018X8Y0ennRabFeVVRws43F5TXu3tKevwi4mg7kM97kI7jArfyIZIkyoHlU1opQ==} + engines: {node: '>=14.0.0'} + cpu: [arm] + os: [linux] + libc: glibc + sass-embedded-linux-musl-arm64@1.105.1: resolution: {integrity: sha512-KizYVR3d70U67iLgKdF+HCKBdQYUxYiv0YWCS3zl6GwNGIbGXlkOtnjxus41CKTA4oOK0KsSus9P5zwhOBjiYA==} engines: {node: '>=14.0.0'} @@ -7736,6 +7790,13 @@ packages: os: [linux] libc: musl + sass-embedded-linux-musl-arm64@1.105.2: + resolution: {integrity: sha512-wPj0bgvkDrKZQV4uFXMJu0v61LdBaWpcZU/ok2xce4Rdu3PC0LP+2DeLBssrDU6A0GFxxkQwVdb4xcSCWVJt4A==} + engines: {node: '>=14.0.0'} + cpu: [arm64] + os: [linux] + libc: musl + sass-embedded-linux-musl-arm@1.105.1: resolution: {integrity: sha512-7u932XawHxGZvuYV4pOqcCvQi05yMONDmNDxVNh8Q7KmpytQP7mnyxBOYWStiw/p665AVL6BYGe7WY/vzCcWGw==} engines: {node: '>=14.0.0'} @@ -7743,6 +7804,13 @@ packages: os: [linux] libc: musl + sass-embedded-linux-musl-arm@1.105.2: + resolution: {integrity: sha512-s2mPkPYtW97l+01VxAeivGBAU/nRdnppb5m5ZfydAwn5lU9dOua8yy+fXKmoSNn4m9yxn0nZief0miY75JyoLg==} + engines: {node: '>=14.0.0'} + cpu: [arm] + os: [linux] + libc: musl + sass-embedded-linux-musl-riscv64@1.105.1: resolution: {integrity: sha512-gs84BgRBVNMX5fHRU3wxc3HuJjl0dUmZFpcVIaDDEVhnp5oXFLQp+gEu0xBBAurTzCHVpPU6GlGK6B1gRKmbhg==} engines: {node: '>=14.0.0'} @@ -7750,6 +7818,13 @@ packages: os: [linux] libc: musl + sass-embedded-linux-musl-riscv64@1.105.2: + resolution: {integrity: sha512-ut/LWn4yV1718FopQxU4pbeeyxNUOsYeoUjqtmTa0AI4j+Ruy9V+yCMNVfZXxrbYmlQ/6KUDZPcqZPJqKG5M8g==} + engines: {node: '>=14.0.0'} + cpu: [riscv64] + os: [linux] + libc: musl + sass-embedded-linux-musl-x64@1.105.1: resolution: {integrity: sha512-jFSRc1BSoCo0bw6GXmBWQMzdj0FBl2FTKSRqQSye3vmlI9O466DwBK4OQL9HRp6MGdY9IQFFMZLPZo5LJWIPsQ==} engines: {node: '>=14.0.0'} @@ -7757,6 +7832,13 @@ packages: os: [linux] libc: musl + sass-embedded-linux-musl-x64@1.105.2: + resolution: {integrity: sha512-h+IMF36ymyshJCahILllQPOFh4Z9V6xDu2sE9MY9eJkYPT8KlJ9baQh0l7mnkSMMch7H4bIjd8srEW7mYQKilw==} + engines: {node: '>=14.0.0'} + cpu: [x64] + os: [linux] + libc: musl + sass-embedded-linux-riscv64@1.105.1: resolution: {integrity: sha512-tkZs6OvA+omJgSf8EaPQavq6M7bJNLm88eKt3yzYnBy0dVGMao4+lyRb/EnsgIq2R/B2lhxUHhSVNWAcY5bgXw==} engines: {node: '>=14.0.0'} @@ -7764,6 +7846,13 @@ packages: os: [linux] libc: glibc + sass-embedded-linux-riscv64@1.105.2: + resolution: {integrity: sha512-huWVMN6VGxo8Prc7c5K8rYxmENNuMcD4Q2Jm/4LtoL0+HU8OeCq/ixRSXd/D+pGNiwzh6Kq6S3rX3PIfAVwd/g==} + engines: {node: '>=14.0.0'} + cpu: [riscv64] + os: [linux] + libc: glibc + sass-embedded-linux-x64@1.105.1: resolution: {integrity: sha512-YF4OyymSlm26OcdPovIZL1blzjTxf5yN/rzgTmoGqAjEk57+yIuYo+7jBCgSQZFov8Rn4uHhZT+u0cpzxNFMRg==} engines: {node: '>=14.0.0'} @@ -7771,27 +7860,55 @@ packages: os: [linux] libc: glibc + sass-embedded-linux-x64@1.105.2: + resolution: {integrity: sha512-ms4LEVWt6+yIbRAOosPMoHpQPT+60+x9KJM6JSviTvBsOhtjbT/Y+otdpAoXotjE3VDgOshnOAUxyazluUIvcg==} + engines: {node: '>=14.0.0'} + cpu: [x64] + os: [linux] + libc: glibc + sass-embedded-unknown-all@1.105.1: resolution: {integrity: sha512-bd2zDf+MdoPdRDH1awSQ+IL67vHvCbiKsWJ95XchPg3I67zQlXjTSf9KqRiE6twjNT1fRV82JUKoc0Hf6CUmfQ==} os: ['!android', '!darwin', '!linux', '!win32'] + sass-embedded-unknown-all@1.105.2: + resolution: {integrity: sha512-mRCho+NEe4AN4x3QKiRBy31dZwivfsYZFYuqzdN4PpiQfquY/IzwgbMgWp6w1/wDMKr5oUyk000YuhKCiVR2Sg==} + os: ['!android', '!darwin', '!linux', '!win32'] + sass-embedded-win32-arm64@1.105.1: resolution: {integrity: sha512-Zpp/RWYL8ZzpLzBrs+/UVMEHOHx7sw4nlq2R52dKQ0qv/0V8oKemAy41PZyLir3c+S2C+YViYyfnFfQLRTAzuA==} engines: {node: '>=14.0.0'} cpu: [arm64] os: [win32] + sass-embedded-win32-arm64@1.105.2: + resolution: {integrity: sha512-UtpUt3B7kRyymLSmEcW0qCTU89qH3r5xaboaKD5Fb3x+PzGA/I3rNu0yn1GI+94Qp4BkAqbLXNdd1Dda7rOC/g==} + engines: {node: '>=14.0.0'} + cpu: [arm64] + os: [win32] + sass-embedded-win32-x64@1.105.1: resolution: {integrity: sha512-DM8EkMDzEsxnYoy11nyA5I4jr8lOV1TVQ/drNYvFQA9undiMzZD+7SkRA0OnCrgD1uCT+uRArCHSpNiiYVks+g==} engines: {node: '>=14.0.0'} cpu: [x64] os: [win32] + sass-embedded-win32-x64@1.105.2: + resolution: {integrity: sha512-O5eP1eUuyaU7RgBgA3/aYKXUT3FqHo11C5MbnHqwBDSMY5tZ+nMqcLVS0yZpzkJs3JOWj3fO6o/6fG+b+PzMpA==} + engines: {node: '>=14.0.0'} + cpu: [x64] + os: [win32] + sass-embedded@1.105.1: resolution: {integrity: sha512-9tKxXG4rq+oGTZUlQehWZwHxBTL80EiB8IWk9AEqz8uOqg910t88JIYbN92eMCxokQ5vrYSQxg15bh0o/3hh3w==} engines: {node: '>=20.19.0'} hasBin: true + sass-embedded@1.105.2: + resolution: {integrity: sha512-I8uIL7+eE3hPL/Ms2yDY7Km0lsn8xbgqUc231WaWuv+uUphy5LRgRQvMm/MQb9nx/okN9lY47x7sJbVk4o4JYQ==} + engines: {node: '>=20.19.0'} + hasBin: true + sass-loader@17.0.1: resolution: {integrity: sha512-pgJMwCuLjVTSIWsv/2luVRXKlCeaViUGcgSe8dx95zMG4hUwqIMFmjbhq29ypFLflJU0GyiJZeLM9iI1n3KYAA==} engines: {node: '>= 22.11.0'} @@ -7815,6 +7932,11 @@ packages: engines: {node: '>=20.19.0'} hasBin: true + sass@1.105.2: + resolution: {integrity: sha512-KxW6ZKZiBKWK3ziQ4YZ3cpqo8/1TlHXE8t9nBNvGDZFoBFbk2MD7RacxYFs8zy8hzeFwpFYkVyAhboi47uYPEQ==} + engines: {node: '>=20.19.0'} + hasBin: true + sax@1.6.1: resolution: {integrity: sha512-42tBVwLWnaQvW5zc4HbZrTuWccECCZfBi92FDuwtqxasH+JbPB3/FOKb1m222K42R4WxuxzzMsTswfzgtSu64Q==} engines: {node: '>=11.0.0'} @@ -8350,14 +8472,14 @@ packages: resolution: {integrity: sha512-R+RODBqp6i2pPflGdq+xIOUkl+RNfGgHwoinecKu/JCuf2uO06cOKoDbI2P7Dn6KcswdKwrczbU6IYJ6K8X+wg==} engines: {node: '>=18.17'} - undici@8.11.2: - resolution: {integrity: sha512-u4UB2/IrKdU6lFxumHmmo1a3fCQO5tzQllRorfoRS63txhrB7xTpSn1PftwC4qEHkOaqP95fCWW4lJzwErwzhQ==} - engines: {node: '>=22.19.0'} - undici@8.12.1: resolution: {integrity: sha512-usz3OVQBeh1LxNn0DzU0voLXMgn5CU/WUdpBsY6Ti5afNao+vTkmn4H/NxoXolc10cOqe2+YIG0Hspq2rsl64w==} engines: {node: '>=22.19.0'} + undici@8.12.2: + resolution: {integrity: sha512-XtuDWVdqTLr3NAxm2ly9/hU6kUsJOgGh1RASzMBbsw6aWCOaQzHdW+QQDfdERjfJ2V5vL5pRPa4RetO9UfivDg==} + engines: {node: '>=22.19.0'} + unicode-canonical-property-names-ecmascript@2.0.1: resolution: {integrity: sha512-dA8WbNeb2a6oQzAQ55YlT5vQAWGV9WXOsi3SskE3bcCdM0P4SDd+24zS/OCacdRq5BkdsRj9q3Pg6YyQoxIGqg==} engines: {node: '>=4'} @@ -8505,20 +8627,20 @@ packages: yaml: optional: true - vitest@5.0.4: - resolution: {integrity: sha512-z0WxZRV2Sg48wF0FSgMq3TFG8JS38/Qr96vZVZdX6+Em9raQTvnXQvdTFJe2m3rfyJnEHeHQ/snceIdi8D1pVg==} + vitest@5.0.5: + resolution: {integrity: sha512-cPODOMF8YnkiiYtDdHo6n4wWmBrOBBbOIYH2d33M4l3CdNn72h+qMmO6uXffUN6A5AZFXNND/d+krS9mgkXRfg==} engines: {node: ^22.12.0 || ^24.0.0 || >=26.0.0} hasBin: true peerDependencies: '@edge-runtime/vm': '*' '@opentelemetry/api': ^1.9.0 '@types/node': ^22.0.0 || >=24.0.0 - '@vitest/browser-playwright': 5.0.4 - '@vitest/browser-preview': 5.0.4 + '@vitest/browser-playwright': 5.0.5 + '@vitest/browser-preview': 5.0.5 '@vitest/browser-webdriverio': ^5.0.0-beta.5 || >=5.0.0 - '@vitest/coverage-istanbul': 5.0.4 - '@vitest/coverage-v8': 5.0.4 - '@vitest/ui': 5.0.4 + '@vitest/coverage-istanbul': 5.0.5 + '@vitest/coverage-v8': 5.0.5 + '@vitest/ui': 5.0.5 happy-dom: '*' jsdom: '*' vite: ^6.4.0 || ^7.0.0 || ^8.0.0 @@ -8558,6 +8680,10 @@ packages: resolution: {integrity: sha512-6i/00NBjP4yGPs+caKSyRfpTF/8Torsu0MOW3mMzIbhgISFder8i7xbqgHlLMwJrdiN8ndBV3UA1/AfzPSr+jg==} engines: {node: '>=10.13.0'} + watchpack@2.6.2: + resolution: {integrity: sha512-67nxRd7I5uAyn+KamYsCqU30iVgCgZ4aj8ZOGzmxs7zNPuvlnoYltm6+6JkOjEcD6WVXdu1BfH+gVQs3FUuW7Q==} + engines: {node: '>=10.13.0'} + weak-lru-cache@1.2.2: resolution: {integrity: sha512-DEAoo25RfSYMuTGc9vPJzZcZullwIqRDSI9LOy+fkCJPi6hykCnfKaXTuPBDuXAUcqHXyOgFtHNp/kB2FjYHbw==} @@ -8578,8 +8704,8 @@ packages: resolution: {integrity: sha512-BMhLD/Sw+GbJC21C/UgyaZX41nPt8bUTg+jWyDeg7e7YN4xOM05YPSIXceACnXVtqyEw/LMClUQMtMZ+PGGpqQ==} engines: {node: '>=20'} - webpack-dev-middleware@8.3.0: - resolution: {integrity: sha512-jFNNMB29ugmkEUFW9cpWNqcWFQNwuMTMVoRpKVAiz/5nh3gA4x9x6DRPhNHGc/SLre7pEP9yrAPDAmCvdCblKg==} + webpack-dev-middleware@8.4.0: + resolution: {integrity: sha512-a/YonExZBacvdZUdVmIFYJ4GbX8FaHXZFdEgQv9T24KBvrVW1zI2wVoWBxalpCW+rNm5rzfNBtFbHIYwypV/lQ==} engines: {node: '>= 20.9.0'} peerDependencies: webpack: ^5.101.0 @@ -8628,6 +8754,16 @@ packages: webpack-cli: optional: true + webpack@5.112.0: + resolution: {integrity: sha512-NIBpsRuCll036haDDt/CfcTDfsWNR9Z782nMRMI9D377BsGcYzZDTNU5TyzhCJzPIcihAxMBaMAhq2WSaDrH8Q==} + engines: {node: '>=10.13.0'} + hasBin: true + peerDependencies: + webpack-cli: '*' + peerDependenciesMeta: + webpack-cli: + optional: true + websocket-driver@0.7.5: resolution: {integrity: sha512-ZL2+3c7kMBdIRCMz6l8jQMHyGVxj+UL+xVk74Ombiciboca8rHa15L86B19E5oh1pL9Ii/uj54gtsIrZGMo6zA==} engines: {node: '>=0.8.0'} @@ -8830,9 +8966,6 @@ packages: resolution: {integrity: sha512-XrBh9ZiQK5mJVRxZBAvD6LwRyAYrK3MFtH3+onyuxFL5hFD44EC3QOmIC1FjTj6H2MMwq46/NAI+NZxLZPZgxg==} engines: {node: '>=14.18.0'} - zod@4.6.5: - resolution: {integrity: sha512-v5l/aFXZQeai4awLbOpSoHecE9UiMrnfx75tEXLjNonXVARxQ5mOeipTjROUchszUNCqnE+hqAMujRsRHsut2Q==} - zod@4.6.7: resolution: {integrity: sha512-g8W2D2kU6a8untc053fX1uVBKzM7yqAxW/3zwk83+6RyF2+SKOuV+c0wBDhUwzV1PaGapmZH+rmcUzPf+3CGwg==} @@ -9034,7 +9167,7 @@ snapshots: '@csstools/css-tokenizer': 4.0.2 lru-cache: 11.5.3 - '@asamuzakjp/dom-selector@9.2.4': + '@asamuzakjp/dom-selector@10.0.4': dependencies: bidi-js: 1.1.0 css-tree: 3.2.1 @@ -9875,18 +10008,18 @@ snapshots: '@esbuild/win32-x64@0.28.2': optional: true - '@eslint-community/eslint-utils@4.10.1(eslint@10.12.0(jiti@2.7.0)(supports-color@11.0.0))': + '@eslint-community/eslint-utils@4.10.1(eslint@10.13.0(jiti@2.7.0)(supports-color@11.0.0))': dependencies: - eslint: 10.12.0(jiti@2.7.0)(supports-color@11.0.0) + eslint: 10.13.0(jiti@2.7.0)(supports-color@11.0.0) eslint-visitor-keys: 3.4.3 '@eslint-community/regexpp@4.12.2': {} - '@eslint/compat@2.1.1(eslint@10.12.0(jiti@2.7.0)(supports-color@11.0.0))': + '@eslint/compat@2.1.1(eslint@10.13.0(jiti@2.7.0)(supports-color@11.0.0))': dependencies: '@eslint/core': 1.2.1 optionalDependencies: - eslint: 10.12.0(jiti@2.7.0)(supports-color@11.0.0) + eslint: 10.13.0(jiti@2.7.0)(supports-color@11.0.0) '@eslint/config-array@0.23.5(supports-color@11.0.0)': dependencies: @@ -9918,9 +10051,9 @@ snapshots: transitivePeerDependencies: - supports-color - '@eslint/js@10.0.1(eslint@10.12.0(jiti@2.7.0)(supports-color@11.0.0))': + '@eslint/js@10.0.1(eslint@10.13.0(jiti@2.7.0)(supports-color@11.0.0))': optionalDependencies: - eslint: 10.12.0(jiti@2.7.0)(supports-color@11.0.0) + eslint: 10.13.0(jiti@2.7.0)(supports-color@11.0.0) '@eslint/object-schema@3.0.5': {} @@ -10782,11 +10915,11 @@ snapshots: '@leichtgewicht/ip-codec@2.0.5': {} - '@listr2/prompt-adapter-inquirer@4.3.1(@inquirer/prompts@8.7.3(@types/node@22.20.5))(@types/node@22.20.5)(listr2@11.2.0)': + '@listr2/prompt-adapter-inquirer@4.3.3(@inquirer/prompts@8.7.3(@types/node@22.20.5))(@types/node@22.20.5)(listr2@11.4.0)': dependencies: '@inquirer/prompts': 8.7.3(@types/node@22.20.5) '@inquirer/type': 4.2.0(@types/node@22.20.5) - listr2: 11.2.0 + listr2: 11.4.0 transitivePeerDependencies: - '@types/node' @@ -11414,9 +11547,9 @@ snapshots: '@rolldown/pluginutils@1.0.1': {} - '@rollup/plugin-commonjs@29.0.3(rollup@4.64.6)': + '@rollup/plugin-commonjs@29.0.3(rollup@4.64.9)': dependencies: - '@rollup/pluginutils': 5.4.0(rollup@4.64.6) + '@rollup/pluginutils': 5.4.0(rollup@4.64.9) commondir: 1.0.1 estree-walker: 2.0.2 fdir: 6.5.0(picomatch@4.0.7) @@ -11424,108 +11557,108 @@ snapshots: magic-string: 0.30.21 picomatch: 4.0.7 optionalDependencies: - rollup: 4.64.6 + rollup: 4.64.9 - '@rollup/plugin-json@6.1.0(rollup@4.64.6)': + '@rollup/plugin-json@6.1.0(rollup@4.64.9)': dependencies: - '@rollup/pluginutils': 5.4.0(rollup@4.64.6) + '@rollup/pluginutils': 5.4.0(rollup@4.64.9) optionalDependencies: - rollup: 4.64.6 + rollup: 4.64.9 - '@rollup/plugin-node-resolve@16.0.3(rollup@4.64.6)': + '@rollup/plugin-node-resolve@16.0.3(rollup@4.64.9)': dependencies: - '@rollup/pluginutils': 5.4.0(rollup@4.64.6) + '@rollup/pluginutils': 5.4.0(rollup@4.64.9) '@types/resolve': 1.20.2 deepmerge: 4.3.1 is-module: 1.0.0 resolve: 1.22.13 optionalDependencies: - rollup: 4.64.6 + rollup: 4.64.9 - '@rollup/pluginutils@5.4.0(rollup@4.64.6)': + '@rollup/pluginutils@5.4.0(rollup@4.64.9)': dependencies: '@types/estree': 1.0.9 estree-walker: 2.0.2 picomatch: 4.0.7 optionalDependencies: - rollup: 4.64.6 + rollup: 4.64.9 - '@rollup/rollup-android-arm-eabi@4.64.6': + '@rollup/rollup-android-arm-eabi@4.64.9': optional: true - '@rollup/rollup-android-arm64@4.64.6': + '@rollup/rollup-android-arm64@4.64.9': optional: true - '@rollup/rollup-darwin-arm64@4.64.6': + '@rollup/rollup-darwin-arm64@4.64.9': optional: true - '@rollup/rollup-darwin-x64@4.64.6': + '@rollup/rollup-darwin-x64@4.64.9': optional: true - '@rollup/rollup-freebsd-arm64@4.64.6': + '@rollup/rollup-freebsd-arm64@4.64.9': optional: true - '@rollup/rollup-freebsd-x64@4.64.6': + '@rollup/rollup-freebsd-x64@4.64.9': optional: true - '@rollup/rollup-linux-arm-gnueabihf@4.64.6': + '@rollup/rollup-linux-arm-gnueabihf@4.64.9': optional: true - '@rollup/rollup-linux-arm-musleabihf@4.64.6': + '@rollup/rollup-linux-arm-musleabihf@4.64.9': optional: true - '@rollup/rollup-linux-arm64-gnu@4.64.6': + '@rollup/rollup-linux-arm64-gnu@4.64.9': optional: true - '@rollup/rollup-linux-arm64-musl@4.64.6': + '@rollup/rollup-linux-arm64-musl@4.64.9': optional: true - '@rollup/rollup-linux-loong64-gnu@4.64.6': + '@rollup/rollup-linux-loong64-gnu@4.64.9': optional: true - '@rollup/rollup-linux-loong64-musl@4.64.6': + '@rollup/rollup-linux-loong64-musl@4.64.9': optional: true - '@rollup/rollup-linux-ppc64-gnu@4.64.6': + '@rollup/rollup-linux-ppc64-gnu@4.64.9': optional: true - '@rollup/rollup-linux-ppc64-musl@4.64.6': + '@rollup/rollup-linux-ppc64-musl@4.64.9': optional: true - '@rollup/rollup-linux-riscv64-gnu@4.64.6': + '@rollup/rollup-linux-riscv64-gnu@4.64.9': optional: true - '@rollup/rollup-linux-riscv64-musl@4.64.6': + '@rollup/rollup-linux-riscv64-musl@4.64.9': optional: true - '@rollup/rollup-linux-s390x-gnu@4.64.6': + '@rollup/rollup-linux-s390x-gnu@4.64.9': optional: true - '@rollup/rollup-linux-x64-gnu@4.64.6': + '@rollup/rollup-linux-x64-gnu@4.64.9': optional: true - '@rollup/rollup-linux-x64-musl@4.64.6': + '@rollup/rollup-linux-x64-musl@4.64.9': optional: true - '@rollup/rollup-openbsd-x64@4.64.6': + '@rollup/rollup-openbsd-x64@4.64.9': optional: true - '@rollup/rollup-openharmony-arm64@4.64.6': + '@rollup/rollup-openharmony-arm64@4.64.9': optional: true - '@rollup/rollup-win32-arm64-msvc@4.64.6': + '@rollup/rollup-win32-arm64-msvc@4.64.9': optional: true - '@rollup/rollup-win32-ia32-msvc@4.64.6': + '@rollup/rollup-win32-ia32-msvc@4.64.9': optional: true - '@rollup/rollup-win32-x64-gnu@4.64.6': + '@rollup/rollup-win32-x64-gnu@4.64.9': optional: true - '@rollup/rollup-win32-x64-msvc@4.64.6': + '@rollup/rollup-win32-x64-msvc@4.64.9': optional: true - '@rollup/wasm-node@4.64.6': + '@rollup/wasm-node@4.64.9': dependencies: '@types/estree': 1.0.9 optionalDependencies: @@ -11548,19 +11681,19 @@ snapshots: '@standard-schema/spec@1.1.0': {} - '@stylistic/eslint-plugin@5.10.0(eslint@10.12.0(jiti@2.7.0)(supports-color@11.0.0))': + '@stylistic/eslint-plugin@5.10.0(eslint@10.13.0(jiti@2.7.0)(supports-color@11.0.0))': dependencies: - '@eslint-community/eslint-utils': 4.10.1(eslint@10.12.0(jiti@2.7.0)(supports-color@11.0.0)) + '@eslint-community/eslint-utils': 4.10.1(eslint@10.13.0(jiti@2.7.0)(supports-color@11.0.0)) '@typescript-eslint/types': 8.71.1 - eslint: 10.12.0(jiti@2.7.0)(supports-color@11.0.0) + eslint: 10.13.0(jiti@2.7.0)(supports-color@11.0.0) eslint-visitor-keys: 4.2.1 espree: 10.4.0 estraverse: 5.3.0 picomatch: 4.0.7 - '@tony.ganchev/eslint-plugin-header@3.4.4(eslint@10.12.0(jiti@2.7.0)(supports-color@11.0.0))': + '@tony.ganchev/eslint-plugin-header@3.4.4(eslint@10.13.0(jiti@2.7.0)(supports-color@11.0.0))': dependencies: - eslint: 10.12.0(jiti@2.7.0)(supports-color@11.0.0) + eslint: 10.13.0(jiti@2.7.0)(supports-color@11.0.0) '@types/babel__core@7.20.5': dependencies: @@ -11687,7 +11820,7 @@ snapshots: '@types/less@3.0.8': {} - '@types/loader-utils@3.0.0(esbuild@0.28.2)(lightningcss@1.33.0)(uglify-js@3.19.3)': + '@types/loader-utils@3.0.0(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.30)(uglify-js@3.19.3)': dependencies: '@types/node': 22.20.5 webpack: 5.111.1(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.30)(uglify-js@3.19.3) @@ -11791,15 +11924,15 @@ snapshots: '@types/yarnpkg__lockfile@1.1.9': {} - '@typescript-eslint/eslint-plugin@8.71.2(@typescript-eslint/parser@8.71.2(eslint@10.12.0(jiti@2.7.0)(supports-color@11.0.0))(supports-color@11.0.0)(typescript@6.0.3))(eslint@10.12.0(jiti@2.7.0)(supports-color@11.0.0))(supports-color@11.0.0)(typescript@6.0.3)': + '@typescript-eslint/eslint-plugin@8.71.2(@typescript-eslint/parser@8.71.2(eslint@10.13.0(jiti@2.7.0)(supports-color@11.0.0))(supports-color@11.0.0)(typescript@6.0.3))(eslint@10.13.0(jiti@2.7.0)(supports-color@11.0.0))(supports-color@11.0.0)(typescript@6.0.3)': dependencies: '@eslint-community/regexpp': 4.12.2 - '@typescript-eslint/parser': 8.71.2(eslint@10.12.0(jiti@2.7.0)(supports-color@11.0.0))(supports-color@11.0.0)(typescript@6.0.3) + '@typescript-eslint/parser': 8.71.2(eslint@10.13.0(jiti@2.7.0)(supports-color@11.0.0))(supports-color@11.0.0)(typescript@6.0.3) '@typescript-eslint/scope-manager': 8.71.2 - '@typescript-eslint/type-utils': 8.71.2(eslint@10.12.0(jiti@2.7.0)(supports-color@11.0.0))(supports-color@11.0.0)(typescript@6.0.3) - '@typescript-eslint/utils': 8.71.2(eslint@10.12.0(jiti@2.7.0)(supports-color@11.0.0))(supports-color@11.0.0)(typescript@6.0.3) + '@typescript-eslint/type-utils': 8.71.2(eslint@10.13.0(jiti@2.7.0)(supports-color@11.0.0))(supports-color@11.0.0)(typescript@6.0.3) + '@typescript-eslint/utils': 8.71.2(eslint@10.13.0(jiti@2.7.0)(supports-color@11.0.0))(supports-color@11.0.0)(typescript@6.0.3) '@typescript-eslint/visitor-keys': 8.71.2 - eslint: 10.12.0(jiti@2.7.0)(supports-color@11.0.0) + eslint: 10.13.0(jiti@2.7.0)(supports-color@11.0.0) ignore: 7.0.12 natural-compare: 1.4.0 ts-api-utils: 2.5.0(typescript@6.0.3) @@ -11807,14 +11940,14 @@ snapshots: transitivePeerDependencies: - supports-color - '@typescript-eslint/parser@8.71.2(eslint@10.12.0(jiti@2.7.0)(supports-color@11.0.0))(supports-color@11.0.0)(typescript@6.0.3)': + '@typescript-eslint/parser@8.71.2(eslint@10.13.0(jiti@2.7.0)(supports-color@11.0.0))(supports-color@11.0.0)(typescript@6.0.3)': dependencies: '@typescript-eslint/scope-manager': 8.71.2 '@typescript-eslint/types': 8.71.2 '@typescript-eslint/typescript-estree': 8.71.2(supports-color@11.0.0)(typescript@6.0.3) '@typescript-eslint/visitor-keys': 8.71.2 debug: 4.4.3(supports-color@11.0.0) - eslint: 10.12.0(jiti@2.7.0)(supports-color@11.0.0) + eslint: 10.13.0(jiti@2.7.0)(supports-color@11.0.0) typescript: 6.0.3 transitivePeerDependencies: - supports-color @@ -11837,13 +11970,13 @@ snapshots: dependencies: typescript: 6.0.3 - '@typescript-eslint/type-utils@8.71.2(eslint@10.12.0(jiti@2.7.0)(supports-color@11.0.0))(supports-color@11.0.0)(typescript@6.0.3)': + '@typescript-eslint/type-utils@8.71.2(eslint@10.13.0(jiti@2.7.0)(supports-color@11.0.0))(supports-color@11.0.0)(typescript@6.0.3)': dependencies: '@typescript-eslint/types': 8.71.2 '@typescript-eslint/typescript-estree': 8.71.2(supports-color@11.0.0)(typescript@6.0.3) - '@typescript-eslint/utils': 8.71.2(eslint@10.12.0(jiti@2.7.0)(supports-color@11.0.0))(supports-color@11.0.0)(typescript@6.0.3) + '@typescript-eslint/utils': 8.71.2(eslint@10.13.0(jiti@2.7.0)(supports-color@11.0.0))(supports-color@11.0.0)(typescript@6.0.3) debug: 4.4.3(supports-color@11.0.0) - eslint: 10.12.0(jiti@2.7.0)(supports-color@11.0.0) + eslint: 10.13.0(jiti@2.7.0)(supports-color@11.0.0) ts-api-utils: 2.5.0(typescript@6.0.3) typescript: 6.0.3 transitivePeerDependencies: @@ -11868,13 +12001,13 @@ snapshots: transitivePeerDependencies: - supports-color - '@typescript-eslint/utils@8.71.2(eslint@10.12.0(jiti@2.7.0)(supports-color@11.0.0))(supports-color@11.0.0)(typescript@6.0.3)': + '@typescript-eslint/utils@8.71.2(eslint@10.13.0(jiti@2.7.0)(supports-color@11.0.0))(supports-color@11.0.0)(typescript@6.0.3)': dependencies: - '@eslint-community/eslint-utils': 4.10.1(eslint@10.12.0(jiti@2.7.0)(supports-color@11.0.0)) + '@eslint-community/eslint-utils': 4.10.1(eslint@10.13.0(jiti@2.7.0)(supports-color@11.0.0)) '@typescript-eslint/scope-manager': 8.71.2 '@typescript-eslint/types': 8.71.2 '@typescript-eslint/typescript-estree': 8.71.2(supports-color@11.0.0)(typescript@6.0.3) - eslint: 10.12.0(jiti@2.7.0)(supports-color@11.0.0) + eslint: 10.13.0(jiti@2.7.0)(supports-color@11.0.0) typescript: 6.0.3 transitivePeerDependencies: - supports-color @@ -12052,11 +12185,11 @@ snapshots: transitivePeerDependencies: - supports-color - '@vitejs/plugin-basic-ssl@2.3.0(vite@8.3.4(@types/node@22.20.5)(esbuild@0.28.2)(jiti@2.7.0)(less@4.9.1(supports-color@11.0.0))(sass-embedded@1.105.1)(sass@1.105.1)(terser@5.51.2)(tsx@4.23.15)(yaml@2.9.1))': + '@vitejs/plugin-basic-ssl@2.3.0(vite@8.3.4(@types/node@22.20.5)(esbuild@0.28.2)(jiti@2.7.0)(less@4.9.1(supports-color@11.0.0))(sass-embedded@1.105.2)(sass@1.105.2)(terser@5.51.2)(tsx@4.23.15)(yaml@2.9.1))': dependencies: - vite: 8.3.4(@types/node@22.20.5)(esbuild@0.28.2)(jiti@2.7.0)(less@4.9.1(supports-color@11.0.0))(sass-embedded@1.105.1)(sass@1.105.1)(terser@5.51.2)(tsx@4.23.15)(yaml@2.9.1) + vite: 8.3.4(@types/node@22.20.5)(esbuild@0.28.2)(jiti@2.7.0)(less@4.9.1(supports-color@11.0.0))(sass-embedded@1.105.2)(sass@1.105.2)(terser@5.51.2)(tsx@4.23.15)(yaml@2.9.1) - '@vitest/coverage-v8@5.0.4(vitest@5.0.4)': + '@vitest/coverage-v8@5.0.5(vitest@5.0.5)': dependencies: '@bcoe/v8-coverage': 1.0.2 '@vitest/istanbul-lib-coverage': 1.0.2 @@ -12066,7 +12199,7 @@ snapshots: obug: 3.0.0 std-env: 4.3.0 tinyrainbow: 3.2.0 - vitest: 5.0.4(@opentelemetry/api@1.9.1)(@types/node@22.20.5)(@vitest/coverage-v8@5.0.4)(jsdom@30.1.2(@noble/hashes@1.8.0))(vite@8.3.4(@types/node@22.20.5)(esbuild@0.28.2)(jiti@2.7.0)(less@4.9.1(supports-color@11.0.0))(sass-embedded@1.105.1)(sass@1.105.1)(terser@5.51.2)(tsx@4.23.15)(yaml@2.9.1)) + vitest: 5.0.5(@opentelemetry/api@1.9.1)(@types/node@22.20.5)(@vitest/coverage-v8@5.0.5)(jsdom@30.1.3(@noble/hashes@1.8.0))(vite@8.3.4(@types/node@22.20.5)(esbuild@0.28.2)(jiti@2.7.0)(less@4.9.1(supports-color@11.0.0))(sass-embedded@1.105.1)(sass@1.105.1)(terser@5.51.2)(tsx@4.23.15)(yaml@2.9.1)) '@vitest/istanbul-lib-coverage@1.0.2': {} @@ -12074,16 +12207,25 @@ snapshots: dependencies: '@vitest/istanbul-lib-coverage': 1.0.2 - '@vitest/mocker@5.0.4(vite@8.3.4(@types/node@22.20.5)(esbuild@0.28.2)(jiti@2.7.0)(less@4.9.1(supports-color@11.0.0))(sass-embedded@1.105.1)(sass@1.105.1)(terser@5.51.2)(tsx@4.23.15)(yaml@2.9.1))': + '@vitest/mocker@5.0.5(vite@8.3.4(@types/node@22.20.5)(esbuild@0.28.2)(jiti@2.7.0)(less@4.9.1(supports-color@11.0.0))(sass-embedded@1.105.1)(sass@1.105.1)(terser@5.51.2)(tsx@4.23.15)(yaml@2.9.1))': dependencies: '@jridgewell/trace-mapping': 0.3.31 - '@vitest/spy': 5.0.4 + '@vitest/spy': 5.0.5 estree-walker: 3.0.3 magic-string: 1.4.3 optionalDependencies: vite: 8.3.4(@types/node@22.20.5)(esbuild@0.28.2)(jiti@2.7.0)(less@4.9.1(supports-color@11.0.0))(sass-embedded@1.105.1)(sass@1.105.1)(terser@5.51.2)(tsx@4.23.15)(yaml@2.9.1) - '@vitest/spy@5.0.4': {} + '@vitest/mocker@5.0.5(vite@8.3.4(@types/node@22.20.5)(esbuild@0.28.2)(jiti@2.7.0)(less@4.9.1(supports-color@11.0.0))(sass-embedded@1.105.2)(sass@1.105.2)(terser@5.51.2)(tsx@4.23.15)(yaml@2.9.1))': + dependencies: + '@jridgewell/trace-mapping': 0.3.31 + '@vitest/spy': 5.0.5 + estree-walker: 3.0.3 + magic-string: 1.4.3 + optionalDependencies: + vite: 8.3.4(@types/node@22.20.5)(esbuild@0.28.2)(jiti@2.7.0)(less@4.9.1(supports-color@11.0.0))(sass-embedded@1.105.2)(sass@1.105.2)(terser@5.51.2)(tsx@4.23.15)(yaml@2.9.1) + + '@vitest/spy@5.0.5': {} '@webassemblyjs/ast@1.14.1': dependencies: @@ -12486,12 +12628,12 @@ snapshots: b4a@1.9.0: {} - babel-loader@10.1.1(@babel/core@8.0.7)(webpack@5.111.1(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.30)(uglify-js@3.19.3)): + babel-loader@10.1.1(@babel/core@8.0.7)(webpack@5.112.0(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.30)(uglify-js@3.19.3)): dependencies: '@babel/core': 8.0.7 find-up: 5.0.0 optionalDependencies: - webpack: 5.111.1(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.30)(uglify-js@3.19.3) + webpack: 5.112.0(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.30)(uglify-js@3.19.3) babel-plugin-polyfill-corejs3@1.0.0(@babel/core@8.0.7): dependencies: @@ -12967,14 +13109,14 @@ snapshots: dependencies: is-what: 4.1.16 - copy-webpack-plugin@14.0.0(webpack@5.111.1(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.30)(uglify-js@3.19.3)): + copy-webpack-plugin@14.0.0(webpack@5.112.0(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.30)(uglify-js@3.19.3)): dependencies: glob-parent: 6.0.2 normalize-path: 3.0.0 schema-utils: 4.5.0 serialize-javascript: 7.1.2 tinyglobby: 0.2.17 - webpack: 5.111.1(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.30)(uglify-js@3.19.3) + webpack: 5.112.0(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.30)(uglify-js@3.19.3) core-js-compat@3.50.0: dependencies: @@ -13004,7 +13146,7 @@ snapshots: shebang-command: 2.0.0 which: 2.0.2 - css-loader@7.1.5(webpack@5.111.1(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.30)(uglify-js@3.19.3)): + css-loader@7.1.5(webpack@5.112.0(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.30)(uglify-js@3.19.3)): dependencies: icss-utils: 5.1.0(postcss@8.5.30) postcss: 8.5.30 @@ -13015,7 +13157,7 @@ snapshots: postcss-value-parser: 4.2.0 semver: 7.8.5 optionalDependencies: - webpack: 5.111.1(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.30)(uglify-js@3.19.3) + webpack: 5.112.0(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.30)(uglify-js@3.19.3) css-select@7.0.0: dependencies: @@ -13434,9 +13576,9 @@ snapshots: escape-string-regexp@4.0.0: {} - eslint-config-prettier@10.1.8(eslint@10.12.0(jiti@2.7.0)(supports-color@11.0.0)): + eslint-config-prettier@10.1.8(eslint@10.13.0(jiti@2.7.0)(supports-color@11.0.0)): dependencies: - eslint: 10.12.0(jiti@2.7.0)(supports-color@11.0.0) + eslint: 10.13.0(jiti@2.7.0)(supports-color@11.0.0) eslint-import-resolver-node@0.3.10(supports-color@11.0.0): dependencies: @@ -13446,17 +13588,17 @@ snapshots: transitivePeerDependencies: - supports-color - eslint-module-utils@2.14.0(@typescript-eslint/parser@8.71.2(eslint@10.12.0(jiti@2.7.0)(supports-color@11.0.0))(supports-color@11.0.0)(typescript@6.0.3))(eslint-import-resolver-node@0.3.10(supports-color@11.0.0))(eslint@10.12.0(jiti@2.7.0)(supports-color@11.0.0))(supports-color@11.0.0): + eslint-module-utils@2.14.0(@typescript-eslint/parser@8.71.2(eslint@10.13.0(jiti@2.7.0)(supports-color@11.0.0))(supports-color@11.0.0)(typescript@6.0.3))(eslint-import-resolver-node@0.3.10(supports-color@11.0.0))(eslint@10.13.0(jiti@2.7.0)(supports-color@11.0.0))(supports-color@11.0.0): dependencies: debug: 3.2.7(supports-color@11.0.0) optionalDependencies: - '@typescript-eslint/parser': 8.71.2(eslint@10.12.0(jiti@2.7.0)(supports-color@11.0.0))(supports-color@11.0.0)(typescript@6.0.3) - eslint: 10.12.0(jiti@2.7.0)(supports-color@11.0.0) + '@typescript-eslint/parser': 8.71.2(eslint@10.13.0(jiti@2.7.0)(supports-color@11.0.0))(supports-color@11.0.0)(typescript@6.0.3) + eslint: 10.13.0(jiti@2.7.0)(supports-color@11.0.0) eslint-import-resolver-node: 0.3.10(supports-color@11.0.0) transitivePeerDependencies: - supports-color - eslint-plugin-import@2.32.0(@typescript-eslint/parser@8.71.2(eslint@10.12.0(jiti@2.7.0)(supports-color@11.0.0))(supports-color@11.0.0)(typescript@6.0.3))(eslint@10.12.0(jiti@2.7.0)(supports-color@11.0.0))(supports-color@11.0.0): + eslint-plugin-import@2.32.0(@typescript-eslint/parser@8.71.2(eslint@10.13.0(jiti@2.7.0)(supports-color@11.0.0))(supports-color@11.0.0)(typescript@6.0.3))(eslint@10.13.0(jiti@2.7.0)(supports-color@11.0.0))(supports-color@11.0.0): dependencies: '@rtsao/scc': 1.1.0 array-includes: 3.2.0 @@ -13465,9 +13607,9 @@ snapshots: array.prototype.flatmap: 1.3.3 debug: 3.2.7(supports-color@11.0.0) doctrine: 2.1.0 - eslint: 10.12.0(jiti@2.7.0)(supports-color@11.0.0) + eslint: 10.13.0(jiti@2.7.0)(supports-color@11.0.0) eslint-import-resolver-node: 0.3.10(supports-color@11.0.0) - eslint-module-utils: 2.14.0(@typescript-eslint/parser@8.71.2(eslint@10.12.0(jiti@2.7.0)(supports-color@11.0.0))(supports-color@11.0.0)(typescript@6.0.3))(eslint-import-resolver-node@0.3.10(supports-color@11.0.0))(eslint@10.12.0(jiti@2.7.0)(supports-color@11.0.0))(supports-color@11.0.0) + eslint-module-utils: 2.14.0(@typescript-eslint/parser@8.71.2(eslint@10.13.0(jiti@2.7.0)(supports-color@11.0.0))(supports-color@11.0.0)(typescript@6.0.3))(eslint-import-resolver-node@0.3.10(supports-color@11.0.0))(eslint@10.13.0(jiti@2.7.0)(supports-color@11.0.0))(supports-color@11.0.0) hasown: 2.0.4 is-core-module: 2.17.0 is-glob: 4.0.3 @@ -13479,7 +13621,7 @@ snapshots: string.prototype.trimend: 1.0.10 tsconfig-paths: 3.15.0 optionalDependencies: - '@typescript-eslint/parser': 8.71.2(eslint@10.12.0(jiti@2.7.0)(supports-color@11.0.0))(supports-color@11.0.0)(typescript@6.0.3) + '@typescript-eslint/parser': 8.71.2(eslint@10.13.0(jiti@2.7.0)(supports-color@11.0.0))(supports-color@11.0.0)(typescript@6.0.3) transitivePeerDependencies: - eslint-import-resolver-typescript - eslint-import-resolver-webpack @@ -13498,9 +13640,9 @@ snapshots: eslint-visitor-keys@5.0.1: {} - eslint@10.12.0(jiti@2.7.0)(supports-color@11.0.0): + eslint@10.13.0(jiti@2.7.0)(supports-color@11.0.0): dependencies: - '@eslint-community/eslint-utils': 4.10.1(eslint@10.12.0(jiti@2.7.0)(supports-color@11.0.0)) + '@eslint-community/eslint-utils': 4.10.1(eslint@10.13.0(jiti@2.7.0)(supports-color@11.0.0)) '@eslint-community/regexpp': 4.12.2 '@eslint/config-array': 0.23.5(supports-color@11.0.0) '@eslint/config-helpers': 0.7.0 @@ -14636,10 +14778,10 @@ snapshots: jsbn@0.1.1: {} - jsdom@30.1.2(@noble/hashes@1.8.0): + jsdom@30.1.3(@noble/hashes@1.8.0): dependencies: '@asamuzakjp/css-color': 7.1.5 - '@asamuzakjp/dom-selector': 9.2.4 + '@asamuzakjp/dom-selector': 10.0.4 '@bramus/specificity': 2.4.3 '@csstools/css-syntax-patches-for-csstree': 1.1.15(css-tree@3.2.1) '@exodus/bytes': 1.16.0(@noble/hashes@1.8.0) @@ -14652,7 +14794,7 @@ snapshots: parse5: 8.0.1 saxes: 6.0.0 tough-cookie: 6.0.2 - undici: 8.11.2 + undici: 8.12.1 w3c-xmlserializer: 6.0.0 webidl-conversions: 8.0.1 whatwg-mimetype: 5.0.0 @@ -14803,12 +14945,12 @@ snapshots: picocolors: 1.1.1 shell-quote: 1.12.0 - less-loader@13.0.0(less@4.9.1(supports-color@11.0.0))(webpack@5.111.1(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.30)(uglify-js@3.19.3)): + less-loader@13.0.0(less@4.9.1(supports-color@11.0.0))(webpack@5.112.0(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.30)(uglify-js@3.19.3)): dependencies: '@types/less': 3.0.8 less: 4.9.1(supports-color@11.0.0) optionalDependencies: - webpack: 5.111.1(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.30)(uglify-js@3.19.3) + webpack: 5.112.0(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.30)(uglify-js@3.19.3) less@4.9.1(supports-color@11.0.0): dependencies: @@ -14830,11 +14972,11 @@ snapshots: prelude-ls: 1.2.1 type-check: 0.4.0 - license-webpack-plugin@4.0.2(webpack@5.111.1(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.30)(uglify-js@3.19.3)): + license-webpack-plugin@4.0.2(webpack@5.112.0(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.30)(uglify-js@3.19.3)): dependencies: webpack-sources: 3.6.0 optionalDependencies: - webpack: 5.111.1(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.30)(uglify-js@3.19.3) + webpack: 5.112.0(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.30)(uglify-js@3.19.3) lightningcss-android-arm64@1.33.0: optional: true @@ -14891,7 +15033,7 @@ snapshots: lines-and-columns@1.2.4: {} - listr2@11.2.0: + listr2@11.4.0: dependencies: cli-truncate: 6.1.1 log-update: 8.0.0 @@ -15089,11 +15231,11 @@ snapshots: mimic-response@4.0.0: {} - mini-css-extract-plugin@2.10.2(webpack@5.111.1(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.30)(uglify-js@3.19.3)): + mini-css-extract-plugin@2.10.2(webpack@5.112.0(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.30)(uglify-js@3.19.3)): dependencies: schema-utils: 4.5.0 tapable: 2.3.3 - webpack: 5.111.1(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.30)(uglify-js@3.19.3) + webpack: 5.112.0(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.30)(uglify-js@3.19.3) minimatch@10.2.6: dependencies: @@ -15113,13 +15255,13 @@ snapshots: minimist@1.2.8: {} - minimizer-webpack-plugin@5.13.0(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.29)(uglify-js@3.19.3)(webpack@5.111.1(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.29)(uglify-js@3.19.3)): + minimizer-webpack-plugin@5.13.0(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.29)(uglify-js@3.19.3)(webpack@5.112.0(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.29)(uglify-js@3.19.3)): dependencies: '@jridgewell/trace-mapping': 0.3.31 jest-worker: 27.5.1 schema-utils: 4.5.0 terser: 5.51.2 - webpack: 5.111.1(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.29)(uglify-js@3.19.3) + webpack: 5.112.0(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.29)(uglify-js@3.19.3) optionalDependencies: esbuild: 0.28.2 lightningcss: 1.33.0 @@ -15139,6 +15281,19 @@ snapshots: postcss: 8.5.30 uglify-js: 3.19.3 + minimizer-webpack-plugin@5.13.0(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.30)(uglify-js@3.19.3)(webpack@5.112.0(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.30)(uglify-js@3.19.3)): + dependencies: + '@jridgewell/trace-mapping': 0.3.31 + jest-worker: 27.5.1 + schema-utils: 4.5.0 + terser: 5.51.2 + webpack: 5.112.0(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.30)(uglify-js@3.19.3) + optionalDependencies: + esbuild: 0.28.2 + lightningcss: 1.33.0 + postcss: 8.5.30 + uglify-js: 3.19.3 + minipass@7.1.3: {} mitt@1.2.0: {} @@ -15593,14 +15748,14 @@ snapshots: possible-typed-array-names@1.1.0: {} - postcss-loader@8.2.1(postcss@8.5.30)(typescript@6.0.3)(webpack@5.111.1(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.30)(uglify-js@3.19.3)): + postcss-loader@8.2.1(postcss@8.5.30)(typescript@6.0.3)(webpack@5.112.0(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.30)(uglify-js@3.19.3)): dependencies: cosmiconfig: 9.0.2(typescript@6.0.3) jiti: 2.7.0 postcss: 8.5.30 semver: 7.8.5 optionalDependencies: - webpack: 5.111.1(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.30)(uglify-js@3.19.3) + webpack: 5.112.0(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.30)(uglify-js@3.19.3) transitivePeerDependencies: - typescript @@ -16035,54 +16190,54 @@ snapshots: '@rolldown/binding-win32-arm64-msvc': 1.2.14 '@rolldown/binding-win32-x64-msvc': 1.2.14 - rollup-plugin-dts@6.5.1(rollup@4.64.6)(typescript@6.0.3): + rollup-plugin-dts@6.5.1(rollup@4.64.9)(typescript@6.0.3): dependencies: '@jridgewell/remapping': 2.3.5 '@jridgewell/sourcemap-codec': 1.6.0 convert-source-map: 2.0.0 magic-string: 0.30.21 - rollup: 4.64.6 + rollup: 4.64.9 typescript: 6.0.3 optionalDependencies: '@babel/code-frame': 8.0.6 - rollup-plugin-sourcemaps2@0.5.9(@types/node@22.20.5)(rollup@4.64.6): + rollup-plugin-sourcemaps2@0.5.9(@types/node@22.20.5)(rollup@4.64.9): dependencies: - '@rollup/pluginutils': 5.4.0(rollup@4.64.6) - rollup: 4.64.6 + '@rollup/pluginutils': 5.4.0(rollup@4.64.9) + rollup: 4.64.9 optionalDependencies: '@types/node': 22.20.5 - rollup@4.64.6: + rollup@4.64.9: dependencies: '@types/estree': 1.0.9 optionalDependencies: '@napi-rs/lzma-linux-x64-gnu': 1.5.1 - '@rollup/rollup-android-arm-eabi': 4.64.6 - '@rollup/rollup-android-arm64': 4.64.6 - '@rollup/rollup-darwin-arm64': 4.64.6 - '@rollup/rollup-darwin-x64': 4.64.6 - '@rollup/rollup-freebsd-arm64': 4.64.6 - '@rollup/rollup-freebsd-x64': 4.64.6 - '@rollup/rollup-linux-arm-gnueabihf': 4.64.6 - '@rollup/rollup-linux-arm-musleabihf': 4.64.6 - '@rollup/rollup-linux-arm64-gnu': 4.64.6 - '@rollup/rollup-linux-arm64-musl': 4.64.6 - '@rollup/rollup-linux-loong64-gnu': 4.64.6 - '@rollup/rollup-linux-loong64-musl': 4.64.6 - '@rollup/rollup-linux-ppc64-gnu': 4.64.6 - '@rollup/rollup-linux-ppc64-musl': 4.64.6 - '@rollup/rollup-linux-riscv64-gnu': 4.64.6 - '@rollup/rollup-linux-riscv64-musl': 4.64.6 - '@rollup/rollup-linux-s390x-gnu': 4.64.6 - '@rollup/rollup-linux-x64-gnu': 4.64.6 - '@rollup/rollup-linux-x64-musl': 4.64.6 - '@rollup/rollup-openbsd-x64': 4.64.6 - '@rollup/rollup-openharmony-arm64': 4.64.6 - '@rollup/rollup-win32-arm64-msvc': 4.64.6 - '@rollup/rollup-win32-ia32-msvc': 4.64.6 - '@rollup/rollup-win32-x64-gnu': 4.64.6 - '@rollup/rollup-win32-x64-msvc': 4.64.6 + '@rollup/rollup-android-arm-eabi': 4.64.9 + '@rollup/rollup-android-arm64': 4.64.9 + '@rollup/rollup-darwin-arm64': 4.64.9 + '@rollup/rollup-darwin-x64': 4.64.9 + '@rollup/rollup-freebsd-arm64': 4.64.9 + '@rollup/rollup-freebsd-x64': 4.64.9 + '@rollup/rollup-linux-arm-gnueabihf': 4.64.9 + '@rollup/rollup-linux-arm-musleabihf': 4.64.9 + '@rollup/rollup-linux-arm64-gnu': 4.64.9 + '@rollup/rollup-linux-arm64-musl': 4.64.9 + '@rollup/rollup-linux-loong64-gnu': 4.64.9 + '@rollup/rollup-linux-loong64-musl': 4.64.9 + '@rollup/rollup-linux-ppc64-gnu': 4.64.9 + '@rollup/rollup-linux-ppc64-musl': 4.64.9 + '@rollup/rollup-linux-riscv64-gnu': 4.64.9 + '@rollup/rollup-linux-riscv64-musl': 4.64.9 + '@rollup/rollup-linux-s390x-gnu': 4.64.9 + '@rollup/rollup-linux-x64-gnu': 4.64.9 + '@rollup/rollup-linux-x64-musl': 4.64.9 + '@rollup/rollup-openbsd-x64': 4.64.9 + '@rollup/rollup-openharmony-arm64': 4.64.9 + '@rollup/rollup-win32-arm64-msvc': 4.64.9 + '@rollup/rollup-win32-ia32-msvc': 4.64.9 + '@rollup/rollup-win32-x64-gnu': 4.64.9 + '@rollup/rollup-win32-x64-msvc': 4.64.9 fsevents: 2.3.3 router@2.2.0(supports-color@11.0.0): @@ -16143,59 +16298,117 @@ snapshots: sass: 1.105.1 optional: true + sass-embedded-all-unknown@1.105.2: + dependencies: + sass: 1.105.2 + optional: true + sass-embedded-android-arm64@1.105.1: optional: true + sass-embedded-android-arm64@1.105.2: + optional: true + sass-embedded-android-arm@1.105.1: optional: true + sass-embedded-android-arm@1.105.2: + optional: true + sass-embedded-android-riscv64@1.105.1: optional: true + sass-embedded-android-riscv64@1.105.2: + optional: true + sass-embedded-android-x64@1.105.1: optional: true + sass-embedded-android-x64@1.105.2: + optional: true + sass-embedded-darwin-arm64@1.105.1: optional: true + sass-embedded-darwin-arm64@1.105.2: + optional: true + sass-embedded-darwin-x64@1.105.1: optional: true + sass-embedded-darwin-x64@1.105.2: + optional: true + sass-embedded-linux-arm64@1.105.1: optional: true + sass-embedded-linux-arm64@1.105.2: + optional: true + sass-embedded-linux-arm@1.105.1: optional: true + sass-embedded-linux-arm@1.105.2: + optional: true + sass-embedded-linux-musl-arm64@1.105.1: optional: true + sass-embedded-linux-musl-arm64@1.105.2: + optional: true + sass-embedded-linux-musl-arm@1.105.1: optional: true + sass-embedded-linux-musl-arm@1.105.2: + optional: true + sass-embedded-linux-musl-riscv64@1.105.1: optional: true + sass-embedded-linux-musl-riscv64@1.105.2: + optional: true + sass-embedded-linux-musl-x64@1.105.1: optional: true + sass-embedded-linux-musl-x64@1.105.2: + optional: true + sass-embedded-linux-riscv64@1.105.1: optional: true + sass-embedded-linux-riscv64@1.105.2: + optional: true + sass-embedded-linux-x64@1.105.1: optional: true + sass-embedded-linux-x64@1.105.2: + optional: true + sass-embedded-unknown-all@1.105.1: dependencies: sass: 1.105.1 optional: true + sass-embedded-unknown-all@1.105.2: + dependencies: + sass: 1.105.2 + optional: true + sass-embedded-win32-arm64@1.105.1: optional: true + sass-embedded-win32-arm64@1.105.2: + optional: true + sass-embedded-win32-x64@1.105.1: optional: true + sass-embedded-win32-x64@1.105.2: + optional: true + sass-embedded@1.105.1: dependencies: '@bufbuild/protobuf': 2.16.0 @@ -16225,11 +16438,40 @@ snapshots: sass-embedded-win32-arm64: 1.105.1 sass-embedded-win32-x64: 1.105.1 - sass-loader@17.0.1(sass-embedded@1.105.1)(sass@1.105.1)(webpack@5.111.1(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.30)(uglify-js@3.19.3)): + sass-embedded@1.105.2: + dependencies: + '@bufbuild/protobuf': 2.16.0 + colorjs.io: 0.7.1 + immutable: 5.1.9 + rxjs: 7.8.2 + supports-color: 8.1.1 + sync-child-process: 1.0.2 + varint: 6.0.0 optionalDependencies: - sass: 1.105.1 + sass-embedded-all-unknown: 1.105.2 + sass-embedded-android-arm: 1.105.2 + sass-embedded-android-arm64: 1.105.2 + sass-embedded-android-riscv64: 1.105.2 + sass-embedded-android-x64: 1.105.2 + sass-embedded-darwin-arm64: 1.105.2 + sass-embedded-darwin-x64: 1.105.2 + sass-embedded-linux-arm: 1.105.2 + sass-embedded-linux-arm64: 1.105.2 + sass-embedded-linux-musl-arm: 1.105.2 + sass-embedded-linux-musl-arm64: 1.105.2 + sass-embedded-linux-musl-riscv64: 1.105.2 + sass-embedded-linux-musl-x64: 1.105.2 + sass-embedded-linux-riscv64: 1.105.2 + sass-embedded-linux-x64: 1.105.2 + sass-embedded-unknown-all: 1.105.2 + sass-embedded-win32-arm64: 1.105.2 + sass-embedded-win32-x64: 1.105.2 + + sass-loader@17.0.1(sass-embedded@1.105.1)(sass@1.105.2)(webpack@5.112.0(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.30)(uglify-js@3.19.3)): + optionalDependencies: + sass: 1.105.2 sass-embedded: 1.105.1 - webpack: 5.111.1(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.30)(uglify-js@3.19.3) + webpack: 5.112.0(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.30)(uglify-js@3.19.3) sass@1.105.1: dependencies: @@ -16239,6 +16481,14 @@ snapshots: optionalDependencies: '@parcel/watcher': 2.6.0 + sass@1.105.2: + dependencies: + chokidar: 5.0.0 + immutable: 5.1.9 + source-map-js: 1.2.2 + optionalDependencies: + '@parcel/watcher': 2.6.0 + sax@1.6.1: optional: true @@ -16455,11 +16705,11 @@ snapshots: source-map-js@1.2.2: {} - source-map-loader@5.0.0(webpack@5.111.1(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.30)(uglify-js@3.19.3)): + source-map-loader@5.0.0(webpack@5.112.0(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.30)(uglify-js@3.19.3)): dependencies: iconv-lite: 0.6.3 source-map-js: 1.2.2 - webpack: 5.111.1(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.30)(uglify-js@3.19.3) + webpack: 5.112.0(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.30)(uglify-js@3.19.3) source-map-support@0.5.21: dependencies: @@ -16885,10 +17135,10 @@ snapshots: undici@6.29.0: {} - undici@8.11.2: {} - undici@8.12.1: {} + undici@8.12.2: {} + unicode-canonical-property-names-ecmascript@2.0.1: {} unicode-match-property-ecmascript@2.0.0: @@ -17046,10 +17296,29 @@ snapshots: tsx: 4.23.15 yaml: 2.9.1 - vitest@5.0.4(@opentelemetry/api@1.9.1)(@types/node@22.20.5)(@vitest/coverage-v8@5.0.4)(jsdom@30.1.2(@noble/hashes@1.8.0))(vite@8.3.4(@types/node@22.20.5)(esbuild@0.28.2)(jiti@2.7.0)(less@4.9.1(supports-color@11.0.0))(sass-embedded@1.105.1)(sass@1.105.1)(terser@5.51.2)(tsx@4.23.15)(yaml@2.9.1)): + vite@8.3.4(@types/node@22.20.5)(esbuild@0.28.2)(jiti@2.7.0)(less@4.9.1(supports-color@11.0.0))(sass-embedded@1.105.2)(sass@1.105.2)(terser@5.51.2)(tsx@4.23.15)(yaml@2.9.1): + dependencies: + lightningcss: 1.33.0 + picomatch: 4.0.7 + postcss: 8.5.30 + rolldown: 1.2.14 + tinyglobby: 0.2.17 + optionalDependencies: + '@types/node': 22.20.5 + esbuild: 0.28.2 + fsevents: 2.3.3 + jiti: 2.7.0 + less: 4.9.1(supports-color@11.0.0) + sass: 1.105.2 + sass-embedded: 1.105.2 + terser: 5.51.2 + tsx: 4.23.15 + yaml: 2.9.1 + + vitest@5.0.5(@opentelemetry/api@1.9.1)(@types/node@22.20.5)(@vitest/coverage-v8@5.0.5)(jsdom@30.1.3(@noble/hashes@1.8.0))(vite@8.3.4(@types/node@22.20.5)(esbuild@0.28.2)(jiti@2.7.0)(less@4.9.1(supports-color@11.0.0))(sass-embedded@1.105.1)(sass@1.105.1)(terser@5.51.2)(tsx@4.23.15)(yaml@2.9.1)): dependencies: '@types/chai': 5.2.3 - '@vitest/mocker': 5.0.4(vite@8.3.4(@types/node@22.20.5)(esbuild@0.28.2)(jiti@2.7.0)(less@4.9.1(supports-color@11.0.0))(sass-embedded@1.105.1)(sass@1.105.1)(terser@5.51.2)(tsx@4.23.15)(yaml@2.9.1)) + '@vitest/mocker': 5.0.5(vite@8.3.4(@types/node@22.20.5)(esbuild@0.28.2)(jiti@2.7.0)(less@4.9.1(supports-color@11.0.0))(sass-embedded@1.105.1)(sass@1.105.1)(terser@5.51.2)(tsx@4.23.15)(yaml@2.9.1)) chai: 6.3.0 es-module-lexer: 2.3.2 expect-type: 1.4.0 @@ -17065,8 +17334,32 @@ snapshots: optionalDependencies: '@opentelemetry/api': 1.9.1 '@types/node': 22.20.5 - '@vitest/coverage-v8': 5.0.4(vitest@5.0.4) - jsdom: 30.1.2(@noble/hashes@1.8.0) + '@vitest/coverage-v8': 5.0.5(vitest@5.0.5) + jsdom: 30.1.3(@noble/hashes@1.8.0) + transitivePeerDependencies: + - msw + + vitest@5.0.5(@opentelemetry/api@1.9.1)(@types/node@22.20.5)(@vitest/coverage-v8@5.0.5)(jsdom@30.1.3(@noble/hashes@1.8.0))(vite@8.3.4(@types/node@22.20.5)(esbuild@0.28.2)(jiti@2.7.0)(less@4.9.1(supports-color@11.0.0))(sass-embedded@1.105.2)(sass@1.105.2)(terser@5.51.2)(tsx@4.23.15)(yaml@2.9.1)): + dependencies: + '@types/chai': 5.2.3 + '@vitest/mocker': 5.0.5(vite@8.3.4(@types/node@22.20.5)(esbuild@0.28.2)(jiti@2.7.0)(less@4.9.1(supports-color@11.0.0))(sass-embedded@1.105.2)(sass@1.105.2)(terser@5.51.2)(tsx@4.23.15)(yaml@2.9.1)) + chai: 6.3.0 + es-module-lexer: 2.3.2 + expect-type: 1.4.0 + magic-string: 1.4.3 + obug: 3.0.0 + picomatch: 4.0.7 + std-env: 4.3.0 + tinybench: 6.2.2 + tinyexec: 1.3.1 + tinyglobby: 0.2.17 + vite: 8.3.4(@types/node@22.20.5)(esbuild@0.28.2)(jiti@2.7.0)(less@4.9.1(supports-color@11.0.0))(sass-embedded@1.105.2)(sass@1.105.2)(terser@5.51.2)(tsx@4.23.15)(yaml@2.9.1) + why-is-node-running: 3.2.1 + optionalDependencies: + '@opentelemetry/api': 1.9.1 + '@types/node': 22.20.5 + '@vitest/coverage-v8': 5.0.5(vitest@5.0.5) + jsdom: 30.1.3(@noble/hashes@1.8.0) transitivePeerDependencies: - msw @@ -17080,6 +17373,10 @@ snapshots: dependencies: graceful-fs: 4.2.11 + watchpack@2.6.2: + dependencies: + graceful-fs: 4.2.11 + weak-lru-cache@1.2.2: optional: true @@ -17093,27 +17390,33 @@ snapshots: webidl-conversions@8.0.1: {} - webpack-dev-middleware@8.3.0(webpack@5.111.1(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.29)(uglify-js@3.19.3)): + webpack-dev-middleware@8.4.0(bufferutil@4.1.0)(utf-8-validate@6.0.6)(webpack@5.112.0(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.29)(uglify-js@3.19.3)): dependencies: - ansi-html-community: 0.0.8 memfs: 4.80.0 - mime-types: 3.0.2 + mime-db: 1.54.0 range-parser: 1.3.0 schema-utils: 4.5.0 optionalDependencies: - webpack: 5.111.1(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.29)(uglify-js@3.19.3) + webpack: 5.112.0(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.29)(uglify-js@3.19.3) + ws: 8.22.0(bufferutil@4.1.0)(utf-8-validate@6.0.6) + transitivePeerDependencies: + - bufferutil + - utf-8-validate - webpack-dev-middleware@8.3.0(webpack@5.111.1(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.30)(uglify-js@3.19.3)): + webpack-dev-middleware@8.4.0(bufferutil@4.1.0)(utf-8-validate@6.0.6)(webpack@5.112.0(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.30)(uglify-js@3.19.3)): dependencies: - ansi-html-community: 0.0.8 memfs: 4.80.0 - mime-types: 3.0.2 + mime-db: 1.54.0 range-parser: 1.3.0 schema-utils: 4.5.0 optionalDependencies: - webpack: 5.111.1(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.30)(uglify-js@3.19.3) + webpack: 5.112.0(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.30)(uglify-js@3.19.3) + ws: 8.22.0(bufferutil@4.1.0)(utf-8-validate@6.0.6) + transitivePeerDependencies: + - bufferutil + - utf-8-validate - webpack-dev-server@6.0.0(bufferutil@4.1.0)(supports-color@11.0.0)(utf-8-validate@6.0.6)(webpack@5.111.1(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.29)(uglify-js@3.19.3)): + webpack-dev-server@6.0.0(bufferutil@4.1.0)(supports-color@11.0.0)(utf-8-validate@6.0.6)(webpack@5.112.0(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.29)(uglify-js@3.19.3)): dependencies: '@types/bonjour': 3.5.13 '@types/connect-history-api-fallback': 1.5.4 @@ -17138,16 +17441,16 @@ snapshots: selfsigned: 5.5.0 serve-index: 1.9.2(supports-color@11.0.0) tinyglobby: 0.2.17 - webpack-dev-middleware: 8.3.0(webpack@5.111.1(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.29)(uglify-js@3.19.3)) + webpack-dev-middleware: 8.4.0(bufferutil@4.1.0)(utf-8-validate@6.0.6)(webpack@5.112.0(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.29)(uglify-js@3.19.3)) ws: 8.22.0(bufferutil@4.1.0)(utf-8-validate@6.0.6) optionalDependencies: - webpack: 5.111.1(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.29)(uglify-js@3.19.3) + webpack: 5.112.0(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.29)(uglify-js@3.19.3) transitivePeerDependencies: - bufferutil - supports-color - utf-8-validate - webpack-dev-server@6.0.0(bufferutil@4.1.0)(supports-color@11.0.0)(utf-8-validate@6.0.6)(webpack@5.111.1(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.30)(uglify-js@3.19.3)): + webpack-dev-server@6.0.0(bufferutil@4.1.0)(supports-color@11.0.0)(utf-8-validate@6.0.6)(webpack@5.112.0(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.30)(uglify-js@3.19.3)): dependencies: '@types/bonjour': 3.5.13 '@types/connect-history-api-fallback': 1.5.4 @@ -17172,10 +17475,10 @@ snapshots: selfsigned: 5.5.0 serve-index: 1.9.2(supports-color@11.0.0) tinyglobby: 0.2.17 - webpack-dev-middleware: 8.3.0(webpack@5.111.1(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.30)(uglify-js@3.19.3)) + webpack-dev-middleware: 8.4.0(bufferutil@4.1.0)(utf-8-validate@6.0.6)(webpack@5.112.0(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.30)(uglify-js@3.19.3)) ws: 8.22.0(bufferutil@4.1.0)(utf-8-validate@6.0.6) optionalDependencies: - webpack: 5.111.1(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.30)(uglify-js@3.19.3) + webpack: 5.112.0(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.30)(uglify-js@3.19.3) transitivePeerDependencies: - bufferutil - supports-color @@ -17189,12 +17492,12 @@ snapshots: webpack-sources@3.6.0: {} - webpack-subresource-integrity@5.1.0(webpack@5.111.1(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.30)(uglify-js@3.19.3)): + webpack-subresource-integrity@5.1.0(webpack@5.112.0(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.30)(uglify-js@3.19.3)): dependencies: typed-assert: 1.0.9 - webpack: 5.111.1(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.30)(uglify-js@3.19.3) + webpack: 5.112.0(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.30)(uglify-js@3.19.3) - webpack@5.111.1(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.29)(uglify-js@3.19.3): + webpack@5.111.1(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.30)(uglify-js@3.19.3): dependencies: '@types/estree': 1.0.9 '@types/json-schema': 7.0.15 @@ -17208,7 +17511,7 @@ snapshots: events: 3.3.0 graceful-fs: 4.2.11 mime-db: 1.54.0 - minimizer-webpack-plugin: 5.13.0(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.29)(uglify-js@3.19.3)(webpack@5.111.1(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.29)(uglify-js@3.19.3)) + minimizer-webpack-plugin: 5.13.0(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.30)(uglify-js@3.19.3)(webpack@5.111.1(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.30)(uglify-js@3.19.3)) schema-utils: 4.5.0 tapable: 2.3.3 watchpack: 2.5.2 @@ -17231,7 +17534,7 @@ snapshots: - svgo - uglify-js - webpack@5.111.1(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.30)(uglify-js@3.19.3): + webpack@5.112.0(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.29)(uglify-js@3.19.3): dependencies: '@types/estree': 1.0.9 '@types/json-schema': 7.0.15 @@ -17245,10 +17548,47 @@ snapshots: events: 3.3.0 graceful-fs: 4.2.11 mime-db: 1.54.0 - minimizer-webpack-plugin: 5.13.0(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.30)(uglify-js@3.19.3)(webpack@5.111.1(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.30)(uglify-js@3.19.3)) + minimizer-webpack-plugin: 5.13.0(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.29)(uglify-js@3.19.3)(webpack@5.112.0(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.29)(uglify-js@3.19.3)) schema-utils: 4.5.0 tapable: 2.3.3 - watchpack: 2.5.2 + watchpack: 2.6.2 + webpack-sources: 3.6.0 + transitivePeerDependencies: + - '@minify-html/node' + - '@napi-rs/image' + - '@swc/core' + - '@swc/css' + - '@swc/html' + - clean-css + - cssnano + - csso + - esbuild + - html-minifier-terser + - imagemin + - lightningcss + - postcss + - sharp + - svgo + - uglify-js + + webpack@5.112.0(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.30)(uglify-js@3.19.3): + dependencies: + '@types/estree': 1.0.9 + '@types/json-schema': 7.0.15 + '@webassemblyjs/ast': 1.14.1 + '@webassemblyjs/wasm-edit': 1.14.1 + '@webassemblyjs/wasm-parser': 1.14.1 + browserslist: 4.29.3 + chrome-trace-event: 1.0.4 + enhanced-resolve: 5.26.0 + es-module-lexer: 2.3.2 + events: 3.3.0 + graceful-fs: 4.2.11 + mime-db: 1.54.0 + minimizer-webpack-plugin: 5.13.0(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.30)(uglify-js@3.19.3)(webpack@5.112.0(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.30)(uglify-js@3.19.3)) + schema-utils: 4.5.0 + tapable: 2.3.3 + watchpack: 2.6.2 webpack-sources: 3.6.0 transitivePeerDependencies: - '@minify-html/node' @@ -17518,8 +17858,6 @@ snapshots: '@yuku-toolchain/types': 0.19.0 yuku-core: 0.19.0 - zod@4.6.5: {} - zod@4.6.7: {} zone.js@0.16.3: {} From 508d6a2152d495001ef341e1c929f75d08d20228 Mon Sep 17 00:00:00 2001 From: Alan Agius <17563226+alan-agius4@users.noreply.github.com> Date: Mon, 19 Oct 2026 08:18:04 +0000 Subject: [PATCH 639/787] refactor(@angular-devkit/build-angular): update internal webpack dependency paths Update internal webpack dependency deep imports to match the reorganized module structure in Webpack 5.112.0. --- .../tools/webpack/plugins/common-js-usage-warn-plugin.ts | 8 ++++---- .../src/tools/webpack/plugins/named-chunks-plugin.ts | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/packages/angular_devkit/build_angular/src/tools/webpack/plugins/common-js-usage-warn-plugin.ts b/packages/angular_devkit/build_angular/src/tools/webpack/plugins/common-js-usage-warn-plugin.ts index 2374243b3121..59e56bf7abfb 100644 --- a/packages/angular_devkit/build_angular/src/tools/webpack/plugins/common-js-usage-warn-plugin.ts +++ b/packages/angular_devkit/build_angular/src/tools/webpack/plugins/common-js-usage-warn-plugin.ts @@ -11,10 +11,10 @@ import { Compilation, Compiler, Dependency, Module, NormalModule } from 'webpack import { addWarning } from '../../../utils/webpack-diagnostics'; // Webpack doesn't export these so the deep imports can potentially break. -const AMDDefineDependency = require('webpack/lib/dependencies/AMDDefineDependency'); -const CommonJsExportsDependency = require('webpack/lib/dependencies/CommonJsExportsDependency'); -const CommonJsRequireDependency = require('webpack/lib/dependencies/CommonJsRequireDependency'); -const CommonJsSelfReferenceDependency = require('webpack/lib/dependencies/CommonJsSelfReferenceDependency'); +const AMDDefineDependency = require('webpack/lib/dependencies/amd/AMDDefineDependency'); +const CommonJsExportsDependency = require('webpack/lib/dependencies/commonjs/CommonJsExportsDependency'); +const CommonJsRequireDependency = require('webpack/lib/dependencies/commonjs/CommonJsRequireDependency'); +const CommonJsSelfReferenceDependency = require('webpack/lib/dependencies/commonjs/CommonJsSelfReferenceDependency'); export interface CommonJsUsageWarnPluginOptions { /** A list of CommonJS or AMD packages that are allowed to be used without a warning. Use `'*'` to allow all. */ diff --git a/packages/angular_devkit/build_angular/src/tools/webpack/plugins/named-chunks-plugin.ts b/packages/angular_devkit/build_angular/src/tools/webpack/plugins/named-chunks-plugin.ts index bc838b2f6a3a..417d11484ef7 100644 --- a/packages/angular_devkit/build_angular/src/tools/webpack/plugins/named-chunks-plugin.ts +++ b/packages/angular_devkit/build_angular/src/tools/webpack/plugins/named-chunks-plugin.ts @@ -9,7 +9,7 @@ import { AsyncDependenciesBlock, Chunk, Compiler, Template, dependencies } from 'webpack'; // `ImportDependency` is not part of Webpack's depenencies typings. -const ImportDependency: typeof dependencies.ModuleDependency = require('webpack/lib/dependencies/ImportDependency'); +const ImportDependency: typeof dependencies.ModuleDependency = require('webpack/lib/dependencies/import/ImportDependency'); const PLUGIN_NAME = 'named-chunks-plugin'; From e93d9cb8bb8d9902bbe437e9dece8f44cb859bfe Mon Sep 17 00:00:00 2001 From: Charles Lyding <19598772+clydin@users.noreply.github.com> Date: Fri, 16 Oct 2026 14:42:09 -0400 Subject: [PATCH 640/787] fix(@angular/build): use distinct chunk naming for web worker bundles Previously, `bundleWebWorker` inherited `chunkNames` from the main esbuild configuration while bundling web workers in a separate synchronous esbuild pass. When both the main application bundle and a web worker dynamically imported modules that shared a common dependency, esbuild generated a shared chunk with identical content and the same `chunk-[hash].js` filename in both builds. During post-build chunk optimization, Rolldown traced only the main application entrypoint, merged the shared chunk into new optimized chunks, and removed the original `chunk-[hash].js` file from the build outputs while the unoptimized web worker chunks still imported it. Setting `chunkNames` to `'worker-chunk-[hash]'` in `bundleWebWorker` ensures that chunks emitted for web workers have distinct filenames and do not collide with main bundle chunks during metafile merging or chunk optimization. Closes #34292 --- .../behavior/web-workers-application_spec.ts | 73 +++++++++++++++++++ .../tools/esbuild/angular/compiler-plugin.ts | 1 + 2 files changed, 74 insertions(+) diff --git a/packages/angular/build/src/builders/application/tests/behavior/web-workers-application_spec.ts b/packages/angular/build/src/builders/application/tests/behavior/web-workers-application_spec.ts index 135d5ff68165..10112afd3b6b 100644 --- a/packages/angular/build/src/builders/application/tests/behavior/web-workers-application_spec.ts +++ b/packages/angular/build/src/builders/application/tests/behavior/web-workers-application_spec.ts @@ -57,5 +57,78 @@ describeBuilder(buildApplication, APPLICATION_BUILDER_INFO, (harness) => { // Ensure built worker is referenced in the application code harness.expectFile('dist/browser/main.js').content.toMatch(REFERENCED_WORKER_REGEXP); }); + + it('should emit all chunks referenced by a web worker when chunk optimization is enabled', async () => { + harness.useTarget('build', { + ...BASE_OPTIONS, + optimization: true, + }); + + await harness.writeFile( + 'src/app/shared.ts', + `export function sharedHelper(value: string) { return [value, value.toUpperCase(), value.toLowerCase(), value.repeat(3)].join('-'); }`, + ); + await harness.writeFile( + 'src/app/lazy-a.ts', + `import { sharedHelper } from './shared'; export const a = () => sharedHelper('a');`, + ); + await harness.writeFile( + 'src/app/lazy-b.ts', + `import { sharedHelper } from './shared'; export const b = () => sharedHelper('b');`, + ); + await harness.writeFile('src/app/lazy-c.ts', `export const c = () => 'c';`); + + await harness.writeFile( + 'src/app/worker.ts', + ` + addEventListener('message', async () => { + const [{ a }, { b }] = await Promise.all([import('./lazy-a'), import('./lazy-b')]); + postMessage(a() + b()); + }); + `, + ); + + await harness.writeFile( + 'src/app/app.component.ts', + ` + import { Component } from '@angular/core'; + @Component({ + selector: 'app-root', + standalone: false, + template: '

Worker Test

', + }) + export class AppComponent { + worker = new Worker(new URL('./worker', import.meta.url), { type: 'module' }); + constructor() { + Promise.all([import('./lazy-a'), import('./lazy-b'), import('./lazy-c')]).then(console.log); + } + } + `, + ); + + const { result } = await harness.executeOnce(); + expect(result?.success).toBeTrue(); + expect(harness.hasFileMatch('dist/browser', /^worker-chunk-/)).toBeTrue(); + + const mainContent = harness.readFile('dist/browser/main.js'); + const workerMatch = mainContent.match(/(worker-[A-Z0-9]{8}\.js)/); + expect(workerMatch).not.toBeNull(); + + const filesToCheck = new Set(['main.js']); + if (workerMatch) { + filesToCheck.add(workerMatch[1]); + } + + for (const file of filesToCheck) { + expect(harness.hasFile(`dist/browser/${file}`)) + .withContext(`Expected dist/browser/${file} to exist`) + .toBeTrue(); + + const content = harness.readFile(`dist/browser/${file}`); + for (const match of content.matchAll(/(?:from|import)\s*\(?["']\.\/([^"']+\.js)["']\)?/g)) { + filesToCheck.add(match[1]); + } + } + }); }); }); diff --git a/packages/angular/build/src/tools/esbuild/angular/compiler-plugin.ts b/packages/angular/build/src/tools/esbuild/angular/compiler-plugin.ts index cd53d6085e65..e90280e02ebb 100644 --- a/packages/angular/build/src/tools/esbuild/angular/compiler-plugin.ts +++ b/packages/angular/build/src/tools/esbuild/angular/compiler-plugin.ts @@ -728,6 +728,7 @@ function bundleWebWorker( metafile: true, format: 'esm', entryNames: 'worker-[hash]', + chunkNames: 'worker-chunk-[hash]', entryPoints: [workerFile], sourcemap: pluginOptions.sourcemap, // Zone.js is not used in Web workers so no need to disable From 405839b16084fb9473c596fe0bcf5d27a9bae803 Mon Sep 17 00:00:00 2001 From: MeAkib Date: Mon, 19 Oct 2026 14:45:35 +0600 Subject: [PATCH 641/787] docs: fix typos in option descriptions and the `ng run` long description Several option descriptions that are published on angular.dev contain typos ("prerending", "These file are", "a unit test files", "comma seperate"). The Karma `browsers: false` description also read "Does use run tests against a browser", which says the opposite of what the option does. The `ng run` long description has a run-on sentence. Correct the wording. --- packages/angular/build/src/builders/application/schema.json | 2 +- packages/angular/build/src/builders/karma/schema.json | 4 ++-- packages/angular/cli/src/commands/run/long-description.md | 2 +- .../build_angular/src/builders/karma/schema.json | 4 ++-- packages/schematics/angular/application/schema.json | 2 +- packages/schematics/angular/ng-new/schema.json | 2 +- 6 files changed, 8 insertions(+), 8 deletions(-) diff --git a/packages/angular/build/src/builders/application/schema.json b/packages/angular/build/src/builders/application/schema.json index 8458d385a3fc..cdf059ce3a25 100644 --- a/packages/angular/build/src/builders/application/schema.json +++ b/packages/angular/build/src/builders/application/schema.json @@ -568,7 +568,7 @@ "oneOf": [ { "type": "boolean", - "description": "Enable prerending of pages of your application during build time." + "description": "Enable prerendering of pages of your application during build time." }, { "type": "object", diff --git a/packages/angular/build/src/builders/karma/schema.json b/packages/angular/build/src/builders/karma/schema.json index 50c739ff69c8..4a41bc4fdad2 100644 --- a/packages/angular/build/src/builders/karma/schema.json +++ b/packages/angular/build/src/builders/karma/schema.json @@ -245,12 +245,12 @@ "oneOf": [ { "type": "string", - "description": "A comma seperate list of browsers to run tests against." + "description": "A comma-separated list of browsers to run tests against." }, { "const": false, "type": "boolean", - "description": "Does use run tests against a browser." + "description": "Does not run tests against a browser." } ] }, diff --git a/packages/angular/cli/src/commands/run/long-description.md b/packages/angular/cli/src/commands/run/long-description.md index e74f8756679d..00ff74da0628 100644 --- a/packages/angular/cli/src/commands/run/long-description.md +++ b/packages/angular/cli/src/commands/run/long-description.md @@ -7,4 +7,4 @@ For example, the `serve` target for a newly generated app has a predefined alternate configuration named `production`. You can define new targets and their configuration options in the `architect` section -of the `angular.json` file which you can run them from the command line using the `ng run` command. +of the `angular.json` file, which you can run from the command line using the `ng run` command. diff --git a/packages/angular_devkit/build_angular/src/builders/karma/schema.json b/packages/angular_devkit/build_angular/src/builders/karma/schema.json index fdd5927cfdac..1704810ab840 100644 --- a/packages/angular_devkit/build_angular/src/builders/karma/schema.json +++ b/packages/angular_devkit/build_angular/src/builders/karma/schema.json @@ -203,12 +203,12 @@ "oneOf": [ { "type": "string", - "description": "A comma seperate list of browsers to run tests against." + "description": "A comma-separated list of browsers to run tests against." }, { "const": false, "type": "boolean", - "description": "Does use run tests against a browser." + "description": "Does not run tests against a browser." } ] }, diff --git a/packages/schematics/angular/application/schema.json b/packages/schematics/angular/application/schema.json index 83df1b163873..d0c4f348feea 100644 --- a/packages/schematics/angular/application/schema.json +++ b/packages/schematics/angular/application/schema.json @@ -84,7 +84,7 @@ "x-user-analytics": "ep.ng_style" }, "skipTests": { - "description": "Skip the generation of a unit test files `spec.ts`.", + "description": "Skip the generation of unit test files `spec.ts`.", "type": "boolean", "default": false, "alias": "S" diff --git a/packages/schematics/angular/ng-new/schema.json b/packages/schematics/angular/ng-new/schema.json index 2c69fa84aaad..6494b1889d96 100644 --- a/packages/schematics/angular/ng-new/schema.json +++ b/packages/schematics/angular/ng-new/schema.json @@ -152,7 +152,7 @@ "aiConfig": { "type": "array", "uniqueItems": true, - "description": "Specifies which AI tools to generate configuration files for. These file are used to improve the outputs of AI tools by following the best practices.", + "description": "Specifies which AI tools to generate configuration files for. These files are used to improve the outputs of AI tools by following the best practices.", "items": { "type": "string", "enum": ["none", "claude-code", "cursor", "gemini-cli", "open-ai-codex", "vscode"] From e3787076ebca0af72079f669b5b047a065b16128 Mon Sep 17 00:00:00 2001 From: MeAkib Date: Mon, 19 Oct 2026 07:29:16 +0600 Subject: [PATCH 642/787] fix(@angular/build): support quotes in `styles` and `polyfills` paths The application builder generated the global styles and polyfills entry modules by wrapping each configured path in single quotes without escaping. A path containing a single quote, such as `src/dev's theme/theme.css`, produced an invalid import and the build failed with "Could not resolve" or a syntax error. Generate the import specifiers with `JSON.stringify` so that such paths are quoted correctly. --- .../application/tests/options/polyfills_spec.ts | 16 ++++++++++++++++ .../application/tests/options/styles_spec.ts | 17 +++++++++++++++++ .../tools/esbuild/application-code-bundle.ts | 12 +++++++----- .../build/src/tools/esbuild/global-styles.ts | 4 +++- 4 files changed, 43 insertions(+), 6 deletions(-) diff --git a/packages/angular/build/src/builders/application/tests/options/polyfills_spec.ts b/packages/angular/build/src/builders/application/tests/options/polyfills_spec.ts index 5fff9bd33a7c..ad68443a2e03 100644 --- a/packages/angular/build/src/builders/application/tests/options/polyfills_spec.ts +++ b/packages/angular/build/src/builders/application/tests/options/polyfills_spec.ts @@ -89,5 +89,21 @@ describeBuilder(buildApplication, APPLICATION_BUILDER_INFO, (harness) => { }); }); } + + it('uses a provided file with a single quote in its path', async () => { + await harness.writeFile('src/main.ts', 'console.log("TEST");'); + await harness.writeFile(`src/dev's polyfills/polyfills.js`, `console.log('main');`); + + harness.useTarget('build', { + ...BASE_OPTIONS, + polyfills: [`src/dev's polyfills/polyfills.js`], + }); + + const { result } = await harness.executeOnce(); + + expect(result?.success).toBe(true); + + harness.expectFile('dist/browser/polyfills.js').content.toContain(`console.log("main")`); + }); }); }); diff --git a/packages/angular/build/src/builders/application/tests/options/styles_spec.ts b/packages/angular/build/src/builders/application/tests/options/styles_spec.ts index 311b0037daa5..7c5b3d52eb8c 100644 --- a/packages/angular/build/src/builders/application/tests/options/styles_spec.ts +++ b/packages/angular/build/src/builders/application/tests/options/styles_spec.ts @@ -62,6 +62,23 @@ describeBuilder(buildApplication, APPLICATION_BUILDER_INFO, (harness) => { .content.toContain(''); }); + it('processes a style with a single quote in its path', async () => { + await harness.writeFile(`src/dev's theme/test-style-a.css`, '.test-a {color: red}'); + + harness.useTarget('build', { + ...BASE_OPTIONS, + styles: [`src/dev's theme/test-style-a.css`], + }); + + const { result } = await harness.executeOnce(); + + expect(result?.success).toBe(true); + + harness + .expectFile('dist/browser/styles.css') + .content.toMatch(/\.test-a {\s*color: red;?\s*}/); + }); + it('processes multiple styles into a single output', async () => { await harness.writeFiles({ 'src/test-style-a.css': '.test-a {color: red}', diff --git a/packages/angular/build/src/tools/esbuild/application-code-bundle.ts b/packages/angular/build/src/tools/esbuild/application-code-bundle.ts index af53e04f58af..c98ad3bcae28 100644 --- a/packages/angular/build/src/tools/esbuild/application-code-bundle.ts +++ b/packages/angular/build/src/tools/esbuild/application-code-bundle.ts @@ -364,8 +364,8 @@ export function createServerMainCodeBundleOptions( `export { ɵresetCompiledComponents } from '@angular/core';`, // Re-export all symbols including default export from 'main.server.ts' - `export { default } from '${mainServerEntryPointJsImport}';`, - `export * from '${mainServerEntryPointJsImport}';`, + `export { default } from ${JSON.stringify(mainServerEntryPointJsImport)};`, + `export * from ${JSON.stringify(mainServerEntryPointJsImport)};`, ]; return { @@ -496,8 +496,8 @@ export function createSsrEntryCodeBundleOptions( `import '${ssrInjectManifestNamespace}';`, // Re-export all symbols including default export - `import * as server from '${serverEntryPointJsImport}';`, - `export * from '${serverEntryPointJsImport}';`, + `import * as server from ${JSON.stringify(serverEntryPointJsImport)};`, + `export * from ${JSON.stringify(serverEntryPointJsImport)};`, // The below is needed to avoid // `Import "default" will always be undefined because there is no matching export` warning when no default is present. `const defaultExportName = 'default';`, @@ -740,7 +740,9 @@ function getEsBuildCommonPolyfillsOptions( } // Generate module contents with an import statement per defined polyfill - let contents = polyfillPaths.map((file) => `import '${toPosixPath(file)}';`).join('\n'); + let contents = polyfillPaths + .map((file) => `import ${JSON.stringify(toPosixPath(file))};`) + .join('\n'); // The below should be done after loading `$localize` as otherwise the locale will be overridden. if (i18nOptions.shouldInline) { diff --git a/packages/angular/build/src/tools/esbuild/global-styles.ts b/packages/angular/build/src/tools/esbuild/global-styles.ts index fd2cb13fa7b2..79afff2008af 100644 --- a/packages/angular/build/src/tools/esbuild/global-styles.ts +++ b/packages/angular/build/src/tools/esbuild/global-styles.ts @@ -92,7 +92,9 @@ export function createGlobalStylesBundleOptions( assert(files, `global style name should always be found [${args.path}]`); return { - contents: files.map((file) => `@import '${toPosixPath(file)}';`).join('\n'), + contents: files + .map((file) => `@import ${JSON.stringify(toPosixPath(file))};`) + .join('\n'), loader: 'css', resolveDir: workspaceRoot, }; From 1c1fe4e88897f69116696a73c46f225b469aebab Mon Sep 17 00:00:00 2001 From: MeAkib Date: Sun, 18 Oct 2026 20:17:43 +0600 Subject: [PATCH 643/787] fix(@schematics/angular): apply `viewEncapsulation` to generated application components The `viewEncapsulation` option of the application schematic had no effect. The root component template did not set `encapsulation`, the value was not added to the component schematic defaults, so components generated later used the default encapsulation, and the `defaultEncapsulation` option added to `bootstrapModule` in `main.ts` for NgModule applications is only used by the JIT compiler. Set `encapsulation` on the root component, add `viewEncapsulation` to the component schematic defaults in `angular.json`, and remove the ineffective `defaultEncapsulation` option from `main.ts`. Fixes #34388 --- .../src/app/app__suffix__.ts.template | 5 ++- .../files/module-files/src/main.ts.template | 7 +--- .../src/app/app__suffix__.ts.template | 5 ++- .../schematics/angular/application/index.ts | 6 ++- .../angular/application/index_spec.ts | 41 ++++++++++++++++--- 5 files changed, 49 insertions(+), 15 deletions(-) diff --git a/packages/schematics/angular/application/files/module-files/src/app/app__suffix__.ts.template b/packages/schematics/angular/application/files/module-files/src/app/app__suffix__.ts.template index ef9aebaa0e14..db9c4cfc0137 100644 --- a/packages/schematics/angular/application/files/module-files/src/app/app__suffix__.ts.template +++ b/packages/schematics/angular/application/files/module-files/src/app/app__suffix__.ts.template @@ -1,6 +1,7 @@ -import { Component, signal } from '@angular/core'; +import { Component, signal<% if (!!viewEncapsulation) { %>, ViewEncapsulation<% } %> } from '@angular/core'; -@Component({ +@Component({<% if (!!viewEncapsulation) { %> + encapsulation: ViewEncapsulation.<%= viewEncapsulation %>,<% } %> selector: '<%= selector %>', standalone: false,<% if (inlineStyle) { %> styles: [],<% } else { %> diff --git a/packages/schematics/angular/application/files/module-files/src/main.ts.template b/packages/schematics/angular/application/files/module-files/src/main.ts.template index 0fcb878b1e23..94cbfa256d61 100644 --- a/packages/schematics/angular/application/files/module-files/src/main.ts.template +++ b/packages/schematics/angular/application/files/module-files/src/main.ts.template @@ -1,8 +1,5 @@ -<% if (!!viewEncapsulation) { %>import { ViewEncapsulation } from '@angular/core'; -<% } %>import { platformBrowser } from '@angular/platform-browser'; +import { platformBrowser } from '@angular/platform-browser'; import { AppModule } from './app/app<%= typeSeparator %>module'; -platformBrowser().bootstrapModule(AppModule, { - <% if (!!viewEncapsulation) { %> defaultEncapsulation: ViewEncapsulation.<%= viewEncapsulation %><% } %> -}) +platformBrowser().bootstrapModule(AppModule) .catch(err => console.error(err)); diff --git a/packages/schematics/angular/application/files/standalone-files/src/app/app__suffix__.ts.template b/packages/schematics/angular/application/files/standalone-files/src/app/app__suffix__.ts.template index dfdb04abcb76..2106166ea22f 100644 --- a/packages/schematics/angular/application/files/standalone-files/src/app/app__suffix__.ts.template +++ b/packages/schematics/angular/application/files/standalone-files/src/app/app__suffix__.ts.template @@ -1,7 +1,8 @@ -import { Component, signal } from '@angular/core';<% if (routing) { %> +import { Component, signal<% if (!!viewEncapsulation) { %>, ViewEncapsulation<% } %> } from '@angular/core';<% if (routing) { %> import { RouterOutlet } from '@angular/router';<% } %> -@Component({ +@Component({<% if (!!viewEncapsulation) { %> + encapsulation: ViewEncapsulation.<%= viewEncapsulation %>,<% } %> imports: [<% if (routing) { %>RouterOutlet<% } %>], selector: '<%= selector %>',<% if (inlineStyle) { %> styles: [],<% } else { %> diff --git a/packages/schematics/angular/application/index.ts b/packages/schematics/angular/application/index.ts index 2820634b1ba8..cac60c23177b 100644 --- a/packages/schematics/angular/application/index.ts +++ b/packages/schematics/angular/application/index.ts @@ -206,7 +206,8 @@ function addAppToWorkspaceFile(options: ApplicationOptions, appDir: string): Rul options.inlineTemplate || options.inlineStyle || options.minimal || - options.style !== Style.Css + options.style !== Style.Css || + options.viewEncapsulation ) { const componentSchematicsOptions: JsonObject = {}; if (options.inlineTemplate ?? options.minimal) { @@ -218,6 +219,9 @@ function addAppToWorkspaceFile(options: ApplicationOptions, appDir: string): Rul if (options.style && options.style !== Style.Css) { componentSchematicsOptions.style = options.style; } + if (options.viewEncapsulation) { + componentSchematicsOptions.viewEncapsulation = options.viewEncapsulation; + } schematics['@schematics/angular:component'] = componentSchematicsOptions; } diff --git a/packages/schematics/angular/application/index_spec.ts b/packages/schematics/angular/application/index_spec.ts index ad2ba04ff348..7f86e245553a 100644 --- a/packages/schematics/angular/application/index_spec.ts +++ b/packages/schematics/angular/application/index_spec.ts @@ -704,6 +704,35 @@ describe('Application Schematic', () => { expect(main).toContain('bootstrapApplication'); }); + it(`should set 'encapsulation' in the root component when 'viewEncapsulation' is provided`, async () => { + const options = { ...defaultOptions, viewEncapsulation: ViewEncapsulation.None }; + const tree = await schematicRunner.runSchematic('application', options, workspaceTree); + + const component = tree.readContent('/projects/foo/src/app/app.ts'); + expect(component).toContain( + `import { Component, signal, ViewEncapsulation } from '@angular/core';`, + ); + expect(component).toContain('encapsulation: ViewEncapsulation.None'); + }); + + it(`should add 'viewEncapsulation' to the component schematic defaults when provided`, async () => { + const options = { ...defaultOptions, viewEncapsulation: ViewEncapsulation.None }; + const tree = await schematicRunner.runSchematic('application', options, workspaceTree); + + const { projects } = JSON.parse(tree.readContent('/angular.json')); + expect(projects.foo.schematics['@schematics/angular:component'].viewEncapsulation).toBe('None'); + }); + + it(`should not set 'encapsulation' in the root component by default`, async () => { + const tree = await schematicRunner.runSchematic('application', defaultOptions, workspaceTree); + + expect(tree.readContent('/projects/foo/src/app/app.ts')).not.toContain('encapsulation'); + const { projects } = JSON.parse(tree.readContent('/angular.json')); + expect(projects.foo.schematics?.['@schematics/angular:component']?.viewEncapsulation).toBe( + undefined, + ); + }); + describe('standalone=false', () => { it('should add the provideZoneChangeDetection with event coalescing option by default with zone.js apps', async () => { const tree = await schematicRunner.runSchematic( @@ -720,7 +749,7 @@ describe('Application Schematic', () => { expect(content).toContain('provideZoneChangeDetection({ eventCoalescing: true })'); }); - it(`should set 'defaultEncapsulation' in main.ts when 'ViewEncapsulation' is provided`, async () => { + it(`should set 'encapsulation' in the root component when 'viewEncapsulation' is provided`, async () => { const tree = await schematicRunner.runSchematic( 'application', { @@ -731,10 +760,12 @@ describe('Application Schematic', () => { workspaceTree, ); - const path = '/projects/foo/src/main.ts'; - const content = tree.readContent(path); - expect(content).toContain('defaultEncapsulation: ViewEncapsulation.ShadowDom'); - expect(content).toContain(`import { ViewEncapsulation } from '@angular/core'`); + const component = tree.readContent('/projects/foo/src/app/app.ts'); + expect(component).toContain( + `import { Component, signal, ViewEncapsulation } from '@angular/core';`, + ); + expect(component).toContain('encapsulation: ViewEncapsulation.ShadowDom'); + expect(tree.readContent('/projects/foo/src/main.ts')).not.toContain('defaultEncapsulation'); }); it('should handle the routing flag', async () => { From 41b54ecdda17b96924d82873042c04dc7d3a4e40 Mon Sep 17 00:00:00 2001 From: MeAkib Date: Sun, 18 Oct 2026 17:12:12 +0600 Subject: [PATCH 644/787] fix(@schematics/angular): skip `webWorkerTsConfig` for unit-test builder test targets The `web-worker` schematic added the `webWorkerTsConfig` option to the project's `test` target regardless of its builder. New applications use the `@angular/build:unit-test` builder, which does not have this option, so `ng test` failed schema validation with `Unknown option "webWorkerTsConfig"` after generating a web worker. The option is no longer added to `test` targets that use the unit-test builder, which reads build options from its `buildTarget`. Other test builders, such as Karma, still receive the option. Fixes #34385 --- .../schematics/angular/web-worker/index.ts | 4 +++- .../angular/web-worker/index_spec.ts | 20 +++++++++++++++++++ 2 files changed, 23 insertions(+), 1 deletion(-) diff --git a/packages/schematics/angular/web-worker/index.ts b/packages/schematics/angular/web-worker/index.ts index a19e2b714174..45e1f39ad34c 100644 --- a/packages/schematics/angular/web-worker/index.ts +++ b/packages/schematics/angular/web-worker/index.ts @@ -26,6 +26,7 @@ import { parseName } from '../utility/parse-name'; import { relativePathToWorkspaceRoot } from '../utility/paths'; import { createProjectSchematic } from '../utility/project'; import { buildDefaultPath, updateWorkspace } from '../utility/workspace'; +import { Builders } from '../utility/workspace-models'; import { Schema as WebWorkerOptions } from './schema'; function addSnippet(options: WebWorkerOptions): Rule { @@ -115,7 +116,8 @@ const webWorkerSchematic: RuleFactory = createProjectSchematic const workerConfigPath = join(root, 'tsconfig.worker.json'); (buildTarget.options ??= {}).webWorkerTsConfig ??= workerConfigPath; - if (testTarget) { + // The unit-test builder has no `webWorkerTsConfig` option and reads it from the build target. + if (testTarget && testTarget.builder !== Builders.BuildUnitTest) { (testTarget.options ??= {}).webWorkerTsConfig ??= workerConfigPath; } }), diff --git a/packages/schematics/angular/web-worker/index_spec.ts b/packages/schematics/angular/web-worker/index_spec.ts index c1ab48b8d196..a922a6d3cee6 100644 --- a/packages/schematics/angular/web-worker/index_spec.ts +++ b/packages/schematics/angular/web-worker/index_spec.ts @@ -9,6 +9,7 @@ import { SchematicTestRunner, UnitTestTree } from '@angular-devkit/schematics/testing'; import { parse as parseJson } from 'jsonc-parser'; import { Schema as ApplicationOptions } from '../application/schema'; +import { Builders } from '../utility/workspace-models'; import { Schema as WorkspaceOptions } from '../workspace/schema'; import { Schema as WebWorkerOptions } from './schema'; @@ -68,6 +69,25 @@ describe('Web Worker Schematic', () => { ); }); + it('should not add the webWorkerTsConfig option to a unit-test builder test target', async () => { + const tree = await schematicRunner.runSchematic('web-worker', defaultOptions, appTree); + const { projects } = JSON.parse(tree.readContent('/angular.json')); + expect(projects.bar.architect.test.builder).toBe(Builders.BuildUnitTest); + expect(projects.bar.architect.test.options?.webWorkerTsConfig).toBeUndefined(); + }); + + it('should add the webWorkerTsConfig option to a karma builder test target', async () => { + const config = JSON.parse(appTree.readContent('/angular.json')); + config.projects.bar.architect.test = { builder: Builders.BuildKarma, options: {} }; + appTree.overwrite('/angular.json', JSON.stringify(config, undefined, 2)); + + const tree = await schematicRunner.runSchematic('web-worker', defaultOptions, appTree); + const { projects } = JSON.parse(tree.readContent('/angular.json')); + expect(projects.bar.architect.test.options.webWorkerTsConfig).toBe( + 'projects/bar/tsconfig.worker.json', + ); + }); + it('should add snippet to sibling file', async () => { const tree = await schematicRunner.runSchematic('web-worker', defaultOptions, appTree); const appComponent = tree.readContent('/projects/bar/src/app/app.ts'); From 32dd079da3fd6b53fe6d57eaba0ee2bcfb8f3b08 Mon Sep 17 00:00:00 2001 From: MeAkib Date: Fri, 16 Oct 2026 21:25:20 +0600 Subject: [PATCH 645/787] fix(@schematics/angular): correct error and warning messages in environments schematic The error for non-application projects concatenated the first sentence with the project type before evaluating the ternary, so the "Only application project types are supported" sentence was never printed and projects without a `projectType` were reported as having a "projectType" of "undefined". The third-party `server` builder warning also printed the `build` target's builder instead of the `server` target's builder. Wrap the ternary in parentheses, use the `server` target's builder in the warning, and fix the typos in both error messages. --- .../schematics/angular/environments/index.ts | 11 ++--- .../angular/environments/index_spec.ts | 44 +++++++++++++++++++ 2 files changed, 50 insertions(+), 5 deletions(-) diff --git a/packages/schematics/angular/environments/index.ts b/packages/schematics/angular/environments/index.ts index 7082689c3348..f32bb850ed3d 100644 --- a/packages/schematics/angular/environments/index.ts +++ b/packages/schematics/angular/environments/index.ts @@ -19,16 +19,17 @@ export default function (options: EnvironmentOptions): Rule { return updateWorkspace((workspace) => { const project = workspace.projects.get(options.project); if (!project) { - throw new SchematicsException(`Project name "${options.project}" doesn't not exist.`); + throw new SchematicsException(`Project name "${options.project}" does not exist.`); } const type = project.extensions['projectType']; if (type !== 'application') { return log( 'error', - 'Only application project types are support by this schematic.' + type - ? ` Project "${options.project}" has a "projectType" of "${type}".` - : ` Project "${options.project}" has no "projectType" defined.`, + 'Only application project types are supported by this schematic.' + + (type + ? ` Project "${options.project}" has a "projectType" of "${type}".` + : ` Project "${options.project}" has no "projectType" defined.`), ); } @@ -89,7 +90,7 @@ function* generateConfigurationEnvironments( if (serverTarget && serverTarget.builder !== AngularBuilder.Server) { yield log( 'warn', - `"server" target found for project "${projectName}" has a third-party builder "${buildTarget.builder}".` + + `"server" target found for project "${projectName}" has a third-party builder "${serverTarget.builder}".` + ' The generated project options may not be compatible with this builder.', ); } diff --git a/packages/schematics/angular/environments/index_spec.ts b/packages/schematics/angular/environments/index_spec.ts index d53026a28a4d..49a249cef715 100644 --- a/packages/schematics/angular/environments/index_spec.ts +++ b/packages/schematics/angular/environments/index_spec.ts @@ -192,4 +192,48 @@ describe('Environments Schematic', () => { }), ); }); + + it('should log an error for non-application projects', async () => { + const config = JSON.parse(applicationTree.readContent('/angular.json')); + config.projects.foo.projectType = 'library'; + applicationTree.overwrite('/angular.json', JSON.stringify(config, undefined, 2)); + + const logs: string[] = []; + const loggerSubscription = schematicRunner.logger.subscribe(({ message }) => + logs.push(message), + ); + + try { + await runEnvironmentsSchematic(); + } finally { + loggerSubscription.unsubscribe(); + } + + expect(logs).toEqual([ + 'Only application project types are supported by this schematic.' + + ' Project "foo" has a "projectType" of "library".', + ]); + }); + + it('should log the builder of a third-party server target', async () => { + const config = JSON.parse(applicationTree.readContent('/angular.json')); + config.projects.foo.architect.server = { builder: 'custom:server' }; + applicationTree.overwrite('/angular.json', JSON.stringify(config, undefined, 2)); + + const logs: string[] = []; + const loggerSubscription = schematicRunner.logger.subscribe(({ message }) => + logs.push(message), + ); + + try { + await runEnvironmentsSchematic(); + } finally { + loggerSubscription.unsubscribe(); + } + + expect(logs).toContain( + '"server" target found for project "foo" has a third-party builder "custom:server".' + + ' The generated project options may not be compatible with this builder.', + ); + }); }); From 452019db8b0b67a076435bc3b08d70a1f943b116 Mon Sep 17 00:00:00 2001 From: MeAkib Date: Sun, 18 Oct 2026 19:39:04 +0600 Subject: [PATCH 646/787] docs(@schematics/angular): correct generated file name examples in `name` descriptions The `name` option descriptions of the directive, service, enum, interface, pipe, guard, interceptor and resolver schematics showed file names that include the type suffix, such as `my-directive.directive.ts` and `my-pipe.pipe.ts`. By default, these schematics no longer add the type to the file name, and the pipe, guard, interceptor and resolver schematics use `-` as the type separator. Update the examples to match the default output. --- packages/schematics/angular/directive/schema.json | 2 +- packages/schematics/angular/enum/schema.json | 2 +- packages/schematics/angular/guard/schema.json | 2 +- packages/schematics/angular/interceptor/schema.json | 2 +- packages/schematics/angular/interface/schema.json | 2 +- packages/schematics/angular/pipe/schema.json | 2 +- packages/schematics/angular/resolver/schema.json | 2 +- packages/schematics/angular/service/schema.json | 2 +- 8 files changed, 8 insertions(+), 8 deletions(-) diff --git a/packages/schematics/angular/directive/schema.json b/packages/schematics/angular/directive/schema.json index 6d672fc4fdeb..37ed01266c4b 100644 --- a/packages/schematics/angular/directive/schema.json +++ b/packages/schematics/angular/directive/schema.json @@ -8,7 +8,7 @@ "properties": { "name": { "type": "string", - "description": "The name for the new directive. This will be used to create the directive's class and spec files (e.g., `my-directive.directive.ts` and `my-directive.directive.spec.ts`).", + "description": "The name for the new directive. This will be used to create the directive's class and spec files (e.g., `my-directive.ts` and `my-directive.spec.ts`).", "$default": { "$source": "argv", "index": 0 diff --git a/packages/schematics/angular/enum/schema.json b/packages/schematics/angular/enum/schema.json index ae6b17f457bd..3b3ec536db8b 100644 --- a/packages/schematics/angular/enum/schema.json +++ b/packages/schematics/angular/enum/schema.json @@ -8,7 +8,7 @@ "properties": { "name": { "type": "string", - "description": "The name for the new enum. This will be used to create the enum file (e.g., `my-enum.enum.ts`).", + "description": "The name for the new enum. This will be used to create the enum file (e.g., `my-enum.ts`).", "$default": { "$source": "argv", "index": 0 diff --git a/packages/schematics/angular/guard/schema.json b/packages/schematics/angular/guard/schema.json index 9e1a9f3084c6..80ee83a35ff7 100644 --- a/packages/schematics/angular/guard/schema.json +++ b/packages/schematics/angular/guard/schema.json @@ -8,7 +8,7 @@ "properties": { "name": { "type": "string", - "description": "The name for the new route guard. This will be used to create the guard's class and spec files (e.g., `my-guard.guard.ts` and `my-guard.guard.spec.ts`).", + "description": "The name for the new route guard. This will be used to create the guard's class and spec files (e.g., `example-guard.ts` and `example-guard.spec.ts`).", "$default": { "$source": "argv", "index": 0 diff --git a/packages/schematics/angular/interceptor/schema.json b/packages/schematics/angular/interceptor/schema.json index e42e0c675e8e..7589743f22b1 100755 --- a/packages/schematics/angular/interceptor/schema.json +++ b/packages/schematics/angular/interceptor/schema.json @@ -8,7 +8,7 @@ "properties": { "name": { "type": "string", - "description": "The name for the new interceptor. This will be used to create the interceptor's class and spec files (e.g., `my-interceptor.interceptor.ts` and `my-interceptor.interceptor.spec.ts`).", + "description": "The name for the new interceptor. This will be used to create the interceptor's class and spec files (e.g., `example-interceptor.ts` and `example-interceptor.spec.ts`).", "$default": { "$source": "argv", "index": 0 diff --git a/packages/schematics/angular/interface/schema.json b/packages/schematics/angular/interface/schema.json index ab47d1713ab4..52c117fa7068 100644 --- a/packages/schematics/angular/interface/schema.json +++ b/packages/schematics/angular/interface/schema.json @@ -8,7 +8,7 @@ "properties": { "name": { "type": "string", - "description": "The name for the new interface. This will be used to create the interface file (e.g., `my-interface.interface.ts`).", + "description": "The name for the new interface. This will be used to create the interface file (e.g., `my-interface.ts`).", "$default": { "$source": "argv", "index": 0 diff --git a/packages/schematics/angular/pipe/schema.json b/packages/schematics/angular/pipe/schema.json index 19803a524ed4..2aaf6e062e7e 100644 --- a/packages/schematics/angular/pipe/schema.json +++ b/packages/schematics/angular/pipe/schema.json @@ -8,7 +8,7 @@ "properties": { "name": { "type": "string", - "description": "The name for the new pipe. This will be used to create the pipe's class and spec files (e.g., `my-pipe.pipe.ts` and `my-pipe.pipe.spec.ts`).", + "description": "The name for the new pipe. This will be used to create the pipe's class and spec files (e.g., `example-pipe.ts` and `example-pipe.spec.ts`).", "$default": { "$source": "argv", "index": 0 diff --git a/packages/schematics/angular/resolver/schema.json b/packages/schematics/angular/resolver/schema.json index 1a5654f3c7cf..db6a7d4ff73d 100644 --- a/packages/schematics/angular/resolver/schema.json +++ b/packages/schematics/angular/resolver/schema.json @@ -8,7 +8,7 @@ "properties": { "name": { "type": "string", - "description": "The name for the new resolver. This will be used to create the resolver's class and spec files (e.g., `my-resolver.resolver.ts` and `my-resolver.resolver.spec.ts`).", + "description": "The name for the new resolver. This will be used to create the resolver's class and spec files (e.g., `example-resolver.ts` and `example-resolver.spec.ts`).", "$default": { "$source": "argv", "index": 0 diff --git a/packages/schematics/angular/service/schema.json b/packages/schematics/angular/service/schema.json index a3ebf9d3a3fe..b081c31dada2 100644 --- a/packages/schematics/angular/service/schema.json +++ b/packages/schematics/angular/service/schema.json @@ -8,7 +8,7 @@ "properties": { "name": { "type": "string", - "description": "The name for the new service. This will be used to create the service's class and spec files (e.g., `my-service.service.ts` and `my-service.service.spec.ts`).", + "description": "The name for the new service. This will be used to create the service's class and spec files (e.g., `my-service.ts` and `my-service.spec.ts`).", "$default": { "$source": "argv", "index": 0 From 7305b7c7378c86fc2d539f012c5b809da36d9885 Mon Sep 17 00:00:00 2001 From: MeAkib Date: Fri, 16 Oct 2026 00:13:49 +0600 Subject: [PATCH 647/787] docs(@angular/cli): correct CSS resource output location in `ng build` description The long description stated that resources referenced in CSS, such as images and fonts, are written and fingerprinted at the root of the output folder. The application builder writes them to the `media` directory of the browser output, which is configurable with `outputPath.media`, and only adds a hash when `outputHashing` is `all` or `media`. --- packages/angular/cli/src/commands/build/long-description.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/packages/angular/cli/src/commands/build/long-description.md b/packages/angular/cli/src/commands/build/long-description.md index b2c14d8f23fe..cba16adeb716 100644 --- a/packages/angular/cli/src/commands/build/long-description.md +++ b/packages/angular/cli/src/commands/build/long-description.md @@ -13,6 +13,7 @@ Note that in the configuration file, you must specify names in camelCase. Some additional options can only be set through the configuration file, either by direct editing or with the `ng config` command. These include `assets`, `styles`, and `scripts` objects that provide runtime-global resources to include in the project. -Resources in CSS, such as images and fonts, are automatically written and fingerprinted at the root of the output folder. +Resources in CSS, such as images and fonts, are automatically written to the `media` directory of the browser output +(configurable with the `outputPath.media` option) and fingerprinted when `outputHashing` is set to `all` or `media`. For further details, see [Workspace Configuration](reference/configs/workspace-config). From 4a883c88213124b63c475373271b673bc4ec00ef Mon Sep 17 00:00:00 2001 From: Shuaib Hasan Akib <48770016+MeAkib@users.noreply.github.com> Date: Mon, 19 Oct 2026 22:02:26 +0600 Subject: [PATCH 648/787] docs(@angular/cli): remove references to the default project The `ng deploy` descriptions stated that the deploy builder runs for the default project when no project name is supplied, and the `ng new` long description described the initial application as the workspace's default project. The CLI no longer has a default project: architect commands use the only project that has the target, or the project in the current working directory. Describe that behavior instead. --- packages/angular/cli/src/commands/deploy/cli.ts | 3 ++- packages/angular/cli/src/commands/deploy/long-description.md | 3 ++- packages/angular/cli/src/commands/new/long-description.md | 2 +- 3 files changed, 5 insertions(+), 3 deletions(-) diff --git a/packages/angular/cli/src/commands/deploy/cli.ts b/packages/angular/cli/src/commands/deploy/cli.ts index fb305c94aaf1..4dc270bdf49c 100644 --- a/packages/angular/cli/src/commands/deploy/cli.ts +++ b/packages/angular/cli/src/commands/deploy/cli.ts @@ -39,5 +39,6 @@ export default class DeployCommandModule command = 'deploy [project]'; override longDescription = longDescription; describe = - 'Invokes the deploy builder for a specified project or for the default project in the workspace.'; + 'Invokes the deploy builder for a specified project, the only project with a deploy target, ' + + 'or the project in the current working directory.'; } diff --git a/packages/angular/cli/src/commands/deploy/long-description.md b/packages/angular/cli/src/commands/deploy/long-description.md index 0436390680a4..53a2253be42b 100644 --- a/packages/angular/cli/src/commands/deploy/long-description.md +++ b/packages/angular/cli/src/commands/deploy/long-description.md @@ -1,5 +1,6 @@ The command takes an optional project name, as specified in the `projects` section of the `angular.json` workspace configuration file. -When a project name is not supplied, executes the `deploy` builder for the default project. +When a project name is not supplied, executes the `deploy` builder for the only project that has a `deploy` target, +or for the project in the current working directory. To use the `ng deploy` command, use `ng add` to add a package that implements deployment capabilities to your favorite platform. Adding the package automatically updates your workspace configuration, adding a deployment diff --git a/packages/angular/cli/src/commands/new/long-description.md b/packages/angular/cli/src/commands/new/long-description.md index 1166f974887a..e211dadb5f35 100644 --- a/packages/angular/cli/src/commands/new/long-description.md +++ b/packages/angular/cli/src/commands/new/long-description.md @@ -1,4 +1,4 @@ -Creates and initializes a new Angular application that is the default project for a new workspace. +Creates and initializes a new Angular workspace with an initial application. Provides interactive prompts for optional configuration, such as adding routing support. All prompts can safely be allowed to default. From adcdcc6688fd773491dcb9f5197eefffd4aeee45 Mon Sep 17 00:00:00 2001 From: Nayeem Hossain Date: Sat, 17 Oct 2026 11:31:45 +0600 Subject: [PATCH 649/787] fix(@angular/build): invalidate Vite module cache for removed dev server output files Content-hashed chunks are renamed on every rebuild that changes them. The dev server removed the old names from its own file maps but left their transformed code and source maps in Vite's module graph, so memory grew with each save and the old chunk URLs kept serving stale code. Invalidate the Vite modules for removed files, as is already done for updated files. --- .../behavior/serve-renamed-chunks_spec.ts | 57 +++++++++++++++++++ .../src/builders/dev-server/vite/index.ts | 7 +++ 2 files changed, 64 insertions(+) create mode 100644 packages/angular/build/src/builders/dev-server/tests/behavior/serve-renamed-chunks_spec.ts diff --git a/packages/angular/build/src/builders/dev-server/tests/behavior/serve-renamed-chunks_spec.ts b/packages/angular/build/src/builders/dev-server/tests/behavior/serve-renamed-chunks_spec.ts new file mode 100644 index 000000000000..d43d47def463 --- /dev/null +++ b/packages/angular/build/src/builders/dev-server/tests/behavior/serve-renamed-chunks_spec.ts @@ -0,0 +1,57 @@ +/** + * @license + * Copyright Google LLC All Rights Reserved. + * + * Use of this source code is governed by an MIT-style license that can be + * found in the LICENSE file at https://angular.dev/license + */ + +import { executeDevServer } from '../../index'; +import { describeServeBuilder } from '../jasmine-helpers'; +import { BASE_OPTIONS, DEV_SERVER_BUILDER_INFO } from '../setup'; + +describeServeBuilder(executeDevServer, DEV_SERVER_BUILDER_INFO, (harness, setupTarget) => { + describe('Behavior: "Renamed chunks"', () => { + beforeEach(async () => { + setupTarget(harness); + + await harness.writeFile('src/lazy.ts', `export const value = 'first';`); + await harness.writeFile('src/main.ts', `import('./lazy').then((m) => console.log(m.value));`); + }); + + it('does not serve a lazy chunk that a rebuild renamed', async () => { + harness.useTarget('serve', { + ...BASE_OPTIONS, + watch: true, + }); + + let oldChunk = ''; + + await harness.executeWithCases([ + async ({ result }) => { + expect(result?.success).toBeTrue(); + + const main = await (await fetch(new URL('main.js', `${result?.baseUrl}`))).text(); + oldChunk = main.match(/chunk-[a-zA-Z0-9]+\.js/)?.[0] ?? ''; + expect(oldChunk).not.toBe(''); + + // Request the chunk so that Vite transforms and caches it + const response = await fetch(new URL(oldChunk, `${result?.baseUrl}`)); + expect(response.status).toBe(200); + expect(await response.text()).toContain('first'); + + await harness.modifyFile('src/lazy.ts', (content) => content.replace('first', 'second')); + }, + async ({ result }) => { + expect(result?.success).toBeTrue(); + + const main = await (await fetch(new URL('main.js', `${result?.baseUrl}`))).text(); + expect(main).not.toContain(oldChunk); + + const response = await fetch(new URL(oldChunk, `${result?.baseUrl}`)); + expect(response.status).toBe(404); + }, + ]); + }); + }); +}); diff --git a/packages/angular/build/src/builders/dev-server/vite/index.ts b/packages/angular/build/src/builders/dev-server/vite/index.ts index 4800559a2171..7f36740cc3f5 100644 --- a/packages/angular/build/src/builders/dev-server/vite/index.ts +++ b/packages/angular/build/src/builders/dev-server/vite/index.ts @@ -288,6 +288,13 @@ export async function* serveWithVite( const filePath = '/' + normalizePath(removed.path); generatedFiles.delete(filePath); assetFiles.delete(filePath); + + // Release Vite's cached transform result for output files that no longer exist, + // such as content-hashed chunks that were renamed by the rebuild. + const moduleGraph = server.moduleGraph; + moduleGraph + .getModulesByFile(normalizePath(join(server.config.root, filePath))) + ?.forEach((m) => moduleGraph.invalidateModule(m)); } for (const file of result.files) { From b42cfeecfac376d1ed365ffbf9d247dbfc2bde59 Mon Sep 17 00:00:00 2001 From: SkyZeroZx <73321943+SkyZeroZx@users.noreply.github.com> Date: Thu, 15 Oct 2026 13:09:40 -0500 Subject: [PATCH 650/787] fix(@angular/ssr): use only the first value of the `X-Forwarded-Prefix` header The `X-Forwarded-Prefix` header is validated using its first comma-separated value, like the other `X-Forwarded-*` headers. However, redirects used the entire header value. With a trusted header, any value after the first one was added to the `Location` header without being validated. The first value is now used wherever the header is read, which matches how `X-Forwarded-Host`, `X-Forwarded-Proto` and `X-Forwarded-Port` are handled. --- packages/angular/ssr/src/app-engine.ts | 3 ++- packages/angular/ssr/src/app.ts | 3 ++- packages/angular/ssr/src/utils/ng.ts | 5 ++++- packages/angular/ssr/test/app-engine_spec.ts | 13 +++++++++++++ packages/angular/ssr/test/app_spec.ts | 10 ++++++++++ 5 files changed, 31 insertions(+), 3 deletions(-) diff --git a/packages/angular/ssr/src/app-engine.ts b/packages/angular/ssr/src/app-engine.ts index a5f10fbc7d92..1fa69c1f2629 100644 --- a/packages/angular/ssr/src/app-engine.ts +++ b/packages/angular/ssr/src/app-engine.ts @@ -13,6 +13,7 @@ import { EntryPointExports, getAngularAppEngineManifest } from './manifest'; import { createRedirectResponse } from './utils/redirect'; import { joinUrlParts } from './utils/url'; import { + getFirstHeaderValue, normalizeTrustProxyHeaders, sanitizeRequestHeaders, validateRequest, @@ -208,7 +209,7 @@ export class AngularAppEngine { if (preferredLocale) { const subPath = supportedLocales[preferredLocale]; if (subPath !== undefined) { - const prefix = request.headers.get('X-Forwarded-Prefix') ?? ''; + const prefix = getFirstHeaderValue(request.headers.get('X-Forwarded-Prefix')) ?? ''; return createRedirectResponse( joinUrlParts(prefix, pathname, subPath), diff --git a/packages/angular/ssr/src/app.ts b/packages/angular/ssr/src/app.ts index 517cf1e31727..69d5f9e6e100 100644 --- a/packages/angular/ssr/src/app.ts +++ b/packages/angular/ssr/src/app.ts @@ -25,6 +25,7 @@ import { AngularBootstrap, renderAngular } from './utils/ng'; import { promiseWithAbort } from './utils/promise'; import { createRedirectResponse } from './utils/redirect'; import { buildPathWithParams, joinUrlParts, stripLeadingSlash } from './utils/url'; +import { getFirstHeaderValue } from './utils/validation'; /** * A set of well-known URLs that are not handled by Angular. @@ -167,7 +168,7 @@ export class AngularServerApp { if (redirectTo !== undefined) { const location = joinUrlParts( - request.headers.get('X-Forwarded-Prefix') ?? '', + getFirstHeaderValue(request.headers.get('X-Forwarded-Prefix')) ?? '', buildPathWithParams(redirectTo, url.pathname), ); diff --git a/packages/angular/ssr/src/utils/ng.ts b/packages/angular/ssr/src/utils/ng.ts index 4ae3a7f4ed0f..028136749b17 100644 --- a/packages/angular/ssr/src/utils/ng.ts +++ b/packages/angular/ssr/src/utils/ng.ts @@ -25,6 +25,7 @@ import { import { ActivatedRoute, Router } from '@angular/router'; import { Console } from '../console'; import { addTrailingSlash, joinUrlParts, stripIndexHtmlFromURL, stripTrailingSlash } from './url'; +import { getFirstHeaderValue } from './validation'; /** * Represents the bootstrap mechanism for an Angular application. @@ -126,7 +127,9 @@ export async function renderAngular( const requestPrefix = envInjector.get(APP_BASE_HREF, null, { optional: true }) ?? - envInjector.get(REQUEST, null, { optional: true })?.headers.get('X-Forwarded-Prefix'); + getFirstHeaderValue( + envInjector.get(REQUEST, null, { optional: true })?.headers.get('X-Forwarded-Prefix'), + ); const { pathname, search, hash } = envInjector.get(PlatformLocation); const finalUrl = constructSerializedUrl(router, { pathname, search, hash }, requestPrefix); diff --git a/packages/angular/ssr/test/app-engine_spec.ts b/packages/angular/ssr/test/app-engine_spec.ts index eae063eec700..db03015b85f1 100644 --- a/packages/angular/ssr/test/app-engine_spec.ts +++ b/packages/angular/ssr/test/app-engine_spec.ts @@ -202,6 +202,19 @@ describe('AngularAppEngine', () => { expect(response?.headers.get('Vary')).toBe('X-Forwarded-Prefix, Accept-Language'); }); + it('should only use the first value of the forwarded prefix in locale redirect location', async () => { + const request = new Request('https://example.com', { + headers: { + 'Accept-Language': 'it', + 'X-Forwarded-Prefix': '/app, /"', + }, + }); + + const response = await appEngine.handle(request); + expect(response?.status).toBe(302); + expect(response?.headers.get('Location')).toBe('/app/it'); + }); + it('should completely ignore proxy headers if not allowed', async () => { const strictEngine = new AngularAppEngine({ trustProxyHeaders: false }); const request = new Request('https://example.com', { diff --git a/packages/angular/ssr/test/app_spec.ts b/packages/angular/ssr/test/app_spec.ts index 8d8ee9add00b..68e3ed2eb1c2 100644 --- a/packages/angular/ssr/test/app_spec.ts +++ b/packages/angular/ssr/test/app_spec.ts @@ -538,6 +538,16 @@ describe('AngularServerApp', () => { expect(response?.headers.get('location')).toBe('/base/home?filter=test'); expect(response?.status).toBe(302); }); + + it('should only use the first value of the "X-Forwarded-Prefix" header in redirects', async () => { + const response = await app.handle( + new Request('http://localhost/redirect', { + headers: { 'X-Forwarded-Prefix': '/base, /"' }, + }), + ); + expect(response?.headers.get('location')).toBe('/base/home'); + expect(response?.status).toBe(302); + }); }); describe('Critical CSS inlining', () => { From f9f3864974e90c6ea78c53cc4a0cab3f2e4477dc Mon Sep 17 00:00:00 2001 From: Charles Lyding <19598772+clydin@users.noreply.github.com> Date: Fri, 16 Oct 2026 11:35:33 -0400 Subject: [PATCH 651/787] fix(@angular/build): match proxy glob patterns against URL pathname only When normalizing proxy configurations for Vite, glob patterns are converted into regular expression strings using picomatch. Because picomatch builds regular expressions assuming the input is a file path and anchors them with `$`, whereas Vite tests regex proxy keys against `req.url` (which includes any query string), requests with query parameters could fail to match glob entries such as `/search/**` or `/api/*.json`, or inadvertently match wildcards against query string parameters. Adapt the generated regular expression so that wildcard tokens do not match across the `?` query delimiter and end-of-path anchors allow an optional query string after the matched pathname. Closes #34257 --- .../tests/options/proxy-config_spec.ts | 52 ++++++- .../build/src/utils/load-proxy-config.ts | 32 ++++- .../build/src/utils/load-proxy-config_spec.ts | 129 ++++++++++++++++++ 3 files changed, 211 insertions(+), 2 deletions(-) create mode 100644 packages/angular/build/src/utils/load-proxy-config_spec.ts diff --git a/packages/angular/build/src/builders/dev-server/tests/options/proxy-config_spec.ts b/packages/angular/build/src/builders/dev-server/tests/options/proxy-config_spec.ts index 745da6eee969..31ea54fc4004 100644 --- a/packages/angular/build/src/builders/dev-server/tests/options/proxy-config_spec.ts +++ b/packages/angular/build/src/builders/dev-server/tests/options/proxy-config_spec.ts @@ -330,6 +330,56 @@ describeServeBuilder(executeDevServer, DEV_SERVER_BUILDER_INFO, (harness, setupT await otherProxyServer.close(); } }); + + it('matches glob entries against the URL pathname when a query string is present', async () => { + harness.useTarget('serve', { + ...BASE_OPTIONS, + proxyConfig: 'proxy.config.json', + }); + + const proxyServer = await createProxyServer(); + try { + await harness.writeFiles({ + 'proxy.config.json': ` + { + "/api/test/**": { "target": "http://127.0.0.1:${proxyServer.address.port}" } + } + `, + }); + + const { result, response } = await executeOnceAndFetch(harness, '/api/test?q=angular'); + + expect(result?.success).toBeTrue(); + expect(await response?.text()).toContain('TEST_API_RETURN'); + } finally { + await proxyServer.close(); + } + }); + + it('does not match glob wildcards against query string parameters', async () => { + harness.useTarget('serve', { + ...BASE_OPTIONS, + proxyConfig: 'proxy.config.json', + }); + + const proxyServer = await createProxyServer(); + try { + await harness.writeFiles({ + 'proxy.config.json': ` + { + "/api/*.json": { "target": "http://127.0.0.1:${proxyServer.address.port}" } + } + `, + }); + + const { result, response } = await executeOnceAndFetch(harness, '/api/test?file=data.json'); + + expect(result?.success).toBeTrue(); + expect(await response?.text()).not.toContain('TEST_API_RETURN'); + } finally { + await proxyServer.close(); + } + }); }); }); @@ -340,7 +390,7 @@ describeServeBuilder(executeDevServer, DEV_SERVER_BUILDER_INFO, (harness, setupT */ async function createProxyServer(body = 'TEST_API_RETURN') { const proxyServer = createServer((request, response) => { - if (request.url?.endsWith('/test')) { + if (request.url?.split('?')[0].endsWith('/test')) { response.writeHead(200); response.end(body); } else { diff --git a/packages/angular/build/src/utils/load-proxy-config.ts b/packages/angular/build/src/utils/load-proxy-config.ts index e40b1981d764..f32db992ac92 100644 --- a/packages/angular/build/src/utils/load-proxy-config.ts +++ b/packages/angular/build/src/utils/load-proxy-config.ts @@ -118,7 +118,7 @@ function normalizeProxyConfiguration( // since Vite proxies a request with the first entry that matches it. const orderedProxy: Record = {}; for (const [key, value] of Object.entries(normalizedProxy)) { - const context = key[0] !== '^' && isDynamicPattern(key) ? makeRegExpFromGlob(key).source : key; + const context = key[0] !== '^' && isDynamicPattern(key) ? makeUrlRegExpFromGlob(key) : key; orderedProxy[context] = value; } normalizedProxy = orderedProxy; @@ -151,6 +151,36 @@ function normalizeProxyConfiguration( return normalizedProxy; } +/** + * Converts a glob pattern to a regular expression source string that matches + * the pathname portion of a request URL while allowing an optional query string. + * + * Vite tests regex proxy keys against `req.url`, which includes the query string, + * whereas `picomatch` generates regexes assuming the input is only a pathname. + */ +function makeUrlRegExpFromGlob(glob: string): string { + const { source } = makeRegExpFromGlob(glob); + + return ( + source + // Ensure picomatch's "at least one character" lookahead does not + // treat the `?` query delimiter as a pathname character (e.g., `/api/*` on `/api/?a=1`). + .replaceAll('(?=.)', '(?=[^?])') + // Prevent single-segment wildcards (`*` and `?`) from matching + // across `?` into the query string (e.g., `/api/*.json` on `/api/users?file=data.json`). + .replaceAll('[^/]', '[^/?]') + // Prevent leading-dot-aware `?` wildcards from matching the `?` delimiter. + .replaceAll('[^.\\/]', '[^.\\/?]') + // Prevent multi-segment globstars (`**`) from matching across `?` into the query string + // (e.g., `/api/**/users` on `/api/other?redirect=/users`). + .replaceAll('\\.).)*?', '\\.)[^?])*?') + // Replace unescaped end-of-input anchors (`$`, both at the end of the pattern and inside + // internal alternation groups for trailing `/**` or negated globs) so an optional query + // string is permitted after the matched pathname. + .replace(/(? { + let tempDir: string; + + beforeEach(async () => { + const baseTmpDir = process.env['TEST_TMPDIR']; + assert(baseTmpDir, 'TEST_TMPDIR is not set'); + tempDir = await mkdtemp(join(baseTmpDir, 'angular-proxy-config-spec-')); + }); + + afterEach(async () => { + await rm(tempDir, { recursive: true, force: true }); + }); + + async function createGlobMatcher(glob: string): Promise<(url: string) => boolean> { + const configPath = join(tempDir, 'proxy.conf.json'); + await writeFile(configPath, JSON.stringify({ [glob]: { target: 'http://localhost:3000' } })); + const proxy = await loadProxyConfiguration(tempDir, 'proxy.conf.json'); + assert(proxy, 'Expected proxy configuration to be loaded'); + const keys = Object.keys(proxy); + expect(keys.length).toBe(1); + const regex = new RegExp(keys[0]); + + return (url: string) => regex.test(url); + } + + describe('glob to RegExp conversion with query strings', () => { + it('handles trailing globstar (/**) with and without query strings', async () => { + const matches = await createGlobMatcher('/search/**'); + + expect(matches('/search')).toBeTrue(); + expect(matches('/search?q=angular')).toBeTrue(); + expect(matches('/search/')).toBeTrue(); + expect(matches('/search/?q=angular')).toBeTrue(); + expect(matches('/search/items')).toBeTrue(); + expect(matches('/search/items?q=angular')).toBeTrue(); + expect(matches('/search/items?callback=/.hidden')).toBeTrue(); + + expect(matches('/searching')).toBeFalse(); + expect(matches('/searching?q=angular')).toBeFalse(); + expect(matches('/other?redirect=/search')).toBeFalse(); + }); + + it('handles single-segment wildcard (*) without matching across slashes or query strings', async () => { + const matches = await createGlobMatcher('/api/*'); + + expect(matches('/api/users')).toBeTrue(); + expect(matches('/api/users?id=1')).toBeTrue(); + expect(matches('/api/users?redirect=/home/page')).toBeTrue(); + + expect(matches('/api')).toBeFalse(); + expect(matches('/api/')).toBeFalse(); + expect(matches('/api/?a=1')).toBeFalse(); + expect(matches('/api/users/profile')).toBeFalse(); + expect(matches('/api/users/profile?a=1')).toBeFalse(); + }); + + it('handles suffix globs (*.json) without matching query parameters', async () => { + const matches = await createGlobMatcher('/api/*.json'); + + expect(matches('/api/data.json')).toBeTrue(); + expect(matches('/api/data.json?v=1')).toBeTrue(); + + expect(matches('/api/users')).toBeFalse(); + expect(matches('/api/users?file=data.json')).toBeFalse(); + expect(matches('/api/.json?v=1')).toBeFalse(); + }); + + it('handles middle globstar (/**/) without matching paths in query parameters', async () => { + const matches = await createGlobMatcher('/api/**/users'); + + expect(matches('/api/users')).toBeTrue(); + expect(matches('/api/users?page=1')).toBeTrue(); + expect(matches('/api/v1/users?page=1')).toBeTrue(); + expect(matches('/api/v1/v2/users?page=1')).toBeTrue(); + + expect(matches('/api/other?redirect=/users')).toBeFalse(); + expect(matches('/api/users/profile?page=1')).toBeFalse(); + }); + + it('handles single-character wildcard (?) without matching the query delimiter', async () => { + const matches = await createGlobMatcher('/api/v?'); + + expect(matches('/api/v1')).toBeTrue(); + expect(matches('/api/v1?a=1')).toBeTrue(); + + expect(matches('/api/v')).toBeFalse(); + expect(matches('/api/v?')).toBeFalse(); + expect(matches('/api/v?a=1')).toBeFalse(); + expect(matches('/api/v12?a=1')).toBeFalse(); + }); + + it('handles negated globs (!) with and without query strings', async () => { + const matches = await createGlobMatcher('!/api/public/**'); + + expect(matches('/api/public')).toBeFalse(); + expect(matches('/api/public?foo=1')).toBeFalse(); + expect(matches('/api/public/assets?foo=1')).toBeFalse(); + + expect(matches('/api/private')).toBeTrue(); + expect(matches('/api/private?foo=1')).toBeTrue(); + }); + + it('handles brace expansion and extglobs with query strings', async () => { + const matchesBraces = await createGlobMatcher('/api/{auth,users}/**'); + expect(matchesBraces('/api/auth?q=1')).toBeTrue(); + expect(matchesBraces('/api/users/list?q=1')).toBeTrue(); + expect(matchesBraces('/api/other?q=1')).toBeFalse(); + + const matchesExtglob = await createGlobMatcher('/**/!(*.d).ts'); + expect(matchesExtglob('/app/main.ts')).toBeTrue(); + expect(matchesExtglob('/app/main.ts?extra=.d.ts')).toBeTrue(); + expect(matchesExtglob('/app/main.d.ts')).toBeFalse(); + expect(matchesExtglob('/app/main.d.ts?extra=.ts')).toBeFalse(); + }); + }); +}); From 8baa9fe3750617614695e54aae4899ca6bfc3fe3 Mon Sep 17 00:00:00 2001 From: Angular Robot Date: Mon, 19 Oct 2026 08:45:25 +0000 Subject: [PATCH 652/787] build: update cross-repo angular dependencies See associated pull request for more information. --- tests/e2e/ng-snapshot/package.json | 32 +++++++++++++++--------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/tests/e2e/ng-snapshot/package.json b/tests/e2e/ng-snapshot/package.json index e02c1dcd10e4..f413e800e924 100644 --- a/tests/e2e/ng-snapshot/package.json +++ b/tests/e2e/ng-snapshot/package.json @@ -2,21 +2,21 @@ "description": "snapshot versions of Angular for e2e testing", "private": true, "dependencies": { - "@angular/animations": "github:angular/animations-builds#43efef5cbf38f5261191e5c11d7f49c276428137", - "@angular/cdk": "github:angular/cdk-builds#43c02174c1dc0f4b74a85342bbd9f43d040bf1ae", - "@angular/common": "github:angular/common-builds#89d9b5d43c81051c59a33d24ccccd75b51f6dc48", - "@angular/compiler": "github:angular/compiler-builds#e91181d83e7086debe8f32f21bfa434c4bd94afd", - "@angular/compiler-cli": "github:angular/compiler-cli-builds#bfd2191e1955c38a1ce52aa467508702d132e7ba", - "@angular/core": "github:angular/core-builds#31cf6f74f000a8499b3ce204ad9b339e830dcc39", - "@angular/forms": "github:angular/forms-builds#1dbb38cca305af00e3362cb59c5293b44a7ae7f1", - "@angular/language-service": "github:angular/language-service-builds#54ce2dee3572da8657674dc965d010fd37b6d15b", - "@angular/localize": "github:angular/localize-builds#bcdfcaf668fd983db3496cdb696ca8b3aa2f68aa", - "@angular/material": "github:angular/material-builds#2c82c94514f7cb2bc3dafd3b5db2160aa9c01517", - "@angular/material-moment-adapter": "github:angular/material-moment-adapter-builds#728a7be6d90391791e0967357a07959d2a4fa3d3", - "@angular/platform-browser": "github:angular/platform-browser-builds#a1b99915c2e91ab779ee0443904bd0194b8e2fb0", - "@angular/platform-browser-dynamic": "github:angular/platform-browser-dynamic-builds#cdfb691b31a234662977f12f0982b880035bb72e", - "@angular/platform-server": "github:angular/platform-server-builds#9e3f315c175ed493a83d91b2d1743582e4934ab3", - "@angular/router": "github:angular/router-builds#972a0d117fd048a478e2cb035ef5b442e8cc5ceb", - "@angular/service-worker": "github:angular/service-worker-builds#f3e0f7d39cadb10a0257cf826cc0519e7809e8e2" + "@angular/animations": "github:angular/animations-builds#9061d3badcf171ceaf4c3f257d525bb367e64d2f", + "@angular/cdk": "github:angular/cdk-builds#a7133af71098f1a8b94e78328f1706713b223aff", + "@angular/common": "github:angular/common-builds#fb3dff8abc701a57c86d107c4a1ce29aa66cf713", + "@angular/compiler": "github:angular/compiler-builds#8d0c0552dd6a5699a47d85ecd7a923c584da36b4", + "@angular/compiler-cli": "github:angular/compiler-cli-builds#c38b2f14f87adfe70437e4a565edb9993048226c", + "@angular/core": "github:angular/core-builds#8254123e1c7d65912132e40a500239776e19e85c", + "@angular/forms": "github:angular/forms-builds#697994110d89849a23140f8faf7619efd3637d96", + "@angular/language-service": "github:angular/language-service-builds#8cc6dd2ceeddf62afa365d9bc0da8b3b42e42439", + "@angular/localize": "github:angular/localize-builds#375898b753874e1002c4650597856d33d380c6d8", + "@angular/material": "github:angular/material-builds#94ca526e9bf74b2c55e2073ae104ff6e3a5582c3", + "@angular/material-moment-adapter": "github:angular/material-moment-adapter-builds#7de680bb1a2da811477e1fcdf460843c9202a116", + "@angular/platform-browser": "github:angular/platform-browser-builds#fc2f3d8ef2ffea6182f6526b7a8ed793adb8f95a", + "@angular/platform-browser-dynamic": "github:angular/platform-browser-dynamic-builds#8eab001dfabb015a143f1fca1e8e16650aec270c", + "@angular/platform-server": "github:angular/platform-server-builds#9640726146a30387e82653343864cf986822e6a3", + "@angular/router": "github:angular/router-builds#6a4f8546aa8da003b43cf0b5d4ee235ab1923dec", + "@angular/service-worker": "github:angular/service-worker-builds#8942152d2c80ed6ebcf920b030df23eace9157d0" } } From b8180a6530cfb7a39515de016a5386ec48ef1fdb Mon Sep 17 00:00:00 2001 From: Alan Agius <17563226+alan-agius4@users.noreply.github.com> Date: Mon, 19 Oct 2026 12:58:58 +0000 Subject: [PATCH 653/787] fix(@angular/build): support incremental asset updates and output cleanup in library watch mode Ensure the library builder properly handles created, modified, and deleted assets during watch mode rebuilds, and removes stale bundle, sourcemap, and manifest output files from disk when entry points or exports are removed. --- .../src/builders/library/builder-state.ts | 174 ++++++++++++-- .../builders/library/builder-state_spec.ts | 150 +++++++++++- .../build/src/builders/library/builder.ts | 24 +- .../src/builders/library/pipeline/assets.ts | 104 +++++++-- .../builders/library/pipeline/build-action.ts | 55 ++--- .../src/builders/library/pipeline/bundler.ts | 109 +++++---- .../library/pipeline/entry-points_spec.ts | 2 + .../tests/behavior/watch-cleanup_spec.ts | 216 ++++++++++++++++++ .../build/src/builders/library/types.ts | 14 +- 9 files changed, 707 insertions(+), 141 deletions(-) create mode 100644 packages/angular/build/src/builders/library/tests/behavior/watch-cleanup_spec.ts diff --git a/packages/angular/build/src/builders/library/builder-state.ts b/packages/angular/build/src/builders/library/builder-state.ts index 81b4e21e778d..9a468c2fb543 100644 --- a/packages/angular/build/src/builders/library/builder-state.ts +++ b/packages/angular/build/src/builders/library/builder-state.ts @@ -8,6 +8,13 @@ import { toPosixPath } from '../../utils/path'; import { ExecutionResult } from './execution-result'; +import { + type AssetMatcher, + type CollectedAssets, + collectAssetsToEmit, + createAssetMatchers, +} from './pipeline/assets'; +import type { OutputFile } from './pipeline/utils'; import type { BundleResult, LibraryCompilationOutput, @@ -17,17 +24,27 @@ import type { /** * Encapsulates incremental compilation state, transitive resource reference tracking, - * watched compilation file tracking, and execution results across watch-mode rebuilds. + * asset matchers, and emitted output file tracking across watch-mode rebuilds. */ export class BuilderState { readonly #referencingFiles = new Map>(); readonly #referencedByFile = new Map>(); readonly #watchedCompilationFiles = new Set(); readonly #pendingCompilationFiles = new Set(); + readonly #pendingAssetFiles = new Set(); + readonly #assetMatchers?: readonly AssetMatcher[]; + + #emittedBundleFiles = new Set(); + #emittedManifestFiles = new Set(); + readonly #emittedAssets = new Map>(); + #hasEmittedAssets = false; #executionResult = new ExecutionResult(); + #hasUpdatedBundles = false; + #singleProgramCache?: SingleProgramCache; #compilationMode?: 'partial' | 'full'; + #hasEmittedTslib = false; /** Map of entry point names to their previous bundle results. */ readonly previousBundleResults = new Map(); @@ -44,18 +61,12 @@ export class BuilderState { /** Whether package.json and secondary entry point manifests have been emitted. */ hasEmittedManifests = false; - /** Whether the last emitted root package.json included a tslib dependency. */ - hasEmittedTslib = false; - - /** Whether static assets have been emitted in a prior iteration. */ - hasEmittedAssets = false; - /** Whether entry points in package.json changed since the last compilation. */ hasEntryPointsChanges = false; constructor( options?: Partial< - Pick + Pick >, ) { if (options?.tsConfigPath) { @@ -69,6 +80,8 @@ export class BuilderState { this.#watchedCompilationFiles.add(entryPoint.entryFilePath); } } + + this.#assetMatchers = options?.assets ? createAssetMatchers(options.assets) : undefined; } /** Cached unified TypeScript and Angular compilation state. */ @@ -81,6 +94,11 @@ export class BuilderState { return this.#compilationMode; } + /** Whether the last emitted root package.json included a tslib dependency. */ + get hasEmittedTslib(): boolean { + return this.#hasEmittedTslib; + } + /** Whether any active entry point bundle imports `tslib`. */ get hasTslibImport(): boolean { for (const result of this.previousBundleResults.values()) { @@ -109,12 +127,13 @@ export class BuilderState { } /** - * Resets the execution result for a new build iteration. + * Resets the execution result and staged output state for a new build iteration. * * @returns The fresh `ExecutionResult` instance for the current build iteration. */ resetExecutionResult(): ExecutionResult { this.#executionResult = new ExecutionResult(); + this.#hasUpdatedBundles = false; return this.#executionResult; } @@ -221,6 +240,9 @@ export class BuilderState { if (file !== packageJsonPath) { this.#pendingCompilationFiles.add(file); } + if (this.#hasEmittedAssets) { + this.#pendingAssetFiles.add(file); + } } } @@ -294,12 +316,13 @@ export class BuilderState { } /** - * Records active bundle results across entry points after compilation and bundling succeed, - * clearing pending compilation/bundle flags. + * Records active bundle results across entry points after compilation and bundling succeed + * and clears pending compilation/bundle flags. * * @param bundleResults Newly bundled results keyed by entry point name. */ recordBundleOutput(bundleResults: ReadonlyMap): void { + const hadEntryPointsChanges = this.hasEntryPointsChanges; this.hasCompilationError = false; this.hasEntryPointsChanges = false; this.pendingChangedEsmFiles.clear(); @@ -308,6 +331,126 @@ export class BuilderState { for (const [name, bundleResult] of bundleResults) { this.previousBundleResults.set(name, bundleResult); } + + if (bundleResults.size > 0 || hadEntryPointsChanges || this.#emittedBundleFiles.size === 0) { + this.#hasUpdatedBundles = true; + } + } + + /** + * Resolves and collects configured library assets to be emitted to or deleted from disk. + * + * @param options Normalized library options containing `assets` and `workspaceRoot`. + * @param modifiedFiles Optional set of modified POSIX file paths in watch mode. + * @returns The collected asset files to emit and delete. + */ + collectAssets( + options: Pick, + modifiedFiles?: ReadonlySet, + ): Promise { + let effectiveModifiedFiles: ReadonlySet | undefined; + if (this.#hasEmittedAssets && modifiedFiles) { + for (const file of modifiedFiles) { + this.#pendingAssetFiles.add(file); + } + effectiveModifiedFiles = this.#pendingAssetFiles; + } + + return collectAssetsToEmit( + options.assets, + options.workspaceRoot, + this.#emittedAssets, + effectiveModifiedFiles, + this.#assetMatchers, + ); + } + + /** + * Records emitted bundle, manifest, and asset output files after disk emission, + * returning any stale or deleted output paths to remove from disk. + * + * @param collectedAssets Collected asset files emitted and deleted in this iteration. + * @param manifestFiles Optional manifest output files generated in this iteration. + * @returns Read-only set of relative POSIX output paths to delete from disk. + */ + recordEmittedOutputs( + collectedAssets: CollectedAssets, + manifestFiles?: readonly OutputFile[], + ): ReadonlySet { + const filesToDelete = new Set(); + + if (this.#hasUpdatedBundles) { + this.#hasUpdatedBundles = false; + const nextBundleFiles = new Set(); + for (const result of this.previousBundleResults.values()) { + for (const file of result.esmOutputFiles) { + nextBundleFiles.add(file); + } + for (const file of result.dtsOutputFiles) { + nextBundleFiles.add(file); + } + } + + for (const prevFile of this.#emittedBundleFiles) { + if (!nextBundleFiles.has(prevFile)) { + filesToDelete.add(prevFile); + } + } + + this.#emittedBundleFiles = nextBundleFiles; + } + + if (manifestFiles) { + const nextManifestFiles = new Set(manifestFiles.map((file) => file.path)); + for (const prevFile of this.#emittedManifestFiles) { + if (!nextManifestFiles.has(prevFile)) { + filesToDelete.add(prevFile); + } + } + + this.#emittedManifestFiles = nextManifestFiles; + } + + const { filesToDelete: toDelete, filesToEmit: toEmit } = collectedAssets; + + for (const emittedAsset of toEmit) { + let outputs = this.#emittedAssets.get(emittedAsset.source); + if (!outputs) { + outputs = new Set(); + this.#emittedAssets.set(emittedAsset.source, outputs); + } + outputs.add(emittedAsset.path); + } + + if (toDelete.length) { + const candidateDeletes = new Set(); + for (const source of toDelete) { + const outputs = this.#emittedAssets.get(source); + if (outputs) { + for (const output of outputs) { + candidateDeletes.add(output); + } + this.#emittedAssets.delete(source); + } + } + + for (const outputs of this.#emittedAssets.values()) { + for (const output of outputs) { + candidateDeletes.delete(output); + } + } + + for (const output of candidateDeletes) { + filesToDelete.add(output); + } + } + + this.hasEmittedManifests = true; + this.#hasEmittedTslib = this.hasTslibImport; + this.#hasEmittedAssets = true; + this.#pendingAssetFiles.clear(); + + return filesToDelete; } /** @@ -317,8 +460,8 @@ export class BuilderState { await this.#singleProgramCache?.compilationInstance.close?.(); this.#singleProgramCache = undefined; this.#compilationMode = undefined; - this.hasEmittedTslib = false; - this.hasEmittedAssets = false; + this.#hasEmittedTslib = false; + this.#hasEmittedAssets = false; this.hasCompilationError = false; this.hasEmittedManifests = false; this.hasEntryPointsChanges = false; @@ -326,8 +469,13 @@ export class BuilderState { this.pendingChangedEsmFiles.clear(); this.pendingChangedDtsFiles.clear(); this.#pendingCompilationFiles.clear(); + this.#pendingAssetFiles.clear(); this.#referencingFiles.clear(); this.#referencedByFile.clear(); this.#watchedCompilationFiles.clear(); + this.#emittedBundleFiles.clear(); + this.#emittedManifestFiles.clear(); + this.#emittedAssets.clear(); + this.#hasUpdatedBundles = false; } } diff --git a/packages/angular/build/src/builders/library/builder-state_spec.ts b/packages/angular/build/src/builders/library/builder-state_spec.ts index ae84bbaa7331..da7420afc3e5 100644 --- a/packages/angular/build/src/builders/library/builder-state_spec.ts +++ b/packages/angular/build/src/builders/library/builder-state_spec.ts @@ -6,7 +6,11 @@ * found in the LICENSE file at https://angular.dev/license */ +import assert from 'node:assert'; +import { mkdtemp, rm, writeFile } from 'node:fs/promises'; +import { join } from 'node:path'; import { BuilderState } from './builder-state'; +import { createDiskOutputFile, createMemoryOutputFile } from './pipeline/utils'; import type { LibraryCompilationOutput, SingleProgramCache } from './types'; describe('BuilderState', () => { @@ -183,7 +187,151 @@ describe('BuilderState', () => { }); }); - describe('dispose', () => { + describe('output tracking and cleanup', () => { + it('should track bundle and manifest outputs and queue stale files for deletion', () => { + const state = new BuilderState(); + + const initialBundles = new Map([ + [ + '.', + { + esmModuleIds: new Set(['/src/index.js']), + dtsModuleIds: new Set(['/src/index.d.ts']), + esmOutputFiles: new Set(['fesm2022/my-lib.mjs']), + dtsOutputFiles: new Set(['types/my-lib.d.ts']), + hasTslibImport: false, + }, + ], + [ + 'testing', + { + esmModuleIds: new Set(['/testing/index.js']), + dtsModuleIds: new Set(['/testing/index.d.ts']), + esmOutputFiles: new Set(['fesm2022/my-lib-testing.mjs']), + dtsOutputFiles: new Set(['types/my-lib-testing.d.ts']), + hasTslibImport: true, + }, + ], + ]); + + state.recordBundleOutput(initialBundles); + expect(state.hasTslibImport).toBeTrue(); + + const initialFilesToDelete = state.recordEmittedOutputs( + { + filesToEmit: [], + filesToDelete: [], + }, + [ + createMemoryOutputFile('package.json', '{}'), + createMemoryOutputFile('testing/package.json', '{}'), + ], + ); + expect(initialFilesToDelete).toHaveSize(0); + expect(state.hasEmittedTslib).toBeTrue(); + + // No-op bundle pass when nothing changed + state.resetExecutionResult(); + state.recordBundleOutput(new Map()); + expect(state.recordEmittedOutputs({ filesToEmit: [], filesToDelete: [] })).toHaveSize(0); + + // Remove secondary entry point 'testing' + state.resetExecutionResult(); + state.previousBundleResults.delete('testing'); + state.hasEntryPointsChanges = true; + expect(state.hasTslibImport).toBeFalse(); + + state.recordBundleOutput(new Map()); + const filesToDelete = state.recordEmittedOutputs( + { + filesToEmit: [], + filesToDelete: [], + }, + [createMemoryOutputFile('package.json', '{}')], + ); + + expect(state.hasEntryPointsChanges).toBeFalse(); + expect(state.hasEmittedTslib).toBeFalse(); + expect(filesToDelete).toEqual( + new Set([ + 'fesm2022/my-lib-testing.mjs', + 'types/my-lib-testing.d.ts', + 'testing/package.json', + ]), + ); + }); + + it('should not delete an asset output path when another source still emits to it', () => { + const state = new BuilderState(); + + const sourceA = '/workspace/projects/my-lib/README.md'; + const sourceB = '/workspace/docs/README.md'; + + state.recordEmittedOutputs({ + filesToEmit: [ + createDiskOutputFile(sourceA, 'README.md'), + createDiskOutputFile(sourceB, 'README.md'), + ], + filesToDelete: [], + }); + + // Delete sourceB while sourceA remains active + state.resetExecutionResult(); + const firstDeletes = state.recordEmittedOutputs({ + filesToEmit: [], + filesToDelete: [sourceB], + }); + expect(firstDeletes.has('README.md')).toBeFalse(); + + // Delete sourceA as well; now README.md should be queued for deletion + state.resetExecutionResult(); + const secondDeletes = state.recordEmittedOutputs({ + filesToEmit: [], + filesToDelete: [sourceA], + }); + expect(secondDeletes.has('README.md')).toBeTrue(); + }); + + it('should preserve pending asset modifications across failed iterations', async () => { + const baseTmpDir = process.env['TEST_TMPDIR']; + assert(baseTmpDir, 'TEST_TMPDIR is not set'); + const tempRoot = await mkdtemp(join(baseTmpDir, 'angular-cli-builder-state-')); + + try { + const readmePath = join(tempRoot, 'README.md'); + await writeFile(readmePath, '# Initial'); + + const options = { + workspaceRoot: tempRoot, + assets: [{ glob: 'README.md', input: tempRoot, output: '.' }], + }; + const state = new BuilderState(options); + + // Initial build emits README.md + const initialAssets = await state.collectAssets(options); + expect(initialAssets.filesToEmit).toHaveSize(1); + state.recordEmittedOutputs(initialAssets); + + // Watch iteration 1: README.md is modified, but build fails before recordEmittedOutputs + await writeFile(readmePath, '# Updated'); + const failedIterAssets = await state.collectAssets(options, new Set([readmePath])); + expect(failedIterAssets.filesToEmit).toHaveSize(1); + + // Watch iteration 2: only an unrelated file is in modifiedFiles; README.md is still collected + const unrelatedFile = join(tempRoot, 'src/index.ts'); + const recoveryAssets = await state.collectAssets(options, new Set([unrelatedFile])); + expect(recoveryAssets.filesToEmit).toHaveSize(1); + expect(recoveryAssets.filesToEmit[0]?.source).toBe(readmePath); + + // Once recovery outputs are recorded, pending asset modifications are cleared + state.recordEmittedOutputs(recoveryAssets); + const subsequentAssets = await state.collectAssets(options, new Set([unrelatedFile])); + expect(subsequentAssets.filesToEmit).toHaveSize(0); + } finally { + await rm(tempRoot, { recursive: true, force: true }); + } + }); + it('should close compilationInstance and clear cached state on dispose', async () => { const closeSpy = jasmine.createSpy('close').and.resolveTo(); const state = new BuilderState({ packageJsonPath }); diff --git a/packages/angular/build/src/builders/library/builder.ts b/packages/angular/build/src/builders/library/builder.ts index 42be7f99b211..1e5d08b55b5f 100644 --- a/packages/angular/build/src/builders/library/builder.ts +++ b/packages/angular/build/src/builders/library/builder.ts @@ -215,11 +215,6 @@ async function executeBuild( } finally { if (watcher) { watcher.add(Array.from(buildState.watchedCompilationFiles)); - - const { assetsToEmit } = actionContext; - if (assetsToEmit?.length) { - watcher.add(assetsToEmit.map((asset) => asset.source)); - } } } } @@ -247,9 +242,7 @@ async function* runWatchLoop( buildAction: typeof import('./pipeline/build-action').buildAction, signal: AbortSignal, ): AsyncIterableIterator { - const { collectAssetsToEmit } = await import('./pipeline/assets'); - - const { workspaceRoot, packageJsonPath, assets, clearScreen } = options; + const { packageJsonPath, clearScreen } = options; for await (const changes of watcher) { if (signal.aborted) { @@ -298,13 +291,14 @@ async function* runWatchLoop( await buildState.singleProgramCache?.compilationInstance.update?.(changedFiles); } - const assetsToEmit = await collectAssetsToEmit( - assets, - workspaceRoot, - buildState.hasEmittedAssets ? changedFiles : undefined, - ); + const collectedAssets = await buildState.collectAssets(options, changedFiles); - if (!hasSourceChanges && buildState.hasEmittedManifests && assetsToEmit.length === 0) { + if ( + !hasSourceChanges && + buildState.hasEmittedManifests && + collectedAssets.filesToEmit.length === 0 && + collectedAssets.filesToDelete.length === 0 + ) { continue; } @@ -316,7 +310,7 @@ async function* runWatchLoop( isWatchMode: true, buildState, modifiedFiles: changedFiles, - assetsToEmit, + collectedAssets, }, logger, withProgress, diff --git a/packages/angular/build/src/builders/library/pipeline/assets.ts b/packages/angular/build/src/builders/library/pipeline/assets.ts index 7b8329a7865a..90c6d5c10fa4 100644 --- a/packages/angular/build/src/builders/library/pipeline/assets.ts +++ b/packages/angular/build/src/builders/library/pipeline/assets.ts @@ -9,32 +9,90 @@ import { statSync } from 'node:fs'; import path from 'node:path'; import picomatch from 'picomatch'; +import type { NormalizedAssetsPattern } from '../../../utils'; import { DEFAULT_ASSET_IGNORE, resolveAssets } from '../../../utils/resolve-assets'; -import type { NormalizedLibraryOptions } from '../types'; import { type DiskOutputFile, createDiskOutputFile } from './utils'; /** - * Resolves and collects configured library assets to be emitted to disk. + * Result of resolving and collecting library assets for a build iteration. + */ +export interface CollectedAssets { + /** Asset files to emit to disk, with POSIX source and destination paths. */ + filesToEmit: DiskOutputFile[]; + + /** Previously emitted POSIX asset source file paths that were deleted from disk. */ + filesToDelete: string[]; +} + +/** + * Compiled asset matcher for incremental watch-mode matching. + */ +export interface AssetMatcher { + /** Normalized asset pattern configuration. */ + asset: NormalizedAssetsPattern; + + /** Normalized POSIX input directory path with a trailing slash. */ + prefix: string; + + /** Compiled picomatch matcher function for the asset glob. */ + isMatch: picomatch.Matcher; +} + +/** + * Compiles picomatch matchers and POSIX input prefixes for each asset configuration. + * + * @param assets The normalized asset patterns with POSIX input and output paths. + * @returns An array of compiled asset matcher descriptors. + */ +export function createAssetMatchers(assets: NormalizedAssetsPattern[]): readonly AssetMatcher[] { + return assets.map((asset) => { + const isMatch = picomatch(asset.glob, { + dot: true, + ignore: [...DEFAULT_ASSET_IGNORE, ...(asset.ignore ?? [])], + }); + const prefix = asset.input.endsWith('/') ? asset.input : `${asset.input}/`; + + return { asset, prefix, isMatch }; + }); +} + +/** + * Resolves and collects configured library assets to be emitted to or deleted from disk. * - * @param assets The normalized asset patterns with POSIX paths. - * @param workspaceRoot The normalized POSIX workspace root directory path. + * @param assets The normalized asset patterns with POSIX input and output paths. + * @param workspaceRoot The workspace root POSIX directory path. + * @param emittedAssets Map of previously emitted POSIX source file paths. * @param modifiedFiles Optional set of modified POSIX file paths for incremental copying in watch mode. - * @returns An array of disk file emission descriptors. + * @param assetMatchers Optional pre-compiled asset matchers for incremental matching. + * @returns The collected asset files to emit and delete. */ export async function collectAssetsToEmit( - assets: NormalizedLibraryOptions['assets'], + assets: NormalizedAssetsPattern[], workspaceRoot: string, + emittedAssets: ReadonlyMap, modifiedFiles?: ReadonlySet, -): Promise { + assetMatchers?: readonly AssetMatcher[], +): Promise { if (assets.length === 0 || modifiedFiles?.size === 0) { - return []; + return { filesToEmit: [], filesToDelete: [] }; } if (modifiedFiles) { - const matchers = createAssetMatchers(assets); + const matchers = assetMatchers ?? createAssetMatchers(assets); const filesToEmit: DiskOutputFile[] = []; + const filesToDelete: string[] = []; for (const file of modifiedFiles) { + let isFile: boolean | undefined; + + if (emittedAssets.has(file)) { + isFile = statSync(file, { throwIfNoEntry: false })?.isFile() ?? false; + if (!isFile) { + filesToDelete.push(file); + continue; + } + } + for (const { asset, prefix, isMatch } of matchers) { if (!file.startsWith(prefix)) { continue; @@ -45,28 +103,24 @@ export async function collectAssetsToEmit( continue; } - if (statSync(file, { throwIfNoEntry: false })?.isFile()) { - filesToEmit.push(createDiskOutputFile(file, path.posix.join(asset.output, relative))); + isFile ??= statSync(file, { throwIfNoEntry: false })?.isFile() ?? false; + if (!isFile) { + break; } + + filesToEmit.push(createDiskOutputFile(file, path.posix.join(asset.output, relative))); } } - return filesToEmit; + return { filesToEmit, filesToDelete }; } const resolvedAssets = await resolveAssets(assets, workspaceRoot); - return resolvedAssets.map(({ source, destination }) => createDiskOutputFile(source, destination)); -} - -function createAssetMatchers(assets: NormalizedLibraryOptions['assets']) { - return assets.map((asset) => { - const isMatch = picomatch(asset.glob, { - dot: true, - ignore: [...DEFAULT_ASSET_IGNORE, ...(asset.ignore ?? [])], - }); - const prefix = asset.input.endsWith('/') ? asset.input : `${asset.input}/`; - - return { asset, prefix, isMatch }; - }); + return { + filesToEmit: resolvedAssets.map(({ source, destination }) => + createDiskOutputFile(source, destination), + ), + filesToDelete: [], + }; } diff --git a/packages/angular/build/src/builders/library/pipeline/build-action.ts b/packages/angular/build/src/builders/library/pipeline/build-action.ts index 734ea23c544e..9d579e58a76a 100644 --- a/packages/angular/build/src/builders/library/pipeline/build-action.ts +++ b/packages/angular/build/src/builders/library/pipeline/build-action.ts @@ -8,17 +8,17 @@ import path from 'node:path'; import type { ComponentStylesheetBundler } from '../../../tools/esbuild/angular/component-stylesheets'; -import { emitFilesToDisk } from '../../../utils/disk-files'; +import { deleteFilesFromDisk, emitFilesToDisk } from '../../../utils/disk-files'; import { assertIsError } from '../../../utils/error'; import type { BuilderState } from '../builder-state'; import type { ExecutionResult } from '../execution-result'; import type { NormalizedLibraryOptions } from '../types'; -import { collectAssetsToEmit } from './assets'; +import type { CollectedAssets } from './assets'; import { type BundleEntryPointsOutput, bundleEntryPoints } from './bundler'; import { compileLibrary } from './compilation'; import { collectEntryPointsToBundle } from './entry-points'; import { generatePackageManifests } from './package-manifests'; -import type { DiskOutputFile, OutputFile } from './utils'; +import type { OutputFile } from './utils'; /** * Context required to execute a single library build iteration. @@ -33,19 +33,18 @@ export interface BuildActionContext { /** Whether the builder is running in watch mode. */ isWatchMode: boolean; - /** Build state tracking compilation caches and emitted outputs. */ + /** Build state tracking compilation caches, file references, and emitted outputs. */ buildState: BuilderState; /** Set of POSIX file paths modified since the last build iteration. */ modifiedFiles?: Set; /** - * Asset files to emit for the current build iteration. - * Pre-collected in the watch loop to avoid redundant asset matching, or resolved and - * populated by `buildAction` when omitted (such as during the initial build) so the - * caller can register their POSIX source paths with the file watcher. + * Collected asset changes for the current build iteration. + * Pre-collected in the watch loop to avoid redundant asset matching, or resolved by + * `buildAction` when omitted (such as during the initial build). */ - assetsToEmit?: DiskOutputFile[]; + collectedAssets?: CollectedAssets; } /** @@ -131,32 +130,34 @@ export async function buildAction(actionContext: BuildActionContext): Promise path.posix.join(options.outputPath, file.path)); - buildState.hasEmittedManifests = true; - buildState.hasEmittedTslib = hasTslibImport; - buildState.hasEmittedAssets = true; + const filesToDelete = buildState.recordEmittedOutputs(collectedAssets, manifestFiles); + + if (filesToDelete.size) { + await deleteFilesFromDisk( + Array.from(filesToDelete, (file) => path.posix.join(options.outputPath, file)), + ); + } } catch (error) { assertIsError(error); result.addError(error.message); diff --git a/packages/angular/build/src/builders/library/pipeline/bundler.ts b/packages/angular/build/src/builders/library/pipeline/bundler.ts index c48942885083..eccd4cd04e12 100644 --- a/packages/angular/build/src/builders/library/pipeline/bundler.ts +++ b/packages/angular/build/src/builders/library/pipeline/bundler.ts @@ -26,7 +26,7 @@ export interface BundleEntryPointsOutput { /** In-memory files produced by bundling to be written to disk. */ filesToEmit: MemoryOutputFile[]; - /** Map of entry point names to their bundle results containing bundled module IDs. */ + /** Map of entry point names to their bundle results. */ bundleResults: Map; /** Warning messages emitted during bundling. */ @@ -53,6 +53,20 @@ export interface BundleEntryPointInput { const ESM_EXTENSIONS = ['.js', '.mjs', '/index.js', '/index.mjs'] as const; const DTS_EXTENSIONS = ['.d.ts', '.d.mts', '/index.d.ts', '/index.d.mts'] as const; +/** + * Bundled module IDs, output files, and metadata for a single entry point bundle. + */ +interface EntryBundleOutput { + /** Set of virtual POSIX module IDs included in the bundle. */ + moduleIds: Set; + + /** Set of relative POSIX output paths generated for the bundle. */ + outputFiles: Set; + + /** Whether the bundle imports 'tslib'. */ + hasTslibImport: boolean; +} + /** * Output of a multi-entry-point Rolldown bundling invocation. */ @@ -60,11 +74,8 @@ interface MultiBundleOutput { /** In-memory files generated by the bundle invocation. */ filesToEmit: MemoryOutputFile[]; - /** Map of bundle entry names to the set of virtual POSIX module IDs included in the bundle. */ - moduleIdsByBundle: Map>; - - /** Set of bundle entry names that import 'tslib'. */ - tslibBundles: Set; + /** Map of bundle entry names to their bundled module IDs, output files, and metadata. */ + bundles: Map; /** Warning messages emitted during the bundle invocation. */ warnings: string[]; @@ -110,16 +121,15 @@ export async function bundleEntryPoints( for (const { entryPoint, previousBundleResult } of items) { const { bundleName, name } = entryPoint; - const esmModuleIds = esmOutput.moduleIdsByBundle.get(bundleName); + const esmBundle = esmOutput.bundles.get(bundleName); + const dtsBundle = dtsOutput.bundles.get(bundleName); + bundleResults.set(name, { - esmModuleIds: esmModuleIds ?? previousBundleResult?.esmModuleIds ?? new Set(), - dtsModuleIds: - dtsOutput.moduleIdsByBundle.get(bundleName) ?? - previousBundleResult?.dtsModuleIds ?? - new Set(), - hasTslibImport: esmModuleIds - ? esmOutput.tslibBundles.has(bundleName) - : (previousBundleResult?.hasTslibImport ?? false), + esmModuleIds: esmBundle?.moduleIds ?? previousBundleResult?.esmModuleIds ?? new Set(), + dtsModuleIds: dtsBundle?.moduleIds ?? previousBundleResult?.dtsModuleIds ?? new Set(), + esmOutputFiles: esmBundle?.outputFiles ?? previousBundleResult?.esmOutputFiles ?? new Set(), + dtsOutputFiles: dtsBundle?.outputFiles ?? previousBundleResult?.dtsOutputFiles ?? new Set(), + hasTslibImport: esmBundle?.hasTslibImport ?? previousBundleResult?.hasTslibImport ?? false, }); } @@ -177,7 +187,7 @@ function createMemoryFileLoaderPlugin( return files.has(id) ? { id, external: false } : undefined; } - if (id[0] !== '.' && !path.isAbsolute(id)) { + if (id[0] !== '.' && !path.posix.isAbsolute(id)) { return { id, external: true }; } @@ -220,7 +230,8 @@ function createMemoryFileLoaderPlugin( /** * Processes Rolldown output assets and chunks, extracting emitted files and computing - * the transitive set of module IDs belonging to each entry point bundle. + * the transitive sets of module IDs, output file paths, and tslib imports belonging to + * each entry point bundle. * * @param output The array of output chunks and assets from Rolldown. * @param dir The destination POSIX output directory prefix. @@ -231,12 +242,13 @@ function processRolldownOutput( dir: string, ): Omit { const filesToEmit: MemoryOutputFile[] = []; - const moduleIdsByBundle = new Map>(); - const tslibBundles = new Set(); + const bundles = new Map(); const chunksByFileName = new Map(); + const outputFileNames = new Set(); const entryChunks: OutputChunk[] = []; for (const item of output) { + outputFileNames.add(item.fileName); filesToEmit.push( createMemoryOutputFile( path.posix.join(dir, item.fileName), @@ -253,44 +265,40 @@ function processRolldownOutput( } for (const entryChunk of entryChunks) { - const modSet = new Set(); - moduleIdsByBundle.set(entryChunk.name, modSet); - - const visited = new Set(); - const queue: OutputChunk[] = [entryChunk]; - - while (queue.length) { - const chunk = queue.pop(); - if (!chunk) { - break; - } - - if (visited.has(chunk)) { - continue; + const moduleIds = new Set(); + const outputFiles = new Set(); + let hasTslibImport = false; + + const visited = new Set([entryChunk]); + for (const chunk of visited) { + outputFiles.add(path.posix.join(dir, chunk.fileName)); + const mapFileName = `${chunk.fileName}.map`; + if (outputFileNames.has(mapFileName)) { + outputFiles.add(path.posix.join(dir, mapFileName)); } - visited.add(chunk); - for (const modId of chunk.moduleIds) { if (modId[0] !== '\0') { - modSet.add(toPosixPath(modId)); + moduleIds.add(toPosixPath(modId)); } } for (const depFile of [...chunk.imports, ...chunk.dynamicImports]) { if (depFile === 'tslib') { - tslibBundles.add(entryChunk.name); + hasTslibImport = true; } const depChunk = chunksByFileName.get(depFile); - if (depChunk && !visited.has(depChunk)) { - queue.push(depChunk); + if (depChunk) { + visited.add(depChunk); } } } + + bundles.set(entryChunk.name, { moduleIds, outputFiles, hasTslibImport }); } - return { filesToEmit, moduleIdsByBundle, tslibBundles }; + return { filesToEmit, bundles }; } /** @@ -319,18 +327,9 @@ async function executeMultiBundle( ): Promise { const { workspaceRoot, preserveSymlinks, declarationMap, outputPath } = options; const isDts = extension === 'd.ts'; - - let sourcemap: boolean; - let dir: string; - - if (isDts) { - dir = TYPES_OUTPUT_DIR; - sourcemap = !!declarationMap; - } else { - dir = FESM_OUTPUT_DIR; - // FESM (.mjs) sourcemaps are always enabled. - sourcemap = true; - } + const dir = isDts ? TYPES_OUTPUT_DIR : FESM_OUTPUT_DIR; + // FESM (.mjs) sourcemaps are always enabled. + const sourcemap = isDts ? !!declarationMap : true; const warnings: string[] = []; const { rolldown } = await loadRolldown(); @@ -393,8 +392,7 @@ async function bundleAllEsm( if (entryPoints.length === 0) { return { filesToEmit: [], - moduleIdsByBundle: new Map(), - tslibBundles: new Set(), + bundles: new Map(), warnings: [], }; } @@ -423,8 +421,7 @@ async function bundleAllDts( if (entryPoints.length === 0) { return { filesToEmit: [], - moduleIdsByBundle: new Map(), - tslibBundles: new Set(), + bundles: new Map(), warnings: [], }; } diff --git a/packages/angular/build/src/builders/library/pipeline/entry-points_spec.ts b/packages/angular/build/src/builders/library/pipeline/entry-points_spec.ts index e4653ef56e2b..b5b4aac20059 100644 --- a/packages/angular/build/src/builders/library/pipeline/entry-points_spec.ts +++ b/packages/angular/build/src/builders/library/pipeline/entry-points_spec.ts @@ -31,6 +31,8 @@ describe('entry-points pipeline', () => { return { esmModuleIds: new Set(), dtsModuleIds: new Set(), + esmOutputFiles: new Set(), + dtsOutputFiles: new Set(), hasTslibImport: false, ...overrides, }; diff --git a/packages/angular/build/src/builders/library/tests/behavior/watch-cleanup_spec.ts b/packages/angular/build/src/builders/library/tests/behavior/watch-cleanup_spec.ts new file mode 100644 index 000000000000..6518b459b023 --- /dev/null +++ b/packages/angular/build/src/builders/library/tests/behavior/watch-cleanup_spec.ts @@ -0,0 +1,216 @@ +/** + * @license + * Copyright Google LLC All Rights Reserved. + * + * Use of this source code is governed by an MIT-style license that can be + * found in the LICENSE file at https://angular.dev/license + */ + +import { executeLibraryBuilder } from '../../builder'; +import { BASE_OPTIONS, LIBRARY_BUILDER_INFO, describeLibraryBuilder } from '../setup'; + +describeLibraryBuilder(executeLibraryBuilder, LIBRARY_BUILDER_INFO, (harness) => { + describe('Behavior: "Watch Mode Asset and Output Cleanup"', () => { + it('should emit newly created assets, respect ignore patterns, and clean up deleted assets in watch mode', async () => { + await harness.writeFiles({ + 'projects/lib/assets-dir/keep.txt': 'keep', + }); + + harness.useTarget('build', { + ...BASE_OPTIONS, + assets: [ + { + glob: '**/*.txt', + input: 'projects/lib/assets-dir', + output: 'assets', + ignore: ['**/ignored.txt'], + }, + ], + watch: true, + }); + + await harness.executeWithCases([ + async ({ result }) => { + expect(result?.success).toBeTrue(); + expect(harness.readFile('dist/lib/assets/keep.txt')).toBe('keep'); + + // Create an ignored file and a matching nested asset file + await harness.writeFiles({ + 'projects/lib/assets-dir/sub/ignored.txt': 'ignored', + 'projects/lib/assets-dir/sub/added.txt': 'added', + }); + }, + async ({ result }) => { + expect(result?.success).toBeTrue(); + expect(harness.readFile('dist/lib/assets/sub/added.txt')).toBe('added'); + expect(harness.hasFile('dist/lib/assets/sub/ignored.txt')).toBeFalse(); + + // Remove the added asset file + await harness.removeFile('projects/lib/assets-dir/sub/added.txt'); + }, + ({ result }) => { + expect(result?.success).toBeTrue(); + expect(harness.readFile('dist/lib/assets/keep.txt')).toBe('keep'); + expect(harness.hasFile('dist/lib/assets/sub/added.txt')).toBeFalse(); + }, + ]); + }); + + it('should clean up output files when a secondary entry point is removed in watch mode', async () => { + await harness.writeFile( + 'projects/lib/secondary/src/public-api.ts', + `export const secondary = 'secondary-value';`, + ); + + await harness.modifyFile('projects/lib/package.json', (content) => { + const pkg = JSON.parse(content); + pkg.exports = { + '.': './src/public-api.ts', + './secondary': './secondary/src/public-api.ts', + }; + + return JSON.stringify(pkg, null, 2); + }); + + harness.useTarget('build', { + ...BASE_OPTIONS, + declarationMap: true, + watch: true, + }); + + await harness.executeWithCases([ + async ({ result }) => { + expect(result?.success).toBeTrue(); + expect(harness.hasFile('dist/lib/fesm2022/lib.mjs')).toBeTrue(); + expect(harness.hasFile('dist/lib/fesm2022/lib-secondary.mjs')).toBeTrue(); + expect(harness.hasFile('dist/lib/fesm2022/lib-secondary.mjs.map')).toBeTrue(); + expect(harness.hasFile('dist/lib/types/lib-secondary.d.ts')).toBeTrue(); + expect(harness.hasFile('dist/lib/types/lib-secondary.d.ts.map')).toBeTrue(); + expect(harness.hasFile('dist/lib/secondary/package.json')).toBeTrue(); + expect(harness.hasFile('dist/lib/.npmignore')).toBeTrue(); + + // Remove the secondary entry point from package.json exports + await harness.modifyFile('projects/lib/package.json', (content) => { + const pkg = JSON.parse(content); + pkg.exports = { + '.': './src/public-api.ts', + }; + + return JSON.stringify(pkg, null, 2); + }); + }, + ({ result }) => { + expect(result?.success).toBeTrue(); + expect(harness.hasFile('dist/lib/fesm2022/lib.mjs')).toBeTrue(); + expect(harness.hasFile('dist/lib/fesm2022/lib-secondary.mjs')).toBeFalse(); + expect(harness.hasFile('dist/lib/fesm2022/lib-secondary.mjs.map')).toBeFalse(); + expect(harness.hasFile('dist/lib/types/lib-secondary.d.ts')).toBeFalse(); + expect(harness.hasFile('dist/lib/types/lib-secondary.d.ts.map')).toBeFalse(); + expect(harness.hasFile('dist/lib/secondary/package.json')).toBeFalse(); + expect(harness.hasFile('dist/lib/.npmignore')).toBeFalse(); + + const pkg = JSON.parse(harness.readFile('dist/lib/package.json')); + expect(pkg.exports['./secondary']).toBeUndefined(); + }, + ]); + }); + + it('should prune removed nested secondary entry point files and update .npmignore in watch mode', async () => { + await harness.writeFiles({ + 'projects/lib/shared/src/public-api.ts': `export const SHARED = 'shared';\n`, + 'projects/lib/testing/sub/src/public-api.ts': `export const SUB = 'sub';\n`, + }); + + await harness.modifyFile('projects/lib/package.json', (content) => { + const pkg = JSON.parse(content); + pkg.exports = { + '.': './src/public-api.ts', + './shared': './shared/src/public-api.ts', + './testing/sub': './testing/sub/src/public-api.ts', + }; + + return JSON.stringify(pkg, null, 2); + }); + + harness.useTarget('build', { + ...BASE_OPTIONS, + watch: true, + }); + + await harness.executeWithCases([ + async ({ result }) => { + expect(result?.success).toBeTrue(); + harness.expectFile('dist/lib/fesm2022/lib-shared.mjs').toExist(); + harness.expectFile('dist/lib/fesm2022/lib-testing-sub.mjs').toExist(); + harness.expectFile('dist/lib/types/lib-testing-sub.d.ts').toExist(); + harness.expectFile('dist/lib/testing/sub/package.json').toExist(); + expect(harness.readFile('dist/lib/.npmignore')).toContain('/testing/sub/package.json'); + + // Remove './testing/sub' while keeping './shared' + await harness.modifyFile('projects/lib/package.json', (content) => { + const pkg = JSON.parse(content); + pkg.exports = { + '.': './src/public-api.ts', + './shared': './shared/src/public-api.ts', + }; + + return JSON.stringify(pkg, null, 2); + }); + }, + ({ result }) => { + expect(result?.success).toBeTrue(); + harness.expectFile('dist/lib/fesm2022/lib-shared.mjs').toExist(); + harness.expectFile('dist/lib/fesm2022/lib-testing-sub.mjs').toNotExist(); + harness.expectFile('dist/lib/fesm2022/lib-testing-sub.mjs.map').toNotExist(); + harness.expectFile('dist/lib/types/lib-testing-sub.d.ts').toNotExist(); + harness.expectFile('dist/lib/testing/sub/package.json').toNotExist(); + + const npmignore = harness.readFile('dist/lib/.npmignore'); + expect(npmignore).toContain('/shared/package.json'); + expect(npmignore).not.toContain('/testing/sub/package.json'); + }, + ]); + }); + + it('should clean up all output destinations when a single asset source matches multiple patterns and is deleted in watch mode', async () => { + await harness.writeFiles({ + 'projects/lib/assets-dir/shared.txt': 'shared-content', + 'projects/lib/assets-dir/keep.txt': 'keep-content', + }); + + harness.useTarget('build', { + ...BASE_OPTIONS, + assets: [ + { + glob: '**/*.txt', + input: 'projects/lib/assets-dir', + output: 'assets-a', + }, + { + glob: '**/*.txt', + input: 'projects/lib/assets-dir', + output: 'assets-b', + }, + ], + watch: true, + }); + + await harness.executeWithCases([ + async ({ result }) => { + expect(result?.success).toBeTrue(); + expect(harness.readFile('dist/lib/assets-a/shared.txt')).toBe('shared-content'); + expect(harness.readFile('dist/lib/assets-b/shared.txt')).toBe('shared-content'); + + await harness.removeFile('projects/lib/assets-dir/shared.txt'); + }, + ({ result }) => { + expect(result?.success).toBeTrue(); + expect(harness.hasFile('dist/lib/assets-a/shared.txt')).toBeFalse(); + expect(harness.hasFile('dist/lib/assets-b/shared.txt')).toBeFalse(); + expect(harness.readFile('dist/lib/assets-a/keep.txt')).toBe('keep-content'); + expect(harness.readFile('dist/lib/assets-b/keep.txt')).toBe('keep-content'); + }, + ]); + }); + }); +}); diff --git a/packages/angular/build/src/builders/library/types.ts b/packages/angular/build/src/builders/library/types.ts index 2d2d9f61891d..273f7066cb99 100644 --- a/packages/angular/build/src/builders/library/types.ts +++ b/packages/angular/build/src/builders/library/types.ts @@ -8,7 +8,7 @@ import type { AngularCompilation } from '../../tools/angular/compilation'; import type { StylesheetPluginsass } from '../../tools/esbuild/stylesheets/stylesheet-plugin-factory'; -import type { normalizeAssetPatterns } from '../../utils'; +import type { NormalizedAssetsPattern } from '../../utils'; import type { NormalizedCachedOptions } from '../../utils/normalize-cache'; import type { PostcssConfiguration } from '../../utils/postcss-configuration'; @@ -99,7 +99,7 @@ export interface NormalizedLibraryOptions { sass?: StylesheetPluginsass; /** Normalized asset patterns with POSIX `input` and `output` paths. */ - assets: ReturnType; + assets: NormalizedAssetsPattern[]; /** Angular compilation mode (`'partial'` or `'full'`). */ compilationMode?: 'partial' | 'full'; @@ -142,7 +142,7 @@ export interface NormalizedLibraryOptions { } /** - * Cached module ID sets for a bundled entry point. + * Cached module ID and output file sets for a bundled entry point. */ export interface BundleResult { /** Exact set of virtual POSIX ESM module IDs bundled into this entry point. */ @@ -151,8 +151,14 @@ export interface BundleResult { /** Exact set of virtual POSIX DTS module IDs bundled into this entry point. */ dtsModuleIds: ReadonlySet; + /** Relative POSIX output paths of ESM bundle files and sourcemaps emitted for this entry point. */ + esmOutputFiles: ReadonlySet; + + /** Relative POSIX output paths of DTS bundle files and sourcemaps emitted for this entry point. */ + dtsOutputFiles: ReadonlySet; + /** Whether this entry point bundle imports 'tslib'. */ - hasTslibImport?: boolean; + hasTslibImport: boolean; } /** From 0fd4404e52695fcd5b0cb976696747eed83d94be Mon Sep 17 00:00:00 2001 From: Doug Parker Date: Wed, 14 Oct 2026 15:06:41 -0700 Subject: [PATCH 654/787] docs: update `SECURITY.md` Adding some feedback based on AI security reports to help guide them towards what is and is not a legitimate vulnerability. --- SECURITY.md | 40 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) diff --git a/SECURITY.md b/SECURITY.md index 0361308689ab..1d62d6ccd8ae 100644 --- a/SECURITY.md +++ b/SECURITY.md @@ -1,3 +1,43 @@ Angular is part of Google [Open Source Software Vulnerability Reward Program](https://bughunters.google.com/about/rules/6521337925468160/google-open-source-software-vulnerability-reward-program-rules). For vulnerabilities in Angular, please submit your report [here](https://bughunters.google.com/report). For more information, check out [Angular's security policy](https://angular.dev/best-practices/security). + +## Policies + +The following defines some team policies around what does and does not constitute a security vulnerability. + +- Prototype pollution is itself a DoS vulnerability. + - An attacker could pollute any symbol into the wrong type and cause an error, nothing we can do will prevent that. + - Therefore we don't care about any DoS vulnerability which relies on prototype pollution as a precondition. +- We trust the user's source code. + - "A malicious repository can execute untrusted code" is not a viable attack vector. + - A malicious repository could always rebind `node_modules/.bin/ng` to do something malicious, nothing we do can prevent that. + - We assume it is always unsafe to run an untrusted repository outside of a sandbox. +- DoS attacks which break only the attacker's client are not security issues. + - Exception: DoS attacks which waste server resources significantly beyond the cost of the attacker's request may be security issues. +- Memory leaks are considered general bugs, not DoS vulnerabilities. + - While any memory leak is technically a DoS vulnerability in SSR, these are generally low enough impact to not be considered security issues. +- Our public API contract is defined by our TS types, any issue which requires breaking those types (ex. via a cast to any) falls outside Angular's support. + - Ex. It may be possible to leak user state by attaching it to some global data structure in SSR, but we do not consider this to be a valid vulnerability if you have to escape TS types to do it. + +## Invariants + +The following are invariants about Angular's technical infrastructure which limit some potential attack vectors. These statements are asserted by humans, not proven in any formal means. However, any security report should assume them to be true unless and until it can conclusively prove them to be false in an attack. If one of these statements invalidates a security report, that report bears the burden of conclusively demonstrating the statement to be false in its reproduction. + +- Zones don't leak across SSR requests (except for the root) + - Every request gets its own Zone, so data stored on the Zone is unique to that user, no intrinsic risk of leaking user data from one request to an attacker's request. +- Injectors are not shared between applications. + - SSR always creates a new ApplicationRef and root services, no intrinsic risk of leaking user data from one request to an attacker's request. + - Exception: Module-scoped data is shared and is a potential vector for data leakage. +- `ngDevMode` / `ngServerMode` are set at compile time in production deployments and cannot be manipulated by attackers. + +## Prioritization Guide + +Angular is not a product, and almost no vulnerability is an exploit in and of itself, given there is nothing to compromise. Angular can only be exploited through a real deployment of a specific application. The vast majority of potential issues do not affect the default `ng new` app, and require additional steps of varying use/misuse of the framework before introducing a vulnerability on that real application. This goes beyond just an attacker finding the right sequence of characters to cause an exploit, and requires a well-intentioned developer to make a legitimate mistake introducing the vulnerability in the first place. Therefore we need to examine prioritization through the lens of how likely a developer is to make that mistake and the severity of what happens when they do. + +- **High:** A vulnerability impacts ~all users of a major feature in common usage such as SSR, hydration, templating, or routing (ex. SSRF via a malicious `Host` header affects all SSR + `HttpClient` users, which is a fairly common use case). +- **Medium:** A vulnerability impacts users interacting with public APIs in their reasonable usage. +- **Low:** A vulnerability impacts users interacting with public APIs misused in an unintended or unreasonable way (ex. vulnerability from unsanitized user input polluting the `APP_ID` value, which should never be user writable). +- **None:** A vulnerability impacts users of private APIs or explicitly unsupported use cases. + +Experimental / developer preview APIs _are not_ exempted from these priorities. While we make no hard guarantees about these APIs publicly, a vulnerability in such features should be raised to our attention and addressed before reaching stability. From 2160454a503babef1f68c389af0e812e9962a85c Mon Sep 17 00:00:00 2001 From: Charles Lyding <19598772+clydin@users.noreply.github.com> Date: Mon, 19 Oct 2026 15:30:49 -0400 Subject: [PATCH 655/787] refactor(@angular/build): extract shared breadth-first initial file analysis Previously, both `BundlerContext` and `optimizeChunks` maintained separate implementations for discovering transitive initial files and calculating their import depths from the esbuild metafile. Both implementations used a depth-first stack traversal via `Array.prototype.pop()`, which visited deeper branches in reverse import order and failed to propagate updated minimum depths to the transitive dependencies of already-visited chunks in diamond dependency graphs. This commit extracts a shared `findTransitiveInitialFiles` helper that uses a breadth-first queue traversal over direct static imports. Processing chunks in breadth-first order guarantees that each file is discovered at its true shortest import depth on first visit, preserves the natural declaration order of imports at each depth level, and eliminates the duplicated metafile traversal logic across initial bundling and chunk optimization. --- .../builders/application/chunk-optimizer.ts | 54 +--- .../src/tools/esbuild/bundler-context.ts | 37 +-- .../build/src/tools/esbuild/bundler-files.ts | 53 +++- .../src/tools/esbuild/bundler-files_spec.ts | 298 ++++++++++++++++++ 4 files changed, 358 insertions(+), 84 deletions(-) create mode 100644 packages/angular/build/src/tools/esbuild/bundler-files_spec.ts diff --git a/packages/angular/build/src/builders/application/chunk-optimizer.ts b/packages/angular/build/src/builders/application/chunk-optimizer.ts index cd5e4e1814ec..1c9cb8eb51d6 100644 --- a/packages/angular/build/src/builders/application/chunk-optimizer.ts +++ b/packages/angular/build/src/builders/application/chunk-optimizer.ts @@ -24,8 +24,8 @@ import { BundleMergedContextResult } from '../../tools/esbuild/bundler-context'; import { type BuildOutputFile, BuildOutputFileType, - type InitialFileRecord, createOutputFile, + findTransitiveInitialFiles, } from '../../tools/esbuild/bundler-files'; import { useRolldownChunks } from '../../utils/environment-options'; import { assertIsError } from '../../utils/error'; @@ -166,21 +166,6 @@ function bundleOutputToEsbuildMetafile( return newMetafile; } -/** - * Creates an InitialFileRecord object with a specified depth. - * @param depth The depth of the file in the dependency graph. - * @returns An InitialFileRecord object. - */ -function createInitialFileRecord(depth: number): InitialFileRecord { - return { - type: 'script', - entrypoint: false, - external: false, - serverFile: false, - depth, - }; -} - /** * Creates an esbuild message object for a chunk optimization failure. * @param message The error message detailing the cause of the failure. @@ -369,14 +354,11 @@ export async function optimizeChunks( ); // Add new optimized chunks - const importsPerFile: Record = {}; for (const optimizedFile of optimizedOutput) { if (optimizedFile.type !== 'chunk') { continue; } - importsPerFile[optimizedFile.fileName] = optimizedFile.imports; - original.outputFiles.push( createOutputFile(optimizedFile.fileName, optimizedFile.code, BuildOutputFileType.Browser), ); @@ -392,41 +374,17 @@ export async function optimizeChunks( } // Update initial files to reflect optimized chunks - const entriesToAnalyze: [string, InitialFileRecord][] = []; for (const usedFile of usedChunks) { // Leave the main file since its information did not change - if (usedFile === mainFile) { - // eslint-disable-next-line @typescript-eslint/no-non-null-assertion - entriesToAnalyze.push([mainFile, original.initialFiles.get(mainFile)!]); - continue; + if (usedFile !== mainFile) { + original.initialFiles.delete(usedFile); } - - // Remove all other used chunks - original.initialFiles.delete(usedFile); } // Analyze for transitive initial files - let currentEntry; - while ((currentEntry = entriesToAnalyze.pop())) { - const [entryPath, entryRecord] = currentEntry; - - for (const importPath of importsPerFile[entryPath]) { - const existingRecord = original.initialFiles.get(importPath); - if (existingRecord) { - // Store the smallest value depth - if (existingRecord.depth > entryRecord.depth + 1) { - existingRecord.depth = entryRecord.depth + 1; - } - - continue; - } - - const record = createInitialFileRecord(entryRecord.depth + 1); - - original.initialFiles.set(importPath, record); - entriesToAnalyze.push([importPath, record]); - } - } + const mainRecord = original.initialFiles.get(mainFile); + assert(mainRecord, `Main file record should always be present in initialFiles [${mainFile}].`); + findTransitiveInitialFiles(newMetafile, original.initialFiles, [[mainFile, mainRecord]]); return original; } diff --git a/packages/angular/build/src/tools/esbuild/bundler-context.ts b/packages/angular/build/src/tools/esbuild/bundler-context.ts index 202ab514cbfe..c2a53df67b8c 100644 --- a/packages/angular/build/src/tools/esbuild/bundler-context.ts +++ b/packages/angular/build/src/tools/esbuild/bundler-context.ts @@ -24,6 +24,7 @@ import { BuildOutputFileType, type InitialFileRecord, convertOutputFile, + findTransitiveInitialFiles, } from './bundler-files'; import { LoadResultCache, MemoryLoadResultCache } from './load-result-cache'; @@ -363,41 +364,7 @@ export class BundlerContext { } // Analyze for transitive initial files - const entriesToAnalyze = [...initialFiles]; - let currentEntry; - while ((currentEntry = entriesToAnalyze.pop())) { - const [entryPath, entryRecord] = currentEntry; - - for (const initialImport of result.metafile.outputs[entryPath].imports) { - const existingRecord = initialFiles.get(initialImport.path); - if (existingRecord) { - // Store the smallest value depth - if (existingRecord.depth > entryRecord.depth + 1) { - existingRecord.depth = entryRecord.depth + 1; - } - - continue; - } - - if (initialImport.kind === 'import-statement' || initialImport.kind === 'import-rule') { - const record: InitialFileRecord = { - type: initialImport.kind === 'import-rule' ? 'style' : 'script', - entrypoint: false, - external: initialImport.external, - serverFile: isPlatformServer, - depth: entryRecord.depth + 1, - }; - - if (!this.initialFilter || this.initialFilter(record)) { - initialFiles.set(initialImport.path, record); - } - - if (!initialImport.external) { - entriesToAnalyze.push([initialImport.path, record]); - } - } - } - } + findTransitiveInitialFiles(result.metafile, initialFiles, undefined, this.initialFilter); // Collect all external package names const externalImports = new Set(); diff --git a/packages/angular/build/src/tools/esbuild/bundler-files.ts b/packages/angular/build/src/tools/esbuild/bundler-files.ts index 168c41e65940..af4b04ad9e56 100644 --- a/packages/angular/build/src/tools/esbuild/bundler-files.ts +++ b/packages/angular/build/src/tools/esbuild/bundler-files.ts @@ -6,7 +6,7 @@ * found in the LICENSE file at https://angular.dev/license */ -import type { OutputFile } from 'esbuild'; +import type { Metafile, OutputFile } from 'esbuild'; import { calculateHash } from '../../utils/hash'; export interface InitialFileRecord { @@ -18,6 +18,57 @@ export interface InitialFileRecord { depth: number; } +/** + * Analyzes a metafile to find and record all transitive initial files starting from the given + * initial entries using breadth-first traversal so each file is recorded at its minimum depth. + * + * @param metafile The esbuild metafile containing output import relationships. + * @param initialFiles The map of initial files to populate. + * @param entriesToAnalyze Optional starting entries to traverse; defaults to all current `initialFiles`. + * Entries must share the same starting depth (or be ordered by non-decreasing depth) to guarantee + * that each transitive file is visited at its minimum depth first. + * @param initialFilter Optional filter predicate to determine whether a discovered record should be added. + */ +export function findTransitiveInitialFiles( + metafile: Metafile, + initialFiles: Map, + entriesToAnalyze: Iterable<[string, InitialFileRecord]> = initialFiles, + initialFilter?: (initial: Readonly) => boolean, +): void { + const queue = [...entriesToAnalyze]; + for (let i = 0; i < queue.length; i++) { + const [entryPath, entryRecord] = queue[i]; + const entryOutput = metafile.outputs[entryPath]; + if (!entryOutput) { + continue; + } + + for (const initialImport of entryOutput.imports) { + if (initialFiles.has(initialImport.path)) { + continue; + } + + if (initialImport.kind === 'import-statement' || initialImport.kind === 'import-rule') { + const record: InitialFileRecord = { + type: initialImport.kind === 'import-rule' ? 'style' : 'script', + entrypoint: false, + external: initialImport.external, + serverFile: entryRecord.serverFile, + depth: entryRecord.depth + 1, + }; + + if (!initialFilter || initialFilter(record)) { + initialFiles.set(initialImport.path, record); + + if (!initialImport.external) { + queue.push([initialImport.path, record]); + } + } + } + } + } +} + export enum BuildOutputFileType { Browser, Media, diff --git a/packages/angular/build/src/tools/esbuild/bundler-files_spec.ts b/packages/angular/build/src/tools/esbuild/bundler-files_spec.ts new file mode 100644 index 000000000000..be21f7ded608 --- /dev/null +++ b/packages/angular/build/src/tools/esbuild/bundler-files_spec.ts @@ -0,0 +1,298 @@ +/** + * @license + * Copyright Google LLC All Rights Reserved. + * + * Use of this source code is governed by an MIT-style license that can be + * found in the LICENSE file at https://angular.dev/license + */ + +import type { Metafile } from 'esbuild'; +import { type InitialFileRecord, findTransitiveInitialFiles } from './bundler-files'; + +function createMetafile( + outputs: Record< + string, + { + imports: { + path: string; + kind: 'import-statement' | 'import-rule' | 'dynamic-import'; + external?: boolean; + }[]; + } + >, +): Metafile { + return { + inputs: {}, + outputs: Object.fromEntries( + Object.entries(outputs).map(([key, value]) => [ + key, + { + bytes: 0, + inputs: {}, + imports: value.imports, + exports: [], + }, + ]), + ), + }; +} + +describe('findTransitiveInitialFiles', () => { + it('should compute minimum depth and propagate it to transitive children in a DAG', () => { + // main (0) -> [a (1), b (1)] + // b (1) -> c (2) -> d (via b: 3, via a: 2) -> e (should be 3, not 4) + // a (1) -> d (2) + const metafile = createMetafile({ + 'main.js': { + imports: [ + { path: 'chunk-a.js', kind: 'import-statement' }, + { path: 'chunk-b.js', kind: 'import-statement' }, + ], + }, + 'chunk-a.js': { + imports: [{ path: 'chunk-d.js', kind: 'import-statement' }], + }, + 'chunk-b.js': { + imports: [{ path: 'chunk-c.js', kind: 'import-statement' }], + }, + 'chunk-c.js': { + imports: [{ path: 'chunk-d.js', kind: 'import-statement' }], + }, + 'chunk-d.js': { + imports: [{ path: 'chunk-e.js', kind: 'import-statement' }], + }, + 'chunk-e.js': { + imports: [], + }, + }); + + const initialFiles = new Map([ + ['main.js', { entrypoint: true, name: 'main', type: 'script', serverFile: false, depth: 0 }], + ]); + + findTransitiveInitialFiles(metafile, initialFiles); + + expect(initialFiles.get('chunk-a.js')?.depth).toBe(1); + expect(initialFiles.get('chunk-b.js')?.depth).toBe(1); + expect(initialFiles.get('chunk-c.js')?.depth).toBe(2); + expect(initialFiles.get('chunk-d.js')?.depth).toBe(2); + expect(initialFiles.get('chunk-e.js')?.depth).toBe(3); + }); + + it('should record files in breadth-first forward import order', () => { + const metafile = createMetafile({ + 'main.js': { + imports: [ + { path: 'chunk-a.js', kind: 'import-statement' }, + { path: 'chunk-b.js', kind: 'import-statement' }, + ], + }, + 'chunk-a.js': { + imports: [{ path: 'chunk-a1.js', kind: 'import-statement' }], + }, + 'chunk-b.js': { + imports: [{ path: 'chunk-b1.js', kind: 'import-statement' }], + }, + 'chunk-a1.js': { imports: [] }, + 'chunk-b1.js': { imports: [] }, + }); + + const initialFiles = new Map([ + ['main.js', { entrypoint: true, name: 'main', type: 'script', serverFile: false, depth: 0 }], + ]); + + findTransitiveInitialFiles(metafile, initialFiles); + + expect([...initialFiles.keys()]).toEqual([ + 'main.js', + 'chunk-a.js', + 'chunk-b.js', + 'chunk-a1.js', + 'chunk-b1.js', + ]); + }); + + it('should ignore dynamic imports and handle external and style imports', () => { + const metafile = createMetafile({ + 'main.js': { + imports: [ + { path: 'lazy.js', kind: 'dynamic-import' }, + { path: '@angular/core', kind: 'import-statement', external: true }, + ], + }, + 'styles.css': { + imports: [{ path: 'https://example.com/font.css', kind: 'import-rule', external: true }], + }, + 'lazy.js': { + imports: [{ path: 'lazy-dep.js', kind: 'import-statement' }], + }, + }); + + const initialFiles = new Map([ + ['main.js', { entrypoint: true, name: 'main', type: 'script', serverFile: false, depth: 0 }], + [ + 'styles.css', + { entrypoint: true, name: 'styles', type: 'style', serverFile: false, depth: 0 }, + ], + ]); + + findTransitiveInitialFiles(metafile, initialFiles); + + expect(initialFiles.has('lazy.js')).toBeFalse(); + expect(initialFiles.has('lazy-dep.js')).toBeFalse(); + expect(initialFiles.get('@angular/core')).toEqual({ + type: 'script', + entrypoint: false, + external: true, + serverFile: false, + depth: 1, + }); + expect(initialFiles.get('https://example.com/font.css')).toEqual({ + type: 'style', + entrypoint: false, + external: true, + serverFile: false, + depth: 1, + }); + }); + + it('should only traverse from provided entriesToAnalyze while preserving existing initialFiles', () => { + const metafile = createMetafile({ + 'main.js': { + imports: [{ path: 'chunk-main.js', kind: 'import-statement' }], + }, + 'polyfills.js': { + imports: [{ path: 'chunk-polyfills.js', kind: 'import-statement' }], + }, + 'chunk-main.js': { imports: [] }, + 'chunk-polyfills.js': { imports: [] }, + }); + + const mainRecord: InitialFileRecord = { + entrypoint: true, + name: 'main', + type: 'script', + serverFile: false, + depth: 0, + }; + const polyfillsRecord: InitialFileRecord = { + entrypoint: true, + name: 'polyfills', + type: 'script', + serverFile: false, + depth: 0, + }; + const initialFiles = new Map([ + ['main.js', mainRecord], + ['polyfills.js', polyfillsRecord], + ]); + + const entriesToAnalyze: [string, InitialFileRecord][] = [['main.js', mainRecord]]; + findTransitiveInitialFiles(metafile, initialFiles, entriesToAnalyze); + + expect(entriesToAnalyze.length).toBe(1); + expect(initialFiles.has('main.js')).toBeTrue(); + expect(initialFiles.has('polyfills.js')).toBeTrue(); + expect(initialFiles.has('chunk-main.js')).toBeTrue(); + expect(initialFiles.has('chunk-polyfills.js')).toBeFalse(); + }); + + it('should filter discovered records using initialFilter when provided', () => { + const metafile = createMetafile({ + 'main.js': { + imports: [ + { path: 'chunk-a.js', kind: 'import-statement' }, + { path: 'external-lib', kind: 'import-statement', external: true }, + ], + }, + 'chunk-a.js': { + imports: [{ path: 'chunk-b.js', kind: 'import-statement' }], + }, + 'chunk-b.js': { + imports: [{ path: 'chunk-c.js', kind: 'import-statement' }], + }, + 'chunk-c.js': { + imports: [{ path: 'chunk-b.js', kind: 'import-statement' }], + }, + }); + + const initialFiles = new Map([ + ['main.js', { entrypoint: true, name: 'main', type: 'script', serverFile: false, depth: 0 }], + ]); + + findTransitiveInitialFiles( + metafile, + initialFiles, + undefined, + (record) => !record.external && record.depth <= 1, + ); + + expect(initialFiles.has('chunk-a.js')).toBeTrue(); + expect(initialFiles.has('external-lib')).toBeFalse(); + expect(initialFiles.has('chunk-b.js')).toBeFalse(); + expect(initialFiles.has('chunk-c.js')).toBeFalse(); + }); + + it('should handle circular static imports between chunks without infinite recursion', () => { + const metafile = createMetafile({ + 'main.js': { + imports: [{ path: 'chunk-a.js', kind: 'import-statement' }], + }, + 'chunk-a.js': { + imports: [{ path: 'chunk-b.js', kind: 'import-statement' }], + }, + 'chunk-b.js': { + imports: [ + { path: 'chunk-a.js', kind: 'import-statement' }, + { path: 'main.js', kind: 'import-statement' }, + ], + }, + }); + + const initialFiles = new Map([ + ['main.js', { entrypoint: true, name: 'main', type: 'script', serverFile: false, depth: 0 }], + ]); + + findTransitiveInitialFiles(metafile, initialFiles); + + expect(initialFiles.get('main.js')?.depth).toBe(0); + expect(initialFiles.get('chunk-a.js')?.depth).toBe(1); + expect(initialFiles.get('chunk-b.js')?.depth).toBe(2); + }); + + it('should propagate serverFile flag from entry record to transitive imports', () => { + const metafile = createMetafile({ + 'server.mjs': { + imports: [{ path: 'chunk-server-1.mjs', kind: 'import-statement' }], + }, + 'chunk-server-1.mjs': { + imports: [{ path: 'chunk-server-2.mjs', kind: 'import-statement' }], + }, + 'chunk-server-2.mjs': { imports: [] }, + }); + + const initialFiles = new Map([ + [ + 'server.mjs', + { entrypoint: true, name: 'server', type: 'script', serverFile: true, depth: 0 }, + ], + ]); + + findTransitiveInitialFiles(metafile, initialFiles); + + expect(initialFiles.get('chunk-server-1.mjs')).toEqual({ + type: 'script', + entrypoint: false, + external: undefined, + serverFile: true, + depth: 1, + }); + expect(initialFiles.get('chunk-server-2.mjs')).toEqual({ + type: 'script', + entrypoint: false, + external: undefined, + serverFile: true, + depth: 2, + }); + }); +}); From 21846daf3637496e5f4f86c95843300df871c4dd Mon Sep 17 00:00:00 2001 From: Charles <19598772+clydin@users.noreply.github.com> Date: Tue, 20 Oct 2026 08:46:49 -0400 Subject: [PATCH 656/787] fix(@angular/cli): only load autocompletion in interactive shells Previously, `ng completion` appended an unconditional `source <(ng completion script)` statement to the user's shell configuration file. When non-interactive shells (such as those spawned by scripts, automation tools, or coding agents) sourced the configuration file, they still paid the overhead of starting Node.js and generating the completion script despite tab completion not being used. --- .../commands/completion/long-description.md | 4 +- .../angular/cli/src/utilities/completion.ts | 2 +- .../tests/commands/completion/completion.ts | 67 +++++-------------- 3 files changed, 21 insertions(+), 52 deletions(-) diff --git a/packages/angular/cli/src/commands/completion/long-description.md b/packages/angular/cli/src/commands/completion/long-description.md index b75803ac9cb0..ac0f7ce8aa8f 100644 --- a/packages/angular/cli/src/commands/completion/long-description.md +++ b/packages/angular/cli/src/commands/completion/long-description.md @@ -42,7 +42,9 @@ more control over exactly where this configuration lives, you can manually set i shell run at startup: ```bash -source <(ng completion script) +if [[ $- == *i* ]]; then + source <(ng completion script) +fi ``` This is equivalent to what `ng completion` will automatically set up, and gives power users more diff --git a/packages/angular/cli/src/utilities/completion.ts b/packages/angular/cli/src/utilities/completion.ts index 0e23e1f03348..052231ea964e 100644 --- a/packages/angular/cli/src/utilities/completion.ts +++ b/packages/angular/cli/src/utilities/completion.ts @@ -240,7 +240,7 @@ export async function initializeAutocomplete(): Promise { try { await fs.appendFile( rcFile, - '\n\n# Load Angular CLI autocompletion.\nsource <(ng completion script)\n', + '\n\n# Load Angular CLI autocompletion for interactive shells.\nif [[ $- == *i* ]]; then\n source <(ng completion script)\nfi\n', ); } catch (err) { assertIsError(err); diff --git a/tests/e2e/tests/commands/completion/completion.ts b/tests/e2e/tests/commands/completion/completion.ts index 939bdb8c306b..5b81490c8400 100644 --- a/tests/e2e/tests/commands/completion/completion.ts +++ b/tests/e2e/tests/commands/completion/completion.ts @@ -11,6 +11,13 @@ import { const testRegistry = getGlobalVariable('package-registry'); +const AUTOCOMPLETION_SNIPPET = ` +# Load Angular CLI autocompletion for interactive shells. +if [[ $- == *i* ]]; then + source <(ng completion script) +fi +`.trim(); + export default async function () { // Windows Cmd and Powershell do not support autocompletion. Run a different set of tests to // confirm autocompletion fails gracefully. @@ -33,11 +40,7 @@ export default async function () { ); const rcContents = await fs.readFile(path.join(home, '.bashrc'), 'utf-8'); - const expected = ` -# Load Angular CLI autocompletion. -source <(ng completion script) - `.trim(); - if (!rcContents.includes(expected)) { + if (!rcContents.includes(AUTOCOMPLETION_SNIPPET)) { throw new Error(`~/.bashrc does not contain autocompletion script. Contents:\n${rcContents}`); } }); @@ -55,11 +58,7 @@ source <(ng completion script) ); const rcContents = await fs.readFile(path.join(home, '.zshrc'), 'utf-8'); - const expected = ` -# Load Angular CLI autocompletion. -source <(ng completion script) - `.trim(); - if (!rcContents.includes(expected)) { + if (!rcContents.includes(AUTOCOMPLETION_SNIPPET)) { throw new Error(`~/.zshrc does not contain autocompletion script. Contents:\n${rcContents}`); } }); @@ -79,11 +78,7 @@ source <(ng completion script) ); const rcContents = await fs.readFile(bashrc, 'utf-8'); - const expected = `# Other commands... - -# Load Angular CLI autocompletion. -source <(ng completion script) -`; + const expected = `# Other commands...\n\n${AUTOCOMPLETION_SNIPPET}\n`; if (rcContents !== expected) { throw new Error(`~/.bashrc does not match expectation. Contents:\n${rcContents}`); } @@ -104,11 +99,7 @@ source <(ng completion script) ); const rcContents = await fs.readFile(bashProfile, 'utf-8'); - const expected = `# Other commands... - -# Load Angular CLI autocompletion. -source <(ng completion script) -`; + const expected = `# Other commands...\n\n${AUTOCOMPLETION_SNIPPET}\n`; if (rcContents !== expected) { throw new Error(`~/.bash_profile does not match expectation. Contents:\n${rcContents}`); } @@ -129,11 +120,7 @@ source <(ng completion script) ); const rcContents = await fs.readFile(profile, 'utf-8'); - const expected = `# Other commands... - -# Load Angular CLI autocompletion. -source <(ng completion script) -`; + const expected = `# Other commands...\n\n${AUTOCOMPLETION_SNIPPET}\n`; if (rcContents !== expected) { throw new Error(`~/.profile does not match expectation. Contents:\n${rcContents}`); } @@ -159,11 +146,7 @@ source <(ng completion script) ); const bashrcContents = await fs.readFile(bashrc, 'utf-8'); - const bashrcExpected = `# \`.bashrc\` commands... - -# Load Angular CLI autocompletion. -source <(ng completion script) -`; + const bashrcExpected = `# \`.bashrc\` commands...\n\n${AUTOCOMPLETION_SNIPPET}\n`; if (bashrcContents !== bashrcExpected) { throw new Error(`~/.bashrc does not match expectation. Contents:\n${bashrcContents}`); } @@ -194,11 +177,7 @@ source <(ng completion script) ); const rcContents = await fs.readFile(zshrc, 'utf-8'); - const expected = `# Other commands... - -# Load Angular CLI autocompletion. -source <(ng completion script) -`; + const expected = `# Other commands...\n\n${AUTOCOMPLETION_SNIPPET}\n`; if (rcContents !== expected) { throw new Error(`~/.zshrc does not match expectation. Contents:\n${rcContents}`); } @@ -219,11 +198,7 @@ source <(ng completion script) ); const rcContents = await fs.readFile(zshProfile, 'utf-8'); - const expected = `# Other commands... - -# Load Angular CLI autocompletion. -source <(ng completion script) -`; + const expected = `# Other commands...\n\n${AUTOCOMPLETION_SNIPPET}\n`; if (rcContents !== expected) { throw new Error(`~/.zsh_profile does not match expectation. Contents:\n${rcContents}`); } @@ -244,11 +219,7 @@ source <(ng completion script) ); const rcContents = await fs.readFile(profile, 'utf-8'); - const expected = `# Other commands... - -# Load Angular CLI autocompletion. -source <(ng completion script) -`; + const expected = `# Other commands...\n\n${AUTOCOMPLETION_SNIPPET}\n`; if (rcContents !== expected) { throw new Error(`~/.profile does not match expectation. Contents:\n${rcContents}`); } @@ -274,11 +245,7 @@ source <(ng completion script) ); const zshrcContents = await fs.readFile(zshrc, 'utf-8'); - const zshrcExpected = `# \`.zshrc\` commands... - -# Load Angular CLI autocompletion. -source <(ng completion script) -`; + const zshrcExpected = `# \`.zshrc\` commands...\n\n${AUTOCOMPLETION_SNIPPET}\n`; if (zshrcContents !== zshrcExpected) { throw new Error(`~/.zshrc does not match expectation. Contents:\n${zshrcContents}`); } From 13a73464935365ed48bf30ea520bcc4c84828b9e Mon Sep 17 00:00:00 2001 From: MeAkib Date: Mon, 19 Oct 2026 14:54:27 +0600 Subject: [PATCH 657/787] fix(@angular/build): correct typos and spacing in error and warning messages Several messages printed by the CLI contained typos or ran two sentences together: - The application builder named the option `"app-shell"` in its errors about `server` and `index`, but the option is `appShell`. - The `emitDecoratorMetadata` note printed "by Angularand" and "explictly". - The unit-test Karma `--filter` warning printed "expression.Leading". - The `provideServerRendering()` configuration error printed "provideServerRendering().The". - `ng config` reported "Confguration file cannot be found.". - `ng update` reported "registry package identifer". Add the missing spaces, fix the spelling and use the actual option name. --- packages/angular/build/src/builders/application/options.ts | 4 ++-- .../build/src/builders/unit-test/runners/karma/executor.ts | 2 +- .../src/tools/angular/compilation/compiler-options.ts | 4 ++-- packages/angular/cli/src/commands/config/cli.ts | 2 +- packages/angular/cli/src/commands/update/cli.ts | 2 +- packages/angular/ssr/src/routes/route-config.ts | 7 ++----- 6 files changed, 9 insertions(+), 12 deletions(-) diff --git a/packages/angular/build/src/builders/application/options.ts b/packages/angular/build/src/builders/application/options.ts index 0e225be24045..756676c8d290 100644 --- a/packages/angular/build/src/builders/application/options.ts +++ b/packages/angular/build/src/builders/application/options.ts @@ -415,13 +415,13 @@ export async function normalizeOptions( if (appShellOptions || ssrOptions || prerenderOptions) { if (!serverEntryPoint) { throw new Error( - 'The "server" option is required when enabling "ssr", "prerender" or "app-shell".', + 'The "server" option is required when enabling "ssr", "prerender" or "appShell".', ); } if (!indexHtmlOptions) { throw new Error( - 'The "index" option cannot be set to false when enabling "ssr", "prerender" or "app-shell".', + 'The "index" option cannot be set to false when enabling "ssr", "prerender" or "appShell".', ); } } diff --git a/packages/angular/build/src/builders/unit-test/runners/karma/executor.ts b/packages/angular/build/src/builders/unit-test/runners/karma/executor.ts index e558a3a1f3a7..4b06e6f7b81a 100644 --- a/packages/angular/build/src/builders/unit-test/runners/karma/executor.ts +++ b/packages/angular/build/src/builders/unit-test/runners/karma/executor.ts @@ -116,7 +116,7 @@ export class KarmaExecutor implements TestExecutor { let filter = unitTestOptions.filter; if (filter[0] === '/' && filter.at(-1) === '/') { this.context.logger.warn( - 'The `--filter` option is always a regular expression.' + + 'The `--filter` option is always a regular expression. ' + 'Leading and trailing `/` are not required and will be ignored.', ); } else { diff --git a/packages/angular/build/src/tools/angular/compilation/compiler-options.ts b/packages/angular/build/src/tools/angular/compilation/compiler-options.ts index 77bfdfde2f90..38d1a7676aa4 100644 --- a/packages/angular/build/src/tools/angular/compilation/compiler-options.ts +++ b/packages/angular/build/src/tools/angular/compilation/compiler-options.ts @@ -105,8 +105,8 @@ export function transformCompilerOptions( notes: [ { text: - `The 'emitDecoratorMetadata' option is not required by Angular` + - 'and can be removed if not explictly required by the project.', + `The 'emitDecoratorMetadata' option is not required by Angular ` + + 'and can be removed if not explicitly required by the project.', }, ], }); diff --git a/packages/angular/cli/src/commands/config/cli.ts b/packages/angular/cli/src/commands/config/cli.ts index ef7cfd95d5a5..b721d330f741 100644 --- a/packages/angular/cli/src/commands/config/cli.ts +++ b/packages/angular/cli/src/commands/config/cli.ts @@ -101,7 +101,7 @@ export default class ConfigCommandModule const { logger } = this.context; if (!config || !configPath) { - throw new CommandModuleError('Confguration file cannot be found.'); + throw new CommandModuleError('Configuration file cannot be found.'); } const normalizeUUIDValue = (v: string | undefined) => (v === '' ? randomUUID() : `${v}`); diff --git a/packages/angular/cli/src/commands/update/cli.ts b/packages/angular/cli/src/commands/update/cli.ts index fd0eeca166a3..77bfdb297f28 100644 --- a/packages/angular/cli/src/commands/update/cli.ts +++ b/packages/angular/cli/src/commands/update/cli.ts @@ -197,7 +197,7 @@ export default class UpdateCommandModule extends CommandModule Date: Sun, 18 Oct 2026 19:35:53 +0600 Subject: [PATCH 658/787] docs(@angular/build): correct `outputFile` and `port` option descriptions The unit-test `outputFile` description stated that the path applies only to the first reporter, but it is passed to Vitest as is and used by every configured reporter that writes to a file. The dev-server `port` description did not mention that the `PORT` environment variable takes precedence over the option. --- packages/angular/build/src/builders/dev-server/schema.json | 2 +- packages/angular/build/src/builders/unit-test/schema.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/angular/build/src/builders/dev-server/schema.json b/packages/angular/build/src/builders/dev-server/schema.json index 3517d3098887..667bde5692da 100644 --- a/packages/angular/build/src/builders/dev-server/schema.json +++ b/packages/angular/build/src/builders/dev-server/schema.json @@ -11,7 +11,7 @@ }, "port": { "type": "number", - "description": "Port to listen on.", + "description": "Port to listen on. The `PORT` environment variable, when set, takes precedence over this option.", "default": 4200 }, "host": { diff --git a/packages/angular/build/src/builders/unit-test/schema.json b/packages/angular/build/src/builders/unit-test/schema.json index 66081d555cb1..8c7cfcf686b4 100644 --- a/packages/angular/build/src/builders/unit-test/schema.json +++ b/packages/angular/build/src/builders/unit-test/schema.json @@ -258,7 +258,7 @@ }, "outputFile": { "type": "string", - "description": "Specifies a file path for the test report, applying only to the first reporter. To configure output files for multiple reporters, use the tuple format `['reporter-name', { outputFile: '...' }]` within the `reporters` option. When not provided, output is written to the console." + "description": "Specifies a file path for the test report. This path is used by every configured reporter that writes to a file. To write a separate file for each reporter, use the tuple format `['reporter-name', { outputFile: '...' }]` within the `reporters` option. When not provided, output is written to the console." }, "providersFile": { "type": "string", From cd70beb20db711cb178afccf6c688f9475f9e1f9 Mon Sep 17 00:00:00 2001 From: Alan Agius <17563226+alan-agius4@users.noreply.github.com> Date: Tue, 20 Oct 2026 08:57:18 +0000 Subject: [PATCH 659/787] fix(@angular/build): preserve diagnostic locations at offset 0 and guard empty files Ensure `convertTypeScriptDiagnosticInfo` checks `info.start !== undefined` so diagnostics and related information starting at file offset `0` retain their line, column, and lineText location properties. Also clamp `info.file.text.length - 1` to `0` when computing `lastLineOfFile` to prevent a TypeScript `Debug Failure` when reporting diagnostics on empty files. --- .../tools/angular/compilation/diagnostics.ts | 4 +- .../angular/compilation/diagnostics_spec.ts | 111 ++++++++++++++++++ 2 files changed, 113 insertions(+), 2 deletions(-) create mode 100644 packages/angular/build/src/tools/angular/compilation/diagnostics_spec.ts diff --git a/packages/angular/build/src/tools/angular/compilation/diagnostics.ts b/packages/angular/build/src/tools/angular/compilation/diagnostics.ts index bf85b69f707c..41563b90ebbd 100644 --- a/packages/angular/build/src/tools/angular/compilation/diagnostics.ts +++ b/packages/angular/build/src/tools/angular/compilation/diagnostics.ts @@ -37,7 +37,7 @@ function convertTypeScriptDiagnosticInfo( }; // Calculate the line/column location and extract the full line text that has the diagnostic - if (info.start) { + if (info.start !== undefined) { const { line, character } = typescript.getLineAndCharacterOfPosition(info.file, info.start); note.location.line = line + 1; note.location.column = character; @@ -50,7 +50,7 @@ function convertTypeScriptDiagnosticInfo( // will error if a nonexistent line is passed). const { line: lastLineOfFile } = typescript.getLineAndCharacterOfPosition( info.file, - info.file.text.length - 1, + Math.max(0, info.file.text.length - 1), ); const lineEndPosition = line < lastLineOfFile diff --git a/packages/angular/build/src/tools/angular/compilation/diagnostics_spec.ts b/packages/angular/build/src/tools/angular/compilation/diagnostics_spec.ts new file mode 100644 index 000000000000..8ea79c20ba43 --- /dev/null +++ b/packages/angular/build/src/tools/angular/compilation/diagnostics_spec.ts @@ -0,0 +1,111 @@ +/** + * @license + * Copyright Google LLC All Rights Reserved. + * + * Use of this source code is governed by an MIT-style license that can be + * found in the LICENSE file at https://angular.dev/license + */ + +import ts from 'typescript'; +import { convertTypeScriptDiagnostic } from './diagnostics'; + +describe('convertTypeScriptDiagnostic', () => { + it('populates line, column, and lineText when diagnostic or relatedInformation starts at offset 0', () => { + const sourceFile = ts.createSourceFile( + '/src/app/app.component.ts', + 'const invalid: number = "string";\nconst secondLine = 2;\n', + ts.ScriptTarget.Latest, + ); + const templateFile = ts.createSourceFile( + '/src/app/app.component.html', + '\n
Valid
\n', + ts.ScriptTarget.Latest, + ); + + const diagnostic: ts.Diagnostic = { + category: ts.DiagnosticCategory.Error, + code: -998001, + file: templateFile, + start: 0, + length: 17, + messageText: "'unknown-element' is not a known element.", + relatedInformation: [ + { + category: ts.DiagnosticCategory.Message, + code: 0, + file: sourceFile, + start: 0, + length: 5, + messageText: 'Error occurs in the template of component AppComponent.', + }, + ], + }; + + const result = convertTypeScriptDiagnostic(ts, diagnostic); + + expect(result.text).toBe("NG8001: 'unknown-element' is not a known element."); + expect(result.location).toEqual({ + file: '/src/app/app.component.html', + length: 17, + line: 1, + column: 0, + lineText: '', + }); + + expect(result.notes).toEqual([ + { + text: 'Error occurs in the template of component AppComponent.', + location: { + file: '/src/app/app.component.ts', + length: 5, + line: 1, + column: 0, + lineText: 'const invalid: number = "string";', + }, + }, + ]); + }); + + it('does not throw a TypeScript Debug Failure when diagnostic is reported on an empty file', () => { + const emptyFile = ts.createSourceFile('/src/empty.ts', '', ts.ScriptTarget.Latest); + + const diagnosticAtZero: ts.Diagnostic = { + category: ts.DiagnosticCategory.Error, + code: 2306, + file: emptyFile, + start: 0, + length: 0, + messageText: "File '/src/empty.ts' is not a module.", + }; + + expect(() => convertTypeScriptDiagnostic(ts, diagnosticAtZero)).not.toThrow(); + expect(convertTypeScriptDiagnostic(ts, diagnosticAtZero)).toEqual({ + text: "TS2306: File '/src/empty.ts' is not a module.", + location: { + file: '/src/empty.ts', + length: 0, + line: 1, + column: 0, + lineText: '', + }, + }); + + const diagnosticPastEnd: ts.Diagnostic = { + category: ts.DiagnosticCategory.Error, + code: 1005, + file: emptyFile, + start: 1, + length: 0, + messageText: 'Unexpected end of text.', + }; + + expect(() => convertTypeScriptDiagnostic(ts, diagnosticPastEnd)).not.toThrow(); + expect(convertTypeScriptDiagnostic(ts, diagnosticPastEnd).location).toEqual({ + file: '/src/empty.ts', + length: 0, + line: 1, + column: 1, + lineText: '', + }); + }); +}); From 566abde8866d0512f89953dc5b6a0aae6ef63db8 Mon Sep 17 00:00:00 2001 From: Alan Agius Date: Tue, 20 Oct 2026 16:48:42 +0200 Subject: [PATCH 660/787] fix(@angular/build): enforce library compilerOptions and skip unused .tsbuildinfo emit Ensure library compilations explicitly set `noEmit: false`, `emitDeclarationOnly: false`, and `emitDecoratorMetadata: false` in `transformCompilerOptions` so that configurations extending a root `tsconfig.json` with `noEmit` or `emitDeclarationOnly` still emit both JavaScript and declaration files. --- .../compilation/angular-compilation_spec.ts | 29 +++++++++++++++++++ .../angular/compilation/compiler-options.ts | 25 ++++++++-------- 2 files changed, 42 insertions(+), 12 deletions(-) diff --git a/packages/angular/build/src/tools/angular/compilation/angular-compilation_spec.ts b/packages/angular/build/src/tools/angular/compilation/angular-compilation_spec.ts index 58c492ac5214..842be5528f97 100644 --- a/packages/angular/build/src/tools/angular/compilation/angular-compilation_spec.ts +++ b/packages/angular/build/src/tools/angular/compilation/angular-compilation_spec.ts @@ -6,6 +6,7 @@ * found in the LICENSE file at https://angular.dev/license */ +import path from 'node:path'; import ts from 'typescript'; import type { AngularHostOptions } from '../angular-host'; import { CompilerOptionOverrides, transformCompilerOptions } from './compiler-options'; @@ -476,8 +477,36 @@ describe('AngularCompilation', () => { expect(compilerOptions['_useTypeScriptTranspilation']).toBe(true); expect(compilerOptions.supportTestBed).toBe(true); expect(compilerOptions.supportJitMode).toBe(true); + expect(compilerOptions.noEmit).toBe(false); expect(compilerOptions.noEmitOnError).toBe(false); + expect(compilerOptions.emitDeclarationOnly).toBe(false); expect(compilerOptions.composite).toBe(false); }); + + it('enforces library compiler options and skips app-only target warning', () => { + const { compilerOptions, warnings } = transformCompilerOptions( + ts, + { + target: ts.ScriptTarget.ES2020, + noEmit: true, + emitDeclarationOnly: true, + isolatedModules: true, + }, + { + cachePath: '/tmp/cache', + }, + 'tsconfig.lib.json', + 'library', + ); + + expect(compilerOptions.target).toBe(ts.ScriptTarget.ES2022); + expect(compilerOptions.module).toBe(ts.ModuleKind.Preserve); + expect(compilerOptions.useDefineForClassFields).toBeUndefined(); + expect(compilerOptions.noEmit).toBe(false); + expect(compilerOptions.emitDeclarationOnly).toBe(false); + expect(compilerOptions.incremental).toBe(true); + expect(compilerOptions.tsBuildInfoFile).toBe(path.join('/tmp/cache', '.tsbuildinfo')); + expect(warnings).toEqual([]); + }); }); }); diff --git a/packages/angular/build/src/tools/angular/compilation/compiler-options.ts b/packages/angular/build/src/tools/angular/compilation/compiler-options.ts index 38d1a7676aa4..87a7c7822fc3 100644 --- a/packages/angular/build/src/tools/angular/compilation/compiler-options.ts +++ b/packages/angular/build/src/tools/angular/compilation/compiler-options.ts @@ -39,6 +39,17 @@ export function transformCompilerOptions( const warnings: PartialMessage[] = []; const isLibrary = buildType === 'library'; + if (isLibrary) { + compilerOptions.target = typeScript.ScriptTarget.ES2022; + compilerOptions.module = typeScript.ModuleKind.Preserve; + compilerOptions.importHelpers = true; + compilerOptions.declaration = true; + compilerOptions.declarationMap = !!( + overrides?.declarationMap ?? compilerOptions.declarationMap + ); + compilerOptions.declarationDir = undefined; + } + if ( compilerOptions.target === undefined || compilerOptions.target < typeScript.ScriptTarget.ES2022 @@ -112,18 +123,6 @@ export function transformCompilerOptions( }); } - if (isLibrary) { - compilerOptions.target = typeScript.ScriptTarget.ES2022; - compilerOptions.module = typeScript.ModuleKind.ES2022; - compilerOptions.moduleResolution = typeScript.ModuleResolutionKind.Bundler; - compilerOptions.importHelpers = true; - compilerOptions.declaration = true; - compilerOptions.declarationMap = !!( - overrides?.declarationMap ?? compilerOptions.declarationMap - ); - compilerOptions.declarationDir = undefined; - } - // Synchronize custom resolve conditions. // Set if using the supported bundler resolution mode (bundler is the default in new projects) if ( @@ -137,7 +136,9 @@ export function transformCompilerOptions( compilerOptions: { ...compilerOptions, basePath: overrides?.basePath ? toPosixPath(overrides.basePath) : compilerOptions.basePath, + noEmit: false, noEmitOnError: false, + emitDeclarationOnly: false, composite: false, inlineSources: !!overrides?.sourcemap, inlineSourceMap: !isLibrary && !!overrides?.sourcemap, From d69dcec3137f0fd49e591d410c82569b3798f2ec Mon Sep 17 00:00:00 2001 From: Roman Khegay Date: Tue, 20 Oct 2026 19:57:31 +0500 Subject: [PATCH 661/787] fix(@angular/cli): keep schematic positional arguments in index order sort checked `positional` for truthiness, so argument at index 0 was ordered like plain option and help showed it after index 1 when that argument has `x-prompt` both are optional for yargs and values go to wrong argumnets, now positionals are sorted by index --- .../command-builder/utilities/json-schema.ts | 8 ++-- .../utilities/json-schema_spec.ts | 43 +++++++++++++++++++ tests/e2e/tests/generate/help-output.ts | 10 ++--- 3 files changed, 52 insertions(+), 9 deletions(-) diff --git a/packages/angular/cli/src/command-builder/utilities/json-schema.ts b/packages/angular/cli/src/command-builder/utilities/json-schema.ts index 0a4215be8eed..78218465cf02 100644 --- a/packages/angular/cli/src/command-builder/utilities/json-schema.ts +++ b/packages/angular/cli/src/command-builder/utilities/json-schema.ts @@ -390,10 +390,10 @@ export async function parseJsonSchemaToOptions( // Sort by positional and name. return options.sort((a, b) => { - if (a.positional) { - return b.positional ? a.positional - b.positional : a.name.localeCompare(b.name); - } else if (b.positional) { - return -1; + if (a.positional !== undefined) { + return b.positional !== undefined ? a.positional - b.positional : -1; + } else if (b.positional !== undefined) { + return 1; } return a.name.localeCompare(b.name); diff --git a/packages/angular/cli/src/command-builder/utilities/json-schema_spec.ts b/packages/angular/cli/src/command-builder/utilities/json-schema_spec.ts index 496a2094b62c..117b325f26b1 100644 --- a/packages/angular/cli/src/command-builder/utilities/json-schema_spec.ts +++ b/packages/angular/cli/src/command-builder/utilities/json-schema_spec.ts @@ -346,4 +346,47 @@ describe('parseJsonSchemaToOptions', () => { ); }); }); + + describe('with positional arguments not in alphabetical order', () => { + it('sorts positional arguments by their index', async () => { + const jsonSchema = { + '$id': 'FakeSchema', + 'title': 'Fake Schema', + 'type': 'object', + 'required': ['preset'], + 'properties': { + 'preset': { + 'type': 'string', + 'enum': ['form', 'table'], + 'description': 'preset.', + '$default': { + '$source': 'argv', + 'index': 0, + }, + 'x-prompt': 'Which preset?', + }, + 'name': { + 'type': 'string', + 'description': 'name.', + '$default': { + '$source': 'argv', + 'index': 1, + }, + }, + 'path': { + 'type': 'string', + 'description': 'path.', + }, + }, + }; + const registry = new schema.CoreSchemaRegistry(); + const options = await parseJsonSchemaToOptions(registry, jsonSchema, /* interactive= */ true); + + expect(options).toEqual([ + jasmine.objectContaining({ name: 'preset', positional: 0, required: false }), + jasmine.objectContaining({ name: 'name', positional: 1, required: false }), + jasmine.objectContaining({ name: 'path', positional: undefined, required: false }), + ]); + }); + }); }); diff --git a/tests/e2e/tests/generate/help-output.ts b/tests/e2e/tests/generate/help-output.ts index 86fc3b988b38..bd5c71a7d9d1 100644 --- a/tests/e2e/tests/generate/help-output.ts +++ b/tests/e2e/tests/generate/help-output.ts @@ -32,14 +32,14 @@ export default function () { "$id": "FakeSchema", "title": "Fake Schema", "type": "object", - "required": ["a"], + "required": ["b"], "properties": { "b": { "type": "string", "description": "b.", "$default": { "$source": "argv", - "index": 1 + "index": 0 } }, "a": { @@ -47,7 +47,7 @@ export default function () { "description": "a.", "$default": { "$source": "argv", - "index": 0 + "index": 1 } }, "optC": { @@ -76,7 +76,7 @@ export default function () { ) .then(() => ng('generate', 'fake-schematics:fake', '--help')) .then(({ stdout }) => { - assert.match(stdout, /ng generate fake-schematics:fake \[b\]/); + assert.match(stdout, /ng generate fake-schematics:fake \[a\]/); assert.match(stdout, /opt-a[\s\S]*opt-b[\s\S]*opt-c/); }) // set up default collection. @@ -89,7 +89,7 @@ export default function () { .then(() => ng('generate', 'fake', '--help')) // verify same output .then(({ stdout }) => { - assert.match(stdout, /ng generate fake \[b\]/); + assert.match(stdout, /ng generate fake \[a\]/); assert.match(stdout, /opt-a[\s\S]*opt-b[\s\S]*opt-c/); }) From 97efdcf9136230baeb9ec757dcd24a17f12cd223 Mon Sep 17 00:00:00 2001 From: Charles Lyding <19598772+clydin@users.noreply.github.com> Date: Mon, 19 Oct 2026 18:48:11 -0400 Subject: [PATCH 662/787] fix(@angular/build): consolidate initial shared chunks into main with Rolldown When esbuild bundles an application with lazy-loaded routes, modules that are statically reachable from the main entry point and also imported by different subsets of lazy routes are split into separate shared chunks, often forming multi-level import chains from main.js. Previously, the Rollup-based chunk optimization pass recognized that the main entry point is always loaded before any dynamic import can execute and merged all modules in its static closure back into main.js. After switching chunk optimization to Rolldown, unconfigured Rolldown only merged direct single-hop shared chunks into main.js while leaving deeper initial shared chunks as separate files. Configuring Rolldown with preserveEntrySignatures set to allow-extension and a codeSplitting group targeting the built-in $initial tag restores the consolidation of all initial shared modules into the main entry chunk while keeping lazy-only shared chunks separate. --- .../builders/application/chunk-optimizer.ts | 38 ++++- .../chunk-optimization-server_spec.ts | 144 ++++++++++++++++++ 2 files changed, 177 insertions(+), 5 deletions(-) diff --git a/packages/angular/build/src/builders/application/chunk-optimizer.ts b/packages/angular/build/src/builders/application/chunk-optimizer.ts index 1c9cb8eb51d6..7941ebe1f6a7 100644 --- a/packages/angular/build/src/builders/application/chunk-optimizer.ts +++ b/packages/angular/build/src/builders/application/chunk-optimizer.ts @@ -281,19 +281,48 @@ export async function optimizeChunks( }, ]; + const chunkFileNames = (chunkInfo: { name: string }) => + `${chunkInfo.name.replace(/-[a-zA-Z0-9_-]{8}$/, '')}-[hash].js`; + if (useRolldownChunks) { const { rolldown } = await loadRolldown(); bundle = await rolldown({ input: mainFile, + // Allow Rolldown to extend the main entry chunk's exports when merging shared initial + // modules into `main` so that lazy chunks can import those symbols directly from `main`. + preserveEntrySignatures: 'allow-extension', plugins, }); - const result = await bundle.generate({ + let result = await bundle.generate({ minify: { mangle: false, compress: false }, sourcemap, - chunkFileNames: (chunkInfo) => - `${chunkInfo.name.replace(/-[a-zA-Z0-9_-]{8}$/, '')}-[hash].js`, + codeSplitting: { + // Consolidate all modules statically reachable from the initial entry point (`$initial`) + // back into the `main` chunk. This prevents multi-level initial chunk waterfalls caused + // by esbuild splitting out modules that are shared across `main` and subsets of lazy + // routes, while keeping shared chunks used exclusively by lazy routes separate. + groups: [{ name: 'main', tags: ['$initial'] }], + }, + chunkFileNames, }); + + // If any module in `$initial` uses top-level `await`, Rolldown cannot fold the manual + // `main` group into the entry chunk and emits an empty entry facade instead. Fall back to + // Rolldown's default TLA-aware chunking in that case. + if ( + result.output.some( + (chunk) => + chunk.type === 'chunk' && chunk.isEntry && Object.keys(chunk.modules).length === 0, + ) + ) { + result = await bundle.generate({ + minify: { mangle: false, compress: false }, + sourcemap, + chunkFileNames, + }); + } + optimizedOutput = result.output; } else { let rollup; @@ -313,8 +342,7 @@ export async function optimizeChunks( const result = await bundle.generate({ compact: true, sourcemap, - chunkFileNames: (chunkInfo) => - `${chunkInfo.name.replace(/-[a-zA-Z0-9_-]{8}$/, '')}-[hash].js`, + chunkFileNames, }); optimizedOutput = result.output; } diff --git a/packages/angular/build/src/builders/application/tests/behavior/chunk-optimization-server_spec.ts b/packages/angular/build/src/builders/application/tests/behavior/chunk-optimization-server_spec.ts index 18b92e7690a0..3bdef34cae06 100644 --- a/packages/angular/build/src/builders/application/tests/behavior/chunk-optimization-server_spec.ts +++ b/packages/angular/build/src/builders/application/tests/behavior/chunk-optimization-server_spec.ts @@ -187,5 +187,149 @@ describeBuilder(buildApplication, APPLICATION_BUILDER_INFO, (harness) => { .toBeTrue(); } }); + + it('consolidates multi-level initial shared modules into main while preserving lazy-only shared chunks', async () => { + await harness.writeFiles({ + 'src/shared-1.ts': ` + import { shared2 } from './shared-2'; + export function shared1(): string { + return 's1-' + shared2(); + } + `, + 'src/shared-2.ts': ` + import { shared3 } from './shared-3'; + export function shared2(): string { + return 's2-' + shared3(); + } + `, + 'src/shared-3.ts': ` + import { shared4 } from './shared-4'; + export function shared3(): string { + return 's3-' + shared4(); + } + `, + 'src/shared-4.ts': ` + export function shared4(): string { + return 's4-' + Date.now().toString(36); + } + `, + 'src/lazy-shared.ts': ` + export function lazyOnlyShared(): string { + return 'lazy-only-' + Date.now().toString(36); + } + `, + 'src/app/app.component.ts': ` + import { Component } from '@angular/core'; + import { RouterOutlet } from '@angular/router'; + import { shared1 } from '../shared-1'; + + @Component({ + selector: 'app-root', + imports: [RouterOutlet], + template: '

{{ val }}

', + }) + export class AppComponent { + val = shared1(); + } + `, + 'src/app/lazy-a.component.ts': ` + import { Component } from '@angular/core'; + import { shared1 } from '../shared-1'; + import { lazyOnlyShared } from '../lazy-shared'; + + @Component({ selector: 'app-lazy-a', template: '{{ val }}' }) + export default class LazyAComponent { + val = shared1() + lazyOnlyShared(); + } + `, + 'src/app/lazy-b.component.ts': ` + import { Component } from '@angular/core'; + import { shared2 } from '../shared-2'; + import { lazyOnlyShared } from '../lazy-shared'; + + @Component({ selector: 'app-lazy-b', template: '{{ val }}' }) + export default class LazyBComponent { + val = shared2() + lazyOnlyShared(); + } + `, + 'src/app/lazy-c.component.ts': ` + import { Component } from '@angular/core'; + import { shared3 } from '../shared-3'; + + @Component({ selector: 'app-lazy-c', template: '{{ val }}' }) + export default class LazyCComponent { + val = shared3(); + } + `, + 'src/app/lazy-d.component.ts': ` + import { Component } from '@angular/core'; + import { shared4 } from '../shared-4'; + + @Component({ selector: 'app-lazy-d', template: '{{ val }}' }) + export default class LazyDComponent { + val = shared4(); + } + `, + }); + + harness.useTarget('build', { + ...BASE_OPTIONS, + polyfills: ['zone.js'], + optimization: true, + namedChunks: true, + }); + + const { result } = await harness.executeOnce(); + expect(result?.success).toBeTrue(); + + const mainContent = harness.readFile('dist/browser/main.js'); + expect(mainContent).toContain('s1-'); + expect(mainContent).toContain('s2-'); + expect(mainContent).toContain('s3-'); + expect(mainContent).toContain('s4-'); + expect(mainContent).not.toContain('lazy-only-'); + + // No modulepreload hints should be needed in index.html because all initial shared + // modules (shared-1 through shared-4) were consolidated into main.js. + const indexContent = harness.readFile('dist/browser/index.html'); + expect(indexContent).not.toContain('rel="modulepreload"'); + + // The lazy-only shared module should still be emitted as a separate shared chunk. + expect(harness.hasFileMatch('dist/browser', /^chunk-/)).toBeTrue(); + }); + + it('falls back to TLA-safe chunking without emitting an empty main facade when top-level await is used', async () => { + await harness.writeFiles({ + 'src/main.ts': ` + import { provideZonelessChangeDetection } from '@angular/core'; + import { bootstrapApplication } from '@angular/platform-browser'; + import { AppComponent } from './app/app.component'; + import { appConfig } from './app/app.config'; + + await Promise.resolve(); + console.log('main-tla-entry'); + await bootstrapApplication(AppComponent, { + ...appConfig, + providers: [...appConfig.providers, provideZonelessChangeDetection()], + }); + `, + }); + + harness.useTarget('build', { + ...BASE_OPTIONS, + polyfills: [], + optimization: true, + namedChunks: true, + }); + + const { result } = await harness.executeOnce(); + expect(result?.success).toBeTrue(); + + // main.js should contain the entry point code directly rather than being an empty + // facade importing a separate `main-.js` chunk. + expect(harness.hasFileMatch('dist/browser', /^main-/)).toBeFalse(); + const mainContent = harness.readFile('dist/browser/main.js'); + expect(mainContent).toContain('main-tla-entry'); + }); }); }); From 9732721b0e35bd134240e1f5d316f813bd6ed9c3 Mon Sep 17 00:00:00 2001 From: Shuaib Hasan Akib <48770016+MeAkib@users.noreply.github.com> Date: Tue, 20 Oct 2026 21:24:31 +0600 Subject: [PATCH 663/787] fix(@schematics/angular): migrate ng-packagr glob string assets in use-library-builder ng-packagr treats an `assets` string that is neither a file nor a directory as a glob relative to the package root. The migration copied every string as a path, and the library builder treats such a path as a directory, so glob assets like `docs/**/*.md` copied nothing after the migration. --- .../use-library-builder/migration.ts | 18 +++++++- .../use-library-builder/migration_spec.ts | 43 +++++++++++++++++++ 2 files changed, 60 insertions(+), 1 deletion(-) diff --git a/packages/schematics/angular/migrations/use-library-builder/migration.ts b/packages/schematics/angular/migrations/use-library-builder/migration.ts index 68f9e8738e25..285cdf9f2332 100644 --- a/packages/schematics/angular/migrations/use-library-builder/migration.ts +++ b/packages/schematics/angular/migrations/use-library-builder/migration.ts @@ -251,7 +251,23 @@ function migrateTargetOptions( : []; const migratedAssets = ngPackageConfig.assets.map((asset) => { if (typeof asset === 'string') { - return join(projectDir, asset); + const assetPath = join(projectDir, asset); + if (assetPath.startsWith('..')) { + return assetPath; + } + + if (tree.exists(assetPath)) { + return assetPath; + } + + const assetDir = tree.getDir(assetPath); + if (assetDir.subfiles.length || assetDir.subdirs.length) { + return assetPath; + } + + // `ng-packagr` treats a string that is neither a file nor a directory as a glob relative + // to the package root, while the library builder only accepts files and directories. + return { glob: asset, input: projectDir }; } if (isJsonObject(asset) && typeof asset['input'] === 'string') { return { diff --git a/packages/schematics/angular/migrations/use-library-builder/migration_spec.ts b/packages/schematics/angular/migrations/use-library-builder/migration_spec.ts index 11192f8e5897..d54d5f62f61a 100644 --- a/packages/schematics/angular/migrations/use-library-builder/migration_spec.ts +++ b/packages/schematics/angular/migrations/use-library-builder/migration_spec.ts @@ -281,6 +281,7 @@ describe('Migration to use the library builder', () => { }); it('should migrate assets, styleIncludePaths, and sass options from ng-package.json', async () => { + tree.create('/projects/my-lib/CHANGELOG.md', '# Changelog'); tree.overwrite( '/projects/my-lib/ng-package.json', JSON.stringify( @@ -324,6 +325,48 @@ describe('Migration to use the library builder', () => { }); }); + it('should migrate ng-packagr glob string assets to glob objects', async () => { + tree.create('/projects/my-lib/docs/guide.md', '# Guide'); + tree.create('/projects/my-lib/CHANGELOG.md', '# Changelog'); + tree.overwrite( + '/projects/my-lib/ng-package.json', + JSON.stringify({ + assets: ['CHANGELOG.md', 'docs', 'docs/**/*.md'], + lib: { entryFile: 'src/public-api.ts' }, + }), + ); + + const newTree = await schematicRunner.runSchematic(schematicName, {}, tree); + const { + projects: { 'my-lib': lib }, + // eslint-disable-next-line @typescript-eslint/no-explicit-any + } = newTree.readJson('/angular.json') as any; + + expect(lib.architect['build'].options.assets).toEqual([ + 'projects/my-lib/CHANGELOG.md', + 'projects/my-lib/docs', + { glob: 'docs/**/*.md', input: 'projects/my-lib' }, + ]); + }); + + it('should keep ng-packagr assets outside the project root as paths', async () => { + tree.overwrite( + '/projects/my-lib/ng-package.json', + JSON.stringify({ + assets: ['../../../shared-assets'], + lib: { entryFile: 'src/public-api.ts' }, + }), + ); + + const newTree = await schematicRunner.runSchematic(schematicName, {}, tree); + const { + projects: { 'my-lib': lib }, + // eslint-disable-next-line @typescript-eslint/no-explicit-any + } = newTree.readJson('/angular.json') as any; + + expect(lib.architect['build'].options.assets).toEqual(['../shared-assets']); + }); + it('should preserve existing stylePreprocessorOptions.includePaths when migrating styleIncludePaths', async () => { const angularJson = JSON.parse(tree.readContent('/angular.json')); angularJson.projects['my-lib'].architect.build.options.stylePreprocessorOptions = { From 089d39467863643ecadf79cefc5c92a16b0a85d3 Mon Sep 17 00:00:00 2001 From: drakeo338 Date: Mon, 19 Oct 2026 09:39:44 +0000 Subject: [PATCH 664/787] fix(@angular/build): add integrity metadata for all initial chunks beyond the module preload limit With subresource integrity enabled, the import map integrity entries skipped every file in the initial files set. Only the first 10 initial script chunks receive a `modulepreload` hint (and none do when `preloadInitial` is disabled or `externalPackages` is set), so the remaining initial chunks ended up without any integrity metadata. Skip only entry points, which are referenced by their own tag, and files that actually received a hint. All other initial chunks are now included in the import map integrity entries. Closes #34395 --- .../application/index-html-generator.ts | 9 +- .../application/index-html-generator_spec.ts | 114 ++++++++++++++++++ 2 files changed, 122 insertions(+), 1 deletion(-) create mode 100644 packages/angular/build/src/builders/application/index-html-generator_spec.ts diff --git a/packages/angular/build/src/builders/application/index-html-generator.ts b/packages/angular/build/src/builders/application/index-html-generator.ts index d89eadf8b9b0..a1c9cbcc9b30 100644 --- a/packages/angular/build/src/builders/application/index-html-generator.ts +++ b/packages/angular/build/src/builders/application/index-html-generator.ts @@ -91,8 +91,15 @@ export async function generateIndexHtml( let chunksIntegrity: ReadonlyMap | undefined; if (subresourceIntegrity) { const integrity = new Map(); + // Entry points and module preload hints carry their own integrity attribute. Any other + // initial chunk (e.g. beyond the module preload limit) is only covered by the import map. + const hinted = new Set(hints.map(({ url }) => url)); for (const file of browserOutputFiles) { - if (!file.path.endsWith('.js') || initialFiles.has(file.path)) { + if ( + !file.path.endsWith('.js') || + initialFiles.get(file.path)?.entrypoint || + hinted.has(file.path) + ) { continue; } const hash = createHash('sha384').update(file.contents).digest('base64'); diff --git a/packages/angular/build/src/builders/application/index-html-generator_spec.ts b/packages/angular/build/src/builders/application/index-html-generator_spec.ts new file mode 100644 index 000000000000..4f1098086461 --- /dev/null +++ b/packages/angular/build/src/builders/application/index-html-generator_spec.ts @@ -0,0 +1,114 @@ +/** + * @license + * Copyright Google LLC All Rights Reserved. + * + * Use of this source code is governed by an MIT-style license that can be + * found in the LICENSE file at https://angular.dev/license + */ + +import { mkdtemp, rm, writeFile } from 'node:fs/promises'; +import { tmpdir } from 'node:os'; +import { join } from 'node:path'; +import { + BuildOutputFile, + BuildOutputFileType, + InitialFileRecord, +} from '../../tools/esbuild/bundler-files'; +import { generateIndexHtml } from './index-html-generator'; +import { NormalizedApplicationBuildOptions } from './options'; + +describe('generateIndexHtml', () => { + let tempDir: string; + + beforeEach(async () => { + tempDir = await mkdtemp(join(tmpdir(), 'index-html-generator-spec-')); + await writeFile( + join(tempDir, 'index.html'), + '', + ); + }); + + afterEach(async () => { + await rm(tempDir, { recursive: true, force: true }); + }); + + function createOutputFile(path: string): BuildOutputFile { + const text = `console.log(${JSON.stringify(path)});`; + + return { + path, + text, + contents: Buffer.from(text), + type: BuildOutputFileType.Browser, + } as unknown as BuildOutputFile; + } + + function createOptions(subresourceIntegrity: boolean): NormalizedApplicationBuildOptions { + return { + indexHtmlOptions: { + input: join(tempDir, 'index.html'), + insertionOrder: [['main.js', true]], + preloadInitial: true, + }, + subresourceIntegrity, + baseHref: '/', + security: {}, + } as unknown as NormalizedApplicationBuildOptions; + } + + it('adds integrity metadata for every initial chunk when there are more than the module preload limit', async () => { + const chunkCount = 15; + const chunks = Array.from({ length: chunkCount }, (_, i) => `chunk-${i}.js`); + const initialFiles = new Map([ + ['main.js', { entrypoint: true, name: 'main', type: 'script', serverFile: false, depth: 0 }], + ...chunks.map( + (chunk, i) => + [chunk, { entrypoint: false, type: 'script', serverFile: false, depth: i + 1 }] as [ + string, + InitialFileRecord, + ], + ), + ]); + const outputFiles = ['main.js', ...chunks].map(createOutputFile); + + const { csrContent, errors } = await generateIndexHtml( + initialFiles, + outputFiles, + createOptions(true), + ); + expect(errors).toEqual([]); + + const importMapMatch = /`); + + expect(page).not.toContain('