From 0035d82ac95ebbfec1a097b2845415d6374f231e Mon Sep 17 00:00:00 2001 From: Alan Agius <17563226+alan-agius4@users.noreply.github.com> Date: Wed, 16 Sep 2026 12:02:29 +0000 Subject: [PATCH 001/233] release: cut the v22.2.0-rc.0 release --- CHANGELOG.md | 21 +++++++++++++++++++++ package.json | 2 +- 2 files changed, 22 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f7ae51f6dbe9..a67b3ed682d2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,24 @@ + + +# 22.2.0-rc.0 (2026-09-16) + +### @angular/cli + +| Commit | Type | Description | +| ---------------------------------------------------------------------------------------------------- | ---- | ----------------------------------------------------------------- | +| [6e7f809a7d](https://github.com/angular/angular-cli/commit/6e7f809a7d66e4b8d260a1c00297812412a926f1) | perf | skip eager yargs help message formatting during command execution | + +### @angular/build + +| Commit | Type | Description | +| ---------------------------------------------------------------------------------------------------- | ---- | -------------------------------------------------------------------------- | +| [978351af71](https://github.com/angular/angular-cli/commit/978351af71889d4786a18fec9e193eb5b16af7dd) | fix | include inline component stylesheets in referenced watch files | +| [72dc9677cf](https://github.com/angular/angular-cli/commit/72dc9677cf743243d6cb22d2b81782022f71356e) | fix | pass load cache to compiler plugin and escape extension regex in polyfills | +| [31c045639e](https://github.com/angular/angular-cli/commit/31c045639e8bfd114cbd552d83cc70a968fe7f81) | fix | prevent stale bundler caching and correctly resolve load cache | +| [d97c8857c1](https://github.com/angular/angular-cli/commit/d97c8857c18da02fcc6c69a0ea652cc706c5c9b6) | perf | key Sass package resolutions without containing URL qualification | + + + # 22.2.0-next.7 (2026-09-10) diff --git a/package.json b/package.json index 69fd5f4f7f42..771cab189583 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@angular/devkit-repo", - "version": "22.2.0-next.7", + "version": "22.2.0-rc.0", "private": true, "description": "Software Development Kit for Angular", "keywords": [ From deed5d892492c10f1bfd39883362787c84c4c431 Mon Sep 17 00:00:00 2001 From: Charles Lyding <19598772+clydin@users.noreply.github.com> Date: Wed, 16 Sep 2026 14:55:35 -0400 Subject: [PATCH 002/233] test(@angular/build): add performance benchmark suite for i18n inliner Introduces an automated macro performance benchmark suite for the i18n inlining subsystem in @angular/build, executable via the benchmark command. The suite generates synthetic in-memory bundles, source maps, and translation catalogs to evaluate realistic workloads without checking large test fixtures into the repository. Benchmark scenarios cover standard applications with and without source maps, enterprise multilingual applications across 32 locales, monolithic bundles to verify 2D task sharding, and warm persistent cache throughput. Each scenario is executed in an isolated child process, and persistent cache priming is performed out-of-process to avoid cross-scenario memory contamination from the OS memory allocator. The harness collects high-precision timing, peak heap, peak RSS, and memory deltas with explicit garbage collection support. The runner is integrated into devkit-admin with support for baseline comparison, machine-readable JSON output, stale build detection, and automatic rebuilds. (cherry picked from commit 2a636a71efb4473f9b9ef27a16784a73b03c6eca) --- package.json | 1 + scripts/benchmark.mts | 115 ++++++++ scripts/benchmarks/i18n/fixtures.mts | 165 +++++++++++ scripts/benchmarks/i18n/harness.mts | 155 ++++++++++ scripts/benchmarks/i18n/index.mts | 164 +++++++++++ scripts/benchmarks/i18n/init-env.mts | 24 ++ scripts/benchmarks/i18n/reporters.mts | 159 ++++++++++ scripts/benchmarks/i18n/scenarios.mts | 404 ++++++++++++++++++++++++++ 8 files changed, 1187 insertions(+) create mode 100644 scripts/benchmark.mts create mode 100644 scripts/benchmarks/i18n/fixtures.mts create mode 100644 scripts/benchmarks/i18n/harness.mts create mode 100644 scripts/benchmarks/i18n/index.mts create mode 100644 scripts/benchmarks/i18n/init-env.mts create mode 100644 scripts/benchmarks/i18n/reporters.mts create mode 100644 scripts/benchmarks/i18n/scenarios.mts diff --git a/package.json b/package.json index 771cab189583..1cd8f7ceaac3 100644 --- a/package.json +++ b/package.json @@ -15,6 +15,7 @@ "bazel": "bazelisk", "test": "bazel test //packages/...", "build": "pnpm --silent admin build", + "benchmark": "node --no-warnings=ExperimentalWarning --experimental-transform-types --expose-gc ./scripts/devkit-admin.mts benchmark", "build-schema": "bazel build //... --build_tag_filters schema --symlink_prefix dist-schema/", "lint": "eslint --cache --max-warnings=0", "templates": "pnpm --silent admin templates", diff --git a/scripts/benchmark.mts b/scripts/benchmark.mts new file mode 100644 index 000000000000..2f1d13b8f13b --- /dev/null +++ b/scripts/benchmark.mts @@ -0,0 +1,115 @@ +/** + * @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 fs from 'node:fs'; +import { type BenchmarkCliOptions, runI18nBenchmarks } from './benchmarks/i18n/index.mts'; + +function checkBuildStatus(logger: Console): boolean { + const distFile = 'dist/@angular/build/src/tools/esbuild/i18n-inliner.js'; + const srcFile = 'packages/angular/build/src/tools/esbuild/i18n-inliner.ts'; + + if (!fs.existsSync(distFile)) { + logger.error( + 'Error: @angular/build has not been built yet.\nPlease run "pnpm build" before benchmarking.', + ); + + return false; + } + + if (fs.existsSync(srcFile)) { + const srcMtime = fs.statSync(srcFile).mtimeMs; + const distMtime = fs.statSync(distFile).mtimeMs; + if (srcMtime > distMtime) { + logger.warn( + 'Warning: Source files in packages/angular/build are newer than dist/.\n' + + 'Run "pnpm build" to ensure your benchmark reflects your latest local edits.\n', + ); + } + } + + return true; +} + +export default async function ( + options: { + _?: string[]; + scenario?: string; + iterations?: string | number; + warmup?: string | number; + concurrency?: string | number; + build?: boolean; + json?: boolean; + saveBaseline?: string; + 'save-baseline'?: string; + compareBaseline?: string; + 'compare-baseline'?: string; + help?: boolean; + [key: string]: unknown; + }, + _cwd: string, +): Promise { + const positionals = options._ ?? []; + const targetSubsystem = positionals[0] ?? 'i18n'; + + if (options.help || targetSubsystem === 'help') { + // eslint-disable-next-line no-console + console.log(` +Angular CLI Performance Benchmark Runner + +Usage: + pnpm admin benchmark [subsystem] [options] + +Subsystems: + i18n Run i18n inliner performance benchmarks (default) + +Options: + --scenario= Run a specific scenario (e.g. standard-app, enterprise-multilingual) + --iterations= Number of measured iterations (default: 5) + --warmup= Number of warmup iterations (default: 2) + --concurrency= Override worker thread pool concurrency + --build Automatically build packages before benchmarking + --json Output results in machine-readable JSON + --save-baseline= Save run results to a baseline JSON file + --compare-baseline= Compare run results against an existing baseline JSON file + --help Show this help message +`); + + return 0; + } + + if (targetSubsystem !== 'i18n') { + // eslint-disable-next-line no-console + console.error(`Unknown benchmark subsystem: "${targetSubsystem}". Supported subsystems: i18n`); + + return 1; + } + + if (options.build) { + const buildModule = await import('./build.mts'); + await buildModule.default({ local: true }); + } + + // eslint-disable-next-line no-console + if (!checkBuildStatus(console)) { + return 1; + } + + const cliOptions: BenchmarkCliOptions = { + scenario: options.scenario, + iterations: options.iterations !== undefined ? Number(options.iterations) : undefined, + warmup: options.warmup !== undefined ? Number(options.warmup) : undefined, + concurrency: options.concurrency !== undefined ? Number(options.concurrency) : undefined, + json: Boolean(options.json), + saveBaseline: options.saveBaseline ?? options['save-baseline'], + compareBaseline: options.compareBaseline ?? options['compare-baseline'], + }; + + const { exitCode } = await runI18nBenchmarks(cliOptions); + + return exitCode; +} diff --git a/scripts/benchmarks/i18n/fixtures.mts b/scripts/benchmarks/i18n/fixtures.mts new file mode 100644 index 000000000000..16305b766bec --- /dev/null +++ b/scripts/benchmarks/i18n/fixtures.mts @@ -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 './init-env.mts'; +import type { ɵParsedTranslation } from '@angular/localize'; +import { transformSync } from 'esbuild'; +import { createRequire } from 'node:module'; + +import path from 'node:path'; + +import type { BuildOutputFile } from '../../../dist/@angular/build/src/tools/esbuild/bundler-files.d.ts'; +import type { LocaleInlineOptions } from '../../../dist/@angular/build/src/tools/esbuild/i18n-inliner.d.ts'; + +// Setup module paths to resolve dependencies from packages/angular/build +const requireFromBuild = createRequire( + path.resolve(import.meta.dirname, '../../../packages/angular/build/package.json'), +); + +const { BuildOutputFileType, createOutputFile } = requireFromBuild( + '../../../dist/@angular/build/src/tools/esbuild/bundler-files.js', +) as typeof import('../../../packages/angular/build/src/tools/esbuild/bundler-files.js'); + +const { calculateHash, initializeHash } = requireFromBuild( + '../../../dist/@angular/build/src/utils/hash.js', +) as typeof import('../../../packages/angular/build/src/utils/hash.js'); + +let isHashInitialized = false; + +export async function initializeFixtures(): Promise { + if (!isHashInitialized) { + await initializeHash(); + isHashInitialized = true; + } +} + +export function parsedTranslation( + parts: string[], + placeholderNames: string[] = [], + text?: string, +): ɵParsedTranslation { + return { + messageParts: Object.assign([...parts], { raw: [...parts] }), + placeholderNames, + text: text ?? parts.join(''), + }; +} + +export function generateTranslations( + locales: string[], + messageCount: number, +): LocaleInlineOptions[] { + return locales.map((locale) => { + const translation: Record = {}; + + for (let i = 0; i < messageCount; i++) { + const msgId = `msg_${i}`; + translation[msgId] = parsedTranslation( + [`[${locale}] Order #`, ` was confirmed for customer `, `. Thank you!`], + ['orderId', 'customerName'], + `[${locale}] Order #${i} was confirmed for customer Doe. Thank you!`, + ); + } + + const translationIntegrity = calculateHash(JSON.stringify(translation)); + + return { + locale, + translation, + translationIntegrity, + }; + }); +} + +export interface SyntheticBundleOptions { + filename: string; + targetByteSize: number; + messageCount: number; + withSourceMap?: boolean; + messageIdOffset?: number; +} + +export function generateSyntheticBundle(options: SyntheticBundleOptions): { + codeFile: BuildOutputFile; + mapFile?: BuildOutputFile; +} { + const { + filename, + targetByteSize, + messageCount, + withSourceMap = true, + messageIdOffset = 0, + } = options; + + const parts: string[] = [ + '// Synthetic test bundle generated for i18n-inliner benchmark\n', + 'export const BUNDLE_META = { generated: true, timestamp: Date.now() };\n', + ]; + + // Generate functions with $localize call sites + for (let i = 0; i < messageCount; i++) { + const msgId = `msg_${messageIdOffset + i}`; + parts.push( + `export function renderMessage_${i}(orderId, customerName) {\n`, + ` return $localize\`:@@${msgId}:Order #\${orderId}:orderId: ` + + `was confirmed for customer \${customerName}:customerName:. Thank you!\`;\n`, + `}\n`, + ); + } + + // Calculate current approximate size and pad with realistic JS functions if needed + let currentSize = parts.reduce((acc, str) => acc + str.length, 0); + let classIndex = 0; + + while (currentSize < targetByteSize) { + const filler = + `export class DataProcessor_${classIndex} {\n` + + ` constructor(id, options = {}) {\n` + + ` this.id = id;\n` + + ` this.options = Object.assign({ enabled: true, retries: 3 }, options);\n` + + ` this.history = [];\n` + + ` }\n` + + ` process(batch) {\n` + + ` if (!Array.isArray(batch)) return [];\n` + + ` const result = batch.map((item, idx) => ({\n` + + ` id: this.id + '_' + idx,\n` + + ` source: item,\n` + + ` timestamp: Date.now(),\n` + + ` active: true\n` + + ` }));\n` + + ` this.history.push(...result);\n` + + ` return result;\n` + + ` }\n` + + `}\n`; + + parts.push(filler); + currentSize += filler.length; + classIndex++; + } + + const rawCode = parts.join(''); + + let finalCode = rawCode; + let finalMap: string | undefined; + + if (withSourceMap) { + const result = transformSync(rawCode, { + sourcemap: true, + sourcefile: filename.replace(/\.js$/, '.ts'), + }); + finalCode = result.code; + finalMap = result.map; + } + + const codeFile = createOutputFile(filename, finalCode, BuildOutputFileType.Browser); + const mapFile = finalMap + ? createOutputFile(filename + '.map', finalMap, BuildOutputFileType.Browser) + : undefined; + + return { codeFile, mapFile }; +} diff --git a/scripts/benchmarks/i18n/harness.mts b/scripts/benchmarks/i18n/harness.mts new file mode 100644 index 000000000000..700199c0af0b --- /dev/null +++ b/scripts/benchmarks/i18n/harness.mts @@ -0,0 +1,155 @@ +/** + * @license + * Copyright Google LLC All Rights Reserved. + * + * Use of this source code is governed by an MIT-style license that can be + * found in the LICENSE file at https://angular.dev/license + */ + +import './init-env.mts'; + +export interface BenchmarkScenario { + name: string; + description: string; + inputSizeBytes: number; + localeCount: number; + run(iteration: number): Promise; + setup?(): Promise; + teardown?(): Promise; +} + +export interface ScenarioResult { + name: string; + description: string; + inputSizeBytes: number; + localeCount: number; + iterations: number; + warmup: number; + durationsMs: number[]; + minMs: number; + maxMs: number; + meanMs: number; + medianMs: number; + p95Ms: number; + stdDevMs: number; + throughputMBps: number; + peakRssBytes: number; + peakHeapBytes: number; + rssDeltaBytes: number; + heapUsedDeltaBytes: number; +} + +export interface BenchmarkRunOptions { + warmup?: number; + iterations?: number; +} + +function calculatePercentile(sortedValues: number[], percentile: number): number { + if (sortedValues.length === 0) { + return 0; + } + const index = (percentile / 100) * (sortedValues.length - 1); + const lower = Math.floor(index); + const upper = Math.ceil(index); + const weight = index - lower; + + return sortedValues[lower] * (1 - weight) + sortedValues[upper] * weight; +} + +export async function runScenario( + scenario: BenchmarkScenario, + options: BenchmarkRunOptions = {}, +): Promise { + const warmup = options.warmup ?? 2; + const iterations = options.iterations ?? 5; + + await scenario.setup?.(); + + try { + // Warmup phase + for (let w = 0; w < warmup; w++) { + // Force GC if available between warmups + global.gc?.(); + await scenario.run(-(w + 1)); + } + + // Measurement phase + const durationsMs: number[] = []; + let peakRssBytes = 0; + let peakHeapBytes = 0; + let maxRssDeltaBytes = 0; + let initialHeap = 0; + let finalHeap = 0; + + for (let i = 0; i < iterations; i++) { + global.gc?.(); + + const memBefore = process.memoryUsage(); + if (i === 0) { + initialHeap = memBefore.heapUsed; + } + + const start = performance.now(); + await scenario.run(i); + const duration = performance.now() - start; + + durationsMs.push(duration); + + const memAfter = process.memoryUsage(); + if (memAfter.rss > peakRssBytes) { + peakRssBytes = memAfter.rss; + } + if (memAfter.heapUsed > peakHeapBytes) { + peakHeapBytes = memAfter.heapUsed; + } + const rssDelta = Math.max(0, memAfter.rss - memBefore.rss); + if (rssDelta > maxRssDeltaBytes) { + maxRssDeltaBytes = rssDelta; + } + finalHeap = memAfter.heapUsed; + + // Force GC immediately after iteration to clean main thread isolate + global.gc?.(); + } + + // Sort ascending for percentile computation + const sorted = [...durationsMs].sort((a, b) => a - b); + const minMs = sorted[0]; + const maxMs = sorted[sorted.length - 1]; + const meanMs = durationsMs.reduce((sum, d) => sum + d, 0) / durationsMs.length; + const medianMs = calculatePercentile(sorted, 50); + const p95Ms = calculatePercentile(sorted, 95); + + const variance = + durationsMs.reduce((sum, d) => sum + Math.pow(d - meanMs, 2), 0) / durationsMs.length; + const stdDevMs = Math.sqrt(variance); + + // Throughput: total effective processed code volume in MB / mean seconds + const totalProcessedMb = (scenario.inputSizeBytes * scenario.localeCount) / (1024 * 1024); + const meanSeconds = meanMs / 1000; + const throughputMBps = meanSeconds > 0 ? totalProcessedMb / meanSeconds : 0; + + return { + name: scenario.name, + description: scenario.description, + inputSizeBytes: scenario.inputSizeBytes, + localeCount: scenario.localeCount, + iterations, + warmup, + durationsMs, + minMs, + maxMs, + meanMs, + medianMs, + p95Ms, + stdDevMs, + throughputMBps, + peakRssBytes, + peakHeapBytes, + rssDeltaBytes: maxRssDeltaBytes, + heapUsedDeltaBytes: Math.max(0, finalHeap - initialHeap), + }; + } finally { + await scenario.teardown?.(); + } +} diff --git a/scripts/benchmarks/i18n/index.mts b/scripts/benchmarks/i18n/index.mts new file mode 100644 index 000000000000..8b6503d60e83 --- /dev/null +++ b/scripts/benchmarks/i18n/index.mts @@ -0,0 +1,164 @@ +/** + * @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 './init-env.mts'; + +import { spawnSync } from 'node:child_process'; +import fs from 'node:fs/promises'; +import path from 'node:path'; +import { type ScenarioResult, runScenario } from './harness.mts'; +import { + buildReportData, + formatComparisonTable, + formatConsoleTable, + formatJsonReport, +} from './reporters.mts'; +import { type ScenarioFactoryOptions, getAllScenarios, getScenarioByName } from './scenarios.mts'; + +export interface BenchmarkCliOptions extends ScenarioFactoryOptions { + scenario?: string; + iterations?: number; + warmup?: number; + verbose?: boolean; + json?: boolean; + inProcess?: boolean; + saveBaseline?: string; + compareBaseline?: string; +} + +export async function runI18nBenchmarks( + options: BenchmarkCliOptions = {}, +): Promise<{ results: ScenarioResult[]; exitCode: number }> { + const warmup = options.warmup ?? 2; + const iterations = options.iterations ?? 5; + + let scenariosToRun = getAllScenarios({ concurrency: options.concurrency }); + + if (options.scenario) { + const single = getScenarioByName(options.scenario, { concurrency: options.concurrency }); + if (!single) { + // eslint-disable-next-line no-console + console.error( + `Unknown scenario: "${options.scenario}".\nAvailable scenarios: ${scenariosToRun.map((s) => s.name).join(', ')}`, + ); + + return { results: [], exitCode: 1 }; + } + scenariosToRun = [single]; + } + + const results: ScenarioResult[] = []; + + // When running multiple scenarios in a suite, isolate each scenario into its own child process + // so operating system memory and thread caches are not accumulated across scenarios. + if (scenariosToRun.length > 1 && !options.inProcess) { + for (const scenario of scenariosToRun) { + if (!options.json) { + // eslint-disable-next-line no-console + console.log( + `Running scenario: ${scenario.name} (${warmup} warmups, ${iterations} iterations)...`, + ); + } + + const args = [ + '--no-warnings=ExperimentalWarning', + '--experimental-transform-types', + '--expose-gc', + path.resolve(import.meta.dirname, '../../devkit-admin.mts'), + 'benchmark', + 'i18n', + `--scenario=${scenario.name}`, + `--warmup=${warmup}`, + `--iterations=${iterations}`, + '--json', + ]; + if (options.concurrency !== undefined) { + args.push(`--concurrency=${options.concurrency}`); + } + + const proc = spawnSync(process.execPath, args, { encoding: 'utf-8' }); + if (proc.status !== 0) { + // eslint-disable-next-line no-console + console.error(`Error running scenario ${scenario.name}:\n${proc.stderr || proc.stdout}`); + + return { results, exitCode: 1 }; + } + + try { + const parsed = JSON.parse(proc.stdout); + const scenarioResult: ScenarioResult | undefined = Array.isArray(parsed) + ? parsed[0] + : parsed.results?.[0]; + if (scenarioResult) { + results.push(scenarioResult); + } + } catch { + // eslint-disable-next-line no-console + console.error(`Failed to parse result for scenario ${scenario.name}:\n${proc.stdout}`); + + return { results, exitCode: 1 }; + } + } + } else { + for (const scenario of scenariosToRun) { + if (!options.json) { + // eslint-disable-next-line no-console + console.log( + `Running scenario: ${scenario.name} (${warmup} warmups, ${iterations} iterations)...`, + ); + } + + try { + const result = await runScenario(scenario, { warmup, iterations }); + results.push(result); + } catch (error) { + // eslint-disable-next-line no-console + console.error(`Error running scenario ${scenario.name}:`, error); + + return { results, exitCode: 1 }; + } + } + } + + if (options.json) { + // eslint-disable-next-line no-console + console.log(formatJsonReport(results)); + } else { + // eslint-disable-next-line no-console + console.log('\n' + formatConsoleTable(results)); + } + + if (options.saveBaseline) { + const reportData = buildReportData(results); + await fs.writeFile(options.saveBaseline, JSON.stringify(reportData, null, 2), 'utf-8'); + if (!options.json) { + // eslint-disable-next-line no-console + console.log(`Saved baseline to: ${options.saveBaseline}`); + } + } + + if (options.compareBaseline) { + try { + const baselineContent = await fs.readFile(options.compareBaseline, 'utf-8'); + const baselineData = JSON.parse(baselineContent); + const baselineResults: ScenarioResult[] = Array.isArray(baselineData) + ? baselineData + : (baselineData.results ?? []); + + if (!options.json) { + // eslint-disable-next-line no-console + console.log(formatComparisonTable(results, baselineResults)); + } + } catch (error) { + // eslint-disable-next-line no-console + console.error(`Failed to load baseline from ${options.compareBaseline}:`, error); + } + } + + return { results, exitCode: 0 }; +} diff --git a/scripts/benchmarks/i18n/init-env.mts b/scripts/benchmarks/i18n/init-env.mts new file mode 100644 index 000000000000..679281e4dc18 --- /dev/null +++ b/scripts/benchmarks/i18n/init-env.mts @@ -0,0 +1,24 @@ +/** + * @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 Module from 'node:module'; +import path from 'node:path'; + +// Resolve dependencies from packages/angular/build/node_modules for runtime resolution in dist/ +const buildNodeModules = path.resolve( + import.meta.dirname, + '../../../packages/angular/build/node_modules', +); + +const currentPath = process.env.NODE_PATH ?? ''; +if (!currentPath.includes(buildNodeModules)) { + process.env.NODE_PATH = currentPath ? `${buildNodeModules}:${currentPath}` : buildNodeModules; + // Initialize internal search paths for Node CommonJS loader + // eslint-disable-next-line @typescript-eslint/no-explicit-any + (Module as any)._initPaths?.(); +} diff --git a/scripts/benchmarks/i18n/reporters.mts b/scripts/benchmarks/i18n/reporters.mts new file mode 100644 index 000000000000..d5153552a2b3 --- /dev/null +++ b/scripts/benchmarks/i18n/reporters.mts @@ -0,0 +1,159 @@ +/** + * @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 os from 'node:os'; +import type { ScenarioResult } from './harness.mts'; + +export interface BenchmarkReportData { + timestamp: string; + system: { + nodeVersion: string; + platform: string; + arch: string; + cpus: number; + cpuModel: string; + totalMemoryMb: number; + }; + results: ScenarioResult[]; +} + +export function buildReportData(results: ScenarioResult[]): BenchmarkReportData { + const cpus = os.cpus(); + + return { + timestamp: new Date().toISOString(), + system: { + nodeVersion: process.version, + platform: os.platform(), + arch: os.arch(), + cpus: cpus.length, + cpuModel: cpus[0]?.model ?? 'unknown', + totalMemoryMb: Math.round(os.totalmem() / (1024 * 1024)), + }, + results, + }; +} + +export function formatJsonReport(results: ScenarioResult[]): string { + return JSON.stringify(buildReportData(results), null, 2); +} + +function formatBytes(bytes: number): string { + if (bytes < 1024) { + return `${bytes} B`; + } + if (bytes < 1024 * 1024) { + return `${(bytes / 1024).toFixed(1)} KB`; + } + + return `${(bytes / (1024 * 1024)).toFixed(2)} MB`; +} + +function padRight(str: string, len: number): string { + return str.length >= len ? str : str + ' '.repeat(len - str.length); +} + +function padLeft(str: string, len: number): string { + return str.length >= len ? str : ' '.repeat(len - str.length) + str; +} + +export function formatConsoleTable(results: ScenarioResult[]): string { + const cpus = os.cpus(); + const gcStatus = typeof global.gc === 'function' ? 'active' : 'inactive (run with --expose-gc)'; + const header = + `================================================================================================================\n` + + `i18n Inliner Performance Benchmarks (Node ${process.version}, ${cpus.length} CPUs: ${cpus[0]?.model ?? ''} | GC: ${gcStatus})\n` + + `================================================================================================================\n`; + + const columns = [ + { name: 'Scenario', width: 25 }, + { name: 'Input Size', width: 11 }, + { name: 'Locales', width: 8 }, + { name: 'Mean Latency', width: 13 }, + { name: 'p50 / p95', width: 18 }, + { name: 'Throughput', width: 12 }, + { name: 'Peak Heap', width: 11 }, + { name: 'Peak RSS', width: 11 }, + ]; + + const colHeader = columns.map((col) => padRight(col.name, col.width)).join(' '); + const separator = columns.map((col) => '-'.repeat(col.width)).join(' '); + + const rows = results.map((r) => { + const inputFormatted = formatBytes(r.inputSizeBytes); + const meanFormatted = `${r.meanMs.toFixed(1)} ms`; + const p50p95Formatted = `${r.medianMs.toFixed(0)} ms / ${r.p95Ms.toFixed(0)} ms`; + const throughputFormatted = `${r.throughputMBps.toFixed(1)} MB/s`; + const peakHeapFormatted = formatBytes(r.peakHeapBytes ?? 0); + const peakRssFormatted = formatBytes(r.peakRssBytes); + + return [ + padRight(r.name, columns[0].width), + padLeft(inputFormatted, columns[1].width), + padLeft(r.localeCount.toString(), columns[2].width), + padLeft(meanFormatted, columns[3].width), + padLeft(p50p95Formatted, columns[4].width), + padLeft(throughputFormatted, columns[5].width), + padLeft(peakHeapFormatted, columns[6].width), + padLeft(peakRssFormatted, columns[7].width), + ].join(' '); + }); + + return `${header}\n${colHeader}\n${separator}\n${rows.join('\n')}\n${'='.repeat(separator.length)}\n`; +} + +export function formatComparisonTable( + currentResults: ScenarioResult[], + baselineResults: ScenarioResult[], +): string { + const header = + `====================================================================================================\n` + + `i18n Inliner Benchmark Comparison (Current vs Baseline)\n` + + `====================================================================================================\n`; + + const columns = [ + { name: 'Scenario', width: 26 }, + { name: 'Baseline Mean', width: 14 }, + { name: 'Current Mean', width: 14 }, + { name: 'Latency Diff', width: 14 }, + { name: 'Baseline MB/s', width: 14 }, + { name: 'Current MB/s', width: 14 }, + ]; + + const colHeader = columns.map((col) => padRight(col.name, col.width)).join(' '); + const separator = columns.map((col) => '-'.repeat(col.width)).join(' '); + + const rows = currentResults.map((curr) => { + const base = baselineResults.find((b) => b.name === curr.name); + if (!base) { + return [ + padRight(curr.name, columns[0].width), + padLeft('N/A', columns[1].width), + padLeft(`${curr.meanMs.toFixed(1)} ms`, columns[2].width), + padLeft('NEW', columns[3].width), + padLeft('N/A', columns[4].width), + padLeft(`${curr.throughputMBps.toFixed(1)} MB/s`, columns[5].width), + ].join(' '); + } + + const diffPercent = ((curr.meanMs - base.meanMs) / base.meanMs) * 100; + const diffSign = diffPercent > 0 ? '+' : ''; + const diffText = `${diffSign}${diffPercent.toFixed(1)}% ${diffPercent > 1 ? '(slower)' : diffPercent < -1 ? '(faster)' : '(same)'}`; + + return [ + padRight(curr.name, columns[0].width), + padLeft(`${base.meanMs.toFixed(1)} ms`, columns[1].width), + padLeft(`${curr.meanMs.toFixed(1)} ms`, columns[2].width), + padLeft(diffText, columns[3].width), + padLeft(`${base.throughputMBps.toFixed(1)} MB/s`, columns[4].width), + padLeft(`${curr.throughputMBps.toFixed(1)} MB/s`, columns[5].width), + ].join(' '); + }); + + return `${header}\n${colHeader}\n${separator}\n${rows.join('\n')}\n${'='.repeat(separator.length)}\n`; +} diff --git a/scripts/benchmarks/i18n/scenarios.mts b/scripts/benchmarks/i18n/scenarios.mts new file mode 100644 index 000000000000..f862e28c04f6 --- /dev/null +++ b/scripts/benchmarks/i18n/scenarios.mts @@ -0,0 +1,404 @@ +/** + * @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 './init-env.mts'; + +import { spawnSync } from 'node:child_process'; +import fs from 'node:fs/promises'; +import { createRequire } from 'node:module'; +import os from 'node:os'; +import path from 'node:path'; + +import type { BuildOutputFile } from '../../../dist/@angular/build/src/tools/esbuild/bundler-files.d.ts'; +import type { LocaleInlineOptions } from '../../../dist/@angular/build/src/tools/esbuild/i18n-inliner.d.ts'; +import { generateSyntheticBundle, generateTranslations, initializeFixtures } from './fixtures.mts'; +import type { BenchmarkScenario } from './harness.mts'; + +const requireFromBuild = createRequire( + path.resolve(import.meta.dirname, '../../../packages/angular/build/package.json'), +); + +const { I18nInliner } = requireFromBuild( + '../../../dist/@angular/build/src/tools/esbuild/i18n-inliner.js', +) as typeof import('../../../dist/@angular/build/src/tools/esbuild/i18n-inliner.d.ts'); + +export interface ScenarioFactoryOptions { + concurrency?: number; +} + +const DEFAULT_LOCALES_8 = ['fr', 'de', 'es', 'ja', 'zh', 'it', 'pt', 'ko']; +const DEFAULT_LOCALES_32 = [ + 'fr', + 'de', + 'es', + 'ja', + 'zh', + 'it', + 'pt', + 'ko', + 'ru', + 'pl', + 'nl', + 'tr', + 'ar', + 'hi', + 'sv', + 'da', + 'fi', + 'no', + 'cs', + 'el', + 'he', + 'hu', + 'id', + 'ms', + 'ro', + 'sk', + 'th', + 'uk', + 'vi', + 'bg', + 'hr', + 'sr', +]; + +interface GeneratedWorkload { + files: BuildOutputFile[]; + locales: LocaleInlineOptions[]; + totalInputSizeBytes: number; +} + +function createBundleSet( + mainSizeBytes: number, + chunkCount: number, + chunkSizeBytes: number, + messageCount: number, + withSourceMap: boolean, +): BuildOutputFile[] { + const files: BuildOutputFile[] = []; + + const mainMessages = Math.floor(messageCount * 0.4); + const { codeFile: mainCode, mapFile: mainMap } = generateSyntheticBundle({ + filename: 'main.js', + targetByteSize: mainSizeBytes, + messageCount: mainMessages, + withSourceMap, + messageIdOffset: 0, + }); + + files.push(mainCode); + if (mainMap) { + files.push(mainMap); + } + + const remainingMessages = messageCount - mainMessages; + const messagesPerChunk = Math.max(1, Math.floor(remainingMessages / chunkCount)); + + for (let i = 0; i < chunkCount; i++) { + const { codeFile, mapFile } = generateSyntheticBundle({ + filename: `chunk_${i}.js`, + targetByteSize: chunkSizeBytes, + messageCount: messagesPerChunk, + withSourceMap, + messageIdOffset: mainMessages + i * messagesPerChunk, + }); + + files.push(codeFile); + if (mapFile) { + files.push(mapFile); + } + } + + return files; +} + +function calculateInputSizeBytes(files: BuildOutputFile[]): number { + return files.reduce((total, f) => { + // Only count JS code size towards raw input volume (maps are auxiliary) + return f.path.endsWith('.js') ? total + f.size : total; + }, 0); +} + +/** + * 1. Standard App Scenario: + * 1 main bundle (1 MB) + 20 route chunks (50 KB) = ~2 MB input JS, 8 locales, maps enabled. + */ +export function createStandardAppScenario(options: ScenarioFactoryOptions = {}): BenchmarkScenario { + let workload: GeneratedWorkload | undefined; + + return { + name: 'standard-app', + description: 'Standard App: 1 main bundle (1 MB) + 20 chunks (50 KB), 8 locales, sourcemaps ON', + get inputSizeBytes() { + return workload?.totalInputSizeBytes ?? 0; + }, + get localeCount() { + return DEFAULT_LOCALES_8.length; + }, + async setup() { + await initializeFixtures(); + const files = createBundleSet(1024 * 1024, 20, 50 * 1024, 1000, true); + const locales = generateTranslations(DEFAULT_LOCALES_8, 1000); + workload = { + files, + locales, + totalInputSizeBytes: calculateInputSizeBytes(files), + }; + }, + async run() { + if (!workload) { + return; + } + const inliner = new I18nInliner({ + missingTranslation: 'warning', + maxConcurrency: options.concurrency, + }); + try { + await inliner.inlineAll(workload.files, workload.locales); + } finally { + await inliner.close(); + } + }, + }; +} + +/** + * 2. Standard App without Sourcemaps: + * Evaluates inlining without source map generation and remapping. + */ +export function createStandardAppNoMapsScenario( + options: ScenarioFactoryOptions = {}, +): BenchmarkScenario { + let workload: GeneratedWorkload | undefined; + + return { + name: 'standard-app-no-maps', + description: + 'Standard App (No Maps): 1 main bundle (1 MB) + 20 chunks (50 KB), 8 locales, sourcemaps OFF', + get inputSizeBytes() { + return workload?.totalInputSizeBytes ?? 0; + }, + get localeCount() { + return DEFAULT_LOCALES_8.length; + }, + async setup() { + await initializeFixtures(); + const files = createBundleSet(1024 * 1024, 20, 50 * 1024, 1000, false); + const locales = generateTranslations(DEFAULT_LOCALES_8, 1000); + workload = { + files, + locales, + totalInputSizeBytes: calculateInputSizeBytes(files), + }; + }, + async run() { + if (!workload) { + return; + } + const inliner = new I18nInliner({ + missingTranslation: 'warning', + maxConcurrency: options.concurrency, + }); + try { + await inliner.inlineAll(workload.files, workload.locales); + } finally { + await inliner.close(); + } + }, + }; +} + +/** + * 3. Enterprise Multilingual Scenario: + * 1 main bundle (2 MB) + 40 chunks (60 KB), 32 locales, 3,000 translations, sourcemaps ON. + * Exercises sliding window batching (4 windows of 8 locales) and memory scaling. + */ +export function createEnterpriseScenario(options: ScenarioFactoryOptions = {}): BenchmarkScenario { + let workload: GeneratedWorkload | undefined; + + return { + name: 'enterprise-multilingual', + description: 'Enterprise: 1 main (2 MB) + 40 chunks (60 KB), 32 locales, sourcemaps ON', + get inputSizeBytes() { + return workload?.totalInputSizeBytes ?? 0; + }, + get localeCount() { + return DEFAULT_LOCALES_32.length; + }, + async setup() { + await initializeFixtures(); + const files = createBundleSet(2 * 1024 * 1024, 40, 60 * 1024, 3000, true); + const locales = generateTranslations(DEFAULT_LOCALES_32, 3000); + workload = { + files, + locales, + totalInputSizeBytes: calculateInputSizeBytes(files), + }; + }, + async run() { + if (!workload) { + return; + } + const inliner = new I18nInliner({ + missingTranslation: 'warning', + maxConcurrency: options.concurrency, + }); + try { + await inliner.inlineAll(workload.files, workload.locales); + } finally { + await inliner.close(); + } + }, + }; +} + +/** + * 4. Monolithic Dominant Scenario: + * 1 dominant bundle (6 MB) + 5 small runtime chunks (30 KB), 8 locales, sourcemaps ON. + * Evaluates whether LPT + DOMINANT_FILE_RATIO sharding saturates workers efficiently. + */ +export function createMonolithicScenario(options: ScenarioFactoryOptions = {}): BenchmarkScenario { + let workload: GeneratedWorkload | undefined; + + return { + name: 'monolithic-dominant', + description: 'Monolithic: 1 dominant bundle (6 MB) + 5 small chunks (30 KB), 8 locales', + get inputSizeBytes() { + return workload?.totalInputSizeBytes ?? 0; + }, + get localeCount() { + return DEFAULT_LOCALES_8.length; + }, + async setup() { + await initializeFixtures(); + const files = createBundleSet(6 * 1024 * 1024, 5, 30 * 1024, 2000, true); + const locales = generateTranslations(DEFAULT_LOCALES_8, 2000); + workload = { + files, + locales, + totalInputSizeBytes: calculateInputSizeBytes(files), + }; + }, + async run() { + if (!workload) { + return; + } + const inliner = new I18nInliner({ + missingTranslation: 'warning', + maxConcurrency: options.concurrency, + }); + try { + await inliner.inlineAll(workload.files, workload.locales); + } finally { + await inliner.close(); + } + }, + }; +} + +/** + * Helper to prime the persistent cache in an isolated process. + */ +export async function primeCache(cacheDir: string, concurrency?: number): Promise { + await initializeFixtures(); + const files = createBundleSet(1024 * 1024, 15, 50 * 1024, 1000, true); + const locales = generateTranslations(DEFAULT_LOCALES_8, 1000); + const primer = new I18nInliner({ + missingTranslation: 'warning', + persistentCachePath: cacheDir, + maxConcurrency: concurrency, + }); + await primer.inlineAll(files, locales); + await primer.close(); +} + +/** + * 5. Persistent Cache Warm Scenario: + * Evaluates throughput when 100% of transformed files and translations are pre-cached in LMDB. + */ +export function createPersistentCacheWarmScenario( + options: ScenarioFactoryOptions = {}, +): BenchmarkScenario { + let workload: GeneratedWorkload | undefined; + let cacheDir: string | undefined; + + return { + name: 'persistent-cache-warm', + description: + 'Persistent Cache (Warm): 100% LMDB cache hits for transformed files & translations', + get inputSizeBytes() { + return workload?.totalInputSizeBytes ?? 0; + }, + get localeCount() { + return DEFAULT_LOCALES_8.length; + }, + async setup() { + await initializeFixtures(); + cacheDir = await fs.mkdtemp(path.join(os.tmpdir(), 'angular-i18n-bench-cache-')); + const files = createBundleSet(1024 * 1024, 15, 50 * 1024, 1000, true); + const locales = generateTranslations(DEFAULT_LOCALES_8, 1000); + workload = { + files, + locales, + totalInputSizeBytes: calculateInputSizeBytes(files), + }; + + // Prime the persistent cache out-of-process so cold worker thread allocations + // do not inflate this process's RSS metrics. + const primerCode = + `import { primeCache } from ${JSON.stringify(path.resolve(import.meta.dirname, './scenarios.mts'))};\n` + + `await primeCache(${JSON.stringify(cacheDir)}, ${options.concurrency ?? 'undefined'});\n`; + + spawnSync( + process.execPath, + ['--no-warnings=ExperimentalWarning', '--experimental-transform-types', '-e', primerCode], + { stdio: 'inherit' }, + ); + }, + + async run() { + if (!workload || !cacheDir) { + return; + } + const inliner = new I18nInliner({ + missingTranslation: 'warning', + persistentCachePath: cacheDir, + maxConcurrency: options.concurrency, + }); + try { + await inliner.inlineAll(workload.files, workload.locales); + } finally { + await inliner.close(); + } + }, + async teardown() { + if (cacheDir) { + await fs.rm(cacheDir, { recursive: true, force: true }).catch(() => {}); + } + }, + }; +} + +export function getAllScenarios(options: ScenarioFactoryOptions = {}): BenchmarkScenario[] { + return [ + createStandardAppScenario(options), + createStandardAppNoMapsScenario(options), + createEnterpriseScenario(options), + createMonolithicScenario(options), + createPersistentCacheWarmScenario(options), + ]; +} + +export function getScenarioByName( + name: string, + options: ScenarioFactoryOptions = {}, +): BenchmarkScenario | undefined { + const all = getAllScenarios(options); + + return all.find((s) => s.name.toLowerCase() === name.toLowerCase()); +} From 33e6d5feae386b76261117196ca8e3b6676c0dbc Mon Sep 17 00:00:00 2001 From: Charles Lyding <19598772+clydin@users.noreply.github.com> Date: Wed, 16 Sep 2026 15:15:17 -0400 Subject: [PATCH 003/233] test(@angular/build): add large-enterprise-10k benchmark scenario Adds a large-scale stress test scenario to the i18n inliner benchmark suite with 10,000 translation messages across 32 locales. The scenario generates a 3 MB main bundle and 100 route chunks with source maps, evaluating binary translation catalog encoding, small file batching, and memory scaling under maximum enterprise workloads. (cherry picked from commit d285bd85214cedaa31d0bf949381dc5c06f4b164) --- scripts/benchmark.mts | 45 ++++++++++++-- scripts/benchmarks/i18n/fixtures.mts | 4 +- scripts/benchmarks/i18n/harness.mts | 6 +- scripts/benchmarks/i18n/index.mts | 7 ++- scripts/benchmarks/i18n/init-env.mts | 4 +- scripts/benchmarks/i18n/scenarios.mts | 84 +++++++++++++++++++++++++-- 6 files changed, 131 insertions(+), 19 deletions(-) diff --git a/scripts/benchmark.mts b/scripts/benchmark.mts index 2f1d13b8f13b..bf35b97808e3 100644 --- a/scripts/benchmark.mts +++ b/scripts/benchmark.mts @@ -7,6 +7,7 @@ */ import fs from 'node:fs'; +import path from 'node:path'; import { type BenchmarkCliOptions, runI18nBenchmarks } from './benchmarks/i18n/index.mts'; function checkBuildStatus(logger: Console): boolean { @@ -44,6 +45,8 @@ export default async function ( concurrency?: string | number; build?: boolean; json?: boolean; + inProcess?: boolean; + 'in-process'?: boolean; saveBaseline?: string; 'save-baseline'?: string; compareBaseline?: string; @@ -72,6 +75,7 @@ Options: --iterations= Number of measured iterations (default: 5) --warmup= Number of warmup iterations (default: 2) --concurrency= Override worker thread pool concurrency + --in-process Run all scenarios in a single process (useful for debugging) --build Automatically build packages before benchmarking --json Output results in machine-readable JSON --save-baseline= Save run results to a baseline JSON file @@ -99,14 +103,45 @@ Options: return 1; } + const rawSaveBaseline = options.saveBaseline ?? options['save-baseline']; + const rawCompareBaseline = options.compareBaseline ?? options['compare-baseline']; + + const iterations = options.iterations !== undefined ? Number(options.iterations) : undefined; + const warmup = options.warmup !== undefined ? Number(options.warmup) : undefined; + const concurrency = options.concurrency !== undefined ? Number(options.concurrency) : undefined; + + if (iterations !== undefined && (!Number.isInteger(iterations) || iterations < 1)) { + // eslint-disable-next-line no-console + console.error('Error: --iterations must be a positive integer.'); + + return 1; + } + + if (warmup !== undefined && (!Number.isInteger(warmup) || warmup < 0)) { + // eslint-disable-next-line no-console + console.error('Error: --warmup must be a non-negative integer.'); + + return 1; + } + + if (concurrency !== undefined && (!Number.isInteger(concurrency) || concurrency < 1)) { + // eslint-disable-next-line no-console + console.error('Error: --concurrency must be a positive integer.'); + + return 1; + } + const cliOptions: BenchmarkCliOptions = { scenario: options.scenario, - iterations: options.iterations !== undefined ? Number(options.iterations) : undefined, - warmup: options.warmup !== undefined ? Number(options.warmup) : undefined, - concurrency: options.concurrency !== undefined ? Number(options.concurrency) : undefined, + iterations, + warmup, + concurrency, json: Boolean(options.json), - saveBaseline: options.saveBaseline ?? options['save-baseline'], - compareBaseline: options.compareBaseline ?? options['compare-baseline'], + inProcess: Boolean(options.inProcess ?? options['in-process']), + saveBaseline: rawSaveBaseline ? path.resolve(_cwd, String(rawSaveBaseline)) : undefined, + compareBaseline: rawCompareBaseline + ? path.resolve(_cwd, String(rawCompareBaseline)) + : undefined, }; const { exitCode } = await runI18nBenchmarks(cliOptions); diff --git a/scripts/benchmarks/i18n/fixtures.mts b/scripts/benchmarks/i18n/fixtures.mts index 16305b766bec..3d53c3dbff5b 100644 --- a/scripts/benchmarks/i18n/fixtures.mts +++ b/scripts/benchmarks/i18n/fixtures.mts @@ -13,8 +13,8 @@ import { createRequire } from 'node:module'; import path from 'node:path'; -import type { BuildOutputFile } from '../../../dist/@angular/build/src/tools/esbuild/bundler-files.d.ts'; -import type { LocaleInlineOptions } from '../../../dist/@angular/build/src/tools/esbuild/i18n-inliner.d.ts'; +import type { BuildOutputFile } from '../../../packages/angular/build/src/tools/esbuild/bundler-files.js'; +import type { LocaleInlineOptions } from '../../../packages/angular/build/src/tools/esbuild/i18n-inliner.js'; // Setup module paths to resolve dependencies from packages/angular/build const requireFromBuild = createRequire( diff --git a/scripts/benchmarks/i18n/harness.mts b/scripts/benchmarks/i18n/harness.mts index 700199c0af0b..caf7f0753d24 100644 --- a/scripts/benchmarks/i18n/harness.mts +++ b/scripts/benchmarks/i18n/harness.mts @@ -63,9 +63,9 @@ export async function runScenario( const warmup = options.warmup ?? 2; const iterations = options.iterations ?? 5; - await scenario.setup?.(); - try { + await scenario.setup?.(); + // Warmup phase for (let w = 0; w < warmup; w++) { // Force GC if available between warmups @@ -106,10 +106,10 @@ export async function runScenario( if (rssDelta > maxRssDeltaBytes) { maxRssDeltaBytes = rssDelta; } - finalHeap = memAfter.heapUsed; // Force GC immediately after iteration to clean main thread isolate global.gc?.(); + finalHeap = process.memoryUsage().heapUsed; } // Sort ascending for percentile computation diff --git a/scripts/benchmarks/i18n/index.mts b/scripts/benchmarks/i18n/index.mts index 8b6503d60e83..276671c193e0 100644 --- a/scripts/benchmarks/i18n/index.mts +++ b/scripts/benchmarks/i18n/index.mts @@ -82,9 +82,12 @@ export async function runI18nBenchmarks( } const proc = spawnSync(process.execPath, args, { encoding: 'utf-8' }); - if (proc.status !== 0) { + if (proc.status !== 0 || proc.error) { // eslint-disable-next-line no-console - console.error(`Error running scenario ${scenario.name}:\n${proc.stderr || proc.stdout}`); + console.error( + `Error running scenario ${scenario.name}:\n` + + (proc.error?.message ?? (proc.stderr || proc.stdout)), + ); return { results, exitCode: 1 }; } diff --git a/scripts/benchmarks/i18n/init-env.mts b/scripts/benchmarks/i18n/init-env.mts index 679281e4dc18..a1690cf576c8 100644 --- a/scripts/benchmarks/i18n/init-env.mts +++ b/scripts/benchmarks/i18n/init-env.mts @@ -17,7 +17,9 @@ const buildNodeModules = path.resolve( const currentPath = process.env.NODE_PATH ?? ''; if (!currentPath.includes(buildNodeModules)) { - process.env.NODE_PATH = currentPath ? `${buildNodeModules}:${currentPath}` : buildNodeModules; + process.env.NODE_PATH = currentPath + ? `${buildNodeModules}${path.delimiter}${currentPath}` + : buildNodeModules; // Initialize internal search paths for Node CommonJS loader // eslint-disable-next-line @typescript-eslint/no-explicit-any (Module as any)._initPaths?.(); diff --git a/scripts/benchmarks/i18n/scenarios.mts b/scripts/benchmarks/i18n/scenarios.mts index f862e28c04f6..c00f34ded8a2 100644 --- a/scripts/benchmarks/i18n/scenarios.mts +++ b/scripts/benchmarks/i18n/scenarios.mts @@ -13,9 +13,10 @@ import fs from 'node:fs/promises'; import { createRequire } from 'node:module'; import os from 'node:os'; import path from 'node:path'; +import { pathToFileURL } from 'node:url'; -import type { BuildOutputFile } from '../../../dist/@angular/build/src/tools/esbuild/bundler-files.d.ts'; -import type { LocaleInlineOptions } from '../../../dist/@angular/build/src/tools/esbuild/i18n-inliner.d.ts'; +import type { BuildOutputFile } from '../../../packages/angular/build/src/tools/esbuild/bundler-files.js'; +import type { LocaleInlineOptions } from '../../../packages/angular/build/src/tools/esbuild/i18n-inliner.js'; import { generateSyntheticBundle, generateTranslations, initializeFixtures } from './fixtures.mts'; import type { BenchmarkScenario } from './harness.mts'; @@ -25,7 +26,7 @@ const requireFromBuild = createRequire( const { I18nInliner } = requireFromBuild( '../../../dist/@angular/build/src/tools/esbuild/i18n-inliner.js', -) as typeof import('../../../dist/@angular/build/src/tools/esbuild/i18n-inliner.d.ts'); +) as typeof import('../../../packages/angular/build/src/tools/esbuild/i18n-inliner.js'); export interface ScenarioFactoryOptions { concurrency?: number; @@ -124,6 +125,15 @@ function calculateInputSizeBytes(files: BuildOutputFile[]): number { }, 0); } +/** + * Note on Worker Pool Lifecycle: + * Each scenario's run() method instantiates and closes an I18nInliner per iteration. + * This is designed as a macro benchmark to reflect the cold-start behavior of single-shot + * CLI build invocations (including worker thread pool initialization, task dispatch, + * inlining transformations, and thread pool shutdown). Warmup iterations warm up the + * main-thread V8 isolate and runtime paths, while worker threads are initialized per iteration. + */ + /** * 1. Standard App Scenario: * 1 main bundle (1 MB) + 20 route chunks (50 KB) = ~2 MB input JS, 8 locales, maps enabled. @@ -350,15 +360,28 @@ export function createPersistentCacheWarmScenario( // Prime the persistent cache out-of-process so cold worker thread allocations // do not inflate this process's RSS metrics. + const scenariosUrl = pathToFileURL(path.resolve(import.meta.dirname, './scenarios.mts')).href; const primerCode = - `import { primeCache } from ${JSON.stringify(path.resolve(import.meta.dirname, './scenarios.mts'))};\n` + + `import { primeCache } from ${JSON.stringify(scenariosUrl)};\n` + `await primeCache(${JSON.stringify(cacheDir)}, ${options.concurrency ?? 'undefined'});\n`; - spawnSync( + const primerProc = spawnSync( process.execPath, - ['--no-warnings=ExperimentalWarning', '--experimental-transform-types', '-e', primerCode], + [ + '--no-warnings=ExperimentalWarning', + '--experimental-transform-types', + '--input-type=module', + '-e', + primerCode, + ], { stdio: 'inherit' }, ); + + if (primerProc.status !== 0 || primerProc.error) { + throw new Error( + `Failed to prime cache for persistent-cache-warm scenario: ${primerProc.error?.message ?? primerProc.status}`, + ); + } }, async run() { @@ -384,11 +407,60 @@ export function createPersistentCacheWarmScenario( }; } +/** + * 6. Large Enterprise (10k translations) Scenario: + * 1 main bundle (3 MB) + 100 chunks (50 KB), 32 locales, 10,000 translations, sourcemaps ON. + * Maximum scale stress test for binary translation tables, memory retention, and multi-locale windows. + */ +export function createLargeEnterpriseScenario( + options: ScenarioFactoryOptions = {}, +): BenchmarkScenario { + let workload: GeneratedWorkload | undefined; + + return { + name: 'large-enterprise-10k', + description: + 'Large Enterprise (10k msgs): 1 main (3 MB) + 100 chunks (50 KB), 32 locales, 10,000 translations', + get inputSizeBytes() { + return workload?.totalInputSizeBytes ?? 0; + }, + get localeCount() { + return DEFAULT_LOCALES_32.length; + }, + async setup() { + await initializeFixtures(); + const files = createBundleSet(3 * 1024 * 1024, 100, 50 * 1024, 10000, true); + const locales = generateTranslations(DEFAULT_LOCALES_32, 10000); + + workload = { + files, + locales, + totalInputSizeBytes: calculateInputSizeBytes(files), + }; + }, + async run() { + if (!workload) { + return; + } + const inliner = new I18nInliner({ + missingTranslation: 'warning', + maxConcurrency: options.concurrency, + }); + try { + await inliner.inlineAll(workload.files, workload.locales); + } finally { + await inliner.close(); + } + }, + }; +} + export function getAllScenarios(options: ScenarioFactoryOptions = {}): BenchmarkScenario[] { return [ createStandardAppScenario(options), createStandardAppNoMapsScenario(options), createEnterpriseScenario(options), + createLargeEnterpriseScenario(options), createMonolithicScenario(options), createPersistentCacheWarmScenario(options), ]; From 24dc029343b9034a7c550fb437dfba0a2e19bce6 Mon Sep 17 00:00:00 2001 From: Angular Robot Date: Wed, 16 Sep 2026 19:27:50 +0000 Subject: [PATCH 004/233] 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 +-- 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 | 325 +++++++++--------- 14 files changed, 262 insertions(+), 279 deletions(-) diff --git a/.github/workflows/assistant-to-the-branch-manager.yml b/.github/workflows/assistant-to-the-branch-manager.yml index 30585fa707fd..c767c09e4f07 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@183403ae13b785698eaf13c819dda55b9fed430b # main + - uses: angular/dev-infra/github-actions/branch-manager@837e71330341e19050ebc3808e02d7fb2d112be5 # main with: angular-robot-key: ${{ secrets.ANGULAR_ROBOT_PRIVATE_KEY }} diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 5fad471f1244..80027a577866 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@183403ae13b785698eaf13c819dda55b9fed430b # main + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@837e71330341e19050ebc3808e02d7fb2d112be5 # main - name: Setup Bazel - uses: angular/dev-infra/github-actions/bazel/setup@183403ae13b785698eaf13c819dda55b9fed430b # main + uses: angular/dev-infra/github-actions/bazel/setup@837e71330341e19050ebc3808e02d7fb2d112be5 # 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@183403ae13b785698eaf13c819dda55b9fed430b # main + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@837e71330341e19050ebc3808e02d7fb2d112be5 # main - name: Setup Bazel - uses: angular/dev-infra/github-actions/bazel/setup@183403ae13b785698eaf13c819dda55b9fed430b # main + uses: angular/dev-infra/github-actions/bazel/setup@837e71330341e19050ebc3808e02d7fb2d112be5 # main - name: Setup Bazel RBE - uses: angular/dev-infra/github-actions/bazel/configure-remote@183403ae13b785698eaf13c819dda55b9fed430b # main + uses: angular/dev-infra/github-actions/bazel/configure-remote@837e71330341e19050ebc3808e02d7fb2d112be5 # 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@183403ae13b785698eaf13c819dda55b9fed430b # main + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@837e71330341e19050ebc3808e02d7fb2d112be5 # main - name: Setup Bazel - uses: angular/dev-infra/github-actions/bazel/setup@183403ae13b785698eaf13c819dda55b9fed430b # main + uses: angular/dev-infra/github-actions/bazel/setup@837e71330341e19050ebc3808e02d7fb2d112be5 # main - name: Setup Bazel RBE - uses: angular/dev-infra/github-actions/bazel/configure-remote@183403ae13b785698eaf13c819dda55b9fed430b # main + uses: angular/dev-infra/github-actions/bazel/configure-remote@837e71330341e19050ebc3808e02d7fb2d112be5 # 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@183403ae13b785698eaf13c819dda55b9fed430b # main + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@837e71330341e19050ebc3808e02d7fb2d112be5 # main - name: Install node modules run: pnpm install --frozen-lockfile - name: Setup Bazel - uses: angular/dev-infra/github-actions/bazel/setup@183403ae13b785698eaf13c819dda55b9fed430b # main + uses: angular/dev-infra/github-actions/bazel/setup@837e71330341e19050ebc3808e02d7fb2d112be5 # main - name: Setup Bazel RBE - uses: angular/dev-infra/github-actions/bazel/configure-remote@183403ae13b785698eaf13c819dda55b9fed430b # main + uses: angular/dev-infra/github-actions/bazel/configure-remote@837e71330341e19050ebc3808e02d7fb2d112be5 # 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@183403ae13b785698eaf13c819dda55b9fed430b # main + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@837e71330341e19050ebc3808e02d7fb2d112be5 # main - name: Setup Bazel - uses: angular/dev-infra/github-actions/bazel/setup@183403ae13b785698eaf13c819dda55b9fed430b # main + uses: angular/dev-infra/github-actions/bazel/setup@837e71330341e19050ebc3808e02d7fb2d112be5 # main - name: Setup Bazel RBE - uses: angular/dev-infra/github-actions/bazel/configure-remote@183403ae13b785698eaf13c819dda55b9fed430b # main + uses: angular/dev-infra/github-actions/bazel/configure-remote@837e71330341e19050ebc3808e02d7fb2d112be5 # 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@183403ae13b785698eaf13c819dda55b9fed430b # main + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@837e71330341e19050ebc3808e02d7fb2d112be5 # 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@183403ae13b785698eaf13c819dda55b9fed430b # main + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@837e71330341e19050ebc3808e02d7fb2d112be5 # main - name: Install node modules run: pnpm install --frozen-lockfile - name: Setup Bazel - uses: angular/dev-infra/github-actions/bazel/setup@183403ae13b785698eaf13c819dda55b9fed430b # main + uses: angular/dev-infra/github-actions/bazel/setup@837e71330341e19050ebc3808e02d7fb2d112be5 # main - name: Setup Bazel RBE - uses: angular/dev-infra/github-actions/bazel/configure-remote@183403ae13b785698eaf13c819dda55b9fed430b # main + uses: angular/dev-infra/github-actions/bazel/configure-remote@837e71330341e19050ebc3808e02d7fb2d112be5 # 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@183403ae13b785698eaf13c819dda55b9fed430b # main + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@837e71330341e19050ebc3808e02d7fb2d112be5 # main - name: Install node modules run: pnpm install --frozen-lockfile - name: Setup Bazel - uses: angular/dev-infra/github-actions/bazel/setup@183403ae13b785698eaf13c819dda55b9fed430b # main + uses: angular/dev-infra/github-actions/bazel/setup@837e71330341e19050ebc3808e02d7fb2d112be5 # main - name: Setup Bazel RBE - uses: angular/dev-infra/github-actions/bazel/configure-remote@183403ae13b785698eaf13c819dda55b9fed430b # main + uses: angular/dev-infra/github-actions/bazel/configure-remote@837e71330341e19050ebc3808e02d7fb2d112be5 # 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@183403ae13b785698eaf13c819dda55b9fed430b # main + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@837e71330341e19050ebc3808e02d7fb2d112be5 # main - name: Install node modules run: pnpm install --frozen-lockfile - name: Setup Bazel - uses: angular/dev-infra/github-actions/bazel/setup@183403ae13b785698eaf13c819dda55b9fed430b # main + uses: angular/dev-infra/github-actions/bazel/setup@837e71330341e19050ebc3808e02d7fb2d112be5 # main - name: Setup Bazel RBE - uses: angular/dev-infra/github-actions/bazel/configure-remote@183403ae13b785698eaf13c819dda55b9fed430b # main + uses: angular/dev-infra/github-actions/bazel/configure-remote@837e71330341e19050ebc3808e02d7fb2d112be5 # 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@183403ae13b785698eaf13c819dda55b9fed430b # main + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@837e71330341e19050ebc3808e02d7fb2d112be5 # main - name: Install node modules run: pnpm install --frozen-lockfile - name: Setup Bazel - uses: angular/dev-infra/github-actions/bazel/setup@183403ae13b785698eaf13c819dda55b9fed430b # main + uses: angular/dev-infra/github-actions/bazel/setup@837e71330341e19050ebc3808e02d7fb2d112be5 # 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 bb05d9b3dbfe..4dc1c8378728 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@183403ae13b785698eaf13c819dda55b9fed430b # main + - uses: angular/dev-infra/github-actions/labeling/pull-request@837e71330341e19050ebc3808e02d7fb2d112be5 # 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@183403ae13b785698eaf13c819dda55b9fed430b # main + - uses: angular/dev-infra/github-actions/post-approval-changes@837e71330341e19050ebc3808e02d7fb2d112be5 # 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@183403ae13b785698eaf13c819dda55b9fed430b # main + - uses: angular/dev-infra/github-actions/labeling/issue@837e71330341e19050ebc3808e02d7fb2d112be5 # 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 504f7e5136ad..84b5b8cfb21d 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@183403ae13b785698eaf13c819dda55b9fed430b # main + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@837e71330341e19050ebc3808e02d7fb2d112be5 # 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@183403ae13b785698eaf13c819dda55b9fed430b # main + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@837e71330341e19050ebc3808e02d7fb2d112be5 # main - name: Setup Bazel - uses: angular/dev-infra/github-actions/bazel/setup@183403ae13b785698eaf13c819dda55b9fed430b # main + uses: angular/dev-infra/github-actions/bazel/setup@837e71330341e19050ebc3808e02d7fb2d112be5 # 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 8b2baafbd3b4..400910007dda 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@183403ae13b785698eaf13c819dda55b9fed430b # main + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@837e71330341e19050ebc3808e02d7fb2d112be5 # main - name: Setup Bazel - uses: angular/dev-infra/github-actions/bazel/setup@183403ae13b785698eaf13c819dda55b9fed430b # main + uses: angular/dev-infra/github-actions/bazel/setup@837e71330341e19050ebc3808e02d7fb2d112be5 # 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@183403ae13b785698eaf13c819dda55b9fed430b # main + uses: angular/dev-infra/github-actions/linting/licenses@837e71330341e19050ebc3808e02d7fb2d112be5 # main build: runs-on: ubuntu-latest steps: - name: Initialize environment - uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@183403ae13b785698eaf13c819dda55b9fed430b # main + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@837e71330341e19050ebc3808e02d7fb2d112be5 # main - name: Setup Bazel - uses: angular/dev-infra/github-actions/bazel/setup@183403ae13b785698eaf13c819dda55b9fed430b # main + uses: angular/dev-infra/github-actions/bazel/setup@837e71330341e19050ebc3808e02d7fb2d112be5 # main - name: Setup Bazel RBE - uses: angular/dev-infra/github-actions/bazel/configure-remote@183403ae13b785698eaf13c819dda55b9fed430b # main + uses: angular/dev-infra/github-actions/bazel/configure-remote@837e71330341e19050ebc3808e02d7fb2d112be5 # 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@183403ae13b785698eaf13c819dda55b9fed430b # main + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@837e71330341e19050ebc3808e02d7fb2d112be5 # main - name: Setup Bazel - uses: angular/dev-infra/github-actions/bazel/setup@183403ae13b785698eaf13c819dda55b9fed430b # main + uses: angular/dev-infra/github-actions/bazel/setup@837e71330341e19050ebc3808e02d7fb2d112be5 # main - name: Setup Bazel RBE - uses: angular/dev-infra/github-actions/bazel/configure-remote@183403ae13b785698eaf13c819dda55b9fed430b # main + uses: angular/dev-infra/github-actions/bazel/configure-remote@837e71330341e19050ebc3808e02d7fb2d112be5 # 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@183403ae13b785698eaf13c819dda55b9fed430b # main + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@837e71330341e19050ebc3808e02d7fb2d112be5 # main - name: Install node modules run: pnpm install --frozen-lockfile - name: Setup Bazel - uses: angular/dev-infra/github-actions/bazel/setup@183403ae13b785698eaf13c819dda55b9fed430b # main + uses: angular/dev-infra/github-actions/bazel/setup@837e71330341e19050ebc3808e02d7fb2d112be5 # main - name: Setup Bazel RBE - uses: angular/dev-infra/github-actions/bazel/configure-remote@183403ae13b785698eaf13c819dda55b9fed430b # main + uses: angular/dev-infra/github-actions/bazel/configure-remote@837e71330341e19050ebc3808e02d7fb2d112be5 # 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@183403ae13b785698eaf13c819dda55b9fed430b # main + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@837e71330341e19050ebc3808e02d7fb2d112be5 # main - name: Setup Bazel - uses: angular/dev-infra/github-actions/bazel/setup@183403ae13b785698eaf13c819dda55b9fed430b # main + uses: angular/dev-infra/github-actions/bazel/setup@837e71330341e19050ebc3808e02d7fb2d112be5 # main - name: Setup Bazel RBE - uses: angular/dev-infra/github-actions/bazel/configure-remote@183403ae13b785698eaf13c819dda55b9fed430b # main + uses: angular/dev-infra/github-actions/bazel/configure-remote@837e71330341e19050ebc3808e02d7fb2d112be5 # 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@183403ae13b785698eaf13c819dda55b9fed430b # main + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@837e71330341e19050ebc3808e02d7fb2d112be5 # 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@183403ae13b785698eaf13c819dda55b9fed430b # main + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@837e71330341e19050ebc3808e02d7fb2d112be5 # main - name: Install node modules run: pnpm install --frozen-lockfile - name: Setup Bazel - uses: angular/dev-infra/github-actions/bazel/setup@183403ae13b785698eaf13c819dda55b9fed430b # main + uses: angular/dev-infra/github-actions/bazel/setup@837e71330341e19050ebc3808e02d7fb2d112be5 # main - name: Setup Bazel RBE - uses: angular/dev-infra/github-actions/bazel/configure-remote@183403ae13b785698eaf13c819dda55b9fed430b # main + uses: angular/dev-infra/github-actions/bazel/configure-remote@837e71330341e19050ebc3808e02d7fb2d112be5 # 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@183403ae13b785698eaf13c819dda55b9fed430b # main + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@837e71330341e19050ebc3808e02d7fb2d112be5 # main - name: Install node modules run: pnpm install --frozen-lockfile - name: Setup Bazel - uses: angular/dev-infra/github-actions/bazel/setup@183403ae13b785698eaf13c819dda55b9fed430b # main + uses: angular/dev-infra/github-actions/bazel/setup@837e71330341e19050ebc3808e02d7fb2d112be5 # main - name: Setup Bazel RBE - uses: angular/dev-infra/github-actions/bazel/configure-remote@183403ae13b785698eaf13c819dda55b9fed430b # main + uses: angular/dev-infra/github-actions/bazel/configure-remote@837e71330341e19050ebc3808e02d7fb2d112be5 # 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 470c5e258947..d5d7e9df8670 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 = "5fa856469c642490a6e381a05d7f58f60fad1913", + commit = "3f933b9dde5139e67575b6c2437c854986ecd10a", remote = "https://github.com/angular/rules_angular.git", ) bazel_dep(name = "devinfra") git_override( module_name = "devinfra", - commit = "183403ae13b785698eaf13c819dda55b9fed430b", + commit = "837e71330341e19050ebc3808e02d7fb2d112be5", remote = "https://github.com/angular/dev-infra.git", ) bazel_dep(name = "rules_browsers") git_override( module_name = "rules_browsers", - commit = "c37398d63f5e990d618d02f4c6fb2fefe40f1a79", + commit = "f87a5f7fc587219ff328da2972e06370f297a621", remote = "https://github.com/angular/rules_browsers.git", ) diff --git a/MODULE.bazel.lock b/MODULE.bazel.lock index 43e07b4b4f31..27af19eb5cb6 100644 --- a/MODULE.bazel.lock +++ b/MODULE.bazel.lock @@ -433,16 +433,16 @@ }, "@@rules_browsers+//browsers:extensions.bzl%browsers": { "general": { - "bzlTransitiveDigest": "eNfcpVF2YJFb8xQfN64Y9PQgMrXYK0ju3uglArt8IO8=", + "bzlTransitiveDigest": "jwGo+QiVY+i/AnJLUkEJ+vaplFYfygil2SJt8C7kM5o=", "usagesDigest": "FmXYJVoVJlnfUU8x8gObSvu4qWcco/9Faw61aC/wBF0=", "recordedInputs": [], "generatedRepoSpecs": { "rules_browsers_chrome_linux": { "repoRuleId": "@@rules_browsers+//browsers/private:browser_repo.bzl%browser_repo", "attributes": { - "sha256": "ad2e73e1e42c0831930dfd02d4aa8653a5f23f60b0376a5d76ddf8ecd7a41e4b", + "sha256": "11d48f3e2ee11fc2a53a230eb364b2becc44c1b67a7aa4683edb7cb8a950b6ab", "urls": [ - "https://storage.googleapis.com/chrome-for-testing-public/155.0.8043.0/linux64/chrome-headless-shell-linux64.zip" + "https://storage.googleapis.com/chrome-for-testing-public/156.0.8060.2/linux64/chrome-headless-shell-linux64.zip" ], "named_files": { "CHROME-HEADLESS-SHELL": "chrome-headless-shell-linux64/chrome-headless-shell" @@ -458,9 +458,9 @@ "rules_browsers_chrome_mac": { "repoRuleId": "@@rules_browsers+//browsers/private:browser_repo.bzl%browser_repo", "attributes": { - "sha256": "d66b730ed9760ae88b83aca1fa89351ac027ede430be4f5283fabd156198762d", + "sha256": "42c60eb1793fe76aabf19664b03c299170e5de53baa23ae72578f063dc9b2614", "urls": [ - "https://storage.googleapis.com/chrome-for-testing-public/155.0.8043.0/mac-x64/chrome-headless-shell-mac-x64.zip" + "https://storage.googleapis.com/chrome-for-testing-public/156.0.8060.2/mac-x64/chrome-headless-shell-mac-x64.zip" ], "named_files": { "CHROME-HEADLESS-SHELL": "chrome-headless-shell-mac-x64/chrome-headless-shell" @@ -476,9 +476,9 @@ "rules_browsers_chrome_mac_arm": { "repoRuleId": "@@rules_browsers+//browsers/private:browser_repo.bzl%browser_repo", "attributes": { - "sha256": "44c784c59af60ef62233b6100820ebb8b158e7d105b96c684818f007d6576848", + "sha256": "4afc1dbaeea03ad545b434c0f9eba50af326923fc265bc25927b3b4c7d9ca377", "urls": [ - "https://storage.googleapis.com/chrome-for-testing-public/155.0.8043.0/mac-arm64/chrome-headless-shell-mac-arm64.zip" + "https://storage.googleapis.com/chrome-for-testing-public/156.0.8060.2/mac-arm64/chrome-headless-shell-mac-arm64.zip" ], "named_files": { "CHROME-HEADLESS-SHELL": "chrome-headless-shell-mac-arm64/chrome-headless-shell" @@ -494,9 +494,9 @@ "rules_browsers_chrome_win64": { "repoRuleId": "@@rules_browsers+//browsers/private:browser_repo.bzl%browser_repo", "attributes": { - "sha256": "996537a6c3d31bb5c75ef328af5d4827b5f92c4a36ff7ea250e437eadf46eac0", + "sha256": "9de8381d4ca9c9f0471fd1cce15e44146328c3e11f55fec43cd667ae1a5bd482", "urls": [ - "https://storage.googleapis.com/chrome-for-testing-public/155.0.8043.0/win64/chrome-headless-shell-win64.zip" + "https://storage.googleapis.com/chrome-for-testing-public/156.0.8060.2/win64/chrome-headless-shell-win64.zip" ], "named_files": { "CHROME-HEADLESS-SHELL": "chrome-headless-shell-win64/chrome-headless-shell.exe" @@ -512,9 +512,9 @@ "rules_browsers_chromedriver_linux": { "repoRuleId": "@@rules_browsers+//browsers/private:browser_repo.bzl%browser_repo", "attributes": { - "sha256": "f1db8caff52251dec46117a2f518a74cd1e4a2abadcbecc0d5bdd49e42175afa", + "sha256": "29be812bf4392619d06dfb5716d2bf9d72a278304670a594e3977d4c2cce7502", "urls": [ - "https://storage.googleapis.com/chrome-for-testing-public/155.0.8043.0/linux64/chromedriver-linux64.zip" + "https://storage.googleapis.com/chrome-for-testing-public/156.0.8060.2/linux64/chromedriver-linux64.zip" ], "named_files": { "CHROMEDRIVER": "chromedriver-linux64/chromedriver" @@ -528,9 +528,9 @@ "rules_browsers_chromedriver_mac": { "repoRuleId": "@@rules_browsers+//browsers/private:browser_repo.bzl%browser_repo", "attributes": { - "sha256": "5062675bc868f3f6a1e4850cab72b736a5c17f98f01d610736b8d0a6e009bf54", + "sha256": "d4dc141aadd9525e67c92fc78ec65e2926226c436eca7d90e39cdc813726513d", "urls": [ - "https://storage.googleapis.com/chrome-for-testing-public/155.0.8043.0/mac-x64/chromedriver-mac-x64.zip" + "https://storage.googleapis.com/chrome-for-testing-public/156.0.8060.2/mac-x64/chromedriver-mac-x64.zip" ], "named_files": { "CHROMEDRIVER": "chromedriver-mac-x64/chromedriver" @@ -544,9 +544,9 @@ "rules_browsers_chromedriver_mac_arm": { "repoRuleId": "@@rules_browsers+//browsers/private:browser_repo.bzl%browser_repo", "attributes": { - "sha256": "04f07a2a13e969f120dbea61eef291dc4e20617a6d424dec20e90f903da0263b", + "sha256": "984056c6d3dd189569cc89affd28564a9de949d58297279fc23a045c8fc53080", "urls": [ - "https://storage.googleapis.com/chrome-for-testing-public/155.0.8043.0/mac-arm64/chromedriver-mac-arm64.zip" + "https://storage.googleapis.com/chrome-for-testing-public/156.0.8060.2/mac-arm64/chromedriver-mac-arm64.zip" ], "named_files": { "CHROMEDRIVER": "chromedriver-mac-arm64/chromedriver" @@ -560,9 +560,9 @@ "rules_browsers_chromedriver_win64": { "repoRuleId": "@@rules_browsers+//browsers/private:browser_repo.bzl%browser_repo", "attributes": { - "sha256": "7701074890112ed3b780af26104cb9f57ce68e229ca3076bfade6a1af93730d7", + "sha256": "a5bcbd013b64e6a15acc84c164fe974d0f1a58d4e061fba79d24b31cced64d88", "urls": [ - "https://storage.googleapis.com/chrome-for-testing-public/155.0.8043.0/win64/chromedriver-win64.zip" + "https://storage.googleapis.com/chrome-for-testing-public/156.0.8060.2/win64/chromedriver-win64.zip" ], "named_files": { "CHROMEDRIVER": "chromedriver-win64/chromedriver.exe" @@ -576,9 +576,9 @@ "rules_browsers_firefox_linux": { "repoRuleId": "@@rules_browsers+//browsers/private:browser_repo.bzl%browser_repo", "attributes": { - "sha256": "fd9ec3f5f113d0825ca0bd1ab3c0756fbc40241034eefce6743be953bcca7473", + "sha256": "1d44cd02351c307c3e19061ea2a4d18a30f236e6be862b94f2282564afdb0167", "urls": [ - "https://archive.mozilla.org/pub/firefox/releases/155.0/linux-x86_64/en-US/firefox-155.0.tar.xz" + "https://archive.mozilla.org/pub/firefox/releases/156.0/linux-x86_64/en-US/firefox-156.0.tar.xz" ], "named_files": { "FIREFOX": "firefox/firefox" @@ -592,9 +592,9 @@ "rules_browsers_firefox_mac": { "repoRuleId": "@@rules_browsers+//browsers/private:browser_repo.bzl%browser_repo", "attributes": { - "sha256": "3ae135f2023cf0c6cbce3bb757e06564ff8148b1266f682b8eccff0993a1a9f5", + "sha256": "fecc46103039ca4a77ecb2b2ef7b03892f922e13db0782f8570c512b2e458515", "urls": [ - "https://archive.mozilla.org/pub/firefox/releases/155.0/mac/en-US/Firefox%20155.0.dmg" + "https://archive.mozilla.org/pub/firefox/releases/156.0/mac/en-US/Firefox%20156.0.dmg" ], "named_files": { "FIREFOX": "Firefox.app/Contents/MacOS/firefox" @@ -608,9 +608,9 @@ "rules_browsers_firefox_mac_arm": { "repoRuleId": "@@rules_browsers+//browsers/private:browser_repo.bzl%browser_repo", "attributes": { - "sha256": "3ae135f2023cf0c6cbce3bb757e06564ff8148b1266f682b8eccff0993a1a9f5", + "sha256": "fecc46103039ca4a77ecb2b2ef7b03892f922e13db0782f8570c512b2e458515", "urls": [ - "https://archive.mozilla.org/pub/firefox/releases/155.0/mac/en-US/Firefox%20155.0.dmg" + "https://archive.mozilla.org/pub/firefox/releases/156.0/mac/en-US/Firefox%20156.0.dmg" ], "named_files": { "FIREFOX": "Firefox.app/Contents/MacOS/firefox" @@ -624,9 +624,9 @@ "rules_browsers_firefox_win64": { "repoRuleId": "@@rules_browsers+//browsers/private:browser_repo.bzl%browser_repo", "attributes": { - "sha256": "2718d4cc4b2cf089aa8ac370111652bc763838e1d2ed6d635d465fc17ab6327c", + "sha256": "86a027237f7408e8a4d18637c57d487455a704cbb2466a32d0d14c2207d2699a", "urls": [ - "https://archive.mozilla.org/pub/firefox/releases/155.0/win64/en-US/Firefox%20Setup%20155.0.exe" + "https://archive.mozilla.org/pub/firefox/releases/156.0/win64/en-US/Firefox%20Setup%20156.0.exe" ], "named_files": { "FIREFOX": "core/firefox.exe" diff --git a/modules/testing/builder/package.json b/modules/testing/builder/package.json index 3e0dc743f7ea..d76148352027 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.5", + "ng-packagr": "22.2.0-rc.0", "rxjs": "7.8.2", "vitest": "5.0.1" } diff --git a/package.json b/package.json index 1cd8f7ceaac3..49ef7f8b1128 100644 --- a/package.json +++ b/package.json @@ -43,23 +43,23 @@ }, "homepage": "https://github.com/angular/angular-cli", "dependencies": { - "@angular/compiler-cli": "22.2.0-next.5", + "@angular/compiler-cli": "22.2.0-rc.0", "typescript": "6.0.3" }, "devDependencies": { - "@angular/animations": "22.2.0-next.5", - "@angular/cdk": "22.2.0-next.4", - "@angular/common": "22.2.0-next.5", - "@angular/compiler": "22.2.0-next.5", - "@angular/core": "22.2.0-next.5", - "@angular/forms": "22.2.0-next.5", - "@angular/localize": "22.2.0-next.5", - "@angular/material": "22.2.0-next.4", - "@angular/ng-dev": "https://github.com/angular/dev-infra-private-ng-dev-builds.git#c3d7ed184d71d390d3eacff85f4b2b3f16b82660", - "@angular/platform-browser": "22.2.0-next.5", - "@angular/platform-server": "22.2.0-next.5", - "@angular/router": "22.2.0-next.5", - "@angular/service-worker": "22.2.0-next.5", + "@angular/animations": "22.2.0-rc.0", + "@angular/cdk": "22.2.0-rc.0", + "@angular/common": "22.2.0-rc.0", + "@angular/compiler": "22.2.0-rc.0", + "@angular/core": "22.2.0-rc.0", + "@angular/forms": "22.2.0-rc.0", + "@angular/localize": "22.2.0-rc.0", + "@angular/material": "22.2.0-rc.0", + "@angular/ng-dev": "https://github.com/angular/dev-infra-private-ng-dev-builds.git#f166178ac5c37cd3aadab7b8cb7212f34d71b2a6", + "@angular/platform-browser": "22.2.0-rc.0", + "@angular/platform-server": "22.2.0-rc.0", + "@angular/router": "22.2.0-rc.0", + "@angular/service-worker": "22.2.0-rc.0", "@babel/core": "8.0.5", "@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 25d640c7619f..9e0b0b7c4ff1 100644 --- a/packages/angular/build/package.json +++ b/packages/angular/build/package.json @@ -57,7 +57,7 @@ "istanbul-lib-instrument": "6.0.3", "jsdom": "30.0.1", "less": "4.9.1", - "ng-packagr": "22.2.0-next.5", + "ng-packagr": "22.2.0-rc.0", "postcss": "8.5.28", "rollup": "4.63.3", "rxjs": "7.8.2", diff --git a/packages/angular/ssr/package.json b/packages/angular/ssr/package.json index 82edb52e27d8..b48e12387746 100644 --- a/packages/angular/ssr/package.json +++ b/packages/angular/ssr/package.json @@ -38,12 +38,12 @@ }, "devDependencies": { "@angular-devkit/schematics": "workspace:*", - "@angular/common": "22.2.0-next.5", - "@angular/compiler": "22.2.0-next.5", - "@angular/core": "22.2.0-next.5", - "@angular/platform-browser": "22.2.0-next.5", - "@angular/platform-server": "22.2.0-next.5", - "@angular/router": "22.2.0-next.5", + "@angular/common": "22.2.0-rc.0", + "@angular/compiler": "22.2.0-rc.0", + "@angular/core": "22.2.0-rc.0", + "@angular/platform-browser": "22.2.0-rc.0", + "@angular/platform-server": "22.2.0-rc.0", + "@angular/router": "22.2.0-rc.0", "@schematics/angular": "workspace:*" }, "sideEffects": false, diff --git a/packages/angular_devkit/build_angular/package.json b/packages/angular_devkit/build_angular/package.json index d7b95edd650a..4f699d7fbac5 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.5", + "ng-packagr": "22.2.0-rc.0", "sass": "1.104.1", "undici": "8.10.2" }, diff --git a/packages/ngtools/webpack/package.json b/packages/ngtools/webpack/package.json index aaca4ed7005e..07e9660520f8 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.5", - "@angular/compiler-cli": "22.2.0-next.5", + "@angular/compiler": "22.2.0-rc.0", + "@angular/compiler-cli": "22.2.0-rc.0", "typescript": "6.0.3", "webpack": "5.111.0" } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index e4cb97b4c448..11feaf7d1151 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -172,8 +172,8 @@ importers: .: dependencies: '@angular/compiler-cli': - specifier: 22.2.0-next.5 - version: 22.2.0-next.5(@angular/compiler@22.2.0-next.5)(typescript@6.0.3) + specifier: 22.2.0-rc.0 + version: 22.2.0-rc.0(@angular/compiler@22.2.0-rc.0)(typescript@6.0.3) typescript: specifier: 6.0.3 version: 6.0.3 @@ -184,44 +184,44 @@ importers: built: true devDependencies: '@angular/animations': - specifier: 22.2.0-next.5 - version: 22.2.0-next.5(@angular/core@22.2.0-next.5(@angular/compiler@22.2.0-next.5)(rxjs@7.8.2)(zone.js@0.16.3)) + specifier: 22.2.0-rc.0 + version: 22.2.0-rc.0(@angular/core@22.2.0-rc.0(@angular/compiler@22.2.0-rc.0)(rxjs@7.8.2)(zone.js@0.16.3)) '@angular/cdk': - specifier: 22.2.0-next.4 - version: 22.2.0-next.4(164cec07f845c9f2a6f509bb1888cfce) + specifier: 22.2.0-rc.0 + version: 22.2.0-rc.0(32444abcc2be6e3bf2b6c059aa24d737) '@angular/common': - specifier: 22.2.0-next.5 - version: 22.2.0-next.5(@angular/core@22.2.0-next.5(@angular/compiler@22.2.0-next.5)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2) + specifier: 22.2.0-rc.0 + version: 22.2.0-rc.0(@angular/core@22.2.0-rc.0(@angular/compiler@22.2.0-rc.0)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2) '@angular/compiler': - specifier: 22.2.0-next.5 - version: 22.2.0-next.5 + specifier: 22.2.0-rc.0 + version: 22.2.0-rc.0 '@angular/core': - specifier: 22.2.0-next.5 - version: 22.2.0-next.5(@angular/compiler@22.2.0-next.5)(rxjs@7.8.2)(zone.js@0.16.3) + specifier: 22.2.0-rc.0 + version: 22.2.0-rc.0(@angular/compiler@22.2.0-rc.0)(rxjs@7.8.2)(zone.js@0.16.3) '@angular/forms': - specifier: 22.2.0-next.5 - version: 22.2.0-next.5(@angular/common@22.2.0-next.5(@angular/core@22.2.0-next.5(@angular/compiler@22.2.0-next.5)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2))(@angular/core@22.2.0-next.5(@angular/compiler@22.2.0-next.5)(rxjs@7.8.2)(zone.js@0.16.3))(@angular/platform-browser@22.2.0-next.5(@angular/animations@22.2.0-next.5(@angular/core@22.2.0-next.5(@angular/compiler@22.2.0-next.5)(rxjs@7.8.2)(zone.js@0.16.3)))(@angular/common@22.2.0-next.5(@angular/core@22.2.0-next.5(@angular/compiler@22.2.0-next.5)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2))(@angular/core@22.2.0-next.5(@angular/compiler@22.2.0-next.5)(rxjs@7.8.2)(zone.js@0.16.3)))(rxjs@7.8.2) + specifier: 22.2.0-rc.0 + version: 22.2.0-rc.0(@angular/common@22.2.0-rc.0(@angular/core@22.2.0-rc.0(@angular/compiler@22.2.0-rc.0)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2))(@angular/core@22.2.0-rc.0(@angular/compiler@22.2.0-rc.0)(rxjs@7.8.2)(zone.js@0.16.3))(@angular/platform-browser@22.2.0-rc.0(@angular/animations@22.2.0-rc.0(@angular/core@22.2.0-rc.0(@angular/compiler@22.2.0-rc.0)(rxjs@7.8.2)(zone.js@0.16.3)))(@angular/common@22.2.0-rc.0(@angular/core@22.2.0-rc.0(@angular/compiler@22.2.0-rc.0)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2))(@angular/core@22.2.0-rc.0(@angular/compiler@22.2.0-rc.0)(rxjs@7.8.2)(zone.js@0.16.3)))(rxjs@7.8.2) '@angular/localize': - specifier: 22.2.0-next.5 - version: 22.2.0-next.5(@angular/compiler-cli@22.2.0-next.5(@angular/compiler@22.2.0-next.5)(typescript@6.0.3))(@angular/compiler@22.2.0-next.5) + specifier: 22.2.0-rc.0 + version: 22.2.0-rc.0(@angular/compiler-cli@22.2.0-rc.0(@angular/compiler@22.2.0-rc.0)(typescript@6.0.3))(@angular/compiler@22.2.0-rc.0) '@angular/material': - specifier: 22.2.0-next.4 - version: 22.2.0-next.4(95bc9c8a06206acb56b97c62cbcd354e) + specifier: 22.2.0-rc.0 + version: 22.2.0-rc.0(25ddf4063a130bbf19862bd16a6ab5d4) '@angular/ng-dev': - specifier: https://github.com/angular/dev-infra-private-ng-dev-builds.git#c3d7ed184d71d390d3eacff85f4b2b3f16b82660 - version: https://codeload.github.com/angular/dev-infra-private-ng-dev-builds/tar.gz/c3d7ed184d71d390d3eacff85f4b2b3f16b82660 + specifier: https://github.com/angular/dev-infra-private-ng-dev-builds.git#f166178ac5c37cd3aadab7b8cb7212f34d71b2a6 + version: https://codeload.github.com/angular/dev-infra-private-ng-dev-builds/tar.gz/f166178ac5c37cd3aadab7b8cb7212f34d71b2a6 '@angular/platform-browser': - specifier: 22.2.0-next.5 - version: 22.2.0-next.5(@angular/animations@22.2.0-next.5(@angular/core@22.2.0-next.5(@angular/compiler@22.2.0-next.5)(rxjs@7.8.2)(zone.js@0.16.3)))(@angular/common@22.2.0-next.5(@angular/core@22.2.0-next.5(@angular/compiler@22.2.0-next.5)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2))(@angular/core@22.2.0-next.5(@angular/compiler@22.2.0-next.5)(rxjs@7.8.2)(zone.js@0.16.3)) + specifier: 22.2.0-rc.0 + version: 22.2.0-rc.0(@angular/animations@22.2.0-rc.0(@angular/core@22.2.0-rc.0(@angular/compiler@22.2.0-rc.0)(rxjs@7.8.2)(zone.js@0.16.3)))(@angular/common@22.2.0-rc.0(@angular/core@22.2.0-rc.0(@angular/compiler@22.2.0-rc.0)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2))(@angular/core@22.2.0-rc.0(@angular/compiler@22.2.0-rc.0)(rxjs@7.8.2)(zone.js@0.16.3)) '@angular/platform-server': - specifier: 22.2.0-next.5 - version: 22.2.0-next.5(@angular/common@22.2.0-next.5(@angular/core@22.2.0-next.5(@angular/compiler@22.2.0-next.5)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2))(@angular/compiler@22.2.0-next.5)(@angular/core@22.2.0-next.5(@angular/compiler@22.2.0-next.5)(rxjs@7.8.2)(zone.js@0.16.3))(@angular/platform-browser@22.2.0-next.5(@angular/animations@22.2.0-next.5(@angular/core@22.2.0-next.5(@angular/compiler@22.2.0-next.5)(rxjs@7.8.2)(zone.js@0.16.3)))(@angular/common@22.2.0-next.5(@angular/core@22.2.0-next.5(@angular/compiler@22.2.0-next.5)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2))(@angular/core@22.2.0-next.5(@angular/compiler@22.2.0-next.5)(rxjs@7.8.2)(zone.js@0.16.3)))(rxjs@7.8.2) + specifier: 22.2.0-rc.0 + version: 22.2.0-rc.0(@angular/common@22.2.0-rc.0(@angular/core@22.2.0-rc.0(@angular/compiler@22.2.0-rc.0)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2))(@angular/compiler@22.2.0-rc.0)(@angular/core@22.2.0-rc.0(@angular/compiler@22.2.0-rc.0)(rxjs@7.8.2)(zone.js@0.16.3))(@angular/platform-browser@22.2.0-rc.0(@angular/animations@22.2.0-rc.0(@angular/core@22.2.0-rc.0(@angular/compiler@22.2.0-rc.0)(rxjs@7.8.2)(zone.js@0.16.3)))(@angular/common@22.2.0-rc.0(@angular/core@22.2.0-rc.0(@angular/compiler@22.2.0-rc.0)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2))(@angular/core@22.2.0-rc.0(@angular/compiler@22.2.0-rc.0)(rxjs@7.8.2)(zone.js@0.16.3)))(rxjs@7.8.2) '@angular/router': - specifier: 22.2.0-next.5 - version: 22.2.0-next.5(@angular/common@22.2.0-next.5(@angular/core@22.2.0-next.5(@angular/compiler@22.2.0-next.5)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2))(@angular/core@22.2.0-next.5(@angular/compiler@22.2.0-next.5)(rxjs@7.8.2)(zone.js@0.16.3))(@angular/platform-browser@22.2.0-next.5(@angular/animations@22.2.0-next.5(@angular/core@22.2.0-next.5(@angular/compiler@22.2.0-next.5)(rxjs@7.8.2)(zone.js@0.16.3)))(@angular/common@22.2.0-next.5(@angular/core@22.2.0-next.5(@angular/compiler@22.2.0-next.5)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2))(@angular/core@22.2.0-next.5(@angular/compiler@22.2.0-next.5)(rxjs@7.8.2)(zone.js@0.16.3)))(rxjs@7.8.2) + specifier: 22.2.0-rc.0 + version: 22.2.0-rc.0(@angular/common@22.2.0-rc.0(@angular/core@22.2.0-rc.0(@angular/compiler@22.2.0-rc.0)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2))(@angular/core@22.2.0-rc.0(@angular/compiler@22.2.0-rc.0)(rxjs@7.8.2)(zone.js@0.16.3))(@angular/platform-browser@22.2.0-rc.0(@angular/animations@22.2.0-rc.0(@angular/core@22.2.0-rc.0(@angular/compiler@22.2.0-rc.0)(rxjs@7.8.2)(zone.js@0.16.3)))(@angular/common@22.2.0-rc.0(@angular/core@22.2.0-rc.0(@angular/compiler@22.2.0-rc.0)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2))(@angular/core@22.2.0-rc.0(@angular/compiler@22.2.0-rc.0)(rxjs@7.8.2)(zone.js@0.16.3)))(rxjs@7.8.2) '@angular/service-worker': - specifier: 22.2.0-next.5 - version: 22.2.0-next.5(@angular/core@22.2.0-next.5(@angular/compiler@22.2.0-next.5)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2) + specifier: 22.2.0-rc.0 + version: 22.2.0-rc.0(@angular/core@22.2.0-rc.0(@angular/compiler@22.2.0-rc.0)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2) '@babel/core': specifier: 8.0.5 version: 8.0.5 @@ -463,8 +463,8 @@ importers: specifier: 30.0.1 version: 30.0.1 ng-packagr: - specifier: 22.2.0-next.5 - version: 22.2.0-next.5(@angular/compiler-cli@22.2.0-next.5(@angular/compiler@22.2.0-next.5)(typescript@6.0.3))(supports-color@11.0.0)(tslib@2.8.1)(typescript@6.0.3) + specifier: 22.2.0-rc.0 + version: 22.2.0-rc.0(@angular/compiler-cli@22.2.0-rc.0(@angular/compiler@22.2.0-rc.0)(typescript@6.0.3))(supports-color@11.0.0)(tslib@2.8.1)(typescript@6.0.3) rxjs: specifier: 7.8.2 version: 7.8.2 @@ -578,8 +578,8 @@ importers: specifier: 4.9.1 version: 4.9.1(supports-color@11.0.0) ng-packagr: - specifier: 22.2.0-next.5 - version: 22.2.0-next.5(@angular/compiler-cli@22.2.0-next.5(@angular/compiler@22.2.0-next.5)(typescript@6.0.3))(supports-color@11.0.0)(tslib@2.8.1)(typescript@6.0.3) + specifier: 22.2.0-rc.0 + version: 22.2.0-rc.0(@angular/compiler-cli@22.2.0-rc.0(@angular/compiler@22.2.0-rc.0)(typescript@6.0.3))(supports-color@11.0.0)(tslib@2.8.1)(typescript@6.0.3) postcss: specifier: 8.5.28 version: 8.5.28 @@ -667,23 +667,23 @@ importers: specifier: workspace:* version: link:../../angular_devkit/schematics '@angular/common': - specifier: 22.2.0-next.5 - version: 22.2.0-next.5(@angular/core@22.2.0-next.5(@angular/compiler@22.2.0-next.5)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2) + specifier: 22.2.0-rc.0 + version: 22.2.0-rc.0(@angular/core@22.2.0-rc.0(@angular/compiler@22.2.0-rc.0)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2) '@angular/compiler': - specifier: 22.2.0-next.5 - version: 22.2.0-next.5 + specifier: 22.2.0-rc.0 + version: 22.2.0-rc.0 '@angular/core': - specifier: 22.2.0-next.5 - version: 22.2.0-next.5(@angular/compiler@22.2.0-next.5)(rxjs@7.8.2)(zone.js@0.16.3) + specifier: 22.2.0-rc.0 + version: 22.2.0-rc.0(@angular/compiler@22.2.0-rc.0)(rxjs@7.8.2)(zone.js@0.16.3) '@angular/platform-browser': - specifier: 22.2.0-next.5 - version: 22.2.0-next.5(@angular/animations@22.2.0-next.5(@angular/core@22.2.0-next.5(@angular/compiler@22.2.0-next.5)(rxjs@7.8.2)(zone.js@0.16.3)))(@angular/common@22.2.0-next.5(@angular/core@22.2.0-next.5(@angular/compiler@22.2.0-next.5)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2))(@angular/core@22.2.0-next.5(@angular/compiler@22.2.0-next.5)(rxjs@7.8.2)(zone.js@0.16.3)) + specifier: 22.2.0-rc.0 + version: 22.2.0-rc.0(@angular/animations@22.2.0-rc.0(@angular/core@22.2.0-rc.0(@angular/compiler@22.2.0-rc.0)(rxjs@7.8.2)(zone.js@0.16.3)))(@angular/common@22.2.0-rc.0(@angular/core@22.2.0-rc.0(@angular/compiler@22.2.0-rc.0)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2))(@angular/core@22.2.0-rc.0(@angular/compiler@22.2.0-rc.0)(rxjs@7.8.2)(zone.js@0.16.3)) '@angular/platform-server': - specifier: 22.2.0-next.5 - version: 22.2.0-next.5(@angular/common@22.2.0-next.5(@angular/core@22.2.0-next.5(@angular/compiler@22.2.0-next.5)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2))(@angular/compiler@22.2.0-next.5)(@angular/core@22.2.0-next.5(@angular/compiler@22.2.0-next.5)(rxjs@7.8.2)(zone.js@0.16.3))(@angular/platform-browser@22.2.0-next.5(@angular/animations@22.2.0-next.5(@angular/core@22.2.0-next.5(@angular/compiler@22.2.0-next.5)(rxjs@7.8.2)(zone.js@0.16.3)))(@angular/common@22.2.0-next.5(@angular/core@22.2.0-next.5(@angular/compiler@22.2.0-next.5)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2))(@angular/core@22.2.0-next.5(@angular/compiler@22.2.0-next.5)(rxjs@7.8.2)(zone.js@0.16.3)))(rxjs@7.8.2) + specifier: 22.2.0-rc.0 + version: 22.2.0-rc.0(@angular/common@22.2.0-rc.0(@angular/core@22.2.0-rc.0(@angular/compiler@22.2.0-rc.0)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2))(@angular/compiler@22.2.0-rc.0)(@angular/core@22.2.0-rc.0(@angular/compiler@22.2.0-rc.0)(rxjs@7.8.2)(zone.js@0.16.3))(@angular/platform-browser@22.2.0-rc.0(@angular/animations@22.2.0-rc.0(@angular/core@22.2.0-rc.0(@angular/compiler@22.2.0-rc.0)(rxjs@7.8.2)(zone.js@0.16.3)))(@angular/common@22.2.0-rc.0(@angular/core@22.2.0-rc.0(@angular/compiler@22.2.0-rc.0)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2))(@angular/core@22.2.0-rc.0(@angular/compiler@22.2.0-rc.0)(rxjs@7.8.2)(zone.js@0.16.3)))(rxjs@7.8.2) '@angular/router': - specifier: 22.2.0-next.5 - version: 22.2.0-next.5(@angular/common@22.2.0-next.5(@angular/core@22.2.0-next.5(@angular/compiler@22.2.0-next.5)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2))(@angular/core@22.2.0-next.5(@angular/compiler@22.2.0-next.5)(rxjs@7.8.2)(zone.js@0.16.3))(@angular/platform-browser@22.2.0-next.5(@angular/animations@22.2.0-next.5(@angular/core@22.2.0-next.5(@angular/compiler@22.2.0-next.5)(rxjs@7.8.2)(zone.js@0.16.3)))(@angular/common@22.2.0-next.5(@angular/core@22.2.0-next.5(@angular/compiler@22.2.0-next.5)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2))(@angular/core@22.2.0-next.5(@angular/compiler@22.2.0-next.5)(rxjs@7.8.2)(zone.js@0.16.3)))(rxjs@7.8.2) + specifier: 22.2.0-rc.0 + version: 22.2.0-rc.0(@angular/common@22.2.0-rc.0(@angular/core@22.2.0-rc.0(@angular/compiler@22.2.0-rc.0)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2))(@angular/core@22.2.0-rc.0(@angular/compiler@22.2.0-rc.0)(rxjs@7.8.2)(zone.js@0.16.3))(@angular/platform-browser@22.2.0-rc.0(@angular/animations@22.2.0-rc.0(@angular/core@22.2.0-rc.0(@angular/compiler@22.2.0-rc.0)(rxjs@7.8.2)(zone.js@0.16.3)))(@angular/common@22.2.0-rc.0(@angular/core@22.2.0-rc.0(@angular/compiler@22.2.0-rc.0)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2))(@angular/core@22.2.0-rc.0(@angular/compiler@22.2.0-rc.0)(rxjs@7.8.2)(zone.js@0.16.3)))(rxjs@7.8.2) '@schematics/angular': specifier: workspace:* version: link:../../schematics/angular @@ -866,8 +866,8 @@ importers: specifier: 3.0.4 version: 3.0.4(bufferutil@4.1.0)(debug@4.4.3(supports-color@11.0.0))(supports-color@11.0.0)(utf-8-validate@6.0.6) ng-packagr: - specifier: 22.2.0-next.5 - version: 22.2.0-next.5(@angular/compiler-cli@22.2.0-next.5(@angular/compiler@22.2.0-next.5)(typescript@6.0.3))(supports-color@11.0.0)(tslib@2.8.1)(typescript@6.0.3) + specifier: 22.2.0-rc.0 + version: 22.2.0-rc.0(@angular/compiler-cli@22.2.0-rc.0(@angular/compiler@22.2.0-rc.0)(typescript@6.0.3))(supports-color@11.0.0)(tslib@2.8.1)(typescript@6.0.3) sass: specifier: 1.104.1 version: 1.104.1 @@ -962,11 +962,11 @@ importers: specifier: workspace:0.0.0-PLACEHOLDER version: link:../../angular_devkit/core '@angular/compiler': - specifier: 22.2.0-next.5 - version: 22.2.0-next.5 + specifier: 22.2.0-rc.0 + version: 22.2.0-rc.0 '@angular/compiler-cli': - specifier: 22.2.0-next.5 - version: 22.2.0-next.5(@angular/compiler@22.2.0-next.5)(typescript@6.0.3) + specifier: 22.2.0-rc.0 + version: 22.2.0-rc.0(@angular/compiler@22.2.0-rc.0)(typescript@6.0.3) typescript: specifier: 6.0.3 version: 6.0.3 @@ -1026,15 +1026,14 @@ packages: resolution: {integrity: sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==} engines: {node: '>=6.0.0'} - '@angular/animations@22.2.0-next.5': - resolution: {integrity: sha512-Q2ImjJNM14L+jKh5EvxDtooRf8tshZ+rlomtf24AI6Cxr7FelPXwPOZbYmHkPu0y5hqhey5+WNG5RQLRvKjiLQ==} + '@angular/animations@22.2.0-rc.0': + resolution: {integrity: sha512-MnkNstor6AH92M9ps7RZfcCyUo24SqBZU71soDgYC3aXFJhSYOtJFPKE1/KgrpVt416lTzbhHe/68kAZ3cH9MQ==} 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.5 + '@angular/core': 22.2.0-rc.0 - '@angular/cdk@22.2.0-next.4': - resolution: {integrity: sha512-ZqORCqi7eGIXgiObGA1Lmf7+l+7VP5gp7/ge3cNHUOcJP6HRJlt4ISjUFT+j7t9FU1lkf6nNBSwEcIG2EI+EGw==} + '@angular/cdk@22.2.0-rc.0': + resolution: {integrity: sha512-fG3/uCItdRj+PSetdHOIcd72VUekKhdj/uazHuhjjE1mz7gJJx0WBzDk1CcGUYtfvq0WoYlv9Kq6rhnP2gBAdw==} 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 @@ -1042,33 +1041,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.5': - resolution: {integrity: sha512-D11bjuSXSuIB+EQ04Ep1NyhbvuJHbZqKBkNzXDK0Mfkkbjfl9rN4YOs7vGNcXOm/pFXWSR4DR5IqQWeiiSlUBQ==} + '@angular/common@22.2.0-rc.0': + resolution: {integrity: sha512-j80c+FC/yZ2jz0d6w/kPwvEdMhaIol23gt/IcZxOigvElUywpNfm+g36XjM34/UNy6HDhew5ck7HE9DWYVXwsw==} engines: {node: ^22.22.3 || ^24.15.0 || >=26.0.0} peerDependencies: - '@angular/core': 22.2.0-next.5 + '@angular/core': 22.2.0-rc.0 rxjs: ^6.5.3 || ^7.4.0 - '@angular/compiler-cli@22.2.0-next.5': - resolution: {integrity: sha512-zuAYA4ZAYf1HY82nJRuo7Ft00YwAiRo/aZGuRSU4A+RlHROq57X1W8NyINdMpMPEyL2O14WgRG2/MlGDKnF49Q==} + '@angular/compiler-cli@22.2.0-rc.0': + resolution: {integrity: sha512-51yfbHuAd09YnH5tTLb9jIxzkqFTB8SAj6Gv2/LqR+xDq7AGaZgFiehQOa2pa9kDJ3wNHYbTROF7dHP+AXXj2w==} engines: {node: ^22.22.3 || ^24.15.0 || >=26.0.0} hasBin: true peerDependencies: - '@angular/compiler': 22.2.0-next.5 + '@angular/compiler': 22.2.0-rc.0 typescript: '>=6.0 <6.1' peerDependenciesMeta: typescript: optional: true - '@angular/compiler@22.2.0-next.5': - resolution: {integrity: sha512-EZ3O1e0aQDsYPX8jffsX7mNoyqWHOMqpzP4ULjt45JZkpAT/H/Ss7p8MFKnox60AFbvmEENm/srcnDJ5s9sTLA==} + '@angular/compiler@22.2.0-rc.0': + resolution: {integrity: sha512-vWavQPwkNQhie4/KKGycoQrGGPNcjKbn8VkmMiIcfPVCMtvNvhs8ssPgKENYDXaFRyg+UtJ1Y/2HRdYtIQIw8g==} engines: {node: ^22.22.3 || ^24.15.0 || >=26.0.0} - '@angular/core@22.2.0-next.5': - resolution: {integrity: sha512-Gh+JycsZiZhVZEODpCBEc20XXl6aIN/w+bB7A9a7/d0bMRdX3IBtYNxCOMor9L7bJVfwD+N3NTWpb+wSv81wMQ==} + '@angular/core@22.2.0-rc.0': + resolution: {integrity: sha512-HbeWk0EatMmOf5VF71W35WCVZ9nwjHkeXvdhee+1uZfr2cmpnS3OXuFrIgTP2kSrILc6jEh7xuHW/IT1itjHuA==} engines: {node: ^22.22.3 || ^24.15.0 || >=26.0.0} peerDependencies: - '@angular/compiler': 22.2.0-next.5 + '@angular/compiler': 22.2.0-rc.0 rxjs: ^6.5.3 || ^7.4.0 zone.js: ~0.15.0 || ~0.16.0 peerDependenciesMeta: @@ -1077,74 +1076,74 @@ packages: zone.js: optional: true - '@angular/forms@22.2.0-next.5': - resolution: {integrity: sha512-eyECVvZ/pJGKzXTWf3SC1d+hSIVWQvJreiCo0kX2e9pDzuGoK5Br8gifP38tgwym2FuR/5THJRn2K998pUZ4Xg==} + '@angular/forms@22.2.0-rc.0': + resolution: {integrity: sha512-mg+NratvkCH9ihGBplqZBKS2Q8+eLDdZSyl10FWmIzhaTmJEk9GLoZ70n4kEU0rX65hy2oF0M2aTBpr2CRxZ4w==} engines: {node: ^22.22.3 || ^24.15.0 || >=26.0.0} peerDependencies: - '@angular/common': 22.2.0-next.5 - '@angular/core': 22.2.0-next.5 - '@angular/platform-browser': 22.2.0-next.5 + '@angular/common': 22.2.0-rc.0 + '@angular/core': 22.2.0-rc.0 + '@angular/platform-browser': 22.2.0-rc.0 rxjs: ^6.5.3 || ^7.4.0 - '@angular/localize@22.2.0-next.5': - resolution: {integrity: sha512-kquo2tv5g3SF33acN6SQpiOwr0TpP45/iKRLkX/xcWY6XZ7S9bxU4W6CiJ4fZfelfTDKBr6ZhxA8QNnw7Y1Z8w==} + '@angular/localize@22.2.0-rc.0': + resolution: {integrity: sha512-c0WgdyX0GYrx4hBF9KEPaOXFIcz+j9dIgLDG2hcsxLdjE9r+trmTBFwhR/4/Q7S5GThbnty4/rjVJOrRXpdi7Q==} engines: {node: ^22.22.3 || ^24.15.0 || >=26.0.0} hasBin: true peerDependencies: - '@angular/compiler': 22.2.0-next.5 - '@angular/compiler-cli': 22.2.0-next.5 + '@angular/compiler': 22.2.0-rc.0 + '@angular/compiler-cli': 22.2.0-rc.0 - '@angular/material@22.2.0-next.4': - resolution: {integrity: sha512-BTGnryNFfLvN8jI02msMNbHdNVcOaFL0MMH8S+jpQc8ooULx8bRwQZSWk8LKusayVyZH4JbT3YvV7PW/qw0ndA==} + '@angular/material@22.2.0-rc.0': + resolution: {integrity: sha512-3IaSPe7LnbhJHzo95xAfY0vB7nA5tDxx+ojn8MSZTa/m6Cw8aCRMZiSiJ783Qw7x1doWz37o3Z7B54Wp8n/2Jw==} peerDependencies: - '@angular/cdk': 22.2.0-next.4 + '@angular/cdk': 22.2.0-rc.0 '@angular/common': ^22.0.0-0 || ^22.1.0-0 || ^22.2.0-0 || ^22.3.0-0 || ^23.0.0-0 '@angular/core': ^22.0.0-0 || ^22.1.0-0 || ^22.2.0-0 || ^22.3.0-0 || ^23.0.0-0 '@angular/forms': ^22.0.0-0 || ^22.1.0-0 || ^22.2.0-0 || ^22.3.0-0 || ^23.0.0-0 '@angular/platform-browser': ^22.0.0-0 || ^22.1.0-0 || ^22.2.0-0 || ^22.3.0-0 || ^23.0.0-0 rxjs: ^6.5.3 || ^7.4.0 - '@angular/ng-dev@https://codeload.github.com/angular/dev-infra-private-ng-dev-builds/tar.gz/c3d7ed184d71d390d3eacff85f4b2b3f16b82660': - resolution: {gitHosted: true, integrity: sha512-DBHbT5IV4wnEUd5/+wh1cTxmwKNsxGahmN4DJ92T1aY5DcvCxhsoedLtHNX9Wi81hNEc37phIr+qaDsZWQVdQw==, tarball: https://codeload.github.com/angular/dev-infra-private-ng-dev-builds/tar.gz/c3d7ed184d71d390d3eacff85f4b2b3f16b82660} - version: 0.0.0-f5c817076b8e4da7b6e91783dbcd553c5003a296 + '@angular/ng-dev@https://codeload.github.com/angular/dev-infra-private-ng-dev-builds/tar.gz/f166178ac5c37cd3aadab7b8cb7212f34d71b2a6': + resolution: {gitHosted: true, integrity: sha512-5NrBeSt7Q//Qrxhy1OVNDNuGiZLdFOaIPMLtCgjypDsJc214fEI4xRKqN7zIpAQfMlZDoIFMh7vodM/uB9oq3A==, tarball: https://codeload.github.com/angular/dev-infra-private-ng-dev-builds/tar.gz/f166178ac5c37cd3aadab7b8cb7212f34d71b2a6} + version: 0.0.0-cde7ad16c16f5c7dbd57b62e8b930443813484ec hasBin: true - '@angular/platform-browser@22.2.0-next.5': - resolution: {integrity: sha512-eSTpC4/SqkQ6QDTblFNznT7jRwX9o4X1cO7Hf+F0p07hofbbi8ptDXl0iZs6643C5eSaoyp1Bncd8wJzwoFmPw==} + '@angular/platform-browser@22.2.0-rc.0': + resolution: {integrity: sha512-poN1dCkFKM1t288v/5M2w+OUzragcUuEt3GQfcQQ87lIWCp5atCpClpXxbFJj0VUeYXPKvb9rUwQtFtTMzYohA==} engines: {node: ^22.22.3 || ^24.15.0 || >=26.0.0} peerDependencies: - '@angular/animations': 22.2.0-next.5 - '@angular/common': 22.2.0-next.5 - '@angular/core': 22.2.0-next.5 + '@angular/animations': 22.2.0-rc.0 + '@angular/common': 22.2.0-rc.0 + '@angular/core': 22.2.0-rc.0 peerDependenciesMeta: '@angular/animations': optional: true - '@angular/platform-server@22.2.0-next.5': - resolution: {integrity: sha512-MrXjF0GI2CSnNBbAhOJXjsXraL5H3P32VaG9Eh6DJNNZpR6pzM9HWOjbXHQ1elrYNBN2rV67HRSiDkRYu46AVw==} + '@angular/platform-server@22.2.0-rc.0': + resolution: {integrity: sha512-bohsXRaIV/d/RqFqbsdpmNpmcmurSrV/a1I7lo7IEzJJXAVchHBD/JIjJYFOk+NgqLDYZciq6Z8fF8idLfv1YQ==} engines: {node: ^22.22.3 || ^24.15.0 || >=26.0.0} peerDependencies: - '@angular/common': 22.2.0-next.5 - '@angular/compiler': 22.2.0-next.5 - '@angular/core': 22.2.0-next.5 - '@angular/platform-browser': 22.2.0-next.5 + '@angular/common': 22.2.0-rc.0 + '@angular/compiler': 22.2.0-rc.0 + '@angular/core': 22.2.0-rc.0 + '@angular/platform-browser': 22.2.0-rc.0 rxjs: ^6.5.3 || ^7.4.0 - '@angular/router@22.2.0-next.5': - resolution: {integrity: sha512-40viSK016CMgwVjbW8oLLv0zZSWCNVCFG1bqxOnqujPbP/lW3vlu4ul0Ine9tUlKnkfNZKV+NTCQtHlY1li+5Q==} + '@angular/router@22.2.0-rc.0': + resolution: {integrity: sha512-bIOOdp5T3KM4vB2xL4L6fpXYQ3vJmkPRB+k2tXSb4xW1HLsJDEyGN9GNj/5prnLbaWIGqcfhGNwnTW/mCVm42A==} engines: {node: ^22.22.3 || ^24.15.0 || >=26.0.0} peerDependencies: - '@angular/common': 22.2.0-next.5 - '@angular/core': 22.2.0-next.5 - '@angular/platform-browser': 22.2.0-next.5 + '@angular/common': 22.2.0-rc.0 + '@angular/core': 22.2.0-rc.0 + '@angular/platform-browser': 22.2.0-rc.0 rxjs: ^6.5.3 || ^7.4.0 - '@angular/service-worker@22.2.0-next.5': - resolution: {integrity: sha512-z8oExlAiu3oKkKQFZ0AXnmk1K9jw/+lLEv9IRhuQM1abPNKfFo9AHE298dPZLoE3wqumg85No2u8AJJX9w/1sw==} + '@angular/service-worker@22.2.0-rc.0': + resolution: {integrity: sha512-y03a1Ppfyi765n8QlRgVqeL5kF8k5mFOVxvK+ZlxONave1mN2ChG37Yu35gzJ22wiprBDUgxGm3UdLvscU3YkA==} engines: {node: ^22.22.3 || ^24.15.0 || >=26.0.0} hasBin: true peerDependencies: - '@angular/core': 22.2.0-next.5 + '@angular/core': 22.2.0-rc.0 rxjs: ^6.5.3 || ^7.4.0 '@asamuzakjp/css-color@6.0.7': @@ -1187,10 +1186,6 @@ packages: resolution: {integrity: sha512-gZbepsdh3WDtgZKWL+vTPh71LSBrm/Y4/QDZBVCcYfmeTEEuoOYwlSy+G1StfJg+/Zy550u/3TATbm7qDbbMtg==} engines: {node: '>=6.9.0'} - '@babel/generator@8.0.0': - resolution: {integrity: sha512-NT9NrVwJsbSV6Y2FSstWa71EETOnzrjkL5/wX3D2mYHtKM+qvqB1DvR4D0Setb/gDBsHzRICifwEWMO8CnTF6g==} - engines: {node: ^22.18.0 || >=24.11.0} - '@babel/generator@8.0.5': resolution: {integrity: sha512-f/TuhuMAxJqhwxEGNsJrswuG9VHmh0oNFoQoo6TbpgtFAz9wYZXcTAcWZMHfp7ljesr0RG04bp3Aos9GI59L7w==} engines: {node: ^22.18.0 || >=24.11.0} @@ -6768,8 +6763,8 @@ packages: neo-async@2.6.2: resolution: {integrity: sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==} - ng-packagr@22.2.0-next.5: - resolution: {integrity: sha512-fZixAT5MGDlxZnPISy1ml22DeOFVMwt3Ym/6l/VwzuAlj1K0YVJNgxxRQs+iX/qqDzcXjyVD+CQAAwAq5pQo3Q==} + ng-packagr@22.2.0-rc.0: + resolution: {integrity: sha512-l91WqbCFBKpVmDwW/rttDNe6kpRjsIlHnUf55YTH5JqN0Q7uVGBy6QbRUV2S+4/StyFqc+keOAtVPJUdO2bvxw==} engines: {node: ^22.22.3 || ^24.15.0 || >=26.0.0} hasBin: true peerDependencies: @@ -8794,9 +8789,6 @@ packages: zod@3.25.76: resolution: {integrity: sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ==} - zod@4.5.4: - resolution: {integrity: sha512-sC95tT5iHHH9gtpj6A81kh+NEaRAUFN+qlUPDUbRfOMvNf5QCBqsb3WgvnpVtK5Y+4UfA6KqufotuTvMGiTlsA==} - zod@4.6.5: resolution: {integrity: sha512-v5l/aFXZQeai4awLbOpSoHecE9UiMrnfx75tEXLjNonXVARxQ5mOeipTjROUchszUNCqnE+hqAMujRsRHsut2Q==} @@ -8826,30 +8818,30 @@ snapshots: '@jridgewell/gen-mapping': 0.3.13 '@jridgewell/trace-mapping': 0.3.31 - '@angular/animations@22.2.0-next.5(@angular/core@22.2.0-next.5(@angular/compiler@22.2.0-next.5)(rxjs@7.8.2)(zone.js@0.16.3))': + '@angular/animations@22.2.0-rc.0(@angular/core@22.2.0-rc.0(@angular/compiler@22.2.0-rc.0)(rxjs@7.8.2)(zone.js@0.16.3))': dependencies: - '@angular/core': 22.2.0-next.5(@angular/compiler@22.2.0-next.5)(rxjs@7.8.2)(zone.js@0.16.3) + '@angular/core': 22.2.0-rc.0(@angular/compiler@22.2.0-rc.0)(rxjs@7.8.2)(zone.js@0.16.3) tslib: 2.8.1 - '@angular/cdk@22.2.0-next.4(164cec07f845c9f2a6f509bb1888cfce)': + '@angular/cdk@22.2.0-rc.0(32444abcc2be6e3bf2b6c059aa24d737)': dependencies: - '@angular/common': 22.2.0-next.5(@angular/core@22.2.0-next.5(@angular/compiler@22.2.0-next.5)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2) - '@angular/core': 22.2.0-next.5(@angular/compiler@22.2.0-next.5)(rxjs@7.8.2)(zone.js@0.16.3) - '@angular/forms': 22.2.0-next.5(@angular/common@22.2.0-next.5(@angular/core@22.2.0-next.5(@angular/compiler@22.2.0-next.5)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2))(@angular/core@22.2.0-next.5(@angular/compiler@22.2.0-next.5)(rxjs@7.8.2)(zone.js@0.16.3))(@angular/platform-browser@22.2.0-next.5(@angular/animations@22.2.0-next.5(@angular/core@22.2.0-next.5(@angular/compiler@22.2.0-next.5)(rxjs@7.8.2)(zone.js@0.16.3)))(@angular/common@22.2.0-next.5(@angular/core@22.2.0-next.5(@angular/compiler@22.2.0-next.5)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2))(@angular/core@22.2.0-next.5(@angular/compiler@22.2.0-next.5)(rxjs@7.8.2)(zone.js@0.16.3)))(rxjs@7.8.2) - '@angular/platform-browser': 22.2.0-next.5(@angular/animations@22.2.0-next.5(@angular/core@22.2.0-next.5(@angular/compiler@22.2.0-next.5)(rxjs@7.8.2)(zone.js@0.16.3)))(@angular/common@22.2.0-next.5(@angular/core@22.2.0-next.5(@angular/compiler@22.2.0-next.5)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2))(@angular/core@22.2.0-next.5(@angular/compiler@22.2.0-next.5)(rxjs@7.8.2)(zone.js@0.16.3)) + '@angular/common': 22.2.0-rc.0(@angular/core@22.2.0-rc.0(@angular/compiler@22.2.0-rc.0)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2) + '@angular/core': 22.2.0-rc.0(@angular/compiler@22.2.0-rc.0)(rxjs@7.8.2)(zone.js@0.16.3) + '@angular/forms': 22.2.0-rc.0(@angular/common@22.2.0-rc.0(@angular/core@22.2.0-rc.0(@angular/compiler@22.2.0-rc.0)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2))(@angular/core@22.2.0-rc.0(@angular/compiler@22.2.0-rc.0)(rxjs@7.8.2)(zone.js@0.16.3))(@angular/platform-browser@22.2.0-rc.0(@angular/animations@22.2.0-rc.0(@angular/core@22.2.0-rc.0(@angular/compiler@22.2.0-rc.0)(rxjs@7.8.2)(zone.js@0.16.3)))(@angular/common@22.2.0-rc.0(@angular/core@22.2.0-rc.0(@angular/compiler@22.2.0-rc.0)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2))(@angular/core@22.2.0-rc.0(@angular/compiler@22.2.0-rc.0)(rxjs@7.8.2)(zone.js@0.16.3)))(rxjs@7.8.2) + '@angular/platform-browser': 22.2.0-rc.0(@angular/animations@22.2.0-rc.0(@angular/core@22.2.0-rc.0(@angular/compiler@22.2.0-rc.0)(rxjs@7.8.2)(zone.js@0.16.3)))(@angular/common@22.2.0-rc.0(@angular/core@22.2.0-rc.0(@angular/compiler@22.2.0-rc.0)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2))(@angular/core@22.2.0-rc.0(@angular/compiler@22.2.0-rc.0)(rxjs@7.8.2)(zone.js@0.16.3)) parse5: 8.0.1 rxjs: 7.8.2 tslib: 2.8.1 - '@angular/common@22.2.0-next.5(@angular/core@22.2.0-next.5(@angular/compiler@22.2.0-next.5)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2)': + '@angular/common@22.2.0-rc.0(@angular/core@22.2.0-rc.0(@angular/compiler@22.2.0-rc.0)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2)': dependencies: - '@angular/core': 22.2.0-next.5(@angular/compiler@22.2.0-next.5)(rxjs@7.8.2)(zone.js@0.16.3) + '@angular/core': 22.2.0-rc.0(@angular/compiler@22.2.0-rc.0)(rxjs@7.8.2)(zone.js@0.16.3) rxjs: 7.8.2 tslib: 2.8.1 - '@angular/compiler-cli@22.2.0-next.5(@angular/compiler@22.2.0-next.5)(typescript@6.0.3)': + '@angular/compiler-cli@22.2.0-rc.0(@angular/compiler@22.2.0-rc.0)(typescript@6.0.3)': dependencies: - '@angular/compiler': 22.2.0-next.5 + '@angular/compiler': 22.2.0-rc.0 '@babel/core': 8.0.1 '@jridgewell/sourcemap-codec': 1.6.0 chokidar: 5.0.0 @@ -8861,47 +8853,47 @@ snapshots: optionalDependencies: typescript: 6.0.3 - '@angular/compiler@22.2.0-next.5': + '@angular/compiler@22.2.0-rc.0': dependencies: tslib: 2.8.1 - '@angular/core@22.2.0-next.5(@angular/compiler@22.2.0-next.5)(rxjs@7.8.2)(zone.js@0.16.3)': + '@angular/core@22.2.0-rc.0(@angular/compiler@22.2.0-rc.0)(rxjs@7.8.2)(zone.js@0.16.3)': dependencies: rxjs: 7.8.2 tslib: 2.8.1 optionalDependencies: - '@angular/compiler': 22.2.0-next.5 + '@angular/compiler': 22.2.0-rc.0 zone.js: 0.16.3 - '@angular/forms@22.2.0-next.5(@angular/common@22.2.0-next.5(@angular/core@22.2.0-next.5(@angular/compiler@22.2.0-next.5)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2))(@angular/core@22.2.0-next.5(@angular/compiler@22.2.0-next.5)(rxjs@7.8.2)(zone.js@0.16.3))(@angular/platform-browser@22.2.0-next.5(@angular/animations@22.2.0-next.5(@angular/core@22.2.0-next.5(@angular/compiler@22.2.0-next.5)(rxjs@7.8.2)(zone.js@0.16.3)))(@angular/common@22.2.0-next.5(@angular/core@22.2.0-next.5(@angular/compiler@22.2.0-next.5)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2))(@angular/core@22.2.0-next.5(@angular/compiler@22.2.0-next.5)(rxjs@7.8.2)(zone.js@0.16.3)))(rxjs@7.8.2)': + '@angular/forms@22.2.0-rc.0(@angular/common@22.2.0-rc.0(@angular/core@22.2.0-rc.0(@angular/compiler@22.2.0-rc.0)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2))(@angular/core@22.2.0-rc.0(@angular/compiler@22.2.0-rc.0)(rxjs@7.8.2)(zone.js@0.16.3))(@angular/platform-browser@22.2.0-rc.0(@angular/animations@22.2.0-rc.0(@angular/core@22.2.0-rc.0(@angular/compiler@22.2.0-rc.0)(rxjs@7.8.2)(zone.js@0.16.3)))(@angular/common@22.2.0-rc.0(@angular/core@22.2.0-rc.0(@angular/compiler@22.2.0-rc.0)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2))(@angular/core@22.2.0-rc.0(@angular/compiler@22.2.0-rc.0)(rxjs@7.8.2)(zone.js@0.16.3)))(rxjs@7.8.2)': dependencies: - '@angular/common': 22.2.0-next.5(@angular/core@22.2.0-next.5(@angular/compiler@22.2.0-next.5)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2) - '@angular/core': 22.2.0-next.5(@angular/compiler@22.2.0-next.5)(rxjs@7.8.2)(zone.js@0.16.3) - '@angular/platform-browser': 22.2.0-next.5(@angular/animations@22.2.0-next.5(@angular/core@22.2.0-next.5(@angular/compiler@22.2.0-next.5)(rxjs@7.8.2)(zone.js@0.16.3)))(@angular/common@22.2.0-next.5(@angular/core@22.2.0-next.5(@angular/compiler@22.2.0-next.5)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2))(@angular/core@22.2.0-next.5(@angular/compiler@22.2.0-next.5)(rxjs@7.8.2)(zone.js@0.16.3)) + '@angular/common': 22.2.0-rc.0(@angular/core@22.2.0-rc.0(@angular/compiler@22.2.0-rc.0)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2) + '@angular/core': 22.2.0-rc.0(@angular/compiler@22.2.0-rc.0)(rxjs@7.8.2)(zone.js@0.16.3) + '@angular/platform-browser': 22.2.0-rc.0(@angular/animations@22.2.0-rc.0(@angular/core@22.2.0-rc.0(@angular/compiler@22.2.0-rc.0)(rxjs@7.8.2)(zone.js@0.16.3)))(@angular/common@22.2.0-rc.0(@angular/core@22.2.0-rc.0(@angular/compiler@22.2.0-rc.0)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2))(@angular/core@22.2.0-rc.0(@angular/compiler@22.2.0-rc.0)(rxjs@7.8.2)(zone.js@0.16.3)) '@standard-schema/spec': 1.1.0 rxjs: 7.8.2 tslib: 2.8.1 - zod: 4.5.4 + zod: 4.6.5 - '@angular/localize@22.2.0-next.5(@angular/compiler-cli@22.2.0-next.5(@angular/compiler@22.2.0-next.5)(typescript@6.0.3))(@angular/compiler@22.2.0-next.5)': + '@angular/localize@22.2.0-rc.0(@angular/compiler-cli@22.2.0-rc.0(@angular/compiler@22.2.0-rc.0)(typescript@6.0.3))(@angular/compiler@22.2.0-rc.0)': dependencies: - '@angular/compiler': 22.2.0-next.5 - '@angular/compiler-cli': 22.2.0-next.5(@angular/compiler@22.2.0-next.5)(typescript@6.0.3) + '@angular/compiler': 22.2.0-rc.0 + '@angular/compiler-cli': 22.2.0-rc.0(@angular/compiler@22.2.0-rc.0)(typescript@6.0.3) '@babel/core': 8.0.1 tinyglobby: 0.2.17 yargs: 18.1.0 - '@angular/material@22.2.0-next.4(95bc9c8a06206acb56b97c62cbcd354e)': + '@angular/material@22.2.0-rc.0(25ddf4063a130bbf19862bd16a6ab5d4)': dependencies: - '@angular/cdk': 22.2.0-next.4(164cec07f845c9f2a6f509bb1888cfce) - '@angular/common': 22.2.0-next.5(@angular/core@22.2.0-next.5(@angular/compiler@22.2.0-next.5)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2) - '@angular/core': 22.2.0-next.5(@angular/compiler@22.2.0-next.5)(rxjs@7.8.2)(zone.js@0.16.3) - '@angular/forms': 22.2.0-next.5(@angular/common@22.2.0-next.5(@angular/core@22.2.0-next.5(@angular/compiler@22.2.0-next.5)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2))(@angular/core@22.2.0-next.5(@angular/compiler@22.2.0-next.5)(rxjs@7.8.2)(zone.js@0.16.3))(@angular/platform-browser@22.2.0-next.5(@angular/animations@22.2.0-next.5(@angular/core@22.2.0-next.5(@angular/compiler@22.2.0-next.5)(rxjs@7.8.2)(zone.js@0.16.3)))(@angular/common@22.2.0-next.5(@angular/core@22.2.0-next.5(@angular/compiler@22.2.0-next.5)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2))(@angular/core@22.2.0-next.5(@angular/compiler@22.2.0-next.5)(rxjs@7.8.2)(zone.js@0.16.3)))(rxjs@7.8.2) - '@angular/platform-browser': 22.2.0-next.5(@angular/animations@22.2.0-next.5(@angular/core@22.2.0-next.5(@angular/compiler@22.2.0-next.5)(rxjs@7.8.2)(zone.js@0.16.3)))(@angular/common@22.2.0-next.5(@angular/core@22.2.0-next.5(@angular/compiler@22.2.0-next.5)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2))(@angular/core@22.2.0-next.5(@angular/compiler@22.2.0-next.5)(rxjs@7.8.2)(zone.js@0.16.3)) + '@angular/cdk': 22.2.0-rc.0(32444abcc2be6e3bf2b6c059aa24d737) + '@angular/common': 22.2.0-rc.0(@angular/core@22.2.0-rc.0(@angular/compiler@22.2.0-rc.0)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2) + '@angular/core': 22.2.0-rc.0(@angular/compiler@22.2.0-rc.0)(rxjs@7.8.2)(zone.js@0.16.3) + '@angular/forms': 22.2.0-rc.0(@angular/common@22.2.0-rc.0(@angular/core@22.2.0-rc.0(@angular/compiler@22.2.0-rc.0)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2))(@angular/core@22.2.0-rc.0(@angular/compiler@22.2.0-rc.0)(rxjs@7.8.2)(zone.js@0.16.3))(@angular/platform-browser@22.2.0-rc.0(@angular/animations@22.2.0-rc.0(@angular/core@22.2.0-rc.0(@angular/compiler@22.2.0-rc.0)(rxjs@7.8.2)(zone.js@0.16.3)))(@angular/common@22.2.0-rc.0(@angular/core@22.2.0-rc.0(@angular/compiler@22.2.0-rc.0)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2))(@angular/core@22.2.0-rc.0(@angular/compiler@22.2.0-rc.0)(rxjs@7.8.2)(zone.js@0.16.3)))(rxjs@7.8.2) + '@angular/platform-browser': 22.2.0-rc.0(@angular/animations@22.2.0-rc.0(@angular/core@22.2.0-rc.0(@angular/compiler@22.2.0-rc.0)(rxjs@7.8.2)(zone.js@0.16.3)))(@angular/common@22.2.0-rc.0(@angular/core@22.2.0-rc.0(@angular/compiler@22.2.0-rc.0)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2))(@angular/core@22.2.0-rc.0(@angular/compiler@22.2.0-rc.0)(rxjs@7.8.2)(zone.js@0.16.3)) rxjs: 7.8.2 tslib: 2.8.1 - '@angular/ng-dev@https://codeload.github.com/angular/dev-infra-private-ng-dev-builds/tar.gz/c3d7ed184d71d390d3eacff85f4b2b3f16b82660': + '@angular/ng-dev@https://codeload.github.com/angular/dev-infra-private-ng-dev-builds/tar.gz/f166178ac5c37cd3aadab7b8cb7212f34d71b2a6': 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) @@ -8956,40 +8948,40 @@ snapshots: which: 7.0.0 yaml: 2.9.0 yargs: 18.1.0 - zod: 4.5.4 + zod: 4.6.5 transitivePeerDependencies: - '@modelcontextprotocol/sdk' - '@react-native-async-storage/async-storage' - '@angular/platform-browser@22.2.0-next.5(@angular/animations@22.2.0-next.5(@angular/core@22.2.0-next.5(@angular/compiler@22.2.0-next.5)(rxjs@7.8.2)(zone.js@0.16.3)))(@angular/common@22.2.0-next.5(@angular/core@22.2.0-next.5(@angular/compiler@22.2.0-next.5)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2))(@angular/core@22.2.0-next.5(@angular/compiler@22.2.0-next.5)(rxjs@7.8.2)(zone.js@0.16.3))': + '@angular/platform-browser@22.2.0-rc.0(@angular/animations@22.2.0-rc.0(@angular/core@22.2.0-rc.0(@angular/compiler@22.2.0-rc.0)(rxjs@7.8.2)(zone.js@0.16.3)))(@angular/common@22.2.0-rc.0(@angular/core@22.2.0-rc.0(@angular/compiler@22.2.0-rc.0)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2))(@angular/core@22.2.0-rc.0(@angular/compiler@22.2.0-rc.0)(rxjs@7.8.2)(zone.js@0.16.3))': dependencies: - '@angular/common': 22.2.0-next.5(@angular/core@22.2.0-next.5(@angular/compiler@22.2.0-next.5)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2) - '@angular/core': 22.2.0-next.5(@angular/compiler@22.2.0-next.5)(rxjs@7.8.2)(zone.js@0.16.3) + '@angular/common': 22.2.0-rc.0(@angular/core@22.2.0-rc.0(@angular/compiler@22.2.0-rc.0)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2) + '@angular/core': 22.2.0-rc.0(@angular/compiler@22.2.0-rc.0)(rxjs@7.8.2)(zone.js@0.16.3) tslib: 2.8.1 optionalDependencies: - '@angular/animations': 22.2.0-next.5(@angular/core@22.2.0-next.5(@angular/compiler@22.2.0-next.5)(rxjs@7.8.2)(zone.js@0.16.3)) + '@angular/animations': 22.2.0-rc.0(@angular/core@22.2.0-rc.0(@angular/compiler@22.2.0-rc.0)(rxjs@7.8.2)(zone.js@0.16.3)) - '@angular/platform-server@22.2.0-next.5(@angular/common@22.2.0-next.5(@angular/core@22.2.0-next.5(@angular/compiler@22.2.0-next.5)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2))(@angular/compiler@22.2.0-next.5)(@angular/core@22.2.0-next.5(@angular/compiler@22.2.0-next.5)(rxjs@7.8.2)(zone.js@0.16.3))(@angular/platform-browser@22.2.0-next.5(@angular/animations@22.2.0-next.5(@angular/core@22.2.0-next.5(@angular/compiler@22.2.0-next.5)(rxjs@7.8.2)(zone.js@0.16.3)))(@angular/common@22.2.0-next.5(@angular/core@22.2.0-next.5(@angular/compiler@22.2.0-next.5)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2))(@angular/core@22.2.0-next.5(@angular/compiler@22.2.0-next.5)(rxjs@7.8.2)(zone.js@0.16.3)))(rxjs@7.8.2)': + '@angular/platform-server@22.2.0-rc.0(@angular/common@22.2.0-rc.0(@angular/core@22.2.0-rc.0(@angular/compiler@22.2.0-rc.0)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2))(@angular/compiler@22.2.0-rc.0)(@angular/core@22.2.0-rc.0(@angular/compiler@22.2.0-rc.0)(rxjs@7.8.2)(zone.js@0.16.3))(@angular/platform-browser@22.2.0-rc.0(@angular/animations@22.2.0-rc.0(@angular/core@22.2.0-rc.0(@angular/compiler@22.2.0-rc.0)(rxjs@7.8.2)(zone.js@0.16.3)))(@angular/common@22.2.0-rc.0(@angular/core@22.2.0-rc.0(@angular/compiler@22.2.0-rc.0)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2))(@angular/core@22.2.0-rc.0(@angular/compiler@22.2.0-rc.0)(rxjs@7.8.2)(zone.js@0.16.3)))(rxjs@7.8.2)': dependencies: - '@angular/common': 22.2.0-next.5(@angular/core@22.2.0-next.5(@angular/compiler@22.2.0-next.5)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2) - '@angular/compiler': 22.2.0-next.5 - '@angular/core': 22.2.0-next.5(@angular/compiler@22.2.0-next.5)(rxjs@7.8.2)(zone.js@0.16.3) - '@angular/platform-browser': 22.2.0-next.5(@angular/animations@22.2.0-next.5(@angular/core@22.2.0-next.5(@angular/compiler@22.2.0-next.5)(rxjs@7.8.2)(zone.js@0.16.3)))(@angular/common@22.2.0-next.5(@angular/core@22.2.0-next.5(@angular/compiler@22.2.0-next.5)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2))(@angular/core@22.2.0-next.5(@angular/compiler@22.2.0-next.5)(rxjs@7.8.2)(zone.js@0.16.3)) + '@angular/common': 22.2.0-rc.0(@angular/core@22.2.0-rc.0(@angular/compiler@22.2.0-rc.0)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2) + '@angular/compiler': 22.2.0-rc.0 + '@angular/core': 22.2.0-rc.0(@angular/compiler@22.2.0-rc.0)(rxjs@7.8.2)(zone.js@0.16.3) + '@angular/platform-browser': 22.2.0-rc.0(@angular/animations@22.2.0-rc.0(@angular/core@22.2.0-rc.0(@angular/compiler@22.2.0-rc.0)(rxjs@7.8.2)(zone.js@0.16.3)))(@angular/common@22.2.0-rc.0(@angular/core@22.2.0-rc.0(@angular/compiler@22.2.0-rc.0)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2))(@angular/core@22.2.0-rc.0(@angular/compiler@22.2.0-rc.0)(rxjs@7.8.2)(zone.js@0.16.3)) rxjs: 7.8.2 tslib: 2.8.1 xhr2: 0.2.1 - '@angular/router@22.2.0-next.5(@angular/common@22.2.0-next.5(@angular/core@22.2.0-next.5(@angular/compiler@22.2.0-next.5)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2))(@angular/core@22.2.0-next.5(@angular/compiler@22.2.0-next.5)(rxjs@7.8.2)(zone.js@0.16.3))(@angular/platform-browser@22.2.0-next.5(@angular/animations@22.2.0-next.5(@angular/core@22.2.0-next.5(@angular/compiler@22.2.0-next.5)(rxjs@7.8.2)(zone.js@0.16.3)))(@angular/common@22.2.0-next.5(@angular/core@22.2.0-next.5(@angular/compiler@22.2.0-next.5)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2))(@angular/core@22.2.0-next.5(@angular/compiler@22.2.0-next.5)(rxjs@7.8.2)(zone.js@0.16.3)))(rxjs@7.8.2)': + '@angular/router@22.2.0-rc.0(@angular/common@22.2.0-rc.0(@angular/core@22.2.0-rc.0(@angular/compiler@22.2.0-rc.0)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2))(@angular/core@22.2.0-rc.0(@angular/compiler@22.2.0-rc.0)(rxjs@7.8.2)(zone.js@0.16.3))(@angular/platform-browser@22.2.0-rc.0(@angular/animations@22.2.0-rc.0(@angular/core@22.2.0-rc.0(@angular/compiler@22.2.0-rc.0)(rxjs@7.8.2)(zone.js@0.16.3)))(@angular/common@22.2.0-rc.0(@angular/core@22.2.0-rc.0(@angular/compiler@22.2.0-rc.0)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2))(@angular/core@22.2.0-rc.0(@angular/compiler@22.2.0-rc.0)(rxjs@7.8.2)(zone.js@0.16.3)))(rxjs@7.8.2)': dependencies: - '@angular/common': 22.2.0-next.5(@angular/core@22.2.0-next.5(@angular/compiler@22.2.0-next.5)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2) - '@angular/core': 22.2.0-next.5(@angular/compiler@22.2.0-next.5)(rxjs@7.8.2)(zone.js@0.16.3) - '@angular/platform-browser': 22.2.0-next.5(@angular/animations@22.2.0-next.5(@angular/core@22.2.0-next.5(@angular/compiler@22.2.0-next.5)(rxjs@7.8.2)(zone.js@0.16.3)))(@angular/common@22.2.0-next.5(@angular/core@22.2.0-next.5(@angular/compiler@22.2.0-next.5)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2))(@angular/core@22.2.0-next.5(@angular/compiler@22.2.0-next.5)(rxjs@7.8.2)(zone.js@0.16.3)) + '@angular/common': 22.2.0-rc.0(@angular/core@22.2.0-rc.0(@angular/compiler@22.2.0-rc.0)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2) + '@angular/core': 22.2.0-rc.0(@angular/compiler@22.2.0-rc.0)(rxjs@7.8.2)(zone.js@0.16.3) + '@angular/platform-browser': 22.2.0-rc.0(@angular/animations@22.2.0-rc.0(@angular/core@22.2.0-rc.0(@angular/compiler@22.2.0-rc.0)(rxjs@7.8.2)(zone.js@0.16.3)))(@angular/common@22.2.0-rc.0(@angular/core@22.2.0-rc.0(@angular/compiler@22.2.0-rc.0)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2))(@angular/core@22.2.0-rc.0(@angular/compiler@22.2.0-rc.0)(rxjs@7.8.2)(zone.js@0.16.3)) rxjs: 7.8.2 tslib: 2.8.1 - '@angular/service-worker@22.2.0-next.5(@angular/core@22.2.0-next.5(@angular/compiler@22.2.0-next.5)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2)': + '@angular/service-worker@22.2.0-rc.0(@angular/core@22.2.0-rc.0(@angular/compiler@22.2.0-rc.0)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2)': dependencies: - '@angular/core': 22.2.0-next.5(@angular/compiler@22.2.0-next.5)(rxjs@7.8.2)(zone.js@0.16.3) + '@angular/core': 22.2.0-rc.0(@angular/compiler@22.2.0-rc.0)(rxjs@7.8.2)(zone.js@0.16.3) rxjs: 7.8.2 tslib: 2.8.1 @@ -9046,7 +9038,7 @@ snapshots: '@babel/core@8.0.1': dependencies: '@babel/code-frame': 8.0.0 - '@babel/generator': 8.0.0 + '@babel/generator': 8.0.5 '@babel/helper-compilation-targets': 8.0.5 '@babel/helpers': 8.0.5 '@babel/parser': 8.0.5 @@ -9089,15 +9081,6 @@ snapshots: '@jridgewell/trace-mapping': 0.3.31 jsesc: 3.1.0 - '@babel/generator@8.0.0': - dependencies: - '@babel/parser': 8.0.5 - '@babel/types': 8.0.5 - '@jridgewell/gen-mapping': 0.3.13 - '@jridgewell/trace-mapping': 0.3.31 - '@types/jsesc': 2.5.1 - jsesc: 3.1.0 - '@babel/generator@8.0.5': dependencies: '@babel/parser': 8.0.5 @@ -15129,10 +15112,10 @@ snapshots: neo-async@2.6.2: {} - ng-packagr@22.2.0-next.5(@angular/compiler-cli@22.2.0-next.5(@angular/compiler@22.2.0-next.5)(typescript@6.0.3))(supports-color@11.0.0)(tslib@2.8.1)(typescript@6.0.3): + ng-packagr@22.2.0-rc.0(@angular/compiler-cli@22.2.0-rc.0(@angular/compiler@22.2.0-rc.0)(typescript@6.0.3))(supports-color@11.0.0)(tslib@2.8.1)(typescript@6.0.3): dependencies: '@ampproject/remapping': 2.3.0 - '@angular/compiler-cli': 22.2.0-next.5(@angular/compiler@22.2.0-next.5)(typescript@6.0.3) + '@angular/compiler-cli': 22.2.0-rc.0(@angular/compiler@22.2.0-rc.0)(typescript@6.0.3) ajv: 8.20.0 browserslist: 4.28.9 chokidar: 5.0.0 @@ -15148,8 +15131,8 @@ snapshots: rolldown: 1.2.8 rolldown-plugin-dts: 0.28.5(rolldown@1.2.8)(typescript@6.0.3) rxjs: 7.8.2 - sass: 1.104.0 - sass-embedded: 1.104.0 + sass: 1.104.1 + sass-embedded: 1.104.1 tinyglobby: 0.2.17 tslib: 2.8.1 typescript: 6.0.3 @@ -16158,6 +16141,7 @@ snapshots: sass-embedded-unknown-all: 1.104.0 sass-embedded-win32-arm64: 1.104.0 sass-embedded-win32-x64: 1.104.0 + optional: true sass-embedded@1.104.1: dependencies: @@ -16201,6 +16185,7 @@ snapshots: source-map-js: 1.2.1 optionalDependencies: '@parcel/watcher': 2.6.0 + optional: true sass@1.104.1: dependencies: @@ -17482,8 +17467,6 @@ snapshots: zod@3.25.76: {} - zod@4.5.4: {} - zod@4.6.5: {} zone.js@0.16.3: {} From 6ffd26791199ccd61ac55fdbd34a1149a1af9eed Mon Sep 17 00:00:00 2001 From: Angular Robot Date: Thu, 17 Sep 2026 06:47:34 +0000 Subject: [PATCH 005/233] build: update bazel dependencies See associated pull request for more information. --- MODULE.bazel | 6 +++--- MODULE.bazel.lock | 26 +++++++++++++++++--------- 2 files changed, 20 insertions(+), 12 deletions(-) diff --git a/MODULE.bazel b/MODULE.bazel index d5d7e9df8670..9c3fd0ab9019 100644 --- a/MODULE.bazel +++ b/MODULE.bazel @@ -10,11 +10,11 @@ bazel_dep(name = "rules_nodejs", version = "6.7.5") bazel_dep(name = "aspect_rules_js", version = "3.4.1") bazel_dep(name = "aspect_rules_ts", version = "3.10.1") bazel_dep(name = "rules_pkg", version = "1.3.0") -bazel_dep(name = "rules_cc", version = "0.2.22") -bazel_dep(name = "jq.bzl", version = "0.6.1") +bazel_dep(name = "rules_cc", version = "0.2.25") +bazel_dep(name = "jq.bzl", version = "0.6.2") bazel_dep(name = "bazel_lib", version = "3.7.2") bazel_dep(name = "bazel_skylib", version = "1.9.2") -bazel_dep(name = "aspect_rules_esbuild", version = "0.27.0") +bazel_dep(name = "aspect_rules_esbuild", version = "0.27.1") 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 27af19eb5cb6..31e442ccf216 100644 --- a/MODULE.bazel.lock +++ b/MODULE.bazel.lock @@ -10,6 +10,9 @@ "https://bcr.bazel.build/modules/abseil-cpp/20230802.1/MODULE.bazel": "fa92e2eb41a04df73cdabeec37107316f7e5272650f81d6cc096418fe647b915", "https://bcr.bazel.build/modules/abseil-cpp/20240116.1/MODULE.bazel": "37bcdb4440fbb61df6a1c296ae01b327f19e9bb521f9b8e26ec854b6f97309ed", "https://bcr.bazel.build/modules/abseil-cpp/20240116.1/source.json": "9be551b8d4e3ef76875c0d744b5d6a504a27e3ae67bc6b28f46415fd2d2957da", + "https://bcr.bazel.build/modules/apple_support/1.23.1/MODULE.bazel": "53763fed456a968cf919b3240427cf3a9d5481ec5466abc9d5dc51bc70087442", + "https://bcr.bazel.build/modules/apple_support/2.8.0/MODULE.bazel": "c45f5176057092afba0be6c48a9ea02101666802f8be536947e099e94757f8ed", + "https://bcr.bazel.build/modules/apple_support/2.8.0/source.json": "b7f6d87669c206adaa7d82cc44733349c63e341b80a0e049496ebd91d78c3472", "https://bcr.bazel.build/modules/aspect_bazel_lib/2.0.0/MODULE.bazel": "e118477db5c49419a88d78ebc7a2c2cea9d49600fe0f490c1903324a2c16ecd9", "https://bcr.bazel.build/modules/aspect_bazel_lib/2.14.0/MODULE.bazel": "2b31ffcc9bdc8295b2167e07a757dbbc9ac8906e7028e5170a3708cecaac119f", "https://bcr.bazel.build/modules/aspect_bazel_lib/2.19.2/MODULE.bazel": "30dfabbfae0139b1f0036e01c201dd4c0167da3017f0b7ef3820d78e07622989", @@ -19,7 +22,8 @@ "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.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_esbuild/0.27.1/MODULE.bazel": "99c3978959edd9892e4b513831b218a13cc84a0215bfe1b972a1e3a771c4670e", + "https://bcr.bazel.build/modules/aspect_rules_esbuild/0.27.1/source.json": "20f515102cbcd0835d90bb3976b193eb58c2a0c534093c85cfd3bf6f06dba748", "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", @@ -40,6 +44,7 @@ "https://bcr.bazel.build/modules/bazel_features/1.18.0/MODULE.bazel": "1be0ae2557ab3a72a57aeb31b29be347bcdc5d2b1eb1e70f39e3851a7e97041a", "https://bcr.bazel.build/modules/bazel_features/1.19.0/MODULE.bazel": "59adcdf28230d220f0067b1f435b8537dd033bfff8db21335ef9217919c7fb58", "https://bcr.bazel.build/modules/bazel_features/1.21.0/MODULE.bazel": "675642261665d8eea09989aa3b8afb5c37627f1be178382c320d1b46afba5e3b", + "https://bcr.bazel.build/modules/bazel_features/1.27.0/MODULE.bazel": "621eeee06c4458a9121d1f104efb80f39d34deff4984e778359c60eaf1a8cb65", "https://bcr.bazel.build/modules/bazel_features/1.28.0/MODULE.bazel": "4b4200e6cbf8fa335b2c3f43e1d6ef3e240319c33d43d60cc0fbd4b87ece299d", "https://bcr.bazel.build/modules/bazel_features/1.30.0/MODULE.bazel": "a14b62d05969a293b80257e72e597c2da7f717e1e69fa8b339703ed6731bec87", "https://bcr.bazel.build/modules/bazel_features/1.34.0/MODULE.bazel": "e8475ad7c8965542e0c7aac8af68eb48c4af904be3d614b6aa6274c092c2ea1e", @@ -86,7 +91,8 @@ "https://bcr.bazel.build/modules/jq.bzl/0.1.0/MODULE.bazel": "2ce69b1af49952cd4121a9c3055faa679e748ce774c7f1fda9657f936cae902f", "https://bcr.bazel.build/modules/jq.bzl/0.4.0/MODULE.bazel": "a7b39b37589f2b0dad53fd6c1ccaabbdb290330caa920d7ef3e6aad068cd4ab2", "https://bcr.bazel.build/modules/jq.bzl/0.6.1/MODULE.bazel": "f30c46e0a08a9f7566a8bf60a43d48abea960cd7f57b315b01e2762f1537eb52", - "https://bcr.bazel.build/modules/jq.bzl/0.6.1/source.json": "9ca9e2f90baa6a5bb0a49626ed9528554ec83165adf47b39792673ecc7feda22", + "https://bcr.bazel.build/modules/jq.bzl/0.6.2/MODULE.bazel": "e9c82f9b1e720d4ab0e232d32c05f0f4d0f92a8e8bb6a0da8f7cd27823b93e05", + "https://bcr.bazel.build/modules/jq.bzl/0.6.2/source.json": "e36f8ed173a6ca6e627f9d659ae504733d5a991859805661e4aacd34d8ae0639", "https://bcr.bazel.build/modules/jsoncpp/1.9.5/MODULE.bazel": "31271aedc59e815656f5736f282bb7509a97c7ecb43e927ac1a37966e0578075", "https://bcr.bazel.build/modules/jsoncpp/1.9.5/source.json": "4108ee5085dd2885a341c7fab149429db457b3169b86eb081fa245eadf69169d", "https://bcr.bazel.build/modules/libpfm/4.11.0/MODULE.bazel": "45061ff025b301940f1e30d2c16bea596c25b176c8b6b3087e92615adbd52902", @@ -100,6 +106,7 @@ "https://bcr.bazel.build/modules/platforms/0.0.6/MODULE.bazel": "ad6eeef431dc52aefd2d77ed20a4b353f8ebf0f4ecdd26a807d2da5aa8cd0615", "https://bcr.bazel.build/modules/platforms/0.0.7/MODULE.bazel": "72fd4a0ede9ee5c021f6a8dd92b503e089f46c227ba2813ff183b71616034814", "https://bcr.bazel.build/modules/platforms/0.0.8/MODULE.bazel": "9f142c03e348f6d263719f5074b21ef3adf0b139ee4c5133e2aa35664da9eb2d", + "https://bcr.bazel.build/modules/platforms/0.0.9/MODULE.bazel": "4a87a60c927b56ddd67db50c89acaa62f4ce2a1d2149ccb63ffd871d5ce29ebc", "https://bcr.bazel.build/modules/platforms/1.0.0/MODULE.bazel": "f05feb42b48f1b3c225e4ccf351f367be0371411a803198ec34a389fb22aa580", "https://bcr.bazel.build/modules/platforms/1.1.0/MODULE.bazel": "1c0c09f5bdcf4b3f924720d2478a3711cb39f4977019ca5988685e5b7e18b3d2", "https://bcr.bazel.build/modules/platforms/1.1.0/source.json": "fcf351c47596c939140ab0d333dfdd08ed1ea6ce33c2fe70c12493a301cf1344", @@ -131,8 +138,9 @@ "https://bcr.bazel.build/modules/rules_cc/0.1.1/MODULE.bazel": "2f0222a6f229f0bf44cd711dc13c858dad98c62d52bd51d8fc3a764a83125513", "https://bcr.bazel.build/modules/rules_cc/0.1.5/MODULE.bazel": "88dfc9361e8b5ae1008ac38f7cdfd45ad738e4fa676a3ad67d19204f045a1fd8", "https://bcr.bazel.build/modules/rules_cc/0.2.16/MODULE.bazel": "9242fa89f950c6ef7702801ab53922e99c69b02310c39fb6e62b2bd30df2a1d4", - "https://bcr.bazel.build/modules/rules_cc/0.2.22/MODULE.bazel": "94df4328edef9e44d38de5e73b037cd348e75e7ae55f4e21bf07878c41a31ebb", - "https://bcr.bazel.build/modules/rules_cc/0.2.22/source.json": "b2d6d6f9c332ce269ad75b89c6f3168d809a66173c9040210fb9bcc733ab42fa", + "https://bcr.bazel.build/modules/rules_cc/0.2.20/MODULE.bazel": "f5c07bce5ddcb99be21a0812ff5aadb439e688b7449c6542152363b2fd859c1a", + "https://bcr.bazel.build/modules/rules_cc/0.2.25/MODULE.bazel": "4a3d4f3606d3b3190be495dbc497acca552807d1d5540661ef0d1658472882e3", + "https://bcr.bazel.build/modules/rules_cc/0.2.25/source.json": "8df28a9a97b878fe45f0a4f4adf019869dda51a60ee2f6e15a0c79656a25058d", "https://bcr.bazel.build/modules/rules_cc/0.2.4/MODULE.bazel": "1ff1223dfd24f3ecf8f028446d4a27608aa43c3f41e346d22838a4223980b8cc", "https://bcr.bazel.build/modules/rules_foreign_cc/0.9.0/MODULE.bazel": "c9e8c682bf75b0e7c704166d79b599f93b72cfca5ad7477df596947891feeef6", "https://bcr.bazel.build/modules/rules_fuzzing/0.5.2/MODULE.bazel": "40c97d1144356f52905566c55811f13b299453a14ac7769dfba2ac38192337a8", @@ -222,8 +230,8 @@ "moduleExtensions": { "@@aspect_rules_esbuild+//esbuild:extensions.bzl%esbuild": { "general": { - "bzlTransitiveDigest": "ivnb7fuZRAghsUscNSqk/cyy9pTpUKwbi8xOKhgxNbo=", - "usagesDigest": "LZ71sshnfqI8R/HeWwBTwawxIa7KnitayBl2hYrqPo4=", + "bzlTransitiveDigest": "bn5qyJpbHTM21Kl9gvkARvwxKe1bH7JC951YjIa5vuk=", + "usagesDigest": "ZqBbSnzAi8ZyBL3PXnAGtDMIdC2pcuieJWMY3/94lvA=", "recordedInputs": [ "REPO_MAPPING:aspect_rules_esbuild+,aspect_rules_js aspect_rules_js+", "REPO_MAPPING:aspect_rules_esbuild+,aspect_tools_telemetry_report aspect_tools_telemetry++telemetry+aspect_tools_telemetry_report", @@ -355,7 +363,7 @@ "@@aspect_tools_telemetry+//:extension.bzl%telemetry": { "general": { "bzlTransitiveDigest": "zFgbaCUuPzH6bIE7CBHBVCqjWSJ78/WNXisdzXaKSnU=", - "usagesDigest": "2cLMn8ZcqY/6j/zH70TrPob+ENshTw9h48kUHxn1cUM=", + "usagesDigest": "B4C1UNcAOoRiMjmkXh3VFW7fY2YULy8OZA7RjfEM2UQ=", "recordedInputs": [ "REPO_MAPPING:aspect_tools_telemetry+,bazel_lib bazel_lib+", "REPO_MAPPING:aspect_tools_telemetry+,bazel_skylib bazel_skylib+", @@ -368,11 +376,11 @@ "deps": { "aspect_rules_js": "3.4.1", "aspect_rules_ts": "3.10.1", - "aspect_rules_esbuild": "0.27.0", + "aspect_rules_esbuild": "0.27.1", "aspect_rules_jasmine": "2.0.4", "aspect_tools_telemetry": "0.5.1" }, - "last_notice": 0 + "last_notice": 2 } } }, From c76b2d58a9113f9a38ce6fb2f448b6dc61e4a965 Mon Sep 17 00:00:00 2001 From: Charles Lyding <19598772+clydin@users.noreply.github.com> Date: Thu, 17 Sep 2026 10:19:13 -0400 Subject: [PATCH 006/233] refactor(@angular/build): cap default i18n inlining concurrency to 8 Translation inlining and sourcemap remapping are CPU- and memory-intensive operations. When Piscina is initialized without explicit maxThreads, it defaults to floor(cpus * 1.5), spawning 18 to 48 worker threads on high-core machines. This excessive concurrency causes severe thread oversubscription, memory allocator lock contention, and high-core performance degradation under Promise.all barriers. This change introduces maxInlinerWorkers in environment options defaulting to min(8, availableParallelism()) while preserving explicit overrides via NG_BUILD_MAX_WORKERS. Concurrency passed to I18nInliner in the application builder is bounded to maxInlinerWorkers, capping standalone workers and shared worker pools while honoring shared pool thread limits when lower. (cherry picked from commit 93c118edcc97e9179f1ad01bf9bac09eaffed3b5) --- .../build/src/builders/application/i18n.ts | 6 +- .../build/src/utils/environment-options.ts | 9 +++ .../src/utils/environment-options_spec.ts | 64 +++++++++++++++++++ 3 files changed, 77 insertions(+), 2 deletions(-) diff --git a/packages/angular/build/src/builders/application/i18n.ts b/packages/angular/build/src/builders/application/i18n.ts index d4656c046997..0d6ae77cdea7 100644 --- a/packages/angular/build/src/builders/application/i18n.ts +++ b/packages/angular/build/src/builders/application/i18n.ts @@ -17,7 +17,7 @@ import { } from '../../tools/esbuild/bundler-execution-result'; import { BuildOutputFileType, InitialFileRecord } from '../../tools/esbuild/bundler-files'; import { I18nInliner } from '../../tools/esbuild/i18n-inliner'; -import { maxWorkers } from '../../utils/environment-options'; +import { maxInlinerWorkers } from '../../utils/environment-options'; import { loadTranslations } from '../../utils/i18n-options'; import { createTranslationLoader } from '../../utils/load-translations'; import { createProjectResolver } from '../../utils/resolve-project'; @@ -51,7 +51,9 @@ export async function inlineI18n( const inliner = new I18nInliner( { missingTranslation: i18nOptions.missingTranslationBehavior ?? 'warning', - maxConcurrency: workerPool ? undefined : maxWorkers, + maxConcurrency: workerPool + ? Math.min(workerPool.maxThreads, maxInlinerWorkers) + : maxInlinerWorkers, persistentCachePath: cacheOptions.enabled ? cacheOptions.path : undefined, localizeVersion: i18nOptions.localizeVersion, }, diff --git a/packages/angular/build/src/utils/environment-options.ts b/packages/angular/build/src/utils/environment-options.ts index 29faf3e7bbae..d87c104aba65 100644 --- a/packages/angular/build/src/utils/environment-options.ts +++ b/packages/angular/build/src/utils/environment-options.ts @@ -141,6 +141,15 @@ export const maxWorkers = customMaxWorkers ?? Math.max(availableParallelism() - export const maxTransformWorkers = customMaxWorkers ?? Math.max(1, Math.min(6, Math.floor(availableParallelism() / 4))); +/** + * The maximum number of workers to use for i18n translation inlining. + * Translation inlining and sourcemap remapping are CPU- and memory-intensive operations. + * To prevent thread oversubscription, memory allocator lock contention, and high-core + * performance degradation, concurrency is capped at 8 unless overridden by + * `NG_BUILD_MAX_WORKERS`. + */ +export const maxInlinerWorkers = customMaxWorkers ?? Math.min(8, availableParallelism()); + /** * When `NG_BUILD_PARALLEL_TS` is set to `0` or `false`, parallel TypeScript compilation is disabled. */ diff --git a/packages/angular/build/src/utils/environment-options_spec.ts b/packages/angular/build/src/utils/environment-options_spec.ts index 4146bec8bec1..4ad098a24763 100644 --- a/packages/angular/build/src/utils/environment-options_spec.ts +++ b/packages/angular/build/src/utils/environment-options_spec.ts @@ -181,3 +181,67 @@ describe('environment options - maxTransformWorkers', () => { expect(maxTransformWorkers).toBe(expected); }); }); + +describe('environment options - maxInlinerWorkers', () => { + const originalEnvValue = process.env['NG_BUILD_MAX_WORKERS']; + + function loadEnvironmentOptions(): typeof import('./environment-options') { + delete require.cache[require.resolve('./environment-options')]; + + return require('./environment-options'); + } + + afterEach(() => { + if (originalEnvValue !== undefined) { + process.env['NG_BUILD_MAX_WORKERS'] = originalEnvValue; + } else { + delete process.env['NG_BUILD_MAX_WORKERS']; + } + delete require.cache[require.resolve('./environment-options')]; + }); + + it('defaults maxInlinerWorkers to min(8, availableParallelism()) when NG_BUILD_MAX_WORKERS is unset', () => { + delete process.env['NG_BUILD_MAX_WORKERS']; + const { maxInlinerWorkers } = loadEnvironmentOptions(); + + expect(maxInlinerWorkers).toBe(Math.min(8, availableParallelism())); + }); + + it('uses configured positive integer when NG_BUILD_MAX_WORKERS is set', () => { + process.env['NG_BUILD_MAX_WORKERS'] = '4'; + const { maxInlinerWorkers } = loadEnvironmentOptions(); + + expect(maxInlinerWorkers).toBe(4); + }); + + it('allows maxInlinerWorkers greater than 8 when explicitly configured', () => { + process.env['NG_BUILD_MAX_WORKERS'] = '16'; + const { maxInlinerWorkers } = loadEnvironmentOptions(); + + expect(maxInlinerWorkers).toBe(16); + }); + + it('supports maxInlinerWorkers set to 1', () => { + process.env['NG_BUILD_MAX_WORKERS'] = '1'; + const { maxInlinerWorkers } = loadEnvironmentOptions(); + + expect(maxInlinerWorkers).toBe(1); + }); + + it('falls back to min(8, availableParallelism()) when NG_BUILD_MAX_WORKERS is 0 or negative', () => { + process.env['NG_BUILD_MAX_WORKERS'] = '0'; + const { maxInlinerWorkers: zeroWorkers } = loadEnvironmentOptions(); + expect(zeroWorkers).toBe(Math.min(8, availableParallelism())); + + process.env['NG_BUILD_MAX_WORKERS'] = '-4'; + const { maxInlinerWorkers: negativeWorkers } = loadEnvironmentOptions(); + expect(negativeWorkers).toBe(Math.min(8, availableParallelism())); + }); + + it('falls back to min(8, availableParallelism()) when NG_BUILD_MAX_WORKERS is invalid', () => { + process.env['NG_BUILD_MAX_WORKERS'] = 'invalid'; + const { maxInlinerWorkers } = loadEnvironmentOptions(); + + expect(maxInlinerWorkers).toBe(Math.min(8, availableParallelism())); + }); +}); From 9c6037af8b16f6c44d16324e76c13356173a7a55 Mon Sep 17 00:00:00 2001 From: Alan Agius <17563226+alan-agius4@users.noreply.github.com> Date: Thu, 17 Sep 2026 16:29:53 +0000 Subject: [PATCH 007/233] Revert "refactor(@angular/cli): import markdown files directly for command descriptions" This reverts commit 3d7f081dbc6cc0c25740bab70d49f21c7d178c3c. --- .../cli/src/command-builder/command-module.ts | 46 +++++++++---------- packages/angular/cli/src/commands/add/cli.ts | 5 +- .../angular/cli/src/commands/analytics/cli.ts | 6 +-- .../cli/src/commands/analytics/info/cli.ts | 1 + .../src/commands/analytics/settings/cli.ts | 2 + .../angular/cli/src/commands/build/cli.ts | 6 +-- .../cli/src/commands/cache/clean/cli.ts | 1 + .../angular/cli/src/commands/cache/cli.ts | 6 +-- .../cli/src/commands/cache/info/cli.ts | 1 + .../cli/src/commands/cache/settings/cli.ts | 2 + .../cli/src/commands/completion/cli.ts | 7 ++- .../angular/cli/src/commands/config/cli.ts | 6 +-- .../angular/cli/src/commands/deploy/cli.ts | 6 +-- packages/angular/cli/src/commands/e2e/cli.ts | 1 + .../cli/src/commands/extract-i18n/cli.ts | 1 + .../angular/cli/src/commands/generate/cli.ts | 1 + packages/angular/cli/src/commands/lint/cli.ts | 6 +-- .../cli/src/commands/make-this-awesome/cli.ts | 1 + packages/angular/cli/src/commands/mcp/cli.ts | 1 + packages/angular/cli/src/commands/new/cli.ts | 6 +-- packages/angular/cli/src/commands/run/cli.ts | 6 +-- .../angular/cli/src/commands/serve/cli.ts | 1 + packages/angular/cli/src/commands/test/cli.ts | 6 +-- .../angular/cli/src/commands/update/cli.ts | 5 +- .../angular/cli/src/commands/version/cli.ts | 1 + packages/angular/cli/src/typings.d.ts | 12 ----- .../cli/src/utilities/markdown-loader.ts | 35 -------------- 27 files changed, 59 insertions(+), 119 deletions(-) delete mode 100644 packages/angular/cli/src/typings.d.ts delete mode 100644 packages/angular/cli/src/utilities/markdown-loader.ts diff --git a/packages/angular/cli/src/command-builder/command-module.ts b/packages/angular/cli/src/command-builder/command-module.ts index 35e0d4f8201d..ae0eb82f0cb5 100644 --- a/packages/angular/cli/src/command-builder/command-module.ts +++ b/packages/angular/cli/src/command-builder/command-module.ts @@ -7,6 +7,8 @@ */ import { schema } from '@angular-devkit/core'; +import { readFileSync } from 'node:fs'; +import { join, posix, relative } from 'node:path'; import type { ArgumentsCamelCase, Argv, CommandModule as YargsCommandModule } from 'yargs'; import { Parser as yargsParser } from 'yargs/helpers'; import { getAnalyticsUserId } from '../analytics/analytics'; @@ -18,7 +20,6 @@ import { AngularWorkspace } from '../utilities/config'; import { memoize } from '../utilities/memoize'; import { CommandContext, CommandScope, Options, OtherOptions } from './definitions'; import { Option, addSchemaOptionsToCommand } from './utilities/json-schema'; -import '../utilities/markdown-loader'; export { CommandScope }; export type { CommandContext, Options, OtherOptions }; @@ -30,11 +31,8 @@ export interface CommandModuleImplementation extends Omit< /** Scope in which the command can be executed in. */ scope: CommandScope; - /** Long description for the command in JSON help text. */ - longDescription?: string; - - /** Relative path to the long description file for the command in JSON help text. */ - longDescriptionRelativePath?: string; + /** Path used to load the long description for the command in JSON help text. */ + longDescriptionPath?: string; /** Object declaring the options the command accepts, or a function accepting and returning a yargs instance. */ builder(argv: Argv): Promise> | Argv; @@ -52,8 +50,7 @@ export interface FullDescribe { export abstract class CommandModule implements CommandModuleImplementation { abstract readonly command: string; abstract readonly describe: string | false; - readonly longDescription?: string; - readonly longDescriptionRelativePath?: string; + abstract readonly longDescriptionPath?: string; protected readonly shouldReportAnalytics: boolean = true; readonly scope: CommandScope = CommandScope.Both; @@ -71,22 +68,23 @@ export abstract class CommandModule implements CommandModuleI * `false` will result in a hidden command. */ public get fullDescribe(): FullDescribe | false { - if (this.describe === false) { - return false; - } - - const description: FullDescribe = { - describe: this.describe, - }; - - if (this.longDescription) { - description.longDescription = this.longDescription.replace(/\r\n/g, '\n'); - description.longDescriptionRelativePath = - this.longDescriptionRelativePath ?? - `@angular/cli/src/commands/${this.commandName}/long-description.md`; - } - - return description; + return this.describe === false + ? false + : { + describe: this.describe, + ...(this.longDescriptionPath + ? { + longDescriptionRelativePath: relative( + join(__dirname, '../../../../'), + this.longDescriptionPath, + ).replace(/\\/g, posix.sep), + longDescription: readFileSync(this.longDescriptionPath, 'utf8').replace( + /\r\n/g, + '\n', + ), + } + : {}), + }; } protected get commandName(): string { diff --git a/packages/angular/cli/src/commands/add/cli.ts b/packages/angular/cli/src/commands/add/cli.ts index fb352f70edfd..bc95f33ff8e7 100644 --- a/packages/angular/cli/src/commands/add/cli.ts +++ b/packages/angular/cli/src/commands/add/cli.ts @@ -29,9 +29,6 @@ import { NgAddSaveDependency, PackageManifest, PackageMetadata } from '../../pac import { assertIsError } from '../../utilities/error'; import { isTTY } from '../../utilities/tty'; import { VERSION } from '../../utilities/version'; -// eslint-disable-next-line @typescript-eslint/ban-ts-comment -// @ts-ignore strict-deps: Markdown files are asset dependencies bundled/loaded at runtime -import longDescription from './long-description.md'; class CommandError extends Error {} @@ -103,7 +100,7 @@ export default class AddCommandModule { command = 'add '; describe = 'Adds support for an external library to your project.'; - override longDescription = longDescription; + longDescriptionPath = join(__dirname, 'long-description.md'); protected override allowPrivateSchematics = true; private readonly schematicName = 'ng-add'; private rootRequire = createRequire(this.context.root + '/'); diff --git a/packages/angular/cli/src/commands/analytics/cli.ts b/packages/angular/cli/src/commands/analytics/cli.ts index 9639cbab50e6..da56a2a00460 100644 --- a/packages/angular/cli/src/commands/analytics/cli.ts +++ b/packages/angular/cli/src/commands/analytics/cli.ts @@ -6,6 +6,7 @@ * found in the LICENSE file at https://angular.dev/license */ +import { join } from 'node:path'; import { Argv } from 'yargs'; import { CommandModule, @@ -17,9 +18,6 @@ import { demandCommandFailureMessage, } from '../../command-builder/utilities/command'; import { AnalyticsInfoCommandModule } from './info/cli'; -// eslint-disable-next-line @typescript-eslint/ban-ts-comment -// @ts-ignore strict-deps: Markdown files are asset dependencies bundled/loaded at runtime -import longDescription from './long-description.md'; import { AnalyticsDisableModule, AnalyticsEnableModule, @@ -32,7 +30,7 @@ export default class AnalyticsCommandModule { command = 'analytics'; describe = 'Configures the gathering of Angular CLI usage metrics.'; - override longDescription = longDescription; + longDescriptionPath = join(__dirname, 'long-description.md'); builder(localYargs: Argv): Argv { const subcommands = [ diff --git a/packages/angular/cli/src/commands/analytics/info/cli.ts b/packages/angular/cli/src/commands/analytics/info/cli.ts index 93b34fd06716..e4434d35baee 100644 --- a/packages/angular/cli/src/commands/analytics/info/cli.ts +++ b/packages/angular/cli/src/commands/analytics/info/cli.ts @@ -20,6 +20,7 @@ export class AnalyticsInfoCommandModule { command = 'info'; describe = 'Prints analytics gathering and reporting configuration in the console.'; + longDescriptionPath?: string; builder(localYargs: Argv): Argv { return localYargs.strict(); diff --git a/packages/angular/cli/src/commands/analytics/settings/cli.ts b/packages/angular/cli/src/commands/analytics/settings/cli.ts index 24105de2b060..16f07b353d1a 100644 --- a/packages/angular/cli/src/commands/analytics/settings/cli.ts +++ b/packages/angular/cli/src/commands/analytics/settings/cli.ts @@ -26,6 +26,8 @@ abstract class AnalyticsSettingModule extends CommandModule implements CommandModuleImplementation { + longDescriptionPath?: string; + builder(localYargs: Argv): Argv { return localYargs .option('global', { diff --git a/packages/angular/cli/src/commands/build/cli.ts b/packages/angular/cli/src/commands/build/cli.ts index 031e31b5140f..365420ca3734 100644 --- a/packages/angular/cli/src/commands/build/cli.ts +++ b/packages/angular/cli/src/commands/build/cli.ts @@ -6,12 +6,10 @@ * found in the LICENSE file at https://angular.dev/license */ +import { join } from 'node:path'; import { ArchitectCommandModule } from '../../command-builder/architect-command-module'; import { CommandModuleImplementation } from '../../command-builder/command-module'; import { RootCommands } from '../command-config'; -// eslint-disable-next-line @typescript-eslint/ban-ts-comment -// @ts-ignore strict-deps: Markdown files are asset dependencies bundled/loaded at runtime -import longDescription from './long-description.md'; export default class BuildCommandModule extends ArchitectCommandModule @@ -22,5 +20,5 @@ export default class BuildCommandModule aliases = RootCommands['build'].aliases; describe = 'Compiles an Angular application or library into an output directory named dist/ at the given output path.'; - override longDescription = longDescription; + longDescriptionPath = join(__dirname, 'long-description.md'); } diff --git a/packages/angular/cli/src/commands/cache/clean/cli.ts b/packages/angular/cli/src/commands/cache/clean/cli.ts index 492699271b54..a115b686b7e0 100644 --- a/packages/angular/cli/src/commands/cache/clean/cli.ts +++ b/packages/angular/cli/src/commands/cache/clean/cli.ts @@ -18,6 +18,7 @@ import { getCacheConfig } from '../utilities'; export class CacheCleanModule extends CommandModule implements CommandModuleImplementation { command = 'clean'; describe = 'Deletes persistent disk cache from disk.'; + longDescriptionPath: string | undefined; override scope = CommandScope.In; builder(localYargs: Argv): Argv { diff --git a/packages/angular/cli/src/commands/cache/cli.ts b/packages/angular/cli/src/commands/cache/cli.ts index 25140041ae0e..dad144b034b3 100644 --- a/packages/angular/cli/src/commands/cache/cli.ts +++ b/packages/angular/cli/src/commands/cache/cli.ts @@ -6,6 +6,7 @@ * found in the LICENSE file at https://angular.dev/license */ +import { join } from 'node:path'; import { Argv } from 'yargs'; import { CommandModule, @@ -19,9 +20,6 @@ import { } from '../../command-builder/utilities/command'; import { CacheCleanModule } from './clean/cli'; import { CacheInfoCommandModule } from './info/cli'; -// eslint-disable-next-line @typescript-eslint/ban-ts-comment -// @ts-ignore strict-deps: Markdown files are asset dependencies bundled/loaded at runtime -import longDescription from './long-description.md'; import { CacheDisableModule, CacheEnableModule } from './settings/cli'; export default class CacheCommandModule @@ -30,7 +28,7 @@ export default class CacheCommandModule { command = 'cache'; describe = 'Configure persistent disk cache and retrieve cache statistics.'; - override longDescription = longDescription; + longDescriptionPath = join(__dirname, 'long-description.md'); override scope = CommandScope.In; builder(localYargs: Argv): Argv { diff --git a/packages/angular/cli/src/commands/cache/info/cli.ts b/packages/angular/cli/src/commands/cache/info/cli.ts index 6fd2df0414c7..f4278d52db74 100644 --- a/packages/angular/cli/src/commands/cache/info/cli.ts +++ b/packages/angular/cli/src/commands/cache/info/cli.ts @@ -21,6 +21,7 @@ import { getCacheConfig } from '../utilities'; export class CacheInfoCommandModule extends CommandModule implements CommandModuleImplementation { command = 'info'; describe = 'Prints persistent disk cache configuration and statistics in the console.'; + longDescriptionPath?: string | undefined; override scope = CommandScope.In; builder(localYargs: Argv): Argv { diff --git a/packages/angular/cli/src/commands/cache/settings/cli.ts b/packages/angular/cli/src/commands/cache/settings/cli.ts index 5de2d5496475..9a4f654f7ac7 100644 --- a/packages/angular/cli/src/commands/cache/settings/cli.ts +++ b/packages/angular/cli/src/commands/cache/settings/cli.ts @@ -18,6 +18,7 @@ export class CacheDisableModule extends CommandModule implements CommandModuleIm command = 'disable'; aliases = 'off'; describe = 'Disables persistent disk cache for all projects in the workspace.'; + longDescriptionPath: string | undefined; override scope = CommandScope.In; builder(localYargs: Argv): Argv { @@ -33,6 +34,7 @@ export class CacheEnableModule extends CommandModule implements CommandModuleImp command = 'enable'; aliases = 'on'; describe = 'Enables disk cache for all projects in the workspace.'; + longDescriptionPath: string | undefined; override scope = CommandScope.In; builder(localYargs: Argv): Argv { diff --git a/packages/angular/cli/src/commands/completion/cli.ts b/packages/angular/cli/src/commands/completion/cli.ts index ab81ce5636d8..3fc9dccdc703 100644 --- a/packages/angular/cli/src/commands/completion/cli.ts +++ b/packages/angular/cli/src/commands/completion/cli.ts @@ -6,15 +6,13 @@ * found in the LICENSE file at https://angular.dev/license */ +import { join } from 'node:path'; import { Argv } from 'yargs'; import { CommandModule, CommandModuleImplementation } from '../../command-builder/command-module'; import { addCommandModuleToYargs } from '../../command-builder/utilities/command'; import { colors } from '../../utilities/color'; import { hasGlobalCliInstall, initializeAutocomplete } from '../../utilities/completion'; import { assertIsError } from '../../utilities/error'; -// eslint-disable-next-line @typescript-eslint/ban-ts-comment -// @ts-ignore strict-deps: Markdown files are asset dependencies bundled/loaded at runtime -import longDescription from './long-description.md'; export default class CompletionCommandModule extends CommandModule @@ -22,7 +20,7 @@ export default class CompletionCommandModule { command = 'completion'; describe = 'Set up Angular CLI autocompletion for your terminal.'; - override longDescription = longDescription; + longDescriptionPath = join(__dirname, 'long-description.md'); builder(localYargs: Argv): Argv { addCommandModuleToYargs(CompletionScriptCommandModule, this.context); @@ -66,6 +64,7 @@ Appended \`source <(ng completion script)\` to \`${rcFile}\`. Restart your termi class CompletionScriptCommandModule extends CommandModule implements CommandModuleImplementation { command = 'script'; describe = 'Generate a bash and zsh real-time type-ahead autocompletion script.'; + longDescriptionPath = undefined; builder(localYargs: Argv): Argv { return localYargs; diff --git a/packages/angular/cli/src/commands/config/cli.ts b/packages/angular/cli/src/commands/config/cli.ts index f339fd9bb1ba..06b253b9a42d 100644 --- a/packages/angular/cli/src/commands/config/cli.ts +++ b/packages/angular/cli/src/commands/config/cli.ts @@ -8,6 +8,7 @@ import { JsonValue } from '@angular-devkit/core'; import { randomUUID } from 'node:crypto'; +import { join } from 'node:path'; import { Argv } from 'yargs'; import { CommandModule, @@ -17,9 +18,6 @@ import { } from '../../command-builder/command-module'; import { getWorkspaceRaw, validateWorkspace } from '../../utilities/config'; import { JSONFile, parseJson } from '../../utilities/json-file'; -// eslint-disable-next-line @typescript-eslint/ban-ts-comment -// @ts-ignore strict-deps: Markdown files are asset dependencies bundled/loaded at runtime -import longDescription from './long-description.md'; interface ConfigCommandArgs { 'json-path'?: string; @@ -34,7 +32,7 @@ export default class ConfigCommandModule command = 'config [json-path] [value]'; describe = 'Retrieves or sets Angular configuration values in the angular.json file for the workspace.'; - override longDescription = longDescription; + longDescriptionPath = join(__dirname, 'long-description.md'); builder(localYargs: Argv): Argv { return localYargs diff --git a/packages/angular/cli/src/commands/deploy/cli.ts b/packages/angular/cli/src/commands/deploy/cli.ts index 28317cff1ee1..947dc90af2d4 100644 --- a/packages/angular/cli/src/commands/deploy/cli.ts +++ b/packages/angular/cli/src/commands/deploy/cli.ts @@ -6,12 +6,10 @@ * found in the LICENSE file at https://angular.dev/license */ +import { join } from 'node:path'; import { MissingTargetChoice } from '../../command-builder/architect-base-command-module'; import { ArchitectCommandModule } from '../../command-builder/architect-command-module'; import { CommandModuleImplementation } from '../../command-builder/command-module'; -// eslint-disable-next-line @typescript-eslint/ban-ts-comment -// @ts-ignore strict-deps: Markdown files are asset dependencies bundled/loaded at runtime -import longDescription from './long-description.md'; export default class DeployCommandModule extends ArchitectCommandModule @@ -39,7 +37,7 @@ export default class DeployCommandModule multiTarget = false; command = 'deploy [project]'; - override longDescription = longDescription; + longDescriptionPath = join(__dirname, 'long-description.md'); describe = 'Invokes the deploy builder for a specified project or for the default project in the workspace.'; } diff --git a/packages/angular/cli/src/commands/e2e/cli.ts b/packages/angular/cli/src/commands/e2e/cli.ts index 9d63a8d96fb4..85d9aab173a0 100644 --- a/packages/angular/cli/src/commands/e2e/cli.ts +++ b/packages/angular/cli/src/commands/e2e/cli.ts @@ -42,4 +42,5 @@ export default class E2eCommandModule command = 'e2e [project]'; aliases = RootCommands['e2e'].aliases; describe = 'Builds and serves an Angular application, then runs end-to-end tests.'; + longDescriptionPath?: string; } diff --git a/packages/angular/cli/src/commands/extract-i18n/cli.ts b/packages/angular/cli/src/commands/extract-i18n/cli.ts index 09b3df343403..4f3dea2d8e7e 100644 --- a/packages/angular/cli/src/commands/extract-i18n/cli.ts +++ b/packages/angular/cli/src/commands/extract-i18n/cli.ts @@ -19,6 +19,7 @@ export default class ExtractI18nCommandModule multiTarget = false; command = 'extract-i18n [project]'; describe = 'Extracts i18n messages from source code.'; + longDescriptionPath?: string | undefined; override async findDefaultBuilderName( project: workspaces.ProjectDefinition, diff --git a/packages/angular/cli/src/commands/generate/cli.ts b/packages/angular/cli/src/commands/generate/cli.ts index 8f605e03a18b..4be29c3eaea0 100644 --- a/packages/angular/cli/src/commands/generate/cli.ts +++ b/packages/angular/cli/src/commands/generate/cli.ts @@ -38,6 +38,7 @@ export default class GenerateCommandModule command = 'generate'; aliases = RootCommands['generate'].aliases; describe = 'Generates and/or modifies files based on a schematic.'; + longDescriptionPath?: string | undefined; override async builder(argv: Argv): Promise> { let localYargs = (await super.builder(argv)).command({ diff --git a/packages/angular/cli/src/commands/lint/cli.ts b/packages/angular/cli/src/commands/lint/cli.ts index 3fdd38fc169c..9510dd7afe53 100644 --- a/packages/angular/cli/src/commands/lint/cli.ts +++ b/packages/angular/cli/src/commands/lint/cli.ts @@ -6,12 +6,10 @@ * found in the LICENSE file at https://angular.dev/license */ +import { join } from 'node:path'; import { MissingTargetChoice } from '../../command-builder/architect-base-command-module'; import { ArchitectCommandModule } from '../../command-builder/architect-command-module'; import { CommandModuleImplementation } from '../../command-builder/command-module'; -// eslint-disable-next-line @typescript-eslint/ban-ts-comment -// @ts-ignore strict-deps: Markdown files are asset dependencies bundled/loaded at runtime -import longDescription from './long-description.md'; export default class LintCommandModule extends ArchitectCommandModule @@ -26,6 +24,6 @@ export default class LintCommandModule multiTarget = true; command = 'lint [project]'; - override longDescription = longDescription; + longDescriptionPath = join(__dirname, 'long-description.md'); describe = 'Runs linting tools on Angular application code in a given project folder.'; } diff --git a/packages/angular/cli/src/commands/make-this-awesome/cli.ts b/packages/angular/cli/src/commands/make-this-awesome/cli.ts index 8e36447f1f3a..6a17c5614b94 100644 --- a/packages/angular/cli/src/commands/make-this-awesome/cli.ts +++ b/packages/angular/cli/src/commands/make-this-awesome/cli.ts @@ -17,6 +17,7 @@ export default class AwesomeCommandModule command = 'make-this-awesome'; describe = false as const; deprecated = false; + longDescriptionPath?: string | undefined; builder(localYargs: Argv): Argv { return localYargs; diff --git a/packages/angular/cli/src/commands/mcp/cli.ts b/packages/angular/cli/src/commands/mcp/cli.ts index cbc94499a9ca..a379022e8f5e 100644 --- a/packages/angular/cli/src/commands/mcp/cli.ts +++ b/packages/angular/cli/src/commands/mcp/cli.ts @@ -35,6 +35,7 @@ For more information and documentation, visit: https://angular.dev/ai/mcp export default class McpCommandModule extends CommandModule implements CommandModuleImplementation { command = 'mcp'; describe = false as const; + longDescriptionPath = undefined; builder(localYargs: Argv): Argv { return localYargs diff --git a/packages/angular/cli/src/commands/new/cli.ts b/packages/angular/cli/src/commands/new/cli.ts index c47f3c63153b..6e6545e66421 100644 --- a/packages/angular/cli/src/commands/new/cli.ts +++ b/packages/angular/cli/src/commands/new/cli.ts @@ -6,6 +6,7 @@ * found in the LICENSE file at https://angular.dev/license */ +import { join } from 'node:path'; import { Argv } from 'yargs'; import { CommandModuleImplementation, @@ -20,9 +21,6 @@ import { } from '../../command-builder/schematics-command-module'; import { VERSION } from '../../utilities/version'; import { RootCommands } from '../command-config'; -// eslint-disable-next-line @typescript-eslint/ban-ts-comment -// @ts-ignore strict-deps: Markdown files are asset dependencies bundled/loaded at runtime -import longDescription from './long-description.md'; interface NewCommandArgs extends SchematicsCommandArgs { collection?: string; @@ -39,7 +37,7 @@ export default class NewCommandModule command = 'new [name]'; aliases = RootCommands['new'].aliases; describe = 'Creates a new Angular workspace.'; - override longDescription = longDescription; + longDescriptionPath = join(__dirname, 'long-description.md'); override async builder(argv: Argv): Promise> { const localYargs = (await super.builder(argv)).option('collection', { diff --git a/packages/angular/cli/src/commands/run/cli.ts b/packages/angular/cli/src/commands/run/cli.ts index 774f811aa2a5..aa12cd0158f7 100644 --- a/packages/angular/cli/src/commands/run/cli.ts +++ b/packages/angular/cli/src/commands/run/cli.ts @@ -7,6 +7,7 @@ */ import { Target } from '@angular-devkit/architect'; +import { join } from 'node:path'; import { Argv } from 'yargs'; import { ArchitectBaseCommandModule } from '../../command-builder/architect-base-command-module'; import { @@ -16,9 +17,6 @@ import { Options, OtherOptions, } from '../../command-builder/command-module'; -// eslint-disable-next-line @typescript-eslint/ban-ts-comment -// @ts-ignore strict-deps: Markdown files are asset dependencies bundled/loaded at runtime -import longDescription from './long-description.md'; export interface RunCommandArgs { target: string; @@ -33,7 +31,7 @@ export default class RunCommandModule command = 'run '; describe = 'Runs an Architect target with an optional custom builder configuration defined in your project.'; - override longDescription = longDescription; + longDescriptionPath = join(__dirname, 'long-description.md'); async builder(argv: Argv): Promise> { const { jsonHelp, getYargsCompletions, help } = this.context.args.options; diff --git a/packages/angular/cli/src/commands/serve/cli.ts b/packages/angular/cli/src/commands/serve/cli.ts index 6448c48b9484..3b38fa122acd 100644 --- a/packages/angular/cli/src/commands/serve/cli.ts +++ b/packages/angular/cli/src/commands/serve/cli.ts @@ -18,4 +18,5 @@ export default class ServeCommandModule command = 'serve [project]'; aliases = RootCommands['serve'].aliases; describe = 'Builds and serves your application, rebuilding on file changes.'; + longDescriptionPath?: string | undefined; } diff --git a/packages/angular/cli/src/commands/test/cli.ts b/packages/angular/cli/src/commands/test/cli.ts index f9dcaaf92c8c..600e9f41f517 100644 --- a/packages/angular/cli/src/commands/test/cli.ts +++ b/packages/angular/cli/src/commands/test/cli.ts @@ -6,12 +6,10 @@ * found in the LICENSE file at https://angular.dev/license */ +import { join } from 'node:path'; import { ArchitectCommandModule } from '../../command-builder/architect-command-module'; import { CommandModuleImplementation } from '../../command-builder/command-module'; import { RootCommands } from '../command-config'; -// eslint-disable-next-line @typescript-eslint/ban-ts-comment -// @ts-ignore strict-deps: Markdown files are asset dependencies bundled/loaded at runtime -import longDescription from './long-description.md'; export default class TestCommandModule extends ArchitectCommandModule @@ -21,5 +19,5 @@ export default class TestCommandModule command = 'test [project]'; aliases = RootCommands['test'].aliases; describe = 'Runs unit tests in a project.'; - override longDescription = longDescription; + longDescriptionPath = join(__dirname, 'long-description.md'); } diff --git a/packages/angular/cli/src/commands/update/cli.ts b/packages/angular/cli/src/commands/update/cli.ts index 6418bfc13ce4..005df998b501 100644 --- a/packages/angular/cli/src/commands/update/cli.ts +++ b/packages/angular/cli/src/commands/update/cli.ts @@ -24,9 +24,6 @@ import type { InstalledPackage, PackageManager, PackageManifest } from '../../pa import { colors } from '../../utilities/color'; import { disableVersionCheck } from '../../utilities/environment-options'; import { assertIsError } from '../../utilities/error'; -// eslint-disable-next-line @typescript-eslint/ban-ts-comment -// @ts-ignore strict-deps: Markdown files are asset dependencies bundled/loaded at runtime -import longDescription from './long-description.md'; import { UpdatePlan, applyUpdatePlan, @@ -66,7 +63,7 @@ export default class UpdateCommandModule extends CommandModule { return localYargs diff --git a/packages/angular/cli/src/commands/version/cli.ts b/packages/angular/cli/src/commands/version/cli.ts index 1a79b8b76eef..205f0bc7e55e 100644 --- a/packages/angular/cli/src/commands/version/cli.ts +++ b/packages/angular/cli/src/commands/version/cli.ts @@ -37,6 +37,7 @@ export default class VersionCommandModule command = 'version'; aliases = RootCommands['version'].aliases; describe = 'Outputs Angular CLI version.'; + longDescriptionPath?: string | undefined; /** * Builds the command-line options for the `ng version` command. diff --git a/packages/angular/cli/src/typings.d.ts b/packages/angular/cli/src/typings.d.ts deleted file mode 100644 index 12e7de03c204..000000000000 --- a/packages/angular/cli/src/typings.d.ts +++ /dev/null @@ -1,12 +0,0 @@ -/** - * @license - * Copyright Google LLC All Rights Reserved. - * - * Use of this source code is governed by an MIT-style license that can be - * found in the LICENSE file at https://angular.dev/license - */ - -declare module '*/long-description.md' { - const content: string; - export default content; -} diff --git a/packages/angular/cli/src/utilities/markdown-loader.ts b/packages/angular/cli/src/utilities/markdown-loader.ts deleted file mode 100644 index 3a70a5eaae1c..000000000000 --- a/packages/angular/cli/src/utilities/markdown-loader.ts +++ /dev/null @@ -1,35 +0,0 @@ -/** - * @license - * Copyright Google LLC All Rights Reserved. - * - * Use of this source code is governed by an MIT-style license that can be - * found in the LICENSE file at https://angular.dev/license - */ - -import { readFileSync } from 'node:fs'; - -const LONG_DESCRIPTION_REGEXP = /[/\\]long-description\.md$/; - -function isCommandLongDescription(filePath: string | undefined): boolean { - return !!filePath && LONG_DESCRIPTION_REGEXP.test(filePath); -} - -// Register markdown extension hook for CommonJS execution -if (typeof require !== 'undefined' && require.extensions) { - const originalMdExtension = require.extensions['.md']; - require.extensions['.md'] = (module, filename) => { - if (isCommandLongDescription(filename)) { - module.exports = readFileSync(filename, 'utf8'); - - return; - } - - if (originalMdExtension) { - originalMdExtension(module, filename); - } else { - const err = new Error(`Cannot find module '${filename}'`); - (err as NodeJS.ErrnoException).code = 'MODULE_NOT_FOUND'; - throw err; - } - }; -} From cf21837ca0f35ff8e1866df5fc35437807e78d77 Mon Sep 17 00:00:00 2001 From: Angular Robot Date: Thu, 17 Sep 2026 15:30:26 +0000 Subject: [PATCH 008/233] build: update cross-repo angular dependencies See associated pull request for more information. --- .../assistant-to-the-branch-manager.yml | 2 +- .github/workflows/ci.yml | 52 ++++++++-------- .github/workflows/dev-infra.yml | 6 +- .github/workflows/perf.yml | 6 +- .github/workflows/pr.yml | 44 ++++++------- MODULE.bazel | 4 +- MODULE.bazel.lock | 6 +- package.json | 2 +- pnpm-lock.yaml | 61 ++----------------- 9 files changed, 66 insertions(+), 117 deletions(-) diff --git a/.github/workflows/assistant-to-the-branch-manager.yml b/.github/workflows/assistant-to-the-branch-manager.yml index c767c09e4f07..1fcd15f0c5b9 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@837e71330341e19050ebc3808e02d7fb2d112be5 # main + - uses: angular/dev-infra/github-actions/branch-manager@99d57027286c71dda92d8b91a3607abcf92d8bbd # main with: angular-robot-key: ${{ secrets.ANGULAR_ROBOT_PRIVATE_KEY }} diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 80027a577866..cee6fbdfbda5 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@837e71330341e19050ebc3808e02d7fb2d112be5 # main + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@99d57027286c71dda92d8b91a3607abcf92d8bbd # main - name: Setup Bazel - uses: angular/dev-infra/github-actions/bazel/setup@837e71330341e19050ebc3808e02d7fb2d112be5 # main + uses: angular/dev-infra/github-actions/bazel/setup@99d57027286c71dda92d8b91a3607abcf92d8bbd # 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@837e71330341e19050ebc3808e02d7fb2d112be5 # main + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@99d57027286c71dda92d8b91a3607abcf92d8bbd # main - name: Setup Bazel - uses: angular/dev-infra/github-actions/bazel/setup@837e71330341e19050ebc3808e02d7fb2d112be5 # main + uses: angular/dev-infra/github-actions/bazel/setup@99d57027286c71dda92d8b91a3607abcf92d8bbd # main - name: Setup Bazel RBE - uses: angular/dev-infra/github-actions/bazel/configure-remote@837e71330341e19050ebc3808e02d7fb2d112be5 # main + uses: angular/dev-infra/github-actions/bazel/configure-remote@99d57027286c71dda92d8b91a3607abcf92d8bbd # 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@837e71330341e19050ebc3808e02d7fb2d112be5 # main + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@99d57027286c71dda92d8b91a3607abcf92d8bbd # main - name: Setup Bazel - uses: angular/dev-infra/github-actions/bazel/setup@837e71330341e19050ebc3808e02d7fb2d112be5 # main + uses: angular/dev-infra/github-actions/bazel/setup@99d57027286c71dda92d8b91a3607abcf92d8bbd # main - name: Setup Bazel RBE - uses: angular/dev-infra/github-actions/bazel/configure-remote@837e71330341e19050ebc3808e02d7fb2d112be5 # main + uses: angular/dev-infra/github-actions/bazel/configure-remote@99d57027286c71dda92d8b91a3607abcf92d8bbd # 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@837e71330341e19050ebc3808e02d7fb2d112be5 # main + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@99d57027286c71dda92d8b91a3607abcf92d8bbd # main - name: Install node modules run: pnpm install --frozen-lockfile - name: Setup Bazel - uses: angular/dev-infra/github-actions/bazel/setup@837e71330341e19050ebc3808e02d7fb2d112be5 # main + uses: angular/dev-infra/github-actions/bazel/setup@99d57027286c71dda92d8b91a3607abcf92d8bbd # main - name: Setup Bazel RBE - uses: angular/dev-infra/github-actions/bazel/configure-remote@837e71330341e19050ebc3808e02d7fb2d112be5 # main + uses: angular/dev-infra/github-actions/bazel/configure-remote@99d57027286c71dda92d8b91a3607abcf92d8bbd # 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@837e71330341e19050ebc3808e02d7fb2d112be5 # main + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@99d57027286c71dda92d8b91a3607abcf92d8bbd # main - name: Setup Bazel - uses: angular/dev-infra/github-actions/bazel/setup@837e71330341e19050ebc3808e02d7fb2d112be5 # main + uses: angular/dev-infra/github-actions/bazel/setup@99d57027286c71dda92d8b91a3607abcf92d8bbd # main - name: Setup Bazel RBE - uses: angular/dev-infra/github-actions/bazel/configure-remote@837e71330341e19050ebc3808e02d7fb2d112be5 # main + uses: angular/dev-infra/github-actions/bazel/configure-remote@99d57027286c71dda92d8b91a3607abcf92d8bbd # 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@837e71330341e19050ebc3808e02d7fb2d112be5 # main + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@99d57027286c71dda92d8b91a3607abcf92d8bbd # 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@837e71330341e19050ebc3808e02d7fb2d112be5 # main + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@99d57027286c71dda92d8b91a3607abcf92d8bbd # main - name: Install node modules run: pnpm install --frozen-lockfile - name: Setup Bazel - uses: angular/dev-infra/github-actions/bazel/setup@837e71330341e19050ebc3808e02d7fb2d112be5 # main + uses: angular/dev-infra/github-actions/bazel/setup@99d57027286c71dda92d8b91a3607abcf92d8bbd # main - name: Setup Bazel RBE - uses: angular/dev-infra/github-actions/bazel/configure-remote@837e71330341e19050ebc3808e02d7fb2d112be5 # main + uses: angular/dev-infra/github-actions/bazel/configure-remote@99d57027286c71dda92d8b91a3607abcf92d8bbd # 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@837e71330341e19050ebc3808e02d7fb2d112be5 # main + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@99d57027286c71dda92d8b91a3607abcf92d8bbd # main - name: Install node modules run: pnpm install --frozen-lockfile - name: Setup Bazel - uses: angular/dev-infra/github-actions/bazel/setup@837e71330341e19050ebc3808e02d7fb2d112be5 # main + uses: angular/dev-infra/github-actions/bazel/setup@99d57027286c71dda92d8b91a3607abcf92d8bbd # main - name: Setup Bazel RBE - uses: angular/dev-infra/github-actions/bazel/configure-remote@837e71330341e19050ebc3808e02d7fb2d112be5 # main + uses: angular/dev-infra/github-actions/bazel/configure-remote@99d57027286c71dda92d8b91a3607abcf92d8bbd # 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@837e71330341e19050ebc3808e02d7fb2d112be5 # main + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@99d57027286c71dda92d8b91a3607abcf92d8bbd # main - name: Install node modules run: pnpm install --frozen-lockfile - name: Setup Bazel - uses: angular/dev-infra/github-actions/bazel/setup@837e71330341e19050ebc3808e02d7fb2d112be5 # main + uses: angular/dev-infra/github-actions/bazel/setup@99d57027286c71dda92d8b91a3607abcf92d8bbd # main - name: Setup Bazel RBE - uses: angular/dev-infra/github-actions/bazel/configure-remote@837e71330341e19050ebc3808e02d7fb2d112be5 # main + uses: angular/dev-infra/github-actions/bazel/configure-remote@99d57027286c71dda92d8b91a3607abcf92d8bbd # 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@837e71330341e19050ebc3808e02d7fb2d112be5 # main + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@99d57027286c71dda92d8b91a3607abcf92d8bbd # main - name: Install node modules run: pnpm install --frozen-lockfile - name: Setup Bazel - uses: angular/dev-infra/github-actions/bazel/setup@837e71330341e19050ebc3808e02d7fb2d112be5 # main + uses: angular/dev-infra/github-actions/bazel/setup@99d57027286c71dda92d8b91a3607abcf92d8bbd # 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 4dc1c8378728..b12b3dc168ea 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@837e71330341e19050ebc3808e02d7fb2d112be5 # main + - uses: angular/dev-infra/github-actions/labeling/pull-request@99d57027286c71dda92d8b91a3607abcf92d8bbd # 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@837e71330341e19050ebc3808e02d7fb2d112be5 # main + - uses: angular/dev-infra/github-actions/post-approval-changes@99d57027286c71dda92d8b91a3607abcf92d8bbd # 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@837e71330341e19050ebc3808e02d7fb2d112be5 # main + - uses: angular/dev-infra/github-actions/labeling/issue@99d57027286c71dda92d8b91a3607abcf92d8bbd # 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 84b5b8cfb21d..b837b722a4f4 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@837e71330341e19050ebc3808e02d7fb2d112be5 # main + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@99d57027286c71dda92d8b91a3607abcf92d8bbd # 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@837e71330341e19050ebc3808e02d7fb2d112be5 # main + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@99d57027286c71dda92d8b91a3607abcf92d8bbd # main - name: Setup Bazel - uses: angular/dev-infra/github-actions/bazel/setup@837e71330341e19050ebc3808e02d7fb2d112be5 # main + uses: angular/dev-infra/github-actions/bazel/setup@99d57027286c71dda92d8b91a3607abcf92d8bbd # 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 400910007dda..c62816440333 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@837e71330341e19050ebc3808e02d7fb2d112be5 # main + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@99d57027286c71dda92d8b91a3607abcf92d8bbd # main - name: Setup Bazel - uses: angular/dev-infra/github-actions/bazel/setup@837e71330341e19050ebc3808e02d7fb2d112be5 # main + uses: angular/dev-infra/github-actions/bazel/setup@99d57027286c71dda92d8b91a3607abcf92d8bbd # 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@837e71330341e19050ebc3808e02d7fb2d112be5 # main + uses: angular/dev-infra/github-actions/linting/licenses@99d57027286c71dda92d8b91a3607abcf92d8bbd # main build: runs-on: ubuntu-latest steps: - name: Initialize environment - uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@837e71330341e19050ebc3808e02d7fb2d112be5 # main + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@99d57027286c71dda92d8b91a3607abcf92d8bbd # main - name: Setup Bazel - uses: angular/dev-infra/github-actions/bazel/setup@837e71330341e19050ebc3808e02d7fb2d112be5 # main + uses: angular/dev-infra/github-actions/bazel/setup@99d57027286c71dda92d8b91a3607abcf92d8bbd # main - name: Setup Bazel RBE - uses: angular/dev-infra/github-actions/bazel/configure-remote@837e71330341e19050ebc3808e02d7fb2d112be5 # main + uses: angular/dev-infra/github-actions/bazel/configure-remote@99d57027286c71dda92d8b91a3607abcf92d8bbd # 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@837e71330341e19050ebc3808e02d7fb2d112be5 # main + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@99d57027286c71dda92d8b91a3607abcf92d8bbd # main - name: Setup Bazel - uses: angular/dev-infra/github-actions/bazel/setup@837e71330341e19050ebc3808e02d7fb2d112be5 # main + uses: angular/dev-infra/github-actions/bazel/setup@99d57027286c71dda92d8b91a3607abcf92d8bbd # main - name: Setup Bazel RBE - uses: angular/dev-infra/github-actions/bazel/configure-remote@837e71330341e19050ebc3808e02d7fb2d112be5 # main + uses: angular/dev-infra/github-actions/bazel/configure-remote@99d57027286c71dda92d8b91a3607abcf92d8bbd # 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@837e71330341e19050ebc3808e02d7fb2d112be5 # main + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@99d57027286c71dda92d8b91a3607abcf92d8bbd # main - name: Install node modules run: pnpm install --frozen-lockfile - name: Setup Bazel - uses: angular/dev-infra/github-actions/bazel/setup@837e71330341e19050ebc3808e02d7fb2d112be5 # main + uses: angular/dev-infra/github-actions/bazel/setup@99d57027286c71dda92d8b91a3607abcf92d8bbd # main - name: Setup Bazel RBE - uses: angular/dev-infra/github-actions/bazel/configure-remote@837e71330341e19050ebc3808e02d7fb2d112be5 # main + uses: angular/dev-infra/github-actions/bazel/configure-remote@99d57027286c71dda92d8b91a3607abcf92d8bbd # 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@837e71330341e19050ebc3808e02d7fb2d112be5 # main + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@99d57027286c71dda92d8b91a3607abcf92d8bbd # main - name: Setup Bazel - uses: angular/dev-infra/github-actions/bazel/setup@837e71330341e19050ebc3808e02d7fb2d112be5 # main + uses: angular/dev-infra/github-actions/bazel/setup@99d57027286c71dda92d8b91a3607abcf92d8bbd # main - name: Setup Bazel RBE - uses: angular/dev-infra/github-actions/bazel/configure-remote@837e71330341e19050ebc3808e02d7fb2d112be5 # main + uses: angular/dev-infra/github-actions/bazel/configure-remote@99d57027286c71dda92d8b91a3607abcf92d8bbd # 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@837e71330341e19050ebc3808e02d7fb2d112be5 # main + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@99d57027286c71dda92d8b91a3607abcf92d8bbd # 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@837e71330341e19050ebc3808e02d7fb2d112be5 # main + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@99d57027286c71dda92d8b91a3607abcf92d8bbd # main - name: Install node modules run: pnpm install --frozen-lockfile - name: Setup Bazel - uses: angular/dev-infra/github-actions/bazel/setup@837e71330341e19050ebc3808e02d7fb2d112be5 # main + uses: angular/dev-infra/github-actions/bazel/setup@99d57027286c71dda92d8b91a3607abcf92d8bbd # main - name: Setup Bazel RBE - uses: angular/dev-infra/github-actions/bazel/configure-remote@837e71330341e19050ebc3808e02d7fb2d112be5 # main + uses: angular/dev-infra/github-actions/bazel/configure-remote@99d57027286c71dda92d8b91a3607abcf92d8bbd # 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@837e71330341e19050ebc3808e02d7fb2d112be5 # main + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@99d57027286c71dda92d8b91a3607abcf92d8bbd # main - name: Install node modules run: pnpm install --frozen-lockfile - name: Setup Bazel - uses: angular/dev-infra/github-actions/bazel/setup@837e71330341e19050ebc3808e02d7fb2d112be5 # main + uses: angular/dev-infra/github-actions/bazel/setup@99d57027286c71dda92d8b91a3607abcf92d8bbd # main - name: Setup Bazel RBE - uses: angular/dev-infra/github-actions/bazel/configure-remote@837e71330341e19050ebc3808e02d7fb2d112be5 # main + uses: angular/dev-infra/github-actions/bazel/configure-remote@99d57027286c71dda92d8b91a3607abcf92d8bbd # 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 9c3fd0ab9019..595813a5abf1 100644 --- a/MODULE.bazel +++ b/MODULE.bazel @@ -19,14 +19,14 @@ bazel_dep(name = "aspect_rules_jasmine", version = "2.0.4") bazel_dep(name = "rules_angular") git_override( module_name = "rules_angular", - commit = "3f933b9dde5139e67575b6c2437c854986ecd10a", + commit = "7fdee07b9989b92b88f24c84471e01d6a0a9bc34", remote = "https://github.com/angular/rules_angular.git", ) bazel_dep(name = "devinfra") git_override( module_name = "devinfra", - commit = "837e71330341e19050ebc3808e02d7fb2d112be5", + commit = "99d57027286c71dda92d8b91a3607abcf92d8bbd", remote = "https://github.com/angular/dev-infra.git", ) diff --git a/MODULE.bazel.lock b/MODULE.bazel.lock index 31e442ccf216..2f5985594341 100644 --- a/MODULE.bazel.lock +++ b/MODULE.bazel.lock @@ -21,7 +21,6 @@ "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.27.0/MODULE.bazel": "877dafc0b925f8af19e8bc2abed04a757bb565c57c1866e8851ac4d15ed5e6d2", "https://bcr.bazel.build/modules/aspect_rules_esbuild/0.27.1/MODULE.bazel": "99c3978959edd9892e4b513831b218a13cc84a0215bfe1b972a1e3a771c4670e", "https://bcr.bazel.build/modules/aspect_rules_esbuild/0.27.1/source.json": "20f515102cbcd0835d90bb3976b193eb58c2a0c534093c85cfd3bf6f06dba748", "https://bcr.bazel.build/modules/aspect_rules_jasmine/2.0.4/MODULE.bazel": "fbb819eb8b7e5d7f67fdd38f7cecb413e287594cd666ce192c72c8828527775a", @@ -90,7 +89,6 @@ "https://bcr.bazel.build/modules/googletest/1.14.0/MODULE.bazel": "cfbcbf3e6eac06ef9d85900f64424708cc08687d1b527f0ef65aa7517af8118f", "https://bcr.bazel.build/modules/jq.bzl/0.1.0/MODULE.bazel": "2ce69b1af49952cd4121a9c3055faa679e748ce774c7f1fda9657f936cae902f", "https://bcr.bazel.build/modules/jq.bzl/0.4.0/MODULE.bazel": "a7b39b37589f2b0dad53fd6c1ccaabbdb290330caa920d7ef3e6aad068cd4ab2", - "https://bcr.bazel.build/modules/jq.bzl/0.6.1/MODULE.bazel": "f30c46e0a08a9f7566a8bf60a43d48abea960cd7f57b315b01e2762f1537eb52", "https://bcr.bazel.build/modules/jq.bzl/0.6.2/MODULE.bazel": "e9c82f9b1e720d4ab0e232d32c05f0f4d0f92a8e8bb6a0da8f7cd27823b93e05", "https://bcr.bazel.build/modules/jq.bzl/0.6.2/source.json": "e36f8ed173a6ca6e627f9d659ae504733d5a991859805661e4aacd34d8ae0639", "https://bcr.bazel.build/modules/jsoncpp/1.9.5/MODULE.bazel": "31271aedc59e815656f5736f282bb7509a97c7ecb43e927ac1a37966e0578075", @@ -211,8 +209,8 @@ "https://bcr.bazel.build/modules/stardoc/0.7.2/MODULE.bazel": "fc152419aa2ea0f51c29583fab1e8c99ddefd5b3778421845606ee628629e0e5", "https://bcr.bazel.build/modules/stardoc/0.7.2/source.json": "58b029e5e901d6802967754adf0a9056747e8176f017cfe3607c0851f4d42216", "https://bcr.bazel.build/modules/tar.bzl/0.10.4/MODULE.bazel": "e8f9ff79199e8d9eaad7f1b0a77ad74b30bb82d794b87d8ca942bead5de83ae9", - "https://bcr.bazel.build/modules/tar.bzl/0.10.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.10.9/MODULE.bazel": "4636f5f6a7c34d3d0653634ed95a34560426d548c5301c6c5924c885ef737b46", + "https://bcr.bazel.build/modules/tar.bzl/0.10.9/source.json": "30a5cf0a8281adce53ab1c5a4291e88b2c161e2df1feb6cba4ee50556f1748d7", "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/upb/0.0.0-20220923-a547704/MODULE.bazel": "7298990c00040a0e2f121f6c32544bab27d4452f80d9ce51349b1a28f3005c43", diff --git a/package.json b/package.json index 49ef7f8b1128..331ab53b141f 100644 --- a/package.json +++ b/package.json @@ -55,7 +55,7 @@ "@angular/forms": "22.2.0-rc.0", "@angular/localize": "22.2.0-rc.0", "@angular/material": "22.2.0-rc.0", - "@angular/ng-dev": "https://github.com/angular/dev-infra-private-ng-dev-builds.git#f166178ac5c37cd3aadab7b8cb7212f34d71b2a6", + "@angular/ng-dev": "https://github.com/angular/dev-infra-private-ng-dev-builds.git#f5de34cabca7e005dc8102d3abb026d01a7a881a", "@angular/platform-browser": "22.2.0-rc.0", "@angular/platform-server": "22.2.0-rc.0", "@angular/router": "22.2.0-rc.0", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 11feaf7d1151..c0c4d347a5ef 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -208,8 +208,8 @@ importers: specifier: 22.2.0-rc.0 version: 22.2.0-rc.0(25ddf4063a130bbf19862bd16a6ab5d4) '@angular/ng-dev': - specifier: https://github.com/angular/dev-infra-private-ng-dev-builds.git#f166178ac5c37cd3aadab7b8cb7212f34d71b2a6 - version: https://codeload.github.com/angular/dev-infra-private-ng-dev-builds/tar.gz/f166178ac5c37cd3aadab7b8cb7212f34d71b2a6 + specifier: https://github.com/angular/dev-infra-private-ng-dev-builds.git#f5de34cabca7e005dc8102d3abb026d01a7a881a + version: https://codeload.github.com/angular/dev-infra-private-ng-dev-builds/tar.gz/f5de34cabca7e005dc8102d3abb026d01a7a881a '@angular/platform-browser': specifier: 22.2.0-rc.0 version: 22.2.0-rc.0(@angular/animations@22.2.0-rc.0(@angular/core@22.2.0-rc.0(@angular/compiler@22.2.0-rc.0)(rxjs@7.8.2)(zone.js@0.16.3)))(@angular/common@22.2.0-rc.0(@angular/core@22.2.0-rc.0(@angular/compiler@22.2.0-rc.0)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2))(@angular/core@22.2.0-rc.0(@angular/compiler@22.2.0-rc.0)(rxjs@7.8.2)(zone.js@0.16.3)) @@ -1103,9 +1103,9 @@ packages: '@angular/platform-browser': ^22.0.0-0 || ^22.1.0-0 || ^22.2.0-0 || ^22.3.0-0 || ^23.0.0-0 rxjs: ^6.5.3 || ^7.4.0 - '@angular/ng-dev@https://codeload.github.com/angular/dev-infra-private-ng-dev-builds/tar.gz/f166178ac5c37cd3aadab7b8cb7212f34d71b2a6': - resolution: {gitHosted: true, integrity: sha512-5NrBeSt7Q//Qrxhy1OVNDNuGiZLdFOaIPMLtCgjypDsJc214fEI4xRKqN7zIpAQfMlZDoIFMh7vodM/uB9oq3A==, tarball: https://codeload.github.com/angular/dev-infra-private-ng-dev-builds/tar.gz/f166178ac5c37cd3aadab7b8cb7212f34d71b2a6} - version: 0.0.0-cde7ad16c16f5c7dbd57b62e8b930443813484ec + '@angular/ng-dev@https://codeload.github.com/angular/dev-infra-private-ng-dev-builds/tar.gz/f5de34cabca7e005dc8102d3abb026d01a7a881a': + resolution: {gitHosted: true, integrity: sha512-JEXOlRtQ50aV/E2C+PeGKYCmGHWOi6G70kiS0tTjKGAn+qrYTRQQzFSm4YB2VVYnL16s3jg8oAIwZ4pl/t9WgQ==, tarball: https://codeload.github.com/angular/dev-infra-private-ng-dev-builds/tar.gz/f5de34cabca7e005dc8102d3abb026d01a7a881a} + version: 0.0.0-71e60c68d9d483b0d763b8e6ed4dd9deb8da3b1a hasBin: true '@angular/platform-browser@22.2.0-rc.0': @@ -3265,26 +3265,6 @@ packages: resolution: {integrity: sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==} engines: {node: '>=14'} - '@pnpm/crypto.hash@1000.2.2': - resolution: {integrity: sha512-W8pLZvXWLlGG5p0Z2nCvtBhlM6uuTcbAbsS15wlGS31jBBJKJW2udLoFeM7qfWPo7E2PqRPGxca7APpVYAjJhw==} - engines: {node: '>=18.12'} - - '@pnpm/crypto.polyfill@1000.1.0': - resolution: {integrity: sha512-tNe7a6U4rCpxLMBaR0SIYTdjxGdL0Vwb3G1zY8++sPtHSvy7qd54u8CIB0Z+Y6t5tc9pNYMYCMwhE/wdSY7ltg==} - engines: {node: '>=18.12'} - - '@pnpm/dependency-path@1001.1.10': - resolution: {integrity: sha512-PNImtV2SmNTDpLi4HdN86tJPmsOeIxm4VhmxgBVsMrJPEBfkNEWFcflR3wU6XVn/26g9qWdvlNHaawtCjeB93Q==} - engines: {node: '>=18.12'} - - '@pnpm/graceful-fs@1000.1.0': - resolution: {integrity: sha512-EsMX4slK0qJN2AR0/AYohY5m0HQNYGMNe+jhN74O994zp22/WbX+PbkIKyw3UQn39yQm2+z6SgwklDxbeapsmQ==} - engines: {node: '>=18.12'} - - '@pnpm/types@1001.3.0': - resolution: {integrity: sha512-NLTXheat/u7OEGg5M5vF6Z85zx8uKUZE0+whtX/sbFV2XL48RdnOWGPTKYuVVkv8M+launaLUTgGEXNs/ess2w==} - engines: {node: '>=18.12'} - '@protobufjs/aspromise@1.1.2': resolution: {integrity: sha512-j+gKExEuLmKwvz3OgROXtrJ2UG2x8Ch2YZUxahh+s1F2HZ+wAceUNLkvy6zKCPVRkU++ZWQrdxsUeQXmcg4uoQ==} @@ -7941,10 +7921,6 @@ packages: engines: {node: '>=0.10.0'} hasBin: true - ssri@10.0.5: - resolution: {integrity: sha512-bSf16tAFkGeRlUNDjXu8FzaMQt6g2HZJrun7mtMbIPOddxt3GLMSz5VWUWcqTJUPfLEaDIepGxv+bYQW49596A==} - engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} - stack-trace@0.0.10: resolution: {integrity: sha512-KGzahc7puUKkzyMt+IqAep+TVNbKP+k2Lmwhub39m1AsTSkaDutx56aDCo+HLDzf/D26BIHTJWNiTG1KAJiQCg==} @@ -8893,7 +8869,7 @@ snapshots: rxjs: 7.8.2 tslib: 2.8.1 - '@angular/ng-dev@https://codeload.github.com/angular/dev-infra-private-ng-dev-builds/tar.gz/f166178ac5c37cd3aadab7b8cb7212f34d71b2a6': + '@angular/ng-dev@https://codeload.github.com/angular/dev-infra-private-ng-dev-builds/tar.gz/f5de34cabca7e005dc8102d3abb026d01a7a881a': 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) @@ -8911,7 +8887,6 @@ snapshots: '@octokit/request-error': 7.1.2 '@octokit/rest': 22.0.1 '@octokit/types': 17.0.0 - '@pnpm/dependency-path': 1001.1.10 '@types/cli-progress': 3.11.6 '@types/ejs': 3.1.5 '@types/events': 3.0.3 @@ -11287,26 +11262,6 @@ snapshots: '@pkgjs/parseargs@0.11.0': optional: true - '@pnpm/crypto.hash@1000.2.2': - dependencies: - '@pnpm/crypto.polyfill': 1000.1.0 - '@pnpm/graceful-fs': 1000.1.0 - ssri: 10.0.5 - - '@pnpm/crypto.polyfill@1000.1.0': {} - - '@pnpm/dependency-path@1001.1.10': - dependencies: - '@pnpm/crypto.hash': 1000.2.2 - '@pnpm/types': 1001.3.0 - semver: 7.8.5 - - '@pnpm/graceful-fs@1000.1.0': - dependencies: - graceful-fs: 4.2.11 - - '@pnpm/types@1001.3.0': {} - '@protobufjs/aspromise@1.1.2': {} '@protobufjs/base64@1.1.2': {} @@ -16452,10 +16407,6 @@ snapshots: safer-buffer: 2.1.2 tweetnacl: 0.14.5 - ssri@10.0.5: - dependencies: - minipass: 7.1.3 - stack-trace@0.0.10: {} stackback@0.0.2: {} From 96832f13ba9497df185a42a8b6d8d3de6b28b76a Mon Sep 17 00:00:00 2001 From: Alan Agius <17563226+alan-agius4@users.noreply.github.com> Date: Thu, 17 Sep 2026 16:48:36 +0000 Subject: [PATCH 009/233] refactor(@angular/build): extract shared concurrency, watcher, and styling utilities (cherry picked from commit d0eb6b656ccb51565adb532370eada2e00182668) --- .../testing/builder/src/builder-harness.ts | 2 +- .../src/builders/application/build-action.ts | 75 +------ .../build/src/builders/application/options.ts | 36 +-- .../tests/behavior/build-errors_spec.ts | 4 +- .../esbuild/persistent-load-result-cache.ts | 26 +-- .../esbuild/stylesheets/bundle-options.ts | 3 +- .../stylesheets/css-resource-plugin.ts | 6 +- .../build/src/tools/esbuild/watcher.ts | 103 +++++++++ .../build/src/tools/esbuild/watcher_spec.ts | 51 +++++ .../angular/build/src/utils/concurrency.ts | 93 ++++++++ .../build/src/utils/concurrency_spec.ts | 212 ++++++++++++++++++ .../build/src/utils/postcss-configuration.ts | 32 ++- 12 files changed, 513 insertions(+), 130 deletions(-) create mode 100644 packages/angular/build/src/utils/concurrency.ts create mode 100644 packages/angular/build/src/utils/concurrency_spec.ts diff --git a/modules/testing/builder/src/builder-harness.ts b/modules/testing/builder/src/builder-harness.ts index 67b5f760d148..570939cecd7f 100644 --- a/modules/testing/builder/src/builder-harness.ts +++ b/modules/testing/builder/src/builder-harness.ts @@ -111,7 +111,7 @@ export class BuilderHarness { } } - private resolvePath(path: string): string { + resolvePath(path: string): string { return join(getSystemPath(this.host.root()), path); } diff --git a/packages/angular/build/src/builders/application/build-action.ts b/packages/angular/build/src/builders/application/build-action.ts index edd0ae7d22f0..299d7cf88ef4 100644 --- a/packages/angular/build/src/builders/application/build-action.ts +++ b/packages/angular/build/src/builders/application/build-action.ts @@ -7,8 +7,6 @@ */ import { BuilderContext } from '@angular-devkit/architect'; -import { existsSync } from 'node:fs'; -import path from 'node:path'; import { BuildOutputAsset, ExecutionResult, @@ -21,10 +19,8 @@ import { } from '../../tools/esbuild/stylesheets/sass-language'; 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'; import { ComponentUpdateResult, @@ -35,20 +31,6 @@ import { ResultMessage, } from './results'; -// Watch workspace for package manager changes -const packageWatchFiles = [ - // manifest can affect module resolution - 'package.json', - // npm lock file - 'package-lock.json', - // pnpm lock file - 'pnpm-lock.yaml', - // yarn lock file including Yarn PnP manifest files (https://yarnpkg.com/advanced/pnp-spec/) - 'yarn.lock', - '.pnp.cjs', - '.pnp.data.json', -]; - // eslint-disable-next-line max-lines-per-function export async function* runEsBuildBuildAction( action: (rebuildState?: RebuildState) => Promise, @@ -115,55 +97,18 @@ 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 - normalizedOutputBase, - `${normalizedOutputBase}/**`, - normalizedCacheBase, - `${normalizedCacheBase}/**`, - `${toPosixPath(workspaceRoot)}/**/.*/**`, - ]; - - if (cacheOptions.localBasePath && cacheOptions.localBasePath !== cacheOptions.basePath) { - const normalizedLocalCacheBase = toPosixPath(cacheOptions.localBasePath); - ignored.push(normalizedLocalCacheBase, `${normalizedLocalCacheBase}/**`); - } - // Setup a watcher - const { createWatcher } = await import('../../tools/esbuild/watcher'); - watcher = await createWatcher({ - polling: typeof poll === 'number', - interval: poll, - followSymlinks: preserveSymlinks, - ignored, - cwd: workspaceRoot, + const { setupWatcher } = await import('../../tools/esbuild/watcher'); + watcher = await setupWatcher({ + workspaceRoot, + projectRoot, + outputPath: outputOptions.base, + cacheOptions, + poll, + preserveSymlinks, + signal: options.signal, + watchFiles: result.watchFiles, }); - - // Setup abort support - options.signal?.addEventListener('abort', () => void watcher?.close()); - - // Watch the entire project root if 'NG_BUILD_WATCH_ROOT' environment variable is set - if (shouldWatchRoot) { - if (!preserveSymlinks) { - // Ignore all node modules directories to avoid excessive file watchers. - // Package changes are handled below by watching manifest and lock files. - // NOTE: this is not enable when preserveSymlinks is true as this would break `npm link` usages. - ignored.push('**/node_modules/**'); - - watcher.add( - packageWatchFiles - .map((file) => path.join(workspaceRoot, file)) - .filter((file) => existsSync(file)), - ); - } - - watcher.add(projectRoot); - } - - // Watch locations provided by the initial build result - watcher.add(result.watchFiles); } // Output the first build results after setting up the watcher to ensure that any code executed diff --git a/packages/angular/build/src/builders/application/options.ts b/packages/angular/build/src/builders/application/options.ts index dc53d55b61f0..785d07371d93 100644 --- a/packages/angular/build/src/builders/application/options.ts +++ b/packages/angular/build/src/builders/application/options.ts @@ -9,7 +9,6 @@ import type { BuilderContext } from '@angular-devkit/architect'; import type { Plugin } from 'esbuild'; import { access, constants, readFile } from 'node:fs/promises'; -import { createRequire } from 'node:module'; import path from 'node:path'; import { normalizeAssetPatterns, normalizeOptimization, normalizeSourceMaps } from '../../utils'; import { supportColor } from '../../utils/color'; @@ -19,9 +18,8 @@ import { IndexHtmlTransform } from '../../utils/index-file/index-html-generator' import { normalizeCacheOptions } from '../../utils/normalize-cache'; import { canonicalizePath } from '../../utils/path'; import { - SearchDirectory, - findTailwindConfiguration, generateSearchDirectories, + getTailwindConfig, loadPostcssConfiguration, } from '../../utils/postcss-configuration'; import { getProjectRootPaths, normalizeDirectoryPath } from '../../utils/project-metadata'; @@ -280,7 +278,7 @@ export async function normalizeOptions( // Skip tailwind configuration if postcss is customized const tailwindConfiguration = postcssConfiguration ? undefined - : await getTailwindConfig(searchDirectories, workspaceRoot, context); + : await getTailwindConfig(searchDirectories, workspaceRoot, context.logger); let serverEntryPoint: string | undefined; if (typeof options.server === 'string') { @@ -538,36 +536,6 @@ export async function normalizeOptions( }; } -async function getTailwindConfig( - searchDirectories: SearchDirectory[], - workspaceRoot: string, - context: BuilderContext, -): Promise<{ file: string; package: string } | undefined> { - const tailwindConfigurationPath = findTailwindConfiguration(searchDirectories); - - if (!tailwindConfigurationPath) { - return undefined; - } - - // Create a node resolver from the configuration file - const resolver = createRequire(tailwindConfigurationPath); - try { - return { - file: tailwindConfigurationPath, - package: resolver.resolve('tailwindcss'), - }; - } catch { - const relativeTailwindConfigPath = path.relative(workspaceRoot, tailwindConfigurationPath); - context.logger.warn( - `Tailwind CSS configuration file found (${relativeTailwindConfigPath})` + - ` but the 'tailwindcss' package is not installed.` + - ` To enable Tailwind CSS, please install the 'tailwindcss' package.`, - ); - } - - return undefined; -} - /** * Normalize entry point options. To maintain compatibility with the legacy browser builder, we need a single `browser` * option which defines a single entry point. However, we also want to support multiple entry points as an internal option. diff --git a/packages/angular/build/src/builders/dev-server/tests/behavior/build-errors_spec.ts b/packages/angular/build/src/builders/dev-server/tests/behavior/build-errors_spec.ts index a17c0a198e14..424c520eab2d 100644 --- a/packages/angular/build/src/builders/dev-server/tests/behavior/build-errors_spec.ts +++ b/packages/angular/build/src/builders/dev-server/tests/behavior/build-errors_spec.ts @@ -38,8 +38,8 @@ describeServeBuilder(executeDevServer, DEV_SERVER_BUILDER_INFO, (harness, setupT expectNoLog(logs, 'Unexpected character "EOF"'); }, ], - { outputLogsOnFailure: false, timeout: 60_000 }, + { outputLogsOnFailure: false, timeout: 90_000 }, ); - }, 90_000); + }, 120_000); }); }); 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 97f7d5cbe1c6..9761ff9aff64 100644 --- a/packages/angular/build/src/tools/esbuild/persistent-load-result-cache.ts +++ b/packages/angular/build/src/tools/esbuild/persistent-load-result-cache.ts @@ -31,6 +31,7 @@ import type { Loader, OnLoadResult, PartialMessage } from 'esbuild'; import { readFile, stat } from 'node:fs/promises'; import { isAbsolute } from 'node:path'; import { fileURLToPath } from 'node:url'; +import { mapConcurrent, runConcurrent } from '../../utils/concurrency'; import { calculateHash, createContentHash } from '../../utils/hash'; import type { Cache as PersistentCacheStore } from './cache'; import { LoadResultCache, MemoryLoadResultCache } from './load-result-cache'; @@ -114,29 +115,6 @@ export function extractDiskFilePath(path: string): string | undefined { /** Maximum number of concurrent file system read/stat operations to prevent OS file descriptor exhaustion. */ const MAX_CONCURRENT_READS = 16; -/** - * Maps an array asynchronously with a sliding worker pool to maintain full concurrency saturation. - */ -async function mapConcurrent( - items: T[], - limit: number, - fn: (item: T) => Promise, -): Promise { - const results: R[] = new Array(items.length); - let index = 0; - - const workers = Array.from({ length: Math.min(limit, items.length) }, async () => { - while (index < items.length) { - const i = index++; - results[i] = await fn(items[i]); - } - }); - - await Promise.all(workers); - - return results; -} - /** * Validates that all imported watch files exist on disk and their contents match. * Performs a fast-path metadata check (mtime + size) first, falling back to content hashing. @@ -214,7 +192,7 @@ async function computeMetadataForWatchFiles( ): Promise> { const watchFilesMetadata: Record = {}; - await mapConcurrent(watchFiles, MAX_CONCURRENT_READS, async (filePath) => { + await runConcurrent(watchFiles, MAX_CONCURRENT_READS, async (filePath) => { try { const knownContent = knownContents?.get(filePath); const [content, stats] = await Promise.all([ diff --git a/packages/angular/build/src/tools/esbuild/stylesheets/bundle-options.ts b/packages/angular/build/src/tools/esbuild/stylesheets/bundle-options.ts index 7fa20dde64ae..bb5c945bab7d 100644 --- a/packages/angular/build/src/tools/esbuild/stylesheets/bundle-options.ts +++ b/packages/angular/build/src/tools/esbuild/stylesheets/bundle-options.ts @@ -22,6 +22,7 @@ export interface BundleStylesheetOptions { workspaceRoot: string; optimization: boolean; inlineFonts: boolean; + dataurl?: boolean; preserveSymlinks?: boolean; sourcemap: boolean | 'external' | 'inline' | 'linked'; sourcesContent?: boolean; @@ -62,7 +63,7 @@ export function createStylesheetBundleOptions( pluginFactory.create(SassStylesheetLanguage), pluginFactory.create(LessStylesheetLanguage), pluginFactory.create(CssStylesheetLanguage), - createCssResourcePlugin(cache), + createCssResourcePlugin(cache, options.dataurl), ]; if (options.inlineFonts) { diff --git a/packages/angular/build/src/tools/esbuild/stylesheets/css-resource-plugin.ts b/packages/angular/build/src/tools/esbuild/stylesheets/css-resource-plugin.ts index 7f83e7dc7a8f..ced6422c3fd3 100644 --- a/packages/angular/build/src/tools/esbuild/stylesheets/css-resource-plugin.ts +++ b/packages/angular/build/src/tools/esbuild/stylesheets/css-resource-plugin.ts @@ -25,9 +25,11 @@ const CSS_RESOURCE_RESOLUTION = Symbol('CSS_RESOURCE_RESOLUTION'); * and types to be supported without needing to manually specify all extensions * within the build configuration. * + * @param cache An optional load result cache. + * @param dataurl If true, resources will be loaded with the 'dataurl' loader to inline them as base64 data URIs. * @returns An esbuild {@link Plugin} instance. */ -export function createCssResourcePlugin(cache?: LoadResultCache): Plugin { +export function createCssResourcePlugin(cache?: LoadResultCache, dataurl?: boolean): Plugin { return { name: 'angular-css-resource', setup(build: PluginBuild): void { @@ -119,7 +121,7 @@ export function createCssResourcePlugin(cache?: LoadResultCache): Plugin { return { contents: await readFile(resourcePath), - loader: 'file', + loader: dataurl ? 'dataurl' : 'file', watchFiles: [resourcePath], }; }), diff --git a/packages/angular/build/src/tools/esbuild/watcher.ts b/packages/angular/build/src/tools/esbuild/watcher.ts index fe41275e479e..9923f08fea7f 100644 --- a/packages/angular/build/src/tools/esbuild/watcher.ts +++ b/packages/angular/build/src/tools/esbuild/watcher.ts @@ -11,6 +11,7 @@ import type * as Chokidar from 'chokidar'; import * as fs from 'node:fs'; import * as path from 'node:path'; import picomatch from 'picomatch'; +import { shouldWatchRoot } from '../../utils/environment-options'; import { toPosixPath } from '../../utils/path'; export class ChangedFiles { @@ -47,6 +48,108 @@ export interface WatcherOptions { cwd?: string; } +// Watch workspace for package manager changes +const packageWatchFiles = [ + // manifest can affect module resolution + 'package.json', + // npm lock file + 'package-lock.json', + // pnpm lock file + 'pnpm-lock.yaml', + // yarn lock file including Yarn PnP manifest files (https://yarnpkg.com/advanced/pnp-spec/) + 'yarn.lock', + '.pnp.cjs', + '.pnp.data.json', +]; + +export interface SetupWatcherOptions { + workspaceRoot: string; + projectRoot: string; + outputPath: string; + cacheOptions: { basePath: string; localBasePath?: string }; + poll?: number; + preserveSymlinks?: boolean; + signal?: AbortSignal; + watchFiles?: Iterable; +} + +/** + * Sets up and initializes a file watcher with proper ignore patterns for build outputs and caches. + */ +export async function setupWatcher(options: SetupWatcherOptions): Promise { + const { + workspaceRoot, + projectRoot, + outputPath, + cacheOptions, + poll, + preserveSymlinks, + signal, + watchFiles, + } = options; + + const normalizedOutputBase = toPosixPath(outputPath); + const normalizedCacheBase = toPosixPath(cacheOptions.basePath); + const ignored: string[] = [ + // Ignore the output and cache paths to avoid infinite rebuild cycles + normalizedOutputBase, + `${normalizedOutputBase}/**`, + normalizedCacheBase, + `${normalizedCacheBase}/**`, + `${toPosixPath(workspaceRoot)}/**/.*/**`, + ]; + + if (cacheOptions.localBasePath && cacheOptions.localBasePath !== cacheOptions.basePath) { + const normalizedLocalCacheBase = toPosixPath(cacheOptions.localBasePath); + ignored.push(normalizedLocalCacheBase, `${normalizedLocalCacheBase}/**`); + } + + if (shouldWatchRoot && !preserveSymlinks) { + // Ignore all node modules directories to avoid excessive file watchers. + // Package changes are handled below by watching manifest and lock files. + // NOTE: this is not enabled when preserveSymlinks is true as this would break `npm link` usages. + ignored.push('**/node_modules/**'); + } + + const watcher = await createWatcher({ + polling: typeof poll === 'number', + interval: poll, + followSymlinks: preserveSymlinks, + ignored, + cwd: workspaceRoot, + }); + + // Setup abort support + if (signal) { + const onAbort = () => void watcher.close(); + signal.addEventListener('abort', onAbort, { once: true }); + const originalClose = watcher.close.bind(watcher); + watcher.close = async () => { + signal.removeEventListener('abort', onAbort); + await originalClose(); + }; + } + + // Watch the entire project root if 'NG_BUILD_WATCH_ROOT' environment variable is set + if (shouldWatchRoot) { + if (!preserveSymlinks) { + watcher.add( + packageWatchFiles + .map((file) => path.join(workspaceRoot, file)) + .filter((file) => fs.existsSync(file)), + ); + } + + watcher.add(projectRoot); + } + + if (watchFiles) { + watcher.add(Array.isArray(watchFiles) ? watchFiles : Array.from(watchFiles)); + } + + return watcher; +} + /** * Probes the filesystem at the specified target directory to determine whether it is case-sensitive. */ diff --git a/packages/angular/build/src/tools/esbuild/watcher_spec.ts b/packages/angular/build/src/tools/esbuild/watcher_spec.ts index 5c7853012762..e051c44bd3f2 100644 --- a/packages/angular/build/src/tools/esbuild/watcher_spec.ts +++ b/packages/angular/build/src/tools/esbuild/watcher_spec.ts @@ -16,6 +16,7 @@ import { createWatcher, getDirectoryPath, isPathInside, + setupWatcher, toPosixPathNormalized, } from './watcher'; @@ -117,6 +118,56 @@ describe('Watcher', () => { }); }); + describe('setupWatcher', () => { + let tempDir: string; + + beforeEach(() => { + tempDir = fs.realpathSync(fs.mkdtempSync(path.join(os.tmpdir(), 'setup-watcher-spec-'))); + }); + + afterEach(() => { + if (fs.existsSync(tempDir)) { + fs.rmSync(tempDir, { recursive: true, force: true }); + } + }); + + it('should setup watcher with watchFiles and close on abort signal', async () => { + const abortController = new AbortController(); + const testFile = path.join(tempDir, 'main.ts'); + const watcher = await setupWatcher({ + workspaceRoot: tempDir, + projectRoot: tempDir, + outputPath: path.join(tempDir, 'dist'), + cacheOptions: { basePath: path.join(tempDir, '.cache') }, + watchFiles: [testFile], + signal: abortController.signal, + }); + + expect(watcher).toBeDefined(); + + const closeSpy = spyOn(watcher, 'close').and.callThrough(); + abortController.abort(); + + expect(closeSpy).toHaveBeenCalled(); + await watcher.close(); + }); + + it('should remove abort listener when watcher is closed', async () => { + const abortController = new AbortController(); + const removeSpy = spyOn(abortController.signal, 'removeEventListener').and.callThrough(); + const watcher = await setupWatcher({ + workspaceRoot: tempDir, + projectRoot: tempDir, + outputPath: path.join(tempDir, 'dist'), + cacheOptions: { basePath: path.join(tempDir, '.cache') }, + signal: abortController.signal, + }); + + await watcher.close(); + expect(removeSpy).toHaveBeenCalledWith('abort', jasmine.any(Function)); + }); + }); + describe('createWatcher', () => { let tempDir: string; diff --git a/packages/angular/build/src/utils/concurrency.ts b/packages/angular/build/src/utils/concurrency.ts new file mode 100644 index 000000000000..a38a9a57fa36 --- /dev/null +++ b/packages/angular/build/src/utils/concurrency.ts @@ -0,0 +1,93 @@ +/** + * @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 + */ + +/** + * Executes an asynchronous function for each item in an array concurrently up to a specified limit. + * + * If any task fails, processing of subsequent items stops and the first encountered error is re-thrown + * after all currently in-flight tasks have settled. + * + * @param items Array of items to process. + * @param limit Maximum number of concurrent tasks in flight. + * @param fn Async task function. + */ +export async function runConcurrent( + items: readonly T[], + limit: number, + fn: (item: T, index: number) => Promise, +): Promise { + if (items.length === 0) { + return; + } + + let index = 0; + let firstError: unknown; + + const concurrency = Math.min(Math.max(1, Math.floor(limit) || 1), items.length); + const workers = Array.from({ length: concurrency }, async () => { + while (!firstError && index < items.length) { + const i = index++; + try { + await fn(items[i], i); + } catch (error) { + firstError ??= error; + } + } + }); + + await Promise.allSettled(workers); + + if (firstError) { + throw firstError; + } +} + +/** + * Maps an array asynchronously with a sliding worker pool up to a specified concurrency limit. + * + * If any task fails, processing of subsequent items stops and the first encountered error is re-thrown + * after all currently in-flight tasks have settled. + * + * @param items Array of items to map. + * @param limit Maximum number of concurrent tasks in flight. + * @param fn Async mapper function. + * @returns Array of mapped results in the original item order. + */ +export async function mapConcurrent( + items: readonly T[], + limit: number, + fn: (item: T, index: number) => Promise, +): Promise { + if (items.length === 0) { + return []; + } + + const results: R[] = new Array(items.length); + let index = 0; + let firstError: unknown; + + const concurrency = Math.min(Math.max(1, Math.floor(limit) || 1), items.length); + const workers = Array.from({ length: concurrency }, async () => { + while (!firstError && index < items.length) { + const i = index++; + try { + results[i] = await fn(items[i], i); + } catch (error) { + firstError ??= error; + } + } + }); + + await Promise.allSettled(workers); + + if (firstError) { + throw firstError; + } + + return results; +} diff --git a/packages/angular/build/src/utils/concurrency_spec.ts b/packages/angular/build/src/utils/concurrency_spec.ts new file mode 100644 index 000000000000..ab63054046c5 --- /dev/null +++ b/packages/angular/build/src/utils/concurrency_spec.ts @@ -0,0 +1,212 @@ +/** + * @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 { mapConcurrent, runConcurrent } from './concurrency'; + +describe('concurrency utilities', () => { + describe('runConcurrent', () => { + it('should process all items in an array', async () => { + const items = [1, 2, 3, 4, 5]; + const processed: number[] = []; + + await runConcurrent(items, 2, async (item) => { + processed.push(item); + }); + + expect(processed.sort((a, b) => a - b)).toEqual(items); + }); + + it('should respect the concurrency limit', async () => { + const items = [10, 20, 30, 40, 50, 60]; + const limit = 2; + let active = 0; + let maxActive = 0; + + await runConcurrent(items, limit, async () => { + active++; + maxActive = Math.max(maxActive, active); + await new Promise((resolve) => setTimeout(resolve, 10)); + active--; + }); + + expect(maxActive).toBeLessThanOrEqual(limit); + }); + + it('should handle non-integer and NaN limits', async () => { + const items = [1, 2, 3]; + const processed: number[] = []; + + await runConcurrent(items, 2.7, async (item) => { + processed.push(item); + }); + expect(processed).toEqual(items); + + const processedNaN: number[] = []; + await runConcurrent(items, NaN, async (item) => { + processedNaN.push(item); + }); + expect(processedNaN).toEqual(items); + }); + + it('should handle an empty array', async () => { + let called = false; + await runConcurrent([], 3, async () => { + called = true; + }); + + expect(called).toBe(false); + }); + + it('should pass item and index to callback', async () => { + const items = ['a', 'b', 'c']; + const passed: { item: string; index: number }[] = []; + + await runConcurrent(items, 2, async (item, index) => { + passed.push({ item, index }); + }); + + expect(passed.sort((a, b) => a.index - b.index)).toEqual([ + { item: 'a', index: 0 }, + { item: 'b', index: 1 }, + { item: 'c', index: 2 }, + ]); + }); + + it('should stop processing new items and rethrow the first error', async () => { + const items = [1, 2, 3, 4, 5, 6]; + const executed: number[] = []; + + await expectAsync( + runConcurrent(items, 1, async (item) => { + executed.push(item); + if (item === 2) { + throw new Error('Task failed'); + } + }), + ).toBeRejectedWithError('Task failed'); + + // Subsequent items should not have been executed + expect(executed).toEqual([1, 2]); + }); + + it('should wait for in-flight tasks to settle when an error occurs', async () => { + const items = [1, 2, 3, 4]; + let task2Finished = false; + + await expectAsync( + runConcurrent(items, 2, async (item) => { + if (item === 1) { + throw new Error('Task 1 failed'); + } + if (item === 2) { + await new Promise((resolve) => setTimeout(resolve, 20)); + task2Finished = true; + } + }), + ).toBeRejectedWithError('Task 1 failed'); + + expect(task2Finished).toBe(true); + }); + }); + + describe('mapConcurrent', () => { + it('should map items and return results in original order', async () => { + const items = [1, 2, 3, 4, 5]; + + const results = await mapConcurrent(items, 2, async (item) => { + // Add varying delay so tasks finish out of order + await new Promise((resolve) => setTimeout(resolve, (5 - item) * 5)); + + return item * 2; + }); + + expect(results).toEqual([2, 4, 6, 8, 10]); + }); + + it('should respect the concurrency limit', async () => { + const items = [1, 2, 3, 4, 5]; + const limit = 2; + let active = 0; + let maxActive = 0; + + await mapConcurrent(items, limit, async (item) => { + active++; + maxActive = Math.max(maxActive, active); + await new Promise((resolve) => setTimeout(resolve, 10)); + active--; + + return item; + }); + + expect(maxActive).toBeLessThanOrEqual(limit); + }); + + it('should handle non-integer and NaN limits', async () => { + const items = [1, 2, 3]; + + const results = await mapConcurrent(items, 2.7, async (item) => item * 2); + expect(results).toEqual([2, 4, 6]); + + const resultsNaN = await mapConcurrent(items, NaN, async (item) => item * 2); + expect(resultsNaN).toEqual([2, 4, 6]); + }); + + it('should handle an empty array', async () => { + const results = await mapConcurrent([], 3, async (item) => item); + + expect(results).toEqual([]); + }); + + it('should pass item and index to mapper function', async () => { + const items = ['x', 'y', 'z']; + + const results = await mapConcurrent(items, 2, async (item, index) => `${item}:${index}`); + + expect(results).toEqual(['x:0', 'y:1', 'z:2']); + }); + + it('should stop processing new items and rethrow the first error', async () => { + const items = [1, 2, 3, 4, 5, 6]; + const executed: number[] = []; + + await expectAsync( + mapConcurrent(items, 1, async (item) => { + executed.push(item); + if (item === 2) { + throw new Error('Map failed'); + } + + return item; + }), + ).toBeRejectedWithError('Map failed'); + + expect(executed).toEqual([1, 2]); + }); + + it('should wait for in-flight tasks to settle when an error occurs', async () => { + const items = [1, 2, 3, 4]; + let task2Finished = false; + + await expectAsync( + mapConcurrent(items, 2, async (item) => { + if (item === 1) { + throw new Error('Map 1 failed'); + } + if (item === 2) { + await new Promise((resolve) => setTimeout(resolve, 20)); + task2Finished = true; + } + + return item; + }), + ).toBeRejectedWithError('Map 1 failed'); + + expect(task2Finished).toBe(true); + }); + }); +}); diff --git a/packages/angular/build/src/utils/postcss-configuration.ts b/packages/angular/build/src/utils/postcss-configuration.ts index 6f3f1f3671f9..abde0e632b30 100644 --- a/packages/angular/build/src/utils/postcss-configuration.ts +++ b/packages/angular/build/src/utils/postcss-configuration.ts @@ -7,7 +7,8 @@ */ import { readFile, readdir } from 'node:fs/promises'; -import { join } from 'node:path'; +import { createRequire } from 'node:module'; +import { join, relative } from 'node:path'; export interface PostcssConfiguration { plugins: [name: string, options?: object | string][]; @@ -62,6 +63,35 @@ export function findTailwindConfiguration( return findFile(searchDirectories, tailwindConfigFiles); } +export async function getTailwindConfig( + searchDirectories: SearchDirectory[], + workspaceRoot: string, + logger?: { warn(message: string): void }, +): Promise<{ file: string; package: string } | undefined> { + const tailwindConfigurationPath = findTailwindConfiguration(searchDirectories); + if (!tailwindConfigurationPath) { + return undefined; + } + + // Create a node resolver from the configuration file + const resolver = createRequire(tailwindConfigurationPath); + try { + return { + file: tailwindConfigurationPath, + package: resolver.resolve('tailwindcss'), + }; + } catch { + const relativeTailwindConfigPath = relative(workspaceRoot, tailwindConfigurationPath); + logger?.warn( + `Tailwind CSS configuration file found (${relativeTailwindConfigPath})` + + ` but the 'tailwindcss' package is not installed.` + + ` To enable Tailwind CSS, please install the 'tailwindcss' package.`, + ); + } + + return undefined; +} + async function readPostcssConfiguration( configurationFile: string, ): Promise { From e31bd66f67fbb55d17997920634a10a51a4a7886 Mon Sep 17 00:00:00 2001 From: Charles Lyding <19598772+clydin@users.noreply.github.com> Date: Tue, 15 Sep 2026 12:09:11 -0400 Subject: [PATCH 010/233] fix(@angular/build): support standard JavaScript MIME types and case insensitivity in auto-CSP Previously, isJavascriptMimeType() in auto-csp.ts only performed a case-sensitive check against 'text/javascript' on the slice prior to the first semicolon. This caused several issues: 1. Valid and common JavaScript MIME types specified in the HTML Living Standard such as application/javascript and text/ecmascript were not recognized as JavaScript. 2. Case differences (e.g. type="text/JavaScript" or type="Module") were not matched, despite HTML attribute matching and MIME types being ASCII case-insensitive. 3. Whitespace around the essence (e.g. type="text/javascript ; charset=utf-8" or type=" text/javascript") caused the strict equality check to fail. When a script tag with one of these valid types was not recognized, auto-csp bypassed dynamic script rewriting and emitted the script element as-is into index.html. Under the generated strict CSP, the browser would then block the script from executing. This change introduces JAVASCRIPT_MIME_TYPES containing all HTML-standard JavaScript MIME types, normalizes the essence (stripping parameters, trimming surrounding whitespace, and lowercasing), and updates shouldDynamicallyLoadScriptTagBasedOnType to support case-insensitive module types. (cherry picked from commit 8e1b20253a06ea6614bb27f70ea252a6e0e67e1a) --- .../build/src/utils/index-file/auto-csp.ts | 37 +++++- .../src/utils/index-file/auto-csp_spec.ts | 119 +++++++++++++++++- 2 files changed, 151 insertions(+), 5 deletions(-) diff --git a/packages/angular/build/src/utils/index-file/auto-csp.ts b/packages/angular/build/src/utils/index-file/auto-csp.ts index df33f0766607..5c1899015a7e 100644 --- a/packages/angular/build/src/utils/index-file/auto-csp.ts +++ b/packages/angular/build/src/utils/index-file/auto-csp.ts @@ -36,15 +36,40 @@ function getScriptAttributeValue(tag: StartTag, attrName: string): string | unde return tag.attrs.find((attr) => attr.name === attrName)?.value; } +/** + * All MIME types associated with JavaScript according to the HTML specification: + * https://html.spec.whatwg.org/multipage/scripting.html#javascript-mime-type + */ +const JAVASCRIPT_MIME_TYPES = new Set([ + 'application/ecmascript', + 'application/javascript', + 'application/x-ecmascript', + 'application/x-javascript', + 'text/ecmascript', + 'text/javascript', + 'text/javascript1.0', + 'text/javascript1.1', + 'text/javascript1.2', + 'text/javascript1.3', + 'text/javascript1.4', + 'text/javascript1.5', + 'text/jscript', + 'text/livescript', + 'text/x-ecmascript', + 'text/x-javascript', +]); + /** * Checks whether a particular string is a MIME type associated with JavaScript, according to - * https://developer.mozilla.org/en-US/docs/Web/HTTP/MIME_types#textjavascript + * https://html.spec.whatwg.org/multipage/scripting.html#javascript-mime-type * * @param mimeType a string that may be a MIME type * @returns whether the string is a MIME type that is associated with JavaScript */ -function isJavascriptMimeType(mimeType: string): boolean { - return mimeType.split(';')[0] === 'text/javascript'; +export function isJavascriptMimeType(mimeType: string): boolean { + const [essence] = mimeType.split(';', 1); + + return JAVASCRIPT_MIME_TYPES.has(essence.trim().toLowerCase()); } /** @@ -54,7 +79,11 @@ function isJavascriptMimeType(mimeType: string): boolean { * @returns whether to add the script tag to the dynamically loaded script tag */ function shouldDynamicallyLoadScriptTagBasedOnType(scriptType: string | undefined): boolean { - return !scriptType || scriptType === 'module' || isJavascriptMimeType(scriptType); + if (!scriptType) { + return true; + } + + return scriptType.trim().toLowerCase() === 'module' || isJavascriptMimeType(scriptType); } /** diff --git a/packages/angular/build/src/utils/index-file/auto-csp_spec.ts b/packages/angular/build/src/utils/index-file/auto-csp_spec.ts index 29e9bff68074..4fe2888efa42 100644 --- a/packages/angular/build/src/utils/index-file/auto-csp_spec.ts +++ b/packages/angular/build/src/utils/index-file/auto-csp_spec.ts @@ -6,7 +6,7 @@ * found in the LICENSE file at https://angular.dev/license */ -import { autoCsp, hashTextContent } from './auto-csp'; +import { autoCsp, hashTextContent, isJavascriptMimeType } from './auto-csp'; // Utility function to grab the meta tag CSPs from the HTML response. const getCsps = (html: string) => { @@ -281,4 +281,121 @@ describe('auto-csp', () => { `const scripts = [['./main.js', '', false, false, null, "anonymous"]];`, ); }); + + it('should rewrite scripts with application/javascript type', async () => { + const result = await autoCsp(` + + + + + + + `); + + const csps = getCsps(result); + expect(csps).toHaveSize(1); + expect(csps[0]).toMatch(CSP_SINGLE_HASH_REGEX); + expect(result).toContain( + `const scripts = [['./main.js', 'application/javascript', false, false, null, null]];`, + ); + }); + + it('should rewrite scripts with case-insensitive type and parameters with whitespace', async () => { + const result = await autoCsp(` + + + + + + + `); + + const csps = getCsps(result); + expect(csps).toHaveSize(1); + expect(csps[0]).toMatch(CSP_SINGLE_HASH_REGEX); + expect(result).toContain( + `const scripts = [['./main.js', 'Text/JavaScript ; charset=utf-8', false, false, null, null]];`, + ); + }); + + it('should rewrite scripts with case-insensitive module type', async () => { + const result = await autoCsp(` + + + + + + + `); + + const csps = getCsps(result); + expect(csps).toHaveSize(1); + expect(csps[0]).toMatch(CSP_SINGLE_HASH_REGEX); + expect(result).toContain( + `const scripts = [['./main.js', 'Module', false, false, null, null]];`, + ); + }); + + it('should not rewrite non-JavaScript script tags', async () => { + const result = await autoCsp(` + + + + + + + `); + + // No dynamic loader script is emitted because application/json is not JavaScript. + expect(result).toContain(''); + expect(result).not.toContain('const scripts ='); + }); + + describe('isJavascriptMimeType', () => { + it('should identify standard JavaScript MIME types', () => { + expect(isJavascriptMimeType('text/javascript')).toBeTrue(); + expect(isJavascriptMimeType('application/javascript')).toBeTrue(); + expect(isJavascriptMimeType('application/x-javascript')).toBeTrue(); + expect(isJavascriptMimeType('text/ecmascript')).toBeTrue(); + expect(isJavascriptMimeType('application/ecmascript')).toBeTrue(); + expect(isJavascriptMimeType('text/jscript')).toBeTrue(); + expect(isJavascriptMimeType('text/livescript')).toBeTrue(); + expect(isJavascriptMimeType('text/x-ecmascript')).toBeTrue(); + expect(isJavascriptMimeType('text/x-javascript')).toBeTrue(); + expect(isJavascriptMimeType('text/javascript1.5')).toBeTrue(); + }); + + it('should ignore parameters when matching MIME type', () => { + expect(isJavascriptMimeType('text/javascript; charset=utf-8')).toBeTrue(); + expect(isJavascriptMimeType('application/javascript;version=1.8')).toBeTrue(); + }); + + it('should handle leading, trailing, and parameter whitespace', () => { + expect(isJavascriptMimeType(' text/javascript ')).toBeTrue(); + expect(isJavascriptMimeType('text/javascript ; charset=utf-8')).toBeTrue(); + expect(isJavascriptMimeType(' application/javascript ; version=1.0 ')).toBeTrue(); + }); + + it('should be case-insensitive', () => { + expect(isJavascriptMimeType('Text/JavaScript')).toBeTrue(); + expect(isJavascriptMimeType('APPLICATION/JAVASCRIPT')).toBeTrue(); + expect(isJavascriptMimeType('text/JAVASCRIPT; charset=UTF-8')).toBeTrue(); + }); + + it('should reject non-JavaScript MIME types', () => { + expect(isJavascriptMimeType('application/json')).toBeFalse(); + expect(isJavascriptMimeType('text/html')).toBeFalse(); + expect(isJavascriptMimeType('text/css')).toBeFalse(); + expect(isJavascriptMimeType('image/svg+xml')).toBeFalse(); + expect(isJavascriptMimeType('importmap')).toBeFalse(); + expect(isJavascriptMimeType('module')).toBeFalse(); + expect(isJavascriptMimeType('')).toBeFalse(); + }); + + it('should reject invalid MIME types with whitespace inside the essence', () => { + expect(isJavascriptMimeType('text / javascript')).toBeFalse(); + expect(isJavascriptMimeType('application / javascript')).toBeFalse(); + expect(isJavascriptMimeType('text/java script')).toBeFalse(); + }); + }); }); From c0e6b3cf684b458c8ef1e0b64197303234e0492f Mon Sep 17 00:00:00 2001 From: rk Date: Fri, 18 Sep 2026 00:13:00 +0500 Subject: [PATCH 011/233] fix(@angular-devkit/core): name the unknown option in a schema validation error An unknown property in `angular.json` or in a builder's options reported `Data path "" must NOT have additional properties(allowedCommonJsDependencies).`, which names neither the object the property was found in nor what is valid there. It now reads `Unknown option "allowedCommonJsDependencies". Valid options are: assets, browser, ...`, with `at "/cli"` where the instance path is not empty. Errors that are not about an unknown option are unchanged. Listing the valid options needs ajv's `verbose` option, which is what puts `parentSchema` on an error. That is the schema the property was rejected by, so a `$ref` and a `oneOf` branch each list their own options; a schema that declares no `properties` at all stops after the option name rather than offering an empty list. (cherry picked from commit 8c438891c9c8be4e66a82148908343befbb462a2) --- .../core/src/json/schema/registry.ts | 31 ++++--- .../core/src/json/schema/registry_spec.ts | 91 +++++++++++++++++++ .../config/config-global-validation.ts | 12 +-- tests/e2e/tests/commands/config/config-set.ts | 5 +- 4 files changed, 114 insertions(+), 25 deletions(-) diff --git a/packages/angular_devkit/core/src/json/schema/registry.ts b/packages/angular_devkit/core/src/json/schema/registry.ts index 77aeab6646a1..928771337bb5 100644 --- a/packages/angular_devkit/core/src/json/schema/registry.ts +++ b/packages/angular_devkit/core/src/json/schema/registry.ts @@ -61,19 +61,24 @@ export class SchemaValidationException extends BaseException { } const messages = errors.map((err) => { + if (err.keyword === 'additionalProperties') { + const unknown = err.params?.additionalProperty; + // `parentSchema` is the schema that rejected the property, which ajv only attaches when + // the validator was created with `verbose: true`. A schema that declares no `properties` + // of its own, such as one using only `patternProperties`, has no options to offer. + const known = Object.keys(err.parentSchema?.properties ?? {}); + + return ( + `Unknown option "${unknown}"${err.instancePath ? ` at "${err.instancePath}"` : ''}.` + + (known.length ? ` Valid options are: ${known.join(', ')}.` : '') + ); + } + let message = `Data path ${JSON.stringify(err.instancePath)} ${err.message}`; - if (err.params) { - switch (err.keyword) { - case 'additionalProperties': - message += `(${err.params.additionalProperty})`; - break; - - case 'enum': - message += `. Allowed values are: ${(err.params.allowedValues as string[] | undefined) - ?.map((v) => `"${v}"`) - .join(', ')}`; - break; - } + if (err.keyword === 'enum' && err.params) { + message += `. Allowed values are: ${(err.params.allowedValues as string[] | undefined) + ?.map((v) => `"${v}"`) + .join(', ')}`; } return message + '.'; @@ -106,6 +111,8 @@ export class CoreSchemaRegistry implements SchemaRegistry { strict: false, loadSchema: (uri: string) => this._fetch(uri), passContext: true, + // Needed to list the valid options of the object an unknown option was found in. + verbose: true, }); ajvAddFormats(this._ajv); diff --git a/packages/angular_devkit/core/src/json/schema/registry_spec.ts b/packages/angular_devkit/core/src/json/schema/registry_spec.ts index 34e404a63b29..32c601154d16 100644 --- a/packages/angular_devkit/core/src/json/schema/registry_spec.ts +++ b/packages/angular_devkit/core/src/json/schema/registry_spec.ts @@ -7,8 +7,10 @@ */ /* eslint-disable @typescript-eslint/no-explicit-any */ +import { JsonValue } from '../utils'; import { SchemaFormat } from './interface'; import { CoreSchemaRegistry, SchemaValidationException } from './registry'; +import { JsonSchema } from './schema'; import { addUndefinedDefaults } from './transforms'; describe('CoreSchemaRegistry', () => { @@ -340,4 +342,93 @@ describe('CoreSchemaRegistry', () => { expect(deprecatedMessages[1]).toBe('Option "bar" is deprecated.'); expect(result.success).toBe(true, result.errors); }); + + describe('error messages', () => { + async function messagesFor(schema: JsonSchema, data: JsonValue): Promise { + const registry = new CoreSchemaRegistry(); + const validator = await registry.compile(schema); + const result = await validator(data); + expect(result.success).toBe(false); + + return SchemaValidationException.createMessages(result.errors); + } + + it('names an unknown option and the options that are valid there', async () => { + const messages = await messagesFor( + { + properties: { version: { type: 'number' }, projects: { type: 'object' } }, + additionalProperties: false, + }, + { allowedCommonJsDependencies: [] }, + ); + + expect(messages).toEqual([ + 'Unknown option "allowedCommonJsDependencies". Valid options are: version, projects.', + ]); + }); + + it('points at the object an unknown option was found in', async () => { + const messages = await messagesFor( + { + properties: { + cli: { + type: 'object', + properties: { cache: { type: 'object' }, packageManager: { type: 'string' } }, + additionalProperties: false, + }, + }, + }, + { cli: { completion: true } }, + ); + + expect(messages).toEqual([ + 'Unknown option "completion" at "/cli". Valid options are: cache, packageManager.', + ]); + }); + + it('looks through a $ref for the valid options', async () => { + const messages = await messagesFor( + { + $ref: '#/definitions/global', + definitions: { + global: { + type: 'object', + properties: { cli: { type: 'object' }, schematics: { type: 'object' } }, + additionalProperties: false, + }, + }, + }, + { version: 1 }, + ); + + expect(messages).toEqual(['Unknown option "version". Valid options are: cli, schematics.']); + }); + + it('omits the valid options when the schema does not list any', async () => { + const messages = await messagesFor( + { + $ref: '#/definitions/cli', + definitions: { + cli: { + type: 'object', + patternProperties: { '^x-': { type: 'string' } }, + additionalProperties: false, + }, + }, + }, + { completion: true }, + ); + + expect(messages).toEqual(['Unknown option "completion".']); + }); + + it('leaves an error that is not about an unknown option alone', async () => { + const messages = await messagesFor( + { properties: { outputPath: { type: 'string' } } }, + { outputPath: 42 }, + ); + + expect(messages).toEqual(['Data path "/outputPath" must be string.']); + }); + }); }); diff --git a/tests/e2e/tests/commands/config/config-global-validation.ts b/tests/e2e/tests/commands/config/config-global-validation.ts index 7be29130dca0..39fa611075a9 100644 --- a/tests/e2e/tests/commands/config/config-global-validation.ts +++ b/tests/e2e/tests/commands/config/config-global-validation.ts @@ -9,21 +9,15 @@ export default async function () { let ngError: Error; ngError = await expectToFail(() => silentNg('config', 'cli.completion.prompted', 'true')); - assert.match( - ngError.message, - /Data path "\/cli" must NOT have additional properties\(completion\)\./, - ); + assert.match(ngError.message, /Unknown option "completion" at "\/cli"\./); ngError = await expectToFail(() => silentNg('config', '--global', 'cli.completion.invalid', 'true'), ); - assert.match( - ngError.message, - /Data path "\/cli\/completion" must NOT have additional properties\(invalid\)\./, - ); + assert.match(ngError.message, /Unknown option "invalid" at "\/cli\/completion"\./); ngError = await expectToFail(() => silentNg('config', '--global', 'cli.cache.enabled', 'true')); - assert.match(ngError.message, /Data path "\/cli" must NOT have additional properties\(cache\)\./); + assert.match(ngError.message, /Unknown option "cache" at "\/cli"\./); ngError = await expectToFail(() => silentNg('config', 'cli.completion.prompted')); assert.match(ngError.message, /Value cannot be found\./); diff --git a/tests/e2e/tests/commands/config/config-set.ts b/tests/e2e/tests/commands/config/config-set.ts index 2152e573132e..05fa364bcb37 100644 --- a/tests/e2e/tests/commands/config/config-set.ts +++ b/tests/e2e/tests/commands/config/config-set.ts @@ -6,10 +6,7 @@ export default async function () { let ngError: Error; ngError = await expectToFail(() => silentNg('config', 'cli.warnings.zzzz', 'true')); - assert.match( - ngError.message, - /Data path "\/cli\/warnings" must NOT have additional properties\(zzzz\)\./, - ); + assert.match(ngError.message, /Unknown option "zzzz" at "\/cli\/warnings"\./); ngError = await expectToFail(() => silentNg('config', 'cli.warnings.zzzz')); assert.match(ngError.message, /Value cannot be found\./); From 4ebaa667bbcb569151434bebe3f27af94ed17c95 Mon Sep 17 00:00:00 2001 From: rk Date: Fri, 18 Sep 2026 15:09:17 +0500 Subject: [PATCH 012/233] fix(@schematics/angular): update @types/node to a version vitest 5 accepts `ng new --ssr` and `ng add @angular/ssr` fail to install their dependencies: the server schematic adds `@types/node@^20.17.19`, and vitest 5, which the same schematics now add, has `@types/node@^22.0.0 || >=24.0.0` as a peer. npm refuses the tree and the workspace is left without `node_modules`. `^22.12.0` is what this repository uses for `@types/node` itself, and Node 20 is already outside the `engines.node` range of the generated project. (cherry picked from commit 1627ccbc1f61cd0a9ff093bb23cefc9d90b338ba) --- .../schematics/angular/utility/latest-versions/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/schematics/angular/utility/latest-versions/package.json b/packages/schematics/angular/utility/latest-versions/package.json index 111c8296c202..75481eb2b23d 100644 --- a/packages/schematics/angular/utility/latest-versions/package.json +++ b/packages/schematics/angular/utility/latest-versions/package.json @@ -5,7 +5,7 @@ "dependencies": { "@types/express": "^5.0.1", "@types/jasmine": "~6.0.0", - "@types/node": "^20.17.19", + "@types/node": "^22.12.0", "browser-sync": "^3.0.0", "express": "^5.1.0", "istanbul-lib-instrument": "^6.0.3", From ee3041325cd2400c26e239e64e14a0e314ab6031 Mon Sep 17 00:00:00 2001 From: Alan Agius Date: Fri, 18 Sep 2026 18:36:24 +0200 Subject: [PATCH 013/233] fix(@angular/build): ensure chokidar watcher is ready before returning When initializing chokidar.watch with ignoreInitial: true, files visited during the initial scan are treated as the initial baseline and do not emit change events. If createChokidarWatcher returns before the initial scan completes, subsequent file modifications made shortly after setup can be visited for the first time during the initial scan, causing the change event to be dropped. (cherry picked from commit dc79270a8d56a59b79cc2a44653885d5111b9ba7) --- .../dev-server/tests/behavior/build-errors_spec.ts | 4 ++-- packages/angular/build/src/tools/esbuild/watcher.ts | 8 ++++++++ 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/packages/angular/build/src/builders/dev-server/tests/behavior/build-errors_spec.ts b/packages/angular/build/src/builders/dev-server/tests/behavior/build-errors_spec.ts index 424c520eab2d..9608e0dc976e 100644 --- a/packages/angular/build/src/builders/dev-server/tests/behavior/build-errors_spec.ts +++ b/packages/angular/build/src/builders/dev-server/tests/behavior/build-errors_spec.ts @@ -38,8 +38,8 @@ describeServeBuilder(executeDevServer, DEV_SERVER_BUILDER_INFO, (harness, setupT expectNoLog(logs, 'Unexpected character "EOF"'); }, ], - { outputLogsOnFailure: false, timeout: 90_000 }, + { outputLogsOnFailure: false }, ); - }, 120_000); + }); }); }); diff --git a/packages/angular/build/src/tools/esbuild/watcher.ts b/packages/angular/build/src/tools/esbuild/watcher.ts index 9923f08fea7f..e30909fa6813 100644 --- a/packages/angular/build/src/tools/esbuild/watcher.ts +++ b/packages/angular/build/src/tools/esbuild/watcher.ts @@ -8,6 +8,7 @@ import type * as ParcelWatcher from '@parcel/watcher'; import type * as Chokidar from 'chokidar'; +import { once } from 'node:events'; import * as fs from 'node:fs'; import * as path from 'node:path'; import picomatch from 'picomatch'; @@ -663,8 +664,15 @@ async function createChokidarWatcher( usePolling: !!options?.polling, interval: options?.interval, }); + const initTime = Date.now(); + // Wait for the watcher to complete its initial filesystem scan before returning. + // With `ignoreInitial: true`, any file visited during the initial scan is treated as the initial baseline + // and will not emit 'add' or 'change' events. Awaiting 'ready' ensures that rapid file modifications + // made right after watcher setup (e.g. in rebuild tests) are not swallowed as initial files. + await once(watcher, 'ready'); + const handleEvent = (type: 'added' | 'modified' | 'removed', rawPath: string) => { const posixPath = toPosixPathNormalized(rawPath); const lookupKey = toLookupKey(posixPath, isCaseSensitive); From e7ebbcdc25ee0cb0329be3389d2795182a65f0a1 Mon Sep 17 00:00:00 2001 From: Alan Agius <17563226+alan-agius4@users.noreply.github.com> Date: Mon, 21 Sep 2026 09:42:58 +0000 Subject: [PATCH 014/233] refactor(@angular/build): relocate non-esbuild utilities out of tools/esbuild Relocate several utilities from `src/tools/esbuild` to more appropriate locations, as they are not specific to esbuild: - `watcher.ts`: moved to `src/utils/watcher.ts`. - `profiling.ts`: moved to `src/utils/profiling.ts`. - `cache.ts`, `sqlite-cache-store.ts`, `lmdb-cache-store.ts`: moved to `src/utils/cache/`. - `javascript-transformer.ts`, `javascript-transformer-worker.ts`: moved to `src/tools/javascript-transformer/`. - `i18n-inliner.ts`, `i18n-inliner-worker.ts`, `i18n-translation-*`: moved to `src/tools/i18n/`, with locale data helpers in `src/tools/i18n/locale-data.ts`. - `index-html-generator.ts`: moved to `src/builders/application/index-html-generator.ts`. (cherry picked from commit eb1edeb5147adf51ef6261c04cd0c79bad9d6cd3) --- .../src/builders/application/build-action.ts | 6 +- .../src/builders/application/execute-build.ts | 2 +- .../application/execute-post-bundle.ts | 7 +- .../build/src/builders/application/i18n.ts | 2 +- .../application}/index-html-generator.ts | 8 +- .../build/src/builders/dev-server/internal.ts | 2 +- packages/angular/build/src/private.ts | 4 +- .../angular/compilation/aot-compilation.ts | 2 +- .../angular/compilation/jit-compilation.ts | 2 +- .../compilation/parallel-compilation.ts | 2 +- .../angular/compilation/parallel-worker.ts | 2 +- .../compilation/typescript-compilation.ts | 2 +- .../tools/esbuild/angular/compiler-plugin.ts | 10 +- .../esbuild/angular/component-stylesheets.ts | 2 +- .../tools/esbuild/bundler-execution-result.ts | 2 +- .../src/tools/esbuild/i18n-locale-plugin.ts | 145 ++---------------- .../esbuild/persistent-load-result-cache.ts | 2 +- .../persistent-load-result-cache_spec.ts | 2 +- .../esbuild/stylesheets/sass-language.ts | 2 +- .../{esbuild => i18n}/i18n-inliner-worker.ts | 4 +- .../tools/{esbuild => i18n}/i18n-inliner.ts | 12 +- .../{esbuild => i18n}/i18n-inliner_spec.ts | 8 +- .../i18n-translation-encoder.ts | 0 .../i18n-translation-encoder_spec.ts | 0 .../i18n-translation-reader.ts | 0 .../angular/build/src/tools/i18n/index.ts | 12 ++ .../build/src/tools/i18n/locale-data.ts | 138 +++++++++++++++++ .../src/tools/javascript-transformer/index.ts | 9 ++ .../javascript-transformer-worker.ts | 0 .../javascript-transformer.ts | 2 +- .../javascript-transformer_spec.ts | 0 .../angular/build/src/tools/vite/utils.ts | 2 +- .../{tools/esbuild => utils/cache}/cache.ts | 4 +- .../esbuild => utils/cache}/cache_spec.ts | 0 .../angular/build/src/utils/cache/index.ts | 9 ++ .../cache}/lmdb-cache-store.ts | 0 .../cache}/sqlite-cache-store.ts | 0 .../cache}/sqlite-cache-store_spec.ts | 0 .../src/{tools/esbuild => utils}/profiling.ts | 2 +- .../src/{tools/esbuild => utils}/watcher.ts | 4 +- .../{tools/esbuild => utils}/watcher_spec.ts | 0 scripts/benchmark.mts | 4 +- scripts/benchmarks/i18n/fixtures.mts | 2 +- scripts/benchmarks/i18n/scenarios.mts | 6 +- 44 files changed, 247 insertions(+), 177 deletions(-) rename packages/angular/build/src/{tools/esbuild => builders/application}/index-html-generator.ts (96%) rename packages/angular/build/src/tools/{esbuild => i18n}/i18n-inliner-worker.ts (99%) rename packages/angular/build/src/tools/{esbuild => i18n}/i18n-inliner.ts (99%) rename packages/angular/build/src/tools/{esbuild => i18n}/i18n-inliner_spec.ts (99%) rename packages/angular/build/src/tools/{esbuild => i18n}/i18n-translation-encoder.ts (100%) rename packages/angular/build/src/tools/{esbuild => i18n}/i18n-translation-encoder_spec.ts (100%) rename packages/angular/build/src/tools/{esbuild => i18n}/i18n-translation-reader.ts (100%) create mode 100644 packages/angular/build/src/tools/i18n/index.ts create mode 100644 packages/angular/build/src/tools/i18n/locale-data.ts create mode 100644 packages/angular/build/src/tools/javascript-transformer/index.ts rename packages/angular/build/src/tools/{esbuild => javascript-transformer}/javascript-transformer-worker.ts (100%) rename packages/angular/build/src/tools/{esbuild => javascript-transformer}/javascript-transformer.ts (99%) rename packages/angular/build/src/tools/{esbuild => javascript-transformer}/javascript-transformer_spec.ts (100%) rename packages/angular/build/src/{tools/esbuild => utils/cache}/cache.ts (98%) rename packages/angular/build/src/{tools/esbuild => utils/cache}/cache_spec.ts (100%) create mode 100644 packages/angular/build/src/utils/cache/index.ts rename packages/angular/build/src/{tools/esbuild => utils/cache}/lmdb-cache-store.ts (100%) rename packages/angular/build/src/{tools/esbuild => utils/cache}/sqlite-cache-store.ts (100%) rename packages/angular/build/src/{tools/esbuild => utils/cache}/sqlite-cache-store_spec.ts (100%) rename packages/angular/build/src/{tools/esbuild => utils}/profiling.ts (97%) rename packages/angular/build/src/{tools/esbuild => utils}/watcher.ts (99%) rename packages/angular/build/src/{tools/esbuild => utils}/watcher_spec.ts (100%) diff --git a/packages/angular/build/src/builders/application/build-action.ts b/packages/angular/build/src/builders/application/build-action.ts index 299d7cf88ef4..52e70ff87e99 100644 --- a/packages/angular/build/src/builders/application/build-action.ts +++ b/packages/angular/build/src/builders/application/build-action.ts @@ -18,9 +18,9 @@ import { shutdownSassWorkerPool, } from '../../tools/esbuild/stylesheets/sass-language'; import { logMessages, withNoProgress, withSpinner } from '../../tools/esbuild/utils'; -import { ChangedFiles } from '../../tools/esbuild/watcher'; import { initializeHash } from '../../utils/hash'; import { NormalizedCachedOptions } from '../../utils/normalize-cache'; +import { ChangedFiles } from '../../utils/watcher'; import { NormalizedApplicationBuildOptions, NormalizedOutputOptions } from './options'; import { ComponentUpdateResult, @@ -88,7 +88,7 @@ export async function* runEsBuildBuildAction( } } - let watcher: import('../../tools/esbuild/watcher').BuildWatcher | undefined; + let watcher: import('../../utils/watcher').BuildWatcher | undefined; let watchLoopStarted = false; try { // Setup watcher if watch mode enabled @@ -98,7 +98,7 @@ export async function* runEsBuildBuildAction( } // Setup a watcher - const { setupWatcher } = await import('../../tools/esbuild/watcher'); + const { setupWatcher } = await import('../../utils/watcher'); watcher = await setupWatcher({ workspaceRoot, projectRoot, diff --git a/packages/angular/build/src/builders/application/execute-build.ts b/packages/angular/build/src/builders/application/execute-build.ts index 379566e4de4d..d3b628a169e2 100644 --- a/packages/angular/build/src/builders/application/execute-build.ts +++ b/packages/angular/build/src/builders/application/execute-build.ts @@ -20,7 +20,6 @@ import { BuildOutputFileType } from '../../tools/esbuild/bundler-files'; import { checkCommonJSModules } from '../../tools/esbuild/commonjs-checker'; import { LOCALE_DATA_BASE_MODULE } from '../../tools/esbuild/i18n-locale-plugin'; import { extractLicenses } from '../../tools/esbuild/license-extractor'; -import { profileAsync } from '../../tools/esbuild/profiling'; import { transformSupportedBrowsersToTargets } from '../../tools/esbuild/target'; import { calculateEstimatedTransferSizes, @@ -29,6 +28,7 @@ import { } from '../../tools/esbuild/utils'; import { BudgetCalculatorResult, checkBudgets } from '../../utils/bundle-calculator'; import { optimizeChunksThreshold } from '../../utils/environment-options'; +import { profileAsync } from '../../utils/profiling'; import { resolveAssets } from '../../utils/resolve-assets'; import { SERVER_APP_ENGINE_MANIFEST_FILENAME, diff --git a/packages/angular/build/src/builders/application/execute-post-bundle.ts b/packages/angular/build/src/builders/application/execute-post-bundle.ts index 07639a43c3e5..99e23bcb30c9 100644 --- a/packages/angular/build/src/builders/application/execute-post-bundle.ts +++ b/packages/angular/build/src/builders/application/execute-post-bundle.ts @@ -18,18 +18,15 @@ import { type InitialFileRecord, createOutputFile, } from '../../tools/esbuild/bundler-files'; -import { generateIndexHtml } from '../../tools/esbuild/index-html-generator'; import { maxWorkers } from '../../utils/environment-options'; import { SERVER_APP_MANIFEST_FILENAME, generateAngularServerAppManifest, } from '../../utils/server-rendering/manifest'; -import { - RouteRenderMode, - WritableSerializableRouteTreeNode, -} from '../../utils/server-rendering/models'; +import { WritableSerializableRouteTreeNode } from '../../utils/server-rendering/models'; import { prerenderPages } from '../../utils/server-rendering/prerender'; import { augmentAppWithServiceWorkerEsbuild } from '../../utils/service-worker'; +import { generateIndexHtml } from './index-html-generator'; import { injectDebugIds } from './inject-debug-ids'; import { INDEX_HTML_CSR, INDEX_HTML_SERVER, NormalizedApplicationBuildOptions } from './options'; import { OutputMode } from './schema'; diff --git a/packages/angular/build/src/builders/application/i18n.ts b/packages/angular/build/src/builders/application/i18n.ts index 0d6ae77cdea7..839384421f1f 100644 --- a/packages/angular/build/src/builders/application/i18n.ts +++ b/packages/angular/build/src/builders/application/i18n.ts @@ -16,7 +16,7 @@ import { PrerenderedRoutesRecord, } from '../../tools/esbuild/bundler-execution-result'; import { BuildOutputFileType, InitialFileRecord } from '../../tools/esbuild/bundler-files'; -import { I18nInliner } from '../../tools/esbuild/i18n-inliner'; +import { I18nInliner } from '../../tools/i18n'; import { maxInlinerWorkers } from '../../utils/environment-options'; import { loadTranslations } from '../../utils/i18n-options'; import { createTranslationLoader } from '../../utils/load-translations'; diff --git a/packages/angular/build/src/tools/esbuild/index-html-generator.ts b/packages/angular/build/src/builders/application/index-html-generator.ts similarity index 96% rename from packages/angular/build/src/tools/esbuild/index-html-generator.ts rename to packages/angular/build/src/builders/application/index-html-generator.ts index a7ad3fd47e7f..d89eadf8b9b0 100644 --- a/packages/angular/build/src/tools/esbuild/index-html-generator.ts +++ b/packages/angular/build/src/builders/application/index-html-generator.ts @@ -9,9 +9,13 @@ import assert from 'node:assert'; import { createHash } from 'node:crypto'; import path from 'node:path'; -import { NormalizedApplicationBuildOptions } from '../../builders/application/options'; +import { + BuildOutputFile, + BuildOutputFileType, + InitialFileRecord, +} from '../../tools/esbuild/bundler-files'; import { IndexHtmlGenerator } from '../../utils/index-file/index-html-generator'; -import { BuildOutputFile, BuildOutputFileType, InitialFileRecord } from './bundler-files'; +import { NormalizedApplicationBuildOptions } from './options'; /** * The maximum number of module preload link elements that should be added for diff --git a/packages/angular/build/src/builders/dev-server/internal.ts b/packages/angular/build/src/builders/dev-server/internal.ts index 96587acb5cff..19ca0cf3e92e 100644 --- a/packages/angular/build/src/builders/dev-server/internal.ts +++ b/packages/angular/build/src/builders/dev-server/internal.ts @@ -8,7 +8,7 @@ export { type BuildOutputFile, BuildOutputFileType } from '../../tools/esbuild/bundler-files'; export { createRxjsEsmResolutionPlugin } from '../../tools/esbuild/rxjs-esm-resolution-plugin'; -export { JavaScriptTransformer } from '../../tools/esbuild/javascript-transformer'; +export { JavaScriptTransformer } from '../../tools/javascript-transformer'; export { getFeatureSupport, isZonelessApp } from '../../tools/esbuild/utils'; export { type IndexHtmlTransform } from '../../utils/index-file/index-html-generator'; export { purgeStaleBuildCache } from '../../utils/purge-cache'; diff --git a/packages/angular/build/src/private.ts b/packages/angular/build/src/private.ts index 1fe8765b2646..9db709640b57 100644 --- a/packages/angular/build/src/private.ts +++ b/packages/angular/build/src/private.ts @@ -39,9 +39,9 @@ export { transformSupportedBrowsersToTargets } from './tools/esbuild/target'; export { SassCompiler } from './tools/sass/sass-service'; export { SourceFileCache } from './tools/esbuild/angular/source-file-cache'; -export { Cache } from './tools/esbuild/cache'; +export { Cache } from './utils/cache'; export { createJitResourceTransformer } from './tools/angular/transformers/jit-resource-transformer'; -export { JavaScriptTransformer } from './tools/esbuild/javascript-transformer'; +export { JavaScriptTransformer } from './tools/javascript-transformer'; export function createCompilerPlugin( pluginOptions: CompilerPluginOptions & { diff --git a/packages/angular/build/src/tools/angular/compilation/aot-compilation.ts b/packages/angular/build/src/tools/angular/compilation/aot-compilation.ts index ca74e721ba7d..b42b1273592d 100644 --- a/packages/angular/build/src/tools/angular/compilation/aot-compilation.ts +++ b/packages/angular/build/src/tools/angular/compilation/aot-compilation.ts @@ -11,7 +11,7 @@ import assert from 'node:assert'; import { relative } from 'node:path'; import ts from 'typescript'; import { useTypeChecking } from '../../../utils/environment-options'; -import { profileAsync, profileSync } from '../../esbuild/profiling'; +import { profileAsync, profileSync } from '../../../utils/profiling'; import { AngularHostOptions, createAngularCompilerHost, diff --git a/packages/angular/build/src/tools/angular/compilation/jit-compilation.ts b/packages/angular/build/src/tools/angular/compilation/jit-compilation.ts index 233f5977e5a6..e89db1e75aa4 100644 --- a/packages/angular/build/src/tools/angular/compilation/jit-compilation.ts +++ b/packages/angular/build/src/tools/angular/compilation/jit-compilation.ts @@ -9,7 +9,7 @@ import type * as ng from '@angular/compiler-cli'; import assert from 'node:assert'; import ts from 'typescript'; -import { profileSync } from '../../esbuild/profiling'; +import { profileSync } from '../../../utils/profiling'; import { AngularHostOptions, createAngularCompilerHost } from '../angular-host'; import { createJitResourceTransformer } from '../transformers/jit-resource-transformer'; import { lazyRoutesTransformer } from '../transformers/lazy-routes-transformer'; diff --git a/packages/angular/build/src/tools/angular/compilation/parallel-compilation.ts b/packages/angular/build/src/tools/angular/compilation/parallel-compilation.ts index 4df13b3a500e..0b58423a418b 100644 --- a/packages/angular/build/src/tools/angular/compilation/parallel-compilation.ts +++ b/packages/angular/build/src/tools/angular/compilation/parallel-compilation.ts @@ -9,8 +9,8 @@ import type { PartialMessage } from 'esbuild'; import { createRequire } from 'node:module'; import { MessageChannel } from 'node:worker_threads'; +import { mergeCumulativeDurations } from '../../../utils/profiling'; import { WorkerPool } from '../../../utils/worker-pool'; -import { mergeCumulativeDurations } from '../../esbuild/profiling'; import type { AngularHostOptions } from '../angular-host'; import { AngularCompilation, diff --git a/packages/angular/build/src/tools/angular/compilation/parallel-worker.ts b/packages/angular/build/src/tools/angular/compilation/parallel-worker.ts index 71b4d34e2756..5bf293da727d 100644 --- a/packages/angular/build/src/tools/angular/compilation/parallel-worker.ts +++ b/packages/angular/build/src/tools/angular/compilation/parallel-worker.ts @@ -11,7 +11,7 @@ import assert from 'node:assert'; import { randomUUID } from 'node:crypto'; import { type MessagePort, receiveMessageOnPort } from 'node:worker_threads'; import { initializeHash } from '../../../utils/hash'; -import { getAndClearCumulativeDurations } from '../../esbuild/profiling'; +import { getAndClearCumulativeDurations } from '../../../utils/profiling'; import type { AngularCompilation, AngularCompilationResult, diff --git a/packages/angular/build/src/tools/angular/compilation/typescript-compilation.ts b/packages/angular/build/src/tools/angular/compilation/typescript-compilation.ts index 71061031f3a4..05403b728fda 100644 --- a/packages/angular/build/src/tools/angular/compilation/typescript-compilation.ts +++ b/packages/angular/build/src/tools/angular/compilation/typescript-compilation.ts @@ -10,7 +10,7 @@ import type * as ng from '@angular/compiler-cli'; import type { PartialMessage } from 'esbuild'; import ts from 'typescript'; import { toPosixPath } from '../../../utils/path'; -import { profileAsync, profileSync } from '../../esbuild/profiling'; +import { profileAsync, profileSync } from '../../../utils/profiling'; import { AngularCompilation, DiagnosticModes } from './angular-compilation'; import { type CompilerOptionOverrides, transformCompilerOptions } from './compiler-options'; import { convertTypeScriptDiagnostic } from './diagnostics'; diff --git a/packages/angular/build/src/tools/esbuild/angular/compiler-plugin.ts b/packages/angular/build/src/tools/esbuild/angular/compiler-plugin.ts index 00c82b328085..a9c71e8db888 100644 --- a/packages/angular/build/src/tools/esbuild/angular/compiler-plugin.ts +++ b/packages/angular/build/src/tools/esbuild/angular/compiler-plugin.ts @@ -20,14 +20,18 @@ import type { import assert from 'node:assert'; import { readFile } from 'node:fs/promises'; import * as path from 'node:path'; +import { type PersistentCacheStore, createPersistentCacheStore } from '../../../utils/cache'; import { maxTransformWorkers, useTypeChecking } from '../../../utils/environment-options'; import { calculateHash, initializeHash } from '../../../utils/hash'; +import { + logCumulativeDurations, + profileAsync, + resetCumulativeDurations, +} from '../../../utils/profiling'; import { AngularHostOptions } from '../../angular/angular-host'; import { AngularCompilation, DiagnosticModes } from '../../angular/compilation'; -import { type PersistentCacheStore, createPersistentCacheStore } from '../cache'; -import { JavaScriptTransformer } from '../javascript-transformer'; +import { JavaScriptTransformer } from '../../javascript-transformer'; import { LoadResultCache, createCachedLoad } from '../load-result-cache'; -import { logCumulativeDurations, profileAsync, resetCumulativeDurations } from '../profiling'; import { AngularCompilationContext, PrimaryCompilationContext } from './compilation-state'; import { ComponentStylesheetBundler } from './component-stylesheets'; import { FileReferenceTracker } from './file-reference-tracker'; diff --git a/packages/angular/build/src/tools/esbuild/angular/component-stylesheets.ts b/packages/angular/build/src/tools/esbuild/angular/component-stylesheets.ts index 75ce354341ad..b5d2e453b57e 100644 --- a/packages/angular/build/src/tools/esbuild/angular/component-stylesheets.ts +++ b/packages/angular/build/src/tools/esbuild/angular/component-stylesheets.ts @@ -8,10 +8,10 @@ import assert from 'node:assert'; import path from 'node:path'; +import { MemoryCache } from '../../../utils/cache'; import { createContentHash } from '../../../utils/hash'; import { BundleContextResult, BundlerContext } from '../bundler-context'; import { type BuildOutputFile, BuildOutputFileType } from '../bundler-files'; -import { MemoryCache } from '../cache'; import { MemoryLoadResultCache } from '../load-result-cache'; import { BundleStylesheetOptions, diff --git a/packages/angular/build/src/tools/esbuild/bundler-execution-result.ts b/packages/angular/build/src/tools/esbuild/bundler-execution-result.ts index eeb7045dfb61..991ad988662b 100644 --- a/packages/angular/build/src/tools/esbuild/bundler-execution-result.ts +++ b/packages/angular/build/src/tools/esbuild/bundler-execution-result.ts @@ -8,7 +8,7 @@ import type { Message, PartialMessage } from 'esbuild'; import { normalize } from 'node:path'; -import type { ChangedFiles } from '../../tools/esbuild/watcher'; +import type { ChangedFiles } from '../../utils/watcher'; import type { ComponentStylesheetBundler } from './angular/component-stylesheets'; import type { SourceFileCache } from './angular/source-file-cache'; import type { BundlerContext } from './bundler-context'; diff --git a/packages/angular/build/src/tools/esbuild/i18n-locale-plugin.ts b/packages/angular/build/src/tools/esbuild/i18n-locale-plugin.ts index 8ffddf19adb7..b4c89cf644c1 100644 --- a/packages/angular/build/src/tools/esbuild/i18n-locale-plugin.ts +++ b/packages/angular/build/src/tools/esbuild/i18n-locale-plugin.ts @@ -7,136 +7,23 @@ */ import type { Plugin } from 'esbuild'; -import { readFile } from 'node:fs/promises'; import { createProjectResolver } from '../../utils/resolve-project'; - -/** - * The internal namespace used by generated locale import statements and Angular locale data plugin. - */ -export const LOCALE_DATA_NAMESPACE = 'angular:locale/data'; - -/** - * The base module location used to search for locale specific data. - */ -export const LOCALE_DATA_BASE_MODULE = '@angular/common/locales/global'; - -/** - * Result of resolving locale data for a given locale tag. - */ -export interface LocaleDataResolution { - path?: string; - warning?: string; - error?: string; -} - -/** - * Result of loading locale data for a given locale tag. - */ -export interface LoadedLocaleData { - code?: string; - warning?: string; - error?: string; -} - -const localeDataCache = new Map>(); - -/** - * Resolves the path to the Angular locale data file for a given locale tag. - * - * @param rawLocaleTag The raw locale identifier (e.g. "fr-CA", "de", "en-US"). - * @param projectResolve A function that attempts to resolve a path string to an absolute file path. - * @returns Resolution result with file path, or warning/error diagnostics if applicable. - */ -export function resolveLocaleDataPath( - rawLocaleTag: string, - projectResolve: (potentialPath: string) => string | undefined, -): LocaleDataResolution { - let partialLocaleTag: string; - try { - const locale = new Intl.Locale(rawLocaleTag); - partialLocaleTag = locale.baseName; - } catch { - return { - error: `Invalid or unsupported locale provided in configuration: "${rawLocaleTag}"`, - }; - } - - let exact = true; - while (partialLocaleTag) { - // Angular embeds the `en`/`en-US` locale into the framework and it does not need to be included again here. - if (partialLocaleTag === 'en' || partialLocaleTag === 'en-US') { - return {}; - } - - const potentialPath = `${LOCALE_DATA_BASE_MODULE}/${partialLocaleTag}`; - try { - const resolvedPath = projectResolve(potentialPath); - if (resolvedPath) { - return { - path: resolvedPath, - warning: exact - ? undefined - : `Locale data for '${rawLocaleTag}' cannot be found. Using locale data for '${partialLocaleTag}'.`, - }; - } - } catch {} - - // Remove the last subtag and try again with a less specific locale. - const parts = partialLocaleTag.split('-'); - partialLocaleTag = parts.slice(0, -1).join('-'); - exact = false; - } - - return { - warning: `Locale data for '${rawLocaleTag}' cannot be found. No locale data will be included for this locale.`, - }; -} - -/** - * Loads the Angular global locale data script for a specified locale tag. - * - * @param rawLocaleTag The raw locale identifier (e.g. "fr-CA", "de", "en-US"). - * @param projectRoot Optional project root for module resolution. - * @returns A promise resolving to the loaded locale data script code and any diagnostic warnings. - */ -export function loadLocaleData( - rawLocaleTag: string, - projectRoot?: string, -): Promise { - let cached = localeDataCache.get(rawLocaleTag); - if (!cached) { - cached = (async () => { - const projectResolve = createProjectResolver(projectRoot ?? process.cwd()); - const resolution = resolveLocaleDataPath(rawLocaleTag, (potentialPath) => { - try { - return projectResolve(potentialPath); - } catch { - return undefined; - } - }); - - if (resolution.error) { - return { error: resolution.error }; - } - - if (resolution.path) { - try { - const code = await readFile(resolution.path, 'utf8'); - - return { code, warning: resolution.warning }; - } catch (e) { - return { error: `Failed to read locale data file: ${(e as Error).message}` }; - } - } - - return { warning: resolution.warning }; - })(); - - localeDataCache.set(rawLocaleTag, cached); - } - - return cached; -} +import { + LOCALE_DATA_NAMESPACE, + type LoadedLocaleData, + type LocaleDataResolution, + loadLocaleData, + resolveLocaleDataPath, +} from '../i18n/locale-data'; + +export { + LOCALE_DATA_NAMESPACE, + LOCALE_DATA_BASE_MODULE, + type LoadedLocaleData, + type LocaleDataResolution, + loadLocaleData, + resolveLocaleDataPath, +} from '../i18n/locale-data'; /** * Creates an esbuild plugin that resolves Angular locale data files from `@angular/common`. diff --git a/packages/angular/build/src/tools/esbuild/persistent-load-result-cache.ts b/packages/angular/build/src/tools/esbuild/persistent-load-result-cache.ts index 9761ff9aff64..c5dcee90ccf9 100644 --- a/packages/angular/build/src/tools/esbuild/persistent-load-result-cache.ts +++ b/packages/angular/build/src/tools/esbuild/persistent-load-result-cache.ts @@ -31,9 +31,9 @@ import type { Loader, OnLoadResult, PartialMessage } from 'esbuild'; import { readFile, stat } from 'node:fs/promises'; import { isAbsolute } from 'node:path'; import { fileURLToPath } from 'node:url'; +import type { Cache as PersistentCacheStore } from '../../utils/cache'; import { mapConcurrent, runConcurrent } from '../../utils/concurrency'; import { calculateHash, createContentHash } from '../../utils/hash'; -import type { Cache as PersistentCacheStore } from './cache'; import { LoadResultCache, MemoryLoadResultCache } from './load-result-cache'; /** diff --git a/packages/angular/build/src/tools/esbuild/persistent-load-result-cache_spec.ts b/packages/angular/build/src/tools/esbuild/persistent-load-result-cache_spec.ts index f8ecc0611818..b41add55031d 100644 --- a/packages/angular/build/src/tools/esbuild/persistent-load-result-cache_spec.ts +++ b/packages/angular/build/src/tools/esbuild/persistent-load-result-cache_spec.ts @@ -10,8 +10,8 @@ import type { OnLoadResult } from 'esbuild'; import fs from 'node:fs'; import os from 'node:os'; import path from 'node:path'; +import type { Cache as PersistentCacheStore } from '../../utils/cache'; import { initializeHash } from '../../utils/hash'; -import type { Cache as PersistentCacheStore } from './cache'; import { type CachedLoadResultEntry, PersistentLoadResultCache, diff --git a/packages/angular/build/src/tools/esbuild/stylesheets/sass-language.ts b/packages/angular/build/src/tools/esbuild/stylesheets/sass-language.ts index cce85f61b9a2..b519a408bfb8 100644 --- a/packages/angular/build/src/tools/esbuild/stylesheets/sass-language.ts +++ b/packages/angular/build/src/tools/esbuild/stylesheets/sass-language.ts @@ -10,8 +10,8 @@ import type { OnLoadResult, PartialMessage, PartialNote, ResolveResult } from 'e import { dirname, join } from 'node:path'; import { fileURLToPath, pathToFileURL } from 'node:url'; import type { CanonicalizeContext, CompileResult, Exception, Syntax } from 'sass-embedded'; +import { MemoryCache } from '../../../utils/cache'; import type { SassCompiler } from '../../sass/sass-service'; -import { MemoryCache } from '../cache'; import { StylesheetLanguage, StylesheetPluginOptions } from './stylesheet-plugin-factory'; let sassService: SassCompiler | undefined; diff --git a/packages/angular/build/src/tools/esbuild/i18n-inliner-worker.ts b/packages/angular/build/src/tools/i18n/i18n-inliner-worker.ts similarity index 99% rename from packages/angular/build/src/tools/esbuild/i18n-inliner-worker.ts rename to packages/angular/build/src/tools/i18n/i18n-inliner-worker.ts index ac75ab246d8d..6a7e84b308b7 100644 --- a/packages/angular/build/src/tools/esbuild/i18n-inliner-worker.ts +++ b/packages/angular/build/src/tools/i18n/i18n-inliner-worker.ts @@ -8,14 +8,12 @@ import remapping, { type DecodedSourceMap, type SourceMapInput } from '@ampproject/remapping'; import type { ɵParsedTranslation } from '@angular/localize'; -import type { Node } from '@oxc-project/types'; import { MagicString } from 'magic-string'; -import assert from 'node:assert'; import { deserialize } from 'node:v8'; import { parseSync } from 'oxc-parser'; import { traversePostOrder } from '../oxc/traversal'; -import { loadLocaleData } from './i18n-locale-plugin'; import { createSharedTranslationProxy } from './i18n-translation-reader'; +import { loadLocaleData } from './locale-data'; /** * The options passed to the inliner for each code request diff --git a/packages/angular/build/src/tools/esbuild/i18n-inliner.ts b/packages/angular/build/src/tools/i18n/i18n-inliner.ts similarity index 99% rename from packages/angular/build/src/tools/esbuild/i18n-inliner.ts rename to packages/angular/build/src/tools/i18n/i18n-inliner.ts index e5ec68f48e26..581a2477adc5 100644 --- a/packages/angular/build/src/tools/esbuild/i18n-inliner.ts +++ b/packages/angular/build/src/tools/i18n/i18n-inliner.ts @@ -11,10 +11,18 @@ import assert from 'node:assert'; import { createRequire } from 'node:module'; import { extname, join } from 'node:path'; import { serialize } from 'node:v8'; +import { + type Cache, + type PersistentCacheStore, + createPersistentCacheStore, +} from '../../utils/cache'; import { calculateHash, createContentHash, initializeHash } from '../../utils/hash'; import { WorkerPool } from '../../utils/worker-pool'; -import { type BuildOutputFile, BuildOutputFileType, createOutputFile } from './bundler-files'; -import { type Cache, type PersistentCacheStore, createPersistentCacheStore } from './cache'; +import { + type BuildOutputFile, + BuildOutputFileType, + createOutputFile, +} from '../esbuild/bundler-files'; import type { InlineCodeRequest, InlineCodeResult, diff --git a/packages/angular/build/src/tools/esbuild/i18n-inliner_spec.ts b/packages/angular/build/src/tools/i18n/i18n-inliner_spec.ts similarity index 99% rename from packages/angular/build/src/tools/esbuild/i18n-inliner_spec.ts rename to packages/angular/build/src/tools/i18n/i18n-inliner_spec.ts index 8f73c018e4bd..bbc827b94c7f 100644 --- a/packages/angular/build/src/tools/esbuild/i18n-inliner_spec.ts +++ b/packages/angular/build/src/tools/i18n/i18n-inliner_spec.ts @@ -11,10 +11,14 @@ import { transform } from 'esbuild'; import fs from 'node:fs/promises'; import os from 'node:os'; import path from 'node:path'; +import { createPersistentCacheStore } from '../../utils/cache'; import { initializeHash } from '../../utils/hash'; import { WorkerPool } from '../../utils/worker-pool'; -import { type BuildOutputFile, BuildOutputFileType, createOutputFile } from './bundler-files'; -import { createPersistentCacheStore } from './cache'; +import { + type BuildOutputFile, + BuildOutputFileType, + createOutputFile, +} from '../esbuild/bundler-files'; import { I18nInliner, type I18nInlinerOptions } from './i18n-inliner'; /** diff --git a/packages/angular/build/src/tools/esbuild/i18n-translation-encoder.ts b/packages/angular/build/src/tools/i18n/i18n-translation-encoder.ts similarity index 100% rename from packages/angular/build/src/tools/esbuild/i18n-translation-encoder.ts rename to packages/angular/build/src/tools/i18n/i18n-translation-encoder.ts diff --git a/packages/angular/build/src/tools/esbuild/i18n-translation-encoder_spec.ts b/packages/angular/build/src/tools/i18n/i18n-translation-encoder_spec.ts similarity index 100% rename from packages/angular/build/src/tools/esbuild/i18n-translation-encoder_spec.ts rename to packages/angular/build/src/tools/i18n/i18n-translation-encoder_spec.ts diff --git a/packages/angular/build/src/tools/esbuild/i18n-translation-reader.ts b/packages/angular/build/src/tools/i18n/i18n-translation-reader.ts similarity index 100% rename from packages/angular/build/src/tools/esbuild/i18n-translation-reader.ts rename to packages/angular/build/src/tools/i18n/i18n-translation-reader.ts diff --git a/packages/angular/build/src/tools/i18n/index.ts b/packages/angular/build/src/tools/i18n/index.ts new file mode 100644 index 000000000000..a2f8cdd2d8f3 --- /dev/null +++ b/packages/angular/build/src/tools/i18n/index.ts @@ -0,0 +1,12 @@ +/** + * @license + * Copyright Google LLC All Rights Reserved. + * + * Use of this source code is governed by an MIT-style license that can be + * found in the LICENSE file at https://angular.dev/license + */ + +export * from './i18n-inliner'; +export * from './i18n-translation-encoder'; +export * from './i18n-translation-reader'; +export * from './locale-data'; diff --git a/packages/angular/build/src/tools/i18n/locale-data.ts b/packages/angular/build/src/tools/i18n/locale-data.ts new file mode 100644 index 000000000000..0418830b69a8 --- /dev/null +++ b/packages/angular/build/src/tools/i18n/locale-data.ts @@ -0,0 +1,138 @@ +/** + * @license + * Copyright Google LLC All Rights Reserved. + * + * Use of this source code is governed by an MIT-style license that can be + * found in the LICENSE file at https://angular.dev/license + */ + +import { readFile } from 'node:fs/promises'; +import { createProjectResolver } from '../../utils/resolve-project'; + +/** + * The internal namespace used by generated locale import statements and Angular locale data plugin. + */ +export const LOCALE_DATA_NAMESPACE = 'angular:locale/data'; + +/** + * The base module location used to search for locale specific data. + */ +export const LOCALE_DATA_BASE_MODULE = '@angular/common/locales/global'; + +/** + * Result of resolving locale data for a given locale tag. + */ +export interface LocaleDataResolution { + path?: string; + warning?: string; + error?: string; +} + +/** + * Result of loading locale data for a given locale tag. + */ +export interface LoadedLocaleData { + code?: string; + warning?: string; + error?: string; +} + +const localeDataCache = new Map>(); + +/** + * Resolves the path to the Angular locale data file for a given locale tag. + * + * @param rawLocaleTag The raw locale identifier (e.g. "fr-CA", "de", "en-US"). + * @param projectResolve A function that attempts to resolve a path string to an absolute file path. + * @returns Resolution result with file path, or warning/error diagnostics if applicable. + */ +export function resolveLocaleDataPath( + rawLocaleTag: string, + projectResolve: (potentialPath: string) => string | undefined, +): LocaleDataResolution { + let partialLocaleTag: string; + try { + const locale = new Intl.Locale(rawLocaleTag); + partialLocaleTag = locale.baseName; + } catch { + return { + error: `Invalid or unsupported locale provided in configuration: "${rawLocaleTag}"`, + }; + } + + let exact = true; + while (partialLocaleTag) { + // Angular embeds the `en`/`en-US` locale into the framework and it does not need to be included again here. + if (partialLocaleTag === 'en' || partialLocaleTag === 'en-US') { + return {}; + } + + const potentialPath = `${LOCALE_DATA_BASE_MODULE}/${partialLocaleTag}`; + try { + const resolvedPath = projectResolve(potentialPath); + if (resolvedPath) { + return { + path: resolvedPath, + warning: exact + ? undefined + : `Locale data for '${rawLocaleTag}' cannot be found. Using locale data for '${partialLocaleTag}'.`, + }; + } + } catch {} + + // Remove the last subtag and try again with a less specific locale. + const parts = partialLocaleTag.split('-'); + partialLocaleTag = parts.slice(0, -1).join('-'); + exact = false; + } + + return { + warning: `Locale data for '${rawLocaleTag}' cannot be found. No locale data will be included for this locale.`, + }; +} + +/** + * Loads the Angular global locale data script for a specified locale tag. + * + * @param rawLocaleTag The raw locale identifier (e.g. "fr-CA", "de", "en-US"). + * @param projectRoot Optional project root for module resolution. + * @returns A promise resolving to the loaded locale data script code and any diagnostic warnings. + */ +export function loadLocaleData( + rawLocaleTag: string, + projectRoot?: string, +): Promise { + let cached = localeDataCache.get(rawLocaleTag); + if (!cached) { + cached = (async () => { + const projectResolve = createProjectResolver(projectRoot ?? process.cwd()); + const resolution = resolveLocaleDataPath(rawLocaleTag, (potentialPath) => { + try { + return projectResolve(potentialPath); + } catch { + return undefined; + } + }); + + if (resolution.error) { + return { error: resolution.error }; + } + + if (resolution.path) { + try { + const code = await readFile(resolution.path, 'utf8'); + + return { code, warning: resolution.warning }; + } catch (e) { + return { error: `Failed to read locale data file: ${(e as Error).message}` }; + } + } + + return { warning: resolution.warning }; + })(); + + localeDataCache.set(rawLocaleTag, cached); + } + + return cached; +} diff --git a/packages/angular/build/src/tools/javascript-transformer/index.ts b/packages/angular/build/src/tools/javascript-transformer/index.ts new file mode 100644 index 000000000000..399eea87e644 --- /dev/null +++ b/packages/angular/build/src/tools/javascript-transformer/index.ts @@ -0,0 +1,9 @@ +/** + * @license + * Copyright Google LLC All Rights Reserved. + * + * Use of this source code is governed by an MIT-style license that can be + * found in the LICENSE file at https://angular.dev/license + */ + +export * from './javascript-transformer'; diff --git a/packages/angular/build/src/tools/esbuild/javascript-transformer-worker.ts b/packages/angular/build/src/tools/javascript-transformer/javascript-transformer-worker.ts similarity index 100% rename from packages/angular/build/src/tools/esbuild/javascript-transformer-worker.ts rename to packages/angular/build/src/tools/javascript-transformer/javascript-transformer-worker.ts diff --git a/packages/angular/build/src/tools/esbuild/javascript-transformer.ts b/packages/angular/build/src/tools/javascript-transformer/javascript-transformer.ts similarity index 99% rename from packages/angular/build/src/tools/esbuild/javascript-transformer.ts rename to packages/angular/build/src/tools/javascript-transformer/javascript-transformer.ts index 2917222a3277..56a7b4eb6ed9 100644 --- a/packages/angular/build/src/tools/esbuild/javascript-transformer.ts +++ b/packages/angular/build/src/tools/javascript-transformer/javascript-transformer.ts @@ -7,11 +7,11 @@ */ import { readFile } from 'node:fs/promises'; +import { Cache } from '../../utils/cache'; import { createContentHash } from '../../utils/hash'; import { IMPORT_EXEC_ARGV } from '../../utils/server-rendering/esm-in-memory-loader/utils'; import { removeSourceMappingURL } from '../../utils/source-map'; import { WorkerPool, WorkerPoolOptions } from '../../utils/worker-pool'; -import { Cache } from './cache'; const LINKER_DECLARATION_PREFIX = 'ɵɵngDeclare'; const LINKER_DECLARATION_PREFIX_BYTES = Buffer.from(LINKER_DECLARATION_PREFIX, 'utf-8'); diff --git a/packages/angular/build/src/tools/esbuild/javascript-transformer_spec.ts b/packages/angular/build/src/tools/javascript-transformer/javascript-transformer_spec.ts similarity index 100% rename from packages/angular/build/src/tools/esbuild/javascript-transformer_spec.ts rename to packages/angular/build/src/tools/javascript-transformer/javascript-transformer_spec.ts diff --git a/packages/angular/build/src/tools/vite/utils.ts b/packages/angular/build/src/tools/vite/utils.ts index dc7094b8ffe4..fa833066f8ed 100644 --- a/packages/angular/build/src/tools/vite/utils.ts +++ b/packages/angular/build/src/tools/vite/utils.ts @@ -13,7 +13,7 @@ import type { DepOptimizationConfig } from 'vite' with { 'resolution-mode': 'import', }; import type { ExternalResultMetadata } from '../esbuild/bundler-execution-result'; -import { JavaScriptTransformer } from '../esbuild/javascript-transformer'; +import { JavaScriptTransformer } from '../javascript-transformer'; export type AngularMemoryOutputFiles = Map< string, diff --git a/packages/angular/build/src/tools/esbuild/cache.ts b/packages/angular/build/src/utils/cache/cache.ts similarity index 98% rename from packages/angular/build/src/tools/esbuild/cache.ts rename to packages/angular/build/src/utils/cache/cache.ts index 40c6787abee3..1773caca71ea 100644 --- a/packages/angular/build/src/tools/esbuild/cache.ts +++ b/packages/angular/build/src/utils/cache/cache.ts @@ -11,8 +11,8 @@ * Provides infrastructure for common caching functionality within the build system. */ -import { persistentCacheStoreSetting } from '../../utils/environment-options'; -import { assertIsError } from '../../utils/error'; +import { persistentCacheStoreSetting } from '../environment-options'; +import { assertIsError } from '../error'; /** * A backing data store for one or more Cache instances. diff --git a/packages/angular/build/src/tools/esbuild/cache_spec.ts b/packages/angular/build/src/utils/cache/cache_spec.ts similarity index 100% rename from packages/angular/build/src/tools/esbuild/cache_spec.ts rename to packages/angular/build/src/utils/cache/cache_spec.ts diff --git a/packages/angular/build/src/utils/cache/index.ts b/packages/angular/build/src/utils/cache/index.ts new file mode 100644 index 000000000000..417d13326f50 --- /dev/null +++ b/packages/angular/build/src/utils/cache/index.ts @@ -0,0 +1,9 @@ +/** + * @license + * Copyright Google LLC All Rights Reserved. + * + * Use of this source code is governed by an MIT-style license that can be + * found in the LICENSE file at https://angular.dev/license + */ + +export * from './cache'; diff --git a/packages/angular/build/src/tools/esbuild/lmdb-cache-store.ts b/packages/angular/build/src/utils/cache/lmdb-cache-store.ts similarity index 100% rename from packages/angular/build/src/tools/esbuild/lmdb-cache-store.ts rename to packages/angular/build/src/utils/cache/lmdb-cache-store.ts diff --git a/packages/angular/build/src/tools/esbuild/sqlite-cache-store.ts b/packages/angular/build/src/utils/cache/sqlite-cache-store.ts similarity index 100% rename from packages/angular/build/src/tools/esbuild/sqlite-cache-store.ts rename to packages/angular/build/src/utils/cache/sqlite-cache-store.ts diff --git a/packages/angular/build/src/tools/esbuild/sqlite-cache-store_spec.ts b/packages/angular/build/src/utils/cache/sqlite-cache-store_spec.ts similarity index 100% rename from packages/angular/build/src/tools/esbuild/sqlite-cache-store_spec.ts rename to packages/angular/build/src/utils/cache/sqlite-cache-store_spec.ts diff --git a/packages/angular/build/src/tools/esbuild/profiling.ts b/packages/angular/build/src/utils/profiling.ts similarity index 97% rename from packages/angular/build/src/tools/esbuild/profiling.ts rename to packages/angular/build/src/utils/profiling.ts index 80fd26c32d0e..762a739bd318 100644 --- a/packages/angular/build/src/tools/esbuild/profiling.ts +++ b/packages/angular/build/src/utils/profiling.ts @@ -6,7 +6,7 @@ * found in the LICENSE file at https://angular.dev/license */ -import { debugPerformance } from '../../utils/environment-options'; +import { debugPerformance } from './environment-options'; let cumulativeDurations: Map | undefined; diff --git a/packages/angular/build/src/tools/esbuild/watcher.ts b/packages/angular/build/src/utils/watcher.ts similarity index 99% rename from packages/angular/build/src/tools/esbuild/watcher.ts rename to packages/angular/build/src/utils/watcher.ts index e30909fa6813..be38151f7a48 100644 --- a/packages/angular/build/src/tools/esbuild/watcher.ts +++ b/packages/angular/build/src/utils/watcher.ts @@ -12,8 +12,8 @@ import { once } from 'node:events'; import * as fs from 'node:fs'; import * as path from 'node:path'; import picomatch from 'picomatch'; -import { shouldWatchRoot } from '../../utils/environment-options'; -import { toPosixPath } from '../../utils/path'; +import { shouldWatchRoot } from './environment-options'; +import { toPosixPath } from './path'; export class ChangedFiles { readonly added = new Set(); diff --git a/packages/angular/build/src/tools/esbuild/watcher_spec.ts b/packages/angular/build/src/utils/watcher_spec.ts similarity index 100% rename from packages/angular/build/src/tools/esbuild/watcher_spec.ts rename to packages/angular/build/src/utils/watcher_spec.ts diff --git a/scripts/benchmark.mts b/scripts/benchmark.mts index bf35b97808e3..0237f5101bc4 100644 --- a/scripts/benchmark.mts +++ b/scripts/benchmark.mts @@ -11,8 +11,8 @@ import path from 'node:path'; import { type BenchmarkCliOptions, runI18nBenchmarks } from './benchmarks/i18n/index.mts'; function checkBuildStatus(logger: Console): boolean { - const distFile = 'dist/@angular/build/src/tools/esbuild/i18n-inliner.js'; - const srcFile = 'packages/angular/build/src/tools/esbuild/i18n-inliner.ts'; + const distFile = 'dist/@angular/build/src/tools/i18n/i18n-inliner.js'; + const srcFile = 'packages/angular/build/src/tools/i18n/i18n-inliner.ts'; if (!fs.existsSync(distFile)) { logger.error( diff --git a/scripts/benchmarks/i18n/fixtures.mts b/scripts/benchmarks/i18n/fixtures.mts index 3d53c3dbff5b..6a926d07a29e 100644 --- a/scripts/benchmarks/i18n/fixtures.mts +++ b/scripts/benchmarks/i18n/fixtures.mts @@ -14,7 +14,7 @@ import { createRequire } from 'node:module'; import path from 'node:path'; import type { BuildOutputFile } from '../../../packages/angular/build/src/tools/esbuild/bundler-files.js'; -import type { LocaleInlineOptions } from '../../../packages/angular/build/src/tools/esbuild/i18n-inliner.js'; +import type { LocaleInlineOptions } from '../../../packages/angular/build/src/tools/i18n/i18n-inliner.js'; // Setup module paths to resolve dependencies from packages/angular/build const requireFromBuild = createRequire( diff --git a/scripts/benchmarks/i18n/scenarios.mts b/scripts/benchmarks/i18n/scenarios.mts index c00f34ded8a2..d1bdcb8cfa40 100644 --- a/scripts/benchmarks/i18n/scenarios.mts +++ b/scripts/benchmarks/i18n/scenarios.mts @@ -16,7 +16,7 @@ import path from 'node:path'; import { pathToFileURL } from 'node:url'; import type { BuildOutputFile } from '../../../packages/angular/build/src/tools/esbuild/bundler-files.js'; -import type { LocaleInlineOptions } from '../../../packages/angular/build/src/tools/esbuild/i18n-inliner.js'; +import type { LocaleInlineOptions } from '../../../packages/angular/build/src/tools/i18n/i18n-inliner.js'; import { generateSyntheticBundle, generateTranslations, initializeFixtures } from './fixtures.mts'; import type { BenchmarkScenario } from './harness.mts'; @@ -25,8 +25,8 @@ const requireFromBuild = createRequire( ); const { I18nInliner } = requireFromBuild( - '../../../dist/@angular/build/src/tools/esbuild/i18n-inliner.js', -) as typeof import('../../../packages/angular/build/src/tools/esbuild/i18n-inliner.js'); + '../../../dist/@angular/build/src/tools/i18n/i18n-inliner.js', +) as typeof import('../../../packages/angular/build/src/tools/i18n/i18n-inliner.js'); export interface ScenarioFactoryOptions { concurrency?: number; From 5cd20e141ad176c87e4002da2d4ee3755f97cd3e Mon Sep 17 00:00:00 2001 From: Alan Agius <17563226+alan-agius4@users.noreply.github.com> Date: Fri, 18 Sep 2026 08:20:21 +0000 Subject: [PATCH 015/233] perf(@angular/build): only reset Sass worker pool caches when stylesheet files change (cherry picked from commit 42eaa9779c88f75e24f7ceeae19da24bb1e0d741) --- .../angular/build/src/builders/application/build-action.ts | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/packages/angular/build/src/builders/application/build-action.ts b/packages/angular/build/src/builders/application/build-action.ts index 52e70ff87e99..b728ab9a8df5 100644 --- a/packages/angular/build/src/builders/application/build-action.ts +++ b/packages/angular/build/src/builders/application/build-action.ts @@ -158,7 +158,10 @@ export async function* runEsBuildBuildAction( // Clear removed files from current watch files changes.removed.forEach((removedPath) => currentWatchFiles.delete(removedPath)); - resetSassWorkerPoolCaches(); + const hasSassChanges = changes.all.some((f) => /\.(scss|sass|css)$/i.test(f)); + if (hasSassChanges) { + resetSassWorkerPoolCaches(); + } const rebuildState = result.createRebuildState(changes); result = await withProgress('Changes detected. Rebuilding...', () => action(rebuildState)); From 1fc2732795069ad521645b06a94e5df3a55c3d9c Mon Sep 17 00:00:00 2001 From: Charles Lyding <19598772+clydin@users.noreply.github.com> Date: Mon, 21 Sep 2026 12:25:56 -0400 Subject: [PATCH 016/233] fix(@angular/build): support parenthesized expressions in oxc linker Unwrap parenthesized expressions in `OxcAstHost` to ensure parity with Babel and prevent fatal linker errors when parsing functions returning parenthesized expressions (such as `resolveMetadata: () => ({ ... })` in deferred component metadata) and other parenthesized declaration properties. Fixes #34129 (cherry picked from commit 43aab6a1cf4f15e420c5fb8fe17ab38583d11c25) --- .../src/tools/angular/linker/oxc-ast-host.ts | 63 +++++++++++++--- .../tools/angular/linker/oxc-ast-host_spec.ts | 74 +++++++++++++++++++ .../tools/angular/linker/oxc-linker_spec.ts | 23 ++++++ 3 files changed, 149 insertions(+), 11 deletions(-) diff --git a/packages/angular/build/src/tools/angular/linker/oxc-ast-host.ts b/packages/angular/build/src/tools/angular/linker/oxc-ast-host.ts index 5a11959fff66..245443781601 100644 --- a/packages/angular/build/src/tools/angular/linker/oxc-ast-host.ts +++ b/packages/angular/build/src/tools/angular/linker/oxc-ast-host.ts @@ -26,11 +26,20 @@ function isNode(node: unknown): node is Node { return typeof node === 'object' && node !== null && 'type' in node; } +function unwrapParentheses(node: unknown): unknown { + while (isNode(node) && node.type === 'ParenthesizedExpression') { + node = node.expression; + } + + return node; +} + /** * An implementation of `AstHost` that queries information from `oxc-parser` AST nodes. */ export class OxcAstHost implements AstHost { getSymbolName(node: unknown): string | null { + node = unwrapParentheses(node); if (!isNode(node)) { return null; } @@ -47,10 +56,13 @@ export class OxcAstHost implements AstHost { } isStringLiteral(node: unknown): node is StringLiteral { + node = unwrapParentheses(node); + return isNode(node) && node.type === 'Literal' && typeof node.value === 'string'; } parseStringLiteral(str: unknown): string { + str = unwrapParentheses(str); if (!this.isStringLiteral(str)) { throw new FatalLinkerError(str as object, 'Unsupported syntax, expected a string literal.'); } @@ -59,10 +71,13 @@ export class OxcAstHost implements AstHost { } isNumericLiteral(node: unknown): node is NumericLiteral { + node = unwrapParentheses(node); + return isNode(node) && node.type === 'Literal' && typeof node.value === 'number'; } parseNumericLiteral(num: unknown): number { + num = unwrapParentheses(num); if (!this.isNumericLiteral(num)) { throw new FatalLinkerError(num as object, 'Unsupported syntax, expected a numeric literal.'); } @@ -71,6 +86,7 @@ export class OxcAstHost implements AstHost { } isBooleanLiteral(node: unknown): node is BooleanLiteral | UnaryExpression { + node = unwrapParentheses(node); if (!isNode(node)) { return false; } @@ -81,6 +97,7 @@ export class OxcAstHost implements AstHost { } parseBooleanLiteral(bool: unknown): boolean { + bool = unwrapParentheses(bool); if (isNode(bool)) { if (bool.type === 'Literal' && typeof bool.value === 'boolean') { return bool.value; @@ -94,14 +111,19 @@ export class OxcAstHost implements AstHost { } isNull(node: unknown): node is NullLiteral { + node = unwrapParentheses(node); + return isNode(node) && node.type === 'Literal' && node.value === null; } isArrayLiteral(node: unknown): node is ArrayExpression { + node = unwrapParentheses(node); + return isNode(node) && node.type === 'ArrayExpression'; } parseArrayLiteral(array: unknown): unknown[] { + array = unwrapParentheses(array); if (!this.isArrayLiteral(array)) { throw new FatalLinkerError(array as object, 'Unsupported syntax, expected an array literal.'); } @@ -115,23 +137,27 @@ export class OxcAstHost implements AstHost { 'Unsupported syntax, element in array not to be empty.', ); } - if (element.type === 'SpreadElement') { + const unwrappedElement = unwrapParentheses(element); + if (isNode(unwrappedElement) && unwrappedElement.type === 'SpreadElement') { throw new FatalLinkerError( - element as object, + unwrappedElement as object, 'Unsupported syntax, element in array not to use spread syntax.', ); } - result.push(element); + result.push(unwrappedElement); } return result; } isObjectLiteral(node: unknown): node is ObjectExpression { + node = unwrapParentheses(node); + return isNode(node) && node.type === 'ObjectExpression'; } parseObjectLiteral(obj: unknown): Map { + obj = unwrapParentheses(obj); if (!this.isObjectLiteral(obj)) { throw new FatalLinkerError(obj as object, 'Unsupported syntax, expected an object literal.'); } @@ -146,7 +172,13 @@ export class OxcAstHost implements AstHost { ); } - const keyNode = property.key; + const keyNode = unwrapParentheses(property.key); + if (!isNode(keyNode)) { + throw new FatalLinkerError( + property.key as object, + 'Unsupported syntax, expected a property name.', + ); + } let key: string; if (keyNode.type === 'Identifier') { @@ -162,13 +194,14 @@ export class OxcAstHost implements AstHost { ); } - result.set(key, property.value); + result.set(key, unwrapParentheses(property.value)); } return result; } isFunctionExpression(node: unknown): node is FunctionNode | ArrowFunctionExpression { + node = unwrapParentheses(node); if (!isNode(node)) { return false; } @@ -181,6 +214,7 @@ export class OxcAstHost implements AstHost { } parseReturnValue(fn: unknown): unknown { + fn = unwrapParentheses(fn); if (!this.isFunctionExpression(fn)) { throw new FatalLinkerError(fn as object, 'Unsupported syntax, expected a function.'); } @@ -191,7 +225,7 @@ export class OxcAstHost implements AstHost { } if (body.type !== 'BlockStatement') { - return body; + return unwrapParentheses(body); } const statements = body.body; @@ -217,10 +251,11 @@ export class OxcAstHost implements AstHost { ); } - return stmt.argument; + return unwrapParentheses(stmt.argument); } parseParameters(fn: unknown): unknown[] { + fn = unwrapParentheses(fn); if (!this.isFunctionExpression(fn)) { throw new FatalLinkerError(fn as object, 'Unsupported syntax, expected a function.'); } @@ -229,18 +264,22 @@ export class OxcAstHost implements AstHost { } isCallExpression(node: unknown): node is CallExpression { + node = unwrapParentheses(node); + return isNode(node) && node.type === 'CallExpression'; } parseCallee(call: unknown): unknown { + call = unwrapParentheses(call); if (!this.isCallExpression(call)) { throw new FatalLinkerError(call as object, 'Unsupported syntax, expected a call expression.'); } - return call.callee; + return unwrapParentheses(call.callee); } parseArguments(call: unknown): unknown[] { + call = unwrapParentheses(call); if (!this.isCallExpression(call)) { throw new FatalLinkerError(call as object, 'Unsupported syntax, expected a call expression.'); } @@ -248,19 +287,21 @@ export class OxcAstHost implements AstHost { const result: unknown[] = []; for (const arg of call.arguments) { - if (arg.type === 'SpreadElement') { + const unwrappedArg = unwrapParentheses(arg); + if (isNode(unwrappedArg) && unwrappedArg.type === 'SpreadElement') { throw new FatalLinkerError( - arg as object, + unwrappedArg as object, 'Unsupported syntax, argument not to use spread syntax.', ); } - result.push(arg); + result.push(unwrappedArg); } return result; } getRange(node: unknown): Range { + node = unwrapParentheses(node); if (!isNode(node) || typeof node.start !== 'number' || typeof node.end !== 'number') { throw new FatalLinkerError( node as object, diff --git a/packages/angular/build/src/tools/angular/linker/oxc-ast-host_spec.ts b/packages/angular/build/src/tools/angular/linker/oxc-ast-host_spec.ts index 79027584066d..cbe0d6a25292 100644 --- a/packages/angular/build/src/tools/angular/linker/oxc-ast-host_spec.ts +++ b/packages/angular/build/src/tools/angular/linker/oxc-ast-host_spec.ts @@ -34,11 +34,13 @@ describe('OxcAstHost', () => { it('should return the name of an identifier', () => { const expr = parseExpression('foo'); expect(host.getSymbolName(expr)).toBe('foo'); + expect(host.getSymbolName(parseExpression('(foo)'))).toBe('foo'); }); it('should return the property name of a member expression', () => { const expr = parseExpression('foo.bar'); expect(host.getSymbolName(expr)).toBe('bar'); + expect(host.getSymbolName(parseExpression('(foo.bar)'))).toBe('bar'); }); it('should return null for non-identifier or computed member expressions', () => { @@ -53,6 +55,10 @@ describe('OxcAstHost', () => { const expr = parseExpression('"hello"'); expect(host.isStringLiteral(expr)).toBe(true); expect(host.parseStringLiteral(expr)).toBe('hello'); + + const parenthesized = parseExpression('("hello")'); + expect(host.isStringLiteral(parenthesized)).toBe(true); + expect(host.parseStringLiteral(parenthesized)).toBe('hello'); }); it('should throw when parsing non-string literals', () => { @@ -67,6 +73,10 @@ describe('OxcAstHost', () => { const expr = parseExpression('123'); expect(host.isNumericLiteral(expr)).toBe(true); expect(host.parseNumericLiteral(expr)).toBe(123); + + const parenthesized = parseExpression('(123)'); + expect(host.isNumericLiteral(parenthesized)).toBe(true); + expect(host.parseNumericLiteral(parenthesized)).toBe(123); }); it('should throw when parsing non-numeric literals', () => { @@ -84,6 +94,10 @@ describe('OxcAstHost', () => { expect(host.parseBooleanLiteral(trueExpr)).toBe(true); expect(host.isBooleanLiteral(falseExpr)).toBe(true); expect(host.parseBooleanLiteral(falseExpr)).toBe(false); + + const parenthesizedTrue = parseExpression('(true)'); + expect(host.isBooleanLiteral(parenthesizedTrue)).toBe(true); + expect(host.parseBooleanLiteral(parenthesizedTrue)).toBe(true); }); it('should recognize and parse minified boolean literals (!0 and !1)', () => { @@ -93,6 +107,10 @@ describe('OxcAstHost', () => { expect(host.parseBooleanLiteral(trueExpr)).toBe(true); expect(host.isBooleanLiteral(falseExpr)).toBe(true); expect(host.parseBooleanLiteral(falseExpr)).toBe(false); + + const parenthesizedMinified = parseExpression('(!0)'); + expect(host.isBooleanLiteral(parenthesizedMinified)).toBe(true); + expect(host.parseBooleanLiteral(parenthesizedMinified)).toBe(true); }); it('should return false for invalid boolean expressions', () => { @@ -106,6 +124,18 @@ describe('OxcAstHost', () => { const expr = parseExpression('[1, "a", true]'); expect(host.isArrayLiteral(expr)).toBe(true); expect(host.parseArrayLiteral(expr).length).toBe(3); + + const parenthesized = parseExpression('([1, "a", true])'); + expect(host.isArrayLiteral(parenthesized)).toBe(true); + expect(host.parseArrayLiteral(parenthesized).length).toBe(3); + }); + + it('should unwrap parenthesized elements in array literals', () => { + const expr = parseExpression('[(1), ("a")]'); + const elements = host.parseArrayLiteral(expr); + expect(elements.length).toBe(2); + expect(host.isNumericLiteral(elements[0])).toBe(true); + expect(host.isStringLiteral(elements[1])).toBe(true); }); it('should throw when array contains empty elements or spread syntax', () => { @@ -115,6 +145,9 @@ describe('OxcAstHost', () => { expect(() => host.parseArrayLiteral(parseExpression('[1, ...a]'))).toThrowError( FatalLinkerError, ); + expect(() => host.parseArrayLiteral(parseExpression('[1, ...(a)]'))).toThrowError( + FatalLinkerError, + ); }); }); @@ -130,6 +163,16 @@ describe('OxcAstHost', () => { expect(map.has('3')).toBe(true); }); + it('should recognize and parse parenthesized object literals', () => { + const expr = parseExpression('({ a: (1), b: ("c") })'); + expect(host.isObjectLiteral(expr)).toBe(true); + + const map = host.parseObjectLiteral(expr); + expect(map.size).toBe(2); + expect(host.isNumericLiteral(map.get('a'))).toBe(true); + expect(host.isStringLiteral(map.get('b'))).toBe(true); + }); + it('should throw when object literal contains spread or non-property assignments', () => { expect(() => host.parseObjectLiteral(parseExpression('{ ...a }'))).toThrowError( FatalLinkerError, @@ -147,6 +190,21 @@ describe('OxcAstHost', () => { expect(host.isNumericLiteral(returnValue)).toBe(true); }); + it('should parse parenthesized arrow functions and concise bodies returning parenthesized object literals', () => { + const expr = parseExpression('() => ({ a: 1 })'); + expect(host.isFunctionExpression(expr)).toBe(true); + + const returnValue = host.parseReturnValue(expr); + expect(host.isObjectLiteral(returnValue)).toBe(true); + const map = host.parseObjectLiteral(returnValue); + expect(map.has('a')).toBe(true); + + const wrappedArrow = parseExpression('((a) => (42))'); + expect(host.isFunctionExpression(wrappedArrow)).toBe(true); + expect(host.parseParameters(wrappedArrow).length).toBe(1); + expect(host.isNumericLiteral(host.parseReturnValue(wrappedArrow))).toBe(true); + }); + it('should parse return value from function with block statement containing single return', () => { const stmt = parseStatement('function foo(a) { return "hello"; }'); expect(host.isFunctionExpression(stmt)).toBe(true); @@ -155,6 +213,14 @@ describe('OxcAstHost', () => { expect(host.isStringLiteral(returnValue)).toBe(true); }); + it('should parse return value from function returning parenthesized expression', () => { + const stmt = parseStatement('function foo() { return ({ a: 1 }); }'); + expect(host.isFunctionExpression(stmt)).toBe(true); + + const returnValue = host.parseReturnValue(stmt); + expect(host.isObjectLiteral(returnValue)).toBe(true); + }); + it('should throw when function body has multiple statements or no return', () => { expect(() => host.parseReturnValue(parseStatement('function foo() { const x = 1; return x; }')), @@ -171,6 +237,14 @@ describe('OxcAstHost', () => { expect(host.isCallExpression(expr)).toBe(true); expect(host.getSymbolName(host.parseCallee(expr))).toBe('foo'); expect(host.parseArguments(expr).length).toBe(2); + + const parenthesized = parseExpression('((foo)((1), ("a")))'); + expect(host.isCallExpression(parenthesized)).toBe(true); + expect(host.getSymbolName(host.parseCallee(parenthesized))).toBe('foo'); + const args = host.parseArguments(parenthesized); + expect(args.length).toBe(2); + expect(host.isNumericLiteral(args[0])).toBe(true); + expect(host.isStringLiteral(args[1])).toBe(true); }); it('should throw when call expression arguments contain spread syntax', () => { diff --git a/packages/angular/build/src/tools/angular/linker/oxc-linker_spec.ts b/packages/angular/build/src/tools/angular/linker/oxc-linker_spec.ts index fa62c1c5ece1..467658eb1991 100644 --- a/packages/angular/build/src/tools/angular/linker/oxc-linker_spec.ts +++ b/packages/angular/build/src/tools/angular/linker/oxc-linker_spec.ts @@ -76,4 +76,27 @@ describe('oxc-linker', () => { expect(result.map?.version).toBe(3); expect(result.map?.sources).toContain('test.js'); }); + + it('should link ɵɵngDeclareClassMetadataAsync with parenthesized resolveMetadata return', () => { + const input = ` + import * as i0 from "@angular/core"; + export class DeferredFixture {} + i0.ɵɵngDeclareClassMetadataAsync({ + minVersion: "18.0.0", + version: "22.1.7", + ngImport: i0, + type: DeferredFixture, + resolveDeferredDeps: () => [], + resolveMetadata: () => ({ + decorators: [], + ctorParameters: null, + propDecorators: null, + }), + }); + `; + + const result = transform('test.js', input, { link: true, advancedOptimizations: false }); + expect(result.code).toContain('ɵsetClassMetadataAsync'); + expect(result.code).not.toContain('ɵɵngDeclareClassMetadataAsync'); + }); }); From 80acd6236eac6b1b07543583717e94cbd1de1180 Mon Sep 17 00:00:00 2001 From: Alan Agius <17563226+alan-agius4@users.noreply.github.com> Date: Tue, 22 Sep 2026 11:29:16 +0000 Subject: [PATCH 017/233] fix(@angular/build): execute setup file hooks for each spec file when coverage is enabled When code coverage is enabled with the Vitest runner, test entry points are served as a virtual one-line import stub (`import "./${outputPath}";`) so that the test files themselves can be excluded from coverage reports after sourcemap remapping. However, setup files configured via `setupFiles` were also treated as test entry points and served as virtual stubs. Because Vitest only invalidates the top-level setup module between spec files, the imported intermediate bundle was cached in `vite-node` after its initial evaluation and never re-evaluated on subsequent spec files. This caused setup file hooks (e.g. `beforeEach` / `afterEach`) to silently only run for the first spec file of each worker. This commit excludes setup files from being wrapped in the virtual coverage stub, allowing them to be directly evaluated and re-evaluated by Vitest before each spec file. Fixes #34137 (cherry picked from commit cea7febe5203715a99346bfc6c2a157821952b7b) --- .../unit-test/runners/vitest/executor.ts | 1 + .../unit-test/runners/vitest/plugins.ts | 14 ++++- .../tests/options/setup-files_spec.ts | 63 +++++++++++++++++++ 3 files changed, 76 insertions(+), 2 deletions(-) diff --git a/packages/angular/build/src/builders/unit-test/runners/vitest/executor.ts b/packages/angular/build/src/builders/unit-test/runners/vitest/executor.ts index fc64e432e19f..55003b4fc82a 100644 --- a/packages/angular/build/src/builders/unit-test/runners/vitest/executor.ts +++ b/packages/angular/build/src/builders/unit-test/runners/vitest/executor.ts @@ -333,6 +333,7 @@ export class VitestExecutor implements TestExecutor { projectName, buildResultFiles: this.buildResultFiles, testFileToEntryPoint: this.testFileToEntryPoint, + setupFiles: testSetupFiles, }); const debugOptions = debug diff --git a/packages/angular/build/src/builders/unit-test/runners/vitest/plugins.ts b/packages/angular/build/src/builders/unit-test/runners/vitest/plugins.ts index ee81e417bb5d..6be4c6e8ebe3 100644 --- a/packages/angular/build/src/builders/unit-test/runners/vitest/plugins.ts +++ b/packages/angular/build/src/builders/unit-test/runners/vitest/plugins.ts @@ -37,6 +37,7 @@ interface PluginOptions { projectName: string; buildResultFiles: ReadonlyMap; testFileToEntryPoint: ReadonlyMap; + setupFiles: readonly string[]; } type VitestCoverageOption = Exclude; @@ -313,8 +314,13 @@ async function loadResultFile(file: ResultFile): Promise { } export function createVitestPlugins(pluginOptions: PluginOptions): Vite.Plugin[] { - const { workspaceRoot, buildResultFiles, testFileToEntryPoint } = pluginOptions; + const { workspaceRoot, buildResultFiles, testFileToEntryPoint, setupFiles } = pluginOptions; const isWindows = platform() === 'win32'; + const setupFileSet = new Set( + setupFiles.map((file) => + toPosixPath(path.isAbsolute(file) ? file : path.join(workspaceRoot, file)), + ), + ); let vitestConfig: ResolvedConfig; return [ @@ -387,7 +393,11 @@ export function createVitestPlugins(pluginOptions: PluginOptions): Vite.Plugin[] if (entryPoint) { outputPath = entryPoint + '.js'; - if (vitestConfig?.coverage?.enabled) { + // Setup files must not be wrapped in a virtual import stub because Vitest only invalidates + // the setup file itself between test files; wrapping it would cause the underlying bundle + // to be cached, preventing per-test hooks from running on subsequent test files. + const isSetupFile = setupFileSet.has(id); + if (vitestConfig?.coverage?.enabled && !isSetupFile) { // To support coverage exclusion of the actual test file, the virtual // test entry point only references the built and bundled intermediate file. // If vitest supported an "excludeOnlyAfterRemap" option, this could be removed completely. diff --git a/packages/angular/build/src/builders/unit-test/tests/options/setup-files_spec.ts b/packages/angular/build/src/builders/unit-test/tests/options/setup-files_spec.ts index 65d0dadf17b8..44241bbcfd8a 100644 --- a/packages/angular/build/src/builders/unit-test/tests/options/setup-files_spec.ts +++ b/packages/angular/build/src/builders/unit-test/tests/options/setup-files_spec.ts @@ -54,5 +54,68 @@ describeBuilder(execute, UNIT_TEST_BUILDER_INFO, (harness) => { const { result } = await harness.executeOnce(); expect(result?.success).toBeTrue(); }); + + it('should run setup file hooks for each spec file when coverage is enabled', async () => { + await harness.writeFiles({ + 'custom-vitest.config.mts': ` + import { defineConfig } from 'vitest/config'; + + export default defineConfig({ + test: { + fileParallelism: false, + }, + }); + `, + 'src/setup.ts': ` + import { afterEach, beforeEach, expect } from 'vitest'; + const global = globalThis as typeof globalThis & { + setupHookCalls?: string[]; + }; + const setupHookCalls = (global.setupHookCalls ??= []); + beforeEach(() => { + const testName = expect.getState().currentTestName ?? ''; + setupHookCalls.push('beforeEach:' + testName); + }); + afterEach(() => { + const testName = expect.getState().currentTestName ?? ''; + setupHookCalls.push('afterEach:' + testName); + }); + `, + 'src/app/app.component.spec.ts': ` + import { expect, it } from 'vitest'; + it('runs setup hooks for first test in app.component.spec', () => { + const global = globalThis as typeof globalThis & { setupHookCalls?: string[] }; + expect(global.setupHookCalls).toContain('beforeEach:runs setup hooks for first test in app.component.spec'); + }); + it('runs setup hooks for second test in app.component.spec', () => { + const global = globalThis as typeof globalThis & { setupHookCalls?: string[] }; + expect(global.setupHookCalls).toContain('beforeEach:runs setup hooks for second test in app.component.spec'); + expect(global.setupHookCalls).toContain('afterEach:runs setup hooks for first test in app.component.spec'); + }); + `, + 'src/app/second.spec.ts': ` + import { expect, it } from 'vitest'; + it('runs setup hooks for first test in second.spec', () => { + const global = globalThis as typeof globalThis & { setupHookCalls?: string[] }; + expect(global.setupHookCalls).toContain('beforeEach:runs setup hooks for first test in second.spec'); + }); + it('runs setup hooks for second test in second.spec', () => { + const global = globalThis as typeof globalThis & { setupHookCalls?: string[] }; + expect(global.setupHookCalls).toContain('beforeEach:runs setup hooks for second test in second.spec'); + expect(global.setupHookCalls).toContain('afterEach:runs setup hooks for first test in second.spec'); + }); + `, + }); + + harness.useTarget('test', { + ...BASE_OPTIONS, + coverage: true, + runnerConfig: 'custom-vitest.config.mts', + setupFiles: ['src/setup.ts'], + }); + + const { result } = await harness.executeOnce(); + expect(result?.success).toBeTrue(); + }); }); }); From f47f77f5f6db5cda1493652f813c98c26f172ea9 Mon Sep 17 00:00:00 2001 From: Alan Agius <17563226+alan-agius4@users.noreply.github.com> Date: Tue, 22 Sep 2026 14:43:38 +0000 Subject: [PATCH 018/233] fix(@angular/build): only compile included test files in unit-test builder When running the `unit-test` builder with `--include`, TypeScript compilation previously compiled all test files matched by the tsconfig file, causing compilation errors in unrelated test files to fail the test run. This change introduces a `rootFiles` option that restricts the TypeScript program's root files to only the test files to be executed (plus setup files and providers), while preserving ambient `.d.ts` declaration files discovered by `readConfiguration`. Fixes #34089 (cherry picked from commit 5e0537350725027d0eeb2f09c4823acb870a589b) --- .../build/src/builders/application/options.ts | 7 +++++ .../unit-test/runners/vitest/build-options.ts | 22 ++++++++++++--- .../unit-test/tests/options/include_spec.ts | 27 +++++++++++++++++++ .../angular/compilation/compiler-options.ts | 1 + .../compilation/typescript-compilation.ts | 17 ++++++++++-- .../tools/esbuild/angular/compiler-plugin.ts | 5 ++++ .../tools/esbuild/compiler-plugin-options.ts | 2 ++ 7 files changed, 76 insertions(+), 5 deletions(-) diff --git a/packages/angular/build/src/builders/application/options.ts b/packages/angular/build/src/builders/application/options.ts index 785d07371d93..f7e60f4cc029 100644 --- a/packages/angular/build/src/builders/application/options.ts +++ b/packages/angular/build/src/builders/application/options.ts @@ -138,6 +138,11 @@ interface InternalOptions { * there. Used exclusively for tests and shouldn't be used for other kinds of builds. */ disableCodeSplitting?: boolean; + + /** + * An array of files to restrict the TypeScript compilation root names to. + */ + rootFiles?: string[]; } /** Full set of options for `application` builder. */ @@ -447,6 +452,7 @@ export async function normalizeOptions( verbose, watch, progress = true, + rootFiles, externalPackages, namedChunks, budgets, @@ -494,6 +500,7 @@ export async function normalizeOptions( workspaceRoot, entryPoints, disableCodeSplitting, + rootFiles: rootFiles?.map((file: string) => path.resolve(workspaceRoot, file)), optimizationOptions, outputOptions, outExtension, diff --git a/packages/angular/build/src/builders/unit-test/runners/vitest/build-options.ts b/packages/angular/build/src/builders/unit-test/runners/vitest/build-options.ts index 9c5abb9386bf..622ca7beebd3 100644 --- a/packages/angular/build/src/builders/unit-test/runners/vitest/build-options.ts +++ b/packages/angular/build/src/builders/unit-test/runners/vitest/build-options.ts @@ -198,7 +198,15 @@ export async function getVitestBuildOptions( options: NormalizedUnitTestBuilderOptions, baseBuildOptions: Partial, ): Promise { - const { workspaceRoot, projectSourceRoot, include, exclude = [], watch, providersFile } = options; + const { + workspaceRoot, + projectSourceRoot, + include, + exclude = [], + watch, + providersFile, + setupFiles, + } = options; // Find test files const testFiles = await findTests(include, exclude, workspaceRoot, projectSourceRoot); @@ -217,8 +225,15 @@ export async function getVitestBuildOptions( removeTestExtension: true, }); - if (options.setupFiles?.length) { - const setupEntryPoints = getTestEntrypoints(options.setupFiles, { + const rootFiles = [...testFiles]; + if (providersFile) { + rootFiles.push(providersFile); + } + + if (setupFiles?.length) { + rootFiles.push(...setupFiles); + + const setupEntryPoints = getTestEntrypoints(setupFiles, { projectSourceRoot, workspaceRoot, removeTestExtension: false, @@ -258,6 +273,7 @@ export async function getVitestBuildOptions( optimization: false, namedChunks: false, entryPoints, + rootFiles, // Vitest's Node-based module loading emulation (vite-node) is not fully spec compliant and lacks // live ESM bindings across chunk boundaries. This can cause uninitialized exports or break mocking. // Disabling code splitting avoids shared chunks, but increases build and coverage memory/time. diff --git a/packages/angular/build/src/builders/unit-test/tests/options/include_spec.ts b/packages/angular/build/src/builders/unit-test/tests/options/include_spec.ts index f1cdd4a14f0b..d3d4e19a30f9 100644 --- a/packages/angular/build/src/builders/unit-test/tests/options/include_spec.ts +++ b/packages/angular/build/src/builders/unit-test/tests/options/include_spec.ts @@ -83,5 +83,32 @@ describeBuilder(execute, UNIT_TEST_BUILDER_INFO, (harness) => { expect(result?.success).toBeTrue(); }); }); + + it('should ignore TypeScript compilation errors in non-included test files', async () => { + await harness.writeFiles({ + 'src/app/services/test.service.spec.ts': ` + describe('TestService', () => { + it('should succeed', () => { + expect(true).toBe(true); + }); + });`, + 'src/app/broken.service.spec.ts': ` + // This test has a TypeScript type error that would fail compilation if compiled + const invalidNumber: number = 'not a number'; + describe('BrokenService', () => { + it('should fail compilation', () => { + expect(invalidNumber).toBe(1); + }); + });`, + }); + + harness.useTarget('test', { + ...BASE_OPTIONS, + include: ['src/app/services/test.service.spec.ts'], + }); + + const { result } = await harness.executeOnce(); + expect(result?.success).toBeTrue(); + }); }); }); diff --git a/packages/angular/build/src/tools/angular/compilation/compiler-options.ts b/packages/angular/build/src/tools/angular/compilation/compiler-options.ts index bb8c494f2213..45af80eae6d3 100644 --- a/packages/angular/build/src/tools/angular/compilation/compiler-options.ts +++ b/packages/angular/build/src/tools/angular/compilation/compiler-options.ts @@ -20,6 +20,7 @@ export interface CompilerOptionOverrides { instrumentForCoverage?: boolean; includeTestMetadata?: boolean; customConditions?: string[]; + rootFiles?: string[]; } export function transformCompilerOptions( diff --git a/packages/angular/build/src/tools/angular/compilation/typescript-compilation.ts b/packages/angular/build/src/tools/angular/compilation/typescript-compilation.ts index 05403b728fda..48975b672154 100644 --- a/packages/angular/build/src/tools/angular/compilation/typescript-compilation.ts +++ b/packages/angular/build/src/tools/angular/compilation/typescript-compilation.ts @@ -9,7 +9,7 @@ import type * as ng from '@angular/compiler-cli'; import type { PartialMessage } from 'esbuild'; import ts from 'typescript'; -import { toPosixPath } from '../../../utils/path'; +import { canonicalizePath, toPosixPath } from '../../../utils/path'; import { profileAsync, profileSync } from '../../../utils/profiling'; import { AngularCompilation, DiagnosticModes } from './angular-compilation'; import { type CompilerOptionOverrides, transformCompilerOptions } from './compiler-options'; @@ -39,7 +39,7 @@ export abstract class TypeScriptCompilation extends AngularCompilation { const { options: originalCompilerOptions, - rootNames, + rootNames: originalRootNames, errors, } = profileSync('NG_READ_CONFIG', () => readConfiguration(tsconfig, { @@ -60,6 +60,19 @@ export abstract class TypeScriptCompilation extends AngularCompilation { }), ); + let rootNames = originalRootNames; + if (compilerOptionOverrides?.rootFiles?.length) { + const rootFilesSet = new Set( + compilerOptionOverrides.rootFiles.map((file) => canonicalizePath(toPosixPath(file))), + ); + for (const file of originalRootNames) { + if (/\.d\.[cm]?ts$/i.test(file)) { + rootFilesSet.add(canonicalizePath(toPosixPath(file))); + } + } + rootNames = [...rootFilesSet]; + } + const { compilerOptions, warnings } = transformCompilerOptions( ts, originalCompilerOptions, diff --git a/packages/angular/build/src/tools/esbuild/angular/compiler-plugin.ts b/packages/angular/build/src/tools/esbuild/angular/compiler-plugin.ts index a9c71e8db888..9a36eea56d61 100644 --- a/packages/angular/build/src/tools/esbuild/angular/compiler-plugin.ts +++ b/packages/angular/build/src/tools/esbuild/angular/compiler-plugin.ts @@ -61,6 +61,7 @@ export interface CompilerPluginOptions { externalRuntimeStyles?: boolean; instrumentForCoverage?: (request: string) => boolean; templateUpdates?: Map; + rootFiles?: string[]; } // eslint-disable-next-line max-lines-per-function @@ -329,17 +330,21 @@ export function createCompilerPlugin( instrumentForCoverage: !!pluginOptions.instrumentForCoverage, includeTestMetadata: !!pluginOptions.includeTestMetadata, customConditions: build.initialOptions.conditions, + rootFiles: pluginOptions.rootFiles, }, ); + if (initializationResult.warnings?.length) { setupWarnings?.push(...initializationResult.warnings); } + angularCompilationContext.setCompilerOptions(initializationResult.compilerOptions); shouldTsIgnoreJs = !initializationResult.compilerOptions.allowJs; useTypeScriptTranspilation = !!initializationResult.compilerOptions['_useTypeScriptTranspilation']; referencedFiles = initializationResult.referencedFiles; externalStylesheets = initializationResult.externalStylesheets; + if (initializationResult.templateUpdates) { // Propagate any template updates initializationResult.templateUpdates.forEach((value, key) => diff --git a/packages/angular/build/src/tools/esbuild/compiler-plugin-options.ts b/packages/angular/build/src/tools/esbuild/compiler-plugin-options.ts index 04ce3ef94f4a..573b8616da60 100644 --- a/packages/angular/build/src/tools/esbuild/compiler-plugin-options.ts +++ b/packages/angular/build/src/tools/esbuild/compiler-plugin-options.ts @@ -28,6 +28,7 @@ export function createCompilerPluginOptions( externalRuntimeStyles, instrumentForCoverage, optimizationOptions, + rootFiles, } = options; const incremental = !!options.watch; @@ -45,5 +46,6 @@ export function createCompilerPluginOptions( instrumentForCoverage, templateUpdates, includeTestMetadata: !optimizationOptions.scripts, + rootFiles, }; } From 040bc21ec3d4fa1bdfa8513206f463d89e20d9a1 Mon Sep 17 00:00:00 2001 From: rk Date: Fri, 18 Sep 2026 15:39:58 +0500 Subject: [PATCH 019/233] fix(@angular/build): scope Sass package resolution caching for stylesheets in node_modules Package specifiers were cached without any qualification, so the resolution made for one stylesheet was reused for every other stylesheet in the build. A dependency within `node_modules` that has its own nested version of a package received the version resolved for the application, the application received the nested version when the dependency was compiled first, and a failed resolution was reused for a dependency that is able to resolve the package. Which of these occurred depended on the order the stylesheets were compiled in. Package resolutions and package roots are now qualified with a scope. A stylesheet within `node_modules` uses the root of its enclosing package as the scope, so every file of a package shares one resolution while nested dependency versions stay isolated. All other stylesheets use the working directory of the build, so the component stylesheets of an application continue to share a single resolution. The scope is derived from the path of the stylesheet alone and requires no file system access. A containing URL that does not use the `file:` scheme is resolved from the working directory instead of causing an error. (cherry picked from commit ed52db253ffb98ad7b591fbb53ed5e1d54850828) --- .../esbuild/stylesheets/sass-language.ts | 62 ++++- .../esbuild/stylesheets/sass-language_spec.ts | 243 +++++++++++++++++- 2 files changed, 290 insertions(+), 15 deletions(-) diff --git a/packages/angular/build/src/tools/esbuild/stylesheets/sass-language.ts b/packages/angular/build/src/tools/esbuild/stylesheets/sass-language.ts index b519a408bfb8..432ae7ba79b8 100644 --- a/packages/angular/build/src/tools/esbuild/stylesheets/sass-language.ts +++ b/packages/angular/build/src/tools/esbuild/stylesheets/sass-language.ts @@ -9,7 +9,7 @@ import type { OnLoadResult, PartialMessage, PartialNote, ResolveResult } from 'esbuild'; import { dirname, join } from 'node:path'; import { fileURLToPath, pathToFileURL } from 'node:url'; -import type { CanonicalizeContext, CompileResult, Exception, Syntax } from 'sass-embedded'; +import type { CompileResult, Exception, Syntax } from 'sass-embedded'; import { MemoryCache } from '../../../utils/cache'; import type { SassCompiler } from '../../sass/sass-service'; import { StylesheetLanguage, StylesheetPluginOptions } from './stylesheet-plugin-factory'; @@ -50,12 +50,7 @@ export const SassStylesheetLanguage = Object.freeze({ fileFilter: /\.s[ac]ss$/, process(data, file, format, options, build) { const syntax = format === 'sass' ? 'indented' : 'scss'; - const resolveUrl = async (url: string, options: CanonicalizeContext) => { - let resolveDir = build.initialOptions.absWorkingDir; - if (options.containingUrl) { - resolveDir = dirname(fileURLToPath(options.containingUrl)); - } - + const resolveUrl = async (url: string, resolveDir: string | undefined) => { const path = url.startsWith('pkg:') ? url.slice(4) : url; const result = await build.resolve(path, { kind: 'import-rule', @@ -65,7 +60,14 @@ export const SassStylesheetLanguage = Object.freeze({ return result; }; - return compileString(data, file, syntax, options, resolveUrl); + return compileString( + data, + file, + syntax, + options, + resolveUrl, + build.initialOptions.absWorkingDir, + ); }, }); @@ -97,12 +99,35 @@ function parsePackageName(url: string): { packageName: string; readonly pathSegm }; } +/** + * Returns the scope that qualifies the cached package resolutions of a stylesheet. A stylesheet + * within `node_modules` uses the root of its enclosing package, since every file of a package + * resolves its dependencies against the same `node_modules` directories. All other stylesheets use + * the working directory, allowing component stylesheets to share package resolutions. + */ +export function getPackageScope( + containingPath: string | undefined, + workingDirectory: string | undefined, +): string { + // The directory segments of the stylesheet, excluding the file name + const segments = containingPath?.split(/[\\/]/).slice(0, -1) ?? []; + const index = segments.lastIndexOf('node_modules'); + if (index === -1) { + return workingDirectory ?? ''; + } + + const packageNameLength = segments[index + 1]?.[0] === '@' ? 2 : 1; + + return segments.slice(0, index + 1 + packageNameLength).join('/'); +} + async function compileString( data: string, filePath: string, syntax: Syntax, options: StylesheetPluginOptions, - resolveUrl: (url: string, options: CanonicalizeContext) => Promise, + resolveUrl: (url: string, resolveDir: string | undefined) => Promise, + workingDirectory: string | undefined, ): Promise { // Lazily load Sass when a Sass file is found if (sassService === undefined) { @@ -119,7 +144,8 @@ async function compileString( } // Caching follows Sass behavior where a given package url will always resolve to the same value - // regardless of its importer's path. Relative paths are qualified with the containing URL. + // regardless of its importer's path, except for importers within `node_modules`, which are + // scoped to their enclosing package. Relative paths are qualified with the containing URL. // A null value indicates that the cached resolution attempt failed to find a location and // later stage resolution should be attempted. This avoids potentially expensive repeat // failing resolution attempts. @@ -145,11 +171,19 @@ async function compileString( importers: [ { findFileUrl: (url, options) => { + const containingPath = + options.containingUrl?.protocol === 'file:' + ? fileURLToPath(options.containingUrl) + : undefined; + const resolveDir = containingPath ? dirname(containingPath) : workingDirectory; const isPackage = isPackageUrl(url); - const cacheKey = isPackage ? url : `${options.containingUrl?.href ?? ''}:${url}`; + const scope = getPackageScope(containingPath, workingDirectory); + const cacheKey = isPackage + ? `${scope}:${url}` + : `${options.containingUrl?.href ?? ''}:${url}`; return currentResolutionCache.getOrCreate(cacheKey, async () => { - const result = await resolveUrl(url, options); + const result = await resolveUrl(url, resolveDir); if (result.path) { return pathToFileURL(result.path); } @@ -164,10 +198,10 @@ async function compileString( // Caching package root locations is particularly beneficial for `@material/*` packages // which extensively use deep imports. const packageRoot = await currentPackageRootCache.getOrCreate( - packageName, + `${scope}:${packageName}`, async () => { // Use the required presence of a package root `package.json` file to resolve the location - const packageResult = await resolveUrl(packageName + '/package.json', options); + const packageResult = await resolveUrl(packageName + '/package.json', resolveDir); return packageResult.path ? dirname(packageResult.path) : null; }, diff --git a/packages/angular/build/src/tools/esbuild/stylesheets/sass-language_spec.ts b/packages/angular/build/src/tools/esbuild/stylesheets/sass-language_spec.ts index 7be104741caa..cdd4d7e7c8db 100644 --- a/packages/angular/build/src/tools/esbuild/stylesheets/sass-language_spec.ts +++ b/packages/angular/build/src/tools/esbuild/stylesheets/sass-language_spec.ts @@ -6,7 +6,20 @@ * found in the LICENSE file at https://angular.dev/license */ -import { isPackageUrl } from './sass-language'; +import type { PluginBuild } from 'esbuild'; +import assert from 'node:assert'; +import { statSync } from 'node:fs'; +import { mkdir, mkdtemp, rm, writeFile } from 'node:fs/promises'; +import { dirname, join } from 'node:path'; +import { pathToFileURL } from 'node:url'; +import { SassCompiler } from '../../sass/sass-service'; +import { + SassStylesheetLanguage, + getPackageScope, + isPackageUrl, + resetSassWorkerPoolCaches, + shutdownSassWorkerPool, +} from './sass-language'; describe('sass-language', () => { describe('isPackageUrl', () => { @@ -46,4 +59,232 @@ describe('sass-language', () => { expect(isPackageUrl('')).toBeFalse(); }); }); + + describe('getPackageScope', () => { + const scope = (containingPath?: string) => getPackageScope(containingPath, '/app'); + + it('should use the working directory for a stylesheet outside node_modules', () => { + expect(scope('/app/src/app.scss')).toBe('/app'); + expect(scope('/app/src/foo-node_modules/a.scss')).toBe('/app'); + expect(scope('/app/src/node_modules.scss')).toBe('/app'); + expect(scope(undefined)).toBe('/app'); + }); + + it('should use the enclosing package root for a stylesheet within node_modules', () => { + expect(scope('/app/node_modules/pkg/a.scss')).toBe('/app/node_modules/pkg'); + expect(scope('/app/node_modules/pkg/sub/a.scss')).toBe('/app/node_modules/pkg'); + expect(scope('/app/node_modules/@scope/pkg/sub/a.scss')).toBe('/app/node_modules/@scope/pkg'); + expect(scope('/app/node_modules/foo-node_modules/a.scss')).toBe( + '/app/node_modules/foo-node_modules', + ); + expect(scope('/app/node_modules/a.scss')).toBe('/app/node_modules'); + }); + + it('should use the innermost package root for a nested dependency', () => { + expect(scope('/app/node_modules/dep/node_modules/pkg/a.scss')).toBe( + '/app/node_modules/dep/node_modules/pkg', + ); + expect(scope('/app/node_modules/.pnpm/pkg@1.0.0/node_modules/pkg/a.scss')).toBe( + '/app/node_modules/.pnpm/pkg@1.0.0/node_modules/pkg', + ); + }); + + it('should support Windows path separators', () => { + expect(getPackageScope('C:\\app\\node_modules\\pkg\\sub\\a.scss', 'C:\\app')).toBe( + 'C:/app/node_modules/pkg', + ); + expect(getPackageScope('C:\\app\\src\\app.scss', 'C:\\app')).toBe('C:\\app'); + }); + }); + + describe('package resolution caching', () => { + let temporaryRoot: string; + let projectRoot: string; + let buttonStylesheet: string; + let cardStylesheet: string; + let dependencyStylesheet: string; + let resolveRequests: string[]; + + /** + * Creates a build stub that resolves a package specifier by searching the `node_modules` + * directories visible from the resolve directory, which is how esbuild resolves the + * package specifiers of a stylesheet. + */ + function createBuildStub(): PluginBuild { + return { + initialOptions: { absWorkingDir: projectRoot }, + resolve: async (path: string, options: { resolveDir: string }) => { + resolveRequests.push(`${options.resolveDir}:${path}`); + + for (let directory = options.resolveDir; ; directory = dirname(directory)) { + // A package specifier resolves to the index file of the package, and an explicit file + // within it to that file. A deeper subpath is left unresolved, as esbuild leaves one + // that the `exports` of the package does not name; the Sass importer then resolves it + // against the package root instead. + for (const candidate of [ + join(directory, 'node_modules', path, '_index.scss'), + join(directory, 'node_modules', path), + ]) { + if (statSync(candidate, { throwIfNoEntry: false })?.isFile()) { + return { path: candidate, errors: [], warnings: [] }; + } + } + + if (dirname(directory) === directory) { + return { path: undefined, errors: [], warnings: [] }; + } + } + }, + } as unknown as PluginBuild; + } + + async function compile(stylesheet: string, source = "@use 'theme';"): Promise { + const result = await SassStylesheetLanguage.process?.( + source, + stylesheet, + 'scss', + { sourcemap: false }, + createBuildStub(), + ); + if (!result) { + throw new Error('The Sass stylesheet language has no process function.'); + } + + if (result.errors?.length) { + return `error: ${result.errors[0].text}`; + } + + return (result.contents as string).trim(); + } + + async function writePackage(directory: string, marker: string): Promise { + await mkdir(join(directory, 'sub'), { recursive: true }); + await writeFile(join(directory, 'package.json'), '{}'); + await writeFile(join(directory, '_index.scss'), `.marker { content: "${marker}"; }`); + await writeFile( + join(directory, 'sub', '_other.scss'), + `.deep { content: "${marker} deep"; }`, + ); + } + + beforeAll(async () => { + const baseTmpDir = process.env['TEST_TMPDIR']; + assert(baseTmpDir, 'TEST_TMPDIR is not set'); + temporaryRoot = await mkdtemp(join(baseTmpDir, 'angular-cli-sass-language-')); + projectRoot = join(temporaryRoot, 'project'); + const dependencyRoot = join(projectRoot, 'node_modules', 'dependency'); + + // An application using a `theme` package, and a dependency with its own nested version of + // `theme` plus an `extra` package that only the dependency can see. + await writePackage(join(projectRoot, 'node_modules', 'theme'), 'project'); + await writePackage(join(dependencyRoot, 'node_modules', 'theme'), 'dependency'); + await writePackage(join(dependencyRoot, 'node_modules', 'extra'), 'extra'); + + buttonStylesheet = join(projectRoot, 'src', 'app', 'button', 'button.scss'); + cardStylesheet = join(projectRoot, 'src', 'app', 'card', 'card.scss'); + dependencyStylesheet = join(dependencyRoot, 'styles.scss'); + for (const stylesheet of [buttonStylesheet, cardStylesheet]) { + await mkdir(dirname(stylesheet), { recursive: true }); + } + }); + + afterAll(async () => { + shutdownSassWorkerPool(); + await rm(temporaryRoot, { force: true, recursive: true }); + }); + + beforeEach(() => { + resetSassWorkerPoolCaches(); + resolveRequests = []; + }); + + it('should not use the package resolution of a dependency for the application', async () => { + const dependency = await compile(dependencyStylesheet); + const application = await compile(buttonStylesheet); + + expect(dependency).toContain('content: "dependency";'); + expect(application).toContain('content: "project";'); + }); + + it('should not use the package resolution of the application for a dependency', async () => { + const application = await compile(buttonStylesheet); + const dependency = await compile(dependencyStylesheet); + + expect(application).toContain('content: "project";'); + expect(dependency).toContain('content: "dependency";'); + }); + + it('should not reuse a failed package resolution of the application for a dependency', async () => { + const source = "@use 'extra';"; + const application = await compile(buttonStylesheet, source); + const dependency = await compile(dependencyStylesheet, source); + + expect(application).toContain("Can't find stylesheet to import."); + expect(dependency).toContain('content: "extra";'); + }); + + it('should not use the package root of a dependency for a deep import of the application', async () => { + // A subpath that resolves to no file of its own is located through the root of the package, + // which is cached separately from the resolution of the specifier. + const source = "@use 'theme/sub/other';"; + const dependency = await compile(dependencyStylesheet, source); + const application = await compile(buttonStylesheet, source); + + expect(dependency).toContain('content: "dependency deep";'); + expect(application).toContain('content: "project deep";'); + }); + + it('should share a package resolution between the stylesheets of different components', async () => { + const button = await compile(buttonStylesheet); + const card = await compile(cardStylesheet); + + expect(button).toContain('content: "project";'); + expect(card).toContain('content: "project";'); + expect(resolveRequests.length).toBe(1); + }); + + it('should share a package resolution between the stylesheets of different folders of a dependency', async () => { + const dependencyRoot = join(projectRoot, 'node_modules', 'dependency'); + const first = await compile(join(dependencyRoot, 'sub1', 'styles.scss')); + const second = await compile(join(dependencyRoot, 'sub2', 'styles.scss')); + + expect(first).toContain('content: "dependency";'); + expect(second).toContain('content: "dependency";'); + expect(resolveRequests.length).toBe(1); + }); + + it('should share a package resolution between the stylesheets of different folders of a scoped package', async () => { + const packageRoot = join(projectRoot, 'node_modules', '@scope', 'pkg'); + const first = await compile(join(packageRoot, 'sub1', 'styles.scss')); + const second = await compile(join(packageRoot, 'sub2', 'styles.scss')); + + expect(first).toContain('content: "project";'); + expect(second).toContain('content: "project";'); + expect(resolveRequests.length).toBe(1); + }); + + it('should resolve a package url of a non-file containing URL from the working directory', async () => { + // The stylesheets of a build have file URLs, but Sass does not limit a containing URL to them. + spyOn(SassCompiler.prototype, 'compileStringAsync').and.callFake(async (_, options) => { + const importer = options.importers?.[0] as { + findFileUrl( + url: string, + context: { containingUrl: URL; fromImport: boolean }, + ): Promise; + }; + const url = await importer.findFileUrl('theme', { + containingUrl: new URL('custom:styles.scss'), + fromImport: false, + }); + + return { css: url?.href ?? '', loadedUrls: [] }; + }); + + const result = await compile(buttonStylesheet); + + expect(result).toBe( + pathToFileURL(join(projectRoot, 'node_modules', 'theme', '_index.scss')).href, + ); + }); + }); }); From bd0dd487133a961a96099886d0e322c4c2850f1d Mon Sep 17 00:00:00 2001 From: Angular Robot Date: Tue, 22 Sep 2026 14:55:17 +0000 Subject: [PATCH 020/233] build: update cross-repo angular dependencies See associated pull request for more information. --- .../assistant-to-the-branch-manager.yml | 2 +- .github/workflows/ci.yml | 52 +-- .github/workflows/dev-infra.yml | 6 +- .github/workflows/perf.yml | 6 +- .github/workflows/pr.yml | 44 +- MODULE.bazel | 6 +- package.json | 2 +- pnpm-lock.yaml | 439 ++++++++---------- 8 files changed, 264 insertions(+), 293 deletions(-) diff --git a/.github/workflows/assistant-to-the-branch-manager.yml b/.github/workflows/assistant-to-the-branch-manager.yml index 1fcd15f0c5b9..d96db1e3d645 100644 --- a/.github/workflows/assistant-to-the-branch-manager.yml +++ b/.github/workflows/assistant-to-the-branch-manager.yml @@ -18,6 +18,6 @@ jobs: - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: persist-credentials: false - - uses: angular/dev-infra/github-actions/branch-manager@99d57027286c71dda92d8b91a3607abcf92d8bbd # main + - uses: angular/dev-infra/github-actions/branch-manager@bf1d18837b5aaed70cf858ecd177583bf320be50 # main with: angular-robot-key: ${{ secrets.ANGULAR_ROBOT_PRIVATE_KEY }} diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index cee6fbdfbda5..5bc5ede289ce 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -21,9 +21,9 @@ jobs: runs-on: ubuntu-latest steps: - name: Initialize environment - uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@99d57027286c71dda92d8b91a3607abcf92d8bbd # main + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@bf1d18837b5aaed70cf858ecd177583bf320be50 # main - name: Setup Bazel - uses: angular/dev-infra/github-actions/bazel/setup@99d57027286c71dda92d8b91a3607abcf92d8bbd # main + uses: angular/dev-infra/github-actions/bazel/setup@bf1d18837b5aaed70cf858ecd177583bf320be50 # main - name: Install node modules run: pnpm install --frozen-lockfile - name: Generate JSON schema types @@ -44,11 +44,11 @@ jobs: runs-on: ubuntu-latest steps: - name: Initialize environment - uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@99d57027286c71dda92d8b91a3607abcf92d8bbd # main + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@bf1d18837b5aaed70cf858ecd177583bf320be50 # main - name: Setup Bazel - uses: angular/dev-infra/github-actions/bazel/setup@99d57027286c71dda92d8b91a3607abcf92d8bbd # main + uses: angular/dev-infra/github-actions/bazel/setup@bf1d18837b5aaed70cf858ecd177583bf320be50 # main - name: Setup Bazel RBE - uses: angular/dev-infra/github-actions/bazel/configure-remote@99d57027286c71dda92d8b91a3607abcf92d8bbd # main + uses: angular/dev-infra/github-actions/bazel/configure-remote@bf1d18837b5aaed70cf858ecd177583bf320be50 # main with: google_credential: ${{ secrets.RBE_TRUSTED_BUILDS_USER }} - name: Install node modules @@ -61,11 +61,11 @@ jobs: runs-on: ubuntu-latest steps: - name: Initialize environment - uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@99d57027286c71dda92d8b91a3607abcf92d8bbd # main + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@bf1d18837b5aaed70cf858ecd177583bf320be50 # main - name: Setup Bazel - uses: angular/dev-infra/github-actions/bazel/setup@99d57027286c71dda92d8b91a3607abcf92d8bbd # main + uses: angular/dev-infra/github-actions/bazel/setup@bf1d18837b5aaed70cf858ecd177583bf320be50 # main - name: Setup Bazel RBE - uses: angular/dev-infra/github-actions/bazel/configure-remote@99d57027286c71dda92d8b91a3607abcf92d8bbd # main + uses: angular/dev-infra/github-actions/bazel/configure-remote@bf1d18837b5aaed70cf858ecd177583bf320be50 # main with: google_credential: ${{ secrets.RBE_TRUSTED_BUILDS_USER }} - name: Install node modules @@ -84,13 +84,13 @@ jobs: runs-on: ubuntu-latest steps: - name: Initialize environment - uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@99d57027286c71dda92d8b91a3607abcf92d8bbd # main + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@bf1d18837b5aaed70cf858ecd177583bf320be50 # main - name: Install node modules run: pnpm install --frozen-lockfile - name: Setup Bazel - uses: angular/dev-infra/github-actions/bazel/setup@99d57027286c71dda92d8b91a3607abcf92d8bbd # main + uses: angular/dev-infra/github-actions/bazel/setup@bf1d18837b5aaed70cf858ecd177583bf320be50 # main - name: Setup Bazel RBE - uses: angular/dev-infra/github-actions/bazel/configure-remote@99d57027286c71dda92d8b91a3607abcf92d8bbd # main + uses: angular/dev-infra/github-actions/bazel/configure-remote@bf1d18837b5aaed70cf858ecd177583bf320be50 # main with: google_credential: ${{ secrets.RBE_TRUSTED_BUILDS_USER }} - name: Run CLI E2E tests @@ -100,11 +100,11 @@ jobs: runs-on: ubuntu-latest steps: - name: Initialize environment - uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@99d57027286c71dda92d8b91a3607abcf92d8bbd # main + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@bf1d18837b5aaed70cf858ecd177583bf320be50 # main - name: Setup Bazel - uses: angular/dev-infra/github-actions/bazel/setup@99d57027286c71dda92d8b91a3607abcf92d8bbd # main + uses: angular/dev-infra/github-actions/bazel/setup@bf1d18837b5aaed70cf858ecd177583bf320be50 # main - name: Setup Bazel RBE - uses: angular/dev-infra/github-actions/bazel/configure-remote@99d57027286c71dda92d8b91a3607abcf92d8bbd # main + uses: angular/dev-infra/github-actions/bazel/configure-remote@bf1d18837b5aaed70cf858ecd177583bf320be50 # main with: google_credential: ${{ secrets.RBE_TRUSTED_BUILDS_USER }} - name: Install node modules @@ -137,7 +137,7 @@ jobs: runs-on: windows-2025 steps: - name: Initialize environment - uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@99d57027286c71dda92d8b91a3607abcf92d8bbd # main + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@bf1d18837b5aaed70cf858ecd177583bf320be50 # main - name: Install node modules run: pnpm install --frozen-lockfile - name: Download built Windows E2E tests @@ -164,13 +164,13 @@ jobs: runs-on: ubuntu-latest steps: - name: Initialize environment - uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@99d57027286c71dda92d8b91a3607abcf92d8bbd # main + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@bf1d18837b5aaed70cf858ecd177583bf320be50 # main - name: Install node modules run: pnpm install --frozen-lockfile - name: Setup Bazel - uses: angular/dev-infra/github-actions/bazel/setup@99d57027286c71dda92d8b91a3607abcf92d8bbd # main + uses: angular/dev-infra/github-actions/bazel/setup@bf1d18837b5aaed70cf858ecd177583bf320be50 # main - name: Setup Bazel RBE - uses: angular/dev-infra/github-actions/bazel/configure-remote@99d57027286c71dda92d8b91a3607abcf92d8bbd # main + uses: angular/dev-infra/github-actions/bazel/configure-remote@bf1d18837b5aaed70cf858ecd177583bf320be50 # main with: google_credential: ${{ secrets.RBE_TRUSTED_BUILDS_USER }} - name: Run CLI E2E tests @@ -188,13 +188,13 @@ jobs: runs-on: ubuntu-latest steps: - name: Initialize environment - uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@99d57027286c71dda92d8b91a3607abcf92d8bbd # main + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@bf1d18837b5aaed70cf858ecd177583bf320be50 # main - name: Install node modules run: pnpm install --frozen-lockfile - name: Setup Bazel - uses: angular/dev-infra/github-actions/bazel/setup@99d57027286c71dda92d8b91a3607abcf92d8bbd # main + uses: angular/dev-infra/github-actions/bazel/setup@bf1d18837b5aaed70cf858ecd177583bf320be50 # main - name: Setup Bazel RBE - uses: angular/dev-infra/github-actions/bazel/configure-remote@99d57027286c71dda92d8b91a3607abcf92d8bbd # main + uses: angular/dev-infra/github-actions/bazel/configure-remote@bf1d18837b5aaed70cf858ecd177583bf320be50 # main with: google_credential: ${{ secrets.RBE_TRUSTED_BUILDS_USER }} - name: Run CLI E2E tests @@ -208,13 +208,13 @@ jobs: SAUCE_TUNNEL_IDENTIFIER: angular-cli-${{ github.workflow }}-${{ github.run_number }} steps: - name: Initialize environment - uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@99d57027286c71dda92d8b91a3607abcf92d8bbd # main + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@bf1d18837b5aaed70cf858ecd177583bf320be50 # main - name: Install node modules run: pnpm install --frozen-lockfile - name: Setup Bazel - uses: angular/dev-infra/github-actions/bazel/setup@99d57027286c71dda92d8b91a3607abcf92d8bbd # main + uses: angular/dev-infra/github-actions/bazel/setup@bf1d18837b5aaed70cf858ecd177583bf320be50 # main - name: Setup Bazel RBE - uses: angular/dev-infra/github-actions/bazel/configure-remote@99d57027286c71dda92d8b91a3607abcf92d8bbd # main + uses: angular/dev-infra/github-actions/bazel/configure-remote@bf1d18837b5aaed70cf858ecd177583bf320be50 # main with: google_credential: ${{ secrets.RBE_TRUSTED_BUILDS_USER }} - name: Start Sauce Connect @@ -245,11 +245,11 @@ jobs: CIRCLE_BRANCH: ${{ github.ref_name }} steps: - name: Initialize environment - uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@99d57027286c71dda92d8b91a3607abcf92d8bbd # main + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@bf1d18837b5aaed70cf858ecd177583bf320be50 # main - name: Install node modules run: pnpm install --frozen-lockfile - name: Setup Bazel - uses: angular/dev-infra/github-actions/bazel/setup@99d57027286c71dda92d8b91a3607abcf92d8bbd # main + uses: angular/dev-infra/github-actions/bazel/setup@bf1d18837b5aaed70cf858ecd177583bf320be50 # main - run: pnpm admin snapshots --verbose env: SNAPSHOT_BUILDS_GITHUB_TOKEN: ${{ secrets.SNAPSHOT_BUILDS_GITHUB_TOKEN }} diff --git a/.github/workflows/dev-infra.yml b/.github/workflows/dev-infra.yml index b12b3dc168ea..0f4aea85fdb0 100644 --- a/.github/workflows/dev-infra.yml +++ b/.github/workflows/dev-infra.yml @@ -16,21 +16,21 @@ jobs: if: github.event_name == 'pull_request_target' runs-on: ubuntu-latest steps: - - uses: angular/dev-infra/github-actions/labeling/pull-request@99d57027286c71dda92d8b91a3607abcf92d8bbd # main + - uses: angular/dev-infra/github-actions/labeling/pull-request@bf1d18837b5aaed70cf858ecd177583bf320be50 # main with: angular-robot-key: ${{ secrets.ANGULAR_ROBOT_PRIVATE_KEY }} post_approval_changes: if: github.event_name == 'pull_request_target' runs-on: ubuntu-latest steps: - - uses: angular/dev-infra/github-actions/post-approval-changes@99d57027286c71dda92d8b91a3607abcf92d8bbd # main + - uses: angular/dev-infra/github-actions/post-approval-changes@bf1d18837b5aaed70cf858ecd177583bf320be50 # main with: angular-robot-key: ${{ secrets.ANGULAR_ROBOT_PRIVATE_KEY }} issue_labels: if: github.event_name == 'issues' runs-on: ubuntu-latest steps: - - uses: angular/dev-infra/github-actions/labeling/issue@99d57027286c71dda92d8b91a3607abcf92d8bbd # main + - uses: angular/dev-infra/github-actions/labeling/issue@bf1d18837b5aaed70cf858ecd177583bf320be50 # main with: angular-robot-key: ${{ secrets.ANGULAR_ROBOT_PRIVATE_KEY }} google-generative-ai-key: ${{ secrets.GOOGLE_GENERATIVE_AI_KEY }} diff --git a/.github/workflows/perf.yml b/.github/workflows/perf.yml index b837b722a4f4..a3170cf0add5 100644 --- a/.github/workflows/perf.yml +++ b/.github/workflows/perf.yml @@ -22,7 +22,7 @@ jobs: workflows: ${{ steps.workflows.outputs.workflows }} steps: - name: Initialize environment - uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@99d57027286c71dda92d8b91a3607abcf92d8bbd # main + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@bf1d18837b5aaed70cf858ecd177583bf320be50 # main - name: Install node modules run: pnpm install --frozen-lockfile - id: workflows @@ -40,9 +40,9 @@ jobs: workflow: ${{ fromJSON(needs.list.outputs.workflows) }} steps: - name: Initialize environment - uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@99d57027286c71dda92d8b91a3607abcf92d8bbd # main + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@bf1d18837b5aaed70cf858ecd177583bf320be50 # main - name: Setup Bazel - uses: angular/dev-infra/github-actions/bazel/setup@99d57027286c71dda92d8b91a3607abcf92d8bbd # main + uses: angular/dev-infra/github-actions/bazel/setup@bf1d18837b5aaed70cf858ecd177583bf320be50 # main - name: Install node modules run: pnpm install --frozen-lockfile # We utilize the google-github-actions/auth action to allow us to get an active credential using workflow diff --git a/.github/workflows/pr.yml b/.github/workflows/pr.yml index c62816440333..5d86977c77a4 100644 --- a/.github/workflows/pr.yml +++ b/.github/workflows/pr.yml @@ -34,9 +34,9 @@ jobs: runs-on: ubuntu-latest steps: - name: Initialize environment - uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@99d57027286c71dda92d8b91a3607abcf92d8bbd # main + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@bf1d18837b5aaed70cf858ecd177583bf320be50 # main - name: Setup Bazel - uses: angular/dev-infra/github-actions/bazel/setup@99d57027286c71dda92d8b91a3607abcf92d8bbd # main + uses: angular/dev-infra/github-actions/bazel/setup@bf1d18837b5aaed70cf858ecd177583bf320be50 # main - name: Setup ESLint Caching uses: actions/cache@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0 with: @@ -66,17 +66,17 @@ jobs: # it has been merged. run: pnpm ng-dev format changed --check ${{ github.event.pull_request.base.sha }} - name: Check Package Licenses - uses: angular/dev-infra/github-actions/linting/licenses@99d57027286c71dda92d8b91a3607abcf92d8bbd # main + uses: angular/dev-infra/github-actions/linting/licenses@bf1d18837b5aaed70cf858ecd177583bf320be50 # main build: runs-on: ubuntu-latest steps: - name: Initialize environment - uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@99d57027286c71dda92d8b91a3607abcf92d8bbd # main + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@bf1d18837b5aaed70cf858ecd177583bf320be50 # main - name: Setup Bazel - uses: angular/dev-infra/github-actions/bazel/setup@99d57027286c71dda92d8b91a3607abcf92d8bbd # main + uses: angular/dev-infra/github-actions/bazel/setup@bf1d18837b5aaed70cf858ecd177583bf320be50 # main - name: Setup Bazel RBE - uses: angular/dev-infra/github-actions/bazel/configure-remote@99d57027286c71dda92d8b91a3607abcf92d8bbd # main + uses: angular/dev-infra/github-actions/bazel/configure-remote@bf1d18837b5aaed70cf858ecd177583bf320be50 # main - name: Install node modules run: pnpm install --frozen-lockfile - name: Build release targets @@ -93,11 +93,11 @@ jobs: runs-on: ubuntu-latest steps: - name: Initialize environment - uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@99d57027286c71dda92d8b91a3607abcf92d8bbd # main + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@bf1d18837b5aaed70cf858ecd177583bf320be50 # main - name: Setup Bazel - uses: angular/dev-infra/github-actions/bazel/setup@99d57027286c71dda92d8b91a3607abcf92d8bbd # main + uses: angular/dev-infra/github-actions/bazel/setup@bf1d18837b5aaed70cf858ecd177583bf320be50 # main - name: Setup Bazel RBE - uses: angular/dev-infra/github-actions/bazel/configure-remote@99d57027286c71dda92d8b91a3607abcf92d8bbd # main + uses: angular/dev-infra/github-actions/bazel/configure-remote@bf1d18837b5aaed70cf858ecd177583bf320be50 # main - name: Install node modules run: pnpm install --frozen-lockfile - name: Run module and package tests @@ -114,13 +114,13 @@ jobs: runs-on: ubuntu-latest steps: - name: Initialize environment - uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@99d57027286c71dda92d8b91a3607abcf92d8bbd # main + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@bf1d18837b5aaed70cf858ecd177583bf320be50 # main - name: Install node modules run: pnpm install --frozen-lockfile - name: Setup Bazel - uses: angular/dev-infra/github-actions/bazel/setup@99d57027286c71dda92d8b91a3607abcf92d8bbd # main + uses: angular/dev-infra/github-actions/bazel/setup@bf1d18837b5aaed70cf858ecd177583bf320be50 # main - name: Setup Bazel RBE - uses: angular/dev-infra/github-actions/bazel/configure-remote@99d57027286c71dda92d8b91a3607abcf92d8bbd # main + uses: angular/dev-infra/github-actions/bazel/configure-remote@bf1d18837b5aaed70cf858ecd177583bf320be50 # main - name: Run CLI E2E tests run: pnpm bazel test --test_env=E2E_SHARD_TOTAL=6 --test_env=E2E_SHARD_INDEX=${{ matrix.shard }} --config=e2e //tests:e2e.${{ matrix.subset }}_node${{ matrix.node }} @@ -128,11 +128,11 @@ jobs: runs-on: ubuntu-latest steps: - name: Initialize environment - uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@99d57027286c71dda92d8b91a3607abcf92d8bbd # main + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@bf1d18837b5aaed70cf858ecd177583bf320be50 # main - name: Setup Bazel - uses: angular/dev-infra/github-actions/bazel/setup@99d57027286c71dda92d8b91a3607abcf92d8bbd # main + uses: angular/dev-infra/github-actions/bazel/setup@bf1d18837b5aaed70cf858ecd177583bf320be50 # main - name: Setup Bazel RBE - uses: angular/dev-infra/github-actions/bazel/configure-remote@99d57027286c71dda92d8b91a3607abcf92d8bbd # main + uses: angular/dev-infra/github-actions/bazel/configure-remote@bf1d18837b5aaed70cf858ecd177583bf320be50 # main - name: Install node modules run: pnpm install --frozen-lockfile - name: Build E2E tests for Windows on Linux @@ -156,7 +156,7 @@ jobs: runs-on: windows-2025 steps: - name: Initialize environment - uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@99d57027286c71dda92d8b91a3607abcf92d8bbd # main + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@bf1d18837b5aaed70cf858ecd177583bf320be50 # main - name: Install node modules run: pnpm install --frozen-lockfile - name: Download built Windows E2E tests @@ -183,13 +183,13 @@ jobs: runs-on: ubuntu-latest steps: - name: Initialize environment - uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@99d57027286c71dda92d8b91a3607abcf92d8bbd # main + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@bf1d18837b5aaed70cf858ecd177583bf320be50 # main - name: Install node modules run: pnpm install --frozen-lockfile - name: Setup Bazel - uses: angular/dev-infra/github-actions/bazel/setup@99d57027286c71dda92d8b91a3607abcf92d8bbd # main + uses: angular/dev-infra/github-actions/bazel/setup@bf1d18837b5aaed70cf858ecd177583bf320be50 # main - name: Setup Bazel RBE - uses: angular/dev-infra/github-actions/bazel/configure-remote@99d57027286c71dda92d8b91a3607abcf92d8bbd # main + uses: angular/dev-infra/github-actions/bazel/configure-remote@bf1d18837b5aaed70cf858ecd177583bf320be50 # main - name: Run CLI E2E tests run: pnpm bazel test --test_env=E2E_SHARD_TOTAL=3 --test_env=E2E_SHARD_INDEX=${{ matrix.shard }} --config=e2e //tests:e2e.${{ matrix.subset }}_node${{ matrix.node }} @@ -205,12 +205,12 @@ jobs: runs-on: ubuntu-latest steps: - name: Initialize environment - uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@99d57027286c71dda92d8b91a3607abcf92d8bbd # main + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@bf1d18837b5aaed70cf858ecd177583bf320be50 # main - name: Install node modules run: pnpm install --frozen-lockfile - name: Setup Bazel - uses: angular/dev-infra/github-actions/bazel/setup@99d57027286c71dda92d8b91a3607abcf92d8bbd # main + uses: angular/dev-infra/github-actions/bazel/setup@bf1d18837b5aaed70cf858ecd177583bf320be50 # main - name: Setup Bazel RBE - uses: angular/dev-infra/github-actions/bazel/configure-remote@99d57027286c71dda92d8b91a3607abcf92d8bbd # main + uses: angular/dev-infra/github-actions/bazel/configure-remote@bf1d18837b5aaed70cf858ecd177583bf320be50 # main - name: Run CLI E2E tests run: pnpm bazel test --test_env=E2E_SHARD_TOTAL=6 --test_env=E2E_SHARD_INDEX=${{ matrix.shard }} --config=e2e //tests:e2e.snapshots.${{ matrix.subset }}_node${{ matrix.node }} diff --git a/MODULE.bazel b/MODULE.bazel index 595813a5abf1..5e0096477618 100644 --- a/MODULE.bazel +++ b/MODULE.bazel @@ -19,21 +19,21 @@ bazel_dep(name = "aspect_rules_jasmine", version = "2.0.4") bazel_dep(name = "rules_angular") git_override( module_name = "rules_angular", - commit = "7fdee07b9989b92b88f24c84471e01d6a0a9bc34", + commit = "6468bfd6c2f90b7a025d86273b070d0dd0a443db", remote = "https://github.com/angular/rules_angular.git", ) bazel_dep(name = "devinfra") git_override( module_name = "devinfra", - commit = "99d57027286c71dda92d8b91a3607abcf92d8bbd", + commit = "bf1d18837b5aaed70cf858ecd177583bf320be50", remote = "https://github.com/angular/dev-infra.git", ) bazel_dep(name = "rules_browsers") git_override( module_name = "rules_browsers", - commit = "f87a5f7fc587219ff328da2972e06370f297a621", + commit = "ba55f13997d951c9ac02192cf6d1cadad03c1237", remote = "https://github.com/angular/rules_browsers.git", ) diff --git a/package.json b/package.json index 331ab53b141f..390c22cd5890 100644 --- a/package.json +++ b/package.json @@ -55,7 +55,7 @@ "@angular/forms": "22.2.0-rc.0", "@angular/localize": "22.2.0-rc.0", "@angular/material": "22.2.0-rc.0", - "@angular/ng-dev": "https://github.com/angular/dev-infra-private-ng-dev-builds.git#f5de34cabca7e005dc8102d3abb026d01a7a881a", + "@angular/ng-dev": "https://github.com/angular/dev-infra-private-ng-dev-builds.git#90a76327155df50e90a41fe76aed67b98a9cf954", "@angular/platform-browser": "22.2.0-rc.0", "@angular/platform-server": "22.2.0-rc.0", "@angular/router": "22.2.0-rc.0", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index c0c4d347a5ef..08f0650a056d 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -208,8 +208,8 @@ importers: specifier: 22.2.0-rc.0 version: 22.2.0-rc.0(25ddf4063a130bbf19862bd16a6ab5d4) '@angular/ng-dev': - specifier: https://github.com/angular/dev-infra-private-ng-dev-builds.git#f5de34cabca7e005dc8102d3abb026d01a7a881a - version: https://codeload.github.com/angular/dev-infra-private-ng-dev-builds/tar.gz/f5de34cabca7e005dc8102d3abb026d01a7a881a + specifier: https://github.com/angular/dev-infra-private-ng-dev-builds.git#90a76327155df50e90a41fe76aed67b98a9cf954 + version: https://codeload.github.com/angular/dev-infra-private-ng-dev-builds/tar.gz/90a76327155df50e90a41fe76aed67b98a9cf954 '@angular/platform-browser': specifier: 22.2.0-rc.0 version: 22.2.0-rc.0(@angular/animations@22.2.0-rc.0(@angular/core@22.2.0-rc.0(@angular/compiler@22.2.0-rc.0)(rxjs@7.8.2)(zone.js@0.16.3)))(@angular/common@22.2.0-rc.0(@angular/core@22.2.0-rc.0(@angular/compiler@22.2.0-rc.0)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2))(@angular/core@22.2.0-rc.0(@angular/compiler@22.2.0-rc.0)(rxjs@7.8.2)(zone.js@0.16.3)) @@ -1103,9 +1103,9 @@ packages: '@angular/platform-browser': ^22.0.0-0 || ^22.1.0-0 || ^22.2.0-0 || ^22.3.0-0 || ^23.0.0-0 rxjs: ^6.5.3 || ^7.4.0 - '@angular/ng-dev@https://codeload.github.com/angular/dev-infra-private-ng-dev-builds/tar.gz/f5de34cabca7e005dc8102d3abb026d01a7a881a': - resolution: {gitHosted: true, integrity: sha512-JEXOlRtQ50aV/E2C+PeGKYCmGHWOi6G70kiS0tTjKGAn+qrYTRQQzFSm4YB2VVYnL16s3jg8oAIwZ4pl/t9WgQ==, tarball: https://codeload.github.com/angular/dev-infra-private-ng-dev-builds/tar.gz/f5de34cabca7e005dc8102d3abb026d01a7a881a} - version: 0.0.0-71e60c68d9d483b0d763b8e6ed4dd9deb8da3b1a + '@angular/ng-dev@https://codeload.github.com/angular/dev-infra-private-ng-dev-builds/tar.gz/90a76327155df50e90a41fe76aed67b98a9cf954': + resolution: {gitHosted: true, integrity: sha512-VmtUf+oZIHjATMGTjURjB3gJJ72gPo4nCDWEDUtW3MqgLPl088ISDgnV9CPXEt62EbByn9+0vVULCCk4p8YcVg==, tarball: https://codeload.github.com/angular/dev-infra-private-ng-dev-builds/tar.gz/90a76327155df50e90a41fe76aed67b98a9cf954} + version: 0.0.0-20b69d39859eae19d7ac04b6f1902f73286f7686 hasBin: true '@angular/platform-browser@22.2.0-rc.0': @@ -2020,15 +2020,15 @@ packages: '@noble/hashes': optional: true - '@firebase/ai@2.15.0': - resolution: {integrity: sha512-Aj7TbFdAIWZdkX8JfdDStERpR35g6WNs+7XhNPtFLFOizUotj6k4N/D8HJkR45165HhnMJBe4hjOeeaxnnn56Q==} + '@firebase/ai@2.16.0': + resolution: {integrity: sha512-WRVxl58B61Orwf7st7949ZIW2L4huV80Gpaum1z8v2eH+m2xaxWtC8mOjQyVAOirr6O/yf89cBjlPvoyBpBfTg==} engines: {node: '>=20.0.0'} peerDependencies: '@firebase/app': 0.x '@firebase/app-types': 0.x - '@firebase/analytics-compat@0.2.30': - resolution: {integrity: sha512-uVZEKlLaW4AHAhv8zoN9cTmveX6v86AVqcJ4LCaRCMTChTH8/NsjbisTq1lpBfWCLWS1spqwSHB4vol/YSCdMA==} + '@firebase/analytics-compat@0.2.31': + resolution: {integrity: sha512-msTlG9REujk5rjtOHNLngiuPmvaWGQte8ugL4/F6ZCMb+92Ue7SgjSEpNxINkM8ZtTrbGS83j5SZkt0r+M1Tjw==} peerDependencies: '@firebase/app': 0.x '@firebase/app-compat': 0.x @@ -2036,8 +2036,8 @@ packages: '@firebase/analytics-types@0.8.5': resolution: {integrity: sha512-kdnooE7Bis2jEnsqcerRwn/UQpH5D3uvHpku7OdUM9TJN3omlu6iYtbyAQ6XkAJRgJtO0aNf9OOkW8J6D59oCA==} - '@firebase/analytics@0.10.24': - resolution: {integrity: sha512-OfIAcIIwoqXjBzS+DnUQpOZ7i3ePaNFg83KPpDWjBZUKJmqMwzzAtLJqmKZOkQnW8im6vFR6f2I3M/9hxVd+QA==} + '@firebase/analytics@0.10.25': + resolution: {integrity: sha512-oDagV3PHeNXBdxemksZCdj+GmUT19eCnTOcLdQePIIovFXlm3zWy3Gjeaokt9Nqx24kc4ljK8lU0XGcGmmKZ1A==} peerDependencies: '@firebase/app': 0.x @@ -2060,19 +2060,19 @@ packages: peerDependencies: '@firebase/app': 0.x - '@firebase/app-compat@0.5.17': - resolution: {integrity: sha512-5GdJWobqs6jbNYOnaQiSa4Ng8gnFerhqr7nY+v5jlnT7o9QbEeIZRLPQpnLe0TxYSWfRV2lAMbyR0kbXeIos9Q==} + '@firebase/app-compat@0.5.18': + resolution: {integrity: sha512-77H57WuGEsgrv59HdtuhHG+eQdP8di6myz7O93yW6yTZlR/tLSmsCxCq5vHp6AWWDwSV0EVtKUvizXQiQZVBWA==} engines: {node: '>=20.0.0'} '@firebase/app-types@0.9.6': resolution: {integrity: sha512-yPLahy7Esfu2w/yme3msVK4xTkDXQqq6szfQn8yVOQpCKiT5GVFjqNpLbuz6NkX0WuTwUidkmPewW3r4xkvpeg==} - '@firebase/app@0.16.1': - resolution: {integrity: sha512-tjUEorFyKrurH7PbLWv9zDHRuU4mLefgD/yY38D584ziorIRlQz/PVjx4c/SCGyCuUlmyzt72mK+Lh+COAywNQ==} + '@firebase/app@0.16.2': + resolution: {integrity: sha512-fyCLPahl3r0Zb7Wzm+JLWcOOH3SaDgAyJzJ8EWIDiv51aNiv+2Pjbpa6myEuP7iXxjmJqrcbVm0GUF7h229T1Q==} engines: {node: '>=20.0.0'} - '@firebase/auth-compat@0.6.10': - resolution: {integrity: sha512-Bvklg2nL7BrBFCAqdsleW8fse9Jh0fARqJPlJmA40uermfWx1bJiO7dnKyZN3J39d2TFVd4VJXtg3i6Wg92/YQ==} + '@firebase/auth-compat@0.6.11': + resolution: {integrity: sha512-L+xp3DTJQrBV08Vt0UhcL/ofUOSjXom7JOJfbT6oas4o7gCrQnTYFKs8wfiuKLmHoo8BxMr5LdgjAs7o6aAsqQ==} engines: {node: '>=20.0.0'} peerDependencies: '@firebase/app': 0.x @@ -2087,8 +2087,8 @@ packages: '@firebase/app-types': 0.x '@firebase/util': 1.x - '@firebase/auth@1.13.5': - resolution: {integrity: sha512-1AXoBJqBVD8WL8FZYo3S2GmJF9YUoom6Y6ngMxOSkzzhW5sT83pLchb6TGFgxes91dfXx8s/VYc5VrLDNqpLog==} + '@firebase/auth@1.13.6': + resolution: {integrity: sha512-MKRLvF72HJ/irNn2fJR0Gv5FOZNtqv1IBeJHRwK8l8pZ/wi9vuUw8ecyCMvQDDNxfS6uW0MWACL5KC4Y8Pp+fA==} engines: {node: '>=20.0.0'} peerDependencies: '@firebase/app': 0.x @@ -2125,8 +2125,8 @@ packages: resolution: {integrity: sha512-/JGpvszLoNXNgzilRXocigGfFF4hbcPA9wN1i1kjJx6oKkXgkHteZYl3lQs1lJX3ETDf6bv7zI15lPMVUp4sAQ==} engines: {node: '>=20.0.0'} - '@firebase/firestore-compat@0.4.13': - resolution: {integrity: sha512-l9dCewxMzzLOIhcwTjERCKxrWOn1kZ9JvwOQq9zZNq4I/Nbvb/B9njT230V61uvQ9qZ3/qpUG758D8DDTEFXnw==} + '@firebase/firestore-compat@0.4.14': + resolution: {integrity: sha512-HJ2HBNgNPrRsWIJ4E+Kc0u0h1U7HlF7If8AtYjie9HZXlMUmwYSJaXBj9VFm6gkSj5dlKZNcOQ0Ou25CVVG6rA==} engines: {node: '>=20.0.0'} peerDependencies: '@firebase/app': 0.x @@ -2138,8 +2138,8 @@ packages: '@firebase/app-types': 0.x '@firebase/util': 1.x - '@firebase/firestore@4.17.1': - resolution: {integrity: sha512-8lqPNf2w10CtYG+tayVjZO1pSyQpnhztQRudeD109VtXDzNbASTaYdO43sj5PMsDcWq0aOYY3RmJOUlXu9++jw==} + '@firebase/firestore@4.17.2': + resolution: {integrity: sha512-SiyQEK1dYPOjItFVA+kZGdvOoRAtMebDBvUaSxJPNZMkKcRwYYK2kzWo5UXTZZj523uMxJnkr+KKVySEMme3kQ==} engines: {node: '>=20.0.0'} peerDependencies: '@firebase/app': 0.x @@ -2180,8 +2180,8 @@ packages: resolution: {integrity: sha512-J2VO4NFTc0xQFrxV1B/lm5balicm9cwuX2acR9Yn41fN8KgUeQFo+VJV222IqW2FPSXKDu9uo5WdQFWf9TPbYg==} engines: {node: '>=20.0.0'} - '@firebase/messaging-compat@0.2.29': - resolution: {integrity: sha512-8Twe4CeYvAx8AzjBxyyQFKzinaMGGt13hPQBqaARQ2QZjagrEaqSVBe+Zy6F4L/vT8DV168yRgRu7W/RK7p+4w==} + '@firebase/messaging-compat@0.2.30': + resolution: {integrity: sha512-m1DPT2ET5x0qYqXLoHwKMAyf1mgZZOhuoE6H6/H4OPsp8zSxMIDEFPaW7MaffPJsCA5J7kHzo+BHVNXK4ZoV+w==} peerDependencies: '@firebase/app': 0.x '@firebase/app-compat': 0.x @@ -2189,8 +2189,8 @@ packages: '@firebase/messaging-interop-types@0.2.6': resolution: {integrity: sha512-MVzvkKe2V4H2dHu5oOxRfeKQcfTwWmCgnzsC4V1q3ixun5iiL8riCZ2qI35rDhCL4glPGiu0jHxDbpVNuTKfow==} - '@firebase/messaging@0.13.2': - resolution: {integrity: sha512-KcZoqUu2ih4sLH91dW9tmyHjCR0IQyNzSLZunX5uq7cLeImXb4uO2I0wq5FACduO2I+FoTeWa2BtUv7Jpowqdw==} + '@firebase/messaging@0.13.3': + resolution: {integrity: sha512-nRXPAp+z0kA3KziJtRY9kktHECvRwaaONzHvislFgllhCwJMscW7icWNQA5IjyP8Uc2+GS/4px8Uz6rx6ftTag==} peerDependencies: '@firebase/app': 0.x @@ -2279,8 +2279,8 @@ packages: resolution: {integrity: sha512-IJn+8A3QZJfe7FUtWqHVNo3xJs7KFpurCWGWCiCz3oEh+BkRymKZ1QxfAbU2yGMDzTytLGQ2IV6T2r3cuo75/w==} engines: {node: '>=18'} - '@google/genai@2.20.0': - resolution: {integrity: sha512-kFEzARfA064oCNAmYTyOaAeJ9KSkbZ2Upxz36oO5eVNlcxAXsixLlGbwY1oy+Ab8HJ6nMWMD9hg+NdIron6wJw==} + '@google/genai@2.22.0': + resolution: {integrity: sha512-NE90Nl0AP75YZ2tGxXjQQs6Gkunma7a1JmPCx5g5CxvjHXshmuI2aNoPJ1xLrRixjkNxog898oylM+MyNudUQw==} engines: {node: '>=20.0.0'} peerDependencies: '@modelcontextprotocol/sdk': ^1.25.2 @@ -2418,15 +2418,6 @@ packages: '@types/node': optional: true - '@inquirer/prompts@8.7.0': - resolution: {integrity: sha512-yQwBMYvpJ6jqrXtKiOwRD5XezjJoyt3VQvIyjsr5Arqb519nfIohOQymWVJ8/vEgg8xtZerrCsqlSaqt/LPC9A==} - engines: {node: '>=23.5.0 || ^22.13.0 || ^20.17.0'} - peerDependencies: - '@types/node': '>=18' - peerDependenciesMeta: - '@types/node': - optional: true - '@inquirer/prompts@8.7.2': resolution: {integrity: sha512-QoRB4wFIjgH5iOhSjoIKMkTvSHDuV+O3OITlIqAYO0oK5x364GJILXiMBvlPiE+klg7Xx9tq5XVqQHcGUDYYPA==} engines: {node: '>=23.5.0 || ^22.13.0 || ^20.17.0'} @@ -2463,15 +2454,6 @@ packages: '@types/node': optional: true - '@inquirer/type@4.1.0': - resolution: {integrity: sha512-FMiJpuHUG3Dk0ex+UIXkre7i+i4OcwHWk9YdcVtZHFwb/r2rnrU2ipTCNAB7A+QOP0ryzIcqOfy76fRyyvOEAw==} - engines: {node: '>=23.5.0 || ^22.13.0 || ^20.17.0'} - peerDependencies: - '@types/node': '>=18' - peerDependenciesMeta: - '@types/node': - optional: true - '@inquirer/type@4.1.1': resolution: {integrity: sha512-yJoHYrMnxIsJZCY+0Vb66Dy3he3kL3e2wOBKhoSwWWAzZAY82emlxwgprCtp6yRixvNRNq9ztfRWQYPNr3Go7A==} engines: {node: '>=23.5.0 || ^22.13.0 || ^20.17.0'} @@ -3729,8 +3711,8 @@ packages: '@types/node@22.20.2': resolution: {integrity: sha512-xlvWf4Vs9n1PEVYwP1n4vvG07M6y8WgvJ2t0vbrWTmijsIHp1cS+uJ2kMIRdY3nHZK0nCYKrPeD171+SzF4/zw==} - '@types/node@24.13.3': - resolution: {integrity: sha512-Dh8vAsV36ig5wa9OX4pXvMc9D3Veibfw2wix0CUwYODLD8nkj9UsLjASr49nPg+2eKzxhBV+v7L8pXvT4e639Q==} + '@types/node@24.13.5': + resolution: {integrity: sha512-TXyindR+lBr22aJIdMQzCFHPHR6cR4js838mRDCSz5hOKWZvZwsXSSiXDmjRj4iJmgl+sR9O+1mkoVBSMadNug==} '@types/npm-package-arg@6.1.4': resolution: {integrity: sha512-vDgdbMy2QXHnAruzlv68pUtXCjmqUk3WrBAsRboRovsOmxbfn/WiYCjmecyKjGztnMps5dWp4Uq2prp+Ilo17Q==} @@ -5419,8 +5401,8 @@ packages: resolution: {integrity: sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==} engines: {node: '>=10'} - firebase@12.18.0: - resolution: {integrity: sha512-XaL6tlE5Xd20ZDhckqOMIw+JJTET+wTdeZPxQ7ihc42oxRb7kWUyn/j1LO5V9dH1xq8Rv5R71Pv1fBCdIkt9Rw==} + firebase@12.19.0: + resolution: {integrity: sha512-kwXCLcI0ly2lkwygkbuRx6SsX3DSO96355YrWh9SWZ5ncsxK/y5cirn3sY6nZVSiBVE++2nL6Hchzu1EB8uohQ==} flat-cache@6.1.23: resolution: {integrity: sha512-f++BY9pTk+983xK1FLzlLpmM0i0z+jHmx3QESGkURMXujQZz1k5wzwX6hjnQ8goaD0B+sYnDK1yZ6MTyZfUaqA==} @@ -8711,11 +8693,6 @@ packages: yallist@3.1.1: resolution: {integrity: sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==} - yaml@2.9.0: - resolution: {integrity: sha512-2AvhNX3mb8zd6Zy7INTtSpl1F15HW6Wnqj0srWlkKLcpYl/gMIMJiyuGq2KeI2YFxUPjdlB+3Lc10seMLtL4cA==} - engines: {node: '>= 14.6'} - hasBin: true - yaml@2.9.1: resolution: {integrity: sha512-3NxN8+78OdzbT7C/WjGsyfPAtJaN3FNDsWxv7Y7mcDsT/oOmgW8BpyQQFFBnvZE3j9Y2Sdz1ULFLezL7Eb2yFw==} engines: {node: '>= 14.6'} @@ -8869,14 +8846,14 @@ snapshots: rxjs: 7.8.2 tslib: 2.8.1 - '@angular/ng-dev@https://codeload.github.com/angular/dev-infra-private-ng-dev-builds/tar.gz/f5de34cabca7e005dc8102d3abb026d01a7a881a': + '@angular/ng-dev@https://codeload.github.com/angular/dev-infra-private-ng-dev-builds/tar.gz/90a76327155df50e90a41fe76aed67b98a9cf954': dependencies: '@actions/core': 3.0.1 '@conventional-changelog/git-client': 3.1.2(conventional-commits-filter@6.0.1)(conventional-commits-parser@7.1.2) '@google-cloud/spanner': 8.0.0(supports-color@11.0.0) - '@google/genai': 2.20.0(bufferutil@4.1.0)(supports-color@11.0.0)(utf-8-validate@6.0.6) - '@inquirer/prompts': 8.7.0(@types/node@24.13.3) - '@inquirer/type': 4.1.0(@types/node@24.13.3) + '@google/genai': 2.22.0(bufferutil@4.1.0)(supports-color@11.0.0)(utf-8-validate@6.0.6) + '@inquirer/prompts': 8.7.2(@types/node@24.13.5) + '@inquirer/type': 4.1.1(@types/node@24.13.5) '@octokit/auth-app': 8.3.1 '@octokit/core': 7.0.8 '@octokit/graphql': 9.0.5 @@ -8892,7 +8869,7 @@ snapshots: '@types/events': 3.0.3 '@types/folder-hash': 4.0.4 '@types/jasmine': 6.0.0 - '@types/node': 24.13.3 + '@types/node': 24.13.5 '@types/semver': 7.8.0 '@types/which': 3.0.4 '@types/yargs': 17.0.35 @@ -8905,7 +8882,7 @@ snapshots: ejs: 6.0.1 encoding: 0.1.13 fast-glob: 3.3.3 - firebase: 12.18.0 + firebase: 12.19.0 folder-hash: 4.1.3(supports-color@11.0.0) jasmine: 6.3.0 jasmine-core: 6.3.0 @@ -8921,7 +8898,7 @@ snapshots: typescript: 6.0.3 utf-8-validate: 6.0.6 which: 7.0.0 - yaml: 2.9.0 + yaml: 2.9.1 yargs: 18.1.0 zod: 4.6.5 transitivePeerDependencies: @@ -9884,9 +9861,9 @@ snapshots: '@exodus/bytes@1.15.1': {} - '@firebase/ai@2.15.0(@firebase/app-types@0.9.6)(@firebase/app@0.16.1)': + '@firebase/ai@2.16.0(@firebase/app-types@0.9.6)(@firebase/app@0.16.2)': dependencies: - '@firebase/app': 0.16.1 + '@firebase/app': 0.16.2 '@firebase/app-check-interop-types': 0.3.5 '@firebase/app-types': 0.9.6 '@firebase/component': 0.7.5 @@ -9894,33 +9871,33 @@ snapshots: '@firebase/util': 1.15.3 tslib: 2.8.1 - '@firebase/analytics-compat@0.2.30(@firebase/app-compat@0.5.17)(@firebase/app@0.16.1)': + '@firebase/analytics-compat@0.2.31(@firebase/app-compat@0.5.18)(@firebase/app@0.16.2)': dependencies: - '@firebase/analytics': 0.10.24(@firebase/app@0.16.1) + '@firebase/analytics': 0.10.25(@firebase/app@0.16.2) '@firebase/analytics-types': 0.8.5 - '@firebase/app': 0.16.1 - '@firebase/app-compat': 0.5.17 + '@firebase/app': 0.16.2 + '@firebase/app-compat': 0.5.18 '@firebase/component': 0.7.5 '@firebase/util': 1.15.3 tslib: 2.8.1 '@firebase/analytics-types@0.8.5': {} - '@firebase/analytics@0.10.24(@firebase/app@0.16.1)': + '@firebase/analytics@0.10.25(@firebase/app@0.16.2)': dependencies: - '@firebase/app': 0.16.1 + '@firebase/app': 0.16.2 '@firebase/component': 0.7.5 - '@firebase/installations': 0.6.24(@firebase/app@0.16.1) + '@firebase/installations': 0.6.24(@firebase/app@0.16.2) '@firebase/logger': 0.5.2 '@firebase/util': 1.15.3 tslib: 2.8.1 - '@firebase/app-check-compat@0.4.7(@firebase/app-compat@0.5.17)(@firebase/app@0.16.1)': + '@firebase/app-check-compat@0.4.7(@firebase/app-compat@0.5.18)(@firebase/app@0.16.2)': dependencies: - '@firebase/app': 0.16.1 - '@firebase/app-check': 0.13.1(@firebase/app@0.16.1) + '@firebase/app': 0.16.2 + '@firebase/app-check': 0.13.1(@firebase/app@0.16.2) '@firebase/app-check-types': 0.5.5 - '@firebase/app-compat': 0.5.17 + '@firebase/app-compat': 0.5.18 '@firebase/component': 0.7.5 '@firebase/logger': 0.5.2 '@firebase/util': 1.15.3 @@ -9930,17 +9907,17 @@ snapshots: '@firebase/app-check-types@0.5.5': {} - '@firebase/app-check@0.13.1(@firebase/app@0.16.1)': + '@firebase/app-check@0.13.1(@firebase/app@0.16.2)': dependencies: - '@firebase/app': 0.16.1 + '@firebase/app': 0.16.2 '@firebase/component': 0.7.5 '@firebase/logger': 0.5.2 '@firebase/util': 1.15.3 tslib: 2.8.1 - '@firebase/app-compat@0.5.17': + '@firebase/app-compat@0.5.18': dependencies: - '@firebase/app': 0.16.1 + '@firebase/app': 0.16.2 '@firebase/component': 0.7.5 '@firebase/logger': 0.5.2 '@firebase/util': 1.15.3 @@ -9950,7 +9927,7 @@ snapshots: dependencies: '@firebase/logger': 0.5.2 - '@firebase/app@0.16.1': + '@firebase/app@0.16.2': dependencies: '@firebase/component': 0.7.5 '@firebase/logger': 0.5.2 @@ -9958,11 +9935,11 @@ snapshots: idb: 7.1.1 tslib: 2.8.1 - '@firebase/auth-compat@0.6.10(@firebase/app-compat@0.5.17)(@firebase/app-types@0.9.6)(@firebase/app@0.16.1)': + '@firebase/auth-compat@0.6.11(@firebase/app-compat@0.5.18)(@firebase/app-types@0.9.6)(@firebase/app@0.16.2)': dependencies: - '@firebase/app': 0.16.1 - '@firebase/app-compat': 0.5.17 - '@firebase/auth': 1.13.5(@firebase/app@0.16.1) + '@firebase/app': 0.16.2 + '@firebase/app-compat': 0.5.18 + '@firebase/auth': 1.13.6(@firebase/app@0.16.2) '@firebase/auth-types': 0.13.2(@firebase/app-types@0.9.6)(@firebase/util@1.15.3) '@firebase/component': 0.7.5 '@firebase/util': 1.15.3 @@ -9978,9 +9955,9 @@ snapshots: '@firebase/app-types': 0.9.6 '@firebase/util': 1.15.3 - '@firebase/auth@1.13.5(@firebase/app@0.16.1)': + '@firebase/auth@1.13.6(@firebase/app@0.16.2)': dependencies: - '@firebase/app': 0.16.1 + '@firebase/app': 0.16.2 '@firebase/component': 0.7.5 '@firebase/logger': 0.5.2 '@firebase/util': 1.15.3 @@ -9991,16 +9968,16 @@ snapshots: '@firebase/util': 1.15.3 tslib: 2.8.1 - '@firebase/data-connect@0.7.4(@firebase/app@0.16.1)': + '@firebase/data-connect@0.7.4(@firebase/app@0.16.2)': dependencies: - '@firebase/app': 0.16.1 + '@firebase/app': 0.16.2 '@firebase/auth-interop-types': 0.2.6 '@firebase/component': 0.7.5 '@firebase/logger': 0.5.2 '@firebase/util': 1.15.3 tslib: 2.8.1 - '@firebase/database-compat@2.1.7(@firebase/app-compat@0.5.17)(@firebase/app@0.16.1)': + '@firebase/database-compat@2.1.7(@firebase/app-compat@0.5.18)(@firebase/app@0.16.2)': dependencies: '@firebase/component': 0.7.5 '@firebase/database': 1.1.5 @@ -10009,8 +9986,8 @@ snapshots: '@firebase/util': 1.15.3 tslib: 2.8.1 optionalDependencies: - '@firebase/app': 0.16.1 - '@firebase/app-compat': 0.5.17 + '@firebase/app': 0.16.2 + '@firebase/app-compat': 0.5.18 '@firebase/database-types@1.0.22': dependencies: @@ -10027,12 +10004,12 @@ snapshots: faye-websocket: 0.11.4 tslib: 2.8.1 - '@firebase/firestore-compat@0.4.13(@firebase/app-compat@0.5.17)(@firebase/app-types@0.9.6)(@firebase/app@0.16.1)': + '@firebase/firestore-compat@0.4.14(@firebase/app-compat@0.5.18)(@firebase/app-types@0.9.6)(@firebase/app@0.16.2)': dependencies: - '@firebase/app': 0.16.1 - '@firebase/app-compat': 0.5.17 + '@firebase/app': 0.16.2 + '@firebase/app-compat': 0.5.18 '@firebase/component': 0.7.5 - '@firebase/firestore': 4.17.1(@firebase/app@0.16.1) + '@firebase/firestore': 4.17.2(@firebase/app@0.16.2) '@firebase/firestore-types': 3.0.5(@firebase/app-types@0.9.6)(@firebase/util@1.15.3) '@firebase/util': 1.15.3 tslib: 2.8.1 @@ -10044,9 +10021,9 @@ snapshots: '@firebase/app-types': 0.9.6 '@firebase/util': 1.15.3 - '@firebase/firestore@4.17.1(@firebase/app@0.16.1)': + '@firebase/firestore@4.17.2(@firebase/app@0.16.2)': dependencies: - '@firebase/app': 0.16.1 + '@firebase/app': 0.16.2 '@firebase/component': 0.7.5 '@firebase/logger': 0.5.2 '@firebase/util': 1.15.3 @@ -10056,21 +10033,21 @@ snapshots: re2js: 2.8.6 tslib: 2.8.1 - '@firebase/functions-compat@0.5.0(@firebase/app-compat@0.5.17)(@firebase/app@0.16.1)': + '@firebase/functions-compat@0.5.0(@firebase/app-compat@0.5.18)(@firebase/app@0.16.2)': dependencies: - '@firebase/app': 0.16.1 - '@firebase/app-compat': 0.5.17 + '@firebase/app': 0.16.2 + '@firebase/app-compat': 0.5.18 '@firebase/component': 0.7.5 - '@firebase/functions': 0.14.0(@firebase/app@0.16.1) + '@firebase/functions': 0.14.0(@firebase/app@0.16.2) '@firebase/functions-types': 0.6.5 '@firebase/util': 1.15.3 tslib: 2.8.1 '@firebase/functions-types@0.6.5': {} - '@firebase/functions@0.14.0(@firebase/app@0.16.1)': + '@firebase/functions@0.14.0(@firebase/app@0.16.2)': dependencies: - '@firebase/app': 0.16.1 + '@firebase/app': 0.16.2 '@firebase/app-check-interop-types': 0.3.5 '@firebase/auth-interop-types': 0.2.6 '@firebase/component': 0.7.5 @@ -10078,12 +10055,12 @@ snapshots: '@firebase/util': 1.15.3 tslib: 2.8.1 - '@firebase/installations-compat@0.2.24(@firebase/app-compat@0.5.17)(@firebase/app-types@0.9.6)(@firebase/app@0.16.1)': + '@firebase/installations-compat@0.2.24(@firebase/app-compat@0.5.18)(@firebase/app-types@0.9.6)(@firebase/app@0.16.2)': dependencies: - '@firebase/app': 0.16.1 - '@firebase/app-compat': 0.5.17 + '@firebase/app': 0.16.2 + '@firebase/app-compat': 0.5.18 '@firebase/component': 0.7.5 - '@firebase/installations': 0.6.24(@firebase/app@0.16.1) + '@firebase/installations': 0.6.24(@firebase/app@0.16.2) '@firebase/installations-types': 0.5.5(@firebase/app-types@0.9.6) '@firebase/util': 1.15.3 tslib: 2.8.1 @@ -10094,9 +10071,9 @@ snapshots: dependencies: '@firebase/app-types': 0.9.6 - '@firebase/installations@0.6.24(@firebase/app@0.16.1)': + '@firebase/installations@0.6.24(@firebase/app@0.16.2)': dependencies: - '@firebase/app': 0.16.1 + '@firebase/app': 0.16.2 '@firebase/component': 0.7.5 '@firebase/util': 1.15.3 idb: 7.1.1 @@ -10106,78 +10083,78 @@ snapshots: dependencies: tslib: 2.8.1 - '@firebase/messaging-compat@0.2.29(@firebase/app-compat@0.5.17)(@firebase/app@0.16.1)': + '@firebase/messaging-compat@0.2.30(@firebase/app-compat@0.5.18)(@firebase/app@0.16.2)': dependencies: - '@firebase/app': 0.16.1 - '@firebase/app-compat': 0.5.17 + '@firebase/app': 0.16.2 + '@firebase/app-compat': 0.5.18 '@firebase/component': 0.7.5 - '@firebase/messaging': 0.13.2(@firebase/app@0.16.1) + '@firebase/messaging': 0.13.3(@firebase/app@0.16.2) '@firebase/util': 1.15.3 tslib: 2.8.1 '@firebase/messaging-interop-types@0.2.6': {} - '@firebase/messaging@0.13.2(@firebase/app@0.16.1)': + '@firebase/messaging@0.13.3(@firebase/app@0.16.2)': dependencies: - '@firebase/app': 0.16.1 + '@firebase/app': 0.16.2 '@firebase/component': 0.7.5 - '@firebase/installations': 0.6.24(@firebase/app@0.16.1) + '@firebase/installations': 0.6.24(@firebase/app@0.16.2) '@firebase/messaging-interop-types': 0.2.6 '@firebase/util': 1.15.3 idb: 7.1.1 tslib: 2.8.1 - '@firebase/performance-compat@0.2.27(@firebase/app-compat@0.5.17)(@firebase/app@0.16.1)': + '@firebase/performance-compat@0.2.27(@firebase/app-compat@0.5.18)(@firebase/app@0.16.2)': dependencies: - '@firebase/app': 0.16.1 - '@firebase/app-compat': 0.5.17 + '@firebase/app': 0.16.2 + '@firebase/app-compat': 0.5.18 '@firebase/component': 0.7.5 '@firebase/logger': 0.5.2 - '@firebase/performance': 0.7.14(@firebase/app@0.16.1) + '@firebase/performance': 0.7.14(@firebase/app@0.16.2) '@firebase/performance-types': 0.2.5 '@firebase/util': 1.15.3 tslib: 2.8.1 '@firebase/performance-types@0.2.5': {} - '@firebase/performance@0.7.14(@firebase/app@0.16.1)': + '@firebase/performance@0.7.14(@firebase/app@0.16.2)': dependencies: - '@firebase/app': 0.16.1 + '@firebase/app': 0.16.2 '@firebase/component': 0.7.5 - '@firebase/installations': 0.6.24(@firebase/app@0.16.1) + '@firebase/installations': 0.6.24(@firebase/app@0.16.2) '@firebase/logger': 0.5.2 '@firebase/util': 1.15.3 tslib: 2.8.1 web-vitals: 4.2.4 - '@firebase/remote-config-compat@0.2.29(@firebase/app-compat@0.5.17)(@firebase/app@0.16.1)': + '@firebase/remote-config-compat@0.2.29(@firebase/app-compat@0.5.18)(@firebase/app@0.16.2)': dependencies: - '@firebase/app': 0.16.1 - '@firebase/app-compat': 0.5.17 + '@firebase/app': 0.16.2 + '@firebase/app-compat': 0.5.18 '@firebase/component': 0.7.5 '@firebase/logger': 0.5.2 - '@firebase/remote-config': 0.9.2(@firebase/app@0.16.1) + '@firebase/remote-config': 0.9.2(@firebase/app@0.16.2) '@firebase/remote-config-types': 0.5.2 '@firebase/util': 1.15.3 tslib: 2.8.1 '@firebase/remote-config-types@0.5.2': {} - '@firebase/remote-config@0.9.2(@firebase/app@0.16.1)': + '@firebase/remote-config@0.9.2(@firebase/app@0.16.2)': dependencies: - '@firebase/app': 0.16.1 + '@firebase/app': 0.16.2 '@firebase/component': 0.7.5 - '@firebase/installations': 0.6.24(@firebase/app@0.16.1) + '@firebase/installations': 0.6.24(@firebase/app@0.16.2) '@firebase/logger': 0.5.2 '@firebase/util': 1.15.3 tslib: 2.8.1 - '@firebase/storage-compat@0.4.5(@firebase/app-compat@0.5.17)(@firebase/app-types@0.9.6)(@firebase/app@0.16.1)': + '@firebase/storage-compat@0.4.5(@firebase/app-compat@0.5.18)(@firebase/app-types@0.9.6)(@firebase/app@0.16.2)': dependencies: - '@firebase/app': 0.16.1 - '@firebase/app-compat': 0.5.17 + '@firebase/app': 0.16.2 + '@firebase/app-compat': 0.5.18 '@firebase/component': 0.7.5 - '@firebase/storage': 0.14.5(@firebase/app@0.16.1) + '@firebase/storage': 0.14.5(@firebase/app@0.16.2) '@firebase/storage-types': 0.8.5(@firebase/app-types@0.9.6)(@firebase/util@1.15.3) '@firebase/util': 1.15.3 tslib: 2.8.1 @@ -10189,9 +10166,9 @@ snapshots: '@firebase/app-types': 0.9.6 '@firebase/util': 1.15.3 - '@firebase/storage@0.14.5(@firebase/app@0.16.1)': + '@firebase/storage@0.14.5(@firebase/app@0.16.2)': dependencies: - '@firebase/app': 0.16.1 + '@firebase/app': 0.16.2 '@firebase/component': 0.7.5 '@firebase/util': 1.15.3 tslib: 2.8.1 @@ -10263,7 +10240,7 @@ snapshots: transitivePeerDependencies: - supports-color - '@google/genai@2.20.0(bufferutil@4.1.0)(supports-color@11.0.0)(utf-8-validate@6.0.6)': + '@google/genai@2.22.0(bufferutil@4.1.0)(supports-color@11.0.0)(utf-8-validate@6.0.6)': dependencies: google-auth-library: 10.9.1(supports-color@11.0.0) p-retry: 4.6.2 @@ -10328,14 +10305,14 @@ snapshots: optionalDependencies: '@types/node': 22.20.2 - '@inquirer/checkbox@5.2.5(@types/node@24.13.3)': + '@inquirer/checkbox@5.2.5(@types/node@24.13.5)': dependencies: '@inquirer/ansi': 2.0.8 - '@inquirer/core': 12.0.3(@types/node@24.13.3) + '@inquirer/core': 12.0.3(@types/node@24.13.5) '@inquirer/figures': 2.0.9 - '@inquirer/type': 4.1.1(@types/node@24.13.3) + '@inquirer/type': 4.1.1(@types/node@24.13.5) optionalDependencies: - '@types/node': 24.13.3 + '@types/node': 24.13.5 '@inquirer/confirm@6.3.2(@types/node@22.20.2)': dependencies: @@ -10344,12 +10321,12 @@ snapshots: optionalDependencies: '@types/node': 22.20.2 - '@inquirer/confirm@6.3.2(@types/node@24.13.3)': + '@inquirer/confirm@6.3.2(@types/node@24.13.5)': dependencies: - '@inquirer/core': 12.0.3(@types/node@24.13.3) - '@inquirer/type': 4.1.1(@types/node@24.13.3) + '@inquirer/core': 12.0.3(@types/node@24.13.5) + '@inquirer/type': 4.1.1(@types/node@24.13.5) optionalDependencies: - '@types/node': 24.13.3 + '@types/node': 24.13.5 '@inquirer/core@12.0.3(@types/node@22.20.2)': dependencies: @@ -10363,17 +10340,17 @@ snapshots: optionalDependencies: '@types/node': 22.20.2 - '@inquirer/core@12.0.3(@types/node@24.13.3)': + '@inquirer/core@12.0.3(@types/node@24.13.5)': dependencies: '@inquirer/ansi': 2.0.8 '@inquirer/figures': 2.0.9 - '@inquirer/type': 4.1.1(@types/node@24.13.3) + '@inquirer/type': 4.1.1(@types/node@24.13.5) cli-width: 4.1.0 fast-wrap-ansi: 0.2.2 mute-stream: 3.0.0 signal-exit: 4.1.0 optionalDependencies: - '@types/node': 24.13.3 + '@types/node': 24.13.5 '@inquirer/editor@5.3.3(@types/node@22.20.2)': dependencies: @@ -10383,13 +10360,13 @@ snapshots: optionalDependencies: '@types/node': 22.20.2 - '@inquirer/editor@5.3.3(@types/node@24.13.3)': + '@inquirer/editor@5.3.3(@types/node@24.13.5)': dependencies: - '@inquirer/core': 12.0.3(@types/node@24.13.3) - '@inquirer/external-editor': 3.0.5(@types/node@24.13.3) - '@inquirer/type': 4.1.1(@types/node@24.13.3) + '@inquirer/core': 12.0.3(@types/node@24.13.5) + '@inquirer/external-editor': 3.0.5(@types/node@24.13.5) + '@inquirer/type': 4.1.1(@types/node@24.13.5) optionalDependencies: - '@types/node': 24.13.3 + '@types/node': 24.13.5 '@inquirer/expand@5.1.5(@types/node@22.20.2)': dependencies: @@ -10398,12 +10375,12 @@ snapshots: optionalDependencies: '@types/node': 22.20.2 - '@inquirer/expand@5.1.5(@types/node@24.13.3)': + '@inquirer/expand@5.1.5(@types/node@24.13.5)': dependencies: - '@inquirer/core': 12.0.3(@types/node@24.13.3) - '@inquirer/type': 4.1.1(@types/node@24.13.3) + '@inquirer/core': 12.0.3(@types/node@24.13.5) + '@inquirer/type': 4.1.1(@types/node@24.13.5) optionalDependencies: - '@types/node': 24.13.3 + '@types/node': 24.13.5 '@inquirer/external-editor@3.0.5(@types/node@22.20.2)': dependencies: @@ -10412,12 +10389,12 @@ snapshots: optionalDependencies: '@types/node': 22.20.2 - '@inquirer/external-editor@3.0.5(@types/node@24.13.3)': + '@inquirer/external-editor@3.0.5(@types/node@24.13.5)': dependencies: chardet: 2.2.0 iconv-lite: 0.7.3 optionalDependencies: - '@types/node': 24.13.3 + '@types/node': 24.13.5 '@inquirer/figures@2.0.9': {} @@ -10428,12 +10405,12 @@ snapshots: optionalDependencies: '@types/node': 22.20.2 - '@inquirer/input@5.1.6(@types/node@24.13.3)': + '@inquirer/input@5.1.6(@types/node@24.13.5)': dependencies: - '@inquirer/core': 12.0.3(@types/node@24.13.3) - '@inquirer/type': 4.1.1(@types/node@24.13.3) + '@inquirer/core': 12.0.3(@types/node@24.13.5) + '@inquirer/type': 4.1.1(@types/node@24.13.5) optionalDependencies: - '@types/node': 24.13.3 + '@types/node': 24.13.5 '@inquirer/number@4.2.3(@types/node@22.20.2)': dependencies: @@ -10442,12 +10419,12 @@ snapshots: optionalDependencies: '@types/node': 22.20.2 - '@inquirer/number@4.2.3(@types/node@24.13.3)': + '@inquirer/number@4.2.3(@types/node@24.13.5)': dependencies: - '@inquirer/core': 12.0.3(@types/node@24.13.3) - '@inquirer/type': 4.1.1(@types/node@24.13.3) + '@inquirer/core': 12.0.3(@types/node@24.13.5) + '@inquirer/type': 4.1.1(@types/node@24.13.5) optionalDependencies: - '@types/node': 24.13.3 + '@types/node': 24.13.5 '@inquirer/password@5.2.2(@types/node@22.20.2)': dependencies: @@ -10457,28 +10434,13 @@ snapshots: optionalDependencies: '@types/node': 22.20.2 - '@inquirer/password@5.2.2(@types/node@24.13.3)': + '@inquirer/password@5.2.2(@types/node@24.13.5)': dependencies: '@inquirer/ansi': 2.0.8 - '@inquirer/core': 12.0.3(@types/node@24.13.3) - '@inquirer/type': 4.1.1(@types/node@24.13.3) + '@inquirer/core': 12.0.3(@types/node@24.13.5) + '@inquirer/type': 4.1.1(@types/node@24.13.5) optionalDependencies: - '@types/node': 24.13.3 - - '@inquirer/prompts@8.7.0(@types/node@24.13.3)': - dependencies: - '@inquirer/checkbox': 5.2.5(@types/node@24.13.3) - '@inquirer/confirm': 6.3.2(@types/node@24.13.3) - '@inquirer/editor': 5.3.3(@types/node@24.13.3) - '@inquirer/expand': 5.1.5(@types/node@24.13.3) - '@inquirer/input': 5.1.6(@types/node@24.13.3) - '@inquirer/number': 4.2.3(@types/node@24.13.3) - '@inquirer/password': 5.2.2(@types/node@24.13.3) - '@inquirer/rawlist': 5.3.5(@types/node@24.13.3) - '@inquirer/search': 4.3.3(@types/node@24.13.3) - '@inquirer/select': 5.2.5(@types/node@24.13.3) - optionalDependencies: - '@types/node': 24.13.3 + '@types/node': 24.13.5 '@inquirer/prompts@8.7.2(@types/node@22.20.2)': dependencies: @@ -10495,6 +10457,21 @@ snapshots: optionalDependencies: '@types/node': 22.20.2 + '@inquirer/prompts@8.7.2(@types/node@24.13.5)': + dependencies: + '@inquirer/checkbox': 5.2.5(@types/node@24.13.5) + '@inquirer/confirm': 6.3.2(@types/node@24.13.5) + '@inquirer/editor': 5.3.3(@types/node@24.13.5) + '@inquirer/expand': 5.1.5(@types/node@24.13.5) + '@inquirer/input': 5.1.6(@types/node@24.13.5) + '@inquirer/number': 4.2.3(@types/node@24.13.5) + '@inquirer/password': 5.2.2(@types/node@24.13.5) + '@inquirer/rawlist': 5.3.5(@types/node@24.13.5) + '@inquirer/search': 4.3.3(@types/node@24.13.5) + '@inquirer/select': 5.2.5(@types/node@24.13.5) + optionalDependencies: + '@types/node': 24.13.5 + '@inquirer/rawlist@5.3.5(@types/node@22.20.2)': dependencies: '@inquirer/core': 12.0.3(@types/node@22.20.2) @@ -10502,12 +10479,12 @@ snapshots: optionalDependencies: '@types/node': 22.20.2 - '@inquirer/rawlist@5.3.5(@types/node@24.13.3)': + '@inquirer/rawlist@5.3.5(@types/node@24.13.5)': dependencies: - '@inquirer/core': 12.0.3(@types/node@24.13.3) - '@inquirer/type': 4.1.1(@types/node@24.13.3) + '@inquirer/core': 12.0.3(@types/node@24.13.5) + '@inquirer/type': 4.1.1(@types/node@24.13.5) optionalDependencies: - '@types/node': 24.13.3 + '@types/node': 24.13.5 '@inquirer/search@4.3.3(@types/node@22.20.2)': dependencies: @@ -10517,13 +10494,13 @@ snapshots: optionalDependencies: '@types/node': 22.20.2 - '@inquirer/search@4.3.3(@types/node@24.13.3)': + '@inquirer/search@4.3.3(@types/node@24.13.5)': dependencies: - '@inquirer/core': 12.0.3(@types/node@24.13.3) + '@inquirer/core': 12.0.3(@types/node@24.13.5) '@inquirer/figures': 2.0.9 - '@inquirer/type': 4.1.1(@types/node@24.13.3) + '@inquirer/type': 4.1.1(@types/node@24.13.5) optionalDependencies: - '@types/node': 24.13.3 + '@types/node': 24.13.5 '@inquirer/select@5.2.5(@types/node@22.20.2)': dependencies: @@ -10534,26 +10511,22 @@ snapshots: optionalDependencies: '@types/node': 22.20.2 - '@inquirer/select@5.2.5(@types/node@24.13.3)': + '@inquirer/select@5.2.5(@types/node@24.13.5)': dependencies: '@inquirer/ansi': 2.0.8 - '@inquirer/core': 12.0.3(@types/node@24.13.3) + '@inquirer/core': 12.0.3(@types/node@24.13.5) '@inquirer/figures': 2.0.9 - '@inquirer/type': 4.1.1(@types/node@24.13.3) + '@inquirer/type': 4.1.1(@types/node@24.13.5) optionalDependencies: - '@types/node': 24.13.3 - - '@inquirer/type@4.1.0(@types/node@24.13.3)': - optionalDependencies: - '@types/node': 24.13.3 + '@types/node': 24.13.5 '@inquirer/type@4.1.1(@types/node@22.20.2)': optionalDependencies: '@types/node': 22.20.2 - '@inquirer/type@4.1.1(@types/node@24.13.3)': + '@inquirer/type@4.1.1(@types/node@24.13.5)': optionalDependencies: - '@types/node': 24.13.3 + '@types/node': 24.13.5 '@isaacs/cliui@8.0.2': dependencies: @@ -11636,7 +11609,7 @@ snapshots: dependencies: undici-types: 6.21.0 - '@types/node@24.13.3': + '@types/node@24.13.5': dependencies: undici-types: 7.18.2 @@ -13649,35 +13622,35 @@ snapshots: locate-path: 6.0.0 path-exists: 4.0.0 - firebase@12.18.0: + firebase@12.19.0: dependencies: - '@firebase/ai': 2.15.0(@firebase/app-types@0.9.6)(@firebase/app@0.16.1) - '@firebase/analytics': 0.10.24(@firebase/app@0.16.1) - '@firebase/analytics-compat': 0.2.30(@firebase/app-compat@0.5.17)(@firebase/app@0.16.1) - '@firebase/app': 0.16.1 - '@firebase/app-check': 0.13.1(@firebase/app@0.16.1) - '@firebase/app-check-compat': 0.4.7(@firebase/app-compat@0.5.17)(@firebase/app@0.16.1) - '@firebase/app-compat': 0.5.17 + '@firebase/ai': 2.16.0(@firebase/app-types@0.9.6)(@firebase/app@0.16.2) + '@firebase/analytics': 0.10.25(@firebase/app@0.16.2) + '@firebase/analytics-compat': 0.2.31(@firebase/app-compat@0.5.18)(@firebase/app@0.16.2) + '@firebase/app': 0.16.2 + '@firebase/app-check': 0.13.1(@firebase/app@0.16.2) + '@firebase/app-check-compat': 0.4.7(@firebase/app-compat@0.5.18)(@firebase/app@0.16.2) + '@firebase/app-compat': 0.5.18 '@firebase/app-types': 0.9.6 - '@firebase/auth': 1.13.5(@firebase/app@0.16.1) - '@firebase/auth-compat': 0.6.10(@firebase/app-compat@0.5.17)(@firebase/app-types@0.9.6)(@firebase/app@0.16.1) - '@firebase/data-connect': 0.7.4(@firebase/app@0.16.1) + '@firebase/auth': 1.13.6(@firebase/app@0.16.2) + '@firebase/auth-compat': 0.6.11(@firebase/app-compat@0.5.18)(@firebase/app-types@0.9.6)(@firebase/app@0.16.2) + '@firebase/data-connect': 0.7.4(@firebase/app@0.16.2) '@firebase/database': 1.1.5 - '@firebase/database-compat': 2.1.7(@firebase/app-compat@0.5.17)(@firebase/app@0.16.1) - '@firebase/firestore': 4.17.1(@firebase/app@0.16.1) - '@firebase/firestore-compat': 0.4.13(@firebase/app-compat@0.5.17)(@firebase/app-types@0.9.6)(@firebase/app@0.16.1) - '@firebase/functions': 0.14.0(@firebase/app@0.16.1) - '@firebase/functions-compat': 0.5.0(@firebase/app-compat@0.5.17)(@firebase/app@0.16.1) - '@firebase/installations': 0.6.24(@firebase/app@0.16.1) - '@firebase/installations-compat': 0.2.24(@firebase/app-compat@0.5.17)(@firebase/app-types@0.9.6)(@firebase/app@0.16.1) - '@firebase/messaging': 0.13.2(@firebase/app@0.16.1) - '@firebase/messaging-compat': 0.2.29(@firebase/app-compat@0.5.17)(@firebase/app@0.16.1) - '@firebase/performance': 0.7.14(@firebase/app@0.16.1) - '@firebase/performance-compat': 0.2.27(@firebase/app-compat@0.5.17)(@firebase/app@0.16.1) - '@firebase/remote-config': 0.9.2(@firebase/app@0.16.1) - '@firebase/remote-config-compat': 0.2.29(@firebase/app-compat@0.5.17)(@firebase/app@0.16.1) - '@firebase/storage': 0.14.5(@firebase/app@0.16.1) - '@firebase/storage-compat': 0.4.5(@firebase/app-compat@0.5.17)(@firebase/app-types@0.9.6)(@firebase/app@0.16.1) + '@firebase/database-compat': 2.1.7(@firebase/app-compat@0.5.18)(@firebase/app@0.16.2) + '@firebase/firestore': 4.17.2(@firebase/app@0.16.2) + '@firebase/firestore-compat': 0.4.14(@firebase/app-compat@0.5.18)(@firebase/app-types@0.9.6)(@firebase/app@0.16.2) + '@firebase/functions': 0.14.0(@firebase/app@0.16.2) + '@firebase/functions-compat': 0.5.0(@firebase/app-compat@0.5.18)(@firebase/app@0.16.2) + '@firebase/installations': 0.6.24(@firebase/app@0.16.2) + '@firebase/installations-compat': 0.2.24(@firebase/app-compat@0.5.18)(@firebase/app-types@0.9.6)(@firebase/app@0.16.2) + '@firebase/messaging': 0.13.3(@firebase/app@0.16.2) + '@firebase/messaging-compat': 0.2.30(@firebase/app-compat@0.5.18)(@firebase/app@0.16.2) + '@firebase/performance': 0.7.14(@firebase/app@0.16.2) + '@firebase/performance-compat': 0.2.27(@firebase/app-compat@0.5.18)(@firebase/app@0.16.2) + '@firebase/remote-config': 0.9.2(@firebase/app@0.16.2) + '@firebase/remote-config-compat': 0.2.29(@firebase/app-compat@0.5.18)(@firebase/app@0.16.2) + '@firebase/storage': 0.14.5(@firebase/app@0.16.2) + '@firebase/storage-compat': 0.4.5(@firebase/app-compat@0.5.18)(@firebase/app-types@0.9.6)(@firebase/app@0.16.2) '@firebase/util': 1.15.3 transitivePeerDependencies: - '@react-native-async-storage/async-storage' @@ -17334,8 +17307,6 @@ snapshots: yallist@3.1.1: {} - yaml@2.9.0: {} - yaml@2.9.1: {} yargs-parser@20.2.9: {} From 10e2be96919e35657bbf0e0515797de68e0869dc Mon Sep 17 00:00:00 2001 From: Angular Robot Date: Wed, 23 Sep 2026 13:49:22 +0000 Subject: [PATCH 021/233] build: lock file maintenance See associated pull request for more information. --- MODULE.bazel.lock | 2 +- pnpm-lock.yaml | 1686 +++++++++++++++++++-------------------------- 2 files changed, 692 insertions(+), 996 deletions(-) diff --git a/MODULE.bazel.lock b/MODULE.bazel.lock index 2f5985594341..21303bfb9125 100644 --- a/MODULE.bazel.lock +++ b/MODULE.bazel.lock @@ -378,7 +378,7 @@ "aspect_rules_jasmine": "2.0.4", "aspect_tools_telemetry": "0.5.1" }, - "last_notice": 2 + "last_notice": 0 } } }, diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 08f0650a056d..04ae53f129b3 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -290,13 +290,13 @@ importers: version: 3.0.8 '@types/loader-utils': specifier: ^3.0.0 - version: 3.0.0(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.28)(uglify-js@3.19.3) + version: 3.0.0(esbuild@0.28.2)(lightningcss@1.33.0)(uglify-js@3.19.3) '@types/lodash': specifier: ^4.17.0 version: 4.17.25 '@types/node': specifier: ^22.12.0 - version: 22.20.2 + version: 22.20.4 '@types/npm-package-arg': specifier: ^6.1.0 version: 6.1.4 @@ -398,7 +398,7 @@ importers: version: 1.4.1 prettier: specifier: ^3.0.0 - version: 3.9.6 + version: 3.9.8 puppeteer: specifier: 25.11.0 version: 25.11.0(bufferutil@4.1.0)(utf-8-validate@6.0.6) @@ -413,7 +413,7 @@ importers: version: 6.5.1(rollup@4.63.3)(typescript@6.0.3) rollup-plugin-sourcemaps2: specifier: 0.5.8 - version: 0.5.8(@types/node@22.20.2)(rollup@4.63.3) + version: 0.5.8(@types/node@22.20.4)(rollup@4.63.3) semver: specifier: 7.8.5 version: 7.8.5 @@ -461,7 +461,7 @@ importers: version: 6.0.3(supports-color@11.0.0) jsdom: specifier: 30.0.1 - version: 30.0.1 + version: 30.0.1(@noble/hashes@1.8.0) ng-packagr: specifier: 22.2.0-rc.0 version: 22.2.0-rc.0(@angular/compiler-cli@22.2.0-rc.0(@angular/compiler@22.2.0-rc.0)(typescript@6.0.3))(supports-color@11.0.0)(tslib@2.8.1)(typescript@6.0.3) @@ -470,7 +470,7 @@ importers: version: 7.8.2 vitest: specifier: 5.0.1 - version: 5.0.1(@opentelemetry/api@1.9.1)(@types/node@22.20.2)(@vitest/coverage-v8@5.0.1)(jsdom@30.0.1)(vite@8.3.0(@types/node@22.20.2)(esbuild@0.28.2)(jiti@2.7.0)(less@4.9.1(supports-color@11.0.0))(sass-embedded@1.104.0)(sass@1.104.0)(terser@5.51.2)(tsx@4.23.13)(yaml@2.9.1)) + version: 5.0.1(@opentelemetry/api@1.9.1)(@types/node@22.20.4)(@vitest/coverage-v8@5.0.1)(jsdom@30.0.1(@noble/hashes@1.8.0))(vite@8.3.0(@types/node@22.20.4)(esbuild@0.28.2)(jiti@2.7.0)(less@4.9.1(supports-color@11.0.0))(sass-embedded@1.104.1)(sass@1.104.1)(terser@5.51.2)(tsx@4.23.13)(yaml@2.9.1)) packages/angular/build: dependencies: @@ -485,19 +485,19 @@ importers: version: 8.0.5 '@inquirer/confirm': specifier: 6.3.2 - version: 6.3.2(@types/node@22.20.2) + version: 6.3.2(@types/node@22.20.4) '@parcel/watcher': specifier: 2.6.0 version: 2.6.0 '@vitejs/plugin-basic-ssl': specifier: 2.3.0 - version: 2.3.0(vite@8.3.0(@types/node@22.20.2)(esbuild@0.28.2)(jiti@2.7.0)(less@4.9.1(supports-color@11.0.0))(sass-embedded@1.104.1)(sass@1.104.1)(terser@5.51.2)(tsx@4.23.13)(yaml@2.9.1)) + version: 2.3.0(vite@8.3.0(@types/node@22.20.4)(esbuild@0.28.2)(jiti@2.7.0)(less@4.9.1(supports-color@11.0.0))(sass-embedded@1.104.1)(sass@1.104.1)(terser@5.51.2)(tsx@4.23.13)(yaml@2.9.1)) beasties: specifier: 0.5.4 version: 0.5.4 browserslist: specifier: ^4.26.0 - version: 4.28.9 + version: 4.29.0 chokidar: specifier: 5.0.0 version: 5.0.0 @@ -551,7 +551,7 @@ importers: version: 0.2.17 vite: specifier: 8.3.0 - version: 8.3.0(@types/node@22.20.2)(esbuild@0.28.2)(jiti@2.7.0)(less@4.9.1(supports-color@11.0.0))(sass-embedded@1.104.1)(sass@1.104.1)(terser@5.51.2)(tsx@4.23.13)(yaml@2.9.1) + version: 8.3.0(@types/node@22.20.4)(esbuild@0.28.2)(jiti@2.7.0)(less@4.9.1(supports-color@11.0.0))(sass-embedded@1.104.1)(sass@1.104.1)(terser@5.51.2)(tsx@4.23.13)(yaml@2.9.1) xxhash-wasm: specifier: 1.1.0 version: 1.1.0 @@ -573,7 +573,7 @@ importers: version: 6.0.3(supports-color@11.0.0) jsdom: specifier: 30.0.1 - version: 30.0.1 + version: 30.0.1(@noble/hashes@1.8.0) less: specifier: 4.9.1 version: 4.9.1(supports-color@11.0.0) @@ -591,7 +591,7 @@ importers: version: 7.8.2 vitest: specifier: 5.0.1 - version: 5.0.1(@opentelemetry/api@1.9.1)(@types/node@22.20.2)(@vitest/coverage-v8@5.0.1)(jsdom@30.0.1)(vite@8.3.0(@types/node@22.20.2)(esbuild@0.28.2)(jiti@2.7.0)(less@4.9.1(supports-color@11.0.0))(sass-embedded@1.104.1)(sass@1.104.1)(terser@5.51.2)(tsx@4.23.13)(yaml@2.9.1)) + version: 5.0.1(@opentelemetry/api@1.9.1)(@types/node@22.20.4)(@vitest/coverage-v8@5.0.1)(jsdom@30.0.1(@noble/hashes@1.8.0))(vite@8.3.0(@types/node@22.20.4)(esbuild@0.28.2)(jiti@2.7.0)(less@4.9.1(supports-color@11.0.0))(sass-embedded@1.104.1)(sass@1.104.1)(terser@5.51.2)(tsx@4.23.13)(yaml@2.9.1)) optionalDependencies: lmdb: specifier: 3.5.6 @@ -610,10 +610,10 @@ importers: version: link:../../angular_devkit/schematics '@inquirer/prompts': specifier: 8.7.2 - version: 8.7.2(@types/node@22.20.2) + version: 8.7.2(@types/node@22.20.4) '@listr2/prompt-adapter-inquirer': specifier: 4.2.7 - version: 4.2.7(@inquirer/prompts@8.7.2(@types/node@22.20.2))(@types/node@22.20.2)(listr2@11.1.0) + version: 4.2.7(@inquirer/prompts@8.7.2(@types/node@22.20.4))(@types/node@22.20.4)(listr2@11.1.0) '@modelcontextprotocol/server': specifier: 2.0.0 version: 2.0.0 @@ -761,7 +761,7 @@ importers: version: 0.5.4 browserslist: specifier: ^4.26.0 - version: 4.28.9 + version: 4.29.0 copy-webpack-plugin: specifier: 14.0.0 version: 14.0.0(webpack@5.111.0(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.28)(uglify-js@3.19.3)) @@ -824,7 +824,7 @@ importers: version: 7.8.2 sass-loader: specifier: 17.0.1 - version: 17.0.1(sass-embedded@1.104.0)(sass@1.104.1)(webpack@5.111.0(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.28)(uglify-js@3.19.3)) + version: 17.0.1(sass-embedded@1.104.1)(sass@1.104.1)(webpack@5.111.0(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.28)(uglify-js@3.19.3)) semver: specifier: 7.8.5 version: 7.8.5 @@ -848,10 +848,10 @@ importers: version: 5.111.0(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.28)(uglify-js@3.19.3) webpack-dev-middleware: specifier: 8.3.0 - version: 8.3.0(webpack@5.111.0(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.28)(uglify-js@3.19.3)) + version: 8.3.0(webpack@5.111.0(esbuild@0.28.2)(lightningcss@1.33.0)(uglify-js@3.19.3)) webpack-dev-server: specifier: 6.0.0 - version: 6.0.0(bufferutil@4.1.0)(supports-color@11.0.0)(utf-8-validate@6.0.6)(webpack@5.111.0(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.28)(uglify-js@3.19.3)) + version: 6.0.0(bufferutil@4.1.0)(supports-color@11.0.0)(utf-8-validate@6.0.6)(webpack@5.111.0(esbuild@0.28.2)(lightningcss@1.33.0)(uglify-js@3.19.3)) webpack-merge: specifier: 6.0.1 version: 6.0.1 @@ -899,7 +899,7 @@ importers: version: 5.111.0(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.28)(uglify-js@3.19.3) webpack-dev-server: specifier: 6.0.0 - version: 6.0.0(bufferutil@4.1.0)(supports-color@11.0.0)(utf-8-validate@6.0.6)(webpack@5.111.0(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.28)(uglify-js@3.19.3)) + version: 6.0.0(bufferutil@4.1.0)(supports-color@11.0.0)(utf-8-validate@6.0.6)(webpack@5.111.0(esbuild@0.28.2)(lightningcss@1.33.0)(uglify-js@3.19.3)) packages/angular_devkit/core: dependencies: @@ -954,7 +954,7 @@ importers: version: link:../schematics '@inquirer/prompts': specifier: 8.7.2 - version: 8.7.2(@types/node@22.20.2) + version: 8.7.2(@types/node@22.20.4) packages/ngtools/webpack: devDependencies: @@ -1158,8 +1158,8 @@ packages: resolution: {integrity: sha512-Aup7aUOfpbAUg2ROOJN6Iw5f9DMBlzu0mIkm/malLQFN/YQgO48wCj0Kxa3sEHJvPVFg7siR+qRInwXd2qhQKw==} engines: {node: '>=6.9.0'} - '@babel/code-frame@8.0.0': - resolution: {integrity: sha512-dYYg153EyN2Ekbqw2zAsbd6/JR+9N2SEoC7YV2GyyqMM7x9bLDTjBD6XBhSMLH0wtIVyJj03jWNriQhaN+eoCw==} + '@babel/code-frame@8.0.6': + resolution: {integrity: sha512-uMHhvmDmwFiLuiozaoRYTZHqMFuu3fem/X9JY78lohAuLoh8LSGGC8JqUzo2cVuBsBxkjMZNk56CE7ock8Xxkw==} engines: {node: ^22.18.0 || >=24.11.0} '@babel/compat-data@7.29.7': @@ -1190,6 +1190,10 @@ packages: resolution: {integrity: sha512-f/TuhuMAxJqhwxEGNsJrswuG9VHmh0oNFoQoo6TbpgtFAz9wYZXcTAcWZMHfp7ljesr0RG04bp3Aos9GI59L7w==} engines: {node: ^22.18.0 || >=24.11.0} + '@babel/generator@8.0.6': + resolution: {integrity: sha512-/pcanjdRsonCexCuxgGD8fKnBLLzk2i9uM4kmcmGyyev2R5YDs+rafMYZ89RvaGY1mW8T7C5au0TyYaEeHBGng==} + engines: {node: ^22.18.0 || >=24.11.0} + '@babel/helper-annotate-as-pure@8.0.0': resolution: {integrity: sha512-NSpMkMsvvZqzThJ0p1B02cbtA2ObEyfBvq950bmNkyxsxvcxwhvvCB036rKhlEnuBBo30bOrk13u3FzlKSoRrw==} engines: {node: ^22.18.0 || >=24.11.0} @@ -1198,12 +1202,12 @@ packages: resolution: {integrity: sha512-wem6WaBj4NaVYVdNhLPPVacES6ZJ+KBBfSkTMD3YZxbP3rm3Di85tJU5ljaUNhaOynt+Aj0xruhYuzQBt8n71g==} engines: {node: '>=6.9.0'} - '@babel/helper-compilation-targets@8.0.5': - resolution: {integrity: sha512-Qk8ahMGooH5mz6uuhoDvfZGkUf/Mf3RTBucVVl4MKx4LKMTv872TeW8O92h15iVtlN8wAROBIpI1aV6x1z0LCQ==} + '@babel/helper-compilation-targets@8.0.6': + resolution: {integrity: sha512-HTrtZ4+iA0+kzdbCgvdSk1U4pEl3BvpGnlUbualCGNbrVhhQvhgBzurTUmqpWyvyHbWYWaIfdx2mOlL9LJjsew==} engines: {node: ^22.18.0 || >=24.11.0} - '@babel/helper-create-class-features-plugin@8.0.5': - resolution: {integrity: sha512-ckUE7tmolBbW4QV02lD874sWSPy8da2A09i/h0qS+IWolR+WiNhpq7C/rHZm00uOIkUb0Cp6+0Cy1ku/wj5uQQ==} + '@babel/helper-create-class-features-plugin@8.0.6': + resolution: {integrity: sha512-Hy7wG2Pk1LnAkFMq0CbBk789XMTYVzYGxR7tKgk+TOpZckQRME3Tdou4mMT/8DFjJFxFZ8R6UsS4DR/duBKlVA==} engines: {node: ^22.18.0 || >=24.11.0} peerDependencies: '@babel/core': ^8.0.0 @@ -1224,8 +1228,8 @@ packages: resolution: {integrity: sha512-3nQVUAtvkKH9zahfWgw96Jc/uFOmjACE1kQz82E2lqWmHBgjzbNlsC22nuQTfahmWeQtTq5nQ/4Nnd2A1wj4zA==} engines: {node: '>=6.9.0'} - '@babel/helper-globals@8.0.0': - resolution: {integrity: sha512-lLozHOM6sWWlxNo8CYqHy4MBZeTvHXNgVPBfPOGsjPKUzHC2Az9QwB6gxdQmpwHl6GlQtbGgS+lj5887guDiLw==} + '@babel/helper-globals@8.0.6': + resolution: {integrity: sha512-OdnA/N52LhzFpeUuVz5YGuSWjc7TPHiFmVYZbPlSgExocO2GwbxVpSni9MVs5wwW+wZ4kPuwBEBN9pIPDYz1mA==} engines: {node: ^22.18.0 || >=24.11.0} '@babel/helper-member-expression-to-functions@8.0.5': @@ -1246,8 +1250,8 @@ packages: peerDependencies: '@babel/core': ^7.0.0 - '@babel/helper-module-transforms@8.0.5': - resolution: {integrity: sha512-lUsSqMD0l5cJKl+3vlTV/hPDA/IvNkcHWVI3zFud2Vur+C9bCKdpqbpkN9eABembedbdWwF0qow6nbdIpNlpcw==} + '@babel/helper-module-transforms@8.0.6': + resolution: {integrity: sha512-YUi+3X0cb0v97xKhuqkLdrwQtP6XXv1eVbhLRCFyMwG481UskbMQk4mjH7K/Jg3oJ1KLskvFwwq4kF/QnABkWQ==} engines: {node: ^22.18.0 || >=24.11.0} peerDependencies: '@babel/core': ^8.0.0 @@ -1286,16 +1290,16 @@ packages: resolution: {integrity: sha512-Pb5ijPrZ89GDH8223L4UP8i6QApWxs04RbPQJTeWDV0/keR2E36MeKnyr6LYmUUvqRRI+Iv87SuF1W6ErINzYw==} engines: {node: '>=6.9.0'} - '@babel/helper-string-parser@8.0.0': - resolution: {integrity: sha512-6mJgmFFFIIO82vvoLt9XtRC7/TkzXfts1t/SpRX4IHSzMgqoPYCWesVu1udUPUWioAE/2fcG6WuI8zrkE1gwrg==} + '@babel/helper-string-parser@8.0.6': + resolution: {integrity: sha512-+6HYEBnsDRZHJtUTAEfMQd0zMDqdFHS7C+5vAsEZqBUr3vEMWOWlHJ0Jz1gS8jJIlCvLsuA6ivmeoqzH936YcA==} engines: {node: ^22.18.0 || >=24.11.0} '@babel/helper-validator-identifier@7.29.7': resolution: {integrity: sha512-qehxGkRj55h/ff8EMaJ+cYhyaKlHIxqYDn682wQD7RNp9UujOQsHog2uS0r2vzr4pW+sXf90NeeayjcNaX3fFg==} engines: {node: '>=6.9.0'} - '@babel/helper-validator-identifier@8.0.4': - resolution: {integrity: sha512-4wFaiLd0bVo4cIoTXI3zKI038NIWE/cr3jvBjejOVYVxV/m8Ltav1USiGzG1fmS5J2RhgEOgXNNK46cRPnRsrg==} + '@babel/helper-validator-identifier@8.0.6': + resolution: {integrity: sha512-HYx0YmuchRxRSpnjvcNffnPS8DCauKNmnumIuHG3jnQAVewRA7kfJGwF13ayEpSZs7s4R/oBH4eppuXcAQd5JQ==} engines: {node: ^22.18.0 || >=24.11.0} '@babel/helper-validator-option@7.29.7': @@ -1318,13 +1322,13 @@ packages: resolution: {integrity: sha512-fQtPOXjYOYv85PIdwotp2TJGVYOycX0PQq+l844fFAxOULtBy8BVF35GyeueX0r4KvDthqPH5xAI1clQPk/2uA==} engines: {node: ^22.18.0 || >=24.11.0} - '@babel/parser@7.29.8': - resolution: {integrity: sha512-E8lTAYNB1KW+FH+VGJuZM1ioAx2E6oVlvQFRrf5P8ZZmsiJXYAD9vTFV7yyEURNzgh1dFqMZuO6tUwcARbqFCA==} + '@babel/parser@7.29.9': + resolution: {integrity: sha512-CjXrNHTnvqBVqHgdBysY3vk2T8tpJHb5/RMeHJBTyVa9xgugCB0CJTx/3oO8RV2QRQP391RWpB7D6hLjm8V9uA==} engines: {node: '>=6.0.0'} hasBin: true - '@babel/parser@8.0.5': - resolution: {integrity: sha512-51RXvQNFakaS0bTpYiGkxNbUVwkPO4kONv6EVLorZABxsx+KZ6Z7uSYvi/wmKS/+X+rfj9RvOw0/ZNh+cmI0Rw==} + '@babel/parser@8.0.6': + resolution: {integrity: sha512-LpGDIYJAzc3Y3PT9x+FxBrGYu2PlWxLmyN7SwPTzaX0LSwEmFJBsRnPBqmaXF2r1v+Zhz6lNiEJ+7yKtM5+Ugg==} engines: {node: ^22.18.0 || >=24.11.0} hasBin: true @@ -1346,8 +1350,8 @@ packages: peerDependencies: '@babel/core': ^8.0.0 - '@babel/plugin-bugfix-safari-rest-destructuring-rhs-array@8.0.5': - resolution: {integrity: sha512-e5eeoBASO+893sCNdFE/vQ9STIxkSRtIcQwBmLdfDOWn1nnXDY+/ngqFC5zTSUTRl0yWR3inkPRlOQD4MMHeFg==} + '@babel/plugin-bugfix-safari-rest-destructuring-rhs-array@8.0.6': + resolution: {integrity: sha512-vk9CzgaQGcTTBL8F0YNr7LBEka6pXP/I5KcMj0oicGXUquWSNqxiijHGQkHF+s8m910NbGMpn5mU2sFV7AQjBA==} engines: {node: ^22.18.0 || >=24.11.0} peerDependencies: '@babel/core': ^8.0.0 @@ -1598,8 +1602,8 @@ packages: peerDependencies: '@babel/core': ^8.0.0 - '@babel/plugin-transform-regenerator@8.0.5': - resolution: {integrity: sha512-eSjLoICd0l8SkUAyV7hnVrsDycTVK7DRKXi3Pr1oqAVe37vdd4sesp8t6aZ/Wa23rV2ZQbnYJWDn7pOIf9Z/Jw==} + '@babel/plugin-transform-regenerator@8.0.6': + resolution: {integrity: sha512-ky/yW+PcQfHyOhbQFNkcHOCIHXaEANYaXCucZ1MY1PdSJRjaf3AX/TMKS6nCij73YtU1bVNy7Zx5NWAJy42TQA==} engines: {node: ^22.18.0 || >=24.11.0} peerDependencies: '@babel/core': ^8.0.0 @@ -1702,16 +1706,16 @@ packages: resolution: {integrity: sha512-I5z7H3bf/41ktsNVLtpN0wAa336HkqIHQ5BuPLEhTkt1jVSyZpeNKIzTgEWmlxjdg81R0IgUCcaE+Ok3NvrfZg==} engines: {node: '>=6.9.0'} - '@babel/traverse@8.0.5': - resolution: {integrity: sha512-XFfnuvapSc/vJOcUO7kwORSvpBIvraofKEZ2dhT0PjiF21BRCD7YbAFC8UEeDJNeLoQz82/gVqzgX5hCzkCbdg==} + '@babel/traverse@8.0.6': + resolution: {integrity: sha512-ilYV+qLStGzSKLipJlETdvdtpK3rAuwfCmCoGKv15MU4EoeIuLkespSNoNLFGOPSciEHx9TLWtN5mv0fz5w5mQ==} engines: {node: ^22.18.0 || >=24.11.0} '@babel/types@7.29.8': resolution: {integrity: sha512-Vj1jF3cPfxg7OAfoI7QnVKLoILlm2JF9pnVHrX8qx7AHMiYWT+NDAA7jChlNgRS4WTLc/fD1lXLmPixluj+3Gg==} engines: {node: '>=6.9.0'} - '@babel/types@8.0.5': - resolution: {integrity: sha512-eVdMqi3ej5aHhyQ2Si6yD2cAWeV8FJK9UrhK5aL0Sd8hu5GhT+YswhVNbVheOGVYMg8kuGuMaUpkB3stjj4z8A==} + '@babel/types@8.0.6': + resolution: {integrity: sha512-c+xgSWboV2pdwXP67BUWDVRHi2BO5Q3KwxyFVs7taVTY+fsK47/L51ZXQoV9rozHJDNHvJ4v4WEsI/IlxV2l2A==} engines: {node: ^22.18.0 || >=24.11.0} '@bazel/bazelisk@1.28.1': @@ -1783,16 +1787,16 @@ packages: peerDependencies: '@csstools/css-tokenizer': ^4.0.0 - '@csstools/css-syntax-patches-for-csstree@1.1.13': - resolution: {integrity: sha512-i9ZylF5QNhmNfPA9l0vHAWK4kPrbIp6g9lKgaiIFsIBz2F/WNB7OLrzlNNcCOm+h42bkaSD2v1PG+IBPHhc3ZA==} + '@csstools/css-syntax-patches-for-csstree@1.1.14': + resolution: {integrity: sha512-HpbVXyrofRXpHpgkNIjU/3EWR4WJvOkO3emNK/L6X/mTJU7bGUI3AkkpoTNXznQLp0KRjLHELTGeKI5dIkI9JQ==} peerDependencies: css-tree: ^3.2.1 peerDependenciesMeta: css-tree: optional: true - '@csstools/css-tokenizer@4.0.0': - resolution: {integrity: sha512-QxULHAm7cNu72w97JUNCBFODFaXpbDg+dP8b/oWFAZ2MTRppA3U00Y2L1HqaS4J6yBqxwa/Y3nMBaxVKbB/NsA==} + '@csstools/css-tokenizer@4.0.1': + resolution: {integrity: sha512-bPlN9S9O1A0euCpEWE4qnvB5YDuyYVsUTrxSgmAM1Is0j4tICHoVyOVAXfWMP/kS9ZrjvyIXWV2PmomiAXXqOw==} engines: {node: '>=20.19.0'} '@cypress/request@4.0.1': @@ -2011,8 +2015,8 @@ packages: resolution: {integrity: sha512-IkO+/KEUvwbVpiURZg+P7zF74z5Jxe0UgJxVni+RtoHQ6IZieXaO02kmadomap/q+l6bc/jdPGGqTjhuZnuz1Q==} engines: {node: ^20.19.0 || ^22.13.0 || >=24} - '@exodus/bytes@1.15.1': - resolution: {integrity: sha512-S6mL0yNB/Abt9Ei4tq8gDhcczc4S3+vQ4ra7vxnAf+YHC02srtqxKKZghx2Dq6p0e66THKwR6r8N6P95wEty7Q==} + '@exodus/bytes@1.16.0': + resolution: {integrity: sha512-IcpW84uEn3N7ETtNZMlxKhfl6Pec8rUNGOTBtWbK1FKhJxIFAptZyVrvVRVBimAJxJCgc3PxepxkdWWG4DVzfA==} engines: {node: ^20.19.0 || ^22.12.0 || >=24.0.0} peerDependencies: '@noble/hashes': ^1.8.0 || ^2.0.0 @@ -2288,8 +2292,8 @@ packages: '@modelcontextprotocol/sdk': optional: true - '@grpc/grpc-js@1.14.4': - resolution: {integrity: sha512-k9Dj3DV/itK9D06Y8f190Qgop7/Ui+D0njFV3LHMPwPT75DpXLQohE9Wmz0QElrJnzsjB7KPWiKJbOl7IPDArQ==} + '@grpc/grpc-js@1.14.5': + resolution: {integrity: sha512-7VZM+SVdEcUUqSQeNI3zM8Qs/BhQKZndPo2h5VkYkAM8Iz0wJIa8mKV5ekQGqG8UUsnkQ0NMxIxwkIHYvj0qOw==} engines: {node: '>=12.10.0'} '@grpc/grpc-js@1.9.16': @@ -2535,50 +2539,50 @@ packages: peerDependencies: tslib: '2' - '@jsonjoy.com/fs-core@4.78.0': - resolution: {integrity: sha512-0YE5XQj383AwNj5fG0Mm1gyx/ViVe2DJzS5FeVbJulw0pteEK9mfbeB0MWH3/ARoXb2AhHHuiiNthdWF0Y6EYQ==} + '@jsonjoy.com/fs-core@4.79.0': + resolution: {integrity: sha512-bxSwMrDY71OjEdj2mAYBxSe4BnHtAOjOxqUoFJc0WsllcGgA8iYl6wRF+4aVdFUjjEyHfBwxVv0QqW4AweIUZw==} engines: {node: '>=10.0'} peerDependencies: tslib: '2' - '@jsonjoy.com/fs-fsa@4.78.0': - resolution: {integrity: sha512-V1lUo5k4xUypsfdmvCrrUJ44BCixbgvpus71WI3a3BOQt39bK2LasU/HgpJ1P9or8a2d5mWR3kk26sRoehDlaw==} + '@jsonjoy.com/fs-fsa@4.79.0': + resolution: {integrity: sha512-EdadmStAvZw4jYg4iW3mDxBmzMFSI8jcHQkSl+rIQIO7dWbPdXaB83PBQhNCCtMBeX7zwcOFjpp0ecXqbYbjUA==} engines: {node: '>=10.0'} peerDependencies: tslib: '2' - '@jsonjoy.com/fs-node-builtins@4.78.0': - resolution: {integrity: sha512-yiyMh9uKnQvRVDYzINP9P2AXZPdHYM2iVsQ/2U2V+g+gfTr4vPcT1Ox0aQs0IIXGQRAnksyA63KSqpOOJ/O3lA==} + '@jsonjoy.com/fs-node-builtins@4.79.0': + resolution: {integrity: sha512-LoBHewVHp/bZQ8Om1Iivl6NEHg7Mmby9kXJZysfnHYW4256rzXFSEcEpto1qgSAka+sq2v4N/Cnl562Z15MByA==} engines: {node: '>=10.0'} peerDependencies: tslib: '2' - '@jsonjoy.com/fs-node-to-fsa@4.78.0': - resolution: {integrity: sha512-L1e0UgRJ/igqt3JUDJh3z8YXTKqJc9r9MY4ZakEMOqqEDq/C5fmSZDDzq03d7HqdG1rehkmCDpKyXWqQEVpQGw==} + '@jsonjoy.com/fs-node-to-fsa@4.79.0': + resolution: {integrity: sha512-xFza/t81sVL4rik7h3SlcymC6X7pvNllI88LW1GESEANDXinf5lZoqju59i3AsGLyy4i0eBQvPiizWSMwCunQA==} engines: {node: '>=10.0'} peerDependencies: tslib: '2' - '@jsonjoy.com/fs-node-utils@4.78.0': - resolution: {integrity: sha512-Am25+Y/rEFtkJBZCFgs84XPXqeqXq4FvXmCYMZ0bEC/M+vT0e6tHBU4Camp9/Yzuf6NoxaInC3iXIN791wVu9g==} + '@jsonjoy.com/fs-node-utils@4.79.0': + resolution: {integrity: sha512-Rj/WevHB8DV8VyEvFGSvDD3m3JHOVk3fO1biH26iworL9/rqdUMKQQeyiKTLbdf3Z9s9vVZnn8ZC0FWZgtO2mg==} engines: {node: '>=10.0'} peerDependencies: tslib: '2' - '@jsonjoy.com/fs-node@4.78.0': - resolution: {integrity: sha512-AhoKCEEzsTU5C+9pSegNkErrQijvpHj10kzVhaXIxjs/0taxjCCLG7zE+Y+EWCMNCVmgFEyca+oTQQWm2RO+sg==} + '@jsonjoy.com/fs-node@4.79.0': + resolution: {integrity: sha512-/k18aT1X+A2yLdlTe3WKpL5y2qrvbcUY1BXA4A+s8fBfTeXfi+xdvEB85JVXVf2i9kzASQZFx8dHw9OchgMUhQ==} engines: {node: '>=10.0'} peerDependencies: tslib: '2' - '@jsonjoy.com/fs-print@4.78.0': - resolution: {integrity: sha512-Uwk0SvDN1X+5FNW3MxibrFVXXUnd0nTUP6qwvPikg3QDeXRiRww91mz34lXYa/xO5eVuUqa1WXmd0ljy1+Ej0w==} + '@jsonjoy.com/fs-print@4.79.0': + resolution: {integrity: sha512-Bp5Q+OV1Dnl8oKf8hVhmboeI+NWbWRk1GxtJzuRvopDeNBDBh0RLevEsfnOVtwBwgRZaptSXn3e/mm3kbOzfDw==} engines: {node: '>=10.0'} peerDependencies: tslib: '2' - '@jsonjoy.com/fs-snapshot@4.78.0': - resolution: {integrity: sha512-+HvPGwV1IcXtwFFxMBK5x8rmqBuIkPpEFZMGkO8BolJH+AuSvQGVwvlKulUjQ9KECpN4GTCcgeQtyUvYC8heSA==} + '@jsonjoy.com/fs-snapshot@4.79.0': + resolution: {integrity: sha512-/GY+eMvOl4ZQHUnrKYjC/t3N0BImBg7zv/cAGm3kiwUfqSQuo87jtbjmD3mzgQMv16K8zttkHE2wT9GaVsehvA==} engines: {node: '>=10.0'} peerDependencies: tslib: '2' @@ -2835,9 +2839,9 @@ packages: resolution: {integrity: sha512-xJIPs+bYuc9ASBl+cvGsKbGrJmS6fAKaSZCnT0lhahT5rhA2VVy9/EcIgd2JhtEuFOJNx7UHNn/qiTPTY4nrQw==} engines: {node: '>= 10'} - '@noble/hashes@1.4.0': - resolution: {integrity: sha512-V1JJ1WTRUqHHrOSh597hURcMqVKVGL/ea3kv0gSnEdsEZ0/+VyPghM1lMNGc00z7CIQorSvbKpuJkxvuHbvdbg==} - engines: {node: '>= 16'} + '@noble/hashes@1.8.0': + resolution: {integrity: sha512-jCs9ldd7NwzpgXDIf6P3+NrHh9/sD6CQdxHyjQI+h/6rDNo88ypBxxz45UDuZHz9r3tNz7N/VInSVoVdtXEI4A==} + engines: {node: ^14.21.3 || >=16} '@nodelib/fs.scandir@2.1.5': resolution: {integrity: sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==} @@ -3193,44 +3197,44 @@ packages: resolution: {integrity: sha512-7FNeNl8NCE7aINx7WXiKQrPYZWC/hvrTsmk6zmxbI7LTXE7hVek/n8AfVgpe2y82zl3w0HvCHN0bVKMBoJcC0w==} engines: {node: '>= 10.0.0'} - '@peculiar/asn1-cms@2.9.4': - resolution: {integrity: sha512-cben7oxmQsUGZqotus7yt0srYdncOT6RNWcTQ77T2RFOXejYVYkXadrfePdRcrVpO9K95IRLKKglG2k38jKXuw==} + '@peculiar/asn1-cms@2.9.5': + resolution: {integrity: sha512-4Ivz0fsyFofe0bslNsYcGN9+iETdHX4v+BFwIPr+K/BAt61sHXECP63ff9FntU9zcfVQELJFdUG9so44OjUlBQ==} engines: {node: '>=14'} - '@peculiar/asn1-csr@2.9.4': - resolution: {integrity: sha512-xd4YN4vpRjkDAQWVfZZkeu12IEND7DOpkqaHSIHxZl1uggUNa9Ju0QxY2jHvDAS9pP0zhRBytg8ifsnGo3V0jw==} + '@peculiar/asn1-csr@2.9.5': + resolution: {integrity: sha512-9dO6PcoJeI+1xJ4rG7eINMa6f9Ix/QdRs5UGZ0D7v/R3TzmsbVr5cqAgfYw4xgS9U54ouHYqEz0bIZBbM/UY1g==} engines: {node: '>=14'} - '@peculiar/asn1-ecc@2.9.4': - resolution: {integrity: sha512-JJXefFshRAuVAjWQo/39bkg1ywc1VaiO44S8RRC+Ykvf/u2KDmYffoDb0ZBPCR5uJy4AGKQhl8mX+Q8ShcWaXQ==} + '@peculiar/asn1-ecc@2.9.5': + resolution: {integrity: sha512-OD+HLlcV7wCL64w0rheX/C0J31DbJce0nf8ulv3UNftQ617JEZE3sQ4cMN6PotXWlJ1M5GQx90G3bywtdKOstw==} engines: {node: '>=14'} - '@peculiar/asn1-pfx@2.9.4': - resolution: {integrity: sha512-khuGzHTzNzk4GDlIBEILyIs6Lce0yn0ZBdoI9v93kmNncfZRhD+AQ5ODFqdhvoE8cMJF/JMTQ8yA+t1D14kqCw==} + '@peculiar/asn1-pfx@2.9.5': + resolution: {integrity: sha512-btcH7lbcD4410qnjHvv7F0kEuMNKbX8CFAZSs9CDPWHKzT1byLPHYeR40AnUw9z4CzsijMY0daBFYUvVx75sdA==} engines: {node: '>=14'} - '@peculiar/asn1-pkcs8@2.9.4': - resolution: {integrity: sha512-duRdotlUx9eDZe6QrQpQKl61RbWykCHBCkKayP8V8XdEFwlKHZ8qGGDMyS6Pye7OX7nLFttTTpRkJeet78ckwQ==} + '@peculiar/asn1-pkcs8@2.9.5': + resolution: {integrity: sha512-c7UghAGQdBfAHL9JdwcJkAc/lDJKNXfCdYXPXlf8BZdD/fVJjJnXKHxX4gyLhkFTvnGhME7caieSgc2ROtqYTQ==} engines: {node: '>=14'} - '@peculiar/asn1-pkcs9@2.9.4': - resolution: {integrity: sha512-kaL4cNxBpdQE2dKlyZBqz4ygCrwffO+8wfoxTEqM1Z8RadvCeELBRzcv0dzM8aY9azHMwODO5nxU65zXmhToOQ==} + '@peculiar/asn1-pkcs9@2.9.5': + resolution: {integrity: sha512-4R/zMgLSHbQIZRBwP1KzX6iuNHmW3xFWwu9TS9A00N60fmQqp9DkkqnQFyd0mAYMQTrQefuzQ/yP4U8sOLGUgQ==} engines: {node: '>=14'} - '@peculiar/asn1-rsa@2.9.4': - resolution: {integrity: sha512-pZ96eD1PptovcWQ/GSmuNFXd/7EQJNlKfDaNCyE2rx3W0v6QFelkzquVqRSRyyDXXCYD69ZXJDzZ8GhIiQzKoA==} + '@peculiar/asn1-rsa@2.9.5': + resolution: {integrity: sha512-kHwBLVMkm9ljlM521ovS7y4z4mr8xuHTdNyyoPlDvckBwFKSgs9HqKBryLBeqHqL2YpIgl+Vspl7kzNGG2phzA==} engines: {node: '>=14'} - '@peculiar/asn1-schema@2.9.4': - resolution: {integrity: sha512-GjzePcT9Iw8NzeOPf73iNS9xM+TBhd/FilAfP+RQGkTMQJTVWtytN3JHJACCjf/ABNau5S7mS3g+DcuxmRgYEg==} + '@peculiar/asn1-schema@2.9.5': + resolution: {integrity: sha512-Ez3wLKVjaxdsLcgeWN4OE31QkM7oBOgKuuBJxldRYAkfYw2C+8zJPcSd/SThnbhszsEOlAmoaS5kIIkN29fGKQ==} engines: {node: '>=14'} - '@peculiar/asn1-x509-attr@2.9.4': - resolution: {integrity: sha512-ehQXbpQaQYycgu8OrvigwSPTFfVRcu0ECNYCWw+yzBp02Lw5paRqzzhUpfOgO2K38+WfFZuEz/0RPtam5g0OMg==} + '@peculiar/asn1-x509-attr@2.9.5': + resolution: {integrity: sha512-PlbL1a74RZiry7puPCZ5hdk/puvivxYJPbjadr2i7DBjHCJFEKCfTRPKL3DILeZFtzJjn95J5EBtSc4/TB9/6Q==} engines: {node: '>=14'} - '@peculiar/asn1-x509@2.9.4': - resolution: {integrity: sha512-CxhBo/RdEbMMob7T31ZdQjGuoyRFLVwrDzTn25bihzBasRg9kRm/0IxIPvhgQtcK/9dNcO1XQL2fuPugwELL0Q==} + '@peculiar/asn1-x509@2.9.5': + resolution: {integrity: sha512-NP3ecvN6zTDlwCvogIWL7MJN9AZNuskkIbnlhrlkB97Mn2EqirBUQ8GKzsOmdAL3pRvjGu1Uk/a4DNfiZrWxhw==} engines: {node: '>=14'} '@peculiar/utils@2.0.3': @@ -3708,8 +3712,8 @@ packages: '@types/micromatch@2.3.35': resolution: {integrity: sha512-J749bHo/Zu56w0G0NI/IGHLQPiSsjx//0zJhfEVAN95K/xM5C8ZDmhkXtU3qns0sBOao7HuQzr8XV1/2o5LbXA==} - '@types/node@22.20.2': - resolution: {integrity: sha512-xlvWf4Vs9n1PEVYwP1n4vvG07M6y8WgvJ2t0vbrWTmijsIHp1cS+uJ2kMIRdY3nHZK0nCYKrPeD171+SzF4/zw==} + '@types/node@22.20.4': + resolution: {integrity: sha512-zJRE40jpHtKqE/C4fgHrAKQLJuSpzEnP9ff9Y7YtoR3Wd2pwqzlekDeEuUQXjRd+QCYnVnNwuJYmhdk9XV8gvA==} '@types/node@24.13.5': resolution: {integrity: sha512-TXyindR+lBr22aJIdMQzCFHPHR6cR4js838mRDCSz5hOKWZvZwsXSSiXDmjRj4iJmgl+sR9O+1mkoVBSMadNug==} @@ -3822,6 +3826,10 @@ packages: resolution: {integrity: sha512-asTOIYhDg4zdzOScCyaytrsV3cR6B4ecPQlXw/dJIm7J/MZTtCtfVII9JD8Geh4jTCrK/Xe6cg5UevoleMcoJQ==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + '@typescript-eslint/types@8.70.1': + resolution: {integrity: sha512-Dm1ypdhhrGCTyyehxElhgJ6kgk8MVCv5qXdoOVqPr1uqk42jX8KjrZqhROvdShczA8qrDoYiOWn1ykWlx2k81Q==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + '@typescript-eslint/typescript-estree@8.70.0': resolution: {integrity: sha512-d9NmHMPEKQ7QCLLm1jI3zmoQBwT5KwFYjXBJ9ymZfKCUU+5rmTRykKAFvH5Qn/ZCds3CEAFS9OC9M/jkl0X2bA==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} @@ -4005,140 +4013,140 @@ packages: '@yarnpkg/lockfile@1.1.0': resolution: {integrity: sha512-GpSwvyXOcOOlV70vbnzjj4fW5xW/FdUF6nQEt1ENy7m4ZCczi1+/buVUPAqmGfqznsORNFzUMjctTIp8a9tuCQ==} - '@yuku-codegen/binding-android-arm64@0.9.5': - resolution: {integrity: sha512-jrOY5WM+AaAqkv51fHP1x28ifto4WgcZVzodLUyMU1jMWn5Sq+VciRdk/n8E0Ey5w4p4cWWE+m5GfXWOYh7Kzw==} + '@yuku-codegen/binding-android-arm64@0.10.2': + resolution: {integrity: sha512-Oc2KInVkPfUjEB4PeV6X0NvIoyYTzDe/WmqFrTwBqKs6YKnz4A7XwWQvJTb7M0rLz9a6WgpUUiiS5QKaCi4O/g==} cpu: [arm64] os: [android] - '@yuku-codegen/binding-darwin-arm64@0.9.5': - resolution: {integrity: sha512-4O4lkCQIzPZGjiNB1GORSI6hBECbiiSBS/APZXPvNKYH+nhY4uuqv03LNXA+SET3hoBjvr95P5rIhY8KQaQUBA==} + '@yuku-codegen/binding-darwin-arm64@0.10.2': + resolution: {integrity: sha512-3H7eNPIHJndUJXZ4QUGBPq1zC6RGcUZfm7bymJes+/N7wTVWUn1bxZ9JcozYHpkWQNm9f23G8YWbaHD9aYH72A==} cpu: [arm64] os: [darwin] - '@yuku-codegen/binding-darwin-x64@0.9.5': - resolution: {integrity: sha512-9EvoUO0SEhD6/d8VHdWuPerepPMSR1y84+UEgz8Un1Ope14Oe7xMvePpEQLTLovoIFZ8Zg3iZ8z8E11pZMqC3g==} + '@yuku-codegen/binding-darwin-x64@0.10.2': + resolution: {integrity: sha512-AJOUpR2s3LF9AWiiub/Uyc/UoXNTWcq8hK3cVI6fUSXtwh34dG21J6hRuNlO6JVJFTo4o3ScVvZOrh/YFfUEAA==} cpu: [x64] os: [darwin] - '@yuku-codegen/binding-freebsd-x64@0.9.5': - resolution: {integrity: sha512-HqT78WwgHTmp8lwujoUa9CrIortX4DdpuiVC18ZPSGvuuJf4ylpIEI6QrQEM78Zwz3muhAWAOXZ5irdiYY+AyA==} + '@yuku-codegen/binding-freebsd-x64@0.10.2': + resolution: {integrity: sha512-ms7DcZu87u5CiK/wMwvpKAvAmtaqKjCQIXNweMLypG6qbuiaOMQf1jpbB5+j46xBcgCovo8TQMcv0bCQLKIL9w==} cpu: [x64] os: [freebsd] - '@yuku-codegen/binding-linux-arm-gnu@0.9.5': - resolution: {integrity: sha512-QJXwIW6Ms3QIawbcBIedmrmXnfdpuAOjZJ/eAABq5XTzWvSxZ7lutu9W5yIHahlaTaFnBo7ikrVMD1szLTpPUw==} + '@yuku-codegen/binding-linux-arm-gnu@0.10.2': + resolution: {integrity: sha512-xJDpYAsKV5+eaiBhTYl05fvT6sst4PsCeuIFMRu9b0/WCSrNQPfCDtAQ5/MS6xNpsdujdZEPR+gmfWk3ZG5i3A==} cpu: [arm] os: [linux] libc: [glibc] - '@yuku-codegen/binding-linux-arm-musl@0.9.5': - resolution: {integrity: sha512-eHbFy3IHGb+IYarrYwAo0yWSEQV3eAmEn6VrsKA6I1Wy1YPJxWqSJlV69JhqsHtJuJlljUIF3ex0y46yaKIu9w==} + '@yuku-codegen/binding-linux-arm-musl@0.10.2': + resolution: {integrity: sha512-qfTkgd7AEx61l4K9VtXWCGTxc/fmXJ4ZheDz3i+/AAJUtg4sa0bPrc0VBxPggB/rayR8Z3+JfrBItuyanBJJ9Q==} cpu: [arm] os: [linux] libc: [musl] - '@yuku-codegen/binding-linux-arm64-gnu@0.9.5': - resolution: {integrity: sha512-ByoJMbySTaDhjAXSu8q6Lh7HKg3YoesXpcT72aYk0Aiw4PCznmY4ybpLTq0RCvp0RIPhFm/6yECFiGBwyCC1nw==} + '@yuku-codegen/binding-linux-arm64-gnu@0.10.2': + resolution: {integrity: sha512-4e6Mifm/4UdjtU3D8mATIrvgP+xEiH8xtQOjd0zpd72XKWT7ug3sdyhq2utkkZFP6BvYp7SgZrI+aR4VeIOHdw==} cpu: [arm64] os: [linux] libc: [glibc] - '@yuku-codegen/binding-linux-arm64-musl@0.9.5': - resolution: {integrity: sha512-gD9vfXIoBw1toSxhO9rgmSu/FEfy3PMznJAxVjIuH8DrWEiDKXmJO0pJKfj1Ltbe/TmtWVZR+TjISqeSIGQzMg==} + '@yuku-codegen/binding-linux-arm64-musl@0.10.2': + resolution: {integrity: sha512-RdsJrUfDYFVV3JOmWFUWwSu31fa1APn12xDeIKxgl/YWxrabwtxsDBNjF2561c7tmcbiewdCUvngqRs8AyGVLA==} cpu: [arm64] os: [linux] libc: [musl] - '@yuku-codegen/binding-linux-x64-gnu@0.9.5': - resolution: {integrity: sha512-BARvdnvqMGjOr5Iel2JH+9H5vAIE0R6H0Z2fsT02xrvmI/1ZXNB8lkuX+ZGevPhZb3zJ9WeC/R8JZstrsUOK5g==} + '@yuku-codegen/binding-linux-x64-gnu@0.10.2': + resolution: {integrity: sha512-mVzWimEPPreaPyXIUvxsHoJzvO7ckZ5j0LgQFHz04zQIRwt9A9T2hA7K5/jYjJKkMxWG/U2VjhGNwVhtyU+uqg==} cpu: [x64] os: [linux] libc: [glibc] - '@yuku-codegen/binding-linux-x64-musl@0.9.5': - resolution: {integrity: sha512-x8flcevS1fbb7ESrmpOY/pON4eInSaE/7Ktjqx2udOE2W33BNSZmJuwpyUgo54AoHNqrcaM7szqydyJn5fNvew==} + '@yuku-codegen/binding-linux-x64-musl@0.10.2': + resolution: {integrity: sha512-Y77fyISurmr2mvO1yeq3u+x/WJbACgPR4w+lzEVx30ViCxZzIGrZPRN1yEdZ9xUNPNsIO5thBHIdRNG+UGUG+Q==} cpu: [x64] os: [linux] libc: [musl] - '@yuku-codegen/binding-win32-arm64@0.9.5': - resolution: {integrity: sha512-KOL/rBatWqH4ZpCNoF8ZtSNdOJbAxBJLmk/VeRciepGROPTbPum1A9t67GpFgOU7qrkUWlPJdJ+KHKbvbmOt+w==} + '@yuku-codegen/binding-win32-arm64@0.10.2': + resolution: {integrity: sha512-1+tGLyG0u5YYy0lev4ck7/0sd8xJ9SZde0dLut7qLDPZV5WVTV8x6OxNXUne/PGuHZyO1vK+txPQzzHOyXHGSw==} cpu: [arm64] os: [win32] - '@yuku-codegen/binding-win32-x64@0.9.5': - resolution: {integrity: sha512-FxENahEjWSan59Syh/us/Kf4wNq8qrJLFJ3R2N4Oiwtb6yNdz/rWLNTIoNSssnsp7IoWJdUP6o/Z8ppg7lXMcg==} + '@yuku-codegen/binding-win32-x64@0.10.2': + resolution: {integrity: sha512-8a2SExRohRbwC0MY4VpOF0/RSckrJ2ASZqAor5/RYSJJaeadR93n10gZzcKT6pY9ukiSOIZCRKVRD2tH73T0qA==} cpu: [x64] os: [win32] - '@yuku-parser/binding-android-arm64@0.9.5': - resolution: {integrity: sha512-A2JCFCSHfnficqYEw4Iujpx7XrkMM3UfFcgJFmYpZSo9zM4nyhmdIIE0FogSduuU60lhM0/UcfuUBXIVNBMlGQ==} + '@yuku-parser/binding-android-arm64@0.10.2': + resolution: {integrity: sha512-2VPBU9fRGRAQ2xPAvghnec3oou5Nrxm2Bezhf+13UMspAxQSkF/32r+ySKXSwIPA5/RivumDJDxAxc301Sgicw==} cpu: [arm64] os: [android] - '@yuku-parser/binding-darwin-arm64@0.9.5': - resolution: {integrity: sha512-3PiyU+Eare4YuKaQ22N98/yAiROPY5o/NQJHraICzDvk4pgS+m+bgLKOvkGBRn33OnV95Vdv1Mn38b+MQHpULQ==} + '@yuku-parser/binding-darwin-arm64@0.10.2': + resolution: {integrity: sha512-LD+PMZE51tCYTOss5HBkm3/AE39MvcMDBfWJx7A4yDcjfNbAQDnHZKtzSOuqrswx+TQHY0ws5xn6+fWOwtmfBA==} cpu: [arm64] os: [darwin] - '@yuku-parser/binding-darwin-x64@0.9.5': - resolution: {integrity: sha512-blFMAFI7AInI83XaiOF8cIeiRM46Nz9EfpZtZPRLbKxSA9aAr5v8aHYpmfN6NoyXxAv/10pwS4gsAuc1W6fy5Q==} + '@yuku-parser/binding-darwin-x64@0.10.2': + resolution: {integrity: sha512-mmZ8cND+AoIIMRERyMinlg5ApHxP23B9jH2B5wT7T+dliPa9rubLxneB/SUjFwyUjGaFnB5G7t4YvpfbO5zbkQ==} cpu: [x64] os: [darwin] - '@yuku-parser/binding-freebsd-x64@0.9.5': - resolution: {integrity: sha512-TsNuL4qsZdO0tHp5GW43Y5fHeLPpPHA675wdcPNTcdq2ZO5AvsQWFFoiDg8CH4oBktfsQ9tdvKhjLnLYwKvp4g==} + '@yuku-parser/binding-freebsd-x64@0.10.2': + resolution: {integrity: sha512-gVIjaaIddbRfAhHlC8N809wQWml7mxfSVnzaLtzGXObTeFTPAg/YVnQXt1UOhPM1ah5eG/8Y0RUlNpB4GVe7eQ==} cpu: [x64] os: [freebsd] - '@yuku-parser/binding-linux-arm-gnu@0.9.5': - resolution: {integrity: sha512-b0afYK5gHeV8RdmOcqAlgM8ONsye4cax4DMnIBaoJyPMd1UTGvTbpkqQcPVdhmHlcfcGVGMV1laeVovlr/dscw==} + '@yuku-parser/binding-linux-arm-gnu@0.10.2': + resolution: {integrity: sha512-q/XPPQQAPdlw05aPj30ygBhekmQryGOwxVraBgApjKK8yY1kNQgqq6XCYLF1WHSee+lhxclrTO7W0/bt7dR1GA==} cpu: [arm] os: [linux] libc: [glibc] - '@yuku-parser/binding-linux-arm-musl@0.9.5': - resolution: {integrity: sha512-fD3lKzl+r6j6n8DwiMY53qnh5DLqD8KJjCp+NbVud54Nnh3Q9Wprqss3YzyMHP3NSJk663Wlg1E1X5qOuFVFig==} + '@yuku-parser/binding-linux-arm-musl@0.10.2': + resolution: {integrity: sha512-A+Cb0I1hFF4wilTQpWs79k1aNnj4B2tkrHx3zsuUNF9BtVY2zPZ4yeQEM/zjXrS/qJlNMZVK9NrWJjwdpnTrfg==} cpu: [arm] os: [linux] libc: [musl] - '@yuku-parser/binding-linux-arm64-gnu@0.9.5': - resolution: {integrity: sha512-aRU/aCphV1MWCl/lvI6NX8LgucHQ68Fx+vz7NBb/5MEr2EuzCxiPOQqeFcMdWh+2AED/p0AvAREch0c+cSnlhA==} + '@yuku-parser/binding-linux-arm64-gnu@0.10.2': + resolution: {integrity: sha512-aGNSzqIqqphFwAdIFwVvKIyXD1Iy3CxrEJVIZAT87Ecyi4vCmmDD2v2l9h+Gd3/wSy3JZlOI792LJbKAjyy9rQ==} cpu: [arm64] os: [linux] libc: [glibc] - '@yuku-parser/binding-linux-arm64-musl@0.9.5': - resolution: {integrity: sha512-5+Guro0l8H473YXlEjVNBRLN/IbPbJdnQh1zo0OLt49xxnON+XMJRRaEyTOTfkn9QSRg0+BhEKGR4W9Gu2uZJQ==} + '@yuku-parser/binding-linux-arm64-musl@0.10.2': + resolution: {integrity: sha512-Ddl1sF0rtuCXyHGSOV6dcmdx+ETv1iD+IVFqQuOjzkJZWclxJxdBWX6ZJMRtTiGqGUTbqLEKiTXxpR/Bvqk+2A==} cpu: [arm64] os: [linux] libc: [musl] - '@yuku-parser/binding-linux-x64-gnu@0.9.5': - resolution: {integrity: sha512-pwwSyV9q+GlvzSXlsMZBMlgk22L5bud714/vqZCdeUTivzeUVltQzUaf3IQXOGXdpc59JYTeuMCtbGquaAUoCA==} + '@yuku-parser/binding-linux-x64-gnu@0.10.2': + resolution: {integrity: sha512-/nlcpR6IF5U+0m5L9wvAIXeQa2DT+BXuvqKDsTcOTlcc0B4dHNyqE5hTXsS4hAyimpy2ZK8A1zMNF5hTrjg2cg==} cpu: [x64] os: [linux] libc: [glibc] - '@yuku-parser/binding-linux-x64-musl@0.9.5': - resolution: {integrity: sha512-z18j6JN3lBHH8vzN7gG1M8fI0nlgItSfnC9PfbmUbt97iHViKfw2iA2G9fGwRMe5LyPRZBrejIlapbygPbpdaw==} + '@yuku-parser/binding-linux-x64-musl@0.10.2': + resolution: {integrity: sha512-GX80dxTQD/M/OryyuxJcFzFENzry3cDFPvCFTyWogNWQH3fSHfMrNfpwpl1YzMos1eV9NygK5GSDG7VArQlb4w==} cpu: [x64] os: [linux] libc: [musl] - '@yuku-parser/binding-win32-arm64@0.9.5': - resolution: {integrity: sha512-s6Gwttb1dQvtPX6Bgkw+UPC9IO3UBDXc6Zezog8MMgvu3UfJBBB9TQqKBX/2quu0Eyh+lLSAyNlIyyecaagUPg==} + '@yuku-parser/binding-win32-arm64@0.10.2': + resolution: {integrity: sha512-agePQBV4VHewiGU0ACSjscZ/hJd283f9JfAF19Gf1rI5+wy5tTgx4GS36i0b3xim15AQ4RCpDRosEvhLZ4zAOw==} cpu: [arm64] os: [win32] - '@yuku-parser/binding-win32-x64@0.9.5': - resolution: {integrity: sha512-FrERt9YWatY3bJfSUdi4YWY+6iQcyo3MzCC821BxlWM5TFZEHijnpz/bknR79VHlXY/9CvXz8ZlaAGPsTtN3nw==} + '@yuku-parser/binding-win32-x64@0.10.2': + resolution: {integrity: sha512-s8//CMpgL5+y1lvDCdyh1rwGI5+ytDJywFJRe1vnhI7n0j+caxshNucurikYLLVeQ2SYFex6aPrzgQxkabBQRA==} cpu: [x64] os: [win32] - '@yuku-toolchain/types@0.9.5': - resolution: {integrity: sha512-KiuLNNgX9uNealaWAR+G3/cMXnRk9x4TY2EkYe/KIag+UPdwiA0RRf1hr1WAxzTP8KGzCTkqUdLPvqh32sEO3w==} + '@yuku-toolchain/types@0.10.2': + resolution: {integrity: sha512-sSeo4SSSToiS+sSD+bwn/s94EEcaLJ7tG5LCp8gFYC1G5VzxzX7fqB6m9RU1yMD8KTpu6zdU/I1NlQf8hVBJ9Q==} JSONStream@1.3.5: resolution: {integrity: sha512-E+iruNOY8VV9s4JEbe1aNEm6MiszPRr/UfcHMz0TQh1BXSxHK+ASV1R6W4HpjBhSeS+54PIsAMCBmwD06LLsqQ==} @@ -4303,8 +4311,8 @@ packages: resolution: {integrity: sha512-Izi8RQcffqCeNVgFigKli1ssklIbpHnCYc6AknXGYoB6grJqyeby7jv12JUQgmTAnIDnbck1uxksT4dzN3PWBA==} engines: {node: '>=12'} - ast-v8-to-istanbul@1.0.6: - resolution: {integrity: sha512-fvpl29helSO2w/z7utIbrkNXILdrLwDwAMH2I/zPKlGf5244+gf+B4cyS1sANcrPY2h+hWCGSgC8N61s/+AF9A==} + ast-v8-to-istanbul@1.0.7: + resolution: {integrity: sha512-kFL68AG6ajd8fg248zwM9GQrUWEp79gsmjum34OEXjs4yHuUMZfYKwOLW9GMmB4oNvVrj+EAGxsP7ye2UR9UlA==} async-each-series@0.1.1: resolution: {integrity: sha512-p4jj6Fws4Iy2m0iCmI2am2ZNZCgbdgE+P8F/8csmn2vx7ixXrO2zGcuNsD46X5uZSVecmkEy/M06X2vG8KD6dQ==} @@ -4422,8 +4430,8 @@ packages: resolution: {integrity: sha512-lGe34o6EHj9y3Kts9R4ZYs/Gr+6N7MCaMlIFA3F1R2O5/m7K06AxfSeO5530PEERE6/WyEg3lsuyw4GHlPZHog==} engines: {node: ^4.5.0 || >= 5.9} - baseline-browser-mapping@2.11.23: - resolution: {integrity: sha512-le521dGVfxM7yRX0EikCoSz+rOK+hHzdDt/E7mG1jOJB/6WAAUuwVroLwaB7ApaUsz5Q0kFlDXLSA9MheUIfRQ==} + baseline-browser-mapping@2.11.25: + resolution: {integrity: sha512-gMmEShwwq7FJqMwvfRwvCl00v4kN+KOfJqXn+f4nrufak5gNHJOksd/60Dvjuz7sI8Y5WiSFBa8FEYr+zoyqCw==} engines: {node: '>=6.0.0'} hasBin: true @@ -4474,14 +4482,14 @@ packages: resolution: {integrity: sha512-DkVaaQHymRhpYEYo9x1oo7Q7B0Y6KJUsjm3c9eTyFDby4MHLBTwZ6ZDWBel5zrYxj1WsZgC5oLpiz+93MluXeA==} engines: {node: '>=20.19.0'} - brace-expansion@1.1.18: - resolution: {integrity: sha512-Edep/X9fGqVNmzKBVsDYIOtD+z1tuezV70LBjdCst9Tqu76lsnvRiZ6oTic1n+/BIwX6QDGAO94PN4N2SADvtw==} + brace-expansion@1.1.21: + resolution: {integrity: sha512-9zeA+KLZNNzglF2TPKRQEDyx6Yby7daAkuy8MiPzpXPsYDWi/DRM8jmwUDxokQjYqBpv5DgPiwD4h4ZZSy1Ujw==} - brace-expansion@2.1.4: - resolution: {integrity: sha512-hGfVzPxthbf3+2yjg/RBs60cB0FhqBS/zvdV/4wn4/BmN0bNMMHPc4V/BbFieqf1TKAGGAHnY4eSjajCl0f2Xg==} + brace-expansion@2.1.7: + resolution: {integrity: sha512-uZbew1NqdmPDTMJ8ah1y+b+9QEJrfkXFk3RcTQw3X0jW/xRUvFKsg1CfQdSYGdTbXZWExtU3J3ccxtnfw1Fi0g==} - brace-expansion@5.0.9: - resolution: {integrity: sha512-ScQ4IuvIEF1TMlP7Zt+vjJ//9zlPb2SDcxWxM3bk8s6t6GGdJ7KO1dCcTidOPJKePW30LE/2cT7wCyPho9/Wxg==} + brace-expansion@5.0.12: + resolution: {integrity: sha512-YovQ3rzhaLMIrDjNDMkNS01tea93qhEhG5xy8f6+R0l+dw3Ki+5sCoIoI942iuLZTHWogWktgwVDhU09iNEimQ==} engines: {node: 20 || >=22} braces@3.0.3: @@ -4506,8 +4514,8 @@ packages: browserify-zlib@0.1.4: resolution: {integrity: sha512-19OEpq7vWgsH6WkvkBJQDFvJS1uPcbFOQ4v9CU839dO+ZZXUZO6XpE6hNCqvlIIj+4fZvRiJ6DsAQ382GwiyTQ==} - browserslist@4.28.9: - resolution: {integrity: sha512-EWazOblFYUvlGZcfGhPUPmYh3nikUxBVb+y9MJun5f3hBi812X+8MSQTujLBtgK3cf51fJWbWfOjyeO954d+Eg==} + browserslist@4.29.0: + resolution: {integrity: sha512-3GSvyjvDI4Dur1Meg2BekJquu5uF+9R9a1+5M1Mde192eZoXbeXjzgOsgqPS2V8D5wrrip0gR5Hf/GhWQ9ZzaA==} engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7} hasBin: true @@ -4738,8 +4746,8 @@ packages: resolution: {integrity: sha512-mj7UPXE0jaqaOsukNZRUEfEi2AcL7C/vwmwcHV0O97eO1E1pxBZuyjlZrx5seTaNBg1U6+o35wpa35Qfcc+7ag==} engines: {node: '>=18'} - content-type@3.1.0: - resolution: {integrity: sha512-z26wZR7iXahgpSK7XgnB4IbRVmUNSODvsX9qC9TAru7AcWGiqn5YKy+OH3PLRrwyAnewykKhCqnD+VV3a8uT8Q==} + content-type@3.1.1: + resolution: {integrity: sha512-GW4qUsfFo59d0HbUibDlWv5wPz+vAAcaTWbKIuKCf0JkC7wWkSyf8f13IpXn5JkeMlB2P8iTSSIjwXljorg2vA==} engines: {node: '>=22'} conventional-commits-filter@6.0.1: @@ -5046,8 +5054,8 @@ packages: engines: {node: '>=0.12.18'} hasBin: true - electron-to-chromium@1.5.427: - resolution: {integrity: sha512-n14zb3FdsChZ2BNobqNHAJMcP3ifFv4paox2LvCrfVAQcqGiSURgbJl+PfMpHVCNFkStnNc+RRVtPBTVW5PDgw==} + electron-to-chromium@1.5.434: + resolution: {integrity: sha512-7EeFW9OLf1NN9NKQP9xdOE/XKqjxv7JDPP6AEAkHli11+Fae1OaLoNuAf13hQv1PPNtuES0pLQSPk2+fS3s8ww==} emoji-regex@10.6.0: resolution: {integrity: sha512-toUI84YS5YmxW219erniWD0CIVOo46xGKColeNQRgOzDorgBi1v4D71/OFzgD9GO2UGKIv1C3Sp8DAn0+j5w7A==} @@ -5062,8 +5070,8 @@ packages: resolution: {integrity: sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q==} engines: {node: '>= 4'} - empathic@2.0.1: - resolution: {integrity: sha512-YGRs8knHhKHVShLkFET/rWAU8kmHbOV5LwN938RHI0pljAJ1Gf6SzXsSmRaEzcXTtOOmVqJ5+WtQPL5uigY50Q==} + empathic@2.1.0: + resolution: {integrity: sha512-AnfC1ATldl49/cvZdLPDjBfrRNwbDO05aibiOtzQu3qtlbJtomNLhF30HEtn/7iBz50dlMECqATo3fG0LrdEgw==} engines: {node: '>=14'} encodeurl@1.0.2: @@ -5340,8 +5348,8 @@ packages: fast-string-width@3.0.2: resolution: {integrity: sha512-gX8LrtNEI5hq8DVUfRQMbr5lpaS4nMIWV+7XEbXk2b8kiQIizgnlr12B4dA3ZEx3308ze0O4Q1R+cHts8kyUJg==} - fast-uri@3.1.7: - resolution: {integrity: sha512-dOvZVzjdZdz7phd9v6jCbwxrBW3fK6n8Rc0CtdmM4bumzMnxywBYhuph6J819RRw/ku+rLbelwfMunktuzVVHg==} + fast-uri@3.1.8: + resolution: {integrity: sha512-GZMtZUTNRpOVIECoXwLNZS5xUGE+mVNbTB8h/7Rwh2TFWcBQiPzTgyZi05BF9UMZKkLJv8XBRJTlU7zg8+ZfMg==} fast-wrap-ansi@0.2.2: resolution: {integrity: sha512-7F2Fl+TjRSenLqlU3UjSH0iyqopqoZIu7eZVpEirP2g1GtWa2G/ecEmBdgz31+Mxr+ELclgg6sokpSFIQiZ02Q==} @@ -5414,6 +5422,10 @@ packages: flatted@3.4.4: resolution: {integrity: sha512-5+ybhBZANEJxaH3X5evAFatUxLfEHSr7n6kYJ+1Qd0mUqr4eu9gIf6GDbWHf8RJijHrjjO8G+la14SlL2SeS1Q==} + flru@1.0.2: + resolution: {integrity: sha512-kWyh8ADvHBFz6ua5xYOPnUroZTT/bwWfrCeL0Wj1dzG4/YOmOcfJ99W8dOVyyynJN35rZ9aCOtHChqQovV7yog==} + engines: {node: '>=6'} + folder-hash@4.1.3: resolution: {integrity: sha512-94fj+fXj1XHT8zGumUy/VlyFARc/yrslKJ2+vjrP/U6ftTdL7u68+gQhvSBjz9wrwTuty6BpZ7JsbEK5OU9RNw==} engines: {node: '>=10.10.0'} @@ -5519,8 +5531,8 @@ packages: resolution: {integrity: sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==} engines: {node: 6.* || 8.* || >= 10.*} - get-east-asian-width@1.6.0: - resolution: {integrity: sha512-QRbvDIbx6YklUe6RxeTeleMR0yv3cYH6PsPZHcnVn7xv7zO1BHN8r0XETu8n6Ye3Q+ahtSarc3WgtNWmehIBfA==} + get-east-asian-width@1.7.0: + resolution: {integrity: sha512-XjH1AECxf0giL2V1aU8vKyRR2ppRUb5c0EvT7zuJTokQ74bNo52zOtghqdWIqrhUD79fo3x0WfKZdOqxF6LG1Q==} engines: {node: '>=18'} get-intrinsic@1.3.0: @@ -5858,8 +5870,8 @@ packages: resolution: {integrity: sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==} engines: {node: '>= 0.4'} - is-core-module@2.16.2: - resolution: {integrity: sha512-evOr8xfXKxE6qSR0hSXL2r3sd7ALj8+7jQEUvPYcm5sgZFdJ+AYzT6yNmJenvIYQBgIGwfwz08sL8zoL7yq2BA==} + is-core-module@2.17.0: + resolution: {integrity: sha512-J/vG0zBCbIKOQFfufSwyXdMrsohyJIUNkrnmo6WZGzoM7tr/lsbfW5b2BvisL6zsyMzK9UxV9L6c7AoFbyXHOA==} engines: {node: '>= 0.4'} is-data-view@1.0.2: @@ -6451,8 +6463,8 @@ packages: lru-cache@10.4.3: resolution: {integrity: sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==} - lru-cache@11.5.2: - resolution: {integrity: sha512-4pfM1Ff0x50o0tQwb5ucw/RzNyD0/YJME6IVcStalZuMWxdt3sR3huStTtxz4PUmvZfRguvDejasvQ2kifR11g==} + lru-cache@11.5.3: + resolution: {integrity: sha512-U4N8FgzmWxc8k1VH8Kr6lQg18U7Fjvby6wXHVRX/ZZ7IwWbRMgrRbP0Wrb5q5NVinryp4SQampHKdvtecItxUg==} engines: {node: 20 || >=22} lru-cache@5.1.1: @@ -6465,9 +6477,6 @@ packages: magic-string@0.30.21: resolution: {integrity: sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==} - magic-string@1.2.3: - resolution: {integrity: sha512-Bpb0W2TbLKOZ7vJnOUnVRGq3WL2p+ISV29M6hYPL1AFCpyKZpdr5ytiXoTSSxRVhg8YW7f65+6gbG8WG6PCa/g==} - magic-string@1.4.1: resolution: {integrity: sha512-8lyCu36ErXR0J9uaGKlKQoiLZKmtI63YGLE8G2o9jyRPdr4X47LusSOwgOJOzcVtp81fTAAjxR7BwKz682Jhow==} @@ -6497,8 +6506,8 @@ packages: resolution: {integrity: sha512-yz3xRaG20c6/BOzvYoDaGtPmGscs7YivItZEEqe6GbwNfHuxu9YNmvnEkMzKldAGY4/80pRcQRZSEnhquk9XuQ==} engines: {node: '>= 0.8'} - memfs@4.78.0: - resolution: {integrity: sha512-gX14RGPP+fyNodL8g9jc5DfKtWNCronEMItOKDyZatTI3CPpMZDPtm7rAbftDqQAFovP4nzR0RO80sESSEnI4g==} + memfs@4.79.0: + resolution: {integrity: sha512-vDFqA9WSa//xa3XIKwMmVqxgWWft4PMKW0k69gBM2rYOzZ3VqL9BrK3Kyl45jSxS7qImDgwejZzEb/xDWhP37g==} merge-descriptors@1.0.3: resolution: {integrity: sha512-gaNvAS7TZ897/rVaZ0nMtAyxNyi/pdbjbAwUpFQpN70GqnVfOiXpeUUMKRBmzXaSQ8DdTX4/0ms62r2K+hE6mQ==} @@ -6585,8 +6594,8 @@ packages: minimist@1.2.8: resolution: {integrity: sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==} - minimizer-webpack-plugin@5.10.1: - resolution: {integrity: sha512-+dsZEyTcy1lkq41lxdiOqvb26gXbYGgwY+30w37f9PqUVkuEBejBLDotsHOTjuga9xJyGLW2DqzKDUyJ4W/PMQ==} + minimizer-webpack-plugin@5.11.0: + resolution: {integrity: sha512-2JVy2DY+iBtfRyrQB5cRM7lfurnJIi6jFTgLip/7FxDu0WxswrIRzr4fBySQ0X7HqM7BcwE28zm+HfQ5V6y4Cg==} engines: {node: '>= 10.13.0'} peerDependencies: '@minify-html/node': '*' @@ -6778,8 +6787,8 @@ packages: resolution: {integrity: sha512-LA4ZjwlnUblHVgq0oBF3Jl/6h/Nvs5fzBLwdEF4nuxnFdsfajde4WfxtJr3CaiH+F6ewcIB/q4jQ4UzPyid+CQ==} hasBin: true - node-releases@2.0.55: - resolution: {integrity: sha512-mIrE/Cw9y+9Au6dS5vDKDhQza9YvG6w+ZrS6X+ZzA7yFW/soAeaups4Qzn1bL6g5FVy8WtP79+0j82oPIbqRjQ==} + node-releases@2.0.56: + resolution: {integrity: sha512-x0InOIyzgdk+eyaWaRJFH5snEtiImgBgblZ2CyPrLmqqcuMQkEvcDPHbzqbD8eDsSeJbVOjn+crzyzHaM4D+/A==} engines: {node: '>=18'} normalize-path@3.0.0: @@ -6838,6 +6847,10 @@ packages: resolution: {integrity: sha512-XrsrhT5sybtKI6wakr2SPOlGZWWYbUXZ7a0jT8/QOeAPau+1X/bSegNe5YR75oJmEZQbKningirmGOEJCIk61Q==} engines: {node: '>=12.20.0'} + obug@3.0.0: + resolution: {integrity: sha512-5vvB5+W7ePv+p3uqxi+RcW1XAzLW0/hxt3/4X4Lc4qHudzOhmBiBwOY6DRob4WnanAEGvNcLjF+KNOufrUoEQw==} + engines: {node: '>=12.20.0'} + on-exit-leak-free@2.1.2: resolution: {integrity: sha512-0eJJY6hXLGf1udHwfNftBqH+g73EU4B504nZeKpz1sYRKafAghwxEJunB2O7rDZkL4PGfsMVnTXZ2EjibbqcsA==} engines: {node: '>=14.0.0'} @@ -7025,8 +7038,8 @@ packages: resolution: {integrity: sha512-4peoBq4Wks0riS0z8741NVv+/8IiTvqnZAr8QGgtdifrtpdXbNw/FxRS1l6NFqm4EMzuS0EDqNNx4XGaz8cuyQ==} engines: {node: '>=18'} - pkijs@3.4.0: - resolution: {integrity: sha512-emEcLuomt2j03vxD54giVB4SxTjnsqkU692xZOZXHDVoYyypEm+b3jpiTcc+Cf+myooc+/Ly0z01jqeNHVgJGw==} + pkijs@3.4.1: + resolution: {integrity: sha512-Oo/NZcSWccq8KyoG7gLE9fnltgHns+pNCjCAp/WmjsUySi+sX7y4z4Xqu4fVb42CDHzRPl33fjzT15V1wvcyhA==} engines: {node: '>=16.0.0'} pluralize@8.0.0: @@ -7110,8 +7123,8 @@ packages: resolution: {integrity: sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==} engines: {node: '>= 0.8.0'} - prettier@3.9.6: - resolution: {integrity: sha512-OpN0zzVdiaiAhxpuuj5efpIS4sY9j7bY6uR5mnj5yPzGkdkjNKSJeUThPb60Jw29QuAZgA4o+/iB49kFiaBX6g==} + prettier@3.9.8: + resolution: {integrity: sha512-WRFq3Wn3WId7LLROfMLdH7xaFr2jR62wU8nLO6rQUOLOxNZUviyJQs1M0iIhLexSFy+L+w0ch66wtoO2jRjG0A==} engines: {node: '>=14'} hasBin: true @@ -7147,8 +7160,8 @@ packages: resolution: {integrity: sha512-dYDWdjSl5RNb7SgPxGQcRU+GtvP7s2fpkrY0r432PcOIaZ0/rBcxEZnQN67iJhFuQiVw754JDoPruPCNdGsbjg==} engines: {node: '>=12.0.0'} - proxy-addr@2.0.7: - resolution: {integrity: sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==} + proxy-addr@2.0.8: + resolution: {integrity: sha512-5nnx0yGyVUcY6t9RnWcARWtwT9F1D8O9rt08htPvnd49W1IgZtmLkhu9WfMzQj1cFxjHIO6connUNVW5k7AVyQ==} engines: {node: '>= 0.10'} proxy-agent-negotiate@1.1.0: @@ -7297,8 +7310,8 @@ packages: regjsgen@0.8.0: resolution: {integrity: sha512-RvwtGe3d7LvWiDQXeQw8p5asZUmfU1G/l6WbUXeHta7Y2PEIvBTwH6E2EfmYUK8pxcxEdEmaomqyp0vZZ7C+3Q==} - regjsparser@0.13.2: - resolution: {integrity: sha512-NgRBy2Nx/bE+9F27nVHnqcN5HjyLmecqsqx2PJHu3/IEtADD4WuxuXIVExD5PoSDFVrl78dOonfcOe5O+5nbzQ==} + regjsparser@0.13.3: + resolution: {integrity: sha512-ycwFAS14Jw4mppvmK4GR/J6u3WpWpjkEApehuHtLc/8VpPNpDMbQ4WjqwplXifGeyKOzHSFLmSPqzksDQE2Sfg==} hasBin: true require-directory@2.1.1: @@ -7372,12 +7385,13 @@ packages: resolution: {integrity: sha512-l0OE8wL34P4nJH/H2ffoaniAokM2qSmrtXHmlpvYr5AVVX8msAyW0l8NVJFDxlSK4u3Uh/f41cQheDVdnYijwQ==} hasBin: true - rolldown-plugin-dts@0.28.5: - resolution: {integrity: sha512-yYd3C9CeJwqjOc9X23m0Tyxcqic491uLZlfg51szT287S8zCCqLR2uoySoElgqy2CLn7PdXcEo1dlkBs4n1WHg==} + rolldown-plugin-dts@0.28.6: + resolution: {integrity: sha512-qKrFtBfRfR2hP233m7Ic9zf3wv6MSYdZghWKMdEO6dRYZGlNfINJAa1P5ZVvyHh3mrcd7IJQvIY8L9vnm+v5rQ==} engines: {node: ^22.18.0 || ^24.11.0 || >=26.0.0} peerDependencies: '@typescript/native-preview': '*' '@volar/typescript': ~2.4.0 + '@vue/language-core': ~3.2.0 || ~3.3.0 rolldown: ^1.2.0 typescript: ^5.0.0 || ^6.0.0 || ~7.0.0 vue-tsc: ~3.2.0 || ~3.3.0 @@ -7386,6 +7400,8 @@ packages: optional: true '@volar/typescript': optional: true + '@vue/language-core': + optional: true typescript: optional: true vue-tsc: @@ -7467,93 +7483,46 @@ packages: sanitize-filename@1.6.4: resolution: {integrity: sha512-9ZyI08PsvdQl2r/bBIGubpVdR3RR9sY6RDiWFPreA21C/EFlQhmgo20UZlNjZMMZNubusLhAQozkA0Od5J21Eg==} - sass-embedded-all-unknown@1.104.0: - resolution: {integrity: sha512-+S5We++QAg0/wXeVstn4kaZQNZiHi/1FHFsuVRu6Qns/9+YH6aIExg5e8dE+ceNpnYIZUpoK3mdBJoxJhirReQ==} - cpu: ['!arm', '!arm64', '!riscv64', '!x64'] - sass-embedded-all-unknown@1.104.1: resolution: {integrity: sha512-toyMCyUKkT6DsYlHuKZGjd8T6WltaW4TGX07F7HnF4tNJM5m/8VaVsd74zrq3QSPqGE9JjxIDK4NrNc/QY9pkA==} cpu: ['!arm', '!arm64', '!riscv64', '!x64'] - sass-embedded-android-arm64@1.104.0: - resolution: {integrity: sha512-Trknl/A+KTTGRsPWrKaVIF/uq468iTqZzXWMEK/e707bqnbodYvWBBkA7uOM1wtnJQIrepeYSp/CIQJnFr95EQ==} - engines: {node: '>=14.0.0'} - cpu: [arm64] - os: [android] - sass-embedded-android-arm64@1.104.1: resolution: {integrity: sha512-yW3BVW4YFpN2vu2cVQ+Pz5JrRTvoIz36aCdo+J/Mo1A9gEN8eVPV/AL7aeZ803YdKgIitd3qw3pY4wpmT6TXNg==} engines: {node: '>=14.0.0'} cpu: [arm64] os: [android] - sass-embedded-android-arm@1.104.0: - resolution: {integrity: sha512-yojf6KAo4EKbXVzzy4FkYJAez+qzj6NV2inEzsQQxvNfKxfX9INtC6u8UNwSjXL40M9vzAH03lygutq9zmhTCg==} - engines: {node: '>=14.0.0'} - cpu: [arm] - os: [android] - sass-embedded-android-arm@1.104.1: resolution: {integrity: sha512-g/XPAJYAzSSQZFP4xCdGD0HLKB4mf24cJ/+5Nls8rMool3jNkBv9+AFO4EV0b+RxN8rLcEsMccH1CR64yIFYcQ==} engines: {node: '>=14.0.0'} cpu: [arm] os: [android] - sass-embedded-android-riscv64@1.104.0: - resolution: {integrity: sha512-UPR1U/qsTzIikl/DAmZn/11oPrz4DrnrbWANB7WGwz3AtYvLZeixEiVj8Yo2jNy6749zPD09Pyo352io8Y2Mxw==} - engines: {node: '>=14.0.0'} - cpu: [riscv64] - os: [android] - sass-embedded-android-riscv64@1.104.1: resolution: {integrity: sha512-ZYY8oMKQS7Q/6FBoC8w3T16O3MucDe3xv8iKym41Nht5uvLCGGpm4fC4OF5nlv7wQkJv8oactYddGG3Wd0Rqkg==} engines: {node: '>=14.0.0'} cpu: [riscv64] os: [android] - sass-embedded-android-x64@1.104.0: - resolution: {integrity: sha512-NebAKvwfj4a7EbOf9LAzgo4f/uO1xFJbIoebzW8bmqdjeIMSAwJvFToIizxjDuOsIJ9M6AaADxwvDxgm8JTq+w==} - engines: {node: '>=14.0.0'} - cpu: [x64] - os: [android] - sass-embedded-android-x64@1.104.1: resolution: {integrity: sha512-5WZKC4lSfjMIjzZdQUlYQUAV+UiatBhD8w28U7cYLLj4/dMgEPOBd4g3VMv0BwpgH2JOaycMS42dXq29W2bcDg==} engines: {node: '>=14.0.0'} cpu: [x64] os: [android] - sass-embedded-darwin-arm64@1.104.0: - resolution: {integrity: sha512-DYxsoOtA90/LabvQiFs/UVo6jrPbIlIvelSC0B9fxlB051ZBpEFnWamjLV2Xncp48E63voWTYGKpLlsHsi7clg==} - engines: {node: '>=14.0.0'} - cpu: [arm64] - os: [darwin] - sass-embedded-darwin-arm64@1.104.1: resolution: {integrity: sha512-oatuHzn0NsEg0d9Dcze6CuWUPvuETtMxRK4cv0eRAg7p6R0vHnv5GZRyWG6gEy3nc/ha/L+GtTasWVU82f4jrQ==} engines: {node: '>=14.0.0'} cpu: [arm64] os: [darwin] - sass-embedded-darwin-x64@1.104.0: - resolution: {integrity: sha512-zozGKOnR3mnlBqKhzfGH8ZqjPphaDzE5Zjx+H/IOb/ruR/KApTvYkRdi9Eq7OQvSJwL/EHYiyT2jgHaqQulOWw==} - engines: {node: '>=14.0.0'} - cpu: [x64] - os: [darwin] - sass-embedded-darwin-x64@1.104.1: resolution: {integrity: sha512-gql/5sHGzUTVwuHfM3QLCDeb6NYwen+LLj22gz81C2NKHF/4nUtDyh4N+fURWdT7J0/EhtMOd0+FLML3sGNP7g==} engines: {node: '>=14.0.0'} cpu: [x64] os: [darwin] - sass-embedded-linux-arm64@1.104.0: - resolution: {integrity: sha512-2TWOQodxIbwcp9fS01FCUbO2c8bnsdOgUCLB7aZDAhm6ZAkEL8GNIAyKxSMkVIjxndMqNHsG2UtCR2++03DQ+Q==} - engines: {node: '>=14.0.0'} - cpu: [arm64] - os: [linux] - libc: glibc - sass-embedded-linux-arm64@1.104.1: resolution: {integrity: sha512-sVWUKXNTu8sP3X95Df0xo/t49Ce5IseTIMqXHxhFBKVmx7gf7kBWNLK0wH5ym+4khc+B5nNJPgq4IxpelG8tMQ==} engines: {node: '>=14.0.0'} @@ -7561,13 +7530,6 @@ packages: os: [linux] libc: glibc - sass-embedded-linux-arm@1.104.0: - resolution: {integrity: sha512-RX4t5jBlYtGrZwpuc1mtD3lzGuat+jyPidyN5hD5DURV7q39y4IampzopVJ9fvNZqsiGElYWnKyRJA49Q4xk7w==} - engines: {node: '>=14.0.0'} - cpu: [arm] - os: [linux] - libc: glibc - sass-embedded-linux-arm@1.104.1: resolution: {integrity: sha512-WfmshPJOp9vUKxgp8wZ2ncaKBbyrlW9J51M2aUQHWECjMNxTULnGOHWSmD7FViXv4zwn1Co5FIFQUipW7RCxtA==} engines: {node: '>=14.0.0'} @@ -7575,13 +7537,6 @@ packages: os: [linux] libc: glibc - sass-embedded-linux-musl-arm64@1.104.0: - resolution: {integrity: sha512-NPcl0Cw9QXdGzYgjtLZD9MU3Mmr+N31R+Wa+hbbmlNwg1yghbF/bWrpE96oixrQivtCsY1yh9cONl6d+9NrS6Q==} - engines: {node: '>=14.0.0'} - cpu: [arm64] - os: [linux] - libc: musl - sass-embedded-linux-musl-arm64@1.104.1: resolution: {integrity: sha512-H7b+LzZ/w8pwNExInM8HDHraqvxCMdUc5ZRGU/aSJJhZ9HjeRKBjF3GxaisVHnx7o18j1l4VQ5cLBL9tTmNzZw==} engines: {node: '>=14.0.0'} @@ -7589,13 +7544,6 @@ packages: os: [linux] libc: musl - sass-embedded-linux-musl-arm@1.104.0: - resolution: {integrity: sha512-KjXKRY/1TDCNbRg/Htq4puzf5etQ9eFXG83O/328Km/1x2FuQMCmD+pSFTqQrj2LskZ8if+NYZJb3CQ1wzF0Pw==} - engines: {node: '>=14.0.0'} - cpu: [arm] - os: [linux] - libc: musl - sass-embedded-linux-musl-arm@1.104.1: resolution: {integrity: sha512-k0cQ/CxBzFVYiQEObg6CpF6CUglkdEhi/DZgZXQbwC27kbGGY+fatmIs/cFPJL2z1ulACwoAr86RQUFzYvw5eg==} engines: {node: '>=14.0.0'} @@ -7603,13 +7551,6 @@ packages: os: [linux] libc: musl - sass-embedded-linux-musl-riscv64@1.104.0: - resolution: {integrity: sha512-/1JR6G1AfGs/paJk5nemuJmg7pOUgwXlz/WW2NhSDRHBgZnb6Zy6yMpkSHoienAOJSBGUmKceT03dQ/4b409CA==} - engines: {node: '>=14.0.0'} - cpu: [riscv64] - os: [linux] - libc: musl - sass-embedded-linux-musl-riscv64@1.104.1: resolution: {integrity: sha512-9DYdn4wfrkidjxJVtEd2iCx8HKdZe+uF82GDmrYEZhgu4NjVE6a4fQyW7OLwzn3erZMHKBaObBOH1d37DnXI1A==} engines: {node: '>=14.0.0'} @@ -7617,13 +7558,6 @@ packages: os: [linux] libc: musl - sass-embedded-linux-musl-x64@1.104.0: - resolution: {integrity: sha512-5wVjkPR74JdsoH9+NSKV7UCPAdMTxNoayZdu7B9PnmNkOJMRE5O8Jb2oJ3JXgSH/kcGXJ6Vl6dL8/EPLBAKkcg==} - engines: {node: '>=14.0.0'} - cpu: [x64] - os: [linux] - libc: musl - sass-embedded-linux-musl-x64@1.104.1: resolution: {integrity: sha512-5xz+nAr01b6yaRdrGVgE7lNvm1lGFjwNdUvnz+teidvHCbD5oTcbhrRVrnDoLHHvq5n3Jve9TzWaaHhezaEfHA==} engines: {node: '>=14.0.0'} @@ -7631,13 +7565,6 @@ packages: os: [linux] libc: musl - sass-embedded-linux-riscv64@1.104.0: - resolution: {integrity: sha512-Bq9xrONn23cyv5bdSuLm0RG1dcKl+lFQRc1k1UlncI2B2gqb6/OdakEa4Gv2HAmo+O6iOtK39lG9XT1ivTIoww==} - engines: {node: '>=14.0.0'} - cpu: [riscv64] - os: [linux] - libc: glibc - sass-embedded-linux-riscv64@1.104.1: resolution: {integrity: sha512-oWryPJWTXK5adtlz/FD7wd2kS4I0CEgp6mWLUVb4oMFURMLz9bA9fO87D7lc4SV++lds7T51PU1kykCbOvNHMg==} engines: {node: '>=14.0.0'} @@ -7645,13 +7572,6 @@ packages: os: [linux] libc: glibc - sass-embedded-linux-x64@1.104.0: - resolution: {integrity: sha512-xznKQzFnNVNq+GiXPmBXIHLL2rlIoekDxE8HXNKgxXX6bn4fByuHApCmj5Uz+MpVOB154EYCbErztyoEcmnb9Q==} - engines: {node: '>=14.0.0'} - cpu: [x64] - os: [linux] - libc: glibc - sass-embedded-linux-x64@1.104.1: resolution: {integrity: sha512-j/sX/yKTx/wJKepC5/ISlR6kPeSuHKThf76D2za5i2VnbHg0MN19jQq3WMorowR3kRghqt6azs3awogG+e7IRA==} engines: {node: '>=14.0.0'} @@ -7659,43 +7579,22 @@ packages: os: [linux] libc: glibc - sass-embedded-unknown-all@1.104.0: - resolution: {integrity: sha512-0+zhxrAt9PIsdWEVTe5Wgo+gtYdlyv0ASuuAEXT4e9w2yNArUqZ9Gez4Jn8EmtbF7x9uuZxPWbdnq9z65gCH7g==} - os: ['!android', '!darwin', '!linux', '!win32'] - sass-embedded-unknown-all@1.104.1: resolution: {integrity: sha512-RaMsYZB5mRioL4qhoI7T5mmNb2OunakbPTJW2cuu3MeIULnGoxo7Wd5QKFxeQvF7sSQL57RuaQ+q9pH+/pQ9Fg==} os: ['!android', '!darwin', '!linux', '!win32'] - sass-embedded-win32-arm64@1.104.0: - resolution: {integrity: sha512-b8dKmgdgmTx0rSBLNPqLQiq4r/SDau0/3we7MG/8ULMneMSl2OoVttN2ilKSz993lqQu8FJSjx5fEjLSeXVaiA==} - engines: {node: '>=14.0.0'} - cpu: [arm64] - os: [win32] - sass-embedded-win32-arm64@1.104.1: resolution: {integrity: sha512-fS6DL7lcnTPclqGLF4xRt8egZlFY9cU23d57ufbWqaUbCFu9JTu0+8qB4jMxfx1la6byi3GoSTfbnNOLfWv8sw==} engines: {node: '>=14.0.0'} cpu: [arm64] os: [win32] - sass-embedded-win32-x64@1.104.0: - resolution: {integrity: sha512-tVL4NZKUo0+fIO2sT9V1DnBOo9wUbkRoic/NbVBThQdCjl07dn7PKW+ISSnY0EwQhCxdulMDek/JZT7c46vTCA==} - engines: {node: '>=14.0.0'} - cpu: [x64] - os: [win32] - sass-embedded-win32-x64@1.104.1: resolution: {integrity: sha512-/c4N2A93Ckms6DuRFVftKYISuI1tyC8gmlVJ8WaWFzgCBN/Swq2rARJIBUNeuxlmxjmYXfd3+2f/u887K63wbA==} engines: {node: '>=14.0.0'} cpu: [x64] os: [win32] - sass-embedded@1.104.0: - resolution: {integrity: sha512-AW1ZaKM/o4t137+FNe9zkMFWAZlw+EbWuHopVbP0yc0vpvlYj8NqxgKKSsSqODZVgGON2FzKeFMJJHR+tXNzqA==} - engines: {node: '>=20.19.0'} - hasBin: true - sass-embedded@1.104.1: resolution: {integrity: sha512-7LxbtPJ1MWKVbhzOnGx1sHTkHTcHVJ9hbgVsU29p/8gY1VeXt19fcJFr5xsx2f6zfrrR3FeOcYMt0uYDLAxpgw==} engines: {node: '>=20.19.0'} @@ -7719,11 +7618,6 @@ packages: webpack: optional: true - sass@1.104.0: - resolution: {integrity: sha512-btHMApW2bgolvClhRW8AlQJzgI9lUB3pPSofBQQT+E46GWvf9o0TVQ13SYv5riWZVFyPN+JNz3TKW9XhBlc10w==} - engines: {node: '>=20.19.0'} - hasBin: true - sass@1.104.1: resolution: {integrity: sha512-yDA+1aIG3EHgN4V/BvuhCvu61FF6hEd4e+9DxikUm9U0CAGuvdIZ/UYy7qbOxjhbbWQraoyLlMuzdRGOSV5Bmw==} engines: {node: '>=20.19.0'} @@ -7842,8 +7736,8 @@ packages: resolution: {integrity: sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==} engines: {node: '>=8'} - slice-ansi@9.0.0: - resolution: {integrity: sha512-SO/3iYL5S3W57LLEniscOGPZgOqZUPCx6d3dB+52B80yJ0XstzsC/eV8gnA4tM3MHDrKz+OCFSLNjswdSC+/bA==} + slice-ansi@9.0.1: + resolution: {integrity: sha512-aBY19bn/XA+hKOKX0qL7Z0UfdBsbQvc9hn993U8ALUjzxCvDcuZqLoRXjGJrUARWAlwMnsRVD9sw2AFNOYvalA==} engines: {node: '>=22'} socket.io-adapter@2.5.8: @@ -8111,15 +8005,15 @@ packages: tldts-core@6.1.86: resolution: {integrity: sha512-Je6p7pkk+KMzMv2XXKmAE3McmolOQFdxkKw0R8EYNr7sELW46JqnNeTX8ybPiQgvg1ymCoF8LXs5fzFaZvJPTA==} - tldts-core@7.4.13: - resolution: {integrity: sha512-mbYsrih5FRtGxs3Usvl/PqwJsNpp+jsmrdFviiK02teHDG0/HebBG/pqCylje3kzgXYzuLoHJF/0mz9W53t8Xg==} + tldts-core@7.4.14: + resolution: {integrity: sha512-KYkjfJHnIC5t+Gy7hPrMHgJmWc/N9FfmS+fggRPSlpFckidpB9HD6OzPsSTkfDH+MpZgcu2tJPGgLfHl979N1Q==} tldts@6.1.86: resolution: {integrity: sha512-WMi/OQ2axVTf/ykqCQgXiIct+mSQDFdH2fkwhPwgEwvJ1kSzZRiinb0zF2Xb8u4+OqPChmyI6MEu4EezNJz+FQ==} hasBin: true - tldts@7.4.13: - resolution: {integrity: sha512-iHtaIWWIbMDkCeJdTBzZFGgbluE5J+oHlb2g7+oAz1S1gpuVpabRZdQyd471Vl8UUkcz2vXSL8xZH2kyCe8tfA==} + tldts@7.4.14: + resolution: {integrity: sha512-EahQoi+Q5oqmG3yxRHx+bwn36OaLbtw6jnTFcGjc8fcmktzTgk45xRnzAx8Ch87PFEiqRhoc3FWBmY+LBrvEGQ==} hasBin: true tmp@0.2.7: @@ -8203,8 +8097,8 @@ packages: resolution: {integrity: sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==} engines: {node: '>= 0.8.0'} - type-fest@5.9.0: - resolution: {integrity: sha512-yANm3Jr3GiJ1qgJlxGAVxTOIcEOk1rhQHamlXtnrCK7EHP4HeM9OGxtMg/W7HFdrVzw/ZWJKGVIJusVH85sLtw==} + type-fest@5.10.0: + resolution: {integrity: sha512-NoSdpq/WEiAg5sjmBkmV/hfxv6HJH4NqPNrqjtSO5CwRmpsDfaf4begxW34KdJykH/l1yHtwBWQkCRdoXO8mPA==} engines: {node: '>=20'} type-is@1.6.18: @@ -8223,8 +8117,8 @@ packages: resolution: {integrity: sha512-BaXgOuIxz8n8pIq3e7Atg/7s+DpiYrxn4vdot3w9KbnBhcRQq6o3xemQdIfynqSeXeDrF32x+WvfzmOjPiY9lg==} engines: {node: '>= 0.4'} - typed-array-byte-offset@1.0.4: - resolution: {integrity: sha512-bTlAFB/FBYMcuX81gbL4OcpH5PmlFHqlCCpAl8AlEzMz5k53oNDvN8p1PNOWLEmI2x4orp3raOFB51tv9X+MFQ==} + typed-array-byte-offset@1.0.5: + resolution: {integrity: sha512-0FHJvLPqZ7KJzp17O13jfsAjsqazgrxBu2zEK95PmUz8lv2+GjRuxUInCr2Rk9Dms3ihN21zJ929ZO43yJ95QQ==} engines: {node: '>= 0.4'} typed-array-length@1.0.8: @@ -8541,16 +8435,6 @@ packages: html-webpack-plugin: optional: true - webpack@5.110.3: - resolution: {integrity: sha512-GuizBzRvo9YPpyoNMf3ag7AzxbaW85qrRSqTha345KyJbAFPt3/cMzBM0h+RWg7SK/7DdzRLINP3LvQ0hvr4hg==} - engines: {node: '>=10.13.0'} - hasBin: true - peerDependencies: - webpack-cli: '*' - peerDependenciesMeta: - webpack-cli: - optional: true - webpack@5.111.0: resolution: {integrity: sha512-A2R74kfE6b3eLKS91iZiol03Ebx7avmJJBOyiP+4LePW9NNeNJGQkKeSQos4dk6R4H0YAMYlv+aOrs1CyWT3eA==} engines: {node: '>=10.13.0'} @@ -8577,8 +8461,8 @@ packages: resolution: {integrity: sha512-1to4zXBxmXHV3IiSSEInrreIlu02vUOvrhxJJH5vcxYTBDAx51cqZiKdyTxlecdKNSjj8EcxGBxNf6Vg+945gw==} engines: {node: ^20.19.0 || ^22.12.0 || >=24.0.0} - whatwg-url@17.1.1: - resolution: {integrity: sha512-ohjk1mdUebJVadRt3bAhQhx8lSnISq+GDttK79LFl8EHQkAPvzwctoasC4hs8tBt6kLAncBWWyq1N52qEfKvDw==} + whatwg-url@17.1.2: + resolution: {integrity: sha512-TEZA+Zqxin7Jjsm2cjRohCmen5awh+hT6Zi3VZdqZlNRk7zvOI/9WpBFg/DWlA56bWnzwm6DuB8NS0EsxQH9uQ==} engines: {node: ^22.14.0 || >=24.0.0} whatwg-url@5.0.0: @@ -8596,8 +8480,8 @@ packages: resolution: {integrity: sha512-K4jVyjnBdgvc86Y6BkaLZEN933SwYOuBFkdmBu9ZfkcAbdVbpITnDmjvZ/aQjRXQrv5EPkTnD1s39GiiqbngCw==} engines: {node: '>= 0.4'} - which-typed-array@1.1.22: - resolution: {integrity: sha512-fvO4ExWMFsqyhG3AiPAObMuY1lxaqgYcxbc49CNdWDDECOJNgQyvsOWVwbZc+qf3rzRtxojBK+CMEv0Ld5CYpw==} + which-typed-array@1.1.24: + resolution: {integrity: sha512-wk4Mf4pR5mRP7eYuuTBCIQ9d0ud2Fv2jRLQpfgnRjbOxAFHmjKFValgTpitVKzJJS8ajnYQV2Du1SZ8j6b/EUQ==} engines: {node: '>= 0.4'} which@1.3.1: @@ -8629,8 +8513,8 @@ packages: wordwrap@1.0.0: resolution: {integrity: sha512-gvVzJFlPycKc5dZN4yPkP8w7Dc37BtP1yczEneOb4uq34pXZcvrtRTmWV8W+Ume+XCxKgbjM+nevkyFPMybd4Q==} - wrap-ansi@10.0.1: - resolution: {integrity: sha512-M0N4xzyzosiIok3svYlEo1sdLZts/8FPgYH/GPC3wvlmPoRvnoManGMrE54waYj3tISA8w6lsdesfVv67qSr8Q==} + wrap-ansi@10.0.2: + resolution: {integrity: sha512-6OLRNZqRntVGBm26ghZ5eZhCuWWyOkRCSn8XsOIuq5stpCE/tjLbdozd93naILZig0lmD8ANfRwnhn0DLeXGlg==} engines: {node: '>=20'} wrap-ansi@7.0.0: @@ -8730,14 +8614,14 @@ packages: resolution: {integrity: sha512-xYqdZFUK/VYazNl/oCDYN+3WloWQwMfZxBoiNt6qNyk+xfOdi598muWE42rNZFp1kNOiqW936q5RhUdnpqElSg==} engines: {node: '>=18'} - yuku-ast@0.9.5: - resolution: {integrity: sha512-Q8qW8WwQnN5Cm0ZZivdRIfv0sRLTjUq0YumXJkw8CYN1aCdICH9rk4C47/4n6kA5EqDtlj+F608twoTSV2MwdQ==} + yuku-ast@0.10.2: + resolution: {integrity: sha512-UnG9mA6giglCvSErft2/40TVFX750Sj1xgwddPLpG7J7rlr/P1wPADg9G2RK+d/1tNLtRVoLdMMOMVBB9561TQ==} - yuku-codegen@0.9.5: - resolution: {integrity: sha512-zGUVyDpSK4b6c9B0yyxi2P0wujn1XZTbG9dCb7d6gyAoP63EMgyLzUwPUvwxPG5jgYqhlI7w+S3oCyapqGr4PA==} + yuku-codegen@0.10.2: + resolution: {integrity: sha512-hentl2dtrF6cPjiAirtkfxfFZBA6Hdm61UqRJ7cA0qrlDNMk9PZGOjw5w1mx3E0hu/6pHcJF4dJW+D0SXHPZOA==} - yuku-parser@0.9.5: - resolution: {integrity: sha512-IBnAdNVMswWbJcM7woPluOudectJzFjJ1N8jVRxP9Uq4CIv5hZdBIcdmtRbFDYF/Ph2j2gVup4YJ4N9mh0jYFA==} + yuku-parser@0.10.2: + resolution: {integrity: sha512-CgaU0/PPjCAIEZ3WQroosOxTY3eeKldAN3h+vk8pMNz4+jl1CZzBR4pW+K/rRPF112VooCL5FdjJoiMNjDrL2A==} zod@3.25.76: resolution: {integrity: sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ==} @@ -8939,18 +8823,18 @@ snapshots: '@asamuzakjp/css-color@6.0.7': dependencies: - '@csstools/css-calc': 3.4.0(@csstools/css-parser-algorithms@4.0.0(@csstools/css-tokenizer@4.0.0))(@csstools/css-tokenizer@4.0.0) - '@csstools/css-color-parser': 4.2.3(@csstools/css-parser-algorithms@4.0.0(@csstools/css-tokenizer@4.0.0))(@csstools/css-tokenizer@4.0.0) - '@csstools/css-parser-algorithms': 4.0.0(@csstools/css-tokenizer@4.0.0) - '@csstools/css-tokenizer': 4.0.0 - lru-cache: 11.5.2 + '@csstools/css-calc': 3.4.0(@csstools/css-parser-algorithms@4.0.0(@csstools/css-tokenizer@4.0.1))(@csstools/css-tokenizer@4.0.1) + '@csstools/css-color-parser': 4.2.3(@csstools/css-parser-algorithms@4.0.0(@csstools/css-tokenizer@4.0.1))(@csstools/css-tokenizer@4.0.1) + '@csstools/css-parser-algorithms': 4.0.0(@csstools/css-tokenizer@4.0.1) + '@csstools/css-tokenizer': 4.0.1 + lru-cache: 11.5.3 '@asamuzakjp/dom-selector@8.3.2': dependencies: bidi-js: 1.1.0 css-tree: 3.2.1 is-potential-custom-element-name: 1.0.1 - lru-cache: 11.5.2 + lru-cache: 11.5.3 '@babel/code-frame@7.29.7': dependencies: @@ -8958,9 +8842,9 @@ snapshots: js-tokens: 4.0.0 picocolors: 1.1.1 - '@babel/code-frame@8.0.0': + '@babel/code-frame@8.0.6': dependencies: - '@babel/helper-validator-identifier': 8.0.4 + '@babel/helper-validator-identifier': 8.0.6 js-tokens: 10.0.0 '@babel/compat-data@7.29.7': {} @@ -8974,7 +8858,7 @@ snapshots: '@babel/helper-compilation-targets': 7.29.7 '@babel/helper-module-transforms': 7.29.7(@babel/core@7.29.7(supports-color@11.0.0))(supports-color@11.0.0) '@babel/helpers': 7.29.7 - '@babel/parser': 7.29.8 + '@babel/parser': 7.29.9 '@babel/template': 7.29.7 '@babel/traverse': 7.29.8(supports-color@11.0.0) '@babel/types': 7.29.8 @@ -8989,17 +8873,17 @@ snapshots: '@babel/core@8.0.1': dependencies: - '@babel/code-frame': 8.0.0 + '@babel/code-frame': 8.0.6 '@babel/generator': 8.0.5 - '@babel/helper-compilation-targets': 8.0.5 + '@babel/helper-compilation-targets': 8.0.6 '@babel/helpers': 8.0.5 - '@babel/parser': 8.0.5 + '@babel/parser': 8.0.6 '@babel/template': 8.0.0 - '@babel/traverse': 8.0.5 - '@babel/types': 8.0.5 + '@babel/traverse': 8.0.6 + '@babel/types': 8.0.6 '@types/gensync': 1.0.5 convert-source-map: 2.0.0 - empathic: 2.0.1 + empathic: 2.1.0 gensync: 1.0.0-beta.2 import-meta-resolve: 4.2.0 json5: 2.2.3 @@ -9008,17 +8892,17 @@ snapshots: '@babel/core@8.0.5': dependencies: - '@babel/code-frame': 8.0.0 + '@babel/code-frame': 8.0.6 '@babel/generator': 8.0.5 - '@babel/helper-compilation-targets': 8.0.5 + '@babel/helper-compilation-targets': 8.0.6 '@babel/helpers': 8.0.5 - '@babel/parser': 8.0.5 + '@babel/parser': 8.0.6 '@babel/template': 8.0.0 - '@babel/traverse': 8.0.5 - '@babel/types': 8.0.5 + '@babel/traverse': 8.0.6 + '@babel/types': 8.0.6 '@types/gensync': 1.0.5 convert-source-map: 2.0.0 - empathic: 2.0.1 + empathic: 2.1.0 gensync: 1.0.0-beta.2 import-meta-resolve: 4.2.0 json5: 2.2.3 @@ -9027,7 +8911,7 @@ snapshots: '@babel/generator@7.29.8': dependencies: - '@babel/parser': 7.29.8 + '@babel/parser': 7.29.9 '@babel/types': 7.29.8 '@jridgewell/gen-mapping': 0.3.13 '@jridgewell/trace-mapping': 0.3.31 @@ -9035,8 +8919,17 @@ snapshots: '@babel/generator@8.0.5': dependencies: - '@babel/parser': 8.0.5 - '@babel/types': 8.0.5 + '@babel/parser': 8.0.6 + '@babel/types': 8.0.6 + '@jridgewell/gen-mapping': 0.4.0-beta.0 + '@jridgewell/trace-mapping': 0.3.31 + '@types/jsesc': 2.5.1 + jsesc: 3.1.0 + + '@babel/generator@8.0.6': + dependencies: + '@babel/parser': 8.0.6 + '@babel/types': 8.0.6 '@jridgewell/gen-mapping': 0.4.0-beta.0 '@jridgewell/trace-mapping': 0.3.31 '@types/jsesc': 2.5.1 @@ -9044,25 +8937,25 @@ snapshots: '@babel/helper-annotate-as-pure@8.0.0': dependencies: - '@babel/types': 8.0.5 + '@babel/types': 8.0.6 '@babel/helper-compilation-targets@7.29.7': dependencies: '@babel/compat-data': 7.29.7 '@babel/helper-validator-option': 7.29.7 - browserslist: 4.28.9 + browserslist: 4.29.0 lru-cache: 5.1.1 semver: 6.3.1 - '@babel/helper-compilation-targets@8.0.5': + '@babel/helper-compilation-targets@8.0.6': dependencies: '@babel/compat-data': 8.0.5 '@babel/helper-validator-option': 8.0.0 - browserslist: 4.28.9 - lru-cache: 11.5.2 + browserslist: 4.29.0 + flru: 1.0.2 verkit: 0.3.2 - '@babel/helper-create-class-features-plugin@8.0.5(@babel/core@8.0.5)': + '@babel/helper-create-class-features-plugin@8.0.6(@babel/core@8.0.5)': dependencies: '@babel/core': 8.0.5 '@babel/helper-annotate-as-pure': 8.0.0 @@ -9070,7 +8963,7 @@ snapshots: '@babel/helper-optimise-call-expression': 8.0.0 '@babel/helper-replace-supers': 8.0.1(@babel/core@8.0.5) '@babel/helper-skip-transparent-expression-wrappers': 8.0.0 - '@babel/traverse': 8.0.5 + '@babel/traverse': 8.0.6 verkit: 0.3.2 '@babel/helper-create-regexp-features-plugin@8.0.5(@babel/core@8.0.5)': @@ -9083,18 +8976,18 @@ snapshots: '@babel/helper-define-polyfill-provider@1.0.0(@babel/core@8.0.5)': dependencies: '@babel/core': 8.0.5 - '@babel/helper-compilation-targets': 8.0.5 + '@babel/helper-compilation-targets': 8.0.6 '@babel/helper-plugin-utils': 8.0.1(@babel/core@8.0.5) lodash.debounce: 4.0.8 '@babel/helper-globals@7.29.7': {} - '@babel/helper-globals@8.0.0': {} + '@babel/helper-globals@8.0.6': {} '@babel/helper-member-expression-to-functions@8.0.5': dependencies: - '@babel/traverse': 8.0.5 - '@babel/types': 8.0.5 + '@babel/traverse': 8.0.6 + '@babel/types': 8.0.6 '@babel/helper-module-imports@7.29.7(supports-color@11.0.0)': dependencies: @@ -9105,8 +8998,8 @@ snapshots: '@babel/helper-module-imports@8.0.0': dependencies: - '@babel/traverse': 8.0.5 - '@babel/types': 8.0.5 + '@babel/traverse': 8.0.6 + '@babel/types': 8.0.6 '@babel/helper-module-transforms@7.29.7(@babel/core@7.29.7(supports-color@11.0.0))(supports-color@11.0.0)': dependencies: @@ -9117,16 +9010,16 @@ snapshots: transitivePeerDependencies: - supports-color - '@babel/helper-module-transforms@8.0.5(@babel/core@8.0.5)': + '@babel/helper-module-transforms@8.0.6(@babel/core@8.0.5)': dependencies: '@babel/core': 8.0.5 '@babel/helper-module-imports': 8.0.0 - '@babel/helper-validator-identifier': 8.0.4 - '@babel/traverse': 8.0.5 + '@babel/helper-validator-identifier': 8.0.6 + '@babel/traverse': 8.0.6 '@babel/helper-optimise-call-expression@8.0.0': dependencies: - '@babel/types': 8.0.5 + '@babel/types': 8.0.6 '@babel/helper-plugin-utils@8.0.1(@babel/core@8.0.5)': dependencies: @@ -9137,19 +9030,19 @@ snapshots: '@babel/core': 8.0.5 '@babel/helper-annotate-as-pure': 8.0.0 '@babel/helper-wrap-function': 8.0.0 - '@babel/traverse': 8.0.5 + '@babel/traverse': 8.0.6 '@babel/helper-replace-supers@8.0.1(@babel/core@8.0.5)': dependencies: '@babel/core': 8.0.5 '@babel/helper-member-expression-to-functions': 8.0.5 '@babel/helper-optimise-call-expression': 8.0.0 - '@babel/traverse': 8.0.5 + '@babel/traverse': 8.0.6 '@babel/helper-skip-transparent-expression-wrappers@8.0.0': dependencies: - '@babel/traverse': 8.0.5 - '@babel/types': 8.0.5 + '@babel/traverse': 8.0.6 + '@babel/types': 8.0.6 '@babel/helper-split-export-declaration@7.24.7': dependencies: @@ -9157,11 +9050,11 @@ snapshots: '@babel/helper-string-parser@7.29.7': {} - '@babel/helper-string-parser@8.0.0': {} + '@babel/helper-string-parser@8.0.6': {} '@babel/helper-validator-identifier@7.29.7': {} - '@babel/helper-validator-identifier@8.0.4': {} + '@babel/helper-validator-identifier@8.0.6': {} '@babel/helper-validator-option@7.29.7': {} @@ -9170,8 +9063,8 @@ snapshots: '@babel/helper-wrap-function@8.0.0': dependencies: '@babel/template': 8.0.0 - '@babel/traverse': 8.0.5 - '@babel/types': 8.0.5 + '@babel/traverse': 8.0.6 + '@babel/types': 8.0.6 '@babel/helpers@7.29.7': dependencies: @@ -9181,15 +9074,15 @@ snapshots: '@babel/helpers@8.0.5': dependencies: '@babel/template': 8.0.0 - '@babel/types': 8.0.5 + '@babel/types': 8.0.6 - '@babel/parser@7.29.8': + '@babel/parser@7.29.9': dependencies: '@babel/types': 7.29.8 - '@babel/parser@8.0.5': + '@babel/parser@8.0.6': dependencies: - '@babel/types': 8.0.5 + '@babel/types': 8.0.6 '@babel/plugin-bugfix-firefox-class-in-computed-class-key@8.0.1(@babel/core@8.0.5)': dependencies: @@ -9206,7 +9099,7 @@ snapshots: '@babel/core': 8.0.5 '@babel/helper-plugin-utils': 8.0.1(@babel/core@8.0.5) - '@babel/plugin-bugfix-safari-rest-destructuring-rhs-array@8.0.5(@babel/core@8.0.5)': + '@babel/plugin-bugfix-safari-rest-destructuring-rhs-array@8.0.6(@babel/core@8.0.5)': dependencies: '@babel/core': 8.0.5 '@babel/helper-plugin-utils': 8.0.1(@babel/core@8.0.5) @@ -9234,7 +9127,7 @@ snapshots: '@babel/core': 8.0.5 '@babel/helper-plugin-utils': 8.0.1(@babel/core@8.0.5) '@babel/helper-remap-async-to-generator': 8.0.1(@babel/core@8.0.5) - '@babel/traverse': 8.0.5 + '@babel/traverse': 8.0.6 '@babel/plugin-transform-async-to-generator@8.0.1(@babel/core@8.0.5)': dependencies: @@ -9256,24 +9149,24 @@ snapshots: '@babel/plugin-transform-class-properties@8.0.1(@babel/core@8.0.5)': dependencies: '@babel/core': 8.0.5 - '@babel/helper-create-class-features-plugin': 8.0.5(@babel/core@8.0.5) + '@babel/helper-create-class-features-plugin': 8.0.6(@babel/core@8.0.5) '@babel/helper-plugin-utils': 8.0.1(@babel/core@8.0.5) '@babel/plugin-transform-class-static-block@8.0.5(@babel/core@8.0.5)': dependencies: '@babel/core': 8.0.5 - '@babel/helper-create-class-features-plugin': 8.0.5(@babel/core@8.0.5) + '@babel/helper-create-class-features-plugin': 8.0.6(@babel/core@8.0.5) '@babel/helper-plugin-utils': 8.0.1(@babel/core@8.0.5) '@babel/plugin-transform-classes@8.0.5(@babel/core@8.0.5)': dependencies: '@babel/core': 8.0.5 '@babel/helper-annotate-as-pure': 8.0.0 - '@babel/helper-compilation-targets': 8.0.5 - '@babel/helper-globals': 8.0.0 + '@babel/helper-compilation-targets': 8.0.6 + '@babel/helper-globals': 8.0.6 '@babel/helper-plugin-utils': 8.0.1(@babel/core@8.0.5) '@babel/helper-replace-supers': 8.0.1(@babel/core@8.0.5) - '@babel/traverse': 8.0.5 + '@babel/traverse': 8.0.6 '@babel/plugin-transform-computed-properties@8.0.1(@babel/core@8.0.5)': dependencies: @@ -9332,7 +9225,7 @@ snapshots: '@babel/plugin-transform-function-name@8.0.1(@babel/core@8.0.5)': dependencies: '@babel/core': 8.0.5 - '@babel/helper-compilation-targets': 8.0.5 + '@babel/helper-compilation-targets': 8.0.6 '@babel/helper-plugin-utils': 8.0.1(@babel/core@8.0.5) '@babel/plugin-transform-json-strings@8.0.1(@babel/core@8.0.5)': @@ -9358,26 +9251,26 @@ snapshots: '@babel/plugin-transform-modules-amd@8.0.1(@babel/core@8.0.5)': dependencies: '@babel/core': 8.0.5 - '@babel/helper-module-transforms': 8.0.5(@babel/core@8.0.5) + '@babel/helper-module-transforms': 8.0.6(@babel/core@8.0.5) '@babel/helper-plugin-utils': 8.0.1(@babel/core@8.0.5) '@babel/plugin-transform-modules-commonjs@8.0.1(@babel/core@8.0.5)': dependencies: '@babel/core': 8.0.5 - '@babel/helper-module-transforms': 8.0.5(@babel/core@8.0.5) + '@babel/helper-module-transforms': 8.0.6(@babel/core@8.0.5) '@babel/helper-plugin-utils': 8.0.1(@babel/core@8.0.5) '@babel/plugin-transform-modules-systemjs@8.0.1(@babel/core@8.0.5)': dependencies: '@babel/core': 8.0.5 - '@babel/helper-module-transforms': 8.0.5(@babel/core@8.0.5) + '@babel/helper-module-transforms': 8.0.6(@babel/core@8.0.5) '@babel/helper-plugin-utils': 8.0.1(@babel/core@8.0.5) - '@babel/helper-validator-identifier': 8.0.4 + '@babel/helper-validator-identifier': 8.0.6 '@babel/plugin-transform-modules-umd@8.0.1(@babel/core@8.0.5)': dependencies: '@babel/core': 8.0.5 - '@babel/helper-module-transforms': 8.0.5(@babel/core@8.0.5) + '@babel/helper-module-transforms': 8.0.6(@babel/core@8.0.5) '@babel/helper-plugin-utils': 8.0.1(@babel/core@8.0.5) '@babel/plugin-transform-named-capturing-groups-regex@8.0.1(@babel/core@8.0.5)': @@ -9404,7 +9297,7 @@ snapshots: '@babel/plugin-transform-object-rest-spread@8.0.1(@babel/core@8.0.5)': dependencies: '@babel/core': 8.0.5 - '@babel/helper-compilation-targets': 8.0.5 + '@babel/helper-compilation-targets': 8.0.6 '@babel/helper-plugin-utils': 8.0.1(@babel/core@8.0.5) '@babel/plugin-transform-destructuring': 8.0.5(@babel/core@8.0.5) '@babel/plugin-transform-parameters': 8.0.5(@babel/core@8.0.5) @@ -9434,14 +9327,14 @@ snapshots: '@babel/plugin-transform-private-methods@8.0.1(@babel/core@8.0.5)': dependencies: '@babel/core': 8.0.5 - '@babel/helper-create-class-features-plugin': 8.0.5(@babel/core@8.0.5) + '@babel/helper-create-class-features-plugin': 8.0.6(@babel/core@8.0.5) '@babel/helper-plugin-utils': 8.0.1(@babel/core@8.0.5) '@babel/plugin-transform-private-property-in-object@8.0.5(@babel/core@8.0.5)': dependencies: '@babel/core': 8.0.5 '@babel/helper-annotate-as-pure': 8.0.0 - '@babel/helper-create-class-features-plugin': 8.0.5(@babel/core@8.0.5) + '@babel/helper-create-class-features-plugin': 8.0.6(@babel/core@8.0.5) '@babel/helper-plugin-utils': 8.0.1(@babel/core@8.0.5) '@babel/plugin-transform-property-literals@8.0.1(@babel/core@8.0.5)': @@ -9449,7 +9342,7 @@ snapshots: '@babel/core': 8.0.5 '@babel/helper-plugin-utils': 8.0.1(@babel/core@8.0.5) - '@babel/plugin-transform-regenerator@8.0.5(@babel/core@8.0.5)': + '@babel/plugin-transform-regenerator@8.0.6(@babel/core@8.0.5)': dependencies: '@babel/core': 8.0.5 '@babel/helper-plugin-utils': 8.0.1(@babel/core@8.0.5) @@ -9524,13 +9417,13 @@ snapshots: dependencies: '@babel/compat-data': 8.0.5 '@babel/core': 8.0.5 - '@babel/helper-compilation-targets': 8.0.5 + '@babel/helper-compilation-targets': 8.0.6 '@babel/helper-plugin-utils': 8.0.1(@babel/core@8.0.5) '@babel/helper-validator-option': 8.0.0 '@babel/plugin-bugfix-firefox-class-in-computed-class-key': 8.0.1(@babel/core@8.0.5) '@babel/plugin-bugfix-safari-class-field-initializer-scope': 8.0.1(@babel/core@8.0.5) '@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression': 8.0.1(@babel/core@8.0.5) - '@babel/plugin-bugfix-safari-rest-destructuring-rhs-array': 8.0.5(@babel/core@8.0.5) + '@babel/plugin-bugfix-safari-rest-destructuring-rhs-array': 8.0.6(@babel/core@8.0.5) '@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining': 8.0.1(@babel/core@8.0.5) '@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly': 8.0.1(@babel/core@8.0.5) '@babel/plugin-transform-arrow-functions': 8.0.1(@babel/core@8.0.5) @@ -9572,7 +9465,7 @@ snapshots: '@babel/plugin-transform-private-methods': 8.0.1(@babel/core@8.0.5) '@babel/plugin-transform-private-property-in-object': 8.0.5(@babel/core@8.0.5) '@babel/plugin-transform-property-literals': 8.0.1(@babel/core@8.0.5) - '@babel/plugin-transform-regenerator': 8.0.5(@babel/core@8.0.5) + '@babel/plugin-transform-regenerator': 8.0.6(@babel/core@8.0.5) '@babel/plugin-transform-regexp-modifiers': 8.0.1(@babel/core@8.0.5) '@babel/plugin-transform-reserved-words': 8.0.1(@babel/core@8.0.5) '@babel/plugin-transform-shorthand-properties': 8.0.1(@babel/core@8.0.5) @@ -9595,7 +9488,7 @@ snapshots: '@babel/helper-plugin-utils': 8.0.1(@babel/core@8.0.5) '@babel/plugin-transform-dotall-regex': 8.0.1(@babel/core@8.0.5) '@babel/plugin-transform-unicode-property-regex': 8.0.1(@babel/core@8.0.5) - '@babel/types': 8.0.5 + '@babel/types': 8.0.6 esutils: 2.0.3 '@babel/runtime@8.0.5': {} @@ -9603,35 +9496,35 @@ snapshots: '@babel/template@7.29.7': dependencies: '@babel/code-frame': 7.29.7 - '@babel/parser': 7.29.8 + '@babel/parser': 7.29.9 '@babel/types': 7.29.8 '@babel/template@8.0.0': dependencies: - '@babel/code-frame': 8.0.0 - '@babel/parser': 8.0.5 - '@babel/types': 8.0.5 + '@babel/code-frame': 8.0.6 + '@babel/parser': 8.0.6 + '@babel/types': 8.0.6 '@babel/traverse@7.29.8(supports-color@11.0.0)': dependencies: '@babel/code-frame': 7.29.7 '@babel/generator': 7.29.8 '@babel/helper-globals': 7.29.7 - '@babel/parser': 7.29.8 + '@babel/parser': 7.29.9 '@babel/template': 7.29.7 '@babel/types': 7.29.8 debug: 4.4.3(supports-color@11.0.0) transitivePeerDependencies: - supports-color - '@babel/traverse@8.0.5': + '@babel/traverse@8.0.6': dependencies: - '@babel/code-frame': 8.0.0 - '@babel/generator': 8.0.5 - '@babel/helper-globals': 8.0.0 - '@babel/parser': 8.0.5 + '@babel/code-frame': 8.0.6 + '@babel/generator': 8.0.6 + '@babel/helper-globals': 8.0.6 + '@babel/parser': 8.0.6 '@babel/template': 8.0.0 - '@babel/types': 8.0.5 + '@babel/types': 8.0.6 obug: 2.2.1 '@babel/types@7.29.8': @@ -9639,10 +9532,10 @@ snapshots: '@babel/helper-string-parser': 7.29.7 '@babel/helper-validator-identifier': 7.29.7 - '@babel/types@8.0.5': + '@babel/types@8.0.6': dependencies: - '@babel/helper-string-parser': 8.0.0 - '@babel/helper-validator-identifier': 8.0.4 + '@babel/helper-string-parser': 8.0.6 + '@babel/helper-validator-identifier': 8.0.6 '@bazel/bazelisk@1.28.1': {} @@ -9683,27 +9576,27 @@ snapshots: '@csstools/color-helpers@6.1.1': {} - '@csstools/css-calc@3.4.0(@csstools/css-parser-algorithms@4.0.0(@csstools/css-tokenizer@4.0.0))(@csstools/css-tokenizer@4.0.0)': + '@csstools/css-calc@3.4.0(@csstools/css-parser-algorithms@4.0.0(@csstools/css-tokenizer@4.0.1))(@csstools/css-tokenizer@4.0.1)': dependencies: - '@csstools/css-parser-algorithms': 4.0.0(@csstools/css-tokenizer@4.0.0) - '@csstools/css-tokenizer': 4.0.0 + '@csstools/css-parser-algorithms': 4.0.0(@csstools/css-tokenizer@4.0.1) + '@csstools/css-tokenizer': 4.0.1 - '@csstools/css-color-parser@4.2.3(@csstools/css-parser-algorithms@4.0.0(@csstools/css-tokenizer@4.0.0))(@csstools/css-tokenizer@4.0.0)': + '@csstools/css-color-parser@4.2.3(@csstools/css-parser-algorithms@4.0.0(@csstools/css-tokenizer@4.0.1))(@csstools/css-tokenizer@4.0.1)': dependencies: '@csstools/color-helpers': 6.1.1 - '@csstools/css-calc': 3.4.0(@csstools/css-parser-algorithms@4.0.0(@csstools/css-tokenizer@4.0.0))(@csstools/css-tokenizer@4.0.0) - '@csstools/css-parser-algorithms': 4.0.0(@csstools/css-tokenizer@4.0.0) - '@csstools/css-tokenizer': 4.0.0 + '@csstools/css-calc': 3.4.0(@csstools/css-parser-algorithms@4.0.0(@csstools/css-tokenizer@4.0.1))(@csstools/css-tokenizer@4.0.1) + '@csstools/css-parser-algorithms': 4.0.0(@csstools/css-tokenizer@4.0.1) + '@csstools/css-tokenizer': 4.0.1 - '@csstools/css-parser-algorithms@4.0.0(@csstools/css-tokenizer@4.0.0)': + '@csstools/css-parser-algorithms@4.0.0(@csstools/css-tokenizer@4.0.1)': dependencies: - '@csstools/css-tokenizer': 4.0.0 + '@csstools/css-tokenizer': 4.0.1 - '@csstools/css-syntax-patches-for-csstree@1.1.13(css-tree@3.2.1)': + '@csstools/css-syntax-patches-for-csstree@1.1.14(css-tree@3.2.1)': optionalDependencies: css-tree: 3.2.1 - '@csstools/css-tokenizer@4.0.0': {} + '@csstools/css-tokenizer@4.0.1': {} '@cypress/request@4.0.1': dependencies: @@ -9859,7 +9752,9 @@ snapshots: '@eslint/core': 1.2.1 levn: 0.4.1 - '@exodus/bytes@1.15.1': {} + '@exodus/bytes@1.16.0(@noble/hashes@1.8.0)': + optionalDependencies: + '@noble/hashes': 1.8.0 '@firebase/ai@2.16.0(@firebase/app-types@0.9.6)(@firebase/app@0.16.2)': dependencies: @@ -10251,7 +10146,7 @@ snapshots: - supports-color - utf-8-validate - '@grpc/grpc-js@1.14.4': + '@grpc/grpc-js@1.14.5': dependencies: '@grpc/proto-loader': 0.8.1 '@js-sdsl/ordered-map': 4.4.2 @@ -10259,7 +10154,7 @@ snapshots: '@grpc/grpc-js@1.9.16': dependencies: '@grpc/proto-loader': 0.7.15 - '@types/node': 22.20.2 + '@types/node': 22.20.4 '@grpc/proto-loader@0.7.15': dependencies: @@ -10296,14 +10191,14 @@ snapshots: '@inquirer/ansi@2.0.8': {} - '@inquirer/checkbox@5.2.5(@types/node@22.20.2)': + '@inquirer/checkbox@5.2.5(@types/node@22.20.4)': dependencies: '@inquirer/ansi': 2.0.8 - '@inquirer/core': 12.0.3(@types/node@22.20.2) + '@inquirer/core': 12.0.3(@types/node@22.20.4) '@inquirer/figures': 2.0.9 - '@inquirer/type': 4.1.1(@types/node@22.20.2) + '@inquirer/type': 4.1.1(@types/node@22.20.4) optionalDependencies: - '@types/node': 22.20.2 + '@types/node': 22.20.4 '@inquirer/checkbox@5.2.5(@types/node@24.13.5)': dependencies: @@ -10314,12 +10209,12 @@ snapshots: optionalDependencies: '@types/node': 24.13.5 - '@inquirer/confirm@6.3.2(@types/node@22.20.2)': + '@inquirer/confirm@6.3.2(@types/node@22.20.4)': dependencies: - '@inquirer/core': 12.0.3(@types/node@22.20.2) - '@inquirer/type': 4.1.1(@types/node@22.20.2) + '@inquirer/core': 12.0.3(@types/node@22.20.4) + '@inquirer/type': 4.1.1(@types/node@22.20.4) optionalDependencies: - '@types/node': 22.20.2 + '@types/node': 22.20.4 '@inquirer/confirm@6.3.2(@types/node@24.13.5)': dependencies: @@ -10328,17 +10223,17 @@ snapshots: optionalDependencies: '@types/node': 24.13.5 - '@inquirer/core@12.0.3(@types/node@22.20.2)': + '@inquirer/core@12.0.3(@types/node@22.20.4)': dependencies: '@inquirer/ansi': 2.0.8 '@inquirer/figures': 2.0.9 - '@inquirer/type': 4.1.1(@types/node@22.20.2) + '@inquirer/type': 4.1.1(@types/node@22.20.4) cli-width: 4.1.0 fast-wrap-ansi: 0.2.2 mute-stream: 3.0.0 signal-exit: 4.1.0 optionalDependencies: - '@types/node': 22.20.2 + '@types/node': 22.20.4 '@inquirer/core@12.0.3(@types/node@24.13.5)': dependencies: @@ -10352,13 +10247,13 @@ snapshots: optionalDependencies: '@types/node': 24.13.5 - '@inquirer/editor@5.3.3(@types/node@22.20.2)': + '@inquirer/editor@5.3.3(@types/node@22.20.4)': dependencies: - '@inquirer/core': 12.0.3(@types/node@22.20.2) - '@inquirer/external-editor': 3.0.5(@types/node@22.20.2) - '@inquirer/type': 4.1.1(@types/node@22.20.2) + '@inquirer/core': 12.0.3(@types/node@22.20.4) + '@inquirer/external-editor': 3.0.5(@types/node@22.20.4) + '@inquirer/type': 4.1.1(@types/node@22.20.4) optionalDependencies: - '@types/node': 22.20.2 + '@types/node': 22.20.4 '@inquirer/editor@5.3.3(@types/node@24.13.5)': dependencies: @@ -10368,12 +10263,12 @@ snapshots: optionalDependencies: '@types/node': 24.13.5 - '@inquirer/expand@5.1.5(@types/node@22.20.2)': + '@inquirer/expand@5.1.5(@types/node@22.20.4)': dependencies: - '@inquirer/core': 12.0.3(@types/node@22.20.2) - '@inquirer/type': 4.1.1(@types/node@22.20.2) + '@inquirer/core': 12.0.3(@types/node@22.20.4) + '@inquirer/type': 4.1.1(@types/node@22.20.4) optionalDependencies: - '@types/node': 22.20.2 + '@types/node': 22.20.4 '@inquirer/expand@5.1.5(@types/node@24.13.5)': dependencies: @@ -10382,12 +10277,12 @@ snapshots: optionalDependencies: '@types/node': 24.13.5 - '@inquirer/external-editor@3.0.5(@types/node@22.20.2)': + '@inquirer/external-editor@3.0.5(@types/node@22.20.4)': dependencies: chardet: 2.2.0 iconv-lite: 0.7.3 optionalDependencies: - '@types/node': 22.20.2 + '@types/node': 22.20.4 '@inquirer/external-editor@3.0.5(@types/node@24.13.5)': dependencies: @@ -10398,12 +10293,12 @@ snapshots: '@inquirer/figures@2.0.9': {} - '@inquirer/input@5.1.6(@types/node@22.20.2)': + '@inquirer/input@5.1.6(@types/node@22.20.4)': dependencies: - '@inquirer/core': 12.0.3(@types/node@22.20.2) - '@inquirer/type': 4.1.1(@types/node@22.20.2) + '@inquirer/core': 12.0.3(@types/node@22.20.4) + '@inquirer/type': 4.1.1(@types/node@22.20.4) optionalDependencies: - '@types/node': 22.20.2 + '@types/node': 22.20.4 '@inquirer/input@5.1.6(@types/node@24.13.5)': dependencies: @@ -10412,12 +10307,12 @@ snapshots: optionalDependencies: '@types/node': 24.13.5 - '@inquirer/number@4.2.3(@types/node@22.20.2)': + '@inquirer/number@4.2.3(@types/node@22.20.4)': dependencies: - '@inquirer/core': 12.0.3(@types/node@22.20.2) - '@inquirer/type': 4.1.1(@types/node@22.20.2) + '@inquirer/core': 12.0.3(@types/node@22.20.4) + '@inquirer/type': 4.1.1(@types/node@22.20.4) optionalDependencies: - '@types/node': 22.20.2 + '@types/node': 22.20.4 '@inquirer/number@4.2.3(@types/node@24.13.5)': dependencies: @@ -10426,13 +10321,13 @@ snapshots: optionalDependencies: '@types/node': 24.13.5 - '@inquirer/password@5.2.2(@types/node@22.20.2)': + '@inquirer/password@5.2.2(@types/node@22.20.4)': dependencies: '@inquirer/ansi': 2.0.8 - '@inquirer/core': 12.0.3(@types/node@22.20.2) - '@inquirer/type': 4.1.1(@types/node@22.20.2) + '@inquirer/core': 12.0.3(@types/node@22.20.4) + '@inquirer/type': 4.1.1(@types/node@22.20.4) optionalDependencies: - '@types/node': 22.20.2 + '@types/node': 22.20.4 '@inquirer/password@5.2.2(@types/node@24.13.5)': dependencies: @@ -10442,20 +10337,20 @@ snapshots: optionalDependencies: '@types/node': 24.13.5 - '@inquirer/prompts@8.7.2(@types/node@22.20.2)': - dependencies: - '@inquirer/checkbox': 5.2.5(@types/node@22.20.2) - '@inquirer/confirm': 6.3.2(@types/node@22.20.2) - '@inquirer/editor': 5.3.3(@types/node@22.20.2) - '@inquirer/expand': 5.1.5(@types/node@22.20.2) - '@inquirer/input': 5.1.6(@types/node@22.20.2) - '@inquirer/number': 4.2.3(@types/node@22.20.2) - '@inquirer/password': 5.2.2(@types/node@22.20.2) - '@inquirer/rawlist': 5.3.5(@types/node@22.20.2) - '@inquirer/search': 4.3.3(@types/node@22.20.2) - '@inquirer/select': 5.2.5(@types/node@22.20.2) + '@inquirer/prompts@8.7.2(@types/node@22.20.4)': + dependencies: + '@inquirer/checkbox': 5.2.5(@types/node@22.20.4) + '@inquirer/confirm': 6.3.2(@types/node@22.20.4) + '@inquirer/editor': 5.3.3(@types/node@22.20.4) + '@inquirer/expand': 5.1.5(@types/node@22.20.4) + '@inquirer/input': 5.1.6(@types/node@22.20.4) + '@inquirer/number': 4.2.3(@types/node@22.20.4) + '@inquirer/password': 5.2.2(@types/node@22.20.4) + '@inquirer/rawlist': 5.3.5(@types/node@22.20.4) + '@inquirer/search': 4.3.3(@types/node@22.20.4) + '@inquirer/select': 5.2.5(@types/node@22.20.4) optionalDependencies: - '@types/node': 22.20.2 + '@types/node': 22.20.4 '@inquirer/prompts@8.7.2(@types/node@24.13.5)': dependencies: @@ -10472,12 +10367,12 @@ snapshots: optionalDependencies: '@types/node': 24.13.5 - '@inquirer/rawlist@5.3.5(@types/node@22.20.2)': + '@inquirer/rawlist@5.3.5(@types/node@22.20.4)': dependencies: - '@inquirer/core': 12.0.3(@types/node@22.20.2) - '@inquirer/type': 4.1.1(@types/node@22.20.2) + '@inquirer/core': 12.0.3(@types/node@22.20.4) + '@inquirer/type': 4.1.1(@types/node@22.20.4) optionalDependencies: - '@types/node': 22.20.2 + '@types/node': 22.20.4 '@inquirer/rawlist@5.3.5(@types/node@24.13.5)': dependencies: @@ -10486,13 +10381,13 @@ snapshots: optionalDependencies: '@types/node': 24.13.5 - '@inquirer/search@4.3.3(@types/node@22.20.2)': + '@inquirer/search@4.3.3(@types/node@22.20.4)': dependencies: - '@inquirer/core': 12.0.3(@types/node@22.20.2) + '@inquirer/core': 12.0.3(@types/node@22.20.4) '@inquirer/figures': 2.0.9 - '@inquirer/type': 4.1.1(@types/node@22.20.2) + '@inquirer/type': 4.1.1(@types/node@22.20.4) optionalDependencies: - '@types/node': 22.20.2 + '@types/node': 22.20.4 '@inquirer/search@4.3.3(@types/node@24.13.5)': dependencies: @@ -10502,14 +10397,14 @@ snapshots: optionalDependencies: '@types/node': 24.13.5 - '@inquirer/select@5.2.5(@types/node@22.20.2)': + '@inquirer/select@5.2.5(@types/node@22.20.4)': dependencies: '@inquirer/ansi': 2.0.8 - '@inquirer/core': 12.0.3(@types/node@22.20.2) + '@inquirer/core': 12.0.3(@types/node@22.20.4) '@inquirer/figures': 2.0.9 - '@inquirer/type': 4.1.1(@types/node@22.20.2) + '@inquirer/type': 4.1.1(@types/node@22.20.4) optionalDependencies: - '@types/node': 22.20.2 + '@types/node': 22.20.4 '@inquirer/select@5.2.5(@types/node@24.13.5)': dependencies: @@ -10520,9 +10415,9 @@ snapshots: optionalDependencies: '@types/node': 24.13.5 - '@inquirer/type@4.1.1(@types/node@22.20.2)': + '@inquirer/type@4.1.1(@types/node@22.20.4)': optionalDependencies: - '@types/node': 22.20.2 + '@types/node': 22.20.4 '@inquirer/type@4.1.1(@types/node@24.13.5)': optionalDependencies: @@ -10596,59 +10491,59 @@ snapshots: dependencies: tslib: 2.8.1 - '@jsonjoy.com/fs-core@4.78.0(tslib@2.8.1)': + '@jsonjoy.com/fs-core@4.79.0(tslib@2.8.1)': dependencies: - '@jsonjoy.com/fs-node-builtins': 4.78.0(tslib@2.8.1) - '@jsonjoy.com/fs-node-utils': 4.78.0(tslib@2.8.1) + '@jsonjoy.com/fs-node-builtins': 4.79.0(tslib@2.8.1) + '@jsonjoy.com/fs-node-utils': 4.79.0(tslib@2.8.1) thingies: 2.6.1(tslib@2.8.1) tslib: 2.8.1 - '@jsonjoy.com/fs-fsa@4.78.0(tslib@2.8.1)': + '@jsonjoy.com/fs-fsa@4.79.0(tslib@2.8.1)': dependencies: - '@jsonjoy.com/fs-core': 4.78.0(tslib@2.8.1) - '@jsonjoy.com/fs-node-builtins': 4.78.0(tslib@2.8.1) - '@jsonjoy.com/fs-node-utils': 4.78.0(tslib@2.8.1) + '@jsonjoy.com/fs-core': 4.79.0(tslib@2.8.1) + '@jsonjoy.com/fs-node-builtins': 4.79.0(tslib@2.8.1) + '@jsonjoy.com/fs-node-utils': 4.79.0(tslib@2.8.1) thingies: 2.6.1(tslib@2.8.1) tslib: 2.8.1 - '@jsonjoy.com/fs-node-builtins@4.78.0(tslib@2.8.1)': + '@jsonjoy.com/fs-node-builtins@4.79.0(tslib@2.8.1)': dependencies: tslib: 2.8.1 - '@jsonjoy.com/fs-node-to-fsa@4.78.0(tslib@2.8.1)': + '@jsonjoy.com/fs-node-to-fsa@4.79.0(tslib@2.8.1)': dependencies: - '@jsonjoy.com/fs-fsa': 4.78.0(tslib@2.8.1) - '@jsonjoy.com/fs-node-builtins': 4.78.0(tslib@2.8.1) - '@jsonjoy.com/fs-node-utils': 4.78.0(tslib@2.8.1) + '@jsonjoy.com/fs-fsa': 4.79.0(tslib@2.8.1) + '@jsonjoy.com/fs-node-builtins': 4.79.0(tslib@2.8.1) + '@jsonjoy.com/fs-node-utils': 4.79.0(tslib@2.8.1) tslib: 2.8.1 - '@jsonjoy.com/fs-node-utils@4.78.0(tslib@2.8.1)': + '@jsonjoy.com/fs-node-utils@4.79.0(tslib@2.8.1)': dependencies: - '@jsonjoy.com/fs-node-builtins': 4.78.0(tslib@2.8.1) + '@jsonjoy.com/fs-node-builtins': 4.79.0(tslib@2.8.1) glob-to-regex.js: 1.3.1(tslib@2.8.1) tslib: 2.8.1 - '@jsonjoy.com/fs-node@4.78.0(tslib@2.8.1)': + '@jsonjoy.com/fs-node@4.79.0(tslib@2.8.1)': dependencies: - '@jsonjoy.com/fs-core': 4.78.0(tslib@2.8.1) - '@jsonjoy.com/fs-node-builtins': 4.78.0(tslib@2.8.1) - '@jsonjoy.com/fs-node-utils': 4.78.0(tslib@2.8.1) - '@jsonjoy.com/fs-print': 4.78.0(tslib@2.8.1) - '@jsonjoy.com/fs-snapshot': 4.78.0(tslib@2.8.1) + '@jsonjoy.com/fs-core': 4.79.0(tslib@2.8.1) + '@jsonjoy.com/fs-node-builtins': 4.79.0(tslib@2.8.1) + '@jsonjoy.com/fs-node-utils': 4.79.0(tslib@2.8.1) + '@jsonjoy.com/fs-print': 4.79.0(tslib@2.8.1) + '@jsonjoy.com/fs-snapshot': 4.79.0(tslib@2.8.1) glob-to-regex.js: 1.3.1(tslib@2.8.1) thingies: 2.6.1(tslib@2.8.1) tslib: 2.8.1 - '@jsonjoy.com/fs-print@4.78.0(tslib@2.8.1)': + '@jsonjoy.com/fs-print@4.79.0(tslib@2.8.1)': dependencies: - '@jsonjoy.com/fs-node-utils': 4.78.0(tslib@2.8.1) + '@jsonjoy.com/fs-node-utils': 4.79.0(tslib@2.8.1) tree-dump: 1.1.0(tslib@2.8.1) tslib: 2.8.1 - '@jsonjoy.com/fs-snapshot@4.78.0(tslib@2.8.1)': + '@jsonjoy.com/fs-snapshot@4.79.0(tslib@2.8.1)': dependencies: '@jsonjoy.com/buffers': 17.67.0(tslib@2.8.1) - '@jsonjoy.com/fs-node-utils': 4.78.0(tslib@2.8.1) + '@jsonjoy.com/fs-node-utils': 4.79.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 @@ -10710,10 +10605,10 @@ snapshots: '@leichtgewicht/ip-codec@2.0.5': {} - '@listr2/prompt-adapter-inquirer@4.2.7(@inquirer/prompts@8.7.2(@types/node@22.20.2))(@types/node@22.20.2)(listr2@11.1.0)': + '@listr2/prompt-adapter-inquirer@4.2.7(@inquirer/prompts@8.7.2(@types/node@22.20.4))(@types/node@22.20.4)(listr2@11.1.0)': dependencies: - '@inquirer/prompts': 8.7.2(@types/node@22.20.2) - '@inquirer/type': 4.1.1(@types/node@22.20.2) + '@inquirer/prompts': 8.7.2(@types/node@22.20.4) + '@inquirer/type': 4.1.1(@types/node@22.20.4) listr2: 11.1.0 transitivePeerDependencies: - '@types/node' @@ -10850,7 +10745,7 @@ snapshots: '@napi-rs/nice-win32-x64-msvc': 1.1.1 optional: true - '@noble/hashes@1.4.0': {} + '@noble/hashes@1.8.0': {} '@nodelib/fs.scandir@2.1.5': dependencies: @@ -10974,7 +10869,7 @@ snapshots: '@octokit/endpoint': 11.0.5 '@octokit/request-error': 7.1.2 '@octokit/types': 18.0.0 - content-type: 3.1.0 + content-type: 3.1.1 json-with-bigint: 3.5.12 universal-user-agent: 7.0.3 @@ -11136,78 +11031,78 @@ snapshots: '@parcel/watcher-win32-arm64': 2.6.0 '@parcel/watcher-win32-x64': 2.6.0 - '@peculiar/asn1-cms@2.9.4': + '@peculiar/asn1-cms@2.9.5': dependencies: - '@peculiar/asn1-schema': 2.9.4 - '@peculiar/asn1-x509': 2.9.4 - '@peculiar/asn1-x509-attr': 2.9.4 + '@peculiar/asn1-schema': 2.9.5 + '@peculiar/asn1-x509': 2.9.5 + '@peculiar/asn1-x509-attr': 2.9.5 asn1js: 3.0.10 tslib: 2.8.1 - '@peculiar/asn1-csr@2.9.4': + '@peculiar/asn1-csr@2.9.5': dependencies: - '@peculiar/asn1-schema': 2.9.4 - '@peculiar/asn1-x509': 2.9.4 + '@peculiar/asn1-schema': 2.9.5 + '@peculiar/asn1-x509': 2.9.5 asn1js: 3.0.10 tslib: 2.8.1 - '@peculiar/asn1-ecc@2.9.4': + '@peculiar/asn1-ecc@2.9.5': dependencies: - '@peculiar/asn1-schema': 2.9.4 - '@peculiar/asn1-x509': 2.9.4 + '@peculiar/asn1-schema': 2.9.5 + '@peculiar/asn1-x509': 2.9.5 asn1js: 3.0.10 tslib: 2.8.1 - '@peculiar/asn1-pfx@2.9.4': + '@peculiar/asn1-pfx@2.9.5': dependencies: - '@peculiar/asn1-cms': 2.9.4 - '@peculiar/asn1-pkcs8': 2.9.4 - '@peculiar/asn1-rsa': 2.9.4 - '@peculiar/asn1-schema': 2.9.4 + '@peculiar/asn1-cms': 2.9.5 + '@peculiar/asn1-pkcs8': 2.9.5 + '@peculiar/asn1-rsa': 2.9.5 + '@peculiar/asn1-schema': 2.9.5 asn1js: 3.0.10 tslib: 2.8.1 - '@peculiar/asn1-pkcs8@2.9.4': + '@peculiar/asn1-pkcs8@2.9.5': dependencies: - '@peculiar/asn1-schema': 2.9.4 - '@peculiar/asn1-x509': 2.9.4 + '@peculiar/asn1-schema': 2.9.5 + '@peculiar/asn1-x509': 2.9.5 asn1js: 3.0.10 tslib: 2.8.1 - '@peculiar/asn1-pkcs9@2.9.4': + '@peculiar/asn1-pkcs9@2.9.5': dependencies: - '@peculiar/asn1-cms': 2.9.4 - '@peculiar/asn1-pfx': 2.9.4 - '@peculiar/asn1-pkcs8': 2.9.4 - '@peculiar/asn1-schema': 2.9.4 - '@peculiar/asn1-x509': 2.9.4 - '@peculiar/asn1-x509-attr': 2.9.4 + '@peculiar/asn1-cms': 2.9.5 + '@peculiar/asn1-pfx': 2.9.5 + '@peculiar/asn1-pkcs8': 2.9.5 + '@peculiar/asn1-schema': 2.9.5 + '@peculiar/asn1-x509': 2.9.5 + '@peculiar/asn1-x509-attr': 2.9.5 asn1js: 3.0.10 tslib: 2.8.1 - '@peculiar/asn1-rsa@2.9.4': + '@peculiar/asn1-rsa@2.9.5': dependencies: - '@peculiar/asn1-schema': 2.9.4 - '@peculiar/asn1-x509': 2.9.4 + '@peculiar/asn1-schema': 2.9.5 + '@peculiar/asn1-x509': 2.9.5 asn1js: 3.0.10 tslib: 2.8.1 - '@peculiar/asn1-schema@2.9.4': + '@peculiar/asn1-schema@2.9.5': dependencies: '@peculiar/utils': 2.0.3 asn1js: 3.0.10 tslib: 2.8.1 - '@peculiar/asn1-x509-attr@2.9.4': + '@peculiar/asn1-x509-attr@2.9.5': dependencies: - '@peculiar/asn1-schema': 2.9.4 - '@peculiar/asn1-x509': 2.9.4 + '@peculiar/asn1-schema': 2.9.5 + '@peculiar/asn1-x509': 2.9.5 asn1js: 3.0.10 tslib: 2.8.1 - '@peculiar/asn1-x509@2.9.4': + '@peculiar/asn1-x509@2.9.5': dependencies: - '@peculiar/asn1-schema': 2.9.4 + '@peculiar/asn1-schema': 2.9.5 '@peculiar/utils': 2.0.3 asn1js: 3.0.10 tslib: 2.8.1 @@ -11218,13 +11113,13 @@ snapshots: '@peculiar/x509@1.14.3': dependencies: - '@peculiar/asn1-cms': 2.9.4 - '@peculiar/asn1-csr': 2.9.4 - '@peculiar/asn1-ecc': 2.9.4 - '@peculiar/asn1-pkcs9': 2.9.4 - '@peculiar/asn1-rsa': 2.9.4 - '@peculiar/asn1-schema': 2.9.4 - '@peculiar/asn1-x509': 2.9.4 + '@peculiar/asn1-cms': 2.9.5 + '@peculiar/asn1-csr': 2.9.5 + '@peculiar/asn1-ecc': 2.9.5 + '@peculiar/asn1-pkcs9': 2.9.5 + '@peculiar/asn1-rsa': 2.9.5 + '@peculiar/asn1-schema': 2.9.5 + '@peculiar/asn1-x509': 2.9.5 pvtsutils: 1.3.6 reflect-metadata: 0.2.2 tslib: 2.8.1 @@ -11444,7 +11339,7 @@ snapshots: '@stylistic/eslint-plugin@5.10.0(eslint@10.10.0(jiti@2.7.0)(supports-color@11.0.0))': dependencies: '@eslint-community/eslint-utils': 4.10.1(eslint@10.10.0(jiti@2.7.0)(supports-color@11.0.0)) - '@typescript-eslint/types': 8.70.0 + '@typescript-eslint/types': 8.70.1 eslint: 10.10.0(jiti@2.7.0)(supports-color@11.0.0) eslint-visitor-keys: 4.2.1 espree: 10.4.0 @@ -11457,7 +11352,7 @@ snapshots: '@types/babel__core@7.20.5': dependencies: - '@babel/parser': 7.29.8 + '@babel/parser': 7.29.9 '@babel/types': 7.29.8 '@types/babel__generator': 7.27.0 '@types/babel__template': 7.4.4 @@ -11469,7 +11364,7 @@ snapshots: '@types/babel__template@7.4.4': dependencies: - '@babel/parser': 7.29.8 + '@babel/parser': 7.29.9 '@babel/types': 7.29.8 '@types/babel__traverse@7.28.0': @@ -11481,16 +11376,16 @@ snapshots: '@types/body-parser@1.19.6': dependencies: '@types/connect': 3.4.38 - '@types/node': 22.20.2 + '@types/node': 22.20.4 '@types/bonjour@3.5.13': dependencies: - '@types/node': 22.20.2 + '@types/node': 22.20.4 '@types/browser-sync@2.29.1': dependencies: '@types/micromatch': 2.3.35 - '@types/node': 22.20.2 + '@types/node': 22.20.4 '@types/serve-static': 2.2.0 chokidar: 3.6.0 @@ -11501,26 +11396,26 @@ snapshots: '@types/cli-progress@3.11.6': dependencies: - '@types/node': 22.20.2 + '@types/node': 22.20.4 '@types/connect-history-api-fallback@1.5.4': dependencies: '@types/express-serve-static-core': 5.1.3 - '@types/node': 22.20.2 + '@types/node': 22.20.4 '@types/connect@3.4.38': dependencies: - '@types/node': 22.20.2 + '@types/node': 22.20.4 '@types/cors@2.8.19': dependencies: - '@types/node': 22.20.2 + '@types/node': 22.20.4 '@types/deep-eql@4.0.2': {} '@types/duplexify@3.6.5': dependencies: - '@types/node': 22.20.2 + '@types/node': 22.20.4 '@types/ejs@3.1.5': {} @@ -11532,7 +11427,7 @@ snapshots: '@types/express-serve-static-core@5.1.3': dependencies: - '@types/node': 22.20.2 + '@types/node': 22.20.4 '@types/qs': 6.15.1 '@types/range-parser': 1.2.7 '@types/send': 1.2.1 @@ -11553,7 +11448,7 @@ snapshots: '@types/http-proxy@1.17.17': dependencies: - '@types/node': 22.20.2 + '@types/node': 22.20.4 '@types/jasmine-reporters@2.5.3': dependencies: @@ -11569,17 +11464,17 @@ snapshots: '@types/karma@6.3.9(supports-color@11.0.0)': dependencies: - '@types/node': 22.20.2 + '@types/node': 22.20.4 log4js: 6.9.1(supports-color@11.0.0) transitivePeerDependencies: - supports-color '@types/less@3.0.8': {} - '@types/loader-utils@3.0.0(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.28)(uglify-js@3.19.3)': + '@types/loader-utils@3.0.0(esbuild@0.28.2)(lightningcss@1.33.0)(uglify-js@3.19.3)': dependencies: - '@types/node': 22.20.2 - webpack: 5.110.3(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.28)(uglify-js@3.19.3) + '@types/node': 22.20.4 + webpack: 5.111.0(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.28)(uglify-js@3.19.3) transitivePeerDependencies: - '@minify-html/node' - '@napi-rs/image' @@ -11605,7 +11500,7 @@ snapshots: dependencies: '@types/parse-glob': 3.0.32 - '@types/node@22.20.2': + '@types/node@22.20.4': dependencies: undici-types: 6.21.0 @@ -11621,12 +11516,12 @@ snapshots: '@types/progress@2.0.7': dependencies: - '@types/node': 22.20.2 + '@types/node': 22.20.4 '@types/pumpify@1.4.5': dependencies: '@types/duplexify': 3.6.5 - '@types/node': 22.20.2 + '@types/node': 22.20.4 '@types/qs@6.15.1': {} @@ -11634,7 +11529,7 @@ snapshots: '@types/readable-stream@4.0.10': dependencies: - '@types/node': 22.20.2 + '@types/node': 22.20.4 safe-buffer: 5.1.2 '@types/resolve@1.20.2': {} @@ -11645,7 +11540,7 @@ snapshots: '@types/send@1.2.1': dependencies: - '@types/node': 22.20.2 + '@types/node': 22.20.4 '@types/serve-index@1.9.4': dependencies: @@ -11654,13 +11549,13 @@ snapshots: '@types/serve-static@2.2.0': dependencies: '@types/http-errors': 2.0.5 - '@types/node': 22.20.2 + '@types/node': 22.20.4 '@types/stack-trace@0.0.33': {} '@types/tar-stream@3.1.4': dependencies: - '@types/node': 22.20.2 + '@types/node': 22.20.4 '@types/urijs@1.19.26': {} @@ -11668,7 +11563,7 @@ snapshots: '@types/ws@8.18.1': dependencies: - '@types/node': 22.20.2 + '@types/node': 22.20.4 '@types/yargs-parser@21.0.3': {} @@ -11738,6 +11633,8 @@ snapshots: '@typescript-eslint/types@8.70.0': {} + '@typescript-eslint/types@8.70.1': {} + '@typescript-eslint/typescript-estree@8.70.0(supports-color@11.0.0)(typescript@6.0.3)': dependencies: '@typescript-eslint/project-service': 8.70.0(supports-color@11.0.0)(typescript@6.0.3) @@ -11927,21 +11824,21 @@ snapshots: transitivePeerDependencies: - supports-color - '@vitejs/plugin-basic-ssl@2.3.0(vite@8.3.0(@types/node@22.20.2)(esbuild@0.28.2)(jiti@2.7.0)(less@4.9.1(supports-color@11.0.0))(sass-embedded@1.104.1)(sass@1.104.1)(terser@5.51.2)(tsx@4.23.13)(yaml@2.9.1))': + '@vitejs/plugin-basic-ssl@2.3.0(vite@8.3.0(@types/node@22.20.4)(esbuild@0.28.2)(jiti@2.7.0)(less@4.9.1(supports-color@11.0.0))(sass-embedded@1.104.1)(sass@1.104.1)(terser@5.51.2)(tsx@4.23.13)(yaml@2.9.1))': dependencies: - vite: 8.3.0(@types/node@22.20.2)(esbuild@0.28.2)(jiti@2.7.0)(less@4.9.1(supports-color@11.0.0))(sass-embedded@1.104.1)(sass@1.104.1)(terser@5.51.2)(tsx@4.23.13)(yaml@2.9.1) + vite: 8.3.0(@types/node@22.20.4)(esbuild@0.28.2)(jiti@2.7.0)(less@4.9.1(supports-color@11.0.0))(sass-embedded@1.104.1)(sass@1.104.1)(terser@5.51.2)(tsx@4.23.13)(yaml@2.9.1) '@vitest/coverage-v8@5.0.1(vitest@5.0.1)': dependencies: '@bcoe/v8-coverage': 1.0.2 '@vitest/istanbul-lib-coverage': 1.0.1 '@vitest/istanbul-lib-report': 1.0.1 - ast-v8-to-istanbul: 1.0.6 + ast-v8-to-istanbul: 1.0.7 magicast: 0.5.5 obug: 2.2.1 std-env: 4.2.0 tinyrainbow: 3.1.1 - vitest: 5.0.1(@opentelemetry/api@1.9.1)(@types/node@22.20.2)(@vitest/coverage-v8@5.0.1)(jsdom@30.0.1)(vite@8.3.0(@types/node@22.20.2)(esbuild@0.28.2)(jiti@2.7.0)(less@4.9.1(supports-color@11.0.0))(sass-embedded@1.104.0)(sass@1.104.0)(terser@5.51.2)(tsx@4.23.13)(yaml@2.9.1)) + vitest: 5.0.1(@opentelemetry/api@1.9.1)(@types/node@22.20.4)(@vitest/coverage-v8@5.0.1)(jsdom@30.0.1(@noble/hashes@1.8.0))(vite@8.3.0(@types/node@22.20.4)(esbuild@0.28.2)(jiti@2.7.0)(less@4.9.1(supports-color@11.0.0))(sass-embedded@1.104.1)(sass@1.104.1)(terser@5.51.2)(tsx@4.23.13)(yaml@2.9.1)) '@vitest/istanbul-lib-coverage@1.0.1': {} @@ -11949,23 +11846,14 @@ snapshots: dependencies: '@vitest/istanbul-lib-coverage': 1.0.1 - '@vitest/mocker@5.0.1(vite@8.3.0(@types/node@22.20.2)(esbuild@0.28.2)(jiti@2.7.0)(less@4.9.1(supports-color@11.0.0))(sass-embedded@1.104.0)(sass@1.104.0)(terser@5.51.2)(tsx@4.23.13)(yaml@2.9.1))': - dependencies: - '@jridgewell/trace-mapping': 0.3.31 - '@vitest/spy': 5.0.1 - estree-walker: 3.0.3 - magic-string: 1.2.3 - optionalDependencies: - vite: 8.3.0(@types/node@22.20.2)(esbuild@0.28.2)(jiti@2.7.0)(less@4.9.1(supports-color@11.0.0))(sass-embedded@1.104.0)(sass@1.104.0)(terser@5.51.2)(tsx@4.23.13)(yaml@2.9.1) - - '@vitest/mocker@5.0.1(vite@8.3.0(@types/node@22.20.2)(esbuild@0.28.2)(jiti@2.7.0)(less@4.9.1(supports-color@11.0.0))(sass-embedded@1.104.1)(sass@1.104.1)(terser@5.51.2)(tsx@4.23.13)(yaml@2.9.1))': + '@vitest/mocker@5.0.1(vite@8.3.0(@types/node@22.20.4)(esbuild@0.28.2)(jiti@2.7.0)(less@4.9.1(supports-color@11.0.0))(sass-embedded@1.104.1)(sass@1.104.1)(terser@5.51.2)(tsx@4.23.13)(yaml@2.9.1))': dependencies: '@jridgewell/trace-mapping': 0.3.31 '@vitest/spy': 5.0.1 estree-walker: 3.0.3 - magic-string: 1.2.3 + magic-string: 1.4.1 optionalDependencies: - vite: 8.3.0(@types/node@22.20.2)(esbuild@0.28.2)(jiti@2.7.0)(less@4.9.1(supports-color@11.0.0))(sass-embedded@1.104.1)(sass@1.104.1)(terser@5.51.2)(tsx@4.23.13)(yaml@2.9.1) + vite: 8.3.0(@types/node@22.20.4)(esbuild@0.28.2)(jiti@2.7.0)(less@4.9.1(supports-color@11.0.0))(sass-embedded@1.104.1)(sass@1.104.1)(terser@5.51.2)(tsx@4.23.13)(yaml@2.9.1) '@vitest/spy@5.0.1': {} @@ -12053,79 +11941,79 @@ snapshots: '@yarnpkg/lockfile@1.1.0': {} - '@yuku-codegen/binding-android-arm64@0.9.5': + '@yuku-codegen/binding-android-arm64@0.10.2': optional: true - '@yuku-codegen/binding-darwin-arm64@0.9.5': + '@yuku-codegen/binding-darwin-arm64@0.10.2': optional: true - '@yuku-codegen/binding-darwin-x64@0.9.5': + '@yuku-codegen/binding-darwin-x64@0.10.2': optional: true - '@yuku-codegen/binding-freebsd-x64@0.9.5': + '@yuku-codegen/binding-freebsd-x64@0.10.2': optional: true - '@yuku-codegen/binding-linux-arm-gnu@0.9.5': + '@yuku-codegen/binding-linux-arm-gnu@0.10.2': optional: true - '@yuku-codegen/binding-linux-arm-musl@0.9.5': + '@yuku-codegen/binding-linux-arm-musl@0.10.2': optional: true - '@yuku-codegen/binding-linux-arm64-gnu@0.9.5': + '@yuku-codegen/binding-linux-arm64-gnu@0.10.2': optional: true - '@yuku-codegen/binding-linux-arm64-musl@0.9.5': + '@yuku-codegen/binding-linux-arm64-musl@0.10.2': optional: true - '@yuku-codegen/binding-linux-x64-gnu@0.9.5': + '@yuku-codegen/binding-linux-x64-gnu@0.10.2': optional: true - '@yuku-codegen/binding-linux-x64-musl@0.9.5': + '@yuku-codegen/binding-linux-x64-musl@0.10.2': optional: true - '@yuku-codegen/binding-win32-arm64@0.9.5': + '@yuku-codegen/binding-win32-arm64@0.10.2': optional: true - '@yuku-codegen/binding-win32-x64@0.9.5': + '@yuku-codegen/binding-win32-x64@0.10.2': optional: true - '@yuku-parser/binding-android-arm64@0.9.5': + '@yuku-parser/binding-android-arm64@0.10.2': optional: true - '@yuku-parser/binding-darwin-arm64@0.9.5': + '@yuku-parser/binding-darwin-arm64@0.10.2': optional: true - '@yuku-parser/binding-darwin-x64@0.9.5': + '@yuku-parser/binding-darwin-x64@0.10.2': optional: true - '@yuku-parser/binding-freebsd-x64@0.9.5': + '@yuku-parser/binding-freebsd-x64@0.10.2': optional: true - '@yuku-parser/binding-linux-arm-gnu@0.9.5': + '@yuku-parser/binding-linux-arm-gnu@0.10.2': optional: true - '@yuku-parser/binding-linux-arm-musl@0.9.5': + '@yuku-parser/binding-linux-arm-musl@0.10.2': optional: true - '@yuku-parser/binding-linux-arm64-gnu@0.9.5': + '@yuku-parser/binding-linux-arm64-gnu@0.10.2': optional: true - '@yuku-parser/binding-linux-arm64-musl@0.9.5': + '@yuku-parser/binding-linux-arm64-musl@0.10.2': optional: true - '@yuku-parser/binding-linux-x64-gnu@0.9.5': + '@yuku-parser/binding-linux-x64-gnu@0.10.2': optional: true - '@yuku-parser/binding-linux-x64-musl@0.9.5': + '@yuku-parser/binding-linux-x64-musl@0.10.2': optional: true - '@yuku-parser/binding-win32-arm64@0.9.5': + '@yuku-parser/binding-win32-arm64@0.10.2': optional: true - '@yuku-parser/binding-win32-x64@0.9.5': + '@yuku-parser/binding-win32-x64@0.10.2': optional: true - '@yuku-toolchain/types@0.9.5': {} + '@yuku-toolchain/types@0.10.2': {} JSONStream@1.3.5: dependencies: @@ -12186,7 +12074,7 @@ snapshots: ajv@8.20.0: dependencies: fast-deep-equal: 3.1.3 - fast-uri: 3.1.7 + fast-uri: 3.1.8 json-schema-traverse: 1.0.0 require-from-string: 2.0.2 @@ -12293,7 +12181,7 @@ snapshots: assertion-error@2.0.1: {} - ast-v8-to-istanbul@1.0.6: + ast-v8-to-istanbul@1.0.7: dependencies: '@jridgewell/trace-mapping': 0.3.31 estree-walker: 3.0.3 @@ -12315,7 +12203,7 @@ snapshots: autoprefixer@10.6.0(postcss@8.5.28): dependencies: - browserslist: 4.28.9 + browserslist: 4.29.0 caniuse-lite: 1.0.30001810 fraction.js: 5.3.4 picocolors: 1.1.1 @@ -12382,7 +12270,7 @@ snapshots: base64id@2.0.0: {} - baseline-browser-mapping@2.11.23: {} + baseline-browser-mapping@2.11.25: {} batch@0.6.1: {} @@ -12456,16 +12344,16 @@ snapshots: boolbase@2.0.0: {} - brace-expansion@1.1.18: + brace-expansion@1.1.21: dependencies: balanced-match: 1.0.2 concat-map: 0.0.1 - brace-expansion@2.1.4: + brace-expansion@2.1.7: dependencies: balanced-match: 1.0.2 - brace-expansion@5.0.9: + brace-expansion@5.0.12: dependencies: balanced-match: 4.0.4 @@ -12535,13 +12423,13 @@ snapshots: dependencies: pako: 0.2.9 - browserslist@4.28.9: + browserslist@4.29.0: dependencies: - baseline-browser-mapping: 2.11.23 + baseline-browser-mapping: 2.11.25 caniuse-lite: 1.0.30001810 - electron-to-chromium: 1.5.427 - node-releases: 2.0.55 - update-browserslist-db: 1.3.3(browserslist@4.28.9) + electron-to-chromium: 1.5.434 + node-releases: 2.0.56 + update-browserslist-db: 1.3.3(browserslist@4.29.0) bs-recipes@1.3.4: {} @@ -12668,7 +12556,7 @@ snapshots: cli-truncate@6.1.1: dependencies: - slice-ansi: 9.0.0 + slice-ansi: 9.0.1 string-width: 8.2.2 cli-width@4.1.0: {} @@ -12790,7 +12678,7 @@ snapshots: content-type@2.1.0: {} - content-type@3.1.0: {} + content-type@3.1.1: {} conventional-commits-filter@6.0.1: {} @@ -12824,7 +12712,7 @@ snapshots: core-js-compat@3.50.0: dependencies: - browserslist: 4.28.9 + browserslist: 4.29.0 core-util-is@1.0.2: {} @@ -12888,10 +12776,10 @@ snapshots: data-uri-to-buffer@4.0.1: {} - data-urls@7.0.0: + data-urls@7.0.0(@noble/hashes@1.8.0): dependencies: whatwg-mimetype: 5.0.0 - whatwg-url: 16.0.1 + whatwg-url: 16.0.1(@noble/hashes@1.8.0) transitivePeerDependencies: - '@noble/hashes' @@ -13072,7 +12960,7 @@ snapshots: ejs@6.0.1: {} - electron-to-chromium@1.5.427: {} + electron-to-chromium@1.5.434: {} emoji-regex@10.6.0: {} @@ -13082,7 +12970,7 @@ snapshots: emojis-list@3.0.0: {} - empathic@2.0.1: {} + empathic@2.1.0: {} encodeurl@1.0.2: {} @@ -13113,7 +13001,7 @@ snapshots: engine.io@6.6.10(bufferutil@4.1.0)(supports-color@11.0.0)(utf-8-validate@6.0.6): dependencies: '@types/cors': 2.8.19 - '@types/node': 22.20.2 + '@types/node': 22.20.4 '@types/ws': 8.18.1 accepts: 1.3.8 cookie: 0.7.2 @@ -13214,10 +13102,10 @@ snapshots: string.prototype.trimstart: 1.0.8 typed-array-buffer: 1.0.3 typed-array-byte-length: 1.0.3 - typed-array-byte-offset: 1.0.4 + typed-array-byte-offset: 1.0.5 typed-array-length: 1.0.8 unbox-primitive: 1.1.0 - which-typed-array: 1.1.22 + which-typed-array: 1.1.24 es-define-property@1.0.1: {} @@ -13293,7 +13181,7 @@ snapshots: eslint-import-resolver-node@0.3.10(supports-color@11.0.0): dependencies: debug: 3.2.7(supports-color@11.0.0) - is-core-module: 2.16.2 + is-core-module: 2.17.0 resolve: 2.0.0-next.7 transitivePeerDependencies: - supports-color @@ -13321,7 +13209,7 @@ snapshots: eslint-import-resolver-node: 0.3.10(supports-color@11.0.0) eslint-module-utils: 2.14.0(@typescript-eslint/parser@8.70.0(eslint@10.10.0(jiti@2.7.0)(supports-color@11.0.0))(supports-color@11.0.0)(typescript@6.0.3))(eslint-import-resolver-node@0.3.10(supports-color@11.0.0))(eslint@10.10.0(jiti@2.7.0)(supports-color@11.0.0))(supports-color@11.0.0) hasown: 2.0.4 - is-core-module: 2.16.2 + is-core-module: 2.17.0 is-glob: 4.0.3 minimatch: 3.1.5 object.fromentries: 2.0.8 @@ -13459,7 +13347,7 @@ snapshots: on-finished: 2.4.1 parseurl: 1.3.3 path-to-regexp: 0.1.13 - proxy-addr: 2.0.7 + proxy-addr: 2.0.8 qs: 6.15.3 range-parser: 1.2.1 safe-buffer: 5.2.1 @@ -13494,7 +13382,7 @@ snapshots: on-finished: 2.4.1 once: 1.4.0 parseurl: 1.3.3 - proxy-addr: 2.0.7 + proxy-addr: 2.0.8 qs: 6.16.0 range-parser: 1.3.0 router: 2.2.0(supports-color@11.0.0) @@ -13532,7 +13420,7 @@ snapshots: dependencies: fast-string-truncated-width: 3.0.3 - fast-uri@3.1.7: {} + fast-uri@3.1.8: {} fast-wrap-ansi@0.2.2: dependencies: @@ -13665,6 +13553,8 @@ snapshots: flatted@3.4.4: {} + flru@1.0.2: {} + folder-hash@4.1.3(supports-color@11.0.0): dependencies: debug: 4.4.0(supports-color@11.0.0) @@ -13781,7 +13671,7 @@ snapshots: get-caller-file@2.0.5: {} - get-east-asian-width@1.6.0: {} + get-east-asian-width@1.7.0: {} get-intrinsic@1.3.0: dependencies: @@ -13899,7 +13789,7 @@ snapshots: google-gax@5.0.8(supports-color@11.0.0): dependencies: - '@grpc/grpc-js': 1.14.4 + '@grpc/grpc-js': 1.14.5 '@grpc/proto-loader': 0.8.1 duplexify: 4.1.3 google-auth-library: 10.5.0(supports-color@11.0.0) @@ -13929,7 +13819,7 @@ snapshots: keyv: 5.6.0 lowercase-keys: 4.0.1 responselike: 4.0.2 - type-fest: 5.9.0 + type-fest: 5.10.0 uint8array-extras: 1.5.0 graceful-fs@4.2.11: {} @@ -13943,7 +13833,7 @@ snapshots: grpc-gcp@1.1.1: dependencies: - '@grpc/grpc-js': 1.14.4 + '@grpc/grpc-js': 1.14.5 protobufjs: 7.6.6 gtoken@8.0.0(supports-color@11.0.0): @@ -14003,11 +13893,11 @@ snapshots: hosted-git-info@10.1.1: dependencies: - lru-cache: 11.5.2 + lru-cache: 11.5.3 - html-encoding-sniffer@6.0.0: + html-encoding-sniffer@6.0.0(@noble/hashes@1.8.0): dependencies: - '@exodus/bytes': 1.15.1 + '@exodus/bytes': 1.16.0(@noble/hashes@1.8.0) transitivePeerDependencies: - '@noble/hashes' @@ -14198,7 +14088,7 @@ snapshots: is-callable@1.2.7: {} - is-core-module@2.16.2: + is-core-module@2.17.0: dependencies: hasown: 2.0.4 @@ -14231,7 +14121,7 @@ snapshots: is-fullwidth-code-point@5.1.0: dependencies: - get-east-asian-width: 1.6.0 + get-east-asian-width: 1.7.0 is-generator-function@1.1.2: dependencies: @@ -14322,7 +14212,7 @@ snapshots: is-typed-array@1.1.15: dependencies: - which-typed-array: 1.1.22 + which-typed-array: 1.1.24 is-typedarray@1.0.0: {} @@ -14370,7 +14260,7 @@ snapshots: istanbul-lib-instrument@5.2.1(supports-color@11.0.0): dependencies: '@babel/core': 7.29.7(supports-color@11.0.0) - '@babel/parser': 7.29.8 + '@babel/parser': 7.29.9 '@istanbuljs/schema': 0.1.6 istanbul-lib-coverage: 3.2.2 semver: 6.3.1 @@ -14380,7 +14270,7 @@ snapshots: istanbul-lib-instrument@6.0.3(supports-color@11.0.0): dependencies: '@babel/core': 7.29.7(supports-color@11.0.0) - '@babel/parser': 7.29.8 + '@babel/parser': 7.29.9 '@istanbuljs/schema': 0.1.6 istanbul-lib-coverage: 3.2.2 semver: 7.8.5 @@ -14433,7 +14323,7 @@ snapshots: jest-worker@27.5.1: dependencies: - '@types/node': 22.20.2 + '@types/node': 22.20.4 merge-stream: 2.0.0 supports-color: 8.1.1 @@ -14453,19 +14343,19 @@ snapshots: jsbn@0.1.1: {} - jsdom@30.0.1: + jsdom@30.0.1(@noble/hashes@1.8.0): dependencies: '@asamuzakjp/css-color': 6.0.7 '@asamuzakjp/dom-selector': 8.3.2 '@bramus/specificity': 2.4.2 - '@csstools/css-syntax-patches-for-csstree': 1.1.13(css-tree@3.2.1) - '@exodus/bytes': 1.15.1 + '@csstools/css-syntax-patches-for-csstree': 1.1.14(css-tree@3.2.1) + '@exodus/bytes': 1.16.0(@noble/hashes@1.8.0) css-tree: 3.2.1 - data-urls: 7.0.0 + data-urls: 7.0.0(@noble/hashes@1.8.0) decimal.js: 10.6.0 - html-encoding-sniffer: 6.0.0 + html-encoding-sniffer: 6.0.0(@noble/hashes@1.8.0) is-potential-custom-element-name: 1.0.1 - lru-cache: 11.5.2 + lru-cache: 11.5.3 parse5: 8.0.1 saxes: 6.0.0 symbol-tree: 3.2.4 @@ -14474,7 +14364,7 @@ snapshots: w3c-xmlserializer: 5.0.0 webidl-conversions: 8.0.1 whatwg-mimetype: 5.0.0 - whatwg-url: 17.1.1 + whatwg-url: 17.1.2(@noble/hashes@1.8.0) xml-name-validator: 5.0.0 transitivePeerDependencies: - '@noble/hashes' @@ -14713,7 +14603,7 @@ snapshots: dependencies: cli-truncate: 6.1.1 log-update: 8.0.0 - wrap-ansi: 10.0.1 + wrap-ansi: 10.0.2 lmdb@3.5.6: dependencies: @@ -14785,10 +14675,10 @@ snapshots: dependencies: ansi-escapes: 7.3.0 cli-cursor: 5.0.0 - slice-ansi: 9.0.0 + slice-ansi: 9.0.1 string-width: 8.2.2 strip-ansi: 7.2.0 - wrap-ansi: 10.0.1 + wrap-ansi: 10.0.2 log4js@6.9.1(supports-color@11.0.0): dependencies: @@ -14816,7 +14706,7 @@ snapshots: lru-cache@10.4.3: {} - lru-cache@11.5.2: {} + lru-cache@11.5.3: {} lru-cache@5.1.1: dependencies: @@ -14828,17 +14718,13 @@ snapshots: dependencies: '@jridgewell/sourcemap-codec': 1.6.0 - magic-string@1.2.3: - dependencies: - '@jridgewell/sourcemap-codec': 1.6.0 - magic-string@1.4.1: dependencies: '@jridgewell/sourcemap-codec': 1.6.0 magicast@0.5.5: dependencies: - '@babel/parser': 7.29.8 + '@babel/parser': 7.29.9 '@babel/types': 7.29.8 source-map-js: 1.2.1 @@ -14857,16 +14743,16 @@ snapshots: media-typer@1.1.1: {} - memfs@4.78.0: + memfs@4.79.0: dependencies: - '@jsonjoy.com/fs-core': 4.78.0(tslib@2.8.1) - '@jsonjoy.com/fs-fsa': 4.78.0(tslib@2.8.1) - '@jsonjoy.com/fs-node': 4.78.0(tslib@2.8.1) - '@jsonjoy.com/fs-node-builtins': 4.78.0(tslib@2.8.1) - '@jsonjoy.com/fs-node-to-fsa': 4.78.0(tslib@2.8.1) - '@jsonjoy.com/fs-node-utils': 4.78.0(tslib@2.8.1) - '@jsonjoy.com/fs-print': 4.78.0(tslib@2.8.1) - '@jsonjoy.com/fs-snapshot': 4.78.0(tslib@2.8.1) + '@jsonjoy.com/fs-core': 4.79.0(tslib@2.8.1) + '@jsonjoy.com/fs-fsa': 4.79.0(tslib@2.8.1) + '@jsonjoy.com/fs-node': 4.79.0(tslib@2.8.1) + '@jsonjoy.com/fs-node-builtins': 4.79.0(tslib@2.8.1) + '@jsonjoy.com/fs-node-to-fsa': 4.79.0(tslib@2.8.1) + '@jsonjoy.com/fs-node-utils': 4.79.0(tslib@2.8.1) + '@jsonjoy.com/fs-print': 4.79.0(tslib@2.8.1) + '@jsonjoy.com/fs-snapshot': 4.79.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.3.1(tslib@2.8.1) @@ -14919,36 +14805,23 @@ snapshots: minimatch@10.2.6: dependencies: - brace-expansion: 5.0.9 + brace-expansion: 5.0.12 minimatch@3.1.5: dependencies: - brace-expansion: 1.1.18 + brace-expansion: 1.1.21 minimatch@7.4.9: dependencies: - brace-expansion: 2.1.4 + brace-expansion: 2.1.7 minimatch@9.0.9: dependencies: - brace-expansion: 2.1.4 + brace-expansion: 2.1.7 minimist@1.2.8: {} - minimizer-webpack-plugin@5.10.1(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.28)(uglify-js@3.19.3)(webpack@5.110.3(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.28)(uglify-js@3.19.3)): - dependencies: - '@jridgewell/trace-mapping': 0.3.31 - jest-worker: 27.5.1 - schema-utils: 4.5.0 - terser: 5.51.2 - webpack: 5.110.3(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.28)(uglify-js@3.19.3) - optionalDependencies: - esbuild: 0.28.2 - lightningcss: 1.33.0 - postcss: 8.5.28 - uglify-js: 3.19.3 - - minimizer-webpack-plugin@5.10.1(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.28)(uglify-js@3.19.3)(webpack@5.111.0(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.28)(uglify-js@3.19.3)): + minimizer-webpack-plugin@5.11.0(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.28)(uglify-js@3.19.3)(webpack@5.111.0(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.28)(uglify-js@3.19.3)): dependencies: '@jridgewell/trace-mapping': 0.3.31 jest-worker: 27.5.1 @@ -15045,7 +14918,7 @@ snapshots: '@ampproject/remapping': 2.3.0 '@angular/compiler-cli': 22.2.0-rc.0(@angular/compiler@22.2.0-rc.0)(typescript@6.0.3) ajv: 8.20.0 - browserslist: 4.28.9 + browserslist: 4.29.0 chokidar: 5.0.0 commander: 15.0.0 dependency-graph: 1.0.0 @@ -15057,7 +14930,7 @@ snapshots: ora: 9.4.1 postcss: 8.5.28 rolldown: 1.2.8 - rolldown-plugin-dts: 0.28.5(rolldown@1.2.8)(typescript@6.0.3) + rolldown-plugin-dts: 0.28.6(rolldown@1.2.8)(typescript@6.0.3) rxjs: 7.8.2 sass: 1.104.1 sass-embedded: 1.104.1 @@ -15067,6 +14940,7 @@ snapshots: transitivePeerDependencies: - '@typescript/native-preview' - '@volar/typescript' + - '@vue/language-core' - oxc-resolver - supports-color - vue-tsc @@ -15110,7 +14984,7 @@ snapshots: node-gyp-build@4.8.4: {} - node-releases@2.0.55: {} + node-releases@2.0.56: {} normalize-path@3.0.0: {} @@ -15173,6 +15047,8 @@ snapshots: obug@2.2.1: {} + obug@3.0.0: {} + on-exit-leak-free@2.1.2: {} on-finished@2.3.0: @@ -15338,7 +15214,7 @@ snapshots: path-scurry@2.0.2: dependencies: - lru-cache: 11.5.2 + lru-cache: 11.5.3 minipass: 7.1.3 path-to-regexp@0.1.13: {} @@ -15396,9 +15272,9 @@ snapshots: dependencies: find-up-simple: 1.0.1 - pkijs@3.4.0: + pkijs@3.4.1: dependencies: - '@noble/hashes': 1.4.0 + '@noble/hashes': 1.8.0 asn1js: 3.0.10 bytestreamjs: 2.0.1 pvtsutils: 1.3.6 @@ -15471,7 +15347,7 @@ snapshots: prelude-ls@1.2.1: {} - prettier@3.9.6: {} + prettier@3.9.8: {} probe-image-size@7.4.0(supports-color@11.0.0): dependencies: @@ -15509,10 +15385,10 @@ snapshots: '@protobufjs/path': 1.1.2 '@protobufjs/pool': 1.1.0 '@protobufjs/utf8': 1.1.2 - '@types/node': 22.20.2 + '@types/node': 22.20.4 long: 5.3.2 - proxy-addr@2.0.7: + proxy-addr@2.0.8: dependencies: forwarded: 0.2.0 ipaddr.js: 1.9.1 @@ -15704,13 +15580,13 @@ snapshots: regenerate: 1.4.2 regenerate-unicode-properties: 10.2.2 regjsgen: 0.8.0 - regjsparser: 0.13.2 + regjsparser: 0.13.3 unicode-match-property-ecmascript: 2.0.0 unicode-match-property-value-ecmascript: 2.2.1 regjsgen@0.8.0: {} - regjsparser@0.13.2: + regjsparser@0.13.3: dependencies: jsesc: 3.1.0 @@ -15737,14 +15613,14 @@ snapshots: resolve@1.22.12: dependencies: es-errors: 1.3.0 - is-core-module: 2.16.2 + is-core-module: 2.17.0 path-parse: 1.0.7 supports-preserve-symlinks-flag: 1.0.0 resolve@2.0.0-next.7: dependencies: es-errors: 1.3.0 - is-core-module: 2.16.2 + is-core-module: 2.17.0 node-exports-info: 1.6.2 object-keys: 1.1.1 path-parse: 1.0.7 @@ -15787,15 +15663,15 @@ snapshots: dependencies: glob: 10.5.0 - rolldown-plugin-dts@0.28.5(rolldown@1.2.8)(typescript@6.0.3): + rolldown-plugin-dts@0.28.6(rolldown@1.2.8)(typescript@6.0.3): dependencies: dts-resolver: 3.0.0 get-tsconfig: 5.0.0-beta.6 - obug: 2.2.1 + obug: 3.0.0 rolldown: 1.2.8 - yuku-ast: 0.9.5 - yuku-codegen: 0.9.5 - yuku-parser: 0.9.5 + yuku-ast: 0.10.2 + yuku-codegen: 0.10.2 + yuku-parser: 0.10.2 optionalDependencies: typescript: 6.0.3 transitivePeerDependencies: @@ -15831,14 +15707,14 @@ snapshots: rollup: 4.63.3 typescript: 6.0.3 optionalDependencies: - '@babel/code-frame': 8.0.0 + '@babel/code-frame': 8.0.6 - rollup-plugin-sourcemaps2@0.5.8(@types/node@22.20.2)(rollup@4.63.3): + rollup-plugin-sourcemaps2@0.5.8(@types/node@22.20.4)(rollup@4.63.3): dependencies: '@rollup/pluginutils': 5.4.0(rollup@4.63.3) rollup: 4.63.3 optionalDependencies: - '@types/node': 22.20.2 + '@types/node': 22.20.4 rollup@4.63.3: dependencies: @@ -15925,152 +15801,64 @@ snapshots: dependencies: truncate-utf8-bytes: 1.0.2 - sass-embedded-all-unknown@1.104.0: - dependencies: - sass: 1.104.0 - optional: true - sass-embedded-all-unknown@1.104.1: dependencies: sass: 1.104.1 optional: true - sass-embedded-android-arm64@1.104.0: - optional: true - sass-embedded-android-arm64@1.104.1: optional: true - sass-embedded-android-arm@1.104.0: - optional: true - sass-embedded-android-arm@1.104.1: optional: true - sass-embedded-android-riscv64@1.104.0: - optional: true - sass-embedded-android-riscv64@1.104.1: optional: true - sass-embedded-android-x64@1.104.0: - optional: true - sass-embedded-android-x64@1.104.1: optional: true - sass-embedded-darwin-arm64@1.104.0: - optional: true - sass-embedded-darwin-arm64@1.104.1: optional: true - sass-embedded-darwin-x64@1.104.0: - optional: true - sass-embedded-darwin-x64@1.104.1: optional: true - sass-embedded-linux-arm64@1.104.0: - optional: true - sass-embedded-linux-arm64@1.104.1: optional: true - sass-embedded-linux-arm@1.104.0: - optional: true - sass-embedded-linux-arm@1.104.1: optional: true - sass-embedded-linux-musl-arm64@1.104.0: - optional: true - sass-embedded-linux-musl-arm64@1.104.1: optional: true - sass-embedded-linux-musl-arm@1.104.0: - optional: true - sass-embedded-linux-musl-arm@1.104.1: optional: true - sass-embedded-linux-musl-riscv64@1.104.0: - optional: true - sass-embedded-linux-musl-riscv64@1.104.1: optional: true - sass-embedded-linux-musl-x64@1.104.0: - optional: true - sass-embedded-linux-musl-x64@1.104.1: optional: true - sass-embedded-linux-riscv64@1.104.0: - optional: true - sass-embedded-linux-riscv64@1.104.1: optional: true - sass-embedded-linux-x64@1.104.0: - optional: true - sass-embedded-linux-x64@1.104.1: optional: true - sass-embedded-unknown-all@1.104.0: - dependencies: - sass: 1.104.0 - optional: true - sass-embedded-unknown-all@1.104.1: dependencies: sass: 1.104.1 optional: true - sass-embedded-win32-arm64@1.104.0: - optional: true - sass-embedded-win32-arm64@1.104.1: optional: true - sass-embedded-win32-x64@1.104.0: - optional: true - sass-embedded-win32-x64@1.104.1: optional: true - sass-embedded@1.104.0: - dependencies: - '@bufbuild/protobuf': 2.15.0 - colorjs.io: 0.7.1 - immutable: 5.1.9 - rxjs: 7.8.2 - supports-color: 8.1.1 - sync-child-process: 1.0.2 - varint: 6.0.0 - optionalDependencies: - sass-embedded-all-unknown: 1.104.0 - sass-embedded-android-arm: 1.104.0 - sass-embedded-android-arm64: 1.104.0 - sass-embedded-android-riscv64: 1.104.0 - sass-embedded-android-x64: 1.104.0 - sass-embedded-darwin-arm64: 1.104.0 - sass-embedded-darwin-x64: 1.104.0 - sass-embedded-linux-arm: 1.104.0 - sass-embedded-linux-arm64: 1.104.0 - sass-embedded-linux-musl-arm: 1.104.0 - sass-embedded-linux-musl-arm64: 1.104.0 - sass-embedded-linux-musl-riscv64: 1.104.0 - sass-embedded-linux-musl-x64: 1.104.0 - sass-embedded-linux-riscv64: 1.104.0 - sass-embedded-linux-x64: 1.104.0 - sass-embedded-unknown-all: 1.104.0 - sass-embedded-win32-arm64: 1.104.0 - sass-embedded-win32-x64: 1.104.0 - optional: true - sass-embedded@1.104.1: dependencies: '@bufbuild/protobuf': 2.15.0 @@ -16100,21 +15888,12 @@ snapshots: sass-embedded-win32-arm64: 1.104.1 sass-embedded-win32-x64: 1.104.1 - sass-loader@17.0.1(sass-embedded@1.104.0)(sass@1.104.1)(webpack@5.111.0(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.28)(uglify-js@3.19.3)): + sass-loader@17.0.1(sass-embedded@1.104.1)(sass@1.104.1)(webpack@5.111.0(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.28)(uglify-js@3.19.3)): optionalDependencies: sass: 1.104.1 - sass-embedded: 1.104.0 + sass-embedded: 1.104.1 webpack: 5.111.0(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.28)(uglify-js@3.19.3) - sass@1.104.0: - dependencies: - chokidar: 5.0.0 - immutable: 5.1.9 - source-map-js: 1.2.1 - optionalDependencies: - '@parcel/watcher': 2.6.0 - optional: true - sass@1.104.1: dependencies: chokidar: 5.0.0 @@ -16140,7 +15919,7 @@ snapshots: selfsigned@5.5.0: dependencies: '@peculiar/x509': 1.14.3 - pkijs: 3.4.0 + pkijs: 3.4.1 semver@6.3.1: {} @@ -16286,7 +16065,7 @@ snapshots: slash@3.0.0: {} - slice-ansi@9.0.0: + slice-ansi@9.0.1: dependencies: ansi-styles: 6.2.3 is-fullwidth-code-point: 5.1.0 @@ -16455,12 +16234,12 @@ snapshots: string-width@7.2.0: dependencies: emoji-regex: 10.6.0 - get-east-asian-width: 1.6.0 + get-east-asian-width: 1.7.0 strip-ansi: 7.2.0 string-width@8.2.2: dependencies: - get-east-asian-width: 1.6.0 + get-east-asian-width: 1.7.0 strip-ansi: 7.2.0 string.prototype.trim@1.2.11: @@ -16620,15 +16399,15 @@ snapshots: tldts-core@6.1.86: {} - tldts-core@7.4.13: {} + tldts-core@7.4.14: {} tldts@6.1.86: dependencies: tldts-core: 6.1.86 - tldts@7.4.13: + tldts@7.4.14: dependencies: - tldts-core: 7.4.13 + tldts-core: 7.4.14 tmp@0.2.7: {} @@ -16646,7 +16425,7 @@ snapshots: tough-cookie@6.0.2: dependencies: - tldts: 7.4.13 + tldts: 7.4.14 tr46@0.0.3: {} @@ -16701,7 +16480,7 @@ snapshots: dependencies: prelude-ls: 1.2.1 - type-fest@5.9.0: + type-fest@5.10.0: dependencies: tagged-tag: 1.0.0 @@ -16730,13 +16509,12 @@ snapshots: has-proto: 1.2.0 is-typed-array: 1.1.15 - typed-array-byte-offset@1.0.4: + typed-array-byte-offset@1.0.5: dependencies: available-typed-arrays: 1.0.7 call-bind: 1.0.9 for-each: 0.3.5 gopd: 1.2.0 - has-proto: 1.2.0 is-typed-array: 1.1.15 reflect.getprototypeof: 1.0.10 @@ -16812,9 +16590,9 @@ snapshots: unpipe@1.0.0: {} - update-browserslist-db@1.3.3(browserslist@4.28.9): + update-browserslist-db@1.3.3(browserslist@4.29.0): dependencies: - browserslist: 4.28.9 + browserslist: 4.29.0 escalade: 3.2.0 picocolors: 1.1.1 @@ -16919,7 +16697,7 @@ snapshots: core-util-is: 1.0.2 extsprintf: 1.3.0 - vite@8.3.0(@types/node@22.20.2)(esbuild@0.28.2)(jiti@2.7.0)(less@4.9.1(supports-color@11.0.0))(sass-embedded@1.104.0)(sass@1.104.0)(terser@5.51.2)(tsx@4.23.13)(yaml@2.9.1): + vite@8.3.0(@types/node@22.20.4)(esbuild@0.28.2)(jiti@2.7.0)(less@4.9.1(supports-color@11.0.0))(sass-embedded@1.104.1)(sass@1.104.1)(terser@5.51.2)(tsx@4.23.13)(yaml@2.9.1): dependencies: lightningcss: 1.33.0 picomatch: 4.0.7 @@ -16927,26 +16705,7 @@ snapshots: rolldown: 1.2.8 tinyglobby: 0.2.17 optionalDependencies: - '@types/node': 22.20.2 - esbuild: 0.28.2 - fsevents: 2.3.3 - jiti: 2.7.0 - less: 4.9.1(supports-color@11.0.0) - sass: 1.104.0 - sass-embedded: 1.104.0 - terser: 5.51.2 - tsx: 4.23.13 - yaml: 2.9.1 - - vite@8.3.0(@types/node@22.20.2)(esbuild@0.28.2)(jiti@2.7.0)(less@4.9.1(supports-color@11.0.0))(sass-embedded@1.104.1)(sass@1.104.1)(terser@5.51.2)(tsx@4.23.13)(yaml@2.9.1): - dependencies: - lightningcss: 1.33.0 - picomatch: 4.0.7 - postcss: 8.5.28 - rolldown: 1.2.8 - tinyglobby: 0.2.17 - optionalDependencies: - '@types/node': 22.20.2 + '@types/node': 22.20.4 esbuild: 0.28.2 fsevents: 2.3.3 jiti: 2.7.0 @@ -16957,51 +16716,27 @@ snapshots: tsx: 4.23.13 yaml: 2.9.1 - vitest@5.0.1(@opentelemetry/api@1.9.1)(@types/node@22.20.2)(@vitest/coverage-v8@5.0.1)(jsdom@30.0.1)(vite@8.3.0(@types/node@22.20.2)(esbuild@0.28.2)(jiti@2.7.0)(less@4.9.1(supports-color@11.0.0))(sass-embedded@1.104.0)(sass@1.104.0)(terser@5.51.2)(tsx@4.23.13)(yaml@2.9.1)): + vitest@5.0.1(@opentelemetry/api@1.9.1)(@types/node@22.20.4)(@vitest/coverage-v8@5.0.1)(jsdom@30.0.1(@noble/hashes@1.8.0))(vite@8.3.0(@types/node@22.20.4)(esbuild@0.28.2)(jiti@2.7.0)(less@4.9.1(supports-color@11.0.0))(sass-embedded@1.104.1)(sass@1.104.1)(terser@5.51.2)(tsx@4.23.13)(yaml@2.9.1)): dependencies: '@types/chai': 5.2.3 - '@vitest/mocker': 5.0.1(vite@8.3.0(@types/node@22.20.2)(esbuild@0.28.2)(jiti@2.7.0)(less@4.9.1(supports-color@11.0.0))(sass-embedded@1.104.0)(sass@1.104.0)(terser@5.51.2)(tsx@4.23.13)(yaml@2.9.1)) + '@vitest/mocker': 5.0.1(vite@8.3.0(@types/node@22.20.4)(esbuild@0.28.2)(jiti@2.7.0)(less@4.9.1(supports-color@11.0.0))(sass-embedded@1.104.1)(sass@1.104.1)(terser@5.51.2)(tsx@4.23.13)(yaml@2.9.1)) chai: 6.2.2 es-module-lexer: 2.3.2 expect-type: 1.4.0 - magic-string: 1.2.3 + magic-string: 1.4.1 obug: 2.2.1 picomatch: 4.0.7 std-env: 4.2.0 tinybench: 6.1.4 tinyexec: 1.3.0 tinyglobby: 0.2.17 - vite: 8.3.0(@types/node@22.20.2)(esbuild@0.28.2)(jiti@2.7.0)(less@4.9.1(supports-color@11.0.0))(sass-embedded@1.104.0)(sass@1.104.0)(terser@5.51.2)(tsx@4.23.13)(yaml@2.9.1) + vite: 8.3.0(@types/node@22.20.4)(esbuild@0.28.2)(jiti@2.7.0)(less@4.9.1(supports-color@11.0.0))(sass-embedded@1.104.1)(sass@1.104.1)(terser@5.51.2)(tsx@4.23.13)(yaml@2.9.1) why-is-node-running: 2.3.0 optionalDependencies: '@opentelemetry/api': 1.9.1 - '@types/node': 22.20.2 + '@types/node': 22.20.4 '@vitest/coverage-v8': 5.0.1(vitest@5.0.1) - jsdom: 30.0.1 - transitivePeerDependencies: - - msw - - vitest@5.0.1(@opentelemetry/api@1.9.1)(@types/node@22.20.2)(@vitest/coverage-v8@5.0.1)(jsdom@30.0.1)(vite@8.3.0(@types/node@22.20.2)(esbuild@0.28.2)(jiti@2.7.0)(less@4.9.1(supports-color@11.0.0))(sass-embedded@1.104.1)(sass@1.104.1)(terser@5.51.2)(tsx@4.23.13)(yaml@2.9.1)): - dependencies: - '@types/chai': 5.2.3 - '@vitest/mocker': 5.0.1(vite@8.3.0(@types/node@22.20.2)(esbuild@0.28.2)(jiti@2.7.0)(less@4.9.1(supports-color@11.0.0))(sass-embedded@1.104.1)(sass@1.104.1)(terser@5.51.2)(tsx@4.23.13)(yaml@2.9.1)) - chai: 6.2.2 - es-module-lexer: 2.3.2 - expect-type: 1.4.0 - magic-string: 1.2.3 - obug: 2.2.1 - picomatch: 4.0.7 - std-env: 4.2.0 - tinybench: 6.1.4 - tinyexec: 1.3.0 - tinyglobby: 0.2.17 - vite: 8.3.0(@types/node@22.20.2)(esbuild@0.28.2)(jiti@2.7.0)(less@4.9.1(supports-color@11.0.0))(sass-embedded@1.104.1)(sass@1.104.1)(terser@5.51.2)(tsx@4.23.13)(yaml@2.9.1) - why-is-node-running: 2.3.0 - optionalDependencies: - '@opentelemetry/api': 1.9.1 - '@types/node': 22.20.2 - '@vitest/coverage-v8': 5.0.1(vitest@5.0.1) - jsdom: 30.0.1 + jsdom: 30.0.1(@noble/hashes@1.8.0) transitivePeerDependencies: - msw @@ -17028,17 +16763,17 @@ snapshots: webidl-conversions@8.0.1: {} - webpack-dev-middleware@8.3.0(webpack@5.111.0(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.28)(uglify-js@3.19.3)): + webpack-dev-middleware@8.3.0(webpack@5.111.0(esbuild@0.28.2)(lightningcss@1.33.0)(uglify-js@3.19.3)): dependencies: ansi-html-community: 0.0.8 - memfs: 4.78.0 + memfs: 4.79.0 mime-types: 3.0.2 range-parser: 1.3.0 schema-utils: 4.5.0 optionalDependencies: webpack: 5.111.0(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.28)(uglify-js@3.19.3) - webpack-dev-server@6.0.0(bufferutil@4.1.0)(supports-color@11.0.0)(utf-8-validate@6.0.6)(webpack@5.111.0(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.28)(uglify-js@3.19.3)): + webpack-dev-server@6.0.0(bufferutil@4.1.0)(supports-color@11.0.0)(utf-8-validate@6.0.6)(webpack@5.111.0(esbuild@0.28.2)(lightningcss@1.33.0)(uglify-js@3.19.3)): dependencies: '@types/bonjour': 3.5.13 '@types/connect-history-api-fallback': 1.5.4 @@ -17063,7 +16798,7 @@ snapshots: selfsigned: 5.5.0 serve-index: 1.9.2(supports-color@11.0.0) tinyglobby: 0.2.17 - webpack-dev-middleware: 8.3.0(webpack@5.111.0(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.28)(uglify-js@3.19.3)) + webpack-dev-middleware: 8.3.0(webpack@5.111.0(esbuild@0.28.2)(lightningcss@1.33.0)(uglify-js@3.19.3)) ws: 8.21.3(bufferutil@4.1.0)(utf-8-validate@6.0.6) optionalDependencies: webpack: 5.111.0(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.28)(uglify-js@3.19.3) @@ -17085,45 +16820,6 @@ snapshots: typed-assert: 1.0.9 webpack: 5.111.0(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.28)(uglify-js@3.19.3) - webpack@5.110.3(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.28)(uglify-js@3.19.3): - dependencies: - '@types/estree': 1.0.9 - '@types/json-schema': 7.0.15 - '@webassemblyjs/ast': 1.14.1 - '@webassemblyjs/wasm-edit': 1.14.1 - '@webassemblyjs/wasm-parser': 1.14.1 - acorn: 8.18.0 - browserslist: 4.28.9 - chrome-trace-event: 1.0.4 - enhanced-resolve: 5.25.1 - es-module-lexer: 2.3.2 - events: 3.3.0 - graceful-fs: 4.2.11 - mime-db: 1.54.0 - minimizer-webpack-plugin: 5.10.1(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.28)(uglify-js@3.19.3)(webpack@5.110.3(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.28)(uglify-js@3.19.3)) - neo-async: 2.6.2 - schema-utils: 4.5.0 - tapable: 2.3.3 - watchpack: 2.5.2 - webpack-sources: 3.5.1 - transitivePeerDependencies: - - '@minify-html/node' - - '@napi-rs/image' - - '@swc/core' - - '@swc/css' - - '@swc/html' - - clean-css - - cssnano - - csso - - esbuild - - html-minifier-terser - - imagemin - - lightningcss - - postcss - - sharp - - svgo - - uglify-js - webpack@5.111.0(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.28)(uglify-js@3.19.3): dependencies: '@types/estree': 1.0.9 @@ -17131,14 +16827,14 @@ snapshots: '@webassemblyjs/ast': 1.14.1 '@webassemblyjs/wasm-edit': 1.14.1 '@webassemblyjs/wasm-parser': 1.14.1 - browserslist: 4.28.9 + browserslist: 4.29.0 chrome-trace-event: 1.0.4 enhanced-resolve: 5.25.1 es-module-lexer: 2.3.2 events: 3.3.0 graceful-fs: 4.2.11 mime-db: 1.54.0 - minimizer-webpack-plugin: 5.10.1(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.28)(uglify-js@3.19.3)(webpack@5.111.0(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.28)(uglify-js@3.19.3)) + minimizer-webpack-plugin: 5.11.0(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.28)(uglify-js@3.19.3)(webpack@5.111.0(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.28)(uglify-js@3.19.3)) schema-utils: 4.5.0 tapable: 2.3.3 watchpack: 2.5.2 @@ -17171,17 +16867,17 @@ snapshots: whatwg-mimetype@5.0.0: {} - whatwg-url@16.0.1: + whatwg-url@16.0.1(@noble/hashes@1.8.0): dependencies: - '@exodus/bytes': 1.15.1 + '@exodus/bytes': 1.16.0(@noble/hashes@1.8.0) tr46: 6.0.0 webidl-conversions: 8.0.1 transitivePeerDependencies: - '@noble/hashes' - whatwg-url@17.1.1: + whatwg-url@17.1.2(@noble/hashes@1.8.0): dependencies: - '@exodus/bytes': 1.15.1 + '@exodus/bytes': 1.16.0(@noble/hashes@1.8.0) tr46: 6.0.0 webidl-conversions: 8.0.1 transitivePeerDependencies: @@ -17214,7 +16910,7 @@ snapshots: isarray: 2.0.5 which-boxed-primitive: 1.1.1 which-collection: 1.0.2 - which-typed-array: 1.1.22 + which-typed-array: 1.1.24 which-collection@1.0.2: dependencies: @@ -17223,7 +16919,7 @@ snapshots: is-weakmap: 2.0.2 is-weakset: 2.0.4 - which-typed-array@1.1.22: + which-typed-array@1.1.24: dependencies: available-typed-arrays: 1.0.7 call-bind: 1.0.9 @@ -17256,7 +16952,7 @@ snapshots: wordwrap@1.0.0: {} - wrap-ansi@10.0.1: + wrap-ansi@10.0.2: dependencies: ansi-styles: 6.2.3 string-width: 8.2.2 @@ -17348,44 +17044,44 @@ snapshots: yoctocolors@2.2.0: {} - yuku-ast@0.9.5: + yuku-ast@0.10.2: dependencies: - '@yuku-toolchain/types': 0.9.5 + '@yuku-toolchain/types': 0.10.2 - yuku-codegen@0.9.5: + yuku-codegen@0.10.2: dependencies: - '@yuku-toolchain/types': 0.9.5 + '@yuku-toolchain/types': 0.10.2 optionalDependencies: - '@yuku-codegen/binding-android-arm64': 0.9.5 - '@yuku-codegen/binding-darwin-arm64': 0.9.5 - '@yuku-codegen/binding-darwin-x64': 0.9.5 - '@yuku-codegen/binding-freebsd-x64': 0.9.5 - '@yuku-codegen/binding-linux-arm-gnu': 0.9.5 - '@yuku-codegen/binding-linux-arm-musl': 0.9.5 - '@yuku-codegen/binding-linux-arm64-gnu': 0.9.5 - '@yuku-codegen/binding-linux-arm64-musl': 0.9.5 - '@yuku-codegen/binding-linux-x64-gnu': 0.9.5 - '@yuku-codegen/binding-linux-x64-musl': 0.9.5 - '@yuku-codegen/binding-win32-arm64': 0.9.5 - '@yuku-codegen/binding-win32-x64': 0.9.5 - - yuku-parser@0.9.5: - dependencies: - '@yuku-toolchain/types': 0.9.5 - yuku-ast: 0.9.5 + '@yuku-codegen/binding-android-arm64': 0.10.2 + '@yuku-codegen/binding-darwin-arm64': 0.10.2 + '@yuku-codegen/binding-darwin-x64': 0.10.2 + '@yuku-codegen/binding-freebsd-x64': 0.10.2 + '@yuku-codegen/binding-linux-arm-gnu': 0.10.2 + '@yuku-codegen/binding-linux-arm-musl': 0.10.2 + '@yuku-codegen/binding-linux-arm64-gnu': 0.10.2 + '@yuku-codegen/binding-linux-arm64-musl': 0.10.2 + '@yuku-codegen/binding-linux-x64-gnu': 0.10.2 + '@yuku-codegen/binding-linux-x64-musl': 0.10.2 + '@yuku-codegen/binding-win32-arm64': 0.10.2 + '@yuku-codegen/binding-win32-x64': 0.10.2 + + yuku-parser@0.10.2: + dependencies: + '@yuku-toolchain/types': 0.10.2 + yuku-ast: 0.10.2 optionalDependencies: - '@yuku-parser/binding-android-arm64': 0.9.5 - '@yuku-parser/binding-darwin-arm64': 0.9.5 - '@yuku-parser/binding-darwin-x64': 0.9.5 - '@yuku-parser/binding-freebsd-x64': 0.9.5 - '@yuku-parser/binding-linux-arm-gnu': 0.9.5 - '@yuku-parser/binding-linux-arm-musl': 0.9.5 - '@yuku-parser/binding-linux-arm64-gnu': 0.9.5 - '@yuku-parser/binding-linux-arm64-musl': 0.9.5 - '@yuku-parser/binding-linux-x64-gnu': 0.9.5 - '@yuku-parser/binding-linux-x64-musl': 0.9.5 - '@yuku-parser/binding-win32-arm64': 0.9.5 - '@yuku-parser/binding-win32-x64': 0.9.5 + '@yuku-parser/binding-android-arm64': 0.10.2 + '@yuku-parser/binding-darwin-arm64': 0.10.2 + '@yuku-parser/binding-darwin-x64': 0.10.2 + '@yuku-parser/binding-freebsd-x64': 0.10.2 + '@yuku-parser/binding-linux-arm-gnu': 0.10.2 + '@yuku-parser/binding-linux-arm-musl': 0.10.2 + '@yuku-parser/binding-linux-arm64-gnu': 0.10.2 + '@yuku-parser/binding-linux-arm64-musl': 0.10.2 + '@yuku-parser/binding-linux-x64-gnu': 0.10.2 + '@yuku-parser/binding-linux-x64-musl': 0.10.2 + '@yuku-parser/binding-win32-arm64': 0.10.2 + '@yuku-parser/binding-win32-x64': 0.10.2 zod@3.25.76: {} From 82f19729b74d7cfb4b8c5ee26c8afc865bea3fe7 Mon Sep 17 00:00:00 2001 From: Doug Parker Date: Wed, 23 Sep 2026 10:48:49 -0700 Subject: [PATCH 022/233] refactor: bump framework and `ng-packagr` deps for 22.2.0 release --- constants.bzl | 8 +- modules/testing/builder/package.json | 2 +- .../hello-world-lib/projects/lib/package.json | 4 +- package.json | 26 +- 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 | 314 +++++++++--------- 9 files changed, 187 insertions(+), 187 deletions(-) diff --git a/constants.bzl b/constants.bzl index 143ee7243735..f07e0955fe36 100644 --- a/constants.bzl +++ b/constants.bzl @@ -3,10 +3,10 @@ RELEASE_ENGINES_NODE = "^22.22.3 || ^24.15.0 || >=26.0.0" RELEASE_ENGINES_NPM = "^6.11.0 || ^7.5.6 || >=8.0.0" RELEASE_ENGINES_YARN = ">= 1.13.0" -NG_PACKAGR_VERSION = "^22.2.0-next.0" -ANGULAR_FW_VERSION = "^22.2.0-next.0" -ANGULAR_FW_PEER_DEP = "^22.0.0 || ^22.2.0-next.0" -NG_PACKAGR_PEER_DEP = "^22.0.0 || ^22.2.0-next.0" +NG_PACKAGR_VERSION = "^22.2.0" +ANGULAR_FW_VERSION = "^22.2.0" +ANGULAR_FW_PEER_DEP = "^22.0.0" +NG_PACKAGR_PEER_DEP = "^22.0.0" # Baseline widely-available date in `YYYY-MM-DD` format which defines Angular's # browser support. This date serves as the source of truth for the Angular CLI's diff --git a/modules/testing/builder/package.json b/modules/testing/builder/package.json index d76148352027..526ac8aeb667 100644 --- a/modules/testing/builder/package.json +++ b/modules/testing/builder/package.json @@ -8,7 +8,7 @@ "browser-sync": "3.0.4", "istanbul-lib-instrument": "6.0.3", "jsdom": "30.0.1", - "ng-packagr": "22.2.0-rc.0", + "ng-packagr": "22.2.0", "rxjs": "7.8.2", "vitest": "5.0.1" } diff --git a/modules/testing/builder/projects/hello-world-lib/projects/lib/package.json b/modules/testing/builder/projects/hello-world-lib/projects/lib/package.json index c8105b2c16b4..eb52eedada4e 100644 --- a/modules/testing/builder/projects/hello-world-lib/projects/lib/package.json +++ b/modules/testing/builder/projects/hello-world-lib/projects/lib/package.json @@ -2,7 +2,7 @@ "name": "lib", "version": "0.0.1", "peerDependencies": { - "@angular/common": "^22.2.0-next", - "@angular/core": "^22.2.0-next" + "@angular/common": "^22.2.0", + "@angular/core": "^22.2.0" } } \ No newline at end of file diff --git a/package.json b/package.json index 390c22cd5890..3481919f3074 100644 --- a/package.json +++ b/package.json @@ -43,23 +43,23 @@ }, "homepage": "https://github.com/angular/angular-cli", "dependencies": { - "@angular/compiler-cli": "22.2.0-rc.0", + "@angular/compiler-cli": "22.2.0", "typescript": "6.0.3" }, "devDependencies": { - "@angular/animations": "22.2.0-rc.0", - "@angular/cdk": "22.2.0-rc.0", - "@angular/common": "22.2.0-rc.0", - "@angular/compiler": "22.2.0-rc.0", - "@angular/core": "22.2.0-rc.0", - "@angular/forms": "22.2.0-rc.0", - "@angular/localize": "22.2.0-rc.0", - "@angular/material": "22.2.0-rc.0", + "@angular/animations": "22.2.0", + "@angular/cdk": "22.2.0", + "@angular/common": "22.2.0", + "@angular/compiler": "22.2.0", + "@angular/core": "22.2.0", + "@angular/forms": "22.2.0", + "@angular/localize": "22.2.0", + "@angular/material": "22.2.0", "@angular/ng-dev": "https://github.com/angular/dev-infra-private-ng-dev-builds.git#90a76327155df50e90a41fe76aed67b98a9cf954", - "@angular/platform-browser": "22.2.0-rc.0", - "@angular/platform-server": "22.2.0-rc.0", - "@angular/router": "22.2.0-rc.0", - "@angular/service-worker": "22.2.0-rc.0", + "@angular/platform-browser": "22.2.0", + "@angular/platform-server": "22.2.0", + "@angular/router": "22.2.0", + "@angular/service-worker": "22.2.0", "@babel/core": "8.0.5", "@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 9e0b0b7c4ff1..351f7640a86e 100644 --- a/packages/angular/build/package.json +++ b/packages/angular/build/package.json @@ -57,7 +57,7 @@ "istanbul-lib-instrument": "6.0.3", "jsdom": "30.0.1", "less": "4.9.1", - "ng-packagr": "22.2.0-rc.0", + "ng-packagr": "22.2.0", "postcss": "8.5.28", "rollup": "4.63.3", "rxjs": "7.8.2", diff --git a/packages/angular/ssr/package.json b/packages/angular/ssr/package.json index b48e12387746..d7f969e359db 100644 --- a/packages/angular/ssr/package.json +++ b/packages/angular/ssr/package.json @@ -38,12 +38,12 @@ }, "devDependencies": { "@angular-devkit/schematics": "workspace:*", - "@angular/common": "22.2.0-rc.0", - "@angular/compiler": "22.2.0-rc.0", - "@angular/core": "22.2.0-rc.0", - "@angular/platform-browser": "22.2.0-rc.0", - "@angular/platform-server": "22.2.0-rc.0", - "@angular/router": "22.2.0-rc.0", + "@angular/common": "22.2.0", + "@angular/compiler": "22.2.0", + "@angular/core": "22.2.0", + "@angular/platform-browser": "22.2.0", + "@angular/platform-server": "22.2.0", + "@angular/router": "22.2.0", "@schematics/angular": "workspace:*" }, "sideEffects": false, diff --git a/packages/angular_devkit/build_angular/package.json b/packages/angular_devkit/build_angular/package.json index 4f699d7fbac5..1d138f78dffc 100644 --- a/packages/angular_devkit/build_angular/package.json +++ b/packages/angular_devkit/build_angular/package.json @@ -66,7 +66,7 @@ "devDependencies": { "@angular/ssr": "workspace:*", "browser-sync": "3.0.4", - "ng-packagr": "22.2.0-rc.0", + "ng-packagr": "22.2.0", "sass": "1.104.1", "undici": "8.10.2" }, diff --git a/packages/ngtools/webpack/package.json b/packages/ngtools/webpack/package.json index 07e9660520f8..3e28c0021e40 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-rc.0", - "@angular/compiler-cli": "22.2.0-rc.0", + "@angular/compiler": "22.2.0", + "@angular/compiler-cli": "22.2.0", "typescript": "6.0.3", "webpack": "5.111.0" } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 04ae53f129b3..c749e2d115d5 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -172,8 +172,8 @@ importers: .: dependencies: '@angular/compiler-cli': - specifier: 22.2.0-rc.0 - version: 22.2.0-rc.0(@angular/compiler@22.2.0-rc.0)(typescript@6.0.3) + specifier: 22.2.0 + version: 22.2.0(@angular/compiler@22.2.0)(typescript@6.0.3) typescript: specifier: 6.0.3 version: 6.0.3 @@ -184,44 +184,44 @@ importers: built: true devDependencies: '@angular/animations': - specifier: 22.2.0-rc.0 - version: 22.2.0-rc.0(@angular/core@22.2.0-rc.0(@angular/compiler@22.2.0-rc.0)(rxjs@7.8.2)(zone.js@0.16.3)) + specifier: 22.2.0 + version: 22.2.0(@angular/core@22.2.0(@angular/compiler@22.2.0)(rxjs@7.8.2)(zone.js@0.16.3)) '@angular/cdk': - specifier: 22.2.0-rc.0 - version: 22.2.0-rc.0(32444abcc2be6e3bf2b6c059aa24d737) + specifier: 22.2.0 + version: 22.2.0(de96355f700a7339df12db5b0650ad5f) '@angular/common': - specifier: 22.2.0-rc.0 - version: 22.2.0-rc.0(@angular/core@22.2.0-rc.0(@angular/compiler@22.2.0-rc.0)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2) + specifier: 22.2.0 + version: 22.2.0(@angular/core@22.2.0(@angular/compiler@22.2.0)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2) '@angular/compiler': - specifier: 22.2.0-rc.0 - version: 22.2.0-rc.0 + specifier: 22.2.0 + version: 22.2.0 '@angular/core': - specifier: 22.2.0-rc.0 - version: 22.2.0-rc.0(@angular/compiler@22.2.0-rc.0)(rxjs@7.8.2)(zone.js@0.16.3) + specifier: 22.2.0 + version: 22.2.0(@angular/compiler@22.2.0)(rxjs@7.8.2)(zone.js@0.16.3) '@angular/forms': - specifier: 22.2.0-rc.0 - version: 22.2.0-rc.0(@angular/common@22.2.0-rc.0(@angular/core@22.2.0-rc.0(@angular/compiler@22.2.0-rc.0)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2))(@angular/core@22.2.0-rc.0(@angular/compiler@22.2.0-rc.0)(rxjs@7.8.2)(zone.js@0.16.3))(@angular/platform-browser@22.2.0-rc.0(@angular/animations@22.2.0-rc.0(@angular/core@22.2.0-rc.0(@angular/compiler@22.2.0-rc.0)(rxjs@7.8.2)(zone.js@0.16.3)))(@angular/common@22.2.0-rc.0(@angular/core@22.2.0-rc.0(@angular/compiler@22.2.0-rc.0)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2))(@angular/core@22.2.0-rc.0(@angular/compiler@22.2.0-rc.0)(rxjs@7.8.2)(zone.js@0.16.3)))(rxjs@7.8.2) + specifier: 22.2.0 + version: 22.2.0(@angular/common@22.2.0(@angular/core@22.2.0(@angular/compiler@22.2.0)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2))(@angular/core@22.2.0(@angular/compiler@22.2.0)(rxjs@7.8.2)(zone.js@0.16.3))(@angular/platform-browser@22.2.0(@angular/animations@22.2.0(@angular/core@22.2.0(@angular/compiler@22.2.0)(rxjs@7.8.2)(zone.js@0.16.3)))(@angular/common@22.2.0(@angular/core@22.2.0(@angular/compiler@22.2.0)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2))(@angular/core@22.2.0(@angular/compiler@22.2.0)(rxjs@7.8.2)(zone.js@0.16.3)))(rxjs@7.8.2) '@angular/localize': - specifier: 22.2.0-rc.0 - version: 22.2.0-rc.0(@angular/compiler-cli@22.2.0-rc.0(@angular/compiler@22.2.0-rc.0)(typescript@6.0.3))(@angular/compiler@22.2.0-rc.0) + specifier: 22.2.0 + version: 22.2.0(@angular/compiler-cli@22.2.0(@angular/compiler@22.2.0)(typescript@6.0.3))(@angular/compiler@22.2.0) '@angular/material': - specifier: 22.2.0-rc.0 - version: 22.2.0-rc.0(25ddf4063a130bbf19862bd16a6ab5d4) + specifier: 22.2.0 + version: 22.2.0(40004d7e10fb4ba9a3893f0ca483936a) '@angular/ng-dev': specifier: https://github.com/angular/dev-infra-private-ng-dev-builds.git#90a76327155df50e90a41fe76aed67b98a9cf954 version: https://codeload.github.com/angular/dev-infra-private-ng-dev-builds/tar.gz/90a76327155df50e90a41fe76aed67b98a9cf954 '@angular/platform-browser': - specifier: 22.2.0-rc.0 - version: 22.2.0-rc.0(@angular/animations@22.2.0-rc.0(@angular/core@22.2.0-rc.0(@angular/compiler@22.2.0-rc.0)(rxjs@7.8.2)(zone.js@0.16.3)))(@angular/common@22.2.0-rc.0(@angular/core@22.2.0-rc.0(@angular/compiler@22.2.0-rc.0)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2))(@angular/core@22.2.0-rc.0(@angular/compiler@22.2.0-rc.0)(rxjs@7.8.2)(zone.js@0.16.3)) + specifier: 22.2.0 + version: 22.2.0(@angular/animations@22.2.0(@angular/core@22.2.0(@angular/compiler@22.2.0)(rxjs@7.8.2)(zone.js@0.16.3)))(@angular/common@22.2.0(@angular/core@22.2.0(@angular/compiler@22.2.0)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2))(@angular/core@22.2.0(@angular/compiler@22.2.0)(rxjs@7.8.2)(zone.js@0.16.3)) '@angular/platform-server': - specifier: 22.2.0-rc.0 - version: 22.2.0-rc.0(@angular/common@22.2.0-rc.0(@angular/core@22.2.0-rc.0(@angular/compiler@22.2.0-rc.0)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2))(@angular/compiler@22.2.0-rc.0)(@angular/core@22.2.0-rc.0(@angular/compiler@22.2.0-rc.0)(rxjs@7.8.2)(zone.js@0.16.3))(@angular/platform-browser@22.2.0-rc.0(@angular/animations@22.2.0-rc.0(@angular/core@22.2.0-rc.0(@angular/compiler@22.2.0-rc.0)(rxjs@7.8.2)(zone.js@0.16.3)))(@angular/common@22.2.0-rc.0(@angular/core@22.2.0-rc.0(@angular/compiler@22.2.0-rc.0)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2))(@angular/core@22.2.0-rc.0(@angular/compiler@22.2.0-rc.0)(rxjs@7.8.2)(zone.js@0.16.3)))(rxjs@7.8.2) + specifier: 22.2.0 + version: 22.2.0(@angular/common@22.2.0(@angular/core@22.2.0(@angular/compiler@22.2.0)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2))(@angular/compiler@22.2.0)(@angular/core@22.2.0(@angular/compiler@22.2.0)(rxjs@7.8.2)(zone.js@0.16.3))(@angular/platform-browser@22.2.0(@angular/animations@22.2.0(@angular/core@22.2.0(@angular/compiler@22.2.0)(rxjs@7.8.2)(zone.js@0.16.3)))(@angular/common@22.2.0(@angular/core@22.2.0(@angular/compiler@22.2.0)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2))(@angular/core@22.2.0(@angular/compiler@22.2.0)(rxjs@7.8.2)(zone.js@0.16.3)))(rxjs@7.8.2) '@angular/router': - specifier: 22.2.0-rc.0 - version: 22.2.0-rc.0(@angular/common@22.2.0-rc.0(@angular/core@22.2.0-rc.0(@angular/compiler@22.2.0-rc.0)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2))(@angular/core@22.2.0-rc.0(@angular/compiler@22.2.0-rc.0)(rxjs@7.8.2)(zone.js@0.16.3))(@angular/platform-browser@22.2.0-rc.0(@angular/animations@22.2.0-rc.0(@angular/core@22.2.0-rc.0(@angular/compiler@22.2.0-rc.0)(rxjs@7.8.2)(zone.js@0.16.3)))(@angular/common@22.2.0-rc.0(@angular/core@22.2.0-rc.0(@angular/compiler@22.2.0-rc.0)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2))(@angular/core@22.2.0-rc.0(@angular/compiler@22.2.0-rc.0)(rxjs@7.8.2)(zone.js@0.16.3)))(rxjs@7.8.2) + specifier: 22.2.0 + version: 22.2.0(@angular/common@22.2.0(@angular/core@22.2.0(@angular/compiler@22.2.0)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2))(@angular/core@22.2.0(@angular/compiler@22.2.0)(rxjs@7.8.2)(zone.js@0.16.3))(@angular/platform-browser@22.2.0(@angular/animations@22.2.0(@angular/core@22.2.0(@angular/compiler@22.2.0)(rxjs@7.8.2)(zone.js@0.16.3)))(@angular/common@22.2.0(@angular/core@22.2.0(@angular/compiler@22.2.0)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2))(@angular/core@22.2.0(@angular/compiler@22.2.0)(rxjs@7.8.2)(zone.js@0.16.3)))(rxjs@7.8.2) '@angular/service-worker': - specifier: 22.2.0-rc.0 - version: 22.2.0-rc.0(@angular/core@22.2.0-rc.0(@angular/compiler@22.2.0-rc.0)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2) + specifier: 22.2.0 + version: 22.2.0(@angular/core@22.2.0(@angular/compiler@22.2.0)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2) '@babel/core': specifier: 8.0.5 version: 8.0.5 @@ -463,8 +463,8 @@ importers: specifier: 30.0.1 version: 30.0.1(@noble/hashes@1.8.0) ng-packagr: - specifier: 22.2.0-rc.0 - version: 22.2.0-rc.0(@angular/compiler-cli@22.2.0-rc.0(@angular/compiler@22.2.0-rc.0)(typescript@6.0.3))(supports-color@11.0.0)(tslib@2.8.1)(typescript@6.0.3) + specifier: 22.2.0 + version: 22.2.0(@angular/compiler-cli@22.2.0(@angular/compiler@22.2.0)(typescript@6.0.3))(supports-color@11.0.0)(tslib@2.8.1)(typescript@6.0.3) rxjs: specifier: 7.8.2 version: 7.8.2 @@ -578,8 +578,8 @@ importers: specifier: 4.9.1 version: 4.9.1(supports-color@11.0.0) ng-packagr: - specifier: 22.2.0-rc.0 - version: 22.2.0-rc.0(@angular/compiler-cli@22.2.0-rc.0(@angular/compiler@22.2.0-rc.0)(typescript@6.0.3))(supports-color@11.0.0)(tslib@2.8.1)(typescript@6.0.3) + specifier: 22.2.0 + version: 22.2.0(@angular/compiler-cli@22.2.0(@angular/compiler@22.2.0)(typescript@6.0.3))(supports-color@11.0.0)(tslib@2.8.1)(typescript@6.0.3) postcss: specifier: 8.5.28 version: 8.5.28 @@ -667,23 +667,23 @@ importers: specifier: workspace:* version: link:../../angular_devkit/schematics '@angular/common': - specifier: 22.2.0-rc.0 - version: 22.2.0-rc.0(@angular/core@22.2.0-rc.0(@angular/compiler@22.2.0-rc.0)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2) + specifier: 22.2.0 + version: 22.2.0(@angular/core@22.2.0(@angular/compiler@22.2.0)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2) '@angular/compiler': - specifier: 22.2.0-rc.0 - version: 22.2.0-rc.0 + specifier: 22.2.0 + version: 22.2.0 '@angular/core': - specifier: 22.2.0-rc.0 - version: 22.2.0-rc.0(@angular/compiler@22.2.0-rc.0)(rxjs@7.8.2)(zone.js@0.16.3) + specifier: 22.2.0 + version: 22.2.0(@angular/compiler@22.2.0)(rxjs@7.8.2)(zone.js@0.16.3) '@angular/platform-browser': - specifier: 22.2.0-rc.0 - version: 22.2.0-rc.0(@angular/animations@22.2.0-rc.0(@angular/core@22.2.0-rc.0(@angular/compiler@22.2.0-rc.0)(rxjs@7.8.2)(zone.js@0.16.3)))(@angular/common@22.2.0-rc.0(@angular/core@22.2.0-rc.0(@angular/compiler@22.2.0-rc.0)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2))(@angular/core@22.2.0-rc.0(@angular/compiler@22.2.0-rc.0)(rxjs@7.8.2)(zone.js@0.16.3)) + specifier: 22.2.0 + version: 22.2.0(@angular/animations@22.2.0(@angular/core@22.2.0(@angular/compiler@22.2.0)(rxjs@7.8.2)(zone.js@0.16.3)))(@angular/common@22.2.0(@angular/core@22.2.0(@angular/compiler@22.2.0)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2))(@angular/core@22.2.0(@angular/compiler@22.2.0)(rxjs@7.8.2)(zone.js@0.16.3)) '@angular/platform-server': - specifier: 22.2.0-rc.0 - version: 22.2.0-rc.0(@angular/common@22.2.0-rc.0(@angular/core@22.2.0-rc.0(@angular/compiler@22.2.0-rc.0)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2))(@angular/compiler@22.2.0-rc.0)(@angular/core@22.2.0-rc.0(@angular/compiler@22.2.0-rc.0)(rxjs@7.8.2)(zone.js@0.16.3))(@angular/platform-browser@22.2.0-rc.0(@angular/animations@22.2.0-rc.0(@angular/core@22.2.0-rc.0(@angular/compiler@22.2.0-rc.0)(rxjs@7.8.2)(zone.js@0.16.3)))(@angular/common@22.2.0-rc.0(@angular/core@22.2.0-rc.0(@angular/compiler@22.2.0-rc.0)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2))(@angular/core@22.2.0-rc.0(@angular/compiler@22.2.0-rc.0)(rxjs@7.8.2)(zone.js@0.16.3)))(rxjs@7.8.2) + specifier: 22.2.0 + version: 22.2.0(@angular/common@22.2.0(@angular/core@22.2.0(@angular/compiler@22.2.0)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2))(@angular/compiler@22.2.0)(@angular/core@22.2.0(@angular/compiler@22.2.0)(rxjs@7.8.2)(zone.js@0.16.3))(@angular/platform-browser@22.2.0(@angular/animations@22.2.0(@angular/core@22.2.0(@angular/compiler@22.2.0)(rxjs@7.8.2)(zone.js@0.16.3)))(@angular/common@22.2.0(@angular/core@22.2.0(@angular/compiler@22.2.0)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2))(@angular/core@22.2.0(@angular/compiler@22.2.0)(rxjs@7.8.2)(zone.js@0.16.3)))(rxjs@7.8.2) '@angular/router': - specifier: 22.2.0-rc.0 - version: 22.2.0-rc.0(@angular/common@22.2.0-rc.0(@angular/core@22.2.0-rc.0(@angular/compiler@22.2.0-rc.0)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2))(@angular/core@22.2.0-rc.0(@angular/compiler@22.2.0-rc.0)(rxjs@7.8.2)(zone.js@0.16.3))(@angular/platform-browser@22.2.0-rc.0(@angular/animations@22.2.0-rc.0(@angular/core@22.2.0-rc.0(@angular/compiler@22.2.0-rc.0)(rxjs@7.8.2)(zone.js@0.16.3)))(@angular/common@22.2.0-rc.0(@angular/core@22.2.0-rc.0(@angular/compiler@22.2.0-rc.0)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2))(@angular/core@22.2.0-rc.0(@angular/compiler@22.2.0-rc.0)(rxjs@7.8.2)(zone.js@0.16.3)))(rxjs@7.8.2) + specifier: 22.2.0 + version: 22.2.0(@angular/common@22.2.0(@angular/core@22.2.0(@angular/compiler@22.2.0)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2))(@angular/core@22.2.0(@angular/compiler@22.2.0)(rxjs@7.8.2)(zone.js@0.16.3))(@angular/platform-browser@22.2.0(@angular/animations@22.2.0(@angular/core@22.2.0(@angular/compiler@22.2.0)(rxjs@7.8.2)(zone.js@0.16.3)))(@angular/common@22.2.0(@angular/core@22.2.0(@angular/compiler@22.2.0)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2))(@angular/core@22.2.0(@angular/compiler@22.2.0)(rxjs@7.8.2)(zone.js@0.16.3)))(rxjs@7.8.2) '@schematics/angular': specifier: workspace:* version: link:../../schematics/angular @@ -848,10 +848,10 @@ importers: version: 5.111.0(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.28)(uglify-js@3.19.3) webpack-dev-middleware: specifier: 8.3.0 - version: 8.3.0(webpack@5.111.0(esbuild@0.28.2)(lightningcss@1.33.0)(uglify-js@3.19.3)) + version: 8.3.0(webpack@5.111.0(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.28)(uglify-js@3.19.3)) webpack-dev-server: specifier: 6.0.0 - version: 6.0.0(bufferutil@4.1.0)(supports-color@11.0.0)(utf-8-validate@6.0.6)(webpack@5.111.0(esbuild@0.28.2)(lightningcss@1.33.0)(uglify-js@3.19.3)) + version: 6.0.0(bufferutil@4.1.0)(supports-color@11.0.0)(utf-8-validate@6.0.6)(webpack@5.111.0(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.28)(uglify-js@3.19.3)) webpack-merge: specifier: 6.0.1 version: 6.0.1 @@ -866,8 +866,8 @@ importers: specifier: 3.0.4 version: 3.0.4(bufferutil@4.1.0)(debug@4.4.3(supports-color@11.0.0))(supports-color@11.0.0)(utf-8-validate@6.0.6) ng-packagr: - specifier: 22.2.0-rc.0 - version: 22.2.0-rc.0(@angular/compiler-cli@22.2.0-rc.0(@angular/compiler@22.2.0-rc.0)(typescript@6.0.3))(supports-color@11.0.0)(tslib@2.8.1)(typescript@6.0.3) + specifier: 22.2.0 + version: 22.2.0(@angular/compiler-cli@22.2.0(@angular/compiler@22.2.0)(typescript@6.0.3))(supports-color@11.0.0)(tslib@2.8.1)(typescript@6.0.3) sass: specifier: 1.104.1 version: 1.104.1 @@ -899,7 +899,7 @@ importers: version: 5.111.0(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.28)(uglify-js@3.19.3) webpack-dev-server: specifier: 6.0.0 - version: 6.0.0(bufferutil@4.1.0)(supports-color@11.0.0)(utf-8-validate@6.0.6)(webpack@5.111.0(esbuild@0.28.2)(lightningcss@1.33.0)(uglify-js@3.19.3)) + version: 6.0.0(bufferutil@4.1.0)(supports-color@11.0.0)(utf-8-validate@6.0.6)(webpack@5.111.0(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.28)(uglify-js@3.19.3)) packages/angular_devkit/core: dependencies: @@ -962,11 +962,11 @@ importers: specifier: workspace:0.0.0-PLACEHOLDER version: link:../../angular_devkit/core '@angular/compiler': - specifier: 22.2.0-rc.0 - version: 22.2.0-rc.0 + specifier: 22.2.0 + version: 22.2.0 '@angular/compiler-cli': - specifier: 22.2.0-rc.0 - version: 22.2.0-rc.0(@angular/compiler@22.2.0-rc.0)(typescript@6.0.3) + specifier: 22.2.0 + version: 22.2.0(@angular/compiler@22.2.0)(typescript@6.0.3) typescript: specifier: 6.0.3 version: 6.0.3 @@ -1026,48 +1026,48 @@ packages: resolution: {integrity: sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==} engines: {node: '>=6.0.0'} - '@angular/animations@22.2.0-rc.0': - resolution: {integrity: sha512-MnkNstor6AH92M9ps7RZfcCyUo24SqBZU71soDgYC3aXFJhSYOtJFPKE1/KgrpVt416lTzbhHe/68kAZ3cH9MQ==} + '@angular/animations@22.2.0': + resolution: {integrity: sha512-JfBaStn07PC4kIw7vHPlKgyjzIM+d3ZgoxjHuTbLMa6lW1IXmUqgJVNSzgI3TUWmYUBtereMjOnZ2PVuIA+L4g==} engines: {node: ^22.22.3 || ^24.15.0 || >=26.0.0} peerDependencies: - '@angular/core': 22.2.0-rc.0 + '@angular/core': 22.2.0 - '@angular/cdk@22.2.0-rc.0': - resolution: {integrity: sha512-fG3/uCItdRj+PSetdHOIcd72VUekKhdj/uazHuhjjE1mz7gJJx0WBzDk1CcGUYtfvq0WoYlv9Kq6rhnP2gBAdw==} + '@angular/cdk@22.2.0': + resolution: {integrity: sha512-Vxiqo03yKxzmON+hfa0UkUSC+TrWdtRgc1MtkE5l3NJQ5euF9Os4kOqDfW1nDt3/AjCplE64HX3h0gOK5m3zjw==} peerDependencies: - '@angular/common': ^22.0.0-0 || ^22.1.0-0 || ^22.2.0-0 || ^22.3.0-0 || ^23.0.0-0 - '@angular/core': ^22.0.0-0 || ^22.1.0-0 || ^22.2.0-0 || ^22.3.0-0 || ^23.0.0-0 - '@angular/forms': ^22.0.0-0 || ^22.1.0-0 || ^22.2.0-0 || ^22.3.0-0 || ^23.0.0-0 - '@angular/platform-browser': ^22.0.0-0 || ^22.1.0-0 || ^22.2.0-0 || ^22.3.0-0 || ^23.0.0-0 + '@angular/common': ^22.0.0 || ^23.0.0 + '@angular/core': ^22.0.0 || ^23.0.0 + '@angular/forms': ^22.0.0 || ^23.0.0 + '@angular/platform-browser': ^22.0.0 || ^23.0.0 rxjs: ^6.5.3 || ^7.4.0 - '@angular/common@22.2.0-rc.0': - resolution: {integrity: sha512-j80c+FC/yZ2jz0d6w/kPwvEdMhaIol23gt/IcZxOigvElUywpNfm+g36XjM34/UNy6HDhew5ck7HE9DWYVXwsw==} + '@angular/common@22.2.0': + resolution: {integrity: sha512-BUKkncKwnaEcF/qatBOpzSIx2NthFZLYlTcE7iHwwsw+XQrwB9hU8Ca/l5HqaTJiMg0D8MjI/SWHnD4LFtNN+w==} engines: {node: ^22.22.3 || ^24.15.0 || >=26.0.0} peerDependencies: - '@angular/core': 22.2.0-rc.0 + '@angular/core': 22.2.0 rxjs: ^6.5.3 || ^7.4.0 - '@angular/compiler-cli@22.2.0-rc.0': - resolution: {integrity: sha512-51yfbHuAd09YnH5tTLb9jIxzkqFTB8SAj6Gv2/LqR+xDq7AGaZgFiehQOa2pa9kDJ3wNHYbTROF7dHP+AXXj2w==} + '@angular/compiler-cli@22.2.0': + resolution: {integrity: sha512-xDOvPlNv+RT7sE01wjuGFRMc5SDxWs3RZpGfO5NoI3a0jxM87UW49HmmgwQ6PaU0fya9mttNkHufhfOAbh0ZKQ==} engines: {node: ^22.22.3 || ^24.15.0 || >=26.0.0} hasBin: true peerDependencies: - '@angular/compiler': 22.2.0-rc.0 + '@angular/compiler': 22.2.0 typescript: '>=6.0 <6.1' peerDependenciesMeta: typescript: optional: true - '@angular/compiler@22.2.0-rc.0': - resolution: {integrity: sha512-vWavQPwkNQhie4/KKGycoQrGGPNcjKbn8VkmMiIcfPVCMtvNvhs8ssPgKENYDXaFRyg+UtJ1Y/2HRdYtIQIw8g==} + '@angular/compiler@22.2.0': + resolution: {integrity: sha512-bnqql/HfhnhDXoS7isNaXJAsbKYszcH+nFVWA6YhiAVZhqo3f+XoQb30qeqNtEOKuuC7SZfaAJ3jBkAvyC5CKg==} engines: {node: ^22.22.3 || ^24.15.0 || >=26.0.0} - '@angular/core@22.2.0-rc.0': - resolution: {integrity: sha512-HbeWk0EatMmOf5VF71W35WCVZ9nwjHkeXvdhee+1uZfr2cmpnS3OXuFrIgTP2kSrILc6jEh7xuHW/IT1itjHuA==} + '@angular/core@22.2.0': + resolution: {integrity: sha512-VhAgJ4GCdGgAy9+zADpSyEM9gt4pKg6+cqNeK3RBNeF3M3B8y7AWfD/nYRdM3Xzi152Pu+ipgFFNHpupCLTsvQ==} engines: {node: ^22.22.3 || ^24.15.0 || >=26.0.0} peerDependencies: - '@angular/compiler': 22.2.0-rc.0 + '@angular/compiler': 22.2.0 rxjs: ^6.5.3 || ^7.4.0 zone.js: ~0.15.0 || ~0.16.0 peerDependenciesMeta: @@ -1076,31 +1076,31 @@ packages: zone.js: optional: true - '@angular/forms@22.2.0-rc.0': - resolution: {integrity: sha512-mg+NratvkCH9ihGBplqZBKS2Q8+eLDdZSyl10FWmIzhaTmJEk9GLoZ70n4kEU0rX65hy2oF0M2aTBpr2CRxZ4w==} + '@angular/forms@22.2.0': + resolution: {integrity: sha512-Nm8o1uBk31EuQGzsK5EunNBVFzTN9MuTYLSrmg1SCPTcava4qK3AzSpl1+Put+cZTTnGtEBIy45AFaxHR2oryg==} engines: {node: ^22.22.3 || ^24.15.0 || >=26.0.0} peerDependencies: - '@angular/common': 22.2.0-rc.0 - '@angular/core': 22.2.0-rc.0 - '@angular/platform-browser': 22.2.0-rc.0 + '@angular/common': 22.2.0 + '@angular/core': 22.2.0 + '@angular/platform-browser': 22.2.0 rxjs: ^6.5.3 || ^7.4.0 - '@angular/localize@22.2.0-rc.0': - resolution: {integrity: sha512-c0WgdyX0GYrx4hBF9KEPaOXFIcz+j9dIgLDG2hcsxLdjE9r+trmTBFwhR/4/Q7S5GThbnty4/rjVJOrRXpdi7Q==} + '@angular/localize@22.2.0': + resolution: {integrity: sha512-RfaF5tAKWyQwGzu0P5bJUavB8QWrWdM/xU5gDXydIFopBk4WERaMYh5E5fGm39h09dod2vmFH3JND1Ht0Vgy6w==} engines: {node: ^22.22.3 || ^24.15.0 || >=26.0.0} hasBin: true peerDependencies: - '@angular/compiler': 22.2.0-rc.0 - '@angular/compiler-cli': 22.2.0-rc.0 + '@angular/compiler': 22.2.0 + '@angular/compiler-cli': 22.2.0 - '@angular/material@22.2.0-rc.0': - resolution: {integrity: sha512-3IaSPe7LnbhJHzo95xAfY0vB7nA5tDxx+ojn8MSZTa/m6Cw8aCRMZiSiJ783Qw7x1doWz37o3Z7B54Wp8n/2Jw==} + '@angular/material@22.2.0': + resolution: {integrity: sha512-upeJyTUwiq3oMxGsLtTmddTjdqN8xgO0M2Rs3GaLSPqcXp/n7ScrDdN6sFHYLZtIs1KHmMEYnSBHm5F1ofVZow==} peerDependencies: - '@angular/cdk': 22.2.0-rc.0 - '@angular/common': ^22.0.0-0 || ^22.1.0-0 || ^22.2.0-0 || ^22.3.0-0 || ^23.0.0-0 - '@angular/core': ^22.0.0-0 || ^22.1.0-0 || ^22.2.0-0 || ^22.3.0-0 || ^23.0.0-0 - '@angular/forms': ^22.0.0-0 || ^22.1.0-0 || ^22.2.0-0 || ^22.3.0-0 || ^23.0.0-0 - '@angular/platform-browser': ^22.0.0-0 || ^22.1.0-0 || ^22.2.0-0 || ^22.3.0-0 || ^23.0.0-0 + '@angular/cdk': 22.2.0 + '@angular/common': ^22.0.0 || ^23.0.0 + '@angular/core': ^22.0.0 || ^23.0.0 + '@angular/forms': ^22.0.0 || ^23.0.0 + '@angular/platform-browser': ^22.0.0 || ^23.0.0 rxjs: ^6.5.3 || ^7.4.0 '@angular/ng-dev@https://codeload.github.com/angular/dev-infra-private-ng-dev-builds/tar.gz/90a76327155df50e90a41fe76aed67b98a9cf954': @@ -1108,42 +1108,42 @@ packages: version: 0.0.0-20b69d39859eae19d7ac04b6f1902f73286f7686 hasBin: true - '@angular/platform-browser@22.2.0-rc.0': - resolution: {integrity: sha512-poN1dCkFKM1t288v/5M2w+OUzragcUuEt3GQfcQQ87lIWCp5atCpClpXxbFJj0VUeYXPKvb9rUwQtFtTMzYohA==} + '@angular/platform-browser@22.2.0': + resolution: {integrity: sha512-XMUOyn8WARk9NdFGO3uRgdC3hPrp+2xsSYNeSkaEZ4jI3Pc23f22e4GI8Vayl/UOmShHVn/i+NWfTWh3SEbbSw==} engines: {node: ^22.22.3 || ^24.15.0 || >=26.0.0} peerDependencies: - '@angular/animations': 22.2.0-rc.0 - '@angular/common': 22.2.0-rc.0 - '@angular/core': 22.2.0-rc.0 + '@angular/animations': 22.2.0 + '@angular/common': 22.2.0 + '@angular/core': 22.2.0 peerDependenciesMeta: '@angular/animations': optional: true - '@angular/platform-server@22.2.0-rc.0': - resolution: {integrity: sha512-bohsXRaIV/d/RqFqbsdpmNpmcmurSrV/a1I7lo7IEzJJXAVchHBD/JIjJYFOk+NgqLDYZciq6Z8fF8idLfv1YQ==} + '@angular/platform-server@22.2.0': + resolution: {integrity: sha512-Ppb0Zqr0lLubAW2UvjsNYDuoh+WX8ZeKdrmEMa8qhpVIxD1UL6CAQnKSlQQabWfuCQOphzBi7u7QeotGsTajKQ==} engines: {node: ^22.22.3 || ^24.15.0 || >=26.0.0} peerDependencies: - '@angular/common': 22.2.0-rc.0 - '@angular/compiler': 22.2.0-rc.0 - '@angular/core': 22.2.0-rc.0 - '@angular/platform-browser': 22.2.0-rc.0 + '@angular/common': 22.2.0 + '@angular/compiler': 22.2.0 + '@angular/core': 22.2.0 + '@angular/platform-browser': 22.2.0 rxjs: ^6.5.3 || ^7.4.0 - '@angular/router@22.2.0-rc.0': - resolution: {integrity: sha512-bIOOdp5T3KM4vB2xL4L6fpXYQ3vJmkPRB+k2tXSb4xW1HLsJDEyGN9GNj/5prnLbaWIGqcfhGNwnTW/mCVm42A==} + '@angular/router@22.2.0': + resolution: {integrity: sha512-+pxHMwWWKg+ejS1vKa+tS91CDusCIK1MOSy6fVLc89McMOY/C8tsLrh1uJaMjklejsz+3XUhJgrLOvl3ISNz6w==} engines: {node: ^22.22.3 || ^24.15.0 || >=26.0.0} peerDependencies: - '@angular/common': 22.2.0-rc.0 - '@angular/core': 22.2.0-rc.0 - '@angular/platform-browser': 22.2.0-rc.0 + '@angular/common': 22.2.0 + '@angular/core': 22.2.0 + '@angular/platform-browser': 22.2.0 rxjs: ^6.5.3 || ^7.4.0 - '@angular/service-worker@22.2.0-rc.0': - resolution: {integrity: sha512-y03a1Ppfyi765n8QlRgVqeL5kF8k5mFOVxvK+ZlxONave1mN2ChG37Yu35gzJ22wiprBDUgxGm3UdLvscU3YkA==} + '@angular/service-worker@22.2.0': + resolution: {integrity: sha512-2De4hFreCr9bKPkgbB7MNXqQH10FsoglFaDaGbqUTAbf+P2Lt8bKXzJfNa5r2Dt0Jjm3+YbDwZNtUfMuUQVwsw==} engines: {node: ^22.22.3 || ^24.15.0 || >=26.0.0} hasBin: true peerDependencies: - '@angular/core': 22.2.0-rc.0 + '@angular/core': 22.2.0 rxjs: ^6.5.3 || ^7.4.0 '@asamuzakjp/css-color@6.0.7': @@ -6734,12 +6734,12 @@ packages: neo-async@2.6.2: resolution: {integrity: sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==} - ng-packagr@22.2.0-rc.0: - resolution: {integrity: sha512-l91WqbCFBKpVmDwW/rttDNe6kpRjsIlHnUf55YTH5JqN0Q7uVGBy6QbRUV2S+4/StyFqc+keOAtVPJUdO2bvxw==} + ng-packagr@22.2.0: + resolution: {integrity: sha512-VsH3X8R3E24yX6h/atwke1ytWB/lt8AShbbKA6cRZLrwLf07N5eQF1kV4XrPqabiPWUCJNSU0zvnSkdjXAo7Zw==} engines: {node: ^22.22.3 || ^24.15.0 || >=26.0.0} hasBin: true peerDependencies: - '@angular/compiler-cli': ^22.2.0-next + '@angular/compiler-cli': ^22.0.0 || ^22.3.0-next tailwindcss: ^2.0.0 || ^3.0.0 || ^4.0.0 tslib: ^2.3.0 typescript: '>=6.0 <6.1' @@ -8655,30 +8655,30 @@ snapshots: '@jridgewell/gen-mapping': 0.3.13 '@jridgewell/trace-mapping': 0.3.31 - '@angular/animations@22.2.0-rc.0(@angular/core@22.2.0-rc.0(@angular/compiler@22.2.0-rc.0)(rxjs@7.8.2)(zone.js@0.16.3))': + '@angular/animations@22.2.0(@angular/core@22.2.0(@angular/compiler@22.2.0)(rxjs@7.8.2)(zone.js@0.16.3))': dependencies: - '@angular/core': 22.2.0-rc.0(@angular/compiler@22.2.0-rc.0)(rxjs@7.8.2)(zone.js@0.16.3) + '@angular/core': 22.2.0(@angular/compiler@22.2.0)(rxjs@7.8.2)(zone.js@0.16.3) tslib: 2.8.1 - '@angular/cdk@22.2.0-rc.0(32444abcc2be6e3bf2b6c059aa24d737)': + '@angular/cdk@22.2.0(de96355f700a7339df12db5b0650ad5f)': dependencies: - '@angular/common': 22.2.0-rc.0(@angular/core@22.2.0-rc.0(@angular/compiler@22.2.0-rc.0)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2) - '@angular/core': 22.2.0-rc.0(@angular/compiler@22.2.0-rc.0)(rxjs@7.8.2)(zone.js@0.16.3) - '@angular/forms': 22.2.0-rc.0(@angular/common@22.2.0-rc.0(@angular/core@22.2.0-rc.0(@angular/compiler@22.2.0-rc.0)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2))(@angular/core@22.2.0-rc.0(@angular/compiler@22.2.0-rc.0)(rxjs@7.8.2)(zone.js@0.16.3))(@angular/platform-browser@22.2.0-rc.0(@angular/animations@22.2.0-rc.0(@angular/core@22.2.0-rc.0(@angular/compiler@22.2.0-rc.0)(rxjs@7.8.2)(zone.js@0.16.3)))(@angular/common@22.2.0-rc.0(@angular/core@22.2.0-rc.0(@angular/compiler@22.2.0-rc.0)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2))(@angular/core@22.2.0-rc.0(@angular/compiler@22.2.0-rc.0)(rxjs@7.8.2)(zone.js@0.16.3)))(rxjs@7.8.2) - '@angular/platform-browser': 22.2.0-rc.0(@angular/animations@22.2.0-rc.0(@angular/core@22.2.0-rc.0(@angular/compiler@22.2.0-rc.0)(rxjs@7.8.2)(zone.js@0.16.3)))(@angular/common@22.2.0-rc.0(@angular/core@22.2.0-rc.0(@angular/compiler@22.2.0-rc.0)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2))(@angular/core@22.2.0-rc.0(@angular/compiler@22.2.0-rc.0)(rxjs@7.8.2)(zone.js@0.16.3)) + '@angular/common': 22.2.0(@angular/core@22.2.0(@angular/compiler@22.2.0)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2) + '@angular/core': 22.2.0(@angular/compiler@22.2.0)(rxjs@7.8.2)(zone.js@0.16.3) + '@angular/forms': 22.2.0(@angular/common@22.2.0(@angular/core@22.2.0(@angular/compiler@22.2.0)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2))(@angular/core@22.2.0(@angular/compiler@22.2.0)(rxjs@7.8.2)(zone.js@0.16.3))(@angular/platform-browser@22.2.0(@angular/animations@22.2.0(@angular/core@22.2.0(@angular/compiler@22.2.0)(rxjs@7.8.2)(zone.js@0.16.3)))(@angular/common@22.2.0(@angular/core@22.2.0(@angular/compiler@22.2.0)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2))(@angular/core@22.2.0(@angular/compiler@22.2.0)(rxjs@7.8.2)(zone.js@0.16.3)))(rxjs@7.8.2) + '@angular/platform-browser': 22.2.0(@angular/animations@22.2.0(@angular/core@22.2.0(@angular/compiler@22.2.0)(rxjs@7.8.2)(zone.js@0.16.3)))(@angular/common@22.2.0(@angular/core@22.2.0(@angular/compiler@22.2.0)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2))(@angular/core@22.2.0(@angular/compiler@22.2.0)(rxjs@7.8.2)(zone.js@0.16.3)) parse5: 8.0.1 rxjs: 7.8.2 tslib: 2.8.1 - '@angular/common@22.2.0-rc.0(@angular/core@22.2.0-rc.0(@angular/compiler@22.2.0-rc.0)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2)': + '@angular/common@22.2.0(@angular/core@22.2.0(@angular/compiler@22.2.0)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2)': dependencies: - '@angular/core': 22.2.0-rc.0(@angular/compiler@22.2.0-rc.0)(rxjs@7.8.2)(zone.js@0.16.3) + '@angular/core': 22.2.0(@angular/compiler@22.2.0)(rxjs@7.8.2)(zone.js@0.16.3) rxjs: 7.8.2 tslib: 2.8.1 - '@angular/compiler-cli@22.2.0-rc.0(@angular/compiler@22.2.0-rc.0)(typescript@6.0.3)': + '@angular/compiler-cli@22.2.0(@angular/compiler@22.2.0)(typescript@6.0.3)': dependencies: - '@angular/compiler': 22.2.0-rc.0 + '@angular/compiler': 22.2.0 '@babel/core': 8.0.1 '@jridgewell/sourcemap-codec': 1.6.0 chokidar: 5.0.0 @@ -8690,43 +8690,43 @@ snapshots: optionalDependencies: typescript: 6.0.3 - '@angular/compiler@22.2.0-rc.0': + '@angular/compiler@22.2.0': dependencies: tslib: 2.8.1 - '@angular/core@22.2.0-rc.0(@angular/compiler@22.2.0-rc.0)(rxjs@7.8.2)(zone.js@0.16.3)': + '@angular/core@22.2.0(@angular/compiler@22.2.0)(rxjs@7.8.2)(zone.js@0.16.3)': dependencies: rxjs: 7.8.2 tslib: 2.8.1 optionalDependencies: - '@angular/compiler': 22.2.0-rc.0 + '@angular/compiler': 22.2.0 zone.js: 0.16.3 - '@angular/forms@22.2.0-rc.0(@angular/common@22.2.0-rc.0(@angular/core@22.2.0-rc.0(@angular/compiler@22.2.0-rc.0)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2))(@angular/core@22.2.0-rc.0(@angular/compiler@22.2.0-rc.0)(rxjs@7.8.2)(zone.js@0.16.3))(@angular/platform-browser@22.2.0-rc.0(@angular/animations@22.2.0-rc.0(@angular/core@22.2.0-rc.0(@angular/compiler@22.2.0-rc.0)(rxjs@7.8.2)(zone.js@0.16.3)))(@angular/common@22.2.0-rc.0(@angular/core@22.2.0-rc.0(@angular/compiler@22.2.0-rc.0)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2))(@angular/core@22.2.0-rc.0(@angular/compiler@22.2.0-rc.0)(rxjs@7.8.2)(zone.js@0.16.3)))(rxjs@7.8.2)': + '@angular/forms@22.2.0(@angular/common@22.2.0(@angular/core@22.2.0(@angular/compiler@22.2.0)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2))(@angular/core@22.2.0(@angular/compiler@22.2.0)(rxjs@7.8.2)(zone.js@0.16.3))(@angular/platform-browser@22.2.0(@angular/animations@22.2.0(@angular/core@22.2.0(@angular/compiler@22.2.0)(rxjs@7.8.2)(zone.js@0.16.3)))(@angular/common@22.2.0(@angular/core@22.2.0(@angular/compiler@22.2.0)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2))(@angular/core@22.2.0(@angular/compiler@22.2.0)(rxjs@7.8.2)(zone.js@0.16.3)))(rxjs@7.8.2)': dependencies: - '@angular/common': 22.2.0-rc.0(@angular/core@22.2.0-rc.0(@angular/compiler@22.2.0-rc.0)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2) - '@angular/core': 22.2.0-rc.0(@angular/compiler@22.2.0-rc.0)(rxjs@7.8.2)(zone.js@0.16.3) - '@angular/platform-browser': 22.2.0-rc.0(@angular/animations@22.2.0-rc.0(@angular/core@22.2.0-rc.0(@angular/compiler@22.2.0-rc.0)(rxjs@7.8.2)(zone.js@0.16.3)))(@angular/common@22.2.0-rc.0(@angular/core@22.2.0-rc.0(@angular/compiler@22.2.0-rc.0)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2))(@angular/core@22.2.0-rc.0(@angular/compiler@22.2.0-rc.0)(rxjs@7.8.2)(zone.js@0.16.3)) + '@angular/common': 22.2.0(@angular/core@22.2.0(@angular/compiler@22.2.0)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2) + '@angular/core': 22.2.0(@angular/compiler@22.2.0)(rxjs@7.8.2)(zone.js@0.16.3) + '@angular/platform-browser': 22.2.0(@angular/animations@22.2.0(@angular/core@22.2.0(@angular/compiler@22.2.0)(rxjs@7.8.2)(zone.js@0.16.3)))(@angular/common@22.2.0(@angular/core@22.2.0(@angular/compiler@22.2.0)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2))(@angular/core@22.2.0(@angular/compiler@22.2.0)(rxjs@7.8.2)(zone.js@0.16.3)) '@standard-schema/spec': 1.1.0 rxjs: 7.8.2 tslib: 2.8.1 zod: 4.6.5 - '@angular/localize@22.2.0-rc.0(@angular/compiler-cli@22.2.0-rc.0(@angular/compiler@22.2.0-rc.0)(typescript@6.0.3))(@angular/compiler@22.2.0-rc.0)': + '@angular/localize@22.2.0(@angular/compiler-cli@22.2.0(@angular/compiler@22.2.0)(typescript@6.0.3))(@angular/compiler@22.2.0)': dependencies: - '@angular/compiler': 22.2.0-rc.0 - '@angular/compiler-cli': 22.2.0-rc.0(@angular/compiler@22.2.0-rc.0)(typescript@6.0.3) + '@angular/compiler': 22.2.0 + '@angular/compiler-cli': 22.2.0(@angular/compiler@22.2.0)(typescript@6.0.3) '@babel/core': 8.0.1 tinyglobby: 0.2.17 yargs: 18.1.0 - '@angular/material@22.2.0-rc.0(25ddf4063a130bbf19862bd16a6ab5d4)': + '@angular/material@22.2.0(40004d7e10fb4ba9a3893f0ca483936a)': dependencies: - '@angular/cdk': 22.2.0-rc.0(32444abcc2be6e3bf2b6c059aa24d737) - '@angular/common': 22.2.0-rc.0(@angular/core@22.2.0-rc.0(@angular/compiler@22.2.0-rc.0)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2) - '@angular/core': 22.2.0-rc.0(@angular/compiler@22.2.0-rc.0)(rxjs@7.8.2)(zone.js@0.16.3) - '@angular/forms': 22.2.0-rc.0(@angular/common@22.2.0-rc.0(@angular/core@22.2.0-rc.0(@angular/compiler@22.2.0-rc.0)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2))(@angular/core@22.2.0-rc.0(@angular/compiler@22.2.0-rc.0)(rxjs@7.8.2)(zone.js@0.16.3))(@angular/platform-browser@22.2.0-rc.0(@angular/animations@22.2.0-rc.0(@angular/core@22.2.0-rc.0(@angular/compiler@22.2.0-rc.0)(rxjs@7.8.2)(zone.js@0.16.3)))(@angular/common@22.2.0-rc.0(@angular/core@22.2.0-rc.0(@angular/compiler@22.2.0-rc.0)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2))(@angular/core@22.2.0-rc.0(@angular/compiler@22.2.0-rc.0)(rxjs@7.8.2)(zone.js@0.16.3)))(rxjs@7.8.2) - '@angular/platform-browser': 22.2.0-rc.0(@angular/animations@22.2.0-rc.0(@angular/core@22.2.0-rc.0(@angular/compiler@22.2.0-rc.0)(rxjs@7.8.2)(zone.js@0.16.3)))(@angular/common@22.2.0-rc.0(@angular/core@22.2.0-rc.0(@angular/compiler@22.2.0-rc.0)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2))(@angular/core@22.2.0-rc.0(@angular/compiler@22.2.0-rc.0)(rxjs@7.8.2)(zone.js@0.16.3)) + '@angular/cdk': 22.2.0(de96355f700a7339df12db5b0650ad5f) + '@angular/common': 22.2.0(@angular/core@22.2.0(@angular/compiler@22.2.0)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2) + '@angular/core': 22.2.0(@angular/compiler@22.2.0)(rxjs@7.8.2)(zone.js@0.16.3) + '@angular/forms': 22.2.0(@angular/common@22.2.0(@angular/core@22.2.0(@angular/compiler@22.2.0)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2))(@angular/core@22.2.0(@angular/compiler@22.2.0)(rxjs@7.8.2)(zone.js@0.16.3))(@angular/platform-browser@22.2.0(@angular/animations@22.2.0(@angular/core@22.2.0(@angular/compiler@22.2.0)(rxjs@7.8.2)(zone.js@0.16.3)))(@angular/common@22.2.0(@angular/core@22.2.0(@angular/compiler@22.2.0)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2))(@angular/core@22.2.0(@angular/compiler@22.2.0)(rxjs@7.8.2)(zone.js@0.16.3)))(rxjs@7.8.2) + '@angular/platform-browser': 22.2.0(@angular/animations@22.2.0(@angular/core@22.2.0(@angular/compiler@22.2.0)(rxjs@7.8.2)(zone.js@0.16.3)))(@angular/common@22.2.0(@angular/core@22.2.0(@angular/compiler@22.2.0)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2))(@angular/core@22.2.0(@angular/compiler@22.2.0)(rxjs@7.8.2)(zone.js@0.16.3)) rxjs: 7.8.2 tslib: 2.8.1 @@ -8789,35 +8789,35 @@ snapshots: - '@modelcontextprotocol/sdk' - '@react-native-async-storage/async-storage' - '@angular/platform-browser@22.2.0-rc.0(@angular/animations@22.2.0-rc.0(@angular/core@22.2.0-rc.0(@angular/compiler@22.2.0-rc.0)(rxjs@7.8.2)(zone.js@0.16.3)))(@angular/common@22.2.0-rc.0(@angular/core@22.2.0-rc.0(@angular/compiler@22.2.0-rc.0)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2))(@angular/core@22.2.0-rc.0(@angular/compiler@22.2.0-rc.0)(rxjs@7.8.2)(zone.js@0.16.3))': + '@angular/platform-browser@22.2.0(@angular/animations@22.2.0(@angular/core@22.2.0(@angular/compiler@22.2.0)(rxjs@7.8.2)(zone.js@0.16.3)))(@angular/common@22.2.0(@angular/core@22.2.0(@angular/compiler@22.2.0)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2))(@angular/core@22.2.0(@angular/compiler@22.2.0)(rxjs@7.8.2)(zone.js@0.16.3))': dependencies: - '@angular/common': 22.2.0-rc.0(@angular/core@22.2.0-rc.0(@angular/compiler@22.2.0-rc.0)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2) - '@angular/core': 22.2.0-rc.0(@angular/compiler@22.2.0-rc.0)(rxjs@7.8.2)(zone.js@0.16.3) + '@angular/common': 22.2.0(@angular/core@22.2.0(@angular/compiler@22.2.0)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2) + '@angular/core': 22.2.0(@angular/compiler@22.2.0)(rxjs@7.8.2)(zone.js@0.16.3) tslib: 2.8.1 optionalDependencies: - '@angular/animations': 22.2.0-rc.0(@angular/core@22.2.0-rc.0(@angular/compiler@22.2.0-rc.0)(rxjs@7.8.2)(zone.js@0.16.3)) + '@angular/animations': 22.2.0(@angular/core@22.2.0(@angular/compiler@22.2.0)(rxjs@7.8.2)(zone.js@0.16.3)) - '@angular/platform-server@22.2.0-rc.0(@angular/common@22.2.0-rc.0(@angular/core@22.2.0-rc.0(@angular/compiler@22.2.0-rc.0)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2))(@angular/compiler@22.2.0-rc.0)(@angular/core@22.2.0-rc.0(@angular/compiler@22.2.0-rc.0)(rxjs@7.8.2)(zone.js@0.16.3))(@angular/platform-browser@22.2.0-rc.0(@angular/animations@22.2.0-rc.0(@angular/core@22.2.0-rc.0(@angular/compiler@22.2.0-rc.0)(rxjs@7.8.2)(zone.js@0.16.3)))(@angular/common@22.2.0-rc.0(@angular/core@22.2.0-rc.0(@angular/compiler@22.2.0-rc.0)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2))(@angular/core@22.2.0-rc.0(@angular/compiler@22.2.0-rc.0)(rxjs@7.8.2)(zone.js@0.16.3)))(rxjs@7.8.2)': + '@angular/platform-server@22.2.0(@angular/common@22.2.0(@angular/core@22.2.0(@angular/compiler@22.2.0)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2))(@angular/compiler@22.2.0)(@angular/core@22.2.0(@angular/compiler@22.2.0)(rxjs@7.8.2)(zone.js@0.16.3))(@angular/platform-browser@22.2.0(@angular/animations@22.2.0(@angular/core@22.2.0(@angular/compiler@22.2.0)(rxjs@7.8.2)(zone.js@0.16.3)))(@angular/common@22.2.0(@angular/core@22.2.0(@angular/compiler@22.2.0)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2))(@angular/core@22.2.0(@angular/compiler@22.2.0)(rxjs@7.8.2)(zone.js@0.16.3)))(rxjs@7.8.2)': dependencies: - '@angular/common': 22.2.0-rc.0(@angular/core@22.2.0-rc.0(@angular/compiler@22.2.0-rc.0)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2) - '@angular/compiler': 22.2.0-rc.0 - '@angular/core': 22.2.0-rc.0(@angular/compiler@22.2.0-rc.0)(rxjs@7.8.2)(zone.js@0.16.3) - '@angular/platform-browser': 22.2.0-rc.0(@angular/animations@22.2.0-rc.0(@angular/core@22.2.0-rc.0(@angular/compiler@22.2.0-rc.0)(rxjs@7.8.2)(zone.js@0.16.3)))(@angular/common@22.2.0-rc.0(@angular/core@22.2.0-rc.0(@angular/compiler@22.2.0-rc.0)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2))(@angular/core@22.2.0-rc.0(@angular/compiler@22.2.0-rc.0)(rxjs@7.8.2)(zone.js@0.16.3)) + '@angular/common': 22.2.0(@angular/core@22.2.0(@angular/compiler@22.2.0)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2) + '@angular/compiler': 22.2.0 + '@angular/core': 22.2.0(@angular/compiler@22.2.0)(rxjs@7.8.2)(zone.js@0.16.3) + '@angular/platform-browser': 22.2.0(@angular/animations@22.2.0(@angular/core@22.2.0(@angular/compiler@22.2.0)(rxjs@7.8.2)(zone.js@0.16.3)))(@angular/common@22.2.0(@angular/core@22.2.0(@angular/compiler@22.2.0)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2))(@angular/core@22.2.0(@angular/compiler@22.2.0)(rxjs@7.8.2)(zone.js@0.16.3)) rxjs: 7.8.2 tslib: 2.8.1 xhr2: 0.2.1 - '@angular/router@22.2.0-rc.0(@angular/common@22.2.0-rc.0(@angular/core@22.2.0-rc.0(@angular/compiler@22.2.0-rc.0)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2))(@angular/core@22.2.0-rc.0(@angular/compiler@22.2.0-rc.0)(rxjs@7.8.2)(zone.js@0.16.3))(@angular/platform-browser@22.2.0-rc.0(@angular/animations@22.2.0-rc.0(@angular/core@22.2.0-rc.0(@angular/compiler@22.2.0-rc.0)(rxjs@7.8.2)(zone.js@0.16.3)))(@angular/common@22.2.0-rc.0(@angular/core@22.2.0-rc.0(@angular/compiler@22.2.0-rc.0)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2))(@angular/core@22.2.0-rc.0(@angular/compiler@22.2.0-rc.0)(rxjs@7.8.2)(zone.js@0.16.3)))(rxjs@7.8.2)': + '@angular/router@22.2.0(@angular/common@22.2.0(@angular/core@22.2.0(@angular/compiler@22.2.0)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2))(@angular/core@22.2.0(@angular/compiler@22.2.0)(rxjs@7.8.2)(zone.js@0.16.3))(@angular/platform-browser@22.2.0(@angular/animations@22.2.0(@angular/core@22.2.0(@angular/compiler@22.2.0)(rxjs@7.8.2)(zone.js@0.16.3)))(@angular/common@22.2.0(@angular/core@22.2.0(@angular/compiler@22.2.0)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2))(@angular/core@22.2.0(@angular/compiler@22.2.0)(rxjs@7.8.2)(zone.js@0.16.3)))(rxjs@7.8.2)': dependencies: - '@angular/common': 22.2.0-rc.0(@angular/core@22.2.0-rc.0(@angular/compiler@22.2.0-rc.0)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2) - '@angular/core': 22.2.0-rc.0(@angular/compiler@22.2.0-rc.0)(rxjs@7.8.2)(zone.js@0.16.3) - '@angular/platform-browser': 22.2.0-rc.0(@angular/animations@22.2.0-rc.0(@angular/core@22.2.0-rc.0(@angular/compiler@22.2.0-rc.0)(rxjs@7.8.2)(zone.js@0.16.3)))(@angular/common@22.2.0-rc.0(@angular/core@22.2.0-rc.0(@angular/compiler@22.2.0-rc.0)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2))(@angular/core@22.2.0-rc.0(@angular/compiler@22.2.0-rc.0)(rxjs@7.8.2)(zone.js@0.16.3)) + '@angular/common': 22.2.0(@angular/core@22.2.0(@angular/compiler@22.2.0)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2) + '@angular/core': 22.2.0(@angular/compiler@22.2.0)(rxjs@7.8.2)(zone.js@0.16.3) + '@angular/platform-browser': 22.2.0(@angular/animations@22.2.0(@angular/core@22.2.0(@angular/compiler@22.2.0)(rxjs@7.8.2)(zone.js@0.16.3)))(@angular/common@22.2.0(@angular/core@22.2.0(@angular/compiler@22.2.0)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2))(@angular/core@22.2.0(@angular/compiler@22.2.0)(rxjs@7.8.2)(zone.js@0.16.3)) rxjs: 7.8.2 tslib: 2.8.1 - '@angular/service-worker@22.2.0-rc.0(@angular/core@22.2.0-rc.0(@angular/compiler@22.2.0-rc.0)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2)': + '@angular/service-worker@22.2.0(@angular/core@22.2.0(@angular/compiler@22.2.0)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2)': dependencies: - '@angular/core': 22.2.0-rc.0(@angular/compiler@22.2.0-rc.0)(rxjs@7.8.2)(zone.js@0.16.3) + '@angular/core': 22.2.0(@angular/compiler@22.2.0)(rxjs@7.8.2)(zone.js@0.16.3) rxjs: 7.8.2 tslib: 2.8.1 @@ -11604,7 +11604,7 @@ snapshots: '@typescript-eslint/project-service@8.70.0(supports-color@11.0.0)(typescript@6.0.3)': dependencies: '@typescript-eslint/tsconfig-utils': 8.70.0(typescript@6.0.3) - '@typescript-eslint/types': 8.70.0 + '@typescript-eslint/types': 8.70.1 debug: 4.4.3(supports-color@11.0.0) typescript: 6.0.3 transitivePeerDependencies: @@ -14913,10 +14913,10 @@ snapshots: neo-async@2.6.2: {} - ng-packagr@22.2.0-rc.0(@angular/compiler-cli@22.2.0-rc.0(@angular/compiler@22.2.0-rc.0)(typescript@6.0.3))(supports-color@11.0.0)(tslib@2.8.1)(typescript@6.0.3): + ng-packagr@22.2.0(@angular/compiler-cli@22.2.0(@angular/compiler@22.2.0)(typescript@6.0.3))(supports-color@11.0.0)(tslib@2.8.1)(typescript@6.0.3): dependencies: '@ampproject/remapping': 2.3.0 - '@angular/compiler-cli': 22.2.0-rc.0(@angular/compiler@22.2.0-rc.0)(typescript@6.0.3) + '@angular/compiler-cli': 22.2.0(@angular/compiler@22.2.0)(typescript@6.0.3) ajv: 8.20.0 browserslist: 4.29.0 chokidar: 5.0.0 @@ -16763,7 +16763,7 @@ snapshots: webidl-conversions@8.0.1: {} - webpack-dev-middleware@8.3.0(webpack@5.111.0(esbuild@0.28.2)(lightningcss@1.33.0)(uglify-js@3.19.3)): + webpack-dev-middleware@8.3.0(webpack@5.111.0(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.28)(uglify-js@3.19.3)): dependencies: ansi-html-community: 0.0.8 memfs: 4.79.0 @@ -16773,7 +16773,7 @@ snapshots: optionalDependencies: webpack: 5.111.0(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.28)(uglify-js@3.19.3) - webpack-dev-server@6.0.0(bufferutil@4.1.0)(supports-color@11.0.0)(utf-8-validate@6.0.6)(webpack@5.111.0(esbuild@0.28.2)(lightningcss@1.33.0)(uglify-js@3.19.3)): + webpack-dev-server@6.0.0(bufferutil@4.1.0)(supports-color@11.0.0)(utf-8-validate@6.0.6)(webpack@5.111.0(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.28)(uglify-js@3.19.3)): dependencies: '@types/bonjour': 3.5.13 '@types/connect-history-api-fallback': 1.5.4 @@ -16798,7 +16798,7 @@ snapshots: selfsigned: 5.5.0 serve-index: 1.9.2(supports-color@11.0.0) tinyglobby: 0.2.17 - webpack-dev-middleware: 8.3.0(webpack@5.111.0(esbuild@0.28.2)(lightningcss@1.33.0)(uglify-js@3.19.3)) + webpack-dev-middleware: 8.3.0(webpack@5.111.0(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.28)(uglify-js@3.19.3)) ws: 8.21.3(bufferutil@4.1.0)(utf-8-validate@6.0.6) optionalDependencies: webpack: 5.111.0(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.28)(uglify-js@3.19.3) From cbed94428f2ad2a689ae541354c8b76e7bb9735d Mon Sep 17 00:00:00 2001 From: Doug Parker Date: Wed, 23 Sep 2026 14:07:33 -0700 Subject: [PATCH 023/233] release: cut the v22.2.0 release --- CHANGELOG.md | 299 ++++++++++----------------------------------------- package.json | 2 +- 2 files changed, 55 insertions(+), 246 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index a67b3ed682d2..d3606a43d1bc 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,27 +1,6 @@ - + -# 22.2.0-rc.0 (2026-09-16) - -### @angular/cli - -| Commit | Type | Description | -| ---------------------------------------------------------------------------------------------------- | ---- | ----------------------------------------------------------------- | -| [6e7f809a7d](https://github.com/angular/angular-cli/commit/6e7f809a7d66e4b8d260a1c00297812412a926f1) | perf | skip eager yargs help message formatting during command execution | - -### @angular/build - -| Commit | Type | Description | -| ---------------------------------------------------------------------------------------------------- | ---- | -------------------------------------------------------------------------- | -| [978351af71](https://github.com/angular/angular-cli/commit/978351af71889d4786a18fec9e193eb5b16af7dd) | fix | include inline component stylesheets in referenced watch files | -| [72dc9677cf](https://github.com/angular/angular-cli/commit/72dc9677cf743243d6cb22d2b81782022f71356e) | fix | pass load cache to compiler plugin and escape extension regex in polyfills | -| [31c045639e](https://github.com/angular/angular-cli/commit/31c045639e8bfd114cbd552d83cc70a968fe7f81) | fix | prevent stale bundler caching and correctly resolve load cache | -| [d97c8857c1](https://github.com/angular/angular-cli/commit/d97c8857c18da02fcc6c69a0ea652cc706c5c9b6) | perf | key Sass package resolutions without containing URL qualification | - - - - - -# 22.2.0-next.7 (2026-09-10) +# 22.2.0 (2026-09-23) ## Deprecations @@ -31,31 +10,63 @@ Disabling code splitting is no longer necessary with Vitest 5, as the issue where shared-module exports were uninitialized in class-field initializers under JSDOM has been resolved. +### @angular/cli + +| Commit | Type | Description | +| --------------------------------------------------------------------------------------------------- | ---- | ----------------------------------------------------------------- | +| [41555dfb3](https://github.com/angular/angular-cli/commit/41555dfb3b71d08cdfe2853bf2cbeca5b6942f67) | feat | add `--root` command line option to `mcp` command | +| [6e7f809a7](https://github.com/angular/angular-cli/commit/6e7f809a7d66e4b8d260a1c00297812412a926f1) | perf | skip eager yargs help message formatting during command execution | + ### @angular/build -| Commit | Type | Description | -| ---------------------------------------------------------------------------------------------------- | -------- | ---------------------------------------------------------------------------------------------------------------------------- | -| [fe2f180fd0](https://github.com/angular/angular-cli/commit/fe2f180fd0c2fa02706353ca6a034d235feb6c59) | fix | add automatic corruption recovery in SQLite cache store | -| [675f1f5274](https://github.com/angular/angular-cli/commit/675f1f5274ff853f153832f7adc69273fa63f0cd) | fix | avoid pure comment pattern in oxc transform | -| [d396324b4e](https://github.com/angular/angular-cli/commit/d396324b4eb3b16640526a64365d953642bc7ca1) | fix | default preloadInitial to false when serviceWorker is enabled | -| [8504cfffcf](https://github.com/angular/angular-cli/commit/8504cfffcfb943fcd8fda62507e4b236e4bf429a) | fix | disable root config extension for inline test project | -| [5d21812aae](https://github.com/angular/angular-cli/commit/5d21812aaedc57cbd9378a99d9747f80c413cdc3) | fix | disable strictPort when port 0 is used in dev-server | -| [54d712f579](https://github.com/angular/angular-cli/commit/54d712f57904d2f612eec27a0507ea298b40915e) | fix | ensure parent directory exists in SQLite cache store | -| [b423bc39cd](https://github.com/angular/angular-cli/commit/b423bc39cd59c73ae79402c6cccdc0ecf1d7aaa1) | fix | use chokidar watcher when followSymlinks is enabled | -| [5a0d226b7c](https://github.com/angular/angular-cli/commit/5a0d226b7ccb945edd234fa0c839994f4876e2ee) | perf | avoid full JSON parsing when updating sourcemap ignore list | -| [482f6d8aab](https://github.com/angular/angular-cli/commit/482f6d8aab289fbd6dc5f9aecdcf7b8e1b6cac4f) | perf | decouple diagnostic type checking from build start | -| [f1afa603b4](https://github.com/angular/angular-cli/commit/f1afa603b48566e45dfb8d95930375a71f0bfa0b) | perf | read rendered module length once per module in chunk optimizer ([#34045](https://github.com/angular/angular-cli/pull/34045)) | -| [0ba4d8e29c](https://github.com/angular/angular-cli/commit/0ba4d8e29c0fb9abe6b07432edfab9e39066ca29) | perf | reduce watcher debounce latency for faster incremental rebuilds | -| [4d11a1334f](https://github.com/angular/angular-cli/commit/4d11a1334ff5fabfe5338cc3de5ce4f45f6afa5f) | perf | selectively compress large entries in SQLite cache store | -| [0a137f98d0](https://github.com/angular/angular-cli/commit/0a137f98d035f3dbd9a5daf1b6999246f73610c8) | perf | share sass directory and resolution caches across stylesheets | -| [d11a663e77](https://github.com/angular/angular-cli/commit/d11a663e77dad3dc9dbb6336e782f23b8a6f595c) | perf | verify cache metadata before reading file and eliminate sqlite read-locks | -| [66bd6bd1ea](https://github.com/angular/angular-cli/commit/66bd6bd1eab41484ed5db38f5545e80de4090b34) | refactor | deprecate splitting option in unit-test builder | +| Commit | Type | Description | +| --------------------------------------------------------------------------------------------------- | -------- | -------------------------------------------------------------------------------- | +| [ad8271320](https://github.com/angular/angular-cli/commit/ad8271320f67c2b1502e446f1e3cb0a05444d04f) | feat | migrate Angular Linker to oxc-parser and magic-string | +| [175273931](https://github.com/angular/angular-cli/commit/175273931ebb0cf08bf62dd1694dbde5ff5229b6) | feat | Support splitting browser and server stats jsonfiles for easier consumption | +| [fe2f180fd](https://github.com/angular/angular-cli/commit/fe2f180fd0c2fa02706353ca6a034d235feb6c59) | fix | add automatic corruption recovery in SQLite cache store | +| [675f1f527](https://github.com/angular/angular-cli/commit/675f1f5274ff853f153832f7adc69273fa63f0cd) | fix | avoid pure comment pattern in oxc transform | +| [d396324b4](https://github.com/angular/angular-cli/commit/d396324b4eb3b16640526a64365d953642bc7ca1) | fix | default preloadInitial to false when serviceWorker is enabled | +| [7e5510e46](https://github.com/angular/angular-cli/commit/7e5510e464eb423d8757ae6f058f73fc17249d81) | fix | disable linker internal source mapping in OXC linker | +| [8504cfffc](https://github.com/angular/angular-cli/commit/8504cfffcfb943fcd8fda62507e4b236e4bf429a) | fix | disable root config extension for inline test project | +| [ee3041325](https://github.com/angular/angular-cli/commit/ee3041325cd2400c26e239e64e14a0e314ab6031) | fix | ensure chokidar watcher is ready before returning | +| [54d712f57](https://github.com/angular/angular-cli/commit/54d712f57904d2f612eec27a0507ea298b40915e) | fix | ensure parent directory exists in SQLite cache store | +| [80acd6236](https://github.com/angular/angular-cli/commit/80acd6236eac6b1b07543583717e94cbd1de1180) | fix | execute setup file hooks for each spec file when coverage is enabled | +| [978351af7](https://github.com/angular/angular-cli/commit/978351af71889d4786a18fec9e193eb5b16af7dd) | fix | include inline component stylesheets in referenced watch files | +| [f47f77f5f](https://github.com/angular/angular-cli/commit/f47f77f5f6db5cda1493652f813c98c26f172ea9) | fix | only compile included test files in unit-test builder | +| [72dc9677c](https://github.com/angular/angular-cli/commit/72dc9677cf743243d6cb22d2b81782022f71356e) | fix | pass load cache to compiler plugin and escape extension regex in polyfills | +| [701bde481](https://github.com/angular/angular-cli/commit/701bde4818439de0e49c99d57dc749b0dd22c4dd) | fix | preserve duplicate bundle filenames across output file types | +| [e4111ae81](https://github.com/angular/angular-cli/commit/e4111ae8180f3cd5800f248c23010844aa1730ad) | fix | prevent memory leaks in parallel compilation and caches | +| [31c045639](https://github.com/angular/angular-cli/commit/31c045639e8bfd114cbd552d83cc70a968fe7f81) | fix | prevent stale bundler caching and correctly resolve load cache | +| [bad31421c](https://github.com/angular/angular-cli/commit/bad31421cbf23339d4fbd389a91d198df405697d) | fix | prevent syntax corruption in linker and oxc transform | +| [0d9851600](https://github.com/angular/angular-cli/commit/0d9851600ca618ccabfc3143a9c552a5448d6eec) | fix | recursively ignore output and cache paths in watch mode | +| [040bc21ec](https://github.com/angular/angular-cli/commit/040bc21ec3d4fa1bdfa8513206f463d89e20d9a1) | fix | scope Sass package resolution caching for stylesheets in node_modules | +| [1fc273279](https://github.com/angular/angular-cli/commit/1fc2732795069ad521645b06a94e5df3a55c3d9c) | fix | support parenthesized expressions in oxc linker | +| [b423bc39c](https://github.com/angular/angular-cli/commit/b423bc39cd59c73ae79402c6cccdc0ecf1d7aaa1) | fix | use chokidar watcher when followSymlinks is enabled | +| [87551ad5c](https://github.com/angular/angular-cli/commit/87551ad5c53f90cbdc68fdb5e47007b9436c7f75) | perf | avoid encoding intermediate source maps before remapping | +| [6ee559ca9](https://github.com/angular/angular-cli/commit/6ee559ca9d209fb4c53de2aaf9918d10e5f062a1) | perf | bypass worker dispatch for files without transform candidates | +| [0589edd9c](https://github.com/angular/angular-cli/commit/0589edd9cdc493ecf34a160cc7b8491618b59f72) | perf | consolidate component stylesheet bundling with shared load result cache | +| [482f6d8aa](https://github.com/angular/angular-cli/commit/482f6d8aab289fbd6dc5f9aecdcf7b8e1b6cac4f) | perf | decouple diagnostic type checking from build start | +| [a877aa7eb](https://github.com/angular/angular-cli/commit/a877aa7ebdbf919d6bc17e6ec0920ca702db0db4) | perf | implement SharedArrayBuffer translation dictionaries for zero-copy worker access | +| [f1cc95943](https://github.com/angular/angular-cli/commit/f1cc959439d8ca11a45d693520c34dd94e0b6548) | perf | implement sliding-window batching and worker translation eviction | +| [d97c8857c](https://github.com/angular/angular-cli/commit/d97c8857c18da02fcc6c69a0ea652cc706c5c9b6) | perf | key Sass package resolutions without containing URL qualification | +| [5cd20e141](https://github.com/angular/angular-cli/commit/5cd20e141ad176c87e4002da2d4ee3755f97cd3e) | perf | only reset Sass worker pool caches when stylesheet files change | +| [1c00edce0](https://github.com/angular/angular-cli/commit/1c00edce02bdd0201546417d71518f78bfb89d34) | perf | optimize sourcemap stripping and loading with buffer fast path | +| [0ba4d8e29](https://github.com/angular/angular-cli/commit/0ba4d8e29c0fb9abe6b07432edfab9e39066ca29) | perf | reduce watcher debounce latency for faster incremental rebuilds | +| [a6ef9cfbe](https://github.com/angular/angular-cli/commit/a6ef9cfbeace725d58c0f7f65640ef6de9b39c33) | perf | replace watchpack with @parcel/watcher and chokidar | +| [4d11a1334](https://github.com/angular/angular-cli/commit/4d11a1334ff5fabfe5338cc3de5ce4f45f6afa5f) | perf | selectively compress large entries in SQLite cache store | +| [0a137f98d](https://github.com/angular/angular-cli/commit/0a137f98d035f3dbd9a5daf1b6999246f73610c8) | perf | share sass directory and resolution caches across stylesheets | +| [f4dad31cc](https://github.com/angular/angular-cli/commit/f4dad31cce41bc3e8ed8767256d9e50a712c3a72) | perf | unify Oxc linking and optimization AST traversal passes | +| [2b85529e8](https://github.com/angular/angular-cli/commit/2b85529e8290c8c916539b5a0336b4efdb68578c) | perf | use iterative post-order AST traversal for OXC transforms | +| [ecbcd87b8](https://github.com/angular/angular-cli/commit/ecbcd87b8857225e4df3df7896b3236d63553f23) | perf | use native sass-embedded compiler daemon | +| [ce83ac0e8](https://github.com/angular/angular-cli/commit/ce83ac0e82981efd9408e07a35315e3cef9e1a36) | perf | use size-weighted task heuristics in i18n inliner | +| [d11a663e7](https://github.com/angular/angular-cli/commit/d11a663e77dad3dc9dbb6336e782f23b8a6f595c) | perf | verify cache metadata before reading file and eliminate sqlite read-locks | +| [66bd6bd1e](https://github.com/angular/angular-cli/commit/66bd6bd1eab41484ed5db38f5545e80de4090b34) | refactor | deprecate splitting option in unit-test builder | ### @angular/ssr -| Commit | Type | Description | -| ---------------------------------------------------------------------------------------------------- | ---- | -------------------------------------------- | -| [23e3d44a7f](https://github.com/angular/angular-cli/commit/23e3d44a7f051cd3bb67700b8d8407f73b7aa7f3) | perf | pre-compile critical CSS plans at build time | +| Commit | Type | Description | +| --------------------------------------------------------------------------------------------------- | ---- | -------------------------------------------- | +| [23e3d44a7](https://github.com/angular/angular-cli/commit/23e3d44a7f051cd3bb67700b8d8407f73b7aa7f3) | perf | pre-compile critical CSS plans at build time | @@ -97,40 +108,6 @@ - - -# 22.2.0-next.6 (2026-09-02) - -### @angular/cli - -| Commit | Type | Description | -| --------------------------------------------------------------------------------------------------- | ---- | ------------------------------------------------------------------ | -| [b37c93329](https://github.com/angular/angular-cli/commit/b37c933299dac37e394d9f4fe0d019052db427a9) | fix | isolate temporary package installations from parent Yarn workspace | - -### @angular/build - -| Commit | Type | Description | -| --------------------------------------------------------------------------------------------------- | ---- | ------------------------------------------------------------- | -| [4b8c62a8f](https://github.com/angular/angular-cli/commit/4b8c62a8f1a1d312ef2e1e0df6b7642bf1db5c5f) | fix | add splitting option to unit-test builder | -| [51565d4bc](https://github.com/angular/angular-cli/commit/51565d4bcbd4667c23c607d878f08301afc4c5e3) | fix | enable code splitting for vitest browser tests | -| [5b850fdfc](https://github.com/angular/angular-cli/commit/5b850fdfc7534d33db7ab4a7f1e32e143462eec7) | fix | fail build and exclude routes when prerendering fails | -| [dfa7f03a9](https://github.com/angular/angular-cli/commit/dfa7f03a93b5b24b949aea354bc40f0a91e9582d) | fix | keep dev-server Vite cache worktree-local | -| [135662d9a](https://github.com/angular/angular-cli/commit/135662d9a1de85b42292b26b547160eaca71e5da) | fix | preserve binary values in the SQLite cache store | -| [701bde481](https://github.com/angular/angular-cli/commit/701bde4818439de0e49c99d57dc749b0dd22c4dd) | fix | preserve duplicate bundle filenames across output file types | -| [6ee559ca9](https://github.com/angular/angular-cli/commit/6ee559ca9d209fb4c53de2aaf9918d10e5f062a1) | perf | bypass worker dispatch for files without transform candidates | -| [2b85529e8](https://github.com/angular/angular-cli/commit/2b85529e8290c8c916539b5a0336b4efdb68578c) | perf | use iterative post-order AST traversal for OXC transforms | -| [ecbcd87b8](https://github.com/angular/angular-cli/commit/ecbcd87b8857225e4df3df7896b3236d63553f23) | perf | use native sass-embedded compiler daemon | -| [ce83ac0e8](https://github.com/angular/angular-cli/commit/ce83ac0e82981efd9408e07a35315e3cef9e1a36) | perf | use size-weighted task heuristics in i18n inliner | - -### @angular/ssr - -| Commit | Type | Description | -| --------------------------------------------------------------------------------------------------- | ---- | --------------------------------------------------- | -| [4fa81d403](https://github.com/angular/angular-cli/commit/4fa81d403c93a7480301e58630203cb028aebc69) | fix | decode pathname when constructing server asset path | -| [bb72145f9](https://github.com/angular/angular-cli/commit/bb72145f9ab45aee29f523236b3a25cd0813a841) | fix | ensure public directory containment in CommonEngine | - - - # 22.1.7 (2026-09-02) @@ -196,30 +173,6 @@ - - -# 22.2.0-next.5 (2026-08-26) - -### @angular/build - -| Commit | Type | Description | -| ---------------------------------------------------------------------------------------------------- | ---- | -------------------------------------------------------------------------------- | -| [4d0be683b7](https://github.com/angular/angular-cli/commit/4d0be683b780a9a1629dc8f9cddad49153bddabf) | fix | ignore side-effect annotations in unit test builds | -| [e4111ae818](https://github.com/angular/angular-cli/commit/e4111ae8180f3cd5800f248c23010844aa1730ad) | fix | prevent memory leaks in parallel compilation and caches | -| [62999cabf4](https://github.com/angular/angular-cli/commit/62999cabf4d65cf1060598150a77494e147fcc2a) | perf | batch prerender routes and share in-memory server bundles | -| [0589edd9cd](https://github.com/angular/angular-cli/commit/0589edd9cdc493ecf34a160cc7b8491618b59f72) | perf | consolidate component stylesheet bundling with shared load result cache | -| [a877aa7ebd](https://github.com/angular/angular-cli/commit/a877aa7ebdbf919d6bc17e6ec0920ca702db0db4) | perf | implement SharedArrayBuffer translation dictionaries for zero-copy worker access | -| [f1cc959439](https://github.com/angular/angular-cli/commit/f1cc959439d8ca11a45d693520c34dd94e0b6548) | perf | implement sliding-window batching and worker translation eviction | -| [f4dad31cce](https://github.com/angular/angular-cli/commit/f4dad31cce41bc3e8ed8767256d9e50a712c3a72) | perf | unify Oxc linking and optimization AST traversal passes | - -### @angular/ssr - -| Commit | Type | Description | -| ---------------------------------------------------------------------------------------------------- | ---- | ----------------------------------------------------- | -| [f8576e3c8b](https://github.com/angular/angular-cli/commit/f8576e3c8bfe3490b1b0b85832b489593a4e43ac) | fix | abort web request signal when node request is aborted | - - - # 22.1.6 (2026-08-26) @@ -263,36 +216,6 @@ - - -# 22.2.0-next.4 (2026-08-19) - -### @angular/cli - -| Commit | Type | Description | -| --------------------------------------------------------------------------------------------------- | ---- | ---------------------------------------------------------------- | -| [34e1e0bb5](https://github.com/angular/angular-cli/commit/34e1e0bb5d5ccf374f51a1b241158f6f2ea0dd42) | fix | enforce MCP roots in get_best_practices tool | -| [2b060630c](https://github.com/angular/angular-cli/commit/2b060630c66ce688b7ecbe51d282955869e5d4b0) | fix | handle errors from isAllowedWorkspacePath in best-practices tool | -| [24fd8fce2](https://github.com/angular/angular-cli/commit/24fd8fce2a3ff035acdc5f3e036eb4ba21f71a76) | fix | throw on out-of-roots workspace in best-practices tool | - -### @schematics/angular - -| Commit | Type | Description | -| --------------------------------------------------------------------------------------------------- | ---- | ------------------------------------------------------------ | -| [ce1b60f89](https://github.com/angular/angular-cli/commit/ce1b60f89699c3a76496a0489e5f2b9e4fe62429) | fix | transform fail() to expect.fail() in refactor-jasmine-vitest | - -### @angular/build - -| Commit | Type | Description | -| --------------------------------------------------------------------------------------------------- | ---- | --------------------------------------------------------------------------- | -| [175273931](https://github.com/angular/angular-cli/commit/175273931ebb0cf08bf62dd1694dbde5ff5229b6) | feat | Support splitting browser and server stats jsonfiles for easier consumption | -| [1ee0beca7](https://github.com/angular/angular-cli/commit/1ee0beca7b243cc4c06eb42b25d216d7b256b097) | fix | correct misleading error message for top-level await | -| [0ffe2d27f](https://github.com/angular/angular-cli/commit/0ffe2d27f256a5755809fa4788e4adb97c65b806) | fix | disable code splitting for unit test builds | -| [50994d76e](https://github.com/angular/angular-cli/commit/50994d76e59a4b632f1782c51cd60f80c9cd50fb) | fix | preserve integrity and crossorigin in autoCsp loader | -| [d6fd24320](https://github.com/angular/angular-cli/commit/d6fd243207ad1c3e242b8592698afa986320cc6c) | perf | traverse AST with iterative post-order walker in i18n inliner | - - - # 22.1.5 (2026-08-19) @@ -322,54 +245,6 @@ - - -# 22.2.0-next.3 (2026-08-13) - -### @angular/cli - -| Commit | Type | Description | -| --------------------------------------------------------------------------------------------------- | ---- | ------------------------------------------------------------------------------------------------------------------------------------- | -| [7106676e6](https://github.com/angular/angular-cli/commit/7106676e64ee234641b1b3cbd88fc058703d4d3e) | fix | disable searching current directory for bare executable names on Windows | -| [ecf8c0822](https://github.com/angular/angular-cli/commit/ecf8c0822e5d56b44a0be4be8fccb41373135d3e) | fix | serialize configuration as a single argv token in run_target strategies ([#33657](https://github.com/angular/angular-cli/pull/33657)) | -| [2e4dd90c3](https://github.com/angular/angular-cli/commit/2e4dd90c3ae898bf36af42f699c7b7d560bfc66a) | perf | avoid eager module loading during global bootstrap | - -### @schematics/angular - -| Commit | Type | Description | -| --------------------------------------------------------------------------------------------------- | ---- | ------------------------------------------------------- | -| [1161e6c99](https://github.com/angular/angular-cli/commit/1161e6c99992c884e2e0ce9fc295b0e60b2ae1df) | fix | generate CLAUDE.md for Claude Code instead of AGENTS.md | -| [c536ae364](https://github.com/angular/angular-cli/commit/c536ae364975dd0088fd8717464c723a4dcb74e3) | fix | import UrlSegment instead of subPath in guard generator | - -### @angular/build - -| Commit | Type | Description | -| --------------------------------------------------------------------------------------------------- | ---- | ----------------------------------------------------------------- | -| [04b532772](https://github.com/angular/angular-cli/commit/04b532772f6347d341b182135dee1758616a69d6) | fix | count statically imported chunks in the initial total | -| [2274babb6](https://github.com/angular/angular-cli/commit/2274babb662b8da2189f1ae9faaa528838052c32) | fix | normalize setupFiles paths to POSIX for vitest runner | -| [199a864df](https://github.com/angular/angular-cli/commit/199a864df97fc8c20b8d4e1fc8b891c61140671a) | fix | prevent syntax corruption for Crockford-style enum IIFE | -| [0d9851600](https://github.com/angular/angular-cli/commit/0d9851600ca618ccabfc3143a9c552a5448d6eec) | fix | recursively ignore output and cache paths in watch mode | -| [3eba6f726](https://github.com/angular/angular-cli/commit/3eba6f7269f3b0f8556510d0b668e978ea686c88) | fix | return direct file contents for non-Angular TypeScript files | -| [3c7ac1518](https://github.com/angular/angular-cli/commit/3c7ac1518b062f14409b4d3c6c3e65c956424ad9) | fix | return only lowest version per target engine | -| [3e9fed9a6](https://github.com/angular/angular-cli/commit/3e9fed9a6a1d24f30812ca29ca621d9d9a14496f) | fix | set target for Rolldown dependency prebundling in Vite dev server | -| [87551ad5c](https://github.com/angular/angular-cli/commit/87551ad5c53f90cbdc68fdb5e47007b9436c7f75) | perf | avoid encoding intermediate source maps before remapping | -| [194be2088](https://github.com/angular/angular-cli/commit/194be2088587918ed7b47ed606ea587a7116608a) | perf | avoid encoding the inline source map before remapping | -| [a55a6b78e](https://github.com/angular/angular-cli/commit/a55a6b78e89debb9c93c83375c54f6716bc26c65) | perf | batch last_accessed updates in sqlite cache store | -| [33b305416](https://github.com/angular/angular-cli/commit/33b3054169929dc98f93a758a90da5d26cf522f7) | perf | hash the i18n inline cache key options once per locale | -| [1c00edce0](https://github.com/angular/angular-cli/commit/1c00edce02bdd0201546417d71518f78bfb89d34) | perf | optimize sourcemap stripping and loading with buffer fast path | -| [b6269a816](https://github.com/angular/angular-cli/commit/b6269a8169046a78281808dcf92054140912a77d) | perf | optimize template string size calculation in server manifest | -| [a6ef9cfbe](https://github.com/angular/angular-cli/commit/a6ef9cfbeace725d58c0f7f65640ef6de9b39c33) | perf | replace watchpack with @parcel/watcher and chokidar | -| [596847f89](https://github.com/angular/angular-cli/commit/596847f89913684a84465d004aa3d6c7e1a40b06) | perf | share i18n translations with the inliner workers by reference | -| [19c91e48d](https://github.com/angular/angular-cli/commit/19c91e48d4b8a95a76dfe4bffd105130b416843d) | perf | use Map for chunk asset size lookups in budget calculator | - -### @angular/ssr - -| Commit | Type | Description | -| --------------------------------------------------------------------------------------------------- | ---- | -------------------------------------------------- | -| [6a3446770](https://github.com/angular/angular-cli/commit/6a3446770a8fbfecc7265eb2a6d764e2f1614b3a) | fix | destroy platform when response stream is cancelled | - - - # 22.1.4 (2026-08-13) @@ -451,54 +326,6 @@ - - -# 22.2.0-next.2 (2026-08-05) - -### @angular/build - -| Commit | Type | Description | -| ---------------------------------------------------------------------------------------------------- | ---- | ----------------------------------------------------- | -| [7e5510e464](https://github.com/angular/angular-cli/commit/7e5510e464eb423d8757ae6f058f73fc17249d81) | fix | disable linker internal source mapping in OXC linker | -| [bad31421cb](https://github.com/angular/angular-cli/commit/bad31421cbf23339d4fbd389a91d198df405697d) | fix | prevent syntax corruption in linker and oxc transform | - - - - - -# 22.2.0-next.1 (2026-08-05) - -### @angular/cli - -| Commit | Type | Description | -| ---------------------------------------------------------------------------------------------------- | ---- | --------------------------------------------------------------------------------------------------------------------------------------------- | -| [41555dfb3b](https://github.com/angular/angular-cli/commit/41555dfb3b71d08cdfe2853bf2cbeca5b6942f67) | feat | add `--root` command line option to `mcp` command | -| [035b9d5c9b](https://github.com/angular/angular-cli/commit/035b9d5c9bca624b98e14480f599481f294b49f3) | fix | add packages with built-in schematics to devDependencies only | -| [0ae5690c35](https://github.com/angular/angular-cli/commit/0ae5690c35b9af00f60d4851f1bab4ba5ec8eb19) | fix | always install package during ng add to inspect manifest on disk for schematics ([#33718](https://github.com/angular/angular-cli/pull/33718)) | -| [44ff584b33](https://github.com/angular/angular-cli/commit/44ff584b33830aa839c08feb205f014e4e7b5dca) | fix | correctly report available package updates during bare ng update | -| [1d4f9ebbe9](https://github.com/angular/angular-cli/commit/1d4f9ebbe993a5eb8b23929a3fc55b506597e5aa) | fix | discover migrations from installed packages when omitted by registry metadata ([#33718](https://github.com/angular/angular-cli/pull/33718)) | -| [25034f97ad](https://github.com/angular/angular-cli/commit/25034f97ad1b9a12f4080f646a0e2705425f9726) | fix | normalize Windows drive-letter casing for process.cwd | - -### @angular/build - -| Commit | Type | Description | -| ---------------------------------------------------------------------------------------------------- | ---- | ------------------------------------------------------------------------------------------------------------- | -| [ad8271320f](https://github.com/angular/angular-cli/commit/ad8271320f67c2b1502e446f1e3cb0a05444d04f) | feat | migrate Angular Linker to oxc-parser and magic-string | -| [4fb12292c2](https://github.com/angular/angular-cli/commit/4fb12292c21498c59836f7c80e4f824bb7751cac) | fix | prevent build process hang on unhandled error ([#33715](https://github.com/angular/angular-cli/pull/33715)) | -| [abd8ec9f3e](https://github.com/angular/angular-cli/commit/abd8ec9f3e11f1410fcb87d0d9d60f56016912fe) | fix | prevent IIFE wrapper interleaving for adjacent classes in minified files | -| [bcadbbef20](https://github.com/angular/angular-cli/commit/bcadbbef2054e897b9d22c1456883fc68f0383c0) | fix | retain watch files on error in load result cache | -| [e1c7193dce](https://github.com/angular/angular-cli/commit/e1c7193dcee1c7f2feb07fdf24a6e0656f29cfaf) | fix | support case-insensitive and alternative license file names | -| [f4a0f846e7](https://github.com/angular/angular-cli/commit/f4a0f846e7d14b5ff58c91d04461ef4a027c56b8) | perf | release build resources early in non-watch mode ([#33715](https://github.com/angular/angular-cli/pull/33715)) | - -### @angular/ssr - -| Commit | Type | Description | -| ---------------------------------------------------------------------------------------------------- | ---- | ---------------------------------------------------------- | -| [b74eef889f](https://github.com/angular/angular-cli/commit/b74eef889f9c8812dcbe116400663fa3d68d6b4f) | fix | settle writeResponseToNodeResponse when client disconnects | -| [33169801c6](https://github.com/angular/angular-cli/commit/33169801c6ed7fc7c7dca2c04008e5d405374983) | perf | avoid buffering request body when sanitizing headers | - - - # 22.1.3 (2026-08-05) @@ -602,24 +429,6 @@ - - -# 22.2.0-next.0 (2026-07-30) - -### @angular/cli - -| Commit | Type | Description | -| ---------------------------------------------------------------------------------------------------- | ---- | ----------------------------------------------- | -| [e148a8df93](https://github.com/angular/angular-cli/commit/e148a8df93b309dcd51698b4ce4f9343560edd8e) | fix | support npm 12 metadata array and error formats | - -### @angular/build - -| Commit | Type | Description | -| ---------------------------------------------------------------------------------------------------- | ---- | --------------------------------------------------------------- | -| [6469b5f1f5](https://github.com/angular/angular-cli/commit/6469b5f1f5946415f49000f26bddd88b5647ac3d) | fix | rewrite paths from sandboxed execroots when running under Bazel | - - - # 22.1.0 (2026-07-29) diff --git a/package.json b/package.json index 3481919f3074..f0d81e359c5c 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@angular/devkit-repo", - "version": "22.2.0-rc.0", + "version": "22.2.0", "private": true, "description": "Software Development Kit for Angular", "keywords": [ From ffa5d43a131c0e1b6421c060c26624939eb7e9ae Mon Sep 17 00:00:00 2001 From: Angular Robot Date: Thu, 24 Sep 2026 12:44:19 +0000 Subject: [PATCH 024/233] build: update cross-repo angular dependencies See associated pull request for more information. --- .../assistant-to-the-branch-manager.yml | 2 +- .github/workflows/ci.yml | 52 ++--- .github/workflows/dev-infra.yml | 6 +- .github/workflows/perf.yml | 6 +- .github/workflows/pr.yml | 44 ++-- MODULE.bazel | 6 +- modules/testing/builder/package.json | 2 +- package.json | 2 +- packages/angular/build/package.json | 2 +- .../angular_devkit/build_angular/package.json | 2 +- pnpm-lock.yaml | 203 ++++++++++-------- 11 files changed, 176 insertions(+), 151 deletions(-) diff --git a/.github/workflows/assistant-to-the-branch-manager.yml b/.github/workflows/assistant-to-the-branch-manager.yml index d96db1e3d645..715bb9bf0c56 100644 --- a/.github/workflows/assistant-to-the-branch-manager.yml +++ b/.github/workflows/assistant-to-the-branch-manager.yml @@ -18,6 +18,6 @@ jobs: - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: persist-credentials: false - - uses: angular/dev-infra/github-actions/branch-manager@bf1d18837b5aaed70cf858ecd177583bf320be50 # main + - uses: angular/dev-infra/github-actions/branch-manager@a948cdfda182b725e3abad445b2e6264508db3ed # main with: angular-robot-key: ${{ secrets.ANGULAR_ROBOT_PRIVATE_KEY }} diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 5bc5ede289ce..a8dffcf5aac3 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -21,9 +21,9 @@ jobs: runs-on: ubuntu-latest steps: - name: Initialize environment - uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@bf1d18837b5aaed70cf858ecd177583bf320be50 # main + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@a948cdfda182b725e3abad445b2e6264508db3ed # main - name: Setup Bazel - uses: angular/dev-infra/github-actions/bazel/setup@bf1d18837b5aaed70cf858ecd177583bf320be50 # main + uses: angular/dev-infra/github-actions/bazel/setup@a948cdfda182b725e3abad445b2e6264508db3ed # main - name: Install node modules run: pnpm install --frozen-lockfile - name: Generate JSON schema types @@ -44,11 +44,11 @@ jobs: runs-on: ubuntu-latest steps: - name: Initialize environment - uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@bf1d18837b5aaed70cf858ecd177583bf320be50 # main + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@a948cdfda182b725e3abad445b2e6264508db3ed # main - name: Setup Bazel - uses: angular/dev-infra/github-actions/bazel/setup@bf1d18837b5aaed70cf858ecd177583bf320be50 # main + uses: angular/dev-infra/github-actions/bazel/setup@a948cdfda182b725e3abad445b2e6264508db3ed # main - name: Setup Bazel RBE - uses: angular/dev-infra/github-actions/bazel/configure-remote@bf1d18837b5aaed70cf858ecd177583bf320be50 # main + uses: angular/dev-infra/github-actions/bazel/configure-remote@a948cdfda182b725e3abad445b2e6264508db3ed # main with: google_credential: ${{ secrets.RBE_TRUSTED_BUILDS_USER }} - name: Install node modules @@ -61,11 +61,11 @@ jobs: runs-on: ubuntu-latest steps: - name: Initialize environment - uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@bf1d18837b5aaed70cf858ecd177583bf320be50 # main + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@a948cdfda182b725e3abad445b2e6264508db3ed # main - name: Setup Bazel - uses: angular/dev-infra/github-actions/bazel/setup@bf1d18837b5aaed70cf858ecd177583bf320be50 # main + uses: angular/dev-infra/github-actions/bazel/setup@a948cdfda182b725e3abad445b2e6264508db3ed # main - name: Setup Bazel RBE - uses: angular/dev-infra/github-actions/bazel/configure-remote@bf1d18837b5aaed70cf858ecd177583bf320be50 # main + uses: angular/dev-infra/github-actions/bazel/configure-remote@a948cdfda182b725e3abad445b2e6264508db3ed # main with: google_credential: ${{ secrets.RBE_TRUSTED_BUILDS_USER }} - name: Install node modules @@ -84,13 +84,13 @@ jobs: runs-on: ubuntu-latest steps: - name: Initialize environment - uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@bf1d18837b5aaed70cf858ecd177583bf320be50 # main + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@a948cdfda182b725e3abad445b2e6264508db3ed # main - name: Install node modules run: pnpm install --frozen-lockfile - name: Setup Bazel - uses: angular/dev-infra/github-actions/bazel/setup@bf1d18837b5aaed70cf858ecd177583bf320be50 # main + uses: angular/dev-infra/github-actions/bazel/setup@a948cdfda182b725e3abad445b2e6264508db3ed # main - name: Setup Bazel RBE - uses: angular/dev-infra/github-actions/bazel/configure-remote@bf1d18837b5aaed70cf858ecd177583bf320be50 # main + uses: angular/dev-infra/github-actions/bazel/configure-remote@a948cdfda182b725e3abad445b2e6264508db3ed # main with: google_credential: ${{ secrets.RBE_TRUSTED_BUILDS_USER }} - name: Run CLI E2E tests @@ -100,11 +100,11 @@ jobs: runs-on: ubuntu-latest steps: - name: Initialize environment - uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@bf1d18837b5aaed70cf858ecd177583bf320be50 # main + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@a948cdfda182b725e3abad445b2e6264508db3ed # main - name: Setup Bazel - uses: angular/dev-infra/github-actions/bazel/setup@bf1d18837b5aaed70cf858ecd177583bf320be50 # main + uses: angular/dev-infra/github-actions/bazel/setup@a948cdfda182b725e3abad445b2e6264508db3ed # main - name: Setup Bazel RBE - uses: angular/dev-infra/github-actions/bazel/configure-remote@bf1d18837b5aaed70cf858ecd177583bf320be50 # main + uses: angular/dev-infra/github-actions/bazel/configure-remote@a948cdfda182b725e3abad445b2e6264508db3ed # main with: google_credential: ${{ secrets.RBE_TRUSTED_BUILDS_USER }} - name: Install node modules @@ -137,7 +137,7 @@ jobs: runs-on: windows-2025 steps: - name: Initialize environment - uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@bf1d18837b5aaed70cf858ecd177583bf320be50 # main + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@a948cdfda182b725e3abad445b2e6264508db3ed # main - name: Install node modules run: pnpm install --frozen-lockfile - name: Download built Windows E2E tests @@ -164,13 +164,13 @@ jobs: runs-on: ubuntu-latest steps: - name: Initialize environment - uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@bf1d18837b5aaed70cf858ecd177583bf320be50 # main + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@a948cdfda182b725e3abad445b2e6264508db3ed # main - name: Install node modules run: pnpm install --frozen-lockfile - name: Setup Bazel - uses: angular/dev-infra/github-actions/bazel/setup@bf1d18837b5aaed70cf858ecd177583bf320be50 # main + uses: angular/dev-infra/github-actions/bazel/setup@a948cdfda182b725e3abad445b2e6264508db3ed # main - name: Setup Bazel RBE - uses: angular/dev-infra/github-actions/bazel/configure-remote@bf1d18837b5aaed70cf858ecd177583bf320be50 # main + uses: angular/dev-infra/github-actions/bazel/configure-remote@a948cdfda182b725e3abad445b2e6264508db3ed # main with: google_credential: ${{ secrets.RBE_TRUSTED_BUILDS_USER }} - name: Run CLI E2E tests @@ -188,13 +188,13 @@ jobs: runs-on: ubuntu-latest steps: - name: Initialize environment - uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@bf1d18837b5aaed70cf858ecd177583bf320be50 # main + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@a948cdfda182b725e3abad445b2e6264508db3ed # main - name: Install node modules run: pnpm install --frozen-lockfile - name: Setup Bazel - uses: angular/dev-infra/github-actions/bazel/setup@bf1d18837b5aaed70cf858ecd177583bf320be50 # main + uses: angular/dev-infra/github-actions/bazel/setup@a948cdfda182b725e3abad445b2e6264508db3ed # main - name: Setup Bazel RBE - uses: angular/dev-infra/github-actions/bazel/configure-remote@bf1d18837b5aaed70cf858ecd177583bf320be50 # main + uses: angular/dev-infra/github-actions/bazel/configure-remote@a948cdfda182b725e3abad445b2e6264508db3ed # main with: google_credential: ${{ secrets.RBE_TRUSTED_BUILDS_USER }} - name: Run CLI E2E tests @@ -208,13 +208,13 @@ jobs: SAUCE_TUNNEL_IDENTIFIER: angular-cli-${{ github.workflow }}-${{ github.run_number }} steps: - name: Initialize environment - uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@bf1d18837b5aaed70cf858ecd177583bf320be50 # main + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@a948cdfda182b725e3abad445b2e6264508db3ed # main - name: Install node modules run: pnpm install --frozen-lockfile - name: Setup Bazel - uses: angular/dev-infra/github-actions/bazel/setup@bf1d18837b5aaed70cf858ecd177583bf320be50 # main + uses: angular/dev-infra/github-actions/bazel/setup@a948cdfda182b725e3abad445b2e6264508db3ed # main - name: Setup Bazel RBE - uses: angular/dev-infra/github-actions/bazel/configure-remote@bf1d18837b5aaed70cf858ecd177583bf320be50 # main + uses: angular/dev-infra/github-actions/bazel/configure-remote@a948cdfda182b725e3abad445b2e6264508db3ed # main with: google_credential: ${{ secrets.RBE_TRUSTED_BUILDS_USER }} - name: Start Sauce Connect @@ -245,11 +245,11 @@ jobs: CIRCLE_BRANCH: ${{ github.ref_name }} steps: - name: Initialize environment - uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@bf1d18837b5aaed70cf858ecd177583bf320be50 # main + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@a948cdfda182b725e3abad445b2e6264508db3ed # main - name: Install node modules run: pnpm install --frozen-lockfile - name: Setup Bazel - uses: angular/dev-infra/github-actions/bazel/setup@bf1d18837b5aaed70cf858ecd177583bf320be50 # main + uses: angular/dev-infra/github-actions/bazel/setup@a948cdfda182b725e3abad445b2e6264508db3ed # main - run: pnpm admin snapshots --verbose env: SNAPSHOT_BUILDS_GITHUB_TOKEN: ${{ secrets.SNAPSHOT_BUILDS_GITHUB_TOKEN }} diff --git a/.github/workflows/dev-infra.yml b/.github/workflows/dev-infra.yml index 0f4aea85fdb0..7ac22449d1f1 100644 --- a/.github/workflows/dev-infra.yml +++ b/.github/workflows/dev-infra.yml @@ -16,21 +16,21 @@ jobs: if: github.event_name == 'pull_request_target' runs-on: ubuntu-latest steps: - - uses: angular/dev-infra/github-actions/labeling/pull-request@bf1d18837b5aaed70cf858ecd177583bf320be50 # main + - uses: angular/dev-infra/github-actions/labeling/pull-request@a948cdfda182b725e3abad445b2e6264508db3ed # main with: angular-robot-key: ${{ secrets.ANGULAR_ROBOT_PRIVATE_KEY }} post_approval_changes: if: github.event_name == 'pull_request_target' runs-on: ubuntu-latest steps: - - uses: angular/dev-infra/github-actions/post-approval-changes@bf1d18837b5aaed70cf858ecd177583bf320be50 # main + - uses: angular/dev-infra/github-actions/post-approval-changes@a948cdfda182b725e3abad445b2e6264508db3ed # main with: angular-robot-key: ${{ secrets.ANGULAR_ROBOT_PRIVATE_KEY }} issue_labels: if: github.event_name == 'issues' runs-on: ubuntu-latest steps: - - uses: angular/dev-infra/github-actions/labeling/issue@bf1d18837b5aaed70cf858ecd177583bf320be50 # main + - uses: angular/dev-infra/github-actions/labeling/issue@a948cdfda182b725e3abad445b2e6264508db3ed # main with: angular-robot-key: ${{ secrets.ANGULAR_ROBOT_PRIVATE_KEY }} google-generative-ai-key: ${{ secrets.GOOGLE_GENERATIVE_AI_KEY }} diff --git a/.github/workflows/perf.yml b/.github/workflows/perf.yml index a3170cf0add5..4ebe4ce4c1bd 100644 --- a/.github/workflows/perf.yml +++ b/.github/workflows/perf.yml @@ -22,7 +22,7 @@ jobs: workflows: ${{ steps.workflows.outputs.workflows }} steps: - name: Initialize environment - uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@bf1d18837b5aaed70cf858ecd177583bf320be50 # main + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@a948cdfda182b725e3abad445b2e6264508db3ed # main - name: Install node modules run: pnpm install --frozen-lockfile - id: workflows @@ -40,9 +40,9 @@ jobs: workflow: ${{ fromJSON(needs.list.outputs.workflows) }} steps: - name: Initialize environment - uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@bf1d18837b5aaed70cf858ecd177583bf320be50 # main + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@a948cdfda182b725e3abad445b2e6264508db3ed # main - name: Setup Bazel - uses: angular/dev-infra/github-actions/bazel/setup@bf1d18837b5aaed70cf858ecd177583bf320be50 # main + uses: angular/dev-infra/github-actions/bazel/setup@a948cdfda182b725e3abad445b2e6264508db3ed # main - name: Install node modules run: pnpm install --frozen-lockfile # We utilize the google-github-actions/auth action to allow us to get an active credential using workflow diff --git a/.github/workflows/pr.yml b/.github/workflows/pr.yml index 5d86977c77a4..ae130af4ec3d 100644 --- a/.github/workflows/pr.yml +++ b/.github/workflows/pr.yml @@ -34,9 +34,9 @@ jobs: runs-on: ubuntu-latest steps: - name: Initialize environment - uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@bf1d18837b5aaed70cf858ecd177583bf320be50 # main + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@a948cdfda182b725e3abad445b2e6264508db3ed # main - name: Setup Bazel - uses: angular/dev-infra/github-actions/bazel/setup@bf1d18837b5aaed70cf858ecd177583bf320be50 # main + uses: angular/dev-infra/github-actions/bazel/setup@a948cdfda182b725e3abad445b2e6264508db3ed # main - name: Setup ESLint Caching uses: actions/cache@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0 with: @@ -66,17 +66,17 @@ jobs: # it has been merged. run: pnpm ng-dev format changed --check ${{ github.event.pull_request.base.sha }} - name: Check Package Licenses - uses: angular/dev-infra/github-actions/linting/licenses@bf1d18837b5aaed70cf858ecd177583bf320be50 # main + uses: angular/dev-infra/github-actions/linting/licenses@a948cdfda182b725e3abad445b2e6264508db3ed # main build: runs-on: ubuntu-latest steps: - name: Initialize environment - uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@bf1d18837b5aaed70cf858ecd177583bf320be50 # main + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@a948cdfda182b725e3abad445b2e6264508db3ed # main - name: Setup Bazel - uses: angular/dev-infra/github-actions/bazel/setup@bf1d18837b5aaed70cf858ecd177583bf320be50 # main + uses: angular/dev-infra/github-actions/bazel/setup@a948cdfda182b725e3abad445b2e6264508db3ed # main - name: Setup Bazel RBE - uses: angular/dev-infra/github-actions/bazel/configure-remote@bf1d18837b5aaed70cf858ecd177583bf320be50 # main + uses: angular/dev-infra/github-actions/bazel/configure-remote@a948cdfda182b725e3abad445b2e6264508db3ed # main - name: Install node modules run: pnpm install --frozen-lockfile - name: Build release targets @@ -93,11 +93,11 @@ jobs: runs-on: ubuntu-latest steps: - name: Initialize environment - uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@bf1d18837b5aaed70cf858ecd177583bf320be50 # main + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@a948cdfda182b725e3abad445b2e6264508db3ed # main - name: Setup Bazel - uses: angular/dev-infra/github-actions/bazel/setup@bf1d18837b5aaed70cf858ecd177583bf320be50 # main + uses: angular/dev-infra/github-actions/bazel/setup@a948cdfda182b725e3abad445b2e6264508db3ed # main - name: Setup Bazel RBE - uses: angular/dev-infra/github-actions/bazel/configure-remote@bf1d18837b5aaed70cf858ecd177583bf320be50 # main + uses: angular/dev-infra/github-actions/bazel/configure-remote@a948cdfda182b725e3abad445b2e6264508db3ed # main - name: Install node modules run: pnpm install --frozen-lockfile - name: Run module and package tests @@ -114,13 +114,13 @@ jobs: runs-on: ubuntu-latest steps: - name: Initialize environment - uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@bf1d18837b5aaed70cf858ecd177583bf320be50 # main + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@a948cdfda182b725e3abad445b2e6264508db3ed # main - name: Install node modules run: pnpm install --frozen-lockfile - name: Setup Bazel - uses: angular/dev-infra/github-actions/bazel/setup@bf1d18837b5aaed70cf858ecd177583bf320be50 # main + uses: angular/dev-infra/github-actions/bazel/setup@a948cdfda182b725e3abad445b2e6264508db3ed # main - name: Setup Bazel RBE - uses: angular/dev-infra/github-actions/bazel/configure-remote@bf1d18837b5aaed70cf858ecd177583bf320be50 # main + uses: angular/dev-infra/github-actions/bazel/configure-remote@a948cdfda182b725e3abad445b2e6264508db3ed # main - name: Run CLI E2E tests run: pnpm bazel test --test_env=E2E_SHARD_TOTAL=6 --test_env=E2E_SHARD_INDEX=${{ matrix.shard }} --config=e2e //tests:e2e.${{ matrix.subset }}_node${{ matrix.node }} @@ -128,11 +128,11 @@ jobs: runs-on: ubuntu-latest steps: - name: Initialize environment - uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@bf1d18837b5aaed70cf858ecd177583bf320be50 # main + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@a948cdfda182b725e3abad445b2e6264508db3ed # main - name: Setup Bazel - uses: angular/dev-infra/github-actions/bazel/setup@bf1d18837b5aaed70cf858ecd177583bf320be50 # main + uses: angular/dev-infra/github-actions/bazel/setup@a948cdfda182b725e3abad445b2e6264508db3ed # main - name: Setup Bazel RBE - uses: angular/dev-infra/github-actions/bazel/configure-remote@bf1d18837b5aaed70cf858ecd177583bf320be50 # main + uses: angular/dev-infra/github-actions/bazel/configure-remote@a948cdfda182b725e3abad445b2e6264508db3ed # main - name: Install node modules run: pnpm install --frozen-lockfile - name: Build E2E tests for Windows on Linux @@ -156,7 +156,7 @@ jobs: runs-on: windows-2025 steps: - name: Initialize environment - uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@bf1d18837b5aaed70cf858ecd177583bf320be50 # main + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@a948cdfda182b725e3abad445b2e6264508db3ed # main - name: Install node modules run: pnpm install --frozen-lockfile - name: Download built Windows E2E tests @@ -183,13 +183,13 @@ jobs: runs-on: ubuntu-latest steps: - name: Initialize environment - uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@bf1d18837b5aaed70cf858ecd177583bf320be50 # main + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@a948cdfda182b725e3abad445b2e6264508db3ed # main - name: Install node modules run: pnpm install --frozen-lockfile - name: Setup Bazel - uses: angular/dev-infra/github-actions/bazel/setup@bf1d18837b5aaed70cf858ecd177583bf320be50 # main + uses: angular/dev-infra/github-actions/bazel/setup@a948cdfda182b725e3abad445b2e6264508db3ed # main - name: Setup Bazel RBE - uses: angular/dev-infra/github-actions/bazel/configure-remote@bf1d18837b5aaed70cf858ecd177583bf320be50 # main + uses: angular/dev-infra/github-actions/bazel/configure-remote@a948cdfda182b725e3abad445b2e6264508db3ed # main - name: Run CLI E2E tests run: pnpm bazel test --test_env=E2E_SHARD_TOTAL=3 --test_env=E2E_SHARD_INDEX=${{ matrix.shard }} --config=e2e //tests:e2e.${{ matrix.subset }}_node${{ matrix.node }} @@ -205,12 +205,12 @@ jobs: runs-on: ubuntu-latest steps: - name: Initialize environment - uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@bf1d18837b5aaed70cf858ecd177583bf320be50 # main + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@a948cdfda182b725e3abad445b2e6264508db3ed # main - name: Install node modules run: pnpm install --frozen-lockfile - name: Setup Bazel - uses: angular/dev-infra/github-actions/bazel/setup@bf1d18837b5aaed70cf858ecd177583bf320be50 # main + uses: angular/dev-infra/github-actions/bazel/setup@a948cdfda182b725e3abad445b2e6264508db3ed # main - name: Setup Bazel RBE - uses: angular/dev-infra/github-actions/bazel/configure-remote@bf1d18837b5aaed70cf858ecd177583bf320be50 # main + uses: angular/dev-infra/github-actions/bazel/configure-remote@a948cdfda182b725e3abad445b2e6264508db3ed # main - name: Run CLI E2E tests run: pnpm bazel test --test_env=E2E_SHARD_TOTAL=6 --test_env=E2E_SHARD_INDEX=${{ matrix.shard }} --config=e2e //tests:e2e.snapshots.${{ matrix.subset }}_node${{ matrix.node }} diff --git a/MODULE.bazel b/MODULE.bazel index 5e0096477618..53a88fa03302 100644 --- a/MODULE.bazel +++ b/MODULE.bazel @@ -19,21 +19,21 @@ bazel_dep(name = "aspect_rules_jasmine", version = "2.0.4") bazel_dep(name = "rules_angular") git_override( module_name = "rules_angular", - commit = "6468bfd6c2f90b7a025d86273b070d0dd0a443db", + commit = "c40fd63ad915b6c159a7eba93079757024ad2844", remote = "https://github.com/angular/rules_angular.git", ) bazel_dep(name = "devinfra") git_override( module_name = "devinfra", - commit = "bf1d18837b5aaed70cf858ecd177583bf320be50", + commit = "a948cdfda182b725e3abad445b2e6264508db3ed", remote = "https://github.com/angular/dev-infra.git", ) bazel_dep(name = "rules_browsers") git_override( module_name = "rules_browsers", - commit = "ba55f13997d951c9ac02192cf6d1cadad03c1237", + commit = "a73e3fb4819202ed84bad97e19039e7591b7e87a", remote = "https://github.com/angular/rules_browsers.git", ) diff --git a/modules/testing/builder/package.json b/modules/testing/builder/package.json index 526ac8aeb667..2bdc775b10e4 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", + "ng-packagr": "22.2.1", "rxjs": "7.8.2", "vitest": "5.0.1" } diff --git a/package.json b/package.json index f0d81e359c5c..7e1d00da374f 100644 --- a/package.json +++ b/package.json @@ -55,7 +55,7 @@ "@angular/forms": "22.2.0", "@angular/localize": "22.2.0", "@angular/material": "22.2.0", - "@angular/ng-dev": "https://github.com/angular/dev-infra-private-ng-dev-builds.git#90a76327155df50e90a41fe76aed67b98a9cf954", + "@angular/ng-dev": "https://github.com/angular/dev-infra-private-ng-dev-builds.git#df3931fca45cce0a2fa74c9ccc5876c571ef8406", "@angular/platform-browser": "22.2.0", "@angular/platform-server": "22.2.0", "@angular/router": "22.2.0", diff --git a/packages/angular/build/package.json b/packages/angular/build/package.json index 351f7640a86e..ec4e96473ca7 100644 --- a/packages/angular/build/package.json +++ b/packages/angular/build/package.json @@ -57,7 +57,7 @@ "istanbul-lib-instrument": "6.0.3", "jsdom": "30.0.1", "less": "4.9.1", - "ng-packagr": "22.2.0", + "ng-packagr": "22.2.1", "postcss": "8.5.28", "rollup": "4.63.3", "rxjs": "7.8.2", diff --git a/packages/angular_devkit/build_angular/package.json b/packages/angular_devkit/build_angular/package.json index 1d138f78dffc..1bb9df82d305 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", + "ng-packagr": "22.2.1", "sass": "1.104.1", "undici": "8.10.2" }, diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index c749e2d115d5..23a16236261d 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -208,8 +208,8 @@ importers: specifier: 22.2.0 version: 22.2.0(40004d7e10fb4ba9a3893f0ca483936a) '@angular/ng-dev': - specifier: https://github.com/angular/dev-infra-private-ng-dev-builds.git#90a76327155df50e90a41fe76aed67b98a9cf954 - version: https://codeload.github.com/angular/dev-infra-private-ng-dev-builds/tar.gz/90a76327155df50e90a41fe76aed67b98a9cf954 + specifier: https://github.com/angular/dev-infra-private-ng-dev-builds.git#df3931fca45cce0a2fa74c9ccc5876c571ef8406 + version: https://codeload.github.com/angular/dev-infra-private-ng-dev-builds/tar.gz/df3931fca45cce0a2fa74c9ccc5876c571ef8406 '@angular/platform-browser': specifier: 22.2.0 version: 22.2.0(@angular/animations@22.2.0(@angular/core@22.2.0(@angular/compiler@22.2.0)(rxjs@7.8.2)(zone.js@0.16.3)))(@angular/common@22.2.0(@angular/core@22.2.0(@angular/compiler@22.2.0)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2))(@angular/core@22.2.0(@angular/compiler@22.2.0)(rxjs@7.8.2)(zone.js@0.16.3)) @@ -463,8 +463,8 @@ importers: specifier: 30.0.1 version: 30.0.1(@noble/hashes@1.8.0) ng-packagr: - specifier: 22.2.0 - version: 22.2.0(@angular/compiler-cli@22.2.0(@angular/compiler@22.2.0)(typescript@6.0.3))(supports-color@11.0.0)(tslib@2.8.1)(typescript@6.0.3) + specifier: 22.2.1 + version: 22.2.1(@angular/compiler-cli@22.2.0(@angular/compiler@22.2.0)(typescript@6.0.3))(supports-color@11.0.0)(tslib@2.8.1)(typescript@6.0.3) rxjs: specifier: 7.8.2 version: 7.8.2 @@ -578,8 +578,8 @@ importers: specifier: 4.9.1 version: 4.9.1(supports-color@11.0.0) ng-packagr: - specifier: 22.2.0 - version: 22.2.0(@angular/compiler-cli@22.2.0(@angular/compiler@22.2.0)(typescript@6.0.3))(supports-color@11.0.0)(tslib@2.8.1)(typescript@6.0.3) + specifier: 22.2.1 + version: 22.2.1(@angular/compiler-cli@22.2.0(@angular/compiler@22.2.0)(typescript@6.0.3))(supports-color@11.0.0)(tslib@2.8.1)(typescript@6.0.3) postcss: specifier: 8.5.28 version: 8.5.28 @@ -866,8 +866,8 @@ importers: specifier: 3.0.4 version: 3.0.4(bufferutil@4.1.0)(debug@4.4.3(supports-color@11.0.0))(supports-color@11.0.0)(utf-8-validate@6.0.6) ng-packagr: - specifier: 22.2.0 - version: 22.2.0(@angular/compiler-cli@22.2.0(@angular/compiler@22.2.0)(typescript@6.0.3))(supports-color@11.0.0)(tslib@2.8.1)(typescript@6.0.3) + specifier: 22.2.1 + version: 22.2.1(@angular/compiler-cli@22.2.0(@angular/compiler@22.2.0)(typescript@6.0.3))(supports-color@11.0.0)(tslib@2.8.1)(typescript@6.0.3) sass: specifier: 1.104.1 version: 1.104.1 @@ -1103,9 +1103,9 @@ packages: '@angular/platform-browser': ^22.0.0 || ^23.0.0 rxjs: ^6.5.3 || ^7.4.0 - '@angular/ng-dev@https://codeload.github.com/angular/dev-infra-private-ng-dev-builds/tar.gz/90a76327155df50e90a41fe76aed67b98a9cf954': - resolution: {gitHosted: true, integrity: sha512-VmtUf+oZIHjATMGTjURjB3gJJ72gPo4nCDWEDUtW3MqgLPl088ISDgnV9CPXEt62EbByn9+0vVULCCk4p8YcVg==, tarball: https://codeload.github.com/angular/dev-infra-private-ng-dev-builds/tar.gz/90a76327155df50e90a41fe76aed67b98a9cf954} - version: 0.0.0-20b69d39859eae19d7ac04b6f1902f73286f7686 + '@angular/ng-dev@https://codeload.github.com/angular/dev-infra-private-ng-dev-builds/tar.gz/df3931fca45cce0a2fa74c9ccc5876c571ef8406': + resolution: {gitHosted: true, integrity: sha512-tyRa8ookiGkLtXBEOK9KSOkp+OgCOKhK7WW0Sv9RYeZZ0fqQHZrYvW+M9v2xBE3TNi/rD3iHXqkH6I5prls10Q==, tarball: https://codeload.github.com/angular/dev-infra-private-ng-dev-builds/tar.gz/df3931fca45cce0a2fa74c9ccc5876c571ef8406} + version: 0.0.0-a98a0a6d48067af7768f4dded0c4f159af687e2b hasBin: true '@angular/platform-browser@22.2.0': @@ -2283,8 +2283,8 @@ packages: resolution: {integrity: sha512-IJn+8A3QZJfe7FUtWqHVNo3xJs7KFpurCWGWCiCz3oEh+BkRymKZ1QxfAbU2yGMDzTytLGQ2IV6T2r3cuo75/w==} engines: {node: '>=18'} - '@google/genai@2.22.0': - resolution: {integrity: sha512-NE90Nl0AP75YZ2tGxXjQQs6Gkunma7a1JmPCx5g5CxvjHXshmuI2aNoPJ1xLrRixjkNxog898oylM+MyNudUQw==} + '@google/genai@2.24.0': + resolution: {integrity: sha512-bIu5eoxF1AaPWs9ivmUJGp1RpDHyapoODvWvnkzRDx2CTIW6UJXFhDdjj0BlRve3ZHMMuEkQBVrA/ALqpW4apA==} engines: {node: '>=20.0.0'} peerDependencies: '@modelcontextprotocol/sdk': ^1.25.2 @@ -3715,8 +3715,8 @@ packages: '@types/node@22.20.4': resolution: {integrity: sha512-zJRE40jpHtKqE/C4fgHrAKQLJuSpzEnP9ff9Y7YtoR3Wd2pwqzlekDeEuUQXjRd+QCYnVnNwuJYmhdk9XV8gvA==} - '@types/node@24.13.5': - resolution: {integrity: sha512-TXyindR+lBr22aJIdMQzCFHPHR6cR4js838mRDCSz5hOKWZvZwsXSSiXDmjRj4iJmgl+sR9O+1mkoVBSMadNug==} + '@types/node@24.13.6': + resolution: {integrity: sha512-SGrw/h3KPFshy3OE6ZL53LMBG5vGQQ8/gIpiqz/kRZhPJ7HgwCEs8LBuNtWLa8dvGZVpSF7+Bf+c11HUrCb/yg==} '@types/npm-package-arg@6.1.4': resolution: {integrity: sha512-vDgdbMy2QXHnAruzlv68pUtXCjmqUk3WrBAsRboRovsOmxbfn/WiYCjmecyKjGztnMps5dWp4Uq2prp+Ilo17Q==} @@ -6734,12 +6734,12 @@ packages: neo-async@2.6.2: resolution: {integrity: sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==} - ng-packagr@22.2.0: - resolution: {integrity: sha512-VsH3X8R3E24yX6h/atwke1ytWB/lt8AShbbKA6cRZLrwLf07N5eQF1kV4XrPqabiPWUCJNSU0zvnSkdjXAo7Zw==} + ng-packagr@22.2.1: + resolution: {integrity: sha512-dp9/HZdELB8LVzAQxK2ruBNVU4O6wDwX0tdpGJoyYRm7I0umStgVhxFqq9KLKKD0cxTTJGBubK8aAnHCQSRT2A==} engines: {node: ^22.22.3 || ^24.15.0 || >=26.0.0} hasBin: true peerDependencies: - '@angular/compiler-cli': ^22.0.0 || ^22.3.0-next + '@angular/compiler-cli': ^22.0.0 || ^22.2.0-next || ^22.3.0-next tailwindcss: ^2.0.0 || ^3.0.0 || ^4.0.0 tslib: ^2.3.0 typescript: '>=6.0 <6.1' @@ -8076,6 +8076,11 @@ packages: engines: {node: '>=18.0.0'} hasBin: true + tsx@4.23.15: + resolution: {integrity: sha512-Yiex1Ovn8z2xPpOWckIiysV1SSyRMY9BkLF++q0yKiDxCqRhosKfMg3janKkiLBwZ5c/YryloKwGZcrEmtwxKw==} + engines: {node: '>=18.0.0'} + hasBin: true + tsyringe@4.10.0: resolution: {integrity: sha512-axr3IdNuVIxnaK5XGEUFTu3YmAQ6lllgrvqfEoR16g/HGnYY/6We4oWENtAnzK6/LpJ2ur9PAb80RBt7/U4ugw==} engines: {node: '>= 6.0.0'} @@ -8606,6 +8611,10 @@ packages: resolution: {integrity: sha512-2rAgRKu54VsHkqI0/tYkmluGXHD4KW7yZoycuqDQ15QOTnc2VVfy0nN/1eMhnQLO00A+dwtK20xuCnc1YGeUyg==} engines: {node: ^20.19.0 || ^22.12.0 || >=23} + yargs@18.2.0: + resolution: {integrity: sha512-9OpKOLeaoNFecEp7P6iYbzze/5CqWoH7N3SMs/6y1XF4nMvFMspEGZzJ6uFi9MmQwXhyzqYoSEKO3tvA3Z/o2w==} + engines: {node: ^20.19.0 || ^22.12.0 || >=23} + yocto-queue@0.1.0: resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==} engines: {node: '>=10'} @@ -8730,14 +8739,14 @@ snapshots: rxjs: 7.8.2 tslib: 2.8.1 - '@angular/ng-dev@https://codeload.github.com/angular/dev-infra-private-ng-dev-builds/tar.gz/90a76327155df50e90a41fe76aed67b98a9cf954': + '@angular/ng-dev@https://codeload.github.com/angular/dev-infra-private-ng-dev-builds/tar.gz/df3931fca45cce0a2fa74c9ccc5876c571ef8406': dependencies: '@actions/core': 3.0.1 '@conventional-changelog/git-client': 3.1.2(conventional-commits-filter@6.0.1)(conventional-commits-parser@7.1.2) '@google-cloud/spanner': 8.0.0(supports-color@11.0.0) - '@google/genai': 2.22.0(bufferutil@4.1.0)(supports-color@11.0.0)(utf-8-validate@6.0.6) - '@inquirer/prompts': 8.7.2(@types/node@24.13.5) - '@inquirer/type': 4.1.1(@types/node@24.13.5) + '@google/genai': 2.24.0(bufferutil@4.1.0)(supports-color@11.0.0)(utf-8-validate@6.0.6) + '@inquirer/prompts': 8.7.2(@types/node@24.13.6) + '@inquirer/type': 4.1.1(@types/node@24.13.6) '@octokit/auth-app': 8.3.1 '@octokit/core': 7.0.8 '@octokit/graphql': 9.0.5 @@ -8753,7 +8762,7 @@ snapshots: '@types/events': 3.0.3 '@types/folder-hash': 4.0.4 '@types/jasmine': 6.0.0 - '@types/node': 24.13.5 + '@types/node': 24.13.6 '@types/semver': 7.8.0 '@types/which': 3.0.4 '@types/yargs': 17.0.35 @@ -8777,13 +8786,13 @@ snapshots: nock: 14.0.17 semver: 7.8.5 supports-color: 11.0.0 - tsx: 4.23.13 + tsx: 4.23.15 typed-graphqlify: 3.1.6 typescript: 6.0.3 utf-8-validate: 6.0.6 which: 7.0.0 yaml: 2.9.1 - yargs: 18.1.0 + yargs: 18.2.0 zod: 4.6.5 transitivePeerDependencies: - '@modelcontextprotocol/sdk' @@ -10135,7 +10144,7 @@ snapshots: transitivePeerDependencies: - supports-color - '@google/genai@2.22.0(bufferutil@4.1.0)(supports-color@11.0.0)(utf-8-validate@6.0.6)': + '@google/genai@2.24.0(bufferutil@4.1.0)(supports-color@11.0.0)(utf-8-validate@6.0.6)': dependencies: google-auth-library: 10.9.1(supports-color@11.0.0) p-retry: 4.6.2 @@ -10200,14 +10209,14 @@ snapshots: optionalDependencies: '@types/node': 22.20.4 - '@inquirer/checkbox@5.2.5(@types/node@24.13.5)': + '@inquirer/checkbox@5.2.5(@types/node@24.13.6)': dependencies: '@inquirer/ansi': 2.0.8 - '@inquirer/core': 12.0.3(@types/node@24.13.5) + '@inquirer/core': 12.0.3(@types/node@24.13.6) '@inquirer/figures': 2.0.9 - '@inquirer/type': 4.1.1(@types/node@24.13.5) + '@inquirer/type': 4.1.1(@types/node@24.13.6) optionalDependencies: - '@types/node': 24.13.5 + '@types/node': 24.13.6 '@inquirer/confirm@6.3.2(@types/node@22.20.4)': dependencies: @@ -10216,12 +10225,12 @@ snapshots: optionalDependencies: '@types/node': 22.20.4 - '@inquirer/confirm@6.3.2(@types/node@24.13.5)': + '@inquirer/confirm@6.3.2(@types/node@24.13.6)': dependencies: - '@inquirer/core': 12.0.3(@types/node@24.13.5) - '@inquirer/type': 4.1.1(@types/node@24.13.5) + '@inquirer/core': 12.0.3(@types/node@24.13.6) + '@inquirer/type': 4.1.1(@types/node@24.13.6) optionalDependencies: - '@types/node': 24.13.5 + '@types/node': 24.13.6 '@inquirer/core@12.0.3(@types/node@22.20.4)': dependencies: @@ -10235,17 +10244,17 @@ snapshots: optionalDependencies: '@types/node': 22.20.4 - '@inquirer/core@12.0.3(@types/node@24.13.5)': + '@inquirer/core@12.0.3(@types/node@24.13.6)': dependencies: '@inquirer/ansi': 2.0.8 '@inquirer/figures': 2.0.9 - '@inquirer/type': 4.1.1(@types/node@24.13.5) + '@inquirer/type': 4.1.1(@types/node@24.13.6) cli-width: 4.1.0 fast-wrap-ansi: 0.2.2 mute-stream: 3.0.0 signal-exit: 4.1.0 optionalDependencies: - '@types/node': 24.13.5 + '@types/node': 24.13.6 '@inquirer/editor@5.3.3(@types/node@22.20.4)': dependencies: @@ -10255,13 +10264,13 @@ snapshots: optionalDependencies: '@types/node': 22.20.4 - '@inquirer/editor@5.3.3(@types/node@24.13.5)': + '@inquirer/editor@5.3.3(@types/node@24.13.6)': dependencies: - '@inquirer/core': 12.0.3(@types/node@24.13.5) - '@inquirer/external-editor': 3.0.5(@types/node@24.13.5) - '@inquirer/type': 4.1.1(@types/node@24.13.5) + '@inquirer/core': 12.0.3(@types/node@24.13.6) + '@inquirer/external-editor': 3.0.5(@types/node@24.13.6) + '@inquirer/type': 4.1.1(@types/node@24.13.6) optionalDependencies: - '@types/node': 24.13.5 + '@types/node': 24.13.6 '@inquirer/expand@5.1.5(@types/node@22.20.4)': dependencies: @@ -10270,12 +10279,12 @@ snapshots: optionalDependencies: '@types/node': 22.20.4 - '@inquirer/expand@5.1.5(@types/node@24.13.5)': + '@inquirer/expand@5.1.5(@types/node@24.13.6)': dependencies: - '@inquirer/core': 12.0.3(@types/node@24.13.5) - '@inquirer/type': 4.1.1(@types/node@24.13.5) + '@inquirer/core': 12.0.3(@types/node@24.13.6) + '@inquirer/type': 4.1.1(@types/node@24.13.6) optionalDependencies: - '@types/node': 24.13.5 + '@types/node': 24.13.6 '@inquirer/external-editor@3.0.5(@types/node@22.20.4)': dependencies: @@ -10284,12 +10293,12 @@ snapshots: optionalDependencies: '@types/node': 22.20.4 - '@inquirer/external-editor@3.0.5(@types/node@24.13.5)': + '@inquirer/external-editor@3.0.5(@types/node@24.13.6)': dependencies: chardet: 2.2.0 iconv-lite: 0.7.3 optionalDependencies: - '@types/node': 24.13.5 + '@types/node': 24.13.6 '@inquirer/figures@2.0.9': {} @@ -10300,12 +10309,12 @@ snapshots: optionalDependencies: '@types/node': 22.20.4 - '@inquirer/input@5.1.6(@types/node@24.13.5)': + '@inquirer/input@5.1.6(@types/node@24.13.6)': dependencies: - '@inquirer/core': 12.0.3(@types/node@24.13.5) - '@inquirer/type': 4.1.1(@types/node@24.13.5) + '@inquirer/core': 12.0.3(@types/node@24.13.6) + '@inquirer/type': 4.1.1(@types/node@24.13.6) optionalDependencies: - '@types/node': 24.13.5 + '@types/node': 24.13.6 '@inquirer/number@4.2.3(@types/node@22.20.4)': dependencies: @@ -10314,12 +10323,12 @@ snapshots: optionalDependencies: '@types/node': 22.20.4 - '@inquirer/number@4.2.3(@types/node@24.13.5)': + '@inquirer/number@4.2.3(@types/node@24.13.6)': dependencies: - '@inquirer/core': 12.0.3(@types/node@24.13.5) - '@inquirer/type': 4.1.1(@types/node@24.13.5) + '@inquirer/core': 12.0.3(@types/node@24.13.6) + '@inquirer/type': 4.1.1(@types/node@24.13.6) optionalDependencies: - '@types/node': 24.13.5 + '@types/node': 24.13.6 '@inquirer/password@5.2.2(@types/node@22.20.4)': dependencies: @@ -10329,13 +10338,13 @@ snapshots: optionalDependencies: '@types/node': 22.20.4 - '@inquirer/password@5.2.2(@types/node@24.13.5)': + '@inquirer/password@5.2.2(@types/node@24.13.6)': dependencies: '@inquirer/ansi': 2.0.8 - '@inquirer/core': 12.0.3(@types/node@24.13.5) - '@inquirer/type': 4.1.1(@types/node@24.13.5) + '@inquirer/core': 12.0.3(@types/node@24.13.6) + '@inquirer/type': 4.1.1(@types/node@24.13.6) optionalDependencies: - '@types/node': 24.13.5 + '@types/node': 24.13.6 '@inquirer/prompts@8.7.2(@types/node@22.20.4)': dependencies: @@ -10352,20 +10361,20 @@ snapshots: optionalDependencies: '@types/node': 22.20.4 - '@inquirer/prompts@8.7.2(@types/node@24.13.5)': - dependencies: - '@inquirer/checkbox': 5.2.5(@types/node@24.13.5) - '@inquirer/confirm': 6.3.2(@types/node@24.13.5) - '@inquirer/editor': 5.3.3(@types/node@24.13.5) - '@inquirer/expand': 5.1.5(@types/node@24.13.5) - '@inquirer/input': 5.1.6(@types/node@24.13.5) - '@inquirer/number': 4.2.3(@types/node@24.13.5) - '@inquirer/password': 5.2.2(@types/node@24.13.5) - '@inquirer/rawlist': 5.3.5(@types/node@24.13.5) - '@inquirer/search': 4.3.3(@types/node@24.13.5) - '@inquirer/select': 5.2.5(@types/node@24.13.5) + '@inquirer/prompts@8.7.2(@types/node@24.13.6)': + dependencies: + '@inquirer/checkbox': 5.2.5(@types/node@24.13.6) + '@inquirer/confirm': 6.3.2(@types/node@24.13.6) + '@inquirer/editor': 5.3.3(@types/node@24.13.6) + '@inquirer/expand': 5.1.5(@types/node@24.13.6) + '@inquirer/input': 5.1.6(@types/node@24.13.6) + '@inquirer/number': 4.2.3(@types/node@24.13.6) + '@inquirer/password': 5.2.2(@types/node@24.13.6) + '@inquirer/rawlist': 5.3.5(@types/node@24.13.6) + '@inquirer/search': 4.3.3(@types/node@24.13.6) + '@inquirer/select': 5.2.5(@types/node@24.13.6) optionalDependencies: - '@types/node': 24.13.5 + '@types/node': 24.13.6 '@inquirer/rawlist@5.3.5(@types/node@22.20.4)': dependencies: @@ -10374,12 +10383,12 @@ snapshots: optionalDependencies: '@types/node': 22.20.4 - '@inquirer/rawlist@5.3.5(@types/node@24.13.5)': + '@inquirer/rawlist@5.3.5(@types/node@24.13.6)': dependencies: - '@inquirer/core': 12.0.3(@types/node@24.13.5) - '@inquirer/type': 4.1.1(@types/node@24.13.5) + '@inquirer/core': 12.0.3(@types/node@24.13.6) + '@inquirer/type': 4.1.1(@types/node@24.13.6) optionalDependencies: - '@types/node': 24.13.5 + '@types/node': 24.13.6 '@inquirer/search@4.3.3(@types/node@22.20.4)': dependencies: @@ -10389,13 +10398,13 @@ snapshots: optionalDependencies: '@types/node': 22.20.4 - '@inquirer/search@4.3.3(@types/node@24.13.5)': + '@inquirer/search@4.3.3(@types/node@24.13.6)': dependencies: - '@inquirer/core': 12.0.3(@types/node@24.13.5) + '@inquirer/core': 12.0.3(@types/node@24.13.6) '@inquirer/figures': 2.0.9 - '@inquirer/type': 4.1.1(@types/node@24.13.5) + '@inquirer/type': 4.1.1(@types/node@24.13.6) optionalDependencies: - '@types/node': 24.13.5 + '@types/node': 24.13.6 '@inquirer/select@5.2.5(@types/node@22.20.4)': dependencies: @@ -10406,22 +10415,22 @@ snapshots: optionalDependencies: '@types/node': 22.20.4 - '@inquirer/select@5.2.5(@types/node@24.13.5)': + '@inquirer/select@5.2.5(@types/node@24.13.6)': dependencies: '@inquirer/ansi': 2.0.8 - '@inquirer/core': 12.0.3(@types/node@24.13.5) + '@inquirer/core': 12.0.3(@types/node@24.13.6) '@inquirer/figures': 2.0.9 - '@inquirer/type': 4.1.1(@types/node@24.13.5) + '@inquirer/type': 4.1.1(@types/node@24.13.6) optionalDependencies: - '@types/node': 24.13.5 + '@types/node': 24.13.6 '@inquirer/type@4.1.1(@types/node@22.20.4)': optionalDependencies: '@types/node': 22.20.4 - '@inquirer/type@4.1.1(@types/node@24.13.5)': + '@inquirer/type@4.1.1(@types/node@24.13.6)': optionalDependencies: - '@types/node': 24.13.5 + '@types/node': 24.13.6 '@isaacs/cliui@8.0.2': dependencies: @@ -11504,7 +11513,7 @@ snapshots: dependencies: undici-types: 6.21.0 - '@types/node@24.13.5': + '@types/node@24.13.6': dependencies: undici-types: 7.18.2 @@ -14913,7 +14922,7 @@ snapshots: neo-async@2.6.2: {} - ng-packagr@22.2.0(@angular/compiler-cli@22.2.0(@angular/compiler@22.2.0)(typescript@6.0.3))(supports-color@11.0.0)(tslib@2.8.1)(typescript@6.0.3): + ng-packagr@22.2.1(@angular/compiler-cli@22.2.0(@angular/compiler@22.2.0)(typescript@6.0.3))(supports-color@11.0.0)(tslib@2.8.1)(typescript@6.0.3): dependencies: '@ampproject/remapping': 2.3.0 '@angular/compiler-cli': 22.2.0(@angular/compiler@22.2.0)(typescript@6.0.3) @@ -16461,6 +16470,13 @@ snapshots: esbuild: 0.28.2 optionalDependencies: fsevents: 2.3.3 + optional: true + + tsx@4.23.15: + dependencies: + esbuild: 0.28.2 + optionalDependencies: + fsevents: 2.3.3 tsyringe@4.10.0: dependencies: @@ -17040,6 +17056,15 @@ snapshots: y18n: 5.0.8 yargs-parser: 22.0.0 + yargs@18.2.0: + dependencies: + cliui: 9.0.1 + escalade: 3.2.0 + get-caller-file: 2.0.5 + string-width: 8.2.2 + y18n: 5.0.8 + yargs-parser: 22.0.0 + yocto-queue@0.1.0: {} yoctocolors@2.2.0: {} From fe5dd6cfb98d9240cc1fe4aceb11c98282e6b322 Mon Sep 17 00:00:00 2001 From: Angular Robot Date: Thu, 24 Sep 2026 06:48:35 +0000 Subject: [PATCH 025/233] build: update pnpm to v12.6.0 See associated pull request for more information. --- MODULE.bazel | 4 +- package.json | 4 +- pnpm-lock.yaml | 122 ++++++++++++++++++++++++------------------------- 3 files changed, 65 insertions(+), 65 deletions(-) diff --git a/MODULE.bazel b/MODULE.bazel index 53a88fa03302..1177072ae1c4 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 = "12.3.4", - pnpm_version_integrity = "sha512-lhqkH7B32joEpEHZ+OFevAyW2o73ELLrZ7+e58sGEOq9SPH9hfUc/+c4RnhfoPh8VqOocqHYk/hEZ0G1zORUVw==", + pnpm_version = "12.6.0", + pnpm_version_integrity = "sha512-PvaPlRyxEawgS0paFvCy3fDaVqluBBPoHYVdnwtV75JnFHCQKOHNAMQFwsX7e56OxNxGd3yAXQNzwvL/AP0g7A==", ) use_repo(pnpm, "pnpm") diff --git a/package.json b/package.json index 7e1d00da374f..48f21b7a5cdc 100644 --- a/package.json +++ b/package.json @@ -29,12 +29,12 @@ "type": "git", "url": "git+https://github.com/angular/angular-cli.git" }, - "packageManager": "pnpm@12.4.2", + "packageManager": "pnpm@12.6.0", "engines": { "node": "^22.22.3 || ^24.15.0 || >=26.0.0", "npm": "Please use pnpm instead of NPM to install dependencies", "yarn": "Please use pnpm instead of Yarn to install dependencies", - "pnpm": "12.4.2" + "pnpm": "12.6.0" }, "author": "Angular Authors", "license": "MIT", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 23a16236261d..9d97b790f9c1 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -7,153 +7,153 @@ importers: configDependencies: {} packageManagerDependencies: pnpm: - specifier: 12.4.2 - version: 12.4.2 + specifier: 12.6.0 + version: 12.6.0 packages: - '@pnpm/exe.android-arm64@12.4.2': - resolution: {integrity: sha512-E255MbcQ0V1577M2BV0ajWuP7KmTPYA0jqZnk3rK6Lq3kTvZWulMMb7iqRmnLsQbyWTkMEB2CfyM70loVDA8xg==} + '@pnpm/exe.android-arm64@12.6.0': + resolution: {integrity: sha512-kviIHft9h02q+7N2In7tSL9T/HRUSGwYmU74YPtsWU5ee7vgqPyC0JT6RRX6miW+NxX1CvHgQxg69qq1qTLJYQ==} cpu: [arm64] os: [android] - '@pnpm/exe.android-x64@12.4.2': - resolution: {integrity: sha512-J1pSeCUwuKxMG70ZzpWn8JzElxiEa8NN/3N0SlZRtU2xbztChaJCKF3HaBNIj9yPfeofWzJo/lwNvDDjraQuZw==} + '@pnpm/exe.android-x64@12.6.0': + resolution: {integrity: sha512-CT8aJKLq2mtZFE71pr4E5Z2xHL8uGnRGr+NclDqsXlVF4SVcQ2QAs14mWi0C8gjT4hbmi+Q0lJRRIkMAWfjjng==} cpu: [x64] os: [android] - '@pnpm/exe.darwin-arm64@12.4.2': - resolution: {integrity: sha512-A0WDo8iErfZBXgrLseQxw8i8Y9ctUpOEl/Uu+cubnTzpD8tT9ykIB548L8YTM2WD4OS+ZOHSxy8aGZcvKq8PaQ==} + '@pnpm/exe.darwin-arm64@12.6.0': + resolution: {integrity: sha512-rafpVkjzugKBMxSvGQd5wK1x5eOTkD/+lcJIFHeQhvd+BJ8kDisOOvwhQDrpGd4vd2Fx+hhW0P2Ptt638OlhFg==} cpu: [arm64] os: [darwin] - '@pnpm/exe.darwin-x64@12.4.2': - resolution: {integrity: sha512-MSgJdovBWHcb5DEOvfPH9yNi/T5O1Xa4ess+E1ESGo/5yuty7S4JoiIjami+fsNXfnoQMlwsMUqYU4zAvBcNCw==} + '@pnpm/exe.darwin-x64@12.6.0': + resolution: {integrity: sha512-72Jpuv1m24gI8zUNcaylYpBWEhBzz1VPhnDIU2GYM2eRP+KsOqVLwV78i+JrihI39zY2NNXmaN4eAKX1inpaDQ==} cpu: [x64] os: [darwin] - '@pnpm/exe.freebsd-x64@12.4.2': - resolution: {integrity: sha512-h2YumlQSNvgbRPv+RXwABohX65f9bOBZn+jMIt7bFDISZPCzQ+Nvpt6Awbp4ip5PwQgYxbu5iREJ1fHE39Fm8A==} + '@pnpm/exe.freebsd-x64@12.6.0': + resolution: {integrity: sha512-LON4QgNy1w/XF4uySZIyC/5hEB0oGdelXsY9tSKqstER+2j2X2oHz67skD11RRd/HWFRtMr64shQZ4I9ZoZ0zg==} cpu: [x64] os: [freebsd] - '@pnpm/exe.linux-arm64-musl@12.4.2': - resolution: {integrity: sha512-LwSEtSEDTv6S51YLs3YvSkPyun/QmfMic1UGICUkPWFu6ByP43RdMlkKvmVkfGhAYCpnxO057vrmyJqtfZrPCA==} + '@pnpm/exe.linux-arm64-musl@12.6.0': + resolution: {integrity: sha512-BdDpX+DeaMUc5x6WNcE6FkmFy36NwrBbBvwsZU737Zt3u1fTY+iKFPchjEQNCM4rT6q6xvF2oN3ZwExGsJCkxQ==} cpu: [arm64] os: [linux] libc: [musl] - '@pnpm/exe.linux-arm64@12.4.2': - resolution: {integrity: sha512-2dSiDXyhx+RTHsewxex8f/jVjqQXWJ2oow4kCVHEWdZKeBpgMxvZ6fHkTAUBJXgqhbKIDHvuNlZBP7gJfUWL5A==} + '@pnpm/exe.linux-arm64@12.6.0': + resolution: {integrity: sha512-8h2sNoIhHDpHDYqZZCh9PXr6krqW10btb0GHVGuw710muDHlFAHMtUG2ogmaHge6zJG1xgY4Y7mwX5g/LWvrYg==} cpu: [arm64] os: [linux] libc: [glibc] - '@pnpm/exe.linux-ppc64@12.4.2': - resolution: {integrity: sha512-8Itc+jQk+MTz04LS9D1RcH+VctAWmzM4l1cJQ+Sx7pAJNo7EKHdRMbC0Tok1jyQ7eEHNJZD5EleYneZqWfZM+g==} + '@pnpm/exe.linux-ppc64@12.6.0': + resolution: {integrity: sha512-ld6xgcEhFCFrsVsJhbmdmR714PnsEspO/Ij8w0/D7OSiz2hYGu3fZd5tKRxOI5m6H6Gl0/RRFAPncTHbsgXVjQ==} cpu: [ppc64] os: [linux] libc: [glibc] - '@pnpm/exe.linux-riscv64@12.4.2': - resolution: {integrity: sha512-hleOeqhTVpH+z9RVMGnxvU4ZnrkBUClWjCbHD9u6kwyqhGSpevoU1wTGish+CBRhmIgMAy9pAfFpqhbAKOKNfw==} + '@pnpm/exe.linux-riscv64@12.6.0': + resolution: {integrity: sha512-HIbImydoC3J8NFt+8MXfhTCf5rO6NjCMyinSAHac0VmV8uCHw+kbQkyAzxV84rzz9ZOzmBOnj0b1N461UIYGsw==} cpu: [riscv64] os: [linux] libc: [glibc] - '@pnpm/exe.linux-s390x@12.4.2': - resolution: {integrity: sha512-LAsQRRdP9aToENR6dtcIJ9l+e1zMYOX0tQcLGpRyLPVBQcYRLlvAPcmDshsiIHQjp05SDa9FI0czX1ZQ1a7a/A==} + '@pnpm/exe.linux-s390x@12.6.0': + resolution: {integrity: sha512-DjSqT7+BZ/lWcDHwNMuzsRVfyxUimh+D54Xw4tSWbdVVQhtWtNMUyI93LVnwCmsoEpar2gC3SFeAgywx37svKQ==} cpu: [s390x] os: [linux] libc: [glibc] - '@pnpm/exe.linux-x64-musl@12.4.2': - resolution: {integrity: sha512-kzfzH2/0BWdTABK14Yj5a1xsdkTEQUp2eXEPNakaD9jKL025lq3hyaKHIz/gIZaPDMe/1bFFK/En4ztFlbBJxw==} + '@pnpm/exe.linux-x64-musl@12.6.0': + resolution: {integrity: sha512-31lKeGPmRE6xfV6I3VjaEGVFRei14pl/zgoFDK4w+UkbJqOuNl2Ht3O1GuqNIg3Gl14qTEb4kZRAYFHXifDx9A==} cpu: [x64] os: [linux] libc: [musl] - '@pnpm/exe.linux-x64@12.4.2': - resolution: {integrity: sha512-/pbt0UVTa8NMDhzOWLQRfZ6G9ROKXlJPZtx845BqyWfc7hCrWXhTLBd70yO2y8+E+IWN3oHM1s/JsIQNGk1yvg==} + '@pnpm/exe.linux-x64@12.6.0': + resolution: {integrity: sha512-qFWBneHJAJ73W4whtbaFOL1M/7DBC6ILHXuxc7ZPtEhfPuT1zeZiGrmKHoMAfJA+mcm6xhOFljqVTUS+00Jabw==} cpu: [x64] os: [linux] libc: [glibc] - '@pnpm/exe.win32-arm64@12.4.2': - resolution: {integrity: sha512-PsW19e4dAUNpZ0cS9flaxFuAmpt2dKlH/Vvi8TZ4qyJjjQzue/CEsWm+6wKVP4CJ7IT8RdL4qh+soOPWIgF2Zw==} + '@pnpm/exe.win32-arm64@12.6.0': + resolution: {integrity: sha512-OhfefXEEykZlslSUhR8PPRe6MVPV3Oink/dVfIecE5velpc7j80cZYsHlaDrtRDcm3TPwQHkaRW1SJ1efX9oFg==} cpu: [arm64] os: [win32] - '@pnpm/exe.win32-x64@12.4.2': - resolution: {integrity: sha512-+xGoeE0g55ztWvl8i5QqdmNfW3nIrTVcoQrNshEOwxthm9Ag48oXton3uxOA3/SANyz5AXexEjj2KO20NnOrEw==} + '@pnpm/exe.win32-x64@12.6.0': + resolution: {integrity: sha512-L2tuyrD2+Imgxs3VK/ST/2L3xD6vDP0ktJQxM0TaGw7TbAQEMq+RMc8iK6Ew7Id579uzjJe8jSfJID2ZGsOHCA==} cpu: [x64] os: [win32] - pnpm@12.4.2: - resolution: {integrity: sha512-CK3GYTGAJ1x8ntraOdzwjJxhrU5+rzMKTzRh8QKw+QdCNFTRF/mOctR/7wYWBwZE17/8lzpqV/UJCm18NosHyQ==} + pnpm@12.6.0: + resolution: {integrity: sha512-PvaPlRyxEawgS0paFvCy3fDaVqluBBPoHYVdnwtV75JnFHCQKOHNAMQFwsX7e56OxNxGd3yAXQNzwvL/AP0g7A==} engines: {node: '>=18.*'} hasBin: true snapshots: - '@pnpm/exe.android-arm64@12.4.2': + '@pnpm/exe.android-arm64@12.6.0': optional: true - '@pnpm/exe.android-x64@12.4.2': + '@pnpm/exe.android-x64@12.6.0': optional: true - '@pnpm/exe.darwin-arm64@12.4.2': + '@pnpm/exe.darwin-arm64@12.6.0': optional: true - '@pnpm/exe.darwin-x64@12.4.2': + '@pnpm/exe.darwin-x64@12.6.0': optional: true - '@pnpm/exe.freebsd-x64@12.4.2': + '@pnpm/exe.freebsd-x64@12.6.0': optional: true - '@pnpm/exe.linux-arm64-musl@12.4.2': + '@pnpm/exe.linux-arm64-musl@12.6.0': optional: true - '@pnpm/exe.linux-arm64@12.4.2': + '@pnpm/exe.linux-arm64@12.6.0': optional: true - '@pnpm/exe.linux-ppc64@12.4.2': + '@pnpm/exe.linux-ppc64@12.6.0': optional: true - '@pnpm/exe.linux-riscv64@12.4.2': + '@pnpm/exe.linux-riscv64@12.6.0': optional: true - '@pnpm/exe.linux-s390x@12.4.2': + '@pnpm/exe.linux-s390x@12.6.0': optional: true - '@pnpm/exe.linux-x64-musl@12.4.2': + '@pnpm/exe.linux-x64-musl@12.6.0': optional: true - '@pnpm/exe.linux-x64@12.4.2': + '@pnpm/exe.linux-x64@12.6.0': optional: true - '@pnpm/exe.win32-arm64@12.4.2': + '@pnpm/exe.win32-arm64@12.6.0': optional: true - '@pnpm/exe.win32-x64@12.4.2': + '@pnpm/exe.win32-x64@12.6.0': optional: true - pnpm@12.4.2: + pnpm@12.6.0: optionalDependencies: - '@pnpm/exe.android-arm64': 12.4.2 - '@pnpm/exe.android-x64': 12.4.2 - '@pnpm/exe.darwin-arm64': 12.4.2 - '@pnpm/exe.darwin-x64': 12.4.2 - '@pnpm/exe.freebsd-x64': 12.4.2 - '@pnpm/exe.linux-arm64': 12.4.2 - '@pnpm/exe.linux-arm64-musl': 12.4.2 - '@pnpm/exe.linux-ppc64': 12.4.2 - '@pnpm/exe.linux-riscv64': 12.4.2 - '@pnpm/exe.linux-s390x': 12.4.2 - '@pnpm/exe.linux-x64': 12.4.2 - '@pnpm/exe.linux-x64-musl': 12.4.2 - '@pnpm/exe.win32-arm64': 12.4.2 - '@pnpm/exe.win32-x64': 12.4.2 + '@pnpm/exe.android-arm64': 12.6.0 + '@pnpm/exe.android-x64': 12.6.0 + '@pnpm/exe.darwin-arm64': 12.6.0 + '@pnpm/exe.darwin-x64': 12.6.0 + '@pnpm/exe.freebsd-x64': 12.6.0 + '@pnpm/exe.linux-arm64': 12.6.0 + '@pnpm/exe.linux-arm64-musl': 12.6.0 + '@pnpm/exe.linux-ppc64': 12.6.0 + '@pnpm/exe.linux-riscv64': 12.6.0 + '@pnpm/exe.linux-s390x': 12.6.0 + '@pnpm/exe.linux-x64': 12.6.0 + '@pnpm/exe.linux-x64-musl': 12.6.0 + '@pnpm/exe.win32-arm64': 12.6.0 + '@pnpm/exe.win32-x64': 12.6.0 --- lockfileVersion: '9.0' From aea1ddebfe574eda559464447dfe44192953cbe2 Mon Sep 17 00:00:00 2001 From: ZainnQureshii <43629888+ZainnQureshii@users.noreply.github.com> Date: Thu, 24 Sep 2026 16:02:47 +0200 Subject: [PATCH 026/233] docs: fix stale Bazel test targets and toolchain versions (cherry picked from commit d9682594bd15a2ca234f01104941480233dda5a6) --- docs/DEVELOPER.md | 8 ++++---- docs/process/bazel.md | 4 ++-- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/docs/DEVELOPER.md b/docs/DEVELOPER.md index 35b07adf1e89..ddb8341e662b 100644 --- a/docs/DEVELOPER.md +++ b/docs/DEVELOPER.md @@ -7,9 +7,9 @@ To get started locally, follow these instructions: 1. If you haven't done it already, [make a fork of this repo](https://github.com/angular/angular-cli/fork). 2. If you are on Windows, see [the extra steps needed for contributing on Windows](#windows) 3. Clone to your local computer using `git`. -4. Make sure that you have Node `v20.19.0` or higher installed. See instructions [here](https://nodejs.org/en/download/). +4. Make sure that you have Node `v22.22.3` or higher installed (see `engines` in `package.json`). See instructions [here](https://nodejs.org/en/download/). 5. Install `pnpm`. - - You can install pnpm by running `npm i -g pnpm@9`. + - You can install pnpm by running `npm i -g pnpm@12`. - See detailed instructions [here](https://pnpm.io/installation). 6. Run `pnpm install` from the root of your clone of this project to install dependencies. @@ -78,7 +78,7 @@ There are two different test suites which can be run locally: ### Unit tests - Run all tests: `pnpm bazel test //packages/...` -- Run a subset of the tests, use the full Bazel target example: `pnpm bazel test //packages/schematics/angular:angular_test` +- Run a subset of the tests, use the full Bazel target example: `pnpm bazel test //packages/schematics/angular:test` - For a complete list of test targets use the following Bazel query: `pnpm bazel query "tests(//packages/...)"` When debugging a specific test, change `describe()` or `it()` to `fdescribe()` @@ -166,7 +166,7 @@ You can use the Chrome Devtools to process it. To do so: Adding a package to this repository means running two separate commands: -1. `schematics devkit:package PACKAGE_NAME`. This will update the `.monorepo` file, and create the +1. `schematics devkit:package PACKAGE_NAME`. This will update the `.monorepo.json` file, and create the base files for the new package (package.json, src/index, etc). 1. `pnpm admin templates`. This will update the README and all other template files that might have changed when adding a new package. diff --git a/docs/process/bazel.md b/docs/process/bazel.md index 86542047745e..458d634ba9b6 100644 --- a/docs/process/bazel.md +++ b/docs/process/bazel.md @@ -65,7 +65,7 @@ the reruns of tests that have been marked as `flaky`. The `.bazelrc` includes a config for running tests with remote debugging enabled: ```sh -pnpm bazel test --config=debug //packages/angular/cli:angular-cli_test +pnpm bazel test --config=debug //packages/angular/cli:test # Also disable reruns of failing tests that were marked as flaky: -pnpm bazel test --config=debug --config=no-sharding //packages/angular/cli:angular-cli_test +pnpm bazel test --config=debug --config=no-sharding //packages/angular/cli:test ``` From a945b7f6bf1e3d9d10768515e86c7aba0d6d9cfc Mon Sep 17 00:00:00 2001 From: Alan Agius <17563226+alan-agius4@users.noreply.github.com> Date: Fri, 25 Sep 2026 08:08:12 +0000 Subject: [PATCH 027/233] refactor(@angular/build): export DEFAULT_ASSET_IGNORE from resolve-assets (cherry picked from commit 7ce093f6766d8499c57c4b4ad920e8e4005010b3) --- packages/angular/build/src/utils/resolve-assets.ts | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/packages/angular/build/src/utils/resolve-assets.ts b/packages/angular/build/src/utils/resolve-assets.ts index 71b1c0e4768b..41ae41d66b9b 100644 --- a/packages/angular/build/src/utils/resolve-assets.ts +++ b/packages/angular/build/src/utils/resolve-assets.ts @@ -10,6 +10,11 @@ import path from 'node:path'; import { glob } from 'tinyglobby'; import { isSubDirectory } from './path'; +/** + * Default glob ignore patterns for assets. + */ +export const DEFAULT_ASSET_IGNORE = ['.gitkeep', '**/.DS_Store', '**/Thumbs.db'] as const; + export async function resolveAssets( entries: { glob: string; @@ -21,8 +26,6 @@ export async function resolveAssets( }[], root: string, ): Promise<{ source: string; destination: string }[]> { - const defaultIgnore = ['.gitkeep', '**/.DS_Store', '**/Thumbs.db']; - const outputFiles: { source: string; destination: string }[] = []; for (const entry of entries) { @@ -35,7 +38,7 @@ export async function resolveAssets( const files = await glob(entry.glob, { cwd, dot: true, - ignore: entry.ignore ? defaultIgnore.concat(entry.ignore) : defaultIgnore, + ignore: entry.ignore ? [...DEFAULT_ASSET_IGNORE, ...entry.ignore] : DEFAULT_ASSET_IGNORE, followSymbolicLinks: entry.followSymlinks, }); From 37cf399d95d9376811cd79144bbd517f3efe3d32 Mon Sep 17 00:00:00 2001 From: Alan Agius <17563226+alan-agius4@users.noreply.github.com> Date: Fri, 25 Sep 2026 08:46:23 +0000 Subject: [PATCH 028/233] fix(@angular/build): reset component updates on dev-server SSR page request When server-side rendering is enabled (either internal or external mode), page reload requests are handled by the SSR middleware before reaching the index HTML middleware. As a result, `resetComponentUpdates` was never invoked on page reloads, causing stale component HMR updates to persist in `templateUpdates` and be re-applied over freshly rendered pages. We now pass `resetComponentUpdates` to `createAngularSsrInternalMiddleware` and `createAngularSsrExternalMiddleware`, and trigger it when an SSR HTML transform occurs (`html:transform:pre`). Fixes #34163 (cherry picked from commit de91345c13640c6ad462e7ffa124a1e6faca20f1) --- packages/angular/build/BUILD.bazel | 1 + .../tools/vite/middlewares/ssr-middleware.ts | 8 +- .../vite/middlewares/ssr-middleware_spec.ts | 130 ++++++++++++++++++ .../vite/plugins/setup-middlewares-plugin.ts | 12 +- 4 files changed, 147 insertions(+), 4 deletions(-) create mode 100644 packages/angular/build/src/tools/vite/middlewares/ssr-middleware_spec.ts diff --git a/packages/angular/build/BUILD.bazel b/packages/angular/build/BUILD.bazel index 9a4de3b5aa64..d648331b70de 100644 --- a/packages/angular/build/BUILD.bazel +++ b/packages/angular/build/BUILD.bazel @@ -148,6 +148,7 @@ ts_project( ":node_modules/@babel/core", ":node_modules/oxc-parser", "//:node_modules/@angular/compiler-cli", + "//:node_modules/@angular/router", "//:node_modules/@types/jasmine", "//:node_modules/esbuild", "//:node_modules/prettier", diff --git a/packages/angular/build/src/tools/vite/middlewares/ssr-middleware.ts b/packages/angular/build/src/tools/vite/middlewares/ssr-middleware.ts index 78458624c4db..c75c63e992bb 100644 --- a/packages/angular/build/src/tools/vite/middlewares/ssr-middleware.ts +++ b/packages/angular/build/src/tools/vite/middlewares/ssr-middleware.ts @@ -21,6 +21,7 @@ import { export function createAngularSsrInternalMiddleware( server: ViteDevServer, + resetComponentUpdates: () => void, indexHtmlTransformer?: (content: string) => Promise, ): Connect.NextHandleFunction { let cachedAngularServerApp: ReturnType | undefined; @@ -53,6 +54,7 @@ export function createAngularSsrInternalMiddleware( // Only Add the transform hook only if it's a different instance. if (cachedAngularServerApp !== angularServerApp) { angularServerApp.hooks.on('html:transform:pre', async ({ html, url }) => { + resetComponentUpdates(); const processedHtml = await server.transformIndexHtml(url.pathname, html); return indexHtmlTransformer?.(processedHtml) ?? processedHtml; @@ -76,13 +78,13 @@ export function createAngularSsrInternalMiddleware( export async function createAngularSsrExternalMiddleware( server: ViteDevServer, + resetComponentUpdates: () => void, indexHtmlTransformer?: (content: string) => Promise, ): Promise { let fallbackWarningShown = false; let cachedAngularAppEngine: typeof SSRAngularAppEngine | undefined; let angularSsrInternalMiddleware: - | ReturnType - | undefined; + ReturnType | undefined; // Load the compiler because `@angular/ssr/node` depends on `@angular/` packages, // which must be processed by the runtime linker, even if they are not used. @@ -120,6 +122,7 @@ export async function createAngularSsrExternalMiddleware( angularSsrInternalMiddleware ??= createAngularSsrInternalMiddleware( server, + resetComponentUpdates, indexHtmlTransformer, ); @@ -132,6 +135,7 @@ export async function createAngularSsrExternalMiddleware( AngularAppEngine.ɵdisableAllowedHostsCheck = disableAllowedHostsCheck; AngularAppEngine.ɵallowStaticRouteRender = true; AngularAppEngine.ɵhooks.on('html:transform:pre', async ({ html, url }) => { + resetComponentUpdates(); const processedHtml = await server.transformIndexHtml(url.pathname, html); return indexHtmlTransformer?.(processedHtml) ?? processedHtml; diff --git a/packages/angular/build/src/tools/vite/middlewares/ssr-middleware_spec.ts b/packages/angular/build/src/tools/vite/middlewares/ssr-middleware_spec.ts new file mode 100644 index 000000000000..a61011043a43 --- /dev/null +++ b/packages/angular/build/src/tools/vite/middlewares/ssr-middleware_spec.ts @@ -0,0 +1,130 @@ +/** + * @license + * Copyright Google LLC All Rights Reserved. + * + * Use of this source code is governed by an MIT-style license that can be + * found in the LICENSE file at https://angular.dev/license + */ + +import type { IncomingMessage, ServerResponse } from 'node:http'; +import { + createAngularSsrExternalMiddleware, + createAngularSsrInternalMiddleware, +} from './ssr-middleware'; + +type ViteDevServer = Parameters[0]; + +describe('SSR dev-server middleware', () => { + function createMockReqRes(): { req: IncomingMessage; res: ServerResponse } { + const req = { + url: '/', + method: 'GET', + headers: { host: 'localhost' }, + } as unknown as IncomingMessage; + + const res = { + statusCode: 200, + setHeader: jasmine.createSpy('setHeader'), + writeHead: jasmine.createSpy('writeHead'), + end: jasmine.createSpy('end'), + } as unknown as ServerResponse; + + return { req, res }; + } + + it('resets component updates when html:transform:pre executes in internal SSR middleware', async () => { + let hookCallback: ((args: { html: string; url: URL }) => Promise) | undefined; + const resetComponentUpdates = jasmine.createSpy('resetComponentUpdates'); + let resolveHookRegistered!: () => void; + const hookRegistered = new Promise((resolve) => { + resolveHookRegistered = resolve; + }); + + const fakeAngularServerApp = { + hooks: { + on: (_name: string, cb: typeof hookCallback) => { + hookCallback = cb; + resolveHookRegistered(); + }, + }, + handle: jasmine.createSpy('handle').and.resolveTo(new Response('rendered')), + }; + + const server = { + config: { server: { allowedHosts: true }, base: '/' }, + ssrLoadModule: jasmine.createSpy('ssrLoadModule').and.resolveTo({ + ɵgetOrCreateAngularServerApp: () => fakeAngularServerApp, + }), + transformIndexHtml: jasmine + .createSpy('transformIndexHtml') + .and.callFake(async (_path: string, html: string) => html), + } as unknown as ViteDevServer; + + const middleware = createAngularSsrInternalMiddleware( + server, + resetComponentUpdates, + async (html) => html + '', + ); + + const { req, res } = createMockReqRes(); + middleware(req, res, () => {}); + + await hookRegistered; + + expect(resetComponentUpdates).not.toHaveBeenCalled(); + expect(hookCallback).toBeDefined(); + const result = await hookCallback?.({ + html: '
test
', + url: new URL('http://localhost/'), + }); + expect(resetComponentUpdates).toHaveBeenCalledTimes(1); + expect(result).toBe('
test
'); + }); + + it('resets component updates when html:transform:pre executes in external SSR middleware', async () => { + let hookCallback: ((args: { html: string; url: URL }) => Promise) | undefined; + const resetComponentUpdates = jasmine.createSpy('resetComponentUpdates'); + let resolveHookRegistered!: () => void; + const hookRegistered = new Promise((resolve) => { + resolveHookRegistered = resolve; + }); + + class FakeAngularAppEngine { + static ɵhooks = { + on: (_name: string, cb: typeof hookCallback) => { + hookCallback = cb; + resolveHookRegistered(); + }, + }; + static ɵdisableAllowedHostsCheck: boolean; + static ɵallowStaticRouteRender: boolean; + } + + const server = { + config: { server: { allowedHosts: true }, base: '/' }, + ssrLoadModule: jasmine.createSpy('ssrLoadModule').and.resolveTo({ + reqHandler: Object.assign(() => new Response('ok'), { __ng_request_handler__: true }), + AngularAppEngine: FakeAngularAppEngine, + }), + transformIndexHtml: jasmine + .createSpy('transformIndexHtml') + .and.callFake(async (_path: string, html: string) => html + ''), + } as unknown as ViteDevServer; + + const middleware = await createAngularSsrExternalMiddleware(server, resetComponentUpdates); + + const { req, res } = createMockReqRes(); + middleware(req, res, () => {}); + + await hookRegistered; + + expect(resetComponentUpdates).not.toHaveBeenCalled(); + expect(hookCallback).toBeDefined(); + const result = await hookCallback?.({ + html: '
test
', + url: new URL('http://localhost/'), + }); + expect(resetComponentUpdates).toHaveBeenCalledTimes(1); + expect(result).toBe('
test
'); + }); +}); diff --git a/packages/angular/build/src/tools/vite/plugins/setup-middlewares-plugin.ts b/packages/angular/build/src/tools/vite/plugins/setup-middlewares-plugin.ts index 78e16304f01d..34b0704f4091 100644 --- a/packages/angular/build/src/tools/vite/plugins/setup-middlewares-plugin.ts +++ b/packages/angular/build/src/tools/vite/plugins/setup-middlewares-plugin.ts @@ -117,13 +117,21 @@ export function createAngularSetupMiddlewaresPlugin( if (ssrMode === ServerSsrMode.ExternalSsrMiddleware) { patchBaseMiddleware(server.middlewares, server.config.base); - middlewares.use(await createAngularSsrExternalMiddleware(server, indexHtmlTransformer)); + middlewares.use( + await createAngularSsrExternalMiddleware( + server, + resetComponentUpdates, + indexHtmlTransformer, + ), + ); return; } if (ssrMode === ServerSsrMode.InternalSsrMiddleware) { - middlewares.use(createAngularSsrInternalMiddleware(server, indexHtmlTransformer)); + middlewares.use( + createAngularSsrInternalMiddleware(server, resetComponentUpdates, indexHtmlTransformer), + ); } middlewares.use(angularHtmlFallbackMiddleware); From 5194b415314a4fb2435b29dcf42ccffbc26070a9 Mon Sep 17 00:00:00 2001 From: Charles Lyding <19598772+clydin@users.noreply.github.com> Date: Thu, 24 Sep 2026 15:09:21 -0400 Subject: [PATCH 029/233] fix(@angular/build): prevent chokidar from scanning unimported node_modules in watch mode When using Chokidar (such as when `preserveSymlinks: true` is configured or polling is active), Chokidar's initial filesystem scan previously walked the entire `workspaceRoot`, including all of `node_modules`. Because `await once(watcher, 'ready')` blocks until the initial scan completes, this caused watch mode in commands like `ng test`, `ng serve`, and `ng build --watch` to hang for minutes before emitting the first build result. This commit introduces selective `node_modules` filtering in Chokidar: - `node_modules` packages corresponding to imported build files (e.g. `npm link` libraries, both unscoped and scoped) are allowed and their directories watched, retaining native symlink traversal. - All other unimported subdirectories in `node_modules` are pruned and ignored during the initial scan and subsequent directory visits. - Packages added dynamically via `watcher.add()` are registered and watched on the fly. Fixes #34162 (cherry picked from commit 91b0947898cef9de69d8aa337927fc12806065f6) --- packages/angular/build/src/utils/watcher.ts | 173 ++++++++++- .../angular/build/src/utils/watcher_spec.ts | 282 +++++++++++++++++- 2 files changed, 433 insertions(+), 22 deletions(-) diff --git a/packages/angular/build/src/utils/watcher.ts b/packages/angular/build/src/utils/watcher.ts index be38151f7a48..8d47ba48e907 100644 --- a/packages/angular/build/src/utils/watcher.ts +++ b/packages/angular/build/src/utils/watcher.ts @@ -49,6 +49,9 @@ export interface WatcherOptions { cwd?: string; } +const NODE_MODULES = 'node_modules'; +const NODE_MODULES_SEGMENT = `/${NODE_MODULES}/`; + // Watch workspace for package manager changes const packageWatchFiles = [ // manifest can affect module resolution @@ -109,7 +112,7 @@ export async function setupWatcher(options: SetupWatcherOptions): Promise(); private readonly pendingSubscriptions = new Map< @@ -625,6 +658,94 @@ async function createParcelWatcher( return buildWatcher; } +/** + * Manages selective node_modules watching for Chokidar. + * + * During Chokidar's initial scan, the allowed packages set is empty, causing Chokidar to prune the entire + * node_modules directory immediately and avoid blocking the 'ready' event for minutes. + * Packages are dynamically allowed and watched at the package root level as files are added via `watcher.add`. + * Tracking files per package allows reference-counting so that package directories are unwatched when no + * longer needed. + */ +class ChokidarNodeModulesManager { + private readonly allowedPackages = new Map>(); + + constructor(private readonly isCaseSensitive: boolean) {} + + registerPackage( + posixPath: string, + lookupKey: string, + ): { isPackage: boolean; newPkgDir?: string } { + const packageDir = extractNodeModulesPackageDir(posixPath); + if (!packageDir) { + return { isPackage: false }; + } + + const packageKey = toLookupKey(packageDir, this.isCaseSensitive); + let watchedInPkg = this.allowedPackages.get(packageKey); + if (!watchedInPkg) { + watchedInPkg = new Set(); + this.allowedPackages.set(packageKey, watchedInPkg); + watchedInPkg.add(lookupKey); + + return { isPackage: true, newPkgDir: packageDir }; + } + + watchedInPkg.add(lookupKey); + + return { isPackage: true }; + } + + removePackageFile( + posixPath: string, + lookupKey: string, + ): { isPackage: boolean; unwatchPkgDir?: string } { + const packageDir = extractNodeModulesPackageDir(posixPath); + if (!packageDir) { + return { isPackage: false }; + } + + const packageKey = toLookupKey(packageDir, this.isCaseSensitive); + const watchedInPkg = this.allowedPackages.get(packageKey); + if (watchedInPkg) { + watchedInPkg.delete(lookupKey); + if (watchedInPkg.size === 0) { + this.allowedPackages.delete(packageKey); + + return { isPackage: true, unwatchPkgDir: packageDir }; + } + } + + return { isPackage: true }; + } + + isIgnored(filePath: string): boolean { + // Fast path: avoid expensive normalization for non-node_modules files + if (!filePath.includes(NODE_MODULES)) { + return false; + } + + const posixPath = toPosixPathNormalized(filePath); + const lookupKey = toLookupKey(posixPath, this.isCaseSensitive); + + if (!`${lookupKey}/`.includes(NODE_MODULES_SEGMENT)) { + return false; + } + + if (this.allowedPackages.has(lookupKey)) { + return false; + } + + for (const pkg of this.allowedPackages.keys()) { + if (isPathInside(lookupKey, pkg)) { + return false; + } + } + + return true; + } +} + async function createChokidarWatcher( options?: WatcherOptions, chokidarModule?: typeof Chokidar, @@ -647,15 +768,25 @@ async function createChokidarWatcher( const rootDirPosix = toPosixPathNormalized(rootDir); const rootDirLookupKey = toLookupKey(rootDirPosix, isCaseSensitive); - const ignored = options?.ignored?.map((pattern) => { - if (/[*?[\]{}()]/.test(pattern)) { - const isMatch = picomatch(pattern, { dot: true }); + const nodeModulesManager = new ChokidarNodeModulesManager(isCaseSensitive); - return (filePath: string) => isMatch(toPosixPathNormalized(filePath)); - } + // Strip static node_modules ignore patterns (e.g. `**/node_modules/**` from setupWatcher). + // If left in place, picomatch would unconditionally ignore all node_modules files and override + // our dynamic package allowlist above. + const customIgnored = + options?.ignored + ?.filter((pattern) => !pattern.includes(NODE_MODULES)) + .map((pattern) => { + if (/[*?[\]{}()]/.test(pattern)) { + const isMatch = picomatch(pattern, { dot: true }); - return { path: toPosixPathNormalized(pattern), recursive: true }; - }); + return (filePath: string) => isMatch(toPosixPathNormalized(filePath)); + } + + return { path: toPosixPathNormalized(pattern), recursive: true }; + }) ?? []; + + const ignored = [...customIgnored, (filePath: string) => nodeModulesManager.isIgnored(filePath)]; const watcher = chokidar.watch(rootDir, { ignoreInitial: true, @@ -714,7 +845,17 @@ async function createChokidarWatcher( const lookupKey = toLookupKey(posixPath, isCaseSensitive); if (!watchedFiles.has(lookupKey)) { watchedFiles.add(lookupKey); - if (!isPathInside(lookupKey, rootDirLookupKey) && lookupKey !== rootDirLookupKey) { + + // For files inside node_modules, register their package directory. Only newly encountered + // package directories need to be added to Chokidar. + const { isPackage, newPkgDir } = nodeModulesManager.registerPackage(posixPath, lookupKey); + if (newPkgDir) { + newPaths.push(newPkgDir); + } else if ( + !isPackage && + !isPathInside(lookupKey, rootDirLookupKey) && + lookupKey !== rootDirLookupKey + ) { newPaths.push(posixPath); } } @@ -732,7 +873,19 @@ async function createChokidarWatcher( const lookupKey = toLookupKey(posixPath, isCaseSensitive); if (watchedFiles.has(lookupKey)) { watchedFiles.delete(lookupKey); - if (!isPathInside(lookupKey, rootDirLookupKey) && lookupKey !== rootDirLookupKey) { + + // When the last watched file in a package is removed, unwatch the package directory. + const { isPackage, unwatchPkgDir } = nodeModulesManager.removePackageFile( + posixPath, + lookupKey, + ); + if (unwatchPkgDir) { + removePaths.push(unwatchPkgDir); + } else if ( + !isPackage && + !isPathInside(lookupKey, rootDirLookupKey) && + lookupKey !== rootDirLookupKey + ) { removePaths.push(posixPath); } } diff --git a/packages/angular/build/src/utils/watcher_spec.ts b/packages/angular/build/src/utils/watcher_spec.ts index e051c44bd3f2..547ad2695f90 100644 --- a/packages/angular/build/src/utils/watcher_spec.ts +++ b/packages/angular/build/src/utils/watcher_spec.ts @@ -6,14 +6,15 @@ * found in the LICENSE file at https://angular.dev/license */ +import assert from 'node:assert'; import * as fs from 'node:fs'; -import * as os from 'node:os'; import * as path from 'node:path'; import { setTimeout } from 'node:timers/promises'; import { type BuildWatcher, ChangedFiles, createWatcher, + extractNodeModulesPackageDir, getDirectoryPath, isPathInside, setupWatcher, @@ -21,6 +22,9 @@ import { } from './watcher'; describe('Watcher', () => { + const TMP_DIR = process.env['TEST_TMPDIR']; + assert(TMP_DIR, 'TEST_TMPDIR must be set'); + describe('toPosixPathNormalized', () => { it('should strip trailing slashes for standard directories', () => { expect(toPosixPathNormalized('/src/app/')).toBe('/src/app'); @@ -57,6 +61,30 @@ describe('Watcher', () => { }); }); + describe('extractNodeModulesPackageDir', () => { + it('should extract unscoped package directory', () => { + expect(extractNodeModulesPackageDir('/project/node_modules/my-lib/index.js')).toBe( + '/project/node_modules/my-lib', + ); + }); + + it('should extract scoped package directory', () => { + expect( + extractNodeModulesPackageDir('/project/node_modules/@my-scope/my-lib/src/index.js'), + ).toBe('/project/node_modules/@my-scope/my-lib'); + }); + + it('should handle package directory path directly', () => { + expect(extractNodeModulesPackageDir('/project/node_modules/my-lib')).toBe( + '/project/node_modules/my-lib', + ); + }); + + it('should return undefined for paths outside node_modules', () => { + expect(extractNodeModulesPackageDir('/project/src/main.ts')).toBeUndefined(); + }); + }); + describe('isPathInside', () => { it('should return true for a file inside a directory', () => { expect(isPathInside('/src/app/main.ts', '/src/app')).toBeTrue(); @@ -122,7 +150,7 @@ describe('Watcher', () => { let tempDir: string; beforeEach(() => { - tempDir = fs.realpathSync(fs.mkdtempSync(path.join(os.tmpdir(), 'setup-watcher-spec-'))); + tempDir = fs.mkdtempSync(path.join(TMP_DIR, 'setup-watcher-spec-')); }); afterEach(() => { @@ -166,13 +194,53 @@ describe('Watcher', () => { await watcher.close(); expect(removeSpy).toHaveBeenCalledWith('abort', jasmine.any(Function)); }); + + it('should setup watcher with preserveSymlinks: true and detect changes in linked package in node_modules', async () => { + const externalDir = fs.mkdtempSync(path.join(TMP_DIR, 'setup-watcher-npm-link-')); + + try { + const externalTargetFile = path.join(externalDir, 'index.ts'); + fs.writeFileSync(externalTargetFile, 'export const a = 1;'); + + const nodeModulesDir = path.join(tempDir, 'node_modules'); + fs.mkdirSync(nodeModulesDir); + + const linkedPkgDir = path.join(nodeModulesDir, 'linked-pkg'); + fs.symlinkSync(externalDir, linkedPkgDir, 'junction'); + const linkedFile = path.join(linkedPkgDir, 'index.ts'); + + const watcher = await setupWatcher({ + workspaceRoot: tempDir, + projectRoot: tempDir, + outputPath: path.join(tempDir, 'dist'), + cacheOptions: { basePath: path.join(tempDir, '.cache') }, + preserveSymlinks: true, + watchFiles: [linkedFile], + }); + + await setTimeout(250); + + const iterator = watcher[Symbol.asyncIterator](); + const nextPromise = iterator.next(); + + fs.writeFileSync(externalTargetFile, 'export const a = 2;'); + + const result = await nextPromise; + expect(result.done).toBeFalsy(); + expect(result.value?.all.some((f: string) => f.includes('linked-pkg'))).toBeTrue(); + + await watcher.close(); + } finally { + fs.rmSync(externalDir, { recursive: true, force: true }); + } + }, 10000); }); describe('createWatcher', () => { let tempDir: string; beforeEach(() => { - tempDir = fs.realpathSync(fs.mkdtempSync(path.join(os.tmpdir(), 'watcher-spec-'))); + tempDir = fs.mkdtempSync(path.join(TMP_DIR, 'watcher-spec-')); }); afterEach(() => { @@ -279,7 +347,7 @@ describe('Watcher', () => { }, 10000); it('should support watching paths outside cwd', async () => { - const externalDir = fs.mkdtempSync(path.join(os.tmpdir(), 'external-watcher-spec-')); + const externalDir = fs.mkdtempSync(path.join(TMP_DIR, 'external-watcher-spec-')); const externalFile = path.join(externalDir, 'external.txt'); fs.writeFileSync(externalFile, 'initial'); @@ -305,7 +373,7 @@ describe('Watcher', () => { }, 10000); it('should handle adding multiple external files in the same directory concurrently', async () => { - const externalDir = fs.mkdtempSync(path.join(os.tmpdir(), 'external-watcher-spec-')); + const externalDir = fs.mkdtempSync(path.join(TMP_DIR, 'external-watcher-spec-')); const file1 = path.join(externalDir, 'file1.txt'); const file2 = path.join(externalDir, 'file2.txt'); fs.writeFileSync(file1, 'initial1'); @@ -335,7 +403,7 @@ describe('Watcher', () => { }, 10000); it('should clean up external subscriptions when all external files in a directory are removed', async () => { - const externalDir = fs.mkdtempSync(path.join(os.tmpdir(), 'external-watcher-spec-')); + const externalDir = fs.mkdtempSync(path.join(TMP_DIR, 'external-watcher-spec-')); const file1 = path.join(externalDir, 'file1.txt'); const file2 = path.join(externalDir, 'file2.txt'); fs.writeFileSync(file1, 'initial1'); @@ -358,7 +426,7 @@ describe('Watcher', () => { }); it('should handle nested external directories without creating duplicate subscriptions', async () => { - const externalDir = fs.mkdtempSync(path.join(os.tmpdir(), 'external-watcher-spec-')); + const externalDir = fs.mkdtempSync(path.join(TMP_DIR, 'external-watcher-spec-')); const subDir = path.join(externalDir, 'sub'); fs.mkdirSync(subDir); const parentFile = path.join(externalDir, 'parent.txt'); @@ -389,7 +457,7 @@ describe('Watcher', () => { }, 10000); it('should subscribe to subsumed external child directory when parent external subscription is removed', async () => { - const externalDir = fs.mkdtempSync(path.join(os.tmpdir(), 'external-watcher-spec-')); + const externalDir = fs.mkdtempSync(path.join(TMP_DIR, 'external-watcher-spec-')); const subDir = path.join(externalDir, 'sub'); fs.mkdirSync(subDir); const parentFile = path.join(externalDir, 'parent.txt'); @@ -536,9 +604,7 @@ describe('Watcher', () => { }, 10000); it('should detect changes behind a directory symlink when followSymlinks is true', async () => { - const externalDir = fs.realpathSync( - fs.mkdtempSync(path.join(os.tmpdir(), 'watcher-external-')), - ); + const externalDir = fs.mkdtempSync(path.join(TMP_DIR, 'watcher-external-')); let watcher: BuildWatcher | undefined; try { @@ -556,7 +622,7 @@ describe('Watcher', () => { }); watcher.add(symlinkedFile); - await setTimeout(150); + await setTimeout(250); const iterator = watcher[Symbol.asyncIterator](); const nextPromise = iterator.next(); @@ -571,5 +637,197 @@ describe('Watcher', () => { fs.rmSync(externalDir, { recursive: true, force: true }); } }, 10000); + + it('should detect changes in linked package in node_modules while ignoring unimported packages', async () => { + const externalDir = fs.mkdtempSync(path.join(TMP_DIR, 'watcher-npm-link-')); + let watcher: BuildWatcher | undefined; + + try { + const externalTargetFile = path.join(externalDir, 'index.ts'); + fs.writeFileSync(externalTargetFile, 'export const a = 1;'); + + const nodeModulesDir = path.join(tempDir, 'node_modules'); + fs.mkdirSync(nodeModulesDir); + + // Unimported package that should be ignored + const unimportedPkgDir = path.join(nodeModulesDir, 'unimported-pkg'); + fs.mkdirSync(unimportedPkgDir); + const unimportedFile = path.join(unimportedPkgDir, 'dep.ts'); + fs.writeFileSync(unimportedFile, 'export const dep = 1;'); + + // Linked package in node_modules + const linkedPkgDir = path.join(nodeModulesDir, 'linked-pkg'); + fs.symlinkSync(externalDir, linkedPkgDir, 'junction'); + const linkedFile = path.join(linkedPkgDir, 'index.ts'); + + watcher = await createWatcher({ + followSymlinks: true, + cwd: tempDir, + }); + + watcher.add(linkedFile); + await setTimeout(250); + + const iterator = watcher[Symbol.asyncIterator](); + const nextPromise = iterator.next(); + + // Modify both the linked file and the unimported file + fs.writeFileSync(unimportedFile, 'export const dep = 2;'); + fs.writeFileSync(externalTargetFile, 'export const a = 2;'); + + const result = await nextPromise; + expect(result.done).toBeFalsy(); + const changed = result.value?.all ?? []; + expect(changed.some((f: string) => f.includes('linked-pkg'))).toBeTrue(); + expect(changed.some((f: string) => f.includes('unimported-pkg'))).toBeFalse(); + } finally { + await watcher?.close(); + fs.rmSync(externalDir, { recursive: true, force: true }); + } + }, 10000); + + it('should detect changes in scoped linked package in node_modules', async () => { + const externalDir = fs.mkdtempSync(path.join(TMP_DIR, 'watcher-scoped-npm-link-')); + let watcher: BuildWatcher | undefined; + + try { + const externalTargetFile = path.join(externalDir, 'index.ts'); + fs.writeFileSync(externalTargetFile, 'export const a = 1;'); + + const nodeModulesDir = path.join(tempDir, 'node_modules'); + const scopeDir = path.join(nodeModulesDir, '@my-scope'); + fs.mkdirSync(scopeDir, { recursive: true }); + + // Unimported package in scope + const unimportedScopedDir = path.join(scopeDir, 'unimported-scoped'); + fs.mkdirSync(unimportedScopedDir); + const unimportedFile = path.join(unimportedScopedDir, 'dep.ts'); + fs.writeFileSync(unimportedFile, 'export const dep = 1;'); + + // Linked scoped package in node_modules + const linkedPkgDir = path.join(scopeDir, 'linked-pkg'); + fs.symlinkSync(externalDir, linkedPkgDir, 'junction'); + const linkedFile = path.join(linkedPkgDir, 'index.ts'); + + watcher = await createWatcher({ + followSymlinks: true, + cwd: tempDir, + }); + + watcher.add(linkedFile); + await setTimeout(250); + + const iterator = watcher[Symbol.asyncIterator](); + const nextPromise = iterator.next(); + + fs.writeFileSync(unimportedFile, 'export const dep = 2;'); + fs.writeFileSync(externalTargetFile, 'export const a = 2;'); + + const result = await nextPromise; + expect(result.done).toBeFalsy(); + const changed = result.value?.all ?? []; + expect(changed.some((f: string) => f.includes('linked-pkg'))).toBeTrue(); + expect(changed.some((f: string) => f.includes('unimported-scoped'))).toBeFalse(); + } finally { + await watcher?.close(); + fs.rmSync(externalDir, { recursive: true, force: true }); + } + }, 10000); + + it('should detect changes in linked package added dynamically via watcher.add', async () => { + const externalDir = fs.mkdtempSync(path.join(TMP_DIR, 'watcher-dynamic-npm-link-')); + let watcher: BuildWatcher | undefined; + + try { + const externalTargetFile = path.join(externalDir, 'index.ts'); + fs.writeFileSync(externalTargetFile, 'export const a = 1;'); + + const nodeModulesDir = path.join(tempDir, 'node_modules'); + fs.mkdirSync(nodeModulesDir); + + const linkedPkgDir = path.join(nodeModulesDir, 'linked-pkg'); + fs.symlinkSync(externalDir, linkedPkgDir, 'junction'); + const linkedFile = path.join(linkedPkgDir, 'index.ts'); + + // Initially create watcher with no watchFiles + watcher = await createWatcher({ + followSymlinks: true, + cwd: tempDir, + }); + + // Add linked file dynamically after watcher creation + watcher.add(linkedFile); + await setTimeout(250); + + const iterator = watcher[Symbol.asyncIterator](); + const nextPromise = iterator.next(); + + fs.writeFileSync(externalTargetFile, 'export const a = 2;'); + + const result = await nextPromise; + expect(result.done).toBeFalsy(); + expect(result.value?.all.some((f: string) => f.includes('linked-pkg'))).toBeTrue(); + } finally { + await watcher?.close(); + fs.rmSync(externalDir, { recursive: true, force: true }); + } + }, 10000); + + it('should unwatch linked package directory when all its files are removed via watcher.remove', async () => { + const externalDir = fs.mkdtempSync(path.join(TMP_DIR, 'watcher-remove-npm-link-')); + let watcher: BuildWatcher | undefined; + + try { + const externalTargetFile = path.join(externalDir, 'index.ts'); + fs.writeFileSync(externalTargetFile, 'export const a = 1;'); + + const nodeModulesDir = path.join(tempDir, 'node_modules'); + fs.mkdirSync(nodeModulesDir); + + const linkedPkgDir = path.join(nodeModulesDir, 'linked-pkg'); + fs.symlinkSync(externalDir, linkedPkgDir, 'junction'); + const linkedFile = path.join(linkedPkgDir, 'index.ts'); + + const regularFile = path.join(tempDir, 'main.ts'); + fs.writeFileSync(regularFile, 'export const main = 1;'); + + watcher = await createWatcher({ + followSymlinks: true, + cwd: tempDir, + }); + + watcher.add([linkedFile, regularFile]); + // Allow a brief moment for Chokidar to register the new watch paths + await setTimeout(250); + + const iterator = watcher[Symbol.asyncIterator](); + + // Verify changes in the linked package are detected initially + let nextPromise = iterator.next(); + fs.writeFileSync(externalTargetFile, 'export const a = 2;'); + let result = await nextPromise; + expect(result.done).toBeFalsy(); + expect(result.value?.all.some((f: string) => f.includes('linked-pkg'))).toBeTrue(); + + // Remove the linked file from the watcher + watcher.remove(linkedFile); + // Allow a brief moment for Chokidar to asynchronously complete unwatching the package directory + await setTimeout(250); + + // Modify both the removed linked file and the regular file + nextPromise = iterator.next(); + fs.writeFileSync(externalTargetFile, 'export const a = 3;'); + fs.writeFileSync(regularFile, 'export const main = 2;'); + + result = await nextPromise; + expect(result.done).toBeFalsy(); + const changed = result.value?.all ?? []; + expect(changed.some((f: string) => f.includes('main.ts'))).toBeTrue(); + expect(changed.some((f: string) => f.includes('linked-pkg'))).toBeFalse(); + } finally { + await watcher?.close(); + fs.rmSync(externalDir, { recursive: true, force: true }); + } + }, 10000); }); }); From 663c580c86645b5b3a31925154427588e48018ba Mon Sep 17 00:00:00 2001 From: Maruthan G Date: Fri, 25 Sep 2026 09:46:41 +0000 Subject: [PATCH 030/233] fix(@schematics/angular): add browsers option to angular.json during vitest browser provider ng-add When adding a Vitest browser provider via ng-add, the schematic now automatically configures the 'browsers' option in angular.json with an appropriate default browser (chromium for Playwright/Preview, chrome for WebDriverIO) instead of only logging a manual instruction. Fixes #32401 (cherry picked from commit 05309443082bb2edc43b18da4f3e51d176d5b761) --- .../angular/vitest-browser/index.ts | 16 ++++- .../angular/vitest-browser/index_spec.ts | 70 ++++++++++++++----- 2 files changed, 64 insertions(+), 22 deletions(-) diff --git a/packages/schematics/angular/vitest-browser/index.ts b/packages/schematics/angular/vitest-browser/index.ts index 78c3bdc6179d..927ac81aa4f1 100644 --- a/packages/schematics/angular/vitest-browser/index.ts +++ b/packages/schematics/angular/vitest-browser/index.ts @@ -22,7 +22,7 @@ import { } from '../utility/dependency'; import { JSONFile } from '../utility/json-file'; import { latestVersions } from '../utility/latest-versions'; -import { getWorkspace } from '../utility/workspace'; +import { getWorkspace, updateWorkspace } from '../utility/workspace'; import { Builders } from '../utility/workspace-models'; import { Schema as VitestBrowserOptions } from './schema'; @@ -89,8 +89,19 @@ export default function (options: VitestBrowserOptions): Rule { } }; + // Update angular.json to add the browsers option to the test target + const defaultBrowser = packageName === '@vitest/browser-webdriverio' ? 'chrome' : 'chromium'; + return chain([ updateTsConfigRule, + updateWorkspace((workspace) => { + const testTarget = workspace.projects.get(options.project)?.targets.get('test'); + + if (testTarget) { + testTarget.options ??= {}; + testTarget.options['browsers'] ??= [defaultBrowser]; + } + }), ...dependencies.map((name) => addDependency(name, latestVersions[name], { type: DependencyType.Dev, @@ -101,8 +112,7 @@ export default function (options: VitestBrowserOptions): Rule { (_, context) => { context.logger.info( 'Vitest browser testing support has been added. ' + - "To run tests in a browser, add a 'browsers' field to the 'test' target in 'angular.json', " + - "or use the '--browsers' command line option.", + `The test target has been configured with '${defaultBrowser}' as browser.`, ); }, ]); diff --git a/packages/schematics/angular/vitest-browser/index_spec.ts b/packages/schematics/angular/vitest-browser/index_spec.ts index 9027742f73a9..83ac0a9d55a6 100644 --- a/packages/schematics/angular/vitest-browser/index_spec.ts +++ b/packages/schematics/angular/vitest-browser/index_spec.ts @@ -35,37 +35,69 @@ describe('Vitest Browser Provider Schematic', () => { ); }); - it('should add dependencies and update tsconfig.spec.json', async () => { - const options = { - project: 'app', - package: '@vitest/browser-playwright', - skipInstall: true, - }; + [ + { pkg: '@vitest/browser-playwright', browser: 'chromium', extraDeps: ['playwright'] }, + { pkg: '@vitest/browser-webdriverio', browser: 'chrome', extraDeps: ['webdriverio'] }, + { pkg: '@vitest/browser-preview', browser: 'chromium', extraDeps: [] as string[] }, + ].forEach(({ pkg, browser, extraDeps }) => { + it(`should add ${browser} to browsers option in angular.json for ${pkg}`, async () => { + const options = { + project: 'app', + package: pkg, + skipInstall: true, + }; - const resultTree = await schematicRunner.runSchematic('vitest-browser', options, tree); + const resultTree = await schematicRunner.runSchematic('vitest-browser', options, tree); - const packageJson = parse(resultTree.readContent('/package.json')); - expect(packageJson.devDependencies['@vitest/browser-playwright']).toBeDefined(); - expect(packageJson.devDependencies['playwright']).toBeDefined(); + const angularJson = parse(resultTree.readContent('/angular.json')); + const project = angularJson.projects.app; + const targets = project.architect || project.targets; + expect(targets.test.options.browsers).toEqual([browser]); + }); - const tsConfig = parse(resultTree.readContent('/projects/app/tsconfig.spec.json')); - expect(tsConfig.compilerOptions.types).toContain('vitest/globals'); - expect(tsConfig.compilerOptions.types).toContain('@vitest/browser-playwright'); - expect(tsConfig.compilerOptions.types).not.toContain('jasmine'); + it(`should add dependencies and update tsconfig.spec.json for ${pkg}`, async () => { + const options = { + project: 'app', + package: pkg, + skipInstall: true, + }; + + const resultTree = await schematicRunner.runSchematic('vitest-browser', options, tree); + + const packageJson = parse(resultTree.readContent('/package.json')); + expect(packageJson.devDependencies[pkg]).toBeDefined(); + for (const dep of extraDeps) { + expect(packageJson.devDependencies[dep]).toBeDefined(); + } + + const tsConfig = parse(resultTree.readContent('/projects/app/tsconfig.spec.json')); + expect(tsConfig.compilerOptions.types).toContain('vitest/globals'); + expect(tsConfig.compilerOptions.types).toContain(pkg); + expect(tsConfig.compilerOptions.types).not.toContain('jasmine'); + }); }); - it('should add webdriverio dependency when @vitest/browser-webdriverio is used', async () => { + it('should not overwrite existing browsers option in angular.json', async () => { + // Set up existing browsers option + const angularJson = parse(tree.readContent('/angular.json')); + const project = angularJson.projects.app; + const targets = project.architect || project.targets; + targets.test.options ??= {}; + targets.test.options.browsers = ['firefox']; + tree.overwrite('/angular.json', JSON.stringify(angularJson)); + const options = { project: 'app', - package: '@vitest/browser-webdriverio', + package: '@vitest/browser-playwright', skipInstall: true, }; const resultTree = await schematicRunner.runSchematic('vitest-browser', options, tree); - const packageJson = parse(resultTree.readContent('/package.json')); - expect(packageJson.devDependencies['@vitest/browser-webdriverio']).toBeDefined(); - expect(packageJson.devDependencies['webdriverio']).toBeDefined(); + const updatedAngularJson = parse(resultTree.readContent('/angular.json')); + const updatedProject = updatedAngularJson.projects.app; + const updatedTargets = updatedProject.architect || updatedProject.targets; + expect(updatedTargets.test.options.browsers).toEqual(['firefox']); }); it('should update tsconfig.spec.json for a library project', async () => { From c1b515418033685a9624140b5eecb6330ec07504 Mon Sep 17 00:00:00 2001 From: yoggydev <280342032+yoggydev@users.noreply.github.com> Date: Tue, 8 Sep 2026 13:49:39 +0900 Subject: [PATCH 031/233] fix(@angular/build): encode script type in auto-CSP loader createLoaderScript() interpolates four script attributes into the generated loader. integrity and crossOrigin are encoded with JSON.stringify and \u003c, but type is inserted directly into a single-quoted JavaScript string literal. The comment above the function states that type can only be 'module', a JS MIME type or an empty string, but isJavascriptMimeType() only compares the part before the first ';', so a value such as text/javascript; reaches the loader unchanged. A quote in that value closes the string literal, and a closing script tag terminates the generated element. Encode type the same way as its neighbours. Both branches of createLoaderScript() share srcListFormatted, so one change covers Trusted Types enabled and disabled. (cherry picked from commit 07e608dd27a44816ad0360ce47aa8ec31c03afec) --- .../build/src/utils/index-file/auto-csp.ts | 6 +- .../src/utils/index-file/auto-csp_spec.ts | 60 +++++++++++++++---- 2 files changed, 53 insertions(+), 13 deletions(-) diff --git a/packages/angular/build/src/utils/index-file/auto-csp.ts b/packages/angular/build/src/utils/index-file/auto-csp.ts index 5c1899015a7e..cd07fb821640 100644 --- a/packages/angular/build/src/utils/index-file/auto-csp.ts +++ b/packages/angular/build/src/utils/index-file/auto-csp.ts @@ -299,8 +299,10 @@ function createLoaderScript(srcList: SrcScriptTag[], enableTrustedTypes = false) .map((s) => { // URI encoding means value can't escape string, JS, or HTML context. const srcAttr = encodeURI(s.src).replaceAll("'", "\\'"); - // Can only be 'module' or a JS MIME type or an empty string. - const typeAttr = s.type ? "'" + s.type + "'" : "''"; + // 'module', a JS MIME type, or an empty string. A JS MIME type may carry + // parameters after a ';', which isJavascriptMimeType() does not constrain, + // so encode this the same way as integrity and crossOrigin below. + const typeAttr = JSON.stringify(s.type ?? '').replaceAll('<', '\\u003c'); const asyncAttr = !!s.async; const deferAttr = !!s.defer; const integrityAttr = JSON.stringify(s.integrity ?? null).replaceAll('<', '\\u003c'); diff --git a/packages/angular/build/src/utils/index-file/auto-csp_spec.ts b/packages/angular/build/src/utils/index-file/auto-csp_spec.ts index 4fe2888efa42..037ab605253a 100644 --- a/packages/angular/build/src/utils/index-file/auto-csp_spec.ts +++ b/packages/angular/build/src/utils/index-file/auto-csp_spec.ts @@ -58,7 +58,7 @@ describe('auto-csp', () => { const csps = getCsps(result); expect(csps).toHaveSize(1); expect(csps[0]).toMatch(CSP_SINGLE_HASH_REGEX); - expect(result).toContain(`const scripts = [['./main.js', '', false, false, null, null]];`); + expect(result).toContain(`const scripts = [['./main.js', "", false, false, null, null]];`); }); it('should rewrite a single source script in place', async () => { @@ -78,7 +78,7 @@ describe('auto-csp', () => { expect(csps[0]).toMatch(CSP_SINGLE_HASH_REGEX); // Our loader script appears after the HTML text content. expect(result).toMatch( - /Some text<\/div>\s*`); @@ -166,12 +166,12 @@ describe('auto-csp', () => { // Loader script for main.js and main2.js appear after 'foo' and before 'bar'. expect(result).toMatch( // eslint-disable-next-line max-len - /console.log\('foo'\);<\/script>\s* + + + `); + + const csps = getCsps(result); + expect(csps).toHaveSize(1); + expect(csps[0]).toMatch(CSP_SINGLE_HASH_REGEX); + // The type stays inside its string literal. + expect(result).toContain( + `const scripts = [['./main.js', "text/javascript;']];var x=1;var junk=[['a','b", false, false, null, null]];`, + ); + }); + + it('should encode a script type that contains a closing script tag', async () => { + const result = await autoCsp(` + + + + + + + + `); + + const csps = getCsps(result); + expect(csps).toHaveSize(1); + expect(csps[0]).toMatch(CSP_SINGLE_HASH_REGEX); + // Only the loader element is emitted. + expect(Array.from(result.matchAll(/'); expect(result).toContain(``); }); + + it('should add the nonce expression to stylesheet and modulepreload link tags', async () => { + const result = await addNonce(` + + + + + + + + + + + `); + + expect(result).toContain(''); + expect(result).toContain(''); + expect(result).toContain(''); + }); + + it('should add the nonce expression when link rel has mixed case or multiple tokens', async () => { + const result = await addNonce(` + + + + + + + + + + `); + + expect(result).toContain(''); + expect(result).toContain(''); + }); }); diff --git a/packages/angular_devkit/build_angular/src/builders/app-shell/app-shell_spec.ts b/packages/angular_devkit/build_angular/src/builders/app-shell/app-shell_spec.ts index d4a470935d10..f39d8da34114 100644 --- a/packages/angular_devkit/build_angular/src/builders/app-shell/app-shell_spec.ts +++ b/packages/angular_devkit/build_angular/src/builders/app-shell/app-shell_spec.ts @@ -195,7 +195,7 @@ describe('AppShell Builder', () => { expect(content).toContain(''); expect(content).toMatch( - //, + //, ); }); }); From a5d5c5c349646533b433cf110947d718a84bbe86 Mon Sep 17 00:00:00 2001 From: Angular Robot Date: Thu, 8 Oct 2026 18:40:04 +0000 Subject: [PATCH 078/233] build: update cross-repo angular dependencies to v22.2.2 See associated pull request for more information. --- package.json | 22 +-- packages/angular/ssr/package.json | 12 +- packages/ngtools/webpack/package.json | 4 +- pnpm-lock.yaml | 258 +++++++++++++------------- 4 files changed, 148 insertions(+), 148 deletions(-) diff --git a/package.json b/package.json index e879887066b0..885a0a81ef48 100644 --- a/package.json +++ b/package.json @@ -43,23 +43,23 @@ }, "homepage": "https://github.com/angular/angular-cli", "dependencies": { - "@angular/compiler-cli": "22.2.1", + "@angular/compiler-cli": "22.2.2", "typescript": "6.0.3" }, "devDependencies": { - "@angular/animations": "22.2.1", + "@angular/animations": "22.2.2", "@angular/cdk": "22.2.2", - "@angular/common": "22.2.1", - "@angular/compiler": "22.2.1", - "@angular/core": "22.2.1", - "@angular/forms": "22.2.1", - "@angular/localize": "22.2.1", + "@angular/common": "22.2.2", + "@angular/compiler": "22.2.2", + "@angular/core": "22.2.2", + "@angular/forms": "22.2.2", + "@angular/localize": "22.2.2", "@angular/material": "22.2.2", "@angular/ng-dev": "https://github.com/angular/dev-infra-private-ng-dev-builds.git#89b8c002e5d47ba1cbc4483d3ec06b0ae0aaccb7", - "@angular/platform-browser": "22.2.1", - "@angular/platform-server": "22.2.1", - "@angular/router": "22.2.1", - "@angular/service-worker": "22.2.1", + "@angular/platform-browser": "22.2.2", + "@angular/platform-server": "22.2.2", + "@angular/router": "22.2.2", + "@angular/service-worker": "22.2.2", "@babel/core": "8.0.5", "@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 0dc12b4d8a6e..d2cbb89d35b6 100644 --- a/packages/angular/ssr/package.json +++ b/packages/angular/ssr/package.json @@ -38,12 +38,12 @@ }, "devDependencies": { "@angular-devkit/schematics": "workspace:*", - "@angular/common": "22.2.1", - "@angular/compiler": "22.2.1", - "@angular/core": "22.2.1", - "@angular/platform-browser": "22.2.1", - "@angular/platform-server": "22.2.1", - "@angular/router": "22.2.1", + "@angular/common": "22.2.2", + "@angular/compiler": "22.2.2", + "@angular/core": "22.2.2", + "@angular/platform-browser": "22.2.2", + "@angular/platform-server": "22.2.2", + "@angular/router": "22.2.2", "@schematics/angular": "workspace:*" }, "sideEffects": false, diff --git a/packages/ngtools/webpack/package.json b/packages/ngtools/webpack/package.json index 0612a8ed7202..4aa72955bcbb 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.1", - "@angular/compiler-cli": "22.2.1", + "@angular/compiler": "22.2.2", + "@angular/compiler-cli": "22.2.2", "typescript": "6.0.3", "webpack": "5.111.0" } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 11f6972f9bf3..8c98e54f3942 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -172,8 +172,8 @@ importers: .: dependencies: '@angular/compiler-cli': - specifier: 22.2.1 - version: 22.2.1(@angular/compiler@22.2.1)(typescript@6.0.3) + specifier: 22.2.2 + version: 22.2.2(@angular/compiler@22.2.2)(typescript@6.0.3) typescript: specifier: 6.0.3 version: 6.0.3 @@ -184,44 +184,44 @@ importers: built: true devDependencies: '@angular/animations': - specifier: 22.2.1 - version: 22.2.1(@angular/core@22.2.1(@angular/compiler@22.2.1)(rxjs@7.8.2)(zone.js@0.16.3)) + specifier: 22.2.2 + version: 22.2.2(@angular/core@22.2.2(@angular/compiler@22.2.2)(rxjs@7.8.2)(zone.js@0.16.3)) '@angular/cdk': specifier: 22.2.2 - version: 22.2.2(539f1c0d474fe13b108bca94cc3bd7b4) + version: 22.2.2(a2e0e17c73c6aceb9301ae9aaf890120) '@angular/common': - specifier: 22.2.1 - version: 22.2.1(@angular/core@22.2.1(@angular/compiler@22.2.1)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2) + specifier: 22.2.2 + version: 22.2.2(@angular/core@22.2.2(@angular/compiler@22.2.2)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2) '@angular/compiler': - specifier: 22.2.1 - version: 22.2.1 + specifier: 22.2.2 + version: 22.2.2 '@angular/core': - specifier: 22.2.1 - version: 22.2.1(@angular/compiler@22.2.1)(rxjs@7.8.2)(zone.js@0.16.3) + specifier: 22.2.2 + version: 22.2.2(@angular/compiler@22.2.2)(rxjs@7.8.2)(zone.js@0.16.3) '@angular/forms': - specifier: 22.2.1 - version: 22.2.1(@angular/common@22.2.1(@angular/core@22.2.1(@angular/compiler@22.2.1)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2))(@angular/core@22.2.1(@angular/compiler@22.2.1)(rxjs@7.8.2)(zone.js@0.16.3))(@angular/platform-browser@22.2.1(@angular/animations@22.2.1(@angular/core@22.2.1(@angular/compiler@22.2.1)(rxjs@7.8.2)(zone.js@0.16.3)))(@angular/common@22.2.1(@angular/core@22.2.1(@angular/compiler@22.2.1)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2))(@angular/core@22.2.1(@angular/compiler@22.2.1)(rxjs@7.8.2)(zone.js@0.16.3)))(rxjs@7.8.2) + specifier: 22.2.2 + version: 22.2.2(@angular/common@22.2.2(@angular/core@22.2.2(@angular/compiler@22.2.2)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2))(@angular/core@22.2.2(@angular/compiler@22.2.2)(rxjs@7.8.2)(zone.js@0.16.3))(@angular/platform-browser@22.2.2(@angular/animations@22.2.2(@angular/core@22.2.2(@angular/compiler@22.2.2)(rxjs@7.8.2)(zone.js@0.16.3)))(@angular/common@22.2.2(@angular/core@22.2.2(@angular/compiler@22.2.2)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2))(@angular/core@22.2.2(@angular/compiler@22.2.2)(rxjs@7.8.2)(zone.js@0.16.3)))(rxjs@7.8.2) '@angular/localize': - specifier: 22.2.1 - version: 22.2.1(@angular/compiler-cli@22.2.1(@angular/compiler@22.2.1)(typescript@6.0.3))(@angular/compiler@22.2.1) + specifier: 22.2.2 + version: 22.2.2(@angular/compiler-cli@22.2.2(@angular/compiler@22.2.2)(typescript@6.0.3))(@angular/compiler@22.2.2) '@angular/material': specifier: 22.2.2 - version: 22.2.2(aa0c13a53721943fac231579df95cd0b) + version: 22.2.2(641510506f6736c740497081311accfd) '@angular/ng-dev': specifier: https://github.com/angular/dev-infra-private-ng-dev-builds.git#89b8c002e5d47ba1cbc4483d3ec06b0ae0aaccb7 version: https://codeload.github.com/angular/dev-infra-private-ng-dev-builds/tar.gz/89b8c002e5d47ba1cbc4483d3ec06b0ae0aaccb7 '@angular/platform-browser': - specifier: 22.2.1 - version: 22.2.1(@angular/animations@22.2.1(@angular/core@22.2.1(@angular/compiler@22.2.1)(rxjs@7.8.2)(zone.js@0.16.3)))(@angular/common@22.2.1(@angular/core@22.2.1(@angular/compiler@22.2.1)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2))(@angular/core@22.2.1(@angular/compiler@22.2.1)(rxjs@7.8.2)(zone.js@0.16.3)) + specifier: 22.2.2 + version: 22.2.2(@angular/animations@22.2.2(@angular/core@22.2.2(@angular/compiler@22.2.2)(rxjs@7.8.2)(zone.js@0.16.3)))(@angular/common@22.2.2(@angular/core@22.2.2(@angular/compiler@22.2.2)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2))(@angular/core@22.2.2(@angular/compiler@22.2.2)(rxjs@7.8.2)(zone.js@0.16.3)) '@angular/platform-server': - specifier: 22.2.1 - version: 22.2.1(@angular/common@22.2.1(@angular/core@22.2.1(@angular/compiler@22.2.1)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2))(@angular/compiler@22.2.1)(@angular/core@22.2.1(@angular/compiler@22.2.1)(rxjs@7.8.2)(zone.js@0.16.3))(@angular/platform-browser@22.2.1(@angular/animations@22.2.1(@angular/core@22.2.1(@angular/compiler@22.2.1)(rxjs@7.8.2)(zone.js@0.16.3)))(@angular/common@22.2.1(@angular/core@22.2.1(@angular/compiler@22.2.1)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2))(@angular/core@22.2.1(@angular/compiler@22.2.1)(rxjs@7.8.2)(zone.js@0.16.3)))(rxjs@7.8.2) + specifier: 22.2.2 + version: 22.2.2(@angular/common@22.2.2(@angular/core@22.2.2(@angular/compiler@22.2.2)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2))(@angular/compiler@22.2.2)(@angular/core@22.2.2(@angular/compiler@22.2.2)(rxjs@7.8.2)(zone.js@0.16.3))(@angular/platform-browser@22.2.2(@angular/animations@22.2.2(@angular/core@22.2.2(@angular/compiler@22.2.2)(rxjs@7.8.2)(zone.js@0.16.3)))(@angular/common@22.2.2(@angular/core@22.2.2(@angular/compiler@22.2.2)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2))(@angular/core@22.2.2(@angular/compiler@22.2.2)(rxjs@7.8.2)(zone.js@0.16.3)))(rxjs@7.8.2) '@angular/router': - specifier: 22.2.1 - version: 22.2.1(@angular/common@22.2.1(@angular/core@22.2.1(@angular/compiler@22.2.1)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2))(@angular/core@22.2.1(@angular/compiler@22.2.1)(rxjs@7.8.2)(zone.js@0.16.3))(@angular/platform-browser@22.2.1(@angular/animations@22.2.1(@angular/core@22.2.1(@angular/compiler@22.2.1)(rxjs@7.8.2)(zone.js@0.16.3)))(@angular/common@22.2.1(@angular/core@22.2.1(@angular/compiler@22.2.1)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2))(@angular/core@22.2.1(@angular/compiler@22.2.1)(rxjs@7.8.2)(zone.js@0.16.3)))(rxjs@7.8.2) + specifier: 22.2.2 + version: 22.2.2(@angular/common@22.2.2(@angular/core@22.2.2(@angular/compiler@22.2.2)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2))(@angular/core@22.2.2(@angular/compiler@22.2.2)(rxjs@7.8.2)(zone.js@0.16.3))(@angular/platform-browser@22.2.2(@angular/animations@22.2.2(@angular/core@22.2.2(@angular/compiler@22.2.2)(rxjs@7.8.2)(zone.js@0.16.3)))(@angular/common@22.2.2(@angular/core@22.2.2(@angular/compiler@22.2.2)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2))(@angular/core@22.2.2(@angular/compiler@22.2.2)(rxjs@7.8.2)(zone.js@0.16.3)))(rxjs@7.8.2) '@angular/service-worker': - specifier: 22.2.1 - version: 22.2.1(@angular/core@22.2.1(@angular/compiler@22.2.1)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2) + specifier: 22.2.2 + version: 22.2.2(@angular/core@22.2.2(@angular/compiler@22.2.2)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2) '@babel/core': specifier: 8.0.5 version: 8.0.5 @@ -464,7 +464,7 @@ importers: version: 30.0.1(@noble/hashes@1.8.0) ng-packagr: specifier: 22.2.4 - version: 22.2.4(@angular/compiler-cli@22.2.1(@angular/compiler@22.2.1)(typescript@6.0.3))(supports-color@11.0.0)(tslib@2.8.1)(typescript@6.0.3) + version: 22.2.4(@angular/compiler-cli@22.2.2(@angular/compiler@22.2.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 @@ -579,7 +579,7 @@ importers: version: 4.9.1(supports-color@11.0.0) ng-packagr: specifier: 22.2.4 - version: 22.2.4(@angular/compiler-cli@22.2.1(@angular/compiler@22.2.1)(typescript@6.0.3))(supports-color@11.0.0)(tslib@2.8.1)(typescript@6.0.3) + version: 22.2.4(@angular/compiler-cli@22.2.2(@angular/compiler@22.2.2)(typescript@6.0.3))(supports-color@11.0.0)(tslib@2.8.1)(typescript@6.0.3) postcss: specifier: 8.5.28 version: 8.5.28 @@ -667,23 +667,23 @@ importers: specifier: workspace:* version: link:../../angular_devkit/schematics '@angular/common': - specifier: 22.2.1 - version: 22.2.1(@angular/core@22.2.1(@angular/compiler@22.2.1)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2) + specifier: 22.2.2 + version: 22.2.2(@angular/core@22.2.2(@angular/compiler@22.2.2)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2) '@angular/compiler': - specifier: 22.2.1 - version: 22.2.1 + specifier: 22.2.2 + version: 22.2.2 '@angular/core': - specifier: 22.2.1 - version: 22.2.1(@angular/compiler@22.2.1)(rxjs@7.8.2)(zone.js@0.16.3) + specifier: 22.2.2 + version: 22.2.2(@angular/compiler@22.2.2)(rxjs@7.8.2)(zone.js@0.16.3) '@angular/platform-browser': - specifier: 22.2.1 - version: 22.2.1(@angular/animations@22.2.1(@angular/core@22.2.1(@angular/compiler@22.2.1)(rxjs@7.8.2)(zone.js@0.16.3)))(@angular/common@22.2.1(@angular/core@22.2.1(@angular/compiler@22.2.1)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2))(@angular/core@22.2.1(@angular/compiler@22.2.1)(rxjs@7.8.2)(zone.js@0.16.3)) + specifier: 22.2.2 + version: 22.2.2(@angular/animations@22.2.2(@angular/core@22.2.2(@angular/compiler@22.2.2)(rxjs@7.8.2)(zone.js@0.16.3)))(@angular/common@22.2.2(@angular/core@22.2.2(@angular/compiler@22.2.2)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2))(@angular/core@22.2.2(@angular/compiler@22.2.2)(rxjs@7.8.2)(zone.js@0.16.3)) '@angular/platform-server': - specifier: 22.2.1 - version: 22.2.1(@angular/common@22.2.1(@angular/core@22.2.1(@angular/compiler@22.2.1)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2))(@angular/compiler@22.2.1)(@angular/core@22.2.1(@angular/compiler@22.2.1)(rxjs@7.8.2)(zone.js@0.16.3))(@angular/platform-browser@22.2.1(@angular/animations@22.2.1(@angular/core@22.2.1(@angular/compiler@22.2.1)(rxjs@7.8.2)(zone.js@0.16.3)))(@angular/common@22.2.1(@angular/core@22.2.1(@angular/compiler@22.2.1)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2))(@angular/core@22.2.1(@angular/compiler@22.2.1)(rxjs@7.8.2)(zone.js@0.16.3)))(rxjs@7.8.2) + specifier: 22.2.2 + version: 22.2.2(@angular/common@22.2.2(@angular/core@22.2.2(@angular/compiler@22.2.2)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2))(@angular/compiler@22.2.2)(@angular/core@22.2.2(@angular/compiler@22.2.2)(rxjs@7.8.2)(zone.js@0.16.3))(@angular/platform-browser@22.2.2(@angular/animations@22.2.2(@angular/core@22.2.2(@angular/compiler@22.2.2)(rxjs@7.8.2)(zone.js@0.16.3)))(@angular/common@22.2.2(@angular/core@22.2.2(@angular/compiler@22.2.2)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2))(@angular/core@22.2.2(@angular/compiler@22.2.2)(rxjs@7.8.2)(zone.js@0.16.3)))(rxjs@7.8.2) '@angular/router': - specifier: 22.2.1 - version: 22.2.1(@angular/common@22.2.1(@angular/core@22.2.1(@angular/compiler@22.2.1)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2))(@angular/core@22.2.1(@angular/compiler@22.2.1)(rxjs@7.8.2)(zone.js@0.16.3))(@angular/platform-browser@22.2.1(@angular/animations@22.2.1(@angular/core@22.2.1(@angular/compiler@22.2.1)(rxjs@7.8.2)(zone.js@0.16.3)))(@angular/common@22.2.1(@angular/core@22.2.1(@angular/compiler@22.2.1)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2))(@angular/core@22.2.1(@angular/compiler@22.2.1)(rxjs@7.8.2)(zone.js@0.16.3)))(rxjs@7.8.2) + specifier: 22.2.2 + version: 22.2.2(@angular/common@22.2.2(@angular/core@22.2.2(@angular/compiler@22.2.2)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2))(@angular/core@22.2.2(@angular/compiler@22.2.2)(rxjs@7.8.2)(zone.js@0.16.3))(@angular/platform-browser@22.2.2(@angular/animations@22.2.2(@angular/core@22.2.2(@angular/compiler@22.2.2)(rxjs@7.8.2)(zone.js@0.16.3)))(@angular/common@22.2.2(@angular/core@22.2.2(@angular/compiler@22.2.2)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2))(@angular/core@22.2.2(@angular/compiler@22.2.2)(rxjs@7.8.2)(zone.js@0.16.3)))(rxjs@7.8.2) '@schematics/angular': specifier: workspace:* version: link:../../schematics/angular @@ -867,7 +867,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.4 - version: 22.2.4(@angular/compiler-cli@22.2.1(@angular/compiler@22.2.1)(typescript@6.0.3))(supports-color@11.0.0)(tslib@2.8.1)(typescript@6.0.3) + version: 22.2.4(@angular/compiler-cli@22.2.2(@angular/compiler@22.2.2)(typescript@6.0.3))(supports-color@11.0.0)(tslib@2.8.1)(typescript@6.0.3) sass: specifier: 1.104.1 version: 1.104.1 @@ -962,11 +962,11 @@ importers: specifier: workspace:0.0.0-PLACEHOLDER version: link:../../angular_devkit/core '@angular/compiler': - specifier: 22.2.1 - version: 22.2.1 + specifier: 22.2.2 + version: 22.2.2 '@angular/compiler-cli': - specifier: 22.2.1 - version: 22.2.1(@angular/compiler@22.2.1)(typescript@6.0.3) + specifier: 22.2.2 + version: 22.2.2(@angular/compiler@22.2.2)(typescript@6.0.3) typescript: specifier: 6.0.3 version: 6.0.3 @@ -1026,12 +1026,12 @@ packages: resolution: {integrity: sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==} engines: {node: '>=6.0.0'} - '@angular/animations@22.2.1': - resolution: {integrity: sha512-vTxZN6uL/m61lv7ZCvfmQ3VuFb4o/tniGLpc3SpkNHE6MLM8WN0IjfNBRLMYMovd1uUBSPwhcG4Llcmucr9dmw==} + '@angular/animations@22.2.2': + resolution: {integrity: sha512-N2VTjsH9xHGWsKlyeWrODcp4b2UEkrT/lGkHMxL4yr+ie0sKpxtZzzwzOQMMCRyv39ff2sfPQjb7q56K8RZ78w==} 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.1 + '@angular/core': 22.2.2 '@angular/cdk@22.2.2': resolution: {integrity: sha512-d5PWfIargIEV0rlwZea2pYDGb8FhF9df6a6XFRLThla6NKiJRs8utqW+7pyY9wCPFR3SSCGHC05xFh7qv91hdw==} @@ -1042,33 +1042,33 @@ packages: '@angular/platform-browser': ^22.0.0 || ^23.0.0 rxjs: ^6.5.3 || ^7.4.0 - '@angular/common@22.2.1': - resolution: {integrity: sha512-OqBH3EY4i8e3PvnYDugZGipSs1HWs2ZrqoClndKtFDS9mQULSSuLoxjG9nF1J/c+yUqhuyZlHjkXWS0n32pEfw==} + '@angular/common@22.2.2': + resolution: {integrity: sha512-d+mbF1UQLpsoJiC7h4pl58G7XeLHKU8DdLbq9u7TuOK0AnC1t2rrphi8M8WqUrZ+bfmFKCU4i1i4+vOF1N5GtA==} engines: {node: ^22.22.3 || ^24.15.0 || >=26.0.0} peerDependencies: - '@angular/core': 22.2.1 + '@angular/core': 22.2.2 rxjs: ^6.5.3 || ^7.4.0 - '@angular/compiler-cli@22.2.1': - resolution: {integrity: sha512-Nh8sCBl0JF6x+H7/1hemY76JeTRC66EfMULT4B3ryF9srRSLYc6X6RfPRtYvrIyjgr6h3jZgrNHlV76wiJaOcA==} + '@angular/compiler-cli@22.2.2': + resolution: {integrity: sha512-7PCIBTVIzG4oyAkDeBRPJpGcgSDLBCKn+2Pp9+gXnXOEETdWhV34so1fpWZ2GWBZsxXav7Ry0K93vFwF93yWoQ==} engines: {node: ^22.22.3 || ^24.15.0 || >=26.0.0} hasBin: true peerDependencies: - '@angular/compiler': 22.2.1 + '@angular/compiler': 22.2.2 typescript: '>=6.0 <6.1' peerDependenciesMeta: typescript: optional: true - '@angular/compiler@22.2.1': - resolution: {integrity: sha512-KRSz0c/T5eEiFa+F1l9OppAebJj9pT8kU3ArBMlxR3v/vzhpCfuQsFVQ4xEFC7dEm3zZIdv9ASKAP6ocNC4D/Q==} + '@angular/compiler@22.2.2': + resolution: {integrity: sha512-hg8Kvhq29w97vs3O5KsSeqA+oobrAKpr/GvsWBIqjRzfrxxeFdjRRoEv1/MVgMSJK36VLigNCjB1qPF3MB17uA==} engines: {node: ^22.22.3 || ^24.15.0 || >=26.0.0} - '@angular/core@22.2.1': - resolution: {integrity: sha512-a8WlYTRiaMPz1KvLE5xjeWrLyZUuQX8bh6Ak7zajUci9iWsTUQefschjSwP1WKlin3JhM3XjmsTEDyZvSLIfRg==} + '@angular/core@22.2.2': + resolution: {integrity: sha512-mFiSoAs7Gp/7VlbdSxDyV2I/FEyYeNZRaHH7QrMWSB9t+k7wm37uCaYOt9fy6fgXU/UbCgBESp09fV9bUTQcmA==} engines: {node: ^22.22.3 || ^24.15.0 || >=26.0.0} peerDependencies: - '@angular/compiler': 22.2.1 + '@angular/compiler': 22.2.2 rxjs: ^6.5.3 || ^7.4.0 zone.js: ~0.15.0 || ~0.16.0 peerDependenciesMeta: @@ -1077,22 +1077,22 @@ packages: zone.js: optional: true - '@angular/forms@22.2.1': - resolution: {integrity: sha512-xHM+PhrvYDJ+edPxh6PWhkE99tXWbsMcxdXCWF6QcyByX+bsW2rVlNZ7dumOsUle9MYa8Yj0lZFACUWbwFw+4w==} + '@angular/forms@22.2.2': + resolution: {integrity: sha512-Fgh+EnDoULSFzuDy44da/5Chi+4Sd2Qc4SLjFj23bktvMJ1yfuBPWkvpR9xgWg9Auq+9x84wJVK6WyNwIjXYWA==} engines: {node: ^22.22.3 || ^24.15.0 || >=26.0.0} peerDependencies: - '@angular/common': 22.2.1 - '@angular/core': 22.2.1 - '@angular/platform-browser': 22.2.1 + '@angular/common': 22.2.2 + '@angular/core': 22.2.2 + '@angular/platform-browser': 22.2.2 rxjs: ^6.5.3 || ^7.4.0 - '@angular/localize@22.2.1': - resolution: {integrity: sha512-fJ3GKhHQbCijcyjTpZsL+2MjVcFWXcJU0jOFlUKrBR3msWYcsF0gCjrPEcJXNlouUKBlC+2dlm9xnjqs2MUy6g==} + '@angular/localize@22.2.2': + resolution: {integrity: sha512-pHahnD4xcv5Znsg/JY6eRtG6FEhe1E2pSqaoxeGfDoMZOp2GZq0+7zhzHE6oq2eXqQcSMIlUAWFXMH/KByNqDw==} engines: {node: ^22.22.3 || ^24.15.0 || >=26.0.0} hasBin: true peerDependencies: - '@angular/compiler': 22.2.1 - '@angular/compiler-cli': 22.2.1 + '@angular/compiler': 22.2.2 + '@angular/compiler-cli': 22.2.2 '@angular/material@22.2.2': resolution: {integrity: sha512-G8nnt6yO7z64yZZbeF0l0fSztgZYv1TBFdGlexweyPfBlRn7N2X14Uv/TWht46vrXvExGuZOiR3c05XELd80fw==} @@ -1109,42 +1109,42 @@ packages: version: 0.0.0-8b6cbbca278a26f2495275c5d9d0d8633573162d hasBin: true - '@angular/platform-browser@22.2.1': - resolution: {integrity: sha512-KQ3oguemaSqyNP00yqEvPouY7NC4Lji+6S8yfjaWaUZjSth/GckpeP/Fo9HtMqd04y6MZ6lEb2hbQtTqFcSdEQ==} + '@angular/platform-browser@22.2.2': + resolution: {integrity: sha512-DnAyZTLty5bVNeDhcSPNQABqb9SmNvYfYhvgU3dKoGEpONrrECfYo/X4MN0g7Z9Dn/DkgBCNRoC9AZWxbO9HDQ==} engines: {node: ^22.22.3 || ^24.15.0 || >=26.0.0} peerDependencies: - '@angular/animations': 22.2.1 - '@angular/common': 22.2.1 - '@angular/core': 22.2.1 + '@angular/animations': 22.2.2 + '@angular/common': 22.2.2 + '@angular/core': 22.2.2 peerDependenciesMeta: '@angular/animations': optional: true - '@angular/platform-server@22.2.1': - resolution: {integrity: sha512-nnk4wuwI0u6AmMZpmpQXvJic+aFwG7+tkoWMtAr9kY2V9yl/WZIOhk8r4QtYHOzmxT3k7YRIpQ4BOlIg+jUXNw==} + '@angular/platform-server@22.2.2': + resolution: {integrity: sha512-CBqkqtkpIkEAtKJBRSplgBlWzNe2CMsbIZ4FFOPh9uHzBTmztA/D/QXqZKgnHLSP79FUmGjzrBizpk8fo9oVSg==} engines: {node: ^22.22.3 || ^24.15.0 || >=26.0.0} peerDependencies: - '@angular/common': 22.2.1 - '@angular/compiler': 22.2.1 - '@angular/core': 22.2.1 - '@angular/platform-browser': 22.2.1 + '@angular/common': 22.2.2 + '@angular/compiler': 22.2.2 + '@angular/core': 22.2.2 + '@angular/platform-browser': 22.2.2 rxjs: ^6.5.3 || ^7.4.0 - '@angular/router@22.2.1': - resolution: {integrity: sha512-HJfJ4yA1znKd9YFtbDOJfKmD12x0PhS7LkmYdWlJRu2WkQZRBVrdGKdmbvV5UvrqCRllVWKpzw1TIZJM69rlcw==} + '@angular/router@22.2.2': + resolution: {integrity: sha512-45HP/henqbPRTCBHzwF4ZV8JU75u2TmBMR4BtwcXcKF5SWragKWE0rMz4NpHnCQIy3bIy5SVTvawpf7EJ/kRyw==} engines: {node: ^22.22.3 || ^24.15.0 || >=26.0.0} peerDependencies: - '@angular/common': 22.2.1 - '@angular/core': 22.2.1 - '@angular/platform-browser': 22.2.1 + '@angular/common': 22.2.2 + '@angular/core': 22.2.2 + '@angular/platform-browser': 22.2.2 rxjs: ^6.5.3 || ^7.4.0 - '@angular/service-worker@22.2.1': - resolution: {integrity: sha512-qV08BnwR7xDZ3tl9nCeG7veIuPHzXFUf5a2RDJWnhvop+yLh0cWknS7nmjQ966F3DTB+Zk2veQ6qRvI0+29dfA==} + '@angular/service-worker@22.2.2': + resolution: {integrity: sha512-60Knjdvr80OSsqUQ7LYc+ibeLN495uj+loeCdmowO4DvKyoPFlW/KW7sKZq7OuZcnKIln+ujHNViYxs4wf23zQ==} engines: {node: ^22.22.3 || ^24.15.0 || >=26.0.0} hasBin: true peerDependencies: - '@angular/core': 22.2.1 + '@angular/core': 22.2.2 rxjs: ^6.5.3 || ^7.4.0 '@asamuzakjp/css-color@6.0.7': @@ -8700,30 +8700,30 @@ snapshots: '@jridgewell/gen-mapping': 0.3.13 '@jridgewell/trace-mapping': 0.3.31 - '@angular/animations@22.2.1(@angular/core@22.2.1(@angular/compiler@22.2.1)(rxjs@7.8.2)(zone.js@0.16.3))': + '@angular/animations@22.2.2(@angular/core@22.2.2(@angular/compiler@22.2.2)(rxjs@7.8.2)(zone.js@0.16.3))': dependencies: - '@angular/core': 22.2.1(@angular/compiler@22.2.1)(rxjs@7.8.2)(zone.js@0.16.3) + '@angular/core': 22.2.2(@angular/compiler@22.2.2)(rxjs@7.8.2)(zone.js@0.16.3) tslib: 2.8.1 - '@angular/cdk@22.2.2(539f1c0d474fe13b108bca94cc3bd7b4)': + '@angular/cdk@22.2.2(a2e0e17c73c6aceb9301ae9aaf890120)': dependencies: - '@angular/common': 22.2.1(@angular/core@22.2.1(@angular/compiler@22.2.1)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2) - '@angular/core': 22.2.1(@angular/compiler@22.2.1)(rxjs@7.8.2)(zone.js@0.16.3) - '@angular/forms': 22.2.1(@angular/common@22.2.1(@angular/core@22.2.1(@angular/compiler@22.2.1)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2))(@angular/core@22.2.1(@angular/compiler@22.2.1)(rxjs@7.8.2)(zone.js@0.16.3))(@angular/platform-browser@22.2.1(@angular/animations@22.2.1(@angular/core@22.2.1(@angular/compiler@22.2.1)(rxjs@7.8.2)(zone.js@0.16.3)))(@angular/common@22.2.1(@angular/core@22.2.1(@angular/compiler@22.2.1)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2))(@angular/core@22.2.1(@angular/compiler@22.2.1)(rxjs@7.8.2)(zone.js@0.16.3)))(rxjs@7.8.2) - '@angular/platform-browser': 22.2.1(@angular/animations@22.2.1(@angular/core@22.2.1(@angular/compiler@22.2.1)(rxjs@7.8.2)(zone.js@0.16.3)))(@angular/common@22.2.1(@angular/core@22.2.1(@angular/compiler@22.2.1)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2))(@angular/core@22.2.1(@angular/compiler@22.2.1)(rxjs@7.8.2)(zone.js@0.16.3)) + '@angular/common': 22.2.2(@angular/core@22.2.2(@angular/compiler@22.2.2)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2) + '@angular/core': 22.2.2(@angular/compiler@22.2.2)(rxjs@7.8.2)(zone.js@0.16.3) + '@angular/forms': 22.2.2(@angular/common@22.2.2(@angular/core@22.2.2(@angular/compiler@22.2.2)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2))(@angular/core@22.2.2(@angular/compiler@22.2.2)(rxjs@7.8.2)(zone.js@0.16.3))(@angular/platform-browser@22.2.2(@angular/animations@22.2.2(@angular/core@22.2.2(@angular/compiler@22.2.2)(rxjs@7.8.2)(zone.js@0.16.3)))(@angular/common@22.2.2(@angular/core@22.2.2(@angular/compiler@22.2.2)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2))(@angular/core@22.2.2(@angular/compiler@22.2.2)(rxjs@7.8.2)(zone.js@0.16.3)))(rxjs@7.8.2) + '@angular/platform-browser': 22.2.2(@angular/animations@22.2.2(@angular/core@22.2.2(@angular/compiler@22.2.2)(rxjs@7.8.2)(zone.js@0.16.3)))(@angular/common@22.2.2(@angular/core@22.2.2(@angular/compiler@22.2.2)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2))(@angular/core@22.2.2(@angular/compiler@22.2.2)(rxjs@7.8.2)(zone.js@0.16.3)) parse5: 8.0.1 rxjs: 7.8.2 tslib: 2.8.1 - '@angular/common@22.2.1(@angular/core@22.2.1(@angular/compiler@22.2.1)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2)': + '@angular/common@22.2.2(@angular/core@22.2.2(@angular/compiler@22.2.2)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2)': dependencies: - '@angular/core': 22.2.1(@angular/compiler@22.2.1)(rxjs@7.8.2)(zone.js@0.16.3) + '@angular/core': 22.2.2(@angular/compiler@22.2.2)(rxjs@7.8.2)(zone.js@0.16.3) rxjs: 7.8.2 tslib: 2.8.1 - '@angular/compiler-cli@22.2.1(@angular/compiler@22.2.1)(typescript@6.0.3)': + '@angular/compiler-cli@22.2.2(@angular/compiler@22.2.2)(typescript@6.0.3)': dependencies: - '@angular/compiler': 22.2.1 + '@angular/compiler': 22.2.2 '@babel/core': 8.0.1 '@jridgewell/sourcemap-codec': 1.6.0 chokidar: 5.0.0 @@ -8735,43 +8735,43 @@ snapshots: optionalDependencies: typescript: 6.0.3 - '@angular/compiler@22.2.1': + '@angular/compiler@22.2.2': dependencies: tslib: 2.8.1 - '@angular/core@22.2.1(@angular/compiler@22.2.1)(rxjs@7.8.2)(zone.js@0.16.3)': + '@angular/core@22.2.2(@angular/compiler@22.2.2)(rxjs@7.8.2)(zone.js@0.16.3)': dependencies: rxjs: 7.8.2 tslib: 2.8.1 optionalDependencies: - '@angular/compiler': 22.2.1 + '@angular/compiler': 22.2.2 zone.js: 0.16.3 - '@angular/forms@22.2.1(@angular/common@22.2.1(@angular/core@22.2.1(@angular/compiler@22.2.1)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2))(@angular/core@22.2.1(@angular/compiler@22.2.1)(rxjs@7.8.2)(zone.js@0.16.3))(@angular/platform-browser@22.2.1(@angular/animations@22.2.1(@angular/core@22.2.1(@angular/compiler@22.2.1)(rxjs@7.8.2)(zone.js@0.16.3)))(@angular/common@22.2.1(@angular/core@22.2.1(@angular/compiler@22.2.1)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2))(@angular/core@22.2.1(@angular/compiler@22.2.1)(rxjs@7.8.2)(zone.js@0.16.3)))(rxjs@7.8.2)': + '@angular/forms@22.2.2(@angular/common@22.2.2(@angular/core@22.2.2(@angular/compiler@22.2.2)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2))(@angular/core@22.2.2(@angular/compiler@22.2.2)(rxjs@7.8.2)(zone.js@0.16.3))(@angular/platform-browser@22.2.2(@angular/animations@22.2.2(@angular/core@22.2.2(@angular/compiler@22.2.2)(rxjs@7.8.2)(zone.js@0.16.3)))(@angular/common@22.2.2(@angular/core@22.2.2(@angular/compiler@22.2.2)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2))(@angular/core@22.2.2(@angular/compiler@22.2.2)(rxjs@7.8.2)(zone.js@0.16.3)))(rxjs@7.8.2)': dependencies: - '@angular/common': 22.2.1(@angular/core@22.2.1(@angular/compiler@22.2.1)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2) - '@angular/core': 22.2.1(@angular/compiler@22.2.1)(rxjs@7.8.2)(zone.js@0.16.3) - '@angular/platform-browser': 22.2.1(@angular/animations@22.2.1(@angular/core@22.2.1(@angular/compiler@22.2.1)(rxjs@7.8.2)(zone.js@0.16.3)))(@angular/common@22.2.1(@angular/core@22.2.1(@angular/compiler@22.2.1)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2))(@angular/core@22.2.1(@angular/compiler@22.2.1)(rxjs@7.8.2)(zone.js@0.16.3)) + '@angular/common': 22.2.2(@angular/core@22.2.2(@angular/compiler@22.2.2)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2) + '@angular/core': 22.2.2(@angular/compiler@22.2.2)(rxjs@7.8.2)(zone.js@0.16.3) + '@angular/platform-browser': 22.2.2(@angular/animations@22.2.2(@angular/core@22.2.2(@angular/compiler@22.2.2)(rxjs@7.8.2)(zone.js@0.16.3)))(@angular/common@22.2.2(@angular/core@22.2.2(@angular/compiler@22.2.2)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2))(@angular/core@22.2.2(@angular/compiler@22.2.2)(rxjs@7.8.2)(zone.js@0.16.3)) '@standard-schema/spec': 1.1.0 rxjs: 7.8.2 tslib: 2.8.1 zod: 4.6.5 - '@angular/localize@22.2.1(@angular/compiler-cli@22.2.1(@angular/compiler@22.2.1)(typescript@6.0.3))(@angular/compiler@22.2.1)': + '@angular/localize@22.2.2(@angular/compiler-cli@22.2.2(@angular/compiler@22.2.2)(typescript@6.0.3))(@angular/compiler@22.2.2)': dependencies: - '@angular/compiler': 22.2.1 - '@angular/compiler-cli': 22.2.1(@angular/compiler@22.2.1)(typescript@6.0.3) + '@angular/compiler': 22.2.2 + '@angular/compiler-cli': 22.2.2(@angular/compiler@22.2.2)(typescript@6.0.3) '@babel/core': 8.0.1 tinyglobby: 0.2.17 yargs: 18.1.0 - '@angular/material@22.2.2(aa0c13a53721943fac231579df95cd0b)': + '@angular/material@22.2.2(641510506f6736c740497081311accfd)': dependencies: - '@angular/cdk': 22.2.2(539f1c0d474fe13b108bca94cc3bd7b4) - '@angular/common': 22.2.1(@angular/core@22.2.1(@angular/compiler@22.2.1)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2) - '@angular/core': 22.2.1(@angular/compiler@22.2.1)(rxjs@7.8.2)(zone.js@0.16.3) - '@angular/forms': 22.2.1(@angular/common@22.2.1(@angular/core@22.2.1(@angular/compiler@22.2.1)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2))(@angular/core@22.2.1(@angular/compiler@22.2.1)(rxjs@7.8.2)(zone.js@0.16.3))(@angular/platform-browser@22.2.1(@angular/animations@22.2.1(@angular/core@22.2.1(@angular/compiler@22.2.1)(rxjs@7.8.2)(zone.js@0.16.3)))(@angular/common@22.2.1(@angular/core@22.2.1(@angular/compiler@22.2.1)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2))(@angular/core@22.2.1(@angular/compiler@22.2.1)(rxjs@7.8.2)(zone.js@0.16.3)))(rxjs@7.8.2) - '@angular/platform-browser': 22.2.1(@angular/animations@22.2.1(@angular/core@22.2.1(@angular/compiler@22.2.1)(rxjs@7.8.2)(zone.js@0.16.3)))(@angular/common@22.2.1(@angular/core@22.2.1(@angular/compiler@22.2.1)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2))(@angular/core@22.2.1(@angular/compiler@22.2.1)(rxjs@7.8.2)(zone.js@0.16.3)) + '@angular/cdk': 22.2.2(a2e0e17c73c6aceb9301ae9aaf890120) + '@angular/common': 22.2.2(@angular/core@22.2.2(@angular/compiler@22.2.2)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2) + '@angular/core': 22.2.2(@angular/compiler@22.2.2)(rxjs@7.8.2)(zone.js@0.16.3) + '@angular/forms': 22.2.2(@angular/common@22.2.2(@angular/core@22.2.2(@angular/compiler@22.2.2)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2))(@angular/core@22.2.2(@angular/compiler@22.2.2)(rxjs@7.8.2)(zone.js@0.16.3))(@angular/platform-browser@22.2.2(@angular/animations@22.2.2(@angular/core@22.2.2(@angular/compiler@22.2.2)(rxjs@7.8.2)(zone.js@0.16.3)))(@angular/common@22.2.2(@angular/core@22.2.2(@angular/compiler@22.2.2)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2))(@angular/core@22.2.2(@angular/compiler@22.2.2)(rxjs@7.8.2)(zone.js@0.16.3)))(rxjs@7.8.2) + '@angular/platform-browser': 22.2.2(@angular/animations@22.2.2(@angular/core@22.2.2(@angular/compiler@22.2.2)(rxjs@7.8.2)(zone.js@0.16.3)))(@angular/common@22.2.2(@angular/core@22.2.2(@angular/compiler@22.2.2)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2))(@angular/core@22.2.2(@angular/compiler@22.2.2)(rxjs@7.8.2)(zone.js@0.16.3)) rxjs: 7.8.2 tslib: 2.8.1 @@ -8834,35 +8834,35 @@ snapshots: - '@modelcontextprotocol/sdk' - '@react-native-async-storage/async-storage' - '@angular/platform-browser@22.2.1(@angular/animations@22.2.1(@angular/core@22.2.1(@angular/compiler@22.2.1)(rxjs@7.8.2)(zone.js@0.16.3)))(@angular/common@22.2.1(@angular/core@22.2.1(@angular/compiler@22.2.1)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2))(@angular/core@22.2.1(@angular/compiler@22.2.1)(rxjs@7.8.2)(zone.js@0.16.3))': + '@angular/platform-browser@22.2.2(@angular/animations@22.2.2(@angular/core@22.2.2(@angular/compiler@22.2.2)(rxjs@7.8.2)(zone.js@0.16.3)))(@angular/common@22.2.2(@angular/core@22.2.2(@angular/compiler@22.2.2)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2))(@angular/core@22.2.2(@angular/compiler@22.2.2)(rxjs@7.8.2)(zone.js@0.16.3))': dependencies: - '@angular/common': 22.2.1(@angular/core@22.2.1(@angular/compiler@22.2.1)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2) - '@angular/core': 22.2.1(@angular/compiler@22.2.1)(rxjs@7.8.2)(zone.js@0.16.3) + '@angular/common': 22.2.2(@angular/core@22.2.2(@angular/compiler@22.2.2)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2) + '@angular/core': 22.2.2(@angular/compiler@22.2.2)(rxjs@7.8.2)(zone.js@0.16.3) tslib: 2.8.1 optionalDependencies: - '@angular/animations': 22.2.1(@angular/core@22.2.1(@angular/compiler@22.2.1)(rxjs@7.8.2)(zone.js@0.16.3)) + '@angular/animations': 22.2.2(@angular/core@22.2.2(@angular/compiler@22.2.2)(rxjs@7.8.2)(zone.js@0.16.3)) - '@angular/platform-server@22.2.1(@angular/common@22.2.1(@angular/core@22.2.1(@angular/compiler@22.2.1)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2))(@angular/compiler@22.2.1)(@angular/core@22.2.1(@angular/compiler@22.2.1)(rxjs@7.8.2)(zone.js@0.16.3))(@angular/platform-browser@22.2.1(@angular/animations@22.2.1(@angular/core@22.2.1(@angular/compiler@22.2.1)(rxjs@7.8.2)(zone.js@0.16.3)))(@angular/common@22.2.1(@angular/core@22.2.1(@angular/compiler@22.2.1)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2))(@angular/core@22.2.1(@angular/compiler@22.2.1)(rxjs@7.8.2)(zone.js@0.16.3)))(rxjs@7.8.2)': + '@angular/platform-server@22.2.2(@angular/common@22.2.2(@angular/core@22.2.2(@angular/compiler@22.2.2)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2))(@angular/compiler@22.2.2)(@angular/core@22.2.2(@angular/compiler@22.2.2)(rxjs@7.8.2)(zone.js@0.16.3))(@angular/platform-browser@22.2.2(@angular/animations@22.2.2(@angular/core@22.2.2(@angular/compiler@22.2.2)(rxjs@7.8.2)(zone.js@0.16.3)))(@angular/common@22.2.2(@angular/core@22.2.2(@angular/compiler@22.2.2)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2))(@angular/core@22.2.2(@angular/compiler@22.2.2)(rxjs@7.8.2)(zone.js@0.16.3)))(rxjs@7.8.2)': dependencies: - '@angular/common': 22.2.1(@angular/core@22.2.1(@angular/compiler@22.2.1)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2) - '@angular/compiler': 22.2.1 - '@angular/core': 22.2.1(@angular/compiler@22.2.1)(rxjs@7.8.2)(zone.js@0.16.3) - '@angular/platform-browser': 22.2.1(@angular/animations@22.2.1(@angular/core@22.2.1(@angular/compiler@22.2.1)(rxjs@7.8.2)(zone.js@0.16.3)))(@angular/common@22.2.1(@angular/core@22.2.1(@angular/compiler@22.2.1)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2))(@angular/core@22.2.1(@angular/compiler@22.2.1)(rxjs@7.8.2)(zone.js@0.16.3)) + '@angular/common': 22.2.2(@angular/core@22.2.2(@angular/compiler@22.2.2)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2) + '@angular/compiler': 22.2.2 + '@angular/core': 22.2.2(@angular/compiler@22.2.2)(rxjs@7.8.2)(zone.js@0.16.3) + '@angular/platform-browser': 22.2.2(@angular/animations@22.2.2(@angular/core@22.2.2(@angular/compiler@22.2.2)(rxjs@7.8.2)(zone.js@0.16.3)))(@angular/common@22.2.2(@angular/core@22.2.2(@angular/compiler@22.2.2)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2))(@angular/core@22.2.2(@angular/compiler@22.2.2)(rxjs@7.8.2)(zone.js@0.16.3)) rxjs: 7.8.2 tslib: 2.8.1 xhr2: 0.2.1 - '@angular/router@22.2.1(@angular/common@22.2.1(@angular/core@22.2.1(@angular/compiler@22.2.1)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2))(@angular/core@22.2.1(@angular/compiler@22.2.1)(rxjs@7.8.2)(zone.js@0.16.3))(@angular/platform-browser@22.2.1(@angular/animations@22.2.1(@angular/core@22.2.1(@angular/compiler@22.2.1)(rxjs@7.8.2)(zone.js@0.16.3)))(@angular/common@22.2.1(@angular/core@22.2.1(@angular/compiler@22.2.1)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2))(@angular/core@22.2.1(@angular/compiler@22.2.1)(rxjs@7.8.2)(zone.js@0.16.3)))(rxjs@7.8.2)': + '@angular/router@22.2.2(@angular/common@22.2.2(@angular/core@22.2.2(@angular/compiler@22.2.2)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2))(@angular/core@22.2.2(@angular/compiler@22.2.2)(rxjs@7.8.2)(zone.js@0.16.3))(@angular/platform-browser@22.2.2(@angular/animations@22.2.2(@angular/core@22.2.2(@angular/compiler@22.2.2)(rxjs@7.8.2)(zone.js@0.16.3)))(@angular/common@22.2.2(@angular/core@22.2.2(@angular/compiler@22.2.2)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2))(@angular/core@22.2.2(@angular/compiler@22.2.2)(rxjs@7.8.2)(zone.js@0.16.3)))(rxjs@7.8.2)': dependencies: - '@angular/common': 22.2.1(@angular/core@22.2.1(@angular/compiler@22.2.1)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2) - '@angular/core': 22.2.1(@angular/compiler@22.2.1)(rxjs@7.8.2)(zone.js@0.16.3) - '@angular/platform-browser': 22.2.1(@angular/animations@22.2.1(@angular/core@22.2.1(@angular/compiler@22.2.1)(rxjs@7.8.2)(zone.js@0.16.3)))(@angular/common@22.2.1(@angular/core@22.2.1(@angular/compiler@22.2.1)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2))(@angular/core@22.2.1(@angular/compiler@22.2.1)(rxjs@7.8.2)(zone.js@0.16.3)) + '@angular/common': 22.2.2(@angular/core@22.2.2(@angular/compiler@22.2.2)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2) + '@angular/core': 22.2.2(@angular/compiler@22.2.2)(rxjs@7.8.2)(zone.js@0.16.3) + '@angular/platform-browser': 22.2.2(@angular/animations@22.2.2(@angular/core@22.2.2(@angular/compiler@22.2.2)(rxjs@7.8.2)(zone.js@0.16.3)))(@angular/common@22.2.2(@angular/core@22.2.2(@angular/compiler@22.2.2)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2))(@angular/core@22.2.2(@angular/compiler@22.2.2)(rxjs@7.8.2)(zone.js@0.16.3)) rxjs: 7.8.2 tslib: 2.8.1 - '@angular/service-worker@22.2.1(@angular/core@22.2.1(@angular/compiler@22.2.1)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2)': + '@angular/service-worker@22.2.2(@angular/core@22.2.2(@angular/compiler@22.2.2)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2)': dependencies: - '@angular/core': 22.2.1(@angular/compiler@22.2.1)(rxjs@7.8.2)(zone.js@0.16.3) + '@angular/core': 22.2.2(@angular/compiler@22.2.2)(rxjs@7.8.2)(zone.js@0.16.3) rxjs: 7.8.2 tslib: 2.8.1 @@ -14974,10 +14974,10 @@ snapshots: neo-async@2.6.2: {} - ng-packagr@22.2.4(@angular/compiler-cli@22.2.1(@angular/compiler@22.2.1)(typescript@6.0.3))(supports-color@11.0.0)(tslib@2.8.1)(typescript@6.0.3): + ng-packagr@22.2.4(@angular/compiler-cli@22.2.2(@angular/compiler@22.2.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.1(@angular/compiler@22.2.1)(typescript@6.0.3) + '@angular/compiler-cli': 22.2.2(@angular/compiler@22.2.2)(typescript@6.0.3) ajv: 8.20.0 browserslist: 4.29.3 chokidar: 5.0.0 From bcff0e76adf73cfa32b02c5256490189675cb132 Mon Sep 17 00:00:00 2001 From: rk Date: Sat, 10 Oct 2026 19:06:37 +0500 Subject: [PATCH 079/233] fix(@angular/cli): keep ng version working when the package manager is not installed `getVersion()` throws when configured package manager is missing, so `ng version` crashed insted of printing `` Version is left undefined now, same as analytics in command-module.ts (cherry picked from commit 2e0f48e3ff40289725d3590fa8e1fc059fbaeb88) --- .../cli/src/commands/version/version-info.ts | 9 ++- .../src/commands/version/version-info_spec.ts | 64 +++++++++++++++++++ 2 files changed, 72 insertions(+), 1 deletion(-) create mode 100644 packages/angular/cli/src/commands/version/version-info_spec.ts diff --git a/packages/angular/cli/src/commands/version/version-info.ts b/packages/angular/cli/src/commands/version/version-info.ts index 128cc8ef5449..9709567e382b 100644 --- a/packages/angular/cli/src/commands/version/version-info.ts +++ b/packages/angular/cli/src/commands/version/version-info.ts @@ -104,6 +104,13 @@ export async function gatherVersionInfo(context: CommandContext): Promise { + let tempRoot: string; + + beforeEach(async () => { + const baseTmpDir = process.env['TEST_TMPDIR']; + assert(baseTmpDir, 'TEST_TMPDIR is not set'); + tempRoot = await mkdtemp(join(baseTmpDir, 'angular-cli-version-info-test-')); + }); + + afterEach(async () => { + await rm(tempRoot, { recursive: true, force: true }); + }); + + function createContext(packageManager: PackageManager): CommandContext { + return { root: tempRoot, packageManager } as unknown as CommandContext; + } + + it('should report the package manager version when it is available', async () => { + const packageManager = new PackageManager( + new MockHost(), + tempRoot, + SUPPORTED_PACKAGE_MANAGERS['npm'], + { version: '10.9.0' }, + ); + + const info = await gatherVersionInfo(createContext(packageManager)); + + expect(info.system.packageManager).toEqual({ name: 'npm', version: '10.9.0' }); + }); + + it('should not fail when the package manager is not installed', async () => { + const packageManager = new PackageManager( + new MockHost(), + tempRoot, + SUPPORTED_PACKAGE_MANAGERS['bun'], + { + initializationError: new Error( + `The project is configured to use 'bun', but it is not installed.`, + ), + }, + ); + + const info = await gatherVersionInfo(createContext(packageManager)); + + expect(info.system.packageManager).toEqual({ name: 'bun', version: undefined }); + }); +}); From 3158e865ffdd828711d645dff16cc17fd26bb58e Mon Sep 17 00:00:00 2001 From: rk Date: Sat, 10 Oct 2026 18:53:58 +0500 Subject: [PATCH 080/233] fix(@angular/cli): accept multi-digit array indices in ng config multi-digit index like `styles[10]` stayed string, so get failed and set threw now any run of digits is parsed as array idnex (cherry picked from commit 5c656152ef91e2731155f6027a845d8014b53e4f) --- .../angular/cli/src/commands/config/cli.ts | 5 +-- .../cli/src/commands/config/cli_spec.ts | 37 +++++++++++++++++++ 2 files changed, 39 insertions(+), 3 deletions(-) create mode 100644 packages/angular/cli/src/commands/config/cli_spec.ts diff --git a/packages/angular/cli/src/commands/config/cli.ts b/packages/angular/cli/src/commands/config/cli.ts index 06b253b9a42d..0be11f4c1759 100644 --- a/packages/angular/cli/src/commands/config/cli.ts +++ b/packages/angular/cli/src/commands/config/cli.ts @@ -133,9 +133,8 @@ export default class ConfigCommandModule * ["a", 3, "foo", "bar", 2]. * @param path The JSON string to parse. * @returns {(string|number)[]} The fragments for the string. - * @private */ -function parseJsonPath(path: string): (string | number)[] { +export function parseJsonPath(path: string): (string | number)[] { const fragments = (path || '').split(/\./g); const result: (string | number)[] = []; @@ -155,7 +154,7 @@ function parseJsonPath(path: string): (string | number)[] { const indices = match[2] .slice(1, -1) .split('][') - .map((x) => (/^\d$/.test(x) ? +x : x.replace(/"|'/g, ''))); + .map((x) => (/^\d+$/.test(x) ? +x : x.replace(/"|'/g, ''))); result.push(...indices); } } diff --git a/packages/angular/cli/src/commands/config/cli_spec.ts b/packages/angular/cli/src/commands/config/cli_spec.ts new file mode 100644 index 000000000000..dd8fe4790e16 --- /dev/null +++ b/packages/angular/cli/src/commands/config/cli_spec.ts @@ -0,0 +1,37 @@ +/** + * @license + * Copyright Google LLC All Rights Reserved. + * + * Use of this source code is governed by an MIT-style license that can be + * found in the LICENSE file at https://angular.dev/license + */ + +import { parseJsonPath } from './cli'; + +describe('parseJsonPath', () => { + it('should parse single digit array indices', () => { + expect(parseJsonPath('a[3].foo.bar[2]')).toEqual(['a', 3, 'foo', 'bar', 2]); + }); + + it('should parse multi digit array indices', () => { + expect(parseJsonPath('projects.app.architect.build.options.styles[10]')).toEqual([ + 'projects', + 'app', + 'architect', + 'build', + 'options', + 'styles', + 10, + ]); + expect(parseJsonPath('a[2][13].b')).toEqual(['a', 2, 13, 'b']); + }); + + it('should keep quoted keys as strings', () => { + expect(parseJsonPath('projects["test-project"].root')).toEqual([ + 'projects', + 'test-project', + 'root', + ]); + expect(parseJsonPath(`a['10']`)).toEqual(['a', '10']); + }); +}); From 881865f364b33b36630aa6ab7a129f7ed665cfa7 Mon Sep 17 00:00:00 2001 From: rk Date: Sat, 10 Oct 2026 18:54:01 +0500 Subject: [PATCH 081/233] fix(@schematics/angular): keep the workspace build version in the use-application-builder migration migration added `@angular/build` at version of CLI running it, so `ng update --name` on older workspace pulled newest major now it reuses `@angular-devkit/build-angular` specifer and leaves existing `@angular/build` alone Fixes #30696 (cherry picked from commit 445cc767e62b72631dd53c0c5324b458fee76608) --- .../use-application-builder/migration.ts | 9 +++- .../use-application-builder/migration_spec.ts | 42 +++++++++++++++++++ 2 files changed, 49 insertions(+), 2 deletions(-) diff --git a/packages/schematics/angular/migrations/use-application-builder/migration.ts b/packages/schematics/angular/migrations/use-application-builder/migration.ts index b481c4f30034..dcf0526a3945 100644 --- a/packages/schematics/angular/migrations/use-application-builder/migration.ts +++ b/packages/schematics/angular/migrations/use-application-builder/migration.ts @@ -19,6 +19,7 @@ import { DependencyType, ExistingBehavior, addDependency, + getDependency, removeDependency, } from '../../utility/dependency'; import { JSONFile } from '../../utility/json-file'; @@ -270,10 +271,14 @@ function updateProjects(tree: Tree, context: SchematicContext) { } // Add direct @angular/build dependencies and remove @angular-devkit/build-angular + // Keep the workspace version since this migration can run from a newer temporary CLI + const buildAngularVersion = + getDependency(tree, '@angular-devkit/build-angular')?.version ?? + latestVersions.AngularBuild; rules.push( - addDependency('@angular/build', latestVersions.DevkitBuildAngular, { + addDependency('@angular/build', buildAngularVersion, { type: DependencyType.Dev, - existing: ExistingBehavior.Replace, + existing: ExistingBehavior.Skip, }), removeDependency('@angular-devkit/build-angular'), ); diff --git a/packages/schematics/angular/migrations/use-application-builder/migration_spec.ts b/packages/schematics/angular/migrations/use-application-builder/migration_spec.ts index fd10352c6eac..05259962dc5d 100644 --- a/packages/schematics/angular/migrations/use-application-builder/migration_spec.ts +++ b/packages/schematics/angular/migrations/use-application-builder/migration_spec.ts @@ -9,6 +9,7 @@ import { JsonObject } from '@angular-devkit/core'; import { EmptyTree } from '@angular-devkit/schematics'; import { SchematicTestRunner, UnitTestTree } from '@angular-devkit/schematics/testing'; +import { latestVersions } from '../../utility/latest-versions'; import { Builders, ProjectType, WorkspaceSchema } from '../../utility/workspace-models'; function createWorkSpaceConfig(tree: UnitTestTree) { @@ -450,6 +451,47 @@ describe(`Migration to use the application builder`, () => { expect(devDependencies['postcss']).toBeUndefined(); }); + describe('"@angular/build" version', () => { + async function migrateWith( + manifest: object, + ): Promise<{ devDependencies: Record }> { + tree.overwrite('/package.json', JSON.stringify(manifest)); + const newTree = await schematicRunner.runSchematic(schematicName, {}, tree); + + return JSON.parse(newTree.readContent('/package.json')); + } + + it('should follow the "@angular-devkit/build-angular" range of the workspace', async () => { + const { devDependencies } = await migrateWith({ + devDependencies: { '@angular-devkit/build-angular': '~19.1.4' }, + }); + + expect(devDependencies['@angular/build']).toBe('~19.1.4'); + }); + + it('should read "@angular-devkit/build-angular" from "dependencies" as well', async () => { + const { devDependencies } = await migrateWith({ + dependencies: { '@angular-devkit/build-angular': '18.2.1' }, + }); + + expect(devDependencies['@angular/build']).toBe('18.2.1'); + }); + + it('should keep an "@angular/build" that is already installed', async () => { + const { devDependencies } = await migrateWith({ + devDependencies: { '@angular-devkit/build-angular': '^19.2.0', '@angular/build': '19.0.3' }, + }); + + expect(devDependencies['@angular/build']).toBe('19.0.3'); + }); + + it('should fall back to the latest "@angular/build" without "@angular-devkit/build-angular"', async () => { + const { devDependencies } = await migrateWith({}); + + expect(devDependencies['@angular/build']).toBe(latestVersions.AngularBuild); + }); + }); + it('it should not add esModuleInterop and moduleResolution when module is preserve', async () => { tree.overwrite( 'tsconfig.json', From fbe208f8392ec0ce82d597e8b690f146370bdc81 Mon Sep 17 00:00:00 2001 From: rk Date: Sat, 10 Oct 2026 19:16:57 +0500 Subject: [PATCH 082/233] fix(@angular/build): always use AOT when extracting i18n messages with `aot: false` on build target, extraction built app in JIT and template messages never got into extracted file webpack extraction alredy forced AOT, application extraction now does same (cherry picked from commit 13923047f64b6e1063f7f07029c70295b5c99d69) --- .../builders/extract-i18n/application-extraction.ts | 1 + .../builders/extract-i18n/application-extraction.ts | 1 + tests/e2e/tests/i18n/extract-ivy.ts | 11 ++++++++++- 3 files changed, 12 insertions(+), 1 deletion(-) diff --git a/packages/angular/build/src/builders/extract-i18n/application-extraction.ts b/packages/angular/build/src/builders/extract-i18n/application-extraction.ts index ff223ba0bd16..b18c8164481f 100644 --- a/packages/angular/build/src/builders/extract-i18n/application-extraction.ts +++ b/packages/angular/build/src/builders/extract-i18n/application-extraction.ts @@ -39,6 +39,7 @@ export async function extractMessages( await context.getTargetOptions(options.buildTarget), builderName, )) as unknown as ApplicationBuilderInternalOptions; + buildOptions.aot = true; buildOptions.optimization = false; buildOptions.sourceMap = { scripts: true, vendor: true, styles: false }; buildOptions.localize = false; diff --git a/packages/angular_devkit/build_angular/src/builders/extract-i18n/application-extraction.ts b/packages/angular_devkit/build_angular/src/builders/extract-i18n/application-extraction.ts index 8de8b6863aaf..68347fa0fb24 100644 --- a/packages/angular_devkit/build_angular/src/builders/extract-i18n/application-extraction.ts +++ b/packages/angular_devkit/build_angular/src/builders/extract-i18n/application-extraction.ts @@ -45,6 +45,7 @@ export async function extractMessages( ); } + buildOptions.aot = true; buildOptions.optimization = false; buildOptions.sourceMap = { scripts: true, vendor: true, styles: false }; buildOptions.localize = false; diff --git a/tests/e2e/tests/i18n/extract-ivy.ts b/tests/e2e/tests/i18n/extract-ivy.ts index 382051e83cce..cf0d23da08e3 100644 --- a/tests/e2e/tests/i18n/extract-ivy.ts +++ b/tests/e2e/tests/i18n/extract-ivy.ts @@ -1,8 +1,9 @@ import { join } from 'node:path'; import { getGlobalVariable } from '../../utils/env'; -import { expectFileToMatch, writeFile } from '../../utils/fs'; +import { deleteFile, expectFileToMatch, writeFile } from '../../utils/fs'; import { uninstallPackage } from '../../utils/packages'; import { ng } from '../../utils/process'; +import { updateJsonFile } from '../../utils/project'; import { expectToFail } from '../../utils/utils'; import { readNgVersion } from '../../utils/version'; @@ -52,5 +53,13 @@ export default async function () { await expectFileToMatch('messages.xlf', 'Hello world'); + // Template messages should also be extracted when the build target disables AOT + await updateJsonFile('angular.json', (workspaceJson) => { + workspaceJson.projects['test-project'].architect.build.options.aot = false; + }); + await deleteFile('messages.xlf'); + await ng('extract-i18n'); + await expectFileToMatch('messages.xlf', 'Hello world'); + await uninstallPackage('@angular/localize'); } From a925468929c74c30a3e64b361a6dc5d6fdc1006a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Benjamin=20Sch=C3=A4ublin?= Date: Mon, 12 Oct 2026 10:08:49 +0200 Subject: [PATCH 083/233] fix(@angular/ssr): preserve query parameters on relative route redirects Route redirects are answered on the server from the route configuration, without running the router. For a relative `redirectTo`, the router keeps the query string of the current URL and ignores a query string in `redirectTo`, but the server did the opposite. It now does the same as the router. Absolute redirects are unchanged, as the router does not keep the query string of the current URL for them either. (cherry picked from commit f2cd8c8cf7c5aa7e7076c87e9c0c55b3bf880f4b) --- packages/angular/ssr/src/app.ts | 13 ++- packages/angular/ssr/src/routes/ng-routes.ts | 9 +- packages/angular/ssr/src/routes/route-tree.ts | 3 + packages/angular/ssr/test/app_spec.ts | 33 +++++++ .../angular/ssr/test/routes/ng-routes_spec.ts | 99 +++++++++++++++++-- .../angular/ssr/test/routes/router_spec.ts | 3 + 6 files changed, 146 insertions(+), 14 deletions(-) diff --git a/packages/angular/ssr/src/app.ts b/packages/angular/ssr/src/app.ts index 6c0202a8f9b3..517cf1e31727 100644 --- a/packages/angular/ssr/src/app.ts +++ b/packages/angular/ssr/src/app.ts @@ -163,14 +163,17 @@ export class AngularServerApp { return null; } - const { redirectTo, status, renderMode, headers } = matchedRoute; + const { redirectTo, relativeRedirect, status, renderMode, headers } = matchedRoute; if (redirectTo !== undefined) { + const location = joinUrlParts( + request.headers.get('X-Forwarded-Prefix') ?? '', + buildPathWithParams(redirectTo, url.pathname), + ); + + // Match Angular router behavior: relative redirects keep the query string. return createRedirectResponse( - joinUrlParts( - request.headers.get('X-Forwarded-Prefix') ?? '', - buildPathWithParams(redirectTo, url.pathname), - ), + relativeRedirect ? location + url.search : location, status, headers, ); diff --git a/packages/angular/ssr/src/routes/ng-routes.ts b/packages/angular/ssr/src/routes/ng-routes.ts index ac83aae8cd4f..63313b875d34 100644 --- a/packages/angular/ssr/src/routes/ng-routes.ts +++ b/packages/angular/ssr/src/routes/ng-routes.ts @@ -192,6 +192,7 @@ async function* handleRoute(options: { yield { ...metadata, redirectTo: resolveRedirectTo(metadata.route, redirectTo), + relativeRedirect: redirectTo[0] !== '/' ? true : undefined, }; } else { yield metadata; @@ -421,6 +422,7 @@ async function* handleSSGRoute( if (redirectTo !== undefined) { meta.redirectTo = resolveRedirectTo(currentRoutePath, redirectTo); + meta.relativeRedirect = redirectTo[0] !== '/' ? true : undefined; } const isCatchAllRoute = CATCH_ALL_REGEXP.test(currentRoutePath); @@ -534,7 +536,8 @@ function handlePrerenderParamsReplacement( * * This function processes the `redirectTo` property to ensure that it correctly * resolves relative to the current route path. If `redirectTo` is an absolute path, - * it is returned as is. If it is a relative path, it is resolved based on the current route path. + * it is returned as is. If it is a relative path, it is resolved based on the current route path, + * and, like in the Angular router, its query and fragment are ignored. * * @param routePath - The current route path. * @param redirectTo - The target path for redirection. @@ -550,7 +553,9 @@ function resolveRedirectTo(routePath: string, redirectTo: string): string { const segments = routePath.replace(URL_PARAMETER_GLOBAL_REGEXP, '*').split('/'); segments.pop(); // Remove the last segment to make it relative. - return joinUrlParts(...segments, redirectTo); + const [path] = redirectTo.split(/[?#]/, 1); + + return joinUrlParts(...segments, path); } /** diff --git a/packages/angular/ssr/src/routes/route-tree.ts b/packages/angular/ssr/src/routes/route-tree.ts index ff689a3c90f5..253783a5f13c 100644 --- a/packages/angular/ssr/src/routes/route-tree.ts +++ b/packages/angular/ssr/src/routes/route-tree.ts @@ -31,6 +31,9 @@ export interface RouteTreeNodeMetadata { */ redirectTo?: string; + /** Indicates if `redirectTo` was defined as a relative path. */ + relativeRedirect?: boolean; + /** * The route path for this node. * diff --git a/packages/angular/ssr/test/app_spec.ts b/packages/angular/ssr/test/app_spec.ts index b317f99f1d3a..91e847f0bf80 100644 --- a/packages/angular/ssr/test/app_spec.ts +++ b/packages/angular/ssr/test/app_spec.ts @@ -88,6 +88,7 @@ describe('AngularServerApp', () => { { path: 'redirect/relative', redirectTo: 'home' }, { path: 'redirect/:param/relative', redirectTo: 'home' }, { path: 'redirect/absolute', redirectTo: '/home' }, + { path: 'redirect-with-query', redirectTo: 'home?param=value' }, { path: 'redirect-to-function', redirectTo: () => 'home', @@ -222,6 +223,28 @@ describe('AngularServerApp', () => { expect(response?.status).toBe(302); }); + it('should preserve query parameters on relative redirects', async () => { + const response = await app.handle(new Request('http://localhost/redirect?filter=test')); + expect(response?.headers.get('location')).toBe('/home?filter=test'); + expect(response?.status).toBe(302); + }); + + it('should ignore query parameters of relative redirect targets', async () => { + const response = await app.handle( + new Request('http://localhost/redirect-with-query?filter=test'), + ); + expect(response?.headers.get('location')).toBe('/home?filter=test'); + expect(response?.status).toBe(302); + }); + + it('should not preserve query parameters on absolute redirects', async () => { + const response = await app.handle( + new Request('http://localhost/redirect/absolute?filter=test'), + ); + expect(response?.headers.get('location')).toBe('/home'); + expect(response?.status).toBe(302); + }); + it('should handle request abortion gracefully', async () => { const controller = new AbortController(); const request = new Request('http://localhost/home', { signal: controller.signal }); @@ -498,6 +521,16 @@ describe('AngularServerApp', () => { expect(response?.headers.get('location')).toBe('/base/home'); expect(response?.status).toBe(302); }); + + it('returns a 302 status and keeps the query string for relative redirects', async () => { + const response = await app.handle( + new Request('http://localhost/redirect?filter=test', { + headers, + }), + ); + expect(response?.headers.get('location')).toBe('/base/home?filter=test'); + expect(response?.status).toBe(302); + }); }); describe('Critical CSS inlining', () => { diff --git a/packages/angular/ssr/test/routes/ng-routes_spec.ts b/packages/angular/ssr/test/routes/ng-routes_spec.ts index e214c31eab71..f26d6fb4913c 100644 --- a/packages/angular/ssr/test/routes/ng-routes_spec.ts +++ b/packages/angular/ssr/test/routes/ng-routes_spec.ts @@ -51,7 +51,13 @@ describe('extractRoutesAndCreateRouteTree', () => { expect(routeTree.toObject()).toEqual([ { route: '/', renderMode: RenderMode.Server }, { route: '/home', renderMode: RenderMode.Client }, - { route: '/redirect', renderMode: RenderMode.Server, status: 301, redirectTo: '/home' }, + { + route: '/redirect', + renderMode: RenderMode.Server, + status: 301, + redirectTo: '/home', + relativeRedirect: true, + }, { route: '/user/*', renderMode: RenderMode.Server }, ]); }); @@ -371,10 +377,25 @@ describe('extractRoutesAndCreateRouteTree', () => { expect(errors).toHaveSize(0); expect(routeTree.toObject()).toEqual([ - { route: '/', renderMode: RenderMode.Prerender, redirectTo: '/some' }, - { route: '/some', renderMode: RenderMode.Prerender, redirectTo: '/some/thing' }, + { + route: '/', + renderMode: RenderMode.Prerender, + redirectTo: '/some', + relativeRedirect: true, + }, + { + route: '/some', + renderMode: RenderMode.Prerender, + redirectTo: '/some/thing', + relativeRedirect: true, + }, { route: '/some/thing', renderMode: RenderMode.Prerender }, - { redirectTo: '/*/thing', route: '/*', renderMode: RenderMode.Server }, + { + redirectTo: '/*/thing', + relativeRedirect: true, + route: '/*', + renderMode: RenderMode.Server, + }, { route: '/*/thing', renderMode: RenderMode.Server }, ]); }); @@ -496,8 +517,13 @@ describe('extractRoutesAndCreateRouteTree', () => { const { routeTree, errors } = await extractRoutesAndCreateRouteTree({ url }); expect(errors).toHaveSize(0); expect(routeTree.toObject()).toEqual([ - { route: '/', renderMode: RenderMode.Server, redirectTo: '/some' }, - { route: '/*', renderMode: RenderMode.Server, redirectTo: '/*/thing' }, + { route: '/', renderMode: RenderMode.Server, redirectTo: '/some', relativeRedirect: true }, + { + route: '/*', + renderMode: RenderMode.Server, + redirectTo: '/*/thing', + relativeRedirect: true, + }, { route: '/*/thing', renderMode: RenderMode.Server }, ]); }); @@ -526,11 +552,70 @@ describe('extractRoutesAndCreateRouteTree', () => { const { routeTree, errors } = await extractRoutesAndCreateRouteTree({ url }); expect(errors).toHaveSize(0); expect(routeTree.toObject()).toEqual([ - { route: '/*/*', renderMode: RenderMode.Server, redirectTo: '/*/*/thing' }, + { + route: '/*/*', + renderMode: RenderMode.Server, + redirectTo: '/*/*/thing', + relativeRedirect: true, + }, { route: '/*/*/thing', renderMode: RenderMode.Server }, ]); }); + it('should not mark absolute redirects as relative', async () => { + setAngularAppTestingManifest( + [ + { path: 'server', redirectTo: '/home' }, + { path: 'prerender', redirectTo: '/home' }, + { path: 'home', component: DummyComponent }, + ], + [ + { path: 'prerender', renderMode: RenderMode.Prerender }, + { path: '**', renderMode: RenderMode.Server }, + ], + ); + + const { routeTree, errors } = await extractRoutesAndCreateRouteTree({ url }); + expect(errors).toHaveSize(0); + expect(routeTree.toObject()).toEqual([ + { route: '/server', renderMode: RenderMode.Server, redirectTo: '/home' }, + { route: '/prerender', renderMode: RenderMode.Prerender, redirectTo: '/home' }, + { route: '/home', renderMode: RenderMode.Server }, + ]); + }); + + it('should ignore the query and fragment of relative redirect targets', async () => { + setAngularAppTestingManifest( + [ + { path: 'server', redirectTo: 'home?param=value#fragment' }, + { path: 'prerender', redirectTo: 'home?param=value#fragment' }, + { path: 'home', component: DummyComponent }, + ], + [ + { path: 'prerender', renderMode: RenderMode.Prerender }, + { path: '**', renderMode: RenderMode.Server }, + ], + ); + + const { routeTree, errors } = await extractRoutesAndCreateRouteTree({ url }); + expect(errors).toHaveSize(0); + expect(routeTree.toObject()).toEqual([ + { + route: '/server', + renderMode: RenderMode.Server, + redirectTo: '/home', + relativeRedirect: true, + }, + { + route: '/prerender', + renderMode: RenderMode.Prerender, + redirectTo: '/home', + relativeRedirect: true, + }, + { route: '/home', renderMode: RenderMode.Server }, + ]); + }); + it('should not resolve parameterized routes for SSG when `invokeGetPrerenderParams` is false', async () => { setAngularAppTestingManifest( [ diff --git a/packages/angular/ssr/test/routes/router_spec.ts b/packages/angular/ssr/test/routes/router_spec.ts index 380bc659549a..95006eda5f5b 100644 --- a/packages/angular/ssr/test/routes/router_spec.ts +++ b/packages/angular/ssr/test/routes/router_spec.ts @@ -55,6 +55,7 @@ describe('ServerRouter', () => { }); expect(router.match(new URL('http://localhost/redirect'))).toEqual({ redirectTo: '/home', + relativeRedirect: true, route: '/redirect', renderMode: RenderMode.Server, status: 301, @@ -89,6 +90,7 @@ describe('ServerRouter', () => { }); expect(redirectMetadata).toEqual({ redirectTo: '/home', + relativeRedirect: true, route: '/redirect', status: 301, renderMode: RenderMode.Server, @@ -110,6 +112,7 @@ describe('ServerRouter', () => { }); expect(redirectMetadata).toEqual({ redirectTo: '/home', + relativeRedirect: true, route: '/redirect', status: 301, renderMode: RenderMode.Server, From a2b86cc94d408ba4c3d422224b58e26b7a68f692 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Benjamin=20Sch=C3=A4ublin?= Date: Mon, 12 Oct 2026 13:07:00 +0200 Subject: [PATCH 084/233] fix(@angular/ssr): resolve relative redirects against the parent route When a route's own path has several segments, such as `old/page`, only its last segment was replaced when resolving a relative `redirectTo` on the server. A redirect to `new/page` was therefore sent to `/old/new/page`, while the router navigates to `/new/page` because it replaces all segments matched by the route. The server now does the same. (cherry picked from commit b3bbada1efd0d3a414cce8843b7284e9560f66fc) --- packages/angular/ssr/src/routes/ng-routes.ts | 29 +++-- packages/angular/ssr/test/app_spec.ts | 17 ++- .../angular/ssr/test/routes/ng-routes_spec.ts | 118 ++++++++++++++++++ 3 files changed, 147 insertions(+), 17 deletions(-) diff --git a/packages/angular/ssr/src/routes/ng-routes.ts b/packages/angular/ssr/src/routes/ng-routes.ts index 63313b875d34..915d7c2b9a47 100644 --- a/packages/angular/ssr/src/routes/ng-routes.ts +++ b/packages/angular/ssr/src/routes/ng-routes.ts @@ -146,6 +146,7 @@ type EntryPointToBrowserMapping = AngularAppManifest['entryPointToBrowserMapping async function* handleRoute(options: { metadata: ServerConfigRouteTreeNodeMetadata; currentRoutePath: string; + parentRoute: string; route: Route; compiler: Compiler; parentInjector: Injector; @@ -158,6 +159,7 @@ async function* handleRoute(options: { const { metadata, currentRoutePath, + parentRoute, route, compiler, parentInjector, @@ -176,6 +178,7 @@ async function* handleRoute(options: { yield* handleSSGRoute( serverConfigRouteTree, typeof redirectTo === 'string' ? redirectTo : undefined, + parentRoute, metadata, parentInjector, invokeGetPrerenderParams, @@ -191,7 +194,7 @@ async function* handleRoute(options: { } else if (typeof redirectTo === 'string') { yield { ...metadata, - redirectTo: resolveRedirectTo(metadata.route, redirectTo), + redirectTo: resolveRedirectTo(parentRoute, redirectTo), relativeRedirect: redirectTo[0] !== '/' ? true : undefined, }; } else { @@ -393,6 +396,7 @@ function appendPreloadToMetadata( * * @param serverConfigRouteTree - The tree representing the server's routing setup. * @param redirectTo - Optional path to redirect to, if specified. + * @param parentRoute - The path of the parent route. * @param metadata - The metadata associated with the route tree node. * @param parentInjector - The dependency injection container for the parent route. * @param invokeGetPrerenderParams - A flag indicating whether to invoke the `getPrerenderParams` function. @@ -402,6 +406,7 @@ function appendPreloadToMetadata( async function* handleSSGRoute( serverConfigRouteTree: RouteTree | undefined, redirectTo: string | undefined, + parentRoute: string, metadata: ServerConfigRouteTreeNodeMetadata, parentInjector: Injector, invokeGetPrerenderParams: boolean, @@ -421,7 +426,7 @@ async function* handleSSGRoute( } if (redirectTo !== undefined) { - meta.redirectTo = resolveRedirectTo(currentRoutePath, redirectTo); + meta.redirectTo = resolveRedirectTo(parentRoute, redirectTo); meta.relativeRedirect = redirectTo[0] !== '/' ? true : undefined; } @@ -480,7 +485,10 @@ async function* handleSSGRoute( redirectTo: redirectTo === undefined ? undefined - : resolveRedirectTo(routeWithResolvedParams, redirectTo), + : resolveRedirectTo( + parentRoute.replace(URL_PARAMETER_GLOBAL_REGEXP, replacer), + redirectTo, + ), }; } } catch (error) { @@ -535,27 +543,24 @@ function handlePrerenderParamsReplacement( * Resolves the `redirectTo` property for a given route. * * This function processes the `redirectTo` property to ensure that it correctly - * resolves relative to the current route path. If `redirectTo` is an absolute path, - * it is returned as is. If it is a relative path, it is resolved based on the current route path, + * resolves relative to the parent route path. If `redirectTo` is an absolute path, + * it is returned as is. If it is a relative path, it is resolved based on the parent route path, * and, like in the Angular router, its query and fragment are ignored. * - * @param routePath - The current route path. + * @param parentRoute - The path of the parent route. * @param redirectTo - The target path for redirection. * @returns The resolved redirect path as a string. */ -function resolveRedirectTo(routePath: string, redirectTo: string): string { +function resolveRedirectTo(parentRoute: string, redirectTo: string): string { if (redirectTo[0] === '/') { // If the redirectTo path is absolute, return it as is. return redirectTo; } - // Resolve relative redirectTo based on the current route path. - const segments = routePath.replace(URL_PARAMETER_GLOBAL_REGEXP, '*').split('/'); - segments.pop(); // Remove the last segment to make it relative. - + // Match Angular router behavior: replace all segments matched by the route. const [path] = redirectTo.split(/[?#]/, 1); - return joinUrlParts(...segments, path); + return joinUrlParts(parentRoute.replace(URL_PARAMETER_GLOBAL_REGEXP, '*'), path); } /** diff --git a/packages/angular/ssr/test/app_spec.ts b/packages/angular/ssr/test/app_spec.ts index 91e847f0bf80..8d8ee9add00b 100644 --- a/packages/angular/ssr/test/app_spec.ts +++ b/packages/angular/ssr/test/app_spec.ts @@ -89,6 +89,7 @@ describe('AngularServerApp', () => { { path: 'redirect/:param/relative', redirectTo: 'home' }, { path: 'redirect/absolute', redirectTo: '/home' }, { path: 'redirect-with-query', redirectTo: 'home?param=value' }, + { path: 'redirect-nested/:param', children: [{ path: 'old', redirectTo: 'new' }] }, { path: 'redirect-to-function', redirectTo: () => 'home', @@ -205,19 +206,25 @@ describe('AngularServerApp', () => { expect(response?.status).toBe(302); }); - it('should correctly handle relative nested redirects', async () => { + it('should correctly handle relative redirects on multi-segment routes', async () => { const response = await app.handle(new Request('http://localhost/redirect/relative')); - expect(response?.headers.get('location')).toBe('/redirect/home'); + expect(response?.headers.get('location')).toBe('/home'); expect(response?.status).toBe(302); }); - it('should correctly handle relative nested redirects with parameter', async () => { + it('should correctly handle relative redirects on multi-segment routes with parameter', async () => { const response = await app.handle(new Request('http://localhost/redirect/param/relative')); - expect(response?.headers.get('location')).toBe('/redirect/param/home'); + expect(response?.headers.get('location')).toBe('/home'); + expect(response?.status).toBe(302); + }); + + it('should correctly handle relative redirects of parameterized parent routes', async () => { + const response = await app.handle(new Request('http://localhost/redirect-nested/x/old')); + expect(response?.headers.get('location')).toBe('/redirect-nested/x/new'); expect(response?.status).toBe(302); }); - it('should correctly handle absolute nested redirects', async () => { + it('should correctly handle absolute redirects on multi-segment routes', async () => { const response = await app.handle(new Request('http://localhost/redirect/absolute')); expect(response?.headers.get('location')).toBe('/home'); expect(response?.status).toBe(302); diff --git a/packages/angular/ssr/test/routes/ng-routes_spec.ts b/packages/angular/ssr/test/routes/ng-routes_spec.ts index f26d6fb4913c..1af823f8f2ba 100644 --- a/packages/angular/ssr/test/routes/ng-routes_spec.ts +++ b/packages/angular/ssr/test/routes/ng-routes_spec.ts @@ -399,6 +399,96 @@ describe('extractRoutesAndCreateRouteTree', () => { { route: '/*/thing', renderMode: RenderMode.Server }, ]); }); + + it('should resolve multi-segment relative redirects of prerendered routes', async () => { + setAngularAppTestingManifest( + [ + { + path: ':param', + children: [ + { path: 'old/page', redirectTo: 'new/page' }, + { path: 'new/page', component: DummyComponent }, + ], + }, + ], + [ + { + path: ':param/old/page', + renderMode: RenderMode.Prerender, + async getPrerenderParams() { + return [{ param: 'some' }]; + }, + }, + { path: '**', renderMode: RenderMode.Server }, + ], + ); + + const { routeTree, errors } = await extractRoutesAndCreateRouteTree({ + url, + invokeGetPrerenderParams: true, + includePrerenderFallbackRoutes: true, + }); + + expect(errors).toHaveSize(0); + expect(routeTree.toObject()).toEqual([ + { route: '/*', renderMode: RenderMode.Server }, + { + route: '/*/old/page', + renderMode: RenderMode.Server, + redirectTo: '/*/new/page', + relativeRedirect: true, + }, + { route: '/*/new/page', renderMode: RenderMode.Server }, + { + route: '/some/old/page', + renderMode: RenderMode.Prerender, + redirectTo: '/some/new/page', + relativeRedirect: true, + }, + ]); + }); + + it('should resolve relative redirects of prerendered catch-all routes', async () => { + setAngularAppTestingManifest( + [ + { path: 'docs/**', redirectTo: 'new' }, + { path: 'new', component: DummyComponent }, + ], + [ + { + path: 'docs/**', + renderMode: RenderMode.Prerender, + async getPrerenderParams() { + return [{ '**': 'a/b' }]; + }, + }, + { path: '**', renderMode: RenderMode.Server }, + ], + ); + + const { routeTree, errors } = await extractRoutesAndCreateRouteTree({ + url, + invokeGetPrerenderParams: true, + includePrerenderFallbackRoutes: true, + }); + + expect(errors).toHaveSize(0); + expect(routeTree.toObject()).toEqual([ + { + route: '/docs/a/b', + renderMode: RenderMode.Prerender, + redirectTo: '/new', + relativeRedirect: true, + }, + { + route: '/docs/**', + renderMode: RenderMode.Server, + redirectTo: '/new', + relativeRedirect: true, + }, + { route: '/new', renderMode: RenderMode.Server }, + ]); + }); }); it('should extract routes with a route level matcher', async () => { @@ -562,6 +652,34 @@ describe('extractRoutesAndCreateRouteTree', () => { ]); }); + it('should resolve multi-segment relative redirects against the parent route', async () => { + setAngularAppTestingManifest( + [ + { + path: ':param', + children: [ + { path: 'old/page', redirectTo: 'new/page' }, + { path: 'new/page', component: DummyComponent }, + ], + }, + ], + [{ path: '**', renderMode: RenderMode.Server }], + ); + + const { routeTree, errors } = await extractRoutesAndCreateRouteTree({ url }); + expect(errors).toHaveSize(0); + expect(routeTree.toObject()).toEqual([ + { route: '/*', renderMode: RenderMode.Server }, + { + route: '/*/old/page', + renderMode: RenderMode.Server, + redirectTo: '/*/new/page', + relativeRedirect: true, + }, + { route: '/*/new/page', renderMode: RenderMode.Server }, + ]); + }); + it('should not mark absolute redirects as relative', async () => { setAngularAppTestingManifest( [ From 792990bc2eacdcc8ed4de6ef46e58ceeb5fe8741 Mon Sep 17 00:00:00 2001 From: Alan Agius <17563226+alan-agius4@users.noreply.github.com> Date: Mon, 12 Oct 2026 11:06:33 +0000 Subject: [PATCH 085/233] fix(@angular/build): disable Vitest fsModuleCache in unit-test builder Vitest 5.0.4 enabled `fsModuleCache` by default, which caches transformed modules on disk keyed by the raw source file content on disk before calling Vite's `load()` hook. Because `@angular/build:unit-test` pre-bundles test entry points and their imported application modules into memory, changes to imported application files do not change the on-disk `.spec.ts` file content, causing Vitest's `fsModuleCache` to serve stale cached bundles across test runs. (cherry picked from commit f0a74e8f0ea04fd3f839be0120346067440b1350) --- .../build/src/builders/unit-test/runners/vitest/plugins.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/packages/angular/build/src/builders/unit-test/runners/vitest/plugins.ts b/packages/angular/build/src/builders/unit-test/runners/vitest/plugins.ts index 6be4c6e8ebe3..ec0cd0a8f269 100644 --- a/packages/angular/build/src/builders/unit-test/runners/vitest/plugins.ts +++ b/packages/angular/build/src/builders/unit-test/runners/vitest/plugins.ts @@ -271,6 +271,7 @@ export async function createVitestConfigPlugin( test: { name: projectName, include, + fsModuleCache: false, // CLI provider browser options override, if present ...(browser ? { browser } : {}), // Only override if the user explicitly set it via CLI @@ -290,6 +291,7 @@ export async function createVitestConfigPlugin( return { test: { + fsModuleCache: false, coverage: await generateCoverageOption( options.coverage, testConfig?.coverage, From 8d8335960de96cca695dd30b4aee49856501e9b5 Mon Sep 17 00:00:00 2001 From: Angular Robot Date: Mon, 12 Oct 2026 14:43:31 +0000 Subject: [PATCH 086/233] build: update cross-repo angular dependencies See associated pull request for more information. --- .../assistant-to-the-branch-manager.yml | 2 +- .github/workflows/ci.yml | 52 +- .github/workflows/dev-infra.yml | 6 +- .github/workflows/perf.yml | 6 +- .github/workflows/pr.yml | 44 +- MODULE.bazel | 6 +- MODULE.bazel.lock | 36 +- package.json | 2 +- pnpm-lock.yaml | 593 +++++++++--------- 9 files changed, 366 insertions(+), 381 deletions(-) diff --git a/.github/workflows/assistant-to-the-branch-manager.yml b/.github/workflows/assistant-to-the-branch-manager.yml index 5431306096a7..8c6035d666dc 100644 --- a/.github/workflows/assistant-to-the-branch-manager.yml +++ b/.github/workflows/assistant-to-the-branch-manager.yml @@ -18,6 +18,6 @@ jobs: - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: persist-credentials: false - - uses: angular/dev-infra/github-actions/branch-manager@b137f89f74478e0d2b3902372c538d5656795e9a # main + - uses: angular/dev-infra/github-actions/branch-manager@28ae58d2ad683fb3991006c23a9829c08b65aaec # main with: angular-robot-key: ${{ secrets.ANGULAR_ROBOT_PRIVATE_KEY }} diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index ad97a6cf125e..56dde16b608c 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -21,9 +21,9 @@ jobs: runs-on: ubuntu-latest steps: - name: Initialize environment - uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@b137f89f74478e0d2b3902372c538d5656795e9a # main + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@28ae58d2ad683fb3991006c23a9829c08b65aaec # main - name: Setup Bazel - uses: angular/dev-infra/github-actions/bazel/setup@b137f89f74478e0d2b3902372c538d5656795e9a # main + uses: angular/dev-infra/github-actions/bazel/setup@28ae58d2ad683fb3991006c23a9829c08b65aaec # main - name: Install node modules run: pnpm install --frozen-lockfile - name: Generate JSON schema types @@ -44,11 +44,11 @@ jobs: runs-on: ubuntu-latest steps: - name: Initialize environment - uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@b137f89f74478e0d2b3902372c538d5656795e9a # main + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@28ae58d2ad683fb3991006c23a9829c08b65aaec # main - name: Setup Bazel - uses: angular/dev-infra/github-actions/bazel/setup@b137f89f74478e0d2b3902372c538d5656795e9a # main + uses: angular/dev-infra/github-actions/bazel/setup@28ae58d2ad683fb3991006c23a9829c08b65aaec # main - name: Setup Bazel RBE - uses: angular/dev-infra/github-actions/bazel/configure-remote@b137f89f74478e0d2b3902372c538d5656795e9a # main + uses: angular/dev-infra/github-actions/bazel/configure-remote@28ae58d2ad683fb3991006c23a9829c08b65aaec # main with: google_credential: ${{ secrets.RBE_TRUSTED_BUILDS_USER }} - name: Install node modules @@ -61,11 +61,11 @@ jobs: runs-on: ubuntu-latest steps: - name: Initialize environment - uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@b137f89f74478e0d2b3902372c538d5656795e9a # main + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@28ae58d2ad683fb3991006c23a9829c08b65aaec # main - name: Setup Bazel - uses: angular/dev-infra/github-actions/bazel/setup@b137f89f74478e0d2b3902372c538d5656795e9a # main + uses: angular/dev-infra/github-actions/bazel/setup@28ae58d2ad683fb3991006c23a9829c08b65aaec # main - name: Setup Bazel RBE - uses: angular/dev-infra/github-actions/bazel/configure-remote@b137f89f74478e0d2b3902372c538d5656795e9a # main + uses: angular/dev-infra/github-actions/bazel/configure-remote@28ae58d2ad683fb3991006c23a9829c08b65aaec # main with: google_credential: ${{ secrets.RBE_TRUSTED_BUILDS_USER }} - name: Install node modules @@ -84,13 +84,13 @@ jobs: runs-on: ubuntu-latest steps: - name: Initialize environment - uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@b137f89f74478e0d2b3902372c538d5656795e9a # main + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@28ae58d2ad683fb3991006c23a9829c08b65aaec # main - name: Install node modules run: pnpm install --frozen-lockfile - name: Setup Bazel - uses: angular/dev-infra/github-actions/bazel/setup@b137f89f74478e0d2b3902372c538d5656795e9a # main + uses: angular/dev-infra/github-actions/bazel/setup@28ae58d2ad683fb3991006c23a9829c08b65aaec # main - name: Setup Bazel RBE - uses: angular/dev-infra/github-actions/bazel/configure-remote@b137f89f74478e0d2b3902372c538d5656795e9a # main + uses: angular/dev-infra/github-actions/bazel/configure-remote@28ae58d2ad683fb3991006c23a9829c08b65aaec # main with: google_credential: ${{ secrets.RBE_TRUSTED_BUILDS_USER }} - name: Run CLI E2E tests @@ -100,11 +100,11 @@ jobs: runs-on: ubuntu-latest steps: - name: Initialize environment - uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@b137f89f74478e0d2b3902372c538d5656795e9a # main + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@28ae58d2ad683fb3991006c23a9829c08b65aaec # main - name: Setup Bazel - uses: angular/dev-infra/github-actions/bazel/setup@b137f89f74478e0d2b3902372c538d5656795e9a # main + uses: angular/dev-infra/github-actions/bazel/setup@28ae58d2ad683fb3991006c23a9829c08b65aaec # main - name: Setup Bazel RBE - uses: angular/dev-infra/github-actions/bazel/configure-remote@b137f89f74478e0d2b3902372c538d5656795e9a # main + uses: angular/dev-infra/github-actions/bazel/configure-remote@28ae58d2ad683fb3991006c23a9829c08b65aaec # main with: google_credential: ${{ secrets.RBE_TRUSTED_BUILDS_USER }} - name: Install node modules @@ -137,7 +137,7 @@ jobs: runs-on: windows-2025 steps: - name: Initialize environment - uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@b137f89f74478e0d2b3902372c538d5656795e9a # main + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@28ae58d2ad683fb3991006c23a9829c08b65aaec # main - name: Install node modules run: pnpm install --frozen-lockfile - name: Download built Windows E2E tests @@ -164,13 +164,13 @@ jobs: runs-on: ubuntu-latest steps: - name: Initialize environment - uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@b137f89f74478e0d2b3902372c538d5656795e9a # main + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@28ae58d2ad683fb3991006c23a9829c08b65aaec # main - name: Install node modules run: pnpm install --frozen-lockfile - name: Setup Bazel - uses: angular/dev-infra/github-actions/bazel/setup@b137f89f74478e0d2b3902372c538d5656795e9a # main + uses: angular/dev-infra/github-actions/bazel/setup@28ae58d2ad683fb3991006c23a9829c08b65aaec # main - name: Setup Bazel RBE - uses: angular/dev-infra/github-actions/bazel/configure-remote@b137f89f74478e0d2b3902372c538d5656795e9a # main + uses: angular/dev-infra/github-actions/bazel/configure-remote@28ae58d2ad683fb3991006c23a9829c08b65aaec # main with: google_credential: ${{ secrets.RBE_TRUSTED_BUILDS_USER }} - name: Run CLI E2E tests @@ -188,13 +188,13 @@ jobs: runs-on: ubuntu-latest steps: - name: Initialize environment - uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@b137f89f74478e0d2b3902372c538d5656795e9a # main + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@28ae58d2ad683fb3991006c23a9829c08b65aaec # main - name: Install node modules run: pnpm install --frozen-lockfile - name: Setup Bazel - uses: angular/dev-infra/github-actions/bazel/setup@b137f89f74478e0d2b3902372c538d5656795e9a # main + uses: angular/dev-infra/github-actions/bazel/setup@28ae58d2ad683fb3991006c23a9829c08b65aaec # main - name: Setup Bazel RBE - uses: angular/dev-infra/github-actions/bazel/configure-remote@b137f89f74478e0d2b3902372c538d5656795e9a # main + uses: angular/dev-infra/github-actions/bazel/configure-remote@28ae58d2ad683fb3991006c23a9829c08b65aaec # main with: google_credential: ${{ secrets.RBE_TRUSTED_BUILDS_USER }} - name: Run CLI E2E tests @@ -208,13 +208,13 @@ jobs: SAUCE_TUNNEL_IDENTIFIER: angular-cli-${{ github.workflow }}-${{ github.run_number }} steps: - name: Initialize environment - uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@b137f89f74478e0d2b3902372c538d5656795e9a # main + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@28ae58d2ad683fb3991006c23a9829c08b65aaec # main - name: Install node modules run: pnpm install --frozen-lockfile - name: Setup Bazel - uses: angular/dev-infra/github-actions/bazel/setup@b137f89f74478e0d2b3902372c538d5656795e9a # main + uses: angular/dev-infra/github-actions/bazel/setup@28ae58d2ad683fb3991006c23a9829c08b65aaec # main - name: Setup Bazel RBE - uses: angular/dev-infra/github-actions/bazel/configure-remote@b137f89f74478e0d2b3902372c538d5656795e9a # main + uses: angular/dev-infra/github-actions/bazel/configure-remote@28ae58d2ad683fb3991006c23a9829c08b65aaec # main with: google_credential: ${{ secrets.RBE_TRUSTED_BUILDS_USER }} - name: Start Sauce Connect @@ -245,11 +245,11 @@ jobs: CIRCLE_BRANCH: ${{ github.ref_name }} steps: - name: Initialize environment - uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@b137f89f74478e0d2b3902372c538d5656795e9a # main + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@28ae58d2ad683fb3991006c23a9829c08b65aaec # main - name: Install node modules run: pnpm install --frozen-lockfile - name: Setup Bazel - uses: angular/dev-infra/github-actions/bazel/setup@b137f89f74478e0d2b3902372c538d5656795e9a # main + uses: angular/dev-infra/github-actions/bazel/setup@28ae58d2ad683fb3991006c23a9829c08b65aaec # main - run: pnpm admin snapshots --verbose env: SNAPSHOT_BUILDS_GITHUB_TOKEN: ${{ secrets.SNAPSHOT_BUILDS_GITHUB_TOKEN }} diff --git a/.github/workflows/dev-infra.yml b/.github/workflows/dev-infra.yml index 98d8d726c99b..f508452e9456 100644 --- a/.github/workflows/dev-infra.yml +++ b/.github/workflows/dev-infra.yml @@ -16,21 +16,21 @@ jobs: if: github.event_name == 'pull_request_target' runs-on: ubuntu-latest steps: - - uses: angular/dev-infra/github-actions/labeling/pull-request@b137f89f74478e0d2b3902372c538d5656795e9a # main + - uses: angular/dev-infra/github-actions/labeling/pull-request@28ae58d2ad683fb3991006c23a9829c08b65aaec # main with: angular-robot-key: ${{ secrets.ANGULAR_ROBOT_PRIVATE_KEY }} post_approval_changes: if: github.event_name == 'pull_request_target' runs-on: ubuntu-latest steps: - - uses: angular/dev-infra/github-actions/post-approval-changes@b137f89f74478e0d2b3902372c538d5656795e9a # main + - uses: angular/dev-infra/github-actions/post-approval-changes@28ae58d2ad683fb3991006c23a9829c08b65aaec # main with: angular-robot-key: ${{ secrets.ANGULAR_ROBOT_PRIVATE_KEY }} issue_labels: if: github.event_name == 'issues' runs-on: ubuntu-latest steps: - - uses: angular/dev-infra/github-actions/labeling/issue@b137f89f74478e0d2b3902372c538d5656795e9a # main + - uses: angular/dev-infra/github-actions/labeling/issue@28ae58d2ad683fb3991006c23a9829c08b65aaec # main with: angular-robot-key: ${{ secrets.ANGULAR_ROBOT_PRIVATE_KEY }} google-generative-ai-key: ${{ secrets.GOOGLE_GENERATIVE_AI_KEY }} diff --git a/.github/workflows/perf.yml b/.github/workflows/perf.yml index e61e4d1bb083..1c275f2d1a0d 100644 --- a/.github/workflows/perf.yml +++ b/.github/workflows/perf.yml @@ -22,7 +22,7 @@ jobs: workflows: ${{ steps.workflows.outputs.workflows }} steps: - name: Initialize environment - uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@b137f89f74478e0d2b3902372c538d5656795e9a # main + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@28ae58d2ad683fb3991006c23a9829c08b65aaec # main - name: Install node modules run: pnpm install --frozen-lockfile - id: workflows @@ -40,9 +40,9 @@ jobs: workflow: ${{ fromJSON(needs.list.outputs.workflows) }} steps: - name: Initialize environment - uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@b137f89f74478e0d2b3902372c538d5656795e9a # main + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@28ae58d2ad683fb3991006c23a9829c08b65aaec # main - name: Setup Bazel - uses: angular/dev-infra/github-actions/bazel/setup@b137f89f74478e0d2b3902372c538d5656795e9a # main + uses: angular/dev-infra/github-actions/bazel/setup@28ae58d2ad683fb3991006c23a9829c08b65aaec # main - name: Install node modules run: pnpm install --frozen-lockfile # We utilize the google-github-actions/auth action to allow us to get an active credential using workflow diff --git a/.github/workflows/pr.yml b/.github/workflows/pr.yml index 7cf337949011..d9195bdf9f8c 100644 --- a/.github/workflows/pr.yml +++ b/.github/workflows/pr.yml @@ -34,9 +34,9 @@ jobs: runs-on: ubuntu-latest steps: - name: Initialize environment - uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@b137f89f74478e0d2b3902372c538d5656795e9a # main + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@28ae58d2ad683fb3991006c23a9829c08b65aaec # main - name: Setup Bazel - uses: angular/dev-infra/github-actions/bazel/setup@b137f89f74478e0d2b3902372c538d5656795e9a # main + uses: angular/dev-infra/github-actions/bazel/setup@28ae58d2ad683fb3991006c23a9829c08b65aaec # main - name: Setup ESLint Caching uses: actions/cache@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0 with: @@ -66,17 +66,17 @@ jobs: # it has been merged. run: pnpm ng-dev format changed --check ${{ github.event.pull_request.base.sha }} - name: Check Package Licenses - uses: angular/dev-infra/github-actions/linting/licenses@b137f89f74478e0d2b3902372c538d5656795e9a # main + uses: angular/dev-infra/github-actions/linting/licenses@28ae58d2ad683fb3991006c23a9829c08b65aaec # main build: runs-on: ubuntu-latest steps: - name: Initialize environment - uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@b137f89f74478e0d2b3902372c538d5656795e9a # main + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@28ae58d2ad683fb3991006c23a9829c08b65aaec # main - name: Setup Bazel - uses: angular/dev-infra/github-actions/bazel/setup@b137f89f74478e0d2b3902372c538d5656795e9a # main + uses: angular/dev-infra/github-actions/bazel/setup@28ae58d2ad683fb3991006c23a9829c08b65aaec # main - name: Setup Bazel RBE - uses: angular/dev-infra/github-actions/bazel/configure-remote@b137f89f74478e0d2b3902372c538d5656795e9a # main + uses: angular/dev-infra/github-actions/bazel/configure-remote@28ae58d2ad683fb3991006c23a9829c08b65aaec # main - name: Install node modules run: pnpm install --frozen-lockfile - name: Build release targets @@ -93,11 +93,11 @@ jobs: runs-on: ubuntu-latest steps: - name: Initialize environment - uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@b137f89f74478e0d2b3902372c538d5656795e9a # main + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@28ae58d2ad683fb3991006c23a9829c08b65aaec # main - name: Setup Bazel - uses: angular/dev-infra/github-actions/bazel/setup@b137f89f74478e0d2b3902372c538d5656795e9a # main + uses: angular/dev-infra/github-actions/bazel/setup@28ae58d2ad683fb3991006c23a9829c08b65aaec # main - name: Setup Bazel RBE - uses: angular/dev-infra/github-actions/bazel/configure-remote@b137f89f74478e0d2b3902372c538d5656795e9a # main + uses: angular/dev-infra/github-actions/bazel/configure-remote@28ae58d2ad683fb3991006c23a9829c08b65aaec # main - name: Install node modules run: pnpm install --frozen-lockfile - name: Run module and package tests @@ -114,13 +114,13 @@ jobs: runs-on: ubuntu-latest steps: - name: Initialize environment - uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@b137f89f74478e0d2b3902372c538d5656795e9a # main + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@28ae58d2ad683fb3991006c23a9829c08b65aaec # main - name: Install node modules run: pnpm install --frozen-lockfile - name: Setup Bazel - uses: angular/dev-infra/github-actions/bazel/setup@b137f89f74478e0d2b3902372c538d5656795e9a # main + uses: angular/dev-infra/github-actions/bazel/setup@28ae58d2ad683fb3991006c23a9829c08b65aaec # main - name: Setup Bazel RBE - uses: angular/dev-infra/github-actions/bazel/configure-remote@b137f89f74478e0d2b3902372c538d5656795e9a # main + uses: angular/dev-infra/github-actions/bazel/configure-remote@28ae58d2ad683fb3991006c23a9829c08b65aaec # main - name: Run CLI E2E tests run: pnpm bazel test --test_env=E2E_SHARD_TOTAL=6 --test_env=E2E_SHARD_INDEX=${{ matrix.shard }} --config=e2e //tests:e2e.${{ matrix.subset }}_node${{ matrix.node }} @@ -128,11 +128,11 @@ jobs: runs-on: ubuntu-latest steps: - name: Initialize environment - uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@b137f89f74478e0d2b3902372c538d5656795e9a # main + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@28ae58d2ad683fb3991006c23a9829c08b65aaec # main - name: Setup Bazel - uses: angular/dev-infra/github-actions/bazel/setup@b137f89f74478e0d2b3902372c538d5656795e9a # main + uses: angular/dev-infra/github-actions/bazel/setup@28ae58d2ad683fb3991006c23a9829c08b65aaec # main - name: Setup Bazel RBE - uses: angular/dev-infra/github-actions/bazel/configure-remote@b137f89f74478e0d2b3902372c538d5656795e9a # main + uses: angular/dev-infra/github-actions/bazel/configure-remote@28ae58d2ad683fb3991006c23a9829c08b65aaec # main - name: Install node modules run: pnpm install --frozen-lockfile - name: Build E2E tests for Windows on Linux @@ -156,7 +156,7 @@ jobs: runs-on: windows-2025 steps: - name: Initialize environment - uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@b137f89f74478e0d2b3902372c538d5656795e9a # main + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@28ae58d2ad683fb3991006c23a9829c08b65aaec # main - name: Install node modules run: pnpm install --frozen-lockfile - name: Download built Windows E2E tests @@ -183,13 +183,13 @@ jobs: runs-on: ubuntu-latest steps: - name: Initialize environment - uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@b137f89f74478e0d2b3902372c538d5656795e9a # main + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@28ae58d2ad683fb3991006c23a9829c08b65aaec # main - name: Install node modules run: pnpm install --frozen-lockfile - name: Setup Bazel - uses: angular/dev-infra/github-actions/bazel/setup@b137f89f74478e0d2b3902372c538d5656795e9a # main + uses: angular/dev-infra/github-actions/bazel/setup@28ae58d2ad683fb3991006c23a9829c08b65aaec # main - name: Setup Bazel RBE - uses: angular/dev-infra/github-actions/bazel/configure-remote@b137f89f74478e0d2b3902372c538d5656795e9a # main + uses: angular/dev-infra/github-actions/bazel/configure-remote@28ae58d2ad683fb3991006c23a9829c08b65aaec # main - name: Run CLI E2E tests run: pnpm bazel test --test_env=E2E_SHARD_TOTAL=3 --test_env=E2E_SHARD_INDEX=${{ matrix.shard }} --config=e2e //tests:e2e.${{ matrix.subset }}_node${{ matrix.node }} @@ -205,12 +205,12 @@ jobs: runs-on: ubuntu-latest steps: - name: Initialize environment - uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@b137f89f74478e0d2b3902372c538d5656795e9a # main + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@28ae58d2ad683fb3991006c23a9829c08b65aaec # main - name: Install node modules run: pnpm install --frozen-lockfile - name: Setup Bazel - uses: angular/dev-infra/github-actions/bazel/setup@b137f89f74478e0d2b3902372c538d5656795e9a # main + uses: angular/dev-infra/github-actions/bazel/setup@28ae58d2ad683fb3991006c23a9829c08b65aaec # main - name: Setup Bazel RBE - uses: angular/dev-infra/github-actions/bazel/configure-remote@b137f89f74478e0d2b3902372c538d5656795e9a # main + uses: angular/dev-infra/github-actions/bazel/configure-remote@28ae58d2ad683fb3991006c23a9829c08b65aaec # main - name: Run CLI E2E tests run: pnpm bazel test --test_env=E2E_SHARD_TOTAL=6 --test_env=E2E_SHARD_INDEX=${{ matrix.shard }} --config=e2e //tests:e2e.snapshots.${{ matrix.subset }}_node${{ matrix.node }} diff --git a/MODULE.bazel b/MODULE.bazel index 084897dc11a9..238a75c1749d 100644 --- a/MODULE.bazel +++ b/MODULE.bazel @@ -19,21 +19,21 @@ bazel_dep(name = "aspect_rules_jasmine", version = "2.0.4") bazel_dep(name = "rules_angular") git_override( module_name = "rules_angular", - commit = "2d9142c529ac31dddf1bb4e7e5a61c696f97a8f4", + commit = "b5869cff3db5d2217b8896d483e75af8a1d26712", remote = "https://github.com/angular/rules_angular.git", ) bazel_dep(name = "devinfra") git_override( module_name = "devinfra", - commit = "b137f89f74478e0d2b3902372c538d5656795e9a", + commit = "28ae58d2ad683fb3991006c23a9829c08b65aaec", remote = "https://github.com/angular/dev-infra.git", ) bazel_dep(name = "rules_browsers") git_override( module_name = "rules_browsers", - commit = "dba44a25ad8789113c37c2aace5574d794faa7ef", + commit = "4b53d68eed02bbb0901b21fb02b8cf99f4f59a52", remote = "https://github.com/angular/rules_browsers.git", ) diff --git a/MODULE.bazel.lock b/MODULE.bazel.lock index baab026be468..6324d403541d 100644 --- a/MODULE.bazel.lock +++ b/MODULE.bazel.lock @@ -93,7 +93,6 @@ "https://bcr.bazel.build/modules/hermetic_launcher/0.0.15/source.json": "aceb903a3bda5131b0a3132ccf77f36f32b96dcb70864049ec8cfdf9c0b0f068", "https://bcr.bazel.build/modules/jq.bzl/0.1.0/MODULE.bazel": "2ce69b1af49952cd4121a9c3055faa679e748ce774c7f1fda9657f936cae902f", "https://bcr.bazel.build/modules/jq.bzl/0.4.0/MODULE.bazel": "a7b39b37589f2b0dad53fd6c1ccaabbdb290330caa920d7ef3e6aad068cd4ab2", - "https://bcr.bazel.build/modules/jq.bzl/0.7.0/MODULE.bazel": "9d382531c42e7a7f6f2ea486aa8f27c605c54f6109e565f04056015e5764deca", "https://bcr.bazel.build/modules/jq.bzl/0.7.1/MODULE.bazel": "2dc4fd806df09b30aa7e0339f141a661f72df6af237f6db1fc4ca5c5045f1772", "https://bcr.bazel.build/modules/jq.bzl/0.7.1/source.json": "0dbd7febb9361e34247c952e749f21f258b5123126248624c0d921c4592eac96", "https://bcr.bazel.build/modules/jsoncpp/1.9.5/MODULE.bazel": "31271aedc59e815656f5736f282bb7509a97c7ecb43e927ac1a37966e0578075", @@ -181,7 +180,6 @@ "https://bcr.bazel.build/modules/rules_nodejs/6.2.0/MODULE.bazel": "ec27907f55eb34705adb4e8257952162a2d4c3ed0f0b3b4c3c1aad1fac7be35e", "https://bcr.bazel.build/modules/rules_nodejs/6.5.0/MODULE.bazel": "546d0cf79f36f9f6e080816045f97234b071c205f4542e3351bd4424282a8810", "https://bcr.bazel.build/modules/rules_nodejs/6.7.3/MODULE.bazel": "c22a48b2a0dbf05a9dc5f83837bbc24c226c1f6e618de3c3a610044c9f336056", - "https://bcr.bazel.build/modules/rules_nodejs/6.7.5/MODULE.bazel": "97e6794043821d23c013baa4a50fd1c599f2e6ae92b06e2c5f1cd7074fd83e7c", "https://bcr.bazel.build/modules/rules_nodejs/6.7.6/MODULE.bazel": "45f203b9c0d721bcb1a5932815f218091fa2169cede2af3d88a8a17a4fb7676a", "https://bcr.bazel.build/modules/rules_nodejs/6.7.6/source.json": "ad9987b7979be1ce93d10ffee9b6af4f84f8835cbc7def27937d632da2e4750e", "https://bcr.bazel.build/modules/rules_pkg/0.7.0/MODULE.bazel": "df99f03fc7934a4737122518bb87e667e62d780b610910f0447665a7e2be62dc", @@ -447,16 +445,16 @@ }, "@@rules_browsers+//browsers:extensions.bzl%browsers": { "general": { - "bzlTransitiveDigest": "v0vEY6SvVg9HBAENk4KWY5NR6epcg4ucdSnkhcCNv8E=", + "bzlTransitiveDigest": "/FonktAou7w4aKjGZUZDFFOlASeGnKNw0QALxUIdtuE=", "usagesDigest": "FmXYJVoVJlnfUU8x8gObSvu4qWcco/9Faw61aC/wBF0=", "recordedInputs": [], "generatedRepoSpecs": { "rules_browsers_chrome_linux": { "repoRuleId": "@@rules_browsers+//browsers/private:browser_repo.bzl%browser_repo", "attributes": { - "sha256": "272b05d40a44082c82d09beb35c7cb7116564a6a85ff2f7a48bc161129fc5772", + "sha256": "9541eafbc02f85e3ec0c24b05f8bbffe88094389949860681bf6055aef668d7b", "urls": [ - "https://storage.googleapis.com/chrome-for-testing-public/157.0.8089.0/linux64/chrome-headless-shell-linux64.zip" + "https://storage.googleapis.com/chrome-for-testing-public/157.0.8099.0/linux64/chrome-headless-shell-linux64.zip" ], "named_files": { "CHROME-HEADLESS-SHELL": "chrome-headless-shell-linux64/chrome-headless-shell" @@ -472,9 +470,9 @@ "rules_browsers_chrome_mac": { "repoRuleId": "@@rules_browsers+//browsers/private:browser_repo.bzl%browser_repo", "attributes": { - "sha256": "9c28150b8c24fa99ac1e9e39fa07247b61d7f6f15f1c25ca9273c1b4273e2afd", + "sha256": "358f032d48a0b825b0601b89b970da5a7c245344ed7a557a3ef8613c342521b0", "urls": [ - "https://storage.googleapis.com/chrome-for-testing-public/157.0.8089.0/mac-x64/chrome-headless-shell-mac-x64.zip" + "https://storage.googleapis.com/chrome-for-testing-public/157.0.8099.0/mac-x64/chrome-headless-shell-mac-x64.zip" ], "named_files": { "CHROME-HEADLESS-SHELL": "chrome-headless-shell-mac-x64/chrome-headless-shell" @@ -490,9 +488,9 @@ "rules_browsers_chrome_mac_arm": { "repoRuleId": "@@rules_browsers+//browsers/private:browser_repo.bzl%browser_repo", "attributes": { - "sha256": "a6471f52b4eeb52af88d2f45e16125a9327517fd8b43512fc5561a3318487640", + "sha256": "c3de600edda5e11aa40918f123781040cd6e9c2509a2acfc466b773bf7c9b326", "urls": [ - "https://storage.googleapis.com/chrome-for-testing-public/157.0.8089.0/mac-arm64/chrome-headless-shell-mac-arm64.zip" + "https://storage.googleapis.com/chrome-for-testing-public/157.0.8099.0/mac-arm64/chrome-headless-shell-mac-arm64.zip" ], "named_files": { "CHROME-HEADLESS-SHELL": "chrome-headless-shell-mac-arm64/chrome-headless-shell" @@ -508,9 +506,9 @@ "rules_browsers_chrome_win64": { "repoRuleId": "@@rules_browsers+//browsers/private:browser_repo.bzl%browser_repo", "attributes": { - "sha256": "64332865f3d250a66f704e90d37a3d57f9800d6ea774138ede35ea37d1af7f2c", + "sha256": "b2e81e06ac46d3355bc6428b3abe97308d34e810d4404427bbd14665111e67a1", "urls": [ - "https://storage.googleapis.com/chrome-for-testing-public/157.0.8089.0/win64/chrome-headless-shell-win64.zip" + "https://storage.googleapis.com/chrome-for-testing-public/157.0.8099.0/win64/chrome-headless-shell-win64.zip" ], "named_files": { "CHROME-HEADLESS-SHELL": "chrome-headless-shell-win64/chrome-headless-shell.exe" @@ -526,9 +524,9 @@ "rules_browsers_chromedriver_linux": { "repoRuleId": "@@rules_browsers+//browsers/private:browser_repo.bzl%browser_repo", "attributes": { - "sha256": "0901026cbac4cce608a95bcbdcc87166e7736c9cc0431f5d3466058c9e570aec", + "sha256": "cf16fed1899de0f0b8999389779cefbb6696c5fd44ad9718ce2195a3ff5ca029", "urls": [ - "https://storage.googleapis.com/chrome-for-testing-public/157.0.8089.0/linux64/chromedriver-linux64.zip" + "https://storage.googleapis.com/chrome-for-testing-public/157.0.8099.0/linux64/chromedriver-linux64.zip" ], "named_files": { "CHROMEDRIVER": "chromedriver-linux64/chromedriver" @@ -542,9 +540,9 @@ "rules_browsers_chromedriver_mac": { "repoRuleId": "@@rules_browsers+//browsers/private:browser_repo.bzl%browser_repo", "attributes": { - "sha256": "69b0982bfe954c969cbc9357a39efb2f1861447f4168017831ffafec62448d90", + "sha256": "ba472bdd32ee62a98f04fcca364015a0df241fdf85ee7d834a048b5fdfd90fd3", "urls": [ - "https://storage.googleapis.com/chrome-for-testing-public/157.0.8089.0/mac-x64/chromedriver-mac-x64.zip" + "https://storage.googleapis.com/chrome-for-testing-public/157.0.8099.0/mac-x64/chromedriver-mac-x64.zip" ], "named_files": { "CHROMEDRIVER": "chromedriver-mac-x64/chromedriver" @@ -558,9 +556,9 @@ "rules_browsers_chromedriver_mac_arm": { "repoRuleId": "@@rules_browsers+//browsers/private:browser_repo.bzl%browser_repo", "attributes": { - "sha256": "18d30af4843f5535d56ab615702749650f1fc9c6b67ec3fd419ed5a9d4fcbf58", + "sha256": "8fe44ebac5303278a5d533c114ad0dbed0df9c218bce5b80d606078472ea95bd", "urls": [ - "https://storage.googleapis.com/chrome-for-testing-public/157.0.8089.0/mac-arm64/chromedriver-mac-arm64.zip" + "https://storage.googleapis.com/chrome-for-testing-public/157.0.8099.0/mac-arm64/chromedriver-mac-arm64.zip" ], "named_files": { "CHROMEDRIVER": "chromedriver-mac-arm64/chromedriver" @@ -574,9 +572,9 @@ "rules_browsers_chromedriver_win64": { "repoRuleId": "@@rules_browsers+//browsers/private:browser_repo.bzl%browser_repo", "attributes": { - "sha256": "9b79fc95eed9212d5888a1a7de456eba68df54d65b6fb490ce34d55efdc5cd48", + "sha256": "1fadd71af32db4e3497ce4faac3f07503f4c4cdad8747e71ff62c5c9c3dd05e1", "urls": [ - "https://storage.googleapis.com/chrome-for-testing-public/157.0.8089.0/win64/chromedriver-win64.zip" + "https://storage.googleapis.com/chrome-for-testing-public/157.0.8099.0/win64/chromedriver-win64.zip" ], "named_files": { "CHROMEDRIVER": "chromedriver-win64/chromedriver.exe" diff --git a/package.json b/package.json index 885a0a81ef48..3079b7f41ec4 100644 --- a/package.json +++ b/package.json @@ -55,7 +55,7 @@ "@angular/forms": "22.2.2", "@angular/localize": "22.2.2", "@angular/material": "22.2.2", - "@angular/ng-dev": "https://github.com/angular/dev-infra-private-ng-dev-builds.git#89b8c002e5d47ba1cbc4483d3ec06b0ae0aaccb7", + "@angular/ng-dev": "https://github.com/angular/dev-infra-private-ng-dev-builds.git#fa4308affb4a0dde34ebc95196b58550752485a2", "@angular/platform-browser": "22.2.2", "@angular/platform-server": "22.2.2", "@angular/router": "22.2.2", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 8c98e54f3942..7181b3bff33e 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -208,8 +208,8 @@ importers: specifier: 22.2.2 version: 22.2.2(641510506f6736c740497081311accfd) '@angular/ng-dev': - specifier: https://github.com/angular/dev-infra-private-ng-dev-builds.git#89b8c002e5d47ba1cbc4483d3ec06b0ae0aaccb7 - version: https://codeload.github.com/angular/dev-infra-private-ng-dev-builds/tar.gz/89b8c002e5d47ba1cbc4483d3ec06b0ae0aaccb7 + specifier: https://github.com/angular/dev-infra-private-ng-dev-builds.git#fa4308affb4a0dde34ebc95196b58550752485a2 + version: https://codeload.github.com/angular/dev-infra-private-ng-dev-builds/tar.gz/fa4308affb4a0dde34ebc95196b58550752485a2 '@angular/platform-browser': specifier: 22.2.2 version: 22.2.2(@angular/animations@22.2.2(@angular/core@22.2.2(@angular/compiler@22.2.2)(rxjs@7.8.2)(zone.js@0.16.3)))(@angular/common@22.2.2(@angular/core@22.2.2(@angular/compiler@22.2.2)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2))(@angular/core@22.2.2(@angular/compiler@22.2.2)(rxjs@7.8.2)(zone.js@0.16.3)) @@ -1104,9 +1104,9 @@ packages: '@angular/platform-browser': ^22.0.0 || ^23.0.0 rxjs: ^6.5.3 || ^7.4.0 - '@angular/ng-dev@https://codeload.github.com/angular/dev-infra-private-ng-dev-builds/tar.gz/89b8c002e5d47ba1cbc4483d3ec06b0ae0aaccb7': - resolution: {gitHosted: true, integrity: sha512-vfMwQfoXYY5dX8IISR/9DpsLT+py7Zm2Nqj6CybryjFosxMxW4ajXKfJ3Zywu2k0wPfRVoQY+PMZ78vfPji+qQ==, tarball: https://codeload.github.com/angular/dev-infra-private-ng-dev-builds/tar.gz/89b8c002e5d47ba1cbc4483d3ec06b0ae0aaccb7} - version: 0.0.0-8b6cbbca278a26f2495275c5d9d0d8633573162d + '@angular/ng-dev@https://codeload.github.com/angular/dev-infra-private-ng-dev-builds/tar.gz/fa4308affb4a0dde34ebc95196b58550752485a2': + resolution: {gitHosted: true, integrity: sha512-zq1Lg7edQb2cf9QrSiQEU/+LwY4e/af9tN9W3hO5jDdYK+gp+sYZbBbuzounSWkmK+j+oG0K5CA9/kmyHAimZg==, tarball: https://codeload.github.com/angular/dev-infra-private-ng-dev-builds/tar.gz/fa4308affb4a0dde34ebc95196b58550752485a2} + version: 0.0.0-f28485704b2d1f81ae380a8296a4f14d9852c248 hasBin: true '@angular/platform-browser@22.2.2': @@ -1752,12 +1752,12 @@ packages: resolution: {integrity: sha512-ooWCrlZP11i8GImSjTHYHLkvFDP48nS4+204nGb1RiX/WXYHmJA2III9/e2DWVabCESdW7hBAEzHRqUn9OUVvQ==} engines: {node: '>=0.1.90'} - '@conventional-changelog/git-client@3.1.2': - resolution: {integrity: sha512-jZqwnJwf7nboIlAcw/mkOjVa6DexCcUOgT2oOQgkoi3z9vR8tGFkcMy2BFcYwjhL9sYcDDXkRQDayiDieCoW7A==} + '@conventional-changelog/git-client@3.2.0': + resolution: {integrity: sha512-sD/E0vzpkoDz/dqM1Hhv0ihC4KBw6RXjefeO8SG1XrX+wGkMxe1pKeedkKDPCtr2JjuhbuS9aJNgOvnT8hbeBw==} engines: {node: '>=22'} peerDependencies: conventional-commits-filter: ^6.0.1 - conventional-commits-parser: ^7.1.2 + conventional-commits-parser: ^7.1.3 peerDependenciesMeta: conventional-commits-filter: optional: true @@ -2025,9 +2025,9 @@ packages: '@noble/hashes': optional: true - '@firebase/ai@2.16.0': - resolution: {integrity: sha512-WRVxl58B61Orwf7st7949ZIW2L4huV80Gpaum1z8v2eH+m2xaxWtC8mOjQyVAOirr6O/yf89cBjlPvoyBpBfTg==} - engines: {node: '>=20.0.0'} + '@firebase/ai@3.0.0': + resolution: {integrity: sha512-66jJAi6JUmyXna89xaDONmfvupO1wNc3f2BegPwUImagbbpKdVeycE3kMqbU4jiDLL14N5PHzadovvxpaqD2hw==} + engines: {node: '>=24.12.0'} peerDependencies: '@firebase/app': 0.x '@firebase/app-types': 0.x @@ -2065,20 +2065,20 @@ packages: peerDependencies: '@firebase/app': 0.x - '@firebase/app-compat@0.5.18': - resolution: {integrity: sha512-77H57WuGEsgrv59HdtuhHG+eQdP8di6myz7O93yW6yTZlR/tLSmsCxCq5vHp6AWWDwSV0EVtKUvizXQiQZVBWA==} - engines: {node: '>=20.0.0'} + '@firebase/app-compat@0.5.19': + resolution: {integrity: sha512-pdT+THcv3h43LcawVJ+MUTzofL7umBaCvCgdbr01fnTXrbQU2RSHb0Po/YsF7w+tgjCycg84zCgZbd51NmoIaA==} + engines: {node: '>=24.12.0'} '@firebase/app-types@0.9.6': resolution: {integrity: sha512-yPLahy7Esfu2w/yme3msVK4xTkDXQqq6szfQn8yVOQpCKiT5GVFjqNpLbuz6NkX0WuTwUidkmPewW3r4xkvpeg==} - '@firebase/app@0.16.2': - resolution: {integrity: sha512-fyCLPahl3r0Zb7Wzm+JLWcOOH3SaDgAyJzJ8EWIDiv51aNiv+2Pjbpa6myEuP7iXxjmJqrcbVm0GUF7h229T1Q==} - engines: {node: '>=20.0.0'} + '@firebase/app@0.16.3': + resolution: {integrity: sha512-L2mYqVV2ilnek+W4JG7yasA97TsXCwx+f7/abweX5uSp3dkPa5Luiglt3s9YWfh1fBR3SWH/AkRgAwUpDGyCjg==} + engines: {node: '>=24.12.0'} - '@firebase/auth-compat@0.6.11': - resolution: {integrity: sha512-L+xp3DTJQrBV08Vt0UhcL/ofUOSjXom7JOJfbT6oas4o7gCrQnTYFKs8wfiuKLmHoo8BxMr5LdgjAs7o6aAsqQ==} - engines: {node: '>=20.0.0'} + '@firebase/auth-compat@0.6.12': + resolution: {integrity: sha512-Vspo2zx1RR6LB7zuM7TduD1clMLT/x3Wr97u2jf9s2JrhYArJAFKeEu8bRWF1DoX54z6W9N77SdPRbPAiLKPpg==} + engines: {node: '>=24.12.0'} peerDependencies: '@firebase/app': 0.x '@firebase/app-compat': 0.x @@ -2092,9 +2092,9 @@ packages: '@firebase/app-types': 0.x '@firebase/util': 1.x - '@firebase/auth@1.13.6': - resolution: {integrity: sha512-MKRLvF72HJ/irNn2fJR0Gv5FOZNtqv1IBeJHRwK8l8pZ/wi9vuUw8ecyCMvQDDNxfS6uW0MWACL5KC4Y8Pp+fA==} - engines: {node: '>=20.0.0'} + '@firebase/auth@1.13.7': + resolution: {integrity: sha512-00wn8cMrh1ZyEPF6RO5G081Xq1b57FN0QxChiAda0hy/D3Q5TrMk30qhWszRWCgXPRipw6yM6qtqUew3u3qEjA==} + engines: {node: '>=24.12.0'} peerDependencies: '@firebase/app': 0.x '@react-native-async-storage/async-storage': ^2.2.0 || ^3.0.0 @@ -2130,9 +2130,9 @@ packages: resolution: {integrity: sha512-/JGpvszLoNXNgzilRXocigGfFF4hbcPA9wN1i1kjJx6oKkXgkHteZYl3lQs1lJX3ETDf6bv7zI15lPMVUp4sAQ==} engines: {node: '>=20.0.0'} - '@firebase/firestore-compat@0.4.14': - resolution: {integrity: sha512-HJ2HBNgNPrRsWIJ4E+Kc0u0h1U7HlF7If8AtYjie9HZXlMUmwYSJaXBj9VFm6gkSj5dlKZNcOQ0Ou25CVVG6rA==} - engines: {node: '>=20.0.0'} + '@firebase/firestore-compat@0.4.15': + resolution: {integrity: sha512-/hWibRTNFsWkZZi1dbDS1hiJIMezYUMPrRjMmBXevel5b368XWY+NvfOaSxgy3+fDb6I+uZ7SKGFyL06gW3vTA==} + engines: {node: '>=24.12.0'} peerDependencies: '@firebase/app': 0.x '@firebase/app-compat': 0.x @@ -2143,9 +2143,9 @@ packages: '@firebase/app-types': 0.x '@firebase/util': 1.x - '@firebase/firestore@4.17.2': - resolution: {integrity: sha512-SiyQEK1dYPOjItFVA+kZGdvOoRAtMebDBvUaSxJPNZMkKcRwYYK2kzWo5UXTZZj523uMxJnkr+KKVySEMme3kQ==} - engines: {node: '>=20.0.0'} + '@firebase/firestore@4.18.0': + resolution: {integrity: sha512-28aKMUeM+L4fuxx5hurvQK31KLh/KRutaP1544avVWuR4mNTAC0FQoHg8gbkN5NoJj3yN9/ZFGSFSVPR8/x/BQ==} + engines: {node: '>=24.12.0'} peerDependencies: '@firebase/app': 0.x @@ -2213,8 +2213,8 @@ packages: peerDependencies: '@firebase/app': 0.x - '@firebase/remote-config-compat@0.2.29': - resolution: {integrity: sha512-mY7JtTISK6F4g4T0x3kVepr5cp0NXL7f5yjIUXXGaTrg4qUlFBWRbENaHaqZ78dwmNcLm24h/yPsOVRlDXEXhA==} + '@firebase/remote-config-compat@0.2.30': + resolution: {integrity: sha512-Q4sQKhQ8TPEMOcCUvUBfGeAP1DfcG7FGBfA9yFUn/XRr4vSToY0DTmK28Nh7lgLQYzs6D5Ng6knSoXH+aGn1Tg==} peerDependencies: '@firebase/app': 0.x '@firebase/app-compat': 0.x @@ -2222,14 +2222,14 @@ packages: '@firebase/remote-config-types@0.5.2': resolution: {integrity: sha512-i8k1omVfoAnaT1ZPv2FFjxMZrATYsO/GnFgHEj5+7fAJLzi8wLnGGv1WK06oEAD6ltrWXSO1HzeNyajn/NjMWw==} - '@firebase/remote-config@0.9.2': - resolution: {integrity: sha512-Rii93DkXjM+RE/ytHdYa7EIiQLJbdBr+W8EEiqd/vbLCOC+1FdkDuRiumJBp6t3yewHGbdqbpjB3fk3z0cZ+8g==} + '@firebase/remote-config@0.9.3': + resolution: {integrity: sha512-9DbuFNAFeUbVJQZmwLZfdoLRNFWV43V4UqaRpDkaSIdTmVWhzctPeISGkWe4sKTsqpoyldRumquS0gqWZg05fQ==} peerDependencies: '@firebase/app': 0.x - '@firebase/storage-compat@0.4.5': - resolution: {integrity: sha512-vO0tFPxXbKDKdlTu8tYT08S9t9ezUTJYEdLCULpWxWq2aq6zojwN1QmAB+1a50AI/g47GlWUJn1XPncm/PDZsw==} - engines: {node: '>=20.0.0'} + '@firebase/storage-compat@0.4.6': + resolution: {integrity: sha512-te0IsqX1bM+OZCJF7jNSKXcMqCA2yYmpshRHjX4axy0lI/P9ZP9GLjEZMVL8wrjUWF4e3cZxMZTbck3Zd5E1hA==} + engines: {node: '>=24.12.0'} peerDependencies: '@firebase/app': 0.x '@firebase/app-compat': 0.x @@ -2240,9 +2240,9 @@ packages: '@firebase/app-types': 0.x '@firebase/util': 1.x - '@firebase/storage@0.14.5': - resolution: {integrity: sha512-r2tozN/BlEewLi70tJNUQPzWwbex9GM7NgXZsamHKQrjKEfcR0i4jGgHBKAKA4hbwiPE9eNMb3hcxWnDpeJZwg==} - engines: {node: '>=20.0.0'} + '@firebase/storage@0.14.6': + resolution: {integrity: sha512-9WjohxpjbfcySjCp8kIbd1ZhtmCQFQLqPtDQ+wmZ5PVXimTDjDsSx/RZjwwK89MjCTXB9fCdmvZkJxplZn4W1A==} + engines: {node: '>=24.12.0'} peerDependencies: '@firebase/app': 0.x @@ -2284,8 +2284,8 @@ packages: resolution: {integrity: sha512-IJn+8A3QZJfe7FUtWqHVNo3xJs7KFpurCWGWCiCz3oEh+BkRymKZ1QxfAbU2yGMDzTytLGQ2IV6T2r3cuo75/w==} engines: {node: '>=18'} - '@google/genai@2.25.0': - resolution: {integrity: sha512-g1hyidWxahzIg+hh+lLqPeBJl+Fu6051we2QKhFXdWgE4yGYf8PWOS8S3mMAdpe3eLx3KCWmhQR7GWyd3LYT1A==} + '@google/genai@2.28.0': + resolution: {integrity: sha512-hyNAJj+ywu3L46qlZod6KO/JvcT3QONz6VCiPevC/FWOjAD+LQb7DMLUoV8vzoLpt61Q0ruQX99iqbxEjPJWmw==} engines: {node: '>=20.0.0'} peerDependencies: '@modelcontextprotocol/sdk': ^1.25.2 @@ -2356,6 +2356,15 @@ packages: '@types/node': optional: true + '@inquirer/confirm@6.3.3': + resolution: {integrity: sha512-ImOBgpl/sJTFp8naeSkNu4S0Sf8F8pxv3/CUx+LoBAdQvCVqFz6rSB2A/oZYsJge3+yphbEDxEkfaRNYq1OU0A==} + engines: {node: '>=23.5.0 || ^22.13.0 || ^20.17.0'} + peerDependencies: + '@types/node': '>=18' + peerDependenciesMeta: + '@types/node': + optional: true + '@inquirer/core@12.0.4': resolution: {integrity: sha512-M5fB67y7jPObI45vhD82RskWwCSm0scOvenV/I6K8tIi2gfr9DXqQqJ+iw+Wi6SgapikdOiJibYzz1gW47fsDg==} engines: {node: '>=23.5.0 || ^22.13.0 || ^20.17.0'} @@ -2432,6 +2441,15 @@ packages: '@types/node': optional: true + '@inquirer/prompts@8.7.3': + resolution: {integrity: sha512-DHK20kO+H5k/XcJQpHQUpVQbMYHHhZchlGWhZVMUV4WIuRuBW5744hipOtriE1vMqPLgnIyXFMHWKkIbTepa4Q==} + engines: {node: '>=23.5.0 || ^22.13.0 || ^20.17.0'} + peerDependencies: + '@types/node': '>=18' + peerDependenciesMeta: + '@types/node': + optional: true + '@inquirer/rawlist@5.3.6': resolution: {integrity: sha512-2exExhQ5xTBqfN/rRlZkvM1Gm3b0eiLcWe2NqxWxe7qYmnU4M3j/n9TwzfPUb+Q7dAAz9TmBtDWWdF3jbp4ZLA==} engines: {node: '>=23.5.0 || ^22.13.0 || ^20.17.0'} @@ -2725,9 +2743,9 @@ packages: cpu: [x64] os: [win32] - '@mswjs/interceptors@0.41.9': - resolution: {integrity: sha512-VVPPgHyQ6ShqnrmDWuxjmUIsO9gWyOZFmuOfLd9LfBGQJwZfy0gvv9pbHSJuoFNIYC7ZDX9aoFwowjcdSC4E8w==} - engines: {node: '>=18'} + '@mswjs/interceptors@0.44.0': + resolution: {integrity: sha512-IYHevRStF4ijM20GI9c9Ndhw483NSAjCydQhUr4/zIB0BNLsTVw3vFAxTo6TlvX4QnV60wEHttUa9539TTAq+A==} + engines: {node: '>=22'} '@napi-rs/lzma-linux-x64-gnu@1.5.1': resolution: {integrity: sha512-oTXEIha4SsuXdTA4Iyskj0kpdx2yVXdhd75c2v3xGrHFfVMsbhTPZU/nMPL4sWKo4pBHm3aucLaqGlF696dTyQ==} @@ -2923,12 +2941,6 @@ packages: peerDependencies: '@octokit/core': '>=6' - '@octokit/plugin-paginate-rest@15.0.0': - resolution: {integrity: sha512-lw9A9YL5s4VPj+VEx8uMxaxQm2YTgrPDkrLEuZuu18R8TK3oPcXF4K6t52nx6xn1RcogZC9i188sAr/4XYJaQQ==} - engines: {node: '>= 20'} - peerDependencies: - '@octokit/core': '>=6' - '@octokit/plugin-request-log@6.0.0': resolution: {integrity: sha512-UkOzeEN3W91/eBq9sPZNQ7sUBvYCqYbrrD8gTbBuGtHEuycE4/awMXcYvx6sVYo7LypPhmQwwpUe4Yyu4QZN5Q==} engines: {node: '>= 20'} @@ -2968,14 +2980,8 @@ packages: '@octokit/types@18.0.0': resolution: {integrity: sha512-l6bAF43PNxkJp6g+W4PjoUSSkxHomXw2nOum5CTftJz1NlV3vu93NImgOYtLf6CbBUb5j+fiuzW0PPQ5JTSvZA==} - '@open-draft/deferred-promise@2.2.0': - resolution: {integrity: sha512-CecwLWx3rhxVQF6V4bAgPS5t+So2sTbPgAzafKkVizyi7tlwpcFpdFqq+wqF2OwNBmqFuu6tOyouTuxgpMfzmA==} - - '@open-draft/logger@0.3.0': - resolution: {integrity: sha512-X2g45fzhxH238HKO4xbSr7+wBS8Fvw6ixhTDuvLd5mqh6bJJCFAPwU9mPDxbcrRtfxv4u5IHCEH77BmxvXmmxQ==} - - '@open-draft/until@2.1.0': - resolution: {integrity: sha512-U69T3ItWHvLwGg5eJ0n3I62nWuE6ilHlmz7zM0npLBRvPRd7e6NYmg54vvRtP5mZG7kZqZCFVdsTWo7BPtBujg==} + '@open-draft/until@3.0.1': + resolution: {integrity: sha512-s7/9ELP4aP9YZtW7RJaa0Xf3RISaRH9+EFN18FtykJYRHGNrl8f9ymvoNXzjhrjmftFvkQudtuDU9RYhk0xs3A==} '@opentelemetry/api@1.9.1': resolution: {integrity: sha512-gLyJlPHPZYdAk1JENA9LeHejZe1Ti77/pTeFm/nMXmQH/HFZlcS/O2XJB+L8fkbrNSqhdtlvjBVjxwUYanNH5Q==} @@ -3653,6 +3659,9 @@ packages: '@types/cors@2.8.19': resolution: {integrity: sha512-mFNylyeyqN93lfe/9CSxOGREz8cpzAhH+E93xJ4xWQf62V8sQ/24reV2nyzUWM6H6Xji+GGHpkbLe7pVoUEskg==} + '@types/debug@4.1.13': + resolution: {integrity: sha512-KSVgmQmzMwPlmtljOomayoR89W4FynCAi3E8PPs7vmDVPe84hT+vGPKkJfThkmXs0x0jAaa9U8uW8bbfyS2fWw==} + '@types/deep-eql@4.0.2': resolution: {integrity: sha512-c9h9dVVMigMPc4bwTvC5dxqtqJZwQPePsWjPlpSOnojbor6pGqdk541lfA7AqFQr5pB1BRdq0juY9db81BwyFw==} @@ -3722,11 +3731,14 @@ packages: '@types/micromatch@2.3.35': resolution: {integrity: sha512-J749bHo/Zu56w0G0NI/IGHLQPiSsjx//0zJhfEVAN95K/xM5C8ZDmhkXtU3qns0sBOao7HuQzr8XV1/2o5LbXA==} + '@types/ms@2.1.0': + resolution: {integrity: sha512-GsCCIZDE/p3i96vtEqx+7dBUGXrc7zeSK3wwPHIaRThS+9OhWIXRqzs4d6k1SVU8g91DrNRWxWUGhp5KXQb2VA==} + '@types/node@22.20.5': resolution: {integrity: sha512-U2+DNr+wSjpsTS/wZGYHq7GcwfuSmKiKvoPvK22zwTlRhU91yOniN4qRR5KhIjvif7ysw/dz/hKmfDH0Ris4aA==} - '@types/node@24.19.0': - resolution: {integrity: sha512-zY+5tKxXdhGh1PYI0ac+7juvEu4OI6vWtVVoj5i2m42jxAY1U+zHGt6QCyOFwykdP62sM3MJ9stoYYUw5aCWew==} + '@types/node@24.19.1': + resolution: {integrity: sha512-aS3/DG0oM05K0RIXXP+hKjinGG5IgSSVGzswZxW3O0sS3pH4/fycXundUC9XsszgKCk4gHXylTEK6hyFxVxnoQ==} '@types/npm-package-arg@6.1.4': resolution: {integrity: sha512-vDgdbMy2QXHnAruzlv68pUtXCjmqUk3WrBAsRboRovsOmxbfn/WiYCjmecyKjGztnMps5dWp4Uq2prp+Ilo17Q==} @@ -4787,8 +4799,8 @@ packages: resolution: {integrity: sha512-cs+LadpH7Kpw0M3k8wurk+sOVVDAENA0iK4OBOrkL94j5lEVYRJ4j3zd2bhY9qgzyrPqthdcYT3axzRN7AliMg==} engines: {node: '>=22'} - conventional-commits-parser@7.1.2: - resolution: {integrity: sha512-O+x4N2yH+ijvqWlIyTHsXTAP+algNWgGbjY2duCe8w2vUMvUB95cLRslCPfTMQyLAKlet3bhZTdu6ozn4M+QJQ==} + conventional-commits-parser@7.1.3: + resolution: {integrity: sha512-Q9oWm1o9uy/oEsZQIraoFMZ4RuPD+79KgwWj6mJVP356tazolCB0piRLZ5Kz9te9p027uSEcUW+Gu44Eh+X79g==} engines: {node: '>=22'} hasBin: true @@ -4925,15 +4937,6 @@ packages: supports-color: optional: true - debug@4.4.0: - resolution: {integrity: sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA==} - engines: {node: '>=6.0'} - peerDependencies: - supports-color: '*' - peerDependenciesMeta: - supports-color: - optional: true - debug@4.4.3: resolution: {integrity: sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==} engines: {node: '>=6.0'} @@ -5441,8 +5444,8 @@ packages: resolution: {integrity: sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==} engines: {node: '>=10'} - firebase@12.19.0: - resolution: {integrity: sha512-kwXCLcI0ly2lkwygkbuRx6SsX3DSO96355YrWh9SWZ5ncsxK/y5cirn3sY6nZVSiBVE++2nL6Hchzu1EB8uohQ==} + firebase@13.0.0: + resolution: {integrity: sha512-4cChZajVtuOijT/t7Vw1GZRTuohCxw+aoc8DAwhF+CSbS+zhqHE+i5PzEVttIySw7oKerBDRZRyDt4FynrWecg==} flat-cache@6.1.23: resolution: {integrity: sha512-f++BY9pTk+983xK1FLzlLpmM0i0z+jHmx3QESGkURMXujQZz1k5wzwX6hjnQ8goaD0B+sYnDK1yZ6MTyZfUaqA==} @@ -5458,8 +5461,8 @@ packages: resolution: {integrity: sha512-kWyh8ADvHBFz6ua5xYOPnUroZTT/bwWfrCeL0Wj1dzG4/YOmOcfJ99W8dOVyyynJN35rZ9aCOtHChqQovV7yog==} engines: {node: '>=6'} - folder-hash@4.1.3: - resolution: {integrity: sha512-94fj+fXj1XHT8zGumUy/VlyFARc/yrslKJ2+vjrP/U6ftTdL7u68+gQhvSBjz9wrwTuty6BpZ7JsbEK5OU9RNw==} + folder-hash@4.1.4: + resolution: {integrity: sha512-BhHpJCYoTej4YH0C3HY4X49C2uOcWntjSD24T1GBYlfWcW/7mkHZov9HbvzCHQO+ZLbJ3VRE+cL1uEiaQvacLw==} engines: {node: '>=10.10.0'} hasBin: true @@ -6777,9 +6780,9 @@ packages: tailwindcss: optional: true - nock@14.0.17: - resolution: {integrity: sha512-EjRr1weMa4ALQX35AgZTEnP+weJJjlW1KGDiNM2IQC2069YDHas4f4B4UUYR+TTLyKWxJvOz2wObDKQs/LNreA==} - engines: {node: '>=18.20.0 <20 || >=20.12.1'} + nock@15.0.1: + resolution: {integrity: sha512-Mjx5Xl4t9vP13eUZPWqwwpjjXNjvhUTo1qTdryVM3+7t6Z2w6WHZ9GVZk/zQ8Ym1vbmloWaglye3cloyHAJ8FA==} + engines: {node: '>=20.12.1'} node-addon-api@6.1.0: resolution: {integrity: sha512-+eawOlIgy680F0kBzPUNFhMZGtJ1YmqM6l4+Crf4IkImjYrO/mqPwRMh352g23uIaQKFItcQ64I7KMaJxHgAVA==} @@ -7174,10 +7177,6 @@ packages: resolution: {integrity: sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A==} engines: {node: '>= 0.6.0'} - propagate@2.0.1: - resolution: {integrity: sha512-vGrhOavPSTz4QVNuBNdcNXePNdNMaO1xj9yBeH1ScQPjk/rhg9sSlCXPhMkFuaNNW/syTvYqsnbIJxMBfRbbag==} - engines: {node: '>= 8'} - proto3-json-serializer@3.0.4: resolution: {integrity: sha512-E1sbAYg3aEbXrq0n1ojJkRHQJGE1kaE/O6GLA94y8rnJBfgvOPTOd1b9hOceQK1FFZI9qMh1vBERCyO2ifubcw==} engines: {node: '>=18'} @@ -7395,6 +7394,9 @@ packages: resolution: {integrity: sha512-XQBQ3I8W1Cge0Seh+6gjj03LbmRFWuoszgK9ooCpwYIrhhoO80pfq4cUkU5DkknwfOfFteRwlZ56PYOGYyFWdg==} engines: {node: '>= 4'} + rettime@0.11.12: + resolution: {integrity: sha512-5ExtR1ppiDBQkVoPw5NAqdbfH4Iq2VOmQKHMtUoaFxA9bo2krzFYBtyq6K40xxbYp+2w/YOr6D+1ToF6tTN53A==} + reusify@1.1.0: resolution: {integrity: sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==} engines: {iojs: '>=1.0.0', node: '>=0.10.0'} @@ -7876,9 +7878,6 @@ packages: streamx@2.28.1: resolution: {integrity: sha512-zEzXb0s5Cds7tqMH6rhZ05lcJydCWiQPEwiNngVqzsxCc962vLY4Uw+mW7od8kDH258k2Uz/JrOkdIAAhSh9VA==} - strict-event-emitter@0.5.1: - resolution: {integrity: sha512-vMgjE/GGEPEFnhFub6pa4FmJBRBVOLpIII2hvCZ8Kzb7K0hlHo7mQv6xYrBvCL2LtAIBwFUK8wvuJgTVSQ5MFQ==} - string-width@4.2.3: resolution: {integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==} engines: {node: '>=8'} @@ -8305,6 +8304,10 @@ packages: resolution: {integrity: sha512-zj/ob3UsvJGN0whEAKFp53REA5X66hvffVqoCtVQAakJKnKlH+/PcOfMoFwIG/o4rElqLv/ycAFlx8ZlXUorCg==} engines: {node: '>=18.12.0'} + verkit@0.5.0: + resolution: {integrity: sha512-u4J1hr6Y+C/hit34GwL3eIcUf3wngT8TlYUjK7tk0jxydKLAq3sYvifjdTDA6U3KCKRcQCQDGf/srjxfZF3l7g==} + engines: {node: '>=18.12.0'} + verror@1.10.0: resolution: {integrity: sha512-ZZKSmDAEFOijERBLkmYfJ+vmk3w+7hOLYDNkRCuRuMJGEmqYNCNLyBBFwWKVMhfwaEF3WOd0Zlw86U/WC/+nYw==} @@ -8775,30 +8778,28 @@ snapshots: rxjs: 7.8.2 tslib: 2.8.1 - '@angular/ng-dev@https://codeload.github.com/angular/dev-infra-private-ng-dev-builds/tar.gz/89b8c002e5d47ba1cbc4483d3ec06b0ae0aaccb7': + '@angular/ng-dev@https://codeload.github.com/angular/dev-infra-private-ng-dev-builds/tar.gz/fa4308affb4a0dde34ebc95196b58550752485a2': dependencies: '@actions/core': 3.0.1 - '@conventional-changelog/git-client': 3.1.2(conventional-commits-filter@6.0.1)(conventional-commits-parser@7.1.2) + '@conventional-changelog/git-client': 3.2.0(conventional-commits-filter@6.0.1)(conventional-commits-parser@7.1.3) '@google-cloud/spanner': 8.0.0(supports-color@11.0.0) - '@google/genai': 2.25.0(bufferutil@4.1.0)(supports-color@11.0.0)(utf-8-validate@6.0.6) - '@inquirer/prompts': 8.7.2(@types/node@24.19.0) - '@inquirer/type': 4.1.1(@types/node@24.19.0) + '@google/genai': 2.28.0(bufferutil@4.1.0)(supports-color@11.0.0)(utf-8-validate@6.0.6) + '@inquirer/prompts': 8.7.3(@types/node@24.19.1) + '@inquirer/type': 4.2.0(@types/node@24.19.1) '@octokit/auth-app': 8.3.1 '@octokit/core': 7.0.8 '@octokit/graphql': 9.0.5 '@octokit/graphql-schema': 15.26.1 - '@octokit/openapi-types': 28.0.0 - '@octokit/plugin-paginate-rest': 15.0.0(@octokit/core@7.0.8) '@octokit/plugin-rest-endpoint-methods': 18.0.0(@octokit/core@7.0.8) '@octokit/request-error': 7.1.2 '@octokit/rest': 22.0.1 - '@octokit/types': 17.0.0 + '@octokit/types': 18.0.0 '@types/cli-progress': 3.11.6 '@types/ejs': 3.1.5 '@types/events': 3.0.3 '@types/folder-hash': 4.0.4 '@types/jasmine': 6.0.0 - '@types/node': 24.19.0 + '@types/node': 24.19.1 '@types/semver': 7.8.0 '@types/which': 3.0.4 '@types/yargs': 17.0.35 @@ -8807,19 +8808,19 @@ snapshots: bufferutil: 4.1.0 cli-progress: 3.12.0 conventional-commits-filter: 6.0.1 - conventional-commits-parser: 7.1.2 + conventional-commits-parser: 7.1.3 ejs: 7.0.1 encoding: 0.1.13 fast-glob: 3.3.3 - firebase: 12.19.0 - folder-hash: 4.1.3(supports-color@11.0.0) + firebase: 13.0.0 + folder-hash: 4.1.4(supports-color@11.0.0) jasmine: 6.3.0 jasmine-core: 6.3.0 jasmine-reporters: 2.5.2 jsonc-parser: 3.3.1 minimatch: 10.2.6 multimatch: 8.0.0 - nock: 14.0.17 + nock: 15.0.1(supports-color@11.0.0) semver: 7.8.5 supports-color: 11.0.0 tsx: 4.23.15 @@ -9610,14 +9611,14 @@ snapshots: '@colors/colors@1.5.0': {} - '@conventional-changelog/git-client@3.1.2(conventional-commits-filter@6.0.1)(conventional-commits-parser@7.1.2)': + '@conventional-changelog/git-client@3.2.0(conventional-commits-filter@6.0.1)(conventional-commits-parser@7.1.3)': dependencies: '@simple-libs/child-process-utils': 2.0.0 '@simple-libs/stream-utils': 2.0.0 - semver: 7.8.5 + verkit: 0.5.0 optionalDependencies: conventional-commits-filter: 6.0.1 - conventional-commits-parser: 7.1.2 + conventional-commits-parser: 7.1.3 '@csstools/color-helpers@6.1.2': {} @@ -9801,9 +9802,9 @@ snapshots: optionalDependencies: '@noble/hashes': 1.8.0 - '@firebase/ai@2.16.0(@firebase/app-types@0.9.6)(@firebase/app@0.16.2)': + '@firebase/ai@3.0.0(@firebase/app-types@0.9.6)(@firebase/app@0.16.3)': dependencies: - '@firebase/app': 0.16.2 + '@firebase/app': 0.16.3 '@firebase/app-check-interop-types': 0.3.5 '@firebase/app-types': 0.9.6 '@firebase/component': 0.7.5 @@ -9811,33 +9812,33 @@ snapshots: '@firebase/util': 1.15.3 tslib: 2.8.1 - '@firebase/analytics-compat@0.2.31(@firebase/app-compat@0.5.18)(@firebase/app@0.16.2)': + '@firebase/analytics-compat@0.2.31(@firebase/app-compat@0.5.19)(@firebase/app@0.16.3)': dependencies: - '@firebase/analytics': 0.10.25(@firebase/app@0.16.2) + '@firebase/analytics': 0.10.25(@firebase/app@0.16.3) '@firebase/analytics-types': 0.8.5 - '@firebase/app': 0.16.2 - '@firebase/app-compat': 0.5.18 + '@firebase/app': 0.16.3 + '@firebase/app-compat': 0.5.19 '@firebase/component': 0.7.5 '@firebase/util': 1.15.3 tslib: 2.8.1 '@firebase/analytics-types@0.8.5': {} - '@firebase/analytics@0.10.25(@firebase/app@0.16.2)': + '@firebase/analytics@0.10.25(@firebase/app@0.16.3)': dependencies: - '@firebase/app': 0.16.2 + '@firebase/app': 0.16.3 '@firebase/component': 0.7.5 - '@firebase/installations': 0.6.24(@firebase/app@0.16.2) + '@firebase/installations': 0.6.24(@firebase/app@0.16.3) '@firebase/logger': 0.5.2 '@firebase/util': 1.15.3 tslib: 2.8.1 - '@firebase/app-check-compat@0.4.7(@firebase/app-compat@0.5.18)(@firebase/app@0.16.2)': + '@firebase/app-check-compat@0.4.7(@firebase/app-compat@0.5.19)(@firebase/app@0.16.3)': dependencies: - '@firebase/app': 0.16.2 - '@firebase/app-check': 0.13.1(@firebase/app@0.16.2) + '@firebase/app': 0.16.3 + '@firebase/app-check': 0.13.1(@firebase/app@0.16.3) '@firebase/app-check-types': 0.5.5 - '@firebase/app-compat': 0.5.18 + '@firebase/app-compat': 0.5.19 '@firebase/component': 0.7.5 '@firebase/logger': 0.5.2 '@firebase/util': 1.15.3 @@ -9847,17 +9848,17 @@ snapshots: '@firebase/app-check-types@0.5.5': {} - '@firebase/app-check@0.13.1(@firebase/app@0.16.2)': + '@firebase/app-check@0.13.1(@firebase/app@0.16.3)': dependencies: - '@firebase/app': 0.16.2 + '@firebase/app': 0.16.3 '@firebase/component': 0.7.5 '@firebase/logger': 0.5.2 '@firebase/util': 1.15.3 tslib: 2.8.1 - '@firebase/app-compat@0.5.18': + '@firebase/app-compat@0.5.19': dependencies: - '@firebase/app': 0.16.2 + '@firebase/app': 0.16.3 '@firebase/component': 0.7.5 '@firebase/logger': 0.5.2 '@firebase/util': 1.15.3 @@ -9867,7 +9868,7 @@ snapshots: dependencies: '@firebase/logger': 0.5.2 - '@firebase/app@0.16.2': + '@firebase/app@0.16.3': dependencies: '@firebase/component': 0.7.5 '@firebase/logger': 0.5.2 @@ -9875,11 +9876,11 @@ snapshots: idb: 7.1.1 tslib: 2.8.1 - '@firebase/auth-compat@0.6.11(@firebase/app-compat@0.5.18)(@firebase/app-types@0.9.6)(@firebase/app@0.16.2)': + '@firebase/auth-compat@0.6.12(@firebase/app-compat@0.5.19)(@firebase/app-types@0.9.6)(@firebase/app@0.16.3)': dependencies: - '@firebase/app': 0.16.2 - '@firebase/app-compat': 0.5.18 - '@firebase/auth': 1.13.6(@firebase/app@0.16.2) + '@firebase/app': 0.16.3 + '@firebase/app-compat': 0.5.19 + '@firebase/auth': 1.13.7(@firebase/app@0.16.3) '@firebase/auth-types': 0.13.2(@firebase/app-types@0.9.6)(@firebase/util@1.15.3) '@firebase/component': 0.7.5 '@firebase/util': 1.15.3 @@ -9895,9 +9896,9 @@ snapshots: '@firebase/app-types': 0.9.6 '@firebase/util': 1.15.3 - '@firebase/auth@1.13.6(@firebase/app@0.16.2)': + '@firebase/auth@1.13.7(@firebase/app@0.16.3)': dependencies: - '@firebase/app': 0.16.2 + '@firebase/app': 0.16.3 '@firebase/component': 0.7.5 '@firebase/logger': 0.5.2 '@firebase/util': 1.15.3 @@ -9908,16 +9909,16 @@ snapshots: '@firebase/util': 1.15.3 tslib: 2.8.1 - '@firebase/data-connect@0.7.4(@firebase/app@0.16.2)': + '@firebase/data-connect@0.7.4(@firebase/app@0.16.3)': dependencies: - '@firebase/app': 0.16.2 + '@firebase/app': 0.16.3 '@firebase/auth-interop-types': 0.2.6 '@firebase/component': 0.7.5 '@firebase/logger': 0.5.2 '@firebase/util': 1.15.3 tslib: 2.8.1 - '@firebase/database-compat@2.1.7(@firebase/app-compat@0.5.18)(@firebase/app@0.16.2)': + '@firebase/database-compat@2.1.7(@firebase/app-compat@0.5.19)(@firebase/app@0.16.3)': dependencies: '@firebase/component': 0.7.5 '@firebase/database': 1.1.5 @@ -9926,8 +9927,8 @@ snapshots: '@firebase/util': 1.15.3 tslib: 2.8.1 optionalDependencies: - '@firebase/app': 0.16.2 - '@firebase/app-compat': 0.5.18 + '@firebase/app': 0.16.3 + '@firebase/app-compat': 0.5.19 '@firebase/database-types@1.0.22': dependencies: @@ -9944,12 +9945,12 @@ snapshots: faye-websocket: 0.11.4 tslib: 2.8.1 - '@firebase/firestore-compat@0.4.14(@firebase/app-compat@0.5.18)(@firebase/app-types@0.9.6)(@firebase/app@0.16.2)': + '@firebase/firestore-compat@0.4.15(@firebase/app-compat@0.5.19)(@firebase/app-types@0.9.6)(@firebase/app@0.16.3)': dependencies: - '@firebase/app': 0.16.2 - '@firebase/app-compat': 0.5.18 + '@firebase/app': 0.16.3 + '@firebase/app-compat': 0.5.19 '@firebase/component': 0.7.5 - '@firebase/firestore': 4.17.2(@firebase/app@0.16.2) + '@firebase/firestore': 4.18.0(@firebase/app@0.16.3) '@firebase/firestore-types': 3.0.5(@firebase/app-types@0.9.6)(@firebase/util@1.15.3) '@firebase/util': 1.15.3 tslib: 2.8.1 @@ -9961,9 +9962,9 @@ snapshots: '@firebase/app-types': 0.9.6 '@firebase/util': 1.15.3 - '@firebase/firestore@4.17.2(@firebase/app@0.16.2)': + '@firebase/firestore@4.18.0(@firebase/app@0.16.3)': dependencies: - '@firebase/app': 0.16.2 + '@firebase/app': 0.16.3 '@firebase/component': 0.7.5 '@firebase/logger': 0.5.2 '@firebase/util': 1.15.3 @@ -9973,21 +9974,21 @@ snapshots: re2js: 2.8.6 tslib: 2.8.1 - '@firebase/functions-compat@0.5.0(@firebase/app-compat@0.5.18)(@firebase/app@0.16.2)': + '@firebase/functions-compat@0.5.0(@firebase/app-compat@0.5.19)(@firebase/app@0.16.3)': dependencies: - '@firebase/app': 0.16.2 - '@firebase/app-compat': 0.5.18 + '@firebase/app': 0.16.3 + '@firebase/app-compat': 0.5.19 '@firebase/component': 0.7.5 - '@firebase/functions': 0.14.0(@firebase/app@0.16.2) + '@firebase/functions': 0.14.0(@firebase/app@0.16.3) '@firebase/functions-types': 0.6.5 '@firebase/util': 1.15.3 tslib: 2.8.1 '@firebase/functions-types@0.6.5': {} - '@firebase/functions@0.14.0(@firebase/app@0.16.2)': + '@firebase/functions@0.14.0(@firebase/app@0.16.3)': dependencies: - '@firebase/app': 0.16.2 + '@firebase/app': 0.16.3 '@firebase/app-check-interop-types': 0.3.5 '@firebase/auth-interop-types': 0.2.6 '@firebase/component': 0.7.5 @@ -9995,12 +9996,12 @@ snapshots: '@firebase/util': 1.15.3 tslib: 2.8.1 - '@firebase/installations-compat@0.2.24(@firebase/app-compat@0.5.18)(@firebase/app-types@0.9.6)(@firebase/app@0.16.2)': + '@firebase/installations-compat@0.2.24(@firebase/app-compat@0.5.19)(@firebase/app-types@0.9.6)(@firebase/app@0.16.3)': dependencies: - '@firebase/app': 0.16.2 - '@firebase/app-compat': 0.5.18 + '@firebase/app': 0.16.3 + '@firebase/app-compat': 0.5.19 '@firebase/component': 0.7.5 - '@firebase/installations': 0.6.24(@firebase/app@0.16.2) + '@firebase/installations': 0.6.24(@firebase/app@0.16.3) '@firebase/installations-types': 0.5.5(@firebase/app-types@0.9.6) '@firebase/util': 1.15.3 tslib: 2.8.1 @@ -10011,9 +10012,9 @@ snapshots: dependencies: '@firebase/app-types': 0.9.6 - '@firebase/installations@0.6.24(@firebase/app@0.16.2)': + '@firebase/installations@0.6.24(@firebase/app@0.16.3)': dependencies: - '@firebase/app': 0.16.2 + '@firebase/app': 0.16.3 '@firebase/component': 0.7.5 '@firebase/util': 1.15.3 idb: 7.1.1 @@ -10023,78 +10024,78 @@ snapshots: dependencies: tslib: 2.8.1 - '@firebase/messaging-compat@0.2.30(@firebase/app-compat@0.5.18)(@firebase/app@0.16.2)': + '@firebase/messaging-compat@0.2.30(@firebase/app-compat@0.5.19)(@firebase/app@0.16.3)': dependencies: - '@firebase/app': 0.16.2 - '@firebase/app-compat': 0.5.18 + '@firebase/app': 0.16.3 + '@firebase/app-compat': 0.5.19 '@firebase/component': 0.7.5 - '@firebase/messaging': 0.13.3(@firebase/app@0.16.2) + '@firebase/messaging': 0.13.3(@firebase/app@0.16.3) '@firebase/util': 1.15.3 tslib: 2.8.1 '@firebase/messaging-interop-types@0.2.6': {} - '@firebase/messaging@0.13.3(@firebase/app@0.16.2)': + '@firebase/messaging@0.13.3(@firebase/app@0.16.3)': dependencies: - '@firebase/app': 0.16.2 + '@firebase/app': 0.16.3 '@firebase/component': 0.7.5 - '@firebase/installations': 0.6.24(@firebase/app@0.16.2) + '@firebase/installations': 0.6.24(@firebase/app@0.16.3) '@firebase/messaging-interop-types': 0.2.6 '@firebase/util': 1.15.3 idb: 7.1.1 tslib: 2.8.1 - '@firebase/performance-compat@0.2.27(@firebase/app-compat@0.5.18)(@firebase/app@0.16.2)': + '@firebase/performance-compat@0.2.27(@firebase/app-compat@0.5.19)(@firebase/app@0.16.3)': dependencies: - '@firebase/app': 0.16.2 - '@firebase/app-compat': 0.5.18 + '@firebase/app': 0.16.3 + '@firebase/app-compat': 0.5.19 '@firebase/component': 0.7.5 '@firebase/logger': 0.5.2 - '@firebase/performance': 0.7.14(@firebase/app@0.16.2) + '@firebase/performance': 0.7.14(@firebase/app@0.16.3) '@firebase/performance-types': 0.2.5 '@firebase/util': 1.15.3 tslib: 2.8.1 '@firebase/performance-types@0.2.5': {} - '@firebase/performance@0.7.14(@firebase/app@0.16.2)': + '@firebase/performance@0.7.14(@firebase/app@0.16.3)': dependencies: - '@firebase/app': 0.16.2 + '@firebase/app': 0.16.3 '@firebase/component': 0.7.5 - '@firebase/installations': 0.6.24(@firebase/app@0.16.2) + '@firebase/installations': 0.6.24(@firebase/app@0.16.3) '@firebase/logger': 0.5.2 '@firebase/util': 1.15.3 tslib: 2.8.1 web-vitals: 4.2.4 - '@firebase/remote-config-compat@0.2.29(@firebase/app-compat@0.5.18)(@firebase/app@0.16.2)': + '@firebase/remote-config-compat@0.2.30(@firebase/app-compat@0.5.19)(@firebase/app@0.16.3)': dependencies: - '@firebase/app': 0.16.2 - '@firebase/app-compat': 0.5.18 + '@firebase/app': 0.16.3 + '@firebase/app-compat': 0.5.19 '@firebase/component': 0.7.5 '@firebase/logger': 0.5.2 - '@firebase/remote-config': 0.9.2(@firebase/app@0.16.2) + '@firebase/remote-config': 0.9.3(@firebase/app@0.16.3) '@firebase/remote-config-types': 0.5.2 '@firebase/util': 1.15.3 tslib: 2.8.1 '@firebase/remote-config-types@0.5.2': {} - '@firebase/remote-config@0.9.2(@firebase/app@0.16.2)': + '@firebase/remote-config@0.9.3(@firebase/app@0.16.3)': dependencies: - '@firebase/app': 0.16.2 + '@firebase/app': 0.16.3 '@firebase/component': 0.7.5 - '@firebase/installations': 0.6.24(@firebase/app@0.16.2) + '@firebase/installations': 0.6.24(@firebase/app@0.16.3) '@firebase/logger': 0.5.2 '@firebase/util': 1.15.3 tslib: 2.8.1 - '@firebase/storage-compat@0.4.5(@firebase/app-compat@0.5.18)(@firebase/app-types@0.9.6)(@firebase/app@0.16.2)': + '@firebase/storage-compat@0.4.6(@firebase/app-compat@0.5.19)(@firebase/app-types@0.9.6)(@firebase/app@0.16.3)': dependencies: - '@firebase/app': 0.16.2 - '@firebase/app-compat': 0.5.18 + '@firebase/app': 0.16.3 + '@firebase/app-compat': 0.5.19 '@firebase/component': 0.7.5 - '@firebase/storage': 0.14.5(@firebase/app@0.16.2) + '@firebase/storage': 0.14.6(@firebase/app@0.16.3) '@firebase/storage-types': 0.8.5(@firebase/app-types@0.9.6)(@firebase/util@1.15.3) '@firebase/util': 1.15.3 tslib: 2.8.1 @@ -10106,9 +10107,9 @@ snapshots: '@firebase/app-types': 0.9.6 '@firebase/util': 1.15.3 - '@firebase/storage@0.14.5(@firebase/app@0.16.2)': + '@firebase/storage@0.14.6(@firebase/app@0.16.3)': dependencies: - '@firebase/app': 0.16.2 + '@firebase/app': 0.16.3 '@firebase/component': 0.7.5 '@firebase/util': 1.15.3 tslib: 2.8.1 @@ -10180,7 +10181,7 @@ snapshots: transitivePeerDependencies: - supports-color - '@google/genai@2.25.0(bufferutil@4.1.0)(supports-color@11.0.0)(utf-8-validate@6.0.6)': + '@google/genai@2.28.0(bufferutil@4.1.0)(supports-color@11.0.0)(utf-8-validate@6.0.6)': dependencies: google-auth-library: 10.9.1(supports-color@11.0.0) p-retry: 4.6.2 @@ -10245,14 +10246,14 @@ snapshots: optionalDependencies: '@types/node': 22.20.5 - '@inquirer/checkbox@5.2.6(@types/node@24.19.0)': + '@inquirer/checkbox@5.2.6(@types/node@24.19.1)': dependencies: '@inquirer/ansi': 2.0.9 - '@inquirer/core': 12.0.4(@types/node@24.19.0) + '@inquirer/core': 12.0.4(@types/node@24.19.1) '@inquirer/figures': 2.0.9 - '@inquirer/type': 4.2.0(@types/node@24.19.0) + '@inquirer/type': 4.2.0(@types/node@24.19.1) optionalDependencies: - '@types/node': 24.19.0 + '@types/node': 24.19.1 '@inquirer/confirm@6.3.2(@types/node@22.20.5)': dependencies: @@ -10261,12 +10262,12 @@ snapshots: optionalDependencies: '@types/node': 22.20.5 - '@inquirer/confirm@6.3.2(@types/node@24.19.0)': + '@inquirer/confirm@6.3.3(@types/node@24.19.1)': dependencies: - '@inquirer/core': 12.0.4(@types/node@24.19.0) - '@inquirer/type': 4.1.1(@types/node@24.19.0) + '@inquirer/core': 12.0.4(@types/node@24.19.1) + '@inquirer/type': 4.2.0(@types/node@24.19.1) optionalDependencies: - '@types/node': 24.19.0 + '@types/node': 24.19.1 '@inquirer/core@12.0.4(@types/node@22.20.5)': dependencies: @@ -10280,17 +10281,17 @@ snapshots: optionalDependencies: '@types/node': 22.20.5 - '@inquirer/core@12.0.4(@types/node@24.19.0)': + '@inquirer/core@12.0.4(@types/node@24.19.1)': dependencies: '@inquirer/ansi': 2.0.9 '@inquirer/figures': 2.0.9 - '@inquirer/type': 4.2.0(@types/node@24.19.0) + '@inquirer/type': 4.2.0(@types/node@24.19.1) cli-width: 4.1.0 fast-wrap-ansi: 0.2.2 mute-stream: 3.0.0 signal-exit: 4.1.0 optionalDependencies: - '@types/node': 24.19.0 + '@types/node': 24.19.1 '@inquirer/editor@5.3.4(@types/node@22.20.5)': dependencies: @@ -10300,13 +10301,13 @@ snapshots: optionalDependencies: '@types/node': 22.20.5 - '@inquirer/editor@5.3.4(@types/node@24.19.0)': + '@inquirer/editor@5.3.4(@types/node@24.19.1)': dependencies: - '@inquirer/core': 12.0.4(@types/node@24.19.0) - '@inquirer/external-editor': 3.0.6(@types/node@24.19.0) - '@inquirer/type': 4.2.0(@types/node@24.19.0) + '@inquirer/core': 12.0.4(@types/node@24.19.1) + '@inquirer/external-editor': 3.0.6(@types/node@24.19.1) + '@inquirer/type': 4.2.0(@types/node@24.19.1) optionalDependencies: - '@types/node': 24.19.0 + '@types/node': 24.19.1 '@inquirer/expand@5.1.6(@types/node@22.20.5)': dependencies: @@ -10315,12 +10316,12 @@ snapshots: optionalDependencies: '@types/node': 22.20.5 - '@inquirer/expand@5.1.6(@types/node@24.19.0)': + '@inquirer/expand@5.1.6(@types/node@24.19.1)': dependencies: - '@inquirer/core': 12.0.4(@types/node@24.19.0) - '@inquirer/type': 4.2.0(@types/node@24.19.0) + '@inquirer/core': 12.0.4(@types/node@24.19.1) + '@inquirer/type': 4.2.0(@types/node@24.19.1) optionalDependencies: - '@types/node': 24.19.0 + '@types/node': 24.19.1 '@inquirer/external-editor@3.0.6(@types/node@22.20.5)': dependencies: @@ -10329,12 +10330,12 @@ snapshots: optionalDependencies: '@types/node': 22.20.5 - '@inquirer/external-editor@3.0.6(@types/node@24.19.0)': + '@inquirer/external-editor@3.0.6(@types/node@24.19.1)': dependencies: chardet: 2.2.0 iconv-lite: 0.7.3 optionalDependencies: - '@types/node': 24.19.0 + '@types/node': 24.19.1 '@inquirer/figures@2.0.9': {} @@ -10345,12 +10346,12 @@ snapshots: optionalDependencies: '@types/node': 22.20.5 - '@inquirer/input@5.1.7(@types/node@24.19.0)': + '@inquirer/input@5.1.7(@types/node@24.19.1)': dependencies: - '@inquirer/core': 12.0.4(@types/node@24.19.0) - '@inquirer/type': 4.2.0(@types/node@24.19.0) + '@inquirer/core': 12.0.4(@types/node@24.19.1) + '@inquirer/type': 4.2.0(@types/node@24.19.1) optionalDependencies: - '@types/node': 24.19.0 + '@types/node': 24.19.1 '@inquirer/number@4.2.4(@types/node@22.20.5)': dependencies: @@ -10359,12 +10360,12 @@ snapshots: optionalDependencies: '@types/node': 22.20.5 - '@inquirer/number@4.2.4(@types/node@24.19.0)': + '@inquirer/number@4.2.4(@types/node@24.19.1)': dependencies: - '@inquirer/core': 12.0.4(@types/node@24.19.0) - '@inquirer/type': 4.2.0(@types/node@24.19.0) + '@inquirer/core': 12.0.4(@types/node@24.19.1) + '@inquirer/type': 4.2.0(@types/node@24.19.1) optionalDependencies: - '@types/node': 24.19.0 + '@types/node': 24.19.1 '@inquirer/password@5.2.3(@types/node@22.20.5)': dependencies: @@ -10374,13 +10375,13 @@ snapshots: optionalDependencies: '@types/node': 22.20.5 - '@inquirer/password@5.2.3(@types/node@24.19.0)': + '@inquirer/password@5.2.3(@types/node@24.19.1)': dependencies: '@inquirer/ansi': 2.0.9 - '@inquirer/core': 12.0.4(@types/node@24.19.0) - '@inquirer/type': 4.2.0(@types/node@24.19.0) + '@inquirer/core': 12.0.4(@types/node@24.19.1) + '@inquirer/type': 4.2.0(@types/node@24.19.1) optionalDependencies: - '@types/node': 24.19.0 + '@types/node': 24.19.1 '@inquirer/prompts@8.7.2(@types/node@22.20.5)': dependencies: @@ -10397,20 +10398,20 @@ snapshots: optionalDependencies: '@types/node': 22.20.5 - '@inquirer/prompts@8.7.2(@types/node@24.19.0)': - dependencies: - '@inquirer/checkbox': 5.2.6(@types/node@24.19.0) - '@inquirer/confirm': 6.3.2(@types/node@24.19.0) - '@inquirer/editor': 5.3.4(@types/node@24.19.0) - '@inquirer/expand': 5.1.6(@types/node@24.19.0) - '@inquirer/input': 5.1.7(@types/node@24.19.0) - '@inquirer/number': 4.2.4(@types/node@24.19.0) - '@inquirer/password': 5.2.3(@types/node@24.19.0) - '@inquirer/rawlist': 5.3.6(@types/node@24.19.0) - '@inquirer/search': 4.3.4(@types/node@24.19.0) - '@inquirer/select': 5.2.6(@types/node@24.19.0) + '@inquirer/prompts@8.7.3(@types/node@24.19.1)': + dependencies: + '@inquirer/checkbox': 5.2.6(@types/node@24.19.1) + '@inquirer/confirm': 6.3.3(@types/node@24.19.1) + '@inquirer/editor': 5.3.4(@types/node@24.19.1) + '@inquirer/expand': 5.1.6(@types/node@24.19.1) + '@inquirer/input': 5.1.7(@types/node@24.19.1) + '@inquirer/number': 4.2.4(@types/node@24.19.1) + '@inquirer/password': 5.2.3(@types/node@24.19.1) + '@inquirer/rawlist': 5.3.6(@types/node@24.19.1) + '@inquirer/search': 4.3.4(@types/node@24.19.1) + '@inquirer/select': 5.2.6(@types/node@24.19.1) optionalDependencies: - '@types/node': 24.19.0 + '@types/node': 24.19.1 '@inquirer/rawlist@5.3.6(@types/node@22.20.5)': dependencies: @@ -10419,12 +10420,12 @@ snapshots: optionalDependencies: '@types/node': 22.20.5 - '@inquirer/rawlist@5.3.6(@types/node@24.19.0)': + '@inquirer/rawlist@5.3.6(@types/node@24.19.1)': dependencies: - '@inquirer/core': 12.0.4(@types/node@24.19.0) - '@inquirer/type': 4.2.0(@types/node@24.19.0) + '@inquirer/core': 12.0.4(@types/node@24.19.1) + '@inquirer/type': 4.2.0(@types/node@24.19.1) optionalDependencies: - '@types/node': 24.19.0 + '@types/node': 24.19.1 '@inquirer/search@4.3.4(@types/node@22.20.5)': dependencies: @@ -10434,13 +10435,13 @@ snapshots: optionalDependencies: '@types/node': 22.20.5 - '@inquirer/search@4.3.4(@types/node@24.19.0)': + '@inquirer/search@4.3.4(@types/node@24.19.1)': dependencies: - '@inquirer/core': 12.0.4(@types/node@24.19.0) + '@inquirer/core': 12.0.4(@types/node@24.19.1) '@inquirer/figures': 2.0.9 - '@inquirer/type': 4.2.0(@types/node@24.19.0) + '@inquirer/type': 4.2.0(@types/node@24.19.1) optionalDependencies: - '@types/node': 24.19.0 + '@types/node': 24.19.1 '@inquirer/select@5.2.6(@types/node@22.20.5)': dependencies: @@ -10451,30 +10452,26 @@ snapshots: optionalDependencies: '@types/node': 22.20.5 - '@inquirer/select@5.2.6(@types/node@24.19.0)': + '@inquirer/select@5.2.6(@types/node@24.19.1)': dependencies: '@inquirer/ansi': 2.0.9 - '@inquirer/core': 12.0.4(@types/node@24.19.0) + '@inquirer/core': 12.0.4(@types/node@24.19.1) '@inquirer/figures': 2.0.9 - '@inquirer/type': 4.2.0(@types/node@24.19.0) + '@inquirer/type': 4.2.0(@types/node@24.19.1) optionalDependencies: - '@types/node': 24.19.0 + '@types/node': 24.19.1 '@inquirer/type@4.1.1(@types/node@22.20.5)': optionalDependencies: '@types/node': 22.20.5 - '@inquirer/type@4.1.1(@types/node@24.19.0)': - optionalDependencies: - '@types/node': 24.19.0 - '@inquirer/type@4.2.0(@types/node@22.20.5)': optionalDependencies: '@types/node': 22.20.5 - '@inquirer/type@4.2.0(@types/node@24.19.0)': + '@inquirer/type@4.2.0(@types/node@24.19.1)': optionalDependencies: - '@types/node': 24.19.0 + '@types/node': 24.19.1 '@isaacs/cliui@8.0.2': dependencies: @@ -10714,14 +10711,16 @@ snapshots: '@msgpackr-extract/msgpackr-extract-win32-x64@3.0.4': optional: true - '@mswjs/interceptors@0.41.9': + '@mswjs/interceptors@0.44.0(supports-color@11.0.0)': dependencies: - '@open-draft/deferred-promise': 2.2.0 - '@open-draft/logger': 0.3.0 - '@open-draft/until': 2.1.0 + '@open-draft/until': 3.0.1 + '@types/debug': 4.1.13 + debug: 4.4.3(supports-color@11.0.0) is-node-process: 1.2.0 outvariant: 1.4.3 - strict-event-emitter: 0.5.1 + rettime: 0.11.12 + transitivePeerDependencies: + - supports-color '@napi-rs/lzma-linux-x64-gnu@1.5.1': optional: true @@ -10894,11 +10893,6 @@ snapshots: '@octokit/core': 7.0.8 '@octokit/types': 16.0.0 - '@octokit/plugin-paginate-rest@15.0.0(@octokit/core@7.0.8)': - dependencies: - '@octokit/core': 7.0.8 - '@octokit/types': 17.0.0 - '@octokit/plugin-request-log@6.0.0(@octokit/core@7.0.8)': dependencies: '@octokit/core': 7.0.8 @@ -10945,14 +10939,7 @@ snapshots: dependencies: '@octokit/openapi-types': 29.0.1 - '@open-draft/deferred-promise@2.2.0': {} - - '@open-draft/logger@0.3.0': - dependencies: - is-node-process: 1.2.0 - outvariant: 1.4.3 - - '@open-draft/until@2.1.0': {} + '@open-draft/until@3.0.1': {} '@opentelemetry/api@1.9.1': {} @@ -11464,6 +11451,10 @@ snapshots: dependencies: '@types/node': 22.20.5 + '@types/debug@4.1.13': + dependencies: + '@types/ms': 2.1.0 + '@types/deep-eql@4.0.2': {} '@types/duplexify@3.6.5': @@ -11553,11 +11544,13 @@ snapshots: dependencies: '@types/parse-glob': 3.0.32 + '@types/ms@2.1.0': {} + '@types/node@22.20.5': dependencies: undici-types: 6.21.0 - '@types/node@24.19.0': + '@types/node@24.19.1': dependencies: undici-types: 7.24.6 @@ -12743,7 +12736,7 @@ snapshots: conventional-commits-filter@6.0.1: {} - conventional-commits-parser@7.1.2: + conventional-commits-parser@7.1.3: dependencies: '@simple-libs/stream-utils': 2.0.0 argue-cli: 3.2.0 @@ -12878,12 +12871,6 @@ snapshots: optionalDependencies: supports-color: 11.0.0 - debug@4.4.0(supports-color@11.0.0): - dependencies: - ms: 2.1.3 - optionalDependencies: - supports-color: 11.0.0 - debug@4.4.3(supports-color@11.0.0): dependencies: ms: 2.1.3 @@ -13571,35 +13558,35 @@ snapshots: locate-path: 6.0.0 path-exists: 4.0.0 - firebase@12.19.0: + firebase@13.0.0: dependencies: - '@firebase/ai': 2.16.0(@firebase/app-types@0.9.6)(@firebase/app@0.16.2) - '@firebase/analytics': 0.10.25(@firebase/app@0.16.2) - '@firebase/analytics-compat': 0.2.31(@firebase/app-compat@0.5.18)(@firebase/app@0.16.2) - '@firebase/app': 0.16.2 - '@firebase/app-check': 0.13.1(@firebase/app@0.16.2) - '@firebase/app-check-compat': 0.4.7(@firebase/app-compat@0.5.18)(@firebase/app@0.16.2) - '@firebase/app-compat': 0.5.18 + '@firebase/ai': 3.0.0(@firebase/app-types@0.9.6)(@firebase/app@0.16.3) + '@firebase/analytics': 0.10.25(@firebase/app@0.16.3) + '@firebase/analytics-compat': 0.2.31(@firebase/app-compat@0.5.19)(@firebase/app@0.16.3) + '@firebase/app': 0.16.3 + '@firebase/app-check': 0.13.1(@firebase/app@0.16.3) + '@firebase/app-check-compat': 0.4.7(@firebase/app-compat@0.5.19)(@firebase/app@0.16.3) + '@firebase/app-compat': 0.5.19 '@firebase/app-types': 0.9.6 - '@firebase/auth': 1.13.6(@firebase/app@0.16.2) - '@firebase/auth-compat': 0.6.11(@firebase/app-compat@0.5.18)(@firebase/app-types@0.9.6)(@firebase/app@0.16.2) - '@firebase/data-connect': 0.7.4(@firebase/app@0.16.2) + '@firebase/auth': 1.13.7(@firebase/app@0.16.3) + '@firebase/auth-compat': 0.6.12(@firebase/app-compat@0.5.19)(@firebase/app-types@0.9.6)(@firebase/app@0.16.3) + '@firebase/data-connect': 0.7.4(@firebase/app@0.16.3) '@firebase/database': 1.1.5 - '@firebase/database-compat': 2.1.7(@firebase/app-compat@0.5.18)(@firebase/app@0.16.2) - '@firebase/firestore': 4.17.2(@firebase/app@0.16.2) - '@firebase/firestore-compat': 0.4.14(@firebase/app-compat@0.5.18)(@firebase/app-types@0.9.6)(@firebase/app@0.16.2) - '@firebase/functions': 0.14.0(@firebase/app@0.16.2) - '@firebase/functions-compat': 0.5.0(@firebase/app-compat@0.5.18)(@firebase/app@0.16.2) - '@firebase/installations': 0.6.24(@firebase/app@0.16.2) - '@firebase/installations-compat': 0.2.24(@firebase/app-compat@0.5.18)(@firebase/app-types@0.9.6)(@firebase/app@0.16.2) - '@firebase/messaging': 0.13.3(@firebase/app@0.16.2) - '@firebase/messaging-compat': 0.2.30(@firebase/app-compat@0.5.18)(@firebase/app@0.16.2) - '@firebase/performance': 0.7.14(@firebase/app@0.16.2) - '@firebase/performance-compat': 0.2.27(@firebase/app-compat@0.5.18)(@firebase/app@0.16.2) - '@firebase/remote-config': 0.9.2(@firebase/app@0.16.2) - '@firebase/remote-config-compat': 0.2.29(@firebase/app-compat@0.5.18)(@firebase/app@0.16.2) - '@firebase/storage': 0.14.5(@firebase/app@0.16.2) - '@firebase/storage-compat': 0.4.5(@firebase/app-compat@0.5.18)(@firebase/app-types@0.9.6)(@firebase/app@0.16.2) + '@firebase/database-compat': 2.1.7(@firebase/app-compat@0.5.19)(@firebase/app@0.16.3) + '@firebase/firestore': 4.18.0(@firebase/app@0.16.3) + '@firebase/firestore-compat': 0.4.15(@firebase/app-compat@0.5.19)(@firebase/app-types@0.9.6)(@firebase/app@0.16.3) + '@firebase/functions': 0.14.0(@firebase/app@0.16.3) + '@firebase/functions-compat': 0.5.0(@firebase/app-compat@0.5.19)(@firebase/app@0.16.3) + '@firebase/installations': 0.6.24(@firebase/app@0.16.3) + '@firebase/installations-compat': 0.2.24(@firebase/app-compat@0.5.19)(@firebase/app-types@0.9.6)(@firebase/app@0.16.3) + '@firebase/messaging': 0.13.3(@firebase/app@0.16.3) + '@firebase/messaging-compat': 0.2.30(@firebase/app-compat@0.5.19)(@firebase/app@0.16.3) + '@firebase/performance': 0.7.14(@firebase/app@0.16.3) + '@firebase/performance-compat': 0.2.27(@firebase/app-compat@0.5.19)(@firebase/app@0.16.3) + '@firebase/remote-config': 0.9.3(@firebase/app@0.16.3) + '@firebase/remote-config-compat': 0.2.30(@firebase/app-compat@0.5.19)(@firebase/app@0.16.3) + '@firebase/storage': 0.14.6(@firebase/app@0.16.3) + '@firebase/storage-compat': 0.4.6(@firebase/app-compat@0.5.19)(@firebase/app-types@0.9.6)(@firebase/app@0.16.3) '@firebase/util': 1.15.3 transitivePeerDependencies: - '@react-native-async-storage/async-storage' @@ -13616,9 +13603,9 @@ snapshots: flru@1.0.2: {} - folder-hash@4.1.3(supports-color@11.0.0): + folder-hash@4.1.4(supports-color@11.0.0): dependencies: - debug: 4.4.0(supports-color@11.0.0) + debug: 4.4.3(supports-color@11.0.0) minimatch: 7.4.9 transitivePeerDependencies: - supports-color @@ -15006,11 +14993,11 @@ snapshots: - supports-color - vue-tsc - nock@14.0.17: + nock@15.0.1(supports-color@11.0.0): dependencies: - '@mswjs/interceptors': 0.41.9 - json-stringify-safe: 5.0.1 - propagate: 2.0.1 + '@mswjs/interceptors': 0.44.0(supports-color@11.0.0) + transitivePeerDependencies: + - supports-color node-addon-api@6.1.0: optional: true @@ -15427,8 +15414,6 @@ snapshots: process@0.11.10: {} - propagate@2.0.1: {} - proto3-json-serializer@3.0.4: dependencies: protobufjs: 7.6.6 @@ -15710,6 +15695,8 @@ snapshots: retry@0.13.1: {} + rettime@0.11.12: {} + reusify@1.1.0: {} rfdc@1.4.1: {} @@ -16275,8 +16262,6 @@ snapshots: - bare-abort-controller - react-native-b4a - strict-event-emitter@0.5.1: {} - string-width@4.2.3: dependencies: emoji-regex: 8.0.0 @@ -16753,6 +16738,8 @@ snapshots: verkit@0.3.2: {} + verkit@0.5.0: {} + verror@1.10.0: dependencies: assert-plus: 1.0.0 From 82439399cbfb4c1d21d1c80d976021efa9e4a39a Mon Sep 17 00:00:00 2001 From: Alan Agius Date: Mon, 12 Oct 2026 22:45:00 +0200 Subject: [PATCH 087/233] fix(@angular/build): ensure Sass importers return global Promise instances `sass-embedded` checks whether an importer's `canonicalize` or `findFileUrl` method returned a promise using `result instanceof Promise`. When SSR executes in the same process during `ng serve` for an application using Zone.js, `zone.js/node` replaces `globalThis.Promise` with `ZoneAwarePromise`. Because native V8 `async` functions always return instances of the intrinsic V8 `%Promise%` rather than `globalThis.Promise`, `result instanceof Promise` evaluates to `false` and `sass-embedded` treats the returned Promise as a synchronous URL value (`"[object Promise]"` / `"%5Bobject%20Promise%5D"`). (cherry picked from commit 47c328d3ef7b409af02f270a48f5e99a520fbe14) --- .../esbuild/stylesheets/sass-language_spec.ts | 64 +++++++++++++++++++ .../build/src/tools/sass/rebasing-importer.ts | 12 ++-- 2 files changed, 72 insertions(+), 4 deletions(-) diff --git a/packages/angular/build/src/tools/esbuild/stylesheets/sass-language_spec.ts b/packages/angular/build/src/tools/esbuild/stylesheets/sass-language_spec.ts index cdd4d7e7c8db..216a2d18fc47 100644 --- a/packages/angular/build/src/tools/esbuild/stylesheets/sass-language_spec.ts +++ b/packages/angular/build/src/tools/esbuild/stylesheets/sass-language_spec.ts @@ -286,5 +286,69 @@ describe('sass-language', () => { pathToFileURL(join(projectRoot, 'node_modules', 'theme', '_index.scss')).href, ); }); + + it('should resolve imports when globalThis.Promise is replaced (e.g., by Zone.js)', async () => { + const originalPromise = globalThis.Promise; + + // Simulate Zone.js replacing globalThis.Promise with a constructor where + // native V8 async function return values fail `instanceof globalThis.Promise`. + class ZoneLikePromise { + #inner: Promise; + + constructor( + executor: ( + resolve: (value: T | PromiseLike) => void, + reject: (reason?: unknown) => void, + ) => void, + ) { + this.#inner = new originalPromise(executor); + } + + then( + onfulfilled?: ((value: T) => TResult1 | PromiseLike) | null, + onrejected?: ((reason: unknown) => TResult2 | PromiseLike) | null, + ): ZoneLikePromise { + return new ZoneLikePromise((resolve, reject) => { + this.#inner.then(onfulfilled, onrejected).then(resolve, reject); + }); + } + + catch( + onrejected?: ((reason: unknown) => TResult | PromiseLike) | null, + ): ZoneLikePromise { + return this.then(undefined, onrejected); + } + + finally(onfinally?: (() => void) | null): ZoneLikePromise { + return new ZoneLikePromise((resolve, reject) => { + this.#inner.finally(onfinally).then(resolve, reject); + }); + } + + static resolve(value?: U | PromiseLike): ZoneLikePromise> { + if (value instanceof ZoneLikePromise) { + return value; + } + + return new ZoneLikePromise((resolve) => resolve(value as Awaited)); + } + + static reject(reason?: unknown): ZoneLikePromise { + return new ZoneLikePromise((_, reject) => reject(reason)); + } + + static all(values: Iterable): ZoneLikePromise { + return ZoneLikePromise.resolve(originalPromise.all(values)); + } + } + + globalThis.Promise = ZoneLikePromise as unknown as PromiseConstructor; + try { + const application = await compile(buttonStylesheet); + expect(application).toContain('content: "project";'); + } finally { + globalThis.Promise = originalPromise; + } + }); }); }); diff --git a/packages/angular/build/src/tools/sass/rebasing-importer.ts b/packages/angular/build/src/tools/sass/rebasing-importer.ts index 7198d8b74f1e..889d26ef567e 100644 --- a/packages/angular/build/src/tools/sass/rebasing-importer.ts +++ b/packages/angular/build/src/tools/sass/rebasing-importer.ts @@ -344,14 +344,18 @@ export class AsyncModuleUrlRebasingImporter implements Importer<'async'> { this.load = this.load.bind(this); } - async canonicalize(url: string, options: CanonicalizeContext): Promise { + canonicalize(url: string, options: CanonicalizeContext): Promise | URL | null { if (url.startsWith('file://')) { return this.relativeImporter.canonicalize(url, options); } - const result = await this.finder(url, options); - - return result ? this.relativeImporter.canonicalize(result.href, options) : null; + // Use `Promise.resolve` instead of an `async` method so the returned promise is an + // instance of the current `globalThis.Promise` (e.g., `ZoneAwarePromise` when Zone.js + // is loaded during SSR). `sass-embedded` checks `result instanceof Promise`, which fails + // for native `async` function return values when `globalThis.Promise` has been replaced. + return Promise.resolve(this.finder(url, options)).then((result) => + result ? this.relativeImporter.canonicalize(result.href, options) : null, + ); } load(canonicalUrl: URL): ImporterResult | null { From 2b97e8250c7d0540416b1b8e87619a87c4f8cca5 Mon Sep 17 00:00:00 2001 From: Charles Lyding <19598772+clydin@users.noreply.github.com> Date: Mon, 12 Oct 2026 09:14:07 -0400 Subject: [PATCH 088/233] test(@angular/build): verify Vitest fsModuleCache is disabled across test runs Add an integration test to ensure that modifying an imported application module between test runs is reflected even when `fsModuleCache` is explicitly enabled in the Vitest runner configuration, and that the `.vitest-cache` directory is not created. (cherry picked from commit 5e0fd4f134967ac879d6f7d34a4b06f69534d0c0) --- .../behavior/runner-config-vitest_spec.ts | 38 +++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/packages/angular/build/src/builders/unit-test/tests/behavior/runner-config-vitest_spec.ts b/packages/angular/build/src/builders/unit-test/tests/behavior/runner-config-vitest_spec.ts index 95107d1baec2..53039adf53e8 100644 --- a/packages/angular/build/src/builders/unit-test/tests/behavior/runner-config-vitest_spec.ts +++ b/packages/angular/build/src/builders/unit-test/tests/behavior/runner-config-vitest_spec.ts @@ -614,5 +614,43 @@ describeBuilder(execute, UNIT_TEST_BUILDER_INFO, (harness) => { const { result } = await harness.executeOnce(); expect(result?.success).toBeTrue(); }); + + it('should not serve stale cached modules across runs when an imported file changes', async () => { + harness.useTarget('test', { + ...BASE_OPTIONS, + runnerConfig: 'vitest.config.mts', + }); + + await harness.writeFiles({ + 'vitest.config.mts': ` + import { defineConfig } from 'vitest/config'; + export default defineConfig({ + test: { + fsModuleCache: true, + fsModuleCachePath: './.vitest-cache', + }, + }); + `, + 'src/app/value.ts': `export const VALUE = 'initial';`, + 'src/app/app.component.spec.ts': ` + import { test, expect } from 'vitest'; + import { VALUE } from './value'; + + test('should use the latest value from imported module', () => { + expect(VALUE).toBe('updated'); + }); + `, + }); + + const firstRun = await harness.executeOnce(); + expect(firstRun.result?.success).toBeFalse(); + + // Update the imported application file without modifying the .spec.ts file on disk + await harness.writeFile('src/app/value.ts', `export const VALUE = 'updated';`); + + const secondRun = await harness.executeOnce(); + expect(secondRun.result?.success).toBeTrue(); + harness.expectDirectory('.vitest-cache').toNotExist(); + }); }); }); From 7a905e84b82da4729a1ad7103b773c73760ac671 Mon Sep 17 00:00:00 2001 From: Charles Lyding <19598772+clydin@users.noreply.github.com> Date: Mon, 12 Oct 2026 09:25:13 -0400 Subject: [PATCH 089/233] test(@angular/build): await file writes in unit-test watch rebuild spec Ensure `harness.writeFiles` calls inside `executeWithCases` callbacks are awaited so file modifications complete before the next watch cycle. (cherry picked from commit 0306faf9e4f9b1c746672711fe107e2e2f0bd406) --- .../unit-test/tests/behavior/watch_rebuild_spec.ts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/packages/angular/build/src/builders/unit-test/tests/behavior/watch_rebuild_spec.ts b/packages/angular/build/src/builders/unit-test/tests/behavior/watch_rebuild_spec.ts index 6ff753c7eac7..cab5afd48a2c 100644 --- a/packages/angular/build/src/builders/unit-test/tests/behavior/watch_rebuild_spec.ts +++ b/packages/angular/build/src/builders/unit-test/tests/behavior/watch_rebuild_spec.ts @@ -28,11 +28,11 @@ describeBuilder(execute, UNIT_TEST_BUILDER_INFO, (harness) => { await harness.executeWithCases([ // 1. Initial success - ({ result }) => { + async ({ result }) => { expect(result?.success).toBeTrue(); // 2. Introduce compilation error - harness.writeFiles({ + await harness.writeFiles({ 'src/app/app.component.spec.ts': ` import { describe, expect, test } from 'vitest' describe('AppComponent', () => { @@ -44,11 +44,11 @@ describeBuilder(execute, UNIT_TEST_BUILDER_INFO, (harness) => { }); }, // 3. Expect compilation error - ({ result }) => { + async ({ result }) => { expect(result?.success).toBeFalse(); // 4. Fix compilation error BUT introduce test failure - harness.writeFiles({ + await harness.writeFiles({ 'src/app/app.component.spec.ts': ` import { describe, expect, test } from 'vitest' describe('AppComponent', () => { From a818de415e933819e7a2e3e679cd0b2d2be734de Mon Sep 17 00:00:00 2001 From: Charles Lyding <19598772+clydin@users.noreply.github.com> Date: Mon, 12 Oct 2026 09:37:15 -0400 Subject: [PATCH 090/233] fix(@angular/build): keep Vite server file watcher disabled in Vitest watch mode In Vitest 5, the internal `vitest:config:append` plugin uses a post `configResolved` hook that resets `server.watch` to `{}` when watch mode is enabled (`server.watch ??= {}`), overriding the `server: { watch: null }` setting passed in `vitestServerConfig`. This caused Vite to start a duplicate Chokidar file watcher alongside the Angular CLI build watcher and trigger redundant, racing test reruns on file changes. Enforce `post` ordering on `angular:vitest-configuration` and reset `config.server.watch = null` in a post `configResolved` hook so Vite uses its no-op watcher. (cherry picked from commit 39d230e1862f2f626d3fba03bbf51873f3578153) --- .../unit-test/runners/vitest/executor.ts | 5 --- .../unit-test/runners/vitest/plugins.ts | 10 ++++++ .../unit-test/tests/options/watch_spec.ts | 33 +++++++++++++++++++ 3 files changed, 43 insertions(+), 5 deletions(-) diff --git a/packages/angular/build/src/builders/unit-test/runners/vitest/executor.ts b/packages/angular/build/src/builders/unit-test/runners/vitest/executor.ts index aa201e24c578..b5c7841c799b 100644 --- a/packages/angular/build/src/builders/unit-test/runners/vitest/executor.ts +++ b/packages/angular/build/src/builders/unit-test/runners/vitest/executor.ts @@ -398,11 +398,6 @@ export class VitestExecutor implements TestExecutor { const vitestServerConfig = { // Note `.vitest` is auto appended to the path. cacheDir: cacheOptions.path, - server: { - // Disable the actual file watcher. The boolean watch option above should still - // be enabled as it controls other internal behavior related to rerunning tests. - watch: null, - }, plugins: [ await createVitestConfigPlugin({ browser: browserOptions.browser, diff --git a/packages/angular/build/src/builders/unit-test/runners/vitest/plugins.ts b/packages/angular/build/src/builders/unit-test/runners/vitest/plugins.ts index ec0cd0a8f269..0a8a2c8990b4 100644 --- a/packages/angular/build/src/builders/unit-test/runners/vitest/plugins.ts +++ b/packages/angular/build/src/builders/unit-test/runners/vitest/plugins.ts @@ -164,6 +164,16 @@ export async function createVitestConfigPlugin( return { name: 'angular:vitest-configuration', + enforce: 'post', + configResolved: { + order: 'post', + handler(config: Vite.ResolvedConfig) { + // Vitest's internal post-configResolved hook resets `server.watch` to `{}` when + // `watch` is enabled (`server.watch ??= {}`). Force it back to `null` so Vite uses + // a no-op watcher and relies solely on the Angular CLI build watcher. + config.server.watch = null; + }, + }, async config(config: UserWorkspaceConfig & Vite.UserConfig) { const testConfig = config.test; diff --git a/packages/angular/build/src/builders/unit-test/tests/options/watch_spec.ts b/packages/angular/build/src/builders/unit-test/tests/options/watch_spec.ts index d1840beb4a96..79e25ca84b27 100644 --- a/packages/angular/build/src/builders/unit-test/tests/options/watch_spec.ts +++ b/packages/angular/build/src/builders/unit-test/tests/options/watch_spec.ts @@ -55,5 +55,38 @@ describeBuilder(execute, UNIT_TEST_BUILDER_INFO, (harness) => { }, ]); }); + + it('should disable the Vite server file watcher when watch is true', async () => { + harness.useTarget('test', { + ...BASE_OPTIONS, + watch: true, + runnerConfig: 'vitest.config.mts', + }); + + await harness.writeFile( + 'vitest.config.mts', + ` + import { defineConfig } from 'vitest/config'; + export default defineConfig({ + plugins: [ + { + name: 'assert-watch-disabled', + configureVitest({ vitest, project }) { + if (vitest.vite.config.server.watch !== null || project.vite.config.server.watch !== null) { + throw new Error('Expected Vite server.watch to be null'); + } + }, + }, + ], + }); + `, + ); + + await harness.executeWithCases([ + ({ result }) => { + expect(result?.success).toBeTrue(); + }, + ]); + }); }); }); From 5570c91d2f38764cd841fcce146f1d13fef49b0c Mon Sep 17 00:00:00 2001 From: Alan Agius Date: Tue, 13 Oct 2026 08:00:44 +0200 Subject: [PATCH 091/233] fix(@angular/cli): resolve package name in npm workspace members Read `package.json` in the working directory first in `getCurrentPackageName` to avoid spawning an unnecessary child process, and handle single-entry workspace objects returned by `npm pkg get name` when falling back to the package manager command. (cherry picked from commit a1cf33bc45882fb74578cc7d1faeba8cecec7b73) --- .../src/package-managers/package-manager.ts | 34 ++++++--- .../package-managers/package-manager_spec.ts | 69 +++++++++++++++++++ 2 files changed, 93 insertions(+), 10 deletions(-) diff --git a/packages/angular/cli/src/package-managers/package-manager.ts b/packages/angular/cli/src/package-managers/package-manager.ts index 234b54851232..272454c21cbd 100644 --- a/packages/angular/cli/src/package-managers/package-manager.ts +++ b/packages/angular/cli/src/package-managers/package-manager.ts @@ -393,25 +393,39 @@ export class PackageManager { * Gets the name of the package in the current project. */ async getCurrentPackageName(): Promise { + try { + const content = await this.host.readFile(join(this.cwd, 'package.json')); + const { name } = JSON.parse(content) as { name?: unknown }; + if (typeof name === 'string') { + return name; + } + } catch { + // Fall back to package manager command if reading file fails + } + if (this.descriptor.getPackageNameCommand) { try { const { stdout } = await this.#run(this.descriptor.getPackageNameCommand); if (stdout) { - return JSON.parse(stdout); + const name = JSON.parse(stdout); + if (typeof name === 'string') { + return name; + } + + // In a workspace member npm prints an object keyed by workspace name instead of a string. + if (name && typeof name === 'object') { + const values = Object.values(name); + if (values.length === 1 && typeof values[0] === 'string') { + return values[0]; + } + } } } catch { - // Fall back to reading file if command fails + // Ignore command failure } } - try { - const content = await this.host.readFile(join(this.cwd, 'package.json')); - const pkgJson = JSON.parse(content); - - return pkgJson.name; - } catch { - return undefined; - } + return undefined; } /** diff --git a/packages/angular/cli/src/package-managers/package-manager_spec.ts b/packages/angular/cli/src/package-managers/package-manager_spec.ts index d500a435d0df..37e0d8aae113 100644 --- a/packages/angular/cli/src/package-managers/package-manager_spec.ts +++ b/packages/angular/cli/src/package-managers/package-manager_spec.ts @@ -378,6 +378,75 @@ describe('PackageManager', () => { }); }); + describe('getCurrentPackageName', () => { + it('should return the name from package.json without running the package manager command', async () => { + const pm = new PackageManager(host, '/repo/app', descriptor); + const readFileSpy = spyOn(host, 'readFile').and.resolveTo('{"name": "app"}'); + + expect(await pm.getCurrentPackageName()).toBe('app'); + expect(readFileSpy).toHaveBeenCalledWith(jasmine.stringMatching(/package\.json$/)); + expect(runCommandSpy).not.toHaveBeenCalled(); + }); + + it('should fall back to the package manager command when reading package.json fails', async () => { + const pm = new PackageManager(host, '/repo/app/src', descriptor); + spyOn(host, 'readFile').and.rejectWith(new Error('ENOENT')); + runCommandSpy.and.resolveTo({ stdout: '"app"', stderr: '' }); + + expect(await pm.getCurrentPackageName()).toBe('app'); + expect(runCommandSpy).toHaveBeenCalledWith( + descriptor.binary, + descriptor.getPackageNameCommand, + jasmine.objectContaining({ cwd: '/repo/app/src' }), + ); + }); + + it('should extract the package name when npm prints a single-entry workspace object', async () => { + const pm = new PackageManager(host, '/repo/apps/app/src', descriptor); + spyOn(host, 'readFile').and.rejectWith(new Error('ENOENT')); + // Inside a workspace member, `npm pkg get name` prints `{ "app": "app" }` instead of `"app"`. + runCommandSpy.and.resolveTo({ stdout: '{\n "app": "app"\n}', stderr: '' }); + + expect(await pm.getCurrentPackageName()).toBe('app'); + }); + + it('should return undefined when npm prints multiple workspace entries and package.json is unavailable', async () => { + const pm = new PackageManager(host, '/repo', descriptor); + spyOn(host, 'readFile').and.rejectWith(new Error('ENOENT')); + runCommandSpy.and.resolveTo({ + stdout: '{\n "app-a": "app-a",\n "app-b": "app-b"\n}', + stderr: '', + }); + + expect(await pm.getCurrentPackageName()).toBeUndefined(); + }); + }); + + describe('getProjectDependencies', () => { + it('should list the dependencies of an npm workspace member', async () => { + const pm = new PackageManager(host, '/repo/apps/app', descriptor); + runCommandSpy.and.resolveTo({ + stdout: JSON.stringify({ + name: 'monorepo', + dependencies: { + app: { + version: '0.0.0', + resolved: 'file:../apps/app', + dependencies: { '@angular/core': { version: '22.0.0' } }, + }, + }, + }), + stderr: '', + }); + spyOn(host, 'readFile').and.resolveTo('{"name": "app"}'); + + const dependencies = await pm.getProjectDependencies(); + + expect([...dependencies.keys()]).toEqual(['@angular/core']); + expect(dependencies.get('@angular/core')?.version).toBe('22.0.0'); + }); + }); + describe('initializationError', () => { it('should throw initializationError when running commands', async () => { const error = new Error('Not installed'); From b0ac394a063f084d885df67660224b6a25e2c614 Mon Sep 17 00:00:00 2001 From: Alan Agius Date: Tue, 13 Oct 2026 08:02:42 +0200 Subject: [PATCH 092/233] perf(@angular/build): resolve asset patterns concurrently with bounded concurrency Avoid sequentially globbing asset entries one-by-one in `resolveAssets` by utilizing `mapConcurrent` bounded by `MAX_CONCURRENT_READS` (16). Additionally, add a fast path for static, non-dynamic file patterns using direct file stats instead of directory walks. (cherry picked from commit fb7efc86228164330f68ed86801f9d5bbe9ad5b0) --- .../esbuild/persistent-load-result-cache.ts | 5 +-- .../angular/build/src/utils/concurrency.ts | 5 +++ .../angular/build/src/utils/resolve-assets.ts | 43 +++++++++++++------ 3 files changed, 37 insertions(+), 16 deletions(-) diff --git a/packages/angular/build/src/tools/esbuild/persistent-load-result-cache.ts b/packages/angular/build/src/tools/esbuild/persistent-load-result-cache.ts index c5dcee90ccf9..7eaf11806f1d 100644 --- a/packages/angular/build/src/tools/esbuild/persistent-load-result-cache.ts +++ b/packages/angular/build/src/tools/esbuild/persistent-load-result-cache.ts @@ -32,7 +32,7 @@ import { readFile, stat } from 'node:fs/promises'; import { isAbsolute } from 'node:path'; import { fileURLToPath } from 'node:url'; import type { Cache as PersistentCacheStore } from '../../utils/cache'; -import { mapConcurrent, runConcurrent } from '../../utils/concurrency'; +import { MAX_CONCURRENT_READS, mapConcurrent, runConcurrent } from '../../utils/concurrency'; import { calculateHash, createContentHash } from '../../utils/hash'; import { LoadResultCache, MemoryLoadResultCache } from './load-result-cache'; @@ -112,9 +112,6 @@ export function extractDiskFilePath(path: string): string | undefined { return isAbsolute(path) ? path : undefined; } -/** Maximum number of concurrent file system read/stat operations to prevent OS file descriptor exhaustion. */ -const MAX_CONCURRENT_READS = 16; - /** * Validates that all imported watch files exist on disk and their contents match. * Performs a fast-path metadata check (mtime + size) first, falling back to content hashing. diff --git a/packages/angular/build/src/utils/concurrency.ts b/packages/angular/build/src/utils/concurrency.ts index a38a9a57fa36..39f2b70c95df 100644 --- a/packages/angular/build/src/utils/concurrency.ts +++ b/packages/angular/build/src/utils/concurrency.ts @@ -6,6 +6,11 @@ * found in the LICENSE file at https://angular.dev/license */ +/** + * Maximum number of concurrent file system read/stat operations to prevent OS file descriptor exhaustion. + */ +export const MAX_CONCURRENT_READS = 16; + /** * Executes an asynchronous function for each item in an array concurrently up to a specified limit. * diff --git a/packages/angular/build/src/utils/resolve-assets.ts b/packages/angular/build/src/utils/resolve-assets.ts index 41ae41d66b9b..c1826c782fdd 100644 --- a/packages/angular/build/src/utils/resolve-assets.ts +++ b/packages/angular/build/src/utils/resolve-assets.ts @@ -6,8 +6,10 @@ * found in the LICENSE file at https://angular.dev/license */ +import { lstat, stat } from 'node:fs/promises'; import path from 'node:path'; -import { glob } from 'tinyglobby'; +import { glob, isDynamicPattern } from 'tinyglobby'; +import { MAX_CONCURRENT_READS, mapConcurrent } from './concurrency'; import { isSubDirectory } from './path'; /** @@ -26,15 +28,34 @@ export async function resolveAssets( }[], root: string, ): Promise<{ source: string; destination: string }[]> { - const outputFiles: { source: string; destination: string }[] = []; - - for (const entry of entries) { + const resolvedEntries = await mapConcurrent(entries, MAX_CONCURRENT_READS, async (entry) => { if (!isSubDirectory(root, entry.input)) { throw new Error(`The ${entry.input} asset path must be within the workspace root.`); } const cwd = path.resolve(root, entry.input); + if (!entry.ignore?.length && !isDynamicPattern(entry.glob)) { + const src = path.join(cwd, entry.glob); + if (isSubDirectory(cwd, src)) { + try { + const stats = await (entry.followSymlinks ? stat(src) : lstat(src)); + if (stats.isFile()) { + const filePath = entry.flatten ? path.basename(entry.glob) : entry.glob; + + return [{ source: src, destination: path.join(entry.output, filePath) }]; + } + + if (!stats.isSymbolicLink()) { + return []; + } + } catch { + // File does not exist or cannot be accessed. + return []; + } + } + } + const files = await glob(entry.glob, { cwd, dot: true, @@ -42,13 +63,11 @@ export async function resolveAssets( followSymbolicLinks: entry.followSymlinks, }); - for (const file of files) { - const src = path.join(cwd, file); - const filePath = entry.flatten ? path.basename(file) : file; - - outputFiles.push({ source: src, destination: path.join(entry.output, filePath) }); - } - } + return files.map((file) => ({ + source: path.join(cwd, file), + destination: path.join(entry.output, entry.flatten ? path.basename(file) : file), + })); + }); - return outputFiles; + return resolvedEntries.flat(); } From c0b66596b5747f947c42f0c99ef9f61fe2c95227 Mon Sep 17 00:00:00 2001 From: Angular Robot Date: Tue, 13 Oct 2026 15:00:08 +0000 Subject: [PATCH 093/233] build: update dependency zod to v4.6.6 See associated pull request for more information. --- packages/angular/cli/package.json | 2 +- pnpm-lock.yaml | 13 +++++++++---- 2 files changed, 10 insertions(+), 5 deletions(-) diff --git a/packages/angular/cli/package.json b/packages/angular/cli/package.json index bd71c4c0922b..8aaae551c358 100644 --- a/packages/angular/cli/package.json +++ b/packages/angular/cli/package.json @@ -25,7 +25,7 @@ "parse5-html-rewriting-stream": "8.0.1", "semver": "7.8.5", "yargs": "18.1.0", - "zod": "4.6.5" + "zod": "4.6.6" }, "ng-update": { "migrations": "@schematics/angular/migrations/migration-collection.json", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 7181b3bff33e..251b0cd7059e 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -639,8 +639,8 @@ importers: specifier: 18.1.0 version: 18.1.0 zod: - specifier: 4.6.5 - version: 4.6.5 + specifier: 4.6.6 + version: 4.6.6 packages/angular/pwa: dependencies: @@ -8677,6 +8677,9 @@ packages: zod@4.6.5: resolution: {integrity: sha512-v5l/aFXZQeai4awLbOpSoHecE9UiMrnfx75tEXLjNonXVARxQ5mOeipTjROUchszUNCqnE+hqAMujRsRHsut2Q==} + zod@4.6.6: + resolution: {integrity: sha512-4UmzQUF5fxvfcYHlbjBmejU+w+hbDnWFx4aS8kBx7nPBHcO2SqPbpAG8snbdg+Xse4pRefR98hgjFgIMCI/UhA==} + zone.js@0.16.3: resolution: {integrity: sha512-ihXL9+vhYyEhXz4TDNpHeAOZN9FVrbog0Il64OIEI28UP/n5AaI6gsccRuOHBfx+206agzyoK527bYIO0Foy6A==} @@ -10686,12 +10689,12 @@ snapshots: '@modelcontextprotocol/core@2.3.1': dependencies: - zod: 4.6.5 + zod: 4.6.6 '@modelcontextprotocol/server@2.3.1': dependencies: '@modelcontextprotocol/core': 2.3.1 - zod: 4.6.5 + zod: 4.6.6 '@msgpackr-extract/msgpackr-extract-darwin-arm64@3.0.4': optional: true @@ -17150,4 +17153,6 @@ snapshots: zod@4.6.5: {} + zod@4.6.6: {} + zone.js@0.16.3: {} From 931377629d16d3a4d9a1c699d84cade3e1b34058 Mon Sep 17 00:00:00 2001 From: Angular Robot Date: Tue, 13 Oct 2026 17:34:43 +0000 Subject: [PATCH 094/233] build: lock file maintenance See associated pull request for more information. --- MODULE.bazel.lock | 2 +- pnpm-lock.yaml | 687 +++++++++++++++++++--------------------------- 2 files changed, 278 insertions(+), 411 deletions(-) diff --git a/MODULE.bazel.lock b/MODULE.bazel.lock index 6324d403541d..1fdbca78a05d 100644 --- a/MODULE.bazel.lock +++ b/MODULE.bazel.lock @@ -384,7 +384,7 @@ "aspect_rules_jasmine": "2.0.4", "aspect_tools_telemetry": "0.5.2" }, - "last_notice": 3 + "last_notice": 0 } } }, diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 251b0cd7059e..b632b6063d5f 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -293,7 +293,7 @@ importers: version: 3.0.0(esbuild@0.28.2)(lightningcss@1.33.0)(uglify-js@3.19.3) '@types/lodash': specifier: ^4.17.0 - version: 4.17.25 + version: 4.17.26 '@types/node': specifier: ^22.12.0 version: 22.20.5 @@ -398,7 +398,7 @@ importers: version: 1.4.1 prettier: specifier: ^3.0.0 - version: 3.9.9 + version: 3.9.10 puppeteer: specifier: 25.11.0 version: 25.11.0(bufferutil@4.1.0)(utf-8-validate@6.0.6) @@ -431,7 +431,7 @@ importers: version: 6.10.3(encoding@0.1.13)(supports-color@11.0.0) verdaccio-auth-memory: specifier: ^13.0.0 - version: 13.1.5(supports-color@11.0.0) + version: 13.1.6(supports-color@11.0.0) zone.js: specifier: ^0.16.0 version: 0.16.3 @@ -1203,18 +1203,18 @@ packages: resolution: {integrity: sha512-wem6WaBj4NaVYVdNhLPPVacES6ZJ+KBBfSkTMD3YZxbP3rm3Di85tJU5ljaUNhaOynt+Aj0xruhYuzQBt8n71g==} engines: {node: '>=6.9.0'} - '@babel/helper-compilation-targets@8.0.6': - resolution: {integrity: sha512-HTrtZ4+iA0+kzdbCgvdSk1U4pEl3BvpGnlUbualCGNbrVhhQvhgBzurTUmqpWyvyHbWYWaIfdx2mOlL9LJjsew==} + '@babel/helper-compilation-targets@8.0.7': + resolution: {integrity: sha512-ilAZCdOOlOVA7dQbaFNw2f/59p6GW33NxTopc3DvEE3efp3ZXTrGX/yZScaKw8/vd9bq31Ag0EcXiLw32bAgJg==} engines: {node: ^22.18.0 || >=24.11.0} - '@babel/helper-create-class-features-plugin@8.0.6': - resolution: {integrity: sha512-Hy7wG2Pk1LnAkFMq0CbBk789XMTYVzYGxR7tKgk+TOpZckQRME3Tdou4mMT/8DFjJFxFZ8R6UsS4DR/duBKlVA==} + '@babel/helper-create-class-features-plugin@8.0.7': + resolution: {integrity: sha512-7ug3KrOhNVPPxFFLTel0/pMzimKzU/vTlNJKVL/dKguCpmNJZjjibyFbWg+Qs8QHmiIZPNuZ2UNnDGdHWGEpOg==} engines: {node: ^22.18.0 || >=24.11.0} peerDependencies: '@babel/core': ^8.0.0 - '@babel/helper-create-regexp-features-plugin@8.0.5': - resolution: {integrity: sha512-TWnIgw21pAv/FbBKB8ks26DMxQ+A3aBdi1HUBp+QhqSE8QdOqJgSK/FEvdMYPTZcHBBJPZ5pN6DDKmC5ZYPJbg==} + '@babel/helper-create-regexp-features-plugin@8.0.7': + resolution: {integrity: sha512-pyia4a5cQ9fmUuimPO4pl3p8aX9aGBBMqZyNUmwhJGO/e3bIbbt/26Zun6SE1CRvNaUWiTsfLuZeaLX6EIIUWQ==} engines: {node: ^22.18.0 || >=24.11.0} peerDependencies: '@babel/core': ^8.0.0 @@ -1315,12 +1315,12 @@ packages: resolution: {integrity: sha512-Qpm8+wi5xfDkBfollanwriCcKniFfBmMmaKB01GVM6VGzKXo1fdxosZp04qEr5HM+LKhwr3hG1yRy8+ORsficA==} engines: {node: ^22.18.0 || >=24.11.0} - '@babel/helpers@7.29.7': - resolution: {integrity: sha512-1k2lAGRMfHTcwuNYcCNUmaUffmQv8KWMfh2iJUUeRlwlwH4FdNG7mfPI10NPfLHJFThE4Tyr4mv7kTNZOiPuBg==} + '@babel/helpers@7.29.10': + resolution: {integrity: sha512-EMCx3AGZ3WfAl6ht7AyQoPm2Lh+BGYEMdc4Q6Hf7uSCDOZFuLq44qNwL+iaim8VlyYhRAo4X43+weadK8ZB4Yg==} engines: {node: '>=6.9.0'} - '@babel/helpers@8.0.5': - resolution: {integrity: sha512-fQtPOXjYOYv85PIdwotp2TJGVYOycX0PQq+l844fFAxOULtBy8BVF35GyeueX0r4KvDthqPH5xAI1clQPk/2uA==} + '@babel/helpers@8.0.7': + resolution: {integrity: sha512-5dMj5kFwS2AY7Dt4PZp4px3c5ThMbbEa7tZfuHTncCGSFYq8uoA1ufDE1IS/lYpQedE+3+GQ3cPZUiplIu195w==} engines: {node: ^22.18.0 || >=24.11.0} '@babel/parser@7.29.9': @@ -1328,8 +1328,8 @@ packages: engines: {node: '>=6.0.0'} hasBin: true - '@babel/parser@8.0.6': - resolution: {integrity: sha512-LpGDIYJAzc3Y3PT9x+FxBrGYu2PlWxLmyN7SwPTzaX0LSwEmFJBsRnPBqmaXF2r1v+Zhz6lNiEJ+7yKtM5+Ugg==} + '@babel/parser@8.0.7': + resolution: {integrity: sha512-UkDwEbPO1px2JQSrdh4qIgaH1JgG7GO/pFeJkpxhDxIETkT/QvGpnigXIw75ViHYPtIgKITmVUJqLjiO+JuWjA==} engines: {node: ^22.18.0 || >=24.11.0} hasBin: true @@ -1393,8 +1393,8 @@ packages: peerDependencies: '@babel/core': ^8.0.0 - '@babel/plugin-transform-block-scoping@8.0.5': - resolution: {integrity: sha512-czkN3g76Ns2wMe1C0IuceKUCqCe/yJ1by0qz4h4znq74K/Ks7K2Fx6Dplq9ecS65Z3rJHxT9a/kDSF2LbEov8w==} + '@babel/plugin-transform-block-scoping@8.0.7': + resolution: {integrity: sha512-JhQli/zQZPXyDO/dhA2OWjDSsKDRgd0jVeN80qsDp4twAmbP8otJNWKwqRZzbsGATNmbsVfVM0b4L9lR5h+8WA==} engines: {node: ^22.18.0 || >=24.11.0} peerDependencies: '@babel/core': ^8.0.0 @@ -1471,8 +1471,8 @@ packages: peerDependencies: '@babel/core': ^8.0.0 - '@babel/plugin-transform-for-of@8.0.1': - resolution: {integrity: sha512-rpeXtgELjpIBQH/+YmyFlD9timPEVCyqY+TNednzoeoTYvXSBEeUvYnYE+BK8rB8m6hHiNK7aL9QWKhGifEJCw==} + '@babel/plugin-transform-for-of@8.0.7': + resolution: {integrity: sha512-h+/9Kyy55fWlnLDmMIWwz21nWLFodIZYpvvCq7gW6Fb55via7sTYPymeTNKbh8N9XZjZ025ClVtg0kxIPnEjGA==} engines: {node: ^22.18.0 || >=24.11.0} peerDependencies: '@babel/core': ^8.0.0 @@ -1703,12 +1703,12 @@ packages: resolution: {integrity: sha512-eAD0QW/AlbamBbw0FeGiwasbCVPq5ncW0HNVyLP3B9czqLyh4gvw+5JTSNt6le9+ziAU7mqDZsKTHf3jTb4chQ==} engines: {node: ^22.18.0 || >=24.11.0} - '@babel/traverse@7.29.8': - resolution: {integrity: sha512-I5z7H3bf/41ktsNVLtpN0wAa336HkqIHQ5BuPLEhTkt1jVSyZpeNKIzTgEWmlxjdg81R0IgUCcaE+Ok3NvrfZg==} + '@babel/traverse@7.29.10': + resolution: {integrity: sha512-B3lYAs2nkKskbgQ1nfy8Ma9ao9Q1rntTAQHrzzyDuj+TSO+X3le6PfWwqDvodsb+OumE10eMFfuMCTQSQ5iuIQ==} engines: {node: '>=6.9.0'} - '@babel/traverse@8.0.6': - resolution: {integrity: sha512-ilYV+qLStGzSKLipJlETdvdtpK3rAuwfCmCoGKv15MU4EoeIuLkespSNoNLFGOPSciEHx9TLWtN5mv0fz5w5mQ==} + '@babel/traverse@8.0.7': + resolution: {integrity: sha512-bVV0brinsTWgc6ptSIoQo3GbITtl0VZAqEUJbHHcyfDPEu+q/fEvlYEa+6H85HoK8IdksKBFtKJbJFZ6Kff+zg==} engines: {node: ^22.18.0 || >=24.11.0} '@babel/types@7.29.8': @@ -1735,8 +1735,8 @@ packages: resolution: {integrity: sha512-6zABk/ECA/QYSCQ1NGiVwwbQerUCZ+TQbp64Q3AgmfNvurHH0j8TtXa1qbShXA6qqkpAj4V5W8pP6mLe1mcMqA==} engines: {node: '>=18'} - '@bramus/specificity@2.4.2': - resolution: {integrity: sha512-ctxtJ/eA+t+6q2++vj5j7FYX3nRu311q1wfYH3xjlLOsczhlhxAg2FWNUXhpGvAw3BWo1xBcvOV6/YLc2r5FJw==} + '@bramus/specificity@2.4.3': + resolution: {integrity: sha512-0GEz8qJWokkUVYQYRukmkSHIFNoBH8QTreeHrAFbvz1XFYc3Y+puhMs8PQ5x8GNugiC2l5jvDBXKLbBIByeSBw==} hasBin: true '@bufbuild/protobuf@2.16.0': @@ -2293,8 +2293,8 @@ packages: '@modelcontextprotocol/sdk': optional: true - '@grpc/grpc-js@1.14.5': - resolution: {integrity: sha512-7VZM+SVdEcUUqSQeNI3zM8Qs/BhQKZndPo2h5VkYkAM8Iz0wJIa8mKV5ekQGqG8UUsnkQ0NMxIxwkIHYvj0qOw==} + '@grpc/grpc-js@1.14.6': + resolution: {integrity: sha512-SgC/B3/VZ8lTyOZ4Cwk6f1skWhmkNAaVfiX90qd5u1rRXGKk1//8FTUEN9GvOUq7rfWIqAYkA3CoyumYVpOS6g==} engines: {node: '>=12.10.0'} '@grpc/grpc-js@1.9.16': @@ -2987,14 +2987,14 @@ packages: resolution: {integrity: sha512-gLyJlPHPZYdAk1JENA9LeHejZe1Ti77/pTeFm/nMXmQH/HFZlcS/O2XJB+L8fkbrNSqhdtlvjBVjxwUYanNH5Q==} engines: {node: '>=8.0.0'} - '@opentelemetry/context-async-hooks@2.11.0': - resolution: {integrity: sha512-Tr79DyWI8itsBdg+jH+opjfrwLzX+erk1/ExkIwhWoAVjVrJIn2y5+cGjTC0Vy8fyNIA/y8wuJPZwr1T3xCZeQ==} + '@opentelemetry/context-async-hooks@2.12.0': + resolution: {integrity: sha512-iK/1nD7mmZVkuYjVjkdFBiCvzntJdFny1S3CYbUYyOq7V5enL6XX+gJ7eh965L1LnS11VA8mQ7Ej/ck04SB0MQ==} engines: {node: ^18.19.0 || >=20.6.0} peerDependencies: '@opentelemetry/api': '>=1.0.0 <1.10.0' - '@opentelemetry/core@2.11.0': - resolution: {integrity: sha512-7YP44XH0tV6+Mb54x2YGf84i7yi+31MBZlE8JwvozkxyTvXbSp10X7cI7YE49ChJ3shMJoBmCJF3+1QFBJctGA==} + '@opentelemetry/core@2.12.0': + resolution: {integrity: sha512-1HsSAuvT4/my0QrXWsyXFdWjKaPeCHsismKZgEEIb8NK13LP6DrMRlsUbvD/0F9mDWK3xDom9AMv3IscxgOnOQ==} engines: {node: ^18.19.0 || >=20.6.0} peerDependencies: '@opentelemetry/api': '>=1.0.0 <1.10.0' @@ -3725,8 +3725,8 @@ packages: '@types/loader-utils@3.0.0': resolution: {integrity: sha512-oOi4OGpiLUbb+Q/cN9FIkkDFgOpOGZ2cUAzb5i03wrGstnG6Syx1WDMhSiB5rcP10XX7cw7Uev8mv++/aplnNg==} - '@types/lodash@4.17.25': - resolution: {integrity: sha512-+K1NIO8I+F9/wNulfVvu23QYd0Pe9/OCqRrim4NoYIf1VoEDL90Ve4ClzpyqBLc7NpGGWRvYNCKZ1BE/Jpf8dQ==} + '@types/lodash@4.17.26': + resolution: {integrity: sha512-48NWfiY6oNcKOh47Z4h+sIvwcQR91h6KPhaYKgeMIrkT2jV82Gy90SErj60vW8jQbeMSOSbhIv3bZ7JoqPPVhA==} '@types/micromatch@2.3.35': resolution: {integrity: sha512-J749bHo/Zu56w0G0NI/IGHLQPiSsjx//0zJhfEVAN95K/xM5C8ZDmhkXtU3qns0sBOao7HuQzr8XV1/2o5LbXA==} @@ -3848,8 +3848,8 @@ packages: resolution: {integrity: sha512-asTOIYhDg4zdzOScCyaytrsV3cR6B4ecPQlXw/dJIm7J/MZTtCtfVII9JD8Geh4jTCrK/Xe6cg5UevoleMcoJQ==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@typescript-eslint/types@8.71.0': - resolution: {integrity: sha512-cJ4OoxPGWvFnBTnSZyaU+qJzGTqPTGJY+gDchj6cRyLRdmIdt4rcsE4twj+zPfrNiWuVi38wijHzShL++Z9atQ==} + '@typescript-eslint/types@8.71.2': + resolution: {integrity: sha512-y5Ukl3oVp7e/VGxqIoEXoeb/Roj71PAJ4WG/N/RGj+eeDvKRLM15kGr9MijLbN0i03S52zxu31Z98E5gWChJKw==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} '@typescript-eslint/typescript-estree@8.70.0': @@ -3881,8 +3881,8 @@ packages: resolution: {integrity: sha512-axlsbrXnENRM1+VeTNbTrR0VOD+9pBxA8sN+41rpt9UfThIQhDgf89YPPlCfu/ks/LH1KTcSzhR7nZuDYypeCw==} engines: {node: '>=22'} - '@verdaccio/core@8.3.2': - resolution: {integrity: sha512-KRYepjgpSgrYYNHjmg77F9Mp7FMzQ0f9dcNc2AP3fmCmQMx0IWH6TYe4okvqkASoYhLnil5NRWqjO4Z4qSOHVg==} + '@verdaccio/core@8.3.3': + resolution: {integrity: sha512-Vhfpo9MIwUOIsNQCGmTKqYn2l73261YQ6NCmRS47NbpXi5YWuSGf7I6i4dIVMZVG7UUtz9633754WtzFFAgFvg==} engines: {node: '>=22'} '@verdaccio/file-locking@13.1.0': @@ -4039,164 +4039,74 @@ packages: '@yarnpkg/lockfile@1.1.0': resolution: {integrity: sha512-GpSwvyXOcOOlV70vbnzjj4fW5xW/FdUF6nQEt1ENy7m4ZCczi1+/buVUPAqmGfqznsORNFzUMjctTIp8a9tuCQ==} - '@yuku-codegen/binding-android-arm64@0.10.2': - resolution: {integrity: sha512-Oc2KInVkPfUjEB4PeV6X0NvIoyYTzDe/WmqFrTwBqKs6YKnz4A7XwWQvJTb7M0rLz9a6WgpUUiiS5QKaCi4O/g==} + '@yuku-core/binding-android-arm64@0.19.0': + resolution: {integrity: sha512-wdL2XmTiZixAOaHk9Z0JJZ8u9Qm8d333Zjpc6gaxXFX+UR5BlsfxZ7a2+2Rm71pamppsPYGUGFq2oVLbh6DISw==} cpu: [arm64] os: [android] - deprecated: yuku-codegen is pure JavaScript since 0.14 - '@yuku-codegen/binding-darwin-arm64@0.10.2': - resolution: {integrity: sha512-3H7eNPIHJndUJXZ4QUGBPq1zC6RGcUZfm7bymJes+/N7wTVWUn1bxZ9JcozYHpkWQNm9f23G8YWbaHD9aYH72A==} + '@yuku-core/binding-darwin-arm64@0.19.0': + resolution: {integrity: sha512-7sNJa6XJhyetnTy64jw3NEi4YgUcezHk1G5GH9FSvXAuC8wIlbaOwT9lgq5qo5sspjrZJQlBR1TWflP49uRpMw==} cpu: [arm64] os: [darwin] - deprecated: yuku-codegen is pure JavaScript since 0.14 - '@yuku-codegen/binding-darwin-x64@0.10.2': - resolution: {integrity: sha512-AJOUpR2s3LF9AWiiub/Uyc/UoXNTWcq8hK3cVI6fUSXtwh34dG21J6hRuNlO6JVJFTo4o3ScVvZOrh/YFfUEAA==} + '@yuku-core/binding-darwin-x64@0.19.0': + resolution: {integrity: sha512-pTC7dYEc59isdyizc3nsuyFNBu2LU5wMYZ1be6UMr59PY/AJNtO1aBLWV0MgL/z7C1nv/2sX4TNjGgKLoeevJw==} cpu: [x64] os: [darwin] - deprecated: yuku-codegen is pure JavaScript since 0.14 - '@yuku-codegen/binding-freebsd-x64@0.10.2': - resolution: {integrity: sha512-ms7DcZu87u5CiK/wMwvpKAvAmtaqKjCQIXNweMLypG6qbuiaOMQf1jpbB5+j46xBcgCovo8TQMcv0bCQLKIL9w==} + '@yuku-core/binding-freebsd-x64@0.19.0': + resolution: {integrity: sha512-xrZjF6XOEwyLOiDIfrwDdRCS6ghxcJeirNC1KivQhVcUwlRonaU79S3/Uiyx3lBylPnT8qKJ3/aMT+H52nGTJQ==} cpu: [x64] os: [freebsd] - deprecated: yuku-codegen is pure JavaScript since 0.14 - '@yuku-codegen/binding-linux-arm-gnu@0.10.2': - resolution: {integrity: sha512-xJDpYAsKV5+eaiBhTYl05fvT6sst4PsCeuIFMRu9b0/WCSrNQPfCDtAQ5/MS6xNpsdujdZEPR+gmfWk3ZG5i3A==} + '@yuku-core/binding-linux-arm-gnu@0.19.0': + resolution: {integrity: sha512-0OyIH53C0I1CbADHn9FSdCfX5qbpeLwJhmOVhonFJNYheybOnkSJ50qGMfTJIb8y5zrwqvLs7FVBvz6Fk8maZg==} cpu: [arm] os: [linux] libc: [glibc] - deprecated: yuku-codegen is pure JavaScript since 0.14 - '@yuku-codegen/binding-linux-arm-musl@0.10.2': - resolution: {integrity: sha512-qfTkgd7AEx61l4K9VtXWCGTxc/fmXJ4ZheDz3i+/AAJUtg4sa0bPrc0VBxPggB/rayR8Z3+JfrBItuyanBJJ9Q==} + '@yuku-core/binding-linux-arm-musl@0.19.0': + resolution: {integrity: sha512-z/iPfkCOCSXE34VXNt0uP1ORSW+4mEa9b5CiJcWZeqZH08g49bFU/jRM2T04f+Wpw5mJ6HIzNBiojxeAbrHjeg==} cpu: [arm] os: [linux] libc: [musl] - deprecated: yuku-codegen is pure JavaScript since 0.14 - '@yuku-codegen/binding-linux-arm64-gnu@0.10.2': - resolution: {integrity: sha512-4e6Mifm/4UdjtU3D8mATIrvgP+xEiH8xtQOjd0zpd72XKWT7ug3sdyhq2utkkZFP6BvYp7SgZrI+aR4VeIOHdw==} + '@yuku-core/binding-linux-arm64-gnu@0.19.0': + resolution: {integrity: sha512-jLNTi+gzaRwBJ+gwhCJ+rDb5dmx/8hEBx93UWd7hjMSqPTL1D1wvVSvXVAldV5kALvju7b0/m51EHEhs4+I1fA==} cpu: [arm64] os: [linux] libc: [glibc] - deprecated: yuku-codegen is pure JavaScript since 0.14 - '@yuku-codegen/binding-linux-arm64-musl@0.10.2': - resolution: {integrity: sha512-RdsJrUfDYFVV3JOmWFUWwSu31fa1APn12xDeIKxgl/YWxrabwtxsDBNjF2561c7tmcbiewdCUvngqRs8AyGVLA==} + '@yuku-core/binding-linux-arm64-musl@0.19.0': + resolution: {integrity: sha512-YwyPIdW/rN2Fmv0MTFWi47FaB3F9g+2b+sJISyAw83Yd60RWH4T3Nx6XkAHHVN+uKJNBAd6So7/BVihSiFYvuQ==} cpu: [arm64] os: [linux] libc: [musl] - deprecated: yuku-codegen is pure JavaScript since 0.14 - '@yuku-codegen/binding-linux-x64-gnu@0.10.2': - resolution: {integrity: sha512-mVzWimEPPreaPyXIUvxsHoJzvO7ckZ5j0LgQFHz04zQIRwt9A9T2hA7K5/jYjJKkMxWG/U2VjhGNwVhtyU+uqg==} + '@yuku-core/binding-linux-x64-gnu@0.19.0': + resolution: {integrity: sha512-/vskaAXVX3ESR43FiTdfiYS7z1b9uoQJwVQ/0RgUHgN2sWoAyCZs+aX4CgU7eKGIHTVfp9VFwv+c+2XchYiEtQ==} cpu: [x64] os: [linux] libc: [glibc] - deprecated: yuku-codegen is pure JavaScript since 0.14 - '@yuku-codegen/binding-linux-x64-musl@0.10.2': - resolution: {integrity: sha512-Y77fyISurmr2mvO1yeq3u+x/WJbACgPR4w+lzEVx30ViCxZzIGrZPRN1yEdZ9xUNPNsIO5thBHIdRNG+UGUG+Q==} + '@yuku-core/binding-linux-x64-musl@0.19.0': + resolution: {integrity: sha512-FuXL5igeSKib9Rye02TdH+D6SQezTyGxIATMu1Qsn/QywrzwpGl35OLpS2C1x5vpGLeVE2XgiLd5mVPFHmIglQ==} cpu: [x64] os: [linux] libc: [musl] - deprecated: yuku-codegen is pure JavaScript since 0.14 - '@yuku-codegen/binding-win32-arm64@0.10.2': - resolution: {integrity: sha512-1+tGLyG0u5YYy0lev4ck7/0sd8xJ9SZde0dLut7qLDPZV5WVTV8x6OxNXUne/PGuHZyO1vK+txPQzzHOyXHGSw==} + '@yuku-core/binding-win32-arm64@0.19.0': + resolution: {integrity: sha512-YuJAe7zEKT1Xa7LuHlhGJpPnYQeVtvo0rZvNjJRqkH0hQGOw4C8QeP30Tg5VKGzZfo2x8CjhjEhKt4TmLwfmdg==} cpu: [arm64] os: [win32] - deprecated: yuku-codegen is pure JavaScript since 0.14 - '@yuku-codegen/binding-win32-x64@0.10.2': - resolution: {integrity: sha512-8a2SExRohRbwC0MY4VpOF0/RSckrJ2ASZqAor5/RYSJJaeadR93n10gZzcKT6pY9ukiSOIZCRKVRD2tH73T0qA==} + '@yuku-core/binding-win32-x64@0.19.0': + resolution: {integrity: sha512-o8iY/mXwlRkedp0LNTr4+TEfXTPQwoNZmv6k+1WIAd1ZXEn8xJJTBCtB0osaVvdZo/x/cNmV16UrWrrGpM5Mvw==} cpu: [x64] os: [win32] - deprecated: yuku-codegen is pure JavaScript since 0.14 - '@yuku-parser/binding-android-arm64@0.10.2': - resolution: {integrity: sha512-2VPBU9fRGRAQ2xPAvghnec3oou5Nrxm2Bezhf+13UMspAxQSkF/32r+ySKXSwIPA5/RivumDJDxAxc301Sgicw==} - cpu: [arm64] - os: [android] - deprecated: yuku-parser runs on yuku-core since 0.14 - - '@yuku-parser/binding-darwin-arm64@0.10.2': - resolution: {integrity: sha512-LD+PMZE51tCYTOss5HBkm3/AE39MvcMDBfWJx7A4yDcjfNbAQDnHZKtzSOuqrswx+TQHY0ws5xn6+fWOwtmfBA==} - cpu: [arm64] - os: [darwin] - deprecated: yuku-parser runs on yuku-core since 0.14 - - '@yuku-parser/binding-darwin-x64@0.10.2': - resolution: {integrity: sha512-mmZ8cND+AoIIMRERyMinlg5ApHxP23B9jH2B5wT7T+dliPa9rubLxneB/SUjFwyUjGaFnB5G7t4YvpfbO5zbkQ==} - cpu: [x64] - os: [darwin] - deprecated: yuku-parser runs on yuku-core since 0.14 - - '@yuku-parser/binding-freebsd-x64@0.10.2': - resolution: {integrity: sha512-gVIjaaIddbRfAhHlC8N809wQWml7mxfSVnzaLtzGXObTeFTPAg/YVnQXt1UOhPM1ah5eG/8Y0RUlNpB4GVe7eQ==} - cpu: [x64] - os: [freebsd] - deprecated: yuku-parser runs on yuku-core since 0.14 - - '@yuku-parser/binding-linux-arm-gnu@0.10.2': - resolution: {integrity: sha512-q/XPPQQAPdlw05aPj30ygBhekmQryGOwxVraBgApjKK8yY1kNQgqq6XCYLF1WHSee+lhxclrTO7W0/bt7dR1GA==} - cpu: [arm] - os: [linux] - libc: [glibc] - deprecated: yuku-parser runs on yuku-core since 0.14 - - '@yuku-parser/binding-linux-arm-musl@0.10.2': - resolution: {integrity: sha512-A+Cb0I1hFF4wilTQpWs79k1aNnj4B2tkrHx3zsuUNF9BtVY2zPZ4yeQEM/zjXrS/qJlNMZVK9NrWJjwdpnTrfg==} - cpu: [arm] - os: [linux] - libc: [musl] - deprecated: yuku-parser runs on yuku-core since 0.14 - - '@yuku-parser/binding-linux-arm64-gnu@0.10.2': - resolution: {integrity: sha512-aGNSzqIqqphFwAdIFwVvKIyXD1Iy3CxrEJVIZAT87Ecyi4vCmmDD2v2l9h+Gd3/wSy3JZlOI792LJbKAjyy9rQ==} - cpu: [arm64] - os: [linux] - libc: [glibc] - deprecated: yuku-parser runs on yuku-core since 0.14 - - '@yuku-parser/binding-linux-arm64-musl@0.10.2': - resolution: {integrity: sha512-Ddl1sF0rtuCXyHGSOV6dcmdx+ETv1iD+IVFqQuOjzkJZWclxJxdBWX6ZJMRtTiGqGUTbqLEKiTXxpR/Bvqk+2A==} - cpu: [arm64] - os: [linux] - libc: [musl] - deprecated: yuku-parser runs on yuku-core since 0.14 - - '@yuku-parser/binding-linux-x64-gnu@0.10.2': - resolution: {integrity: sha512-/nlcpR6IF5U+0m5L9wvAIXeQa2DT+BXuvqKDsTcOTlcc0B4dHNyqE5hTXsS4hAyimpy2ZK8A1zMNF5hTrjg2cg==} - cpu: [x64] - os: [linux] - libc: [glibc] - deprecated: yuku-parser runs on yuku-core since 0.14 - - '@yuku-parser/binding-linux-x64-musl@0.10.2': - resolution: {integrity: sha512-GX80dxTQD/M/OryyuxJcFzFENzry3cDFPvCFTyWogNWQH3fSHfMrNfpwpl1YzMos1eV9NygK5GSDG7VArQlb4w==} - cpu: [x64] - os: [linux] - libc: [musl] - deprecated: yuku-parser runs on yuku-core since 0.14 - - '@yuku-parser/binding-win32-arm64@0.10.2': - resolution: {integrity: sha512-agePQBV4VHewiGU0ACSjscZ/hJd283f9JfAF19Gf1rI5+wy5tTgx4GS36i0b3xim15AQ4RCpDRosEvhLZ4zAOw==} - cpu: [arm64] - os: [win32] - deprecated: yuku-parser runs on yuku-core since 0.14 - - '@yuku-parser/binding-win32-x64@0.10.2': - resolution: {integrity: sha512-s8//CMpgL5+y1lvDCdyh1rwGI5+ytDJywFJRe1vnhI7n0j+caxshNucurikYLLVeQ2SYFex6aPrzgQxkabBQRA==} - cpu: [x64] - os: [win32] - deprecated: yuku-parser runs on yuku-core since 0.14 - - '@yuku-toolchain/types@0.10.2': - resolution: {integrity: sha512-sSeo4SSSToiS+sSD+bwn/s94EEcaLJ7tG5LCp8gFYC1G5VzxzX7fqB6m9RU1yMD8KTpu6zdU/I1NlQf8hVBJ9Q==} + '@yuku-toolchain/types@0.19.0': + resolution: {integrity: sha512-tFkNbsP4WXX9UMUC5syJGdK9dPMLK0PPaIuXCcCYH75sZ8MrebfBZ2XvCILRTw8AgLivSSCfDa4R67iYBDa4Kg==} JSONStream@1.3.5: resolution: {integrity: sha512-E+iruNOY8VV9s4JEbe1aNEm6MiszPRr/UfcHMz0TQh1BXSxHK+ASV1R6W4HpjBhSeS+54PIsAMCBmwD06LLsqQ==} @@ -4219,8 +4129,8 @@ packages: peerDependencies: acorn: ^6.0.0 || ^7.0.0 || ^8.0.0 - acorn@8.18.0: - resolution: {integrity: sha512-lGq+9yr1/GuAWaVYIHRjvvySG5/4VfKIvC8EWxStPdcDh/Ka7FG3twP6v4d5BkravUilhIAsG4Qj83t02LWUPQ==} + acorn@8.19.0: + resolution: {integrity: sha512-oJlA3XiRm7Cyk6qFD2Jn8ak9B7jSy0qy00ADO3+8dpT0LSjFihQYv4C02LFCSYJV3Q37xYwwRy5m+IpIiUzqWw==} engines: {node: '>=0.4.0'} hasBin: true @@ -4443,8 +4353,8 @@ packages: bare-abort-controller: optional: true - bare-fs@4.8.2: - resolution: {integrity: sha512-+ZI68KHMUvosXfKbg/UOHK0tbCdRnegbvPEdEcZ3Nd6TetieQsJPRXBRXPdLyy8+3VSEbPXtsumTpEtt78xv9w==} + bare-fs@4.8.4: + resolution: {integrity: sha512-MPC2eyrpbk3A873sK4y6rk+Iv4o2enxTjHZ8zH3HO0mjrpm5XjnguY2XmfidIsDV6vnjpbMBKUAJpV0ISD2SsQ==} engines: {bare: '>=1.28.0'} peerDependencies: bare-buffer: '*' @@ -4469,14 +4379,14 @@ packages: bare-events: optional: true - bare-url@2.5.4: - resolution: {integrity: sha512-Gxa7UVWBr0/edU1b+TJhn/AZvMQUj9OGspvYsaTYQrAbZA4BOTZGL3LiZxvD+CeMlDH4juwD84+eTAp/bLYW5g==} + bare-url@2.5.5: + resolution: {integrity: sha512-iM9qJCruvpt2rPaLsrumVDru9pogI7PHziHIa9kTNRFt8C8HuSa+kI9kFezK+NvHEFnnz71rKGZ1EAilq/3V/Q==} base64-js@1.5.1: resolution: {integrity: sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==} - baseline-browser-mapping@2.11.27: - resolution: {integrity: sha512-ElY12DaROGuan+lMmZ8Cvo/ZUbXPe7Enc/9VU/b1T3Kp4dwytRcNdR8DoSJN5SNJT/CuvcCA0DHDVmMOCePdRQ==} + baseline-browser-mapping@2.11.28: + resolution: {integrity: sha512-br0LOmjJqr6Rt4AEkadbcNf67Zpo7EPwKsWbjnRrJIa1QYFHQBqM4C7F2WTbV8ahTEcg1Eo+Y0aWjjORInYFyA==} engines: {node: '>=6.0.0'} hasBin: true @@ -4623,8 +4533,8 @@ packages: resolution: {integrity: sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==} engines: {node: '>=6'} - caniuse-lite@1.0.30001814: - resolution: {integrity: sha512-/Uaf1lAzr59XcMpW0o96WoEfr+VXK2OX4U9AgFoiSHsVJ4HppnIFUjtYzsyDH2+tgANaQb2/oxYGwCPapN1FpA==} + caniuse-lite@1.0.30001815: + resolution: {integrity: sha512-uDybUEyfgbyJJ93J1vikTylBX31AkdVYeVPeffMQpf8XN7hSfr0oZOn4VFOIMNvtU5+rHvC5Udg2TgtJKHm23Q==} caseless@0.12.0: resolution: {integrity: sha512-4tYFyifaFfGacoiObjJegolkwSU4xQNGbVgUiNYVUxbQ2x2lUsFvY4hVgVzGiIe6WLOPqycWXA40l+PWsxthUw==} @@ -5090,8 +5000,8 @@ packages: engines: {node: '>=0.12.18'} hasBin: true - electron-to-chromium@1.5.444: - resolution: {integrity: sha512-5ss/uJfoDYDHT0lfJzT6FbcskIzROIOPf0BbbFkGcvDzoJU7i//9GDrwwIHQVmIsrAGiF3ihpADBRIsrEFt1rQ==} + electron-to-chromium@1.5.452: + resolution: {integrity: sha512-cVvk1YBSj6571VmV6hdJTqj94Y79xSu8cj6Y9t6ae4Y4431z8/7EJFvu3rVp90xhfuv9BpPKUmaLfTo4+FOGBg==} emoji-regex@10.6.0: resolution: {integrity: sha512-toUI84YS5YmxW219erniWD0CIVOo46xGKColeNQRgOzDorgBi1v4D71/OFzgD9GO2UGKIv1C3Sp8DAn0+j5w7A==} @@ -6287,8 +6197,8 @@ packages: resolution: {integrity: sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==} engines: {node: '>=0.10.0'} - launch-editor@2.14.1: - resolution: {integrity: sha512-QWBrQsMpH7gPr965dsKD/3cKWiNoTjpATQf++Xq63N6sKRGMwlVXz41O1IZTMfZQgBctD/K5Zt06+/I6pP6+HA==} + launch-editor@2.14.2: + resolution: {integrity: sha512-NHJEb30MGBCkmZXLZwz25t37QR4aY03ZzPYUJXOJaOa92uWwExI9SBQUuIznBYc1xkD7cJNGX7oc3Nl3sq2kQQ==} less-loader@13.0.0: resolution: {integrity: sha512-TIa8d6znKH634Mg+7OU3jevZT6KeOhh0amW+YeMPD0GM9buUn5Y7HvtyCR5pUDdLaFfqLA8AX5PTSIHMNSexEA==} @@ -6734,8 +6644,8 @@ packages: resolution: {integrity: sha512-dkEJPVvun4FryqBmZ5KhDo0K9iDXAwn08tMLDinNdRBNPcYEDiWYysLcc6k3mjTMlbP9KyylvRpd4wFtwrT9rw==} engines: {node: ^20.17.0 || >=22.9.0} - nanoid@3.3.19: - resolution: {integrity: sha512-Y2tUNy4ouw6tq5oDSKeQYGOyhkUBhNOcGV/02KC+6kd9eDGqdZd++mjMiIDilrBYvjEnCYvVtsuHCuP+okSfug==} + nanoid@3.3.20: + resolution: {integrity: sha512-uKdg2G3GNCKQn9byYOpxbGqrT2fGO5KRt5J/8b3pok8rT6qxGWF6hxMyJiEYtAf+FVyYuD9hRaDqX5uPFYJ4ZQ==} engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} hasBin: true @@ -6820,8 +6730,8 @@ packages: resolution: {integrity: sha512-LA4ZjwlnUblHVgq0oBF3Jl/6h/Nvs5fzBLwdEF4nuxnFdsfajde4WfxtJr3CaiH+F6ewcIB/q4jQ4UzPyid+CQ==} hasBin: true - node-releases@2.0.57: - resolution: {integrity: sha512-kQK9LGGFiHtrWiNhZtA7Qbw17AQz+dmsEKODRIVTXA9+e5MS/2gZEBhYJt13GrAz5/IOZKddH/0Z3TP/Zgo+yw==} + node-releases@2.0.58: + resolution: {integrity: sha512-BdiKAgbfRlvfMq/XzO/AF9NPmaA8a+YpLAyAFTVFBj3gARrAIfWvNq7Q7NE4se3KgFu0KkrvQMxTS0XVnsGzHg==} engines: {node: '>=18'} normalize-path@3.0.0: @@ -7152,8 +7062,8 @@ packages: resolution: {integrity: sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==} engines: {node: '>= 0.8.0'} - prettier@3.9.9: - resolution: {integrity: sha512-Z/CJHIkdujO/OtN7nXUii0Rf3VT5SRuhjBA82Xvu2XhBUgX3nhP67T0LHceBdQLex7OOFGTox+Q5Yg8Jk2Qivg==} + prettier@3.9.10: + resolution: {integrity: sha512-skGHTH1Yb9QvaTC4hWnRTzEYtCpApF0UMBPz+t/0ZPzP8ihefo/btKd+QA7pUE0fEwA1SbS/NmhyEcstdXOIdA==} engines: {node: '>=14'} hasBin: true @@ -7170,8 +7080,8 @@ packages: process-warning@1.0.0: resolution: {integrity: sha512-du4wfLyj4yCZq1VupnVSZmRsPJsNuxoDQFdCFHLaYiEbFBD7QE0a+I4D7hOxrVnh78QE/YipFAj9lXHiXocV+Q==} - process-warning@5.1.0: - resolution: {integrity: sha512-jQSaVHsPgtyw60e1rQ/A+/ArPEj/S8pS/vFnyGa/gYFXrKk/6RuDkoqVDQ5NI5MmS01698ltlAk0NoDBNLujRw==} + process-warning@5.1.1: + resolution: {integrity: sha512-oCkNVj4OKnKEcocVBcDfiIugN1/cE6rgfT3nCtzeqZPA8+rIxMaQ0xXzIkGP8Gj2qUaP1UR7uhJ1VD8lUCpzCg==} process@0.11.10: resolution: {integrity: sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A==} @@ -7291,8 +7201,8 @@ packages: resolution: {integrity: sha512-yjavECdqeZ3GLXNgRXgeQEdz9fvDDkNKyHnbHRFtOr7/LcfgBcmct7t/ET+HaCTqfh06OzoAxrkN/IfjJBVe+g==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} - readable-stream@4.7.0: - resolution: {integrity: sha512-oIGGmcpTLwPga8Bn6/Z75SVaH1z5dUut2ibSyAMVhmUggWpmDn2dapB0n7f8nwaSiRtepAsfJyfXIO5DCVAODg==} + readable-stream@4.8.0: + resolution: {integrity: sha512-2jhTTU3Eilp/2DMT71gbcoqC35eQHasMJH0RHkYxwlxIv3+FR6Y5xAFZIwEGLxKkjZYEFlsiMNIdwUqjK2lLHQ==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} readdirp@3.6.0: @@ -7328,15 +7238,15 @@ packages: resolution: {integrity: sha512-dYqgNSZbDwkaJ2ceRd9ojCGjBq+mOm9LmtXnAnEGyHhN/5R7iDW2TRw3h+o/jCFxus3P2LfWIIiwowAjANm7IA==} engines: {node: '>= 0.4'} - regexpu-core@6.5.2: - resolution: {integrity: sha512-zkmVH92DlzjSFc4xKGZp/2BXIFrDIdBQBC8gUXKCsMgKYb1bkCkxfSuoW1werDjaTEMTbULkHtKFHe1L+Abnaw==} + regexpu-core@6.5.3: + resolution: {integrity: sha512-E8VgUoSK+LMQrLboDxavm76MTBGrQhx9RiNuomRmYnZ10Uw12HrI8fkxOOncktb2hBpzIZ9SV/347euQHG5z+g==} engines: {node: '>=4'} regjsgen@0.8.0: resolution: {integrity: sha512-RvwtGe3d7LvWiDQXeQw8p5asZUmfU1G/l6WbUXeHta7Y2PEIvBTwH6E2EfmYUK8pxcxEdEmaomqyp0vZZ7C+3Q==} - regjsparser@0.13.3: - resolution: {integrity: sha512-ycwFAS14Jw4mppvmK4GR/J6u3WpWpjkEApehuHtLc/8VpPNpDMbQ4WjqwplXifGeyKOzHSFLmSPqzksDQE2Sfg==} + regjsparser@0.13.4: + resolution: {integrity: sha512-EWV80YgFaVgFrjGCAsV7oybp4GOxbls5RzBg8OB0nKEVXsBJR1JlV8Di1JhCROg3MzTfe1RI8yitIm1eOs68iA==} hasBin: true require-directory@2.1.1: @@ -7364,8 +7274,8 @@ packages: resolution: {integrity: sha512-uZtduh8/8srhBoMx//5bwqjQ+rfYOUq8zC9NrMUGtjBiGTtFJM42s58/36+hTqeqINcnYe08Nj3LkK9lW4N8Xg==} engines: {node: '>=12'} - resolve@1.22.12: - resolution: {integrity: sha512-TyeJ1zif53BPfHootBGwPRYT1RUt6oGWsaQr8UyZW/eAm9bKoijtvruSDEmZHm92CwS9nj7/fWttqPCgzep8CA==} + resolve@1.22.13: + resolution: {integrity: sha512-Dj/cW9zBV2aRj6XzCxuGIs3ESZKv02jixne3q6jFZYZ3/Tg09gHHviSMDL4kObh9pqSahdRHEnDoaP2gn8YLhA==} engines: {node: '>= 0.4'} hasBin: true @@ -7413,8 +7323,8 @@ packages: resolution: {integrity: sha512-l0OE8wL34P4nJH/H2ffoaniAokM2qSmrtXHmlpvYr5AVVX8msAyW0l8NVJFDxlSK4u3Uh/f41cQheDVdnYijwQ==} hasBin: true - rolldown-plugin-dts@0.28.6: - resolution: {integrity: sha512-qKrFtBfRfR2hP233m7Ic9zf3wv6MSYdZghWKMdEO6dRYZGlNfINJAa1P5ZVvyHh3mrcd7IJQvIY8L9vnm+v5rQ==} + rolldown-plugin-dts@0.28.8: + resolution: {integrity: sha512-FVhfqxorCWcc20BVT5eVRfRjzLLl6mgzjcMR4gSBf0K4oQMXT0qoHhhzfXy0L7y83fQy7Ug5ZDNk90xM3/LiCQ==} engines: {node: ^22.18.0 || ^24.11.0 || >=26.0.0} peerDependencies: '@typescript/native-preview': '*' @@ -8030,15 +7940,15 @@ packages: tldts-core@6.1.86: resolution: {integrity: sha512-Je6p7pkk+KMzMv2XXKmAE3McmolOQFdxkKw0R8EYNr7sELW46JqnNeTX8ybPiQgvg1ymCoF8LXs5fzFaZvJPTA==} - tldts-core@7.4.16: - resolution: {integrity: sha512-MDolfaSJtlSK5Y0A1xl3277ekubZwobpBjugknDizI9O5Rm60a1m8k4ICK+MRsCDzPygT81mp3BBf5RKDlFRfA==} + tldts-core@7.4.18: + resolution: {integrity: sha512-KI2PKvCmvQI/xD6ypPqkU0i7oxNXR/O58RLRaHR4svsgVUQ2JE/XC8BtMbG6PSehD27I8sZJRcC1ASnCy6lp3g==} tldts@6.1.86: resolution: {integrity: sha512-WMi/OQ2axVTf/ykqCQgXiIct+mSQDFdH2fkwhPwgEwvJ1kSzZRiinb0zF2Xb8u4+OqPChmyI6MEu4EezNJz+FQ==} hasBin: true - tldts@7.4.16: - resolution: {integrity: sha512-QwBER5KMR86IIjpIiO7H/Z3IMJPsZ1A6RKPAqzTTgOyUQUSt9FdnKcqhTaJmkY6HVrgouZHZR0ncK5QxvmnQeg==} + tldts@7.4.18: + resolution: {integrity: sha512-somxA8xKAUzlAxl0TX/jMSYIbRNFIVGnI96pVGJPeMc5BsHmfVXn6mOJT6U++ELnl04eGfzpfcEuZe8WiASkXg==} hasBin: true tmp@0.2.7: @@ -8242,8 +8152,8 @@ packages: resolution: {integrity: sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==} engines: {node: '>= 0.8'} - update-browserslist-db@1.3.3: - resolution: {integrity: sha512-pJ2sYawQS0R/WI928Gj5GlPhTGzbMelq0+4INtSYNDV9ErKJcX6xjGWkoG/VnB3dpUm00zALaqkrUD77pO5TDQ==} + update-browserslist-db@1.3.4: + resolution: {integrity: sha512-t8wonIOdQyOjtPd2VktlBu6QjTVTks6v8bSi7kd0r2Vll8TK1JYDZtRRdbmCHOAMphkZgrzK+L+vXK4pyZ8t4A==} hasBin: true peerDependencies: browserslist: '>= 4.21.0' @@ -8287,8 +8197,8 @@ packages: resolution: {integrity: sha512-chCJw1+72wBS4heJgL7a08ACNgZEDoQMz3oZo/4nF4mqanV6pny3xU6BwEru8cRQHOiBvmmvMVDfWNVB6HDJ+A==} engines: {node: '>=22'} - verdaccio-auth-memory@13.1.5: - resolution: {integrity: sha512-rfKDhm1DzZoFdHUjiSwpe8hlXkiKB4brtzagaZcBnZXyBEASwW6SK/mdr4yU4asMcf+Zc8MjUJYnjlI7ji1yaw==} + verdaccio-auth-memory@13.1.6: + resolution: {integrity: sha512-L9LNz1q/JW1I9mPLch+8LUGnma/amo4EpS/+hZA6ZJJRIN7G5QAOKU9hLLPV6WqxO/I8T0KPtwNhyav9Aopqtg==} engines: {node: '>=22'} verdaccio-htpasswd@13.1.3: @@ -8662,21 +8572,25 @@ packages: resolution: {integrity: sha512-xYqdZFUK/VYazNl/oCDYN+3WloWQwMfZxBoiNt6qNyk+xfOdi598muWE42rNZFp1kNOiqW936q5RhUdnpqElSg==} engines: {node: '>=18'} - yuku-ast@0.10.2: - resolution: {integrity: sha512-UnG9mA6giglCvSErft2/40TVFX750Sj1xgwddPLpG7J7rlr/P1wPADg9G2RK+d/1tNLtRVoLdMMOMVBB9561TQ==} + yuku-ast@0.19.0: + resolution: {integrity: sha512-PyCsiScaelhxBGzL8dyeJkLqvRZycoh78R31Vrt/WqYrm0hMFoKwIw/X7Dx5mBKLWAMlV9I9HEyBOHnj2gZVyw==} + engines: {node: '>=14.18.0'} + + yuku-codegen@0.19.0: + resolution: {integrity: sha512-uymAKHjDuaP4BEpkXC/BSLz4DUEF5oArZ5AuD3888nb2miChjWSgpPdojEJxm3pjpXkgUaCRJQyNAbnMN33wHg==} + engines: {node: '>=14.18.0'} - yuku-codegen@0.10.2: - resolution: {integrity: sha512-hentl2dtrF6cPjiAirtkfxfFZBA6Hdm61UqRJ7cA0qrlDNMk9PZGOjw5w1mx3E0hu/6pHcJF4dJW+D0SXHPZOA==} + yuku-core@0.19.0: + resolution: {integrity: sha512-kYK9e1XdfirNhkipzW0wmMcSWcVF/CWnuugodfVYRCUwvoBefweL9HzB96OiKEhsx78V5WbUxbJqlizMX869Qg==} + engines: {node: '>=14.18.0'} - yuku-parser@0.10.2: - resolution: {integrity: sha512-CgaU0/PPjCAIEZ3WQroosOxTY3eeKldAN3h+vk8pMNz4+jl1CZzBR4pW+K/rRPF112VooCL5FdjJoiMNjDrL2A==} + yuku-parser@0.19.0: + resolution: {integrity: sha512-XrBh9ZiQK5mJVRxZBAvD6LwRyAYrK3MFtH3+onyuxFL5hFD44EC3QOmIC1FjTj6H2MMwq46/NAI+NZxLZPZgxg==} + engines: {node: '>=14.18.0'} zod@3.25.76: resolution: {integrity: sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ==} - zod@4.6.5: - resolution: {integrity: sha512-v5l/aFXZQeai4awLbOpSoHecE9UiMrnfx75tEXLjNonXVARxQ5mOeipTjROUchszUNCqnE+hqAMujRsRHsut2Q==} - zod@4.6.6: resolution: {integrity: sha512-4UmzQUF5fxvfcYHlbjBmejU+w+hbDnWFx4aS8kBx7nPBHcO2SqPbpAG8snbdg+Xse4pRefR98hgjFgIMCI/UhA==} @@ -8761,7 +8675,7 @@ snapshots: '@standard-schema/spec': 1.1.0 rxjs: 7.8.2 tslib: 2.8.1 - zod: 4.6.5 + zod: 4.6.6 '@angular/localize@22.2.2(@angular/compiler-cli@22.2.2(@angular/compiler@22.2.2)(typescript@6.0.3))(@angular/compiler@22.2.2)': dependencies: @@ -8833,7 +8747,7 @@ snapshots: which: 7.0.0 yaml: 2.9.1 yargs: 18.2.0 - zod: 4.6.5 + zod: 4.6.6 transitivePeerDependencies: - '@modelcontextprotocol/sdk' - '@react-native-async-storage/async-storage' @@ -8906,10 +8820,10 @@ snapshots: '@babel/generator': 7.29.8 '@babel/helper-compilation-targets': 7.29.7 '@babel/helper-module-transforms': 7.29.7(@babel/core@7.29.7(supports-color@11.0.0))(supports-color@11.0.0) - '@babel/helpers': 7.29.7 + '@babel/helpers': 7.29.10 '@babel/parser': 7.29.9 '@babel/template': 7.29.7 - '@babel/traverse': 7.29.8(supports-color@11.0.0) + '@babel/traverse': 7.29.10(supports-color@11.0.0) '@babel/types': 7.29.8 '@jridgewell/remapping': 2.3.5 convert-source-map: 2.0.0 @@ -8924,11 +8838,11 @@ snapshots: dependencies: '@babel/code-frame': 8.0.6 '@babel/generator': 8.0.5 - '@babel/helper-compilation-targets': 8.0.6 - '@babel/helpers': 8.0.5 - '@babel/parser': 8.0.6 + '@babel/helper-compilation-targets': 8.0.7 + '@babel/helpers': 8.0.7 + '@babel/parser': 8.0.7 '@babel/template': 8.0.0 - '@babel/traverse': 8.0.6 + '@babel/traverse': 8.0.7 '@babel/types': 8.0.6 '@types/gensync': 1.0.5 convert-source-map: 2.0.0 @@ -8943,11 +8857,11 @@ snapshots: dependencies: '@babel/code-frame': 8.0.6 '@babel/generator': 8.0.5 - '@babel/helper-compilation-targets': 8.0.6 - '@babel/helpers': 8.0.5 - '@babel/parser': 8.0.6 + '@babel/helper-compilation-targets': 8.0.7 + '@babel/helpers': 8.0.7 + '@babel/parser': 8.0.7 '@babel/template': 8.0.0 - '@babel/traverse': 8.0.6 + '@babel/traverse': 8.0.7 '@babel/types': 8.0.6 '@types/gensync': 1.0.5 convert-source-map: 2.0.0 @@ -8968,7 +8882,7 @@ snapshots: '@babel/generator@8.0.5': dependencies: - '@babel/parser': 8.0.6 + '@babel/parser': 8.0.7 '@babel/types': 8.0.6 '@jridgewell/gen-mapping': 0.4.0-beta.0 '@jridgewell/trace-mapping': 0.3.31 @@ -8977,7 +8891,7 @@ snapshots: '@babel/generator@8.0.6': dependencies: - '@babel/parser': 8.0.6 + '@babel/parser': 8.0.7 '@babel/types': 8.0.6 '@jridgewell/gen-mapping': 0.4.0-beta.0 '@jridgewell/trace-mapping': 0.3.31 @@ -8996,15 +8910,15 @@ snapshots: lru-cache: 5.1.1 semver: 6.3.1 - '@babel/helper-compilation-targets@8.0.6': + '@babel/helper-compilation-targets@8.0.7': dependencies: '@babel/compat-data': 8.0.5 '@babel/helper-validator-option': 8.0.0 browserslist: 4.29.3 flru: 1.0.2 - verkit: 0.3.2 + verkit: 0.5.0 - '@babel/helper-create-class-features-plugin@8.0.6(@babel/core@8.0.5)': + '@babel/helper-create-class-features-plugin@8.0.7(@babel/core@8.0.5)': dependencies: '@babel/core': 8.0.5 '@babel/helper-annotate-as-pure': 8.0.0 @@ -9012,20 +8926,20 @@ snapshots: '@babel/helper-optimise-call-expression': 8.0.0 '@babel/helper-replace-supers': 8.0.1(@babel/core@8.0.5) '@babel/helper-skip-transparent-expression-wrappers': 8.0.0 - '@babel/traverse': 8.0.6 - verkit: 0.3.2 + '@babel/traverse': 8.0.7 + verkit: 0.5.0 - '@babel/helper-create-regexp-features-plugin@8.0.5(@babel/core@8.0.5)': + '@babel/helper-create-regexp-features-plugin@8.0.7(@babel/core@8.0.5)': dependencies: '@babel/core': 8.0.5 '@babel/helper-annotate-as-pure': 8.0.0 - regexpu-core: 6.5.2 - verkit: 0.3.2 + regexpu-core: 6.5.3 + verkit: 0.5.0 '@babel/helper-define-polyfill-provider@1.0.0(@babel/core@8.0.5)': dependencies: '@babel/core': 8.0.5 - '@babel/helper-compilation-targets': 8.0.6 + '@babel/helper-compilation-targets': 8.0.7 '@babel/helper-plugin-utils': 8.0.1(@babel/core@8.0.5) lodash.debounce: 4.0.8 @@ -9035,19 +8949,19 @@ snapshots: '@babel/helper-member-expression-to-functions@8.0.5': dependencies: - '@babel/traverse': 8.0.6 + '@babel/traverse': 8.0.7 '@babel/types': 8.0.6 '@babel/helper-module-imports@7.29.7(supports-color@11.0.0)': dependencies: - '@babel/traverse': 7.29.8(supports-color@11.0.0) + '@babel/traverse': 7.29.10(supports-color@11.0.0) '@babel/types': 7.29.8 transitivePeerDependencies: - supports-color '@babel/helper-module-imports@8.0.0': dependencies: - '@babel/traverse': 8.0.6 + '@babel/traverse': 8.0.7 '@babel/types': 8.0.6 '@babel/helper-module-transforms@7.29.7(@babel/core@7.29.7(supports-color@11.0.0))(supports-color@11.0.0)': @@ -9055,7 +8969,7 @@ snapshots: '@babel/core': 7.29.7(supports-color@11.0.0) '@babel/helper-module-imports': 7.29.7(supports-color@11.0.0) '@babel/helper-validator-identifier': 7.29.7 - '@babel/traverse': 7.29.8(supports-color@11.0.0) + '@babel/traverse': 7.29.10(supports-color@11.0.0) transitivePeerDependencies: - supports-color @@ -9064,7 +8978,7 @@ snapshots: '@babel/core': 8.0.5 '@babel/helper-module-imports': 8.0.0 '@babel/helper-validator-identifier': 8.0.6 - '@babel/traverse': 8.0.6 + '@babel/traverse': 8.0.7 '@babel/helper-optimise-call-expression@8.0.0': dependencies: @@ -9079,18 +8993,18 @@ snapshots: '@babel/core': 8.0.5 '@babel/helper-annotate-as-pure': 8.0.0 '@babel/helper-wrap-function': 8.0.0 - '@babel/traverse': 8.0.6 + '@babel/traverse': 8.0.7 '@babel/helper-replace-supers@8.0.1(@babel/core@8.0.5)': dependencies: '@babel/core': 8.0.5 '@babel/helper-member-expression-to-functions': 8.0.5 '@babel/helper-optimise-call-expression': 8.0.0 - '@babel/traverse': 8.0.6 + '@babel/traverse': 8.0.7 '@babel/helper-skip-transparent-expression-wrappers@8.0.0': dependencies: - '@babel/traverse': 8.0.6 + '@babel/traverse': 8.0.7 '@babel/types': 8.0.6 '@babel/helper-split-export-declaration@7.24.7': @@ -9112,15 +9026,15 @@ snapshots: '@babel/helper-wrap-function@8.0.0': dependencies: '@babel/template': 8.0.0 - '@babel/traverse': 8.0.6 + '@babel/traverse': 8.0.7 '@babel/types': 8.0.6 - '@babel/helpers@7.29.7': + '@babel/helpers@7.29.10': dependencies: '@babel/template': 7.29.7 '@babel/types': 7.29.8 - '@babel/helpers@8.0.5': + '@babel/helpers@8.0.7': dependencies: '@babel/template': 8.0.0 '@babel/types': 8.0.6 @@ -9129,7 +9043,7 @@ snapshots: dependencies: '@babel/types': 7.29.8 - '@babel/parser@8.0.6': + '@babel/parser@8.0.7': dependencies: '@babel/types': 8.0.6 @@ -9176,7 +9090,7 @@ snapshots: '@babel/core': 8.0.5 '@babel/helper-plugin-utils': 8.0.1(@babel/core@8.0.5) '@babel/helper-remap-async-to-generator': 8.0.1(@babel/core@8.0.5) - '@babel/traverse': 8.0.6 + '@babel/traverse': 8.0.7 '@babel/plugin-transform-async-to-generator@8.0.1(@babel/core@8.0.5)': dependencies: @@ -9190,7 +9104,7 @@ snapshots: '@babel/core': 8.0.5 '@babel/helper-plugin-utils': 8.0.1(@babel/core@8.0.5) - '@babel/plugin-transform-block-scoping@8.0.5(@babel/core@8.0.5)': + '@babel/plugin-transform-block-scoping@8.0.7(@babel/core@8.0.5)': dependencies: '@babel/core': 8.0.5 '@babel/helper-plugin-utils': 8.0.1(@babel/core@8.0.5) @@ -9198,24 +9112,24 @@ snapshots: '@babel/plugin-transform-class-properties@8.0.1(@babel/core@8.0.5)': dependencies: '@babel/core': 8.0.5 - '@babel/helper-create-class-features-plugin': 8.0.6(@babel/core@8.0.5) + '@babel/helper-create-class-features-plugin': 8.0.7(@babel/core@8.0.5) '@babel/helper-plugin-utils': 8.0.1(@babel/core@8.0.5) '@babel/plugin-transform-class-static-block@8.0.5(@babel/core@8.0.5)': dependencies: '@babel/core': 8.0.5 - '@babel/helper-create-class-features-plugin': 8.0.6(@babel/core@8.0.5) + '@babel/helper-create-class-features-plugin': 8.0.7(@babel/core@8.0.5) '@babel/helper-plugin-utils': 8.0.1(@babel/core@8.0.5) '@babel/plugin-transform-classes@8.0.5(@babel/core@8.0.5)': dependencies: '@babel/core': 8.0.5 '@babel/helper-annotate-as-pure': 8.0.0 - '@babel/helper-compilation-targets': 8.0.6 + '@babel/helper-compilation-targets': 8.0.7 '@babel/helper-globals': 8.0.6 '@babel/helper-plugin-utils': 8.0.1(@babel/core@8.0.5) '@babel/helper-replace-supers': 8.0.1(@babel/core@8.0.5) - '@babel/traverse': 8.0.6 + '@babel/traverse': 8.0.7 '@babel/plugin-transform-computed-properties@8.0.1(@babel/core@8.0.5)': dependencies: @@ -9230,7 +9144,7 @@ snapshots: '@babel/plugin-transform-dotall-regex@8.0.1(@babel/core@8.0.5)': dependencies: '@babel/core': 8.0.5 - '@babel/helper-create-regexp-features-plugin': 8.0.5(@babel/core@8.0.5) + '@babel/helper-create-regexp-features-plugin': 8.0.7(@babel/core@8.0.5) '@babel/helper-plugin-utils': 8.0.1(@babel/core@8.0.5) '@babel/plugin-transform-duplicate-keys@8.0.1(@babel/core@8.0.5)': @@ -9241,7 +9155,7 @@ snapshots: '@babel/plugin-transform-duplicate-named-capturing-groups-regex@8.0.1(@babel/core@8.0.5)': dependencies: '@babel/core': 8.0.5 - '@babel/helper-create-regexp-features-plugin': 8.0.5(@babel/core@8.0.5) + '@babel/helper-create-regexp-features-plugin': 8.0.7(@babel/core@8.0.5) '@babel/helper-plugin-utils': 8.0.1(@babel/core@8.0.5) '@babel/plugin-transform-dynamic-import@8.0.1(@babel/core@8.0.5)': @@ -9265,7 +9179,7 @@ snapshots: '@babel/core': 8.0.5 '@babel/helper-plugin-utils': 8.0.1(@babel/core@8.0.5) - '@babel/plugin-transform-for-of@8.0.1(@babel/core@8.0.5)': + '@babel/plugin-transform-for-of@8.0.7(@babel/core@8.0.5)': dependencies: '@babel/core': 8.0.5 '@babel/helper-plugin-utils': 8.0.1(@babel/core@8.0.5) @@ -9274,7 +9188,7 @@ snapshots: '@babel/plugin-transform-function-name@8.0.1(@babel/core@8.0.5)': dependencies: '@babel/core': 8.0.5 - '@babel/helper-compilation-targets': 8.0.6 + '@babel/helper-compilation-targets': 8.0.7 '@babel/helper-plugin-utils': 8.0.1(@babel/core@8.0.5) '@babel/plugin-transform-json-strings@8.0.1(@babel/core@8.0.5)': @@ -9325,7 +9239,7 @@ snapshots: '@babel/plugin-transform-named-capturing-groups-regex@8.0.1(@babel/core@8.0.5)': dependencies: '@babel/core': 8.0.5 - '@babel/helper-create-regexp-features-plugin': 8.0.5(@babel/core@8.0.5) + '@babel/helper-create-regexp-features-plugin': 8.0.7(@babel/core@8.0.5) '@babel/helper-plugin-utils': 8.0.1(@babel/core@8.0.5) '@babel/plugin-transform-new-target@8.0.1(@babel/core@8.0.5)': @@ -9346,7 +9260,7 @@ snapshots: '@babel/plugin-transform-object-rest-spread@8.0.1(@babel/core@8.0.5)': dependencies: '@babel/core': 8.0.5 - '@babel/helper-compilation-targets': 8.0.6 + '@babel/helper-compilation-targets': 8.0.7 '@babel/helper-plugin-utils': 8.0.1(@babel/core@8.0.5) '@babel/plugin-transform-destructuring': 8.0.5(@babel/core@8.0.5) '@babel/plugin-transform-parameters': 8.0.5(@babel/core@8.0.5) @@ -9376,14 +9290,14 @@ snapshots: '@babel/plugin-transform-private-methods@8.0.1(@babel/core@8.0.5)': dependencies: '@babel/core': 8.0.5 - '@babel/helper-create-class-features-plugin': 8.0.6(@babel/core@8.0.5) + '@babel/helper-create-class-features-plugin': 8.0.7(@babel/core@8.0.5) '@babel/helper-plugin-utils': 8.0.1(@babel/core@8.0.5) '@babel/plugin-transform-private-property-in-object@8.0.5(@babel/core@8.0.5)': dependencies: '@babel/core': 8.0.5 '@babel/helper-annotate-as-pure': 8.0.0 - '@babel/helper-create-class-features-plugin': 8.0.6(@babel/core@8.0.5) + '@babel/helper-create-class-features-plugin': 8.0.7(@babel/core@8.0.5) '@babel/helper-plugin-utils': 8.0.1(@babel/core@8.0.5) '@babel/plugin-transform-property-literals@8.0.1(@babel/core@8.0.5)': @@ -9399,7 +9313,7 @@ snapshots: '@babel/plugin-transform-regexp-modifiers@8.0.1(@babel/core@8.0.5)': dependencies: '@babel/core': 8.0.5 - '@babel/helper-create-regexp-features-plugin': 8.0.5(@babel/core@8.0.5) + '@babel/helper-create-regexp-features-plugin': 8.0.7(@babel/core@8.0.5) '@babel/helper-plugin-utils': 8.0.1(@babel/core@8.0.5) '@babel/plugin-transform-reserved-words@8.0.1(@babel/core@8.0.5)': @@ -9447,26 +9361,26 @@ snapshots: '@babel/plugin-transform-unicode-property-regex@8.0.1(@babel/core@8.0.5)': dependencies: '@babel/core': 8.0.5 - '@babel/helper-create-regexp-features-plugin': 8.0.5(@babel/core@8.0.5) + '@babel/helper-create-regexp-features-plugin': 8.0.7(@babel/core@8.0.5) '@babel/helper-plugin-utils': 8.0.1(@babel/core@8.0.5) '@babel/plugin-transform-unicode-regex@8.0.1(@babel/core@8.0.5)': dependencies: '@babel/core': 8.0.5 - '@babel/helper-create-regexp-features-plugin': 8.0.5(@babel/core@8.0.5) + '@babel/helper-create-regexp-features-plugin': 8.0.7(@babel/core@8.0.5) '@babel/helper-plugin-utils': 8.0.1(@babel/core@8.0.5) '@babel/plugin-transform-unicode-sets-regex@8.0.1(@babel/core@8.0.5)': dependencies: '@babel/core': 8.0.5 - '@babel/helper-create-regexp-features-plugin': 8.0.5(@babel/core@8.0.5) + '@babel/helper-create-regexp-features-plugin': 8.0.7(@babel/core@8.0.5) '@babel/helper-plugin-utils': 8.0.1(@babel/core@8.0.5) '@babel/preset-env@8.0.5(@babel/core@8.0.5)': dependencies: '@babel/compat-data': 8.0.5 '@babel/core': 8.0.5 - '@babel/helper-compilation-targets': 8.0.6 + '@babel/helper-compilation-targets': 8.0.7 '@babel/helper-plugin-utils': 8.0.1(@babel/core@8.0.5) '@babel/helper-validator-option': 8.0.0 '@babel/plugin-bugfix-firefox-class-in-computed-class-key': 8.0.1(@babel/core@8.0.5) @@ -9479,7 +9393,7 @@ snapshots: '@babel/plugin-transform-async-generator-functions': 8.0.1(@babel/core@8.0.5) '@babel/plugin-transform-async-to-generator': 8.0.1(@babel/core@8.0.5) '@babel/plugin-transform-block-scoped-functions': 8.0.1(@babel/core@8.0.5) - '@babel/plugin-transform-block-scoping': 8.0.5(@babel/core@8.0.5) + '@babel/plugin-transform-block-scoping': 8.0.7(@babel/core@8.0.5) '@babel/plugin-transform-class-properties': 8.0.1(@babel/core@8.0.5) '@babel/plugin-transform-class-static-block': 8.0.5(@babel/core@8.0.5) '@babel/plugin-transform-classes': 8.0.5(@babel/core@8.0.5) @@ -9492,7 +9406,7 @@ snapshots: '@babel/plugin-transform-explicit-resource-management': 8.0.5(@babel/core@8.0.5) '@babel/plugin-transform-exponentiation-operator': 8.0.1(@babel/core@8.0.5) '@babel/plugin-transform-export-namespace-from': 8.0.1(@babel/core@8.0.5) - '@babel/plugin-transform-for-of': 8.0.1(@babel/core@8.0.5) + '@babel/plugin-transform-for-of': 8.0.7(@babel/core@8.0.5) '@babel/plugin-transform-function-name': 8.0.1(@babel/core@8.0.5) '@babel/plugin-transform-json-strings': 8.0.1(@babel/core@8.0.5) '@babel/plugin-transform-literals': 8.0.1(@babel/core@8.0.5) @@ -9551,10 +9465,10 @@ snapshots: '@babel/template@8.0.0': dependencies: '@babel/code-frame': 8.0.6 - '@babel/parser': 8.0.6 + '@babel/parser': 8.0.7 '@babel/types': 8.0.6 - '@babel/traverse@7.29.8(supports-color@11.0.0)': + '@babel/traverse@7.29.10(supports-color@11.0.0)': dependencies: '@babel/code-frame': 7.29.7 '@babel/generator': 7.29.8 @@ -9566,15 +9480,15 @@ snapshots: transitivePeerDependencies: - supports-color - '@babel/traverse@8.0.6': + '@babel/traverse@8.0.7': dependencies: '@babel/code-frame': 8.0.6 '@babel/generator': 8.0.6 '@babel/helper-globals': 8.0.6 - '@babel/parser': 8.0.6 + '@babel/parser': 8.0.7 '@babel/template': 8.0.0 '@babel/types': 8.0.6 - obug: 2.2.1 + obug: 3.0.0 '@babel/types@7.29.8': dependencies: @@ -9594,7 +9508,7 @@ snapshots: '@bcoe/v8-coverage@1.0.2': {} - '@bramus/specificity@2.4.2': + '@bramus/specificity@2.4.3': dependencies: css-tree: 3.2.1 @@ -10157,8 +10071,8 @@ snapshots: '@google-cloud/promisify': 5.1.0 '@grpc/proto-loader': 0.7.15 '@opentelemetry/api': 1.9.1 - '@opentelemetry/context-async-hooks': 2.11.0(@opentelemetry/api@1.9.1) - '@opentelemetry/core': 2.11.0(@opentelemetry/api@1.9.1) + '@opentelemetry/context-async-hooks': 2.12.0(@opentelemetry/api@1.9.1) + '@opentelemetry/core': 2.12.0(@opentelemetry/api@1.9.1) '@opentelemetry/semantic-conventions': 1.43.0 '@types/big.js': 6.2.2 '@types/stack-trace': 0.0.33 @@ -10195,7 +10109,7 @@ snapshots: - supports-color - utf-8-validate - '@grpc/grpc-js@1.14.5': + '@grpc/grpc-js@1.14.6': dependencies: '@grpc/proto-loader': 0.8.1 '@js-sdsl/ordered-map': 4.4.2 @@ -10946,11 +10860,11 @@ snapshots: '@opentelemetry/api@1.9.1': {} - '@opentelemetry/context-async-hooks@2.11.0(@opentelemetry/api@1.9.1)': + '@opentelemetry/context-async-hooks@2.12.0(@opentelemetry/api@1.9.1)': dependencies: '@opentelemetry/api': 1.9.1 - '@opentelemetry/core@2.11.0(@opentelemetry/api@1.9.1)': + '@opentelemetry/core@2.12.0(@opentelemetry/api@1.9.1)': dependencies: '@opentelemetry/api': 1.9.1 '@opentelemetry/semantic-conventions': 1.43.0 @@ -11269,7 +11183,7 @@ snapshots: '@types/resolve': 1.20.2 deepmerge: 4.3.1 is-module: 1.0.0 - resolve: 1.22.12 + resolve: 1.22.13 optionalDependencies: rollup: 4.63.3 @@ -11382,7 +11296,7 @@ snapshots: '@stylistic/eslint-plugin@5.10.0(eslint@10.10.0(jiti@2.7.0)(supports-color@11.0.0))': dependencies: '@eslint-community/eslint-utils': 4.10.1(eslint@10.10.0(jiti@2.7.0)(supports-color@11.0.0)) - '@typescript-eslint/types': 8.71.0 + '@typescript-eslint/types': 8.71.2 eslint: 10.10.0(jiti@2.7.0)(supports-color@11.0.0) eslint-visitor-keys: 4.2.1 espree: 10.4.0 @@ -11541,7 +11455,7 @@ snapshots: - uglify-js - webpack-cli - '@types/lodash@4.17.25': {} + '@types/lodash@4.17.26': {} '@types/micromatch@2.3.35': dependencies: @@ -11682,7 +11596,7 @@ snapshots: '@typescript-eslint/types@8.70.0': {} - '@typescript-eslint/types@8.71.0': {} + '@typescript-eslint/types@8.71.2': {} '@typescript-eslint/typescript-estree@8.70.0(supports-color@11.0.0)(typescript@6.0.3)': dependencies: @@ -11746,7 +11660,7 @@ snapshots: process-warning: 1.0.0 semver: 7.8.5 - '@verdaccio/core@8.3.2': + '@verdaccio/core@8.3.3': dependencies: ajv: 8.20.0 http-errors: 2.0.1 @@ -12000,79 +11914,43 @@ snapshots: '@yarnpkg/lockfile@1.1.0': {} - '@yuku-codegen/binding-android-arm64@0.10.2': - optional: true - - '@yuku-codegen/binding-darwin-arm64@0.10.2': - optional: true - - '@yuku-codegen/binding-darwin-x64@0.10.2': + '@yuku-core/binding-android-arm64@0.19.0': optional: true - '@yuku-codegen/binding-freebsd-x64@0.10.2': + '@yuku-core/binding-darwin-arm64@0.19.0': optional: true - '@yuku-codegen/binding-linux-arm-gnu@0.10.2': + '@yuku-core/binding-darwin-x64@0.19.0': optional: true - '@yuku-codegen/binding-linux-arm-musl@0.10.2': + '@yuku-core/binding-freebsd-x64@0.19.0': optional: true - '@yuku-codegen/binding-linux-arm64-gnu@0.10.2': + '@yuku-core/binding-linux-arm-gnu@0.19.0': optional: true - '@yuku-codegen/binding-linux-arm64-musl@0.10.2': + '@yuku-core/binding-linux-arm-musl@0.19.0': optional: true - '@yuku-codegen/binding-linux-x64-gnu@0.10.2': + '@yuku-core/binding-linux-arm64-gnu@0.19.0': optional: true - '@yuku-codegen/binding-linux-x64-musl@0.10.2': + '@yuku-core/binding-linux-arm64-musl@0.19.0': optional: true - '@yuku-codegen/binding-win32-arm64@0.10.2': + '@yuku-core/binding-linux-x64-gnu@0.19.0': optional: true - '@yuku-codegen/binding-win32-x64@0.10.2': + '@yuku-core/binding-linux-x64-musl@0.19.0': optional: true - '@yuku-parser/binding-android-arm64@0.10.2': + '@yuku-core/binding-win32-arm64@0.19.0': optional: true - '@yuku-parser/binding-darwin-arm64@0.10.2': + '@yuku-core/binding-win32-x64@0.19.0': optional: true - '@yuku-parser/binding-darwin-x64@0.10.2': - optional: true - - '@yuku-parser/binding-freebsd-x64@0.10.2': - optional: true - - '@yuku-parser/binding-linux-arm-gnu@0.10.2': - optional: true - - '@yuku-parser/binding-linux-arm-musl@0.10.2': - optional: true - - '@yuku-parser/binding-linux-arm64-gnu@0.10.2': - optional: true - - '@yuku-parser/binding-linux-arm64-musl@0.10.2': - optional: true - - '@yuku-parser/binding-linux-x64-gnu@0.10.2': - optional: true - - '@yuku-parser/binding-linux-x64-musl@0.10.2': - optional: true - - '@yuku-parser/binding-win32-arm64@0.10.2': - optional: true - - '@yuku-parser/binding-win32-x64@0.10.2': - optional: true - - '@yuku-toolchain/types@0.10.2': {} + '@yuku-toolchain/types@0.19.0': {} JSONStream@1.3.5: dependencies: @@ -12093,11 +11971,11 @@ snapshots: mime-types: 3.0.2 negotiator: 1.1.0 - acorn-jsx@5.3.2(acorn@8.18.0): + acorn-jsx@5.3.2(acorn@8.19.0): dependencies: - acorn: 8.18.0 + acorn: 8.19.0 - acorn@8.18.0: {} + acorn@8.19.0: {} adjust-sourcemap-loader@4.0.0: dependencies: @@ -12263,7 +12141,7 @@ snapshots: autoprefixer@10.6.0(postcss@8.5.28): dependencies: browserslist: 4.29.3 - caniuse-lite: 1.0.30001814 + caniuse-lite: 1.0.30001815 fraction.js: 5.3.4 picocolors: 1.1.1 postcss: 8.5.28 @@ -12298,12 +12176,12 @@ snapshots: bare-events@2.9.2: {} - bare-fs@4.8.2: + bare-fs@4.8.4: dependencies: bare-events: 2.9.2 bare-path: 3.1.2 bare-stream: 2.13.4(bare-events@2.9.2) - bare-url: 2.5.4 + bare-url: 2.5.5 fast-fifo: 1.3.2 transitivePeerDependencies: - bare-abort-controller @@ -12321,13 +12199,13 @@ snapshots: transitivePeerDependencies: - react-native-b4a - bare-url@2.5.4: + bare-url@2.5.5: dependencies: bare-path: 3.1.2 base64-js@1.5.1: {} - baseline-browser-mapping@2.11.27: {} + baseline-browser-mapping@2.11.28: {} batch@0.6.1: {} @@ -12482,11 +12360,11 @@ snapshots: browserslist@4.29.3: dependencies: - baseline-browser-mapping: 2.11.27 - caniuse-lite: 1.0.30001814 - electron-to-chromium: 1.5.444 - node-releases: 2.0.57 - update-browserslist-db: 1.3.3(browserslist@4.29.3) + baseline-browser-mapping: 2.11.28 + caniuse-lite: 1.0.30001815 + electron-to-chromium: 1.5.452 + node-releases: 2.0.58 + update-browserslist-db: 1.3.4(browserslist@4.29.3) bs-recipes@1.3.4: {} @@ -12552,7 +12430,7 @@ snapshots: callsites@3.1.0: {} - caniuse-lite@1.0.30001814: {} + caniuse-lite@1.0.30001815: {} caseless@0.12.0: {} @@ -13011,7 +12889,7 @@ snapshots: ejs@7.0.1: {} - electron-to-chromium@1.5.444: {} + electron-to-chromium@1.5.452: {} emoji-regex@10.6.0: {} @@ -13328,14 +13206,14 @@ snapshots: espree@10.4.0: dependencies: - acorn: 8.18.0 - acorn-jsx: 5.3.2(acorn@8.18.0) + acorn: 8.19.0 + acorn-jsx: 5.3.2(acorn@8.19.0) eslint-visitor-keys: 4.2.1 espree@11.2.0: dependencies: - acorn: 8.18.0 - acorn-jsx: 5.3.2(acorn@8.18.0) + acorn: 8.19.0 + acorn-jsx: 5.3.2(acorn@8.19.0) eslint-visitor-keys: 5.0.1 esquery@1.7.0: @@ -13840,7 +13718,7 @@ snapshots: google-gax@5.0.8(supports-color@11.0.0): dependencies: - '@grpc/grpc-js': 1.14.5 + '@grpc/grpc-js': 1.14.6 '@grpc/proto-loader': 0.8.1 duplexify: 4.1.3 google-auth-library: 10.5.0(supports-color@11.0.0) @@ -13884,7 +13762,7 @@ snapshots: grpc-gcp@1.1.1: dependencies: - '@grpc/grpc-js': 1.14.5 + '@grpc/grpc-js': 1.14.6 protobufjs: 7.6.6 gtoken@8.0.0(supports-color@11.0.0): @@ -14398,7 +14276,7 @@ snapshots: dependencies: '@asamuzakjp/css-color': 6.0.7 '@asamuzakjp/dom-selector': 8.3.2 - '@bramus/specificity': 2.4.2 + '@bramus/specificity': 2.4.3 '@csstools/css-syntax-patches-for-csstree': 1.1.15(css-tree@3.2.1) '@exodus/bytes': 1.16.0(@noble/hashes@1.8.0) css-tree: 3.2.1 @@ -14557,7 +14435,7 @@ snapshots: kind-of@6.0.3: {} - launch-editor@2.14.1: + launch-editor@2.14.2: dependencies: picocolors: 1.1.1 shell-quote: 1.12.0 @@ -14935,7 +14813,7 @@ snapshots: mute-stream@3.0.0: {} - nanoid@3.3.19: {} + nanoid@3.3.20: {} natural-compare@1.4.0: {} @@ -14981,7 +14859,7 @@ snapshots: ora: 9.4.1 postcss: 8.5.28 rolldown: 1.2.8 - rolldown-plugin-dts: 0.28.6(rolldown@1.2.8)(typescript@6.0.3) + rolldown-plugin-dts: 0.28.8(rolldown@1.2.8)(typescript@6.0.3) rxjs: 7.8.2 sass: 1.104.1 sass-embedded: 1.104.1 @@ -15035,7 +14913,7 @@ snapshots: node-gyp-build@4.8.4: {} - node-releases@2.0.57: {} + node-releases@2.0.58: {} normalize-path@3.0.0: {} @@ -15292,7 +15170,7 @@ snapshots: pino-abstract-transport@1.2.0: dependencies: - readable-stream: 4.7.0 + readable-stream: 4.8.0 split2: 4.2.0 pino-abstract-transport@2.0.0: @@ -15308,7 +15186,7 @@ snapshots: on-exit-leak-free: 2.1.2 pino-abstract-transport: 2.0.0 pino-std-serializers: 7.1.0 - process-warning: 5.1.0 + process-warning: 5.1.1 quick-format-unescaped: 4.0.4 real-require: 0.2.0 safe-stable-stringify: 2.5.0 @@ -15388,7 +15266,7 @@ snapshots: postcss@8.5.28: dependencies: - nanoid: 3.3.19 + nanoid: 3.3.20 picocolors: 1.1.1 source-map-js: 1.2.2 @@ -15396,7 +15274,7 @@ snapshots: prelude-ls@1.2.1: {} - prettier@3.9.9: {} + prettier@3.9.10: {} probe-image-size@7.4.0(supports-color@11.0.0): dependencies: @@ -15413,7 +15291,7 @@ snapshots: process-warning@1.0.0: {} - process-warning@5.1.0: {} + process-warning@5.1.1: {} process@0.11.10: {} @@ -15576,7 +15454,7 @@ snapshots: process: 0.11.10 string_decoder: 1.3.0 - readable-stream@4.7.0: + readable-stream@4.8.0: dependencies: abort-controller: 3.0.0 buffer: 6.0.3 @@ -15622,18 +15500,18 @@ snapshots: gopd: 1.2.0 set-function-name: 2.0.2 - regexpu-core@6.5.2: + regexpu-core@6.5.3: dependencies: regenerate: 1.5.0 regenerate-unicode-properties: 10.3.0 regjsgen: 0.8.0 - regjsparser: 0.13.3 + regjsparser: 0.13.4 unicode-match-property-ecmascript: 2.0.0 unicode-match-property-value-ecmascript: 2.2.1 regjsgen@0.8.0: {} - regjsparser@0.13.3: + regjsparser@0.13.4: dependencies: jsesc: 3.1.0 @@ -15657,7 +15535,7 @@ snapshots: postcss: 8.5.28 source-map: 0.6.1 - resolve@1.22.12: + resolve@1.22.13: dependencies: es-errors: 1.3.0 is-core-module: 2.17.0 @@ -15712,15 +15590,15 @@ snapshots: dependencies: glob: 10.5.0 - rolldown-plugin-dts@0.28.6(rolldown@1.2.8)(typescript@6.0.3): + rolldown-plugin-dts@0.28.8(rolldown@1.2.8)(typescript@6.0.3): dependencies: dts-resolver: 3.0.0 get-tsconfig: 5.0.0-beta.6 obug: 3.0.0 rolldown: 1.2.8 - yuku-ast: 0.10.2 - yuku-codegen: 0.10.2 - yuku-parser: 0.10.2 + yuku-ast: 0.19.0 + yuku-codegen: 0.19.0 + yuku-parser: 0.19.0 optionalDependencies: typescript: 6.0.3 transitivePeerDependencies: @@ -16361,7 +16239,7 @@ snapshots: tar-stream@3.2.0: dependencies: b4a: 1.9.0 - bare-fs: 4.8.2 + bare-fs: 4.8.4 fast-fifo: 1.3.2 streamx: 2.28.1 transitivePeerDependencies: @@ -16372,7 +16250,7 @@ snapshots: tar-stream@3.2.1: dependencies: b4a: 1.9.0 - bare-fs: 4.8.2 + bare-fs: 4.8.4 fast-fifo: 1.3.2 streamx: 2.28.1 transitivePeerDependencies: @@ -16399,7 +16277,7 @@ snapshots: terser@5.51.2: dependencies: '@jridgewell/source-map': 0.3.11 - acorn: 8.18.0 + acorn: 8.19.0 commander: 2.20.3 source-map-support: 0.5.21 @@ -16445,15 +16323,15 @@ snapshots: tldts-core@6.1.86: {} - tldts-core@7.4.16: {} + tldts-core@7.4.18: {} tldts@6.1.86: dependencies: tldts-core: 6.1.86 - tldts@7.4.16: + tldts@7.4.18: dependencies: - tldts-core: 7.4.16 + tldts-core: 7.4.18 tmp@0.2.7: {} @@ -16471,7 +16349,7 @@ snapshots: tough-cookie@6.0.2: dependencies: - tldts: 7.4.16 + tldts: 7.4.18 tr46@0.0.3: {} @@ -16640,7 +16518,7 @@ snapshots: unpipe@1.0.0: {} - update-browserslist-db@1.3.3(browserslist@4.29.3): + update-browserslist-db@1.3.4(browserslist@4.29.3): dependencies: browserslist: 4.29.3 escalade: 3.2.0 @@ -16681,9 +16559,9 @@ snapshots: - encoding - supports-color - verdaccio-auth-memory@13.1.5(supports-color@11.0.0): + verdaccio-auth-memory@13.1.6(supports-color@11.0.0): dependencies: - '@verdaccio/core': 8.3.2 + '@verdaccio/core': 8.3.3 debug: 4.4.3(supports-color@11.0.0) transitivePeerDependencies: - supports-color @@ -16843,7 +16721,7 @@ snapshots: graceful-fs: 4.2.11 http-proxy-middleware: 4.2.0(supports-color@11.0.0) ipaddr.js: 2.5.0 - launch-editor: 2.14.1 + launch-editor: 2.14.2 open: 11.0.4 p-retry: 8.0.1 schema-utils: 4.5.0 @@ -17110,49 +16988,38 @@ snapshots: yoctocolors@2.2.0: {} - yuku-ast@0.10.2: + yuku-ast@0.19.0: dependencies: - '@yuku-toolchain/types': 0.10.2 + '@yuku-toolchain/types': 0.19.0 - yuku-codegen@0.10.2: + yuku-codegen@0.19.0: dependencies: - '@yuku-toolchain/types': 0.10.2 - optionalDependencies: - '@yuku-codegen/binding-android-arm64': 0.10.2 - '@yuku-codegen/binding-darwin-arm64': 0.10.2 - '@yuku-codegen/binding-darwin-x64': 0.10.2 - '@yuku-codegen/binding-freebsd-x64': 0.10.2 - '@yuku-codegen/binding-linux-arm-gnu': 0.10.2 - '@yuku-codegen/binding-linux-arm-musl': 0.10.2 - '@yuku-codegen/binding-linux-arm64-gnu': 0.10.2 - '@yuku-codegen/binding-linux-arm64-musl': 0.10.2 - '@yuku-codegen/binding-linux-x64-gnu': 0.10.2 - '@yuku-codegen/binding-linux-x64-musl': 0.10.2 - '@yuku-codegen/binding-win32-arm64': 0.10.2 - '@yuku-codegen/binding-win32-x64': 0.10.2 - - yuku-parser@0.10.2: - dependencies: - '@yuku-toolchain/types': 0.10.2 - yuku-ast: 0.10.2 + '@yuku-toolchain/types': 0.19.0 + + yuku-core@0.19.0: + dependencies: + '@yuku-toolchain/types': 0.19.0 optionalDependencies: - '@yuku-parser/binding-android-arm64': 0.10.2 - '@yuku-parser/binding-darwin-arm64': 0.10.2 - '@yuku-parser/binding-darwin-x64': 0.10.2 - '@yuku-parser/binding-freebsd-x64': 0.10.2 - '@yuku-parser/binding-linux-arm-gnu': 0.10.2 - '@yuku-parser/binding-linux-arm-musl': 0.10.2 - '@yuku-parser/binding-linux-arm64-gnu': 0.10.2 - '@yuku-parser/binding-linux-arm64-musl': 0.10.2 - '@yuku-parser/binding-linux-x64-gnu': 0.10.2 - '@yuku-parser/binding-linux-x64-musl': 0.10.2 - '@yuku-parser/binding-win32-arm64': 0.10.2 - '@yuku-parser/binding-win32-x64': 0.10.2 + '@yuku-core/binding-android-arm64': 0.19.0 + '@yuku-core/binding-darwin-arm64': 0.19.0 + '@yuku-core/binding-darwin-x64': 0.19.0 + '@yuku-core/binding-freebsd-x64': 0.19.0 + '@yuku-core/binding-linux-arm-gnu': 0.19.0 + '@yuku-core/binding-linux-arm-musl': 0.19.0 + '@yuku-core/binding-linux-arm64-gnu': 0.19.0 + '@yuku-core/binding-linux-arm64-musl': 0.19.0 + '@yuku-core/binding-linux-x64-gnu': 0.19.0 + '@yuku-core/binding-linux-x64-musl': 0.19.0 + '@yuku-core/binding-win32-arm64': 0.19.0 + '@yuku-core/binding-win32-x64': 0.19.0 + + yuku-parser@0.19.0: + dependencies: + '@yuku-toolchain/types': 0.19.0 + yuku-core: 0.19.0 zod@3.25.76: {} - zod@4.6.5: {} - zod@4.6.6: {} zone.js@0.16.3: {} From bd09b98fcaff4b76c7fd65999b51bfaa942d1858 Mon Sep 17 00:00:00 2001 From: Alan Agius <17563226+alan-agius4@users.noreply.github.com> Date: Tue, 13 Oct 2026 07:00:46 +0000 Subject: [PATCH 095/233] fix(@angular/ssr): preserve preload metadata for nested empty-path routes Previously, `handleRoute` yielded a parent route's metadata before appending `loadChildren` preloads or traversing child routes, while `traverseRoutesConfig` appended a trailing slash only to empty-path routes. Under a non-empty parent, the parent ('/pricing') and its empty-path child ('/pricing/') received distinct keys during `getRoutesFromAngularRouterConfig` deduplication (`seenRoutes`) and were only merged later by `RouteTree.insert`. However, when an empty-path route was nested under another empty-path route (such as at the root '/' or under '/es' -> '' -> ''), both the parent and child received the same key, causing `seenRoutes` to keep the outer route's metadata and drop the descendant's accumulated `preload` and redirect metadata. Update `handleRoute` to append `loadChildren` preloads upfront and allow the first matching empty-path child route to override its parent's metadata for the same path, and remove the redundant `addTrailingSlash` keying in `traverseRoutesConfig`. Closes #34320 (cherry picked from commit 0b9a52cc9516d28afa0d9ef0d07ec745967faf56) --- packages/angular/ssr/src/routes/ng-routes.ts | 96 ++++++++++++------- .../angular/ssr/test/routes/ng-routes_spec.ts | 91 ++++++++++++++++++ packages/angular/ssr/test/testing-utils.ts | 5 +- 3 files changed, 156 insertions(+), 36 deletions(-) diff --git a/packages/angular/ssr/src/routes/ng-routes.ts b/packages/angular/ssr/src/routes/ng-routes.ts index 915d7c2b9a47..816155c4df01 100644 --- a/packages/angular/ssr/src/routes/ng-routes.ts +++ b/packages/angular/ssr/src/routes/ng-routes.ts @@ -31,7 +31,7 @@ import { AngularAppManifest, getAngularAppManifest } from '../manifest'; import { AngularBootstrap, isNgModule } from '../utils/ng'; import { promiseWithAbort } from '../utils/promise'; import { VALID_REDIRECT_RESPONSE_CODES, isValidRedirectResponseCode } from '../utils/redirect'; -import { addTrailingSlash, joinUrlParts, stripLeadingSlash } from '../utils/url'; +import { joinUrlParts, stripLeadingSlash } from '../utils/url'; import { PrerenderFallback, RenderMode, @@ -170,12 +170,14 @@ async function* handleRoute(options: { } = options; const { redirectTo, loadChildren, loadComponent, children, ɵentryName } = route; - if (ɵentryName && loadComponent) { + if (ɵentryName && (loadComponent || loadChildren)) { appendPreloadToMetadata(ɵentryName, entryPointToBrowserMapping, metadata); } + const parentRoutes = new Map(); + if (metadata.renderMode === RenderMode.Prerender) { - yield* handleSSGRoute( + for await (const result of handleSSGRoute( serverConfigRouteTree, typeof redirectTo === 'string' ? redirectTo : undefined, parentRoute, @@ -183,7 +185,13 @@ async function* handleRoute(options: { parentInjector, invokeGetPrerenderParams, includePrerenderFallbackRoutes, - ); + )) { + if ('error' in result) { + yield result; + } else { + parentRoutes.set(result.route, result); + } + } } else if (redirectTo !== undefined) { if (metadata.status && !isValidRedirectResponseCode(metadata.status)) { yield { @@ -192,34 +200,23 @@ async function* handleRoute(options: { `Please use one of the following redirect response codes: ${[...VALID_REDIRECT_RESPONSE_CODES.values()].join(', ')}.`, }; } else if (typeof redirectTo === 'string') { - yield { + parentRoutes.set(metadata.route, { ...metadata, redirectTo: resolveRedirectTo(parentRoute, redirectTo), relativeRedirect: redirectTo[0] !== '/' ? true : undefined, - }; + }); } else { - yield metadata; + parentRoutes.set(metadata.route, metadata); } } else { - yield metadata; + parentRoutes.set(metadata.route, metadata); } - // Recursively process child routes - if (children?.length) { - yield* traverseRoutesConfig({ - ...options, - routes: children, - parentRoute: currentRoutePath, - parentPreloads: metadata.preload, - }); - } - - // Load and process lazy-loaded child routes - if (loadChildren) { - if (ɵentryName) { - appendPreloadToMetadata(ɵentryName, entryPointToBrowserMapping, metadata); - } + // Recursively process child and lazy-loaded routes + let childRoutes: Route[] | undefined = children; + let childInjector = parentInjector; + if (!childRoutes?.length && loadChildren) { const routeInjector = route.providers ? createEnvironmentInjector( route.providers, @@ -230,16 +227,48 @@ async function* handleRoute(options: { const loadedChildRoutes = await loadChildrenHelper(route, compiler, routeInjector); if (loadedChildRoutes) { - const { routes: childRoutes, injector = routeInjector } = loadedChildRoutes; - yield* traverseRoutesConfig({ - ...options, - routes: childRoutes, - parentInjector: injector, - parentRoute: currentRoutePath, - parentPreloads: metadata.preload, - }); + childRoutes = loadedChildRoutes.routes; + childInjector = loadedChildRoutes.injector ?? routeInjector; } } + + if (!childRoutes?.length) { + yield* parentRoutes.values(); + + return; + } + + const childResults: (RouteTreeNodeMetadata | { error: string })[] = []; + const overriddenParentRoutes = new Set(); + const traverseChildRoutes = traverseRoutesConfig({ + ...options, + routes: childRoutes, + parentInjector: childInjector, + parentRoute: currentRoutePath, + parentPreloads: metadata.preload, + }); + + for await (const result of traverseChildRoutes) { + if ('error' in result) { + childResults.push(result); + continue; + } + + // If a child route resolves to the exact same path as the parent (i.e., an empty-path child), + // let the first matching child override the parent's metadata so accumulated preloads and + // redirects from the activated descendant chain are preserved. + if (parentRoutes.has(result.route)) { + if (!overriddenParentRoutes.has(result.route)) { + overriddenParentRoutes.add(result.route); + parentRoutes.set(result.route, result); + } + } else { + childResults.push(result); + } + } + + yield* parentRoutes.values(); + yield* childResults; } catch (error) { yield { error: `Error in handleRoute for '${options.currentRoutePath}': ${(error as Error).message}`, @@ -344,10 +373,7 @@ async function* traverseRoutesConfig(options: { renderMode: RenderMode.Prerender, ...matchedMetaData, preload: parentPreloads, - // Match Angular router behavior - // ['one', 'two', ''] -> 'one/two/' - // ['one', 'two', 'three'] -> 'one/two/three' - route: path === '' ? addTrailingSlash(currentRoutePath) : currentRoutePath, + route: currentRoutePath, presentInClientRouter: undefined, }, currentRoutePath, diff --git a/packages/angular/ssr/test/routes/ng-routes_spec.ts b/packages/angular/ssr/test/routes/ng-routes_spec.ts index 1af823f8f2ba..93b8e446ccb4 100644 --- a/packages/angular/ssr/test/routes/ng-routes_spec.ts +++ b/packages/angular/ssr/test/routes/ng-routes_spec.ts @@ -1044,4 +1044,95 @@ describe('extractRoutesAndCreateRouteTree', () => { expect(isDiscoveringRoutes).toBeTrue(); }); + + it('should preserve preload metadata for routes under nested empty-path routes', async () => { + setAngularAppTestingManifest( + [ + { + path: '', + children: [ + { + path: '', + pathMatch: 'full', + loadChildren: () => [ + { + path: '', + loadComponent: () => DummyComponent, + ɵentryName: 'home-page', + } as Route, + ], + ɵentryName: 'home-routes', + } as Route, + { + path: '', + children: [ + { + path: 'pricing', + loadChildren: () => [ + { + path: '', + loadComponent: () => DummyComponent, + ɵentryName: 'pricing-page', + } as Route, + ], + ɵentryName: 'pricing-routes', + } as Route, + ], + }, + ], + }, + { + path: 'es', + children: [ + { + path: '', + pathMatch: 'full', + loadChildren: () => [ + { + path: '', + loadComponent: () => DummyComponent, + ɵentryName: 'home-page', + } as Route, + ], + ɵentryName: 'home-routes', + } as Route, + ], + }, + ], + [{ path: '**', renderMode: RenderMode.Prerender }], + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + { + 'home-routes': ['chunk-home-routes.js'], + 'home-page': ['chunk-home-page.js'], + 'pricing-routes': ['chunk-pricing-routes.js'], + 'pricing-page': ['chunk-pricing-page.js'], + }, + ); + + const { routeTree, errors } = await extractRoutesAndCreateRouteTree({ url }); + expect(errors).toHaveSize(0); + expect(routeTree.toObject()).toEqual([ + { + route: '/', + renderMode: RenderMode.Prerender, + preload: ['chunk-home-routes.js', 'chunk-home-page.js'], + }, + { + route: '/pricing', + renderMode: RenderMode.Prerender, + preload: ['chunk-pricing-routes.js', 'chunk-pricing-page.js'], + }, + { + route: '/es', + renderMode: RenderMode.Prerender, + preload: ['chunk-home-routes.js', 'chunk-home-page.js'], + }, + ]); + }); }); diff --git a/packages/angular/ssr/test/testing-utils.ts b/packages/angular/ssr/test/testing-utils.ts index 6f825507c7a3..dad622d2e802 100644 --- a/packages/angular/ssr/test/testing-utils.ts +++ b/packages/angular/ssr/test/testing-utils.ts @@ -17,7 +17,7 @@ import { bootstrapApplication } from '@angular/platform-browser'; import { RouterOutlet, Routes, provideRouter } from '@angular/router'; import { type CompactPlan, compileSheet, encodePlan } from 'beasties/compiler'; import { destroyAngularServerApp } from '../src/app'; -import { ServerAsset, setAngularAppManifest } from '../src/manifest'; +import { AngularAppManifest, ServerAsset, setAngularAppManifest } from '../src/manifest'; import { ServerRoute, provideServerRendering, withRoutes } from '../src/routes/route-config'; @Component({ @@ -44,6 +44,7 @@ class AppComponent {} * root component and all its children. * @param inlineCriticalCss - An optional record of stylesheet paths to CSS content to be compiled into critical CSS plans. * @param nonce - An optional Content Security Policy (CSP) nonce to be used for inlined critical CSS. + * @param entryPointToBrowserMapping - An optional mapping of entry-point names to their associated browser bundles. */ export function setAngularAppTestingManifest( routes: Routes, @@ -55,6 +56,7 @@ export function setAngularAppTestingManifest( extraProviders: Array = [], inlineCriticalCss?: Record, nonce?: string, + entryPointToBrowserMapping?: AngularAppManifest['entryPointToBrowserMapping'], ): void { destroyAngularServerApp(); @@ -70,6 +72,7 @@ export function setAngularAppTestingManifest( setAngularAppManifest({ criticalCssPlans, nonce, + entryPointToBrowserMapping, baseHref, locale, assets: { From 91bad469ec5ce7b2dfd07e394b482d2cef411407 Mon Sep 17 00:00:00 2001 From: Julien Venet Date: Tue, 13 Oct 2026 13:22:08 -0400 Subject: [PATCH 096/233] fix(@angular/build): sort discovered unit-test files for deterministic builds (cherry picked from commit 01afbf418cf6a7688f3f131988eeba3cdac2bde4) --- .../src/builders/unit-test/test-discovery.ts | 6 ++-- .../builders/unit-test/test-discovery_spec.ts | 34 ++++++++++++++++++- 2 files changed, 37 insertions(+), 3 deletions(-) diff --git a/packages/angular/build/src/builders/unit-test/test-discovery.ts b/packages/angular/build/src/builders/unit-test/test-discovery.ts index f2fc8c221646..2452675a9abf 100644 --- a/packages/angular/build/src/builders/unit-test/test-discovery.ts +++ b/packages/angular/build/src/builders/unit-test/test-discovery.ts @@ -74,8 +74,10 @@ export async function findTests( } } - // 3. Combine and de-duplicate results - return [...resolvedTestFiles]; + // 3. Combine, de-duplicate and sort the results. The glob crawls directories asynchronously and + // returns matches in a varying order; the order feeds the build entry points, so an unsorted list + // makes the output (chunk contents and names) differ between two builds of the same sources. + return [...resolvedTestFiles].sort(); } interface TestEntrypointsOptions { diff --git a/packages/angular/build/src/builders/unit-test/test-discovery_spec.ts b/packages/angular/build/src/builders/unit-test/test-discovery_spec.ts index 764924d9552b..91c33fd0120a 100644 --- a/packages/angular/build/src/builders/unit-test/test-discovery_spec.ts +++ b/packages/angular/build/src/builders/unit-test/test-discovery_spec.ts @@ -6,8 +6,40 @@ * found in the LICENSE file at https://angular.dev/license */ +import assert from 'node:assert'; +import { promises as fs } from 'node:fs'; +import { join } from 'node:path'; import { initializeHash } from '../../utils/hash'; -import { generateNameFromPath, getTestEntrypoints } from './test-discovery'; +import { toPosixPath } from '../../utils/path'; +import { findTests, generateNameFromPath, getTestEntrypoints } from './test-discovery'; + +describe('findTests', () => { + let projectSourceRoot: string; + + beforeEach(async () => { + const baseTmpDir = process.env['TEST_TMPDIR']; + assert(baseTmpDir, 'TEST_TMPDIR is not set'); + projectSourceRoot = await fs.mkdtemp(join(baseTmpDir, 'angular-find-tests-')); + }); + + afterEach(async () => { + await fs.rm(projectSourceRoot, { recursive: true, force: true }); + }); + + it('should return the test files sorted, regardless of the crawl order', async () => { + const files = ['z/z.spec.ts', 'a/b/c.spec.ts', 'm.spec.ts', 'a/a.spec.ts', 'b/x/y.spec.ts']; + for (const file of files) { + const path = join(projectSourceRoot, file); + await fs.mkdir(join(path, '..'), { recursive: true }); + await fs.writeFile(path, ''); + } + + const result = await findTests(['**/*.spec.ts'], [], projectSourceRoot, projectSourceRoot); + + const expected = files.map((file) => toPosixPath(join(projectSourceRoot, file))).sort(); + expect(result).toEqual(expected); + }); +}); describe('getTestEntrypoints', () => { beforeAll(async () => { From cf1f3b9d43177e15cf9a00973e6da3baeaf4b2dd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Adrian=20Turbi=C5=84ski?= Date: Tue, 13 Oct 2026 20:01:06 +0000 Subject: [PATCH 097/233] fix(@angular-devkit/schematics): avoid stack overflow when chaining many rules The chain rule nested one observable per rule, so subscribing to a chain of a few thousand rules exceeded the call stack and the result never settled. Each rule result is now awaited before the next rule runs. (cherry picked from commit b39a5fcdac288e317f3b00468c09173a1d306f98) --- .../angular_devkit/schematics/src/rules/base.ts | 10 +++++----- .../schematics/src/rules/base_spec.ts | 13 +++++++++++++ 2 files changed, 18 insertions(+), 5 deletions(-) diff --git a/packages/angular_devkit/schematics/src/rules/base.ts b/packages/angular_devkit/schematics/src/rules/base.ts index ec380f2aeb0d..1f5d3023c28e 100644 --- a/packages/angular_devkit/schematics/src/rules/base.ts +++ b/packages/angular_devkit/schematics/src/rules/base.ts @@ -6,7 +6,7 @@ * found in the LICENSE file at https://angular.dev/license */ -import { Observable, concat, map, mapTo, toArray } from 'rxjs'; +import { concat, lastValueFrom, map, mapTo, toArray } from 'rxjs'; import { FileOperator, Rule, Source } from '../engine/interface'; import { SchematicsException } from '../exception/exception'; import { FilterHostTree, HostTree } from '../tree/host-tree'; @@ -34,18 +34,18 @@ export function empty(): Source { */ export function chain(rules: Iterable | AsyncIterable): Rule { return async (initialTree, context) => { - let intermediateTree: Observable | undefined; + let intermediateTree = initialTree; if (Symbol.asyncIterator in rules) { for await (const rule of rules) { - intermediateTree = callRule(rule, intermediateTree ?? initialTree, context); + intermediateTree = await lastValueFrom(callRule(rule, intermediateTree, context)); } } else { for (const rule of rules) { - intermediateTree = callRule(rule, intermediateTree ?? initialTree, context); + intermediateTree = await lastValueFrom(callRule(rule, intermediateTree, context)); } } - return () => intermediateTree; + return intermediateTree; }; } diff --git a/packages/angular_devkit/schematics/src/rules/base_spec.ts b/packages/angular_devkit/schematics/src/rules/base_spec.ts index b3578ca8c00a..6eb299ef9890 100644 --- a/packages/angular_devkit/schematics/src/rules/base_spec.ts +++ b/packages/angular_devkit/schematics/src/rules/base_spec.ts @@ -140,6 +140,19 @@ describe('chain', () => { expect(rulesCalled[2]).toBe(tree2); expect(result).toBe(tree3); }); + + it('works with a large number of rules', async () => { + const tree0 = empty(); + let callCount = 0; + const rules: Rule[] = Array.from({ length: 20_000 }, () => () => { + callCount++; + }); + + const result = await lastValueFrom(callRule(chain(rules), tree0, context)); + + expect(result).toBe(tree0); + expect(callCount).toBe(20_000); + }); }); describe('apply', () => { From e84db4af70ca9be490b462e6d8112524dc8eb6d4 Mon Sep 17 00:00:00 2001 From: Alan Agius <17563226+alan-agius4@users.noreply.github.com> Date: Thu, 15 Oct 2026 12:26:33 +0000 Subject: [PATCH 098/233] fix(@angular/build): use module.registerHooks() for in-memory ESM loader Node.js 26 runtime-deprecates `module.register()` (`DEP0205`) in favor of synchronous `module.registerHooks()`. Update the server-rendering in-memory ESM loader hooks to make `load` synchronous using `readFileSync` and register the hooks directly via `registerHooks({ resolve, load })`. Closes #34358 (cherry picked from commit b640b32e148ab68f820b390b1d9f03ae9a809266) --- .../esm-in-memory-loader/loader-hooks.ts | 6 +- .../esm-in-memory-loader/loader-hooks_spec.ts | 69 +++++++++++++------ .../esm-in-memory-loader/register-hooks.ts | 7 +- 3 files changed, 56 insertions(+), 26 deletions(-) diff --git a/packages/angular/build/src/utils/server-rendering/esm-in-memory-loader/loader-hooks.ts b/packages/angular/build/src/utils/server-rendering/esm-in-memory-loader/loader-hooks.ts index 6f21bfbc739b..6ff4c8f8191c 100644 --- a/packages/angular/build/src/utils/server-rendering/esm-in-memory-loader/loader-hooks.ts +++ b/packages/angular/build/src/utils/server-rendering/esm-in-memory-loader/loader-hooks.ts @@ -8,7 +8,7 @@ import assert from 'node:assert'; import { randomUUID } from 'node:crypto'; -import { readFile } from 'node:fs/promises'; +import { readFileSync } from 'node:fs'; import { join } from 'node:path'; import { fileURLToPath, pathToFileURL } from 'node:url'; @@ -110,7 +110,7 @@ export function resolve( }); } -export async function load(url: string, context: { format?: string | null }, nextLoad: Function) { +export function load(url: string, context: { format?: string | null }, nextLoad: Function) { const { format } = context; // Load the file from memory if the URL is based in the virtual root @@ -137,7 +137,7 @@ export async function load(url: string, context: { format?: string | null }, nex } const filePath = fileURLToPath(url); - const fileBytes = await readFile(filePath); + const fileBytes = readFileSync(filePath); const source = Buffer.concat([NG_SERVER_MODE_INIT_BYTES, fileBytes]); return { diff --git a/packages/angular/build/src/utils/server-rendering/esm-in-memory-loader/loader-hooks_spec.ts b/packages/angular/build/src/utils/server-rendering/esm-in-memory-loader/loader-hooks_spec.ts index 2b7622145378..0b32c2248b10 100644 --- a/packages/angular/build/src/utils/server-rendering/esm-in-memory-loader/loader-hooks_spec.ts +++ b/packages/angular/build/src/utils/server-rendering/esm-in-memory-loader/loader-hooks_spec.ts @@ -6,6 +6,10 @@ * found in the LICENSE file at https://angular.dev/license */ +import assert from 'node:assert'; +import { mkdir, mkdtemp, rm, writeFile } from 'node:fs/promises'; +import { join } from 'node:path'; +import { pathToFileURL } from 'node:url'; import { initialize, load, resolve } from './loader-hooks'; import { createSharedServerFiles } from './utils'; @@ -124,12 +128,12 @@ describe('esm-in-memory-loader loader-hooks', () => { }); describe('load', () => { - it('should load in-memory file source from SharedArrayBuffer backed Uint8Array', async () => { + it('should load in-memory file source from SharedArrayBuffer backed Uint8Array', () => { const memoryUrl = new URL('./main.server.mjs', 'memory://').href; const rootResolve = resolve(memoryUrl, { parentURL: undefined }, () => {}); const nextLoad = jasmine.createSpy('nextLoad'); - const result = await load(rootResolve.url, { format: 'module' }, nextLoad); + const result = load(rootResolve.url, { format: 'module' }, nextLoad); expect(nextLoad).not.toHaveBeenCalled(); expect(result.format).toBe('module'); @@ -137,12 +141,12 @@ describe('esm-in-memory-loader loader-hooks', () => { expect(result.source).toBe('export const main = true;'); }); - it('should load in-memory file with multi-byte UTF-8 characters', async () => { + it('should load in-memory file with multi-byte UTF-8 characters', () => { const memoryUrl = new URL('./utf8.mjs', 'memory://').href; const rootResolve = resolve(memoryUrl, { parentURL: undefined }, () => {}); const nextLoad = jasmine.createSpy('nextLoad'); - const result = await load(rootResolve.url, { format: 'module' }, nextLoad); + const result = load(rootResolve.url, { format: 'module' }, nextLoad); expect(nextLoad).not.toHaveBeenCalled(); expect(result.format).toBe('module'); @@ -150,12 +154,12 @@ describe('esm-in-memory-loader loader-hooks', () => { expect(result.source).toBe('export const text = "🔥 UTF-8 🚀";'); }); - it('should load in-memory file with empty content', async () => { + it('should load in-memory file with empty content', () => { const memoryUrl = new URL('./empty.mjs', 'memory://').href; const rootResolve = resolve(memoryUrl, { parentURL: undefined }, () => {}); const nextLoad = jasmine.createSpy('nextLoad'); - const result = await load(rootResolve.url, { format: 'module' }, nextLoad); + const result = load(rootResolve.url, { format: 'module' }, nextLoad); expect(nextLoad).not.toHaveBeenCalled(); expect(result.format).toBe('module'); @@ -163,7 +167,7 @@ describe('esm-in-memory-loader loader-hooks', () => { expect(result.source).toBe(''); }); - it('should load in-memory file source with non-zero byteOffset in Uint8Array', async () => { + it('should load in-memory file source with non-zero byteOffset in Uint8Array', () => { const target = 'export const sliced = 42;'; const fullBuffer = Buffer.from(`__PADDING__${target}__MORE__`); const offset = Buffer.byteLength('__PADDING__', 'utf-8'); @@ -181,7 +185,7 @@ describe('esm-in-memory-loader loader-hooks', () => { const rootResolve = resolve(memoryUrl, { parentURL: undefined }, () => {}); const nextLoad = jasmine.createSpy('nextLoad'); - const result = await load(rootResolve.url, { format: 'module' }, nextLoad); + const result = load(rootResolve.url, { format: 'module' }, nextLoad); expect(nextLoad).not.toHaveBeenCalled(); expect(result.format).toBe('module'); @@ -189,7 +193,7 @@ describe('esm-in-memory-loader loader-hooks', () => { expect(result.source).toBe(target); }); - it('should load in-memory file source when outputFiles contain string values', async () => { + it('should load in-memory file source when outputFiles contain string values', () => { initialize({ workspaceRoot, outputFiles: { @@ -201,7 +205,7 @@ describe('esm-in-memory-loader loader-hooks', () => { const rootResolve = resolve(memoryUrl, { parentURL: undefined }, () => {}); const nextLoad = jasmine.createSpy('nextLoad'); - const result = await load(rootResolve.url, { format: 'module' }, nextLoad); + const result = load(rootResolve.url, { format: 'module' }, nextLoad); expect(nextLoad).not.toHaveBeenCalled(); expect(result.format).toBe('module'); @@ -209,21 +213,46 @@ describe('esm-in-memory-loader loader-hooks', () => { expect(result.source).toBe('export const fromString = 1;'); }); - it('should reject when in-memory file does not exist in outputFiles', async () => { + it('should throw when in-memory file does not exist in outputFiles', () => { const memoryUrl = new URL('./main.server.mjs', 'memory://').href; const rootResolve = resolve(memoryUrl, { parentURL: undefined }, () => {}); const nonExistentVirtualUrl = rootResolve.url.replace('main.server.mjs', 'missing.mjs'); const nextLoad = jasmine.createSpy('nextLoad'); - await expectAsync( - load(nonExistentVirtualUrl, { format: 'module' }, nextLoad), - ).toBeRejectedWithError(/Resolved in-memory ESM file should always exist/); + expect(() => load(nonExistentVirtualUrl, { format: 'module' }, nextLoad)).toThrowError( + /Resolved in-memory ESM file should always exist/, + ); expect(nextLoad).not.toHaveBeenCalled(); }); - it('should delegate to nextLoad for non-angular file URLs', async () => { - const nextLoad = jasmine.createSpy('nextLoad').and.resolveTo({ format: 'module' }); - const result = await load( + it('should prepend ngServerMode initialization for @angular/ file URLs', async () => { + const baseTmpDir = process.env['TEST_TMPDIR']; + assert(baseTmpDir, 'TEST_TMPDIR is not set'); + const tmpDir = await mkdtemp(join(baseTmpDir, 'loader-hooks-test-')); + + try { + const angularDir = join(tmpDir, '@angular/core'); + await mkdir(angularDir, { recursive: true }); + const filePath = join(angularDir, 'index.mjs'); + await writeFile(filePath, 'export const VERSION = "1.0.0";'); + + const nextLoad = jasmine.createSpy('nextLoad'); + const result = load(pathToFileURL(filePath).href, { format: 'module' }, nextLoad); + + expect(nextLoad).not.toHaveBeenCalled(); + expect(result.format).toBe('module'); + expect(result.shortCircuit).toBeTrue(); + expect(new TextDecoder().decode(result.source)).toBe( + 'var ngServerMode=true;export const VERSION = "1.0.0";', + ); + } finally { + await rm(tmpDir, { recursive: true, force: true }); + } + }); + + it('should delegate to nextLoad for non-angular file URLs', () => { + const nextLoad = jasmine.createSpy('nextLoad').and.returnValue({ format: 'module' }); + const result = load( 'file:///workspace/node_modules/rxjs/index.js', { format: 'module' }, nextLoad, @@ -235,9 +264,9 @@ describe('esm-in-memory-loader loader-hooks', () => { expect(result.format).toBe('module'); }); - it('should delegate to nextLoad for non-memory non-file URLs', async () => { - const nextLoad = jasmine.createSpy('nextLoad').and.resolveTo({ format: 'builtin' }); - const result = await load('node:fs', { format: 'builtin' }, nextLoad); + it('should delegate to nextLoad for non-memory non-file URLs', () => { + const nextLoad = jasmine.createSpy('nextLoad').and.returnValue({ format: 'builtin' }); + const result = load('node:fs', { format: 'builtin' }, nextLoad); expect(nextLoad).toHaveBeenCalledWith('node:fs'); expect(result.format).toBe('builtin'); diff --git a/packages/angular/build/src/utils/server-rendering/esm-in-memory-loader/register-hooks.ts b/packages/angular/build/src/utils/server-rendering/esm-in-memory-loader/register-hooks.ts index b23fe297bc19..56747e17bd03 100644 --- a/packages/angular/build/src/utils/server-rendering/esm-in-memory-loader/register-hooks.ts +++ b/packages/angular/build/src/utils/server-rendering/esm-in-memory-loader/register-hooks.ts @@ -6,8 +6,9 @@ * found in the LICENSE file at https://angular.dev/license */ -import { register } from 'node:module'; -import { pathToFileURL } from 'node:url'; +import { registerHooks } from 'node:module'; import { workerData } from 'node:worker_threads'; +import { initialize, load, resolve } from './loader-hooks'; -register('./loader-hooks.js', { parentURL: pathToFileURL(__filename), data: workerData }); +initialize(workerData); +registerHooks({ resolve, load }); From 116cb9324e55b4195f2e252403e0bc3bc87e1ce5 Mon Sep 17 00:00:00 2001 From: Angular Robot Date: Thu, 15 Oct 2026 13:02:55 +0000 Subject: [PATCH 099/233] 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 | 426 +++++++++--------- 11 files changed, 318 insertions(+), 318 deletions(-) diff --git a/.github/workflows/assistant-to-the-branch-manager.yml b/.github/workflows/assistant-to-the-branch-manager.yml index 8c6035d666dc..f50263aad6ab 100644 --- a/.github/workflows/assistant-to-the-branch-manager.yml +++ b/.github/workflows/assistant-to-the-branch-manager.yml @@ -18,6 +18,6 @@ jobs: - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: persist-credentials: false - - uses: angular/dev-infra/github-actions/branch-manager@28ae58d2ad683fb3991006c23a9829c08b65aaec # main + - uses: angular/dev-infra/github-actions/branch-manager@c09a8058c7eee99ed9cec6213ff967bad6d6b73c # main with: angular-robot-key: ${{ secrets.ANGULAR_ROBOT_PRIVATE_KEY }} diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 56dde16b608c..6397ee443590 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -21,9 +21,9 @@ jobs: runs-on: ubuntu-latest steps: - name: Initialize environment - uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@28ae58d2ad683fb3991006c23a9829c08b65aaec # main + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@c09a8058c7eee99ed9cec6213ff967bad6d6b73c # main - name: Setup Bazel - uses: angular/dev-infra/github-actions/bazel/setup@28ae58d2ad683fb3991006c23a9829c08b65aaec # main + uses: angular/dev-infra/github-actions/bazel/setup@c09a8058c7eee99ed9cec6213ff967bad6d6b73c # main - name: Install node modules run: pnpm install --frozen-lockfile - name: Generate JSON schema types @@ -44,11 +44,11 @@ jobs: runs-on: ubuntu-latest steps: - name: Initialize environment - uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@28ae58d2ad683fb3991006c23a9829c08b65aaec # main + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@c09a8058c7eee99ed9cec6213ff967bad6d6b73c # main - name: Setup Bazel - uses: angular/dev-infra/github-actions/bazel/setup@28ae58d2ad683fb3991006c23a9829c08b65aaec # main + uses: angular/dev-infra/github-actions/bazel/setup@c09a8058c7eee99ed9cec6213ff967bad6d6b73c # main - name: Setup Bazel RBE - uses: angular/dev-infra/github-actions/bazel/configure-remote@28ae58d2ad683fb3991006c23a9829c08b65aaec # main + uses: angular/dev-infra/github-actions/bazel/configure-remote@c09a8058c7eee99ed9cec6213ff967bad6d6b73c # main with: google_credential: ${{ secrets.RBE_TRUSTED_BUILDS_USER }} - name: Install node modules @@ -61,11 +61,11 @@ jobs: runs-on: ubuntu-latest steps: - name: Initialize environment - uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@28ae58d2ad683fb3991006c23a9829c08b65aaec # main + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@c09a8058c7eee99ed9cec6213ff967bad6d6b73c # main - name: Setup Bazel - uses: angular/dev-infra/github-actions/bazel/setup@28ae58d2ad683fb3991006c23a9829c08b65aaec # main + uses: angular/dev-infra/github-actions/bazel/setup@c09a8058c7eee99ed9cec6213ff967bad6d6b73c # main - name: Setup Bazel RBE - uses: angular/dev-infra/github-actions/bazel/configure-remote@28ae58d2ad683fb3991006c23a9829c08b65aaec # main + uses: angular/dev-infra/github-actions/bazel/configure-remote@c09a8058c7eee99ed9cec6213ff967bad6d6b73c # main with: google_credential: ${{ secrets.RBE_TRUSTED_BUILDS_USER }} - name: Install node modules @@ -84,13 +84,13 @@ jobs: runs-on: ubuntu-latest steps: - name: Initialize environment - uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@28ae58d2ad683fb3991006c23a9829c08b65aaec # main + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@c09a8058c7eee99ed9cec6213ff967bad6d6b73c # main - name: Install node modules run: pnpm install --frozen-lockfile - name: Setup Bazel - uses: angular/dev-infra/github-actions/bazel/setup@28ae58d2ad683fb3991006c23a9829c08b65aaec # main + uses: angular/dev-infra/github-actions/bazel/setup@c09a8058c7eee99ed9cec6213ff967bad6d6b73c # main - name: Setup Bazel RBE - uses: angular/dev-infra/github-actions/bazel/configure-remote@28ae58d2ad683fb3991006c23a9829c08b65aaec # main + uses: angular/dev-infra/github-actions/bazel/configure-remote@c09a8058c7eee99ed9cec6213ff967bad6d6b73c # main with: google_credential: ${{ secrets.RBE_TRUSTED_BUILDS_USER }} - name: Run CLI E2E tests @@ -100,11 +100,11 @@ jobs: runs-on: ubuntu-latest steps: - name: Initialize environment - uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@28ae58d2ad683fb3991006c23a9829c08b65aaec # main + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@c09a8058c7eee99ed9cec6213ff967bad6d6b73c # main - name: Setup Bazel - uses: angular/dev-infra/github-actions/bazel/setup@28ae58d2ad683fb3991006c23a9829c08b65aaec # main + uses: angular/dev-infra/github-actions/bazel/setup@c09a8058c7eee99ed9cec6213ff967bad6d6b73c # main - name: Setup Bazel RBE - uses: angular/dev-infra/github-actions/bazel/configure-remote@28ae58d2ad683fb3991006c23a9829c08b65aaec # main + uses: angular/dev-infra/github-actions/bazel/configure-remote@c09a8058c7eee99ed9cec6213ff967bad6d6b73c # main with: google_credential: ${{ secrets.RBE_TRUSTED_BUILDS_USER }} - name: Install node modules @@ -137,7 +137,7 @@ jobs: runs-on: windows-2025 steps: - name: Initialize environment - uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@28ae58d2ad683fb3991006c23a9829c08b65aaec # main + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@c09a8058c7eee99ed9cec6213ff967bad6d6b73c # main - name: Install node modules run: pnpm install --frozen-lockfile - name: Download built Windows E2E tests @@ -164,13 +164,13 @@ jobs: runs-on: ubuntu-latest steps: - name: Initialize environment - uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@28ae58d2ad683fb3991006c23a9829c08b65aaec # main + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@c09a8058c7eee99ed9cec6213ff967bad6d6b73c # main - name: Install node modules run: pnpm install --frozen-lockfile - name: Setup Bazel - uses: angular/dev-infra/github-actions/bazel/setup@28ae58d2ad683fb3991006c23a9829c08b65aaec # main + uses: angular/dev-infra/github-actions/bazel/setup@c09a8058c7eee99ed9cec6213ff967bad6d6b73c # main - name: Setup Bazel RBE - uses: angular/dev-infra/github-actions/bazel/configure-remote@28ae58d2ad683fb3991006c23a9829c08b65aaec # main + uses: angular/dev-infra/github-actions/bazel/configure-remote@c09a8058c7eee99ed9cec6213ff967bad6d6b73c # main with: google_credential: ${{ secrets.RBE_TRUSTED_BUILDS_USER }} - name: Run CLI E2E tests @@ -188,13 +188,13 @@ jobs: runs-on: ubuntu-latest steps: - name: Initialize environment - uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@28ae58d2ad683fb3991006c23a9829c08b65aaec # main + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@c09a8058c7eee99ed9cec6213ff967bad6d6b73c # main - name: Install node modules run: pnpm install --frozen-lockfile - name: Setup Bazel - uses: angular/dev-infra/github-actions/bazel/setup@28ae58d2ad683fb3991006c23a9829c08b65aaec # main + uses: angular/dev-infra/github-actions/bazel/setup@c09a8058c7eee99ed9cec6213ff967bad6d6b73c # main - name: Setup Bazel RBE - uses: angular/dev-infra/github-actions/bazel/configure-remote@28ae58d2ad683fb3991006c23a9829c08b65aaec # main + uses: angular/dev-infra/github-actions/bazel/configure-remote@c09a8058c7eee99ed9cec6213ff967bad6d6b73c # main with: google_credential: ${{ secrets.RBE_TRUSTED_BUILDS_USER }} - name: Run CLI E2E tests @@ -208,13 +208,13 @@ jobs: SAUCE_TUNNEL_IDENTIFIER: angular-cli-${{ github.workflow }}-${{ github.run_number }} steps: - name: Initialize environment - uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@28ae58d2ad683fb3991006c23a9829c08b65aaec # main + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@c09a8058c7eee99ed9cec6213ff967bad6d6b73c # main - name: Install node modules run: pnpm install --frozen-lockfile - name: Setup Bazel - uses: angular/dev-infra/github-actions/bazel/setup@28ae58d2ad683fb3991006c23a9829c08b65aaec # main + uses: angular/dev-infra/github-actions/bazel/setup@c09a8058c7eee99ed9cec6213ff967bad6d6b73c # main - name: Setup Bazel RBE - uses: angular/dev-infra/github-actions/bazel/configure-remote@28ae58d2ad683fb3991006c23a9829c08b65aaec # main + uses: angular/dev-infra/github-actions/bazel/configure-remote@c09a8058c7eee99ed9cec6213ff967bad6d6b73c # main with: google_credential: ${{ secrets.RBE_TRUSTED_BUILDS_USER }} - name: Start Sauce Connect @@ -245,11 +245,11 @@ jobs: CIRCLE_BRANCH: ${{ github.ref_name }} steps: - name: Initialize environment - uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@28ae58d2ad683fb3991006c23a9829c08b65aaec # main + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@c09a8058c7eee99ed9cec6213ff967bad6d6b73c # main - name: Install node modules run: pnpm install --frozen-lockfile - name: Setup Bazel - uses: angular/dev-infra/github-actions/bazel/setup@28ae58d2ad683fb3991006c23a9829c08b65aaec # main + uses: angular/dev-infra/github-actions/bazel/setup@c09a8058c7eee99ed9cec6213ff967bad6d6b73c # main - run: pnpm admin snapshots --verbose env: SNAPSHOT_BUILDS_GITHUB_TOKEN: ${{ secrets.SNAPSHOT_BUILDS_GITHUB_TOKEN }} diff --git a/.github/workflows/dev-infra.yml b/.github/workflows/dev-infra.yml index f508452e9456..b85b240f82dc 100644 --- a/.github/workflows/dev-infra.yml +++ b/.github/workflows/dev-infra.yml @@ -16,21 +16,21 @@ jobs: if: github.event_name == 'pull_request_target' runs-on: ubuntu-latest steps: - - uses: angular/dev-infra/github-actions/labeling/pull-request@28ae58d2ad683fb3991006c23a9829c08b65aaec # main + - uses: angular/dev-infra/github-actions/labeling/pull-request@c09a8058c7eee99ed9cec6213ff967bad6d6b73c # main with: angular-robot-key: ${{ secrets.ANGULAR_ROBOT_PRIVATE_KEY }} post_approval_changes: if: github.event_name == 'pull_request_target' runs-on: ubuntu-latest steps: - - uses: angular/dev-infra/github-actions/post-approval-changes@28ae58d2ad683fb3991006c23a9829c08b65aaec # main + - uses: angular/dev-infra/github-actions/post-approval-changes@c09a8058c7eee99ed9cec6213ff967bad6d6b73c # main with: angular-robot-key: ${{ secrets.ANGULAR_ROBOT_PRIVATE_KEY }} issue_labels: if: github.event_name == 'issues' runs-on: ubuntu-latest steps: - - uses: angular/dev-infra/github-actions/labeling/issue@28ae58d2ad683fb3991006c23a9829c08b65aaec # main + - uses: angular/dev-infra/github-actions/labeling/issue@c09a8058c7eee99ed9cec6213ff967bad6d6b73c # main with: angular-robot-key: ${{ secrets.ANGULAR_ROBOT_PRIVATE_KEY }} google-generative-ai-key: ${{ secrets.GOOGLE_GENERATIVE_AI_KEY }} diff --git a/.github/workflows/perf.yml b/.github/workflows/perf.yml index 1c275f2d1a0d..21a061c26de5 100644 --- a/.github/workflows/perf.yml +++ b/.github/workflows/perf.yml @@ -22,7 +22,7 @@ jobs: workflows: ${{ steps.workflows.outputs.workflows }} steps: - name: Initialize environment - uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@28ae58d2ad683fb3991006c23a9829c08b65aaec # main + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@c09a8058c7eee99ed9cec6213ff967bad6d6b73c # main - name: Install node modules run: pnpm install --frozen-lockfile - id: workflows @@ -40,9 +40,9 @@ jobs: workflow: ${{ fromJSON(needs.list.outputs.workflows) }} steps: - name: Initialize environment - uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@28ae58d2ad683fb3991006c23a9829c08b65aaec # main + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@c09a8058c7eee99ed9cec6213ff967bad6d6b73c # main - name: Setup Bazel - uses: angular/dev-infra/github-actions/bazel/setup@28ae58d2ad683fb3991006c23a9829c08b65aaec # main + uses: angular/dev-infra/github-actions/bazel/setup@c09a8058c7eee99ed9cec6213ff967bad6d6b73c # main - name: Install node modules run: pnpm install --frozen-lockfile # We utilize the google-github-actions/auth action to allow us to get an active credential using workflow diff --git a/.github/workflows/pr.yml b/.github/workflows/pr.yml index d9195bdf9f8c..f0eb6e091f47 100644 --- a/.github/workflows/pr.yml +++ b/.github/workflows/pr.yml @@ -34,9 +34,9 @@ jobs: runs-on: ubuntu-latest steps: - name: Initialize environment - uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@28ae58d2ad683fb3991006c23a9829c08b65aaec # main + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@c09a8058c7eee99ed9cec6213ff967bad6d6b73c # main - name: Setup Bazel - uses: angular/dev-infra/github-actions/bazel/setup@28ae58d2ad683fb3991006c23a9829c08b65aaec # main + uses: angular/dev-infra/github-actions/bazel/setup@c09a8058c7eee99ed9cec6213ff967bad6d6b73c # main - name: Setup ESLint Caching uses: actions/cache@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0 with: @@ -66,17 +66,17 @@ jobs: # it has been merged. run: pnpm ng-dev format changed --check ${{ github.event.pull_request.base.sha }} - name: Check Package Licenses - uses: angular/dev-infra/github-actions/linting/licenses@28ae58d2ad683fb3991006c23a9829c08b65aaec # main + uses: angular/dev-infra/github-actions/linting/licenses@c09a8058c7eee99ed9cec6213ff967bad6d6b73c # main build: runs-on: ubuntu-latest steps: - name: Initialize environment - uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@28ae58d2ad683fb3991006c23a9829c08b65aaec # main + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@c09a8058c7eee99ed9cec6213ff967bad6d6b73c # main - name: Setup Bazel - uses: angular/dev-infra/github-actions/bazel/setup@28ae58d2ad683fb3991006c23a9829c08b65aaec # main + uses: angular/dev-infra/github-actions/bazel/setup@c09a8058c7eee99ed9cec6213ff967bad6d6b73c # main - name: Setup Bazel RBE - uses: angular/dev-infra/github-actions/bazel/configure-remote@28ae58d2ad683fb3991006c23a9829c08b65aaec # main + uses: angular/dev-infra/github-actions/bazel/configure-remote@c09a8058c7eee99ed9cec6213ff967bad6d6b73c # main - name: Install node modules run: pnpm install --frozen-lockfile - name: Build release targets @@ -93,11 +93,11 @@ jobs: runs-on: ubuntu-latest steps: - name: Initialize environment - uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@28ae58d2ad683fb3991006c23a9829c08b65aaec # main + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@c09a8058c7eee99ed9cec6213ff967bad6d6b73c # main - name: Setup Bazel - uses: angular/dev-infra/github-actions/bazel/setup@28ae58d2ad683fb3991006c23a9829c08b65aaec # main + uses: angular/dev-infra/github-actions/bazel/setup@c09a8058c7eee99ed9cec6213ff967bad6d6b73c # main - name: Setup Bazel RBE - uses: angular/dev-infra/github-actions/bazel/configure-remote@28ae58d2ad683fb3991006c23a9829c08b65aaec # main + uses: angular/dev-infra/github-actions/bazel/configure-remote@c09a8058c7eee99ed9cec6213ff967bad6d6b73c # main - name: Install node modules run: pnpm install --frozen-lockfile - name: Run module and package tests @@ -114,13 +114,13 @@ jobs: runs-on: ubuntu-latest steps: - name: Initialize environment - uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@28ae58d2ad683fb3991006c23a9829c08b65aaec # main + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@c09a8058c7eee99ed9cec6213ff967bad6d6b73c # main - name: Install node modules run: pnpm install --frozen-lockfile - name: Setup Bazel - uses: angular/dev-infra/github-actions/bazel/setup@28ae58d2ad683fb3991006c23a9829c08b65aaec # main + uses: angular/dev-infra/github-actions/bazel/setup@c09a8058c7eee99ed9cec6213ff967bad6d6b73c # main - name: Setup Bazel RBE - uses: angular/dev-infra/github-actions/bazel/configure-remote@28ae58d2ad683fb3991006c23a9829c08b65aaec # main + uses: angular/dev-infra/github-actions/bazel/configure-remote@c09a8058c7eee99ed9cec6213ff967bad6d6b73c # main - name: Run CLI E2E tests run: pnpm bazel test --test_env=E2E_SHARD_TOTAL=6 --test_env=E2E_SHARD_INDEX=${{ matrix.shard }} --config=e2e //tests:e2e.${{ matrix.subset }}_node${{ matrix.node }} @@ -128,11 +128,11 @@ jobs: runs-on: ubuntu-latest steps: - name: Initialize environment - uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@28ae58d2ad683fb3991006c23a9829c08b65aaec # main + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@c09a8058c7eee99ed9cec6213ff967bad6d6b73c # main - name: Setup Bazel - uses: angular/dev-infra/github-actions/bazel/setup@28ae58d2ad683fb3991006c23a9829c08b65aaec # main + uses: angular/dev-infra/github-actions/bazel/setup@c09a8058c7eee99ed9cec6213ff967bad6d6b73c # main - name: Setup Bazel RBE - uses: angular/dev-infra/github-actions/bazel/configure-remote@28ae58d2ad683fb3991006c23a9829c08b65aaec # main + uses: angular/dev-infra/github-actions/bazel/configure-remote@c09a8058c7eee99ed9cec6213ff967bad6d6b73c # main - name: Install node modules run: pnpm install --frozen-lockfile - name: Build E2E tests for Windows on Linux @@ -156,7 +156,7 @@ jobs: runs-on: windows-2025 steps: - name: Initialize environment - uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@28ae58d2ad683fb3991006c23a9829c08b65aaec # main + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@c09a8058c7eee99ed9cec6213ff967bad6d6b73c # main - name: Install node modules run: pnpm install --frozen-lockfile - name: Download built Windows E2E tests @@ -183,13 +183,13 @@ jobs: runs-on: ubuntu-latest steps: - name: Initialize environment - uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@28ae58d2ad683fb3991006c23a9829c08b65aaec # main + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@c09a8058c7eee99ed9cec6213ff967bad6d6b73c # main - name: Install node modules run: pnpm install --frozen-lockfile - name: Setup Bazel - uses: angular/dev-infra/github-actions/bazel/setup@28ae58d2ad683fb3991006c23a9829c08b65aaec # main + uses: angular/dev-infra/github-actions/bazel/setup@c09a8058c7eee99ed9cec6213ff967bad6d6b73c # main - name: Setup Bazel RBE - uses: angular/dev-infra/github-actions/bazel/configure-remote@28ae58d2ad683fb3991006c23a9829c08b65aaec # main + uses: angular/dev-infra/github-actions/bazel/configure-remote@c09a8058c7eee99ed9cec6213ff967bad6d6b73c # main - name: Run CLI E2E tests run: pnpm bazel test --test_env=E2E_SHARD_TOTAL=3 --test_env=E2E_SHARD_INDEX=${{ matrix.shard }} --config=e2e //tests:e2e.${{ matrix.subset }}_node${{ matrix.node }} @@ -205,12 +205,12 @@ jobs: runs-on: ubuntu-latest steps: - name: Initialize environment - uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@28ae58d2ad683fb3991006c23a9829c08b65aaec # main + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@c09a8058c7eee99ed9cec6213ff967bad6d6b73c # main - name: Install node modules run: pnpm install --frozen-lockfile - name: Setup Bazel - uses: angular/dev-infra/github-actions/bazel/setup@28ae58d2ad683fb3991006c23a9829c08b65aaec # main + uses: angular/dev-infra/github-actions/bazel/setup@c09a8058c7eee99ed9cec6213ff967bad6d6b73c # main - name: Setup Bazel RBE - uses: angular/dev-infra/github-actions/bazel/configure-remote@28ae58d2ad683fb3991006c23a9829c08b65aaec # main + uses: angular/dev-infra/github-actions/bazel/configure-remote@c09a8058c7eee99ed9cec6213ff967bad6d6b73c # main - name: Run CLI E2E tests run: pnpm bazel test --test_env=E2E_SHARD_TOTAL=6 --test_env=E2E_SHARD_INDEX=${{ matrix.shard }} --config=e2e //tests:e2e.snapshots.${{ matrix.subset }}_node${{ matrix.node }} diff --git a/MODULE.bazel b/MODULE.bazel index 238a75c1749d..c4b88f654996 100644 --- a/MODULE.bazel +++ b/MODULE.bazel @@ -19,21 +19,21 @@ bazel_dep(name = "aspect_rules_jasmine", version = "2.0.4") bazel_dep(name = "rules_angular") git_override( module_name = "rules_angular", - commit = "b5869cff3db5d2217b8896d483e75af8a1d26712", + commit = "bfe6e98434982bad38c393f1bd472ec33f16cd32", remote = "https://github.com/angular/rules_angular.git", ) bazel_dep(name = "devinfra") git_override( module_name = "devinfra", - commit = "28ae58d2ad683fb3991006c23a9829c08b65aaec", + commit = "c09a8058c7eee99ed9cec6213ff967bad6d6b73c", remote = "https://github.com/angular/dev-infra.git", ) bazel_dep(name = "rules_browsers") git_override( module_name = "rules_browsers", - commit = "4b53d68eed02bbb0901b21fb02b8cf99f4f59a52", + commit = "48a956da3908e5c923f21e6ffd1c72c5605d61fe", remote = "https://github.com/angular/rules_browsers.git", ) diff --git a/MODULE.bazel.lock b/MODULE.bazel.lock index 1fdbca78a05d..79780e26566c 100644 --- a/MODULE.bazel.lock +++ b/MODULE.bazel.lock @@ -445,16 +445,16 @@ }, "@@rules_browsers+//browsers:extensions.bzl%browsers": { "general": { - "bzlTransitiveDigest": "/FonktAou7w4aKjGZUZDFFOlASeGnKNw0QALxUIdtuE=", + "bzlTransitiveDigest": "OZ8V6/fUTaz9GXcrxaCB7fqf29DyphGiugzTRl7yPR8=", "usagesDigest": "FmXYJVoVJlnfUU8x8gObSvu4qWcco/9Faw61aC/wBF0=", "recordedInputs": [], "generatedRepoSpecs": { "rules_browsers_chrome_linux": { "repoRuleId": "@@rules_browsers+//browsers/private:browser_repo.bzl%browser_repo", "attributes": { - "sha256": "9541eafbc02f85e3ec0c24b05f8bbffe88094389949860681bf6055aef668d7b", + "sha256": "e3f19706550899e76efdadb1ad172c3af2bb89c137a1350fe7f72333d2a4d0a4", "urls": [ - "https://storage.googleapis.com/chrome-for-testing-public/157.0.8099.0/linux64/chrome-headless-shell-linux64.zip" + "https://storage.googleapis.com/chrome-for-testing-public/158.0.8106.0/linux64/chrome-headless-shell-linux64.zip" ], "named_files": { "CHROME-HEADLESS-SHELL": "chrome-headless-shell-linux64/chrome-headless-shell" @@ -470,9 +470,9 @@ "rules_browsers_chrome_mac": { "repoRuleId": "@@rules_browsers+//browsers/private:browser_repo.bzl%browser_repo", "attributes": { - "sha256": "358f032d48a0b825b0601b89b970da5a7c245344ed7a557a3ef8613c342521b0", + "sha256": "1f98187b068d2c631d4465a437ce7c4d83f7bde9b6a0e19faae1c9de04eb4a4d", "urls": [ - "https://storage.googleapis.com/chrome-for-testing-public/157.0.8099.0/mac-x64/chrome-headless-shell-mac-x64.zip" + "https://storage.googleapis.com/chrome-for-testing-public/158.0.8106.0/mac-x64/chrome-headless-shell-mac-x64.zip" ], "named_files": { "CHROME-HEADLESS-SHELL": "chrome-headless-shell-mac-x64/chrome-headless-shell" @@ -488,9 +488,9 @@ "rules_browsers_chrome_mac_arm": { "repoRuleId": "@@rules_browsers+//browsers/private:browser_repo.bzl%browser_repo", "attributes": { - "sha256": "c3de600edda5e11aa40918f123781040cd6e9c2509a2acfc466b773bf7c9b326", + "sha256": "a564d6b8c498a1c8624e9e14f83ece2d9903db1ec2b491e9fa8fdc7805187dce", "urls": [ - "https://storage.googleapis.com/chrome-for-testing-public/157.0.8099.0/mac-arm64/chrome-headless-shell-mac-arm64.zip" + "https://storage.googleapis.com/chrome-for-testing-public/158.0.8106.0/mac-arm64/chrome-headless-shell-mac-arm64.zip" ], "named_files": { "CHROME-HEADLESS-SHELL": "chrome-headless-shell-mac-arm64/chrome-headless-shell" @@ -506,9 +506,9 @@ "rules_browsers_chrome_win64": { "repoRuleId": "@@rules_browsers+//browsers/private:browser_repo.bzl%browser_repo", "attributes": { - "sha256": "b2e81e06ac46d3355bc6428b3abe97308d34e810d4404427bbd14665111e67a1", + "sha256": "3a874f0d0d36a84a89c4fedf7e0dfdcad7e4818bbaf22842ac06762305256b87", "urls": [ - "https://storage.googleapis.com/chrome-for-testing-public/157.0.8099.0/win64/chrome-headless-shell-win64.zip" + "https://storage.googleapis.com/chrome-for-testing-public/158.0.8106.0/win64/chrome-headless-shell-win64.zip" ], "named_files": { "CHROME-HEADLESS-SHELL": "chrome-headless-shell-win64/chrome-headless-shell.exe" @@ -524,9 +524,9 @@ "rules_browsers_chromedriver_linux": { "repoRuleId": "@@rules_browsers+//browsers/private:browser_repo.bzl%browser_repo", "attributes": { - "sha256": "cf16fed1899de0f0b8999389779cefbb6696c5fd44ad9718ce2195a3ff5ca029", + "sha256": "51b3afc67a5765403601420074ad7091e083133ca8f82e878a49b783614256df", "urls": [ - "https://storage.googleapis.com/chrome-for-testing-public/157.0.8099.0/linux64/chromedriver-linux64.zip" + "https://storage.googleapis.com/chrome-for-testing-public/158.0.8106.0/linux64/chromedriver-linux64.zip" ], "named_files": { "CHROMEDRIVER": "chromedriver-linux64/chromedriver" @@ -540,9 +540,9 @@ "rules_browsers_chromedriver_mac": { "repoRuleId": "@@rules_browsers+//browsers/private:browser_repo.bzl%browser_repo", "attributes": { - "sha256": "ba472bdd32ee62a98f04fcca364015a0df241fdf85ee7d834a048b5fdfd90fd3", + "sha256": "944924ff8ba2ca15407e788f1d36918e4979f9f5329d0bdf8689c9a96c1818fc", "urls": [ - "https://storage.googleapis.com/chrome-for-testing-public/157.0.8099.0/mac-x64/chromedriver-mac-x64.zip" + "https://storage.googleapis.com/chrome-for-testing-public/158.0.8106.0/mac-x64/chromedriver-mac-x64.zip" ], "named_files": { "CHROMEDRIVER": "chromedriver-mac-x64/chromedriver" @@ -556,9 +556,9 @@ "rules_browsers_chromedriver_mac_arm": { "repoRuleId": "@@rules_browsers+//browsers/private:browser_repo.bzl%browser_repo", "attributes": { - "sha256": "8fe44ebac5303278a5d533c114ad0dbed0df9c218bce5b80d606078472ea95bd", + "sha256": "2b46fd5f3838e6a2ea73e29e67537c97f43a23eeddbf5522ac15cd27f05a4987", "urls": [ - "https://storage.googleapis.com/chrome-for-testing-public/157.0.8099.0/mac-arm64/chromedriver-mac-arm64.zip" + "https://storage.googleapis.com/chrome-for-testing-public/158.0.8106.0/mac-arm64/chromedriver-mac-arm64.zip" ], "named_files": { "CHROMEDRIVER": "chromedriver-mac-arm64/chromedriver" @@ -572,9 +572,9 @@ "rules_browsers_chromedriver_win64": { "repoRuleId": "@@rules_browsers+//browsers/private:browser_repo.bzl%browser_repo", "attributes": { - "sha256": "1fadd71af32db4e3497ce4faac3f07503f4c4cdad8747e71ff62c5c9c3dd05e1", + "sha256": "5c38e2e1d06b51e34885fb0474bf74a5bb36e4a6a517327df8d74f49d7cf9dd8", "urls": [ - "https://storage.googleapis.com/chrome-for-testing-public/157.0.8099.0/win64/chromedriver-win64.zip" + "https://storage.googleapis.com/chrome-for-testing-public/158.0.8106.0/win64/chromedriver-win64.zip" ], "named_files": { "CHROMEDRIVER": "chromedriver-win64/chromedriver.exe" @@ -588,9 +588,9 @@ "rules_browsers_firefox_linux": { "repoRuleId": "@@rules_browsers+//browsers/private:browser_repo.bzl%browser_repo", "attributes": { - "sha256": "42f2c62a562316982ef5a796738c57602bf84a984f5c616e80bcff4627f78fff", + "sha256": "9549b054ec4cf85f50f6a19d8c6fb79580312e71ebc4ec2cb217ec9af09dc12a", "urls": [ - "https://archive.mozilla.org/pub/firefox/releases/157.0/linux-x86_64/en-US/firefox-157.0.tar.xz" + "https://archive.mozilla.org/pub/firefox/releases/158.0/linux-x86_64/en-US/firefox-158.0.tar.xz" ], "named_files": { "FIREFOX": "firefox/firefox" @@ -604,9 +604,9 @@ "rules_browsers_firefox_mac": { "repoRuleId": "@@rules_browsers+//browsers/private:browser_repo.bzl%browser_repo", "attributes": { - "sha256": "df6d8c79b6126bcf24cb70ebab9371916a662028e2d706e462d432e78fdf396c", + "sha256": "dfe8508ee8880cec1578253eb02b9154b5971a55e832d97396f463cd07b5ef67", "urls": [ - "https://archive.mozilla.org/pub/firefox/releases/157.0/mac/en-US/Firefox%20157.0.dmg" + "https://archive.mozilla.org/pub/firefox/releases/158.0/mac/en-US/Firefox%20158.0.dmg" ], "named_files": { "FIREFOX": "Firefox.app/Contents/MacOS/firefox" @@ -620,9 +620,9 @@ "rules_browsers_firefox_mac_arm": { "repoRuleId": "@@rules_browsers+//browsers/private:browser_repo.bzl%browser_repo", "attributes": { - "sha256": "df6d8c79b6126bcf24cb70ebab9371916a662028e2d706e462d432e78fdf396c", + "sha256": "dfe8508ee8880cec1578253eb02b9154b5971a55e832d97396f463cd07b5ef67", "urls": [ - "https://archive.mozilla.org/pub/firefox/releases/157.0/mac/en-US/Firefox%20157.0.dmg" + "https://archive.mozilla.org/pub/firefox/releases/158.0/mac/en-US/Firefox%20158.0.dmg" ], "named_files": { "FIREFOX": "Firefox.app/Contents/MacOS/firefox" @@ -636,9 +636,9 @@ "rules_browsers_firefox_win64": { "repoRuleId": "@@rules_browsers+//browsers/private:browser_repo.bzl%browser_repo", "attributes": { - "sha256": "58c90afab6e4b9a6b34d2958fe06d1a143dd9226ea8834377e5cd45e815936d7", + "sha256": "450ab1c772e02f0c9ef02f489b153d86c45bd9311b202d10dc233f3c0206f8d1", "urls": [ - "https://archive.mozilla.org/pub/firefox/releases/157.0/win64/en-US/Firefox%20Setup%20157.0.exe" + "https://archive.mozilla.org/pub/firefox/releases/158.0/win64/en-US/Firefox%20Setup%20158.0.exe" ], "named_files": { "FIREFOX": "core/firefox.exe" diff --git a/package.json b/package.json index 3079b7f41ec4..3a019a911cc5 100644 --- a/package.json +++ b/package.json @@ -43,23 +43,23 @@ }, "homepage": "https://github.com/angular/angular-cli", "dependencies": { - "@angular/compiler-cli": "22.2.2", + "@angular/compiler-cli": "22.2.3", "typescript": "6.0.3" }, "devDependencies": { - "@angular/animations": "22.2.2", - "@angular/cdk": "22.2.2", - "@angular/common": "22.2.2", - "@angular/compiler": "22.2.2", - "@angular/core": "22.2.2", - "@angular/forms": "22.2.2", - "@angular/localize": "22.2.2", - "@angular/material": "22.2.2", - "@angular/ng-dev": "https://github.com/angular/dev-infra-private-ng-dev-builds.git#fa4308affb4a0dde34ebc95196b58550752485a2", - "@angular/platform-browser": "22.2.2", - "@angular/platform-server": "22.2.2", - "@angular/router": "22.2.2", - "@angular/service-worker": "22.2.2", + "@angular/animations": "22.2.3", + "@angular/cdk": "22.2.3", + "@angular/common": "22.2.3", + "@angular/compiler": "22.2.3", + "@angular/core": "22.2.3", + "@angular/forms": "22.2.3", + "@angular/localize": "22.2.3", + "@angular/material": "22.2.3", + "@angular/ng-dev": "https://github.com/angular/dev-infra-private-ng-dev-builds.git#940c0beef0de4cb128e90962d47ff80e352a1cd8", + "@angular/platform-browser": "22.2.3", + "@angular/platform-server": "22.2.3", + "@angular/router": "22.2.3", + "@angular/service-worker": "22.2.3", "@babel/core": "8.0.5", "@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 d2cbb89d35b6..fae2d4e78024 100644 --- a/packages/angular/ssr/package.json +++ b/packages/angular/ssr/package.json @@ -38,12 +38,12 @@ }, "devDependencies": { "@angular-devkit/schematics": "workspace:*", - "@angular/common": "22.2.2", - "@angular/compiler": "22.2.2", - "@angular/core": "22.2.2", - "@angular/platform-browser": "22.2.2", - "@angular/platform-server": "22.2.2", - "@angular/router": "22.2.2", + "@angular/common": "22.2.3", + "@angular/compiler": "22.2.3", + "@angular/core": "22.2.3", + "@angular/platform-browser": "22.2.3", + "@angular/platform-server": "22.2.3", + "@angular/router": "22.2.3", "@schematics/angular": "workspace:*" }, "sideEffects": false, diff --git a/packages/ngtools/webpack/package.json b/packages/ngtools/webpack/package.json index 4aa72955bcbb..cd7cd4862322 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.2", - "@angular/compiler-cli": "22.2.2", + "@angular/compiler": "22.2.3", + "@angular/compiler-cli": "22.2.3", "typescript": "6.0.3", "webpack": "5.111.0" } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index b632b6063d5f..a404c415baeb 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -172,8 +172,8 @@ importers: .: dependencies: '@angular/compiler-cli': - specifier: 22.2.2 - version: 22.2.2(@angular/compiler@22.2.2)(typescript@6.0.3) + specifier: 22.2.3 + version: 22.2.3(@angular/compiler@22.2.3)(typescript@6.0.3) typescript: specifier: 6.0.3 version: 6.0.3 @@ -184,44 +184,44 @@ importers: built: true devDependencies: '@angular/animations': - specifier: 22.2.2 - version: 22.2.2(@angular/core@22.2.2(@angular/compiler@22.2.2)(rxjs@7.8.2)(zone.js@0.16.3)) + specifier: 22.2.3 + version: 22.2.3(@angular/core@22.2.3(@angular/compiler@22.2.3)(rxjs@7.8.2)(zone.js@0.16.3)) '@angular/cdk': - specifier: 22.2.2 - version: 22.2.2(a2e0e17c73c6aceb9301ae9aaf890120) + specifier: 22.2.3 + version: 22.2.3(3a298d79b98ffed20e4ada273b186854) '@angular/common': - specifier: 22.2.2 - version: 22.2.2(@angular/core@22.2.2(@angular/compiler@22.2.2)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2) + specifier: 22.2.3 + version: 22.2.3(@angular/core@22.2.3(@angular/compiler@22.2.3)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2) '@angular/compiler': - specifier: 22.2.2 - version: 22.2.2 + specifier: 22.2.3 + version: 22.2.3 '@angular/core': - specifier: 22.2.2 - version: 22.2.2(@angular/compiler@22.2.2)(rxjs@7.8.2)(zone.js@0.16.3) + specifier: 22.2.3 + version: 22.2.3(@angular/compiler@22.2.3)(rxjs@7.8.2)(zone.js@0.16.3) '@angular/forms': - specifier: 22.2.2 - version: 22.2.2(@angular/common@22.2.2(@angular/core@22.2.2(@angular/compiler@22.2.2)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2))(@angular/core@22.2.2(@angular/compiler@22.2.2)(rxjs@7.8.2)(zone.js@0.16.3))(@angular/platform-browser@22.2.2(@angular/animations@22.2.2(@angular/core@22.2.2(@angular/compiler@22.2.2)(rxjs@7.8.2)(zone.js@0.16.3)))(@angular/common@22.2.2(@angular/core@22.2.2(@angular/compiler@22.2.2)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2))(@angular/core@22.2.2(@angular/compiler@22.2.2)(rxjs@7.8.2)(zone.js@0.16.3)))(rxjs@7.8.2) + specifier: 22.2.3 + version: 22.2.3(@angular/common@22.2.3(@angular/core@22.2.3(@angular/compiler@22.2.3)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2))(@angular/core@22.2.3(@angular/compiler@22.2.3)(rxjs@7.8.2)(zone.js@0.16.3))(@angular/platform-browser@22.2.3(@angular/animations@22.2.3(@angular/core@22.2.3(@angular/compiler@22.2.3)(rxjs@7.8.2)(zone.js@0.16.3)))(@angular/common@22.2.3(@angular/core@22.2.3(@angular/compiler@22.2.3)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2))(@angular/core@22.2.3(@angular/compiler@22.2.3)(rxjs@7.8.2)(zone.js@0.16.3)))(rxjs@7.8.2) '@angular/localize': - specifier: 22.2.2 - version: 22.2.2(@angular/compiler-cli@22.2.2(@angular/compiler@22.2.2)(typescript@6.0.3))(@angular/compiler@22.2.2) + specifier: 22.2.3 + version: 22.2.3(@angular/compiler-cli@22.2.3(@angular/compiler@22.2.3)(typescript@6.0.3))(@angular/compiler@22.2.3) '@angular/material': - specifier: 22.2.2 - version: 22.2.2(641510506f6736c740497081311accfd) + specifier: 22.2.3 + version: 22.2.3(631b9d5e68f5be106a233e4babc43f16) '@angular/ng-dev': - specifier: https://github.com/angular/dev-infra-private-ng-dev-builds.git#fa4308affb4a0dde34ebc95196b58550752485a2 - version: https://codeload.github.com/angular/dev-infra-private-ng-dev-builds/tar.gz/fa4308affb4a0dde34ebc95196b58550752485a2 + specifier: https://github.com/angular/dev-infra-private-ng-dev-builds.git#940c0beef0de4cb128e90962d47ff80e352a1cd8 + version: https://codeload.github.com/angular/dev-infra-private-ng-dev-builds/tar.gz/940c0beef0de4cb128e90962d47ff80e352a1cd8 '@angular/platform-browser': - specifier: 22.2.2 - version: 22.2.2(@angular/animations@22.2.2(@angular/core@22.2.2(@angular/compiler@22.2.2)(rxjs@7.8.2)(zone.js@0.16.3)))(@angular/common@22.2.2(@angular/core@22.2.2(@angular/compiler@22.2.2)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2))(@angular/core@22.2.2(@angular/compiler@22.2.2)(rxjs@7.8.2)(zone.js@0.16.3)) + specifier: 22.2.3 + version: 22.2.3(@angular/animations@22.2.3(@angular/core@22.2.3(@angular/compiler@22.2.3)(rxjs@7.8.2)(zone.js@0.16.3)))(@angular/common@22.2.3(@angular/core@22.2.3(@angular/compiler@22.2.3)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2))(@angular/core@22.2.3(@angular/compiler@22.2.3)(rxjs@7.8.2)(zone.js@0.16.3)) '@angular/platform-server': - specifier: 22.2.2 - version: 22.2.2(@angular/common@22.2.2(@angular/core@22.2.2(@angular/compiler@22.2.2)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2))(@angular/compiler@22.2.2)(@angular/core@22.2.2(@angular/compiler@22.2.2)(rxjs@7.8.2)(zone.js@0.16.3))(@angular/platform-browser@22.2.2(@angular/animations@22.2.2(@angular/core@22.2.2(@angular/compiler@22.2.2)(rxjs@7.8.2)(zone.js@0.16.3)))(@angular/common@22.2.2(@angular/core@22.2.2(@angular/compiler@22.2.2)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2))(@angular/core@22.2.2(@angular/compiler@22.2.2)(rxjs@7.8.2)(zone.js@0.16.3)))(rxjs@7.8.2) + specifier: 22.2.3 + version: 22.2.3(@angular/common@22.2.3(@angular/core@22.2.3(@angular/compiler@22.2.3)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2))(@angular/compiler@22.2.3)(@angular/core@22.2.3(@angular/compiler@22.2.3)(rxjs@7.8.2)(zone.js@0.16.3))(@angular/platform-browser@22.2.3(@angular/animations@22.2.3(@angular/core@22.2.3(@angular/compiler@22.2.3)(rxjs@7.8.2)(zone.js@0.16.3)))(@angular/common@22.2.3(@angular/core@22.2.3(@angular/compiler@22.2.3)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2))(@angular/core@22.2.3(@angular/compiler@22.2.3)(rxjs@7.8.2)(zone.js@0.16.3)))(rxjs@7.8.2) '@angular/router': - specifier: 22.2.2 - version: 22.2.2(@angular/common@22.2.2(@angular/core@22.2.2(@angular/compiler@22.2.2)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2))(@angular/core@22.2.2(@angular/compiler@22.2.2)(rxjs@7.8.2)(zone.js@0.16.3))(@angular/platform-browser@22.2.2(@angular/animations@22.2.2(@angular/core@22.2.2(@angular/compiler@22.2.2)(rxjs@7.8.2)(zone.js@0.16.3)))(@angular/common@22.2.2(@angular/core@22.2.2(@angular/compiler@22.2.2)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2))(@angular/core@22.2.2(@angular/compiler@22.2.2)(rxjs@7.8.2)(zone.js@0.16.3)))(rxjs@7.8.2) + specifier: 22.2.3 + version: 22.2.3(@angular/common@22.2.3(@angular/core@22.2.3(@angular/compiler@22.2.3)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2))(@angular/core@22.2.3(@angular/compiler@22.2.3)(rxjs@7.8.2)(zone.js@0.16.3))(@angular/platform-browser@22.2.3(@angular/animations@22.2.3(@angular/core@22.2.3(@angular/compiler@22.2.3)(rxjs@7.8.2)(zone.js@0.16.3)))(@angular/common@22.2.3(@angular/core@22.2.3(@angular/compiler@22.2.3)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2))(@angular/core@22.2.3(@angular/compiler@22.2.3)(rxjs@7.8.2)(zone.js@0.16.3)))(rxjs@7.8.2) '@angular/service-worker': - specifier: 22.2.2 - version: 22.2.2(@angular/core@22.2.2(@angular/compiler@22.2.2)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2) + specifier: 22.2.3 + version: 22.2.3(@angular/core@22.2.3(@angular/compiler@22.2.3)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2) '@babel/core': specifier: 8.0.5 version: 8.0.5 @@ -464,7 +464,7 @@ importers: version: 30.0.1(@noble/hashes@1.8.0) ng-packagr: specifier: 22.2.4 - version: 22.2.4(@angular/compiler-cli@22.2.2(@angular/compiler@22.2.2)(typescript@6.0.3))(supports-color@11.0.0)(tslib@2.8.1)(typescript@6.0.3) + version: 22.2.4(@angular/compiler-cli@22.2.3(@angular/compiler@22.2.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 @@ -579,7 +579,7 @@ importers: version: 4.9.1(supports-color@11.0.0) ng-packagr: specifier: 22.2.4 - version: 22.2.4(@angular/compiler-cli@22.2.2(@angular/compiler@22.2.2)(typescript@6.0.3))(supports-color@11.0.0)(tslib@2.8.1)(typescript@6.0.3) + version: 22.2.4(@angular/compiler-cli@22.2.3(@angular/compiler@22.2.3)(typescript@6.0.3))(supports-color@11.0.0)(tslib@2.8.1)(typescript@6.0.3) postcss: specifier: 8.5.28 version: 8.5.28 @@ -667,23 +667,23 @@ importers: specifier: workspace:* version: link:../../angular_devkit/schematics '@angular/common': - specifier: 22.2.2 - version: 22.2.2(@angular/core@22.2.2(@angular/compiler@22.2.2)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2) + specifier: 22.2.3 + version: 22.2.3(@angular/core@22.2.3(@angular/compiler@22.2.3)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2) '@angular/compiler': - specifier: 22.2.2 - version: 22.2.2 + specifier: 22.2.3 + version: 22.2.3 '@angular/core': - specifier: 22.2.2 - version: 22.2.2(@angular/compiler@22.2.2)(rxjs@7.8.2)(zone.js@0.16.3) + specifier: 22.2.3 + version: 22.2.3(@angular/compiler@22.2.3)(rxjs@7.8.2)(zone.js@0.16.3) '@angular/platform-browser': - specifier: 22.2.2 - version: 22.2.2(@angular/animations@22.2.2(@angular/core@22.2.2(@angular/compiler@22.2.2)(rxjs@7.8.2)(zone.js@0.16.3)))(@angular/common@22.2.2(@angular/core@22.2.2(@angular/compiler@22.2.2)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2))(@angular/core@22.2.2(@angular/compiler@22.2.2)(rxjs@7.8.2)(zone.js@0.16.3)) + specifier: 22.2.3 + version: 22.2.3(@angular/animations@22.2.3(@angular/core@22.2.3(@angular/compiler@22.2.3)(rxjs@7.8.2)(zone.js@0.16.3)))(@angular/common@22.2.3(@angular/core@22.2.3(@angular/compiler@22.2.3)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2))(@angular/core@22.2.3(@angular/compiler@22.2.3)(rxjs@7.8.2)(zone.js@0.16.3)) '@angular/platform-server': - specifier: 22.2.2 - version: 22.2.2(@angular/common@22.2.2(@angular/core@22.2.2(@angular/compiler@22.2.2)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2))(@angular/compiler@22.2.2)(@angular/core@22.2.2(@angular/compiler@22.2.2)(rxjs@7.8.2)(zone.js@0.16.3))(@angular/platform-browser@22.2.2(@angular/animations@22.2.2(@angular/core@22.2.2(@angular/compiler@22.2.2)(rxjs@7.8.2)(zone.js@0.16.3)))(@angular/common@22.2.2(@angular/core@22.2.2(@angular/compiler@22.2.2)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2))(@angular/core@22.2.2(@angular/compiler@22.2.2)(rxjs@7.8.2)(zone.js@0.16.3)))(rxjs@7.8.2) + specifier: 22.2.3 + version: 22.2.3(@angular/common@22.2.3(@angular/core@22.2.3(@angular/compiler@22.2.3)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2))(@angular/compiler@22.2.3)(@angular/core@22.2.3(@angular/compiler@22.2.3)(rxjs@7.8.2)(zone.js@0.16.3))(@angular/platform-browser@22.2.3(@angular/animations@22.2.3(@angular/core@22.2.3(@angular/compiler@22.2.3)(rxjs@7.8.2)(zone.js@0.16.3)))(@angular/common@22.2.3(@angular/core@22.2.3(@angular/compiler@22.2.3)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2))(@angular/core@22.2.3(@angular/compiler@22.2.3)(rxjs@7.8.2)(zone.js@0.16.3)))(rxjs@7.8.2) '@angular/router': - specifier: 22.2.2 - version: 22.2.2(@angular/common@22.2.2(@angular/core@22.2.2(@angular/compiler@22.2.2)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2))(@angular/core@22.2.2(@angular/compiler@22.2.2)(rxjs@7.8.2)(zone.js@0.16.3))(@angular/platform-browser@22.2.2(@angular/animations@22.2.2(@angular/core@22.2.2(@angular/compiler@22.2.2)(rxjs@7.8.2)(zone.js@0.16.3)))(@angular/common@22.2.2(@angular/core@22.2.2(@angular/compiler@22.2.2)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2))(@angular/core@22.2.2(@angular/compiler@22.2.2)(rxjs@7.8.2)(zone.js@0.16.3)))(rxjs@7.8.2) + specifier: 22.2.3 + version: 22.2.3(@angular/common@22.2.3(@angular/core@22.2.3(@angular/compiler@22.2.3)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2))(@angular/core@22.2.3(@angular/compiler@22.2.3)(rxjs@7.8.2)(zone.js@0.16.3))(@angular/platform-browser@22.2.3(@angular/animations@22.2.3(@angular/core@22.2.3(@angular/compiler@22.2.3)(rxjs@7.8.2)(zone.js@0.16.3)))(@angular/common@22.2.3(@angular/core@22.2.3(@angular/compiler@22.2.3)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2))(@angular/core@22.2.3(@angular/compiler@22.2.3)(rxjs@7.8.2)(zone.js@0.16.3)))(rxjs@7.8.2) '@schematics/angular': specifier: workspace:* version: link:../../schematics/angular @@ -867,7 +867,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.4 - version: 22.2.4(@angular/compiler-cli@22.2.2(@angular/compiler@22.2.2)(typescript@6.0.3))(supports-color@11.0.0)(tslib@2.8.1)(typescript@6.0.3) + version: 22.2.4(@angular/compiler-cli@22.2.3(@angular/compiler@22.2.3)(typescript@6.0.3))(supports-color@11.0.0)(tslib@2.8.1)(typescript@6.0.3) sass: specifier: 1.104.1 version: 1.104.1 @@ -962,11 +962,11 @@ importers: specifier: workspace:0.0.0-PLACEHOLDER version: link:../../angular_devkit/core '@angular/compiler': - specifier: 22.2.2 - version: 22.2.2 + specifier: 22.2.3 + version: 22.2.3 '@angular/compiler-cli': - specifier: 22.2.2 - version: 22.2.2(@angular/compiler@22.2.2)(typescript@6.0.3) + specifier: 22.2.3 + version: 22.2.3(@angular/compiler@22.2.3)(typescript@6.0.3) typescript: specifier: 6.0.3 version: 6.0.3 @@ -1026,15 +1026,15 @@ packages: resolution: {integrity: sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==} engines: {node: '>=6.0.0'} - '@angular/animations@22.2.2': - resolution: {integrity: sha512-N2VTjsH9xHGWsKlyeWrODcp4b2UEkrT/lGkHMxL4yr+ie0sKpxtZzzwzOQMMCRyv39ff2sfPQjb7q56K8RZ78w==} + '@angular/animations@22.2.3': + resolution: {integrity: sha512-sslKnTrKwHwtTvT/pWj7UoYq0cfuX3PijZM7v0JtCajQkK1Nj0Ljob0mebxXBXUVBrOixfCnfBS0EG4JNEznFA==} 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.2 + '@angular/core': 22.2.3 - '@angular/cdk@22.2.2': - resolution: {integrity: sha512-d5PWfIargIEV0rlwZea2pYDGb8FhF9df6a6XFRLThla6NKiJRs8utqW+7pyY9wCPFR3SSCGHC05xFh7qv91hdw==} + '@angular/cdk@22.2.3': + resolution: {integrity: sha512-EmRFAbCfDONSexi2yrVOAfyHvvb5mI1jx6Z5GTk7MISgC8Uvv+OYGfrEDrJvHPVEhGm6mtglMd5U8ZwhSrb2Eg==} peerDependencies: '@angular/common': ^22.0.0 || ^23.0.0 '@angular/core': ^22.0.0 || ^23.0.0 @@ -1042,33 +1042,33 @@ packages: '@angular/platform-browser': ^22.0.0 || ^23.0.0 rxjs: ^6.5.3 || ^7.4.0 - '@angular/common@22.2.2': - resolution: {integrity: sha512-d+mbF1UQLpsoJiC7h4pl58G7XeLHKU8DdLbq9u7TuOK0AnC1t2rrphi8M8WqUrZ+bfmFKCU4i1i4+vOF1N5GtA==} + '@angular/common@22.2.3': + resolution: {integrity: sha512-sRzcvxzurbkCDVFJMguNVgsHds3NvDj5qbZ44NHjH7J9MBk5oZYXHppdHVm8AolBhCXAWvMk0vx+NO8Bt4rS7A==} engines: {node: ^22.22.3 || ^24.15.0 || >=26.0.0} peerDependencies: - '@angular/core': 22.2.2 + '@angular/core': 22.2.3 rxjs: ^6.5.3 || ^7.4.0 - '@angular/compiler-cli@22.2.2': - resolution: {integrity: sha512-7PCIBTVIzG4oyAkDeBRPJpGcgSDLBCKn+2Pp9+gXnXOEETdWhV34so1fpWZ2GWBZsxXav7Ry0K93vFwF93yWoQ==} + '@angular/compiler-cli@22.2.3': + resolution: {integrity: sha512-em7Ht0Dv7cN7vZgvl2fl1yscAs+zUG2Vr2YKpVZ/rOWuTL2JZyT1qIfKhC4wQoo/3lN8fiUIwQMpflSGzIEPng==} engines: {node: ^22.22.3 || ^24.15.0 || >=26.0.0} hasBin: true peerDependencies: - '@angular/compiler': 22.2.2 + '@angular/compiler': 22.2.3 typescript: '>=6.0 <6.1' peerDependenciesMeta: typescript: optional: true - '@angular/compiler@22.2.2': - resolution: {integrity: sha512-hg8Kvhq29w97vs3O5KsSeqA+oobrAKpr/GvsWBIqjRzfrxxeFdjRRoEv1/MVgMSJK36VLigNCjB1qPF3MB17uA==} + '@angular/compiler@22.2.3': + resolution: {integrity: sha512-GjDkmOBqW+6RJTeW5mlLRivf6Zy7Ed0auVh+DYD67d4UF4Sk17F1vIt8puF4CQ2PIezlHh7oOnermCBNHAOGkQ==} engines: {node: ^22.22.3 || ^24.15.0 || >=26.0.0} - '@angular/core@22.2.2': - resolution: {integrity: sha512-mFiSoAs7Gp/7VlbdSxDyV2I/FEyYeNZRaHH7QrMWSB9t+k7wm37uCaYOt9fy6fgXU/UbCgBESp09fV9bUTQcmA==} + '@angular/core@22.2.3': + resolution: {integrity: sha512-ponarFrAZsPutT+htRt3PEmkt2/IB7DyrBy2f48sxsIx3ZA6xw09i2HOEBo+VBphlN6B/ynK9q+o04HPhdJ+dQ==} engines: {node: ^22.22.3 || ^24.15.0 || >=26.0.0} peerDependencies: - '@angular/compiler': 22.2.2 + '@angular/compiler': 22.2.3 rxjs: ^6.5.3 || ^7.4.0 zone.js: ~0.15.0 || ~0.16.0 peerDependenciesMeta: @@ -1077,74 +1077,74 @@ packages: zone.js: optional: true - '@angular/forms@22.2.2': - resolution: {integrity: sha512-Fgh+EnDoULSFzuDy44da/5Chi+4Sd2Qc4SLjFj23bktvMJ1yfuBPWkvpR9xgWg9Auq+9x84wJVK6WyNwIjXYWA==} + '@angular/forms@22.2.3': + resolution: {integrity: sha512-TKP8FpeRCY/++vKWsY8GC1J2sNtEkdNNBPdgnMAMLTwheW5JzjwVatuQlbuZEx3WaAjbll1Ux3d+eHeqAVrtQg==} engines: {node: ^22.22.3 || ^24.15.0 || >=26.0.0} peerDependencies: - '@angular/common': 22.2.2 - '@angular/core': 22.2.2 - '@angular/platform-browser': 22.2.2 + '@angular/common': 22.2.3 + '@angular/core': 22.2.3 + '@angular/platform-browser': 22.2.3 rxjs: ^6.5.3 || ^7.4.0 - '@angular/localize@22.2.2': - resolution: {integrity: sha512-pHahnD4xcv5Znsg/JY6eRtG6FEhe1E2pSqaoxeGfDoMZOp2GZq0+7zhzHE6oq2eXqQcSMIlUAWFXMH/KByNqDw==} + '@angular/localize@22.2.3': + resolution: {integrity: sha512-PAiV/k8ps4Qosu0VFk5/HIhjfQa0w4Y28+rx3aPIFei3d+kSak4yG5X9SiPWJQaSXr+YamS5pE/BipLYLNvwqA==} engines: {node: ^22.22.3 || ^24.15.0 || >=26.0.0} hasBin: true peerDependencies: - '@angular/compiler': 22.2.2 - '@angular/compiler-cli': 22.2.2 + '@angular/compiler': 22.2.3 + '@angular/compiler-cli': 22.2.3 - '@angular/material@22.2.2': - resolution: {integrity: sha512-G8nnt6yO7z64yZZbeF0l0fSztgZYv1TBFdGlexweyPfBlRn7N2X14Uv/TWht46vrXvExGuZOiR3c05XELd80fw==} + '@angular/material@22.2.3': + resolution: {integrity: sha512-zbkQRIFJdarPu8uwHnk77O3836ckejJnX5oT9Lx5Ydq/fN+xkAyedTJMpGD6FsAbtAth5Kv7YiAFbZQvBgNLsQ==} peerDependencies: - '@angular/cdk': 22.2.2 + '@angular/cdk': 22.2.3 '@angular/common': ^22.0.0 || ^23.0.0 '@angular/core': ^22.0.0 || ^23.0.0 '@angular/forms': ^22.0.0 || ^23.0.0 '@angular/platform-browser': ^22.0.0 || ^23.0.0 rxjs: ^6.5.3 || ^7.4.0 - '@angular/ng-dev@https://codeload.github.com/angular/dev-infra-private-ng-dev-builds/tar.gz/fa4308affb4a0dde34ebc95196b58550752485a2': - resolution: {gitHosted: true, integrity: sha512-zq1Lg7edQb2cf9QrSiQEU/+LwY4e/af9tN9W3hO5jDdYK+gp+sYZbBbuzounSWkmK+j+oG0K5CA9/kmyHAimZg==, tarball: https://codeload.github.com/angular/dev-infra-private-ng-dev-builds/tar.gz/fa4308affb4a0dde34ebc95196b58550752485a2} - version: 0.0.0-f28485704b2d1f81ae380a8296a4f14d9852c248 + '@angular/ng-dev@https://codeload.github.com/angular/dev-infra-private-ng-dev-builds/tar.gz/940c0beef0de4cb128e90962d47ff80e352a1cd8': + resolution: {gitHosted: true, integrity: sha512-6d8sBwbru5J4TsfMlHneqn1PD+K2p5l5HGKOba3Y/Ygl+bUEtxIJyM8aRgX88WWgVwjcaKSByQ6gClVxjqNznw==, tarball: https://codeload.github.com/angular/dev-infra-private-ng-dev-builds/tar.gz/940c0beef0de4cb128e90962d47ff80e352a1cd8} + version: 0.0.0-f8062d1d0f50e59fcb36a9375a596f416204ee28 hasBin: true - '@angular/platform-browser@22.2.2': - resolution: {integrity: sha512-DnAyZTLty5bVNeDhcSPNQABqb9SmNvYfYhvgU3dKoGEpONrrECfYo/X4MN0g7Z9Dn/DkgBCNRoC9AZWxbO9HDQ==} + '@angular/platform-browser@22.2.3': + resolution: {integrity: sha512-eWZGsbG4bSrSg9UB/NE8wORGVrh1u+x6rirPGpMWqq/mTi6q+nS+pnPxAxmiEs8wmPH5nCz5b2pRKQeYUkhAGA==} engines: {node: ^22.22.3 || ^24.15.0 || >=26.0.0} peerDependencies: - '@angular/animations': 22.2.2 - '@angular/common': 22.2.2 - '@angular/core': 22.2.2 + '@angular/animations': 22.2.3 + '@angular/common': 22.2.3 + '@angular/core': 22.2.3 peerDependenciesMeta: '@angular/animations': optional: true - '@angular/platform-server@22.2.2': - resolution: {integrity: sha512-CBqkqtkpIkEAtKJBRSplgBlWzNe2CMsbIZ4FFOPh9uHzBTmztA/D/QXqZKgnHLSP79FUmGjzrBizpk8fo9oVSg==} + '@angular/platform-server@22.2.3': + resolution: {integrity: sha512-ROuJklv7iQVI1zIulo4MBDnk3Z0ZzihBWuN4nxFY8MTWxVMk97p92j1Wuyt4Kmx2kb5PB+kpcR1Jl6e13idftA==} engines: {node: ^22.22.3 || ^24.15.0 || >=26.0.0} peerDependencies: - '@angular/common': 22.2.2 - '@angular/compiler': 22.2.2 - '@angular/core': 22.2.2 - '@angular/platform-browser': 22.2.2 + '@angular/common': 22.2.3 + '@angular/compiler': 22.2.3 + '@angular/core': 22.2.3 + '@angular/platform-browser': 22.2.3 rxjs: ^6.5.3 || ^7.4.0 - '@angular/router@22.2.2': - resolution: {integrity: sha512-45HP/henqbPRTCBHzwF4ZV8JU75u2TmBMR4BtwcXcKF5SWragKWE0rMz4NpHnCQIy3bIy5SVTvawpf7EJ/kRyw==} + '@angular/router@22.2.3': + resolution: {integrity: sha512-h4C3iJ3OXM9HItErmTo9fFrFRDj1DSqbvweHAWl8eYJvyuhDD80gBNgdpN8/5gpt9K1HV+PXk0YbyjyQ0zMfPA==} engines: {node: ^22.22.3 || ^24.15.0 || >=26.0.0} peerDependencies: - '@angular/common': 22.2.2 - '@angular/core': 22.2.2 - '@angular/platform-browser': 22.2.2 + '@angular/common': 22.2.3 + '@angular/core': 22.2.3 + '@angular/platform-browser': 22.2.3 rxjs: ^6.5.3 || ^7.4.0 - '@angular/service-worker@22.2.2': - resolution: {integrity: sha512-60Knjdvr80OSsqUQ7LYc+ibeLN495uj+loeCdmowO4DvKyoPFlW/KW7sKZq7OuZcnKIln+ujHNViYxs4wf23zQ==} + '@angular/service-worker@22.2.3': + resolution: {integrity: sha512-saMdoMws2M9nIGfM2hdhCHhPospGq1UC1xR3V8pcPQWW9EgQqkpjLZODPrXxJjzxpvprnuHY7w/OSt7dqfbbtA==} engines: {node: ^22.22.3 || ^24.15.0 || >=26.0.0} hasBin: true peerDependencies: - '@angular/core': 22.2.2 + '@angular/core': 22.2.3 rxjs: ^6.5.3 || ^7.4.0 '@asamuzakjp/css-color@6.0.7': @@ -2284,8 +2284,8 @@ packages: resolution: {integrity: sha512-IJn+8A3QZJfe7FUtWqHVNo3xJs7KFpurCWGWCiCz3oEh+BkRymKZ1QxfAbU2yGMDzTytLGQ2IV6T2r3cuo75/w==} engines: {node: '>=18'} - '@google/genai@2.28.0': - resolution: {integrity: sha512-hyNAJj+ywu3L46qlZod6KO/JvcT3QONz6VCiPevC/FWOjAD+LQb7DMLUoV8vzoLpt61Q0ruQX99iqbxEjPJWmw==} + '@google/genai@2.29.1': + resolution: {integrity: sha512-keU+JsY11fT4ykdFA6Q8iQHBgOAAVssFLxPtXRjCIEr5Zt2GzE75c22bBmq87XbhgtpuKaObnSgsrG60rj0ZMA==} engines: {node: '>=20.0.0'} peerDependencies: '@modelcontextprotocol/sdk': ^1.25.2 @@ -3737,8 +3737,8 @@ packages: '@types/node@22.20.5': resolution: {integrity: sha512-U2+DNr+wSjpsTS/wZGYHq7GcwfuSmKiKvoPvK22zwTlRhU91yOniN4qRR5KhIjvif7ysw/dz/hKmfDH0Ris4aA==} - '@types/node@24.19.1': - resolution: {integrity: sha512-aS3/DG0oM05K0RIXXP+hKjinGG5IgSSVGzswZxW3O0sS3pH4/fycXundUC9XsszgKCk4gHXylTEK6hyFxVxnoQ==} + '@types/node@24.19.2': + resolution: {integrity: sha512-93d49wCWJkCyN87MxLpNN6KXPCwFw7bVUg79mGUV1OS40JGWwVCr8n61DXCSqz7CV6/VfPkb7xec7uP2M+QHWQ==} '@types/npm-package-arg@6.1.4': resolution: {integrity: sha512-vDgdbMy2QXHnAruzlv68pUtXCjmqUk3WrBAsRboRovsOmxbfn/WiYCjmecyKjGztnMps5dWp4Uq2prp+Ilo17Q==} @@ -8620,30 +8620,30 @@ snapshots: '@jridgewell/gen-mapping': 0.3.13 '@jridgewell/trace-mapping': 0.3.31 - '@angular/animations@22.2.2(@angular/core@22.2.2(@angular/compiler@22.2.2)(rxjs@7.8.2)(zone.js@0.16.3))': + '@angular/animations@22.2.3(@angular/core@22.2.3(@angular/compiler@22.2.3)(rxjs@7.8.2)(zone.js@0.16.3))': dependencies: - '@angular/core': 22.2.2(@angular/compiler@22.2.2)(rxjs@7.8.2)(zone.js@0.16.3) + '@angular/core': 22.2.3(@angular/compiler@22.2.3)(rxjs@7.8.2)(zone.js@0.16.3) tslib: 2.8.1 - '@angular/cdk@22.2.2(a2e0e17c73c6aceb9301ae9aaf890120)': + '@angular/cdk@22.2.3(3a298d79b98ffed20e4ada273b186854)': dependencies: - '@angular/common': 22.2.2(@angular/core@22.2.2(@angular/compiler@22.2.2)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2) - '@angular/core': 22.2.2(@angular/compiler@22.2.2)(rxjs@7.8.2)(zone.js@0.16.3) - '@angular/forms': 22.2.2(@angular/common@22.2.2(@angular/core@22.2.2(@angular/compiler@22.2.2)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2))(@angular/core@22.2.2(@angular/compiler@22.2.2)(rxjs@7.8.2)(zone.js@0.16.3))(@angular/platform-browser@22.2.2(@angular/animations@22.2.2(@angular/core@22.2.2(@angular/compiler@22.2.2)(rxjs@7.8.2)(zone.js@0.16.3)))(@angular/common@22.2.2(@angular/core@22.2.2(@angular/compiler@22.2.2)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2))(@angular/core@22.2.2(@angular/compiler@22.2.2)(rxjs@7.8.2)(zone.js@0.16.3)))(rxjs@7.8.2) - '@angular/platform-browser': 22.2.2(@angular/animations@22.2.2(@angular/core@22.2.2(@angular/compiler@22.2.2)(rxjs@7.8.2)(zone.js@0.16.3)))(@angular/common@22.2.2(@angular/core@22.2.2(@angular/compiler@22.2.2)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2))(@angular/core@22.2.2(@angular/compiler@22.2.2)(rxjs@7.8.2)(zone.js@0.16.3)) + '@angular/common': 22.2.3(@angular/core@22.2.3(@angular/compiler@22.2.3)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2) + '@angular/core': 22.2.3(@angular/compiler@22.2.3)(rxjs@7.8.2)(zone.js@0.16.3) + '@angular/forms': 22.2.3(@angular/common@22.2.3(@angular/core@22.2.3(@angular/compiler@22.2.3)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2))(@angular/core@22.2.3(@angular/compiler@22.2.3)(rxjs@7.8.2)(zone.js@0.16.3))(@angular/platform-browser@22.2.3(@angular/animations@22.2.3(@angular/core@22.2.3(@angular/compiler@22.2.3)(rxjs@7.8.2)(zone.js@0.16.3)))(@angular/common@22.2.3(@angular/core@22.2.3(@angular/compiler@22.2.3)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2))(@angular/core@22.2.3(@angular/compiler@22.2.3)(rxjs@7.8.2)(zone.js@0.16.3)))(rxjs@7.8.2) + '@angular/platform-browser': 22.2.3(@angular/animations@22.2.3(@angular/core@22.2.3(@angular/compiler@22.2.3)(rxjs@7.8.2)(zone.js@0.16.3)))(@angular/common@22.2.3(@angular/core@22.2.3(@angular/compiler@22.2.3)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2))(@angular/core@22.2.3(@angular/compiler@22.2.3)(rxjs@7.8.2)(zone.js@0.16.3)) parse5: 8.0.1 rxjs: 7.8.2 tslib: 2.8.1 - '@angular/common@22.2.2(@angular/core@22.2.2(@angular/compiler@22.2.2)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2)': + '@angular/common@22.2.3(@angular/core@22.2.3(@angular/compiler@22.2.3)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2)': dependencies: - '@angular/core': 22.2.2(@angular/compiler@22.2.2)(rxjs@7.8.2)(zone.js@0.16.3) + '@angular/core': 22.2.3(@angular/compiler@22.2.3)(rxjs@7.8.2)(zone.js@0.16.3) rxjs: 7.8.2 tslib: 2.8.1 - '@angular/compiler-cli@22.2.2(@angular/compiler@22.2.2)(typescript@6.0.3)': + '@angular/compiler-cli@22.2.3(@angular/compiler@22.2.3)(typescript@6.0.3)': dependencies: - '@angular/compiler': 22.2.2 + '@angular/compiler': 22.2.3 '@babel/core': 8.0.1 '@jridgewell/sourcemap-codec': 1.6.0 chokidar: 5.0.0 @@ -8655,54 +8655,54 @@ snapshots: optionalDependencies: typescript: 6.0.3 - '@angular/compiler@22.2.2': + '@angular/compiler@22.2.3': dependencies: tslib: 2.8.1 - '@angular/core@22.2.2(@angular/compiler@22.2.2)(rxjs@7.8.2)(zone.js@0.16.3)': + '@angular/core@22.2.3(@angular/compiler@22.2.3)(rxjs@7.8.2)(zone.js@0.16.3)': dependencies: rxjs: 7.8.2 tslib: 2.8.1 optionalDependencies: - '@angular/compiler': 22.2.2 + '@angular/compiler': 22.2.3 zone.js: 0.16.3 - '@angular/forms@22.2.2(@angular/common@22.2.2(@angular/core@22.2.2(@angular/compiler@22.2.2)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2))(@angular/core@22.2.2(@angular/compiler@22.2.2)(rxjs@7.8.2)(zone.js@0.16.3))(@angular/platform-browser@22.2.2(@angular/animations@22.2.2(@angular/core@22.2.2(@angular/compiler@22.2.2)(rxjs@7.8.2)(zone.js@0.16.3)))(@angular/common@22.2.2(@angular/core@22.2.2(@angular/compiler@22.2.2)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2))(@angular/core@22.2.2(@angular/compiler@22.2.2)(rxjs@7.8.2)(zone.js@0.16.3)))(rxjs@7.8.2)': + '@angular/forms@22.2.3(@angular/common@22.2.3(@angular/core@22.2.3(@angular/compiler@22.2.3)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2))(@angular/core@22.2.3(@angular/compiler@22.2.3)(rxjs@7.8.2)(zone.js@0.16.3))(@angular/platform-browser@22.2.3(@angular/animations@22.2.3(@angular/core@22.2.3(@angular/compiler@22.2.3)(rxjs@7.8.2)(zone.js@0.16.3)))(@angular/common@22.2.3(@angular/core@22.2.3(@angular/compiler@22.2.3)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2))(@angular/core@22.2.3(@angular/compiler@22.2.3)(rxjs@7.8.2)(zone.js@0.16.3)))(rxjs@7.8.2)': dependencies: - '@angular/common': 22.2.2(@angular/core@22.2.2(@angular/compiler@22.2.2)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2) - '@angular/core': 22.2.2(@angular/compiler@22.2.2)(rxjs@7.8.2)(zone.js@0.16.3) - '@angular/platform-browser': 22.2.2(@angular/animations@22.2.2(@angular/core@22.2.2(@angular/compiler@22.2.2)(rxjs@7.8.2)(zone.js@0.16.3)))(@angular/common@22.2.2(@angular/core@22.2.2(@angular/compiler@22.2.2)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2))(@angular/core@22.2.2(@angular/compiler@22.2.2)(rxjs@7.8.2)(zone.js@0.16.3)) + '@angular/common': 22.2.3(@angular/core@22.2.3(@angular/compiler@22.2.3)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2) + '@angular/core': 22.2.3(@angular/compiler@22.2.3)(rxjs@7.8.2)(zone.js@0.16.3) + '@angular/platform-browser': 22.2.3(@angular/animations@22.2.3(@angular/core@22.2.3(@angular/compiler@22.2.3)(rxjs@7.8.2)(zone.js@0.16.3)))(@angular/common@22.2.3(@angular/core@22.2.3(@angular/compiler@22.2.3)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2))(@angular/core@22.2.3(@angular/compiler@22.2.3)(rxjs@7.8.2)(zone.js@0.16.3)) '@standard-schema/spec': 1.1.0 rxjs: 7.8.2 tslib: 2.8.1 zod: 4.6.6 - '@angular/localize@22.2.2(@angular/compiler-cli@22.2.2(@angular/compiler@22.2.2)(typescript@6.0.3))(@angular/compiler@22.2.2)': + '@angular/localize@22.2.3(@angular/compiler-cli@22.2.3(@angular/compiler@22.2.3)(typescript@6.0.3))(@angular/compiler@22.2.3)': dependencies: - '@angular/compiler': 22.2.2 - '@angular/compiler-cli': 22.2.2(@angular/compiler@22.2.2)(typescript@6.0.3) + '@angular/compiler': 22.2.3 + '@angular/compiler-cli': 22.2.3(@angular/compiler@22.2.3)(typescript@6.0.3) '@babel/core': 8.0.1 tinyglobby: 0.2.17 yargs: 18.1.0 - '@angular/material@22.2.2(641510506f6736c740497081311accfd)': + '@angular/material@22.2.3(631b9d5e68f5be106a233e4babc43f16)': dependencies: - '@angular/cdk': 22.2.2(a2e0e17c73c6aceb9301ae9aaf890120) - '@angular/common': 22.2.2(@angular/core@22.2.2(@angular/compiler@22.2.2)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2) - '@angular/core': 22.2.2(@angular/compiler@22.2.2)(rxjs@7.8.2)(zone.js@0.16.3) - '@angular/forms': 22.2.2(@angular/common@22.2.2(@angular/core@22.2.2(@angular/compiler@22.2.2)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2))(@angular/core@22.2.2(@angular/compiler@22.2.2)(rxjs@7.8.2)(zone.js@0.16.3))(@angular/platform-browser@22.2.2(@angular/animations@22.2.2(@angular/core@22.2.2(@angular/compiler@22.2.2)(rxjs@7.8.2)(zone.js@0.16.3)))(@angular/common@22.2.2(@angular/core@22.2.2(@angular/compiler@22.2.2)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2))(@angular/core@22.2.2(@angular/compiler@22.2.2)(rxjs@7.8.2)(zone.js@0.16.3)))(rxjs@7.8.2) - '@angular/platform-browser': 22.2.2(@angular/animations@22.2.2(@angular/core@22.2.2(@angular/compiler@22.2.2)(rxjs@7.8.2)(zone.js@0.16.3)))(@angular/common@22.2.2(@angular/core@22.2.2(@angular/compiler@22.2.2)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2))(@angular/core@22.2.2(@angular/compiler@22.2.2)(rxjs@7.8.2)(zone.js@0.16.3)) + '@angular/cdk': 22.2.3(3a298d79b98ffed20e4ada273b186854) + '@angular/common': 22.2.3(@angular/core@22.2.3(@angular/compiler@22.2.3)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2) + '@angular/core': 22.2.3(@angular/compiler@22.2.3)(rxjs@7.8.2)(zone.js@0.16.3) + '@angular/forms': 22.2.3(@angular/common@22.2.3(@angular/core@22.2.3(@angular/compiler@22.2.3)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2))(@angular/core@22.2.3(@angular/compiler@22.2.3)(rxjs@7.8.2)(zone.js@0.16.3))(@angular/platform-browser@22.2.3(@angular/animations@22.2.3(@angular/core@22.2.3(@angular/compiler@22.2.3)(rxjs@7.8.2)(zone.js@0.16.3)))(@angular/common@22.2.3(@angular/core@22.2.3(@angular/compiler@22.2.3)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2))(@angular/core@22.2.3(@angular/compiler@22.2.3)(rxjs@7.8.2)(zone.js@0.16.3)))(rxjs@7.8.2) + '@angular/platform-browser': 22.2.3(@angular/animations@22.2.3(@angular/core@22.2.3(@angular/compiler@22.2.3)(rxjs@7.8.2)(zone.js@0.16.3)))(@angular/common@22.2.3(@angular/core@22.2.3(@angular/compiler@22.2.3)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2))(@angular/core@22.2.3(@angular/compiler@22.2.3)(rxjs@7.8.2)(zone.js@0.16.3)) rxjs: 7.8.2 tslib: 2.8.1 - '@angular/ng-dev@https://codeload.github.com/angular/dev-infra-private-ng-dev-builds/tar.gz/fa4308affb4a0dde34ebc95196b58550752485a2': + '@angular/ng-dev@https://codeload.github.com/angular/dev-infra-private-ng-dev-builds/tar.gz/940c0beef0de4cb128e90962d47ff80e352a1cd8': dependencies: '@actions/core': 3.0.1 '@conventional-changelog/git-client': 3.2.0(conventional-commits-filter@6.0.1)(conventional-commits-parser@7.1.3) '@google-cloud/spanner': 8.0.0(supports-color@11.0.0) - '@google/genai': 2.28.0(bufferutil@4.1.0)(supports-color@11.0.0)(utf-8-validate@6.0.6) - '@inquirer/prompts': 8.7.3(@types/node@24.19.1) - '@inquirer/type': 4.2.0(@types/node@24.19.1) + '@google/genai': 2.29.1(bufferutil@4.1.0)(supports-color@11.0.0)(utf-8-validate@6.0.6) + '@inquirer/prompts': 8.7.3(@types/node@24.19.2) + '@inquirer/type': 4.2.0(@types/node@24.19.2) '@octokit/auth-app': 8.3.1 '@octokit/core': 7.0.8 '@octokit/graphql': 9.0.5 @@ -8716,7 +8716,7 @@ snapshots: '@types/events': 3.0.3 '@types/folder-hash': 4.0.4 '@types/jasmine': 6.0.0 - '@types/node': 24.19.1 + '@types/node': 24.19.2 '@types/semver': 7.8.0 '@types/which': 3.0.4 '@types/yargs': 17.0.35 @@ -8752,35 +8752,35 @@ snapshots: - '@modelcontextprotocol/sdk' - '@react-native-async-storage/async-storage' - '@angular/platform-browser@22.2.2(@angular/animations@22.2.2(@angular/core@22.2.2(@angular/compiler@22.2.2)(rxjs@7.8.2)(zone.js@0.16.3)))(@angular/common@22.2.2(@angular/core@22.2.2(@angular/compiler@22.2.2)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2))(@angular/core@22.2.2(@angular/compiler@22.2.2)(rxjs@7.8.2)(zone.js@0.16.3))': + '@angular/platform-browser@22.2.3(@angular/animations@22.2.3(@angular/core@22.2.3(@angular/compiler@22.2.3)(rxjs@7.8.2)(zone.js@0.16.3)))(@angular/common@22.2.3(@angular/core@22.2.3(@angular/compiler@22.2.3)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2))(@angular/core@22.2.3(@angular/compiler@22.2.3)(rxjs@7.8.2)(zone.js@0.16.3))': dependencies: - '@angular/common': 22.2.2(@angular/core@22.2.2(@angular/compiler@22.2.2)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2) - '@angular/core': 22.2.2(@angular/compiler@22.2.2)(rxjs@7.8.2)(zone.js@0.16.3) + '@angular/common': 22.2.3(@angular/core@22.2.3(@angular/compiler@22.2.3)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2) + '@angular/core': 22.2.3(@angular/compiler@22.2.3)(rxjs@7.8.2)(zone.js@0.16.3) tslib: 2.8.1 optionalDependencies: - '@angular/animations': 22.2.2(@angular/core@22.2.2(@angular/compiler@22.2.2)(rxjs@7.8.2)(zone.js@0.16.3)) + '@angular/animations': 22.2.3(@angular/core@22.2.3(@angular/compiler@22.2.3)(rxjs@7.8.2)(zone.js@0.16.3)) - '@angular/platform-server@22.2.2(@angular/common@22.2.2(@angular/core@22.2.2(@angular/compiler@22.2.2)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2))(@angular/compiler@22.2.2)(@angular/core@22.2.2(@angular/compiler@22.2.2)(rxjs@7.8.2)(zone.js@0.16.3))(@angular/platform-browser@22.2.2(@angular/animations@22.2.2(@angular/core@22.2.2(@angular/compiler@22.2.2)(rxjs@7.8.2)(zone.js@0.16.3)))(@angular/common@22.2.2(@angular/core@22.2.2(@angular/compiler@22.2.2)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2))(@angular/core@22.2.2(@angular/compiler@22.2.2)(rxjs@7.8.2)(zone.js@0.16.3)))(rxjs@7.8.2)': + '@angular/platform-server@22.2.3(@angular/common@22.2.3(@angular/core@22.2.3(@angular/compiler@22.2.3)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2))(@angular/compiler@22.2.3)(@angular/core@22.2.3(@angular/compiler@22.2.3)(rxjs@7.8.2)(zone.js@0.16.3))(@angular/platform-browser@22.2.3(@angular/animations@22.2.3(@angular/core@22.2.3(@angular/compiler@22.2.3)(rxjs@7.8.2)(zone.js@0.16.3)))(@angular/common@22.2.3(@angular/core@22.2.3(@angular/compiler@22.2.3)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2))(@angular/core@22.2.3(@angular/compiler@22.2.3)(rxjs@7.8.2)(zone.js@0.16.3)))(rxjs@7.8.2)': dependencies: - '@angular/common': 22.2.2(@angular/core@22.2.2(@angular/compiler@22.2.2)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2) - '@angular/compiler': 22.2.2 - '@angular/core': 22.2.2(@angular/compiler@22.2.2)(rxjs@7.8.2)(zone.js@0.16.3) - '@angular/platform-browser': 22.2.2(@angular/animations@22.2.2(@angular/core@22.2.2(@angular/compiler@22.2.2)(rxjs@7.8.2)(zone.js@0.16.3)))(@angular/common@22.2.2(@angular/core@22.2.2(@angular/compiler@22.2.2)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2))(@angular/core@22.2.2(@angular/compiler@22.2.2)(rxjs@7.8.2)(zone.js@0.16.3)) + '@angular/common': 22.2.3(@angular/core@22.2.3(@angular/compiler@22.2.3)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2) + '@angular/compiler': 22.2.3 + '@angular/core': 22.2.3(@angular/compiler@22.2.3)(rxjs@7.8.2)(zone.js@0.16.3) + '@angular/platform-browser': 22.2.3(@angular/animations@22.2.3(@angular/core@22.2.3(@angular/compiler@22.2.3)(rxjs@7.8.2)(zone.js@0.16.3)))(@angular/common@22.2.3(@angular/core@22.2.3(@angular/compiler@22.2.3)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2))(@angular/core@22.2.3(@angular/compiler@22.2.3)(rxjs@7.8.2)(zone.js@0.16.3)) rxjs: 7.8.2 tslib: 2.8.1 xhr2: 0.2.1 - '@angular/router@22.2.2(@angular/common@22.2.2(@angular/core@22.2.2(@angular/compiler@22.2.2)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2))(@angular/core@22.2.2(@angular/compiler@22.2.2)(rxjs@7.8.2)(zone.js@0.16.3))(@angular/platform-browser@22.2.2(@angular/animations@22.2.2(@angular/core@22.2.2(@angular/compiler@22.2.2)(rxjs@7.8.2)(zone.js@0.16.3)))(@angular/common@22.2.2(@angular/core@22.2.2(@angular/compiler@22.2.2)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2))(@angular/core@22.2.2(@angular/compiler@22.2.2)(rxjs@7.8.2)(zone.js@0.16.3)))(rxjs@7.8.2)': + '@angular/router@22.2.3(@angular/common@22.2.3(@angular/core@22.2.3(@angular/compiler@22.2.3)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2))(@angular/core@22.2.3(@angular/compiler@22.2.3)(rxjs@7.8.2)(zone.js@0.16.3))(@angular/platform-browser@22.2.3(@angular/animations@22.2.3(@angular/core@22.2.3(@angular/compiler@22.2.3)(rxjs@7.8.2)(zone.js@0.16.3)))(@angular/common@22.2.3(@angular/core@22.2.3(@angular/compiler@22.2.3)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2))(@angular/core@22.2.3(@angular/compiler@22.2.3)(rxjs@7.8.2)(zone.js@0.16.3)))(rxjs@7.8.2)': dependencies: - '@angular/common': 22.2.2(@angular/core@22.2.2(@angular/compiler@22.2.2)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2) - '@angular/core': 22.2.2(@angular/compiler@22.2.2)(rxjs@7.8.2)(zone.js@0.16.3) - '@angular/platform-browser': 22.2.2(@angular/animations@22.2.2(@angular/core@22.2.2(@angular/compiler@22.2.2)(rxjs@7.8.2)(zone.js@0.16.3)))(@angular/common@22.2.2(@angular/core@22.2.2(@angular/compiler@22.2.2)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2))(@angular/core@22.2.2(@angular/compiler@22.2.2)(rxjs@7.8.2)(zone.js@0.16.3)) + '@angular/common': 22.2.3(@angular/core@22.2.3(@angular/compiler@22.2.3)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2) + '@angular/core': 22.2.3(@angular/compiler@22.2.3)(rxjs@7.8.2)(zone.js@0.16.3) + '@angular/platform-browser': 22.2.3(@angular/animations@22.2.3(@angular/core@22.2.3(@angular/compiler@22.2.3)(rxjs@7.8.2)(zone.js@0.16.3)))(@angular/common@22.2.3(@angular/core@22.2.3(@angular/compiler@22.2.3)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2))(@angular/core@22.2.3(@angular/compiler@22.2.3)(rxjs@7.8.2)(zone.js@0.16.3)) rxjs: 7.8.2 tslib: 2.8.1 - '@angular/service-worker@22.2.2(@angular/core@22.2.2(@angular/compiler@22.2.2)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2)': + '@angular/service-worker@22.2.3(@angular/core@22.2.3(@angular/compiler@22.2.3)(rxjs@7.8.2)(zone.js@0.16.3))(rxjs@7.8.2)': dependencies: - '@angular/core': 22.2.2(@angular/compiler@22.2.2)(rxjs@7.8.2)(zone.js@0.16.3) + '@angular/core': 22.2.3(@angular/compiler@22.2.3)(rxjs@7.8.2)(zone.js@0.16.3) rxjs: 7.8.2 tslib: 2.8.1 @@ -10098,7 +10098,7 @@ snapshots: transitivePeerDependencies: - supports-color - '@google/genai@2.28.0(bufferutil@4.1.0)(supports-color@11.0.0)(utf-8-validate@6.0.6)': + '@google/genai@2.29.1(bufferutil@4.1.0)(supports-color@11.0.0)(utf-8-validate@6.0.6)': dependencies: google-auth-library: 10.9.1(supports-color@11.0.0) p-retry: 4.6.2 @@ -10163,14 +10163,14 @@ snapshots: optionalDependencies: '@types/node': 22.20.5 - '@inquirer/checkbox@5.2.6(@types/node@24.19.1)': + '@inquirer/checkbox@5.2.6(@types/node@24.19.2)': dependencies: '@inquirer/ansi': 2.0.9 - '@inquirer/core': 12.0.4(@types/node@24.19.1) + '@inquirer/core': 12.0.4(@types/node@24.19.2) '@inquirer/figures': 2.0.9 - '@inquirer/type': 4.2.0(@types/node@24.19.1) + '@inquirer/type': 4.2.0(@types/node@24.19.2) optionalDependencies: - '@types/node': 24.19.1 + '@types/node': 24.19.2 '@inquirer/confirm@6.3.2(@types/node@22.20.5)': dependencies: @@ -10179,12 +10179,12 @@ snapshots: optionalDependencies: '@types/node': 22.20.5 - '@inquirer/confirm@6.3.3(@types/node@24.19.1)': + '@inquirer/confirm@6.3.3(@types/node@24.19.2)': dependencies: - '@inquirer/core': 12.0.4(@types/node@24.19.1) - '@inquirer/type': 4.2.0(@types/node@24.19.1) + '@inquirer/core': 12.0.4(@types/node@24.19.2) + '@inquirer/type': 4.2.0(@types/node@24.19.2) optionalDependencies: - '@types/node': 24.19.1 + '@types/node': 24.19.2 '@inquirer/core@12.0.4(@types/node@22.20.5)': dependencies: @@ -10198,17 +10198,17 @@ snapshots: optionalDependencies: '@types/node': 22.20.5 - '@inquirer/core@12.0.4(@types/node@24.19.1)': + '@inquirer/core@12.0.4(@types/node@24.19.2)': dependencies: '@inquirer/ansi': 2.0.9 '@inquirer/figures': 2.0.9 - '@inquirer/type': 4.2.0(@types/node@24.19.1) + '@inquirer/type': 4.2.0(@types/node@24.19.2) cli-width: 4.1.0 fast-wrap-ansi: 0.2.2 mute-stream: 3.0.0 signal-exit: 4.1.0 optionalDependencies: - '@types/node': 24.19.1 + '@types/node': 24.19.2 '@inquirer/editor@5.3.4(@types/node@22.20.5)': dependencies: @@ -10218,13 +10218,13 @@ snapshots: optionalDependencies: '@types/node': 22.20.5 - '@inquirer/editor@5.3.4(@types/node@24.19.1)': + '@inquirer/editor@5.3.4(@types/node@24.19.2)': dependencies: - '@inquirer/core': 12.0.4(@types/node@24.19.1) - '@inquirer/external-editor': 3.0.6(@types/node@24.19.1) - '@inquirer/type': 4.2.0(@types/node@24.19.1) + '@inquirer/core': 12.0.4(@types/node@24.19.2) + '@inquirer/external-editor': 3.0.6(@types/node@24.19.2) + '@inquirer/type': 4.2.0(@types/node@24.19.2) optionalDependencies: - '@types/node': 24.19.1 + '@types/node': 24.19.2 '@inquirer/expand@5.1.6(@types/node@22.20.5)': dependencies: @@ -10233,12 +10233,12 @@ snapshots: optionalDependencies: '@types/node': 22.20.5 - '@inquirer/expand@5.1.6(@types/node@24.19.1)': + '@inquirer/expand@5.1.6(@types/node@24.19.2)': dependencies: - '@inquirer/core': 12.0.4(@types/node@24.19.1) - '@inquirer/type': 4.2.0(@types/node@24.19.1) + '@inquirer/core': 12.0.4(@types/node@24.19.2) + '@inquirer/type': 4.2.0(@types/node@24.19.2) optionalDependencies: - '@types/node': 24.19.1 + '@types/node': 24.19.2 '@inquirer/external-editor@3.0.6(@types/node@22.20.5)': dependencies: @@ -10247,12 +10247,12 @@ snapshots: optionalDependencies: '@types/node': 22.20.5 - '@inquirer/external-editor@3.0.6(@types/node@24.19.1)': + '@inquirer/external-editor@3.0.6(@types/node@24.19.2)': dependencies: chardet: 2.2.0 iconv-lite: 0.7.3 optionalDependencies: - '@types/node': 24.19.1 + '@types/node': 24.19.2 '@inquirer/figures@2.0.9': {} @@ -10263,12 +10263,12 @@ snapshots: optionalDependencies: '@types/node': 22.20.5 - '@inquirer/input@5.1.7(@types/node@24.19.1)': + '@inquirer/input@5.1.7(@types/node@24.19.2)': dependencies: - '@inquirer/core': 12.0.4(@types/node@24.19.1) - '@inquirer/type': 4.2.0(@types/node@24.19.1) + '@inquirer/core': 12.0.4(@types/node@24.19.2) + '@inquirer/type': 4.2.0(@types/node@24.19.2) optionalDependencies: - '@types/node': 24.19.1 + '@types/node': 24.19.2 '@inquirer/number@4.2.4(@types/node@22.20.5)': dependencies: @@ -10277,12 +10277,12 @@ snapshots: optionalDependencies: '@types/node': 22.20.5 - '@inquirer/number@4.2.4(@types/node@24.19.1)': + '@inquirer/number@4.2.4(@types/node@24.19.2)': dependencies: - '@inquirer/core': 12.0.4(@types/node@24.19.1) - '@inquirer/type': 4.2.0(@types/node@24.19.1) + '@inquirer/core': 12.0.4(@types/node@24.19.2) + '@inquirer/type': 4.2.0(@types/node@24.19.2) optionalDependencies: - '@types/node': 24.19.1 + '@types/node': 24.19.2 '@inquirer/password@5.2.3(@types/node@22.20.5)': dependencies: @@ -10292,13 +10292,13 @@ snapshots: optionalDependencies: '@types/node': 22.20.5 - '@inquirer/password@5.2.3(@types/node@24.19.1)': + '@inquirer/password@5.2.3(@types/node@24.19.2)': dependencies: '@inquirer/ansi': 2.0.9 - '@inquirer/core': 12.0.4(@types/node@24.19.1) - '@inquirer/type': 4.2.0(@types/node@24.19.1) + '@inquirer/core': 12.0.4(@types/node@24.19.2) + '@inquirer/type': 4.2.0(@types/node@24.19.2) optionalDependencies: - '@types/node': 24.19.1 + '@types/node': 24.19.2 '@inquirer/prompts@8.7.2(@types/node@22.20.5)': dependencies: @@ -10315,20 +10315,20 @@ snapshots: optionalDependencies: '@types/node': 22.20.5 - '@inquirer/prompts@8.7.3(@types/node@24.19.1)': - dependencies: - '@inquirer/checkbox': 5.2.6(@types/node@24.19.1) - '@inquirer/confirm': 6.3.3(@types/node@24.19.1) - '@inquirer/editor': 5.3.4(@types/node@24.19.1) - '@inquirer/expand': 5.1.6(@types/node@24.19.1) - '@inquirer/input': 5.1.7(@types/node@24.19.1) - '@inquirer/number': 4.2.4(@types/node@24.19.1) - '@inquirer/password': 5.2.3(@types/node@24.19.1) - '@inquirer/rawlist': 5.3.6(@types/node@24.19.1) - '@inquirer/search': 4.3.4(@types/node@24.19.1) - '@inquirer/select': 5.2.6(@types/node@24.19.1) + '@inquirer/prompts@8.7.3(@types/node@24.19.2)': + dependencies: + '@inquirer/checkbox': 5.2.6(@types/node@24.19.2) + '@inquirer/confirm': 6.3.3(@types/node@24.19.2) + '@inquirer/editor': 5.3.4(@types/node@24.19.2) + '@inquirer/expand': 5.1.6(@types/node@24.19.2) + '@inquirer/input': 5.1.7(@types/node@24.19.2) + '@inquirer/number': 4.2.4(@types/node@24.19.2) + '@inquirer/password': 5.2.3(@types/node@24.19.2) + '@inquirer/rawlist': 5.3.6(@types/node@24.19.2) + '@inquirer/search': 4.3.4(@types/node@24.19.2) + '@inquirer/select': 5.2.6(@types/node@24.19.2) optionalDependencies: - '@types/node': 24.19.1 + '@types/node': 24.19.2 '@inquirer/rawlist@5.3.6(@types/node@22.20.5)': dependencies: @@ -10337,12 +10337,12 @@ snapshots: optionalDependencies: '@types/node': 22.20.5 - '@inquirer/rawlist@5.3.6(@types/node@24.19.1)': + '@inquirer/rawlist@5.3.6(@types/node@24.19.2)': dependencies: - '@inquirer/core': 12.0.4(@types/node@24.19.1) - '@inquirer/type': 4.2.0(@types/node@24.19.1) + '@inquirer/core': 12.0.4(@types/node@24.19.2) + '@inquirer/type': 4.2.0(@types/node@24.19.2) optionalDependencies: - '@types/node': 24.19.1 + '@types/node': 24.19.2 '@inquirer/search@4.3.4(@types/node@22.20.5)': dependencies: @@ -10352,13 +10352,13 @@ snapshots: optionalDependencies: '@types/node': 22.20.5 - '@inquirer/search@4.3.4(@types/node@24.19.1)': + '@inquirer/search@4.3.4(@types/node@24.19.2)': dependencies: - '@inquirer/core': 12.0.4(@types/node@24.19.1) + '@inquirer/core': 12.0.4(@types/node@24.19.2) '@inquirer/figures': 2.0.9 - '@inquirer/type': 4.2.0(@types/node@24.19.1) + '@inquirer/type': 4.2.0(@types/node@24.19.2) optionalDependencies: - '@types/node': 24.19.1 + '@types/node': 24.19.2 '@inquirer/select@5.2.6(@types/node@22.20.5)': dependencies: @@ -10369,14 +10369,14 @@ snapshots: optionalDependencies: '@types/node': 22.20.5 - '@inquirer/select@5.2.6(@types/node@24.19.1)': + '@inquirer/select@5.2.6(@types/node@24.19.2)': dependencies: '@inquirer/ansi': 2.0.9 - '@inquirer/core': 12.0.4(@types/node@24.19.1) + '@inquirer/core': 12.0.4(@types/node@24.19.2) '@inquirer/figures': 2.0.9 - '@inquirer/type': 4.2.0(@types/node@24.19.1) + '@inquirer/type': 4.2.0(@types/node@24.19.2) optionalDependencies: - '@types/node': 24.19.1 + '@types/node': 24.19.2 '@inquirer/type@4.1.1(@types/node@22.20.5)': optionalDependencies: @@ -10386,9 +10386,9 @@ snapshots: optionalDependencies: '@types/node': 22.20.5 - '@inquirer/type@4.2.0(@types/node@24.19.1)': + '@inquirer/type@4.2.0(@types/node@24.19.2)': optionalDependencies: - '@types/node': 24.19.1 + '@types/node': 24.19.2 '@isaacs/cliui@8.0.2': dependencies: @@ -11467,7 +11467,7 @@ snapshots: dependencies: undici-types: 6.21.0 - '@types/node@24.19.1': + '@types/node@24.19.2': dependencies: undici-types: 7.24.6 @@ -14842,10 +14842,10 @@ snapshots: neo-async@2.6.2: {} - ng-packagr@22.2.4(@angular/compiler-cli@22.2.2(@angular/compiler@22.2.2)(typescript@6.0.3))(supports-color@11.0.0)(tslib@2.8.1)(typescript@6.0.3): + ng-packagr@22.2.4(@angular/compiler-cli@22.2.3(@angular/compiler@22.2.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.2(@angular/compiler@22.2.2)(typescript@6.0.3) + '@angular/compiler-cli': 22.2.3(@angular/compiler@22.2.3)(typescript@6.0.3) ajv: 8.20.0 browserslist: 4.29.3 chokidar: 5.0.0 From c1c4216a680891b80670660a621d6736c4aecaf0 Mon Sep 17 00:00:00 2001 From: Charles Lyding <19598772+clydin@users.noreply.github.com> Date: Wed, 14 Oct 2026 16:54:52 -0400 Subject: [PATCH 100/233] fix(@angular/build): coalesce external watcher directories to avoid macOS FSEvents limit Previously, `ParcelExternalManager` immediately created a separate `@parcel/watcher` subscription for the parent directory of every watched file outside the workspace root. In monorepo setups where an application imports from hundreds of external library directories and hoisted `node_modules` packages, this exceeded macOS's ~512 per-process `FSEvents` stream limit, causing subsequent subscriptions to silently fail and miss file changes. To prevent exhausting native watcher streams, `ParcelExternalManager` now normalizes external `node_modules` file paths to their package root directory and batches synchronous file additions and removals within a microtask so nested child directories are subsumed before subscribing. When the number of external target directories exceeds the subscription budget of 256, a prefix tree is used to iteratively collapse the deepest branching subdirectories into common ancestors while preferring directories that do not contain `workspaceRoot`. Additionally, if `parcelWatcher.subscribe()` rejects for an existing directory on disk, the manager dynamically lowers its subscription budget and re-reconciles into higher-level ancestor directories. Closes #34246 (cherry picked from commit d2233e225aa5fd507e3ce7bfd35ae2268c036aa4) --- packages/angular/build/BUILD.bazel | 1 + packages/angular/build/src/utils/watcher.ts | 582 +++++++++++++++--- .../angular/build/src/utils/watcher_spec.ts | 361 +++++++++++ 3 files changed, 866 insertions(+), 78 deletions(-) diff --git a/packages/angular/build/BUILD.bazel b/packages/angular/build/BUILD.bazel index e77d03277780..b8432b0d8f36 100644 --- a/packages/angular/build/BUILD.bazel +++ b/packages/angular/build/BUILD.bazel @@ -146,6 +146,7 @@ ts_project( ":build", ":node_modules/@angular-devkit/core", ":node_modules/@babel/core", + ":node_modules/@parcel/watcher", ":node_modules/oxc-parser", "//:node_modules/@angular/compiler-cli", "//:node_modules/@angular/router", diff --git a/packages/angular/build/src/utils/watcher.ts b/packages/angular/build/src/utils/watcher.ts index 610051c5dcc7..ca0e86f987ff 100644 --- a/packages/angular/build/src/utils/watcher.ts +++ b/packages/angular/build/src/utils/watcher.ts @@ -419,89 +419,364 @@ export function extractNodeModulesPackageDir(posixPath: string): string | undefi return `${nodeModulesPath}/${segments[0]}`; } -class ParcelExternalManager { - private readonly extraSubscriptions = new Map(); - private readonly pendingSubscriptions = new Map< - string, - Promise - >(); - private readonly externalDirFiles = new Map }>(); +/** + * Maximum number of concurrent external directory subscriptions before coalescing + * sibling/cousin directories into common ancestor directories. + * Kept well below macOS's ~512 per-process FSEvents stream limit. + */ +const DEFAULT_MAX_EXTERNAL_SUBSCRIPTIONS = 256; + +/** + * Node in a directory prefix tree used to subsume nested directories + * and coalesce sibling/cousin directories into common ancestors. + */ +interface DirTrieNode { + /** Case-normalized POSIX path key for set/map lookups. */ + dirKey: string; + + /** Original-case POSIX directory path passed to `@parcel/watcher`. */ + dirPath: string; + + /** Depth of this directory node from the filesystem root (0 at root). */ + depth: number; + + /** Parent directory node, or `undefined` if this node is a filesystem root. */ + parent: DirTrieNode | undefined; + + /** Child directory nodes keyed by their `dirKey`. */ + children: Map; + + /** Whether this directory is selected as an active subscription target. */ + isTarget: boolean; + + /** Number of active target leaf directories within this node's subtree. */ + leafCount: number; +} + +/** + * Checks whether any strict ancestor of the given trie node is already marked as a target. + */ +function hasTargetAncestor(node: DirTrieNode): boolean { + let current = node.parent; + while (current) { + if (current.isTarget) { + return true; + } + current = current.parent; + } + + return false; +} + +/** + * Manages `@parcel/watcher` directory subscriptions for watched files located outside the + * primary `workspaceRoot`. + * + * Because `@parcel/watcher` watches directories recursively and macOS limits each process to + * ~512 concurrent `FSEvents` streams, this manager: + * - Normalizes external `node_modules` file paths to their package root directory. + * - Batches synchronous `watchFile` and `removeFile` calls within a microtask before subscribing. + * - Uses a directory prefix tree to subsume nested child directories and iteratively coalesce + * deepest branching subdirectories into common ancestors when the subscription budget is exceeded. + * - Dynamically lowers its subscription budget and coalesces further if `subscribe()` fails on + * an existing directory due to OS stream limits. + */ +export class ParcelExternalManager { + /** Active `@parcel/watcher` subscriptions keyed by subscribed directory lookup key. */ + readonly #extraSubscriptions = new Map(); + + /** Reference-counted watched files grouped by their target external directory lookup key. */ + readonly #externalDirFiles = new Map }>(); + + /** Reverse lookup mapping each watched file lookup key to its target directory lookup key. */ + readonly #fileToDirKey = new Map(); + + /** The `@parcel/watcher` module instance. */ + readonly #parcelWatcher: typeof ParcelWatcher; + + /** Watcher configuration options including ignore patterns. */ + readonly #options: WatcherOptions | undefined; + + /** Normalized POSIX path of the primary watched workspace root. */ + readonly #rootDirPosix: string; + + /** Case-normalized lookup key of the primary watched workspace root. */ + readonly #rootDirLookupKey: string; + + /** Whether the underlying filesystem is case-sensitive. */ + readonly #isCaseSensitive: boolean; + + /** Callback invoked when `@parcel/watcher` emits filesystem events. */ + readonly #handleEvents: (events: ParcelWatcher.Event[]) => void; + + /** Current maximum number of concurrent external directory subscriptions allowed before coalescing. */ + #maxSubscriptions: number; + + /** Whether external directory state has changed and requires a reconciliation pass. */ + #needsReconcile = false; + + /** Whether obsolete subscriptions should be unsubscribed before creating new ones (used after stream limit errors). */ + #shrinkBeforeSubscribe = false; + /** In-flight promise for the currently scheduled or running reconciliation loop. */ + #reconcilePromise: Promise | undefined; + + /** Whether this manager has been closed. */ + #isClosed = false; + + /** + * Creates a new external directory subscription manager for `@parcel/watcher`. + * + * @param parcelWatcher The `@parcel/watcher` module. + * @param options Watcher configuration options. + * @param rootDirPosix Normalized POSIX path of the primary workspace root. + * @param rootDirLookupKey Case-normalized lookup key of the primary workspace root. + * @param isCaseSensitive Whether the filesystem at the workspace root is case-sensitive. + * @param handleEvents Callback to process incoming `@parcel/watcher` events. + * @param maxSubscriptions Maximum number of concurrent external directory subscriptions before coalescing. + */ constructor( - private readonly parcelWatcher: typeof ParcelWatcher, - private readonly options: WatcherOptions | undefined, - private readonly rootDirLookupKey: string, - private readonly handleEvents: (events: ParcelWatcher.Event[]) => void, - ) {} + parcelWatcher: typeof ParcelWatcher, + options: WatcherOptions | undefined, + rootDirPosix: string, + rootDirLookupKey: string, + isCaseSensitive: boolean, + handleEvents: (events: ParcelWatcher.Event[]) => void, + maxSubscriptions = DEFAULT_MAX_EXTERNAL_SUBSCRIPTIONS, + ) { + this.#parcelWatcher = parcelWatcher; + this.#options = options; + this.#rootDirPosix = rootDirPosix; + this.#rootDirLookupKey = rootDirLookupKey; + this.#isCaseSensitive = isCaseSensitive; + this.#handleEvents = handleEvents; + this.#maxSubscriptions = Math.max(1, maxSubscriptions); + } - async ensureWatched(posixPath: string, lookupKey: string): Promise { - if (isPathInside(lookupKey, this.rootDirLookupKey) || lookupKey === this.rootDirLookupKey) { + /** + * Registers a file path to be watched if it resides outside the primary workspace root, + * and schedules an asynchronous subscription reconciliation pass if needed. + * + * @param posixPath Normalized POSIX file path preserving original casing. + * @param lookupKey Case-normalized lookup key for the file path. + */ + watchFile(posixPath: string, lookupKey: string): void { + if ( + this.#isClosed || + isPathInside(lookupKey, this.#rootDirLookupKey) || + lookupKey === this.#rootDirLookupKey + ) { return; } - const dirPath = getDirectoryPath(posixPath); - const dirKey = getDirectoryPath(lookupKey); - let dirEntry = this.externalDirFiles.get(dirKey); + const pkgDir = extractNodeModulesPackageDir(posixPath); + const dirPath = pkgDir ?? getDirectoryPath(posixPath); + const dirKey = pkgDir + ? toLookupKey(pkgDir, this.#isCaseSensitive) + : getDirectoryPath(lookupKey); + + this.#fileToDirKey.set(lookupKey, dirKey); + + let dirEntry = this.#externalDirFiles.get(dirKey); + const isNewDir = !dirEntry; if (!dirEntry) { dirEntry = { dirPath, files: new Set() }; - this.externalDirFiles.set(dirKey, dirEntry); + this.#externalDirFiles.set(dirKey, dirEntry); } dirEntry.files.add(lookupKey); - await this.ensureDirWatched(dirPath, dirKey); + if (isNewDir || !this.#isCoveredByActiveSubscription(dirKey)) { + this.#scheduleReconcile(); + } } + /** + * Unregisters a previously watched external file and schedules a reconciliation pass + * if it was the last watched file in its target directory. + * + * @param lookupKey Case-normalized lookup key for the file path to remove. + */ removeFile(lookupKey: string): void { - if (isPathInside(lookupKey, this.rootDirLookupKey) || lookupKey === this.rootDirLookupKey) { + const dirKey = this.#fileToDirKey.get(lookupKey); + if (!dirKey) { return; } - const dirKey = getDirectoryPath(lookupKey); - const dirEntry = this.externalDirFiles.get(dirKey); + this.#fileToDirKey.delete(lookupKey); + const dirEntry = this.#externalDirFiles.get(dirKey); if (dirEntry) { dirEntry.files.delete(lookupKey); if (dirEntry.files.size === 0) { - this.externalDirFiles.delete(dirKey); - const sub = this.extraSubscriptions.get(dirKey); - if (sub) { - this.extraSubscriptions.delete(dirKey); - sub.unsubscribe().catch(() => {}); - - for (const [remainingDirKey, remainingDirEntry] of this.externalDirFiles.entries()) { - if (!this.isCoveredByExistingExternal(remainingDirKey)) { - this.ensureDirWatched(remainingDirEntry.dirPath, remainingDirKey).catch(() => {}); - } - } - } + this.#externalDirFiles.delete(dirKey); + this.#scheduleReconcile(); } } } + /** + * Waits for any scheduled or in-progress subscription reconciliation pass to complete. + */ + async flush(): Promise { + if (this.#reconcilePromise) { + await this.#reconcilePromise; + } + } + + /** + * Closes the manager, awaiting any pending reconciliation and unsubscribing all active + * external directory subscriptions. + */ async close(): Promise { + this.#isClosed = true; + this.#needsReconcile = false; try { - if (this.pendingSubscriptions.size > 0) { - await Promise.allSettled(Array.from(this.pendingSubscriptions.values())); + if (this.#reconcilePromise) { + await this.#reconcilePromise.catch(() => {}); } - if (this.extraSubscriptions.size > 0) { + if (this.#extraSubscriptions.size > 0) { await Promise.allSettled( - Array.from(this.extraSubscriptions.values()).map((sub) => sub.unsubscribe()), + Array.from(this.#extraSubscriptions.values(), (sub) => sub.unsubscribe()), ); } } finally { - this.extraSubscriptions.clear(); - this.pendingSubscriptions.clear(); - this.externalDirFiles.clear(); + this.#extraSubscriptions.clear(); + this.#externalDirFiles.clear(); + this.#fileToDirKey.clear(); } } - private isCoveredByExistingExternal(dirLookupKey: string): boolean { - for (const existingDir of this.extraSubscriptions.keys()) { - if (dirLookupKey === existingDir || isPathInside(dirLookupKey, existingDir)) { - return true; + /** + * Schedules a microtask to reconcile active `@parcel/watcher` subscriptions with the + * current set of external directories. + */ + #scheduleReconcile(): void { + if (this.#isClosed) { + return; + } + + this.#needsReconcile = true; + this.#reconcilePromise ??= Promise.resolve() + .then(() => this.#runReconcileLoop()) + .finally(() => { + this.#reconcilePromise = undefined; + }); + } + + /** + * Continuously executes reconciliation passes until no further changes are pending. + */ + async #runReconcileLoop(): Promise { + while (this.#needsReconcile && !this.#isClosed) { + this.#needsReconcile = false; + await this.#reconcileOnce(); + } + } + + /** + * Performs a single reconciliation pass: computes the desired coalesced directory set, + * subscribes to newly required directories, unsubscribes obsolete directories, and + * triggers fallback coalescing if OS stream limits are encountered. + */ + async #reconcileOnce(): Promise { + const desiredDirs = this.#computeDesiredDirectories(); + + if (this.#shrinkBeforeSubscribe) { + this.#shrinkBeforeSubscribe = false; + const toUnsubscribe: Promise[] = []; + for (const [existingKey, sub] of this.#extraSubscriptions.entries()) { + if (!desiredDirs.has(existingKey)) { + this.#extraSubscriptions.delete(existingKey); + toUnsubscribe.push(sub.unsubscribe().catch(() => {})); + } + } + if (toUnsubscribe.length > 0) { + await Promise.allSettled(toUnsubscribe); } } - for (const pendingDir of this.pendingSubscriptions.keys()) { - if (dirLookupKey === pendingDir || isPathInside(dirLookupKey, pendingDir)) { + + if (this.#isClosed) { + return; + } + + const toSubscribe: [string, string][] = []; + for (const [dirKey, dirPath] of desiredDirs.entries()) { + if (!this.#extraSubscriptions.has(dirKey)) { + toSubscribe.push([dirKey, dirPath]); + } + } + + let hadExistingDirFailure = false; + if (toSubscribe.length > 0) { + await Promise.allSettled( + toSubscribe.map(async ([dirKey, dirPath]) => { + const ignore = isPathInside(this.#rootDirLookupKey, dirKey) + ? [...(this.#options?.ignored ?? []), this.#rootDirPosix, `${this.#rootDirPosix}/**`] + : this.#options?.ignored; + + try { + const sub = await this.#parcelWatcher.subscribe( + dirPath, + (err, events) => { + if (!err) { + this.#handleEvents(events); + } + }, + { ignore }, + ); + + if (this.#isClosed) { + await sub.unsubscribe().catch(() => {}); + + return; + } + + this.#extraSubscriptions.set(dirKey, sub); + } catch { + // Ignore errors for missing directories; if the directory exists on disk, + // mark failure so the manager can coalesce further if over OS stream limits. + if (!this.#isClosed && fs.existsSync(dirPath)) { + hadExistingDirFailure = true; + } + } + }), + ); + } + + if (this.#isClosed) { + return; + } + + // Unsubscribe any previous subscriptions that are no longer desired and whose + // remaining watched files (if any) are now covered by another active subscription. + for (const [existingKey, sub] of this.#extraSubscriptions.entries()) { + if (!desiredDirs.has(existingKey) && this.#canRemoveSubscription(existingKey)) { + this.#extraSubscriptions.delete(existingKey); + sub.unsubscribe().catch(() => {}); + } + } + + // If subscribing to an existing directory failed (e.g. macOS FSEvents per-process limit), + // dynamically lower the subscription budget and re-reconcile to coalesce into ancestors. + if (hadExistingDirFailure && desiredDirs.size > 1 && this.#maxSubscriptions > 1) { + const nextMax = + this.#extraSubscriptions.size > 0 + ? Math.max(1, Math.floor(this.#extraSubscriptions.size / 2)) + : Math.max(1, Math.floor(Math.min(this.#maxSubscriptions, desiredDirs.size) / 2)); + + if (nextMax < desiredDirs.size && nextMax < this.#maxSubscriptions) { + this.#maxSubscriptions = nextMax; + this.#shrinkBeforeSubscribe = true; + this.#needsReconcile = true; + } + } + } + + /** + * Checks whether a directory lookup key is already covered by an active subscription. + */ + #isCoveredByActiveSubscription(dirLookupKey: string): boolean { + for (const existingDir of this.#extraSubscriptions.keys()) { + if (dirLookupKey === existingDir || isPathInside(dirLookupKey, existingDir)) { return true; } } @@ -509,47 +784,196 @@ class ParcelExternalManager { return false; } - private async ensureDirWatched(dirPath: string, dirKey: string): Promise { - if (this.isCoveredByExistingExternal(dirKey)) { - return; + /** + * Determines whether an existing subscription can be safely removed without leaving + * any remaining watched target directories uncovered. + */ + #canRemoveSubscription(subKey: string): boolean { + for (const targetDirKey of this.#externalDirFiles.keys()) { + if (targetDirKey === subKey || isPathInside(targetDirKey, subKey)) { + let coveredByOther = false; + for (const otherSubKey of this.#extraSubscriptions.keys()) { + if ( + otherSubKey !== subKey && + (targetDirKey === otherSubKey || isPathInside(targetDirKey, otherSubKey)) + ) { + coveredByOther = true; + break; + } + } + if (!coveredByOther) { + return false; + } + } + } + + return true; + } + + /** + * Computes the minimal set of external directories to subscribe to (mapped from `dirKey` to `dirPath`), + * subsuming nested directories and coalescing branching ancestors to stay within `#maxSubscriptions`. + */ + #computeDesiredDirectories(): Map { + if (this.#externalDirFiles.size === 0) { + return new Map(); } - const subPromise = this.parcelWatcher.subscribe( - dirPath, - (err, events) => { - if (!err) { - this.handleEvents(events); + const nodesByKey = new Map(); + const roots: DirTrieNode[] = []; + + for (const [dirKey, { dirPath }] of this.#externalDirFiles.entries()) { + const chain: { dirKey: string; dirPath: string }[] = []; + let currentKey = dirKey; + let currentPath = dirPath; + while (true) { + chain.push({ dirKey: currentKey, dirPath: currentPath }); + const parentKey = getDirectoryPath(currentKey); + if (parentKey === currentKey) { + break; } - }, - { - ignore: this.options?.ignored, - }, - ); + currentKey = parentKey; + currentPath = getDirectoryPath(currentPath); + } - this.pendingSubscriptions.set(dirKey, subPromise); + let parentNode: DirTrieNode | undefined; + for (let i = chain.length - 1; i >= 0; i--) { + const { dirKey: nodeKey, dirPath: nodePath } = chain[i]; + const depth = chain.length - 1 - i; + let node = nodesByKey.get(nodeKey); + if (!node) { + node = { + dirKey: nodeKey, + dirPath: nodePath, + depth, + parent: parentNode, + children: new Map(), + isTarget: false, + leafCount: 0, + }; + nodesByKey.set(nodeKey, node); + if (parentNode) { + parentNode.children.set(nodeKey, node); + } else { + roots.push(node); + } + } + parentNode = node; + } - try { - const sub = await subPromise; - this.pendingSubscriptions.delete(dirKey); + if (parentNode) { + parentNode.isTarget = true; + } + } - if (this.externalDirFiles.has(dirKey) && !this.isCoveredByExistingExternal(dirKey)) { - this.extraSubscriptions.set(dirKey, sub); + const initSubtree = (node: DirTrieNode): number => { + if (node.isTarget) { + node.children.clear(); + node.leafCount = 1; - // Subsume any nested child subscriptions that are now covered by this parent subscription - for (const [childDir, childSub] of this.extraSubscriptions.entries()) { - if (childDir !== dirKey && isPathInside(childDir, dirKey)) { - this.extraSubscriptions.delete(childDir); - childSub.unsubscribe().catch(() => {}); + return 1; + } + + let count = 0; + for (const child of node.children.values()) { + count += initSubtree(child); + } + node.leafCount = count; + + return count; + }; + + let totalLeaves = 0; + for (const root of roots) { + totalLeaves += initSubtree(root); + } + + if (totalLeaves > this.#maxSubscriptions) { + // Tier 1: non-ancestors of workspaceRoot (e.g., /libs, /node_modules) + // Tier 2: ancestors of workspaceRoot (e.g., when sibling apps/libs are directly under it) + const tier1ByDepth = new Map(); + const tier2ByDepth = new Map(); + + const collectInternalNodes = (node: DirTrieNode) => { + if (node.isTarget) { + return; + } + if (node.parent !== undefined && node.leafCount > 1) { + const isWorkspaceAncestor = isPathInside(this.#rootDirLookupKey, node.dirKey); + const bucketMap = isWorkspaceAncestor ? tier2ByDepth : tier1ByDepth; + let bucket = bucketMap.get(node.depth); + if (!bucket) { + bucket = []; + bucketMap.set(node.depth, bucket); } + bucket.push(node); } - } else { - sub.unsubscribe().catch(() => {}); + for (const child of node.children.values()) { + collectInternalNodes(child); + } + }; + + for (const root of roots) { + collectInternalNodes(root); + } + + const collapseTier = (byDepth: Map) => { + const sortedLevels = Array.from(byDepth.entries()).sort(([a], [b]) => b - a); + for (const [, nodes] of sortedLevels) { + if (totalLeaves <= this.#maxSubscriptions) { + return; + } + + const candidates = nodes + .filter((n) => n.leafCount > 1 && !hasTargetAncestor(n)) + .sort((a, b) => b.leafCount - a.leafCount || a.dirKey.localeCompare(b.dirKey)); + + for (const candidate of candidates) { + if (totalLeaves <= this.#maxSubscriptions) { + return; + } + if (candidate.leafCount <= 1 || hasTargetAncestor(candidate)) { + continue; + } + + const reduction = candidate.leafCount - 1; + candidate.isTarget = true; + candidate.children.clear(); + candidate.leafCount = 1; + totalLeaves -= reduction; + + let ancestor = candidate.parent; + while (ancestor) { + ancestor.leafCount -= reduction; + ancestor = ancestor.parent; + } + } + } + }; + + collapseTier(tier1ByDepth); + if (totalLeaves > this.#maxSubscriptions) { + collapseTier(tier2ByDepth); } - } catch { - // Ignore subscription errors for missing or restricted external directories - } finally { - this.pendingSubscriptions.delete(dirKey); } + + const desired = new Map(); + const collectTargets = (node: DirTrieNode) => { + if (node.isTarget) { + desired.set(node.dirKey, node.dirPath); + + return; + } + for (const child of node.children.values()) { + collectTargets(child); + } + }; + + for (const root of roots) { + collectTargets(root); + } + + return desired; } } @@ -609,7 +1033,9 @@ async function createParcelWatcher( const externalManager = new ParcelExternalManager( parcelWatcher, options, + rootDirPosix, rootDirLookupKey, + isCaseSensitive, handleEvents, ); @@ -629,7 +1055,7 @@ async function createParcelWatcher( const lookupKey = toLookupKey(posixPath, isCaseSensitive); if (!watchedFiles.has(lookupKey)) { watchedFiles.add(lookupKey); - void externalManager.ensureWatched(posixPath, lookupKey); + externalManager.watchFile(posixPath, lookupKey); } } }, diff --git a/packages/angular/build/src/utils/watcher_spec.ts b/packages/angular/build/src/utils/watcher_spec.ts index 547ad2695f90..3703eb9f4ce1 100644 --- a/packages/angular/build/src/utils/watcher_spec.ts +++ b/packages/angular/build/src/utils/watcher_spec.ts @@ -6,6 +6,7 @@ * found in the LICENSE file at https://angular.dev/license */ +import type * as ParcelWatcher from '@parcel/watcher'; import assert from 'node:assert'; import * as fs from 'node:fs'; import * as path from 'node:path'; @@ -13,6 +14,7 @@ import { setTimeout } from 'node:timers/promises'; import { type BuildWatcher, ChangedFiles, + ParcelExternalManager, createWatcher, extractNodeModulesPackageDir, getDirectoryPath, @@ -829,5 +831,364 @@ describe('Watcher', () => { fs.rmSync(externalDir, { recursive: true, force: true }); } }, 10000); + + it('should detect changes across multiple external directories when using @parcel/watcher', async () => { + const externalRoot = fs.mkdtempSync(path.join(TMP_DIR, 'parcel-external-spec-')); + let watcher: BuildWatcher | undefined; + + try { + const lib1Dir = path.join(externalRoot, 'libs', 'lib-1', 'src'); + const lib2Dir = path.join(externalRoot, 'libs', 'lib-2', 'src'); + fs.mkdirSync(lib1Dir, { recursive: true }); + fs.mkdirSync(lib2Dir, { recursive: true }); + + const file1 = path.join(lib1Dir, 'index.ts'); + const file2 = path.join(lib2Dir, 'index.ts'); + fs.writeFileSync(file1, 'export const a = 1;'); + fs.writeFileSync(file2, 'export const b = 1;'); + + // Backdate initial file timestamps to earlier than `initTime - 1000` so that any + // delayed initial FSEvents replay from file creation is ignored by the watcher. + const pastTime = new Date(Date.now() - 5000); + fs.utimesSync(file1, pastTime, pastTime); + fs.utimesSync(file2, pastTime, pastTime); + + watcher = await createWatcher({ cwd: tempDir }); + watcher.add([file1, file2]); + + await setTimeout(150); + + const iterator = watcher[Symbol.asyncIterator](); + + let nextPromise = iterator.next(); + fs.writeFileSync(file1, 'export const a = 2;'); + let result = await nextPromise; + expect(result.done).toBeFalsy(); + expect(result.value?.all.some((f: string) => f.includes('lib-1'))).toBeTrue(); + + nextPromise = iterator.next(); + fs.writeFileSync(file2, 'export const b = 2;'); + result = await nextPromise; + expect(result.done).toBeFalsy(); + expect(result.value?.all.some((f: string) => f.includes('lib-2'))).toBeTrue(); + } finally { + await watcher?.close(); + fs.rmSync(externalRoot, { recursive: true, force: true }); + } + }, 10000); + }); + + describe('ParcelExternalManager', () => { + function createMockParcelWatcher(options?: { + failAfter?: number; + onSubscribe?: (dir: string, opts?: ParcelWatcher.Options) => void; + }) { + const activeDirs = new Set(); + const subscribeHistory: { dir: string; options?: ParcelWatcher.Options }[] = []; + let totalCalls = 0; + + const mockWatcher = { + subscribe: jasmine + .createSpy('subscribe') + .and.callFake( + async ( + dir: string, + _cb: ParcelWatcher.SubscribeCallback, + opts?: ParcelWatcher.Options, + ): Promise => { + totalCalls++; + options?.onSubscribe?.(dir, opts); + if (options?.failAfter !== undefined && activeDirs.size >= options.failAfter) { + throw new Error('Error starting FSEvents stream'); + } + activeDirs.add(dir); + subscribeHistory.push({ dir, options: opts }); + + return { + unsubscribe: async () => { + activeDirs.delete(dir); + }, + }; + }, + ), + } as unknown as typeof ParcelWatcher; + + return { + mockWatcher, + activeDirs, + subscribeHistory, + getTotalCalls: () => totalCalls, + }; + } + + it('should batch synchronous watchFile calls and subsume child directories added before parent', async () => { + const { mockWatcher, activeDirs, getTotalCalls } = createMockParcelWatcher(); + const manager = new ParcelExternalManager( + mockWatcher, + undefined, + '/monorepo/apps/app', + '/monorepo/apps/app', + true, + () => {}, + ); + + // Add deeper child directories first, then their parent directory in the same synchronous turn + manager.watchFile( + '/monorepo/libs/lib-1/src/components/button/button.ts', + '/monorepo/libs/lib-1/src/components/button/button.ts', + ); + manager.watchFile( + '/monorepo/libs/lib-1/src/components/card/card.ts', + '/monorepo/libs/lib-1/src/components/card/card.ts', + ); + manager.watchFile('/monorepo/libs/lib-1/src/index.ts', '/monorepo/libs/lib-1/src/index.ts'); + + await manager.flush(); + + // Should only ever have subscribed once to the parent '/monorepo/libs/lib-1/src' + expect(getTotalCalls()).toBe(1); + expect(Array.from(activeDirs)).toEqual(['/monorepo/libs/lib-1/src']); + + await manager.close(); + }); + + it('should normalize external node_modules paths to their package root directory', async () => { + const { mockWatcher, activeDirs, getTotalCalls } = createMockParcelWatcher(); + const manager = new ParcelExternalManager( + mockWatcher, + undefined, + '/monorepo/apps/app', + '/monorepo/apps/app', + true, + () => {}, + ); + + manager.watchFile( + '/monorepo/node_modules/my-pkg/fesm2022/my-pkg.mjs', + '/monorepo/node_modules/my-pkg/fesm2022/my-pkg.mjs', + ); + manager.watchFile( + '/monorepo/node_modules/my-pkg/esm2022/sub/helper.mjs', + '/monorepo/node_modules/my-pkg/esm2022/sub/helper.mjs', + ); + manager.watchFile( + '/monorepo/node_modules/@scope/scoped-pkg/fesm2022/index.mjs', + '/monorepo/node_modules/@scope/scoped-pkg/fesm2022/index.mjs', + ); + manager.watchFile( + '/monorepo/node_modules/@scope/scoped-pkg/package.json', + '/monorepo/node_modules/@scope/scoped-pkg/package.json', + ); + + await manager.flush(); + + expect(getTotalCalls()).toBe(2); + expect(Array.from(activeDirs).sort()).toEqual([ + '/monorepo/node_modules/@scope/scoped-pkg', + '/monorepo/node_modules/my-pkg', + ]); + + // Removing one file from my-pkg should keep the package subscription active + manager.removeFile('/monorepo/node_modules/my-pkg/fesm2022/my-pkg.mjs'); + await manager.flush(); + expect(activeDirs.has('/monorepo/node_modules/my-pkg')).toBeTrue(); + + // Removing the last file from my-pkg should unsubscribe the package directory + manager.removeFile('/monorepo/node_modules/my-pkg/esm2022/sub/helper.mjs'); + await manager.flush(); + expect(activeDirs.has('/monorepo/node_modules/my-pkg')).toBeFalse(); + expect(Array.from(activeDirs)).toEqual(['/monorepo/node_modules/@scope/scoped-pkg']); + + await manager.close(); + }); + + it('should coalesce large numbers of external library and node_modules directories into common ancestors within budget', async () => { + const { mockWatcher, activeDirs, getTotalCalls } = createMockParcelWatcher(); + const manager = new ParcelExternalManager( + mockWatcher, + undefined, + '/monorepo/apps/app', + '/monorepo/apps/app', + true, + () => {}, + 64, + ); + + // Simulate 600 sibling libraries and 200 hoisted node_modules packages (800 external dirs) + for (let i = 0; i < 600; i++) { + const file = `/monorepo/libs/lib-${i}/src/index.ts`; + manager.watchFile(file, file); + } + for (let i = 0; i < 200; i++) { + const file = `/monorepo/node_modules/pkg-${i}/dist/index.mjs`; + manager.watchFile(file, file); + } + + await manager.flush(); + + // All 600 libs coalesce into '/monorepo/libs' and all 200 packages coalesce into '/monorepo/node_modules' + expect(getTotalCalls()).toBe(2); + expect(Array.from(activeDirs).sort()).toEqual(['/monorepo/libs', '/monorepo/node_modules']); + + await manager.close(); + }); + + it('should prioritize collapsing deeper branching subdirectories before broader ancestor directories', async () => { + const { mockWatcher, activeDirs } = createMockParcelWatcher(); + const manager = new ParcelExternalManager( + mockWatcher, + undefined, + '/monorepo/apps/app', + '/monorepo/apps/app', + true, + () => {}, + 3, // Budget of 3 subscriptions + ); + + // lib-1 has 4 component subdirectories, lib-2 and lib-3 have 1 each (total = 6 leaf dirs) + for (let c = 1; c <= 4; c++) { + const file = `/monorepo/libs/lib-1/src/comp-${c}/comp.ts`; + manager.watchFile(file, file); + } + manager.watchFile('/monorepo/libs/lib-2/src/index.ts', '/monorepo/libs/lib-2/src/index.ts'); + manager.watchFile('/monorepo/libs/lib-3/src/index.ts', '/monorepo/libs/lib-3/src/index.ts'); + + await manager.flush(); + + // Collapsing lib-1/src reduces total leaves from 6 to 3, meeting the budget of 3 + // without needing to collapse all of '/monorepo/libs' + expect(Array.from(activeDirs).sort()).toEqual([ + '/monorepo/libs/lib-1/src', + '/monorepo/libs/lib-2/src', + '/monorepo/libs/lib-3/src', + ]); + + await manager.close(); + }); + + it('should ignore workspaceRoot when coalescing into an ancestor of workspaceRoot (Tier 2)', async () => { + const { mockWatcher, activeDirs, subscribeHistory } = createMockParcelWatcher(); + const manager = new ParcelExternalManager( + mockWatcher, + { ignored: ['/monorepo/apps/app/dist'] }, + '/monorepo/apps/app', + '/monorepo/apps/app', + true, + () => {}, + 2, // Budget of 2 subscriptions + ); + + // Sibling apps/packages directly under /monorepo/apps (which is an ancestor of /monorepo/apps/app) + manager.watchFile( + '/monorepo/apps/shared-1/src/index.ts', + '/monorepo/apps/shared-1/src/index.ts', + ); + manager.watchFile( + '/monorepo/apps/shared-2/src/index.ts', + '/monorepo/apps/shared-2/src/index.ts', + ); + manager.watchFile( + '/monorepo/apps/shared-3/src/index.ts', + '/monorepo/apps/shared-3/src/index.ts', + ); + + await manager.flush(); + + expect(Array.from(activeDirs)).toEqual(['/monorepo/apps']); + expect(subscribeHistory.length).toBe(1); + expect(subscribeHistory[0].options?.ignore).toEqual([ + '/monorepo/apps/app/dist', + '/monorepo/apps/app', + '/monorepo/apps/app/**', + ]); + + await manager.close(); + }); + + it('should dynamically lower budget and coalesce into ancestor when subscribe fails with FSEvents stream limit error', async () => { + const externalRoot = fs.mkdtempSync(path.join(TMP_DIR, 'parcel-fallback-spec-')); + + try { + const rootPosix = toPosixPathNormalized(path.join(externalRoot, 'apps', 'app')); + const libFiles: string[] = []; + for (let i = 0; i < 6; i++) { + const libDir = path.join(externalRoot, 'libs', `lib-${i}`, 'src'); + fs.mkdirSync(libDir, { recursive: true }); + const file = toPosixPathNormalized(path.join(libDir, 'index.ts')); + fs.writeFileSync(file, 'export const x = 1;'); + libFiles.push(file); + } + + // Allow at most 2 active FSEvents streams even though manager budget starts at 64 + const { mockWatcher, activeDirs } = createMockParcelWatcher({ failAfter: 2 }); + const manager = new ParcelExternalManager( + mockWatcher, + undefined, + rootPosix, + rootPosix, + true, + () => {}, + 64, + ); + + for (const file of libFiles) { + manager.watchFile(file, file); + } + + await manager.flush(); + + // Should have shrunk and coalesced the 6 libraries into the single '/libs' ancestor directory + const expectedLibsDir = toPosixPathNormalized(path.join(externalRoot, 'libs')); + expect(Array.from(activeDirs)).toEqual([expectedLibsDir]); + + await manager.close(); + } finally { + fs.rmSync(externalRoot, { recursive: true, force: true }); + } + }); + + it('should uncoalesce and subscribe to remaining leaf directories when removals bring count back within budget', async () => { + const { mockWatcher, activeDirs } = createMockParcelWatcher(); + const manager = new ParcelExternalManager( + mockWatcher, + undefined, + '/monorepo/apps/app', + '/monorepo/apps/app', + true, + () => {}, + 2, // Budget of 2 subscriptions + ); + + const file1 = '/monorepo/libs/lib-1/src/index.ts'; + const file2 = '/monorepo/libs/lib-2/src/index.ts'; + const file3 = '/monorepo/libs/lib-3/src/index.ts'; + + manager.watchFile(file1, file1); + manager.watchFile(file2, file2); + manager.watchFile(file3, file3); + + await manager.flush(); + + // 3 directories exceed budget of 2, so they coalesce into '/monorepo/libs' + expect(Array.from(activeDirs)).toEqual(['/monorepo/libs']); + + // Removing file3 brings remaining directories to 2, which fits within budget + manager.removeFile(file3); + await manager.flush(); + + expect(Array.from(activeDirs).sort()).toEqual([ + '/monorepo/libs/lib-1/src', + '/monorepo/libs/lib-2/src', + ]); + + // Removing the remaining files unsubscribes everything + manager.removeFile(file1); + manager.removeFile(file2); + await manager.flush(); + + expect(activeDirs.size).toBe(0); + + await manager.close(); + }); }); }); From cc05ecf28b8c4b09a6604973e39458d6c673d3e8 Mon Sep 17 00:00:00 2001 From: Angular Robot Date: Thu, 15 Oct 2026 06:48:42 +0000 Subject: [PATCH 101/233] build: update pnpm to v12.11.2 See associated pull request for more information. --- MODULE.bazel | 4 +- MODULE.bazel.lock | 2 +- package.json | 4 +- pnpm-lock.yaml | 122 +++++++++++++++++++++++----------------------- 4 files changed, 66 insertions(+), 66 deletions(-) diff --git a/MODULE.bazel b/MODULE.bazel index c4b88f654996..85606ee1d680 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 = "12.10.1", - pnpm_version_integrity = "sha512-ukCjfrGjcNYP6oxM8dNkwTvMzvUY6YrSvO6VT1OdONo3RY5YJho/pV4GUjRQ6g//+fSXsTW+QfLBXBZCusrObA==", + pnpm_version = "12.11.2", + pnpm_version_integrity = "sha512-JaUWUqGWeFr18ovabf6NxYLr76SsHRgCIc4TkCMcX7dmN4IupLbkYzznSs3LCnf3Ja8RutOBd/3t2u6BipVcuQ==", ) use_repo(pnpm, "pnpm") diff --git a/MODULE.bazel.lock b/MODULE.bazel.lock index 79780e26566c..ec705b4eb497 100644 --- a/MODULE.bazel.lock +++ b/MODULE.bazel.lock @@ -1070,7 +1070,7 @@ }, "facts": { "@@aspect_rules_js+//npm:extensions.bzl%pnpm": { - "exe:12.10.1": "{\"darwin-arm64\":\"sha512-0O8tdQ8ijlPJudXspLMTcitMkdBEz6uUflazL5uQE0WMs85oQIp0U+5hfEktMFB64QqEhjqlvvujTwbzdr9oMg==\",\"darwin-x64\":\"sha512-ud+1/uZOKEo8P/AsPynOJc/LNwfI0j6WwCElibj71rU9l4nIBnsSn+wWTIPZPkZ4BBSH5+82azSnAARMyJ1lNA==\",\"linux-arm64\":\"sha512-oBdMp69ScC9UnniG4qZAQVr2fBDSXjm4yk/72vkEVyrlwS23yMxcRQl7Qdo3sgXPAygY6TWnPRKm4rXzjoyW7w==\",\"linux-arm64-musl\":\"sha512-xba+00wZJ8Um6rBJJjWl88uJj0tydB8dtomvjlCLvi0uL32vpa9CRP8Vv26FIXvbiZ1bo2RCzYt/eChxJVV52w==\",\"linux-x64\":\"sha512-ZByV0DRgWzGaDSjT5ddRBASdwz+r/qPMYh7o6RGmPQjtRGNFbSl94xY2DcAM8mqCOZJUUDtAXQ+wpBXcdpKlkg==\",\"linux-x64-musl\":\"sha512-e6IqzVNkPa7srFKJKnY23uWJ+qz0LaRWiTUo/sHfFXRRMRzB5uNOr6qWWip/jqhdGwU91n9J7LrEYZ6e0tRczw==\",\"win32-arm64\":\"sha512-I7QZHcjioG7orFeCRUFUHByJ1G0zFPnAlaGGyrUvb6MGkv5oeNwNPl7t+Gp+7zHfnMcgLGJ1a+Wfim0IDw3lOw==\",\"win32-x64\":\"sha512-4WJFdp58EKlCj0zLobrXU0vpszSZIr4X/3y/uNbAQqGW0zE+VdruZB0gFc3L2kzsUzVwTYbaCn+XEhnCYSAlTg==\"}" + "exe:12.11.2": "{\"darwin-arm64\":\"sha512-n9M4On66y8FDxUAKgMO1FXt0qihyG4e+56p3/F0uo8Bx9KplW8BwKVnXigzCJ8aNM6sVVPkOE6M9XXbeVIxnZA==\",\"darwin-x64\":\"sha512-oSW7n3sBT0c0cyk4kj10T2Y6Mpm+OFEiCAWozgX039tdoI6yqJF1uaFD3sw7ugLdu6VV3+uY0pa1TUZIPdxDWA==\",\"linux-arm64\":\"sha512-6e8ZAQUwFXAWHHHv5FesWqf/kEK04wuitBv5f/gxzkC0DiBfaixr+f+6JQede8SF4Ji5LcMwVFJbzAtffpWxEg==\",\"linux-arm64-musl\":\"sha512-uMEYDwKRktGwANubQ+kYCwmhNwg3Ik6qK89ahsbQ5cP30R/5FVJb/T99vr9XRUBC/A7mZI6eeT92oyVas9ACyg==\",\"linux-x64\":\"sha512-FK7QKe24AYgppJwO3mpooYptduuvIGqKJPi5ac7MdnWkjUy46JBfYhCW0grnkWKC8YOf0x+vGviuQqJEj3SpQQ==\",\"linux-x64-musl\":\"sha512-7eIxQR05fvJxCujUSKp5KTtehJ7QqrgqP/HD1+BcB/SaV2Be4XI1PEHiOgA1zxsiMIeMvTF6E4G4dYHrFjeXRg==\",\"win32-arm64\":\"sha512-PCTjVDdJb6VvraZxrEeFv6EqEA0hhIsAySx28e95J2Tqpi88hLpgOXgNqV0vpxq9A+b8GLQfyk/D+1UlJPv/YQ==\",\"win32-x64\":\"sha512-8sgX86OvRjJ3yZs/TvGR2L31wH9ScPZ+f+geKI3ikuB0RRiK3i4LlTRO8OXN6pdRqj8epMde4312MCjj7JsJdA==\"}" }, "@@aspect_tools_telemetry+//:extension.bzl%telemetry": { "notice_version": "3" diff --git a/package.json b/package.json index 3a019a911cc5..de08fb1c0152 100644 --- a/package.json +++ b/package.json @@ -29,12 +29,12 @@ "type": "git", "url": "git+https://github.com/angular/angular-cli.git" }, - "packageManager": "pnpm@12.10.1", + "packageManager": "pnpm@12.11.2", "engines": { "node": "^22.22.3 || ^24.15.0 || >=26.0.0", "npm": "Please use pnpm instead of NPM to install dependencies", "yarn": "Please use pnpm instead of Yarn to install dependencies", - "pnpm": "12.10.1" + "pnpm": "12.11.2" }, "author": "Angular Authors", "license": "MIT", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index a404c415baeb..e68cfdd14137 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -7,153 +7,153 @@ importers: configDependencies: {} packageManagerDependencies: pnpm: - specifier: 12.10.1 - version: 12.10.1 + specifier: 12.11.2 + version: 12.11.2 packages: - '@pnpm/exe.android-arm64@12.10.1': - resolution: {integrity: sha512-CVTlHPwNvadQCJD9bGSMzWIhFX8QpjtqC2c27dhdnn/9iKzEjZ3qL62o3gHpKbIuo6qn4WxTKRoaokgNdReBig==} + '@pnpm/exe.android-arm64@12.11.2': + resolution: {integrity: sha512-owLw13OfPkEoY+hLBNeeG+dCFhywr7q2d/EHPz4mNL2RhKnv8gNwMARkjkiDQu234aItVwFNDeGnmQXm+ikkAg==} cpu: [arm64] os: [android] - '@pnpm/exe.android-x64@12.10.1': - resolution: {integrity: sha512-NFiYLIaodY7da0XIebwcU3JoP7IK/lzF7zgKSSP+9H+QcFnQ1GDfBkuBKCYJzZ+Xu0WH54neIPLBBCaOjaaauA==} + '@pnpm/exe.android-x64@12.11.2': + resolution: {integrity: sha512-GYPkVebl4iokOA/4MPSpGoUVfFlsth7uqOCe1XiaiM23LAdvUOMJBObqHJijr89ZqjwHm9pO6vO45GRwJ2U2qA==} cpu: [x64] os: [android] - '@pnpm/exe.darwin-arm64@12.10.1': - resolution: {integrity: sha512-0O8tdQ8ijlPJudXspLMTcitMkdBEz6uUflazL5uQE0WMs85oQIp0U+5hfEktMFB64QqEhjqlvvujTwbzdr9oMg==} + '@pnpm/exe.darwin-arm64@12.11.2': + resolution: {integrity: sha512-n9M4On66y8FDxUAKgMO1FXt0qihyG4e+56p3/F0uo8Bx9KplW8BwKVnXigzCJ8aNM6sVVPkOE6M9XXbeVIxnZA==} cpu: [arm64] os: [darwin] - '@pnpm/exe.darwin-x64@12.10.1': - resolution: {integrity: sha512-ud+1/uZOKEo8P/AsPynOJc/LNwfI0j6WwCElibj71rU9l4nIBnsSn+wWTIPZPkZ4BBSH5+82azSnAARMyJ1lNA==} + '@pnpm/exe.darwin-x64@12.11.2': + resolution: {integrity: sha512-oSW7n3sBT0c0cyk4kj10T2Y6Mpm+OFEiCAWozgX039tdoI6yqJF1uaFD3sw7ugLdu6VV3+uY0pa1TUZIPdxDWA==} cpu: [x64] os: [darwin] - '@pnpm/exe.freebsd-x64@12.10.1': - resolution: {integrity: sha512-mj9PE5rf8uAfQQ2K66HSATMSut+lNiB4eSqFd5+azFVCMnxNSy/32xpZQJT21PhnN3Y4qbK+iKHe5nWAxSuRhw==} + '@pnpm/exe.freebsd-x64@12.11.2': + resolution: {integrity: sha512-qbzc3KoDpa/Lkf8vs3jnDe6dUUbso+6eLIyssYFMiliLpYNxn8dirk11YoNnOQcdHVB50v5RFls1Yid6ttT5pg==} cpu: [x64] os: [freebsd] - '@pnpm/exe.linux-arm64-musl@12.10.1': - resolution: {integrity: sha512-xba+00wZJ8Um6rBJJjWl88uJj0tydB8dtomvjlCLvi0uL32vpa9CRP8Vv26FIXvbiZ1bo2RCzYt/eChxJVV52w==} + '@pnpm/exe.linux-arm64-musl@12.11.2': + resolution: {integrity: sha512-uMEYDwKRktGwANubQ+kYCwmhNwg3Ik6qK89ahsbQ5cP30R/5FVJb/T99vr9XRUBC/A7mZI6eeT92oyVas9ACyg==} cpu: [arm64] os: [linux] libc: [musl] - '@pnpm/exe.linux-arm64@12.10.1': - resolution: {integrity: sha512-oBdMp69ScC9UnniG4qZAQVr2fBDSXjm4yk/72vkEVyrlwS23yMxcRQl7Qdo3sgXPAygY6TWnPRKm4rXzjoyW7w==} + '@pnpm/exe.linux-arm64@12.11.2': + resolution: {integrity: sha512-6e8ZAQUwFXAWHHHv5FesWqf/kEK04wuitBv5f/gxzkC0DiBfaixr+f+6JQede8SF4Ji5LcMwVFJbzAtffpWxEg==} cpu: [arm64] os: [linux] libc: [glibc] - '@pnpm/exe.linux-ppc64@12.10.1': - resolution: {integrity: sha512-Yyb3wu09h3c7mLme270uHFiVaAIUHC411Ru9LIU2BKUIstrGlXa9OqqVWoXaRgYRdFdOFknkwG7GNn6ygwLbnw==} + '@pnpm/exe.linux-ppc64@12.11.2': + resolution: {integrity: sha512-Ui8A4nepkVupx2VpuFfysEluMvWK6gTB5rgVts7Ss/+8dj0RD28x3F/seNeH/zSypgC6yKdV6qsKVQh/uffTuQ==} cpu: [ppc64] os: [linux] libc: [glibc] - '@pnpm/exe.linux-riscv64@12.10.1': - resolution: {integrity: sha512-PdkeUFFkybknnGkWP0H22eMpIiS4OZXL5BcQzF4lh+vmrW3IaC2HOkbANKgot/PKO0Kl77pzA/6PKFxgbgfXIQ==} + '@pnpm/exe.linux-riscv64@12.11.2': + resolution: {integrity: sha512-i1yLdQ5bu+wjQ+srtFoJAaY2gN/+oXHFdjul4llCeoDxHE0rTIG3R41NhHfCjyFPW4+CpbBT58933CL9sMOCnA==} cpu: [riscv64] os: [linux] libc: [glibc] - '@pnpm/exe.linux-s390x@12.10.1': - resolution: {integrity: sha512-1okKuHKJwJPAbofDxfhZWAUxEWtee4ZSf7Pah8kcvocaJkf2WxFJ5KVTiNIvDml5GLidDQsgf7Pcf/WHbCak7Q==} + '@pnpm/exe.linux-s390x@12.11.2': + resolution: {integrity: sha512-YS1/lhPjjTsN4QL50VaFZKRa3Uc/bDnhE8eKbJMFvuX06UuFS5YaiDg04APoZdfVSGqTfX27QAg7rfLMSWaqxA==} cpu: [s390x] os: [linux] libc: [glibc] - '@pnpm/exe.linux-x64-musl@12.10.1': - resolution: {integrity: sha512-e6IqzVNkPa7srFKJKnY23uWJ+qz0LaRWiTUo/sHfFXRRMRzB5uNOr6qWWip/jqhdGwU91n9J7LrEYZ6e0tRczw==} + '@pnpm/exe.linux-x64-musl@12.11.2': + resolution: {integrity: sha512-7eIxQR05fvJxCujUSKp5KTtehJ7QqrgqP/HD1+BcB/SaV2Be4XI1PEHiOgA1zxsiMIeMvTF6E4G4dYHrFjeXRg==} cpu: [x64] os: [linux] libc: [musl] - '@pnpm/exe.linux-x64@12.10.1': - resolution: {integrity: sha512-ZByV0DRgWzGaDSjT5ddRBASdwz+r/qPMYh7o6RGmPQjtRGNFbSl94xY2DcAM8mqCOZJUUDtAXQ+wpBXcdpKlkg==} + '@pnpm/exe.linux-x64@12.11.2': + resolution: {integrity: sha512-FK7QKe24AYgppJwO3mpooYptduuvIGqKJPi5ac7MdnWkjUy46JBfYhCW0grnkWKC8YOf0x+vGviuQqJEj3SpQQ==} cpu: [x64] os: [linux] libc: [glibc] - '@pnpm/exe.win32-arm64@12.10.1': - resolution: {integrity: sha512-I7QZHcjioG7orFeCRUFUHByJ1G0zFPnAlaGGyrUvb6MGkv5oeNwNPl7t+Gp+7zHfnMcgLGJ1a+Wfim0IDw3lOw==} + '@pnpm/exe.win32-arm64@12.11.2': + resolution: {integrity: sha512-PCTjVDdJb6VvraZxrEeFv6EqEA0hhIsAySx28e95J2Tqpi88hLpgOXgNqV0vpxq9A+b8GLQfyk/D+1UlJPv/YQ==} cpu: [arm64] os: [win32] - '@pnpm/exe.win32-x64@12.10.1': - resolution: {integrity: sha512-4WJFdp58EKlCj0zLobrXU0vpszSZIr4X/3y/uNbAQqGW0zE+VdruZB0gFc3L2kzsUzVwTYbaCn+XEhnCYSAlTg==} + '@pnpm/exe.win32-x64@12.11.2': + resolution: {integrity: sha512-8sgX86OvRjJ3yZs/TvGR2L31wH9ScPZ+f+geKI3ikuB0RRiK3i4LlTRO8OXN6pdRqj8epMde4312MCjj7JsJdA==} cpu: [x64] os: [win32] - pnpm@12.10.1: - resolution: {integrity: sha512-ukCjfrGjcNYP6oxM8dNkwTvMzvUY6YrSvO6VT1OdONo3RY5YJho/pV4GUjRQ6g//+fSXsTW+QfLBXBZCusrObA==} + pnpm@12.11.2: + resolution: {integrity: sha512-JaUWUqGWeFr18ovabf6NxYLr76SsHRgCIc4TkCMcX7dmN4IupLbkYzznSs3LCnf3Ja8RutOBd/3t2u6BipVcuQ==} engines: {node: '>=18.*'} hasBin: true snapshots: - '@pnpm/exe.android-arm64@12.10.1': + '@pnpm/exe.android-arm64@12.11.2': optional: true - '@pnpm/exe.android-x64@12.10.1': + '@pnpm/exe.android-x64@12.11.2': optional: true - '@pnpm/exe.darwin-arm64@12.10.1': + '@pnpm/exe.darwin-arm64@12.11.2': optional: true - '@pnpm/exe.darwin-x64@12.10.1': + '@pnpm/exe.darwin-x64@12.11.2': optional: true - '@pnpm/exe.freebsd-x64@12.10.1': + '@pnpm/exe.freebsd-x64@12.11.2': optional: true - '@pnpm/exe.linux-arm64-musl@12.10.1': + '@pnpm/exe.linux-arm64-musl@12.11.2': optional: true - '@pnpm/exe.linux-arm64@12.10.1': + '@pnpm/exe.linux-arm64@12.11.2': optional: true - '@pnpm/exe.linux-ppc64@12.10.1': + '@pnpm/exe.linux-ppc64@12.11.2': optional: true - '@pnpm/exe.linux-riscv64@12.10.1': + '@pnpm/exe.linux-riscv64@12.11.2': optional: true - '@pnpm/exe.linux-s390x@12.10.1': + '@pnpm/exe.linux-s390x@12.11.2': optional: true - '@pnpm/exe.linux-x64-musl@12.10.1': + '@pnpm/exe.linux-x64-musl@12.11.2': optional: true - '@pnpm/exe.linux-x64@12.10.1': + '@pnpm/exe.linux-x64@12.11.2': optional: true - '@pnpm/exe.win32-arm64@12.10.1': + '@pnpm/exe.win32-arm64@12.11.2': optional: true - '@pnpm/exe.win32-x64@12.10.1': + '@pnpm/exe.win32-x64@12.11.2': optional: true - pnpm@12.10.1: + pnpm@12.11.2: optionalDependencies: - '@pnpm/exe.android-arm64': 12.10.1 - '@pnpm/exe.android-x64': 12.10.1 - '@pnpm/exe.darwin-arm64': 12.10.1 - '@pnpm/exe.darwin-x64': 12.10.1 - '@pnpm/exe.freebsd-x64': 12.10.1 - '@pnpm/exe.linux-arm64': 12.10.1 - '@pnpm/exe.linux-arm64-musl': 12.10.1 - '@pnpm/exe.linux-ppc64': 12.10.1 - '@pnpm/exe.linux-riscv64': 12.10.1 - '@pnpm/exe.linux-s390x': 12.10.1 - '@pnpm/exe.linux-x64': 12.10.1 - '@pnpm/exe.linux-x64-musl': 12.10.1 - '@pnpm/exe.win32-arm64': 12.10.1 - '@pnpm/exe.win32-x64': 12.10.1 + '@pnpm/exe.android-arm64': 12.11.2 + '@pnpm/exe.android-x64': 12.11.2 + '@pnpm/exe.darwin-arm64': 12.11.2 + '@pnpm/exe.darwin-x64': 12.11.2 + '@pnpm/exe.freebsd-x64': 12.11.2 + '@pnpm/exe.linux-arm64': 12.11.2 + '@pnpm/exe.linux-arm64-musl': 12.11.2 + '@pnpm/exe.linux-ppc64': 12.11.2 + '@pnpm/exe.linux-riscv64': 12.11.2 + '@pnpm/exe.linux-s390x': 12.11.2 + '@pnpm/exe.linux-x64': 12.11.2 + '@pnpm/exe.linux-x64-musl': 12.11.2 + '@pnpm/exe.win32-arm64': 12.11.2 + '@pnpm/exe.win32-x64': 12.11.2 --- lockfileVersion: '9.0' From afa3814ab9bf938006e2b144af8bd3112e38cc96 Mon Sep 17 00:00:00 2001 From: Doug Parker Date: Thu, 15 Oct 2026 10:39:49 -0700 Subject: [PATCH 102/233] release: cut the v22.2.3 release --- CHANGELOG.md | 49 +++++++++++++++++++++++++++++++++++++++++++++++++ package.json | 2 +- 2 files changed, 50 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index e36e30a9d55b..4fe1617f61f7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,52 @@ + + +# 22.2.3 (2026-10-15) + +### @angular/cli + +| Commit | Type | Description | +| --------------------------------------------------------------------------------------------------- | ---- | ----------------------------------------------------------------- | +| [3158e865f](https://github.com/angular/angular-cli/commit/3158e865ffdd828711d645dff16cc17fd26bb58e) | fix | accept multi-digit array indices in ng config | +| [bcff0e76a](https://github.com/angular/angular-cli/commit/bcff0e76adf73cfa32b02c5256490189675cb132) | fix | keep ng version working when the package manager is not installed | +| [5570c91d2](https://github.com/angular/angular-cli/commit/5570c91d2f38764cd841fcce146f1d13fef49b0c) | fix | resolve package name in npm workspace members | + +### @schematics/angular + +| Commit | Type | Description | +| --------------------------------------------------------------------------------------------------- | ---- | ------------------------------------------------------------------------- | +| [881865f36](https://github.com/angular/angular-cli/commit/881865f364b33b36630aa6ab7a129f7ed665cfa7) | fix | keep the workspace build version in the use-application-builder migration | + +### @angular-devkit/schematics + +| Commit | Type | Description | +| --------------------------------------------------------------------------------------------------- | ---- | --------------------------------------------- | +| [cf1f3b9d4](https://github.com/angular/angular-cli/commit/cf1f3b9d43177e15cf9a00973e6da3baeaf4b2dd) | fix | avoid stack overflow when chaining many rules | + +### @angular/build + +| Commit | Type | Description | +| --------------------------------------------------------------------------------------------------- | ---- | ------------------------------------------------------------------- | +| [1d477d6bc](https://github.com/angular/angular-cli/commit/1d477d6bc27159cb0c78288e047fcadfe6fc31d4) | fix | add CSP nonce to stylesheet and modulepreload link elements | +| [fbe208f83](https://github.com/angular/angular-cli/commit/fbe208f8392ec0ce82d597e8b690f146370bdc81) | fix | always use AOT when extracting i18n messages | +| [c1c4216a6](https://github.com/angular/angular-cli/commit/c1c4216a680891b80670660a621d6736c4aecaf0) | fix | coalesce external watcher directories to avoid macOS FSEvents limit | +| [792990bc2](https://github.com/angular/angular-cli/commit/792990bc2eacdcc8ed4de6ef46e58ceeb5fe8741) | fix | disable Vitest fsModuleCache in unit-test builder | +| [82439399c](https://github.com/angular/angular-cli/commit/82439399cbfb4c1d21d1c80d976021efa9e4a39a) | fix | ensure Sass importers return global Promise instances | +| [a818de415](https://github.com/angular/angular-cli/commit/a818de415e933819e7a2e3e679cd0b2d2be734de) | fix | keep Vite server file watcher disabled in Vitest watch mode | +| [91bad469e](https://github.com/angular/angular-cli/commit/91bad469ec5ce7b2dfd07e394b482d2cef411407) | fix | sort discovered unit-test files for deterministic builds | +| [e84db4af7](https://github.com/angular/angular-cli/commit/e84db4af70ca9be490b462e6d8112524dc8eb6d4) | fix | use module.registerHooks() for in-memory ESM loader | +| [a428021b7](https://github.com/angular/angular-cli/commit/a428021b77dbccf404f39712f1c88bed9b8e4272) | perf | avoid invalidating Angular diagnostic cache on stylesheet change | +| [b0ac394a0](https://github.com/angular/angular-cli/commit/b0ac394a063f084d885df67660224b6a25e2c614) | perf | resolve asset patterns concurrently with bounded concurrency | + +### @angular/ssr + +| Commit | Type | Description | +| --------------------------------------------------------------------------------------------------- | ---- | ------------------------------------------------------ | +| [bd09b98fc](https://github.com/angular/angular-cli/commit/bd09b98fcaff4b76c7fd65999b51bfaa942d1858) | fix | preserve preload metadata for nested empty-path routes | +| [a92546892](https://github.com/angular/angular-cli/commit/a925468929c74c30a3e64b361a6dc5d6fdc1006a) | fix | preserve query parameters on relative route redirects | +| [a2b86cc94](https://github.com/angular/angular-cli/commit/a2b86cc94d408ba4c3d422224b58e26b7a68f692) | fix | resolve relative redirects against the parent route | + + + # 22.2.2 (2026-10-07) diff --git a/package.json b/package.json index de08fb1c0152..ba5c9e712709 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@angular/devkit-repo", - "version": "22.2.2", + "version": "22.2.3", "private": true, "description": "Software Development Kit for Angular", "keywords": [ From a057239486e42ec7189f03a61b09e3b0761150c9 Mon Sep 17 00:00:00 2001 From: Charles Lyding <19598772+clydin@users.noreply.github.com> Date: Thu, 15 Oct 2026 12:05:58 -0400 Subject: [PATCH 103/233] fix(@angular/build): watch only explicitly added paths in chokidar watcher When preserveSymlinks or polling is enabled, the build watcher falls back to Chokidar. Previously, createChokidarWatcher initialized Chokidar on the entire workspace root directory and expanded any watched file inside node_modules to its full package root directory via ChokidarNodeModulesManager. Because Chokidar v5 recursively walks watched directories and attaches individual fs.watch handles to every subdirectory and file, projects with many workspace subdirectories or large imported packages could exceed the macOS per-process directory watch limit and crash with an unhandled EMFILE error. This change initializes Chokidar with an empty watch set and registers only the specific paths passed to add() and remove(), eliminating recursive directory scans across the workspace root and node_modules packages. When a directory is explicitly watched (such as when NG_BUILD_WATCH_ROOT is enabled), node_modules subdirectories are pruned unless directly added to the watch set. An error listener is also attached to prevent unhandled watcher errors from terminating the process, and removed files that remain in the watch set are re-registered so subsequent file recreation is detected across multiple watched directories. Closes #34312 (cherry picked from commit 972302ac3dc7b675e4b36dac465b876014a02b1e) --- packages/angular/build/src/utils/watcher.ts | 299 +++++++++--------- .../angular/build/src/utils/watcher_spec.ts | 96 +++++- 2 files changed, 242 insertions(+), 153 deletions(-) diff --git a/packages/angular/build/src/utils/watcher.ts b/packages/angular/build/src/utils/watcher.ts index ca0e86f987ff..fd865ee80b56 100644 --- a/packages/angular/build/src/utils/watcher.ts +++ b/packages/angular/build/src/utils/watcher.ts @@ -8,7 +8,6 @@ import type * as ParcelWatcher from '@parcel/watcher'; import type * as Chokidar from 'chokidar'; -import { once } from 'node:events'; import * as fs from 'node:fs'; import * as path from 'node:path'; import picomatch from 'picomatch'; @@ -1086,92 +1085,94 @@ async function createParcelWatcher( return buildWatcher; } -/** - * Manages selective node_modules watching for Chokidar. - * - * During Chokidar's initial scan, the allowed packages set is empty, causing Chokidar to prune the entire - * node_modules directory immediately and avoid blocking the 'ready' event for minutes. - * Packages are dynamically allowed and watched at the package root level as files are added via `watcher.add`. - * Tracking files per package allows reference-counting so that package directories are unwatched when no - * longer needed. - */ -class ChokidarNodeModulesManager { - private readonly allowedPackages = new Map>(); - - constructor(private readonly isCaseSensitive: boolean) {} - - registerPackage( - posixPath: string, - lookupKey: string, - ): { isPackage: boolean; newPkgDir?: string } { - const packageDir = extractNodeModulesPackageDir(posixPath); - if (!packageDir) { - return { isPackage: false }; - } - - const packageKey = toLookupKey(packageDir, this.isCaseSensitive); - let watchedInPkg = this.allowedPackages.get(packageKey); - if (!watchedInPkg) { - watchedInPkg = new Set(); - this.allowedPackages.set(packageKey, watchedInPkg); - watchedInPkg.add(lookupKey); - - return { isPackage: true, newPkgDir: packageDir }; - } - - watchedInPkg.add(lookupKey); +function createChokidarIgnored( + ignoredPatterns: string[] | undefined, + isCaseSensitive: boolean, + watchedFiles: ReadonlySet, +): Chokidar.Matcher[] { + // Strip static node_modules ignore patterns (e.g. `**/node_modules/**` from setupWatcher). + // If left in place, picomatch would unconditionally ignore all node_modules files and prevent + // watching explicitly added files inside node_modules. + const customIgnored = + ignoredPatterns + ?.filter((pattern) => { + const base = toPosixPathNormalized(pattern).replace(/\/\*\*$/, ''); - return { isPackage: true }; - } + return base !== NODE_MODULES && !base.endsWith(`/${NODE_MODULES}`); + }) + .map((pattern) => { + if (/[*?[\]{}()]/.test(pattern)) { + const isMatch = picomatch(pattern, { dot: true }); - removePackageFile( - posixPath: string, - lookupKey: string, - ): { isPackage: boolean; unwatchPkgDir?: string } { - const packageDir = extractNodeModulesPackageDir(posixPath); - if (!packageDir) { - return { isPackage: false }; - } + return (filePath: string) => isMatch(toPosixPathNormalized(filePath)); + } - const packageKey = toLookupKey(packageDir, this.isCaseSensitive); - const watchedInPkg = this.allowedPackages.get(packageKey); - if (watchedInPkg) { - watchedInPkg.delete(lookupKey); - if (watchedInPkg.size === 0) { - this.allowedPackages.delete(packageKey); + return { path: toPosixPathNormalized(pattern), recursive: true }; + }) ?? []; - return { isPackage: true, unwatchPkgDir: packageDir }; + // When watching a directory (e.g. projectRoot via NG_BUILD_WATCH_ROOT), prune `node_modules` + // directories unless explicitly added to `watchedFiles`. Explicitly added files inside + // `node_modules` do not end with `/node_modules` and remain watchable. + return [ + ...customIgnored, + (filePath: string) => { + if (!filePath.includes(NODE_MODULES)) { + return false; } - } - - return { isPackage: true }; - } - - isIgnored(filePath: string): boolean { - // Fast path: avoid expensive normalization for non-node_modules files - if (!filePath.includes(NODE_MODULES)) { - return false; - } - const posixPath = toPosixPathNormalized(filePath); - const lookupKey = toLookupKey(posixPath, this.isCaseSensitive); + const posixPath = toPosixPathNormalized(filePath); + const lookupKey = toLookupKey(posixPath, isCaseSensitive); - if (!`${lookupKey}/`.includes(NODE_MODULES_SEGMENT)) { - return false; - } + return ( + (lookupKey === NODE_MODULES || lookupKey.endsWith(`/${NODE_MODULES}`)) && + !watchedFiles.has(lookupKey) + ); + }, + ]; +} - if (this.allowedPackages.has(lookupKey)) { - return false; - } +interface ChokidarBaselineEntry { + posixPath: string; + mtimeMs?: number; + size?: number; +} - for (const pkg of this.allowedPackages.keys()) { - if (isPathInside(lookupKey, pkg)) { - return false; +// Chokidar initializes file watchers asynchronously (`await stat(path)` followed by +// `fs.watch` or `fs.watchFile`). If a file is modified or recreated immediately after +// `watcher.add()` is called, Chokidar may capture the post-modification state as its initial +// baseline (or suppress the initial `'add'` event due to `ignoreInitial: true`) and miss the +// change. Re-statting after a short delay catches any modifications or recreations that occurred +// during asynchronous watcher registration, while `fileStats` deduplicates if Chokidar also fired. +async function checkChokidarBaselines( + baselineStats: ReadonlyMap, + watchedFiles: ReadonlySet, + fileStats: ReadonlyMap, + watcher: Chokidar.FSWatcher, + handleEvent: (type: 'added' | 'modified' | 'removed', rawPath: string) => void, +): Promise { + await Promise.all( + Array.from(baselineStats, async ([lookupKey, baseline]) => { + if (!watchedFiles.has(lookupKey)) { + return; + } + const currentStat = await fs.promises.stat(baseline.posixPath).catch(() => null); + if (!watchedFiles.has(lookupKey) || !currentStat?.isFile()) { + return; } - } - return true; - } + if (baseline.mtimeMs === undefined || baseline.size === undefined) { + const recorded = fileStats.get(lookupKey); + if (!recorded) { + watcher.add(baseline.posixPath); + handleEvent('added', path.normalize(baseline.posixPath)); + } else if (currentStat.mtimeMs !== recorded.mtimeMs || currentStat.size !== recorded.size) { + handleEvent('modified', path.normalize(baseline.posixPath)); + } + } else if (currentStat.mtimeMs !== baseline.mtimeMs || currentStat.size !== baseline.size) { + handleEvent('modified', path.normalize(baseline.posixPath)); + } + }), + ); } async function createChokidarWatcher( @@ -1181,43 +1182,19 @@ async function createChokidarWatcher( const chokidar = chokidarModule ?? (await import('chokidar')); const watchedFiles = new Set(); const fileStats = new Map(); + const pendingTimers = new Set>(); - let queue: WatcherQueue; - if (options?.polling) { - const pollingInterval = options.interval ?? 100; - const debounceMs = Math.min(250, Math.max(100, Math.ceil(pollingInterval * 1.5))); - const maxWaitMs = Math.max(500, debounceMs * 3); - queue = new WatcherQueue(debounceMs, maxWaitMs); - } else { - queue = new WatcherQueue(); - } + const pollingInterval = options?.interval ?? 100; + const debounceMs = Math.min(250, Math.max(100, Math.ceil(pollingInterval * 1.5))); + const queue = options?.polling + ? new WatcherQueue(debounceMs, Math.max(500, debounceMs * 3)) + : new WatcherQueue(); const rootDir = options?.cwd ?? process.cwd(); const isCaseSensitive = isFileSystemCaseSensitive(rootDir); - const rootDirPosix = toPosixPathNormalized(rootDir); - const rootDirLookupKey = toLookupKey(rootDirPosix, isCaseSensitive); - - const nodeModulesManager = new ChokidarNodeModulesManager(isCaseSensitive); + const ignored = createChokidarIgnored(options?.ignored, isCaseSensitive, watchedFiles); - // Strip static node_modules ignore patterns (e.g. `**/node_modules/**` from setupWatcher). - // If left in place, picomatch would unconditionally ignore all node_modules files and override - // our dynamic package allowlist above. - const customIgnored = - options?.ignored - ?.filter((pattern) => !pattern.includes(NODE_MODULES)) - .map((pattern) => { - if (/[*?[\]{}()]/.test(pattern)) { - const isMatch = picomatch(pattern, { dot: true }); - - return (filePath: string) => isMatch(toPosixPathNormalized(filePath)); - } - - return { path: toPosixPathNormalized(pattern), recursive: true }; - }) ?? []; - - const ignored = [...customIgnored, (filePath: string) => nodeModulesManager.isIgnored(filePath)]; - - const watcher = chokidar.watch(rootDir, { + const watcher = chokidar.watch([], { ignoreInitial: true, ignored, followSymlinks: options?.followSymlinks, @@ -1225,13 +1202,10 @@ async function createChokidarWatcher( interval: options?.interval, }); - const initTime = Date.now(); + // Prevent unhandled watcher errors (such as EMFILE or EACCES) from crashing the process. + watcher.on('error', () => {}); - // Wait for the watcher to complete its initial filesystem scan before returning. - // With `ignoreInitial: true`, any file visited during the initial scan is treated as the initial baseline - // and will not emit 'add' or 'change' events. Awaiting 'ready' ensures that rapid file modifications - // made right after watcher setup (e.g. in rebuild tests) are not swallowed as initial files. - await once(watcher, 'ready'); + const initTime = Date.now(); const handleEvent = (type: 'added' | 'modified' | 'removed', rawPath: string) => { const posixPath = toPosixPathNormalized(rawPath); @@ -1248,14 +1222,10 @@ async function createChokidarWatcher( } const stat = fs.statSync(rawPath, { throwIfNoEntry: false }); - if (!stat) { - return; - } - // Ignore historical events from before watcher initialization, but allow a 1000 ms window // to account for coarse filesystem timestamp resolution (e.g., ext4/overlayfs integer second // mtime truncation on Linux) where files modified during startup may have truncated .000 ms mtimes. - if (stat.mtimeMs < initTime - 1000) { + if (!stat || stat.mtimeMs < initTime - 1000) { return; } @@ -1273,11 +1243,55 @@ async function createChokidarWatcher( queue.addChange(type, rawPath); }; + const scheduleBaselineCheck = (baselineStats: ReadonlyMap) => { + if (baselineStats.size === 0) { + return; + } + + const timer = setTimeout(() => { + pendingTimers.delete(timer); + void checkChokidarBaselines(baselineStats, watchedFiles, fileStats, watcher, handleEvent); + }, 50); + timer.unref(); + pendingTimers.add(timer); + }; + watcher.on('add', (path) => handleEvent('added', path)); watcher.on('change', (path) => handleEvent('modified', path)); - watcher.on('unlink', (path) => handleEvent('removed', path)); + watcher.on('unlink', (rawPath) => { + const posixPath = toPosixPathNormalized(rawPath); + const lookupKey = toLookupKey(posixPath, isCaseSensitive); + if (!isPathWatched(lookupKey, watchedFiles)) { + return; + } - const buildWatcher: BuildWatcher = { + // When Chokidar processes a file removal, it closes the underlying file watcher unless only a + // single directory is tracked (`_watched.size === 1`). Re-adding a directly watched path + // ensures Chokidar continues watching either the recreated file (if replaced within the atomic + // window) or its parent directory for future recreation. + if (watchedFiles.has(lookupKey)) { + fileStats.delete(lookupKey); + watcher.add(posixPath); + const stat = fs.statSync(rawPath, { throwIfNoEntry: false }); + if (stat?.isFile()) { + handleEvent('modified', rawPath); + scheduleBaselineCheck( + new Map([[lookupKey, { posixPath, mtimeMs: stat.mtimeMs, size: stat.size }]]), + ); + + return; + } + + handleEvent('removed', rawPath); + scheduleBaselineCheck(new Map([[lookupKey, { posixPath }]])); + + return; + } + + handleEvent('removed', rawPath); + }); + + return { [Symbol.asyncIterator]() { return this; }, @@ -1304,28 +1318,23 @@ async function createChokidarWatcher( add(paths) { const targets = typeof paths === 'string' ? [paths] : paths; const newPaths: string[] = []; + const baselineStats = new Map(); + for (const p of targets) { const posixPath = toPosixPathNormalized(p); const lookupKey = toLookupKey(posixPath, isCaseSensitive); if (!watchedFiles.has(lookupKey)) { watchedFiles.add(lookupKey); - - // For files inside node_modules, register their package directory. Only newly encountered - // package directories need to be added to Chokidar. - const { isPackage, newPkgDir } = nodeModulesManager.registerPackage(posixPath, lookupKey); - if (newPkgDir) { - newPaths.push(newPkgDir); - } else if ( - !isPackage && - !isPathInside(lookupKey, rootDirLookupKey) && - lookupKey !== rootDirLookupKey - ) { - newPaths.push(posixPath); + newPaths.push(posixPath); + const stat = fs.statSync(posixPath, { throwIfNoEntry: false }); + if (stat?.isFile()) { + baselineStats.set(lookupKey, { posixPath, mtimeMs: stat.mtimeMs, size: stat.size }); } } } if (newPaths.length > 0) { watcher.add(newPaths); + scheduleBaselineCheck(baselineStats); } }, @@ -1338,21 +1347,7 @@ async function createChokidarWatcher( if (watchedFiles.has(lookupKey)) { watchedFiles.delete(lookupKey); fileStats.delete(lookupKey); - - // When the last watched file in a package is removed, unwatch the package directory. - const { isPackage, unwatchPkgDir } = nodeModulesManager.removePackageFile( - posixPath, - lookupKey, - ); - if (unwatchPkgDir) { - removePaths.push(unwatchPkgDir); - } else if ( - !isPackage && - !isPathInside(lookupKey, rootDirLookupKey) && - lookupKey !== rootDirLookupKey - ) { - removePaths.push(posixPath); - } + removePaths.push(posixPath); } } if (removePaths.length > 0) { @@ -1361,13 +1356,15 @@ async function createChokidarWatcher( }, async close() { + for (const timer of pendingTimers) { + clearTimeout(timer); + } + pendingTimers.clear(); try { await watcher.close(); } finally { queue.close(); } }, - }; - - return buildWatcher; + } satisfies BuildWatcher; } diff --git a/packages/angular/build/src/utils/watcher_spec.ts b/packages/angular/build/src/utils/watcher_spec.ts index 3703eb9f4ce1..ef7a14d831d2 100644 --- a/packages/angular/build/src/utils/watcher_spec.ts +++ b/packages/angular/build/src/utils/watcher_spec.ts @@ -775,7 +775,7 @@ describe('Watcher', () => { } }, 10000); - it('should unwatch linked package directory when all its files are removed via watcher.remove', async () => { + it('should unwatch linked package file when removed via watcher.remove', async () => { const externalDir = fs.mkdtempSync(path.join(TMP_DIR, 'watcher-remove-npm-link-')); let watcher: BuildWatcher | undefined; @@ -813,7 +813,7 @@ describe('Watcher', () => { // Remove the linked file from the watcher watcher.remove(linkedFile); - // Allow a brief moment for Chokidar to asynchronously complete unwatching the package directory + // Allow a brief moment for Chokidar to asynchronously complete unwatching the file await setTimeout(250); // Modify both the removed linked file and the regular file @@ -876,6 +876,98 @@ describe('Watcher', () => { fs.rmSync(externalRoot, { recursive: true, force: true }); } }, 10000); + + it('should detect file deletion and recreation when watching multiple files with followSymlinks: true', async () => { + const subDirA = path.join(tempDir, 'dir-a'); + const subDirB = path.join(tempDir, 'dir-b'); + fs.mkdirSync(subDirA); + fs.mkdirSync(subDirB); + + const fileA = path.join(subDirA, 'a.ts'); + const fileB = path.join(subDirB, 'b.ts'); + fs.writeFileSync(fileA, 'export const a = 1;'); + fs.writeFileSync(fileB, 'export const b = 1;'); + + const watcher = await createWatcher({ + followSymlinks: true, + cwd: tempDir, + }); + + try { + watcher.add([fileA, fileB]); + await setTimeout(250); + + const iterator = watcher[Symbol.asyncIterator](); + + // Delete fileA and wait past Chokidar's atomic write window + fs.rmSync(fileA); + let result = await iterator.next(); + expect(result.done).toBeFalsy(); + expect(result.value?.removed.size).toBeGreaterThan(0); + + await setTimeout(150); + + // Recreate fileA and verify the watcher still detects it + fs.writeFileSync(fileA, 'export const a = 2;'); + result = await iterator.next(); + expect(result.done).toBeFalsy(); + expect(result.value?.all.some((f: string) => f.includes('a.ts'))).toBeTrue(); + + // Modify recreated fileA again to ensure ongoing changes are tracked + await setTimeout(150); + fs.writeFileSync(fileA, 'export const a = 3;'); + result = await iterator.next(); + expect(result.done).toBeFalsy(); + expect(result.value?.all.some((f: string) => f.includes('a.ts'))).toBeTrue(); + } finally { + await watcher.close(); + } + }, 10000); + + it('should prune node_modules when watching root directory while watching added package files', async () => { + const nodeModulesDir = path.join(tempDir, 'node_modules'); + const pkgDir = path.join(nodeModulesDir, 'some-pkg'); + fs.mkdirSync(pkgDir, { recursive: true }); + + const watchedPkgFile = path.join(pkgDir, 'index.js'); + const unwatchedPkgFile = path.join(pkgDir, 'other.js'); + const rootFile = path.join(tempDir, 'main.ts'); + fs.writeFileSync(watchedPkgFile, 'export const idx = 1;'); + fs.writeFileSync(unwatchedPkgFile, 'export const other = 1;'); + fs.writeFileSync(rootFile, 'export const main = 1;'); + + const pastTime = new Date(Date.now() - 5000); + fs.utimesSync(watchedPkgFile, pastTime, pastTime); + fs.utimesSync(unwatchedPkgFile, pastTime, pastTime); + fs.utimesSync(rootFile, pastTime, pastTime); + + const watcher = await createWatcher({ + followSymlinks: true, + cwd: tempDir, + }); + + try { + // Watch both the root directory and a specific file in node_modules + watcher.add([tempDir, watchedPkgFile]); + await setTimeout(250); + + const iterator = watcher[Symbol.asyncIterator](); + const nextPromise = iterator.next(); + + // Modify unwatched file in node_modules (should be ignored even though tempDir is watched) + // and watched file in node_modules + fs.writeFileSync(unwatchedPkgFile, 'export const other = 2;'); + fs.writeFileSync(watchedPkgFile, 'export const idx = 2;'); + + const result = await nextPromise; + expect(result.done).toBeFalsy(); + const changed = result.value?.all ?? []; + expect(changed.some((f: string) => f.includes('index.js'))).toBeTrue(); + expect(changed.some((f: string) => f.includes('other.js'))).toBeFalse(); + } finally { + await watcher.close(); + } + }, 10000); }); describe('ParcelExternalManager', () => { From e89807e0da1a52df5db96cb7a6f996ee72effd65 Mon Sep 17 00:00:00 2001 From: Shuaib Hasan Akib <48770016+MeAkib@users.noreply.github.com> Date: Fri, 16 Oct 2026 22:25:25 +0600 Subject: [PATCH 104/233] docs(@schematics/angular): correct `directory` and `entryFile` option descriptions The `ng new` `directory` option claimed the workspace is created in the current directory when the option is omitted, but a new directory named after the workspace is created instead. The library `entryFile` option described a path relative to the workspace root, but the value is a file name without the `.ts` extension that is placed in the library's `src` directory. (cherry picked from commit 0608ebf8992bc11b43dfb8b042e9322f8b6bdd87) --- packages/schematics/angular/library/schema.json | 2 +- packages/schematics/angular/ng-new/schema.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/schematics/angular/library/schema.json b/packages/schematics/angular/library/schema.json index bb3d227e5245..02c6c6f8acaa 100644 --- a/packages/schematics/angular/library/schema.json +++ b/packages/schematics/angular/library/schema.json @@ -19,7 +19,7 @@ "entryFile": { "type": "string", "format": "path", - "description": "The path to the library's public API file, relative to the workspace root. This file defines what parts of the library are accessible to applications that import it.", + "description": "The name of the library's public API file, without the `.ts` extension, created in the library's `src` directory. This file defines what parts of the library are accessible to applications that import it.", "default": "public-api" }, "prefix": { diff --git a/packages/schematics/angular/ng-new/schema.json b/packages/schematics/angular/ng-new/schema.json index 257628fcda9e..2c69fa84aaad 100644 --- a/packages/schematics/angular/ng-new/schema.json +++ b/packages/schematics/angular/ng-new/schema.json @@ -8,7 +8,7 @@ "properties": { "directory": { "type": "string", - "description": "The directory where the new workspace and project should be created. If not specified, the workspace will be created in the current directory." + "description": "The directory where the new workspace and project should be created. If not specified, the workspace will be created in a subfolder within the current directory, using the workspace's name." }, "name": { "description": "The name for the new workspace and the initial project. This name will be used for the root directory and various identifiers throughout the project.", From fe119a7c717db7a50d92073dd8d3a2f4726bbd6f Mon Sep 17 00:00:00 2001 From: MeAkib Date: Fri, 16 Oct 2026 00:09:22 +0600 Subject: [PATCH 105/233] fix(@schematics/angular): show routing module suffixes in `findModule` error When only routing modules are found, the error message printed the optional `routingModuleExt` parameter, which no schematic passes, so users saw "Modules with suffix 'undefined' are strictly reserved for routing.". Since 0b7d48c7ca the lookup checks both `-routing-module.ts` and `-routing.module.ts`, so list the suffixes that are actually used. (cherry picked from commit 490a6fe2f1938ea3da5299dabf3a41dec4ef8399) --- packages/schematics/angular/utility/find-module.ts | 2 +- packages/schematics/angular/utility/find-module_spec.ts | 3 +++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/packages/schematics/angular/utility/find-module.ts b/packages/schematics/angular/utility/find-module.ts index c98b52a0cbe2..e6ad0c5620e6 100644 --- a/packages/schematics/angular/utility/find-module.ts +++ b/packages/schematics/angular/utility/find-module.ts @@ -117,7 +117,7 @@ export function findModule( const errorMsg = foundRoutingModule ? 'Could not find a non Routing NgModule.' + - `\nModules with suffix '${routingModuleExt}' are strictly reserved for routing.` + + `\nModules with suffix '${routingModuleExtensions.join("' or '")}' are strictly reserved for routing.` + `\nUse the '--skip-import' option to skip importing in NgModule.` : `Could not find an NgModule. Use the '--skip-import' option to skip importing in NgModule.`; diff --git a/packages/schematics/angular/utility/find-module_spec.ts b/packages/schematics/angular/utility/find-module_spec.ts index 0db295ae384f..dcc8a7df057e 100644 --- a/packages/schematics/angular/utility/find-module_spec.ts +++ b/packages/schematics/angular/utility/find-module_spec.ts @@ -56,6 +56,9 @@ describe('find-module', () => { expect(() => findModule(host, 'foo/src/app/anything-routing')).toThrowError( /Could not find a non Routing NgModule/, ); + expect(() => findModule(host, 'foo/src/app/anything-routing')).toThrowError( + /Modules with suffix '-routing-module\.ts' or '-routing\.module\.ts' are strictly reserved/, + ); }); it('should throw if two modules found', () => { From 22f836a70b63da0b00839165a84a92ff8e1bbbde Mon Sep 17 00:00:00 2001 From: MeAkib Date: Fri, 16 Oct 2026 00:11:22 +0600 Subject: [PATCH 106/233] docs(@angular/build): include component templates in dev-server `hmr` description The `hmr` option description stated that only global and component stylesheets are supported. Component template hot replacement is also enabled by default when HMR is active, so list templates alongside the supported stylesheets. (cherry picked from commit c1cfe8f48059e2d48731cf933f8f407e65466428) --- packages/angular/build/src/builders/dev-server/schema.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/angular/build/src/builders/dev-server/schema.json b/packages/angular/build/src/builders/dev-server/schema.json index 023478ff7e52..3517d3098887 100644 --- a/packages/angular/build/src/builders/dev-server/schema.json +++ b/packages/angular/build/src/builders/dev-server/schema.json @@ -91,7 +91,7 @@ }, "hmr": { "type": "boolean", - "description": "Enable hot module replacement. Defaults to the value of 'liveReload'. Currently, only global and component stylesheets are supported." + "description": "Enable hot module replacement. Defaults to the value of 'liveReload'. Currently, global stylesheets, component stylesheets, and component templates are supported." }, "watch": { "type": "boolean", From c345ba07ef700bda6ae224a4d6e41618e4007264 Mon Sep 17 00:00:00 2001 From: Angular Robot Date: Fri, 16 Oct 2026 06:47:47 +0000 Subject: [PATCH 107/233] build: update dependency node to v24.22.0 See associated pull request for more information. --- .nvmrc | 2 +- MODULE.bazel | 16 ++++++++-------- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/.nvmrc b/.nvmrc index df6ae3370f9f..a43a5b943d99 100644 --- a/.nvmrc +++ b/.nvmrc @@ -1 +1 @@ -24.21.0 +24.22.0 diff --git a/MODULE.bazel b/MODULE.bazel index 85606ee1d680..69ddf30cdb73 100644 --- a/MODULE.bazel +++ b/MODULE.bazel @@ -40,15 +40,15 @@ git_override( node = use_extension("@rules_nodejs//nodejs:extensions.bzl", "node") node.toolchain( node_repositories = { - "24.21.0-darwin_arm64": ("node-v24.21.0-darwin-arm64.tar.gz", "node-v24.21.0-darwin-arm64", "bed7eea5325e1108f32ce5228ddd6a5f0f08a499ee42aa7442aea583702f6057"), - "24.21.0-darwin_amd64": ("node-v24.21.0-darwin-x64.tar.gz", "node-v24.21.0-darwin-x64", "1462cb3b3046b815cf8ea436d3da450ec1a9f11dac7e5a46b0ada5305d7e8097"), - "24.21.0-linux_arm64": ("node-v24.21.0-linux-arm64.tar.xz", "node-v24.21.0-linux-arm64", "6ad1325edbdb5649c379b75a237147a666c95d4f9ae8d340fef2d1575d289ad2"), - "24.21.0-linux_ppc64le": ("node-v24.21.0-linux-ppc64le.tar.xz", "node-v24.21.0-linux-ppc64le", "1936fd64623a2f98d1fb31b456686d10c30e92639899cfefdefa8835d22adccd"), - "24.21.0-linux_s390x": ("node-v24.21.0-linux-s390x.tar.xz", "node-v24.21.0-linux-s390x", "2ef7e2ecbf7a6c2f3d08d106f6b2f279419c6dac89fe91b8cad193af7890082c"), - "24.21.0-linux_amd64": ("node-v24.21.0-linux-x64.tar.xz", "node-v24.21.0-linux-x64", "fd8e59d5a511510f6a298afb548f18c7d2b1be404d8b4a27d94fbe49f56cb2d6"), - "24.21.0-windows_amd64": ("node-v24.21.0-win-x64.zip", "node-v24.21.0-win-x64", "158f7685b44de51f6c0df1d153526cbcd3e1bc739a8dfc607721cef75de9e541"), + "24.22.0-darwin_arm64": ("node-v24.22.0-darwin-arm64.tar.gz", "node-v24.22.0-darwin-arm64", "6a9724d9b50a5f22b4816cded441b5a8d9ddae546191a5e5b7efa5a5e2ee26d5"), + "24.22.0-darwin_amd64": ("node-v24.22.0-darwin-x64.tar.gz", "node-v24.22.0-darwin-x64", "495e3f273c645f3c4677d438304cdfc701729ea5dec5728f5c8e76a2dece4b91"), + "24.22.0-linux_arm64": ("node-v24.22.0-linux-arm64.tar.xz", "node-v24.22.0-linux-arm64", "fef00bb4d36e1c50104a9775a10359beee98f162b4104dd12472c75065c6a143"), + "24.22.0-linux_ppc64le": ("node-v24.22.0-linux-ppc64le.tar.xz", "node-v24.22.0-linux-ppc64le", "edfc950d84a74b4fb4fedc8d2a569976682f6bbbf182961a4e916b7aad856013"), + "24.22.0-linux_s390x": ("node-v24.22.0-linux-s390x.tar.xz", "node-v24.22.0-linux-s390x", "ee3a16f7700188d62cd87b50fde39f8cbd8ab82f25611114e5ed6ef00d914431"), + "24.22.0-linux_amd64": ("node-v24.22.0-linux-x64.tar.xz", "node-v24.22.0-linux-x64", "cc2f601cee82d9a5a233302fe307abc600727035fd7d2c3a3571755989e95008"), + "24.22.0-windows_amd64": ("node-v24.22.0-win-x64.zip", "node-v24.22.0-win-x64", "f9683a19877e12a9b167305c8db71040d812876359de21f0d2e97c3f321f80c3"), }, - node_version = "24.21.0", + node_version = "24.22.0", ) use_repo( node, From 36f24fffb3ada3eda0fd8df9b8bf18f720b3e3f3 Mon Sep 17 00:00:00 2001 From: Alan Agius <17563226+alan-agius4@users.noreply.github.com> Date: Mon, 19 Oct 2026 08:18:04 +0000 Subject: [PATCH 108/233] refactor(@angular-devkit/build-angular): update internal webpack dependency paths Update internal webpack dependency deep imports to match the reorganized module structure in Webpack 5.112.0. (cherry picked from commit 508d6a2152d495001ef341e1c929f75d08d20228) --- .../tools/webpack/plugins/common-js-usage-warn-plugin.ts | 8 ++++---- .../src/tools/webpack/plugins/named-chunks-plugin.ts | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/packages/angular_devkit/build_angular/src/tools/webpack/plugins/common-js-usage-warn-plugin.ts b/packages/angular_devkit/build_angular/src/tools/webpack/plugins/common-js-usage-warn-plugin.ts index 2374243b3121..59e56bf7abfb 100644 --- a/packages/angular_devkit/build_angular/src/tools/webpack/plugins/common-js-usage-warn-plugin.ts +++ b/packages/angular_devkit/build_angular/src/tools/webpack/plugins/common-js-usage-warn-plugin.ts @@ -11,10 +11,10 @@ import { Compilation, Compiler, Dependency, Module, NormalModule } from 'webpack import { addWarning } from '../../../utils/webpack-diagnostics'; // Webpack doesn't export these so the deep imports can potentially break. -const AMDDefineDependency = require('webpack/lib/dependencies/AMDDefineDependency'); -const CommonJsExportsDependency = require('webpack/lib/dependencies/CommonJsExportsDependency'); -const CommonJsRequireDependency = require('webpack/lib/dependencies/CommonJsRequireDependency'); -const CommonJsSelfReferenceDependency = require('webpack/lib/dependencies/CommonJsSelfReferenceDependency'); +const AMDDefineDependency = require('webpack/lib/dependencies/amd/AMDDefineDependency'); +const CommonJsExportsDependency = require('webpack/lib/dependencies/commonjs/CommonJsExportsDependency'); +const CommonJsRequireDependency = require('webpack/lib/dependencies/commonjs/CommonJsRequireDependency'); +const CommonJsSelfReferenceDependency = require('webpack/lib/dependencies/commonjs/CommonJsSelfReferenceDependency'); export interface CommonJsUsageWarnPluginOptions { /** A list of CommonJS or AMD packages that are allowed to be used without a warning. Use `'*'` to allow all. */ diff --git a/packages/angular_devkit/build_angular/src/tools/webpack/plugins/named-chunks-plugin.ts b/packages/angular_devkit/build_angular/src/tools/webpack/plugins/named-chunks-plugin.ts index bc838b2f6a3a..417d11484ef7 100644 --- a/packages/angular_devkit/build_angular/src/tools/webpack/plugins/named-chunks-plugin.ts +++ b/packages/angular_devkit/build_angular/src/tools/webpack/plugins/named-chunks-plugin.ts @@ -9,7 +9,7 @@ import { AsyncDependenciesBlock, Chunk, Compiler, Template, dependencies } from 'webpack'; // `ImportDependency` is not part of Webpack's depenencies typings. -const ImportDependency: typeof dependencies.ModuleDependency = require('webpack/lib/dependencies/ImportDependency'); +const ImportDependency: typeof dependencies.ModuleDependency = require('webpack/lib/dependencies/import/ImportDependency'); const PLUGIN_NAME = 'named-chunks-plugin'; From 6d621b2053fca3d6f7d07245292ab665760ef41b Mon Sep 17 00:00:00 2001 From: Angular Robot Date: Mon, 19 Oct 2026 07:38:22 +0000 Subject: [PATCH 109/233] build: update dependency webpack to v5.112.0 See associated pull request for more information. --- .../angular_devkit/build_angular/package.json | 2 +- .../angular_devkit/build_webpack/package.json | 2 +- packages/ngtools/webpack/package.json | 2 +- pnpm-lock.yaml | 160 +++++++++++++----- 4 files changed, 117 insertions(+), 49 deletions(-) diff --git a/packages/angular_devkit/build_angular/package.json b/packages/angular_devkit/build_angular/package.json index 7a3408daafb3..5fcaf1e9e6f5 100644 --- a/packages/angular_devkit/build_angular/package.json +++ b/packages/angular_devkit/build_angular/package.json @@ -54,7 +54,7 @@ "terser": "5.51.2", "tinyglobby": "0.2.17", "tslib": "2.8.1", - "webpack": "5.111.0", + "webpack": "5.112.0", "webpack-dev-middleware": "8.3.0", "webpack-dev-server": "6.0.0", "webpack-merge": "6.0.1", diff --git a/packages/angular_devkit/build_webpack/package.json b/packages/angular_devkit/build_webpack/package.json index 3f5353802958..a00b76bb9640 100644 --- a/packages/angular_devkit/build_webpack/package.json +++ b/packages/angular_devkit/build_webpack/package.json @@ -22,7 +22,7 @@ "devDependencies": { "@angular-devkit/core": "workspace:0.0.0-PLACEHOLDER", "@ngtools/webpack": "workspace:0.0.0-PLACEHOLDER", - "webpack": "5.111.0", + "webpack": "5.112.0", "webpack-dev-server": "6.0.0" }, "peerDependencies": { diff --git a/packages/ngtools/webpack/package.json b/packages/ngtools/webpack/package.json index cd7cd4862322..84ba46303bdf 100644 --- a/packages/ngtools/webpack/package.json +++ b/packages/ngtools/webpack/package.json @@ -20,6 +20,6 @@ "@angular/compiler": "22.2.3", "@angular/compiler-cli": "22.2.3", "typescript": "6.0.3", - "webpack": "5.111.0" + "webpack": "5.112.0" } } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index e68cfdd14137..f5dba5c50208 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -290,7 +290,7 @@ importers: version: 3.0.8 '@types/loader-utils': specifier: ^3.0.0 - version: 3.0.0(esbuild@0.28.2)(lightningcss@1.33.0)(uglify-js@3.19.3) + version: 3.0.0(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.28)(uglify-js@3.19.3) '@types/lodash': specifier: ^4.17.0 version: 4.17.26 @@ -755,7 +755,7 @@ importers: version: 10.6.0(postcss@8.5.28) babel-loader: specifier: 10.1.1 - version: 10.1.1(@babel/core@8.0.5)(webpack@5.111.0(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.28)(uglify-js@3.19.3)) + version: 10.1.1(@babel/core@8.0.5)(webpack@5.112.0(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.28)(uglify-js@3.19.3)) beasties: specifier: 0.5.4 version: 0.5.4 @@ -764,10 +764,10 @@ importers: version: 4.29.3 copy-webpack-plugin: specifier: 14.0.0 - version: 14.0.0(webpack@5.111.0(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.28)(uglify-js@3.19.3)) + version: 14.0.0(webpack@5.112.0(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.28)(uglify-js@3.19.3)) css-loader: specifier: 7.1.5 - version: 7.1.5(webpack@5.111.0(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.28)(uglify-js@3.19.3)) + version: 7.1.5(webpack@5.112.0(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.28)(uglify-js@3.19.3)) esbuild-wasm: specifier: 0.28.2 version: 0.28.2 @@ -788,16 +788,16 @@ importers: version: 4.9.1(supports-color@11.0.0) less-loader: specifier: 13.0.0 - version: 13.0.0(less@4.9.1(supports-color@11.0.0))(webpack@5.111.0(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.28)(uglify-js@3.19.3)) + version: 13.0.0(less@4.9.1(supports-color@11.0.0))(webpack@5.112.0(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.28)(uglify-js@3.19.3)) license-webpack-plugin: specifier: 4.0.2 - version: 4.0.2(webpack@5.111.0(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.28)(uglify-js@3.19.3)) + version: 4.0.2(webpack@5.112.0(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.28)(uglify-js@3.19.3)) loader-utils: specifier: 3.3.1 version: 3.3.1 mini-css-extract-plugin: specifier: 2.10.2 - version: 2.10.2(webpack@5.111.0(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.28)(uglify-js@3.19.3)) + version: 2.10.2(webpack@5.112.0(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.28)(uglify-js@3.19.3)) open: specifier: 11.0.4 version: 11.0.4 @@ -815,7 +815,7 @@ importers: version: 8.5.28 postcss-loader: specifier: 8.2.1 - version: 8.2.1(postcss@8.5.28)(typescript@6.0.3)(webpack@5.111.0(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.28)(uglify-js@3.19.3)) + version: 8.2.1(postcss@8.5.28)(typescript@6.0.3)(webpack@5.112.0(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.28)(uglify-js@3.19.3)) resolve-url-loader: specifier: 5.0.0 version: 5.0.0 @@ -824,13 +824,13 @@ importers: version: 7.8.2 sass-loader: specifier: 17.0.1 - version: 17.0.1(sass-embedded@1.104.1)(sass@1.104.1)(webpack@5.111.0(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.28)(uglify-js@3.19.3)) + version: 17.0.1(sass-embedded@1.104.1)(sass@1.104.1)(webpack@5.112.0(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.28)(uglify-js@3.19.3)) semver: specifier: 7.8.5 version: 7.8.5 source-map-loader: specifier: 5.0.0 - version: 5.0.0(webpack@5.111.0(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.28)(uglify-js@3.19.3)) + version: 5.0.0(webpack@5.112.0(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.28)(uglify-js@3.19.3)) source-map-support: specifier: 0.5.21 version: 0.5.21 @@ -844,20 +844,20 @@ importers: specifier: 2.8.1 version: 2.8.1 webpack: - specifier: 5.111.0 - version: 5.111.0(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.28)(uglify-js@3.19.3) + specifier: 5.112.0 + version: 5.112.0(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.28)(uglify-js@3.19.3) webpack-dev-middleware: specifier: 8.3.0 - version: 8.3.0(webpack@5.111.0(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.28)(uglify-js@3.19.3)) + version: 8.3.0(webpack@5.112.0(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.28)(uglify-js@3.19.3)) webpack-dev-server: specifier: 6.0.0 - version: 6.0.0(bufferutil@4.1.0)(supports-color@11.0.0)(utf-8-validate@6.0.6)(webpack@5.111.0(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.28)(uglify-js@3.19.3)) + version: 6.0.0(bufferutil@4.1.0)(supports-color@11.0.0)(utf-8-validate@6.0.6)(webpack@5.112.0(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.28)(uglify-js@3.19.3)) webpack-merge: specifier: 6.0.1 version: 6.0.1 webpack-subresource-integrity: specifier: 5.1.0 - version: 5.1.0(webpack@5.111.0(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.28)(uglify-js@3.19.3)) + version: 5.1.0(webpack@5.112.0(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.28)(uglify-js@3.19.3)) devDependencies: '@angular/ssr': specifier: workspace:* @@ -895,11 +895,11 @@ importers: specifier: workspace:0.0.0-PLACEHOLDER version: link:../../ngtools/webpack webpack: - specifier: 5.111.0 - version: 5.111.0(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.28)(uglify-js@3.19.3) + specifier: 5.112.0 + version: 5.112.0(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.28)(uglify-js@3.19.3) webpack-dev-server: specifier: 6.0.0 - version: 6.0.0(bufferutil@4.1.0)(supports-color@11.0.0)(utf-8-validate@6.0.6)(webpack@5.111.0(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.28)(uglify-js@3.19.3)) + version: 6.0.0(bufferutil@4.1.0)(supports-color@11.0.0)(utf-8-validate@6.0.6)(webpack@5.112.0(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.28)(uglify-js@3.19.3)) packages/angular_devkit/core: dependencies: @@ -971,8 +971,8 @@ importers: specifier: 6.0.3 version: 6.0.3 webpack: - specifier: 5.111.0 - version: 5.111.0(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.28)(uglify-js@3.19.3) + specifier: 5.112.0 + version: 5.112.0(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.28)(uglify-js@3.19.3) packages/schematics/angular: dependencies: @@ -8317,6 +8317,10 @@ packages: resolution: {integrity: sha512-6i/00NBjP4yGPs+caKSyRfpTF/8Torsu0MOW3mMzIbhgISFder8i7xbqgHlLMwJrdiN8ndBV3UA1/AfzPSr+jg==} engines: {node: '>=10.13.0'} + watchpack@2.6.2: + resolution: {integrity: sha512-67nxRd7I5uAyn+KamYsCqU30iVgCgZ4aj8ZOGzmxs7zNPuvlnoYltm6+6JkOjEcD6WVXdu1BfH+gVQs3FUuW7Q==} + engines: {node: '>=10.13.0'} + weak-lru-cache@1.2.2: resolution: {integrity: sha512-DEAoo25RfSYMuTGc9vPJzZcZullwIqRDSI9LOy+fkCJPi6hykCnfKaXTuPBDuXAUcqHXyOgFtHNp/kB2FjYHbw==} @@ -8387,6 +8391,16 @@ packages: webpack-cli: optional: true + webpack@5.112.0: + resolution: {integrity: sha512-NIBpsRuCll036haDDt/CfcTDfsWNR9Z782nMRMI9D377BsGcYzZDTNU5TyzhCJzPIcihAxMBaMAhq2WSaDrH8Q==} + engines: {node: '>=10.13.0'} + hasBin: true + peerDependencies: + webpack-cli: '*' + peerDependenciesMeta: + webpack-cli: + optional: true + websocket-driver@0.7.5: resolution: {integrity: sha512-ZL2+3c7kMBdIRCMz6l8jQMHyGVxj+UL+xVk74Ombiciboca8rHa15L86B19E5oh1pL9Ii/uj54gtsIrZGMo6zA==} engines: {node: '>=0.8.0'} @@ -11432,7 +11446,7 @@ snapshots: '@types/less@3.0.8': {} - '@types/loader-utils@3.0.0(esbuild@0.28.2)(lightningcss@1.33.0)(uglify-js@3.19.3)': + '@types/loader-utils@3.0.0(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.28)(uglify-js@3.19.3)': dependencies: '@types/node': 22.20.5 webpack: 5.111.0(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.28)(uglify-js@3.19.3) @@ -12157,12 +12171,12 @@ snapshots: b4a@1.9.0: {} - babel-loader@10.1.1(@babel/core@8.0.5)(webpack@5.111.0(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.28)(uglify-js@3.19.3)): + babel-loader@10.1.1(@babel/core@8.0.5)(webpack@5.112.0(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.28)(uglify-js@3.19.3)): dependencies: '@babel/core': 8.0.5 find-up: 5.0.0 optionalDependencies: - webpack: 5.111.0(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.28)(uglify-js@3.19.3) + webpack: 5.112.0(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.28)(uglify-js@3.19.3) babel-plugin-polyfill-corejs3@1.0.0(@babel/core@8.0.5): dependencies: @@ -12636,14 +12650,14 @@ snapshots: dependencies: is-what: 4.1.16 - copy-webpack-plugin@14.0.0(webpack@5.111.0(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.28)(uglify-js@3.19.3)): + copy-webpack-plugin@14.0.0(webpack@5.112.0(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.28)(uglify-js@3.19.3)): dependencies: glob-parent: 6.0.2 normalize-path: 3.0.0 schema-utils: 4.5.0 serialize-javascript: 7.1.2 tinyglobby: 0.2.17 - webpack: 5.111.0(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.28)(uglify-js@3.19.3) + webpack: 5.112.0(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.28)(uglify-js@3.19.3) core-js-compat@3.50.0: dependencies: @@ -12673,7 +12687,7 @@ snapshots: shebang-command: 2.0.0 which: 2.0.2 - css-loader@7.1.5(webpack@5.111.0(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.28)(uglify-js@3.19.3)): + css-loader@7.1.5(webpack@5.112.0(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.28)(uglify-js@3.19.3)): dependencies: icss-utils: 5.1.0(postcss@8.5.28) postcss: 8.5.28 @@ -12684,7 +12698,7 @@ snapshots: postcss-value-parser: 4.2.0 semver: 7.8.5 optionalDependencies: - webpack: 5.111.0(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.28)(uglify-js@3.19.3) + webpack: 5.112.0(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.28)(uglify-js@3.19.3) css-select@7.0.0: dependencies: @@ -14440,12 +14454,12 @@ snapshots: picocolors: 1.1.1 shell-quote: 1.12.0 - less-loader@13.0.0(less@4.9.1(supports-color@11.0.0))(webpack@5.111.0(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.28)(uglify-js@3.19.3)): + less-loader@13.0.0(less@4.9.1(supports-color@11.0.0))(webpack@5.112.0(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.28)(uglify-js@3.19.3)): dependencies: '@types/less': 3.0.8 less: 4.9.1(supports-color@11.0.0) optionalDependencies: - webpack: 5.111.0(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.28)(uglify-js@3.19.3) + webpack: 5.112.0(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.28)(uglify-js@3.19.3) less@4.9.1(supports-color@11.0.0): dependencies: @@ -14467,11 +14481,11 @@ snapshots: prelude-ls: 1.2.1 type-check: 0.4.0 - license-webpack-plugin@4.0.2(webpack@5.111.0(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.28)(uglify-js@3.19.3)): + license-webpack-plugin@4.0.2(webpack@5.112.0(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.28)(uglify-js@3.19.3)): dependencies: webpack-sources: 3.6.0 optionalDependencies: - webpack: 5.111.0(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.28)(uglify-js@3.19.3) + webpack: 5.112.0(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.28)(uglify-js@3.19.3) lightningcss-android-arm64@1.33.0: optional: true @@ -14726,11 +14740,11 @@ snapshots: mimic-response@4.0.0: {} - mini-css-extract-plugin@2.10.2(webpack@5.111.0(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.28)(uglify-js@3.19.3)): + mini-css-extract-plugin@2.10.2(webpack@5.112.0(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.28)(uglify-js@3.19.3)): dependencies: schema-utils: 4.5.0 tapable: 2.3.3 - webpack: 5.111.0(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.28)(uglify-js@3.19.3) + webpack: 5.112.0(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.28)(uglify-js@3.19.3) minimatch@10.2.6: dependencies: @@ -14763,6 +14777,19 @@ snapshots: postcss: 8.5.28 uglify-js: 3.19.3 + minimizer-webpack-plugin@5.13.0(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.28)(uglify-js@3.19.3)(webpack@5.112.0(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.28)(uglify-js@3.19.3)): + dependencies: + '@jridgewell/trace-mapping': 0.3.31 + jest-worker: 27.5.1 + schema-utils: 4.5.0 + terser: 5.51.2 + webpack: 5.112.0(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.28)(uglify-js@3.19.3) + optionalDependencies: + esbuild: 0.28.2 + lightningcss: 1.33.0 + postcss: 8.5.28 + uglify-js: 3.19.3 + minipass@7.1.3: {} mitt@1.2.0: {} @@ -15219,14 +15246,14 @@ snapshots: possible-typed-array-names@1.1.0: {} - postcss-loader@8.2.1(postcss@8.5.28)(typescript@6.0.3)(webpack@5.111.0(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.28)(uglify-js@3.19.3)): + postcss-loader@8.2.1(postcss@8.5.28)(typescript@6.0.3)(webpack@5.112.0(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.28)(uglify-js@3.19.3)): dependencies: cosmiconfig: 9.0.2(typescript@6.0.3) jiti: 2.7.0 postcss: 8.5.28 semver: 7.8.5 optionalDependencies: - webpack: 5.111.0(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.28)(uglify-js@3.19.3) + webpack: 5.112.0(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.28)(uglify-js@3.19.3) transitivePeerDependencies: - typescript @@ -15815,11 +15842,11 @@ snapshots: sass-embedded-win32-arm64: 1.104.1 sass-embedded-win32-x64: 1.104.1 - sass-loader@17.0.1(sass-embedded@1.104.1)(sass@1.104.1)(webpack@5.111.0(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.28)(uglify-js@3.19.3)): + sass-loader@17.0.1(sass-embedded@1.104.1)(sass@1.104.1)(webpack@5.112.0(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.28)(uglify-js@3.19.3)): optionalDependencies: sass: 1.104.1 sass-embedded: 1.104.1 - webpack: 5.111.0(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.28)(uglify-js@3.19.3) + webpack: 5.112.0(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.28)(uglify-js@3.19.3) sass@1.104.1: dependencies: @@ -16047,11 +16074,11 @@ snapshots: source-map-js@1.2.2: {} - source-map-loader@5.0.0(webpack@5.111.0(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.28)(uglify-js@3.19.3)): + source-map-loader@5.0.0(webpack@5.112.0(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.28)(uglify-js@3.19.3)): dependencies: iconv-lite: 0.6.3 source-map-js: 1.2.2 - webpack: 5.111.0(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.28)(uglify-js@3.19.3) + webpack: 5.112.0(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.28)(uglify-js@3.19.3) source-map-support@0.5.21: dependencies: @@ -16680,6 +16707,10 @@ snapshots: dependencies: graceful-fs: 4.2.11 + watchpack@2.6.2: + dependencies: + graceful-fs: 4.2.11 + weak-lru-cache@1.2.2: optional: true @@ -16693,7 +16724,7 @@ snapshots: webidl-conversions@8.0.1: {} - webpack-dev-middleware@8.3.0(webpack@5.111.0(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.28)(uglify-js@3.19.3)): + webpack-dev-middleware@8.3.0(webpack@5.112.0(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.28)(uglify-js@3.19.3)): dependencies: ansi-html-community: 0.0.8 memfs: 4.80.0 @@ -16701,9 +16732,9 @@ snapshots: range-parser: 1.3.0 schema-utils: 4.5.0 optionalDependencies: - webpack: 5.111.0(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.28)(uglify-js@3.19.3) + webpack: 5.112.0(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.28)(uglify-js@3.19.3) - webpack-dev-server@6.0.0(bufferutil@4.1.0)(supports-color@11.0.0)(utf-8-validate@6.0.6)(webpack@5.111.0(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.28)(uglify-js@3.19.3)): + webpack-dev-server@6.0.0(bufferutil@4.1.0)(supports-color@11.0.0)(utf-8-validate@6.0.6)(webpack@5.112.0(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.28)(uglify-js@3.19.3)): dependencies: '@types/bonjour': 3.5.13 '@types/connect-history-api-fallback': 1.5.4 @@ -16728,10 +16759,10 @@ snapshots: selfsigned: 5.5.0 serve-index: 1.9.2(supports-color@11.0.0) tinyglobby: 0.2.17 - webpack-dev-middleware: 8.3.0(webpack@5.111.0(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.28)(uglify-js@3.19.3)) + webpack-dev-middleware: 8.3.0(webpack@5.112.0(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.28)(uglify-js@3.19.3)) ws: 8.22.0(bufferutil@4.1.0)(utf-8-validate@6.0.6) optionalDependencies: - webpack: 5.111.0(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.28)(uglify-js@3.19.3) + webpack: 5.112.0(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.28)(uglify-js@3.19.3) transitivePeerDependencies: - bufferutil - supports-color @@ -16745,10 +16776,10 @@ snapshots: webpack-sources@3.6.0: {} - webpack-subresource-integrity@5.1.0(webpack@5.111.0(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.28)(uglify-js@3.19.3)): + webpack-subresource-integrity@5.1.0(webpack@5.112.0(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.28)(uglify-js@3.19.3)): dependencies: typed-assert: 1.0.9 - webpack: 5.111.0(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.28)(uglify-js@3.19.3) + webpack: 5.112.0(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.28)(uglify-js@3.19.3) webpack@5.111.0(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.28)(uglify-js@3.19.3): dependencies: @@ -16787,6 +16818,43 @@ snapshots: - svgo - uglify-js + webpack@5.112.0(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.28)(uglify-js@3.19.3): + dependencies: + '@types/estree': 1.0.9 + '@types/json-schema': 7.0.15 + '@webassemblyjs/ast': 1.14.1 + '@webassemblyjs/wasm-edit': 1.14.1 + '@webassemblyjs/wasm-parser': 1.14.1 + browserslist: 4.29.3 + chrome-trace-event: 1.0.4 + enhanced-resolve: 5.26.0 + es-module-lexer: 2.3.2 + events: 3.3.0 + graceful-fs: 4.2.11 + mime-db: 1.54.0 + minimizer-webpack-plugin: 5.13.0(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.28)(uglify-js@3.19.3)(webpack@5.112.0(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.28)(uglify-js@3.19.3)) + schema-utils: 4.5.0 + tapable: 2.3.3 + watchpack: 2.6.2 + webpack-sources: 3.6.0 + transitivePeerDependencies: + - '@minify-html/node' + - '@napi-rs/image' + - '@swc/core' + - '@swc/css' + - '@swc/html' + - clean-css + - cssnano + - csso + - esbuild + - html-minifier-terser + - imagemin + - lightningcss + - postcss + - sharp + - svgo + - uglify-js + websocket-driver@0.7.5: dependencies: http-parser-js: 0.5.10 From a9bec13b58550fc757612c3617aa33eefb776041 Mon Sep 17 00:00:00 2001 From: Charles Lyding <19598772+clydin@users.noreply.github.com> Date: Fri, 16 Oct 2026 14:42:09 -0400 Subject: [PATCH 110/233] fix(@angular/build): use distinct chunk naming for web worker bundles Previously, `bundleWebWorker` inherited `chunkNames` from the main esbuild configuration while bundling web workers in a separate synchronous esbuild pass. When both the main application bundle and a web worker dynamically imported modules that shared a common dependency, esbuild generated a shared chunk with identical content and the same `chunk-[hash].js` filename in both builds. During post-build chunk optimization, Rolldown traced only the main application entrypoint, merged the shared chunk into new optimized chunks, and removed the original `chunk-[hash].js` file from the build outputs while the unoptimized web worker chunks still imported it. Setting `chunkNames` to `'worker-chunk-[hash]'` in `bundleWebWorker` ensures that chunks emitted for web workers have distinct filenames and do not collide with main bundle chunks during metafile merging or chunk optimization. Closes #34292 (cherry picked from commit e93d9cb8bb8d9902bbe437e9dece8f44cb859bfe) --- .../behavior/web-workers-application_spec.ts | 73 +++++++++++++++++++ .../tools/esbuild/angular/compiler-plugin.ts | 1 + 2 files changed, 74 insertions(+) diff --git a/packages/angular/build/src/builders/application/tests/behavior/web-workers-application_spec.ts b/packages/angular/build/src/builders/application/tests/behavior/web-workers-application_spec.ts index 135d5ff68165..10112afd3b6b 100644 --- a/packages/angular/build/src/builders/application/tests/behavior/web-workers-application_spec.ts +++ b/packages/angular/build/src/builders/application/tests/behavior/web-workers-application_spec.ts @@ -57,5 +57,78 @@ describeBuilder(buildApplication, APPLICATION_BUILDER_INFO, (harness) => { // Ensure built worker is referenced in the application code harness.expectFile('dist/browser/main.js').content.toMatch(REFERENCED_WORKER_REGEXP); }); + + it('should emit all chunks referenced by a web worker when chunk optimization is enabled', async () => { + harness.useTarget('build', { + ...BASE_OPTIONS, + optimization: true, + }); + + await harness.writeFile( + 'src/app/shared.ts', + `export function sharedHelper(value: string) { return [value, value.toUpperCase(), value.toLowerCase(), value.repeat(3)].join('-'); }`, + ); + await harness.writeFile( + 'src/app/lazy-a.ts', + `import { sharedHelper } from './shared'; export const a = () => sharedHelper('a');`, + ); + await harness.writeFile( + 'src/app/lazy-b.ts', + `import { sharedHelper } from './shared'; export const b = () => sharedHelper('b');`, + ); + await harness.writeFile('src/app/lazy-c.ts', `export const c = () => 'c';`); + + await harness.writeFile( + 'src/app/worker.ts', + ` + addEventListener('message', async () => { + const [{ a }, { b }] = await Promise.all([import('./lazy-a'), import('./lazy-b')]); + postMessage(a() + b()); + }); + `, + ); + + await harness.writeFile( + 'src/app/app.component.ts', + ` + import { Component } from '@angular/core'; + @Component({ + selector: 'app-root', + standalone: false, + template: '

Worker Test

', + }) + export class AppComponent { + worker = new Worker(new URL('./worker', import.meta.url), { type: 'module' }); + constructor() { + Promise.all([import('./lazy-a'), import('./lazy-b'), import('./lazy-c')]).then(console.log); + } + } + `, + ); + + const { result } = await harness.executeOnce(); + expect(result?.success).toBeTrue(); + expect(harness.hasFileMatch('dist/browser', /^worker-chunk-/)).toBeTrue(); + + const mainContent = harness.readFile('dist/browser/main.js'); + const workerMatch = mainContent.match(/(worker-[A-Z0-9]{8}\.js)/); + expect(workerMatch).not.toBeNull(); + + const filesToCheck = new Set(['main.js']); + if (workerMatch) { + filesToCheck.add(workerMatch[1]); + } + + for (const file of filesToCheck) { + expect(harness.hasFile(`dist/browser/${file}`)) + .withContext(`Expected dist/browser/${file} to exist`) + .toBeTrue(); + + const content = harness.readFile(`dist/browser/${file}`); + for (const match of content.matchAll(/(?:from|import)\s*\(?["']\.\/([^"']+\.js)["']\)?/g)) { + filesToCheck.add(match[1]); + } + } + }); }); }); diff --git a/packages/angular/build/src/tools/esbuild/angular/compiler-plugin.ts b/packages/angular/build/src/tools/esbuild/angular/compiler-plugin.ts index 9a36eea56d61..928c9dac7797 100644 --- a/packages/angular/build/src/tools/esbuild/angular/compiler-plugin.ts +++ b/packages/angular/build/src/tools/esbuild/angular/compiler-plugin.ts @@ -727,6 +727,7 @@ function bundleWebWorker( metafile: true, format: 'esm', entryNames: 'worker-[hash]', + chunkNames: 'worker-chunk-[hash]', entryPoints: [workerFile], sourcemap: pluginOptions.sourcemap, // Zone.js is not used in Web workers so no need to disable From fdf8607b4c79c92560840bfeaade5adb085f41fa Mon Sep 17 00:00:00 2001 From: MeAkib Date: Mon, 19 Oct 2026 14:45:35 +0600 Subject: [PATCH 111/233] docs: fix typos in option descriptions and the `ng run` long description Several option descriptions that are published on angular.dev contain typos ("prerending", "These file are", "a unit test files", "comma seperate"). The Karma `browsers: false` description also read "Does use run tests against a browser", which says the opposite of what the option does. The `ng run` long description has a run-on sentence. Correct the wording. (cherry picked from commit 405839b16084fb9473c596fe0bcf5d27a9bae803) --- packages/angular/build/src/builders/application/schema.json | 2 +- packages/angular/build/src/builders/karma/schema.json | 4 ++-- packages/angular/cli/src/commands/run/long-description.md | 2 +- .../build_angular/src/builders/karma/schema.json | 4 ++-- packages/schematics/angular/application/schema.json | 2 +- packages/schematics/angular/ng-new/schema.json | 2 +- 6 files changed, 8 insertions(+), 8 deletions(-) diff --git a/packages/angular/build/src/builders/application/schema.json b/packages/angular/build/src/builders/application/schema.json index 8458d385a3fc..cdf059ce3a25 100644 --- a/packages/angular/build/src/builders/application/schema.json +++ b/packages/angular/build/src/builders/application/schema.json @@ -568,7 +568,7 @@ "oneOf": [ { "type": "boolean", - "description": "Enable prerending of pages of your application during build time." + "description": "Enable prerendering of pages of your application during build time." }, { "type": "object", diff --git a/packages/angular/build/src/builders/karma/schema.json b/packages/angular/build/src/builders/karma/schema.json index 50c739ff69c8..4a41bc4fdad2 100644 --- a/packages/angular/build/src/builders/karma/schema.json +++ b/packages/angular/build/src/builders/karma/schema.json @@ -245,12 +245,12 @@ "oneOf": [ { "type": "string", - "description": "A comma seperate list of browsers to run tests against." + "description": "A comma-separated list of browsers to run tests against." }, { "const": false, "type": "boolean", - "description": "Does use run tests against a browser." + "description": "Does not run tests against a browser." } ] }, diff --git a/packages/angular/cli/src/commands/run/long-description.md b/packages/angular/cli/src/commands/run/long-description.md index e74f8756679d..00ff74da0628 100644 --- a/packages/angular/cli/src/commands/run/long-description.md +++ b/packages/angular/cli/src/commands/run/long-description.md @@ -7,4 +7,4 @@ For example, the `serve` target for a newly generated app has a predefined alternate configuration named `production`. You can define new targets and their configuration options in the `architect` section -of the `angular.json` file which you can run them from the command line using the `ng run` command. +of the `angular.json` file, which you can run from the command line using the `ng run` command. diff --git a/packages/angular_devkit/build_angular/src/builders/karma/schema.json b/packages/angular_devkit/build_angular/src/builders/karma/schema.json index fdd5927cfdac..1704810ab840 100644 --- a/packages/angular_devkit/build_angular/src/builders/karma/schema.json +++ b/packages/angular_devkit/build_angular/src/builders/karma/schema.json @@ -203,12 +203,12 @@ "oneOf": [ { "type": "string", - "description": "A comma seperate list of browsers to run tests against." + "description": "A comma-separated list of browsers to run tests against." }, { "const": false, "type": "boolean", - "description": "Does use run tests against a browser." + "description": "Does not run tests against a browser." } ] }, diff --git a/packages/schematics/angular/application/schema.json b/packages/schematics/angular/application/schema.json index 83df1b163873..d0c4f348feea 100644 --- a/packages/schematics/angular/application/schema.json +++ b/packages/schematics/angular/application/schema.json @@ -84,7 +84,7 @@ "x-user-analytics": "ep.ng_style" }, "skipTests": { - "description": "Skip the generation of a unit test files `spec.ts`.", + "description": "Skip the generation of unit test files `spec.ts`.", "type": "boolean", "default": false, "alias": "S" diff --git a/packages/schematics/angular/ng-new/schema.json b/packages/schematics/angular/ng-new/schema.json index 2c69fa84aaad..6494b1889d96 100644 --- a/packages/schematics/angular/ng-new/schema.json +++ b/packages/schematics/angular/ng-new/schema.json @@ -152,7 +152,7 @@ "aiConfig": { "type": "array", "uniqueItems": true, - "description": "Specifies which AI tools to generate configuration files for. These file are used to improve the outputs of AI tools by following the best practices.", + "description": "Specifies which AI tools to generate configuration files for. These files are used to improve the outputs of AI tools by following the best practices.", "items": { "type": "string", "enum": ["none", "claude-code", "cursor", "gemini-cli", "open-ai-codex", "vscode"] From b3baa20c6cb5b00c9df4d3d4d072435b324566e2 Mon Sep 17 00:00:00 2001 From: MeAkib Date: Mon, 19 Oct 2026 07:29:16 +0600 Subject: [PATCH 112/233] fix(@angular/build): support quotes in `styles` and `polyfills` paths The application builder generated the global styles and polyfills entry modules by wrapping each configured path in single quotes without escaping. A path containing a single quote, such as `src/dev's theme/theme.css`, produced an invalid import and the build failed with "Could not resolve" or a syntax error. Generate the import specifiers with `JSON.stringify` so that such paths are quoted correctly. (cherry picked from commit e3787076ebca0af72079f669b5b047a065b16128) --- .../application/tests/options/polyfills_spec.ts | 16 ++++++++++++++++ .../application/tests/options/styles_spec.ts | 17 +++++++++++++++++ .../tools/esbuild/application-code-bundle.ts | 12 +++++++----- .../build/src/tools/esbuild/global-styles.ts | 4 +++- 4 files changed, 43 insertions(+), 6 deletions(-) diff --git a/packages/angular/build/src/builders/application/tests/options/polyfills_spec.ts b/packages/angular/build/src/builders/application/tests/options/polyfills_spec.ts index 5fff9bd33a7c..ad68443a2e03 100644 --- a/packages/angular/build/src/builders/application/tests/options/polyfills_spec.ts +++ b/packages/angular/build/src/builders/application/tests/options/polyfills_spec.ts @@ -89,5 +89,21 @@ describeBuilder(buildApplication, APPLICATION_BUILDER_INFO, (harness) => { }); }); } + + it('uses a provided file with a single quote in its path', async () => { + await harness.writeFile('src/main.ts', 'console.log("TEST");'); + await harness.writeFile(`src/dev's polyfills/polyfills.js`, `console.log('main');`); + + harness.useTarget('build', { + ...BASE_OPTIONS, + polyfills: [`src/dev's polyfills/polyfills.js`], + }); + + const { result } = await harness.executeOnce(); + + expect(result?.success).toBe(true); + + harness.expectFile('dist/browser/polyfills.js').content.toContain(`console.log("main")`); + }); }); }); diff --git a/packages/angular/build/src/builders/application/tests/options/styles_spec.ts b/packages/angular/build/src/builders/application/tests/options/styles_spec.ts index 311b0037daa5..7c5b3d52eb8c 100644 --- a/packages/angular/build/src/builders/application/tests/options/styles_spec.ts +++ b/packages/angular/build/src/builders/application/tests/options/styles_spec.ts @@ -62,6 +62,23 @@ describeBuilder(buildApplication, APPLICATION_BUILDER_INFO, (harness) => { .content.toContain(''); }); + it('processes a style with a single quote in its path', async () => { + await harness.writeFile(`src/dev's theme/test-style-a.css`, '.test-a {color: red}'); + + harness.useTarget('build', { + ...BASE_OPTIONS, + styles: [`src/dev's theme/test-style-a.css`], + }); + + const { result } = await harness.executeOnce(); + + expect(result?.success).toBe(true); + + harness + .expectFile('dist/browser/styles.css') + .content.toMatch(/\.test-a {\s*color: red;?\s*}/); + }); + it('processes multiple styles into a single output', async () => { await harness.writeFiles({ 'src/test-style-a.css': '.test-a {color: red}', diff --git a/packages/angular/build/src/tools/esbuild/application-code-bundle.ts b/packages/angular/build/src/tools/esbuild/application-code-bundle.ts index af53e04f58af..c98ad3bcae28 100644 --- a/packages/angular/build/src/tools/esbuild/application-code-bundle.ts +++ b/packages/angular/build/src/tools/esbuild/application-code-bundle.ts @@ -364,8 +364,8 @@ export function createServerMainCodeBundleOptions( `export { ɵresetCompiledComponents } from '@angular/core';`, // Re-export all symbols including default export from 'main.server.ts' - `export { default } from '${mainServerEntryPointJsImport}';`, - `export * from '${mainServerEntryPointJsImport}';`, + `export { default } from ${JSON.stringify(mainServerEntryPointJsImport)};`, + `export * from ${JSON.stringify(mainServerEntryPointJsImport)};`, ]; return { @@ -496,8 +496,8 @@ export function createSsrEntryCodeBundleOptions( `import '${ssrInjectManifestNamespace}';`, // Re-export all symbols including default export - `import * as server from '${serverEntryPointJsImport}';`, - `export * from '${serverEntryPointJsImport}';`, + `import * as server from ${JSON.stringify(serverEntryPointJsImport)};`, + `export * from ${JSON.stringify(serverEntryPointJsImport)};`, // The below is needed to avoid // `Import "default" will always be undefined because there is no matching export` warning when no default is present. `const defaultExportName = 'default';`, @@ -740,7 +740,9 @@ function getEsBuildCommonPolyfillsOptions( } // Generate module contents with an import statement per defined polyfill - let contents = polyfillPaths.map((file) => `import '${toPosixPath(file)}';`).join('\n'); + let contents = polyfillPaths + .map((file) => `import ${JSON.stringify(toPosixPath(file))};`) + .join('\n'); // The below should be done after loading `$localize` as otherwise the locale will be overridden. if (i18nOptions.shouldInline) { diff --git a/packages/angular/build/src/tools/esbuild/global-styles.ts b/packages/angular/build/src/tools/esbuild/global-styles.ts index fd2cb13fa7b2..79afff2008af 100644 --- a/packages/angular/build/src/tools/esbuild/global-styles.ts +++ b/packages/angular/build/src/tools/esbuild/global-styles.ts @@ -92,7 +92,9 @@ export function createGlobalStylesBundleOptions( assert(files, `global style name should always be found [${args.path}]`); return { - contents: files.map((file) => `@import '${toPosixPath(file)}';`).join('\n'), + contents: files + .map((file) => `@import ${JSON.stringify(toPosixPath(file))};`) + .join('\n'), loader: 'css', resolveDir: workspaceRoot, }; From eec8dc049a21e8ee685dd07ed365e43d04802cf5 Mon Sep 17 00:00:00 2001 From: MeAkib Date: Sun, 18 Oct 2026 20:17:43 +0600 Subject: [PATCH 113/233] fix(@schematics/angular): apply `viewEncapsulation` to generated application components The `viewEncapsulation` option of the application schematic had no effect. The root component template did not set `encapsulation`, the value was not added to the component schematic defaults, so components generated later used the default encapsulation, and the `defaultEncapsulation` option added to `bootstrapModule` in `main.ts` for NgModule applications is only used by the JIT compiler. Set `encapsulation` on the root component, add `viewEncapsulation` to the component schematic defaults in `angular.json`, and remove the ineffective `defaultEncapsulation` option from `main.ts`. Fixes #34388 (cherry picked from commit 1c1fe4e88897f69116696a73c46f225b469aebab) --- .../src/app/app__suffix__.ts.template | 5 ++- .../files/module-files/src/main.ts.template | 7 +--- .../src/app/app__suffix__.ts.template | 5 ++- .../schematics/angular/application/index.ts | 6 ++- .../angular/application/index_spec.ts | 41 ++++++++++++++++--- 5 files changed, 49 insertions(+), 15 deletions(-) diff --git a/packages/schematics/angular/application/files/module-files/src/app/app__suffix__.ts.template b/packages/schematics/angular/application/files/module-files/src/app/app__suffix__.ts.template index ef9aebaa0e14..db9c4cfc0137 100644 --- a/packages/schematics/angular/application/files/module-files/src/app/app__suffix__.ts.template +++ b/packages/schematics/angular/application/files/module-files/src/app/app__suffix__.ts.template @@ -1,6 +1,7 @@ -import { Component, signal } from '@angular/core'; +import { Component, signal<% if (!!viewEncapsulation) { %>, ViewEncapsulation<% } %> } from '@angular/core'; -@Component({ +@Component({<% if (!!viewEncapsulation) { %> + encapsulation: ViewEncapsulation.<%= viewEncapsulation %>,<% } %> selector: '<%= selector %>', standalone: false,<% if (inlineStyle) { %> styles: [],<% } else { %> diff --git a/packages/schematics/angular/application/files/module-files/src/main.ts.template b/packages/schematics/angular/application/files/module-files/src/main.ts.template index 0fcb878b1e23..94cbfa256d61 100644 --- a/packages/schematics/angular/application/files/module-files/src/main.ts.template +++ b/packages/schematics/angular/application/files/module-files/src/main.ts.template @@ -1,8 +1,5 @@ -<% if (!!viewEncapsulation) { %>import { ViewEncapsulation } from '@angular/core'; -<% } %>import { platformBrowser } from '@angular/platform-browser'; +import { platformBrowser } from '@angular/platform-browser'; import { AppModule } from './app/app<%= typeSeparator %>module'; -platformBrowser().bootstrapModule(AppModule, { - <% if (!!viewEncapsulation) { %> defaultEncapsulation: ViewEncapsulation.<%= viewEncapsulation %><% } %> -}) +platformBrowser().bootstrapModule(AppModule) .catch(err => console.error(err)); diff --git a/packages/schematics/angular/application/files/standalone-files/src/app/app__suffix__.ts.template b/packages/schematics/angular/application/files/standalone-files/src/app/app__suffix__.ts.template index dfdb04abcb76..2106166ea22f 100644 --- a/packages/schematics/angular/application/files/standalone-files/src/app/app__suffix__.ts.template +++ b/packages/schematics/angular/application/files/standalone-files/src/app/app__suffix__.ts.template @@ -1,7 +1,8 @@ -import { Component, signal } from '@angular/core';<% if (routing) { %> +import { Component, signal<% if (!!viewEncapsulation) { %>, ViewEncapsulation<% } %> } from '@angular/core';<% if (routing) { %> import { RouterOutlet } from '@angular/router';<% } %> -@Component({ +@Component({<% if (!!viewEncapsulation) { %> + encapsulation: ViewEncapsulation.<%= viewEncapsulation %>,<% } %> imports: [<% if (routing) { %>RouterOutlet<% } %>], selector: '<%= selector %>',<% if (inlineStyle) { %> styles: [],<% } else { %> diff --git a/packages/schematics/angular/application/index.ts b/packages/schematics/angular/application/index.ts index 2820634b1ba8..cac60c23177b 100644 --- a/packages/schematics/angular/application/index.ts +++ b/packages/schematics/angular/application/index.ts @@ -206,7 +206,8 @@ function addAppToWorkspaceFile(options: ApplicationOptions, appDir: string): Rul options.inlineTemplate || options.inlineStyle || options.minimal || - options.style !== Style.Css + options.style !== Style.Css || + options.viewEncapsulation ) { const componentSchematicsOptions: JsonObject = {}; if (options.inlineTemplate ?? options.minimal) { @@ -218,6 +219,9 @@ function addAppToWorkspaceFile(options: ApplicationOptions, appDir: string): Rul if (options.style && options.style !== Style.Css) { componentSchematicsOptions.style = options.style; } + if (options.viewEncapsulation) { + componentSchematicsOptions.viewEncapsulation = options.viewEncapsulation; + } schematics['@schematics/angular:component'] = componentSchematicsOptions; } diff --git a/packages/schematics/angular/application/index_spec.ts b/packages/schematics/angular/application/index_spec.ts index ad2ba04ff348..7f86e245553a 100644 --- a/packages/schematics/angular/application/index_spec.ts +++ b/packages/schematics/angular/application/index_spec.ts @@ -704,6 +704,35 @@ describe('Application Schematic', () => { expect(main).toContain('bootstrapApplication'); }); + it(`should set 'encapsulation' in the root component when 'viewEncapsulation' is provided`, async () => { + const options = { ...defaultOptions, viewEncapsulation: ViewEncapsulation.None }; + const tree = await schematicRunner.runSchematic('application', options, workspaceTree); + + const component = tree.readContent('/projects/foo/src/app/app.ts'); + expect(component).toContain( + `import { Component, signal, ViewEncapsulation } from '@angular/core';`, + ); + expect(component).toContain('encapsulation: ViewEncapsulation.None'); + }); + + it(`should add 'viewEncapsulation' to the component schematic defaults when provided`, async () => { + const options = { ...defaultOptions, viewEncapsulation: ViewEncapsulation.None }; + const tree = await schematicRunner.runSchematic('application', options, workspaceTree); + + const { projects } = JSON.parse(tree.readContent('/angular.json')); + expect(projects.foo.schematics['@schematics/angular:component'].viewEncapsulation).toBe('None'); + }); + + it(`should not set 'encapsulation' in the root component by default`, async () => { + const tree = await schematicRunner.runSchematic('application', defaultOptions, workspaceTree); + + expect(tree.readContent('/projects/foo/src/app/app.ts')).not.toContain('encapsulation'); + const { projects } = JSON.parse(tree.readContent('/angular.json')); + expect(projects.foo.schematics?.['@schematics/angular:component']?.viewEncapsulation).toBe( + undefined, + ); + }); + describe('standalone=false', () => { it('should add the provideZoneChangeDetection with event coalescing option by default with zone.js apps', async () => { const tree = await schematicRunner.runSchematic( @@ -720,7 +749,7 @@ describe('Application Schematic', () => { expect(content).toContain('provideZoneChangeDetection({ eventCoalescing: true })'); }); - it(`should set 'defaultEncapsulation' in main.ts when 'ViewEncapsulation' is provided`, async () => { + it(`should set 'encapsulation' in the root component when 'viewEncapsulation' is provided`, async () => { const tree = await schematicRunner.runSchematic( 'application', { @@ -731,10 +760,12 @@ describe('Application Schematic', () => { workspaceTree, ); - const path = '/projects/foo/src/main.ts'; - const content = tree.readContent(path); - expect(content).toContain('defaultEncapsulation: ViewEncapsulation.ShadowDom'); - expect(content).toContain(`import { ViewEncapsulation } from '@angular/core'`); + const component = tree.readContent('/projects/foo/src/app/app.ts'); + expect(component).toContain( + `import { Component, signal, ViewEncapsulation } from '@angular/core';`, + ); + expect(component).toContain('encapsulation: ViewEncapsulation.ShadowDom'); + expect(tree.readContent('/projects/foo/src/main.ts')).not.toContain('defaultEncapsulation'); }); it('should handle the routing flag', async () => { From 36d988001e1d36d02a759f2580bd251fff175e07 Mon Sep 17 00:00:00 2001 From: MeAkib Date: Sun, 18 Oct 2026 17:12:12 +0600 Subject: [PATCH 114/233] fix(@schematics/angular): skip `webWorkerTsConfig` for unit-test builder test targets The `web-worker` schematic added the `webWorkerTsConfig` option to the project's `test` target regardless of its builder. New applications use the `@angular/build:unit-test` builder, which does not have this option, so `ng test` failed schema validation with `Unknown option "webWorkerTsConfig"` after generating a web worker. The option is no longer added to `test` targets that use the unit-test builder, which reads build options from its `buildTarget`. Other test builders, such as Karma, still receive the option. Fixes #34385 (cherry picked from commit 41b54ecdda17b96924d82873042c04dc7d3a4e40) --- .../schematics/angular/web-worker/index.ts | 4 +++- .../angular/web-worker/index_spec.ts | 20 +++++++++++++++++++ 2 files changed, 23 insertions(+), 1 deletion(-) diff --git a/packages/schematics/angular/web-worker/index.ts b/packages/schematics/angular/web-worker/index.ts index a19e2b714174..45e1f39ad34c 100644 --- a/packages/schematics/angular/web-worker/index.ts +++ b/packages/schematics/angular/web-worker/index.ts @@ -26,6 +26,7 @@ import { parseName } from '../utility/parse-name'; import { relativePathToWorkspaceRoot } from '../utility/paths'; import { createProjectSchematic } from '../utility/project'; import { buildDefaultPath, updateWorkspace } from '../utility/workspace'; +import { Builders } from '../utility/workspace-models'; import { Schema as WebWorkerOptions } from './schema'; function addSnippet(options: WebWorkerOptions): Rule { @@ -115,7 +116,8 @@ const webWorkerSchematic: RuleFactory = createProjectSchematic const workerConfigPath = join(root, 'tsconfig.worker.json'); (buildTarget.options ??= {}).webWorkerTsConfig ??= workerConfigPath; - if (testTarget) { + // The unit-test builder has no `webWorkerTsConfig` option and reads it from the build target. + if (testTarget && testTarget.builder !== Builders.BuildUnitTest) { (testTarget.options ??= {}).webWorkerTsConfig ??= workerConfigPath; } }), diff --git a/packages/schematics/angular/web-worker/index_spec.ts b/packages/schematics/angular/web-worker/index_spec.ts index c1ab48b8d196..a922a6d3cee6 100644 --- a/packages/schematics/angular/web-worker/index_spec.ts +++ b/packages/schematics/angular/web-worker/index_spec.ts @@ -9,6 +9,7 @@ import { SchematicTestRunner, UnitTestTree } from '@angular-devkit/schematics/testing'; import { parse as parseJson } from 'jsonc-parser'; import { Schema as ApplicationOptions } from '../application/schema'; +import { Builders } from '../utility/workspace-models'; import { Schema as WorkspaceOptions } from '../workspace/schema'; import { Schema as WebWorkerOptions } from './schema'; @@ -68,6 +69,25 @@ describe('Web Worker Schematic', () => { ); }); + it('should not add the webWorkerTsConfig option to a unit-test builder test target', async () => { + const tree = await schematicRunner.runSchematic('web-worker', defaultOptions, appTree); + const { projects } = JSON.parse(tree.readContent('/angular.json')); + expect(projects.bar.architect.test.builder).toBe(Builders.BuildUnitTest); + expect(projects.bar.architect.test.options?.webWorkerTsConfig).toBeUndefined(); + }); + + it('should add the webWorkerTsConfig option to a karma builder test target', async () => { + const config = JSON.parse(appTree.readContent('/angular.json')); + config.projects.bar.architect.test = { builder: Builders.BuildKarma, options: {} }; + appTree.overwrite('/angular.json', JSON.stringify(config, undefined, 2)); + + const tree = await schematicRunner.runSchematic('web-worker', defaultOptions, appTree); + const { projects } = JSON.parse(tree.readContent('/angular.json')); + expect(projects.bar.architect.test.options.webWorkerTsConfig).toBe( + 'projects/bar/tsconfig.worker.json', + ); + }); + it('should add snippet to sibling file', async () => { const tree = await schematicRunner.runSchematic('web-worker', defaultOptions, appTree); const appComponent = tree.readContent('/projects/bar/src/app/app.ts'); From 3a549925e2adf2101ae635da1e4a9cf0217c13d2 Mon Sep 17 00:00:00 2001 From: MeAkib Date: Fri, 16 Oct 2026 21:25:20 +0600 Subject: [PATCH 115/233] fix(@schematics/angular): correct error and warning messages in environments schematic The error for non-application projects concatenated the first sentence with the project type before evaluating the ternary, so the "Only application project types are supported" sentence was never printed and projects without a `projectType` were reported as having a "projectType" of "undefined". The third-party `server` builder warning also printed the `build` target's builder instead of the `server` target's builder. Wrap the ternary in parentheses, use the `server` target's builder in the warning, and fix the typos in both error messages. (cherry picked from commit 32dd079da3fd6b53fe6d57eaba0ee2bcfb8f3b08) --- .../schematics/angular/environments/index.ts | 11 ++--- .../angular/environments/index_spec.ts | 44 +++++++++++++++++++ 2 files changed, 50 insertions(+), 5 deletions(-) diff --git a/packages/schematics/angular/environments/index.ts b/packages/schematics/angular/environments/index.ts index 7082689c3348..f32bb850ed3d 100644 --- a/packages/schematics/angular/environments/index.ts +++ b/packages/schematics/angular/environments/index.ts @@ -19,16 +19,17 @@ export default function (options: EnvironmentOptions): Rule { return updateWorkspace((workspace) => { const project = workspace.projects.get(options.project); if (!project) { - throw new SchematicsException(`Project name "${options.project}" doesn't not exist.`); + throw new SchematicsException(`Project name "${options.project}" does not exist.`); } const type = project.extensions['projectType']; if (type !== 'application') { return log( 'error', - 'Only application project types are support by this schematic.' + type - ? ` Project "${options.project}" has a "projectType" of "${type}".` - : ` Project "${options.project}" has no "projectType" defined.`, + 'Only application project types are supported by this schematic.' + + (type + ? ` Project "${options.project}" has a "projectType" of "${type}".` + : ` Project "${options.project}" has no "projectType" defined.`), ); } @@ -89,7 +90,7 @@ function* generateConfigurationEnvironments( if (serverTarget && serverTarget.builder !== AngularBuilder.Server) { yield log( 'warn', - `"server" target found for project "${projectName}" has a third-party builder "${buildTarget.builder}".` + + `"server" target found for project "${projectName}" has a third-party builder "${serverTarget.builder}".` + ' The generated project options may not be compatible with this builder.', ); } diff --git a/packages/schematics/angular/environments/index_spec.ts b/packages/schematics/angular/environments/index_spec.ts index d53026a28a4d..49a249cef715 100644 --- a/packages/schematics/angular/environments/index_spec.ts +++ b/packages/schematics/angular/environments/index_spec.ts @@ -192,4 +192,48 @@ describe('Environments Schematic', () => { }), ); }); + + it('should log an error for non-application projects', async () => { + const config = JSON.parse(applicationTree.readContent('/angular.json')); + config.projects.foo.projectType = 'library'; + applicationTree.overwrite('/angular.json', JSON.stringify(config, undefined, 2)); + + const logs: string[] = []; + const loggerSubscription = schematicRunner.logger.subscribe(({ message }) => + logs.push(message), + ); + + try { + await runEnvironmentsSchematic(); + } finally { + loggerSubscription.unsubscribe(); + } + + expect(logs).toEqual([ + 'Only application project types are supported by this schematic.' + + ' Project "foo" has a "projectType" of "library".', + ]); + }); + + it('should log the builder of a third-party server target', async () => { + const config = JSON.parse(applicationTree.readContent('/angular.json')); + config.projects.foo.architect.server = { builder: 'custom:server' }; + applicationTree.overwrite('/angular.json', JSON.stringify(config, undefined, 2)); + + const logs: string[] = []; + const loggerSubscription = schematicRunner.logger.subscribe(({ message }) => + logs.push(message), + ); + + try { + await runEnvironmentsSchematic(); + } finally { + loggerSubscription.unsubscribe(); + } + + expect(logs).toContain( + '"server" target found for project "foo" has a third-party builder "custom:server".' + + ' The generated project options may not be compatible with this builder.', + ); + }); }); From 2b8f8ff71ff759a3506e355bb0bba0832139cc7f Mon Sep 17 00:00:00 2001 From: MeAkib Date: Sun, 18 Oct 2026 19:39:04 +0600 Subject: [PATCH 116/233] docs(@schematics/angular): correct generated file name examples in `name` descriptions The `name` option descriptions of the directive, service, enum, interface, pipe, guard, interceptor and resolver schematics showed file names that include the type suffix, such as `my-directive.directive.ts` and `my-pipe.pipe.ts`. By default, these schematics no longer add the type to the file name, and the pipe, guard, interceptor and resolver schematics use `-` as the type separator. Update the examples to match the default output. (cherry picked from commit 452019db8b0b67a076435bc3b08d70a1f943b116) --- packages/schematics/angular/directive/schema.json | 2 +- packages/schematics/angular/enum/schema.json | 2 +- packages/schematics/angular/guard/schema.json | 2 +- packages/schematics/angular/interceptor/schema.json | 2 +- packages/schematics/angular/interface/schema.json | 2 +- packages/schematics/angular/pipe/schema.json | 2 +- packages/schematics/angular/resolver/schema.json | 2 +- packages/schematics/angular/service/schema.json | 2 +- 8 files changed, 8 insertions(+), 8 deletions(-) diff --git a/packages/schematics/angular/directive/schema.json b/packages/schematics/angular/directive/schema.json index 6d672fc4fdeb..37ed01266c4b 100644 --- a/packages/schematics/angular/directive/schema.json +++ b/packages/schematics/angular/directive/schema.json @@ -8,7 +8,7 @@ "properties": { "name": { "type": "string", - "description": "The name for the new directive. This will be used to create the directive's class and spec files (e.g., `my-directive.directive.ts` and `my-directive.directive.spec.ts`).", + "description": "The name for the new directive. This will be used to create the directive's class and spec files (e.g., `my-directive.ts` and `my-directive.spec.ts`).", "$default": { "$source": "argv", "index": 0 diff --git a/packages/schematics/angular/enum/schema.json b/packages/schematics/angular/enum/schema.json index ae6b17f457bd..3b3ec536db8b 100644 --- a/packages/schematics/angular/enum/schema.json +++ b/packages/schematics/angular/enum/schema.json @@ -8,7 +8,7 @@ "properties": { "name": { "type": "string", - "description": "The name for the new enum. This will be used to create the enum file (e.g., `my-enum.enum.ts`).", + "description": "The name for the new enum. This will be used to create the enum file (e.g., `my-enum.ts`).", "$default": { "$source": "argv", "index": 0 diff --git a/packages/schematics/angular/guard/schema.json b/packages/schematics/angular/guard/schema.json index 9e1a9f3084c6..80ee83a35ff7 100644 --- a/packages/schematics/angular/guard/schema.json +++ b/packages/schematics/angular/guard/schema.json @@ -8,7 +8,7 @@ "properties": { "name": { "type": "string", - "description": "The name for the new route guard. This will be used to create the guard's class and spec files (e.g., `my-guard.guard.ts` and `my-guard.guard.spec.ts`).", + "description": "The name for the new route guard. This will be used to create the guard's class and spec files (e.g., `example-guard.ts` and `example-guard.spec.ts`).", "$default": { "$source": "argv", "index": 0 diff --git a/packages/schematics/angular/interceptor/schema.json b/packages/schematics/angular/interceptor/schema.json index e42e0c675e8e..7589743f22b1 100755 --- a/packages/schematics/angular/interceptor/schema.json +++ b/packages/schematics/angular/interceptor/schema.json @@ -8,7 +8,7 @@ "properties": { "name": { "type": "string", - "description": "The name for the new interceptor. This will be used to create the interceptor's class and spec files (e.g., `my-interceptor.interceptor.ts` and `my-interceptor.interceptor.spec.ts`).", + "description": "The name for the new interceptor. This will be used to create the interceptor's class and spec files (e.g., `example-interceptor.ts` and `example-interceptor.spec.ts`).", "$default": { "$source": "argv", "index": 0 diff --git a/packages/schematics/angular/interface/schema.json b/packages/schematics/angular/interface/schema.json index ab47d1713ab4..52c117fa7068 100644 --- a/packages/schematics/angular/interface/schema.json +++ b/packages/schematics/angular/interface/schema.json @@ -8,7 +8,7 @@ "properties": { "name": { "type": "string", - "description": "The name for the new interface. This will be used to create the interface file (e.g., `my-interface.interface.ts`).", + "description": "The name for the new interface. This will be used to create the interface file (e.g., `my-interface.ts`).", "$default": { "$source": "argv", "index": 0 diff --git a/packages/schematics/angular/pipe/schema.json b/packages/schematics/angular/pipe/schema.json index 19803a524ed4..2aaf6e062e7e 100644 --- a/packages/schematics/angular/pipe/schema.json +++ b/packages/schematics/angular/pipe/schema.json @@ -8,7 +8,7 @@ "properties": { "name": { "type": "string", - "description": "The name for the new pipe. This will be used to create the pipe's class and spec files (e.g., `my-pipe.pipe.ts` and `my-pipe.pipe.spec.ts`).", + "description": "The name for the new pipe. This will be used to create the pipe's class and spec files (e.g., `example-pipe.ts` and `example-pipe.spec.ts`).", "$default": { "$source": "argv", "index": 0 diff --git a/packages/schematics/angular/resolver/schema.json b/packages/schematics/angular/resolver/schema.json index 1a5654f3c7cf..db6a7d4ff73d 100644 --- a/packages/schematics/angular/resolver/schema.json +++ b/packages/schematics/angular/resolver/schema.json @@ -8,7 +8,7 @@ "properties": { "name": { "type": "string", - "description": "The name for the new resolver. This will be used to create the resolver's class and spec files (e.g., `my-resolver.resolver.ts` and `my-resolver.resolver.spec.ts`).", + "description": "The name for the new resolver. This will be used to create the resolver's class and spec files (e.g., `example-resolver.ts` and `example-resolver.spec.ts`).", "$default": { "$source": "argv", "index": 0 diff --git a/packages/schematics/angular/service/schema.json b/packages/schematics/angular/service/schema.json index a3ebf9d3a3fe..b081c31dada2 100644 --- a/packages/schematics/angular/service/schema.json +++ b/packages/schematics/angular/service/schema.json @@ -8,7 +8,7 @@ "properties": { "name": { "type": "string", - "description": "The name for the new service. This will be used to create the service's class and spec files (e.g., `my-service.service.ts` and `my-service.service.spec.ts`).", + "description": "The name for the new service. This will be used to create the service's class and spec files (e.g., `my-service.ts` and `my-service.spec.ts`).", "$default": { "$source": "argv", "index": 0 From 98ef1796ee6206ab183dc6868d4d73dba3b65e02 Mon Sep 17 00:00:00 2001 From: MeAkib Date: Fri, 16 Oct 2026 00:13:49 +0600 Subject: [PATCH 117/233] docs(@angular/cli): correct CSS resource output location in `ng build` description The long description stated that resources referenced in CSS, such as images and fonts, are written and fingerprinted at the root of the output folder. The application builder writes them to the `media` directory of the browser output, which is configurable with `outputPath.media`, and only adds a hash when `outputHashing` is `all` or `media`. (cherry picked from commit 7305b7c7378c86fc2d539f012c5b809da36d9885) --- packages/angular/cli/src/commands/build/long-description.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/packages/angular/cli/src/commands/build/long-description.md b/packages/angular/cli/src/commands/build/long-description.md index b2c14d8f23fe..cba16adeb716 100644 --- a/packages/angular/cli/src/commands/build/long-description.md +++ b/packages/angular/cli/src/commands/build/long-description.md @@ -13,6 +13,7 @@ Note that in the configuration file, you must specify names in camelCase. Some additional options can only be set through the configuration file, either by direct editing or with the `ng config` command. These include `assets`, `styles`, and `scripts` objects that provide runtime-global resources to include in the project. -Resources in CSS, such as images and fonts, are automatically written and fingerprinted at the root of the output folder. +Resources in CSS, such as images and fonts, are automatically written to the `media` directory of the browser output +(configurable with the `outputPath.media` option) and fingerprinted when `outputHashing` is set to `all` or `media`. For further details, see [Workspace Configuration](reference/configs/workspace-config). From 5887a6f8e03415410b0811617b9df1ca24944f0b Mon Sep 17 00:00:00 2001 From: Shuaib Hasan Akib <48770016+MeAkib@users.noreply.github.com> Date: Mon, 19 Oct 2026 22:02:26 +0600 Subject: [PATCH 118/233] docs(@angular/cli): remove references to the default project The `ng deploy` descriptions stated that the deploy builder runs for the default project when no project name is supplied, and the `ng new` long description described the initial application as the workspace's default project. The CLI no longer has a default project: architect commands use the only project that has the target, or the project in the current working directory. Describe that behavior instead. (cherry picked from commit 4a883c88213124b63c475373271b673bc4ec00ef) --- packages/angular/cli/src/commands/deploy/cli.ts | 3 ++- packages/angular/cli/src/commands/deploy/long-description.md | 3 ++- packages/angular/cli/src/commands/new/long-description.md | 2 +- 3 files changed, 5 insertions(+), 3 deletions(-) diff --git a/packages/angular/cli/src/commands/deploy/cli.ts b/packages/angular/cli/src/commands/deploy/cli.ts index 947dc90af2d4..563d7ffaafaa 100644 --- a/packages/angular/cli/src/commands/deploy/cli.ts +++ b/packages/angular/cli/src/commands/deploy/cli.ts @@ -39,5 +39,6 @@ export default class DeployCommandModule command = 'deploy [project]'; longDescriptionPath = join(__dirname, 'long-description.md'); describe = - 'Invokes the deploy builder for a specified project or for the default project in the workspace.'; + 'Invokes the deploy builder for a specified project, the only project with a deploy target, ' + + 'or the project in the current working directory.'; } diff --git a/packages/angular/cli/src/commands/deploy/long-description.md b/packages/angular/cli/src/commands/deploy/long-description.md index 0436390680a4..53a2253be42b 100644 --- a/packages/angular/cli/src/commands/deploy/long-description.md +++ b/packages/angular/cli/src/commands/deploy/long-description.md @@ -1,5 +1,6 @@ The command takes an optional project name, as specified in the `projects` section of the `angular.json` workspace configuration file. -When a project name is not supplied, executes the `deploy` builder for the default project. +When a project name is not supplied, executes the `deploy` builder for the only project that has a `deploy` target, +or for the project in the current working directory. To use the `ng deploy` command, use `ng add` to add a package that implements deployment capabilities to your favorite platform. Adding the package automatically updates your workspace configuration, adding a deployment diff --git a/packages/angular/cli/src/commands/new/long-description.md b/packages/angular/cli/src/commands/new/long-description.md index 1166f974887a..e211dadb5f35 100644 --- a/packages/angular/cli/src/commands/new/long-description.md +++ b/packages/angular/cli/src/commands/new/long-description.md @@ -1,4 +1,4 @@ -Creates and initializes a new Angular application that is the default project for a new workspace. +Creates and initializes a new Angular workspace with an initial application. Provides interactive prompts for optional configuration, such as adding routing support. All prompts can safely be allowed to default. From 3e464c3f55d4aa2b7f1cb3d62ee3104c62029a5e Mon Sep 17 00:00:00 2001 From: Nayeem Hossain Date: Sat, 17 Oct 2026 11:31:45 +0600 Subject: [PATCH 119/233] fix(@angular/build): invalidate Vite module cache for removed dev server output files Content-hashed chunks are renamed on every rebuild that changes them. The dev server removed the old names from its own file maps but left their transformed code and source maps in Vite's module graph, so memory grew with each save and the old chunk URLs kept serving stale code. Invalidate the Vite modules for removed files, as is already done for updated files. (cherry picked from commit adcdcc6688fd773491dcb9f5197eefffd4aeee45) --- .../behavior/serve-renamed-chunks_spec.ts | 57 +++++++++++++++++++ .../src/builders/dev-server/vite/index.ts | 7 +++ 2 files changed, 64 insertions(+) create mode 100644 packages/angular/build/src/builders/dev-server/tests/behavior/serve-renamed-chunks_spec.ts diff --git a/packages/angular/build/src/builders/dev-server/tests/behavior/serve-renamed-chunks_spec.ts b/packages/angular/build/src/builders/dev-server/tests/behavior/serve-renamed-chunks_spec.ts new file mode 100644 index 000000000000..d43d47def463 --- /dev/null +++ b/packages/angular/build/src/builders/dev-server/tests/behavior/serve-renamed-chunks_spec.ts @@ -0,0 +1,57 @@ +/** + * @license + * Copyright Google LLC All Rights Reserved. + * + * Use of this source code is governed by an MIT-style license that can be + * found in the LICENSE file at https://angular.dev/license + */ + +import { executeDevServer } from '../../index'; +import { describeServeBuilder } from '../jasmine-helpers'; +import { BASE_OPTIONS, DEV_SERVER_BUILDER_INFO } from '../setup'; + +describeServeBuilder(executeDevServer, DEV_SERVER_BUILDER_INFO, (harness, setupTarget) => { + describe('Behavior: "Renamed chunks"', () => { + beforeEach(async () => { + setupTarget(harness); + + await harness.writeFile('src/lazy.ts', `export const value = 'first';`); + await harness.writeFile('src/main.ts', `import('./lazy').then((m) => console.log(m.value));`); + }); + + it('does not serve a lazy chunk that a rebuild renamed', async () => { + harness.useTarget('serve', { + ...BASE_OPTIONS, + watch: true, + }); + + let oldChunk = ''; + + await harness.executeWithCases([ + async ({ result }) => { + expect(result?.success).toBeTrue(); + + const main = await (await fetch(new URL('main.js', `${result?.baseUrl}`))).text(); + oldChunk = main.match(/chunk-[a-zA-Z0-9]+\.js/)?.[0] ?? ''; + expect(oldChunk).not.toBe(''); + + // Request the chunk so that Vite transforms and caches it + const response = await fetch(new URL(oldChunk, `${result?.baseUrl}`)); + expect(response.status).toBe(200); + expect(await response.text()).toContain('first'); + + await harness.modifyFile('src/lazy.ts', (content) => content.replace('first', 'second')); + }, + async ({ result }) => { + expect(result?.success).toBeTrue(); + + const main = await (await fetch(new URL('main.js', `${result?.baseUrl}`))).text(); + expect(main).not.toContain(oldChunk); + + const response = await fetch(new URL(oldChunk, `${result?.baseUrl}`)); + expect(response.status).toBe(404); + }, + ]); + }); + }); +}); diff --git a/packages/angular/build/src/builders/dev-server/vite/index.ts b/packages/angular/build/src/builders/dev-server/vite/index.ts index 4800559a2171..7f36740cc3f5 100644 --- a/packages/angular/build/src/builders/dev-server/vite/index.ts +++ b/packages/angular/build/src/builders/dev-server/vite/index.ts @@ -288,6 +288,13 @@ export async function* serveWithVite( const filePath = '/' + normalizePath(removed.path); generatedFiles.delete(filePath); assetFiles.delete(filePath); + + // Release Vite's cached transform result for output files that no longer exist, + // such as content-hashed chunks that were renamed by the rebuild. + const moduleGraph = server.moduleGraph; + moduleGraph + .getModulesByFile(normalizePath(join(server.config.root, filePath))) + ?.forEach((m) => moduleGraph.invalidateModule(m)); } for (const file of result.files) { From d365b0008f0c5bb8bca92e83066999253f409b64 Mon Sep 17 00:00:00 2001 From: SkyZeroZx <73321943+SkyZeroZx@users.noreply.github.com> Date: Thu, 15 Oct 2026 13:09:40 -0500 Subject: [PATCH 120/233] fix(@angular/ssr): use only the first value of the `X-Forwarded-Prefix` header The `X-Forwarded-Prefix` header is validated using its first comma-separated value, like the other `X-Forwarded-*` headers. However, redirects used the entire header value. With a trusted header, any value after the first one was added to the `Location` header without being validated. The first value is now used wherever the header is read, which matches how `X-Forwarded-Host`, `X-Forwarded-Proto` and `X-Forwarded-Port` are handled. (cherry picked from commit b42cfeecfac376d1ed365ffbf9d247dbfc2bde59) --- packages/angular/ssr/src/app-engine.ts | 3 ++- packages/angular/ssr/src/app.ts | 3 ++- packages/angular/ssr/src/utils/ng.ts | 5 ++++- packages/angular/ssr/test/app-engine_spec.ts | 13 +++++++++++++ packages/angular/ssr/test/app_spec.ts | 10 ++++++++++ 5 files changed, 31 insertions(+), 3 deletions(-) diff --git a/packages/angular/ssr/src/app-engine.ts b/packages/angular/ssr/src/app-engine.ts index a5f10fbc7d92..1fa69c1f2629 100644 --- a/packages/angular/ssr/src/app-engine.ts +++ b/packages/angular/ssr/src/app-engine.ts @@ -13,6 +13,7 @@ import { EntryPointExports, getAngularAppEngineManifest } from './manifest'; import { createRedirectResponse } from './utils/redirect'; import { joinUrlParts } from './utils/url'; import { + getFirstHeaderValue, normalizeTrustProxyHeaders, sanitizeRequestHeaders, validateRequest, @@ -208,7 +209,7 @@ export class AngularAppEngine { if (preferredLocale) { const subPath = supportedLocales[preferredLocale]; if (subPath !== undefined) { - const prefix = request.headers.get('X-Forwarded-Prefix') ?? ''; + const prefix = getFirstHeaderValue(request.headers.get('X-Forwarded-Prefix')) ?? ''; return createRedirectResponse( joinUrlParts(prefix, pathname, subPath), diff --git a/packages/angular/ssr/src/app.ts b/packages/angular/ssr/src/app.ts index 517cf1e31727..69d5f9e6e100 100644 --- a/packages/angular/ssr/src/app.ts +++ b/packages/angular/ssr/src/app.ts @@ -25,6 +25,7 @@ import { AngularBootstrap, renderAngular } from './utils/ng'; import { promiseWithAbort } from './utils/promise'; import { createRedirectResponse } from './utils/redirect'; import { buildPathWithParams, joinUrlParts, stripLeadingSlash } from './utils/url'; +import { getFirstHeaderValue } from './utils/validation'; /** * A set of well-known URLs that are not handled by Angular. @@ -167,7 +168,7 @@ export class AngularServerApp { if (redirectTo !== undefined) { const location = joinUrlParts( - request.headers.get('X-Forwarded-Prefix') ?? '', + getFirstHeaderValue(request.headers.get('X-Forwarded-Prefix')) ?? '', buildPathWithParams(redirectTo, url.pathname), ); diff --git a/packages/angular/ssr/src/utils/ng.ts b/packages/angular/ssr/src/utils/ng.ts index 4ae3a7f4ed0f..028136749b17 100644 --- a/packages/angular/ssr/src/utils/ng.ts +++ b/packages/angular/ssr/src/utils/ng.ts @@ -25,6 +25,7 @@ import { import { ActivatedRoute, Router } from '@angular/router'; import { Console } from '../console'; import { addTrailingSlash, joinUrlParts, stripIndexHtmlFromURL, stripTrailingSlash } from './url'; +import { getFirstHeaderValue } from './validation'; /** * Represents the bootstrap mechanism for an Angular application. @@ -126,7 +127,9 @@ export async function renderAngular( const requestPrefix = envInjector.get(APP_BASE_HREF, null, { optional: true }) ?? - envInjector.get(REQUEST, null, { optional: true })?.headers.get('X-Forwarded-Prefix'); + getFirstHeaderValue( + envInjector.get(REQUEST, null, { optional: true })?.headers.get('X-Forwarded-Prefix'), + ); const { pathname, search, hash } = envInjector.get(PlatformLocation); const finalUrl = constructSerializedUrl(router, { pathname, search, hash }, requestPrefix); diff --git a/packages/angular/ssr/test/app-engine_spec.ts b/packages/angular/ssr/test/app-engine_spec.ts index eae063eec700..db03015b85f1 100644 --- a/packages/angular/ssr/test/app-engine_spec.ts +++ b/packages/angular/ssr/test/app-engine_spec.ts @@ -202,6 +202,19 @@ describe('AngularAppEngine', () => { expect(response?.headers.get('Vary')).toBe('X-Forwarded-Prefix, Accept-Language'); }); + it('should only use the first value of the forwarded prefix in locale redirect location', async () => { + const request = new Request('https://example.com', { + headers: { + 'Accept-Language': 'it', + 'X-Forwarded-Prefix': '/app, /"', + }, + }); + + const response = await appEngine.handle(request); + expect(response?.status).toBe(302); + expect(response?.headers.get('Location')).toBe('/app/it'); + }); + it('should completely ignore proxy headers if not allowed', async () => { const strictEngine = new AngularAppEngine({ trustProxyHeaders: false }); const request = new Request('https://example.com', { diff --git a/packages/angular/ssr/test/app_spec.ts b/packages/angular/ssr/test/app_spec.ts index 8d8ee9add00b..68e3ed2eb1c2 100644 --- a/packages/angular/ssr/test/app_spec.ts +++ b/packages/angular/ssr/test/app_spec.ts @@ -538,6 +538,16 @@ describe('AngularServerApp', () => { expect(response?.headers.get('location')).toBe('/base/home?filter=test'); expect(response?.status).toBe(302); }); + + it('should only use the first value of the "X-Forwarded-Prefix" header in redirects', async () => { + const response = await app.handle( + new Request('http://localhost/redirect', { + headers: { 'X-Forwarded-Prefix': '/base, /"' }, + }), + ); + expect(response?.headers.get('location')).toBe('/base/home'); + expect(response?.status).toBe(302); + }); }); describe('Critical CSS inlining', () => { From 7d9ba628034866a2ec51a6357f05c9ce426cbb76 Mon Sep 17 00:00:00 2001 From: Charles Lyding <19598772+clydin@users.noreply.github.com> Date: Fri, 16 Oct 2026 11:35:33 -0400 Subject: [PATCH 121/233] fix(@angular/build): match proxy glob patterns against URL pathname only When normalizing proxy configurations for Vite, glob patterns are converted into regular expression strings using picomatch. Because picomatch builds regular expressions assuming the input is a file path and anchors them with `$`, whereas Vite tests regex proxy keys against `req.url` (which includes any query string), requests with query parameters could fail to match glob entries such as `/search/**` or `/api/*.json`, or inadvertently match wildcards against query string parameters. Adapt the generated regular expression so that wildcard tokens do not match across the `?` query delimiter and end-of-path anchors allow an optional query string after the matched pathname. Closes #34257 (cherry picked from commit f9f3864974e90c6ea78c53cc4a0cab3f2e4477dc) --- .../tests/options/proxy-config_spec.ts | 52 ++++++- .../build/src/utils/load-proxy-config.ts | 32 ++++- .../build/src/utils/load-proxy-config_spec.ts | 129 ++++++++++++++++++ 3 files changed, 211 insertions(+), 2 deletions(-) create mode 100644 packages/angular/build/src/utils/load-proxy-config_spec.ts diff --git a/packages/angular/build/src/builders/dev-server/tests/options/proxy-config_spec.ts b/packages/angular/build/src/builders/dev-server/tests/options/proxy-config_spec.ts index 745da6eee969..31ea54fc4004 100644 --- a/packages/angular/build/src/builders/dev-server/tests/options/proxy-config_spec.ts +++ b/packages/angular/build/src/builders/dev-server/tests/options/proxy-config_spec.ts @@ -330,6 +330,56 @@ describeServeBuilder(executeDevServer, DEV_SERVER_BUILDER_INFO, (harness, setupT await otherProxyServer.close(); } }); + + it('matches glob entries against the URL pathname when a query string is present', async () => { + harness.useTarget('serve', { + ...BASE_OPTIONS, + proxyConfig: 'proxy.config.json', + }); + + const proxyServer = await createProxyServer(); + try { + await harness.writeFiles({ + 'proxy.config.json': ` + { + "/api/test/**": { "target": "http://127.0.0.1:${proxyServer.address.port}" } + } + `, + }); + + const { result, response } = await executeOnceAndFetch(harness, '/api/test?q=angular'); + + expect(result?.success).toBeTrue(); + expect(await response?.text()).toContain('TEST_API_RETURN'); + } finally { + await proxyServer.close(); + } + }); + + it('does not match glob wildcards against query string parameters', async () => { + harness.useTarget('serve', { + ...BASE_OPTIONS, + proxyConfig: 'proxy.config.json', + }); + + const proxyServer = await createProxyServer(); + try { + await harness.writeFiles({ + 'proxy.config.json': ` + { + "/api/*.json": { "target": "http://127.0.0.1:${proxyServer.address.port}" } + } + `, + }); + + const { result, response } = await executeOnceAndFetch(harness, '/api/test?file=data.json'); + + expect(result?.success).toBeTrue(); + expect(await response?.text()).not.toContain('TEST_API_RETURN'); + } finally { + await proxyServer.close(); + } + }); }); }); @@ -340,7 +390,7 @@ describeServeBuilder(executeDevServer, DEV_SERVER_BUILDER_INFO, (harness, setupT */ async function createProxyServer(body = 'TEST_API_RETURN') { const proxyServer = createServer((request, response) => { - if (request.url?.endsWith('/test')) { + if (request.url?.split('?')[0].endsWith('/test')) { response.writeHead(200); response.end(body); } else { diff --git a/packages/angular/build/src/utils/load-proxy-config.ts b/packages/angular/build/src/utils/load-proxy-config.ts index e40b1981d764..f32db992ac92 100644 --- a/packages/angular/build/src/utils/load-proxy-config.ts +++ b/packages/angular/build/src/utils/load-proxy-config.ts @@ -118,7 +118,7 @@ function normalizeProxyConfiguration( // since Vite proxies a request with the first entry that matches it. const orderedProxy: Record = {}; for (const [key, value] of Object.entries(normalizedProxy)) { - const context = key[0] !== '^' && isDynamicPattern(key) ? makeRegExpFromGlob(key).source : key; + const context = key[0] !== '^' && isDynamicPattern(key) ? makeUrlRegExpFromGlob(key) : key; orderedProxy[context] = value; } normalizedProxy = orderedProxy; @@ -151,6 +151,36 @@ function normalizeProxyConfiguration( return normalizedProxy; } +/** + * Converts a glob pattern to a regular expression source string that matches + * the pathname portion of a request URL while allowing an optional query string. + * + * Vite tests regex proxy keys against `req.url`, which includes the query string, + * whereas `picomatch` generates regexes assuming the input is only a pathname. + */ +function makeUrlRegExpFromGlob(glob: string): string { + const { source } = makeRegExpFromGlob(glob); + + return ( + source + // Ensure picomatch's "at least one character" lookahead does not + // treat the `?` query delimiter as a pathname character (e.g., `/api/*` on `/api/?a=1`). + .replaceAll('(?=.)', '(?=[^?])') + // Prevent single-segment wildcards (`*` and `?`) from matching + // across `?` into the query string (e.g., `/api/*.json` on `/api/users?file=data.json`). + .replaceAll('[^/]', '[^/?]') + // Prevent leading-dot-aware `?` wildcards from matching the `?` delimiter. + .replaceAll('[^.\\/]', '[^.\\/?]') + // Prevent multi-segment globstars (`**`) from matching across `?` into the query string + // (e.g., `/api/**/users` on `/api/other?redirect=/users`). + .replaceAll('\\.).)*?', '\\.)[^?])*?') + // Replace unescaped end-of-input anchors (`$`, both at the end of the pattern and inside + // internal alternation groups for trailing `/**` or negated globs) so an optional query + // string is permitted after the matched pathname. + .replace(/(? { + let tempDir: string; + + beforeEach(async () => { + const baseTmpDir = process.env['TEST_TMPDIR']; + assert(baseTmpDir, 'TEST_TMPDIR is not set'); + tempDir = await mkdtemp(join(baseTmpDir, 'angular-proxy-config-spec-')); + }); + + afterEach(async () => { + await rm(tempDir, { recursive: true, force: true }); + }); + + async function createGlobMatcher(glob: string): Promise<(url: string) => boolean> { + const configPath = join(tempDir, 'proxy.conf.json'); + await writeFile(configPath, JSON.stringify({ [glob]: { target: 'http://localhost:3000' } })); + const proxy = await loadProxyConfiguration(tempDir, 'proxy.conf.json'); + assert(proxy, 'Expected proxy configuration to be loaded'); + const keys = Object.keys(proxy); + expect(keys.length).toBe(1); + const regex = new RegExp(keys[0]); + + return (url: string) => regex.test(url); + } + + describe('glob to RegExp conversion with query strings', () => { + it('handles trailing globstar (/**) with and without query strings', async () => { + const matches = await createGlobMatcher('/search/**'); + + expect(matches('/search')).toBeTrue(); + expect(matches('/search?q=angular')).toBeTrue(); + expect(matches('/search/')).toBeTrue(); + expect(matches('/search/?q=angular')).toBeTrue(); + expect(matches('/search/items')).toBeTrue(); + expect(matches('/search/items?q=angular')).toBeTrue(); + expect(matches('/search/items?callback=/.hidden')).toBeTrue(); + + expect(matches('/searching')).toBeFalse(); + expect(matches('/searching?q=angular')).toBeFalse(); + expect(matches('/other?redirect=/search')).toBeFalse(); + }); + + it('handles single-segment wildcard (*) without matching across slashes or query strings', async () => { + const matches = await createGlobMatcher('/api/*'); + + expect(matches('/api/users')).toBeTrue(); + expect(matches('/api/users?id=1')).toBeTrue(); + expect(matches('/api/users?redirect=/home/page')).toBeTrue(); + + expect(matches('/api')).toBeFalse(); + expect(matches('/api/')).toBeFalse(); + expect(matches('/api/?a=1')).toBeFalse(); + expect(matches('/api/users/profile')).toBeFalse(); + expect(matches('/api/users/profile?a=1')).toBeFalse(); + }); + + it('handles suffix globs (*.json) without matching query parameters', async () => { + const matches = await createGlobMatcher('/api/*.json'); + + expect(matches('/api/data.json')).toBeTrue(); + expect(matches('/api/data.json?v=1')).toBeTrue(); + + expect(matches('/api/users')).toBeFalse(); + expect(matches('/api/users?file=data.json')).toBeFalse(); + expect(matches('/api/.json?v=1')).toBeFalse(); + }); + + it('handles middle globstar (/**/) without matching paths in query parameters', async () => { + const matches = await createGlobMatcher('/api/**/users'); + + expect(matches('/api/users')).toBeTrue(); + expect(matches('/api/users?page=1')).toBeTrue(); + expect(matches('/api/v1/users?page=1')).toBeTrue(); + expect(matches('/api/v1/v2/users?page=1')).toBeTrue(); + + expect(matches('/api/other?redirect=/users')).toBeFalse(); + expect(matches('/api/users/profile?page=1')).toBeFalse(); + }); + + it('handles single-character wildcard (?) without matching the query delimiter', async () => { + const matches = await createGlobMatcher('/api/v?'); + + expect(matches('/api/v1')).toBeTrue(); + expect(matches('/api/v1?a=1')).toBeTrue(); + + expect(matches('/api/v')).toBeFalse(); + expect(matches('/api/v?')).toBeFalse(); + expect(matches('/api/v?a=1')).toBeFalse(); + expect(matches('/api/v12?a=1')).toBeFalse(); + }); + + it('handles negated globs (!) with and without query strings', async () => { + const matches = await createGlobMatcher('!/api/public/**'); + + expect(matches('/api/public')).toBeFalse(); + expect(matches('/api/public?foo=1')).toBeFalse(); + expect(matches('/api/public/assets?foo=1')).toBeFalse(); + + expect(matches('/api/private')).toBeTrue(); + expect(matches('/api/private?foo=1')).toBeTrue(); + }); + + it('handles brace expansion and extglobs with query strings', async () => { + const matchesBraces = await createGlobMatcher('/api/{auth,users}/**'); + expect(matchesBraces('/api/auth?q=1')).toBeTrue(); + expect(matchesBraces('/api/users/list?q=1')).toBeTrue(); + expect(matchesBraces('/api/other?q=1')).toBeFalse(); + + const matchesExtglob = await createGlobMatcher('/**/!(*.d).ts'); + expect(matchesExtglob('/app/main.ts')).toBeTrue(); + expect(matchesExtglob('/app/main.ts?extra=.d.ts')).toBeTrue(); + expect(matchesExtglob('/app/main.d.ts')).toBeFalse(); + expect(matchesExtglob('/app/main.d.ts?extra=.ts')).toBeFalse(); + }); + }); +}); From 80c7480b4d574ef2cd178e315288d9bfe821a5ac Mon Sep 17 00:00:00 2001 From: Alan Agius Date: Mon, 19 Oct 2026 19:45:24 +0200 Subject: [PATCH 122/233] fix(@angular/build): align lazy route entry names with workspace root for SSR modulepreload MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Override `compilerOptions.basePath` with `build.initialOptions.absWorkingDir` when initializing the Angular compilation so `lazyRoutesTransformer` computes `ɵentryName` relative to the workspace root rather than the tsconfig directory. This matches the workspace-relative keys in `entryPointToBrowserMapping` used for SSR `modulepreload` link generation when the application's `tsconfig` is not located at the workspace root. --- .../behavior/chunk-optimization-server_spec.ts | 16 ++++++++++------ .../compilation/angular-compilation_spec.ts | 8 +++++++- .../angular/compilation/compiler-options.ts | 3 +++ .../src/tools/esbuild/angular/compiler-plugin.ts | 1 + 4 files changed, 21 insertions(+), 7 deletions(-) diff --git a/packages/angular/build/src/builders/application/tests/behavior/chunk-optimization-server_spec.ts b/packages/angular/build/src/builders/application/tests/behavior/chunk-optimization-server_spec.ts index 76ecbbc4329e..18b92e7690a0 100644 --- a/packages/angular/build/src/builders/application/tests/behavior/chunk-optimization-server_spec.ts +++ b/packages/angular/build/src/builders/application/tests/behavior/chunk-optimization-server_spec.ts @@ -151,15 +151,19 @@ describeBuilder(buildApplication, APPLICATION_BUILDER_INFO, (harness) => { .not.toBeNull(); const mapping = JSON.parse(mappingSource![1]) as Record; + const mainServerContent = harness.readFile('dist/server/main.server.mjs'); - // Every lazy route entry point must retain a mapping entry after optimization. + // Every lazy route entry point must retain a mapping entry after optimization + // that matches the ɵentryName emitted into the server bundle. for (const name of LAZY_ROUTE_NAMES) { - const key = Object.keys(mapping).find((entryPoint) => - entryPoint.endsWith(`${name}.component.ts`), - ); - expect(key) - .withContext(`mapping entry for lazy route '${name}' should exist`) + const expectedEntryPoint = `src/app/${name}.component.ts`; + expect(mapping[expectedEntryPoint]) + .withContext(`mapping entry for '${expectedEntryPoint}' should exist`) .toBeDefined(); + + expect(mainServerContent) + .withContext(`main.server.mjs should contain ɵentryName '${expectedEntryPoint}'`) + .toContain(expectedEntryPoint); } // Every browser file referenced by the mapping must exist on disk. diff --git a/packages/angular/build/src/tools/angular/compilation/angular-compilation_spec.ts b/packages/angular/build/src/tools/angular/compilation/angular-compilation_spec.ts index 71eacd562259..0499431fe2c9 100644 --- a/packages/angular/build/src/tools/angular/compilation/angular-compilation_spec.ts +++ b/packages/angular/build/src/tools/angular/compilation/angular-compilation_spec.ts @@ -326,7 +326,11 @@ describe('AngularCompilation', () => { it('applies override options correctly', () => { const { compilerOptions } = transformCompilerOptions( ts, - { target: ts.ScriptTarget.ES2022, isolatedModules: true }, + { + target: ts.ScriptTarget.ES2022, + isolatedModules: true, + basePath: '/workspace/projects/app', + }, { sourcemap: true, preserveSymlinks: true, @@ -334,9 +338,11 @@ describe('AngularCompilation', () => { enableHmr: true, instrumentForCoverage: true, includeTestMetadata: true, + basePath: '/workspace', }, ); + expect(compilerOptions.basePath).toBe('/workspace'); expect(compilerOptions.inlineSources).toBe(true); expect(compilerOptions.inlineSourceMap).toBe(true); expect(compilerOptions.preserveSymlinks).toBe(true); diff --git a/packages/angular/build/src/tools/angular/compilation/compiler-options.ts b/packages/angular/build/src/tools/angular/compilation/compiler-options.ts index 45af80eae6d3..1c0356824d6f 100644 --- a/packages/angular/build/src/tools/angular/compilation/compiler-options.ts +++ b/packages/angular/build/src/tools/angular/compilation/compiler-options.ts @@ -10,6 +10,7 @@ import type * as ng from '@angular/compiler-cli'; import type { PartialMessage } from 'esbuild'; import * as path from 'node:path'; import type ts from 'typescript'; +import { toPosixPath } from '../../../utils/path'; export interface CompilerOptionOverrides { sourcemap?: boolean; @@ -21,6 +22,7 @@ export interface CompilerOptionOverrides { includeTestMetadata?: boolean; customConditions?: string[]; rootFiles?: string[]; + basePath?: string; } export function transformCompilerOptions( @@ -113,6 +115,7 @@ export function transformCompilerOptions( return { compilerOptions: { ...compilerOptions, + basePath: overrides?.basePath ? toPosixPath(overrides.basePath) : compilerOptions.basePath, noEmitOnError: false, composite: false, inlineSources: !!overrides?.sourcemap, diff --git a/packages/angular/build/src/tools/esbuild/angular/compiler-plugin.ts b/packages/angular/build/src/tools/esbuild/angular/compiler-plugin.ts index 928c9dac7797..e90280e02ebb 100644 --- a/packages/angular/build/src/tools/esbuild/angular/compiler-plugin.ts +++ b/packages/angular/build/src/tools/esbuild/angular/compiler-plugin.ts @@ -331,6 +331,7 @@ export function createCompilerPlugin( includeTestMetadata: !!pluginOptions.includeTestMetadata, customConditions: build.initialOptions.conditions, rootFiles: pluginOptions.rootFiles, + basePath: build.initialOptions.absWorkingDir, }, ); From d69966a4a511d082a3c150783e090bed55943f7d Mon Sep 17 00:00:00 2001 From: Doug Parker Date: Wed, 14 Oct 2026 15:06:41 -0700 Subject: [PATCH 123/233] docs: update `SECURITY.md` Adding some feedback based on AI security reports to help guide them towards what is and is not a legitimate vulnerability. (cherry picked from commit 0fd4404e52695fcd5b0cb976696747eed83d94be) --- SECURITY.md | 40 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) diff --git a/SECURITY.md b/SECURITY.md index 0361308689ab..1d62d6ccd8ae 100644 --- a/SECURITY.md +++ b/SECURITY.md @@ -1,3 +1,43 @@ Angular is part of Google [Open Source Software Vulnerability Reward Program](https://bughunters.google.com/about/rules/6521337925468160/google-open-source-software-vulnerability-reward-program-rules). For vulnerabilities in Angular, please submit your report [here](https://bughunters.google.com/report). For more information, check out [Angular's security policy](https://angular.dev/best-practices/security). + +## Policies + +The following defines some team policies around what does and does not constitute a security vulnerability. + +- Prototype pollution is itself a DoS vulnerability. + - An attacker could pollute any symbol into the wrong type and cause an error, nothing we can do will prevent that. + - Therefore we don't care about any DoS vulnerability which relies on prototype pollution as a precondition. +- We trust the user's source code. + - "A malicious repository can execute untrusted code" is not a viable attack vector. + - A malicious repository could always rebind `node_modules/.bin/ng` to do something malicious, nothing we do can prevent that. + - We assume it is always unsafe to run an untrusted repository outside of a sandbox. +- DoS attacks which break only the attacker's client are not security issues. + - Exception: DoS attacks which waste server resources significantly beyond the cost of the attacker's request may be security issues. +- Memory leaks are considered general bugs, not DoS vulnerabilities. + - While any memory leak is technically a DoS vulnerability in SSR, these are generally low enough impact to not be considered security issues. +- Our public API contract is defined by our TS types, any issue which requires breaking those types (ex. via a cast to any) falls outside Angular's support. + - Ex. It may be possible to leak user state by attaching it to some global data structure in SSR, but we do not consider this to be a valid vulnerability if you have to escape TS types to do it. + +## Invariants + +The following are invariants about Angular's technical infrastructure which limit some potential attack vectors. These statements are asserted by humans, not proven in any formal means. However, any security report should assume them to be true unless and until it can conclusively prove them to be false in an attack. If one of these statements invalidates a security report, that report bears the burden of conclusively demonstrating the statement to be false in its reproduction. + +- Zones don't leak across SSR requests (except for the root) + - Every request gets its own Zone, so data stored on the Zone is unique to that user, no intrinsic risk of leaking user data from one request to an attacker's request. +- Injectors are not shared between applications. + - SSR always creates a new ApplicationRef and root services, no intrinsic risk of leaking user data from one request to an attacker's request. + - Exception: Module-scoped data is shared and is a potential vector for data leakage. +- `ngDevMode` / `ngServerMode` are set at compile time in production deployments and cannot be manipulated by attackers. + +## Prioritization Guide + +Angular is not a product, and almost no vulnerability is an exploit in and of itself, given there is nothing to compromise. Angular can only be exploited through a real deployment of a specific application. The vast majority of potential issues do not affect the default `ng new` app, and require additional steps of varying use/misuse of the framework before introducing a vulnerability on that real application. This goes beyond just an attacker finding the right sequence of characters to cause an exploit, and requires a well-intentioned developer to make a legitimate mistake introducing the vulnerability in the first place. Therefore we need to examine prioritization through the lens of how likely a developer is to make that mistake and the severity of what happens when they do. + +- **High:** A vulnerability impacts ~all users of a major feature in common usage such as SSR, hydration, templating, or routing (ex. SSRF via a malicious `Host` header affects all SSR + `HttpClient` users, which is a fairly common use case). +- **Medium:** A vulnerability impacts users interacting with public APIs in their reasonable usage. +- **Low:** A vulnerability impacts users interacting with public APIs misused in an unintended or unreasonable way (ex. vulnerability from unsanitized user input polluting the `APP_ID` value, which should never be user writable). +- **None:** A vulnerability impacts users of private APIs or explicitly unsupported use cases. + +Experimental / developer preview APIs _are not_ exempted from these priorities. While we make no hard guarantees about these APIs publicly, a vulnerability in such features should be raised to our attention and addressed before reaching stability. From 6053771cba3c29a481d21ea6a2f2b9dd279b6db2 Mon Sep 17 00:00:00 2001 From: Charles <19598772+clydin@users.noreply.github.com> Date: Tue, 20 Oct 2026 08:46:49 -0400 Subject: [PATCH 124/233] fix(@angular/cli): only load autocompletion in interactive shells Previously, `ng completion` appended an unconditional `source <(ng completion script)` statement to the user's shell configuration file. When non-interactive shells (such as those spawned by scripts, automation tools, or coding agents) sourced the configuration file, they still paid the overhead of starting Node.js and generating the completion script despite tab completion not being used. (cherry picked from commit 21846daf3637496e5f4f86c95843300df871c4dd) --- .../commands/completion/long-description.md | 4 +- .../angular/cli/src/utilities/completion.ts | 2 +- .../tests/commands/completion/completion.ts | 67 +++++-------------- 3 files changed, 21 insertions(+), 52 deletions(-) diff --git a/packages/angular/cli/src/commands/completion/long-description.md b/packages/angular/cli/src/commands/completion/long-description.md index b75803ac9cb0..ac0f7ce8aa8f 100644 --- a/packages/angular/cli/src/commands/completion/long-description.md +++ b/packages/angular/cli/src/commands/completion/long-description.md @@ -42,7 +42,9 @@ more control over exactly where this configuration lives, you can manually set i shell run at startup: ```bash -source <(ng completion script) +if [[ $- == *i* ]]; then + source <(ng completion script) +fi ``` This is equivalent to what `ng completion` will automatically set up, and gives power users more diff --git a/packages/angular/cli/src/utilities/completion.ts b/packages/angular/cli/src/utilities/completion.ts index 0e23e1f03348..052231ea964e 100644 --- a/packages/angular/cli/src/utilities/completion.ts +++ b/packages/angular/cli/src/utilities/completion.ts @@ -240,7 +240,7 @@ export async function initializeAutocomplete(): Promise { try { await fs.appendFile( rcFile, - '\n\n# Load Angular CLI autocompletion.\nsource <(ng completion script)\n', + '\n\n# Load Angular CLI autocompletion for interactive shells.\nif [[ $- == *i* ]]; then\n source <(ng completion script)\nfi\n', ); } catch (err) { assertIsError(err); diff --git a/tests/e2e/tests/commands/completion/completion.ts b/tests/e2e/tests/commands/completion/completion.ts index 939bdb8c306b..5b81490c8400 100644 --- a/tests/e2e/tests/commands/completion/completion.ts +++ b/tests/e2e/tests/commands/completion/completion.ts @@ -11,6 +11,13 @@ import { const testRegistry = getGlobalVariable('package-registry'); +const AUTOCOMPLETION_SNIPPET = ` +# Load Angular CLI autocompletion for interactive shells. +if [[ $- == *i* ]]; then + source <(ng completion script) +fi +`.trim(); + export default async function () { // Windows Cmd and Powershell do not support autocompletion. Run a different set of tests to // confirm autocompletion fails gracefully. @@ -33,11 +40,7 @@ export default async function () { ); const rcContents = await fs.readFile(path.join(home, '.bashrc'), 'utf-8'); - const expected = ` -# Load Angular CLI autocompletion. -source <(ng completion script) - `.trim(); - if (!rcContents.includes(expected)) { + if (!rcContents.includes(AUTOCOMPLETION_SNIPPET)) { throw new Error(`~/.bashrc does not contain autocompletion script. Contents:\n${rcContents}`); } }); @@ -55,11 +58,7 @@ source <(ng completion script) ); const rcContents = await fs.readFile(path.join(home, '.zshrc'), 'utf-8'); - const expected = ` -# Load Angular CLI autocompletion. -source <(ng completion script) - `.trim(); - if (!rcContents.includes(expected)) { + if (!rcContents.includes(AUTOCOMPLETION_SNIPPET)) { throw new Error(`~/.zshrc does not contain autocompletion script. Contents:\n${rcContents}`); } }); @@ -79,11 +78,7 @@ source <(ng completion script) ); const rcContents = await fs.readFile(bashrc, 'utf-8'); - const expected = `# Other commands... - -# Load Angular CLI autocompletion. -source <(ng completion script) -`; + const expected = `# Other commands...\n\n${AUTOCOMPLETION_SNIPPET}\n`; if (rcContents !== expected) { throw new Error(`~/.bashrc does not match expectation. Contents:\n${rcContents}`); } @@ -104,11 +99,7 @@ source <(ng completion script) ); const rcContents = await fs.readFile(bashProfile, 'utf-8'); - const expected = `# Other commands... - -# Load Angular CLI autocompletion. -source <(ng completion script) -`; + const expected = `# Other commands...\n\n${AUTOCOMPLETION_SNIPPET}\n`; if (rcContents !== expected) { throw new Error(`~/.bash_profile does not match expectation. Contents:\n${rcContents}`); } @@ -129,11 +120,7 @@ source <(ng completion script) ); const rcContents = await fs.readFile(profile, 'utf-8'); - const expected = `# Other commands... - -# Load Angular CLI autocompletion. -source <(ng completion script) -`; + const expected = `# Other commands...\n\n${AUTOCOMPLETION_SNIPPET}\n`; if (rcContents !== expected) { throw new Error(`~/.profile does not match expectation. Contents:\n${rcContents}`); } @@ -159,11 +146,7 @@ source <(ng completion script) ); const bashrcContents = await fs.readFile(bashrc, 'utf-8'); - const bashrcExpected = `# \`.bashrc\` commands... - -# Load Angular CLI autocompletion. -source <(ng completion script) -`; + const bashrcExpected = `# \`.bashrc\` commands...\n\n${AUTOCOMPLETION_SNIPPET}\n`; if (bashrcContents !== bashrcExpected) { throw new Error(`~/.bashrc does not match expectation. Contents:\n${bashrcContents}`); } @@ -194,11 +177,7 @@ source <(ng completion script) ); const rcContents = await fs.readFile(zshrc, 'utf-8'); - const expected = `# Other commands... - -# Load Angular CLI autocompletion. -source <(ng completion script) -`; + const expected = `# Other commands...\n\n${AUTOCOMPLETION_SNIPPET}\n`; if (rcContents !== expected) { throw new Error(`~/.zshrc does not match expectation. Contents:\n${rcContents}`); } @@ -219,11 +198,7 @@ source <(ng completion script) ); const rcContents = await fs.readFile(zshProfile, 'utf-8'); - const expected = `# Other commands... - -# Load Angular CLI autocompletion. -source <(ng completion script) -`; + const expected = `# Other commands...\n\n${AUTOCOMPLETION_SNIPPET}\n`; if (rcContents !== expected) { throw new Error(`~/.zsh_profile does not match expectation. Contents:\n${rcContents}`); } @@ -244,11 +219,7 @@ source <(ng completion script) ); const rcContents = await fs.readFile(profile, 'utf-8'); - const expected = `# Other commands... - -# Load Angular CLI autocompletion. -source <(ng completion script) -`; + const expected = `# Other commands...\n\n${AUTOCOMPLETION_SNIPPET}\n`; if (rcContents !== expected) { throw new Error(`~/.profile does not match expectation. Contents:\n${rcContents}`); } @@ -274,11 +245,7 @@ source <(ng completion script) ); const zshrcContents = await fs.readFile(zshrc, 'utf-8'); - const zshrcExpected = `# \`.zshrc\` commands... - -# Load Angular CLI autocompletion. -source <(ng completion script) -`; + const zshrcExpected = `# \`.zshrc\` commands...\n\n${AUTOCOMPLETION_SNIPPET}\n`; if (zshrcContents !== zshrcExpected) { throw new Error(`~/.zshrc does not match expectation. Contents:\n${zshrcContents}`); } From 0dc103735e9cd42007a0b81cf1c2a563f80b94e6 Mon Sep 17 00:00:00 2001 From: MeAkib Date: Mon, 19 Oct 2026 14:54:27 +0600 Subject: [PATCH 125/233] fix(@angular/build): correct typos and spacing in error and warning messages Several messages printed by the CLI contained typos or ran two sentences together: - The application builder named the option `"app-shell"` in its errors about `server` and `index`, but the option is `appShell`. - The `emitDecoratorMetadata` note printed "by Angularand" and "explictly". - The unit-test Karma `--filter` warning printed "expression.Leading". - The `provideServerRendering()` configuration error printed "provideServerRendering().The". - `ng config` reported "Confguration file cannot be found.". - `ng update` reported "registry package identifer". Add the missing spaces, fix the spelling and use the actual option name. (cherry picked from commit 13a73464935365ed48bf30ea520bcc4c84828b9e) --- packages/angular/build/src/builders/application/options.ts | 4 ++-- .../build/src/builders/unit-test/runners/karma/executor.ts | 2 +- .../src/tools/angular/compilation/compiler-options.ts | 4 ++-- packages/angular/cli/src/commands/config/cli.ts | 2 +- packages/angular/cli/src/commands/update/cli.ts | 2 +- packages/angular/ssr/src/routes/route-config.ts | 7 ++----- 6 files changed, 9 insertions(+), 12 deletions(-) diff --git a/packages/angular/build/src/builders/application/options.ts b/packages/angular/build/src/builders/application/options.ts index f7e60f4cc029..9fcdd1f3d118 100644 --- a/packages/angular/build/src/builders/application/options.ts +++ b/packages/angular/build/src/builders/application/options.ts @@ -411,13 +411,13 @@ export async function normalizeOptions( if (appShellOptions || ssrOptions || prerenderOptions) { if (!serverEntryPoint) { throw new Error( - 'The "server" option is required when enabling "ssr", "prerender" or "app-shell".', + 'The "server" option is required when enabling "ssr", "prerender" or "appShell".', ); } if (!indexHtmlOptions) { throw new Error( - 'The "index" option cannot be set to false when enabling "ssr", "prerender" or "app-shell".', + 'The "index" option cannot be set to false when enabling "ssr", "prerender" or "appShell".', ); } } diff --git a/packages/angular/build/src/builders/unit-test/runners/karma/executor.ts b/packages/angular/build/src/builders/unit-test/runners/karma/executor.ts index 8b82857258b9..0b5a3293cf85 100644 --- a/packages/angular/build/src/builders/unit-test/runners/karma/executor.ts +++ b/packages/angular/build/src/builders/unit-test/runners/karma/executor.ts @@ -116,7 +116,7 @@ export class KarmaExecutor implements TestExecutor { let filter = unitTestOptions.filter; if (filter[0] === '/' && filter.at(-1) === '/') { this.context.logger.warn( - 'The `--filter` option is always a regular expression.' + + 'The `--filter` option is always a regular expression. ' + 'Leading and trailing `/` are not required and will be ignored.', ); } else { diff --git a/packages/angular/build/src/tools/angular/compilation/compiler-options.ts b/packages/angular/build/src/tools/angular/compilation/compiler-options.ts index 1c0356824d6f..56286f3bab0a 100644 --- a/packages/angular/build/src/tools/angular/compilation/compiler-options.ts +++ b/packages/angular/build/src/tools/angular/compilation/compiler-options.ts @@ -96,8 +96,8 @@ export function transformCompilerOptions( notes: [ { text: - `The 'emitDecoratorMetadata' option is not required by Angular` + - 'and can be removed if not explictly required by the project.', + `The 'emitDecoratorMetadata' option is not required by Angular ` + + 'and can be removed if not explicitly required by the project.', }, ], }); diff --git a/packages/angular/cli/src/commands/config/cli.ts b/packages/angular/cli/src/commands/config/cli.ts index 0be11f4c1759..e9792aaa5ed3 100644 --- a/packages/angular/cli/src/commands/config/cli.ts +++ b/packages/angular/cli/src/commands/config/cli.ts @@ -101,7 +101,7 @@ export default class ConfigCommandModule const { logger } = this.context; if (!config || !configPath) { - throw new CommandModuleError('Confguration file cannot be found.'); + throw new CommandModuleError('Configuration file cannot be found.'); } const normalizeUUIDValue = (v: string | undefined) => (v === '' ? randomUUID() : `${v}`); diff --git a/packages/angular/cli/src/commands/update/cli.ts b/packages/angular/cli/src/commands/update/cli.ts index 005df998b501..d3fd18d5ee03 100644 --- a/packages/angular/cli/src/commands/update/cli.ts +++ b/packages/angular/cli/src/commands/update/cli.ts @@ -196,7 +196,7 @@ export default class UpdateCommandModule extends CommandModule Date: Tue, 20 Oct 2026 07:56:27 +0000 Subject: [PATCH 126/233] build: lock file maintenance See associated pull request for more information. --- MODULE.bazel.lock | 2 +- pnpm-lock.yaml | 364 +++++++++++++++++++--------------------------- 2 files changed, 153 insertions(+), 213 deletions(-) diff --git a/MODULE.bazel.lock b/MODULE.bazel.lock index ec705b4eb497..2d994cee38f7 100644 --- a/MODULE.bazel.lock +++ b/MODULE.bazel.lock @@ -384,7 +384,7 @@ "aspect_rules_jasmine": "2.0.4", "aspect_tools_telemetry": "0.5.2" }, - "last_notice": 0 + "last_notice": 3 } } }, diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index f5dba5c50208..dc08ad65ccde 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -290,7 +290,7 @@ importers: version: 3.0.8 '@types/loader-utils': specifier: ^3.0.0 - version: 3.0.0(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.28)(uglify-js@3.19.3) + version: 3.0.0(esbuild@0.28.2)(lightningcss@1.33.0)(uglify-js@3.19.3) '@types/lodash': specifier: ^4.17.0 version: 4.17.26 @@ -3213,44 +3213,44 @@ packages: resolution: {integrity: sha512-7FNeNl8NCE7aINx7WXiKQrPYZWC/hvrTsmk6zmxbI7LTXE7hVek/n8AfVgpe2y82zl3w0HvCHN0bVKMBoJcC0w==} engines: {node: '>= 10.0.0'} - '@peculiar/asn1-cms@2.10.0': - resolution: {integrity: sha512-CkX0H4NCIOMHOU3rh2xXZywinYZ/EnJlaOlJiGI0e5L4XjFqHf4iH30LMbXWChVppdA9ljbanjtzQFOhDNfTWg==} + '@peculiar/asn1-cms@2.11.0': + resolution: {integrity: sha512-SlAiDoT/Cd8qaNmbTt78gqyaEvu2fQd6ML6KWJkdjXGrgDKnHHrusVkfQUelkfinL2p665IIADb0JBixtT8W1g==} engines: {node: '>=14'} - '@peculiar/asn1-csr@2.10.0': - resolution: {integrity: sha512-jTPTr/9rxKM+niQLMF3jiAMb0lWHUhUHIuSOhdGCIfpB4FAQYf9SoiXOgxP8bS/68IB+bj+1OHvVnDVCQfVUZw==} + '@peculiar/asn1-csr@2.11.0': + resolution: {integrity: sha512-M/ED0yJ05qMK+UADPKnIa8vhAeewOJALSxTAZB7RQ/batRHhIJZkwznCcWAbFO5saHJ1yEQ+m4lncEcG9RnQSg==} engines: {node: '>=14'} - '@peculiar/asn1-ecc@2.10.0': - resolution: {integrity: sha512-GFd3iOjFrWX+QWH2R2dO5QSJyyRGv9CIBKtRlGlPNCvb2RvmCbBDexe91MJgV76c69d998Xsa+CvuQ98seoiPg==} + '@peculiar/asn1-ecc@2.11.0': + resolution: {integrity: sha512-jj1alGEKev7/un+cI+exyVK9m31lmP7cCBMCZuCb0wkFQH2zmKmJzNiG4wqXFNzlcP8timHLnzf3lV3OxBpb/Q==} engines: {node: '>=14'} - '@peculiar/asn1-pfx@2.10.0': - resolution: {integrity: sha512-1y3QK9ZH1IPleAMmRoJlPS10eGkAWnULETW8zDFNUK1ffqpG7zmDY+kYBMYQgwlcQZ2iitLm2z2EBP0xzRXpaA==} + '@peculiar/asn1-pfx@2.11.0': + resolution: {integrity: sha512-ykSAWRu8KkmzU8LRpk9ZQC3zuLmBEtoSMjIv9XHVamD5W7amqreV5wttKqnvtjWOzzSJQxA/HVT8/tHwpEEGSQ==} engines: {node: '>=14'} - '@peculiar/asn1-pkcs8@2.10.0': - resolution: {integrity: sha512-Ri+BZT9bnwqlHWmhs7lvWjvJRxKev2hA2+4EbZajgeYWCbR8hyv0znF4DhsFouOhMj2nSDV/iGJ6DMQtwITnCw==} + '@peculiar/asn1-pkcs8@2.11.0': + resolution: {integrity: sha512-lragjkjQGnQ5luxC+sxoAfAO/jBiQ7hOEGlDKJUk7MC5zY3AzjB2DU0GyPUH1Sswdv10t7DurY0zylOYMLb88w==} engines: {node: '>=14'} - '@peculiar/asn1-pkcs9@2.10.0': - resolution: {integrity: sha512-XIXsbDQFezYk6fudczkuvawkRD4GNpISGCqfYhdkJlvcGF/RFknU+0DDJagOaJqBf+PdPzk4J9oMqDGcvfR9HQ==} + '@peculiar/asn1-pkcs9@2.11.0': + resolution: {integrity: sha512-gDdFjpqV0weJjgNUvueUVf4D8uVbpq+VbG0TsxLAY2QGljAkJyL9qwQ7avol9j0jaYSJ7Ey7v7RZp0M3GTcQSA==} engines: {node: '>=14'} - '@peculiar/asn1-rsa@2.10.0': - resolution: {integrity: sha512-4Jvmwlh3gZAhNZ4/u7JSyLuce9hofOFZ4o3PYKAccCImGnyaT5CMym/ATgvAvqpOYFNW531oPZvJlEBhJy9VfA==} + '@peculiar/asn1-rsa@2.11.0': + resolution: {integrity: sha512-S2sBJmbfI09Kzdt9cEhE6pDNjHpVTkURs+811+PxS8AvsTLxC4woMNRhxHYaIbClkkNfAVt0tZxJdINVfUmzuA==} engines: {node: '>=14'} - '@peculiar/asn1-schema@2.10.0': - resolution: {integrity: sha512-GhokD41lV4gQrrLYm3wCkHfBOnJrnhDMgt4XeMW8gzfE1UdJqIuSwsE+ggf82XBjUXRJylcm+KIGQFa4utIVLw==} + '@peculiar/asn1-schema@2.11.0': + resolution: {integrity: sha512-8xh4avo53/vXO6UEv9yaoJ83hY581geaLTygf61NPIXP5AeIZCPjJhpTaYU23IZkG+NpLN/C9FYzWp7hphIT9A==} engines: {node: '>=14'} - '@peculiar/asn1-x509-attr@2.10.0': - resolution: {integrity: sha512-/85GtKOKmgvuSJNlaFfwGWNdRSZZ+hpF02NyM01XiCdzpaZONiBltDyfluFPvFx966CR+ZHNSG1jniwpy07oGg==} + '@peculiar/asn1-x509-attr@2.11.0': + resolution: {integrity: sha512-Fgvnd9REmLxEj/4cbDP54dNUNUXkzUksXLqEHqs1mHBuSRjSTCUSPM/WQIZYSvrdG7ND9CX1AQtPoIBekhgQSA==} engines: {node: '>=14'} - '@peculiar/asn1-x509@2.10.0': - resolution: {integrity: sha512-ucNVg8+ANveTpMN3fy9lA2alryONdXc2A4cEG2hMniWbvQt+YOZoe8BI80YYNO8FBcuDY1qbDQ4uQGQVraHxGA==} + '@peculiar/asn1-x509@2.11.0': + resolution: {integrity: sha512-J1sHAwGNlk+8J+FeR1eLVc6Gq0T9f9ITc3HWyPYgJraoW6U8AJuQiWVJ3SCEpltfTdpOY7fHdHT5oKAsbK/jww==} engines: {node: '>=14'} '@peculiar/utils@2.0.3': @@ -4258,8 +4258,8 @@ packages: asn1@0.2.6: resolution: {integrity: sha512-ix/FxPn0MDjeyJ7i/yoHGFt/EX6LyNbxSEhPPXODPL+KB0VPk86UYfL0lMdy+KCnv+fmvIzySwaK5COwqVbWTQ==} - asn1js@3.0.10: - resolution: {integrity: sha512-S2s3aOytiKdFRdulw2qPE51MzjzVOisppcVv7jVFR+Kw0kxwvFrDcYA0h7Ndqbmj0HkMIXYWaoj7fli8kgx1eg==} + asn1js@3.1.0: + resolution: {integrity: sha512-HWYi1THkOqguCiO+vwj09ZkQFD2kKEsejYHAYCtX0D80WVdoDnvRc9IukXX/jeb0T9NRWJnRtqwdbHltnFjwXA==} engines: {node: '>=12.0.0'} assert-plus@1.0.0: @@ -4385,8 +4385,8 @@ packages: base64-js@1.5.1: resolution: {integrity: sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==} - baseline-browser-mapping@2.11.28: - resolution: {integrity: sha512-br0LOmjJqr6Rt4AEkadbcNf67Zpo7EPwKsWbjnRrJIa1QYFHQBqM4C7F2WTbV8ahTEcg1Eo+Y0aWjjORInYFyA==} + baseline-browser-mapping@2.11.29: + resolution: {integrity: sha512-YeesxhUmR4h5y5V8KF8iBCqJb8YFrBJ++XBTeGcWIaQOYXGN19JM0FoiOjAhwuDoln8owMgXcWBmgHtYSkky2w==} engines: {node: '>=6.0.0'} hasBin: true @@ -4533,8 +4533,8 @@ packages: resolution: {integrity: sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==} engines: {node: '>=6'} - caniuse-lite@1.0.30001815: - resolution: {integrity: sha512-uDybUEyfgbyJJ93J1vikTylBX31AkdVYeVPeffMQpf8XN7hSfr0oZOn4VFOIMNvtU5+rHvC5Udg2TgtJKHm23Q==} + caniuse-lite@1.0.30001816: + resolution: {integrity: sha512-+8Yx7BXCoqk6IF8yTicjfUR6D/ldJzdlsodlEOiOSPmhK844WIgk67/zIQaGAOxNkZyyvBlrRFnLvqKIoqbAFw==} caseless@0.12.0: resolution: {integrity: sha512-4tYFyifaFfGacoiObjJegolkwSU4xQNGbVgUiNYVUxbQ2x2lUsFvY4hVgVzGiIe6WLOPqycWXA40l+PWsxthUw==} @@ -5000,8 +5000,8 @@ packages: engines: {node: '>=0.12.18'} hasBin: true - electron-to-chromium@1.5.452: - resolution: {integrity: sha512-cVvk1YBSj6571VmV6hdJTqj94Y79xSu8cj6Y9t6ae4Y4431z8/7EJFvu3rVp90xhfuv9BpPKUmaLfTo4+FOGBg==} + electron-to-chromium@1.5.459: + resolution: {integrity: sha512-4SC9HHSFjO/liAhifpdOL5hG9b4BP7/5G3y3UPZVO8trlAXr1CaUEEJL0gWK3kOcYcZrOA5rkwG45Gra/lTIgg==} emoji-regex@10.6.0: resolution: {integrity: sha512-toUI84YS5YmxW219erniWD0CIVOo46xGKColeNQRgOzDorgBi1v4D71/OFzgD9GO2UGKIv1C3Sp8DAn0+j5w7A==} @@ -6304,8 +6304,8 @@ packages: resolution: {integrity: sha512-WkUDrojuJs0xkgGf2udWxa3yGBRxPtxUkB79i6aCZLRgc7PM8fZe9TosfPDcvEpQZbuFASnHYmRLBLUbmLOIIA==} engines: {node: '>= 12.0.0'} - lilconfig@3.1.3: - resolution: {integrity: sha512-/vlFKAoH5Cgt3Ie+JLhRbwOsCQePABiU3tJ1egGvyQ+33R/vcwM2Zl2QR/LzjsBeItPt3oSVXapn+m4nQDvpzw==} + lilconfig@3.1.4: + resolution: {integrity: sha512-zJZyBmQhArDRefuWTypZxwDpFDIYmrj8ypSBvwGD5P13Y95s6DjzKgu4DVdGbeQa5PDEsAOCAPNk4X+QOR006w==} engines: {node: '>=14'} limiter@1.1.5: @@ -6537,8 +6537,8 @@ packages: minimist@1.2.8: resolution: {integrity: sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==} - minimizer-webpack-plugin@5.13.0: - resolution: {integrity: sha512-OO1NF2zHj6sf4CNv2AsUWYcS8WEwkVKQDXxxKzlOxx1Xl+WlqYtVC+oNlGNwGkLAOnpj277BSHypWwRtd9w4JQ==} + minimizer-webpack-plugin@5.13.1: + resolution: {integrity: sha512-1mhAfvachWYYOm8tpmany5NLuvP+F2wxZWBSX8DC0uFS2wJpM9q3rWgN9wBooAH9d5V12wX0BjyJe4fMjHMarQ==} engines: {node: '>= 10.13.0'} peerDependencies: '@minify-html/node': '*' @@ -6611,8 +6611,8 @@ packages: engines: {node: '>=10'} hasBin: true - modern-tar@0.8.5: - resolution: {integrity: sha512-snEhs+6G5Tjd4I7tLCDOaoln2RgE0bD19RzEKgvgK2hZ5VKy3MpLhLTZ2fWpXSTg4K2cyPwp+VHATFJhxfnOeA==} + modern-tar@0.8.6: + resolution: {integrity: sha512-LYSks0tNVqbtez/9OB0YFP6qLRSqkdAxJWOQpVaR67lNTbj2zNLyYpowkRMia5lXLCZKzxwoxkxH2MbbBR2aEg==} engines: {node: '>=18.0.0'} mrmime@2.0.1: @@ -6730,8 +6730,8 @@ packages: resolution: {integrity: sha512-LA4ZjwlnUblHVgq0oBF3Jl/6h/Nvs5fzBLwdEF4nuxnFdsfajde4WfxtJr3CaiH+F6ewcIB/q4jQ4UzPyid+CQ==} hasBin: true - node-releases@2.0.58: - resolution: {integrity: sha512-BdiKAgbfRlvfMq/XzO/AF9NPmaA8a+YpLAyAFTVFBj3gARrAIfWvNq7Q7NE4se3KgFu0KkrvQMxTS0XVnsGzHg==} + node-releases@2.0.59: + resolution: {integrity: sha512-5qr2okC4ItAI0hG5SaV0HoYMpnM/Y6+Oqr7AmPYy/2uEoGvS+GbSKLeRxSS1uAdu59yz0ouzcuXievSgg///WA==} engines: {node: '>=18'} normalize-path@3.0.0: @@ -7152,8 +7152,8 @@ packages: resolution: {integrity: sha512-O9gl3zCl5h5blw1KGUzQKhA5oUXSl8rwUIM5o0S3nCXMliSvy5Dzx7/DJcI+SwgICv+IneSZwhBh1oSyEHA71A==} engines: {node: '>=0.6'} - qs@6.16.0: - resolution: {integrity: sha512-h6fhOIaRrID2CbEY2fqs+7t+UXZo+MLAnU5gRIq85uFtdiUPCdsApMlHhXogKVM4HM2DVbIjGNTTYH2OcmP1vA==} + qs@6.16.1: + resolution: {integrity: sha512-5Px6J7rfHBAGUhNQ3es4YzcOdBBw0SDcVtThJml4RdnKw4tKs2epA0kPZ+K8X+WiHktT93RHVcQ/3ym5aTCgtg==} engines: {node: '>=0.6'} queue-microtask@1.2.3: @@ -7186,9 +7186,9 @@ packages: resolution: {integrity: sha512-K5zQjDllxWkf7Z5xJdV0/B0WTNqx6vxG70zJE4N0kBs4LovmEYWJzQGxC9bS9RAKu3bgM40lrd5zoLJ12MQ5BA==} engines: {node: '>= 0.10'} - re2js@2.8.6: - resolution: {integrity: sha512-xLgQil4kIUCrAzVk9fRSkxkFNwmygLFjVxXrLc65aE1F0+Zsb8rxumFBy4XKyvgMCTL6kilDq3EZ0piE2dP/Dg==} - engines: {node: '>=18.0.0'} + re2js@2.8.8: + resolution: {integrity: sha512-E2FVgqD2mzJ+ZmMSHLnkOvZ7PiZ4FgMdfVCA3YsJWs9gtyoaKmUMxyVPCXS1yK209/mz3XkdT7kr3OlMWW2Fww==} + engines: {node: '>=20.0.0'} readable-stream@2.3.8: resolution: {integrity: sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==} @@ -7569,9 +7569,15 @@ packages: resolution: {integrity: sha512-xAg7SOnEhrm5zI3puOOKyy1OMcMlIJZYNJY7xLBwSze0UjhPLnWfj2GF2EpT0jmzaJKIWKHLsaSSajf35bcYnA==} engines: {node: '>=v12.22.7'} - schema-utils@4.5.0: - resolution: {integrity: sha512-zJlMCZ0cAR5p/Y4oVpRoqioDMJcGxaXRrQ/4rP4WyR84vc5z/DolXdbvXeDpTwbtocDFr2rhPqHPErDCUtz2kA==} + schema-utils@4.8.1: + resolution: {integrity: sha512-x39pYlJPyH7Uge5QO64B9XGP9zLDc9WNmiQZc+CE3IzZPvMu3lHOuAMGpYNoPixEL7MSWlGhYTg5UlLSL8G6iw==} engines: {node: '>= 10.13.0'} + hasBin: true + peerDependencies: + webpack: ^5.112.0 + peerDependenciesMeta: + webpack: + optional: true selfsigned@5.5.0: resolution: {integrity: sha512-ftnu3TW4+3eBfLRFnDEkzGxSF/10BJBkaLJuBHZX0kiPS7bRdlpZGu6YGt4KngMkdTwJE6MbjavFpqHvqVt+Ew==} @@ -7860,8 +7866,8 @@ packages: symbol-tree@3.2.4: resolution: {integrity: sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==} - sync-child-process@1.0.2: - resolution: {integrity: sha512-8lD+t2KrrScJ/7KXCSyfhT3/hRq78rC0wBFqNJXv3mZyn6hW2ypM05JmlSvtqRbeq6jqA94oHbxAr2vYsJ8vDA==} + sync-child-process@1.1.0: + resolution: {integrity: sha512-1LMf/x0kU0CKFSesh5DfYktvj1KhiqYi5LAh5HU2G4SkKk1TGDhsMFBOL47g/E+mNfYpgs365pVNlIYOIHPvlQ==} engines: {node: '>=16.0.0'} sync-message-port@1.2.0: @@ -8105,8 +8111,8 @@ packages: undici-types@7.24.6: resolution: {integrity: sha512-WRNW+sJgj5OBN4/0JpHFqtqzhpbnV0GuB+OozA9gCL7a993SmU+1JBZCzLNxYsbMfIeDL+lTsphD5jN5N+n0zg==} - undici@6.29.0: - resolution: {integrity: sha512-R+RODBqp6i2pPflGdq+xIOUkl+RNfGgHwoinecKu/JCuf2uO06cOKoDbI2P7Dn6KcswdKwrczbU6IYJ6K8X+wg==} + undici@6.29.1: + resolution: {integrity: sha512-EvRlUt/QqAEvXdQeRMYUfwOQsfzpDztykrG2owGEE/rBOBoYv9uF39ZzsNDh4lTFHhTr2XOZjKkYgueD12ZmGA==} engines: {node: '>=18.17'} undici@8.10.2: @@ -8313,12 +8319,8 @@ packages: resolution: {integrity: sha512-o8qghlI8NZHU1lLPrpi2+Uq7abh4GGPpYANlalzWxyWteJOCsr/P+oPBA49TOLu5FTZO4d3F9MnWJfiMo4BkmA==} engines: {node: '>=18'} - watchpack@2.5.2: - resolution: {integrity: sha512-6i/00NBjP4yGPs+caKSyRfpTF/8Torsu0MOW3mMzIbhgISFder8i7xbqgHlLMwJrdiN8ndBV3UA1/AfzPSr+jg==} - engines: {node: '>=10.13.0'} - - watchpack@2.6.2: - resolution: {integrity: sha512-67nxRd7I5uAyn+KamYsCqU30iVgCgZ4aj8ZOGzmxs7zNPuvlnoYltm6+6JkOjEcD6WVXdu1BfH+gVQs3FUuW7Q==} + watchpack@2.6.3: + resolution: {integrity: sha512-s3NZy0QpTY9qGqzc0wtz4qI28z3+5qKbbAec4MV4G9N3CfgZ9wgvQRr0cl2jh/tqkWG1NWHkmVMHZpCamev5Wg==} engines: {node: '>=10.13.0'} weak-lru-cache@1.2.2: @@ -8381,16 +8383,6 @@ packages: html-webpack-plugin: optional: true - webpack@5.111.0: - resolution: {integrity: sha512-A2R74kfE6b3eLKS91iZiol03Ebx7avmJJBOyiP+4LePW9NNeNJGQkKeSQos4dk6R4H0YAMYlv+aOrs1CyWT3eA==} - engines: {node: '>=10.13.0'} - hasBin: true - peerDependencies: - webpack-cli: '*' - peerDependenciesMeta: - webpack-cli: - optional: true - webpack@5.112.0: resolution: {integrity: sha512-NIBpsRuCll036haDDt/CfcTDfsWNR9Z782nMRMI9D377BsGcYzZDTNU5TyzhCJzPIcihAxMBaMAhq2WSaDrH8Q==} engines: {node: '>=10.13.0'} @@ -8417,8 +8409,8 @@ packages: resolution: {integrity: sha512-1to4zXBxmXHV3IiSSEInrreIlu02vUOvrhxJJH5vcxYTBDAx51cqZiKdyTxlecdKNSjj8EcxGBxNf6Vg+945gw==} engines: {node: ^20.19.0 || ^22.12.0 || >=24.0.0} - whatwg-url@17.2.0: - resolution: {integrity: sha512-IhLIHNcBrzIixC5XXsbr4DxdjajyA5vQ5RwGZMtrUp+GbtE5Nrsge9QKau7jXrC0aTXLYGV0xiW7Tb4YS2aomw==} + whatwg-url@17.3.0: + resolution: {integrity: sha512-KwOAJrpf+GTgBvcBQJcP38sMF0DsQKdwtG+TxM2pW44P6E5k0hDbWrDmyuJDIF0Uef0aQq0ZoJs+5oI+k8ddhg==} engines: {node: ^22.14.0 || >=24.0.0} whatwg-url@5.0.0: @@ -8625,7 +8617,7 @@ snapshots: '@actions/http-client@4.0.1': dependencies: tunnel: 0.0.6 - undici: 6.29.0 + undici: 6.29.1 '@actions/io@3.0.2': {} @@ -9590,7 +9582,7 @@ snapshots: json-stringify-safe: 5.0.1 mime-types: 2.1.35 performance-now: 2.1.0 - qs: 6.16.0 + qs: 6.16.1 safe-buffer: 5.2.1 tough-cookie: 5.1.2 tunnel-agent: 0.6.0 @@ -9902,7 +9894,7 @@ snapshots: '@firebase/webchannel-wrapper': 1.0.7 '@grpc/grpc-js': 1.9.16 '@grpc/proto-loader': 0.7.15 - re2js: 2.8.6 + re2js: 2.8.8 tslib: 2.8.1 '@firebase/functions-compat@0.5.0(@firebase/app-compat@0.5.19)(@firebase/app@0.16.3)': @@ -11002,80 +10994,80 @@ snapshots: '@parcel/watcher-win32-arm64': 2.6.0 '@parcel/watcher-win32-x64': 2.6.0 - '@peculiar/asn1-cms@2.10.0': + '@peculiar/asn1-cms@2.11.0': dependencies: - '@peculiar/asn1-schema': 2.10.0 - '@peculiar/asn1-x509': 2.10.0 - '@peculiar/asn1-x509-attr': 2.10.0 - asn1js: 3.0.10 + '@peculiar/asn1-schema': 2.11.0 + '@peculiar/asn1-x509': 2.11.0 + '@peculiar/asn1-x509-attr': 2.11.0 + asn1js: 3.1.0 tslib: 2.8.1 - '@peculiar/asn1-csr@2.10.0': + '@peculiar/asn1-csr@2.11.0': dependencies: - '@peculiar/asn1-schema': 2.10.0 - '@peculiar/asn1-x509': 2.10.0 - asn1js: 3.0.10 + '@peculiar/asn1-schema': 2.11.0 + '@peculiar/asn1-x509': 2.11.0 + asn1js: 3.1.0 tslib: 2.8.1 - '@peculiar/asn1-ecc@2.10.0': + '@peculiar/asn1-ecc@2.11.0': dependencies: - '@peculiar/asn1-schema': 2.10.0 - '@peculiar/asn1-x509': 2.10.0 - asn1js: 3.0.10 + '@peculiar/asn1-schema': 2.11.0 + '@peculiar/asn1-x509': 2.11.0 + asn1js: 3.1.0 tslib: 2.8.1 - '@peculiar/asn1-pfx@2.10.0': + '@peculiar/asn1-pfx@2.11.0': dependencies: - '@peculiar/asn1-cms': 2.10.0 - '@peculiar/asn1-pkcs8': 2.10.0 - '@peculiar/asn1-rsa': 2.10.0 - '@peculiar/asn1-schema': 2.10.0 - asn1js: 3.0.10 + '@peculiar/asn1-cms': 2.11.0 + '@peculiar/asn1-pkcs8': 2.11.0 + '@peculiar/asn1-rsa': 2.11.0 + '@peculiar/asn1-schema': 2.11.0 + asn1js: 3.1.0 tslib: 2.8.1 - '@peculiar/asn1-pkcs8@2.10.0': + '@peculiar/asn1-pkcs8@2.11.0': dependencies: - '@peculiar/asn1-schema': 2.10.0 - '@peculiar/asn1-x509': 2.10.0 - asn1js: 3.0.10 + '@peculiar/asn1-schema': 2.11.0 + '@peculiar/asn1-x509': 2.11.0 + asn1js: 3.1.0 tslib: 2.8.1 - '@peculiar/asn1-pkcs9@2.10.0': + '@peculiar/asn1-pkcs9@2.11.0': dependencies: - '@peculiar/asn1-cms': 2.10.0 - '@peculiar/asn1-pfx': 2.10.0 - '@peculiar/asn1-pkcs8': 2.10.0 - '@peculiar/asn1-schema': 2.10.0 - '@peculiar/asn1-x509': 2.10.0 - '@peculiar/asn1-x509-attr': 2.10.0 - asn1js: 3.0.10 + '@peculiar/asn1-cms': 2.11.0 + '@peculiar/asn1-pfx': 2.11.0 + '@peculiar/asn1-pkcs8': 2.11.0 + '@peculiar/asn1-schema': 2.11.0 + '@peculiar/asn1-x509': 2.11.0 + '@peculiar/asn1-x509-attr': 2.11.0 + asn1js: 3.1.0 tslib: 2.8.1 - '@peculiar/asn1-rsa@2.10.0': + '@peculiar/asn1-rsa@2.11.0': dependencies: - '@peculiar/asn1-schema': 2.10.0 - '@peculiar/asn1-x509': 2.10.0 - asn1js: 3.0.10 + '@peculiar/asn1-schema': 2.11.0 + '@peculiar/asn1-x509': 2.11.0 + asn1js: 3.1.0 tslib: 2.8.1 - '@peculiar/asn1-schema@2.10.0': + '@peculiar/asn1-schema@2.11.0': dependencies: '@peculiar/utils': 2.0.3 - asn1js: 3.0.10 + asn1js: 3.1.0 tslib: 2.8.1 - '@peculiar/asn1-x509-attr@2.10.0': + '@peculiar/asn1-x509-attr@2.11.0': dependencies: - '@peculiar/asn1-schema': 2.10.0 - '@peculiar/asn1-x509': 2.10.0 - asn1js: 3.0.10 + '@peculiar/asn1-schema': 2.11.0 + '@peculiar/asn1-x509': 2.11.0 + asn1js: 3.1.0 tslib: 2.8.1 - '@peculiar/asn1-x509@2.10.0': + '@peculiar/asn1-x509@2.11.0': dependencies: - '@peculiar/asn1-schema': 2.10.0 + '@peculiar/asn1-schema': 2.11.0 '@peculiar/utils': 2.0.3 - asn1js: 3.0.10 + asn1js: 3.1.0 tslib: 2.8.1 '@peculiar/utils@2.0.3': @@ -11084,13 +11076,13 @@ snapshots: '@peculiar/x509@1.14.3': dependencies: - '@peculiar/asn1-cms': 2.10.0 - '@peculiar/asn1-csr': 2.10.0 - '@peculiar/asn1-ecc': 2.10.0 - '@peculiar/asn1-pkcs9': 2.10.0 - '@peculiar/asn1-rsa': 2.10.0 - '@peculiar/asn1-schema': 2.10.0 - '@peculiar/asn1-x509': 2.10.0 + '@peculiar/asn1-cms': 2.11.0 + '@peculiar/asn1-csr': 2.11.0 + '@peculiar/asn1-ecc': 2.11.0 + '@peculiar/asn1-pkcs9': 2.11.0 + '@peculiar/asn1-rsa': 2.11.0 + '@peculiar/asn1-schema': 2.11.0 + '@peculiar/asn1-x509': 2.11.0 pvtsutils: 1.3.6 reflect-metadata: 0.2.2 tslib: 2.8.1 @@ -11123,7 +11115,7 @@ snapshots: '@puppeteer/browsers@3.2.2': dependencies: - modern-tar: 0.8.5 + modern-tar: 0.8.6 yargs: 18.1.0 '@rolldown/binding-android-arm-eabi@1.2.8': @@ -11446,10 +11438,10 @@ snapshots: '@types/less@3.0.8': {} - '@types/loader-utils@3.0.0(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.28)(uglify-js@3.19.3)': + '@types/loader-utils@3.0.0(esbuild@0.28.2)(lightningcss@1.33.0)(uglify-js@3.19.3)': dependencies: '@types/node': 22.20.5 - webpack: 5.111.0(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.28)(uglify-js@3.19.3) + webpack: 5.112.0(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.28)(uglify-js@3.19.3) transitivePeerDependencies: - '@minify-html/node' - '@napi-rs/image' @@ -12122,7 +12114,7 @@ snapshots: dependencies: safer-buffer: 2.1.2 - asn1js@3.0.10: + asn1js@3.1.0: dependencies: pvtsutils: 1.3.6 pvutils: 1.2.0 @@ -12155,7 +12147,7 @@ snapshots: autoprefixer@10.6.0(postcss@8.5.28): dependencies: browserslist: 4.29.3 - caniuse-lite: 1.0.30001815 + caniuse-lite: 1.0.30001816 fraction.js: 5.3.4 picocolors: 1.1.1 postcss: 8.5.28 @@ -12219,7 +12211,7 @@ snapshots: base64-js@1.5.1: {} - baseline-browser-mapping@2.11.28: {} + baseline-browser-mapping@2.11.29: {} batch@0.6.1: {} @@ -12265,7 +12257,7 @@ snapshots: http-errors: 2.0.1 iconv-lite: 0.4.24 on-finished: 2.4.1 - qs: 6.16.0 + qs: 6.16.1 raw-body: 2.5.3 type-is: 1.6.18 unpipe: 1.0.0 @@ -12280,7 +12272,7 @@ snapshots: http-errors: 2.0.1 iconv-lite: 0.7.3 on-finished: 2.4.1 - qs: 6.16.0 + qs: 6.16.1 raw-body: 3.0.2 type-is: 2.1.0 transitivePeerDependencies: @@ -12374,10 +12366,10 @@ snapshots: browserslist@4.29.3: dependencies: - baseline-browser-mapping: 2.11.28 - caniuse-lite: 1.0.30001815 - electron-to-chromium: 1.5.452 - node-releases: 2.0.58 + baseline-browser-mapping: 2.11.29 + caniuse-lite: 1.0.30001816 + electron-to-chromium: 1.5.459 + node-releases: 2.0.59 update-browserslist-db: 1.3.4(browserslist@4.29.3) bs-recipes@1.3.4: {} @@ -12444,7 +12436,7 @@ snapshots: callsites@3.1.0: {} - caniuse-lite@1.0.30001815: {} + caniuse-lite@1.0.30001816: {} caseless@0.12.0: {} @@ -12654,7 +12646,7 @@ snapshots: dependencies: glob-parent: 6.0.2 normalize-path: 3.0.0 - schema-utils: 4.5.0 + schema-utils: 4.8.1(webpack@5.112.0(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.28)(uglify-js@3.19.3)) serialize-javascript: 7.1.2 tinyglobby: 0.2.17 webpack: 5.112.0(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.28)(uglify-js@3.19.3) @@ -12903,7 +12895,7 @@ snapshots: ejs@7.0.1: {} - electron-to-chromium@1.5.452: {} + electron-to-chromium@1.5.459: {} emoji-regex@10.6.0: {} @@ -13326,7 +13318,7 @@ snapshots: once: 1.4.0 parseurl: 1.3.3 proxy-addr: 2.0.8 - qs: 6.16.0 + qs: 6.16.1 range-parser: 1.3.0 router: 2.2.0(supports-color@11.0.0) send: 1.2.1(supports-color@11.0.0) @@ -14307,7 +14299,7 @@ snapshots: w3c-xmlserializer: 5.0.0 webidl-conversions: 8.0.1 whatwg-mimetype: 5.0.0 - whatwg-url: 17.2.0(@noble/hashes@1.8.0) + whatwg-url: 17.3.0(@noble/hashes@1.8.0) xml-name-validator: 5.0.0 transitivePeerDependencies: - '@noble/hashes' @@ -14536,7 +14528,7 @@ snapshots: lightningcss-win32-arm64-msvc: 1.33.0 lightningcss-win32-x64-msvc: 1.33.0 - lilconfig@3.1.3: {} + lilconfig@3.1.4: {} limiter@1.1.5: {} @@ -14742,7 +14734,7 @@ snapshots: mini-css-extract-plugin@2.10.2(webpack@5.112.0(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.28)(uglify-js@3.19.3)): dependencies: - schema-utils: 4.5.0 + schema-utils: 4.8.1(webpack@5.112.0(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.28)(uglify-js@3.19.3)) tapable: 2.3.3 webpack: 5.112.0(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.28)(uglify-js@3.19.3) @@ -14764,24 +14756,11 @@ snapshots: minimist@1.2.8: {} - minimizer-webpack-plugin@5.13.0(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.28)(uglify-js@3.19.3)(webpack@5.111.0(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.28)(uglify-js@3.19.3)): - dependencies: - '@jridgewell/trace-mapping': 0.3.31 - jest-worker: 27.5.1 - schema-utils: 4.5.0 - terser: 5.51.2 - webpack: 5.111.0(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.28)(uglify-js@3.19.3) - optionalDependencies: - esbuild: 0.28.2 - lightningcss: 1.33.0 - postcss: 8.5.28 - uglify-js: 3.19.3 - - minimizer-webpack-plugin@5.13.0(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.28)(uglify-js@3.19.3)(webpack@5.112.0(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.28)(uglify-js@3.19.3)): + minimizer-webpack-plugin@5.13.1(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.28)(uglify-js@3.19.3)(webpack@5.112.0(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.28)(uglify-js@3.19.3)): dependencies: '@jridgewell/trace-mapping': 0.3.31 jest-worker: 27.5.1 - schema-utils: 4.5.0 + schema-utils: 4.8.1(webpack@5.112.0(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.28)(uglify-js@3.19.3)) terser: 5.51.2 webpack: 5.112.0(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.28)(uglify-js@3.19.3) optionalDependencies: @@ -14802,7 +14781,7 @@ snapshots: mkdirp@1.0.4: {} - modern-tar@0.8.5: {} + modern-tar@0.8.6: {} mrmime@2.0.1: {} @@ -14940,7 +14919,7 @@ snapshots: node-gyp-build@4.8.4: {} - node-releases@2.0.58: {} + node-releases@2.0.59: {} normalize-path@3.0.0: {} @@ -15231,7 +15210,7 @@ snapshots: pkijs@3.4.1: dependencies: '@noble/hashes': 1.8.0 - asn1js: 3.0.10 + asn1js: 3.1.0 bytestreamjs: 2.0.1 pvtsutils: 1.3.6 pvutils: 1.2.0 @@ -15384,7 +15363,7 @@ snapshots: '@puppeteer/browsers': 3.2.2 chromium-bidi: 17.0.2(devtools-protocol@0.0.1680125) devtools-protocol: 0.0.1680125 - lilconfig: 3.1.3 + lilconfig: 3.1.4 puppeteer-core: 25.11.0(bufferutil@4.1.0)(utf-8-validate@6.0.6) typed-query-selector: 2.12.3 transitivePeerDependencies: @@ -15410,7 +15389,7 @@ snapshots: es-define-property: 1.0.1 side-channel: 1.1.1 - qs@6.16.0: + qs@6.16.1: dependencies: es-define-property: 1.0.1 side-channel: 1.1.1 @@ -15455,7 +15434,7 @@ snapshots: iconv-lite: 0.7.3 unpipe: 1.0.0 - re2js@2.8.6: {} + re2js@2.8.8: {} readable-stream@2.3.8: dependencies: @@ -15820,7 +15799,7 @@ snapshots: immutable: 5.1.9 rxjs: 7.8.2 supports-color: 8.1.1 - sync-child-process: 1.0.2 + sync-child-process: 1.1.0 varint: 6.0.0 optionalDependencies: sass-embedded-all-unknown: 1.104.1 @@ -15863,12 +15842,14 @@ snapshots: dependencies: xmlchars: 2.2.0 - schema-utils@4.5.0: + schema-utils@4.8.1(webpack@5.112.0(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.28)(uglify-js@3.19.3)): dependencies: '@types/json-schema': 7.0.15 ajv: 8.20.0 ajv-formats: 3.0.1(ajv@8.20.0) ajv-keywords: 5.1.0(ajv@8.20.0) + optionalDependencies: + webpack: 5.112.0(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.28)(uglify-js@3.19.3) selfsigned@5.5.0: dependencies: @@ -16253,7 +16234,7 @@ snapshots: symbol-tree@3.2.4: {} - sync-child-process@1.0.2: + sync-child-process@1.1.0: dependencies: sync-message-port: 1.2.0 @@ -16510,7 +16491,7 @@ snapshots: undici-types@7.24.6: {} - undici@6.29.0: {} + undici@6.29.1: {} undici@8.10.2: {} @@ -16703,11 +16684,7 @@ snapshots: dependencies: xml-name-validator: 5.0.0 - watchpack@2.5.2: - dependencies: - graceful-fs: 4.2.11 - - watchpack@2.6.2: + watchpack@2.6.3: dependencies: graceful-fs: 4.2.11 @@ -16730,7 +16707,7 @@ snapshots: memfs: 4.80.0 mime-types: 3.0.2 range-parser: 1.3.0 - schema-utils: 4.5.0 + schema-utils: 4.8.1(webpack@5.112.0(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.28)(uglify-js@3.19.3)) optionalDependencies: webpack: 5.112.0(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.28)(uglify-js@3.19.3) @@ -16755,7 +16732,7 @@ snapshots: launch-editor: 2.14.2 open: 11.0.4 p-retry: 8.0.1 - schema-utils: 4.5.0 + schema-utils: 4.8.1(webpack@5.112.0(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.28)(uglify-js@3.19.3)) selfsigned: 5.5.0 serve-index: 1.9.2(supports-color@11.0.0) tinyglobby: 0.2.17 @@ -16781,43 +16758,6 @@ snapshots: typed-assert: 1.0.9 webpack: 5.112.0(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.28)(uglify-js@3.19.3) - webpack@5.111.0(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.28)(uglify-js@3.19.3): - dependencies: - '@types/estree': 1.0.9 - '@types/json-schema': 7.0.15 - '@webassemblyjs/ast': 1.14.1 - '@webassemblyjs/wasm-edit': 1.14.1 - '@webassemblyjs/wasm-parser': 1.14.1 - browserslist: 4.29.3 - chrome-trace-event: 1.0.4 - enhanced-resolve: 5.26.0 - es-module-lexer: 2.3.2 - events: 3.3.0 - graceful-fs: 4.2.11 - mime-db: 1.54.0 - minimizer-webpack-plugin: 5.13.0(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.28)(uglify-js@3.19.3)(webpack@5.111.0(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.28)(uglify-js@3.19.3)) - schema-utils: 4.5.0 - tapable: 2.3.3 - watchpack: 2.5.2 - webpack-sources: 3.6.0 - transitivePeerDependencies: - - '@minify-html/node' - - '@napi-rs/image' - - '@swc/core' - - '@swc/css' - - '@swc/html' - - clean-css - - cssnano - - csso - - esbuild - - html-minifier-terser - - imagemin - - lightningcss - - postcss - - sharp - - svgo - - uglify-js - webpack@5.112.0(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.28)(uglify-js@3.19.3): dependencies: '@types/estree': 1.0.9 @@ -16832,10 +16772,10 @@ snapshots: events: 3.3.0 graceful-fs: 4.2.11 mime-db: 1.54.0 - minimizer-webpack-plugin: 5.13.0(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.28)(uglify-js@3.19.3)(webpack@5.112.0(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.28)(uglify-js@3.19.3)) - schema-utils: 4.5.0 + minimizer-webpack-plugin: 5.13.1(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.28)(uglify-js@3.19.3)(webpack@5.112.0(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.28)(uglify-js@3.19.3)) + schema-utils: 4.8.1(webpack@5.112.0(esbuild@0.28.2)(lightningcss@1.33.0)(postcss@8.5.28)(uglify-js@3.19.3)) tapable: 2.3.3 - watchpack: 2.6.2 + watchpack: 2.6.3 webpack-sources: 3.6.0 transitivePeerDependencies: - '@minify-html/node' @@ -16873,7 +16813,7 @@ snapshots: transitivePeerDependencies: - '@noble/hashes' - whatwg-url@17.2.0(@noble/hashes@1.8.0): + whatwg-url@17.3.0(@noble/hashes@1.8.0): dependencies: '@exodus/bytes': 1.16.0(@noble/hashes@1.8.0) tr46: 7.0.0 From 176ed907cbea82ca223ecb0816b67ebcbbedc4d8 Mon Sep 17 00:00:00 2001 From: MeAkib Date: Sun, 18 Oct 2026 19:35:53 +0600 Subject: [PATCH 127/233] docs(@angular/build): correct `outputFile` and `port` option descriptions The unit-test `outputFile` description stated that the path applies only to the first reporter, but it is passed to Vitest as is and used by every configured reporter that writes to a file. The dev-server `port` description did not mention that the `PORT` environment variable takes precedence over the option. (cherry picked from commit 5be930a04bf2a8fd560ca329f31b50ede22683de) --- packages/angular/build/src/builders/dev-server/schema.json | 2 +- packages/angular/build/src/builders/unit-test/schema.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/angular/build/src/builders/dev-server/schema.json b/packages/angular/build/src/builders/dev-server/schema.json index 3517d3098887..667bde5692da 100644 --- a/packages/angular/build/src/builders/dev-server/schema.json +++ b/packages/angular/build/src/builders/dev-server/schema.json @@ -11,7 +11,7 @@ }, "port": { "type": "number", - "description": "Port to listen on.", + "description": "Port to listen on. The `PORT` environment variable, when set, takes precedence over this option.", "default": 4200 }, "host": { diff --git a/packages/angular/build/src/builders/unit-test/schema.json b/packages/angular/build/src/builders/unit-test/schema.json index 1b7234a96b51..0313c3789360 100644 --- a/packages/angular/build/src/builders/unit-test/schema.json +++ b/packages/angular/build/src/builders/unit-test/schema.json @@ -258,7 +258,7 @@ }, "outputFile": { "type": "string", - "description": "Specifies a file path for the test report, applying only to the first reporter. To configure output files for multiple reporters, use the tuple format `['reporter-name', { outputFile: '...' }]` within the `reporters` option. When not provided, output is written to the console." + "description": "Specifies a file path for the test report. This path is used by every configured reporter that writes to a file. To write a separate file for each reporter, use the tuple format `['reporter-name', { outputFile: '...' }]` within the `reporters` option. When not provided, output is written to the console." }, "providersFile": { "type": "string", From e78cf0ae9676e77245de3cae7ae86b42a48a6322 Mon Sep 17 00:00:00 2001 From: Alan Agius <17563226+alan-agius4@users.noreply.github.com> Date: Tue, 20 Oct 2026 08:57:18 +0000 Subject: [PATCH 128/233] fix(@angular/build): preserve diagnostic locations at offset 0 and guard empty files Ensure `convertTypeScriptDiagnosticInfo` checks `info.start !== undefined` so diagnostics and related information starting at file offset `0` retain their line, column, and lineText location properties. Also clamp `info.file.text.length - 1` to `0` when computing `lastLineOfFile` to prevent a TypeScript `Debug Failure` when reporting diagnostics on empty files. (cherry picked from commit cd70beb20db711cb178afccf6c688f9475f9e1f9) --- .../tools/angular/compilation/diagnostics.ts | 4 +- .../angular/compilation/diagnostics_spec.ts | 111 ++++++++++++++++++ 2 files changed, 113 insertions(+), 2 deletions(-) create mode 100644 packages/angular/build/src/tools/angular/compilation/diagnostics_spec.ts diff --git a/packages/angular/build/src/tools/angular/compilation/diagnostics.ts b/packages/angular/build/src/tools/angular/compilation/diagnostics.ts index bf85b69f707c..41563b90ebbd 100644 --- a/packages/angular/build/src/tools/angular/compilation/diagnostics.ts +++ b/packages/angular/build/src/tools/angular/compilation/diagnostics.ts @@ -37,7 +37,7 @@ function convertTypeScriptDiagnosticInfo( }; // Calculate the line/column location and extract the full line text that has the diagnostic - if (info.start) { + if (info.start !== undefined) { const { line, character } = typescript.getLineAndCharacterOfPosition(info.file, info.start); note.location.line = line + 1; note.location.column = character; @@ -50,7 +50,7 @@ function convertTypeScriptDiagnosticInfo( // will error if a nonexistent line is passed). const { line: lastLineOfFile } = typescript.getLineAndCharacterOfPosition( info.file, - info.file.text.length - 1, + Math.max(0, info.file.text.length - 1), ); const lineEndPosition = line < lastLineOfFile diff --git a/packages/angular/build/src/tools/angular/compilation/diagnostics_spec.ts b/packages/angular/build/src/tools/angular/compilation/diagnostics_spec.ts new file mode 100644 index 000000000000..8ea79c20ba43 --- /dev/null +++ b/packages/angular/build/src/tools/angular/compilation/diagnostics_spec.ts @@ -0,0 +1,111 @@ +/** + * @license + * Copyright Google LLC All Rights Reserved. + * + * Use of this source code is governed by an MIT-style license that can be + * found in the LICENSE file at https://angular.dev/license + */ + +import ts from 'typescript'; +import { convertTypeScriptDiagnostic } from './diagnostics'; + +describe('convertTypeScriptDiagnostic', () => { + it('populates line, column, and lineText when diagnostic or relatedInformation starts at offset 0', () => { + const sourceFile = ts.createSourceFile( + '/src/app/app.component.ts', + 'const invalid: number = "string";\nconst secondLine = 2;\n', + ts.ScriptTarget.Latest, + ); + const templateFile = ts.createSourceFile( + '/src/app/app.component.html', + '\n
Valid
\n', + ts.ScriptTarget.Latest, + ); + + const diagnostic: ts.Diagnostic = { + category: ts.DiagnosticCategory.Error, + code: -998001, + file: templateFile, + start: 0, + length: 17, + messageText: "'unknown-element' is not a known element.", + relatedInformation: [ + { + category: ts.DiagnosticCategory.Message, + code: 0, + file: sourceFile, + start: 0, + length: 5, + messageText: 'Error occurs in the template of component AppComponent.', + }, + ], + }; + + const result = convertTypeScriptDiagnostic(ts, diagnostic); + + expect(result.text).toBe("NG8001: 'unknown-element' is not a known element."); + expect(result.location).toEqual({ + file: '/src/app/app.component.html', + length: 17, + line: 1, + column: 0, + lineText: '', + }); + + expect(result.notes).toEqual([ + { + text: 'Error occurs in the template of component AppComponent.', + location: { + file: '/src/app/app.component.ts', + length: 5, + line: 1, + column: 0, + lineText: 'const invalid: number = "string";', + }, + }, + ]); + }); + + it('does not throw a TypeScript Debug Failure when diagnostic is reported on an empty file', () => { + const emptyFile = ts.createSourceFile('/src/empty.ts', '', ts.ScriptTarget.Latest); + + const diagnosticAtZero: ts.Diagnostic = { + category: ts.DiagnosticCategory.Error, + code: 2306, + file: emptyFile, + start: 0, + length: 0, + messageText: "File '/src/empty.ts' is not a module.", + }; + + expect(() => convertTypeScriptDiagnostic(ts, diagnosticAtZero)).not.toThrow(); + expect(convertTypeScriptDiagnostic(ts, diagnosticAtZero)).toEqual({ + text: "TS2306: File '/src/empty.ts' is not a module.", + location: { + file: '/src/empty.ts', + length: 0, + line: 1, + column: 0, + lineText: '', + }, + }); + + const diagnosticPastEnd: ts.Diagnostic = { + category: ts.DiagnosticCategory.Error, + code: 1005, + file: emptyFile, + start: 1, + length: 0, + messageText: 'Unexpected end of text.', + }; + + expect(() => convertTypeScriptDiagnostic(ts, diagnosticPastEnd)).not.toThrow(); + expect(convertTypeScriptDiagnostic(ts, diagnosticPastEnd).location).toEqual({ + file: '/src/empty.ts', + length: 0, + line: 1, + column: 1, + lineText: '', + }); + }); +}); From 63e45bcfe711b6e2320db7ee24caba898bb90347 Mon Sep 17 00:00:00 2001 From: Roman Khegay Date: Tue, 20 Oct 2026 19:57:31 +0500 Subject: [PATCH 129/233] fix(@angular/cli): keep schematic positional arguments in index order sort checked `positional` for truthiness, so argument at index 0 was ordered like plain option and help showed it after index 1 when that argument has `x-prompt` both are optional for yargs and values go to wrong argumnets, now positionals are sorted by index (cherry picked from commit d69dcec3137f0fd49e591d410c82569b3798f2ec) --- .../command-builder/utilities/json-schema.ts | 8 ++-- .../utilities/json-schema_spec.ts | 43 +++++++++++++++++++ tests/e2e/tests/generate/help-output.ts | 10 ++--- 3 files changed, 52 insertions(+), 9 deletions(-) diff --git a/packages/angular/cli/src/command-builder/utilities/json-schema.ts b/packages/angular/cli/src/command-builder/utilities/json-schema.ts index 0a4215be8eed..78218465cf02 100644 --- a/packages/angular/cli/src/command-builder/utilities/json-schema.ts +++ b/packages/angular/cli/src/command-builder/utilities/json-schema.ts @@ -390,10 +390,10 @@ export async function parseJsonSchemaToOptions( // Sort by positional and name. return options.sort((a, b) => { - if (a.positional) { - return b.positional ? a.positional - b.positional : a.name.localeCompare(b.name); - } else if (b.positional) { - return -1; + if (a.positional !== undefined) { + return b.positional !== undefined ? a.positional - b.positional : -1; + } else if (b.positional !== undefined) { + return 1; } return a.name.localeCompare(b.name); diff --git a/packages/angular/cli/src/command-builder/utilities/json-schema_spec.ts b/packages/angular/cli/src/command-builder/utilities/json-schema_spec.ts index 11228e4adca0..12b0a5088ddc 100644 --- a/packages/angular/cli/src/command-builder/utilities/json-schema_spec.ts +++ b/packages/angular/cli/src/command-builder/utilities/json-schema_spec.ts @@ -345,4 +345,47 @@ describe('parseJsonSchemaToOptions', () => { ); }); }); + + describe('with positional arguments not in alphabetical order', () => { + it('sorts positional arguments by their index', async () => { + const jsonSchema = { + '$id': 'FakeSchema', + 'title': 'Fake Schema', + 'type': 'object', + 'required': ['preset'], + 'properties': { + 'preset': { + 'type': 'string', + 'enum': ['form', 'table'], + 'description': 'preset.', + '$default': { + '$source': 'argv', + 'index': 0, + }, + 'x-prompt': 'Which preset?', + }, + 'name': { + 'type': 'string', + 'description': 'name.', + '$default': { + '$source': 'argv', + 'index': 1, + }, + }, + 'path': { + 'type': 'string', + 'description': 'path.', + }, + }, + }; + const registry = new schema.CoreSchemaRegistry(); + const options = await parseJsonSchemaToOptions(registry, jsonSchema, /* interactive= */ true); + + expect(options).toEqual([ + jasmine.objectContaining({ name: 'preset', positional: 0, required: false }), + jasmine.objectContaining({ name: 'name', positional: 1, required: false }), + jasmine.objectContaining({ name: 'path', positional: undefined, required: false }), + ]); + }); + }); }); diff --git a/tests/e2e/tests/generate/help-output.ts b/tests/e2e/tests/generate/help-output.ts index 86fc3b988b38..bd5c71a7d9d1 100644 --- a/tests/e2e/tests/generate/help-output.ts +++ b/tests/e2e/tests/generate/help-output.ts @@ -32,14 +32,14 @@ export default function () { "$id": "FakeSchema", "title": "Fake Schema", "type": "object", - "required": ["a"], + "required": ["b"], "properties": { "b": { "type": "string", "description": "b.", "$default": { "$source": "argv", - "index": 1 + "index": 0 } }, "a": { @@ -47,7 +47,7 @@ export default function () { "description": "a.", "$default": { "$source": "argv", - "index": 0 + "index": 1 } }, "optC": { @@ -76,7 +76,7 @@ export default function () { ) .then(() => ng('generate', 'fake-schematics:fake', '--help')) .then(({ stdout }) => { - assert.match(stdout, /ng generate fake-schematics:fake \[b\]/); + assert.match(stdout, /ng generate fake-schematics:fake \[a\]/); assert.match(stdout, /opt-a[\s\S]*opt-b[\s\S]*opt-c/); }) // set up default collection. @@ -89,7 +89,7 @@ export default function () { .then(() => ng('generate', 'fake', '--help')) // verify same output .then(({ stdout }) => { - assert.match(stdout, /ng generate fake \[b\]/); + assert.match(stdout, /ng generate fake \[a\]/); assert.match(stdout, /opt-a[\s\S]*opt-b[\s\S]*opt-c/); }) From c235a9554fb1f5cad734a3fb2df7c4f7e4283f91 Mon Sep 17 00:00:00 2001 From: drakeo338 Date: Mon, 19 Oct 2026 09:39:44 +0000 Subject: [PATCH 130/233] fix(@angular/build): add integrity metadata for all initial chunks beyond the module preload limit With subresource integrity enabled, the import map integrity entries skipped every file in the initial files set. Only the first 10 initial script chunks receive a `modulepreload` hint (and none do when `preloadInitial` is disabled or `externalPackages` is set), so the remaining initial chunks ended up without any integrity metadata. Skip only entry points, which are referenced by their own tag, and files that actually received a hint. All other initial chunks are now included in the import map integrity entries. Closes #34395 (cherry picked from commit 089d39467863643ecadf79cefc5c92a16b0a85d3) --- .../application/index-html-generator.ts | 9 +- .../application/index-html-generator_spec.ts | 114 ++++++++++++++++++ 2 files changed, 122 insertions(+), 1 deletion(-) create mode 100644 packages/angular/build/src/builders/application/index-html-generator_spec.ts diff --git a/packages/angular/build/src/builders/application/index-html-generator.ts b/packages/angular/build/src/builders/application/index-html-generator.ts index d89eadf8b9b0..a1c9cbcc9b30 100644 --- a/packages/angular/build/src/builders/application/index-html-generator.ts +++ b/packages/angular/build/src/builders/application/index-html-generator.ts @@ -91,8 +91,15 @@ export async function generateIndexHtml( let chunksIntegrity: ReadonlyMap | undefined; if (subresourceIntegrity) { const integrity = new Map(); + // Entry points and module preload hints carry their own integrity attribute. Any other + // initial chunk (e.g. beyond the module preload limit) is only covered by the import map. + const hinted = new Set(hints.map(({ url }) => url)); for (const file of browserOutputFiles) { - if (!file.path.endsWith('.js') || initialFiles.has(file.path)) { + if ( + !file.path.endsWith('.js') || + initialFiles.get(file.path)?.entrypoint || + hinted.has(file.path) + ) { continue; } const hash = createHash('sha384').update(file.contents).digest('base64'); diff --git a/packages/angular/build/src/builders/application/index-html-generator_spec.ts b/packages/angular/build/src/builders/application/index-html-generator_spec.ts new file mode 100644 index 000000000000..4f1098086461 --- /dev/null +++ b/packages/angular/build/src/builders/application/index-html-generator_spec.ts @@ -0,0 +1,114 @@ +/** + * @license + * Copyright Google LLC All Rights Reserved. + * + * Use of this source code is governed by an MIT-style license that can be + * found in the LICENSE file at https://angular.dev/license + */ + +import { mkdtemp, rm, writeFile } from 'node:fs/promises'; +import { tmpdir } from 'node:os'; +import { join } from 'node:path'; +import { + BuildOutputFile, + BuildOutputFileType, + InitialFileRecord, +} from '../../tools/esbuild/bundler-files'; +import { generateIndexHtml } from './index-html-generator'; +import { NormalizedApplicationBuildOptions } from './options'; + +describe('generateIndexHtml', () => { + let tempDir: string; + + beforeEach(async () => { + tempDir = await mkdtemp(join(tmpdir(), 'index-html-generator-spec-')); + await writeFile( + join(tempDir, 'index.html'), + '', + ); + }); + + afterEach(async () => { + await rm(tempDir, { recursive: true, force: true }); + }); + + function createOutputFile(path: string): BuildOutputFile { + const text = `console.log(${JSON.stringify(path)});`; + + return { + path, + text, + contents: Buffer.from(text), + type: BuildOutputFileType.Browser, + } as unknown as BuildOutputFile; + } + + function createOptions(subresourceIntegrity: boolean): NormalizedApplicationBuildOptions { + return { + indexHtmlOptions: { + input: join(tempDir, 'index.html'), + insertionOrder: [['main.js', true]], + preloadInitial: true, + }, + subresourceIntegrity, + baseHref: '/', + security: {}, + } as unknown as NormalizedApplicationBuildOptions; + } + + it('adds integrity metadata for every initial chunk when there are more than the module preload limit', async () => { + const chunkCount = 15; + const chunks = Array.from({ length: chunkCount }, (_, i) => `chunk-${i}.js`); + const initialFiles = new Map([ + ['main.js', { entrypoint: true, name: 'main', type: 'script', serverFile: false, depth: 0 }], + ...chunks.map( + (chunk, i) => + [chunk, { entrypoint: false, type: 'script', serverFile: false, depth: i + 1 }] as [ + string, + InitialFileRecord, + ], + ), + ]); + const outputFiles = ['main.js', ...chunks].map(createOutputFile); + + const { csrContent, errors } = await generateIndexHtml( + initialFiles, + outputFiles, + createOptions(true), + ); + expect(errors).toEqual([]); + + const importMapMatch = /`); + + expect(page).not.toContain('