From 5a71bcfabda1e9c745e247178e66754f9376fde9 Mon Sep 17 00:00:00 2001 From: Angular Robot Date: Thu, 6 Aug 2026 06:14:52 +0000 Subject: [PATCH 01/97] build: update dependency bazel_lib to v3.7.1 See associated pull request for more information. --- MODULE.bazel | 2 +- MODULE.bazel.lock | 5 +++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/MODULE.bazel b/MODULE.bazel index d4fb6902ff2a..19944fcccb15 100644 --- a/MODULE.bazel +++ b/MODULE.bazel @@ -12,7 +12,7 @@ bazel_dep(name = "aspect_rules_ts", version = "3.9.2") bazel_dep(name = "rules_pkg", version = "1.2.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.5.0") +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_jasmine", version = "2.0.4") diff --git a/MODULE.bazel.lock b/MODULE.bazel.lock index a30e6d148916..36db732d1e78 100644 --- a/MODULE.bazel.lock +++ b/MODULE.bazel.lock @@ -53,7 +53,8 @@ "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.5.0/source.json": "98d49ec7e2b15298c990f09ec8cdea8d4788c2885497aa9cbb0a74e36e994df8", + "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", "https://bcr.bazel.build/modules/bazel_skylib/1.1.1/MODULE.bazel": "1add3e7d93ff2e6998f9e118022c84d163917d912f5afafb3058e3d2f1545b5e", "https://bcr.bazel.build/modules/bazel_skylib/1.2.0/MODULE.bazel": "44fe84260e454ed94ad326352a698422dbe372b21a1ac9f3eab76eb531223686", @@ -222,7 +223,7 @@ "moduleExtensions": { "@@aspect_rules_esbuild+//esbuild:extensions.bzl%esbuild": { "general": { - "bzlTransitiveDigest": "Nhop9eqlQBcxge+uYzGmhiFAZmagl+D5CUXkaUpOBCc=", + "bzlTransitiveDigest": "DfFT9JjdwDXEFWTCpbJTMqiSwGOU02Jq1C1XgMbRhec=", "usagesDigest": "LSQ+zZp7JNgnBONTxxXnwGr4NTh2qtQYk7qwXXz5qWo=", "recordedFileInputs": {}, "recordedDirentsInputs": {}, From e01874629db960749bc2e6930e74aee779e6c775 Mon Sep 17 00:00:00 2001 From: Angular Robot Date: Thu, 6 Aug 2026 06:14:10 +0000 Subject: [PATCH 02/97] build: update all non-major dependencies See associated pull request for more information. --- package.json | 10 +- packages/angular/build/package.json | 6 +- .../angular_devkit/build_angular/package.json | 4 +- pnpm-lock.yaml | 645 ++++++++---------- 4 files changed, 288 insertions(+), 377 deletions(-) diff --git a/package.json b/package.json index 935b6cae3ecd..c9f634207208 100644 --- a/package.json +++ b/package.json @@ -92,8 +92,8 @@ "@types/watchpack": "^2.4.4", "@types/yargs": "^17.0.20", "@types/yargs-parser": "^21.0.0", - "@typescript-eslint/eslint-plugin": "8.65.0", - "@typescript-eslint/parser": "8.65.0", + "@typescript-eslint/eslint-plugin": "8.66.0", + "@typescript-eslint/parser": "8.66.0", "ajv": "8.20.0", "buffer": "6.0.3", "esbuild": "0.28.1", @@ -120,16 +120,16 @@ "lodash": "^4.17.21", "magic-string": "1.1.0", "prettier": "^3.0.0", - "puppeteer": "25.4.0", + "puppeteer": "25.5.0", "quicktype-core": "26.0.0", "rollup": "4.62.4", "rollup-license-plugin": "~3.2.0", - "rollup-plugin-dts": "6.4.1", + "rollup-plugin-dts": "6.5.1", "rollup-plugin-sourcemaps2": "0.5.8", "semver": "7.8.5", "source-map-support": "0.5.21", "tslib": "2.8.1", - "undici": "8.9.0", + "undici": "8.10.0", "unenv": "^1.10.0", "verdaccio": "6.9.2", "verdaccio-auth-memory": "^13.0.0", diff --git a/packages/angular/build/package.json b/packages/angular/build/package.json index 633064827709..9b1fdce6b518 100644 --- a/packages/angular/build/package.json +++ b/packages/angular/build/package.json @@ -31,11 +31,11 @@ "listr2": "11.0.0", "magic-string": "1.1.0", "mrmime": "2.0.1", - "oxc-parser": "0.142.0", + "oxc-parser": "0.143.0", "parse5-html-rewriting-stream": "8.0.1", "picomatch": "4.0.5", "piscina": "5.3.0", - "rolldown": "1.2.1", + "rolldown": "1.2.2", "sass": "1.102.0", "semver": "7.8.5", "source-map-support": "0.5.21", @@ -49,7 +49,7 @@ "devDependencies": { "@angular-devkit/core": "workspace:*", "@angular/ssr": "workspace:*", - "@oxc-project/types": "0.142.0", + "@oxc-project/types": "0.143.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 bd47aeba1515..3835fe864087 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.0", + "terser": "5.49.1", "tinyglobby": "0.2.17", "tslib": "2.8.1", "webpack": "5.109.2", @@ -67,7 +67,7 @@ "@angular/ssr": "workspace:*", "browser-sync": "3.0.4", "ng-packagr": "22.2.0-next.2", - "undici": "8.9.0" + "undici": "8.10.0" }, "peerDependencies": { "@angular/compiler-cli": "0.0.0-ANGULAR-FW-PEER-DEP", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 0e3c3cd04d51..6c60a1312dd8 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -164,11 +164,11 @@ importers: specifier: ^21.0.0 version: 21.0.3 '@typescript-eslint/eslint-plugin': - specifier: 8.65.0 - version: 8.65.0(@typescript-eslint/parser@8.65.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) + 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) '@typescript-eslint/parser': - specifier: 8.65.0 - version: 8.65.0(eslint@10.8.0(jiti@2.7.0)(supports-color@11.0.0))(supports-color@11.0.0)(typescript@6.0.3) + 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) ajv: specifier: 8.20.0 version: 8.20.0 @@ -189,7 +189,7 @@ importers: version: 10.1.8(eslint@10.8.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.65.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.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) express: specifier: 5.2.1 version: 5.2.1(supports-color@11.0.0) @@ -248,8 +248,8 @@ importers: specifier: ^3.0.0 version: 3.9.6 puppeteer: - specifier: 25.4.0 - version: 25.4.0(bufferutil@4.1.0)(utf-8-validate@6.0.6) + specifier: 25.5.0 + version: 25.5.0(bufferutil@4.1.0)(utf-8-validate@6.0.6) quicktype-core: specifier: 26.0.0 version: 26.0.0 @@ -260,8 +260,8 @@ importers: specifier: ~3.2.0 version: 3.2.1 rollup-plugin-dts: - specifier: 6.4.1 - version: 6.4.1(rollup@4.62.4)(typescript@6.0.3) + specifier: 6.5.1 + version: 6.5.1(rollup@4.62.4)(typescript@6.0.3) rollup-plugin-sourcemaps2: specifier: 0.5.8 version: 0.5.8(@types/node@22.20.1)(rollup@4.62.4) @@ -275,8 +275,8 @@ importers: specifier: 2.8.1 version: 2.8.1 undici: - specifier: 8.9.0 - version: 8.9.0 + specifier: 8.10.0 + version: 8.10.0 unenv: specifier: ^1.10.0 version: 1.10.0 @@ -324,7 +324,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.0)(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.1)(yaml@2.9.0) packages/angular/build: dependencies: @@ -342,7 +342,7 @@ importers: version: 6.1.1(@types/node@22.20.1) '@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.0)(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.1)(yaml@2.9.0)) beasties: specifier: 0.4.3 version: 0.4.3 @@ -368,8 +368,8 @@ importers: specifier: 2.0.1 version: 2.0.1 oxc-parser: - specifier: 0.142.0 - version: 0.142.0 + specifier: 0.143.0 + version: 0.143.0 parse5-html-rewriting-stream: specifier: 8.0.1 version: 8.0.1 @@ -380,8 +380,8 @@ importers: specifier: 5.3.0 version: 5.3.0 rolldown: - specifier: 1.2.1 - version: 1.2.1 + specifier: 1.2.2 + version: 1.2.2 sass: specifier: 1.102.0 version: 1.102.0 @@ -396,7 +396,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.0)(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.1)(yaml@2.9.0) watchpack: specifier: 2.5.2 version: 2.5.2 @@ -408,8 +408,8 @@ importers: specifier: workspace:* version: link:../ssr '@oxc-project/types': - specifier: 0.142.0 - version: 0.142.0 + specifier: 0.143.0 + version: 0.143.0 istanbul-lib-instrument: specifier: 6.0.3 version: 6.0.3(supports-color@11.0.0) @@ -433,7 +433,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.0)(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.1)(yaml@2.9.0) optionalDependencies: lmdb: specifier: 3.5.6 @@ -677,8 +677,8 @@ importers: specifier: 0.5.21 version: 0.5.21 terser: - specifier: 5.49.0 - version: 5.49.0 + specifier: 5.49.1 + version: 5.49.1 tinyglobby: specifier: 0.2.17 version: 0.2.17 @@ -711,8 +711,8 @@ importers: 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) undici: - specifier: 8.9.0 - version: 8.9.0 + specifier: 8.10.0 + version: 8.10.0 optionalDependencies: esbuild: specifier: 0.28.1 @@ -1622,24 +1622,6 @@ packages: resolution: {integrity: sha512-Xc3VhU02wqZ1HvHRJUwL09HkZSTvidqY5Ya0NXBSYOxAp+Ln9dcJr9fySI+CkONzP3PekQo9WdzCv0PGER/mOA==} engines: {node: '>=14.17.0'} - '@emnapi/core@1.11.2': - resolution: {integrity: sha512-TC8MkTuZUtcTSiFeuC0ksCh9QIJ5+F21MvZ4Wn4ORfYaFJ/0dsiudv5tVkejgwZlwQ39jL9WWDe2lz8x0WglOA==} - - '@emnapi/core@2.0.0-alpha.3': - resolution: {integrity: sha512-AZypUeJ/yByuxyS7BlSNRDOMLMlROYtjYdIAuBmJssVz1UJDSeYxLrdizhXCFYhedC5bqd/ASy8EuNXbVVXp9g==} - - '@emnapi/runtime@1.11.2': - resolution: {integrity: sha512-kyOl3X0DuTiT1h2ft8r2fYO8JYtU9a9Xis/zBSiGArNaagCOWx90N1k2wxp18czFDH+OgcWGb5ZP/XMt3dcyPA==} - - '@emnapi/runtime@2.0.0-alpha.3': - resolution: {integrity: sha512-hFPAhMUjJD9BSyCANEISPOogeXC9Zo9ZQl7L6vKnaVsMkCtzznaW/naYypeyl0Gv5rYfWYsZbpixTMpjDJzQeA==} - - '@emnapi/wasi-threads@1.2.2': - resolution: {integrity: sha512-c95qOXkHdydNKhscBTebqEC1CVAZpyqOfVfBzQ1qgzyl3gfeldUjIggDbIZgDKsHLgnsM+igH7TJ/eAasaVuMA==} - - '@emnapi/wasi-threads@2.0.1': - resolution: {integrity: sha512-9DsSk+o5NBX0CCJT8s0EROGSGxjR/tKu6aBTaVyq+SjAEQH4XcdcRxPBRzsBLizTTJ49MJjF+jgu3qnO9GLQcQ==} - '@esbuild/aix-ppc64@0.28.1': resolution: {integrity: sha512-Svl7tq8k/08+p6CXPpRjQ1fKX+1odH/BQbb48fV6fj3CWHhsoIOoY87w1oHXm0qEpkIK3ZfVgp0hed3XBXzXMQ==} engines: {node: '>=18'} @@ -2645,13 +2627,6 @@ packages: resolution: {integrity: sha512-xJIPs+bYuc9ASBl+cvGsKbGrJmS6fAKaSZCnT0lhahT5rhA2VVy9/EcIgd2JhtEuFOJNx7UHNn/qiTPTY4nrQw==} engines: {node: '>= 10'} - '@napi-rs/wasm-runtime@1.2.2': - resolution: {integrity: sha512-JfB4kuJQjaoHuCTseIINHtHWeJnvgEcxjwA5t/Y00ZgaOO1Crz3fjT/p8kT28zA/Caz7oiUMn3d6H2yOVCVwuw==} - engines: {node: ^20.19.0 || ^22.13.0 || >=23.5.0} - peerDependencies: - '@emnapi/core': ^1.7.1 || ^2.0.0-alpha.3 - '@emnapi/runtime': ^1.7.1 || ^2.0.0-alpha.3 - '@noble/hashes@1.4.0': resolution: {integrity: sha512-V1JJ1WTRUqHHrOSh597hURcMqVKVGL/ea3kv0gSnEdsEZ0/+VyPghM1lMNGc00z7CIQorSvbKpuJkxvuHbvdbg==} engines: {node: '>= 16'} @@ -2798,129 +2773,124 @@ packages: resolution: {integrity: sha512-eSYWTm620tTk45EKSedaUL8MFYI8hW164hIXsgIHyxu3VobUB3fFCu5t0hQby6OoWRPsG1KkKUG2M5UadiLiVg==} engines: {node: '>=14'} - '@oxc-parser/binding-android-arm-eabi@0.142.0': - resolution: {integrity: sha512-ZiRGDutGsv1G6bL/ozy/koC0Sv39T1DqyoC4KD1DOy9ZoACm1O5UWhEK2c02Qdk+4lfLVkvFa/mQ0fm/4h1BtQ==} + '@oxc-parser/binding-android-arm-eabi@0.143.0': + resolution: {integrity: sha512-n9uozULWflPqBtdmI8lAabLqGKNgLVNN0ZH8HfgCwpKGNtzRzauB76jTiW/3YLkcA7N1zskpi9GdVnZuu1SAvg==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm] os: [android] - '@oxc-parser/binding-android-arm64@0.142.0': - resolution: {integrity: sha512-WZkvGRLNQTz8lR9zP5nLjUdlroRCopBu3g9zF1p/laE6DzT1UbQo8Rdz5MWhaJUPYg/6gp+jo7HUgsyKaN1FtQ==} + '@oxc-parser/binding-android-arm64@0.143.0': + resolution: {integrity: sha512-9BbdjHETk6O3zH/DDid9IgBtF0GlpLabNKN231uraXpRDSfY+iiZxTP5bk1Z63GBownVdhdINFIeddmMz4MzpQ==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [android] - '@oxc-parser/binding-darwin-arm64@0.142.0': - resolution: {integrity: sha512-l4khS8LQOOVYsGRVARo1gSaCT/aBSceUVXgtovWc2+drnxVuDr082WA3OCHVdVzIz5JIrP/y9CWsSKxBDNmYGg==} + '@oxc-parser/binding-darwin-arm64@0.143.0': + resolution: {integrity: sha512-gh+6ecoHUy4/sUcolBl/1qPXKBbYNxFY0Pk0ujgQvINTMSftJY7o4yb8gOkDJPeZeB8+a+u7xTe6umoP8N5HFA==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [darwin] - '@oxc-parser/binding-darwin-x64@0.142.0': - resolution: {integrity: sha512-QBsNF3nqlXmcH2B1YOPqQYmCJoy4HuIjUxGbBO/k5JAJUl68ghU2psRY2zPk+RyBaWqKP/qfL4oaFgEMCdwskA==} + '@oxc-parser/binding-darwin-x64@0.143.0': + resolution: {integrity: sha512-qd1hl2d+lXgHv/VQ/M9qm8TrMC5T4RqDBwtOnl+1D0QMjwcz+8AaB4JSg8STgeag0GP6a6L74XEGAsrTSJWNzQ==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [darwin] - '@oxc-parser/binding-freebsd-x64@0.142.0': - resolution: {integrity: sha512-b7Q7m4Cqc6XqNhri3R+QhU+GVy646Pn+bkdhrDdWym/Fdi0ZUa+d73H9dm5H91JtbtAQ/z1d8XKMW3oOV8a4tQ==} + '@oxc-parser/binding-freebsd-x64@0.143.0': + resolution: {integrity: sha512-M5XXcNa7aOqLPKTR41msfghKu2yQ4xWvCm11/gwU0JzOzHNk5sgW//rVEjJ+LO48+VDAMzXTSzurUVxIDKwozw==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [freebsd] - '@oxc-parser/binding-linux-arm-gnueabihf@0.142.0': - resolution: {integrity: sha512-3riVS5IhdH3uCZj1Y9ftDQlR0dvLsIlw/edrRqk8JhgNd5K0XSs+UBtgh50N13CAlW9/TXj6sVGXaKNBocd0Yg==} + '@oxc-parser/binding-linux-arm-gnueabihf@0.143.0': + resolution: {integrity: sha512-T/GXusuOkPNQhCQCSBbcU/N8j0rAypuDBl1IyFK+lyYT594XsVz80clPC/OtbSSpBGyJxj8uYEfctxVuxVYoww==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm] os: [linux] - '@oxc-parser/binding-linux-arm-musleabihf@0.142.0': - resolution: {integrity: sha512-NmXUOpgpTSkhl795TiXmWppTwmSJ92RC1qvD6e4XOF+slgmo3e6Ah+kEu+6AN8s7NAOEwqGmir58MgSQSWmBSA==} + '@oxc-parser/binding-linux-arm-musleabihf@0.143.0': + resolution: {integrity: sha512-oKu4RcBlXSqo3OC62dp6YTnQaZIurNDpCX3BnAM3+bJxt7s8J2TJKMnC0UYer1qhlRaDCg6wkTaTw+2IlsZ12w==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm] os: [linux] - '@oxc-parser/binding-linux-arm64-gnu@0.142.0': - resolution: {integrity: sha512-gc0EXsKtXgerujmU2Bql3u1L1HsSQ2774R83idq/FoNMPVV/RY/1ErFsvnit7KoiP/sLvzQixeUo4Ut0ic0wmw==} + '@oxc-parser/binding-linux-arm64-gnu@0.143.0': + resolution: {integrity: sha512-WJBbD186AZmMGaSIhlktC+rPl8L3peCTXAh88Ih9uEvK0en2mPojGyCGYiL6mHtV1RPV3JyfJW5t6n5hh0lXhA==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [linux] libc: [glibc] - '@oxc-parser/binding-linux-arm64-musl@0.142.0': - resolution: {integrity: sha512-F2XvmWSE0uWpie+jHKKIFgdVOe9ypGhkEZxKx5DuW215K6cbAC274yYaPkcM7EqY4Df3Weyhpcz3lsURyH2LVg==} + '@oxc-parser/binding-linux-arm64-musl@0.143.0': + resolution: {integrity: sha512-t1AcYOwEzgceadT4v5e+vaCCb0AncCA3v5AyzfBAz/tMq11qzVccXKzNHtkWdjBsgvTKwRkaUF3QvT4kot8vcQ==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [linux] libc: [musl] - '@oxc-parser/binding-linux-ppc64-gnu@0.142.0': - resolution: {integrity: sha512-wLMbT21U/QxknQsk+VvNF0b9D2/aGWhcaQQQ+VYlE8FwD5+GoWZIPPXNzyHmkYyhm0KB3itL+TBavjMatqNnYA==} + '@oxc-parser/binding-linux-ppc64-gnu@0.143.0': + resolution: {integrity: sha512-RsnO/NoD8376LMJq8JS8TwI0ieNaFRTuNe2GVJntQg6gwZNMENZsEbknHdVwjpOmxdGLGodcwaGSbAeRr5Bgjw==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [ppc64] os: [linux] libc: [glibc] - '@oxc-parser/binding-linux-riscv64-gnu@0.142.0': - resolution: {integrity: sha512-+G8F/4ckwT7FCJV4H2bt09xEzJbjNCfuL4Sp1AYNaFtFMVtgIGMuJlteT82U+K0UIZ/DzAR/LDlMFnEuajG7Kw==} + '@oxc-parser/binding-linux-riscv64-gnu@0.143.0': + resolution: {integrity: sha512-48fSVfR9TZi5CASZFyv0VC6z6BCoeihFsX031mAD/oSH7d9PYsPgIqza7d9mjP7Z2KTEpTFyH6SIu0Ui6R1vdg==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [riscv64] os: [linux] libc: [glibc] - '@oxc-parser/binding-linux-riscv64-musl@0.142.0': - resolution: {integrity: sha512-hTsHtTLxMAfCo+rpF5K3qZJKW2NpPN/CHd4mYB3y7XlSdspHkd2gehDIofP64AacA9nWQw2tY3O7wR6UY8IVOA==} + '@oxc-parser/binding-linux-riscv64-musl@0.143.0': + resolution: {integrity: sha512-T8CpdD+SfE01DnIOD4HpVxu0ZJOfMJ/VhCvikKfaXAxkZ+9veyLM/D2hpi7Y2hFUyPmVQO3FNZHmYzV/WlVR4g==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [riscv64] os: [linux] libc: [musl] - '@oxc-parser/binding-linux-s390x-gnu@0.142.0': - resolution: {integrity: sha512-6y7qYY3TCUDYjqswImdTGl92y+KA/80twALegQPN27kfY+bG7Ib1+L3jbmrCZQx6wrVnai9IPsEZp07I0hx7JQ==} + '@oxc-parser/binding-linux-s390x-gnu@0.143.0': + resolution: {integrity: sha512-QLdeMsCcacenPEFsfxnBUDF1y6opyz5+fmOz9bfD5Y7fiGCMupUCuB3KTPQhNwshIG1P9fPqar9MHxuBDd4bwQ==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [s390x] os: [linux] libc: [glibc] - '@oxc-parser/binding-linux-x64-gnu@0.142.0': - resolution: {integrity: sha512-i69kAWU+2LgoH5bR+zWiiu+UzAw7Oxkwv7COeJTeY19pn4e70nKQcr9Pm6cL2Z0Z54d+gl9qADlK/0yyuCPiBA==} + '@oxc-parser/binding-linux-x64-gnu@0.143.0': + resolution: {integrity: sha512-659ujfqLy6k7cuH3sbzhd8b+ztSq+i6E2E9pG78Q0BmHjAExfGIdgc8cGgMdwAozDXeZFHkJ+LXYJdWsaGdgyw==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [linux] libc: [glibc] - '@oxc-parser/binding-linux-x64-musl@0.142.0': - resolution: {integrity: sha512-4SQs678MmjYVrmhAgCWD4o0vpaFszXw9xLX5p2Z9MMFcltxiLkA88wQjh80YHjPrXtpyZ2CWI5m+1yNKM0m2Pw==} + '@oxc-parser/binding-linux-x64-musl@0.143.0': + resolution: {integrity: sha512-/Mw/9j4TfZcnKphPrzOE6t4MMknXadcAAuVUlDRTF/ETWB5xOgQvOJV2Mh9We/bWxZdoxaGAdc+hy4GuYwQ2yQ==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [linux] libc: [musl] - '@oxc-parser/binding-openharmony-arm64@0.142.0': - resolution: {integrity: sha512-YHpx9N7Ln3a++Tc8rv+H7mrK1zyJQOAwCFg8LZ3lTs1T5afGWeZrLPhPT9HLnIwSjCyJqPWVMIrMxbjcmBr2oQ==} + '@oxc-parser/binding-openharmony-arm64@0.143.0': + resolution: {integrity: sha512-8rIKWR2BFuifbIK/1XB9wTaSdtuJ25dlE7ZQYDnEwj/2xH2vHsxnvIjHT3ZjSVuLLwGGlSslIG/fbOJ8TV8rTw==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [openharmony] - '@oxc-parser/binding-wasm32-wasi@0.142.0': - resolution: {integrity: sha512-3pLDyY3+oogW73RM5uehNgAiR/Xfb7fvO2Q1Z1gIqZ2+50XDVQmBVlRkHXZTU4gKnQHpwETNsYQVsJ3joVB2iA==} - engines: {node: ^20.19.0 || >=22.12.0} - cpu: [wasm32] - - '@oxc-parser/binding-win32-arm64-msvc@0.142.0': - resolution: {integrity: sha512-Had/VeVY28Oyb0K+Q4FV8KCzoBycIh93oDK6pCbya9lkzdq+ikMHMgBubsdqqlybjJmQRawCQRrnBRHyQwYvcQ==} + '@oxc-parser/binding-win32-arm64-msvc@0.143.0': + resolution: {integrity: sha512-5U9kQYMfRRI6Zq7KDxgbIP0RMnKrfn3gLepRMgJuRkPSUALTiRCk9d/uyhb4lGDjUdzwK7mBkKqhLgzBPCmLpQ==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [win32] - '@oxc-parser/binding-win32-ia32-msvc@0.142.0': - resolution: {integrity: sha512-GGi3+YphVHavvgs6gum2UXoNCqzHAmPt/nXkn8ZQZstV2Q1qZD1Mn8fz/nWrDkefHQtrG/+1/XrbMxsBTo6Svw==} + '@oxc-parser/binding-win32-ia32-msvc@0.143.0': + resolution: {integrity: sha512-25P7AaHk4R88Yv2XH4gToDVmh0cOu+bEURQU10CRrmvgabfRArSGAP5osmwUKeSUHj0VS50upbpbRWWW/m7mHA==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [ia32] os: [win32] - '@oxc-parser/binding-win32-x64-msvc@0.142.0': - resolution: {integrity: sha512-Ny/Wv4Us1LGC/ljwNTp+Hx3r/pH15EFfeDF0p+n898gt+TtRd6C9SccHcuUhDiNTb8s5tt7jdeAMDRQZ4Vq6hg==} + '@oxc-parser/binding-win32-x64-msvc@0.143.0': + resolution: {integrity: sha512-ORMh3JE1s6V7ySicdRK7vgaDQnn5o+UHg9ct989PlWHbel8O9ARrmWXM6kZjrBMtNucxNayQ8g69G0VfWzhANw==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [win32] @@ -2928,6 +2898,9 @@ packages: '@oxc-project/types@0.142.0': resolution: {integrity: sha512-7W+2q5AKQVU36fkaryontrHn3YDt1RyUYXatw9i5H8ocYe2sPKSFB6eS8WNPeRKiN1qAWWZUPm7gwFzJGrccqQ==} + '@oxc-project/types@0.143.0': + resolution: {integrity: sha512-u6JZdLBTLotrNC9Vd6vPssINdzcCzleKAH6EJKImQb7GtYvX5keN2dxkoK44stCc4tffE6QQRtZTXVSzsLUlWA==} + '@parcel/watcher-android-arm64@2.6.0': resolution: {integrity: sha512-trgpLSCKRC/huFjXX/Smh+0sWe4+YtKfktIToiMl59ghz7z+qkH6kMvNnUbLyRs9N11t8l4svSCs1+5B3rOAhA==} engines: {node: '>= 10.0.0'} @@ -3101,8 +3074,8 @@ packages: '@protobufjs/utf8@1.1.2': resolution: {integrity: sha512-b1UQwcEZ4yCnMCD8DAL1VlbvBJE9/IX4FTIp7BG1xYpf29SLazLSrqUkj4w7Y5y7cCVP6E5tcqqcI0xemPkHug==} - '@puppeteer/browsers@3.0.6': - resolution: {integrity: sha512-B/gKoqlFkzhvzsI6jo9K1cZz9o5ypviVv/xu8CwA4grZzyVwN+XfkT+tu8T1zrauuEXv6VhS2oGX+6NL95WcKA==} + '@puppeteer/browsers@3.1.0': + resolution: {integrity: sha512-RDLpio3fH/qrj5k4DVY6eyiN8tCS0Zovd/6jW//n605oeqkWcUjn+3k+9ZtZBnbwMpsu0F7xDIiKXvVmG5c5Bw==} engines: {node: '>=22.12.0'} hasBin: true peerDependencies: @@ -3114,96 +3087,92 @@ packages: yauzl: optional: true - '@rolldown/binding-android-arm64@1.2.1': - resolution: {integrity: sha512-02hOeOSryYxVrOIphmLAsqnCJWxwlzFk+pEt/N/i6OgT3lShHO7xGCU5cpgchRDHboAEbSjzgGh+O/u1GswQmA==} + '@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-darwin-arm64@1.2.1': - resolution: {integrity: sha512-fMsTOnN0OjFm3CyppWPitKnc8UlliVARUULW6cfU6AIqjdtgmSFWSk9vecHzZduv/yMWIHDlRhM1e8Iff9uAfA==} + '@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-x64@1.2.1': - resolution: {integrity: sha512-1wjKdz/XLGKHaTNHjQveQ/B23TKx4ItAqm1JbyVuvNPc4Ze0Fb48s49TAd/2zcplPl8okE/UbTgmlVfwT7eFeQ==} + '@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-freebsd-x64@1.2.1': - resolution: {integrity: sha512-Fa0jHR07E7YBN4vOEsbVf2briYNsuOowfLJaXULZM0ldMlaCaj2LJgLMbMe4iacRyZmvR8efFhgR9wKuGclQUg==} + '@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-linux-arm-gnueabihf@1.2.1': - resolution: {integrity: sha512-pzkgu1SSHGgRRyRZ4fbmSgmajbVt+epaLP99NDjFft69v/ypfTi6swBMiVdh2EkQ0OSnHE1lZDM7DRGkyAzUpA==} + '@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-arm64-gnu@1.2.1': - resolution: {integrity: sha512-QI5SEDY8cbiYWHx0VO4vIc3UlS6a32vXHjU8Qy/17adEmZIPuByJg13UEvo9c/UCiUkdcVWY83C+b+JrwnNyUg==} + '@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-musl@1.2.1': - resolution: {integrity: sha512-Sm41FyCeXqmYcERoYOCbGIL5hNfd8w9LQ7Y61Bev48HkcjaJqV/iiVOaiDxjVTRMS+QKrZmD8cfPt4uMVnvM+A==} + '@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-ppc64-gnu@1.2.1': - resolution: {integrity: sha512-2x+WhXTGl9yJYPbltW/BSEPTVz9OIWQyER4N+gJEDWkkn904eRcBzELqh/Hf7K0w/ubGbKNMv0ZC+94QK/IFEg==} + '@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-s390x-gnu@1.2.1': - resolution: {integrity: sha512-eEjmQpuRQayHPWWnywaWHkFT3ToPbP3RYy42VVd/B9aBGDA+Ol25EIWHxKQST3IiWJjikCWUF7KtbfqwZrzVwQ==} + '@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-x64-gnu@1.2.1': - resolution: {integrity: sha512-/Orga1fZYkLc/56jBICcHrKchl8Z2UKdDSr3LG9ToWO1lQ6a4Livk9Xz+9WN91zsz5QR3XQz2NNoSDEvP6qadw==} + '@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-musl@1.2.1': - resolution: {integrity: sha512-xxBJRL+0q0Kce7orznGWLuylHDY65vuARXZRpX+hPdv+DqK2c3NlCsVA98tlWzWNEE7yPqA/1NQ5nnCrj49Y5A==} + '@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-openharmony-arm64@1.2.1': - resolution: {integrity: sha512-M6AdXIXw3s+/8XpKMzdGDEXGS1S7kwUsy+rcTIUIOx5Ge4nXKCtAFHFV9YKkXvGcC5WMoTjAteLzlsQROVI0Yw==} + '@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-wasm32-wasi@1.2.1': - resolution: {integrity: sha512-/TX0SoRGojHzSAHpfVBbavRVSazg5U3h3Y3VXfcc0cdugq6kxdqw8LPGFiPr+/7gE/60zRcsOY2Vi9b9eT0jww==} - engines: {node: ^20.19.0 || ^22.13.0 || >=23.5.0} - - '@rolldown/binding-win32-arm64-msvc@1.2.1': - resolution: {integrity: sha512-EvRrivJieyHG+AO9lleZWgq+g0+S7oV2C51yuqlcyU/R9net+sI4Pj0F+lUoP2bEr6TWX3SqFaaS0SzfLxSzkw==} + '@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-x64-msvc@1.2.1': - resolution: {integrity: sha512-Z4eCmn5QJ/5+azF9knpLWKfVd9aidn0mAe9TpJgvBLId9Ax3t0+JVxBmT25Bv7NBbVW1TZyKjQjQReouMeH5UQ==} + '@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] @@ -3434,9 +3403,6 @@ packages: peerDependencies: eslint: '>=7.7.0' - '@tybys/wasm-util@0.10.3': - resolution: {integrity: sha512-F3fo1MYrRJYL3zER0OUOmkutjr1Vp23m7OsSgp7nq4SP6OqX6C/56XFIPAl5bt3zaBRjmW7SGz3u/6LwFpYcOg==} - '@types/babel__core@7.20.5': resolution: {integrity: sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA==} @@ -3626,39 +3592,39 @@ packages: '@types/yarnpkg__lockfile@1.1.9': resolution: {integrity: sha512-GD4Fk15UoP5NLCNor51YdfL9MSdldKCqOC9EssrRw3HVfar9wUZ5y8Lfnp+qVD6hIinLr8ygklDYnmlnlQo12Q==} - '@typescript-eslint/eslint-plugin@8.65.0': - resolution: {integrity: sha512-IEgob78X12rHpUmtcwFsXhZdVGJtwTVP8FiCLZkR6GlYVrl2PcuB+KhCE5BlVC/eQpQnu8WXRtkHZuPar+gCRA==} + '@typescript-eslint/eslint-plugin@8.66.0': + resolution: {integrity: sha512-p088eaGrzYz1s+7cov0aMOCkNGTJlVxF4jgubf28c8L0Cv9Rloj8YBHnv4hXLq6IIEE1AsjNWavO+k+8kP2Y0A==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: - '@typescript-eslint/parser': ^8.65.0 + '@typescript-eslint/parser': ^8.66.0 eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 typescript: '>=4.8.4 <6.1.0' - '@typescript-eslint/parser@8.65.0': - resolution: {integrity: sha512-CZ4nMxWwgu1HEEFNkeaCptra9QCtkmKdgf3sWh1rl1trIhmxLilgTV4cwcbQ4wemnT4sWQN8CaKOmdYx+g2gMA==} + '@typescript-eslint/parser@8.66.0': + resolution: {integrity: sha512-X6ypGChaWYk6PBtUg2BwuTZEFFcHJAtGTVJ9/lCTOufhZ4i9fNolQNnktq+kkMCwMj7V8Svsq7+TxSDslmhE0g==} 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.65.0': - resolution: {integrity: sha512-SxnPhbTsGahizDgbu7oqFH/xVtzIqMd/s+WtnSxNxJZJpLbdT5IPdzg8EZxO3+PoKahXmwJLeNQOpKJb3/bi7Q==} + '@typescript-eslint/project-service@8.66.0': + resolution: {integrity: sha512-7MthGPTt4BP69lSryqpqq8HQqxuzynssckL/jyDyk3+TNMQ3y2jFWkptCrktWvBrP+EH787Nl5N5Qpw7WZg+5g==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: typescript: '>=4.8.4 <6.1.0' - '@typescript-eslint/scope-manager@8.65.0': - resolution: {integrity: sha512-Esbl8OSYiVxBokYgWPf7VVWg/BE798wXhimnn9ML9Pt5qoDf8bfQlgjlKXR/k98+AcNzlLKYrpCcrcuZ9DZLgg==} + '@typescript-eslint/scope-manager@8.66.0': + resolution: {integrity: sha512-8TGcH25j9zqJ/IULB/ppyhRvxA8QYfFEZ7nfbg6/BN9spDgb8fPWQXlE5l8TWBL50EtUx007uZ1o9VOwrq2/9g==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@typescript-eslint/tsconfig-utils@8.65.0': - resolution: {integrity: sha512-j6GzGqCiRdA7Qhur2VVmKZAkBLfnHFQfx4TaJGL9RMveZqCo48jSHHO0DTgizEnGhtWnqmbtCUSrqSkdiY/0Hg==} + '@typescript-eslint/tsconfig-utils@8.66.0': + resolution: {integrity: sha512-9D5gLYZG4rOjcoag8MQ/fWI8WqA9wcPDyOGyWtWFhvM1lHRbliqUSPIY5J3zqCU1tvSwzXxnnjhQhz5Ne7mJ4g==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: typescript: '>=4.8.4 <6.1.0' - '@typescript-eslint/type-utils@8.65.0': - resolution: {integrity: sha512-YjaZ7PRI5qY7ax2L3PbvX0rRyGtipAReCWs0mhhDBHjH/vl0g0BonaGXrKdKpMbIIsMIwDgbk/xzkBTyAltS5g==} + '@typescript-eslint/type-utils@8.66.0': + resolution: {integrity: sha512-LG2dWfjZQQp0ADtAu/EWJVayefGL2UEZ3CDeI44D9v3rXB/WYUqE/jpO28KrEKul5AySrmI+Zh1v6v+xW2U9+g==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 @@ -3668,21 +3634,25 @@ packages: resolution: {integrity: sha512-JSSwWNy+H0E/01jJEM+hrX6N0OFDzFzeIhHFSAS01tlVaevpG8cFyYRPhS5yjGOvBUx3sqQHVMjCL1CAZZMxBg==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@typescript-eslint/typescript-estree@8.65.0': - resolution: {integrity: sha512-JboAE2swaYt4tb1fHhHTABE2K+OLy09XfcTbhnk4Pw96f9dd2e9iYsJ28gBggHlo5z5x1rkyWvcPoTuNTd4oGg==} + '@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/typescript-estree@8.66.0': + resolution: {integrity: sha512-8/x4INiiQb10jGgXYD7116/zQ+OL84ZIFn0za68wwFHCanT/VLbBEroWht8RV8fn0/ZCAoazHLQgwUC0UQcDfg==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: typescript: '>=4.8.4 <6.1.0' - '@typescript-eslint/utils@8.65.0': - resolution: {integrity: sha512-gXiwIHsYreboxeJucHKPvgwl7dXt50mF8s1/c00cP/WoVTyWKFdtfhRWwZiXYFU5H2O8vVoSLNrexFZjYS/SGA==} + '@typescript-eslint/utils@8.66.0': + resolution: {integrity: sha512-jasearZPolBw5NJNYGMwxzHMF83niVWmMU1VdHzG1CyfI2VS7f7nZltnKtHcg20hW+7Uo5GfK4MeDPoU3qI8EA==} 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.65.0': - resolution: {integrity: sha512-8C71BQkGjiMmXtop7pHVJu1l2NNShFdkCyD6a2ezzs5vU/L3LRtb69EtcteFwz0mYMPzIgOw0n6OV4VBUWZd7A==} + '@typescript-eslint/visitor-keys@8.66.0': + resolution: {integrity: sha512-dkKR8q+lKciskj1Y3vthHktl+3cMLWGyVUP23bRiPZ5O9BRT++4EqDDV+TVeIKBL1VXVEqrJlz8MYbcnvJcAlg==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} '@verdaccio/auth@8.1.1': @@ -6744,8 +6714,8 @@ packages: resolution: {integrity: sha512-19YVAg7T+WTrxggPukVq7DjTv6+PJ867TmhCvBsYwmbFCsZd344rq2Ld1p0wo8f8Qrrhgp82c6FJRqdXWtSEhg==} engines: {node: '>= 0.4'} - oxc-parser@0.142.0: - resolution: {integrity: sha512-kKR+jPiRJYJDexVoziIg/FVGvr1fT1FZSSJOk6tVoMKKSlsf1Cso+cgGCJkOEDWOP174vRntCPFKg+AS7InWvw==} + oxc-parser@0.143.0: + resolution: {integrity: sha512-ov0NzaDCOInknS7mP1cwKdJERt3utPW8ldjtdUXQ8Ty0GEFD08wk422vCUN0d7pST6kqtV7dxoI9w1Zi0l/9TA==} engines: {node: ^20.19.0 || >=22.12.0} p-finally@1.0.0: @@ -7035,12 +7005,12 @@ packages: resolution: {integrity: sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==} engines: {node: '>=6'} - puppeteer-core@25.4.0: - resolution: {integrity: sha512-K1plkLOdeoUnGeT1OvdqF3qxl33v+Ra/uH5VyPEhXdMcpvGiEskHzxxEU3fgpccJpJLIipB/rPUsvkZRWeKqOA==} + puppeteer-core@25.5.0: + resolution: {integrity: sha512-XPNT0dQJtphqQ4I29zxlG4IIPbg1iEHAQKWuQgtMJGXjACV77pZSmJvDi51IIIfd+DTKICcopJwUx4upVQ4XbA==} engines: {node: '>=22.12.0'} - puppeteer@25.4.0: - resolution: {integrity: sha512-xfQp8dFBcGaLc1hEMaVr7s+oW4ZkAurr8Y9H81ilKhu6QoLfSTkZjU7IavnyJ/VWpB9ni3KNJUQHUatslLWyGw==} + puppeteer@25.5.0: + resolution: {integrity: sha512-qpp73xblxNr+bF0nSXTodM3v+zcK5IPo/GkjLsdUqRf/qpLJp/1KxBUbstoMMnwnPw9xD6OMei8kmYf6CLWfGw==} engines: {node: '>=22.12.0'} hasBin: true @@ -7241,8 +7211,8 @@ packages: vue-tsc: optional: true - rolldown@1.2.1: - resolution: {integrity: sha512-4FKJhg8d3OiyQOA6Q1Q0hoFFpW9/OoX+VsHzpECsdsIZoOArrAK90gl59YK/Z+gnDel45bgJZK03ozH/9bCqEw==} + rolldown@1.2.2: + resolution: {integrity: sha512-opwpo1tQBAcpSUJDt94B7hhLNGOKjCdE//XXjeLrnx9b83bjnw45tXdg1b09yEw/VLFBJGZpwRULMmOZo7ol+A==} engines: {node: ^20.19.0 || >=22.12.0} hasBin: true @@ -7250,12 +7220,16 @@ packages: resolution: {integrity: sha512-66iiym49fU6YDJW4DPEYbmUwm4emHXP048lJM9YkecADYGO4cKf0gQZ13U/IqRN00DXbKz0g7O3yOt8m4BNFew==} engines: {node: '>=18.0.0'} - rollup-plugin-dts@6.4.1: - resolution: {integrity: sha512-l//F3Zf7ID5GoOfLfD8kroBjQKEKpy1qfhtAdnpibFZMffPaylrg1CoDC2vGkPeTeyxUe4bVFCln2EFuL7IGGg==} + rollup-plugin-dts@6.5.1: + resolution: {integrity: sha512-jODTXp3H7MK/Ur/ErtsrQ0G1GvaCmc3du+y5pNrdBMf6d7HlL2Nd/N6TkEr+f75CkUj01zEoEd7y2elH0eHi1Q==} engines: {node: '>=20'} peerDependencies: - rollup: ^3.29.4 || ^4 - typescript: ^4.5 || ^5.0 || ^6.0 + '@typescript/typescript6': ^6 + rollup: ^3 || ^4 + typescript: ^4.5 || ^5 || ^6 || ^7 + peerDependenciesMeta: + '@typescript/typescript6': + optional: true rollup-plugin-sourcemaps2@0.5.8: resolution: {integrity: sha512-c5BfiVbKAmaz+RoEhFF44Tg/X2QoLxEB8F7wS/eNWDJF/NKxi0SF7srN3Dg0RUnIcYLyCOwscket5Mr3BImMbg==} @@ -7676,8 +7650,8 @@ packages: teex@1.0.1: resolution: {integrity: sha512-eYE6iEI62Ni1H8oIa7KlDU6uQBtqr4Eajni3wX7rpfXD8ysFx8z0+dri+KWEPWpBsxXfxu58x/0jvTVT1ekOSg==} - terser@5.49.0: - resolution: {integrity: sha512-SNiDnXyHSrxVcIOtVbULzcTmniUiwcV7Nwdyj1twVubeTmbjoa8p69KKDpfkdoOavuM4/GRm1+ykI8qqnavHoA==} + terser@5.49.1: + resolution: {integrity: sha512-7A2xlQ5EnGT8KPA92dUh6RbRYTVw8hEaEN9L1K68l4UOXFuV511NnAqObGoRqGOQofQcMypisu1s3xawCEHrvA==} engines: {node: '>=10'} hasBin: true @@ -7891,8 +7865,8 @@ packages: resolution: {integrity: sha512-LIY910g9TI13YS95lrMFrs8Rm/u/irgHeTWoKCoteeJ04CUJ92eEfj0rVn+7VKMPBpUPiUoBKfhNyLI23EE/KA==} engines: {node: '>=18.17'} - undici@8.9.0: - resolution: {integrity: sha512-aWZpUj7XoGonMClx4gdDRfgBjqeA+F473aDmROQQbM9n6PRfK/u1q/a0X4wMTgcHfT8H6fpbt98PFuDUwFg2YA==} + undici@8.10.0: + resolution: {integrity: sha512-HvltHd7avK13QIw/oLe4qoOLyoVSoafqJ2jYOrtMRBkbYT31eiBQ8O0ehRKZiEZCMEyLFQNIADpgCWC5fALvYQ==} engines: {node: '>=22.19.0'} unenv@1.10.0: @@ -9291,38 +9265,6 @@ snapshots: '@discoveryjs/json-ext@1.1.0': {} - '@emnapi/core@1.11.2': - dependencies: - '@emnapi/wasi-threads': 1.2.2 - tslib: 2.8.1 - optional: true - - '@emnapi/core@2.0.0-alpha.3': - dependencies: - '@emnapi/wasi-threads': 2.0.1 - tslib: 2.8.1 - optional: true - - '@emnapi/runtime@1.11.2': - dependencies: - tslib: 2.8.1 - optional: true - - '@emnapi/runtime@2.0.0-alpha.3': - dependencies: - tslib: 2.8.1 - optional: true - - '@emnapi/wasi-threads@1.2.2': - dependencies: - tslib: 2.8.1 - optional: true - - '@emnapi/wasi-threads@2.0.1': - dependencies: - tslib: 2.8.1 - optional: true - '@esbuild/aix-ppc64@0.28.1': optional: true @@ -10438,20 +10380,6 @@ snapshots: '@napi-rs/nice-win32-x64-msvc': 1.1.1 optional: true - '@napi-rs/wasm-runtime@1.2.2(@emnapi/core@1.11.2)(@emnapi/runtime@1.11.2)': - dependencies: - '@emnapi/core': 1.11.2 - '@emnapi/runtime': 1.11.2 - '@tybys/wasm-util': 0.10.3 - optional: true - - '@napi-rs/wasm-runtime@1.2.2(@emnapi/core@2.0.0-alpha.3)(@emnapi/runtime@2.0.0-alpha.3)': - dependencies: - '@emnapi/core': 2.0.0-alpha.3 - '@emnapi/runtime': 2.0.0-alpha.3 - '@tybys/wasm-util': 0.10.3 - optional: true - '@noble/hashes@1.4.0': {} '@nodelib/fs.scandir@2.1.5': @@ -10619,72 +10547,67 @@ snapshots: '@opentelemetry/semantic-conventions@1.43.0': {} - '@oxc-parser/binding-android-arm-eabi@0.142.0': - optional: true - - '@oxc-parser/binding-android-arm64@0.142.0': + '@oxc-parser/binding-android-arm-eabi@0.143.0': optional: true - '@oxc-parser/binding-darwin-arm64@0.142.0': + '@oxc-parser/binding-android-arm64@0.143.0': optional: true - '@oxc-parser/binding-darwin-x64@0.142.0': + '@oxc-parser/binding-darwin-arm64@0.143.0': optional: true - '@oxc-parser/binding-freebsd-x64@0.142.0': + '@oxc-parser/binding-darwin-x64@0.143.0': optional: true - '@oxc-parser/binding-linux-arm-gnueabihf@0.142.0': + '@oxc-parser/binding-freebsd-x64@0.143.0': optional: true - '@oxc-parser/binding-linux-arm-musleabihf@0.142.0': + '@oxc-parser/binding-linux-arm-gnueabihf@0.143.0': optional: true - '@oxc-parser/binding-linux-arm64-gnu@0.142.0': + '@oxc-parser/binding-linux-arm-musleabihf@0.143.0': optional: true - '@oxc-parser/binding-linux-arm64-musl@0.142.0': + '@oxc-parser/binding-linux-arm64-gnu@0.143.0': optional: true - '@oxc-parser/binding-linux-ppc64-gnu@0.142.0': + '@oxc-parser/binding-linux-arm64-musl@0.143.0': optional: true - '@oxc-parser/binding-linux-riscv64-gnu@0.142.0': + '@oxc-parser/binding-linux-ppc64-gnu@0.143.0': optional: true - '@oxc-parser/binding-linux-riscv64-musl@0.142.0': + '@oxc-parser/binding-linux-riscv64-gnu@0.143.0': optional: true - '@oxc-parser/binding-linux-s390x-gnu@0.142.0': + '@oxc-parser/binding-linux-riscv64-musl@0.143.0': optional: true - '@oxc-parser/binding-linux-x64-gnu@0.142.0': + '@oxc-parser/binding-linux-s390x-gnu@0.143.0': optional: true - '@oxc-parser/binding-linux-x64-musl@0.142.0': + '@oxc-parser/binding-linux-x64-gnu@0.143.0': optional: true - '@oxc-parser/binding-openharmony-arm64@0.142.0': + '@oxc-parser/binding-linux-x64-musl@0.143.0': optional: true - '@oxc-parser/binding-wasm32-wasi@0.142.0': - dependencies: - '@emnapi/core': 1.11.2 - '@emnapi/runtime': 1.11.2 - '@napi-rs/wasm-runtime': 1.2.2(@emnapi/core@1.11.2)(@emnapi/runtime@1.11.2) + '@oxc-parser/binding-openharmony-arm64@0.143.0': optional: true - '@oxc-parser/binding-win32-arm64-msvc@0.142.0': + '@oxc-parser/binding-win32-arm64-msvc@0.143.0': optional: true - '@oxc-parser/binding-win32-ia32-msvc@0.142.0': + '@oxc-parser/binding-win32-ia32-msvc@0.143.0': optional: true - '@oxc-parser/binding-win32-x64-msvc@0.142.0': + '@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': optional: true @@ -10881,58 +10804,51 @@ snapshots: '@protobufjs/utf8@1.1.2': {} - '@puppeteer/browsers@3.0.6': + '@puppeteer/browsers@3.1.0': dependencies: modern-tar: 0.7.7 yargs: 18.1.0 - '@rolldown/binding-android-arm64@1.2.1': - optional: true - - '@rolldown/binding-darwin-arm64@1.2.1': + '@rolldown/binding-android-arm64@1.2.2': optional: true - '@rolldown/binding-darwin-x64@1.2.1': + '@rolldown/binding-darwin-arm64@1.2.2': optional: true - '@rolldown/binding-freebsd-x64@1.2.1': + '@rolldown/binding-darwin-x64@1.2.2': optional: true - '@rolldown/binding-linux-arm-gnueabihf@1.2.1': + '@rolldown/binding-freebsd-x64@1.2.2': optional: true - '@rolldown/binding-linux-arm64-gnu@1.2.1': + '@rolldown/binding-linux-arm-gnueabihf@1.2.2': optional: true - '@rolldown/binding-linux-arm64-musl@1.2.1': + '@rolldown/binding-linux-arm64-gnu@1.2.2': optional: true - '@rolldown/binding-linux-ppc64-gnu@1.2.1': + '@rolldown/binding-linux-arm64-musl@1.2.2': optional: true - '@rolldown/binding-linux-s390x-gnu@1.2.1': + '@rolldown/binding-linux-ppc64-gnu@1.2.2': optional: true - '@rolldown/binding-linux-x64-gnu@1.2.1': + '@rolldown/binding-linux-s390x-gnu@1.2.2': optional: true - '@rolldown/binding-linux-x64-musl@1.2.1': + '@rolldown/binding-linux-x64-gnu@1.2.2': optional: true - '@rolldown/binding-openharmony-arm64@1.2.1': + '@rolldown/binding-linux-x64-musl@1.2.2': optional: true - '@rolldown/binding-wasm32-wasi@1.2.1': - dependencies: - '@emnapi/core': 2.0.0-alpha.3 - '@emnapi/runtime': 2.0.0-alpha.3 - '@napi-rs/wasm-runtime': 1.2.2(@emnapi/core@2.0.0-alpha.3)(@emnapi/runtime@2.0.0-alpha.3) + '@rolldown/binding-openharmony-arm64@1.2.2': optional: true - '@rolldown/binding-win32-arm64-msvc@1.2.1': + '@rolldown/binding-win32-arm64-msvc@1.2.2': optional: true - '@rolldown/binding-win32-x64-msvc@1.2.1': + '@rolldown/binding-win32-x64-msvc@1.2.2': optional: true '@rolldown/pluginutils@1.0.1': {} @@ -11089,11 +11005,6 @@ snapshots: dependencies: eslint: 10.8.0(jiti@2.7.0)(supports-color@11.0.0) - '@tybys/wasm-util@0.10.3': - dependencies: - tslib: 2.8.1 - optional: true - '@types/babel__core@7.20.5': dependencies: '@babel/parser': 7.29.8 @@ -11324,14 +11235,14 @@ snapshots: '@types/yarnpkg__lockfile@1.1.9': {} - '@typescript-eslint/eslint-plugin@8.65.0(@typescript-eslint/parser@8.65.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.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)': dependencies: '@eslint-community/regexpp': 4.12.2 - '@typescript-eslint/parser': 8.65.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/scope-manager': 8.65.0 - '@typescript-eslint/type-utils': 8.65.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.65.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/visitor-keys': 8.65.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) + '@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/visitor-keys': 8.66.0 eslint: 10.8.0(jiti@2.7.0)(supports-color@11.0.0) ignore: 7.0.6 natural-compare: 1.4.0 @@ -11340,41 +11251,41 @@ snapshots: transitivePeerDependencies: - supports-color - '@typescript-eslint/parser@8.65.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.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.65.0 - '@typescript-eslint/types': 8.65.0 - '@typescript-eslint/typescript-estree': 8.65.0(supports-color@11.0.0)(typescript@6.0.3) - '@typescript-eslint/visitor-keys': 8.65.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/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) typescript: 6.0.3 transitivePeerDependencies: - supports-color - '@typescript-eslint/project-service@8.65.0(supports-color@11.0.0)(typescript@6.0.3)': + '@typescript-eslint/project-service@8.66.0(supports-color@11.0.0)(typescript@6.0.3)': dependencies: - '@typescript-eslint/tsconfig-utils': 8.65.0(typescript@6.0.3) - '@typescript-eslint/types': 8.65.0 + '@typescript-eslint/tsconfig-utils': 8.66.0(typescript@6.0.3) + '@typescript-eslint/types': 8.66.0 debug: 4.4.3(supports-color@11.0.0) typescript: 6.0.3 transitivePeerDependencies: - supports-color - '@typescript-eslint/scope-manager@8.65.0': + '@typescript-eslint/scope-manager@8.66.0': dependencies: - '@typescript-eslint/types': 8.65.0 - '@typescript-eslint/visitor-keys': 8.65.0 + '@typescript-eslint/types': 8.66.0 + '@typescript-eslint/visitor-keys': 8.66.0 - '@typescript-eslint/tsconfig-utils@8.65.0(typescript@6.0.3)': + '@typescript-eslint/tsconfig-utils@8.66.0(typescript@6.0.3)': dependencies: typescript: 6.0.3 - '@typescript-eslint/type-utils@8.65.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.0(jiti@2.7.0)(supports-color@11.0.0))(supports-color@11.0.0)(typescript@6.0.3)': dependencies: - '@typescript-eslint/types': 8.65.0 - '@typescript-eslint/typescript-estree': 8.65.0(supports-color@11.0.0)(typescript@6.0.3) - '@typescript-eslint/utils': 8.65.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/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) debug: 4.4.3(supports-color@11.0.0) eslint: 10.8.0(jiti@2.7.0)(supports-color@11.0.0) ts-api-utils: 2.5.0(typescript@6.0.3) @@ -11384,12 +11295,14 @@ snapshots: '@typescript-eslint/types@8.65.0': {} - '@typescript-eslint/typescript-estree@8.65.0(supports-color@11.0.0)(typescript@6.0.3)': + '@typescript-eslint/types@8.66.0': {} + + '@typescript-eslint/typescript-estree@8.66.0(supports-color@11.0.0)(typescript@6.0.3)': dependencies: - '@typescript-eslint/project-service': 8.65.0(supports-color@11.0.0)(typescript@6.0.3) - '@typescript-eslint/tsconfig-utils': 8.65.0(typescript@6.0.3) - '@typescript-eslint/types': 8.65.0 - '@typescript-eslint/visitor-keys': 8.65.0 + '@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 debug: 4.4.3(supports-color@11.0.0) minimatch: 10.2.6 semver: 7.8.5 @@ -11399,20 +11312,20 @@ snapshots: transitivePeerDependencies: - supports-color - '@typescript-eslint/utils@8.65.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)': dependencies: '@eslint-community/eslint-utils': 4.10.1(eslint@10.8.0(jiti@2.7.0)(supports-color@11.0.0)) - '@typescript-eslint/scope-manager': 8.65.0 - '@typescript-eslint/types': 8.65.0 - '@typescript-eslint/typescript-estree': 8.65.0(supports-color@11.0.0)(typescript@6.0.3) + '@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) typescript: 6.0.3 transitivePeerDependencies: - supports-color - '@typescript-eslint/visitor-keys@8.65.0': + '@typescript-eslint/visitor-keys@8.66.0': dependencies: - '@typescript-eslint/types': 8.65.0 + '@typescript-eslint/types': 8.66.0 eslint-visitor-keys: 5.0.1 '@verdaccio/auth@8.1.1(supports-color@11.0.0)': @@ -11578,9 +11491,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.0)(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.1)(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.0)(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.1)(yaml@2.9.0) '@vitest/coverage-v8@4.1.10(vitest@4.1.10)': dependencies: @@ -11594,7 +11507,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.0)(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.1)(yaml@2.9.0) '@vitest/expect@4.1.10': dependencies: @@ -11605,13 +11518,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.0)(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.1)(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.0)(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.1)(yaml@2.9.0) '@vitest/pretty-format@4.1.10': dependencies: @@ -12954,17 +12867,17 @@ snapshots: transitivePeerDependencies: - supports-color - eslint-module-utils@2.14.0(@typescript-eslint/parser@8.65.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.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): dependencies: debug: 3.2.7(supports-color@11.0.0) optionalDependencies: - '@typescript-eslint/parser': 8.65.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.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) 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.65.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.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): dependencies: '@rtsao/scc': 1.1.0 array-includes: 3.1.9 @@ -12975,7 +12888,7 @@ snapshots: doctrine: 2.1.0 eslint: 10.8.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.65.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.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) hasown: 2.0.4 is-core-module: 2.16.2 is-glob: 4.0.3 @@ -12987,7 +12900,7 @@ snapshots: string.prototype.trimend: 1.0.10 tsconfig-paths: 3.15.0 optionalDependencies: - '@typescript-eslint/parser': 8.65.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.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 @@ -14126,7 +14039,7 @@ snapshots: saxes: 6.0.0 symbol-tree: 3.2.4 tough-cookie: 6.0.2 - undici: 8.9.0 + undici: 8.10.0 w3c-xmlserializer: 5.0.0 webidl-conversions: 8.0.1 whatwg-mimetype: 5.0.0 @@ -14602,7 +14515,7 @@ snapshots: '@jridgewell/trace-mapping': 0.3.31 jest-worker: 27.5.1 schema-utils: 4.3.3 - terser: 5.49.0 + 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) optionalDependencies: esbuild: 0.28.1 @@ -14615,7 +14528,7 @@ snapshots: '@jridgewell/trace-mapping': 0.3.31 jest-worker: 27.5.1 schema-utils: 4.3.3 - terser: 5.49.0 + terser: 5.49.1 webpack: 5.109.2(esbuild@0.28.1) optionalDependencies: esbuild: 0.28.1 @@ -14714,8 +14627,8 @@ snapshots: ora: 9.4.1 piscina: 5.3.0 postcss: 8.5.25 - rolldown: 1.2.1 - rolldown-plugin-dts: 0.27.14(rolldown@1.2.1)(typescript@6.0.3) + rolldown: 1.2.2 + rolldown-plugin-dts: 0.27.14(rolldown@1.2.2)(typescript@6.0.3) rxjs: 7.8.2 sass: 1.102.0 tinyglobby: 0.2.17 @@ -14898,30 +14811,29 @@ snapshots: object-keys: 1.1.1 safe-push-apply: 1.0.0 - oxc-parser@0.142.0: + oxc-parser@0.143.0: dependencies: - '@oxc-project/types': 0.142.0 + '@oxc-project/types': 0.143.0 optionalDependencies: - '@oxc-parser/binding-android-arm-eabi': 0.142.0 - '@oxc-parser/binding-android-arm64': 0.142.0 - '@oxc-parser/binding-darwin-arm64': 0.142.0 - '@oxc-parser/binding-darwin-x64': 0.142.0 - '@oxc-parser/binding-freebsd-x64': 0.142.0 - '@oxc-parser/binding-linux-arm-gnueabihf': 0.142.0 - '@oxc-parser/binding-linux-arm-musleabihf': 0.142.0 - '@oxc-parser/binding-linux-arm64-gnu': 0.142.0 - '@oxc-parser/binding-linux-arm64-musl': 0.142.0 - '@oxc-parser/binding-linux-ppc64-gnu': 0.142.0 - '@oxc-parser/binding-linux-riscv64-gnu': 0.142.0 - '@oxc-parser/binding-linux-riscv64-musl': 0.142.0 - '@oxc-parser/binding-linux-s390x-gnu': 0.142.0 - '@oxc-parser/binding-linux-x64-gnu': 0.142.0 - '@oxc-parser/binding-linux-x64-musl': 0.142.0 - '@oxc-parser/binding-openharmony-arm64': 0.142.0 - '@oxc-parser/binding-wasm32-wasi': 0.142.0 - '@oxc-parser/binding-win32-arm64-msvc': 0.142.0 - '@oxc-parser/binding-win32-ia32-msvc': 0.142.0 - '@oxc-parser/binding-win32-x64-msvc': 0.142.0 + '@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 p-finally@1.0.0: {} @@ -15200,9 +15112,9 @@ snapshots: punycode@2.3.1: {} - puppeteer-core@25.4.0(bufferutil@4.1.0)(utf-8-validate@6.0.6): + puppeteer-core@25.5.0(bufferutil@4.1.0)(utf-8-validate@6.0.6): dependencies: - '@puppeteer/browsers': 3.0.6 + '@puppeteer/browsers': 3.1.0 chromium-bidi: 17.0.2(devtools-protocol@0.0.1653615) devtools-protocol: 0.0.1653615 typed-query-selector: 2.12.2 @@ -15214,13 +15126,13 @@ snapshots: - utf-8-validate - yauzl - puppeteer@25.4.0(bufferutil@4.1.0)(utf-8-validate@6.0.6): + puppeteer@25.5.0(bufferutil@4.1.0)(utf-8-validate@6.0.6): dependencies: - '@puppeteer/browsers': 3.0.6 + '@puppeteer/browsers': 3.1.0 chromium-bidi: 17.0.2(devtools-protocol@0.0.1653615) devtools-protocol: 0.0.1653615 lilconfig: 3.1.3 - puppeteer-core: 25.4.0(bufferutil@4.1.0)(utf-8-validate@6.0.6) + puppeteer-core: 25.5.0(bufferutil@4.1.0)(utf-8-validate@6.0.6) typed-query-selector: 2.12.2 transitivePeerDependencies: - bufferutil @@ -15441,12 +15353,12 @@ snapshots: dependencies: glob: 10.5.0 - rolldown-plugin-dts@0.27.14(rolldown@1.2.1)(typescript@6.0.3): + rolldown-plugin-dts@0.27.14(rolldown@1.2.2)(typescript@6.0.3): dependencies: dts-resolver: 3.0.0 get-tsconfig: 5.0.0-beta.5 obug: 2.1.4 - rolldown: 1.2.1 + rolldown: 1.2.2 yuku-ast: 0.8.3 yuku-codegen: 0.8.3 yuku-parser: 0.8.3 @@ -15455,26 +15367,25 @@ snapshots: transitivePeerDependencies: - oxc-resolver - rolldown@1.2.1: + rolldown@1.2.2: dependencies: '@oxc-project/types': 0.142.0 '@rolldown/pluginutils': 1.0.1 optionalDependencies: - '@rolldown/binding-android-arm64': 1.2.1 - '@rolldown/binding-darwin-arm64': 1.2.1 - '@rolldown/binding-darwin-x64': 1.2.1 - '@rolldown/binding-freebsd-x64': 1.2.1 - '@rolldown/binding-linux-arm-gnueabihf': 1.2.1 - '@rolldown/binding-linux-arm64-gnu': 1.2.1 - '@rolldown/binding-linux-arm64-musl': 1.2.1 - '@rolldown/binding-linux-ppc64-gnu': 1.2.1 - '@rolldown/binding-linux-s390x-gnu': 1.2.1 - '@rolldown/binding-linux-x64-gnu': 1.2.1 - '@rolldown/binding-linux-x64-musl': 1.2.1 - '@rolldown/binding-openharmony-arm64': 1.2.1 - '@rolldown/binding-wasm32-wasi': 1.2.1 - '@rolldown/binding-win32-arm64-msvc': 1.2.1 - '@rolldown/binding-win32-x64-msvc': 1.2.1 + '@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 rollup-license-plugin@3.2.1: dependencies: @@ -15483,7 +15394,7 @@ snapshots: semver: 7.8.5 spdx-expression-validate: 2.0.0 - rollup-plugin-dts@6.4.1(rollup@4.62.4)(typescript@6.0.3): + rollup-plugin-dts@6.5.1(rollup@4.62.4)(typescript@6.0.3): dependencies: '@jridgewell/remapping': 2.3.5 '@jridgewell/sourcemap-codec': 1.5.5 @@ -15492,7 +15403,7 @@ snapshots: rollup: 4.62.4 typescript: 6.0.3 optionalDependencies: - '@babel/code-frame': 7.29.7 + '@babel/code-frame': 8.0.0 rollup-plugin-sourcemaps2@0.5.8(@types/node@22.20.1)(rollup@4.62.4): dependencies: @@ -16047,7 +15958,7 @@ snapshots: - bare-abort-controller - react-native-b4a - terser@5.49.0: + terser@5.49.1: dependencies: '@jridgewell/source-map': 0.3.11 acorn: 8.18.0 @@ -16255,7 +16166,7 @@ snapshots: undici@6.28.0: {} - undici@8.9.0: {} + undici@8.10.0: {} unenv@1.10.0: dependencies: @@ -16400,12 +16311,12 @@ 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.0)(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.1)(yaml@2.9.0): dependencies: lightningcss: 1.33.0 picomatch: 4.0.5 postcss: 8.5.25 - rolldown: 1.2.1 + rolldown: 1.2.2 tinyglobby: 0.2.17 optionalDependencies: '@types/node': 22.20.1 @@ -16414,14 +16325,14 @@ snapshots: jiti: 2.7.0 less: 4.8.1(supports-color@11.0.0) sass: 1.102.0 - terser: 5.49.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.0)(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.1)(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.0)(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.1)(yaml@2.9.0)) '@vitest/pretty-format': 4.1.10 '@vitest/runner': 4.1.10 '@vitest/snapshot': 4.1.10 @@ -16438,7 +16349,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.0)(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.1)(yaml@2.9.0) why-is-node-running: 2.3.0 optionalDependencies: '@opentelemetry/api': 1.9.1 From ed1e751561a14be38c022404838db49f6068f0af Mon Sep 17 00:00:00 2001 From: Angular Robot Date: Thu, 6 Aug 2026 06:13:51 +0000 Subject: [PATCH 03/97] build: update all github actions See associated pull request for more information. --- .github/workflows/codeql.yml | 4 ++-- .github/workflows/pr.yml | 2 +- .github/workflows/scorecard.yml | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml index 7a75337fd3df..15fc3e9c9ba5 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@f205ea1c3313d32999d8d6a48b4f6530d4437b38 # v4.37.4 + uses: github/codeql-action/init@5595ccaf912efad79be6eef63a5619ff05969be3 # v4.37.6 with: languages: javascript-typescript build-mode: none config-file: .github/codeql/config.yml - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@f205ea1c3313d32999d8d6a48b4f6530d4437b38 # v4.37.4 + uses: github/codeql-action/analyze@5595ccaf912efad79be6eef63a5619ff05969be3 # v4.37.6 with: category: '/language:javascript-typescript' diff --git a/.github/workflows/pr.yml b/.github/workflows/pr.yml index 4100bed1bcc8..7fdaf0758a26 100644 --- a/.github/workflows/pr.yml +++ b/.github/workflows/pr.yml @@ -23,7 +23,7 @@ jobs: - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: persist-credentials: false - - uses: dorny/paths-filter@7b450fff21473bca461d4b92ce414b9d0420d706 # v4.0.2 + - uses: dorny/paths-filter@ceb8a2b8f2d89434be7ff52d3de7ec3738c5cc9d # v4.0.3 id: filter with: filters: | diff --git a/.github/workflows/scorecard.yml b/.github/workflows/scorecard.yml index ac5d75573754..862ead79f856 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@f205ea1c3313d32999d8d6a48b4f6530d4437b38 # v4.37.4 + uses: github/codeql-action/upload-sarif@5595ccaf912efad79be6eef63a5619ff05969be3 # v4.37.6 with: sarif_file: results.sarif From a8f451bab9097aeef19eb275a153f29079a6778d Mon Sep 17 00:00:00 2001 From: Charles Lyding <19598772+clydin@users.noreply.github.com> Date: Wed, 5 Aug 2026 19:51:17 -0400 Subject: [PATCH 04/97] refactor(@angular/build): optimize removeSourceMappingURL with pre-check and range slicing Add an early substring check to immediately return the original code when no source map comment is present in a file. In addition, replace the character-by-character string accumulator with range slicing to eliminate temporary single-character string allocations on large files, and add unit tests covering zero-comment early returns and CRLF line endings. --- .../angular/build/src/utils/source-map.ts | 60 ++++++++----------- .../build/src/utils/source-map_spec.ts | 10 ++++ 2 files changed, 36 insertions(+), 34 deletions(-) diff --git a/packages/angular/build/src/utils/source-map.ts b/packages/angular/build/src/utils/source-map.ts index 3b91bfb5b5ad..9ce5e838987b 100644 --- a/packages/angular/build/src/utils/source-map.ts +++ b/packages/angular/build/src/utils/source-map.ts @@ -21,7 +21,12 @@ import { fileURLToPath } from 'node:url'; * @returns The code with top-level sourcemap comments removed. */ export function removeSourceMappingURL(code: string): string { + if (!code.includes('//# sourceMappingURL=')) { + return code; + } + const result: string[] = []; + let lastCopiedIndex = 0; let i = 0; const len = code.length; @@ -30,7 +35,6 @@ export function removeSourceMappingURL(code: string): string { let currentState: 'normal' | 'string_double' | 'string_single' | 'template' | 'comment_block' | 'comment_line' = 'normal'; - let isStrippingComment = false; while (i < len) { const char = code[i]; @@ -39,20 +43,19 @@ export function removeSourceMappingURL(code: string): string { if (currentState === 'normal') { if (char === '/' && nextChar === '*') { currentState = 'comment_block'; - result.push('/*'); i += 2; continue; } if (char === '/' && nextChar === '/') { // Detect if the comment is escaped (e.g. inside a regex literal like `/\/\/#/`). let isEscaped = false; - let prevIdx = result.length - 1; - while (prevIdx >= 0 && /\s/.test(result[prevIdx])) { + let prevIdx = i - 1; + while (prevIdx >= 0 && /\s/.test(code[prevIdx])) { prevIdx--; } - if (prevIdx >= 0 && result[prevIdx] === '\\') { + if (prevIdx >= 0 && code[prevIdx] === '\\') { let bsCount = 0; - while (prevIdx >= 0 && result[prevIdx] === '\\') { + while (prevIdx >= 0 && code[prevIdx] === '\\') { bsCount++; prevIdx--; } @@ -62,34 +65,35 @@ export function removeSourceMappingURL(code: string): string { } if (!isEscaped && code.startsWith('//# sourceMappingURL=', i)) { - currentState = 'comment_line'; - isStrippingComment = true; - i += 21; // Skip the '//# sourceMappingURL=' prefix + if (i > lastCopiedIndex) { + result.push(code.slice(lastCopiedIndex, i)); + } + // Skip the rest of the comment line up to the newline + i += 21; + while (i < len && code[i] !== '\n' && code[i] !== '\r') { + i++; + } + lastCopiedIndex = i; continue; } else { currentState = 'comment_line'; - isStrippingComment = false; - result.push('//'); i += 2; continue; } } if (char === '"') { currentState = 'string_double'; - result.push('"'); i++; continue; } if (char === "'") { currentState = 'string_single'; - result.push("'"); i++; continue; } if (char === '`') { currentState = 'template'; stack.push({ type: 'template', braceDepth: 0 }); - result.push('`'); i++; continue; } @@ -98,7 +102,6 @@ export function removeSourceMappingURL(code: string): string { if (top) { top.braceDepth++; } - result.push('{'); i++; continue; } @@ -110,43 +113,35 @@ export function removeSourceMappingURL(code: string): string { // Exiting a template literal interpolation ${ ... } stack.pop(); currentState = 'template'; - result.push('}'); i++; continue; } } - result.push('}'); i++; continue; } - result.push(char); i++; } else if (currentState === 'string_double') { if (char === '\\') { - result.push(char, nextChar || ''); i += 2; continue; } if (char === '"') { currentState = 'normal'; } - result.push(char); i++; } else if (currentState === 'string_single') { if (char === '\\') { - result.push(char, nextChar || ''); i += 2; continue; } if (char === "'") { currentState = 'normal'; } - result.push(char); i++; } else if (currentState === 'template') { if (char === '\\') { - result.push(char, nextChar || ''); i += 2; continue; } @@ -154,7 +149,6 @@ export function removeSourceMappingURL(code: string): string { // Entering template literal interpolation context currentState = 'normal'; stack.push({ type: 'template', braceDepth: 0 }); - result.push('${'); i += 2; continue; } @@ -162,32 +156,30 @@ export function removeSourceMappingURL(code: string): string { stack.pop(); currentState = 'normal'; } - result.push(char); i++; } else if (currentState === 'comment_block') { if (char === '*' && nextChar === '/') { currentState = 'normal'; - result.push('*/'); i += 2; continue; } - result.push(char); i++; } else if (currentState === 'comment_line') { if (char === '\n' || char === '\r') { currentState = 'normal'; - isStrippingComment = false; - result.push(char); - i++; - continue; - } - if (!isStrippingComment) { - result.push(char); } i++; } } + if (lastCopiedIndex === 0) { + return code; + } + + if (lastCopiedIndex < len) { + result.push(code.slice(lastCopiedIndex)); + } + return result.join(''); } diff --git a/packages/angular/build/src/utils/source-map_spec.ts b/packages/angular/build/src/utils/source-map_spec.ts index 7b424b019403..b34d5bc57a98 100644 --- a/packages/angular/build/src/utils/source-map_spec.ts +++ b/packages/angular/build/src/utils/source-map_spec.ts @@ -87,4 +87,14 @@ describe('removeSourceMappingURL', () => { const code = '// # sourceMappingURL=main.js.map\n//# sourceMappingURL=main.js.map'; expect(removeSourceMappingURL(code)).toBe('// # sourceMappingURL=main.js.map\n'); }); + + it('should return the exact input string when no sourcemap comment is present', () => { + const code = 'const x = 1;\nconsole.log(x);'; + expect(removeSourceMappingURL(code)).toBe(code); + }); + + it('should handle sourcemap comments with CRLF newlines', () => { + 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;'); + }); }); From 87551ad5c53f90cbdc68fdb5e47007b9436c7f75 Mon Sep 17 00:00:00 2001 From: Charles Lyding <19598772+clydin@users.noreply.github.com> Date: Wed, 5 Aug 2026 18:18:11 -0400 Subject: [PATCH 05/97] perf(@angular/build): avoid encoding intermediate source maps before remapping Use `generateDecodedMap()` instead of `generateMap()` when intermediate source maps created with `MagicString` are immediately remapped via `@ampproject/remapping`. This applies to: - `oxc-transform`: when an input source map is present - `oxc-linker`: when an input source map is present - Sass URL rebasing: intermediate stylesheet rebase maps stored for Sass source map merging Bypassing VLQ base64 encoding and immediate decoding reduces CPU time and temporary memory allocations during source map generation. --- .../src/tools/angular/linker/oxc-linker.ts | 11 +++-- .../tools/angular/linker/oxc-linker_spec.ts | 49 +++++++++++++++++++ .../build/src/tools/oxc/oxc-transform.ts | 11 +++-- .../build/src/tools/oxc/oxc-transform_spec.ts | 42 ++++++++++++++++ .../build/src/tools/sass/rebasing-importer.ts | 17 ++++--- .../angular/build/src/tools/sass/worker.ts | 4 +- 6 files changed, 117 insertions(+), 17 deletions(-) create mode 100644 packages/angular/build/src/tools/oxc/oxc-transform_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 467a1332cd97..6743fb720c21 100644 --- a/packages/angular/build/src/tools/angular/linker/oxc-linker.ts +++ b/packages/angular/build/src/tools/angular/linker/oxc-linker.ts @@ -6,7 +6,7 @@ * found in the LICENSE file at https://angular.dev/license */ -import type { EncodedSourceMap } from '@ampproject/remapping'; +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'; @@ -170,12 +170,15 @@ export function linkWithOxc(filename: string, code: string, options: OxcLinkerOp let map: string | undefined; if (options.sourcemap) { - const rawMap = s.generateMap({ hires: true, source: filename }); const inputMap = loadInputSourceMap(filename, code); if (inputMap) { - map = remapping([rawMap as EncodedSourceMap, inputMap], () => null).toString(); + const rawMap = s.generateDecodedMap({ hires: true, source: filename }); + map = remapping( + [{ ...rawMap, version: 3 } satisfies DecodedSourceMap, inputMap], + () => null, + ).toString(); } else { - map = rawMap.toString(); + map = s.generateMap({ hires: true, source: filename }).toString(); } } 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 148c67f9dce3..6b1ae742581a 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 @@ -53,4 +53,53 @@ describe('linkWithOxc', () => { expect(result.code).toContain('i0.ɵɵdefineComponent'); expect(result.code).not.toContain('i0.ɵɵngDeclareComponent'); }); + + it('should generate a sourcemap when sourcemap option is enabled', () => { + 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 = 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'); + }); }); diff --git a/packages/angular/build/src/tools/oxc/oxc-transform.ts b/packages/angular/build/src/tools/oxc/oxc-transform.ts index 64a5aa74062e..7f373ff09f08 100644 --- a/packages/angular/build/src/tools/oxc/oxc-transform.ts +++ b/packages/angular/build/src/tools/oxc/oxc-transform.ts @@ -6,7 +6,7 @@ * found in the LICENSE file at https://angular.dev/license */ -import remapping, { type EncodedSourceMap } from '@ampproject/remapping'; +import remapping, { 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'; @@ -749,13 +749,16 @@ export function transform(filename: string, code: string, options: OxcTransformO let map: string | undefined; if (options.sourcemap) { - const rawMap = s.generateMap({ hires: true, source: filename }); const inputMap = loadInputSourceMap(filename, code); if (inputMap) { - map = remapping([rawMap as EncodedSourceMap, inputMap], () => null).toString(); + const rawMap = s.generateDecodedMap({ hires: true, source: filename }); + map = remapping( + [{ ...rawMap, version: 3 } satisfies DecodedSourceMap, inputMap], + () => null, + ).toString(); } else { - map = rawMap.toString(); + map = s.generateMap({ hires: true, source: filename }).toString(); } } diff --git a/packages/angular/build/src/tools/oxc/oxc-transform_spec.ts b/packages/angular/build/src/tools/oxc/oxc-transform_spec.ts new file mode 100644 index 000000000000..ee37c7fec1fb --- /dev/null +++ b/packages/angular/build/src/tools/oxc/oxc-transform_spec.ts @@ -0,0 +1,42 @@ +/** + * @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 { transform } from './oxc-transform'; + +describe('oxc-transform sourcemaps', () => { + it('should generate a sourcemap when sourcemap option is enabled without inputMap', () => { + 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); + }); +}); diff --git a/packages/angular/build/src/tools/sass/rebasing-importer.ts b/packages/angular/build/src/tools/sass/rebasing-importer.ts index ccc90014616d..5d2a4ddc2267 100644 --- a/packages/angular/build/src/tools/sass/rebasing-importer.ts +++ b/packages/angular/build/src/tools/sass/rebasing-importer.ts @@ -6,7 +6,7 @@ * found in the LICENSE file at https://angular.dev/license */ -import { RawSourceMap } from '@ampproject/remapping'; +import type { DecodedSourceMap } from '@ampproject/remapping'; import { MagicString } from 'magic-string'; import { readFileSync, readdirSync, statSync } from 'node:fs'; import { basename, dirname, extname, join, relative } from 'node:path'; @@ -44,7 +44,7 @@ abstract class UrlRebasingImporter implements Importer<'sync'> { */ constructor( private entryDirectory: string, - private rebaseSourceMaps?: Map, + private rebaseSourceMaps?: Map, ) {} abstract canonicalize(url: string, options: { fromImport: boolean }): URL | null; @@ -95,12 +95,15 @@ abstract class UrlRebasingImporter implements Importer<'sync'> { contents = updatedContents.toString(); if (this.rebaseSourceMaps) { // Generate an intermediate source map for the rebasing changes - const map = updatedContents.generateMap({ + const map = updatedContents.generateDecodedMap({ hires: 'boundary', includeContent: true, source: canonicalUrl.href, }); - this.rebaseSourceMaps.set(canonicalUrl.href, map as RawSourceMap); + this.rebaseSourceMaps.set(canonicalUrl.href, { + ...map, + version: 3, + } satisfies DecodedSourceMap); } } @@ -134,7 +137,7 @@ export class RelativeUrlRebasingImporter extends UrlRebasingImporter { constructor( entryDirectory: string, private directoryCache = new Map(), - rebaseSourceMaps?: Map, + rebaseSourceMaps?: Map, ) { super(entryDirectory, rebaseSourceMaps); } @@ -322,7 +325,7 @@ export class ModuleUrlRebasingImporter extends RelativeUrlRebasingImporter { constructor( entryDirectory: string, directoryCache: Map, - rebaseSourceMaps: Map | undefined, + rebaseSourceMaps: Map | undefined, private finder: (specifier: string, options: CanonicalizeContext) => URL | null, ) { super(entryDirectory, directoryCache, rebaseSourceMaps); @@ -349,7 +352,7 @@ export class LoadPathsUrlRebasingImporter extends RelativeUrlRebasingImporter { constructor( entryDirectory: string, directoryCache: Map, - rebaseSourceMaps: Map | undefined, + rebaseSourceMaps: Map | undefined, private loadPaths: Iterable, ) { super(entryDirectory, directoryCache, rebaseSourceMaps); diff --git a/packages/angular/build/src/tools/sass/worker.ts b/packages/angular/build/src/tools/sass/worker.ts index 1a2e1184892f..e4167a3d1c69 100644 --- a/packages/angular/build/src/tools/sass/worker.ts +++ b/packages/angular/build/src/tools/sass/worker.ts @@ -6,7 +6,7 @@ * found in the LICENSE file at https://angular.dev/license */ -import mergeSourceMaps, { RawSourceMap } from '@ampproject/remapping'; +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'; @@ -89,7 +89,7 @@ export default async function renderSassStylesheet( let warnings: SerializableWarningMessage[] | undefined; try { const directoryCache = new Map(); - const rebaseSourceMaps = options.sourceMap ? new Map() : undefined; + 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. From fa7310caed22f0ba5c591df9ba1d77690fa299b1 Mon Sep 17 00:00:00 2001 From: Charles Lyding <19598772+clydin@users.noreply.github.com> Date: Wed, 5 Aug 2026 14:50:03 -0400 Subject: [PATCH 06/97] test(@angular/build): add additional unit tests for the i18n inliner Add four unit tests to `i18n-inliner_spec.ts` to improve test coverage: - Verify special characters, quotes, backslashes, and newlines are safely escaped without syntax errors. - Verify $localize calls containing placeholder expressions are correctly reconstructed as template literals. - Verify multiple $localize calls within the same file are inlined without AST offset drift. - Verify parallel multi-threaded inlining across multiple files safely shares and deserializes translation Blobs across worker threads. --- .../src/tools/esbuild/i18n-inliner_spec.ts | 75 +++++++++++++++++++ 1 file changed, 75 insertions(+) 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 e3e7320e391d..67a2fe5883a2 100644 --- a/packages/angular/build/src/tools/esbuild/i18n-inliner_spec.ts +++ b/packages/angular/build/src/tools/esbuild/i18n-inliner_spec.ts @@ -191,6 +191,81 @@ 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 '), + }); + + 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 07/97] 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 08/97] 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 09/97] 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 10/97] 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 11/97] 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 12/97] 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 13/97] 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 14/97] 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 15/97] 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 16/97] 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 17/97] 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 18/97] 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 19/97] 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 20/97] 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 21/97] 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 22/97] 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 23/97] 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 24/97] 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 25/97] 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 26/97] 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 27/97] 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 28/97] 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 29/97] 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 30/97] 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 31/97] 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 32/97] 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 33/97] 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 34/97] 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 35/97] 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 36/97] 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 37/97] 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 38/97] 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 39/97] 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 40/97] 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 41/97] 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 42/97] 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 43/97] 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 44/97] 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 45/97] 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 46/97] 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 47/97] 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 48/97] 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 49/97] 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 50/97] 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 51/97] 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 52/97] 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 53/97] 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 54/97] 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 55/97] 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 56/97] 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 57/97] 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 58/97] 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 59/97] 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 60/97] 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 61/97] 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 62/97] 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 63/97] 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 64/97] 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 65/97] 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 66/97] 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 67/97] 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 68/97] 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 69/97] 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 70/97] 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 71/97] 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 72/97] 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 73/97] 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 74/97] 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 75/97] 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 76/97] 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 77/97] 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 78/97] 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 79/97] 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 80/97] 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 81/97] 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 82/97] 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 83/97] 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 84/97] 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 85/97] 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 86/97] 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 87/97] 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 88/97] 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 89/97] 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 90/97] 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 91/97] 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 92/97] 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 93/97] 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 94/97] 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 95/97] 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 96/97] 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 97/97] 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); + }, + }, + ); +}