From 4187d46c9192064b3ebcb4d54650a45ebcd7ac03 Mon Sep 17 00:00:00 2001 From: Alan Agius <17563226+alan-agius4@users.noreply.github.com> Date: Wed, 19 Nov 2025 14:38:52 +0000 Subject: [PATCH 01/54] ci: relocate license check to prevent blocking other CI jobs Relocates the "Check Package Licenses" step in `pr.yml` to ensure that failures in this specific check do not prevent other critical CI jobs from completing or providing feedback on pull requests. (cherry picked from commit 89f9c8ac410aa454b938c36e5d7fe82dc93172ac) --- .github/workflows/pr.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/pr.yml b/.github/workflows/pr.yml index d85c230ac9a7..99f850bee44f 100644 --- a/.github/workflows/pr.yml +++ b/.github/workflows/pr.yml @@ -55,8 +55,6 @@ jobs: run: pnpm ts-circular-deps check - name: Run Validation run: pnpm admin validate - - name: Check Package Licenses - uses: angular/dev-infra/github-actions/linting/licenses@c855fffb4b01bc06e743eb3bdfd54c866af09ad8 - name: Check tooling setup run: pnpm check-tooling-setup - name: Check commit message @@ -67,6 +65,8 @@ jobs: # Code formatting checks are only done on pull requests as its too late to validate once # 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@c855fffb4b01bc06e743eb3bdfd54c866af09ad8 build: runs-on: ubuntu-latest From 8ef3d4cafe74f56972e3030c2f505056e2250f20 Mon Sep 17 00:00:00 2001 From: Alan Agius <17563226+alan-agius4@users.noreply.github.com> Date: Tue, 18 Nov 2025 09:18:13 +0000 Subject: [PATCH 02/54] refactor: source best practices from `@angular/core` The best practices markdown file is now sourced directly from `@angular/core/resources/best-practices.md`. This change eliminates duplication and ensures consistency across packages. - `packages/angular/cli/src/commands/mcp/resources/best-practices.md` is now generated from the `@angular/core` resource. - `packages/schematics/angular/ai-config/files/__rulesName__.template` is also generated from the `@angular/core` resource, with additional frontmatter. (cherry picked from commit 240d96cc5be895abe7db537fdbc228135fe6df77) --- packages/angular/cli/BUILD.bazel | 12 +++++ .../commands/mcp/resources/best-practices.md | 47 ------------------ packages/schematics/angular/BUILD.bazel | 16 +++++- .../ai-config/files/__rulesName__.template | 49 ------------------- 4 files changed, 26 insertions(+), 98 deletions(-) delete mode 100644 packages/angular/cli/src/commands/mcp/resources/best-practices.md delete mode 100644 packages/schematics/angular/ai-config/files/__rulesName__.template diff --git a/packages/angular/cli/BUILD.bazel b/packages/angular/cli/BUILD.bazel index 6cbb09b36c31..5158ce1dc26a 100644 --- a/packages/angular/cli/BUILD.bazel +++ b/packages/angular/cli/BUILD.bazel @@ -15,6 +15,17 @@ package(default_visibility = ["//visibility:public"]) npm_link_all_packages() +genrule( + name = "angular_best_practices", + srcs = [ + "//:node_modules/@angular/core/dir", + ], + outs = ["src/commands/mcp/resources/best-practices.md"], + cmd = """ + cp "$(location //:node_modules/@angular/core/dir)/resources/best-practices.md" $@ + """, +) + RUNTIME_ASSETS = glob( include = [ "bin/**/*", @@ -27,6 +38,7 @@ RUNTIME_ASSETS = glob( ) + [ "//packages/angular/cli:lib/config/schema.json", "//packages/angular/cli:lib/code-examples.db", + ":angular_best_practices", ] ts_project( diff --git a/packages/angular/cli/src/commands/mcp/resources/best-practices.md b/packages/angular/cli/src/commands/mcp/resources/best-practices.md deleted file mode 100644 index e3b246935258..000000000000 --- a/packages/angular/cli/src/commands/mcp/resources/best-practices.md +++ /dev/null @@ -1,47 +0,0 @@ -You are an expert in TypeScript, Angular, and scalable web application development. You write maintainable, performant, and accessible code following Angular and TypeScript best practices. - -## TypeScript Best Practices - -- Use strict type checking -- Prefer type inference when the type is obvious -- Avoid the `any` type; use `unknown` when type is uncertain - -## Angular Best Practices - -- Always use standalone components over NgModules -- Must NOT set `standalone: true` inside Angular decorators. It's the default. -- Use signals for state management -- Implement lazy loading for feature routes -- Do NOT use the `@HostBinding` and `@HostListener` decorators. Put host bindings inside the `host` object of the `@Component` or `@Directive` decorator instead -- Use `NgOptimizedImage` for all static images. - - `NgOptimizedImage` does not work for inline base64 images. - -## Components - -- Keep components small and focused on a single responsibility -- Use `input()` and `output()` functions instead of decorators -- Use `computed()` for derived state -- Set `changeDetection: ChangeDetectionStrategy.OnPush` in `@Component` decorator -- Prefer inline templates for small components -- Prefer Reactive forms instead of Template-driven ones -- Do NOT use `ngClass`, use `class` bindings instead -- DO NOT use `ngStyle`, use `style` bindings instead - -## State Management - -- Use signals for local component state -- Use `computed()` for derived state -- Keep state transformations pure and predictable -- Do NOT use `mutate` on signals, use `update` or `set` instead - -## Templates - -- Keep templates simple and avoid complex logic -- Use native control flow (`@if`, `@for`, `@switch`) instead of `*ngIf`, `*ngFor`, `*ngSwitch` -- Use the async pipe to handle observables - -## Services - -- Design services around a single responsibility -- Use the `providedIn: 'root'` option for singleton services -- Use the `inject()` function instead of constructor injection diff --git a/packages/schematics/angular/BUILD.bazel b/packages/schematics/angular/BUILD.bazel index b3fa1e537720..27e1179fa107 100644 --- a/packages/schematics/angular/BUILD.bazel +++ b/packages/schematics/angular/BUILD.bazel @@ -45,11 +45,24 @@ copy_to_bin( srcs = glob(["**/schema.json"]), ) +genrule( + name = "angular_best_practices", + srcs = [ + "//:node_modules/@angular/core/dir", + ], + outs = ["ai-config/files/__rulesName__.template"], + cmd = """ + echo -e "<% if (frontmatter) { %><%= frontmatter %>\\n<% } %>" > $@ + cat "$(location //:node_modules/@angular/core/dir)/resources/best-practices.md" >> $@ + """, +) + RUNTIME_ASSETS = [ "collection.json", "migrations/migration-collection.json", "package.json", "utility/latest-versions/package.json", + ":angular_best_practices", ] + glob( include = [ "*/schema.json", @@ -115,13 +128,12 @@ ts_project( include = [ "**/*_spec.ts", "utility/test/**/*.ts", - "refactor/jasmine-vitest/test-helpers.ts", ], exclude = [ # NB: we need to exclude the nested node_modules that is laid out by yarn workspaces "node_modules/**", ], - ), + ) + ["refactor/jasmine-vitest/test-helpers.ts"], deps = [ ":angular", ":node_modules/@angular-devkit/core", diff --git a/packages/schematics/angular/ai-config/files/__rulesName__.template b/packages/schematics/angular/ai-config/files/__rulesName__.template deleted file mode 100644 index 0d4f1bbf8d41..000000000000 --- a/packages/schematics/angular/ai-config/files/__rulesName__.template +++ /dev/null @@ -1,49 +0,0 @@ -<% if (frontmatter) { %><%= frontmatter %> - -<% } %>You are an expert in TypeScript, Angular, and scalable web application development. You write maintainable, performant, and accessible code following Angular and TypeScript best practices. - -## TypeScript Best Practices - -- Use strict type checking -- Prefer type inference when the type is obvious -- Avoid the `any` type; use `unknown` when type is uncertain - -## Angular Best Practices - -- Always use standalone components over NgModules -- Must NOT set `standalone: true` inside Angular decorators. It's the default. -- Use signals for state management -- Implement lazy loading for feature routes -- Do NOT use the `@HostBinding` and `@HostListener` decorators. Put host bindings inside the `host` object of the `@Component` or `@Directive` decorator instead -- Use `NgOptimizedImage` for all static images. - - `NgOptimizedImage` does not work for inline base64 images. - -## Components - -- Keep components small and focused on a single responsibility -- Use `input()` and `output()` functions instead of decorators -- Use `computed()` for derived state -- Set `changeDetection: ChangeDetectionStrategy.OnPush` in `@Component` decorator -- Prefer inline templates for small components -- Prefer Reactive forms instead of Template-driven ones -- Do NOT use `ngClass`, use `class` bindings instead -- Do NOT use `ngStyle`, use `style` bindings instead - -## State Management - -- Use signals for local component state -- Use `computed()` for derived state -- Keep state transformations pure and predictable -- Do NOT use `mutate` on signals, use `update` or `set` instead - -## Templates - -- Keep templates simple and avoid complex logic -- Use native control flow (`@if`, `@for`, `@switch`) instead of `*ngIf`, `*ngFor`, `*ngSwitch` -- Use the async pipe to handle observables - -## Services - -- Design services around a single responsibility -- Use the `providedIn: 'root'` option for singleton services -- Use the `inject()` function instead of constructor injection From 75b4a01edbbdf0abdb9cc9140efc3aa0de9f0ab4 Mon Sep 17 00:00:00 2001 From: Alan Agius <17563226+alan-agius4@users.noreply.github.com> Date: Mon, 17 Nov 2025 09:23:50 +0000 Subject: [PATCH 03/54] test: delete e2e directories after tests finish Deletes the e2e directories after tests complete to ensure a clean state for subsequent test runs and to free up disk space. (cherry picked from commit 1ac5b1d37484f334935909af518c9470e06f77f5) --- tests/legacy-cli/e2e/utils/assets.ts | 12 +++++++----- tests/legacy-cli/e2e/utils/project.ts | 5 +++++ tests/legacy-cli/e2e_runner.ts | 15 ++++++++++++--- 3 files changed, 24 insertions(+), 8 deletions(-) diff --git a/tests/legacy-cli/e2e/utils/assets.ts b/tests/legacy-cli/e2e/utils/assets.ts index d421086c1b9e..153fdaccc6de 100644 --- a/tests/legacy-cli/e2e/utils/assets.ts +++ b/tests/legacy-cli/e2e/utils/assets.ts @@ -5,7 +5,7 @@ import { getGlobalVariable } from './env'; import { resolve } from 'node:path'; import { copyFile } from './fs'; import { installWorkspacePackages, setRegistry } from './packages'; -import { useBuiltPackagesVersions } from './project'; +import { getTestProjectDir, useBuiltPackagesVersions } from './project'; export function assetDir(assetName: string) { return join(__dirname, '../e2e/assets', assetName); @@ -21,7 +21,7 @@ export function copyProjectAsset(assetName: string, to?: string) { export function copyAssets(assetName: string, to?: string) { const seed = +Date.now(); - const tempRoot = join(getGlobalVariable('projects-root'), 'assets', assetName + '-' + seed); + const tempRoot = join(getTestAssetsDir(), assetName + '-' + seed); const root = assetDir(assetName); return Promise.resolve() @@ -30,9 +30,7 @@ export function copyAssets(assetName: string, to?: string) { return allFiles.reduce((promise, filePath) => { const toPath = - to !== undefined - ? resolve(getGlobalVariable('projects-root'), 'test-project', to, filePath) - : join(tempRoot, filePath); + to !== undefined ? resolve(getTestProjectDir(), to, filePath) : join(tempRoot, filePath); return promise .then(() => copyFile(join(root, filePath), toPath)) @@ -65,3 +63,7 @@ export async function createProjectFromAsset( return () => setRegistry(true /** useTestRegistry */); } + +export function getTestAssetsDir(): string { + return join(getGlobalVariable('projects-root'), 'assets'); +} diff --git a/tests/legacy-cli/e2e/utils/project.ts b/tests/legacy-cli/e2e/utils/project.ts index c84b7fce8e1d..fe9cfd8a0e04 100644 --- a/tests/legacy-cli/e2e/utils/project.ts +++ b/tests/legacy-cli/e2e/utils/project.ts @@ -7,6 +7,7 @@ import { gitCommit } from './git'; import { findFreePort } from './network'; import { installWorkspacePackages, PkgInfo } from './packages'; import { execAndWaitForOutputToMatch, git, ng } from './process'; +import { join } from 'node:path'; export function updateJsonFile(filePath: string, fn: (json: any) => any | void) { return readFile(filePath).then((tsConfigJson) => { @@ -270,3 +271,7 @@ export function updateServerFileForEsbuild(filepath: string): Promise { `, ); } + +export function getTestProjectDir(): string { + return join(getGlobalVariable('projects-root'), 'test-project'); +} diff --git a/tests/legacy-cli/e2e_runner.ts b/tests/legacy-cli/e2e_runner.ts index 5d7031f20489..86a036c5518a 100644 --- a/tests/legacy-cli/e2e_runner.ts +++ b/tests/legacy-cli/e2e_runner.ts @@ -4,6 +4,7 @@ import colors from 'ansi-colors'; import glob from 'fast-glob'; import * as path from 'node:path'; import * as fs from 'node:fs'; +import { rm } from 'node:fs/promises'; import { getGlobalVariable, setGlobalVariable } from './e2e/utils/env'; import { gitClean } from './e2e/utils/git'; import { createNpmRegistry } from './e2e/utils/registry'; @@ -13,7 +14,7 @@ import { findFreePort } from './e2e/utils/network'; import { extractFile } from './e2e/utils/tar'; import { realpathSync } from 'node:fs'; import { PkgInfo } from './e2e/utils/packages'; -import { rm } from 'node:fs/promises'; +import { getTestProjectDir } from './e2e/utils/project'; Error.stackTraceLimit = Infinity; @@ -271,6 +272,14 @@ Promise.all([findFreePort(), findFreePort(), findPackageTars()]) } finally { registryProcess.kill(); secureRegistryProcess.kill(); + + await rm(getGlobalVariable('projects-root'), { + recursive: true, + force: true, + maxRetries: 3, + }).catch(() => { + // If this fails it is not fatal. + }); } }) .catch((err) => { @@ -334,7 +343,7 @@ function runInitializer(absoluteName: string): Promise { * Run a file from the main 'test-project' directory in a subprocess via launchTestProcess(). */ async function runTest(absoluteName: string): Promise { - process.chdir(join(getGlobalVariable('projects-root'), 'test-project')); + process.chdir(getTestProjectDir()); await launchTestProcess(absoluteName); await cleanTestProject(); @@ -343,7 +352,7 @@ async function runTest(absoluteName: string): Promise { async function cleanTestProject() { await gitClean(); - const testProject = join(getGlobalVariable('projects-root'), 'test-project'); + const testProject = getTestProjectDir(); // Note: Dist directory is not cleared between tests, as `git clean` // doesn't delete it. From 9879fd1ffe52a153cc4f2517ad621de419afdc1c Mon Sep 17 00:00:00 2001 From: Alan Agius <17563226+alan-agius4@users.noreply.github.com> Date: Mon, 17 Nov 2025 09:25:27 +0000 Subject: [PATCH 04/54] Revert "ci: bump specs for e2e-package-managers" This reverts commit 7217478809e80c57e8705eaeea38d2fe32a9f9bd. (cherry picked from commit 93da64e222c18cef74254edfa15fac32ba5ab3bb) --- .github/workflows/ci.yml | 4 +--- .github/workflows/pr.yml | 4 +--- 2 files changed, 2 insertions(+), 6 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index dc04161db2aa..0d12dd68a77c 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -160,9 +160,7 @@ jobs: strategy: fail-fast: false matrix: - # These tests can generate a significant amount of temp files, especially when - # flaky targets are retried. The larger machine type comes with 2x more SSD space. - os: [ubuntu-latest-4core] + os: [ubuntu-latest] node: [22] subset: [yarn, pnpm] shard: [0, 1, 2] diff --git a/.github/workflows/pr.yml b/.github/workflows/pr.yml index 99f850bee44f..3c32bc60bd90 100644 --- a/.github/workflows/pr.yml +++ b/.github/workflows/pr.yml @@ -178,9 +178,7 @@ jobs: strategy: fail-fast: false matrix: - # These tests can generate a significant amount of temp files, especially when - # flaky targets are retried. The larger machine type comes with 2x more SSD space. - os: [ubuntu-latest-4core] + os: [ubuntu-latest] node: [22] subset: [yarn, pnpm] shard: [0, 1, 2] From 016699b579d62639bfa5c1aa431741f99a084a23 Mon Sep 17 00:00:00 2001 From: Alan Agius <17563226+alan-agius4@users.noreply.github.com> Date: Wed, 19 Nov 2025 12:56:27 +0000 Subject: [PATCH 05/54] build: clean up verdaccio storage and share storage Ensures that the Verdaccio registry storage is properly cleaned up at the end of E2E tests by placing it within the main temporary directory which is now explicitly deleted on process exit or SIGINT. This change also centralizes the Verdaccio storage location, allowing both HTTP and HTTPS Verdaccio instances to share the same storage, simplifying test setup and cleanup. Removes redundant temporary directory creation logic for npm sandbox and temporary project roots, as these are now managed by a single `tmp-root`. (cherry picked from commit 8335187e7ec5a6610086ec32d8e7b5a3c377eda0) --- .../e2e/setup/001-create-tmp-dir.ts | 19 --- ...{002-npm-sandbox.ts => 001-npm-sandbox.ts} | 0 tests/legacy-cli/e2e/utils/registry.ts | 21 +-- tests/legacy-cli/e2e_runner.ts | 126 ++++++++++-------- 4 files changed, 80 insertions(+), 86 deletions(-) delete mode 100644 tests/legacy-cli/e2e/setup/001-create-tmp-dir.ts rename tests/legacy-cli/e2e/setup/{002-npm-sandbox.ts => 001-npm-sandbox.ts} (100%) diff --git a/tests/legacy-cli/e2e/setup/001-create-tmp-dir.ts b/tests/legacy-cli/e2e/setup/001-create-tmp-dir.ts deleted file mode 100644 index 4914921eca18..000000000000 --- a/tests/legacy-cli/e2e/setup/001-create-tmp-dir.ts +++ /dev/null @@ -1,19 +0,0 @@ -import { dirname } from 'node:path'; -import { getGlobalVariable, setGlobalVariable } from '../utils/env'; -import { mktempd } from '../utils/utils'; - -export default async function () { - const argv = getGlobalVariable('argv'); - - // Get to a temporary directory. - let tempRoot: string; - if (argv.reuse) { - tempRoot = dirname(argv.reuse); - } else if (argv.tmpdir) { - tempRoot = argv.tmpdir; - } else { - tempRoot = await mktempd('angular-cli-e2e-', process.env.E2E_TEMP); - } - console.log(` Using "${tempRoot}" as temporary directory for a new project.`); - setGlobalVariable('tmp-root', tempRoot); -} diff --git a/tests/legacy-cli/e2e/setup/002-npm-sandbox.ts b/tests/legacy-cli/e2e/setup/001-npm-sandbox.ts similarity index 100% rename from tests/legacy-cli/e2e/setup/002-npm-sandbox.ts rename to tests/legacy-cli/e2e/setup/001-npm-sandbox.ts diff --git a/tests/legacy-cli/e2e/utils/registry.ts b/tests/legacy-cli/e2e/utils/registry.ts index 1bd3084d4f48..b4c1b08afcbc 100644 --- a/tests/legacy-cli/e2e/utils/registry.ts +++ b/tests/legacy-cli/e2e/utils/registry.ts @@ -1,9 +1,10 @@ import { ChildProcess, fork } from 'node:child_process'; import { on } from 'node:events'; +import { mkdir } from 'node:fs/promises'; import { join } from 'node:path'; import { getGlobalVariable } from './env'; import { writeFile, readFile } from './fs'; -import { mktempd } from './utils'; +import { existsSync } from 'node:fs'; export async function createNpmRegistry( port: number, @@ -11,14 +12,18 @@ export async function createNpmRegistry( withAuthentication = false, ): Promise { // Setup local package registry - const registryPath = await mktempd('angular-cli-e2e-registry-'); + const registryPath = join(getGlobalVariable('tmp-root'), 'registry'); + if (!existsSync(registryPath)) { + await mkdir(registryPath); + } + + const configFileName = withAuthentication ? 'verdaccio_auth.yaml' : 'verdaccio.yaml'; + let configContent = await readFile(join(__dirname, '../', configFileName)); + configContent = configContent + .replace(/\$\{HTTP_PORT\}/g, String(port)) + .replace(/\$\{HTTPS_PORT\}/g, String(httpsPort)); + const configPath = join(registryPath, configFileName); - let configContent = await readFile( - join(__dirname, '../', withAuthentication ? 'verdaccio_auth.yaml' : 'verdaccio.yaml'), - ); - configContent = configContent.replace(/\$\{HTTP_PORT\}/g, String(port)); - configContent = configContent.replace(/\$\{HTTPS_PORT\}/g, String(httpsPort)); - const configPath = join(registryPath, 'verdaccio.yaml'); await writeFile(configPath, configContent); const verdaccioServer = fork(require.resolve('verdaccio/bin/verdaccio'), ['-c', configPath]); diff --git a/tests/legacy-cli/e2e_runner.ts b/tests/legacy-cli/e2e_runner.ts index 86a036c5518a..0db1dfb01025 100644 --- a/tests/legacy-cli/e2e_runner.ts +++ b/tests/legacy-cli/e2e_runner.ts @@ -15,6 +15,7 @@ import { extractFile } from './e2e/utils/tar'; import { realpathSync } from 'node:fs'; import { PkgInfo } from './e2e/utils/packages'; import { getTestProjectDir } from './e2e/utils/project'; +import { mktempd } from './e2e/utils/utils'; Error.stackTraceLimit = Infinity; @@ -31,13 +32,9 @@ Error.stackTraceLimit = Infinity; * --ng-snapshots Install angular snapshot builds in the test project. * --glob Run tests matching this glob pattern (relative to tests/e2e/). * --ignore Ignore tests matching this glob pattern. - * --reuse=/path Use a path instead of create a new project. That project should have been - * created, and npm installed. Ideally you want a project created by a previous - * run of e2e. * --nb-shards Total number of shards that this is part of. Default is 2 if --shard is * passed in. * --shard Index of this processes' shard. - * --tmpdir=path Override temporary directory to use for new projects. * --package-manager Package manager to use. * --package=path An npm package to be published before running tests * @@ -58,8 +55,6 @@ const parsed = parseArgs({ 'nosilent': { type: 'boolean' }, 'package': { type: 'string', multiple: true, default: ['./dist/_*.tgz'] }, 'package-manager': { type: 'string', default: 'npm' }, - 'reuse': { type: 'string' }, - 'tmpdir': { type: 'string' }, 'verbose': { type: 'boolean' }, 'nb-shards': { type: 'string' }, @@ -227,65 +222,68 @@ process.env.CHROME_BIN = path.resolve(process.env.CHROME_BIN!); process.env.CHROME_PATH = path.resolve(process.env.CHROME_PATH!); process.env.CHROMEDRIVER_BIN = path.resolve(process.env.CHROMEDRIVER_BIN!); -Promise.all([findFreePort(), findFreePort(), findPackageTars()]) - .then(async ([httpPort, httpsPort, packageTars]) => { - setGlobalVariable('package-registry', 'http://localhost:' + httpPort); - setGlobalVariable('package-secure-registry', 'http://localhost:' + httpsPort); - setGlobalVariable('package-tars', packageTars); - - // NPM registries for the lifetime of the test execution - const registryProcess = await createNpmRegistry(httpPort, httpPort); - const secureRegistryProcess = await createNpmRegistry(httpPort, httpsPort, true); - - try { - await runSteps(runSetup, allSetups, 'setup'); - await runSteps(runInitializer, allInitializers, 'initializer'); - await runSteps(runTest, testsToRun, 'test'); - - if (shardId !== null) { - console.log(colors.green(`Done shard ${shardId} of ${nbShards}.`)); - } else { - console.log(colors.green('Done.')); - } +(async () => { + const tempRoot = await mktempd('angular-cli-e2e-', process.env.E2E_TEMP); + setGlobalVariable('tmp-root', tempRoot); + + process.on('SIGINT', deleteTemporaryRoot); + process.on('exit', deleteTemporaryRoot); + + const [httpPort, httpsPort, packageTars] = await Promise.all([ + findFreePort(), + findFreePort(), + findPackageTars(), + ]); + setGlobalVariable('package-registry', 'http://localhost:' + httpPort); + setGlobalVariable('package-secure-registry', 'http://localhost:' + httpsPort); + setGlobalVariable('package-tars', packageTars); + + // NPM registries for the lifetime of the test execution + const registryProcess = await createNpmRegistry(httpPort, httpPort); + const secureRegistryProcess = await createNpmRegistry(httpPort, httpsPort, true); + + try { + console.log(` Using "${tempRoot}" as temporary directory for a new project.`); + + await runSteps(runSetup, allSetups, 'setup'); + await runSteps(runInitializer, allInitializers, 'initializer'); + await runSteps(runTest, testsToRun, 'test'); + + if (shardId !== null) { + console.log(colors.green(`Done shard ${shardId} of ${nbShards}.`)); + } else { + console.log(colors.green('Done.')); + } - process.exitCode = 0; - } catch (err) { - if (err instanceof Error) { - console.log('\n'); - console.error(colors.red(err.message)); - if (err.stack) { - console.error(colors.red(err.stack)); - } - } else { - console.error(colors.red(String(err))); + process.exitCode = 0; + } catch (err) { + if (err instanceof Error) { + console.log('\n'); + console.error(colors.red(err.message)); + if (err.stack) { + console.error(colors.red(err.stack)); } + } else { + console.error(colors.red(String(err))); + } - if (argv.debug) { - console.log(`Current Directory: ${process.cwd()}`); - console.log('Will loop forever while you debug... CTRL-C to quit.'); - - // Wait forever until user explicitly cancels. - await new Promise(() => {}); - } + if (argv.debug) { + console.log(`Current Directory: ${process.cwd()}`); + console.log('Will loop forever while you debug... CTRL-C to quit.'); - process.exitCode = 1; - } finally { - registryProcess.kill(); - secureRegistryProcess.kill(); - - await rm(getGlobalVariable('projects-root'), { - recursive: true, - force: true, - maxRetries: 3, - }).catch(() => { - // If this fails it is not fatal. - }); + // Wait forever until user explicitly cancels. + await new Promise(() => {}); } - }) - .catch((err) => { - console.error(colors.red(`Unkown Error: ${err}`)); + process.exitCode = 1; - }); + } finally { + registryProcess.kill(); + secureRegistryProcess.kill(); + } +})().catch((err) => { + console.error(colors.red(`Unkown Error: ${err}`)); + process.exitCode = 1; +}); async function runSteps( run: (name: string) => Promise | void, @@ -415,3 +413,13 @@ async function findPackageTars(): Promise<{ [pkg: string]: PkgInfo }> { {} as { [pkg: string]: PkgInfo }, ); } + +function deleteTemporaryRoot(): void { + try { + fs.rmSync(getGlobalVariable('tmp-root'), { + recursive: true, + force: true, + maxRetries: 3, + }); + } catch {} +} From 7fb84f69693d06cff4e98787b8caedc1f0064fa3 Mon Sep 17 00:00:00 2001 From: Aristeidis Bampakos Date: Mon, 17 Nov 2025 14:03:34 +0200 Subject: [PATCH 06/54] refactor(@schematics/angular): use the new X link (cherry picked from commit 08f88eb0a9a2ae087862856e56dd242c86230227) --- .../files/common-files/src/app/app__suffix__.html.template | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/schematics/angular/application/files/common-files/src/app/app__suffix__.html.template b/packages/schematics/angular/application/files/common-files/src/app/app__suffix__.html.template index b706f5bff17e..7d9cf8841c9d 100644 --- a/packages/schematics/angular/application/files/common-files/src/app/app__suffix__.html.template +++ b/packages/schematics/angular/application/files/common-files/src/app/app__suffix__.html.template @@ -286,8 +286,8 @@ @@ -297,7 +297,7 @@ viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg" - alt="Twitter" + alt="X" > Date: Tue, 18 Nov 2025 09:34:39 +0000 Subject: [PATCH 07/54] test: improve vitest e2e test stability and performance - Use Chrome binary from `rules_browsers` for Playwright in Vitest browser tests for hermetic testing and avoids re-downloads of chrome. - Batch `ng generate` commands in e2e tests to improve performance. - Remove now redundant chromium install commands from e2e tests. (cherry picked from commit f72e8da42f243838f6871863a01dd915d151a0e6) --- .../e2e/tests/vitest/browser-no-globals.ts | 4 +- .../e2e/tests/vitest/browser-playwright.ts | 4 +- .../tests/vitest/larger-project-coverage.ts | 69 +++++++++++-------- 3 files changed, 42 insertions(+), 35 deletions(-) diff --git a/tests/legacy-cli/e2e/tests/vitest/browser-no-globals.ts b/tests/legacy-cli/e2e/tests/vitest/browser-no-globals.ts index 21135ff42f83..b25f8168c5f7 100644 --- a/tests/legacy-cli/e2e/tests/vitest/browser-no-globals.ts +++ b/tests/legacy-cli/e2e/tests/vitest/browser-no-globals.ts @@ -1,7 +1,7 @@ import assert from 'node:assert/strict'; import { writeFile } from '../../utils/fs'; import { installPackage } from '../../utils/packages'; -import { exec, ng } from '../../utils/process'; +import { ng } from '../../utils/process'; import { applyVitestBuilder } from '../../utils/vitest'; /** @@ -14,8 +14,6 @@ export default async function (): Promise { await installPackage('playwright@1'); await installPackage('@vitest/browser-playwright@4'); - await exec('npx', 'playwright', 'install', 'chromium', '--only-shell'); - await writeFile( 'src/app/app.spec.ts', ` diff --git a/tests/legacy-cli/e2e/tests/vitest/browser-playwright.ts b/tests/legacy-cli/e2e/tests/vitest/browser-playwright.ts index 9b22b81736e4..fa9ec43aabf3 100644 --- a/tests/legacy-cli/e2e/tests/vitest/browser-playwright.ts +++ b/tests/legacy-cli/e2e/tests/vitest/browser-playwright.ts @@ -1,6 +1,6 @@ import assert from 'node:assert/strict'; import { applyVitestBuilder } from '../../utils/vitest'; -import { exec, ng } from '../../utils/process'; +import { ng } from '../../utils/process'; import { installPackage } from '../../utils/packages'; import { writeFile } from '../../utils/fs'; @@ -8,8 +8,6 @@ export default async function (): Promise { await applyVitestBuilder(); await installPackage('playwright@1'); await installPackage('@vitest/browser-playwright@4'); - await exec('npx', 'playwright', 'install', 'chromium', '--only-shell'); - await ng('generate', 'component', 'my-comp'); await writeFile( diff --git a/tests/legacy-cli/e2e/tests/vitest/larger-project-coverage.ts b/tests/legacy-cli/e2e/tests/vitest/larger-project-coverage.ts index 17e642014d8d..4b5d5cc72bfa 100644 --- a/tests/legacy-cli/e2e/tests/vitest/larger-project-coverage.ts +++ b/tests/legacy-cli/e2e/tests/vitest/larger-project-coverage.ts @@ -2,7 +2,6 @@ import { ng } from '../../utils/process'; import { applyVitestBuilder } from '../../utils/vitest'; import assert from 'node:assert'; import { installPackage } from '../../utils/packages'; -import { exec } from '../../utils/process'; import { updateJsonFile } from '../../utils/project'; import { readFile } from '../../utils/fs'; @@ -27,33 +26,7 @@ export default async function () { const artifactCount = 100; const initialTestCount = 1; - const generatedFiles: string[] = []; - - // Generate a mix of components, services, and pipes - for (let i = 0; i < artifactCount; i++) { - const type = i % 3; - const name = `test-artifact${i}`; - let generateType; - let fileSuffix; - - switch (type) { - case 0: - generateType = 'component'; - fileSuffix = '.ts'; - break; - case 1: - generateType = 'service'; - fileSuffix = '.ts'; - break; - default: - generateType = 'pipe'; - fileSuffix = '-pipe.ts'; - break; - } - - await ng('generate', generateType, name, '--skip-tests=false'); - generatedFiles.push(`${name}${fileSuffix}`); - } + const generatedFiles = await generateArtifactsInBatches(artifactCount); const totalTests = initialTestCount + artifactCount; const expectedMessage = new RegExp(`${totalTests} passed`); @@ -78,7 +51,6 @@ export default async function () { // Setup for browser mode await installPackage('playwright@1'); await installPackage('@vitest/browser-playwright@4'); - await exec('npx', 'playwright', 'install', 'chromium', '--only-shell'); // Run tests in browser mode with coverage const { stdout: browserStdout } = await ng( @@ -102,3 +74,42 @@ export default async function () { assert.ok(found, `Expected ${file} to be in the browser coverage report.`); } } + +async function generateArtifactsInBatches(artifactCount: number): Promise { + const BATCH_SIZE = 5; + const generatedFiles: string[] = []; + let commands: Promise[] = []; + + for (let i = 0; i < artifactCount; i++) { + const type = i % 3; + const name = `test-artifact-${i}`; + + let generateType: string; + let fileSuffix: string; + + switch (type) { + case 0: + generateType = 'component'; + fileSuffix = '.ts'; + break; + case 1: + generateType = 'service'; + fileSuffix = '.ts'; + break; + default: + generateType = 'pipe'; + fileSuffix = '-pipe.ts'; + break; + } + + commands.push(ng('generate', generateType, name, '--skip-tests=false')); + generatedFiles.push(`${name}${fileSuffix}`); + + if (commands.length === BATCH_SIZE || i === artifactCount - 1) { + await Promise.all(commands); + commands = []; + } + } + + return generatedFiles; +} From 8f79e6b9f1a072e8a6dc16abe4404e966c74cd6d Mon Sep 17 00:00:00 2001 From: Alan Agius <17563226+alan-agius4@users.noreply.github.com> Date: Tue, 18 Nov 2025 11:07:53 +0000 Subject: [PATCH 08/54] test: refactor vitest include e2e test Refactored the vitest e2e include test to also include testing relative paths. (cherry picked from commit cb8dea84b6071fa6a6e6a78815e38c59c18e3389) --- .../e2e/tests/vitest/absolute-include.ts | 12 ------------ tests/legacy-cli/e2e/tests/vitest/include.ts | 14 ++++++++++++++ 2 files changed, 14 insertions(+), 12 deletions(-) delete mode 100644 tests/legacy-cli/e2e/tests/vitest/absolute-include.ts create mode 100644 tests/legacy-cli/e2e/tests/vitest/include.ts diff --git a/tests/legacy-cli/e2e/tests/vitest/absolute-include.ts b/tests/legacy-cli/e2e/tests/vitest/absolute-include.ts deleted file mode 100644 index 787fe942edbd..000000000000 --- a/tests/legacy-cli/e2e/tests/vitest/absolute-include.ts +++ /dev/null @@ -1,12 +0,0 @@ -import assert from 'node:assert/strict'; -import { applyVitestBuilder } from '../../utils/vitest'; -import { ng } from '../../utils/process'; -import path from 'node:path'; - -export default async function (): Promise { - await applyVitestBuilder(); - - const { stdout } = await ng('test', '--include', path.resolve('src/app/app.spec.ts')); - - assert.match(stdout, /1 passed/, 'Expected 1 test to pass.'); -} diff --git a/tests/legacy-cli/e2e/tests/vitest/include.ts b/tests/legacy-cli/e2e/tests/vitest/include.ts new file mode 100644 index 000000000000..4585194ef3c2 --- /dev/null +++ b/tests/legacy-cli/e2e/tests/vitest/include.ts @@ -0,0 +1,14 @@ +import assert from 'node:assert/strict'; +import { applyVitestBuilder } from '../../utils/vitest'; +import { ng } from '../../utils/process'; +import path from 'node:path'; + +export default async function (): Promise { + await applyVitestBuilder(); + + const { stdout: stdout1 } = await ng('test', '--include', path.resolve('src/app/app.spec.ts')); + assert.match(stdout1, /1 passed/, 'Expected 1 test to pass with absolute include.'); + + const { stdout: stdout2 } = await ng('test', '--include', path.normalize('src/app/app.spec.ts')); + assert.match(stdout2, /1 passed/, 'Expected 1 test to pass with relative include.'); +} From 59ff867f0d2e7f7f88480deefa0ee470c037197a Mon Sep 17 00:00:00 2001 From: Alan Agius <17563226+alan-agius4@users.noreply.github.com> Date: Tue, 18 Nov 2025 13:22:18 +0000 Subject: [PATCH 09/54] fix(@angular/build): normalize `--include` paths to posix This fixes an issue where relative includes didn't work when using backslashes in windows. Closes #31829 (cherry picked from commit d5b4d0303adf36e2a9c0e6e43e4361d276404272) --- .../build/src/builders/unit-test/test-discovery.ts | 8 ++++---- 1 file changed, 4 insertions(+), 4 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 89d38dbbe787..47bfed884ad3 100644 --- a/packages/angular/build/src/builders/unit-test/test-discovery.ts +++ b/packages/angular/build/src/builders/unit-test/test-discovery.ts @@ -65,7 +65,7 @@ export async function findTests( }); for (const match of globMatches) { - resolvedTestFiles.add(match); + resolvedTestFiles.add(toPosixPath(match)); } } @@ -261,15 +261,15 @@ async function resolveStaticPattern( for (const infix of TEST_FILE_INFIXES) { const potentialSpec = join(dirname(fullPath), `${baseName}${infix}${fileExt}`); if (await exists(potentialSpec)) { - return { resolved: [potentialSpec], unresolved: [] }; + return { resolved: [toPosixPath(potentialSpec)], unresolved: [] }; } } if (await exists(fullPath)) { - return { resolved: [fullPath], unresolved: [] }; + return { resolved: [toPosixPath(fullPath)], unresolved: [] }; } - return { resolved: [], unresolved: [pattern] }; + return { resolved: [], unresolved: [toPosixPath(pattern)] }; } /** Checks if a path exists and is a directory. */ From 1737ce2bbd58d4eb3ca1602ac141cca1df3e4fe0 Mon Sep 17 00:00:00 2001 From: Alan Agius Date: Wed, 19 Nov 2025 23:14:41 +0100 Subject: [PATCH 10/54] ci: add bun package manager to e2e tests This commit introduces support for the `bun` package manager in our end-to-end tests. (cherry picked from commit 76ed17868910d6675dce9b7f68bab6bd3aae7b4f) --- .github/workflows/ci.yml | 2 +- .github/workflows/pr.yml | 2 +- packages/angular/cli/src/commands/add/cli.ts | 4 +- .../cli/src/utilities/package-manager.ts | 8 ++- tests/legacy-cli/e2e/assets/BUILD.bazel | 5 +- .../collection.json | 0 .../index.js | 0 .../package.json | 0 tests/legacy-cli/e2e/setup/100-global-cli.ts | 2 +- .../legacy-cli/e2e/tests/commands/add/base.ts | 2 +- .../legacy-cli/e2e/tests/commands/add/dir.ts | 13 +++- .../legacy-cli/e2e/tests/commands/add/peer.ts | 48 ++++++++++----- .../e2e/tests/commands/add/secure-registry.ts | 59 +++++++++++-------- 13 files changed, 95 insertions(+), 50 deletions(-) rename tests/legacy-cli/e2e/assets/{add-collection => add-collection-dir}/collection.json (100%) rename tests/legacy-cli/e2e/assets/{add-collection => add-collection-dir}/index.js (100%) rename tests/legacy-cli/e2e/assets/{add-collection => add-collection-dir}/package.json (100%) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 0d12dd68a77c..f7e9abdb61e8 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -162,7 +162,7 @@ jobs: matrix: os: [ubuntu-latest] node: [22] - subset: [yarn, pnpm] + subset: [yarn, pnpm, bun] shard: [0, 1, 2] runs-on: ${{ matrix.os }} steps: diff --git a/.github/workflows/pr.yml b/.github/workflows/pr.yml index 3c32bc60bd90..69602b916336 100644 --- a/.github/workflows/pr.yml +++ b/.github/workflows/pr.yml @@ -180,7 +180,7 @@ jobs: matrix: os: [ubuntu-latest] node: [22] - subset: [yarn, pnpm] + subset: [yarn, pnpm, bun] shard: [0, 1, 2] runs-on: ${{ matrix.os }} steps: diff --git a/packages/angular/cli/src/commands/add/cli.ts b/packages/angular/cli/src/commands/add/cli.ts index 1ea2fff699c6..aec0014b9114 100644 --- a/packages/angular/cli/src/commands/add/cli.ts +++ b/packages/angular/cli/src/commands/add/cli.ts @@ -493,7 +493,9 @@ export default class AddCommandModule // Only show if installation will actually occur task.title = 'Installing package'; - if (context.savePackage === false) { + if (context.savePackage === false && packageManager.name !== PackageManager.Bun) { + // Bun has a `--no-save` option which we are using to + // install the package and not update the package.json and the lock file. task.title += ' in temporary location'; // Temporary packages are located in a different directory diff --git a/packages/angular/cli/src/utilities/package-manager.ts b/packages/angular/cli/src/utilities/package-manager.ts index 54b5a21df4de..b913a3bfd72d 100644 --- a/packages/angular/cli/src/utilities/package-manager.ts +++ b/packages/angular/cli/src/utilities/package-manager.ts @@ -61,7 +61,7 @@ export class PackageManagerUtils { /** Install a single package. */ async install( packageName: string, - save: 'dependencies' | 'devDependencies' | true = true, + save: 'dependencies' | 'devDependencies' | boolean = true, extraArgs: string[] = [], cwd?: string, ): Promise { @@ -70,6 +70,8 @@ export class PackageManagerUtils { if (save === 'devDependencies') { installArgs.push(packageManagerArgs.saveDev); + } else if (save === false) { + installArgs.push(packageManagerArgs.noLockfile); } return this.run([...installArgs, ...extraArgs], { cwd, silent: true }); @@ -158,11 +160,11 @@ export class PackageManagerUtils { }; case PackageManager.Bun: return { - saveDev: '--development', + saveDev: '--dev', install: 'add', installAll: 'install', prefix: '--cwd', - noLockfile: '', + noLockfile: '--no-save', }; default: return { diff --git a/tests/legacy-cli/e2e/assets/BUILD.bazel b/tests/legacy-cli/e2e/assets/BUILD.bazel index 946db62d0d5a..11bc738d4a29 100644 --- a/tests/legacy-cli/e2e/assets/BUILD.bazel +++ b/tests/legacy-cli/e2e/assets/BUILD.bazel @@ -2,6 +2,9 @@ load("//tools:defaults.bzl", "copy_to_bin") copy_to_bin( name = "assets", - srcs = glob(["**"]), + srcs = glob( + include = ["**"], + exclude = ["BUILD.bazel"], + ), visibility = ["//visibility:public"], ) diff --git a/tests/legacy-cli/e2e/assets/add-collection/collection.json b/tests/legacy-cli/e2e/assets/add-collection-dir/collection.json similarity index 100% rename from tests/legacy-cli/e2e/assets/add-collection/collection.json rename to tests/legacy-cli/e2e/assets/add-collection-dir/collection.json diff --git a/tests/legacy-cli/e2e/assets/add-collection/index.js b/tests/legacy-cli/e2e/assets/add-collection-dir/index.js similarity index 100% rename from tests/legacy-cli/e2e/assets/add-collection/index.js rename to tests/legacy-cli/e2e/assets/add-collection-dir/index.js diff --git a/tests/legacy-cli/e2e/assets/add-collection/package.json b/tests/legacy-cli/e2e/assets/add-collection-dir/package.json similarity index 100% rename from tests/legacy-cli/e2e/assets/add-collection/package.json rename to tests/legacy-cli/e2e/assets/add-collection-dir/package.json diff --git a/tests/legacy-cli/e2e/setup/100-global-cli.ts b/tests/legacy-cli/e2e/setup/100-global-cli.ts index 780c0bbfaf39..9f587fa5c38d 100644 --- a/tests/legacy-cli/e2e/setup/100-global-cli.ts +++ b/tests/legacy-cli/e2e/setup/100-global-cli.ts @@ -6,7 +6,7 @@ const PACKAGE_MANAGER_VERSION = { 'npm': '10.8.1', 'yarn': '1.22.22', 'pnpm': '10.17.1', - 'bun': '1.2.21', + 'bun': '1.3.2', }; export default async function () { diff --git a/tests/legacy-cli/e2e/tests/commands/add/base.ts b/tests/legacy-cli/e2e/tests/commands/add/base.ts index f4e7048df6ac..d31210c6c242 100644 --- a/tests/legacy-cli/e2e/tests/commands/add/base.ts +++ b/tests/legacy-cli/e2e/tests/commands/add/base.ts @@ -4,7 +4,7 @@ import { ng } from '../../../utils/process'; import { expectToFail } from '../../../utils/utils'; export default async function () { - await symlinkFile(assetDir('add-collection'), `./node_modules/add-collection`, 'dir'); + await symlinkFile(assetDir('add-collection-dir'), `./node_modules/add-collection`, 'dir'); await ng('add', 'add-collection'); await expectFileToExist('empty-file'); diff --git a/tests/legacy-cli/e2e/tests/commands/add/dir.ts b/tests/legacy-cli/e2e/tests/commands/add/dir.ts index f5fadc486b3d..7cb00704cc8e 100644 --- a/tests/legacy-cli/e2e/tests/commands/add/dir.ts +++ b/tests/legacy-cli/e2e/tests/commands/add/dir.ts @@ -1,8 +1,19 @@ +import { cp } from 'node:fs/promises'; +import { resolve } from 'node:path'; import { assetDir } from '../../../utils/assets'; import { expectFileToExist } from '../../../utils/fs'; import { ng } from '../../../utils/process'; export default async function () { - await ng('add', assetDir('add-collection'), '--name=blah', '--skip-confirmation'); + const collectionName = 'add-collection-dir'; + const dirCollectionPath = resolve(collectionName); + + // Copy locally as bun doesn't install the dependency correctly if it has symlinks. + await cp(assetDir(collectionName), dirCollectionPath, { + recursive: true, + dereference: true, + }); + + await ng('add', dirCollectionPath, '--name=blah', '--skip-confirmation'); await expectFileToExist('blah'); } diff --git a/tests/legacy-cli/e2e/tests/commands/add/peer.ts b/tests/legacy-cli/e2e/tests/commands/add/peer.ts index d085efadf080..143542e4533c 100644 --- a/tests/legacy-cli/e2e/tests/commands/add/peer.ts +++ b/tests/legacy-cli/e2e/tests/commands/add/peer.ts @@ -1,24 +1,44 @@ import assert from 'node:assert/strict'; +import { resolve } from 'node:path'; +import { cp } from 'node:fs/promises'; import { assetDir } from '../../../utils/assets'; import { ng } from '../../../utils/process'; -const warning = 'Adding the package may not succeed.'; +export default async function (): Promise { + const warning = /Adding the package may not succeed/; -export default async function () { - const { stdout: bad } = await ng( - 'add', - assetDir('add-collection-peer-bad'), - '--skip-confirmation', + const stdout1 = await runNgAdd('add-collection-peer-bad'); + assert.match( + stdout1, + warning, + `Peer warning should be shown for add-collection-peer-bad but was not.`, ); - assert.match(bad, new RegExp(warning), 'peer warning not shown on bad package'); - const { stdout: base } = await ng('add', assetDir('add-collection'), '--skip-confirmation'); - assert.doesNotMatch(base, new RegExp(warning), 'peer warning shown on base package'); + const stdout2 = await runNgAdd('add-collection-dir'); + assert.doesNotMatch( + stdout2, + warning, + `Peer warning should NOT be shown for add-collection-dir but was.`, + ); - const { stdout: good } = await ng( - 'add', - assetDir('add-collection-peer-good'), - '--skip-confirmation', + const stdout3 = await runNgAdd('add-collection-peer-good'); + assert.doesNotMatch( + stdout3, + warning, + `Peer warning should NOT be shown for add-collection-peer-good but was.`, ); - assert.doesNotMatch(good, new RegExp(warning), 'peer warning shown on good package'); +} + +async function runNgAdd(collectionName: string): Promise { + const collectionPath = resolve(collectionName); + + // Copy locally as bun doesn't install the dependency correctly if it has symlinks. + await cp(assetDir(collectionName), collectionPath, { + recursive: true, + dereference: true, + }); + + const { stdout } = await ng('add', collectionPath, '--skip-confirmation'); + + return stdout; } diff --git a/tests/legacy-cli/e2e/tests/commands/add/secure-registry.ts b/tests/legacy-cli/e2e/tests/commands/add/secure-registry.ts index a27ba708637d..95218fd653d9 100644 --- a/tests/legacy-cli/e2e/tests/commands/add/secure-registry.ts +++ b/tests/legacy-cli/e2e/tests/commands/add/secure-registry.ts @@ -1,42 +1,49 @@ -import { expectFileNotToExist, expectFileToExist } from '../../../utils/fs'; +import { expectFileNotToExist, expectFileToExist, rimraf } from '../../../utils/fs'; import { getActivePackageManager, installWorkspacePackages } from '../../../utils/packages'; import { git, ng } from '../../../utils/process'; import { createNpmConfigForAuthentication } from '../../../utils/registry'; import { expectToFail } from '../../../utils/utils'; export default async function () { - // The environment variable has priority over the .npmrc - delete process.env['NPM_CONFIG_REGISTRY']; - const isNpm = getActivePackageManager() === 'npm'; + const originalNpmConfigRegistry = process.env['NPM_CONFIG_REGISTRY']; + try { + // The environment variable has priority over the .npmrc + delete process.env['NPM_CONFIG_REGISTRY']; + const packageManager = getActivePackageManager(); + const supportsUnscopedAuth = packageManager !== 'bun' && packageManager !== 'npm'; + const command = ['add', '@angular/pwa', '--skip-confirmation']; - const command = ['add', '@angular/pwa', '--skip-confirmation']; - await expectFileNotToExist('public/manifest.webmanifest'); + await expectFileNotToExist('public/manifest.webmanifest'); - // Works with unscoped registry authentication details - if (!isNpm) { - // NPM no longer support unscoped. - await createNpmConfigForAuthentication(false); + // Works with unscoped registry authentication details + if (supportsUnscopedAuth) { + // Some package managers such as Bun and NPM do not support unscoped auth. + await createNpmConfigForAuthentication(false); + await ng(...command); + await expectFileToExist('public/manifest.webmanifest'); + await git('clean', '-dxf'); + } + + // Works with scoped registry authentication details + await expectFileNotToExist('public/manifest.webmanifest'); + + await createNpmConfigForAuthentication(true); await ng(...command); await expectFileToExist('public/manifest.webmanifest'); await git('clean', '-dxf'); - } - // Works with scoped registry authentication details - await expectFileNotToExist('public/manifest.webmanifest'); - await createNpmConfigForAuthentication(true); - await ng(...command); - await expectFileToExist('public/manifest.webmanifest'); + // Invalid authentication token + if (!supportsUnscopedAuth) { + // Some package managers such as Bun and NPM do not support unscoped auth. + await createNpmConfigForAuthentication(false, true); + await expectToFail(() => ng(...command)); + } - // Invalid authentication token - if (isNpm) { - // NPM no longer support unscoped. - await createNpmConfigForAuthentication(false, true); + await createNpmConfigForAuthentication(true, true); await expectToFail(() => ng(...command)); + } finally { + process.env['NPM_CONFIG_REGISTRY'] = originalNpmConfigRegistry; + await git('clean', '-dxf'); + await installWorkspacePackages(); } - - await createNpmConfigForAuthentication(true, true); - await expectToFail(() => ng(...command)); - - await git('clean', '-dxf'); - await installWorkspacePackages(); } From decb3bd97ea4f3f58c4120e1f3502a13dbbd5cb2 Mon Sep 17 00:00:00 2001 From: Charles Lyding <19598772+clydin@users.noreply.github.com> Date: Tue, 18 Nov 2025 10:20:15 -0500 Subject: [PATCH 11/54] refactor(@angular/build): optimize Vitest in-memory plugin resolveId Refactors the `resolveId` hook in the `angular:test-in-memory-provider` Vite plugin to improve clarity, efficiency, and cross-platform consistency. Key improvements include: - Consolidating path resolution logic into a single flow. - Ensuring all resolved paths are absolute and consistently POSIX-formatted. - Prioritizing direct test entry point lookups. - Removing redundant checks and assertions. (cherry picked from commit dd99abc24c8e7ddb0ace0f96ebb2c48398cd0f5e) --- .../unit-test/runners/vitest/plugins.ts | 38 ++++++++++--------- 1 file changed, 21 insertions(+), 17 deletions(-) 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 96d3337e0149..05a9f8470253 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 @@ -171,29 +171,33 @@ export function createVitestPlugins(pluginOptions: PluginOptions): VitestPlugins name: 'angular:test-in-memory-provider', enforce: 'pre', resolveId: (id, importer) => { - if (importer && (id[0] === '.' || id[0] === '/')) { - let fullPath; - if (testFileToEntryPoint.has(importer)) { - fullPath = toPosixPath(path.join(workspaceRoot, id)); - } else { - fullPath = toPosixPath(path.join(path.dirname(importer), id)); - } - - const relativePath = path.relative(workspaceRoot, fullPath); - if (buildResultFiles.has(toPosixPath(relativePath))) { - return fullPath; - } - } - + // Fast path for test entry points. if (testFileToEntryPoint.has(id)) { return id; } - assert(buildResultFiles.size > 0, 'buildResult must be available for resolving.'); - const relativePath = path.relative(workspaceRoot, id); + // Determine the base directory for resolution. + let baseDir: string; + if (importer) { + // If the importer is a test entry point, resolve relative to the workspace root. + // Otherwise, resolve relative to the importer's directory. + baseDir = testFileToEntryPoint.has(importer) ? workspaceRoot : path.dirname(importer); + } else { + // If there's no importer, assume the id is relative to the workspace root. + baseDir = workspaceRoot; + } + + // Construct the full, absolute path and normalize it to POSIX format. + const fullPath = toPosixPath(path.join(baseDir, id)); + + // Check if the resolved path corresponds to a known build artifact. + const relativePath = path.relative(workspaceRoot, fullPath); if (buildResultFiles.has(toPosixPath(relativePath))) { - return id; + return fullPath; } + + // If the module cannot be resolved from the build artifacts, let other plugins handle it. + return undefined; }, load: async (id) => { assert(buildResultFiles.size > 0, 'buildResult must be available for in-memory loading.'); From 7491c3dfca7256638c114647daad9c4c64f4db3d Mon Sep 17 00:00:00 2001 From: Charles Lyding <19598772+clydin@users.noreply.github.com> Date: Tue, 18 Nov 2025 11:35:34 -0500 Subject: [PATCH 12/54] refactor(@angular/build): optimize vitest in-memory file loading This commit optimizes the 'angular:test-in-memory-provider' Vitest plugin by introducing a 'loadResultFile' helper. This helper utilizes 'TextDecoder' to decode memory files, avoiding unnecessary buffer copies associated with 'Buffer.from().toString()'. It also removes duplicate file reading logic for source maps. (cherry picked from commit 09e5e32aab832fd29a738051a804f352ab64ce00) --- .../unit-test/runners/vitest/plugins.ts | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) 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 05a9f8470253..d614d16f97b8 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 @@ -163,6 +163,14 @@ export async function createVitestConfigPlugin( }; } +async function loadResultFile(file: ResultFile): Promise { + if (file.origin === 'memory') { + return new TextDecoder('utf-8').decode(file.contents); + } + + return readFile(file.inputPath, 'utf-8'); +} + export function createVitestPlugins(pluginOptions: PluginOptions): VitestPlugins { const { workspaceRoot, buildResultFiles, testFileToEntryPoint } = pluginOptions; @@ -221,17 +229,10 @@ export function createVitestPlugins(pluginOptions: PluginOptions): VitestPlugins const outputFile = buildResultFiles.get(outputPath); if (outputFile) { + const code = await loadResultFile(outputFile); const sourceMapPath = outputPath + '.map'; const sourceMapFile = buildResultFiles.get(sourceMapPath); - const code = - outputFile.origin === 'memory' - ? Buffer.from(outputFile.contents).toString('utf-8') - : await readFile(outputFile.inputPath, 'utf-8'); - const sourceMapText = sourceMapFile - ? sourceMapFile.origin === 'memory' - ? Buffer.from(sourceMapFile.contents).toString('utf-8') - : await readFile(sourceMapFile.inputPath, 'utf-8') - : undefined; + const sourceMapText = sourceMapFile ? await loadResultFile(sourceMapFile) : undefined; // Vitest will include files in the coverage report if the sourcemap contains no sources. // For builder-internal generated code chunks, which are typically helper functions, From 363496ae0d2850545274cd7fe4dc6902ccb64e10 Mon Sep 17 00:00:00 2001 From: Charles Lyding <19598772+clydin@users.noreply.github.com> Date: Tue, 18 Nov 2025 14:11:25 -0500 Subject: [PATCH 13/54] fix(@angular/cli): ensure dependencies are resolved correctly for node modules directory check This commit updates the check for installed node packages in the Architect base command module. Instead of relying on the presence of a 'node_modules' directory or checking for Yarn PnP specifically, it now attempts to resolve '@angular/core' using 'createRequire'. This provides a more robust and agnostic way to verify if dependencies are installed, supporting various package managers and installation strategies. (cherry picked from commit 6009030b855e9061be81efc695f73697030c57b8) --- .../architect-base-command-module.ts | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) diff --git a/packages/angular/cli/src/command-builder/architect-base-command-module.ts b/packages/angular/cli/src/command-builder/architect-base-command-module.ts index 566e0e62b209..fb3508777d74 100644 --- a/packages/angular/cli/src/command-builder/architect-base-command-module.ts +++ b/packages/angular/cli/src/command-builder/architect-base-command-module.ts @@ -12,8 +12,7 @@ import { WorkspaceNodeModulesArchitectHost, } from '@angular-devkit/architect/node'; import { json } from '@angular-devkit/core'; -import { existsSync } from 'node:fs'; -import { resolve } from 'node:path'; +import { createRequire } from 'node:module'; import { isPackageNameSafeForAnalytics } from '../analytics/analytics'; import { EventCustomDimension, EventCustomMetric } from '../analytics/analytics-parameters'; import { assertIsError } from '../utilities/error'; @@ -210,15 +209,13 @@ export abstract class ArchitectBaseCommandModule return; } - // Check if yarn PnP is used. https://yarnpkg.com/advanced/pnpapi#processversionspnp - if (process.versions.pnp) { - return; - } + const workspaceResolve = createRequire(basePath + '/').resolve; + + try { + workspaceResolve('@angular/core'); - // Check for a `node_modules` directory (npm, yarn non-PnP, etc.) - if (existsSync(resolve(basePath, 'node_modules'))) { return; - } + } catch {} this.context.logger.warn( `Node packages may not be installed. Try installing with '${this.context.packageManager.name} install'.`, From 244931ece877a1cacd1cfce64314e04a52526f80 Mon Sep 17 00:00:00 2001 From: Alan Agius <17563226+alan-agius4@users.noreply.github.com> Date: Wed, 19 Nov 2025 07:39:07 +0000 Subject: [PATCH 14/54] fix(@angular/build): correctly invoke `isTTY` as a function Addresses an issue where 'isTTY' was incorrectly treated as a property instead of being called as a function, ensuring proper terminal detection. (cherry picked from commit 38743d922a0ef317bb2bb6465fdf5d259c99c563) --- packages/angular/build/src/utils/check-port.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/angular/build/src/utils/check-port.ts b/packages/angular/build/src/utils/check-port.ts index 58e5a0a0f854..d7c04f0b9f72 100644 --- a/packages/angular/build/src/utils/check-port.ts +++ b/packages/angular/build/src/utils/check-port.ts @@ -32,7 +32,7 @@ export async function checkPort(port: number, host: string): Promise { return; } - if (!isTTY) { + if (!isTTY()) { reject(createInUseError(port)); return; From 99785a7f27c58e52fa2aa45e12ffb34a2e6daedc Mon Sep 17 00:00:00 2001 From: Alan Agius <17563226+alan-agius4@users.noreply.github.com> Date: Wed, 19 Nov 2025 13:51:00 +0000 Subject: [PATCH 15/54] build: remove `build-schema` script This commit migrates the schema generation process to utilize Bazel's tagging system instead of a custom build script. - The `scripts/build-schema.mts` script has been removed. - A new `build-schema` script has been added to `package.json` that executes `bazel build` for targets tagged with "schema". - The CI/PR workflows (`.github/workflows/ci.yml` and `pr.yml`) have been updated to use this new `pnpm run build-schema` command. - The `ng_cli_schema_generator.bzl` and `ts_json_schema.bzl` rules have been updated to include the "schema" tag, allowing them to be picked up by the new build process. (cherry picked from commit dfe021ba6b9a951fe649c1eb2d2a1957c3f82ee9) --- .github/workflows/ci.yml | 2 +- .github/workflows/pr.yml | 2 +- package.json | 1 + scripts/build-schema.mts | 72 ------------------------------- tools/ng_cli_schema_generator.bzl | 1 + tools/ts_json_schema.bzl | 1 + 6 files changed, 5 insertions(+), 74 deletions(-) delete mode 100644 scripts/build-schema.mts diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index f7e9abdb61e8..53ddd5e6d58a 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -28,7 +28,7 @@ jobs: run: pnpm install --frozen-lockfile - name: Generate JSON schema types # Schema types are required to correctly lint the TypeScript code - run: pnpm admin build-schema + run: pnpm run build-schema - name: Run ESLint run: pnpm lint --cache-strategy content - name: Validate NgBot Configuration diff --git a/.github/workflows/pr.yml b/.github/workflows/pr.yml index 69602b916336..b8041e68206b 100644 --- a/.github/workflows/pr.yml +++ b/.github/workflows/pr.yml @@ -46,7 +46,7 @@ jobs: run: pnpm install --frozen-lockfile - name: Generate JSON schema types # Schema types are required to correctly lint the TypeScript code - run: pnpm admin build-schema + run: pnpm run build-schema - name: Run ESLint run: pnpm lint --cache-strategy content - name: Validate NgBot Configuration diff --git a/package.json b/package.json index 365c85df4731..2017743da80e 100644 --- a/package.json +++ b/package.json @@ -15,6 +15,7 @@ "bazel": "bazelisk", "test": "bazel test //packages/...", "build": "pnpm -s admin build", + "build-schema": "bazel build //... --build_tag_filters schema --symlink_prefix dist-schema/", "lint": "eslint --cache --max-warnings=0 \"**/*.@(ts|mts|cts)\"", "templates": "pnpm -s admin templates", "validate": "pnpm -s admin validate", diff --git a/scripts/build-schema.mts b/scripts/build-schema.mts deleted file mode 100644 index ffc042af9630..000000000000 --- a/scripts/build-schema.mts +++ /dev/null @@ -1,72 +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 { spawn } from 'node:child_process'; -import { rm } from 'node:fs/promises'; -import { join, resolve } from 'node:path'; - -const __dirname = import.meta.dirname; -const baseDir = resolve(`${__dirname}/..`); -const bazelCmd = process.env.BAZEL ?? `pnpm -s bazel`; -const distRoot = join(baseDir, '/dist-schema/'); - -function _clean() { - console.info('Cleaning...'); - console.info(' Removing dist-schema/...'); - - return rm(join(__dirname, '../dist-schema'), { force: true, recursive: true, maxRetries: 3 }); -} - -function _exec(cmd: string, captureStdout: boolean): Promise { - return new Promise((resolve, reject) => { - const proc = spawn(cmd, { - stdio: 'pipe', - shell: true, - env: { - HOME: process.env.HOME, - PATH: process.env.PATH, - }, - }); - - let output = ''; - proc.stdout.on('data', (data) => { - console.info(data.toString().trim()); - if (captureStdout) { - output += data.toString(); - } - }); - proc.stderr.on('data', (data) => console.info(data.toString().trim())); - - proc.on('error', (error) => { - console.error(error.message); - }); - - proc.on('exit', (status) => { - if (status !== 0) { - reject(`Command failed: ${cmd}`); - } else { - resolve(output); - } - }); - }); -} - -async function _buildSchemas(): Promise { - console.info(`Building schemas...`); - - const queryTargetsCmd = `${bazelCmd} query --output=label "attr(name, .*_schema, //packages/...)"`; - const targets = (await _exec(queryTargetsCmd, true)).split(/\r?\n/); - - await _exec(`${bazelCmd} build ${targets.join(' ')} --symlink_prefix=${distRoot}`, false); -} - -export default async function (argv: {}): Promise { - await _clean(); - - await _buildSchemas(); -} diff --git a/tools/ng_cli_schema_generator.bzl b/tools/ng_cli_schema_generator.bzl index 9bcc4d287a6a..86d9552dd70c 100644 --- a/tools/ng_cli_schema_generator.bzl +++ b/tools/ng_cli_schema_generator.bzl @@ -4,6 +4,7 @@ def cli_json_schema(name, src, out, data = []): js_run_binary( name = name, outs = [out], + tags = ["schema"], srcs = [src] + data, tool = "//tools:ng_cli_schema", progress_message = "Generating CLI interface from %s" % src, diff --git a/tools/ts_json_schema.bzl b/tools/ts_json_schema.bzl index deb34c0af597..dab651d0d7e0 100644 --- a/tools/ts_json_schema.bzl +++ b/tools/ts_json_schema.bzl @@ -12,6 +12,7 @@ def ts_json_schema(name, src, data = []): name = name + ".interface", outs = [out], srcs = [src] + data, + tags = ["schema"], tool = "//tools:quicktype_runner", progress_message = "Generating TS interface for %s" % src, mnemonic = "TsJsonSchema", From 750709d9457788000ee8ec58569e2423087dddd4 Mon Sep 17 00:00:00 2001 From: cexbrayat Date: Wed, 19 Nov 2025 14:58:34 +0100 Subject: [PATCH 16/54] refactor(@angular/cli): consistent casing for onpush zoneless migration MCP tool name All other tools use `_` in their names. (cherry picked from commit 60e04abda999c218e7bf79de08fcadae3f1c59d8) --- .../mcp/tools/onpush-zoneless-migration/zoneless-migration.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/angular/cli/src/commands/mcp/tools/onpush-zoneless-migration/zoneless-migration.ts b/packages/angular/cli/src/commands/mcp/tools/onpush-zoneless-migration/zoneless-migration.ts index eaca30e274d9..3e6fedd5abd7 100644 --- a/packages/angular/cli/src/commands/mcp/tools/onpush-zoneless-migration/zoneless-migration.ts +++ b/packages/angular/cli/src/commands/mcp/tools/onpush-zoneless-migration/zoneless-migration.ts @@ -21,7 +21,7 @@ import { sendDebugMessage } from './send_debug_message'; import { createSourceFile, getImportSpecifier } from './ts_utils'; export const ZONELESS_MIGRATION_TOOL = declareTool({ - name: 'onpush-zoneless-migration', + name: 'onpush_zoneless_migration', title: 'Plan migration to OnPush and/or zoneless', description: ` From c8bab428d767daea90d6a7f7dc01547fe8871348 Mon Sep 17 00:00:00 2001 From: Doug Parker Date: Wed, 19 Nov 2025 10:49:53 -0800 Subject: [PATCH 17/54] docs: update release docs to cover bumping dev dependencies, which is required to get CI to pass (cherry picked from commit 99820914f4efbefd26b9bec6233289e5afcc7a94) --- docs/process/release.md | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/docs/process/release.md b/docs/process/release.md index 1e060ac2169b..5490e48e8279 100644 --- a/docs/process/release.md +++ b/docs/process/release.md @@ -69,10 +69,15 @@ Releasing is performed using Angular's unified release tooling. Each week, two r Once FW releases the actual minor/major release (for example: `13.0.0` or `13.1.0`), update dependencies with the following: -1. Update [`constants.bzl`](../../constants.bzl) so `@angular/core` and `ng-packagr` are using the release version (drop `-next.0`). - -Merge the above change in a separate PR which lands _after_ FW releases (or else CI will fail) but _before_ the CLI -release PR. Releases are built before the PR is sent for review, so any changes after that point won't be included in the release. +1. Update [`constants.bzl`](../../constants.bzl) so `@angular/core` and `ng-packagr` are using the release version (drop `-rc.*`). +2. Update all `package.json` dependencies on framework packages to to the release version (drop `-rc.*`). + - Components packages release _after_ CLI, so those should be left as `-rc.*`. +3. `pnpm install` to update the `pnpm-lock.yaml` file. + +Create a PR with the above changes ([example](https://github.com/angular/angular-cli/pull/31872)) and merge it directly to the RC +branch. This PR must land _after_ FW releases (or else CI will fail) but _before_ the CLI release PR. Releases are built before +the PR is sent for review, so any changes after that point won't be included in the release and this cannot be combined with the +release PR. **AFTER a minor OR major CLI release:** From 1fe1e81a8c1193c6e0b8d2e2769a7d1872b99fe1 Mon Sep 17 00:00:00 2001 From: Angular Robot Date: Wed, 19 Nov 2025 08:42:05 +0000 Subject: [PATCH 18/54] build: update bazel dependencies See associated pull request for more information. --- MODULE.bazel | 6 ++--- MODULE.bazel.lock | 62 ++++++++++++++++++++++++----------------------- 2 files changed, 35 insertions(+), 33 deletions(-) diff --git a/MODULE.bazel b/MODULE.bazel index a82a4e90c6f0..1b488d92160b 100644 --- a/MODULE.bazel +++ b/MODULE.bazel @@ -4,8 +4,8 @@ module( name = "angular_cli", ) -bazel_dep(name = "yq.bzl", version = "0.3.1") -bazel_dep(name = "rules_nodejs", version = "6.6.1") +bazel_dep(name = "yq.bzl", version = "0.3.2") +bazel_dep(name = "rules_nodejs", version = "6.6.2") bazel_dep(name = "aspect_rules_js", version = "2.8.1") bazel_dep(name = "aspect_rules_ts", version = "3.7.1") bazel_dep(name = "rules_pkg", version = "0.8.1") @@ -47,7 +47,7 @@ git_override( bazel_dep(name = "rules_browsers") git_override( module_name = "rules_browsers", - commit = "6a699bf3e896690e2923cf3ade29fbd4e492e366", + commit = "f066f614451374721fac787fb1f0dbbd818d50d4", remote = "https://github.com/devversion/rules_browsers.git", ) diff --git a/MODULE.bazel.lock b/MODULE.bazel.lock index 4dc7a24f2c2f..7626ecc5e633 100644 --- a/MODULE.bazel.lock +++ b/MODULE.bazel.lock @@ -157,7 +157,8 @@ "https://bcr.bazel.build/modules/rules_nodejs/6.5.0/MODULE.bazel": "546d0cf79f36f9f6e080816045f97234b071c205f4542e3351bd4424282a8810", "https://bcr.bazel.build/modules/rules_nodejs/6.5.2/MODULE.bazel": "7f9ea68a0ce6d82905ce9f74e76ab8a8b4531ed4c747018c9d76424ad0b3370d", "https://bcr.bazel.build/modules/rules_nodejs/6.6.1/MODULE.bazel": "e499aabe7cb796b784e9421be909c702eb79f664c20d21cbf120332a2a8dc378", - "https://bcr.bazel.build/modules/rules_nodejs/6.6.1/source.json": "c5eb6ed233d9ddadad77342e4aeefb836a4616f875acf2dbb181f98057c8c020", + "https://bcr.bazel.build/modules/rules_nodejs/6.6.2/MODULE.bazel": "9fdb5e1d50246a25761f150fcc820dc47e4052330a8408451e628804f9ca64a6", + "https://bcr.bazel.build/modules/rules_nodejs/6.6.2/source.json": "6e8c1ecc64ff8da147c1620f862ad77d7b19c5d1b52b3aa5e847d5b3d0de4cc3", "https://bcr.bazel.build/modules/rules_pkg/0.7.0/MODULE.bazel": "df99f03fc7934a4737122518bb87e667e62d780b610910f0447665a7e2be62dc", "https://bcr.bazel.build/modules/rules_pkg/0.8.1/MODULE.bazel": "7e9e7b5b26bd7ff012dfe63930db2f0176ddcd25e44a858fc72d63e995b6aab9", "https://bcr.bazel.build/modules/rules_pkg/0.8.1/source.json": "15dd7e13dc303f7fcde2b55300bcb8de5c0dd08a7a7269749cbbaa0fb1dfbe16", @@ -199,7 +200,8 @@ "https://bcr.bazel.build/modules/yq.bzl/0.1.1/MODULE.bazel": "9039681f9bcb8958ee2c87ffc74bdafba9f4369096a2b5634b88abc0eaefa072", "https://bcr.bazel.build/modules/yq.bzl/0.2.0/MODULE.bazel": "6f3a675677db8885be4d607fde14cc51829715e3a879fb016eb9bf336786ce6d", "https://bcr.bazel.build/modules/yq.bzl/0.3.1/MODULE.bazel": "9bcb7151b3cd4681b89d350530eaf7b45e32a44dda94843b8932b0cb1cd4594a", - "https://bcr.bazel.build/modules/yq.bzl/0.3.1/source.json": "f0b0f204a2a6b0e34b4c9541efe8c04f2ef1af65948daa784eccea738b21dbd2", + "https://bcr.bazel.build/modules/yq.bzl/0.3.2/MODULE.bazel": "0384efa70e8033d842ea73aa4b7199fa099709e236a7264345c03937166670b6", + "https://bcr.bazel.build/modules/yq.bzl/0.3.2/source.json": "c4ec3e192477e154f08769e29d69e8fd36e8a4f0f623997f3e1f6f7d328f7d7d", "https://bcr.bazel.build/modules/zlib/1.2.11/MODULE.bazel": "07b389abc85fdbca459b69e2ec656ae5622873af3f845e1c9d80fe179f3effa0", "https://bcr.bazel.build/modules/zlib/1.2.12/MODULE.bazel": "3b1a8834ada2a883674be8cbd36ede1b6ec481477ada359cd2d3ddc562340b27", "https://bcr.bazel.build/modules/zlib/1.3.1.bcr.3/MODULE.bazel": "af322bc08976524477c79d1e45e241b6efbeb918c497e8840b8ab116802dda79", @@ -732,7 +734,7 @@ }, "@@rules_browsers~//browsers:extensions.bzl%browsers": { "general": { - "bzlTransitiveDigest": "6QMCx97Hwh2hyQPqZEA9AKAxbpygF41+K8xJfeqJYm8=", + "bzlTransitiveDigest": "ljZlVgWkQJnI6EvlHVfYit2EttUE52gDTbvmota5YO8=", "usagesDigest": "1PlExi+b77pSr2tAxFCVbpCtFoA7oixHabaL3dmas4Y=", "recordedFileInputs": {}, "recordedDirentsInputs": {}, @@ -742,9 +744,9 @@ "bzlFile": "@@rules_browsers~//browsers/private:browser_repo.bzl", "ruleClassName": "browser_repo", "attributes": { - "sha256": "4bc6d611d55dc96b213c8605cb8ac27d3c21973bf8b663df4cbf756c989e6745", + "sha256": "1419fa328bd7ea2697f26412ec693867516e4ef23c32eb13143a0b0b179b604b", "urls": [ - "https://storage.googleapis.com/chrome-for-testing-public/143.0.7482.0/linux64/chrome-headless-shell-linux64.zip" + "https://storage.googleapis.com/chrome-for-testing-public/144.0.7531.0/linux64/chrome-headless-shell-linux64.zip" ], "named_files": { "CHROME-HEADLESS-SHELL": "chrome-headless-shell-linux64/chrome-headless-shell" @@ -761,9 +763,9 @@ "bzlFile": "@@rules_browsers~//browsers/private:browser_repo.bzl", "ruleClassName": "browser_repo", "attributes": { - "sha256": "830cc2aafedbe7c9fe671c9898046f8900c06da89d12653ddc3ef26084d2f516", + "sha256": "792cbf9b77219b4476e41c49647bcd15e55f0988002fa1e4e6a720eb430c7eda", "urls": [ - "https://storage.googleapis.com/chrome-for-testing-public/143.0.7482.0/mac-x64/chrome-headless-shell-mac-x64.zip" + "https://storage.googleapis.com/chrome-for-testing-public/144.0.7531.0/mac-x64/chrome-headless-shell-mac-x64.zip" ], "named_files": { "CHROME-HEADLESS-SHELL": "chrome-headless-shell-mac-x64/chrome-headless-shell" @@ -780,9 +782,9 @@ "bzlFile": "@@rules_browsers~//browsers/private:browser_repo.bzl", "ruleClassName": "browser_repo", "attributes": { - "sha256": "5b5792f5c2d05c3f1f782346910869b61a37b9003f212315b19f4e46710cf8b9", + "sha256": "f0c1917769775e826dfa69936381d0d95b06fe67cf631ecd842380d5de0e4c7f", "urls": [ - "https://storage.googleapis.com/chrome-for-testing-public/143.0.7482.0/mac-arm64/chrome-headless-shell-mac-arm64.zip" + "https://storage.googleapis.com/chrome-for-testing-public/144.0.7531.0/mac-arm64/chrome-headless-shell-mac-arm64.zip" ], "named_files": { "CHROME-HEADLESS-SHELL": "chrome-headless-shell-mac-arm64/chrome-headless-shell" @@ -799,9 +801,9 @@ "bzlFile": "@@rules_browsers~//browsers/private:browser_repo.bzl", "ruleClassName": "browser_repo", "attributes": { - "sha256": "19bdbf6e1579b6c056b74709520ac9df573f4e80e4f026cc2360a29443cf6c0c", + "sha256": "6ce0f20dd743a804890f45f5349370e1aa7cd3ac3482c04686fcff5fafd01bb3", "urls": [ - "https://storage.googleapis.com/chrome-for-testing-public/143.0.7482.0/win64/chrome-headless-shell-win64.zip" + "https://storage.googleapis.com/chrome-for-testing-public/144.0.7531.0/win64/chrome-headless-shell-win64.zip" ], "named_files": { "CHROME-HEADLESS-SHELL": "chrome-headless-shell-win64/chrome-headless-shell.exe" @@ -818,9 +820,9 @@ "bzlFile": "@@rules_browsers~//browsers/private:browser_repo.bzl", "ruleClassName": "browser_repo", "attributes": { - "sha256": "ea41e7a217d878c00e9d66a0724ff54be7d02d08adb7f6458b7d8487b6fbcd84", + "sha256": "baf4bf9d22881265487732f17d35a49e9aadd0837aa5c1c1eea520c8aa24a97f", "urls": [ - "https://storage.googleapis.com/chrome-for-testing-public/143.0.7482.0/linux64/chromedriver-linux64.zip" + "https://storage.googleapis.com/chrome-for-testing-public/144.0.7531.0/linux64/chromedriver-linux64.zip" ], "named_files": { "CHROMEDRIVER": "chromedriver-linux64/chromedriver" @@ -835,9 +837,9 @@ "bzlFile": "@@rules_browsers~//browsers/private:browser_repo.bzl", "ruleClassName": "browser_repo", "attributes": { - "sha256": "aede9b67301b930ff9c673df28429aa82ce05c105a4ccbef7e0cd30a97ae429d", + "sha256": "87560768d5aa203b37c0a1b8459a35b05e4ece54afee2df530f3bc33de4f63c5", "urls": [ - "https://storage.googleapis.com/chrome-for-testing-public/143.0.7482.0/mac-x64/chromedriver-mac-x64.zip" + "https://storage.googleapis.com/chrome-for-testing-public/144.0.7531.0/mac-x64/chromedriver-mac-x64.zip" ], "named_files": { "CHROMEDRIVER": "chromedriver-mac-x64/chromedriver" @@ -852,9 +854,9 @@ "bzlFile": "@@rules_browsers~//browsers/private:browser_repo.bzl", "ruleClassName": "browser_repo", "attributes": { - "sha256": "5adf89a3e8edc6755920f4cfe2fe0515d40684878ef5201da5e02a9d491c4003", + "sha256": "99821795fa7c87eb92fb15248e23b237c83f397486d22ad9a10771622c36a5a0", "urls": [ - "https://storage.googleapis.com/chrome-for-testing-public/143.0.7482.0/mac-arm64/chromedriver-mac-arm64.zip" + "https://storage.googleapis.com/chrome-for-testing-public/144.0.7531.0/mac-arm64/chromedriver-mac-arm64.zip" ], "named_files": { "CHROMEDRIVER": "chromedriver-mac-arm64/chromedriver" @@ -869,9 +871,9 @@ "bzlFile": "@@rules_browsers~//browsers/private:browser_repo.bzl", "ruleClassName": "browser_repo", "attributes": { - "sha256": "a3dfe62b3e9e7a42bd324c07dcbbcc3a733a736b2a59f0e93b9250b88103ab73", + "sha256": "6e180e234a710c3cbf69566f64a662ed85473db6ae82275fd359f80ab288df99", "urls": [ - "https://storage.googleapis.com/chrome-for-testing-public/143.0.7482.0/win64/chromedriver-win64.zip" + "https://storage.googleapis.com/chrome-for-testing-public/144.0.7531.0/win64/chromedriver-win64.zip" ], "named_files": { "CHROMEDRIVER": "chromedriver-win64/chromedriver.exe" @@ -886,9 +888,9 @@ "bzlFile": "@@rules_browsers~//browsers/private:browser_repo.bzl", "ruleClassName": "browser_repo", "attributes": { - "sha256": "c66a48222ff67d51560240d321895c6926c9b3af345cbf688ced8517781d88d1", + "sha256": "00fb922cda6bab971e02bcbfb77923b0a234388ed7d77c23506ca0a1a61d4a86", "urls": [ - "https://archive.mozilla.org/pub/firefox/releases/144.0/linux-x86_64/en-US/firefox-144.0.tar.xz" + "https://archive.mozilla.org/pub/firefox/releases/145.0/linux-x86_64/en-US/firefox-145.0.tar.xz" ], "named_files": { "FIREFOX": "firefox/firefox" @@ -903,9 +905,9 @@ "bzlFile": "@@rules_browsers~//browsers/private:browser_repo.bzl", "ruleClassName": "browser_repo", "attributes": { - "sha256": "1e444b80921bc999d56c05a7decc1eaf88c0297cac5b90416299af2c77f5ecc9", + "sha256": "1c4556480deac8424049f3081a6de1e2c6de619bab3e8ce53e5a497b8d6d919e", "urls": [ - "https://archive.mozilla.org/pub/firefox/releases/144.0/mac/en-US/Firefox%20144.0.dmg" + "https://archive.mozilla.org/pub/firefox/releases/145.0/mac/en-US/Firefox%20145.0.dmg" ], "named_files": { "FIREFOX": "Firefox.app/Contents/MacOS/firefox" @@ -920,9 +922,9 @@ "bzlFile": "@@rules_browsers~//browsers/private:browser_repo.bzl", "ruleClassName": "browser_repo", "attributes": { - "sha256": "1e444b80921bc999d56c05a7decc1eaf88c0297cac5b90416299af2c77f5ecc9", + "sha256": "1c4556480deac8424049f3081a6de1e2c6de619bab3e8ce53e5a497b8d6d919e", "urls": [ - "https://archive.mozilla.org/pub/firefox/releases/144.0/mac/en-US/Firefox%20144.0.dmg" + "https://archive.mozilla.org/pub/firefox/releases/145.0/mac/en-US/Firefox%20145.0.dmg" ], "named_files": { "FIREFOX": "Firefox.app/Contents/MacOS/firefox" @@ -937,9 +939,9 @@ "bzlFile": "@@rules_browsers~//browsers/private:browser_repo.bzl", "ruleClassName": "browser_repo", "attributes": { - "sha256": "d1e8a7c061e25a41c8dfa85e3aee8e86e9263c69104d80906c978c8d0556563a", + "sha256": "4b0345c113242653d923b369fcbd48e3089c57658f8c1542f887c8a375d50306", "urls": [ - "https://archive.mozilla.org/pub/firefox/releases/144.0/win64/en-US/Firefox%20Setup%20144.0.exe" + "https://archive.mozilla.org/pub/firefox/releases/145.0/win64/en-US/Firefox%20Setup%20145.0.exe" ], "named_files": { "FIREFOX": "core/firefox.exe" @@ -1139,8 +1141,8 @@ }, "@@rules_nodejs~//nodejs:extensions.bzl%node": { "general": { - "bzlTransitiveDigest": "Oex83HlYG4+sPr0oUbvldjyP3JnYazq0jAVgUXDx7yU=", - "usagesDigest": "3BeF7a1MDbYZesa8EOSh4Ihre1HMpOUWna9iTCBluY0=", + "bzlTransitiveDigest": "NwcLXHrbh2hoorA/Ybmcpjxsn/6avQmewDglodkDrgo=", + "usagesDigest": "6u/wPA8vJI6qkxtlJXv2v5SKQPZ1GrCSLH9fuOW/ay8=", "recordedFileInputs": {}, "recordedDirentsInputs": {}, "envVariables": {}, @@ -4602,7 +4604,7 @@ "@@yq.bzl~//yq:extensions.bzl%yq": { "general": { "bzlTransitiveDigest": "61Uz+o5PnlY0jJfPZEUNqsKxnM/UCLeWsn5VVCc8u5Y=", - "usagesDigest": "X+3wxc/+KjF0tyJJ5qca2U/BgoeAEmAD0kuz8iBcX+0=", + "usagesDigest": "d69aUcr/oJv29ydTdFN0JWU618+QzKkxecQFV9S2xjU=", "recordedFileInputs": {}, "recordedDirentsInputs": {}, "envVariables": {}, From c568c0d34610d0ec75ead43df7d6022c5357ee27 Mon Sep 17 00:00:00 2001 From: Angular Robot Date: Tue, 18 Nov 2025 04:07:21 +0000 Subject: [PATCH 19/54] build: lock file maintenance See associated pull request for more information. --- pnpm-lock.yaml | 667 ++++++++++++++++++++++++------------------------- 1 file changed, 324 insertions(+), 343 deletions(-) diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 1651634d1369..e628179997a0 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -114,7 +114,7 @@ importers: version: 4.1.1 '@types/jasmine': specifier: ~5.1.0 - version: 5.1.12 + version: 5.1.13 '@types/jasmine-reporters': specifier: ^2 version: 2.5.3 @@ -132,7 +132,7 @@ importers: version: 4.17.20 '@types/node': specifier: ^22.12.0 - version: 22.19.0 + version: 22.19.1 '@types/npm-package-arg': specifier: ^6.1.0 version: 6.1.4 @@ -153,10 +153,10 @@ importers: version: 7.7.1 '@types/watchpack': specifier: ^2.4.4 - version: 2.4.4 + version: 2.4.5 '@types/yargs': specifier: ^17.0.20 - version: 17.0.34 + version: 17.0.35 '@types/yargs-parser': specifier: ^21.0.0 version: 21.0.3 @@ -276,7 +276,7 @@ importers: version: 6.2.3(rollup@4.52.5)(typescript@5.9.3) rollup-plugin-sourcemaps2: specifier: 0.5.4 - version: 0.5.4(@types/node@22.19.0)(rollup@4.52.5) + version: 0.5.4(@types/node@22.19.1)(rollup@4.52.5) semver: specifier: 7.7.3 version: 7.7.3 @@ -288,7 +288,7 @@ importers: version: 7.5.2 ts-node: specifier: ^10.9.1 - version: 10.9.2(@types/node@22.19.0)(typescript@5.9.3) + version: 10.9.2(@types/node@22.19.1)(typescript@5.9.3) tslib: specifier: 2.8.1 version: 2.8.1 @@ -375,7 +375,7 @@ importers: version: 0.3.5 browserslist: specifier: ^4.26.0 - version: 4.27.0 + version: 4.28.0 esbuild: specifier: 0.26.0 version: 0.26.0 @@ -658,7 +658,7 @@ importers: version: 10.0.0(@babel/core@7.28.4)(webpack@5.102.1(esbuild@0.26.0)) browserslist: specifier: ^4.26.0 - version: 4.27.0 + version: 4.28.0 copy-webpack-plugin: specifier: 13.0.1 version: 13.0.1(webpack@5.102.1(esbuild@0.26.0)) @@ -1677,8 +1677,8 @@ packages: peerDependencies: '@csstools/css-tokenizer': ^3.0.4 - '@csstools/css-syntax-patches-for-csstree@1.0.15': - resolution: {integrity: sha512-q0p6zkVq2lJnmzZVPR33doA51G7YOja+FBvRdp5ISIthL0MtFCgYHHhR563z9WFGxcOn0WfjSkPDJ5Qig3H3Sw==} + '@csstools/css-syntax-patches-for-csstree@1.0.16': + resolution: {integrity: sha512-2SpS4/UaWQaGpBINyG5ZuCHnUDeVByOhvbkARwfmnfxDvTaj80yOI1cD8Tw93ICV5Fx4fnyDKWQZI1CDtcWyUg==} engines: {node: '>=18'} '@csstools/css-tokenizer@3.0.4': @@ -1693,11 +1693,11 @@ packages: resolution: {integrity: sha512-4B4OijXeVNOPZlYA2oEwWOTkzyltLao+xbotHQeqN++Rv27Y6s818+n2Qkp8q+Fxhn0t/5lA5X1Mxktud8eayQ==} engines: {node: '>=14.17.0'} - '@emnapi/core@1.7.0': - resolution: {integrity: sha512-pJdKGq/1iquWYtv1RRSljZklxHCOCAJFJrImO5ZLKPJVJlVUcs8yFwNQlqS0Lo8xT1VAXXTCZocF9n26FWEKsw==} + '@emnapi/core@1.7.1': + resolution: {integrity: sha512-o1uhUASyo921r2XtHYOHy7gdkGLge8ghBEQHMWmyJFoXlpU58kIrhhN3w26lpQb6dspetweapMn2CSNwQ8I4wg==} - '@emnapi/runtime@1.7.0': - resolution: {integrity: sha512-oAYoQnCYaQZKVS53Fq23ceWMRxq5EhQsE0x0RdQ55jT7wagMu5k+fS39v1fiSLrtrLQlXwVINenqhLMtTrV/1Q==} + '@emnapi/runtime@1.7.1': + resolution: {integrity: sha512-PVtJr5CmLwYAU9PZDMITZoR5iAOShYREoR45EyyLrbntV50mdePTgUn4AmOw90Ifcj+x2kRjdzr1HP3RrNiHGA==} '@emnapi/wasi-threads@1.1.0': resolution: {integrity: sha512-WI0DdZ8xFSbgMjR1sFsKABJ/C5OnRrjT06JXbZKexJGrDuPTzZdDYfFlsgcCXCyf+suG5QU2e/y1Wo2V/OapLQ==} @@ -2516,8 +2516,8 @@ packages: resolution: {integrity: sha512-S8qNSZiYzFd0wAcyG5AXCvUHC5Sr7xpZ9wZ2py9XR88jUz8wooStVx5M6dRzczbBWjic9NP7+rY0Xi7qqK/aMQ==} engines: {node: '>=18'} - '@inquirer/checkbox@4.3.1': - resolution: {integrity: sha512-rOcLotrptYIy59SGQhKlU0xBg1vvcVl2FdPIEclUvKHh0wo12OfGkId/01PIMJ/V+EimJ77t085YabgnQHBa5A==} + '@inquirer/checkbox@4.3.2': + resolution: {integrity: sha512-VXukHf0RR1doGe6Sm4F0Em7SWYLTHSsbGfJdS9Ja2bX5/D5uwVOEjr07cncLROdBvmnvCATYEWlHqYmXv2IlQA==} engines: {node: '>=18'} peerDependencies: '@types/node': '>=18' @@ -2534,8 +2534,8 @@ packages: '@types/node': optional: true - '@inquirer/confirm@5.1.20': - resolution: {integrity: sha512-HDGiWh2tyRZa0M1ZnEIUCQro25gW/mN8ODByicQrbR1yHx4hT+IOpozCMi5TgBtUdklLwRI2mv14eNpftDluEw==} + '@inquirer/confirm@5.1.21': + resolution: {integrity: sha512-KR8edRkIsUayMXV+o3Gv+q4jlhENF9nMYUZs9PA2HzrXeHI8M5uDag70U7RJn9yyiMZSbtF5/UexBtAVtZGSbQ==} engines: {node: '>=18'} peerDependencies: '@types/node': '>=18' @@ -2543,8 +2543,8 @@ packages: '@types/node': optional: true - '@inquirer/core@10.3.1': - resolution: {integrity: sha512-hzGKIkfomGFPgxKmnKEKeA+uCYBqC+TKtRx5LgyHRCrF6S2MliwRIjp3sUaWwVzMp7ZXVs8elB0Tfe682Rpg4w==} + '@inquirer/core@10.3.2': + resolution: {integrity: sha512-43RTuEbfP8MbKzedNqBrlhhNKVwoK//vUFNW3Q3vZ88BLcrs4kYpGg+B2mm5p2K/HfygoCxuKwJJiv8PbGmE0A==} engines: {node: '>=18'} peerDependencies: '@types/node': '>=18' @@ -2552,8 +2552,8 @@ packages: '@types/node': optional: true - '@inquirer/editor@4.2.22': - resolution: {integrity: sha512-8yYZ9TCbBKoBkzHtVNMF6PV1RJEUvMlhvmS3GxH4UvXMEHlS45jFyqFy0DU+K42jBs5slOaA78xGqqqWAx3u6A==} + '@inquirer/editor@4.2.23': + resolution: {integrity: sha512-aLSROkEwirotxZ1pBaP8tugXRFCxW94gwrQLxXfrZsKkfjOYC1aRvAZuhpJOb5cu4IBTJdsCigUlf2iCOu4ZDQ==} engines: {node: '>=18'} peerDependencies: '@types/node': '>=18' @@ -2561,8 +2561,8 @@ packages: '@types/node': optional: true - '@inquirer/expand@4.0.22': - resolution: {integrity: sha512-9XOjCjvioLjwlq4S4yXzhvBmAXj5tG+jvva0uqedEsQ9VD8kZ+YT7ap23i0bIXOtow+di4+u3i6u26nDqEfY4Q==} + '@inquirer/expand@4.0.23': + resolution: {integrity: sha512-nRzdOyFYnpeYTTR2qFwEVmIWypzdAx/sIkCMeTNTcflFOovfqUk+HcFhQQVBftAh9gmGrpFj6QcGEqrDMDOiew==} engines: {node: '>=18'} peerDependencies: '@types/node': '>=18' @@ -2583,8 +2583,8 @@ packages: resolution: {integrity: sha512-t2IEY+unGHOzAaVM5Xx6DEWKeXlDDcNPeDyUpsRc6CUhBfU3VQOEl+Vssh7VNp1dR8MdUJBWhuObjXCsVpjN5g==} engines: {node: '>=18'} - '@inquirer/input@4.3.0': - resolution: {integrity: sha512-h4fgse5zeGsBSW3cRQqu9a99OXRdRsNCvHoBqVmz40cjYjYFzcfwD0KA96BHIPlT7rZw0IpiefQIqXrjbzjS4Q==} + '@inquirer/input@4.3.1': + resolution: {integrity: sha512-kN0pAM4yPrLjJ1XJBjDxyfDduXOuQHrBB8aLDMueuwUGn+vNpF7Gq7TvyVxx8u4SHlFFj4trmj+a2cbpG4Jn1g==} engines: {node: '>=18'} peerDependencies: '@types/node': '>=18' @@ -2592,8 +2592,8 @@ packages: '@types/node': optional: true - '@inquirer/number@3.0.22': - resolution: {integrity: sha512-oAdMJXz++fX58HsIEYmvuf5EdE8CfBHHXjoi9cTcQzgFoHGZE+8+Y3P38MlaRMeBvAVnkWtAxMUF6urL2zYsbg==} + '@inquirer/number@3.0.23': + resolution: {integrity: sha512-5Smv0OK7K0KUzUfYUXDXQc9jrf8OHo4ktlEayFlelCjwMXz0299Y8OrI+lj7i4gCBY15UObk76q0QtxjzFcFcg==} engines: {node: '>=18'} peerDependencies: '@types/node': '>=18' @@ -2601,8 +2601,8 @@ packages: '@types/node': optional: true - '@inquirer/password@4.0.22': - resolution: {integrity: sha512-CbdqK1ioIr0Y3akx03k/+Twf+KSlHjn05hBL+rmubMll7PsDTGH0R4vfFkr+XrkB0FOHrjIwVP9crt49dgt+1g==} + '@inquirer/password@4.0.23': + resolution: {integrity: sha512-zREJHjhT5vJBMZX/IUbyI9zVtVfOLiTO66MrF/3GFZYZ7T4YILW5MSkEYHceSii/KtRk+4i3RE7E1CUXA2jHcA==} engines: {node: '>=18'} peerDependencies: '@types/node': '>=18' @@ -2628,8 +2628,8 @@ packages: '@types/node': optional: true - '@inquirer/rawlist@4.1.10': - resolution: {integrity: sha512-Du4uidsgTMkoH5izgpfyauTL/ItVHOLsVdcY+wGeoGaG56BV+/JfmyoQGniyhegrDzXpfn3D+LFHaxMDRygcAw==} + '@inquirer/rawlist@4.1.11': + resolution: {integrity: sha512-+LLQB8XGr3I5LZN/GuAHo+GpDJegQwuPARLChlMICNdwW7OwV2izlCSCxN6cqpL0sMXmbKbFcItJgdQq5EBXTw==} engines: {node: '>=18'} peerDependencies: '@types/node': '>=18' @@ -2637,8 +2637,8 @@ packages: '@types/node': optional: true - '@inquirer/search@3.2.1': - resolution: {integrity: sha512-cKiuUvETublmTmaOneEermfG2tI9ABpb7fW/LqzZAnSv4ZaJnbEis05lOkiBuYX5hNdnX0Q9ryOQyrNidb55WA==} + '@inquirer/search@3.2.2': + resolution: {integrity: sha512-p2bvRfENXCZdWF/U2BXvnSI9h+tuA8iNqtUKb9UWbmLYCRQxd8WkvwWvYn+3NgYaNwdUkHytJMGG4MMLucI1kA==} engines: {node: '>=18'} peerDependencies: '@types/node': '>=18' @@ -2646,8 +2646,8 @@ packages: '@types/node': optional: true - '@inquirer/select@4.4.1': - resolution: {integrity: sha512-E9hbLU4XsNe2SAOSsFrtYtYQDVi1mfbqJrPDvXKnGlnRiApBdWMJz7r3J2Ff38AqULkPUD3XjQMD4492TymD7Q==} + '@inquirer/select@4.4.2': + resolution: {integrity: sha512-l4xMuJo55MAe+N7Qr4rX90vypFwCajSakx59qe/tMaC1aEHWLyw68wF4o0A4SLAY4E0nd+Vt+EyskeDIqu1M6w==} engines: {node: '>=18'} peerDependencies: '@types/node': '>=18' @@ -2956,10 +2956,6 @@ packages: resolution: {integrity: sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==} engines: {node: '>= 8'} - '@npmcli/agent@3.0.0': - resolution: {integrity: sha512-S79NdEgDQd/NGCay6TCoVzXSj74skRZIKJcpJjC5lOq34SZzyI6MqtiiWoiVWoVrTcGjNeC4ipbh1VIHlpfF5Q==} - engines: {node: ^18.17.0 || >=20.5.0} - '@npmcli/agent@4.0.0': resolution: {integrity: sha512-kAQTcEN9E8ERLVg5AsGwLNoFb+oEG6engbqAU2P43gD4JEIkNGMHdVQ096FsOAAYpZPB0RSt0zgInKIAS1l5QA==} engines: {node: ^20.17.0 || >=22.9.0} @@ -2968,8 +2964,8 @@ packages: resolution: {integrity: sha512-/xGlezI6xfGO9NwuJlnwz/K14qD1kCSAGtacBHnGzeAIuJGazcp45KP5NuyARXoKb7cwulAGWVsbeSxdG/cb0Q==} engines: {node: ^18.17.0 || >=20.5.0} - '@npmcli/git@7.0.0': - resolution: {integrity: sha512-vnz7BVGtOctJAIHouCJdvWBhsTVSICMeUgZo2c7XAi5d5Rrl80S1H7oPym7K03cRuinK5Q6s2dw36+PgXQTcMA==} + '@npmcli/git@7.0.1': + resolution: {integrity: sha512-+XTFxK2jJF/EJJ5SoAzXk3qwIDfvFc5/g+bD274LZ7uY7LE8sTfG6Z8rOanPl2ZEvZWqNvmEdtXC25cE54VcoA==} engines: {node: ^20.17.0 || >=22.9.0} '@npmcli/installed-package-contents@3.0.0': @@ -2989,16 +2985,16 @@ packages: resolution: {integrity: sha512-Yb00SWaL4F8w+K8YGhQ55+xE4RUNdMHV43WZGsiTM92gS+lC0mGsn7I4hLug7pbao035S6bj3Y3w0cUNGLfmkg==} engines: {node: ^18.17.0 || >=20.5.0} - '@npmcli/promise-spawn@9.0.0': - resolution: {integrity: sha512-qxvGj3ZM6Zuk8YeVMY0gZHY19WN6g3OGxwR4MBaxHImfD/4zD0HpgBHNOSayEaisj/p3PyQjdQlO9tbl5ZBFZg==} + '@npmcli/promise-spawn@9.0.1': + resolution: {integrity: sha512-OLUaoqBuyxeTqUvjA3FZFiXUfYC1alp3Sa99gW3EUDz3tZ3CbXDdcZ7qWKBzicrJleIgucoWamWH1saAmH/l2Q==} engines: {node: ^20.17.0 || >=22.9.0} - '@npmcli/redact@3.2.2': - resolution: {integrity: sha512-7VmYAmk4csGv08QzrDKScdzn11jHPFGyqJW39FyPgPuAp3zIaUmuCo1yxw9aGs+NEJuTGQ9Gwqpt93vtJubucg==} - engines: {node: ^18.17.0 || >=20.5.0} + '@npmcli/redact@4.0.0': + resolution: {integrity: sha512-gOBg5YHMfZy+TfHArfVogwgfBeQnKbbGo3pSUyK/gSI0AVu+pEiDVcKlQb0D8Mg1LNRZILZ6XG8I5dJ4KuAd9Q==} + engines: {node: ^20.17.0 || >=22.9.0} - '@npmcli/run-script@10.0.2': - resolution: {integrity: sha512-9lCTqxaoa9c9cdkzSSx+q/qaYrCrUPEwTWzLkVYg1/T8ESH3BG9vmb1zRc6ODsBVB0+gnGRSqSr01pxTS1yX3A==} + '@npmcli/run-script@10.0.3': + resolution: {integrity: sha512-ER2N6itRkzWbbtVmZ9WKaWxVlKlOeBFF1/7xx+KA5J1xKa4JjUwBdb6tDpk0v1qA+d+VDwHI9qmLcXSWcmi+Rw==} engines: {node: ^20.17.0 || >=22.9.0} '@octokit/auth-app@8.1.2': @@ -3069,8 +3065,8 @@ packages: resolution: {integrity: sha512-U8piOROoQQUyExw5c6dTkU3GKxts5/ERRThIauNL7yaRoeXW0q/5bgHWT7JfWBw1UyrbK8ERId2wVkcB32n0uQ==} engines: {node: '>= 20'} - '@octokit/request@10.0.6': - resolution: {integrity: sha512-FO+UgZCUu+pPnZAR+iKdUt64kPE7QW7ciqpldaMXaNzixz5Jld8dJ31LAUewk0cfSRkNSRKyqG438ba9c/qDlQ==} + '@octokit/request@10.0.7': + resolution: {integrity: sha512-v93h0i1yu4idj8qFPZwjehoJx4j3Ntn+JhXsdJrG9pYaX6j/XRz2RmasMUHtNgQD39nrv/VwTWSqK0RNXR8upA==} engines: {node: '>= 20'} '@octokit/rest@22.0.1': @@ -3592,8 +3588,8 @@ packages: '@tootallnate/quickjs-emscripten@0.23.0': resolution: {integrity: sha512-C5Mc6rdnsaJDjO3UpGW/CQTHtCKaYlScZTly4JIu97Jxo/odCiH0ITnDXSJPTOrEKk/ycSZ0AOgTmkDtkOsvIA==} - '@tsconfig/node10@1.0.11': - resolution: {integrity: sha512-DcRjDCujK/kCk/cUe8Xz8ZSpm8mS3mNNpta+jGCA6USEDfktlNvm1+IuZ9eTcDbNk41BHwpHHeW+N1lKCz4zOw==} + '@tsconfig/node10@1.0.12': + resolution: {integrity: sha512-UCYBaeFvM11aU2y3YPZ//O5Rhj+xKyzy7mvcIoAjASbigy8mHMryP5cK7dgjlz2hWxh1g5pLw084E0a/wlUSFQ==} '@tsconfig/node12@1.0.11': resolution: {integrity: sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==} @@ -3747,6 +3743,9 @@ packages: '@types/jasmine@5.1.12': resolution: {integrity: sha512-1BzPxNsFDLDfj9InVR3IeY0ZVf4o9XV+4mDqoCfyPkbsA7dYyKAPAb2co6wLFlHcvxPlt1wShm7zQdV7uTfLGA==} + '@types/jasmine@5.1.13': + resolution: {integrity: sha512-MYCcDkruFc92LeYZux5BC0dmqo2jk+M5UIZ4/oFnAPCXN9mCcQhLyj7F3/Za7rocVyt5YRr1MmqJqFlvQ9LVcg==} + '@types/json-schema@7.0.15': resolution: {integrity: sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==} @@ -3786,8 +3785,8 @@ packages: '@types/node-forge@1.3.14': resolution: {integrity: sha512-mhVF2BnD4BO+jtOp7z1CdzaK4mbuK0LLQYAvdOLqHTavxFNq4zA1EmYkpnFjP8HOUzedfQkRnp0E2ulSAYSzAw==} - '@types/node@22.19.0': - resolution: {integrity: sha512-xpr/lmLPQEj+TUnHmR+Ab91/glhJvsqcjB+yY0Ix9GO70H6Lb4FHH5GeqdOE5btAx7eIMwuHkp4H2MSkLcqWbA==} + '@types/node@22.19.1': + resolution: {integrity: sha512-LCCV0HdSZZZb34qifBsyWlUmok6W7ouER+oQIGBScS8EsZsQbrtFTUrDX4hOl+CS6p7cnNC4td+qrSVGSCTUfQ==} '@types/node@24.10.0': resolution: {integrity: sha512-qzQZRBqkFsYyaSWXuEHc2WR9c0a0CXwiE5FWUvn7ZM+vdy1uZLfCunD38UzhuB7YN/J11ndbDBcTmOdxJo9Q7A==} @@ -3870,8 +3869,8 @@ packages: '@types/stack-trace@0.0.33': resolution: {integrity: sha512-O7in6531Bbvlb2KEsJ0dq0CHZvc3iWSR5ZYMtvGgnHA56VgriAN/AU2LorfmcvAl2xc9N5fbCTRyMRRl8nd74g==} - '@types/watchpack@2.4.4': - resolution: {integrity: sha512-SbuSavsPxfOPZwVHBgQUVuzYBe6+8KL7dwiJLXaj5rmv3DxktOMwX5WP1J6UontwUbewjVoc7pCgZvqy6rPn+A==} + '@types/watchpack@2.4.5': + resolution: {integrity: sha512-8CarnGOIYYRL342jwQyHrGwz4vCD3y5uwwYmzQVzT2Z24DqSd6wwBva6m0eNJX4S5pVmrx9xUEbOsOoqBVhWsg==} '@types/which@3.0.4': resolution: {integrity: sha512-liyfuo/106JdlgSchJzXEQCVArk0CvevqPote8F8HgWgJ3dRCcTHgJIsLDuee0kxk/mhbInzIZk3QWSZJ8R+2w==} @@ -3888,6 +3887,9 @@ packages: '@types/yargs@17.0.34': resolution: {integrity: sha512-KExbHVa92aJpw9WDQvzBaGVE2/Pz+pLZQloT2hjL8IqsZnV62rlPOYvNnLmf/L2dyllfVUOVBj64M0z/46eR2A==} + '@types/yargs@17.0.35': + resolution: {integrity: sha512-qUHkeCyQFxMXg79wQfTtfndEC+N9ZZg76HJftDJp+qH2tV7Gj4OJi7l+PiWwJ+pWtW8GwSmqsDj/oymhrTWXjg==} + '@types/yarnpkg__lockfile@1.1.9': resolution: {integrity: sha512-GD4Fk15UoP5NLCNor51YdfL9MSdldKCqOC9EssrRw3HVfar9wUZ5y8Lfnp+qVD6hIinLr8ygklDYnmlnlQo12Q==} @@ -3936,8 +3938,8 @@ packages: resolution: {integrity: sha512-lNCWCbq7rpg7qDsQrd3D6NyWYu+gkTENkG5IKYhUIcxSb59SQC/hEQ+MrG4sTgBVghTonNWq42bA/d4yYumldQ==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@typescript-eslint/types@8.46.3': - resolution: {integrity: sha512-G7Ok9WN/ggW7e/tOf8TQYMaxgID3Iujn231hfi0Pc7ZheztIJVpO44ekY00b7akqc6nZcvregk0Jpah3kep6hA==} + '@typescript-eslint/types@8.46.4': + resolution: {integrity: sha512-USjyxm3gQEePdUwJBFjjGNG18xY9A2grDVGuk7/9AkjIF1L+ZrVnwR5VAU5JXtUnBL/Nwt3H31KlRDaksnM7/w==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} '@typescript-eslint/typescript-estree@8.46.2': @@ -4192,9 +4194,9 @@ packages: resolution: {integrity: sha512-E+iruNOY8VV9s4JEbe1aNEm6MiszPRr/UfcHMz0TQh1BXSxHK+ASV1R6W4HpjBhSeS+54PIsAMCBmwD06LLsqQ==} hasBin: true - abbrev@3.0.1: - resolution: {integrity: sha512-AO2ac6pjRB3SJmGJo+v5/aK6Omggp6fsLrs6wN9bd35ulu4cCwaAU9+7ZhXjeqHVkaHThLuzH0nZr0YpCDhygg==} - engines: {node: ^18.17.0 || >=20.5.0} + abbrev@4.0.0: + resolution: {integrity: sha512-a1wflyaL0tHtJSmLSOVybYhy22vRih4eduhhrkcjgrWGnRfrZtovJ2FRjxuTtkkj47O/baf0R86QU5OuYpz8fA==} + engines: {node: ^20.17.0 || >=22.9.0} abort-controller@3.0.0: resolution: {integrity: sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg==} @@ -4530,8 +4532,8 @@ packages: resolution: {integrity: sha512-lGe34o6EHj9y3Kts9R4ZYs/Gr+6N7MCaMlIFA3F1R2O5/m7K06AxfSeO5530PEERE6/WyEg3lsuyw4GHlPZHog==} engines: {node: ^4.5.0 || >= 5.9} - baseline-browser-mapping@2.8.25: - resolution: {integrity: sha512-2NovHVesVF5TXefsGX1yzx1xgr7+m9JQenvz6FQY3qd+YXkKkYiv+vTCc7OriP9mcDZpTC5mAOYN4ocd29+erA==} + baseline-browser-mapping@2.8.28: + resolution: {integrity: sha512-gYjt7OIqdM0PcttNYP2aVrr2G0bMALkBaoehD4BuRGjAOtipg0b6wHg1yNL+s5zSnLZZrGHOw4IrND8CD+3oIQ==} hasBin: true basic-ftp@5.0.5: @@ -4620,8 +4622,8 @@ packages: browserify-zlib@0.1.4: resolution: {integrity: sha512-19OEpq7vWgsH6WkvkBJQDFvJS1uPcbFOQ4v9CU839dO+ZZXUZO6XpE6hNCqvlIIj+4fZvRiJ6DsAQ382GwiyTQ==} - browserslist@4.27.0: - resolution: {integrity: sha512-AXVQwdhot1eqLihwasPElhX2tAZiBjWdJ9i/Zcj2S6QYIjkx62OKSfnobkriB81C3l4w0rVy3Nt4jaTBltYEpw==} + browserslist@4.28.0: + resolution: {integrity: sha512-tbydkR/CxfMwelN0vwdP/pLkDwyAASZ+VfWm4EOwlB6SWhx1sYnWLqo8N5j0rAzPfzfRaxt0mM/4wPU/Su84RQ==} engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7} hasBin: true @@ -4658,10 +4660,6 @@ packages: resolution: {integrity: sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==} engines: {node: '>= 0.8'} - cacache@19.0.1: - resolution: {integrity: sha512-hdsUxulXCi5STId78vRVYEtDAjq99ICAUktLTeTYsLoTE6Z8dS0c8pWNCxwdrk9YfJeobDZc2Y186hD/5ZQgFQ==} - engines: {node: ^18.17.0 || >=20.5.0} - cacache@20.0.1: resolution: {integrity: sha512-+7LYcYGBYoNqTp1Rv7Ny1YjUo5E0/ftkQtraH3vkfAGgVHc+ouWdC8okAwQgQR7EVIdW6JTzTmhKFwzb+4okAQ==} engines: {node: ^20.17.0 || >=22.9.0} @@ -4702,14 +4700,14 @@ packages: resolution: {integrity: sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==} engines: {node: '>=10'} - caniuse-lite@1.0.30001754: - resolution: {integrity: sha512-x6OeBXueoAceOmotzx3PO4Zpt4rzpeIFsSr6AAePTZxSkXiYDUmpypEl7e2+8NCd9bD7bXjqyef8CJYPC1jfxg==} + caniuse-lite@1.0.30001755: + resolution: {integrity: sha512-44V+Jm6ctPj7R52Na4TLi3Zri4dWUljJd+RDm+j8LtNCc/ihLCT+X1TzoOAkRETEWqjuLnh9581Tl80FvK7jVA==} caseless@0.12.0: resolution: {integrity: sha512-4tYFyifaFfGacoiObjJegolkwSU4xQNGbVgUiNYVUxbQ2x2lUsFvY4hVgVzGiIe6WLOPqycWXA40l+PWsxthUw==} - chai@6.2.0: - resolution: {integrity: sha512-aUTnJc/JipRzJrNADXVvpVqi6CO0dn3nx4EVPxijri+fj3LUUDyZQOgVeW54Ob3Y1Xh9Iz8f+CgaCl8v0mn9bA==} + chai@6.2.1: + resolution: {integrity: sha512-p4Z49OGG5W/WBCPSS/dH3jQ73kD6tiMmUM+bckNK6Jr5JHMG3k9bg/BvKR8lKmtVBKmOiuVaV2ws8s9oSbwysg==} engines: {node: '>=18'} chalk-template@0.4.0: @@ -4758,8 +4756,8 @@ packages: resolution: {integrity: sha512-rNjApaLzuwaOTjCiT8lSDdGN1APCiqkChLMJxJPWLunPAt5fy8xgU9/jNOchV84wfIxrA0lRQB7oCT8jrn/wrQ==} engines: {node: '>=6.0'} - chromium-bidi@10.5.1: - resolution: {integrity: sha512-rlj6OyhKhVTnk4aENcUme3Jl9h+cq4oXu4AzBcvr8RMmT6BR4a3zSNT9dbIfXr9/BS6ibzRyDhowuw4n2GgzsQ==} + chromium-bidi@11.0.0: + resolution: {integrity: sha512-cM3DI+OOb89T3wO8cpPSro80Q9eKYJ7hGVXoGS3GkDPxnYSqiv+6xwpIf6XERyJ9Tdsl09hmNmY94BkgZdVekw==} peerDependencies: devtools-protocol: '*' @@ -5141,12 +5139,12 @@ packages: resolution: {integrity: sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==} engines: {node: '>=0.10.0'} - default-browser-id@5.0.0: - resolution: {integrity: sha512-A6p/pu/6fyBcA1TRz/GqWYPViplrftcW2gZC9q79ngNCKAeR/X3gcEdXQHl4KNXV+3wgIJ1CPkJQ3IHM6lcsyA==} + default-browser-id@5.0.1: + resolution: {integrity: sha512-x1VCxdX4t+8wVfd1so/9w+vQ4vx7lKd2Qp5tDRutErwmR85OgmfX7RlLRMWafRMY7hbEiXIbudNrjOAPa/hL8Q==} engines: {node: '>=18'} - default-browser@5.2.1: - resolution: {integrity: sha512-WY/3TUME0x3KPYdRRxEJJvXRHV4PyPoUsxtZa78lwItwRQRHhd2U9xOscaT/YTf8uCXIAjeJOFBVEh/7FtD8Xg==} + default-browser@5.4.0: + resolution: {integrity: sha512-XDuvSq38Hr1MdN47EDvYtx3U0MTqpCEn+F6ft8z2vYDzMrvQhVp0ui9oQdqW3MvK3vqUETglt1tVGgjLuJ5izg==} engines: {node: '>=18'} default-gateway@6.0.3: @@ -5308,8 +5306,8 @@ packages: engines: {node: '>=0.10.0'} hasBin: true - electron-to-chromium@1.5.249: - resolution: {integrity: sha512-5vcfL3BBe++qZ5kuFhD/p8WOM1N9m3nwvJPULJx+4xf2usSlZFJ0qoNYO2fOX4hi3ocuDcmDobtA+5SFr4OmBg==} + electron-to-chromium@1.5.254: + resolution: {integrity: sha512-DcUsWpVhv9svsKRxnSCZ86SjD+sp32SGidNB37KpqXJncp1mfUgKbHvBomE89WJDbfVKw1mdv5+ikrvd43r+Bg==} emoji-regex@10.6.0: resolution: {integrity: sha512-toUI84YS5YmxW219erniWD0CIVOo46xGKColeNQRgOzDorgBi1v4D71/OFzgD9GO2UGKIv1C3Sp8DAn0+j5w7A==} @@ -5964,12 +5962,12 @@ packages: resolution: {integrity: sha512-7ABviyMOlX5hIVD60YOfHw4/CxOfBhyduaYB+wbFWCWoni4N7SLcV46hrVRktuBbZjFC9ONyqamZITN7q3n32w==} engines: {node: '>=18'} - google-gax@5.0.5: - resolution: {integrity: sha512-VuC6nVnPVfo/M1WudLoS4Y3dTepVndZatUmeb0nUNmfzft6mKSy8ffDh4h5qxR7L9lslDxNpWPYsuPrFboOmTw==} + google-gax@5.0.6: + resolution: {integrity: sha512-1kGbqVQBZPAAu4+/R1XxPQKP0ydbNYoLAr4l0ZO2bMV0kLyLW4I1gAk++qBLWt7DPORTzmWRMsCZe86gDjShJA==} engines: {node: '>=18'} - google-logging-utils@1.1.2: - resolution: {integrity: sha512-YsFPGVgDFf4IzSwbwIR0iaFJQFmR5Jp7V1WuYSjuRgAm9yWqsMhKE9YPlL+wvFLnc/wMiFV4SQUD9Y/JMpxIxQ==} + google-logging-utils@1.1.3: + resolution: {integrity: sha512-eAmLkjDjAFCVXg7A1unxHsLf961m6y17QFqXqAXGj/gVkKFrEICfStRfwUlGNfeCEjNRa32JEWOUTlYXPyyKvA==} engines: {node: '>=14'} gopd@1.2.0: @@ -6248,6 +6246,10 @@ packages: resolution: {integrity: sha512-+N0ngpO3e7cRUWOJAS7qw0IZIVc6XPrW4MlFBdD066F2L4k1L6ker3hLqSq7iXxU5tgS4WGkIUElWn5vogAEnw==} engines: {node: ^18.17.0 || >=20.5.0} + ini@6.0.0: + resolution: {integrity: sha512-IBTdIkzZNOpqm7q3dRqJvMaldXjDHWkEDfrwGEQTs5eaQMWV+djAhR+wahyNNMAa+qpbDUhBMVt4ZKNwpPm7xQ==} + engines: {node: ^20.17.0 || >=22.9.0} + injection-js@2.6.1: resolution: {integrity: sha512-dbR5bdhi7TWDoCye9cByZqeg/gAfamm8Vu3G1KZOTYkOif8WkuM8CD0oeDPtZYMzT5YH76JAFB7bkmyY9OJi2A==} @@ -6515,8 +6517,8 @@ packages: resolution: {integrity: sha512-iHrqe5shvBUcFbmZq9zOQHBoeOhZJu6RQGrDpBgenUm/Am+F3JM2MgQj+rK3Z601fzrL5gLZWtAPH2OBaSVcyw==} engines: {node: '>= 8.0.0'} - isbinaryfile@5.0.6: - resolution: {integrity: sha512-I+NmIfBHUl+r2wcDd6JwE9yWje/PIVY/R5/CmV8dXLZd5K+L9X2klAOwfAHNnondLXkbHyTAleQAWonpTJBTtw==} + isbinaryfile@5.0.7: + resolution: {integrity: sha512-gnWD14Jh3FzS3CPhF0AxNOJ8CxqeblPTADzI38r0wt8ZyQl5edpy75myt08EG2oKvpyiqSqsx+Wkz9vtkbTqYQ==} engines: {node: '>= 18.0.0'} isexe@2.0.0: @@ -6621,6 +6623,10 @@ packages: resolution: {integrity: sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==} hasBin: true + js-yaml@4.1.1: + resolution: {integrity: sha512-qQKT4zQxXl8lLwBtHMWwaTcGfFOZviOJet3Oy/xmGk2gZH677CJM9EvtfdSkgWcATZhj/55JZ0rmy3myCT5lsA==} + hasBin: true + jsbn@0.1.1: resolution: {integrity: sha512-UVU9dibq2JcFWxQPA6KCqj5O42VOmAY3zQUfEKxU0KpTGXwNoCjkX1e13eHNvw/xPynt6pU0rZ1htjWTNTSXsg==} @@ -6957,12 +6963,8 @@ packages: make-error@1.3.6: resolution: {integrity: sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==} - make-fetch-happen@14.0.3: - resolution: {integrity: sha512-QMjGbFTP0blj97EeidG5hk/QhKQ3T4ICckQGLgz38QF7Vgbk6e6FTARN8KhKxyBbWn8R0HU+bnw8aSoFPD4qtQ==} - engines: {node: ^18.17.0 || >=20.5.0} - - make-fetch-happen@15.0.2: - resolution: {integrity: sha512-sI1NY4lWlXBAfjmCtVWIIpBypbBdhHtcjnwnv+gtCnsaOffyFil3aidszGC8hgzJe+fT1qix05sWxmD/Bmf/oQ==} + make-fetch-happen@15.0.3: + resolution: {integrity: sha512-iyyEpDty1mwW3dGlYXAJqC/azFn5PPvgKVwXayOGBSmKLxhKZ9fg4qIan2ePpp1vJIwfFiO34LAPZgq9SZW9Aw==} engines: {node: ^20.17.0 || >=22.9.0} marky@1.3.0: @@ -6983,8 +6985,8 @@ packages: resolution: {integrity: sha512-aisnrDP4GNe06UcKFnV5bfMNPBUw4jsLGaWwWfnH3v02GnBuXX2MCVn5RbrWo0j3pczUilYblq7fQ7Nw2t5XKw==} engines: {node: '>= 0.8'} - memfs@4.50.0: - resolution: {integrity: sha512-N0LUYQMUA1yS5tJKmMtU9yprPm6ZIg24yr/OVv/7t6q0kKDIho4cBbXRi1XKttUmNYDYgF/q45qrKE/UhGO0CA==} + memfs@4.51.0: + resolution: {integrity: sha512-4zngfkVM/GpIhC8YazOsM6E8hoB33NP0BCESPOA6z7qaL6umPJNqkO8CNYaLV2FB2MV6H1O3x2luHHOSqppv+A==} meow@13.2.0: resolution: {integrity: sha512-pxQJQzB6djGPXh08dacEloMFopsOqGVRKFPYvPOt9XDZ1HasbgDZA74CJGreSU4G3Ak7EFJGoiH2auq+yXISgA==} @@ -7094,9 +7096,9 @@ packages: resolution: {integrity: sha512-D7V8PO9oaz7PWGLbCACuI1qEOsq7UKfLotx/C0Aet43fCUB/wfQ7DYeq2oR/svFJGYDHPr38SHATeaj/ZoKHKw==} engines: {node: '>=16 || 14 >=14.17'} - minipass-fetch@4.0.1: - resolution: {integrity: sha512-j7U11C5HXigVuutxebFadoYBbd7VSdZWggSe64NVdvWNBqGAiXPL2QVCehjmw7lY1oF9gOllYbORh+hiNgfPgQ==} - engines: {node: ^18.17.0 || >=20.5.0} + minipass-fetch@5.0.0: + resolution: {integrity: sha512-fiCdUALipqgPWrOVTz9fw0XhcazULXOSU6ie40DDbX1F49p1dBrSRBuswndTx1x3vEb/g0FT7vC4c4C2u/mh3A==} + engines: {node: ^20.17.0 || >=22.9.0} minipass-flush@1.0.5: resolution: {integrity: sha512-JmQSYYpPUqX5Jyn1mXaRwOda1uQ8HP5KAT/oDSLCzt1BYRhQU0/hDtsB1ufZfEEzMZ9aAVmsBw8+FWsIXlClWw==} @@ -7168,9 +7170,9 @@ packages: resolution: {integrity: sha512-SYU3HBAdF4psHEL/+jXDKHO95/m5P2RvboHT2Y0WtTttvJLP4H/2WS9WlQPFvF6C8d6SpLw8vjCnQOnVIVOSJQ==} engines: {node: '>=18'} - mute-stream@3.0.0: - resolution: {integrity: sha512-dkEJPVvun4FryqBmZ5KhDo0K9iDXAwn08tMLDinNdRBNPcYEDiWYysLcc6k3mjTMlbP9KyylvRpd4wFtwrT9rw==} - engines: {node: ^20.17.0 || >=22.9.0} + mute-stream@2.0.0: + resolution: {integrity: sha512-WWdIxpyjEn+FhQJQQv9aQAYlHoNVdzIzUySNV1gHUPDSdZJ3yZn7pAAbQcV7B56Mvu881q9FZV+0Vx2xC44VWA==} + engines: {node: ^18.17.0 || >=20.5.0} nanocolors@0.2.13: resolution: {integrity: sha512-0n3mSAQLPpGLV9ORXT5+C/D4mwew7Ebws69Hx4E2sgz2ZA5+32Q80B9tL8PbL7XHnRDiAxH/pnrUJ9a4fkTNTA==} @@ -7272,17 +7274,17 @@ packages: resolution: {integrity: sha512-LA4ZjwlnUblHVgq0oBF3Jl/6h/Nvs5fzBLwdEF4nuxnFdsfajde4WfxtJr3CaiH+F6ewcIB/q4jQ4UzPyid+CQ==} hasBin: true - node-gyp@11.5.0: - resolution: {integrity: sha512-ra7Kvlhxn5V9Slyus0ygMa2h+UqExPqUIkfk7Pc8QTLT956JLSy51uWFwHtIYy0vI8cB4BDhc/S03+880My/LQ==} - engines: {node: ^18.17.0 || >=20.5.0} + node-gyp@12.1.0: + resolution: {integrity: sha512-W+RYA8jBnhSr2vrTtlPYPc1K+CSjGpVDRZxcqJcERZ8ND3A1ThWPHRwctTx3qC3oW99jt726jhdz3Y6ky87J4g==} + engines: {node: ^20.17.0 || >=22.9.0} hasBin: true node-releases@2.0.27: resolution: {integrity: sha512-nmh3lCkYZ3grZvqcCH+fjmQ7X+H0OeZgP40OierEaAptX4XofMh5kwNbWh7lBduUzCcV/8kZ+NDLCwm2iorIlA==} - nopt@8.1.0: - resolution: {integrity: sha512-ieGu42u/Qsa4TFktmaKEwM6MQH0pOWnaB3htzh0JRtx84+Mebc0cbZYN5bC+6WTZ4+77xrL9Pn5m7CV6VIkV7A==} - engines: {node: ^18.17.0 || >=20.5.0} + nopt@9.0.0: + resolution: {integrity: sha512-Zhq3a+yFKrYwSBluL4H9XP3m3y5uvQkB/09CwDruCiRmR/UJYnn9W4R48ry0uGC70aeTPKLynBtscP9efFFcPw==} + engines: {node: ^20.17.0 || >=22.9.0} hasBin: true normalize-path@3.0.0: @@ -7325,8 +7327,8 @@ packages: resolution: {integrity: sha512-buzyCfeoGY/PxKqmBqn1IUJrZnUi1VVJTdSSRPGI60tJdUhUoSQFhs0zycJokDdOznQentgrpf8LayEHyyYlqQ==} engines: {node: ^20.17.0 || >=22.9.0} - npm-registry-fetch@19.1.0: - resolution: {integrity: sha512-xyZLfs7TxPu/WKjHUs0jZOPinzBAI32kEUel6za0vH+JUTnFZ5zbHI1ZoGZRDm6oMjADtrli6FxtMlk/5ABPNw==} + npm-registry-fetch@19.1.1: + resolution: {integrity: sha512-TakBap6OM1w0H73VZVDf44iFXsOS3h+L4wVMXmbWOQroZgFhMch0juN6XSzBNlD965yIKvWg2dfu7NSiaYLxtw==} engines: {node: ^20.17.0 || >=22.9.0} npm-run-path@4.0.1: @@ -7466,8 +7468,8 @@ packages: resolution: {integrity: sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==} engines: {node: '>=10'} - p-map@7.0.3: - resolution: {integrity: sha512-VkndIv2fIB99swvQoA65bm+fsmt6UNdGeIB0oxBs+WhAhdh08QA04JXpI7rbB9r08/nkbysKoya9rtDERYOYMA==} + p-map@7.0.4: + resolution: {integrity: sha512-tkAQEw8ysMzmkhgw8k+1U/iPhWNhykKnSk4Rd5zLoPJCuJaGRPo6YposrZgaxHKzDHdDWWZvE/Sk7hsL2X/CpQ==} engines: {node: '>=18'} p-queue@6.6.2: @@ -7803,8 +7805,8 @@ packages: resolution: {integrity: sha512-MRtTAZfQTluz3U2oU/X2VqVWPcR1+94nbA2V6ZrSZRVEwLqZ8eclZ551qGFQD/vD2PYqHJwWOW/fpC721uznVw==} engines: {node: '>=14.1.0'} - puppeteer-core@24.29.1: - resolution: {integrity: sha512-ErJ9qKCK+bdLvBa7QVSQTBSPm8KZbl1yC/WvhrZ0ut27hDf2QBzjDsn1IukzE1i1KtZ7NYGETOV4W1beoo9izA==} + puppeteer-core@24.30.0: + resolution: {integrity: sha512-2S3Smy0t0W4wJnNvDe7W0bE7wDmZjfZ3ljfMgJd6hn2Hq/f0jgN+x9PULZo2U3fu5UUIJ+JP8cNUGllu8P91Pg==} engines: {node: '>=18'} puppeteer@18.2.1: @@ -8376,6 +8378,10 @@ packages: resolution: {integrity: sha512-S7iGNosepx9RadX82oimUkvr0Ct7IjJbEbs4mJcTxst8um95J3sDYU1RBEOvdu6oL1Wek2ODI5i4MAw+dZ6cAQ==} engines: {node: ^18.17.0 || >=20.5.0} + ssri@13.0.0: + resolution: {integrity: sha512-yizwGBpbCn4YomB2lzhZqrHLJoqFGXihNbib3ozhqF/cIp5ue+xSmOQrjNasEE62hFxsCcg/V/z23t4n8jMEng==} + engines: {node: ^20.17.0 || >=22.9.0} + stack-trace@0.0.10: resolution: {integrity: sha512-KGzahc7puUKkzyMt+IqAep+TVNbKP+k2Lmwhub39m1AsTSkaDutx56aDCo+HLDzf/D26BIHTJWNiTG1KAJiQCg==} @@ -9731,7 +9737,7 @@ snapshots: dependencies: '@babel/compat-data': 7.28.5 '@babel/helper-validator-option': 7.27.1 - browserslist: 4.27.0 + browserslist: 4.28.0 lru-cache: 5.1.1 semver: 6.3.1 @@ -10395,7 +10401,7 @@ snapshots: dependencies: '@csstools/css-tokenizer': 3.0.4 - '@csstools/css-syntax-patches-for-csstree@1.0.15': {} + '@csstools/css-syntax-patches-for-csstree@1.0.16': {} '@csstools/css-tokenizer@3.0.4': {} @@ -10422,13 +10428,13 @@ snapshots: '@discoveryjs/json-ext@0.6.3': {} - '@emnapi/core@1.7.0': + '@emnapi/core@1.7.1': dependencies: '@emnapi/wasi-threads': 1.1.0 tslib: 2.8.1 optional: true - '@emnapi/runtime@1.7.0': + '@emnapi/runtime@1.7.1': dependencies: tslib: 2.8.1 optional: true @@ -10713,7 +10719,7 @@ snapshots: globals: 14.0.0 ignore: 5.3.2 import-fresh: 3.3.1 - js-yaml: 4.1.0 + js-yaml: 4.1.1 minimatch: 3.1.2 strip-json-comments: 3.1.1 transitivePeerDependencies: @@ -11093,7 +11099,7 @@ snapshots: events-intercept: 2.0.0 extend: 3.0.2 google-auth-library: 10.5.0(supports-color@10.2.2) - google-gax: 5.0.5(supports-color@10.2.2) + google-gax: 5.0.6(supports-color@10.2.2) grpc-gcp: 1.0.1(protobufjs@7.5.4) is: 3.3.2 lodash.snakecase: 4.1.1 @@ -11128,7 +11134,7 @@ snapshots: '@grpc/grpc-js@1.9.15': dependencies: '@grpc/proto-loader': 0.7.15 - '@types/node': 22.19.0 + '@types/node': 22.19.1 '@grpc/proto-loader@0.7.15': dependencies: @@ -11159,10 +11165,10 @@ snapshots: '@inquirer/ansi@1.0.2': {} - '@inquirer/checkbox@4.3.1(@types/node@24.10.0)': + '@inquirer/checkbox@4.3.2(@types/node@24.10.0)': dependencies: '@inquirer/ansi': 1.0.2 - '@inquirer/core': 10.3.1(@types/node@24.10.0) + '@inquirer/core': 10.3.2(@types/node@24.10.0) '@inquirer/figures': 1.0.15 '@inquirer/type': 3.0.10(@types/node@24.10.0) yoctocolors-cjs: 2.1.3 @@ -11171,42 +11177,42 @@ snapshots: '@inquirer/confirm@5.1.19(@types/node@24.10.0)': dependencies: - '@inquirer/core': 10.3.1(@types/node@24.10.0) + '@inquirer/core': 10.3.2(@types/node@24.10.0) '@inquirer/type': 3.0.10(@types/node@24.10.0) optionalDependencies: '@types/node': 24.10.0 - '@inquirer/confirm@5.1.20(@types/node@24.10.0)': + '@inquirer/confirm@5.1.21(@types/node@24.10.0)': dependencies: - '@inquirer/core': 10.3.1(@types/node@24.10.0) + '@inquirer/core': 10.3.2(@types/node@24.10.0) '@inquirer/type': 3.0.10(@types/node@24.10.0) optionalDependencies: '@types/node': 24.10.0 - '@inquirer/core@10.3.1(@types/node@24.10.0)': + '@inquirer/core@10.3.2(@types/node@24.10.0)': dependencies: '@inquirer/ansi': 1.0.2 '@inquirer/figures': 1.0.15 '@inquirer/type': 3.0.10(@types/node@24.10.0) cli-width: 4.1.0 - mute-stream: 3.0.0 + mute-stream: 2.0.0 signal-exit: 4.1.0 wrap-ansi: 6.2.0 yoctocolors-cjs: 2.1.3 optionalDependencies: '@types/node': 24.10.0 - '@inquirer/editor@4.2.22(@types/node@24.10.0)': + '@inquirer/editor@4.2.23(@types/node@24.10.0)': dependencies: - '@inquirer/core': 10.3.1(@types/node@24.10.0) + '@inquirer/core': 10.3.2(@types/node@24.10.0) '@inquirer/external-editor': 1.0.3(@types/node@24.10.0) '@inquirer/type': 3.0.10(@types/node@24.10.0) optionalDependencies: '@types/node': 24.10.0 - '@inquirer/expand@4.0.22(@types/node@24.10.0)': + '@inquirer/expand@4.0.23(@types/node@24.10.0)': dependencies: - '@inquirer/core': 10.3.1(@types/node@24.10.0) + '@inquirer/core': 10.3.2(@types/node@24.10.0) '@inquirer/type': 3.0.10(@types/node@24.10.0) yoctocolors-cjs: 2.1.3 optionalDependencies: @@ -11221,79 +11227,79 @@ snapshots: '@inquirer/figures@1.0.15': {} - '@inquirer/input@4.3.0(@types/node@24.10.0)': + '@inquirer/input@4.3.1(@types/node@24.10.0)': dependencies: - '@inquirer/core': 10.3.1(@types/node@24.10.0) + '@inquirer/core': 10.3.2(@types/node@24.10.0) '@inquirer/type': 3.0.10(@types/node@24.10.0) optionalDependencies: '@types/node': 24.10.0 - '@inquirer/number@3.0.22(@types/node@24.10.0)': + '@inquirer/number@3.0.23(@types/node@24.10.0)': dependencies: - '@inquirer/core': 10.3.1(@types/node@24.10.0) + '@inquirer/core': 10.3.2(@types/node@24.10.0) '@inquirer/type': 3.0.10(@types/node@24.10.0) optionalDependencies: '@types/node': 24.10.0 - '@inquirer/password@4.0.22(@types/node@24.10.0)': + '@inquirer/password@4.0.23(@types/node@24.10.0)': dependencies: '@inquirer/ansi': 1.0.2 - '@inquirer/core': 10.3.1(@types/node@24.10.0) + '@inquirer/core': 10.3.2(@types/node@24.10.0) '@inquirer/type': 3.0.10(@types/node@24.10.0) optionalDependencies: '@types/node': 24.10.0 '@inquirer/prompts@7.10.0(@types/node@24.10.0)': dependencies: - '@inquirer/checkbox': 4.3.1(@types/node@24.10.0) - '@inquirer/confirm': 5.1.20(@types/node@24.10.0) - '@inquirer/editor': 4.2.22(@types/node@24.10.0) - '@inquirer/expand': 4.0.22(@types/node@24.10.0) - '@inquirer/input': 4.3.0(@types/node@24.10.0) - '@inquirer/number': 3.0.22(@types/node@24.10.0) - '@inquirer/password': 4.0.22(@types/node@24.10.0) - '@inquirer/rawlist': 4.1.10(@types/node@24.10.0) - '@inquirer/search': 3.2.1(@types/node@24.10.0) - '@inquirer/select': 4.4.1(@types/node@24.10.0) + '@inquirer/checkbox': 4.3.2(@types/node@24.10.0) + '@inquirer/confirm': 5.1.21(@types/node@24.10.0) + '@inquirer/editor': 4.2.23(@types/node@24.10.0) + '@inquirer/expand': 4.0.23(@types/node@24.10.0) + '@inquirer/input': 4.3.1(@types/node@24.10.0) + '@inquirer/number': 3.0.23(@types/node@24.10.0) + '@inquirer/password': 4.0.23(@types/node@24.10.0) + '@inquirer/rawlist': 4.1.11(@types/node@24.10.0) + '@inquirer/search': 3.2.2(@types/node@24.10.0) + '@inquirer/select': 4.4.2(@types/node@24.10.0) optionalDependencies: '@types/node': 24.10.0 '@inquirer/prompts@7.9.0(@types/node@24.10.0)': dependencies: - '@inquirer/checkbox': 4.3.1(@types/node@24.10.0) + '@inquirer/checkbox': 4.3.2(@types/node@24.10.0) '@inquirer/confirm': 5.1.19(@types/node@24.10.0) - '@inquirer/editor': 4.2.22(@types/node@24.10.0) - '@inquirer/expand': 4.0.22(@types/node@24.10.0) - '@inquirer/input': 4.3.0(@types/node@24.10.0) - '@inquirer/number': 3.0.22(@types/node@24.10.0) - '@inquirer/password': 4.0.22(@types/node@24.10.0) - '@inquirer/rawlist': 4.1.10(@types/node@24.10.0) - '@inquirer/search': 3.2.1(@types/node@24.10.0) - '@inquirer/select': 4.4.1(@types/node@24.10.0) + '@inquirer/editor': 4.2.23(@types/node@24.10.0) + '@inquirer/expand': 4.0.23(@types/node@24.10.0) + '@inquirer/input': 4.3.1(@types/node@24.10.0) + '@inquirer/number': 3.0.23(@types/node@24.10.0) + '@inquirer/password': 4.0.23(@types/node@24.10.0) + '@inquirer/rawlist': 4.1.11(@types/node@24.10.0) + '@inquirer/search': 3.2.2(@types/node@24.10.0) + '@inquirer/select': 4.4.2(@types/node@24.10.0) optionalDependencies: '@types/node': 24.10.0 - '@inquirer/rawlist@4.1.10(@types/node@24.10.0)': + '@inquirer/rawlist@4.1.11(@types/node@24.10.0)': dependencies: - '@inquirer/core': 10.3.1(@types/node@24.10.0) + '@inquirer/core': 10.3.2(@types/node@24.10.0) '@inquirer/type': 3.0.10(@types/node@24.10.0) yoctocolors-cjs: 2.1.3 optionalDependencies: '@types/node': 24.10.0 - '@inquirer/search@3.2.1(@types/node@24.10.0)': + '@inquirer/search@3.2.2(@types/node@24.10.0)': dependencies: - '@inquirer/core': 10.3.1(@types/node@24.10.0) + '@inquirer/core': 10.3.2(@types/node@24.10.0) '@inquirer/figures': 1.0.15 '@inquirer/type': 3.0.10(@types/node@24.10.0) yoctocolors-cjs: 2.1.3 optionalDependencies: '@types/node': 24.10.0 - '@inquirer/select@4.4.1(@types/node@24.10.0)': + '@inquirer/select@4.4.2(@types/node@24.10.0)': dependencies: '@inquirer/ansi': 1.0.2 - '@inquirer/core': 10.3.1(@types/node@24.10.0) + '@inquirer/core': 10.3.2(@types/node@24.10.0) '@inquirer/figures': 1.0.15 '@inquirer/type': 3.0.10(@types/node@24.10.0) yoctocolors-cjs: 2.1.3 @@ -11541,8 +11547,8 @@ snapshots: '@napi-rs/wasm-runtime@1.0.7': dependencies: - '@emnapi/core': 1.7.0 - '@emnapi/runtime': 1.7.0 + '@emnapi/core': 1.7.1 + '@emnapi/runtime': 1.7.1 '@tybys/wasm-util': 0.10.1 optional: true @@ -11558,16 +11564,6 @@ snapshots: '@nodelib/fs.scandir': 2.1.5 fastq: 1.19.1 - '@npmcli/agent@3.0.0': - dependencies: - agent-base: 7.1.4 - http-proxy-agent: 7.0.2 - https-proxy-agent: 7.0.6(supports-color@10.2.2) - lru-cache: 10.4.3 - socks-proxy-agent: 8.0.5 - transitivePeerDependencies: - - supports-color - '@npmcli/agent@4.0.0': dependencies: agent-base: 7.1.4 @@ -11582,16 +11578,16 @@ snapshots: dependencies: semver: 7.7.3 - '@npmcli/git@7.0.0': + '@npmcli/git@7.0.1': dependencies: - '@npmcli/promise-spawn': 8.0.3 - ini: 5.0.0 + '@npmcli/promise-spawn': 9.0.1 + ini: 6.0.0 lru-cache: 11.2.2 npm-pick-manifest: 11.0.3 - proc-log: 5.0.0 + proc-log: 6.0.0 promise-retry: 2.0.1 semver: 7.7.3 - which: 5.0.0 + which: 6.0.0 '@npmcli/installed-package-contents@3.0.0': dependencies: @@ -11602,7 +11598,7 @@ snapshots: '@npmcli/package-json@7.0.2': dependencies: - '@npmcli/git': 7.0.0 + '@npmcli/git': 7.0.1 glob: 11.0.3 hosted-git-info: 9.0.2 json-parse-even-better-errors: 5.0.0 @@ -11614,20 +11610,20 @@ snapshots: dependencies: which: 5.0.0 - '@npmcli/promise-spawn@9.0.0': + '@npmcli/promise-spawn@9.0.1': dependencies: - which: 5.0.0 + which: 6.0.0 - '@npmcli/redact@3.2.2': {} + '@npmcli/redact@4.0.0': {} - '@npmcli/run-script@10.0.2': + '@npmcli/run-script@10.0.3': dependencies: '@npmcli/node-gyp': 5.0.0 '@npmcli/package-json': 7.0.2 - '@npmcli/promise-spawn': 9.0.0 - node-gyp: 11.5.0 + '@npmcli/promise-spawn': 9.0.1 + node-gyp: 12.1.0 proc-log: 6.0.0 - which: 5.0.0 + which: 6.0.0 transitivePeerDependencies: - supports-color @@ -11635,7 +11631,7 @@ snapshots: dependencies: '@octokit/auth-oauth-app': 9.0.3 '@octokit/auth-oauth-user': 6.0.2 - '@octokit/request': 10.0.6 + '@octokit/request': 10.0.7 '@octokit/request-error': 7.0.2 '@octokit/types': 16.0.0 toad-cache: 3.7.0 @@ -11646,14 +11642,14 @@ snapshots: dependencies: '@octokit/auth-oauth-device': 8.0.3 '@octokit/auth-oauth-user': 6.0.2 - '@octokit/request': 10.0.6 + '@octokit/request': 10.0.7 '@octokit/types': 16.0.0 universal-user-agent: 7.0.3 '@octokit/auth-oauth-device@8.0.3': dependencies: '@octokit/oauth-methods': 6.0.2 - '@octokit/request': 10.0.6 + '@octokit/request': 10.0.7 '@octokit/types': 16.0.0 universal-user-agent: 7.0.3 @@ -11661,7 +11657,7 @@ snapshots: dependencies: '@octokit/auth-oauth-device': 8.0.3 '@octokit/oauth-methods': 6.0.2 - '@octokit/request': 10.0.6 + '@octokit/request': 10.0.7 '@octokit/types': 16.0.0 universal-user-agent: 7.0.3 @@ -11671,7 +11667,7 @@ snapshots: dependencies: '@octokit/auth-token': 6.0.0 '@octokit/graphql': 9.0.3 - '@octokit/request': 10.0.6 + '@octokit/request': 10.0.7 '@octokit/request-error': 7.0.2 '@octokit/types': 16.0.0 before-after-hook: 4.0.0 @@ -11689,7 +11685,7 @@ snapshots: '@octokit/graphql@9.0.3': dependencies: - '@octokit/request': 10.0.6 + '@octokit/request': 10.0.7 '@octokit/types': 16.0.0 universal-user-agent: 7.0.3 @@ -11698,7 +11694,7 @@ snapshots: '@octokit/oauth-methods@6.0.2': dependencies: '@octokit/oauth-authorization-url': 8.0.0 - '@octokit/request': 10.0.6 + '@octokit/request': 10.0.7 '@octokit/request-error': 7.0.2 '@octokit/types': 16.0.0 @@ -11722,7 +11718,7 @@ snapshots: dependencies: '@octokit/types': 16.0.0 - '@octokit/request@10.0.6': + '@octokit/request@10.0.7': dependencies: '@octokit/endpoint': 11.0.2 '@octokit/request-error': 7.0.2 @@ -12078,7 +12074,7 @@ snapshots: '@sigstore/bundle': 4.0.0 '@sigstore/core': 3.0.0 '@sigstore/protobuf-specs': 0.5.0 - make-fetch-happen: 15.0.2 + make-fetch-happen: 15.0.3 proc-log: 5.0.0 promise-retry: 2.0.1 transitivePeerDependencies: @@ -12106,7 +12102,7 @@ snapshots: '@stylistic/eslint-plugin@5.5.0(eslint@9.38.0(jiti@2.6.1))': dependencies: '@eslint-community/eslint-utils': 4.9.0(eslint@9.38.0(jiti@2.6.1)) - '@typescript-eslint/types': 8.46.3 + '@typescript-eslint/types': 8.46.4 eslint: 9.38.0(jiti@2.6.1) eslint-visitor-keys: 4.2.1 espree: 10.4.0 @@ -12121,7 +12117,7 @@ snapshots: '@tootallnate/quickjs-emscripten@0.23.0': {} - '@tsconfig/node10@1.0.11': {} + '@tsconfig/node10@1.0.12': {} '@tsconfig/node12@1.0.11': {} @@ -12143,7 +12139,7 @@ snapshots: '@types/accepts@1.3.7': dependencies: - '@types/node': 22.19.0 + '@types/node': 22.19.1 '@types/babel__code-frame@7.0.6': {} @@ -12173,16 +12169,16 @@ snapshots: '@types/body-parser@1.19.6': dependencies: '@types/connect': 3.4.38 - '@types/node': 22.19.0 + '@types/node': 22.19.1 '@types/bonjour@3.5.13': dependencies: - '@types/node': 22.19.0 + '@types/node': 22.19.1 '@types/browser-sync@2.29.1': dependencies: '@types/micromatch': 2.3.35 - '@types/node': 22.19.0 + '@types/node': 22.19.1 '@types/serve-static': 2.2.0 chokidar: 3.6.0 @@ -12193,23 +12189,23 @@ snapshots: '@types/cli-progress@3.11.6': dependencies: - '@types/node': 22.19.0 + '@types/node': 22.19.1 '@types/co-body@6.1.3': dependencies: - '@types/node': 22.19.0 + '@types/node': 22.19.1 '@types/qs': 6.14.0 '@types/command-line-args@5.2.3': {} '@types/connect-history-api-fallback@1.5.4': dependencies: - '@types/express-serve-static-core': 5.1.0 - '@types/node': 22.19.0 + '@types/express-serve-static-core': 4.19.7 + '@types/node': 22.19.1 '@types/connect@3.4.38': dependencies: - '@types/node': 22.19.0 + '@types/node': 22.19.1 '@types/content-disposition@0.5.9': {} @@ -12220,11 +12216,11 @@ snapshots: '@types/connect': 3.4.38 '@types/express': 5.0.5 '@types/keygrip': 1.0.6 - '@types/node': 22.19.0 + '@types/node': 22.19.1 '@types/cors@2.8.19': dependencies: - '@types/node': 22.19.0 + '@types/node': 22.19.1 '@types/debounce@1.2.4': {} @@ -12232,7 +12228,7 @@ snapshots: '@types/duplexify@3.6.5': dependencies: - '@types/node': 22.19.0 + '@types/node': 22.19.1 '@types/ejs@3.1.5': {} @@ -12252,14 +12248,14 @@ snapshots: '@types/express-serve-static-core@4.19.7': dependencies: - '@types/node': 22.19.0 + '@types/node': 22.19.1 '@types/qs': 6.14.0 '@types/range-parser': 1.2.7 '@types/send': 1.2.1 '@types/express-serve-static-core@5.1.0': dependencies: - '@types/node': 22.19.0 + '@types/node': 22.19.1 '@types/qs': 6.14.0 '@types/range-parser': 1.2.7 '@types/send': 1.2.1 @@ -12281,11 +12277,11 @@ snapshots: '@types/git-raw-commits@5.0.1': dependencies: - '@types/node': 22.19.0 + '@types/node': 22.19.1 '@types/graceful-fs@4.1.9': dependencies: - '@types/node': 22.19.0 + '@types/node': 22.19.1 '@types/http-assert@1.5.6': {} @@ -12293,7 +12289,7 @@ snapshots: '@types/http-proxy@1.17.17': dependencies: - '@types/node': 22.19.0 + '@types/node': 22.19.1 '@types/ini@4.1.1': {} @@ -12309,17 +12305,19 @@ snapshots: '@types/jasmine-reporters@2.5.3': dependencies: - '@types/jasmine': 5.1.12 + '@types/jasmine': 5.1.13 '@types/jasmine@5.1.12': {} + '@types/jasmine@5.1.13': {} + '@types/json-schema@7.0.15': {} '@types/json5@0.0.29': {} '@types/karma@6.3.9': dependencies: - '@types/node': 22.19.0 + '@types/node': 22.19.1 log4js: 6.9.1 transitivePeerDependencies: - supports-color @@ -12339,13 +12337,13 @@ snapshots: '@types/http-errors': 2.0.5 '@types/keygrip': 1.0.6 '@types/koa-compose': 3.2.9 - '@types/node': 22.19.0 + '@types/node': 22.19.1 '@types/less@3.0.8': {} '@types/loader-utils@3.0.0(esbuild@0.26.0)': dependencies: - '@types/node': 22.19.0 + '@types/node': 22.19.1 webpack: 5.102.1(esbuild@0.26.0) transitivePeerDependencies: - '@swc/core' @@ -12363,14 +12361,14 @@ snapshots: '@types/node-fetch@2.6.13': dependencies: - '@types/node': 22.19.0 + '@types/node': 22.19.1 form-data: 4.0.4 '@types/node-forge@1.3.14': dependencies: - '@types/node': 22.19.0 + '@types/node': 22.19.1 - '@types/node@22.19.0': + '@types/node@22.19.1': dependencies: undici-types: 7.16.0 @@ -12382,7 +12380,7 @@ snapshots: '@types/npm-registry-fetch@8.0.9': dependencies: - '@types/node': 22.19.0 + '@types/node': 22.19.1 '@types/node-fetch': 2.6.13 '@types/npm-package-arg': 6.1.4 '@types/npmlog': 7.0.0 @@ -12390,11 +12388,11 @@ snapshots: '@types/npmlog@7.0.0': dependencies: - '@types/node': 22.19.0 + '@types/node': 22.19.1 '@types/pacote@11.1.8': dependencies: - '@types/node': 22.19.0 + '@types/node': 22.19.1 '@types/npm-registry-fetch': 8.0.9 '@types/npmlog': 7.0.0 '@types/ssri': 7.1.5 @@ -12407,12 +12405,12 @@ snapshots: '@types/progress@2.0.7': dependencies: - '@types/node': 22.19.0 + '@types/node': 22.19.1 '@types/pumpify@1.4.5': dependencies: '@types/duplexify': 3.6.5 - '@types/node': 22.19.0 + '@types/node': 22.19.1 '@types/q@0.0.32': {} @@ -12426,7 +12424,7 @@ snapshots: '@types/responselike@1.0.0': dependencies: - '@types/node': 22.19.0 + '@types/node': 22.19.1 '@types/retry@0.12.2': {} @@ -12437,11 +12435,11 @@ snapshots: '@types/send@0.17.6': dependencies: '@types/mime': 1.3.5 - '@types/node': 22.19.0 + '@types/node': 22.19.1 '@types/send@1.2.1': dependencies: - '@types/node': 22.19.0 + '@types/node': 22.19.1 '@types/serve-index@1.9.4': dependencies: @@ -12450,38 +12448,38 @@ snapshots: '@types/serve-static@1.15.10': dependencies: '@types/http-errors': 2.0.5 - '@types/node': 22.19.0 + '@types/node': 22.19.1 '@types/send': 0.17.6 '@types/serve-static@2.2.0': dependencies: '@types/http-errors': 2.0.5 - '@types/node': 22.19.0 + '@types/node': 22.19.1 '@types/sockjs@0.3.36': dependencies: - '@types/node': 22.19.0 + '@types/node': 22.19.1 '@types/ssri@7.1.5': dependencies: - '@types/node': 22.19.0 + '@types/node': 22.19.1 '@types/stack-trace@0.0.33': {} - '@types/watchpack@2.4.4': + '@types/watchpack@2.4.5': dependencies: '@types/graceful-fs': 4.1.9 - '@types/node': 22.19.0 + '@types/node': 22.19.1 '@types/which@3.0.4': {} '@types/ws@7.4.7': dependencies: - '@types/node': 22.19.0 + '@types/node': 22.19.1 '@types/ws@8.18.1': dependencies: - '@types/node': 22.19.0 + '@types/node': 22.19.1 '@types/yargs-parser@21.0.3': {} @@ -12489,11 +12487,15 @@ snapshots: dependencies: '@types/yargs-parser': 21.0.3 + '@types/yargs@17.0.35': + dependencies: + '@types/yargs-parser': 21.0.3 + '@types/yarnpkg__lockfile@1.1.9': {} '@types/yauzl@2.10.3': dependencies: - '@types/node': 22.19.0 + '@types/node': 22.19.1 optional: true '@typescript-eslint/eslint-plugin@8.46.2(@typescript-eslint/parser@8.46.2(eslint@9.38.0(jiti@2.6.1))(typescript@5.9.3))(eslint@9.38.0(jiti@2.6.1))(typescript@5.9.3)': @@ -12557,7 +12559,7 @@ snapshots: '@typescript-eslint/types@8.46.2': {} - '@typescript-eslint/types@8.46.3': {} + '@typescript-eslint/types@8.46.4': {} '@typescript-eslint/typescript-estree@8.46.2(typescript@5.9.3)': dependencies: @@ -12778,7 +12780,7 @@ snapshots: '@types/chai': 5.2.3 '@vitest/spy': 4.0.8 '@vitest/utils': 4.0.8 - chai: 6.2.0 + chai: 6.2.1 tinyrainbow: 3.0.3 '@vitest/mocker@4.0.8(vite@7.2.2(@types/node@24.10.0)(jiti@2.6.1)(less@4.4.2)(sass@1.93.2)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1))': @@ -12827,7 +12829,7 @@ snapshots: es-module-lexer: 1.7.0 get-stream: 6.0.1 is-stream: 2.0.1 - isbinaryfile: 5.0.6 + isbinaryfile: 5.0.7 koa: 2.16.3 koa-etag: 4.0.0 koa-send: 5.0.1 @@ -12886,7 +12888,7 @@ snapshots: '@web/test-runner-core': 0.13.4(bufferutil@4.0.9) '@web/test-runner-coverage-v8': 0.8.0(bufferutil@4.0.9) chrome-launcher: 0.15.2 - puppeteer-core: 24.29.1(bufferutil@4.0.9) + puppeteer-core: 24.30.0(bufferutil@4.0.9) transitivePeerDependencies: - bare-abort-controller - bare-buffer @@ -13072,7 +13074,7 @@ snapshots: jsonparse: 1.3.1 through: 2.3.8 - abbrev@3.0.1: {} + abbrev@4.0.0: {} abort-controller@3.0.0: dependencies: @@ -13310,8 +13312,8 @@ snapshots: autoprefixer@10.4.21(postcss@8.5.6): dependencies: - browserslist: 4.27.0 - caniuse-lite: 1.0.30001754 + browserslist: 4.28.0 + caniuse-lite: 1.0.30001755 fraction.js: 4.3.7 normalize-range: 0.1.2 picocolors: 1.1.1 @@ -13401,7 +13403,7 @@ snapshots: base64id@2.0.0: {} - baseline-browser-mapping@2.8.25: {} + baseline-browser-mapping@2.8.28: {} basic-ftp@5.0.5: {} @@ -13561,13 +13563,13 @@ snapshots: dependencies: pako: 0.2.9 - browserslist@4.27.0: + browserslist@4.28.0: dependencies: - baseline-browser-mapping: 2.8.25 - caniuse-lite: 1.0.30001754 - electron-to-chromium: 1.5.249 + baseline-browser-mapping: 2.8.28 + caniuse-lite: 1.0.30001755 + electron-to-chromium: 1.5.254 node-releases: 2.0.27 - update-browserslist-db: 1.1.4(browserslist@4.27.0) + update-browserslist-db: 1.1.4(browserslist@4.28.0) browserstack@1.6.1: dependencies: @@ -13603,21 +13605,6 @@ snapshots: bytes@3.1.2: {} - cacache@19.0.1: - dependencies: - '@npmcli/fs': 4.0.0 - fs-minipass: 3.0.3 - glob: 10.4.5 - lru-cache: 10.4.3 - minipass: 7.1.2 - minipass-collect: 2.0.1 - minipass-flush: 1.0.5 - minipass-pipeline: 1.2.4 - p-map: 7.0.3 - ssri: 12.0.0 - tar: 7.5.2 - unique-filename: 4.0.0 - cacache@20.0.1: dependencies: '@npmcli/fs': 4.0.0 @@ -13628,7 +13615,7 @@ snapshots: minipass-collect: 2.0.1 minipass-flush: 1.0.5 minipass-pipeline: 1.2.4 - p-map: 7.0.3 + p-map: 7.0.4 ssri: 12.0.0 unique-filename: 4.0.0 @@ -13672,11 +13659,11 @@ snapshots: camelcase@6.3.0: {} - caniuse-lite@1.0.30001754: {} + caniuse-lite@1.0.30001755: {} caseless@0.12.0: {} - chai@6.2.0: {} + chai@6.2.1: {} chalk-template@0.4.0: dependencies: @@ -13729,7 +13716,7 @@ snapshots: chrome-launcher@0.15.2: dependencies: - '@types/node': 22.19.0 + '@types/node': 22.19.1 escape-string-regexp: 4.0.0 is-wsl: 2.2.0 lighthouse-logger: 1.4.2 @@ -13738,7 +13725,7 @@ snapshots: chrome-trace-event@1.0.4: {} - chromium-bidi@10.5.1(devtools-protocol@0.0.1521046): + chromium-bidi@11.0.0(devtools-protocol@0.0.1521046): dependencies: devtools-protocol: 0.0.1521046 mitt: 3.0.1 @@ -13943,7 +13930,7 @@ snapshots: core-js-compat@3.46.0: dependencies: - browserslist: 4.27.0 + browserslist: 4.28.0 core-util-is@1.0.2: {} @@ -13958,7 +13945,7 @@ snapshots: dependencies: env-paths: 2.2.1 import-fresh: 3.3.1 - js-yaml: 4.1.0 + js-yaml: 4.1.1 parse-json: 5.2.0 optionalDependencies: typescript: 5.9.3 @@ -14016,7 +14003,7 @@ snapshots: cssstyle@5.3.3: dependencies: '@asamuzakjp/css-color': 4.0.5 - '@csstools/css-syntax-patches-for-csstree': 1.0.15 + '@csstools/css-syntax-patches-for-csstree': 1.0.16 css-tree: 3.1.0 custom-event@1.0.1: {} @@ -14104,12 +14091,12 @@ snapshots: deepmerge@4.3.1: {} - default-browser-id@5.0.0: {} + default-browser-id@5.0.1: {} - default-browser@5.2.1: + default-browser@5.4.0: dependencies: bundle-name: 4.1.0 - default-browser-id: 5.0.0 + default-browser-id: 5.0.1 default-gateway@6.0.3: dependencies: @@ -14267,7 +14254,7 @@ snapshots: dependencies: jake: 10.9.4 - electron-to-chromium@1.5.249: {} + electron-to-chromium@1.5.254: {} emoji-regex@10.6.0: {} @@ -14306,7 +14293,7 @@ snapshots: engine.io@6.6.4(bufferutil@4.0.9)(utf-8-validate@6.0.5): dependencies: '@types/cors': 2.8.19 - '@types/node': 22.19.0 + '@types/node': 22.19.1 accepts: 1.3.8 base64id: 2.0.0 cookie: 0.7.2 @@ -14807,7 +14794,7 @@ snapshots: extract-zip@2.0.1: dependencies: - debug: 4.4.3(supports-color@10.2.2) + debug: 4.3.4 get-stream: 5.2.0 yauzl: 2.10.0 optionalDependencies: @@ -15080,7 +15067,7 @@ snapshots: gcp-metadata@8.1.2(supports-color@10.2.2): dependencies: gaxios: 7.1.3(supports-color@10.2.2) - google-logging-utils: 1.1.2 + google-logging-utils: 1.1.3 json-bigint: 1.0.0 transitivePeerDependencies: - supports-color @@ -15223,19 +15210,19 @@ snapshots: ecdsa-sig-formatter: 1.0.11 gaxios: 7.1.3(supports-color@10.2.2) gcp-metadata: 8.1.2(supports-color@10.2.2) - google-logging-utils: 1.1.2 + google-logging-utils: 1.1.3 gtoken: 8.0.0(supports-color@10.2.2) jws: 4.0.0 transitivePeerDependencies: - supports-color - google-gax@5.0.5(supports-color@10.2.2): + google-gax@5.0.6(supports-color@10.2.2): dependencies: '@grpc/grpc-js': 1.14.1 '@grpc/proto-loader': 0.8.0 duplexify: 4.1.3 google-auth-library: 10.5.0(supports-color@10.2.2) - google-logging-utils: 1.1.2 + google-logging-utils: 1.1.3 node-fetch: 3.3.2 object-hash: 3.0.0 proto3-json-serializer: 3.0.4 @@ -15245,7 +15232,7 @@ snapshots: transitivePeerDependencies: - supports-color - google-logging-utils@1.1.2: {} + google-logging-utils@1.1.3: {} gopd@1.2.0: {} @@ -15551,6 +15538,8 @@ snapshots: ini@5.0.0: {} + ini@6.0.0: {} + injection-js@2.6.1: dependencies: tslib: 2.8.1 @@ -15782,7 +15771,7 @@ snapshots: isbinaryfile@4.0.10: {} - isbinaryfile@5.0.6: {} + isbinaryfile@5.0.7: {} isexe@2.0.0: {} @@ -15887,7 +15876,7 @@ snapshots: jest-worker@27.5.1: dependencies: - '@types/node': 22.19.0 + '@types/node': 22.19.1 merge-stream: 2.0.0 supports-color: 8.1.1 @@ -15903,6 +15892,10 @@ snapshots: dependencies: argparse: 2.0.1 + js-yaml@4.1.1: + dependencies: + argparse: 2.0.1 + jsbn@0.1.1: {} jsdom@27.1.0(bufferutil@4.0.9)(utf-8-validate@6.0.5): @@ -16359,35 +16352,19 @@ snapshots: make-error@1.3.6: {} - make-fetch-happen@14.0.3: - dependencies: - '@npmcli/agent': 3.0.0 - cacache: 19.0.1 - http-cache-semantics: 4.2.0 - minipass: 7.1.2 - minipass-fetch: 4.0.1 - minipass-flush: 1.0.5 - minipass-pipeline: 1.2.4 - negotiator: 1.0.0 - proc-log: 5.0.0 - promise-retry: 2.0.1 - ssri: 12.0.0 - transitivePeerDependencies: - - supports-color - - make-fetch-happen@15.0.2: + make-fetch-happen@15.0.3: dependencies: '@npmcli/agent': 4.0.0 cacache: 20.0.1 http-cache-semantics: 4.2.0 minipass: 7.1.2 - minipass-fetch: 4.0.1 + minipass-fetch: 5.0.0 minipass-flush: 1.0.5 minipass-pipeline: 1.2.4 negotiator: 1.0.0 - proc-log: 5.0.0 + proc-log: 6.0.0 promise-retry: 2.0.1 - ssri: 12.0.0 + ssri: 13.0.0 transitivePeerDependencies: - supports-color @@ -16401,7 +16378,7 @@ snapshots: media-typer@1.1.0: {} - memfs@4.50.0: + memfs@4.51.0: dependencies: '@jsonjoy.com/json-pack': 1.21.0(tslib@2.8.1) '@jsonjoy.com/util': 1.9.0(tslib@2.8.1) @@ -16487,7 +16464,7 @@ snapshots: dependencies: minipass: 7.1.2 - minipass-fetch@4.0.1: + minipass-fetch@5.0.0: dependencies: minipass: 7.1.2 minipass-sized: 1.0.3 @@ -16565,7 +16542,7 @@ snapshots: array-union: 3.0.1 minimatch: 9.0.5 - mute-stream@3.0.0: {} + mute-stream@2.0.0: {} nanocolors@0.2.13: {} @@ -16597,7 +16574,7 @@ snapshots: '@rollup/wasm-node': 4.53.2 ajv: 8.17.1 ansi-colors: 4.1.3 - browserslist: 4.27.0 + browserslist: 4.28.0 chokidar: 4.0.3 commander: 14.0.2 dependency-graph: 1.0.0 @@ -16661,26 +16638,26 @@ snapshots: node-gyp-build@4.8.4: {} - node-gyp@11.5.0: + node-gyp@12.1.0: dependencies: env-paths: 2.2.1 exponential-backoff: 3.1.3 graceful-fs: 4.2.11 - make-fetch-happen: 14.0.3 - nopt: 8.1.0 - proc-log: 5.0.0 + make-fetch-happen: 15.0.3 + nopt: 9.0.0 + proc-log: 6.0.0 semver: 7.7.3 tar: 7.5.2 tinyglobby: 0.2.15 - which: 5.0.0 + which: 6.0.0 transitivePeerDependencies: - supports-color node-releases@2.0.27: {} - nopt@8.1.0: + nopt@9.0.0: dependencies: - abbrev: 3.0.1 + abbrev: 4.0.0 normalize-path@3.0.0: {} @@ -16719,16 +16696,16 @@ snapshots: npm-package-arg: 13.0.1 semver: 7.7.3 - npm-registry-fetch@19.1.0: + npm-registry-fetch@19.1.1: dependencies: - '@npmcli/redact': 3.2.2 + '@npmcli/redact': 4.0.0 jsonparse: 1.3.1 - make-fetch-happen: 15.0.2 + make-fetch-happen: 15.0.3 minipass: 7.1.2 - minipass-fetch: 4.0.1 + minipass-fetch: 5.0.0 minizlib: 3.1.0 npm-package-arg: 13.0.1 - proc-log: 5.0.0 + proc-log: 6.0.0 transitivePeerDependencies: - supports-color @@ -16809,7 +16786,7 @@ snapshots: open@10.2.0: dependencies: - default-browser: 5.2.1 + default-browser: 5.4.0 define-lazy-prop: 3.0.0 is-inside-container: 1.0.0 wsl-utils: 0.1.0 @@ -16882,7 +16859,7 @@ snapshots: dependencies: p-limit: 3.1.0 - p-map@7.0.3: {} + p-map@7.0.4: {} p-queue@6.6.2: dependencies: @@ -16923,18 +16900,18 @@ snapshots: pacote@21.0.3: dependencies: - '@npmcli/git': 7.0.0 + '@npmcli/git': 7.0.1 '@npmcli/installed-package-contents': 3.0.0 '@npmcli/package-json': 7.0.2 '@npmcli/promise-spawn': 8.0.3 - '@npmcli/run-script': 10.0.2 + '@npmcli/run-script': 10.0.3 cacache: 20.0.1 fs-minipass: 3.0.3 minipass: 7.1.2 npm-package-arg: 13.0.1 npm-packlist: 10.0.3 npm-pick-manifest: 11.0.3 - npm-registry-fetch: 19.1.0 + npm-registry-fetch: 19.1.1 proc-log: 5.0.0 promise-retry: 2.0.1 sigstore: 4.0.0 @@ -17176,7 +17153,7 @@ snapshots: '@protobufjs/path': 1.1.2 '@protobufjs/pool': 1.1.0 '@protobufjs/utf8': 1.1.0 - '@types/node': 22.19.0 + '@types/node': 22.19.1 long: 5.3.2 protractor@7.0.0: @@ -17264,10 +17241,10 @@ snapshots: - supports-color - utf-8-validate - puppeteer-core@24.29.1(bufferutil@4.0.9): + puppeteer-core@24.30.0(bufferutil@4.0.9): dependencies: '@puppeteer/browsers': 2.10.13 - chromium-bidi: 10.5.1(devtools-protocol@0.0.1521046) + chromium-bidi: 11.0.0(devtools-protocol@0.0.1521046) debug: 4.4.3(supports-color@10.2.2) devtools-protocol: 0.0.1521046 typed-query-selector: 2.12.0 @@ -17575,12 +17552,12 @@ snapshots: optionalDependencies: '@babel/code-frame': 7.27.1 - rollup-plugin-sourcemaps2@0.5.4(@types/node@22.19.0)(rollup@4.52.5): + rollup-plugin-sourcemaps2@0.5.4(@types/node@22.19.1)(rollup@4.52.5): dependencies: '@rollup/pluginutils': 5.2.0(rollup@4.52.5) rollup: 4.52.5 optionalDependencies: - '@types/node': 22.19.0 + '@types/node': 22.19.1 rollup@4.52.5: dependencies: @@ -18066,6 +18043,10 @@ snapshots: dependencies: minipass: 7.1.2 + ssri@13.0.0: + dependencies: + minipass: 7.1.2 + stack-trace@0.0.10: {} stackback@0.0.2: {} @@ -18388,14 +18369,14 @@ snapshots: dependencies: typescript: 5.9.3 - ts-node@10.9.2(@types/node@22.19.0)(typescript@5.9.3): + ts-node@10.9.2(@types/node@22.19.1)(typescript@5.9.3): dependencies: '@cspotcode/source-map-support': 0.8.1 - '@tsconfig/node10': 1.0.11 + '@tsconfig/node10': 1.0.12 '@tsconfig/node12': 1.0.11 '@tsconfig/node14': 1.0.3 '@tsconfig/node16': 1.0.4 - '@types/node': 22.19.0 + '@types/node': 22.19.1 acorn: 8.15.0 acorn-walk: 8.3.4 arg: 4.1.3 @@ -18428,7 +18409,7 @@ snapshots: dependencies: '@tufjs/models': 4.0.0 debug: 4.4.3(supports-color@10.2.2) - make-fetch-happen: 15.0.2 + make-fetch-happen: 15.0.3 transitivePeerDependencies: - supports-color @@ -18578,9 +18559,9 @@ snapshots: unpipe@1.0.0: {} - update-browserslist-db@1.1.4(browserslist@4.27.0): + update-browserslist-db@1.1.4(browserslist@4.28.0): dependencies: - browserslist: 4.27.0 + browserslist: 4.28.0 escalade: 3.2.0 picocolors: 1.1.1 @@ -18804,7 +18785,7 @@ snapshots: webpack-dev-middleware@7.4.5(webpack@5.102.1(esbuild@0.26.0)): dependencies: colorette: 2.0.20 - memfs: 4.50.0 + memfs: 4.51.0 mime-types: 3.0.1 on-finished: 2.4.1 range-parser: 1.2.1 @@ -18873,7 +18854,7 @@ snapshots: '@webassemblyjs/wasm-parser': 1.14.1 acorn: 8.15.0 acorn-import-phases: 1.0.4(acorn@8.15.0) - browserslist: 4.27.0 + browserslist: 4.28.0 chrome-trace-event: 1.0.4 enhanced-resolve: 5.18.3 es-module-lexer: 1.7.0 From d097df2d7088dd2bb97643c3acfc1f977a767dd9 Mon Sep 17 00:00:00 2001 From: Charles Lyding <19598772+clydin@users.noreply.github.com> Date: Tue, 18 Nov 2025 23:03:09 -0500 Subject: [PATCH 20/54] fix(@angular/build): correct Vitest coverage path resolution for JSDOM on Windows This commit addresses an issue where Vitest coverage reports were incomplete on Windows when using the JSDOM test environment. The root cause is an improperly formatted absolute path that can result from manually converting a file URL back to a path on Windows, leading to a superfluous leading slash (e.g., '/D:/path' instead of 'D:/path'). The 'angular:test-in-memory-provider' plugin now explicitly detects and removes this leading slash from absolute Windows paths, thereby correcting the path format and enabling proper source file mapping for coverage collection. (cherry picked from commit 3020b5066a8a41d051f2254205929648529a8daa) --- .../unit-test/runners/vitest/plugins.ts | 27 +++++++++++++++++++ .../tests/vitest/larger-project-coverage.ts | 16 +++++------ 2 files changed, 33 insertions(+), 10 deletions(-) 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 d614d16f97b8..93ef7cfb9f85 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 @@ -9,6 +9,7 @@ import assert from 'node:assert'; import { readFile } from 'node:fs/promises'; import { createRequire } from 'node:module'; +import { platform } from 'node:os'; import path from 'node:path'; import type { BrowserConfigOptions, @@ -173,6 +174,7 @@ async function loadResultFile(file: ResultFile): Promise { export function createVitestPlugins(pluginOptions: PluginOptions): VitestPlugins { const { workspaceRoot, buildResultFiles, testFileToEntryPoint } = pluginOptions; + const isWindows = platform() === 'win32'; return [ { @@ -184,6 +186,31 @@ export function createVitestPlugins(pluginOptions: PluginOptions): VitestPlugins return id; } + // Workaround for Vitest in Windows when a fully qualified absolute path is provided with + // a superfluous leading slash. This can currently occur with the `@vitest/coverage-v8` provider + // when it uses `removeStartsWith(url, FILE_PROTOCOL)` to convert a file URL resulting in + // `/D:/tmp_dir/...` instead of `D:/tmp_dir/...`. + if (id[0] === '/' && isWindows) { + const slicedId = id.slice(1); + if (path.isAbsolute(slicedId)) { + return slicedId; + } + } + + if (importer && (id[0] === '.' || id[0] === '/')) { + let fullPath; + if (testFileToEntryPoint.has(importer)) { + fullPath = toPosixPath(path.join(workspaceRoot, id)); + } else { + fullPath = toPosixPath(path.join(path.dirname(importer), id)); + } + + const relativePath = path.relative(workspaceRoot, fullPath); + if (buildResultFiles.has(toPosixPath(relativePath))) { + return fullPath; + } + } + // Determine the base directory for resolution. let baseDir: string; if (importer) { diff --git a/tests/legacy-cli/e2e/tests/vitest/larger-project-coverage.ts b/tests/legacy-cli/e2e/tests/vitest/larger-project-coverage.ts index 4b5d5cc72bfa..3594bdc7dfee 100644 --- a/tests/legacy-cli/e2e/tests/vitest/larger-project-coverage.ts +++ b/tests/legacy-cli/e2e/tests/vitest/larger-project-coverage.ts @@ -36,16 +36,12 @@ export default async function () { const { stdout: jsdomStdout } = await ng('test', '--no-watch', '--coverage'); assert.match(jsdomStdout, expectedMessage, `Expected ${totalTests} tests to pass in JSDOM mode.`); - // TODO: Investigate why coverage-final.json is empty on Windows in JSDOM mode. - // For now, skip the coverage report check on Windows. - if (process.platform !== 'win32') { - // Assert that every generated file is in the coverage report by reading the JSON output. - const jsdomSummary = JSON.parse(await readFile(coverageJsonPath)); - const jsdomSummaryKeys = Object.keys(jsdomSummary); - for (const file of generatedFiles) { - const found = jsdomSummaryKeys.some((key) => key.endsWith(file)); - assert.ok(found, `Expected ${file} to be in the JSDOM coverage report.`); - } + // Assert that every generated file is in the coverage report by reading the JSON output. + const jsdomSummary = JSON.parse(await readFile(coverageJsonPath)); + const jsdomSummaryKeys = Object.keys(jsdomSummary); + for (const file of generatedFiles) { + const found = jsdomSummaryKeys.some((key) => key.endsWith(file)); + assert.ok(found, `Expected ${file} to be in the JSDOM coverage report.`); } // Setup for browser mode From dc61d4047821f31cfc3e48e91b0f3f87e8ef024e Mon Sep 17 00:00:00 2001 From: Angular Robot Date: Wed, 19 Nov 2025 22:38:25 +0000 Subject: [PATCH 21/54] 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 | 4 +- .github/workflows/feature-requests.yml | 2 +- .github/workflows/perf.yml | 6 +- .github/workflows/pr.yml | 44 +- MODULE.bazel | 2 +- MODULE.bazel.lock | 28 +- package.json | 6 +- pnpm-lock.yaml | 736 +++++++++++------- 10 files changed, 548 insertions(+), 334 deletions(-) diff --git a/.github/workflows/assistant-to-the-branch-manager.yml b/.github/workflows/assistant-to-the-branch-manager.yml index 6bab3ffca674..6df4ef55c1e0 100644 --- a/.github/workflows/assistant-to-the-branch-manager.yml +++ b/.github/workflows/assistant-to-the-branch-manager.yml @@ -16,6 +16,6 @@ jobs: - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 with: persist-credentials: false - - uses: angular/dev-infra/github-actions/branch-manager@c855fffb4b01bc06e743eb3bdfd54c866af09ad8 + - uses: angular/dev-infra/github-actions/branch-manager@f47684669736e28fd77eab64e65b2952c8a948ee with: angular-robot-key: ${{ secrets.ANGULAR_ROBOT_PRIVATE_KEY }} diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 53ddd5e6d58a..7f8082f2e5c2 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@c855fffb4b01bc06e743eb3bdfd54c866af09ad8 + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@f47684669736e28fd77eab64e65b2952c8a948ee - name: Setup Bazel - uses: angular/dev-infra/github-actions/bazel/setup@c855fffb4b01bc06e743eb3bdfd54c866af09ad8 + uses: angular/dev-infra/github-actions/bazel/setup@f47684669736e28fd77eab64e65b2952c8a948ee - 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@c855fffb4b01bc06e743eb3bdfd54c866af09ad8 + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@f47684669736e28fd77eab64e65b2952c8a948ee - name: Setup Bazel - uses: angular/dev-infra/github-actions/bazel/setup@c855fffb4b01bc06e743eb3bdfd54c866af09ad8 + uses: angular/dev-infra/github-actions/bazel/setup@f47684669736e28fd77eab64e65b2952c8a948ee - name: Setup Bazel RBE - uses: angular/dev-infra/github-actions/bazel/configure-remote@c855fffb4b01bc06e743eb3bdfd54c866af09ad8 + uses: angular/dev-infra/github-actions/bazel/configure-remote@f47684669736e28fd77eab64e65b2952c8a948ee 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@c855fffb4b01bc06e743eb3bdfd54c866af09ad8 + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@f47684669736e28fd77eab64e65b2952c8a948ee - name: Setup Bazel - uses: angular/dev-infra/github-actions/bazel/setup@c855fffb4b01bc06e743eb3bdfd54c866af09ad8 + uses: angular/dev-infra/github-actions/bazel/setup@f47684669736e28fd77eab64e65b2952c8a948ee - name: Setup Bazel RBE - uses: angular/dev-infra/github-actions/bazel/configure-remote@c855fffb4b01bc06e743eb3bdfd54c866af09ad8 + uses: angular/dev-infra/github-actions/bazel/configure-remote@f47684669736e28fd77eab64e65b2952c8a948ee with: google_credential: ${{ secrets.RBE_TRUSTED_BUILDS_USER }} - name: Install node modules @@ -85,13 +85,13 @@ jobs: runs-on: ${{ matrix.os }} steps: - name: Initialize environment - uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@c855fffb4b01bc06e743eb3bdfd54c866af09ad8 + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@f47684669736e28fd77eab64e65b2952c8a948ee - name: Install node modules run: pnpm install --frozen-lockfile - name: Setup Bazel - uses: angular/dev-infra/github-actions/bazel/setup@c855fffb4b01bc06e743eb3bdfd54c866af09ad8 + uses: angular/dev-infra/github-actions/bazel/setup@f47684669736e28fd77eab64e65b2952c8a948ee - name: Setup Bazel RBE - uses: angular/dev-infra/github-actions/bazel/configure-remote@c855fffb4b01bc06e743eb3bdfd54c866af09ad8 + uses: angular/dev-infra/github-actions/bazel/configure-remote@f47684669736e28fd77eab64e65b2952c8a948ee with: google_credential: ${{ secrets.RBE_TRUSTED_BUILDS_USER }} - name: Run CLI E2E tests @@ -101,11 +101,11 @@ jobs: runs-on: ubuntu-latest steps: - name: Initialize environment - uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@c855fffb4b01bc06e743eb3bdfd54c866af09ad8 + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@f47684669736e28fd77eab64e65b2952c8a948ee - name: Setup Bazel - uses: angular/dev-infra/github-actions/bazel/setup@c855fffb4b01bc06e743eb3bdfd54c866af09ad8 + uses: angular/dev-infra/github-actions/bazel/setup@f47684669736e28fd77eab64e65b2952c8a948ee - name: Setup Bazel RBE - uses: angular/dev-infra/github-actions/bazel/configure-remote@c855fffb4b01bc06e743eb3bdfd54c866af09ad8 + uses: angular/dev-infra/github-actions/bazel/configure-remote@f47684669736e28fd77eab64e65b2952c8a948ee with: google_credential: ${{ secrets.RBE_TRUSTED_BUILDS_USER }} - name: Install node modules @@ -139,7 +139,7 @@ jobs: runs-on: ${{ matrix.os }} steps: - name: Initialize environment - uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@c855fffb4b01bc06e743eb3bdfd54c866af09ad8 + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@f47684669736e28fd77eab64e65b2952c8a948ee - name: Install node modules run: pnpm install --frozen-lockfile - name: Download built Windows E2E tests @@ -167,13 +167,13 @@ jobs: runs-on: ${{ matrix.os }} steps: - name: Initialize environment - uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@c855fffb4b01bc06e743eb3bdfd54c866af09ad8 + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@f47684669736e28fd77eab64e65b2952c8a948ee - name: Install node modules run: pnpm install --frozen-lockfile - name: Setup Bazel - uses: angular/dev-infra/github-actions/bazel/setup@c855fffb4b01bc06e743eb3bdfd54c866af09ad8 + uses: angular/dev-infra/github-actions/bazel/setup@f47684669736e28fd77eab64e65b2952c8a948ee - name: Setup Bazel RBE - uses: angular/dev-infra/github-actions/bazel/configure-remote@c855fffb4b01bc06e743eb3bdfd54c866af09ad8 + uses: angular/dev-infra/github-actions/bazel/configure-remote@f47684669736e28fd77eab64e65b2952c8a948ee with: google_credential: ${{ secrets.RBE_TRUSTED_BUILDS_USER }} - name: Run CLI E2E tests @@ -192,13 +192,13 @@ jobs: runs-on: ${{ matrix.os }} steps: - name: Initialize environment - uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@c855fffb4b01bc06e743eb3bdfd54c866af09ad8 + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@f47684669736e28fd77eab64e65b2952c8a948ee - name: Install node modules run: pnpm install --frozen-lockfile - name: Setup Bazel - uses: angular/dev-infra/github-actions/bazel/setup@c855fffb4b01bc06e743eb3bdfd54c866af09ad8 + uses: angular/dev-infra/github-actions/bazel/setup@f47684669736e28fd77eab64e65b2952c8a948ee - name: Setup Bazel RBE - uses: angular/dev-infra/github-actions/bazel/configure-remote@c855fffb4b01bc06e743eb3bdfd54c866af09ad8 + uses: angular/dev-infra/github-actions/bazel/configure-remote@f47684669736e28fd77eab64e65b2952c8a948ee with: google_credential: ${{ secrets.RBE_TRUSTED_BUILDS_USER }} - name: Run CLI E2E tests @@ -212,13 +212,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@c855fffb4b01bc06e743eb3bdfd54c866af09ad8 + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@f47684669736e28fd77eab64e65b2952c8a948ee - name: Install node modules run: pnpm install --frozen-lockfile - name: Setup Bazel - uses: angular/dev-infra/github-actions/bazel/setup@c855fffb4b01bc06e743eb3bdfd54c866af09ad8 + uses: angular/dev-infra/github-actions/bazel/setup@f47684669736e28fd77eab64e65b2952c8a948ee - name: Setup Bazel RBE - uses: angular/dev-infra/github-actions/bazel/configure-remote@c855fffb4b01bc06e743eb3bdfd54c866af09ad8 + uses: angular/dev-infra/github-actions/bazel/configure-remote@f47684669736e28fd77eab64e65b2952c8a948ee with: google_credential: ${{ secrets.RBE_TRUSTED_BUILDS_USER }} - name: Run E2E Browser tests @@ -248,11 +248,11 @@ jobs: CIRCLE_BRANCH: ${{ github.ref_name }} steps: - name: Initialize environment - uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@c855fffb4b01bc06e743eb3bdfd54c866af09ad8 + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@f47684669736e28fd77eab64e65b2952c8a948ee - name: Install node modules run: pnpm install --frozen-lockfile - name: Setup Bazel - uses: angular/dev-infra/github-actions/bazel/setup@c855fffb4b01bc06e743eb3bdfd54c866af09ad8 + uses: angular/dev-infra/github-actions/bazel/setup@f47684669736e28fd77eab64e65b2952c8a948ee - 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 4768ebd16a36..5a8731c9002e 100644 --- a/.github/workflows/dev-infra.yml +++ b/.github/workflows/dev-infra.yml @@ -13,13 +13,13 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 - - uses: angular/dev-infra/github-actions/pull-request-labeling@c855fffb4b01bc06e743eb3bdfd54c866af09ad8 + - uses: angular/dev-infra/github-actions/pull-request-labeling@f47684669736e28fd77eab64e65b2952c8a948ee with: angular-robot-key: ${{ secrets.ANGULAR_ROBOT_PRIVATE_KEY }} post_approval_changes: runs-on: ubuntu-latest steps: - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 - - uses: angular/dev-infra/github-actions/post-approval-changes@c855fffb4b01bc06e743eb3bdfd54c866af09ad8 + - uses: angular/dev-infra/github-actions/post-approval-changes@f47684669736e28fd77eab64e65b2952c8a948ee with: angular-robot-key: ${{ secrets.ANGULAR_ROBOT_PRIVATE_KEY }} diff --git a/.github/workflows/feature-requests.yml b/.github/workflows/feature-requests.yml index 0c61f5b0ded6..5d29b9ef151f 100644 --- a/.github/workflows/feature-requests.yml +++ b/.github/workflows/feature-requests.yml @@ -16,6 +16,6 @@ jobs: if: github.repository == 'angular/angular-cli' runs-on: ubuntu-latest steps: - - uses: angular/dev-infra/github-actions/feature-request@c855fffb4b01bc06e743eb3bdfd54c866af09ad8 + - uses: angular/dev-infra/github-actions/feature-request@f47684669736e28fd77eab64e65b2952c8a948ee with: angular-robot-key: ${{ secrets.ANGULAR_ROBOT_PRIVATE_KEY }} diff --git a/.github/workflows/perf.yml b/.github/workflows/perf.yml index 508c7f109e44..a1e0f8dad657 100644 --- a/.github/workflows/perf.yml +++ b/.github/workflows/perf.yml @@ -23,7 +23,7 @@ jobs: workflows: ${{ steps.workflows.outputs.workflows }} steps: - name: Initialize environment - uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@c855fffb4b01bc06e743eb3bdfd54c866af09ad8 + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@f47684669736e28fd77eab64e65b2952c8a948ee - name: Install node modules run: pnpm install --frozen-lockfile - id: workflows @@ -38,9 +38,9 @@ jobs: workflow: ${{ fromJSON(needs.list.outputs.workflows) }} steps: - name: Initialize environment - uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@c855fffb4b01bc06e743eb3bdfd54c866af09ad8 + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@f47684669736e28fd77eab64e65b2952c8a948ee - name: Setup Bazel - uses: angular/dev-infra/github-actions/bazel/setup@c855fffb4b01bc06e743eb3bdfd54c866af09ad8 + uses: angular/dev-infra/github-actions/bazel/setup@f47684669736e28fd77eab64e65b2952c8a948ee - 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 b8041e68206b..694ef896fa91 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@c855fffb4b01bc06e743eb3bdfd54c866af09ad8 + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@f47684669736e28fd77eab64e65b2952c8a948ee - name: Setup Bazel - uses: angular/dev-infra/github-actions/bazel/setup@c855fffb4b01bc06e743eb3bdfd54c866af09ad8 + uses: angular/dev-infra/github-actions/bazel/setup@f47684669736e28fd77eab64e65b2952c8a948ee - name: Setup ESLint Caching uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.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@c855fffb4b01bc06e743eb3bdfd54c866af09ad8 + uses: angular/dev-infra/github-actions/linting/licenses@f47684669736e28fd77eab64e65b2952c8a948ee build: runs-on: ubuntu-latest steps: - name: Initialize environment - uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@c855fffb4b01bc06e743eb3bdfd54c866af09ad8 + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@f47684669736e28fd77eab64e65b2952c8a948ee - name: Setup Bazel - uses: angular/dev-infra/github-actions/bazel/setup@c855fffb4b01bc06e743eb3bdfd54c866af09ad8 + uses: angular/dev-infra/github-actions/bazel/setup@f47684669736e28fd77eab64e65b2952c8a948ee - name: Setup Bazel RBE - uses: angular/dev-infra/github-actions/bazel/configure-remote@c855fffb4b01bc06e743eb3bdfd54c866af09ad8 + uses: angular/dev-infra/github-actions/bazel/configure-remote@f47684669736e28fd77eab64e65b2952c8a948ee - 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@c855fffb4b01bc06e743eb3bdfd54c866af09ad8 + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@f47684669736e28fd77eab64e65b2952c8a948ee - name: Setup Bazel - uses: angular/dev-infra/github-actions/bazel/setup@c855fffb4b01bc06e743eb3bdfd54c866af09ad8 + uses: angular/dev-infra/github-actions/bazel/setup@f47684669736e28fd77eab64e65b2952c8a948ee - name: Setup Bazel RBE - uses: angular/dev-infra/github-actions/bazel/configure-remote@c855fffb4b01bc06e743eb3bdfd54c866af09ad8 + uses: angular/dev-infra/github-actions/bazel/configure-remote@f47684669736e28fd77eab64e65b2952c8a948ee - name: Install node modules run: pnpm install --frozen-lockfile - name: Run module and package tests @@ -115,13 +115,13 @@ jobs: runs-on: ${{ matrix.os }} steps: - name: Initialize environment - uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@c855fffb4b01bc06e743eb3bdfd54c866af09ad8 + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@f47684669736e28fd77eab64e65b2952c8a948ee - name: Install node modules run: pnpm install --frozen-lockfile - name: Setup Bazel - uses: angular/dev-infra/github-actions/bazel/setup@c855fffb4b01bc06e743eb3bdfd54c866af09ad8 + uses: angular/dev-infra/github-actions/bazel/setup@f47684669736e28fd77eab64e65b2952c8a948ee - name: Setup Bazel RBE - uses: angular/dev-infra/github-actions/bazel/configure-remote@c855fffb4b01bc06e743eb3bdfd54c866af09ad8 + uses: angular/dev-infra/github-actions/bazel/configure-remote@f47684669736e28fd77eab64e65b2952c8a948ee - 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/legacy-cli:e2e.${{ matrix.subset }}_node${{ matrix.node }} @@ -129,11 +129,11 @@ jobs: runs-on: ubuntu-latest steps: - name: Initialize environment - uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@c855fffb4b01bc06e743eb3bdfd54c866af09ad8 + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@f47684669736e28fd77eab64e65b2952c8a948ee - name: Setup Bazel - uses: angular/dev-infra/github-actions/bazel/setup@c855fffb4b01bc06e743eb3bdfd54c866af09ad8 + uses: angular/dev-infra/github-actions/bazel/setup@f47684669736e28fd77eab64e65b2952c8a948ee - name: Setup Bazel RBE - uses: angular/dev-infra/github-actions/bazel/configure-remote@c855fffb4b01bc06e743eb3bdfd54c866af09ad8 + uses: angular/dev-infra/github-actions/bazel/configure-remote@f47684669736e28fd77eab64e65b2952c8a948ee - name: Install node modules run: pnpm install --frozen-lockfile - name: Build E2E tests for Windows on Linux @@ -157,7 +157,7 @@ jobs: runs-on: windows-2025 steps: - name: Initialize environment - uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@c855fffb4b01bc06e743eb3bdfd54c866af09ad8 + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@f47684669736e28fd77eab64e65b2952c8a948ee - name: Install node modules run: pnpm install --frozen-lockfile - name: Download built Windows E2E tests @@ -185,13 +185,13 @@ jobs: runs-on: ${{ matrix.os }} steps: - name: Initialize environment - uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@c855fffb4b01bc06e743eb3bdfd54c866af09ad8 + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@f47684669736e28fd77eab64e65b2952c8a948ee - name: Install node modules run: pnpm install --frozen-lockfile - name: Setup Bazel - uses: angular/dev-infra/github-actions/bazel/setup@c855fffb4b01bc06e743eb3bdfd54c866af09ad8 + uses: angular/dev-infra/github-actions/bazel/setup@f47684669736e28fd77eab64e65b2952c8a948ee - name: Setup Bazel RBE - uses: angular/dev-infra/github-actions/bazel/configure-remote@c855fffb4b01bc06e743eb3bdfd54c866af09ad8 + uses: angular/dev-infra/github-actions/bazel/configure-remote@f47684669736e28fd77eab64e65b2952c8a948ee - 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/legacy-cli:e2e.${{ matrix.subset }}_node${{ matrix.node }} @@ -208,12 +208,12 @@ jobs: runs-on: ${{ matrix.os }} steps: - name: Initialize environment - uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@c855fffb4b01bc06e743eb3bdfd54c866af09ad8 + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@f47684669736e28fd77eab64e65b2952c8a948ee - name: Install node modules run: pnpm install --frozen-lockfile - name: Setup Bazel - uses: angular/dev-infra/github-actions/bazel/setup@c855fffb4b01bc06e743eb3bdfd54c866af09ad8 + uses: angular/dev-infra/github-actions/bazel/setup@f47684669736e28fd77eab64e65b2952c8a948ee - name: Setup Bazel RBE - uses: angular/dev-infra/github-actions/bazel/configure-remote@c855fffb4b01bc06e743eb3bdfd54c866af09ad8 + uses: angular/dev-infra/github-actions/bazel/configure-remote@f47684669736e28fd77eab64e65b2952c8a948ee - 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/legacy-cli:e2e.snapshots.${{ matrix.subset }}_node${{ matrix.node }} diff --git a/MODULE.bazel b/MODULE.bazel index 1b488d92160b..57200a6c1ae3 100644 --- a/MODULE.bazel +++ b/MODULE.bazel @@ -33,7 +33,7 @@ git_override( bazel_dep(name = "devinfra") git_override( module_name = "devinfra", - commit = "c855fffb4b01bc06e743eb3bdfd54c866af09ad8", + commit = "f47684669736e28fd77eab64e65b2952c8a948ee", remote = "https://github.com/angular/dev-infra.git", ) diff --git a/MODULE.bazel.lock b/MODULE.bazel.lock index 7626ecc5e633..d616eea2d7cd 100644 --- a/MODULE.bazel.lock +++ b/MODULE.bazel.lock @@ -156,7 +156,6 @@ "https://bcr.bazel.build/modules/rules_nodejs/6.3.0/MODULE.bazel": "45345e4aba35dd6e4701c1eebf5a4e67af4ed708def9ebcdc6027585b34ee52d", "https://bcr.bazel.build/modules/rules_nodejs/6.5.0/MODULE.bazel": "546d0cf79f36f9f6e080816045f97234b071c205f4542e3351bd4424282a8810", "https://bcr.bazel.build/modules/rules_nodejs/6.5.2/MODULE.bazel": "7f9ea68a0ce6d82905ce9f74e76ab8a8b4531ed4c747018c9d76424ad0b3370d", - "https://bcr.bazel.build/modules/rules_nodejs/6.6.1/MODULE.bazel": "e499aabe7cb796b784e9421be909c702eb79f664c20d21cbf120332a2a8dc378", "https://bcr.bazel.build/modules/rules_nodejs/6.6.2/MODULE.bazel": "9fdb5e1d50246a25761f150fcc820dc47e4052330a8408451e628804f9ca64a6", "https://bcr.bazel.build/modules/rules_nodejs/6.6.2/source.json": "6e8c1ecc64ff8da147c1620f862ad77d7b19c5d1b52b3aa5e847d5b3d0de4cc3", "https://bcr.bazel.build/modules/rules_pkg/0.7.0/MODULE.bazel": "df99f03fc7934a4737122518bb87e667e62d780b610910f0447665a7e2be62dc", @@ -194,12 +193,11 @@ "https://bcr.bazel.build/modules/stardoc/0.7.2/source.json": "58b029e5e901d6802967754adf0a9056747e8176f017cfe3607c0851f4d42216", "https://bcr.bazel.build/modules/tar.bzl/0.2.1/MODULE.bazel": "52d1c00a80a8cc67acbd01649e83d8dd6a9dc426a6c0b754a04fe8c219c76468", "https://bcr.bazel.build/modules/tar.bzl/0.5.1/MODULE.bazel": "7c2eb3dcfc53b0f3d6f9acdfd911ca803eaf92aadf54f8ca6e4c1f3aee288351", - "https://bcr.bazel.build/modules/tar.bzl/0.6.0/MODULE.bazel": "a3584b4edcfafcabd9b0ef9819808f05b372957bbdff41601429d5fd0aac2e7c", - "https://bcr.bazel.build/modules/tar.bzl/0.6.0/source.json": "4a620381df075a16cb3a7ed57bd1d05f7480222394c64a20fa51bdb636fda658", + "https://bcr.bazel.build/modules/tar.bzl/0.7.0/MODULE.bazel": "cc1acd85da33c80e430b65219a620d54d114628df24a618c3a5fa0b65e988da9", + "https://bcr.bazel.build/modules/tar.bzl/0.7.0/source.json": "9becb80306f42d4810bfa16379fb48aad0b01ce5342bc12fe47dcd6af3ac4d7a", "https://bcr.bazel.build/modules/upb/0.0.0-20220923-a547704/MODULE.bazel": "7298990c00040a0e2f121f6c32544bab27d4452f80d9ce51349b1a28f3005c43", "https://bcr.bazel.build/modules/yq.bzl/0.1.1/MODULE.bazel": "9039681f9bcb8958ee2c87ffc74bdafba9f4369096a2b5634b88abc0eaefa072", "https://bcr.bazel.build/modules/yq.bzl/0.2.0/MODULE.bazel": "6f3a675677db8885be4d607fde14cc51829715e3a879fb016eb9bf336786ce6d", - "https://bcr.bazel.build/modules/yq.bzl/0.3.1/MODULE.bazel": "9bcb7151b3cd4681b89d350530eaf7b45e32a44dda94843b8932b0cb1cd4594a", "https://bcr.bazel.build/modules/yq.bzl/0.3.2/MODULE.bazel": "0384efa70e8033d842ea73aa4b7199fa099709e236a7264345c03937166670b6", "https://bcr.bazel.build/modules/yq.bzl/0.3.2/source.json": "c4ec3e192477e154f08769e29d69e8fd36e8a4f0f623997f3e1f6f7d328f7d7d", "https://bcr.bazel.build/modules/zlib/1.2.11/MODULE.bazel": "07b389abc85fdbca459b69e2ec656ae5622873af3f845e1c9d80fe179f3effa0", @@ -212,7 +210,7 @@ "moduleExtensions": { "@@aspect_rules_esbuild~//esbuild:extensions.bzl%esbuild": { "general": { - "bzlTransitiveDigest": "PXvA3NOvgV+GXd72C+Zd7J5oEOKpEXHsGxKvRiqCb9U=", + "bzlTransitiveDigest": "GraoR12PYCcA5bpasvNm9vmnBGp+8JXnCK4y7D5+qkg=", "usagesDigest": "w3kRc6iou9hC6M+vwECvdfk0P8nsVNjHSl4Ftru44zU=", "recordedFileInputs": {}, "recordedDirentsInputs": {}, @@ -386,6 +384,11 @@ "bazel_tools", "bazel_tools" ], + [ + "bazel_lib~", + "bazel_skylib", + "bazel_skylib~" + ], [ "bazel_lib~", "bazel_tools", @@ -393,8 +396,8 @@ ], [ "tar.bzl~", - "aspect_bazel_lib", - "aspect_bazel_lib~" + "bazel_lib", + "bazel_lib~" ], [ "tar.bzl~", @@ -411,7 +414,7 @@ }, "@@aspect_rules_js~//npm:extensions.bzl%pnpm": { "general": { - "bzlTransitiveDigest": "MDL1U5KxASXhKcoXRgOqr7qxCgpKkNaQ2HSyFvw6u1U=", + "bzlTransitiveDigest": "AhiDaIgaI2cWTIbzA5ZbR/OmQSUpMCFEhsCzil+lwW4=", "usagesDigest": "J526kdgX5AQ2bYrNGwe6lTrakPUSZPfyHG24PGMUG0s=", "recordedFileInputs": {}, "recordedDirentsInputs": {}, @@ -532,6 +535,11 @@ "bazel_features_version", "bazel_features~~version_extension~bazel_features_version" ], + [ + "bazel_lib~", + "bazel_skylib", + "bazel_skylib~" + ], [ "bazel_lib~", "bazel_tools", @@ -539,8 +547,8 @@ ], [ "tar.bzl~", - "aspect_bazel_lib", - "aspect_bazel_lib~" + "bazel_lib", + "bazel_lib~" ], [ "tar.bzl~", diff --git a/package.json b/package.json index 2017743da80e..937ad8e5dd35 100644 --- a/package.json +++ b/package.json @@ -46,15 +46,15 @@ "homepage": "https://github.com/angular/angular-cli", "devDependencies": { "@angular/animations": "21.0.0", - "@angular/cdk": "21.0.0-rc.2", + "@angular/cdk": "21.0.0", "@angular/common": "21.0.0", "@angular/compiler": "21.0.0", "@angular/compiler-cli": "21.0.0", "@angular/core": "21.0.0", "@angular/forms": "21.0.0", "@angular/localize": "21.0.0", - "@angular/material": "21.0.0-rc.2", - "@angular/ng-dev": "https://github.com/angular/dev-infra-private-ng-dev-builds.git#49d7316da246484759b94f87e6eda47fde86b992", + "@angular/material": "21.0.0", + "@angular/ng-dev": "https://github.com/angular/dev-infra-private-ng-dev-builds.git#e0bb3b2b000ff0c0c18a2020d5d42371bca51ecf", "@angular/platform-browser": "21.0.0", "@angular/platform-server": "21.0.0", "@angular/router": "21.0.0", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index e628179997a0..1174da611b91 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -23,8 +23,8 @@ importers: specifier: 21.0.0 version: 21.0.0(@angular/core@21.0.0(@angular/compiler@21.0.0)(rxjs@7.8.2)(zone.js@0.15.1)) '@angular/cdk': - specifier: 21.0.0-rc.2 - version: 21.0.0-rc.2(@angular/common@21.0.0(@angular/core@21.0.0(@angular/compiler@21.0.0)(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/core@21.0.0(@angular/compiler@21.0.0)(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2) + specifier: 21.0.0 + version: 21.0.0(@angular/common@21.0.0(@angular/core@21.0.0(@angular/compiler@21.0.0)(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/core@21.0.0(@angular/compiler@21.0.0)(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2) '@angular/common': specifier: 21.0.0 version: 21.0.0(@angular/core@21.0.0(@angular/compiler@21.0.0)(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2) @@ -44,11 +44,11 @@ importers: specifier: 21.0.0 version: 21.0.0(@angular/compiler-cli@21.0.0(@angular/compiler@21.0.0)(typescript@5.9.3))(@angular/compiler@21.0.0) '@angular/material': - specifier: 21.0.0-rc.2 - version: 21.0.0-rc.2(f4675ee543acc620f23bcd7edbe6b867) + specifier: 21.0.0 + version: 21.0.0(280d15a59d7c55264f5164ad0fb0f648) '@angular/ng-dev': - specifier: https://github.com/angular/dev-infra-private-ng-dev-builds.git#49d7316da246484759b94f87e6eda47fde86b992 - version: https://codeload.github.com/angular/dev-infra-private-ng-dev-builds/tar.gz/49d7316da246484759b94f87e6eda47fde86b992(@modelcontextprotocol/sdk@1.20.1) + specifier: https://github.com/angular/dev-infra-private-ng-dev-builds.git#e0bb3b2b000ff0c0c18a2020d5d42371bca51ecf + version: https://codeload.github.com/angular/dev-infra-private-ng-dev-builds/tar.gz/e0bb3b2b000ff0c0c18a2020d5d42371bca51ecf(@modelcontextprotocol/sdk@1.20.1) '@angular/platform-browser': specifier: 21.0.0 version: 21.0.0(@angular/animations@21.0.0(@angular/core@21.0.0(@angular/compiler@21.0.0)(rxjs@7.8.2)(zone.js@0.15.1)))(@angular/common@21.0.0(@angular/core@21.0.0(@angular/compiler@21.0.0)(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/core@21.0.0(@angular/compiler@21.0.0)(rxjs@7.8.2)(zone.js@0.15.1)) @@ -333,7 +333,7 @@ importers: version: link:../../../packages/angular/ssr '@vitest/coverage-v8': specifier: 4.0.8 - version: 4.0.8(vitest@4.0.8(@types/node@24.10.0)(jiti@2.6.1)(jsdom@27.1.0(bufferutil@4.0.9)(utf-8-validate@6.0.5))(less@4.4.2)(sass@1.93.2)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1)) + version: 4.0.8(vitest@4.0.8(@types/node@24.10.1)(jiti@2.6.1)(jsdom@27.1.0(bufferutil@4.0.9)(utf-8-validate@6.0.5))(less@4.4.2)(sass@1.93.2)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1)) browser-sync: specifier: 3.0.4 version: 3.0.4(bufferutil@4.0.9)(utf-8-validate@6.0.5) @@ -345,7 +345,7 @@ importers: version: 7.8.2 vitest: specifier: 4.0.8 - version: 4.0.8(@types/node@24.10.0)(jiti@2.6.1)(jsdom@27.1.0(bufferutil@4.0.9)(utf-8-validate@6.0.5))(less@4.4.2)(sass@1.93.2)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1) + version: 4.0.8(@types/node@24.10.1)(jiti@2.6.1)(jsdom@27.1.0(bufferutil@4.0.9)(utf-8-validate@6.0.5))(less@4.4.2)(sass@1.93.2)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1) packages/angular/build: dependencies: @@ -366,10 +366,10 @@ importers: version: 7.24.7 '@inquirer/confirm': specifier: 5.1.19 - version: 5.1.19(@types/node@24.10.0) + version: 5.1.19(@types/node@24.10.1) '@vitejs/plugin-basic-ssl': specifier: 2.1.0 - version: 2.1.0(vite@7.2.2(@types/node@24.10.0)(jiti@2.6.1)(less@4.4.2)(sass@1.93.2)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1)) + version: 2.1.0(vite@7.2.2(@types/node@24.10.1)(jiti@2.6.1)(less@4.4.2)(sass@1.93.2)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1)) beasties: specifier: 0.3.5 version: 0.3.5 @@ -426,7 +426,7 @@ importers: version: 7.16.0 vite: specifier: 7.2.2 - version: 7.2.2(@types/node@24.10.0)(jiti@2.6.1)(less@4.4.2)(sass@1.93.2)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1) + version: 7.2.2(@types/node@24.10.1)(jiti@2.6.1)(less@4.4.2)(sass@1.93.2)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1) watchpack: specifier: 2.4.4 version: 2.4.4 @@ -454,7 +454,7 @@ importers: version: 7.8.2 vitest: specifier: 4.0.8 - version: 4.0.8(@types/node@24.10.0)(jiti@2.6.1)(jsdom@27.1.0(bufferutil@4.0.9)(utf-8-validate@6.0.5))(less@4.4.2)(sass@1.93.2)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1) + version: 4.0.8(@types/node@24.10.1)(jiti@2.6.1)(jsdom@27.1.0(bufferutil@4.0.9)(utf-8-validate@6.0.5))(less@4.4.2)(sass@1.93.2)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1) optionalDependencies: lmdb: specifier: 3.4.3 @@ -473,10 +473,10 @@ importers: version: link:../../angular_devkit/schematics '@inquirer/prompts': specifier: 7.9.0 - version: 7.9.0(@types/node@24.10.0) + version: 7.9.0(@types/node@24.10.1) '@listr2/prompt-adapter-inquirer': specifier: 3.0.5 - version: 3.0.5(@inquirer/prompts@7.9.0(@types/node@24.10.0))(@types/node@24.10.0)(listr2@9.0.5) + version: 3.0.5(@inquirer/prompts@7.9.0(@types/node@24.10.1))(@types/node@24.10.1)(listr2@9.0.5) '@modelcontextprotocol/sdk': specifier: 1.20.1 version: 1.20.1 @@ -857,7 +857,7 @@ importers: version: link:../schematics '@inquirer/prompts': specifier: 7.9.0 - version: 7.9.0(@types/node@24.10.0) + version: 7.9.0(@types/node@24.10.1) ansi-colors: specifier: 4.1.3 version: 4.1.3 @@ -990,11 +990,11 @@ packages: peerDependencies: '@angular/core': 21.0.0 - '@angular/cdk@21.0.0-rc.2': - resolution: {integrity: sha512-QO+0m1OXHwbpB4hoFnx+tkWsvChcNXvyHv3I4bN+wI8iv54yBuVgT5r8w+3VOAg/QB0em0AQEU7fdXfI3mwb3w==} + '@angular/cdk@21.0.0': + resolution: {integrity: sha512-wCr5D3mEC+p69IMDC7vf8bWx18mfUNNRdsiK3XD0m1PqfeNfnCJb+Bnkks37MC/SU01uCNrAokRaTbWL6pk1Wg==} peerDependencies: - '@angular/common': ^21.0.0-0 || ^21.1.0-0 || ^21.2.0-0 || ^21.3.0-0 || ^22.0.0-0 - '@angular/core': ^21.0.0-0 || ^21.1.0-0 || ^21.2.0-0 || ^21.3.0-0 || ^22.0.0-0 + '@angular/common': ^21.0.0 || ^22.0.0 + '@angular/core': ^21.0.0 || ^22.0.0 rxjs: ^6.5.3 || ^7.4.0 '@angular/common@21.0.0': @@ -1050,19 +1050,19 @@ packages: '@angular/compiler': 21.0.0 '@angular/compiler-cli': 21.0.0 - '@angular/material@21.0.0-rc.2': - resolution: {integrity: sha512-ousayydWUWkrWw7lKuiN9b/BeTNEio/75Z51+Hkg0n5xzgGWNV5tVT/IFw8IwssKWlsJslSCzohj/j5l9Hl7rw==} + '@angular/material@21.0.0': + resolution: {integrity: sha512-s3+fhN7F5T1TAltZXYXOgY1wuVbICCrBJpV2TN8nJXDT0wroTYAljgBmsr6ZjDwYJewwP0OPvcj2NlOGDpa6oA==} peerDependencies: - '@angular/cdk': 21.0.0-rc.2 - '@angular/common': ^21.0.0-0 || ^21.1.0-0 || ^21.2.0-0 || ^21.3.0-0 || ^22.0.0-0 - '@angular/core': ^21.0.0-0 || ^21.1.0-0 || ^21.2.0-0 || ^21.3.0-0 || ^22.0.0-0 - '@angular/forms': ^21.0.0-0 || ^21.1.0-0 || ^21.2.0-0 || ^21.3.0-0 || ^22.0.0-0 - '@angular/platform-browser': ^21.0.0-0 || ^21.1.0-0 || ^21.2.0-0 || ^21.3.0-0 || ^22.0.0-0 + '@angular/cdk': 21.0.0 + '@angular/common': ^21.0.0 || ^22.0.0 + '@angular/core': ^21.0.0 || ^22.0.0 + '@angular/forms': ^21.0.0 || ^22.0.0 + '@angular/platform-browser': ^21.0.0 || ^22.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/49d7316da246484759b94f87e6eda47fde86b992': - resolution: {tarball: https://codeload.github.com/angular/dev-infra-private-ng-dev-builds/tar.gz/49d7316da246484759b94f87e6eda47fde86b992} - version: 0.0.0-c855fffb4b01bc06e743eb3bdfd54c866af09ad8 + '@angular/ng-dev@https://codeload.github.com/angular/dev-infra-private-ng-dev-builds/tar.gz/e0bb3b2b000ff0c0c18a2020d5d42371bca51ecf': + resolution: {tarball: https://codeload.github.com/angular/dev-infra-private-ng-dev-builds/tar.gz/e0bb3b2b000ff0c0c18a2020d5d42371bca51ecf} + version: 0.0.0-f47684669736e28fd77eab64e65b2952c8a948ee hasBin: true '@angular/platform-browser@21.0.0': @@ -2225,8 +2225,8 @@ packages: resolution: {integrity: sha512-vBZP4NlzfOlerQTnba4aqZoMhE/a9HY7HRqoOPaETQcSQuWEIyZMHGfVu6w9wGtGK5fED5qRs2DteVCjOH60sA==} engines: {node: '>=14'} - '@firebase/ai@2.5.0': - resolution: {integrity: sha512-OXv/jZLRjV9jTejWA4KOvW8gM1hNsLvQSCPwKhi2CEfe0Nap3rM6z+Ial0PGqXga0WgzhpypEvJOFvaAUFX3kg==} + '@firebase/ai@2.6.0': + resolution: {integrity: sha512-NGyE7NQDFznOv683Xk4+WoUv39iipa9lEfrwvvPz33ChzVbCCiB69FJQTK2BI/11pRtzYGbHo1/xMz7gxWWhJw==} engines: {node: '>=20.0.0'} peerDependencies: '@firebase/app': 0.x @@ -2263,15 +2263,15 @@ packages: peerDependencies: '@firebase/app': 0.x - '@firebase/app-compat@0.5.5': - resolution: {integrity: sha512-lVG/nRnXaot0rQSZazmTNqy83ti9O3+kdwoaE0d5wahRIWNoDirbIMcGVjDDgdmf4IE6FYreWOMh0L3DV1475w==} + '@firebase/app-compat@0.5.6': + resolution: {integrity: sha512-YYGARbutghQY4zZUWMYia0ib0Y/rb52y72/N0z3vglRHL7ii/AaK9SA7S/dzScVOlCdnbHXz+sc5Dq+r8fwFAg==} engines: {node: '>=20.0.0'} '@firebase/app-types@0.9.3': resolution: {integrity: sha512-kRVpIl4vVGJ4baogMDINbyrIOtOxqhkZQg4jTq3l8Lw6WSk0xfpEYzezFu+Kl4ve4fbPl79dvwRtaFqAC/ucCw==} - '@firebase/app@0.14.5': - resolution: {integrity: sha512-zyNY77xJOGwcuB+xCxF8z8lSiHvD4ox7BCsqLEHEvgqQoRjxFZ0fkROR6NV5QyXmCqRLodMM8J5d2EStOocWIw==} + '@firebase/app@0.14.6': + resolution: {integrity: sha512-4uyt8BOrBsSq6i4yiOV/gG6BnnrvTeyymlNcaN/dKvyU1GoolxAafvIvaNP1RCGPlNab3OuE4MKUQuv2lH+PLQ==} engines: {node: '>=20.0.0'} '@firebase/auth-compat@0.6.1': @@ -2303,8 +2303,8 @@ packages: resolution: {integrity: sha512-wR9En2A+WESUHexjmRHkqtaVH94WLNKt6rmeqZhSLBybg4Wyf0Umk04SZsS6sBq4102ZsDBFwoqMqJYj2IoDSg==} engines: {node: '>=20.0.0'} - '@firebase/data-connect@0.3.11': - resolution: {integrity: sha512-G258eLzAD6im9Bsw+Qm1Z+P4x0PGNQ45yeUuuqe5M9B1rn0RJvvsQCRHXgE52Z+n9+WX1OJd/crcuunvOGc7Vw==} + '@firebase/data-connect@0.3.12': + resolution: {integrity: sha512-baPddcoNLj/+vYo+HSJidJUdr5W4OkhT109c5qhR8T1dJoZcyJpkv/dFpYlw/VJ3dV66vI8GHQFrmAZw/xUS4g==} peerDependencies: '@firebase/app': 0.x @@ -2466,8 +2466,8 @@ packages: resolution: {integrity: sha512-IJn+8A3QZJfe7FUtWqHVNo3xJs7KFpurCWGWCiCz3oEh+BkRymKZ1QxfAbU2yGMDzTytLGQ2IV6T2r3cuo75/w==} engines: {node: '>=18'} - '@google/genai@1.29.0': - resolution: {integrity: sha512-cQP7Ssa06W+MSAyVtL/812FBtZDoDehnFObIpK1xo5Uv4XvqBcVZ8OhXgihOIXWn7xvPQGvLclR8+yt3Ysnd9g==} + '@google/genai@1.30.0': + resolution: {integrity: sha512-3MRcgczBFbUat1wIlZoLJ0vCCfXgm7Qxjh59cZi2X08RgWLtm9hKOspzp7TOg1TV2e26/MLxR2GR5yD5GmBV2w==} engines: {node: '>=20.0.0'} peerDependencies: '@modelcontextprotocol/sdk': ^1.20.1 @@ -2516,6 +2516,10 @@ packages: resolution: {integrity: sha512-S8qNSZiYzFd0wAcyG5AXCvUHC5Sr7xpZ9wZ2py9XR88jUz8wooStVx5M6dRzczbBWjic9NP7+rY0Xi7qqK/aMQ==} engines: {node: '>=18'} + '@inquirer/ansi@2.0.1': + resolution: {integrity: sha512-QAZUk6BBncv/XmSEZTscd8qazzjV3E0leUMrEPjxCd51QBgCKmprUGLex5DTsNtURm7LMzv+CLcd6S86xvBfYg==} + engines: {node: '>=23.5.0 || ^22.13.0 || ^21.7.0 || ^20.12.0'} + '@inquirer/checkbox@4.3.2': resolution: {integrity: sha512-VXukHf0RR1doGe6Sm4F0Em7SWYLTHSsbGfJdS9Ja2bX5/D5uwVOEjr07cncLROdBvmnvCATYEWlHqYmXv2IlQA==} engines: {node: '>=18'} @@ -2525,6 +2529,15 @@ packages: '@types/node': optional: true + '@inquirer/checkbox@5.0.1': + resolution: {integrity: sha512-5VPFBK8jKdsjMK3DTFOlbR0+Kkd4q0AWB7VhWQn6ppv44dr3b7PU8wSJQTC5oA0f/aGW7v/ZozQJAY9zx6PKig==} + engines: {node: '>=23.5.0 || ^22.13.0 || ^21.7.0 || ^20.12.0'} + peerDependencies: + '@types/node': '>=18' + peerDependenciesMeta: + '@types/node': + optional: true + '@inquirer/confirm@5.1.19': resolution: {integrity: sha512-wQNz9cfcxrtEnUyG5PndC8g3gZ7lGDBzmWiXZkX8ot3vfZ+/BLjR8EvyGX4YzQLeVqtAlY/YScZpW7CW8qMoDQ==} engines: {node: '>=18'} @@ -2534,9 +2547,9 @@ packages: '@types/node': optional: true - '@inquirer/confirm@5.1.21': - resolution: {integrity: sha512-KR8edRkIsUayMXV+o3Gv+q4jlhENF9nMYUZs9PA2HzrXeHI8M5uDag70U7RJn9yyiMZSbtF5/UexBtAVtZGSbQ==} - engines: {node: '>=18'} + '@inquirer/confirm@6.0.1': + resolution: {integrity: sha512-wD+pM7IxLn1TdcQN12Q6wcFe5VpyCuh/I2sSmqO5KjWH2R4v+GkUToHb+PsDGobOe1MtAlXMwGNkZUPc2+L6NA==} + engines: {node: '>=23.5.0 || ^22.13.0 || ^21.7.0 || ^20.12.0'} peerDependencies: '@types/node': '>=18' peerDependenciesMeta: @@ -2552,6 +2565,15 @@ packages: '@types/node': optional: true + '@inquirer/core@11.0.1': + resolution: {integrity: sha512-Tpf49h50e4KYffVUCXzkx4gWMafUi3aDQDwfVAAGBNnVcXiwJIj4m2bKlZ7Kgyf6wjt1eyXH1wDGXcAokm4Ssw==} + engines: {node: '>=23.5.0 || ^22.13.0 || ^21.7.0 || ^20.12.0'} + peerDependencies: + '@types/node': '>=18' + peerDependenciesMeta: + '@types/node': + optional: true + '@inquirer/editor@4.2.23': resolution: {integrity: sha512-aLSROkEwirotxZ1pBaP8tugXRFCxW94gwrQLxXfrZsKkfjOYC1aRvAZuhpJOb5cu4IBTJdsCigUlf2iCOu4ZDQ==} engines: {node: '>=18'} @@ -2561,6 +2583,15 @@ packages: '@types/node': optional: true + '@inquirer/editor@5.0.1': + resolution: {integrity: sha512-zDKobHI7Ry++4noiV9Z5VfYgSVpPZoMApviIuGwLOMciQaP+dGzCO+1fcwI441riklRiZg4yURWyEoX0Zy2zZw==} + engines: {node: '>=23.5.0 || ^22.13.0 || ^21.7.0 || ^20.12.0'} + peerDependencies: + '@types/node': '>=18' + peerDependenciesMeta: + '@types/node': + optional: true + '@inquirer/expand@4.0.23': resolution: {integrity: sha512-nRzdOyFYnpeYTTR2qFwEVmIWypzdAx/sIkCMeTNTcflFOovfqUk+HcFhQQVBftAh9gmGrpFj6QcGEqrDMDOiew==} engines: {node: '>=18'} @@ -2570,6 +2601,15 @@ packages: '@types/node': optional: true + '@inquirer/expand@5.0.1': + resolution: {integrity: sha512-TBrTpAB6uZNnGQHtSEkbvJZIQ3dXZOrwqQSO9uUbwct3G2LitwBCE5YZj98MbQ5nzihzs5pRjY1K9RRLH4WgoA==} + engines: {node: '>=23.5.0 || ^22.13.0 || ^21.7.0 || ^20.12.0'} + peerDependencies: + '@types/node': '>=18' + peerDependenciesMeta: + '@types/node': + optional: true + '@inquirer/external-editor@1.0.3': resolution: {integrity: sha512-RWbSrDiYmO4LbejWY7ttpxczuwQyZLBUyygsA9Nsv95hpzUWwnNTVQmAq3xuh7vNwCp07UTmE5i11XAEExx4RA==} engines: {node: '>=18'} @@ -2579,10 +2619,23 @@ packages: '@types/node': optional: true + '@inquirer/external-editor@2.0.1': + resolution: {integrity: sha512-BPYWJXCAK9w6R+pb2s3WyxUz9ts9SP/LDOUwA9fu7LeuyYgojz83i0DSRwezu736BgMwz14G63Xwj70hSzHohQ==} + engines: {node: '>=23.5.0 || ^22.13.0 || ^21.7.0 || ^20.12.0'} + peerDependencies: + '@types/node': '>=18' + peerDependenciesMeta: + '@types/node': + optional: true + '@inquirer/figures@1.0.15': resolution: {integrity: sha512-t2IEY+unGHOzAaVM5Xx6DEWKeXlDDcNPeDyUpsRc6CUhBfU3VQOEl+Vssh7VNp1dR8MdUJBWhuObjXCsVpjN5g==} engines: {node: '>=18'} + '@inquirer/figures@2.0.1': + resolution: {integrity: sha512-KtMxyjLCuDFqAWHmCY9qMtsZ09HnjMsm8H3OvpSIpfhHdfw3/AiGWHNrfRwbyvHPtOJpumm8wGn5fkhtvkWRsg==} + engines: {node: '>=23.5.0 || ^22.13.0 || ^21.7.0 || ^20.12.0'} + '@inquirer/input@4.3.1': resolution: {integrity: sha512-kN0pAM4yPrLjJ1XJBjDxyfDduXOuQHrBB8aLDMueuwUGn+vNpF7Gq7TvyVxx8u4SHlFFj4trmj+a2cbpG4Jn1g==} engines: {node: '>=18'} @@ -2592,6 +2645,15 @@ packages: '@types/node': optional: true + '@inquirer/input@5.0.1': + resolution: {integrity: sha512-cEhEUohCpE2BCuLKtFFZGp4Ief05SEcqeAOq9NxzN5ThOQP8Rl5N/Nt9VEDORK1bRb2Sk/zoOyQYfysPQwyQtA==} + engines: {node: '>=23.5.0 || ^22.13.0 || ^21.7.0 || ^20.12.0'} + peerDependencies: + '@types/node': '>=18' + peerDependenciesMeta: + '@types/node': + optional: true + '@inquirer/number@3.0.23': resolution: {integrity: sha512-5Smv0OK7K0KUzUfYUXDXQc9jrf8OHo4ktlEayFlelCjwMXz0299Y8OrI+lj7i4gCBY15UObk76q0QtxjzFcFcg==} engines: {node: '>=18'} @@ -2601,6 +2663,15 @@ packages: '@types/node': optional: true + '@inquirer/number@4.0.1': + resolution: {integrity: sha512-4//zgBGHe8Q/FfCoUXZUrUHyK/q5dyqiwsePz3oSSPSmw1Ijo35ZkjaftnxroygcUlLYfXqm+0q08lnB5hd49A==} + engines: {node: '>=23.5.0 || ^22.13.0 || ^21.7.0 || ^20.12.0'} + peerDependencies: + '@types/node': '>=18' + peerDependenciesMeta: + '@types/node': + optional: true + '@inquirer/password@4.0.23': resolution: {integrity: sha512-zREJHjhT5vJBMZX/IUbyI9zVtVfOLiTO66MrF/3GFZYZ7T4YILW5MSkEYHceSii/KtRk+4i3RE7E1CUXA2jHcA==} engines: {node: '>=18'} @@ -2610,9 +2681,9 @@ packages: '@types/node': optional: true - '@inquirer/prompts@7.10.0': - resolution: {integrity: sha512-X2HAjY9BClfFkJ2RP3iIiFxlct5JJVdaYYXhA7RKxsbc9KL+VbId79PSoUGH/OLS011NFbHHDMDcBKUj3T89+Q==} - engines: {node: '>=18'} + '@inquirer/password@5.0.1': + resolution: {integrity: sha512-UJudHpd7Ia30Q+x+ctYqI9Nh6SyEkaBscpa7J6Ts38oc1CNSws0I1hJEdxbQBlxQd65z5GEJPM4EtNf6tzfWaQ==} + engines: {node: '>=23.5.0 || ^22.13.0 || ^21.7.0 || ^20.12.0'} peerDependencies: '@types/node': '>=18' peerDependenciesMeta: @@ -2628,6 +2699,15 @@ packages: '@types/node': optional: true + '@inquirer/prompts@8.0.1': + resolution: {integrity: sha512-MURRu/cyvLm9vchDDaVZ9u4p+ADnY0Mz3LQr0KTgihrrvuKZlqcWwlBC4lkOMvd0KKX4Wz7Ww9+uA7qEpQaqjg==} + engines: {node: '>=23.5.0 || ^22.13.0 || ^21.7.0 || ^20.12.0'} + peerDependencies: + '@types/node': '>=18' + peerDependenciesMeta: + '@types/node': + optional: true + '@inquirer/rawlist@4.1.11': resolution: {integrity: sha512-+LLQB8XGr3I5LZN/GuAHo+GpDJegQwuPARLChlMICNdwW7OwV2izlCSCxN6cqpL0sMXmbKbFcItJgdQq5EBXTw==} engines: {node: '>=18'} @@ -2637,6 +2717,15 @@ packages: '@types/node': optional: true + '@inquirer/rawlist@5.0.1': + resolution: {integrity: sha512-vVfVHKUgH6rZmMlyd0jOuGZo0Fw1jfcOqZF96lMwlgavx7g0x7MICe316bV01EEoI+c68vMdbkTTawuw3O+Fgw==} + engines: {node: '>=23.5.0 || ^22.13.0 || ^21.7.0 || ^20.12.0'} + peerDependencies: + '@types/node': '>=18' + peerDependenciesMeta: + '@types/node': + optional: true + '@inquirer/search@3.2.2': resolution: {integrity: sha512-p2bvRfENXCZdWF/U2BXvnSI9h+tuA8iNqtUKb9UWbmLYCRQxd8WkvwWvYn+3NgYaNwdUkHytJMGG4MMLucI1kA==} engines: {node: '>=18'} @@ -2646,6 +2735,15 @@ packages: '@types/node': optional: true + '@inquirer/search@4.0.1': + resolution: {integrity: sha512-XwiaK5xBvr31STX6Ji8iS3HCRysBXfL/jUbTzufdWTS6LTGtvDQA50oVETt1BJgjKyQBp9vt0VU6AmU/AnOaGA==} + engines: {node: '>=23.5.0 || ^22.13.0 || ^21.7.0 || ^20.12.0'} + peerDependencies: + '@types/node': '>=18' + peerDependenciesMeta: + '@types/node': + optional: true + '@inquirer/select@4.4.2': resolution: {integrity: sha512-l4xMuJo55MAe+N7Qr4rX90vypFwCajSakx59qe/tMaC1aEHWLyw68wF4o0A4SLAY4E0nd+Vt+EyskeDIqu1M6w==} engines: {node: '>=18'} @@ -2655,6 +2753,15 @@ packages: '@types/node': optional: true + '@inquirer/select@5.0.1': + resolution: {integrity: sha512-gPByrgYoezGyKMq5KjV7Tuy1JU2ArIy6/sI8sprw0OpXope3VGQwP5FK1KD4eFFqEhKu470Dwe6/AyDPmGRA0Q==} + engines: {node: '>=23.5.0 || ^22.13.0 || ^21.7.0 || ^20.12.0'} + peerDependencies: + '@types/node': '>=18' + peerDependenciesMeta: + '@types/node': + optional: true + '@inquirer/type@3.0.10': resolution: {integrity: sha512-BvziSRxfz5Ov8ch0z/n3oijRSEcEsHnhggm4xFZe93DHcUCTlutlq9Ox4SVENAfcRD22UQq7T/atg9Wr3k09eA==} engines: {node: '>=18'} @@ -2664,6 +2771,15 @@ packages: '@types/node': optional: true + '@inquirer/type@4.0.1': + resolution: {integrity: sha512-odO8YwoQAw/eVu/PSPsDDVPmqO77r/Mq7zcoF5VduVqIu2wSRWUgmYb5K9WH1no0SjLnOe8MDKtDL++z6mfo2g==} + engines: {node: '>=23.5.0 || ^22.13.0 || ^21.7.0 || ^20.12.0'} + peerDependencies: + '@types/node': '>=18' + peerDependenciesMeta: + '@types/node': + optional: true + '@isaacs/balanced-match@4.0.1': resolution: {integrity: sha512-yzMTt9lEb8Gv7zRioUilSglI0c0smZ9k5D65677DLWLtWJaXIS3CqcGyUFByYKlnUj6TkjLVs54fBl6+TiGQDQ==} engines: {node: 20 || >=22} @@ -3061,8 +3177,8 @@ packages: peerDependencies: '@octokit/core': '>=6' - '@octokit/request-error@7.0.2': - resolution: {integrity: sha512-U8piOROoQQUyExw5c6dTkU3GKxts5/ERRThIauNL7yaRoeXW0q/5bgHWT7JfWBw1UyrbK8ERId2wVkcB32n0uQ==} + '@octokit/request-error@7.1.0': + resolution: {integrity: sha512-KMQIfq5sOPpkQYajXHwnhjCC0slzCNScLHs9JafXc4RAJI+9f+jNDlBNaIMTvazOPLgb4BnlhGJOTbnN0wIjPw==} engines: {node: '>= 20'} '@octokit/request@10.0.7': @@ -3740,9 +3856,6 @@ packages: '@types/jasmine-reporters@2.5.3': resolution: {integrity: sha512-8aojAUdgdiD9VQbllBJb/9gny3lOjz9T5gyMcbYlKe6npwGVsarbr8v2JYSFJSZSuFYXcPVzFG2lLX3ib0j/DA==} - '@types/jasmine@5.1.12': - resolution: {integrity: sha512-1BzPxNsFDLDfj9InVR3IeY0ZVf4o9XV+4mDqoCfyPkbsA7dYyKAPAb2co6wLFlHcvxPlt1wShm7zQdV7uTfLGA==} - '@types/jasmine@5.1.13': resolution: {integrity: sha512-MYCcDkruFc92LeYZux5BC0dmqo2jk+M5UIZ4/oFnAPCXN9mCcQhLyj7F3/Za7rocVyt5YRr1MmqJqFlvQ9LVcg==} @@ -3788,8 +3901,8 @@ packages: '@types/node@22.19.1': resolution: {integrity: sha512-LCCV0HdSZZZb34qifBsyWlUmok6W7ouER+oQIGBScS8EsZsQbrtFTUrDX4hOl+CS6p7cnNC4td+qrSVGSCTUfQ==} - '@types/node@24.10.0': - resolution: {integrity: sha512-qzQZRBqkFsYyaSWXuEHc2WR9c0a0CXwiE5FWUvn7ZM+vdy1uZLfCunD38UzhuB7YN/J11ndbDBcTmOdxJo9Q7A==} + '@types/node@24.10.1': + resolution: {integrity: sha512-GNWcUTRBgIRJD5zj+Tq0fKOJ5XZajIiBroOF0yvj2bSU1WvNdYS/dn9UxwsujGW4JX06dnHyjV2y9rRaybH0iQ==} '@types/npm-package-arg@6.1.4': resolution: {integrity: sha512-vDgdbMy2QXHnAruzlv68pUtXCjmqUk3WrBAsRboRovsOmxbfn/WiYCjmecyKjGztnMps5dWp4Uq2prp+Ilo17Q==} @@ -3884,9 +3997,6 @@ packages: '@types/yargs-parser@21.0.3': resolution: {integrity: sha512-I4q9QU9MQv4oEOz4tAHJtNz1cwuLxn2F3xcc2iV5WdqLPpUnj30aUuxt1mAxYTG+oe8CZMV/+6rU4S4gRDzqtQ==} - '@types/yargs@17.0.34': - resolution: {integrity: sha512-KExbHVa92aJpw9WDQvzBaGVE2/Pz+pLZQloT2hjL8IqsZnV62rlPOYvNnLmf/L2dyllfVUOVBj64M0z/46eR2A==} - '@types/yargs@17.0.35': resolution: {integrity: sha512-qUHkeCyQFxMXg79wQfTtfndEC+N9ZZg76HJftDJp+qH2tV7Gj4OJi7l+PiWwJ+pWtW8GwSmqsDj/oymhrTWXjg==} @@ -5744,8 +5854,8 @@ packages: resolution: {integrity: sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==} engines: {node: '>=10'} - firebase@12.5.0: - resolution: {integrity: sha512-Ak8JcpH7FL6kiv0STwkv5+3CYEROO9iFWSx7OCZVvc4kIIABAIyAGs1mPGaHRxGUIApFZdMCXA7baq17uS6Mow==} + firebase@12.6.0: + resolution: {integrity: sha512-8ZD1Gcv916Qp8/nsFH2+QMIrfX/76ti6cJwxQUENLXXnKlOX/IJZaU2Y3bdYf5r1mbownrQKfnWtrt+MVgdwLA==} flat-cache@4.0.1: resolution: {integrity: sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw==} @@ -7174,6 +7284,10 @@ packages: resolution: {integrity: sha512-WWdIxpyjEn+FhQJQQv9aQAYlHoNVdzIzUySNV1gHUPDSdZJ3yZn7pAAbQcV7B56Mvu881q9FZV+0Vx2xC44VWA==} engines: {node: ^18.17.0 || >=20.5.0} + mute-stream@3.0.0: + resolution: {integrity: sha512-dkEJPVvun4FryqBmZ5KhDo0K9iDXAwn08tMLDinNdRBNPcYEDiWYysLcc6k3mjTMlbP9KyylvRpd4wFtwrT9rw==} + engines: {node: ^20.17.0 || >=22.9.0} + nanocolors@0.2.13: resolution: {integrity: sha512-0n3mSAQLPpGLV9ORXT5+C/D4mwew7Ebws69Hx4E2sgz2ZA5+32Q80B9tL8PbL7XHnRDiAxH/pnrUJ9a4fkTNTA==} @@ -9502,7 +9616,7 @@ snapshots: '@angular/core': 21.0.0(@angular/compiler@21.0.0)(rxjs@7.8.2)(zone.js@0.15.1) tslib: 2.8.1 - '@angular/cdk@21.0.0-rc.2(@angular/common@21.0.0(@angular/core@21.0.0(@angular/compiler@21.0.0)(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/core@21.0.0(@angular/compiler@21.0.0)(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2)': + '@angular/cdk@21.0.0(@angular/common@21.0.0(@angular/core@21.0.0(@angular/compiler@21.0.0)(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/core@21.0.0(@angular/compiler@21.0.0)(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2)': dependencies: '@angular/common': 21.0.0(@angular/core@21.0.0(@angular/compiler@21.0.0)(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2) '@angular/core': 21.0.0(@angular/compiler@21.0.0)(rxjs@7.8.2)(zone.js@0.15.1) @@ -9564,9 +9678,9 @@ snapshots: transitivePeerDependencies: - supports-color - '@angular/material@21.0.0-rc.2(f4675ee543acc620f23bcd7edbe6b867)': + '@angular/material@21.0.0(280d15a59d7c55264f5164ad0fb0f648)': dependencies: - '@angular/cdk': 21.0.0-rc.2(@angular/common@21.0.0(@angular/core@21.0.0(@angular/compiler@21.0.0)(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/core@21.0.0(@angular/compiler@21.0.0)(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2) + '@angular/cdk': 21.0.0(@angular/common@21.0.0(@angular/core@21.0.0(@angular/compiler@21.0.0)(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/core@21.0.0(@angular/compiler@21.0.0)(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2) '@angular/common': 21.0.0(@angular/core@21.0.0(@angular/compiler@21.0.0)(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2) '@angular/core': 21.0.0(@angular/compiler@21.0.0)(rxjs@7.8.2)(zone.js@0.15.1) '@angular/forms': 21.0.0(@angular/common@21.0.0(@angular/core@21.0.0(@angular/compiler@21.0.0)(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/core@21.0.0(@angular/compiler@21.0.0)(rxjs@7.8.2)(zone.js@0.15.1))(@angular/platform-browser@21.0.0(@angular/animations@21.0.0(@angular/core@21.0.0(@angular/compiler@21.0.0)(rxjs@7.8.2)(zone.js@0.15.1)))(@angular/common@21.0.0(@angular/core@21.0.0(@angular/compiler@21.0.0)(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/core@21.0.0(@angular/compiler@21.0.0)(rxjs@7.8.2)(zone.js@0.15.1)))(@standard-schema/spec@1.0.0)(rxjs@7.8.2) @@ -9574,13 +9688,13 @@ 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/49d7316da246484759b94f87e6eda47fde86b992(@modelcontextprotocol/sdk@1.20.1)': + '@angular/ng-dev@https://codeload.github.com/angular/dev-infra-private-ng-dev-builds/tar.gz/e0bb3b2b000ff0c0c18a2020d5d42371bca51ecf(@modelcontextprotocol/sdk@1.20.1)': dependencies: '@actions/core': 1.11.1 '@google-cloud/spanner': 8.0.0(supports-color@10.2.2) - '@google/genai': 1.29.0(@modelcontextprotocol/sdk@1.20.1)(bufferutil@4.0.9)(supports-color@10.2.2)(utf-8-validate@6.0.5) - '@inquirer/prompts': 7.10.0(@types/node@24.10.0) - '@inquirer/type': 3.0.10(@types/node@24.10.0) + '@google/genai': 1.30.0(@modelcontextprotocol/sdk@1.20.1)(bufferutil@4.0.9)(supports-color@10.2.2)(utf-8-validate@6.0.5) + '@inquirer/prompts': 8.0.1(@types/node@24.10.1) + '@inquirer/type': 4.0.1(@types/node@24.10.1) '@octokit/auth-app': 8.1.2 '@octokit/core': 7.0.6 '@octokit/graphql': 9.0.3 @@ -9588,7 +9702,7 @@ snapshots: '@octokit/openapi-types': 27.0.0 '@octokit/plugin-paginate-rest': 14.0.0(@octokit/core@7.0.6) '@octokit/plugin-rest-endpoint-methods': 17.0.0(@octokit/core@7.0.6) - '@octokit/request-error': 7.0.2 + '@octokit/request-error': 7.1.0 '@octokit/rest': 22.0.1 '@octokit/types': 16.0.0 '@pnpm/dependency-path': 1001.1.4 @@ -9597,22 +9711,21 @@ snapshots: '@types/events': 3.0.3 '@types/folder-hash': 4.0.4 '@types/git-raw-commits': 5.0.1 - '@types/jasmine': 5.1.12 - '@types/node': 24.10.0 + '@types/jasmine': 5.1.13 + '@types/node': 24.10.1 '@types/semver': 7.7.1 '@types/which': 3.0.4 - '@types/yargs': 17.0.34 + '@types/yargs': 17.0.35 '@types/yarnpkg__lockfile': 1.1.9 '@yarnpkg/lockfile': 1.1.0 bufferutil: 4.0.9 - chalk: 5.6.2 cli-progress: 3.12.0 conventional-commits-filter: 5.0.0 conventional-commits-parser: 6.2.1 ejs: 3.1.10 encoding: 0.1.13 fast-glob: 3.3.3 - firebase: 12.5.0 + firebase: 12.6.0 folder-hash: 4.1.1(supports-color@10.2.2) git-raw-commits: 5.0.0(conventional-commits-filter@5.0.0)(conventional-commits-parser@6.2.1) jasmine: 5.12.0 @@ -10736,9 +10849,9 @@ snapshots: '@fastify/busboy@2.1.1': {} - '@firebase/ai@2.5.0(@firebase/app-types@0.9.3)(@firebase/app@0.14.5)': + '@firebase/ai@2.6.0(@firebase/app-types@0.9.3)(@firebase/app@0.14.6)': dependencies: - '@firebase/app': 0.14.5 + '@firebase/app': 0.14.6 '@firebase/app-check-interop-types': 0.3.3 '@firebase/app-types': 0.9.3 '@firebase/component': 0.7.0 @@ -10746,11 +10859,11 @@ snapshots: '@firebase/util': 1.13.0 tslib: 2.8.1 - '@firebase/analytics-compat@0.2.25(@firebase/app-compat@0.5.5)(@firebase/app@0.14.5)': + '@firebase/analytics-compat@0.2.25(@firebase/app-compat@0.5.6)(@firebase/app@0.14.6)': dependencies: - '@firebase/analytics': 0.10.19(@firebase/app@0.14.5) + '@firebase/analytics': 0.10.19(@firebase/app@0.14.6) '@firebase/analytics-types': 0.8.3 - '@firebase/app-compat': 0.5.5 + '@firebase/app-compat': 0.5.6 '@firebase/component': 0.7.0 '@firebase/util': 1.13.0 tslib: 2.8.1 @@ -10759,20 +10872,20 @@ snapshots: '@firebase/analytics-types@0.8.3': {} - '@firebase/analytics@0.10.19(@firebase/app@0.14.5)': + '@firebase/analytics@0.10.19(@firebase/app@0.14.6)': dependencies: - '@firebase/app': 0.14.5 + '@firebase/app': 0.14.6 '@firebase/component': 0.7.0 - '@firebase/installations': 0.6.19(@firebase/app@0.14.5) + '@firebase/installations': 0.6.19(@firebase/app@0.14.6) '@firebase/logger': 0.5.0 '@firebase/util': 1.13.0 tslib: 2.8.1 - '@firebase/app-check-compat@0.4.0(@firebase/app-compat@0.5.5)(@firebase/app@0.14.5)': + '@firebase/app-check-compat@0.4.0(@firebase/app-compat@0.5.6)(@firebase/app@0.14.6)': dependencies: - '@firebase/app-check': 0.11.0(@firebase/app@0.14.5) + '@firebase/app-check': 0.11.0(@firebase/app@0.14.6) '@firebase/app-check-types': 0.5.3 - '@firebase/app-compat': 0.5.5 + '@firebase/app-compat': 0.5.6 '@firebase/component': 0.7.0 '@firebase/logger': 0.5.0 '@firebase/util': 1.13.0 @@ -10784,17 +10897,17 @@ snapshots: '@firebase/app-check-types@0.5.3': {} - '@firebase/app-check@0.11.0(@firebase/app@0.14.5)': + '@firebase/app-check@0.11.0(@firebase/app@0.14.6)': dependencies: - '@firebase/app': 0.14.5 + '@firebase/app': 0.14.6 '@firebase/component': 0.7.0 '@firebase/logger': 0.5.0 '@firebase/util': 1.13.0 tslib: 2.8.1 - '@firebase/app-compat@0.5.5': + '@firebase/app-compat@0.5.6': dependencies: - '@firebase/app': 0.14.5 + '@firebase/app': 0.14.6 '@firebase/component': 0.7.0 '@firebase/logger': 0.5.0 '@firebase/util': 1.13.0 @@ -10802,7 +10915,7 @@ snapshots: '@firebase/app-types@0.9.3': {} - '@firebase/app@0.14.5': + '@firebase/app@0.14.6': dependencies: '@firebase/component': 0.7.0 '@firebase/logger': 0.5.0 @@ -10810,10 +10923,10 @@ snapshots: idb: 7.1.1 tslib: 2.8.1 - '@firebase/auth-compat@0.6.1(@firebase/app-compat@0.5.5)(@firebase/app-types@0.9.3)(@firebase/app@0.14.5)': + '@firebase/auth-compat@0.6.1(@firebase/app-compat@0.5.6)(@firebase/app-types@0.9.3)(@firebase/app@0.14.6)': dependencies: - '@firebase/app-compat': 0.5.5 - '@firebase/auth': 1.11.1(@firebase/app@0.14.5) + '@firebase/app-compat': 0.5.6 + '@firebase/auth': 1.11.1(@firebase/app@0.14.6) '@firebase/auth-types': 0.13.0(@firebase/app-types@0.9.3)(@firebase/util@1.13.0) '@firebase/component': 0.7.0 '@firebase/util': 1.13.0 @@ -10830,9 +10943,9 @@ snapshots: '@firebase/app-types': 0.9.3 '@firebase/util': 1.13.0 - '@firebase/auth@1.11.1(@firebase/app@0.14.5)': + '@firebase/auth@1.11.1(@firebase/app@0.14.6)': dependencies: - '@firebase/app': 0.14.5 + '@firebase/app': 0.14.6 '@firebase/component': 0.7.0 '@firebase/logger': 0.5.0 '@firebase/util': 1.13.0 @@ -10843,9 +10956,9 @@ snapshots: '@firebase/util': 1.13.0 tslib: 2.8.1 - '@firebase/data-connect@0.3.11(@firebase/app@0.14.5)': + '@firebase/data-connect@0.3.12(@firebase/app@0.14.6)': dependencies: - '@firebase/app': 0.14.5 + '@firebase/app': 0.14.6 '@firebase/auth-interop-types': 0.2.4 '@firebase/component': 0.7.0 '@firebase/logger': 0.5.0 @@ -10876,11 +10989,11 @@ snapshots: faye-websocket: 0.11.4 tslib: 2.8.1 - '@firebase/firestore-compat@0.4.2(@firebase/app-compat@0.5.5)(@firebase/app-types@0.9.3)(@firebase/app@0.14.5)': + '@firebase/firestore-compat@0.4.2(@firebase/app-compat@0.5.6)(@firebase/app-types@0.9.3)(@firebase/app@0.14.6)': dependencies: - '@firebase/app-compat': 0.5.5 + '@firebase/app-compat': 0.5.6 '@firebase/component': 0.7.0 - '@firebase/firestore': 4.9.2(@firebase/app@0.14.5) + '@firebase/firestore': 4.9.2(@firebase/app@0.14.6) '@firebase/firestore-types': 3.0.3(@firebase/app-types@0.9.3)(@firebase/util@1.13.0) '@firebase/util': 1.13.0 tslib: 2.8.1 @@ -10893,9 +11006,9 @@ snapshots: '@firebase/app-types': 0.9.3 '@firebase/util': 1.13.0 - '@firebase/firestore@4.9.2(@firebase/app@0.14.5)': + '@firebase/firestore@4.9.2(@firebase/app@0.14.6)': dependencies: - '@firebase/app': 0.14.5 + '@firebase/app': 0.14.6 '@firebase/component': 0.7.0 '@firebase/logger': 0.5.0 '@firebase/util': 1.13.0 @@ -10904,11 +11017,11 @@ snapshots: '@grpc/proto-loader': 0.7.15 tslib: 2.8.1 - '@firebase/functions-compat@0.4.1(@firebase/app-compat@0.5.5)(@firebase/app@0.14.5)': + '@firebase/functions-compat@0.4.1(@firebase/app-compat@0.5.6)(@firebase/app@0.14.6)': dependencies: - '@firebase/app-compat': 0.5.5 + '@firebase/app-compat': 0.5.6 '@firebase/component': 0.7.0 - '@firebase/functions': 0.13.1(@firebase/app@0.14.5) + '@firebase/functions': 0.13.1(@firebase/app@0.14.6) '@firebase/functions-types': 0.6.3 '@firebase/util': 1.13.0 tslib: 2.8.1 @@ -10917,9 +11030,9 @@ snapshots: '@firebase/functions-types@0.6.3': {} - '@firebase/functions@0.13.1(@firebase/app@0.14.5)': + '@firebase/functions@0.13.1(@firebase/app@0.14.6)': dependencies: - '@firebase/app': 0.14.5 + '@firebase/app': 0.14.6 '@firebase/app-check-interop-types': 0.3.3 '@firebase/auth-interop-types': 0.2.4 '@firebase/component': 0.7.0 @@ -10927,11 +11040,11 @@ snapshots: '@firebase/util': 1.13.0 tslib: 2.8.1 - '@firebase/installations-compat@0.2.19(@firebase/app-compat@0.5.5)(@firebase/app-types@0.9.3)(@firebase/app@0.14.5)': + '@firebase/installations-compat@0.2.19(@firebase/app-compat@0.5.6)(@firebase/app-types@0.9.3)(@firebase/app@0.14.6)': dependencies: - '@firebase/app-compat': 0.5.5 + '@firebase/app-compat': 0.5.6 '@firebase/component': 0.7.0 - '@firebase/installations': 0.6.19(@firebase/app@0.14.5) + '@firebase/installations': 0.6.19(@firebase/app@0.14.6) '@firebase/installations-types': 0.5.3(@firebase/app-types@0.9.3) '@firebase/util': 1.13.0 tslib: 2.8.1 @@ -10943,9 +11056,9 @@ snapshots: dependencies: '@firebase/app-types': 0.9.3 - '@firebase/installations@0.6.19(@firebase/app@0.14.5)': + '@firebase/installations@0.6.19(@firebase/app@0.14.6)': dependencies: - '@firebase/app': 0.14.5 + '@firebase/app': 0.14.6 '@firebase/component': 0.7.0 '@firebase/util': 1.13.0 idb: 7.1.1 @@ -10955,11 +11068,11 @@ snapshots: dependencies: tslib: 2.8.1 - '@firebase/messaging-compat@0.2.23(@firebase/app-compat@0.5.5)(@firebase/app@0.14.5)': + '@firebase/messaging-compat@0.2.23(@firebase/app-compat@0.5.6)(@firebase/app@0.14.6)': dependencies: - '@firebase/app-compat': 0.5.5 + '@firebase/app-compat': 0.5.6 '@firebase/component': 0.7.0 - '@firebase/messaging': 0.12.23(@firebase/app@0.14.5) + '@firebase/messaging': 0.12.23(@firebase/app@0.14.6) '@firebase/util': 1.13.0 tslib: 2.8.1 transitivePeerDependencies: @@ -10967,22 +11080,22 @@ snapshots: '@firebase/messaging-interop-types@0.2.3': {} - '@firebase/messaging@0.12.23(@firebase/app@0.14.5)': + '@firebase/messaging@0.12.23(@firebase/app@0.14.6)': dependencies: - '@firebase/app': 0.14.5 + '@firebase/app': 0.14.6 '@firebase/component': 0.7.0 - '@firebase/installations': 0.6.19(@firebase/app@0.14.5) + '@firebase/installations': 0.6.19(@firebase/app@0.14.6) '@firebase/messaging-interop-types': 0.2.3 '@firebase/util': 1.13.0 idb: 7.1.1 tslib: 2.8.1 - '@firebase/performance-compat@0.2.22(@firebase/app-compat@0.5.5)(@firebase/app@0.14.5)': + '@firebase/performance-compat@0.2.22(@firebase/app-compat@0.5.6)(@firebase/app@0.14.6)': dependencies: - '@firebase/app-compat': 0.5.5 + '@firebase/app-compat': 0.5.6 '@firebase/component': 0.7.0 '@firebase/logger': 0.5.0 - '@firebase/performance': 0.7.9(@firebase/app@0.14.5) + '@firebase/performance': 0.7.9(@firebase/app@0.14.6) '@firebase/performance-types': 0.2.3 '@firebase/util': 1.13.0 tslib: 2.8.1 @@ -10991,22 +11104,22 @@ snapshots: '@firebase/performance-types@0.2.3': {} - '@firebase/performance@0.7.9(@firebase/app@0.14.5)': + '@firebase/performance@0.7.9(@firebase/app@0.14.6)': dependencies: - '@firebase/app': 0.14.5 + '@firebase/app': 0.14.6 '@firebase/component': 0.7.0 - '@firebase/installations': 0.6.19(@firebase/app@0.14.5) + '@firebase/installations': 0.6.19(@firebase/app@0.14.6) '@firebase/logger': 0.5.0 '@firebase/util': 1.13.0 tslib: 2.8.1 web-vitals: 4.2.4 - '@firebase/remote-config-compat@0.2.20(@firebase/app-compat@0.5.5)(@firebase/app@0.14.5)': + '@firebase/remote-config-compat@0.2.20(@firebase/app-compat@0.5.6)(@firebase/app@0.14.6)': dependencies: - '@firebase/app-compat': 0.5.5 + '@firebase/app-compat': 0.5.6 '@firebase/component': 0.7.0 '@firebase/logger': 0.5.0 - '@firebase/remote-config': 0.7.0(@firebase/app@0.14.5) + '@firebase/remote-config': 0.7.0(@firebase/app@0.14.6) '@firebase/remote-config-types': 0.5.0 '@firebase/util': 1.13.0 tslib: 2.8.1 @@ -11015,20 +11128,20 @@ snapshots: '@firebase/remote-config-types@0.5.0': {} - '@firebase/remote-config@0.7.0(@firebase/app@0.14.5)': + '@firebase/remote-config@0.7.0(@firebase/app@0.14.6)': dependencies: - '@firebase/app': 0.14.5 + '@firebase/app': 0.14.6 '@firebase/component': 0.7.0 - '@firebase/installations': 0.6.19(@firebase/app@0.14.5) + '@firebase/installations': 0.6.19(@firebase/app@0.14.6) '@firebase/logger': 0.5.0 '@firebase/util': 1.13.0 tslib: 2.8.1 - '@firebase/storage-compat@0.4.0(@firebase/app-compat@0.5.5)(@firebase/app-types@0.9.3)(@firebase/app@0.14.5)': + '@firebase/storage-compat@0.4.0(@firebase/app-compat@0.5.6)(@firebase/app-types@0.9.3)(@firebase/app@0.14.6)': dependencies: - '@firebase/app-compat': 0.5.5 + '@firebase/app-compat': 0.5.6 '@firebase/component': 0.7.0 - '@firebase/storage': 0.14.0(@firebase/app@0.14.5) + '@firebase/storage': 0.14.0(@firebase/app@0.14.6) '@firebase/storage-types': 0.8.3(@firebase/app-types@0.9.3)(@firebase/util@1.13.0) '@firebase/util': 1.13.0 tslib: 2.8.1 @@ -11041,9 +11154,9 @@ snapshots: '@firebase/app-types': 0.9.3 '@firebase/util': 1.13.0 - '@firebase/storage@0.14.0(@firebase/app@0.14.5)': + '@firebase/storage@0.14.0(@firebase/app@0.14.6)': dependencies: - '@firebase/app': 0.14.5 + '@firebase/app': 0.14.6 '@firebase/component': 0.7.0 '@firebase/util': 1.13.0 tslib: 2.8.1 @@ -11115,7 +11228,7 @@ snapshots: transitivePeerDependencies: - supports-color - '@google/genai@1.29.0(@modelcontextprotocol/sdk@1.20.1)(bufferutil@4.0.9)(supports-color@10.2.2)(utf-8-validate@6.0.5)': + '@google/genai@1.30.0(@modelcontextprotocol/sdk@1.20.1)(bufferutil@4.0.9)(supports-color@10.2.2)(utf-8-validate@6.0.5)': dependencies: google-auth-library: 10.5.0(supports-color@10.2.2) ws: 8.18.3(bufferutil@4.0.9)(utf-8-validate@6.0.5) @@ -11165,150 +11278,247 @@ snapshots: '@inquirer/ansi@1.0.2': {} - '@inquirer/checkbox@4.3.2(@types/node@24.10.0)': + '@inquirer/ansi@2.0.1': {} + + '@inquirer/checkbox@4.3.2(@types/node@24.10.1)': dependencies: '@inquirer/ansi': 1.0.2 - '@inquirer/core': 10.3.2(@types/node@24.10.0) + '@inquirer/core': 10.3.2(@types/node@24.10.1) '@inquirer/figures': 1.0.15 - '@inquirer/type': 3.0.10(@types/node@24.10.0) + '@inquirer/type': 3.0.10(@types/node@24.10.1) yoctocolors-cjs: 2.1.3 optionalDependencies: - '@types/node': 24.10.0 + '@types/node': 24.10.1 + + '@inquirer/checkbox@5.0.1(@types/node@24.10.1)': + dependencies: + '@inquirer/ansi': 2.0.1 + '@inquirer/core': 11.0.1(@types/node@24.10.1) + '@inquirer/figures': 2.0.1 + '@inquirer/type': 4.0.1(@types/node@24.10.1) + optionalDependencies: + '@types/node': 24.10.1 - '@inquirer/confirm@5.1.19(@types/node@24.10.0)': + '@inquirer/confirm@5.1.19(@types/node@24.10.1)': dependencies: - '@inquirer/core': 10.3.2(@types/node@24.10.0) - '@inquirer/type': 3.0.10(@types/node@24.10.0) + '@inquirer/core': 10.3.2(@types/node@24.10.1) + '@inquirer/type': 3.0.10(@types/node@24.10.1) optionalDependencies: - '@types/node': 24.10.0 + '@types/node': 24.10.1 - '@inquirer/confirm@5.1.21(@types/node@24.10.0)': + '@inquirer/confirm@6.0.1(@types/node@24.10.1)': dependencies: - '@inquirer/core': 10.3.2(@types/node@24.10.0) - '@inquirer/type': 3.0.10(@types/node@24.10.0) + '@inquirer/core': 11.0.1(@types/node@24.10.1) + '@inquirer/type': 4.0.1(@types/node@24.10.1) optionalDependencies: - '@types/node': 24.10.0 + '@types/node': 24.10.1 - '@inquirer/core@10.3.2(@types/node@24.10.0)': + '@inquirer/core@10.3.2(@types/node@24.10.1)': dependencies: '@inquirer/ansi': 1.0.2 '@inquirer/figures': 1.0.15 - '@inquirer/type': 3.0.10(@types/node@24.10.0) + '@inquirer/type': 3.0.10(@types/node@24.10.1) cli-width: 4.1.0 mute-stream: 2.0.0 signal-exit: 4.1.0 wrap-ansi: 6.2.0 yoctocolors-cjs: 2.1.3 optionalDependencies: - '@types/node': 24.10.0 + '@types/node': 24.10.1 + + '@inquirer/core@11.0.1(@types/node@24.10.1)': + dependencies: + '@inquirer/ansi': 2.0.1 + '@inquirer/figures': 2.0.1 + '@inquirer/type': 4.0.1(@types/node@24.10.1) + cli-width: 4.1.0 + mute-stream: 3.0.0 + signal-exit: 4.1.0 + wrap-ansi: 9.0.2 + optionalDependencies: + '@types/node': 24.10.1 + + '@inquirer/editor@4.2.23(@types/node@24.10.1)': + dependencies: + '@inquirer/core': 10.3.2(@types/node@24.10.1) + '@inquirer/external-editor': 1.0.3(@types/node@24.10.1) + '@inquirer/type': 3.0.10(@types/node@24.10.1) + optionalDependencies: + '@types/node': 24.10.1 - '@inquirer/editor@4.2.23(@types/node@24.10.0)': + '@inquirer/editor@5.0.1(@types/node@24.10.1)': dependencies: - '@inquirer/core': 10.3.2(@types/node@24.10.0) - '@inquirer/external-editor': 1.0.3(@types/node@24.10.0) - '@inquirer/type': 3.0.10(@types/node@24.10.0) + '@inquirer/core': 11.0.1(@types/node@24.10.1) + '@inquirer/external-editor': 2.0.1(@types/node@24.10.1) + '@inquirer/type': 4.0.1(@types/node@24.10.1) optionalDependencies: - '@types/node': 24.10.0 + '@types/node': 24.10.1 - '@inquirer/expand@4.0.23(@types/node@24.10.0)': + '@inquirer/expand@4.0.23(@types/node@24.10.1)': dependencies: - '@inquirer/core': 10.3.2(@types/node@24.10.0) - '@inquirer/type': 3.0.10(@types/node@24.10.0) + '@inquirer/core': 10.3.2(@types/node@24.10.1) + '@inquirer/type': 3.0.10(@types/node@24.10.1) yoctocolors-cjs: 2.1.3 optionalDependencies: - '@types/node': 24.10.0 + '@types/node': 24.10.1 + + '@inquirer/expand@5.0.1(@types/node@24.10.1)': + dependencies: + '@inquirer/core': 11.0.1(@types/node@24.10.1) + '@inquirer/type': 4.0.1(@types/node@24.10.1) + optionalDependencies: + '@types/node': 24.10.1 - '@inquirer/external-editor@1.0.3(@types/node@24.10.0)': + '@inquirer/external-editor@1.0.3(@types/node@24.10.1)': dependencies: chardet: 2.1.1 iconv-lite: 0.7.0 optionalDependencies: - '@types/node': 24.10.0 + '@types/node': 24.10.1 + + '@inquirer/external-editor@2.0.1(@types/node@24.10.1)': + dependencies: + chardet: 2.1.1 + iconv-lite: 0.7.0 + optionalDependencies: + '@types/node': 24.10.1 '@inquirer/figures@1.0.15': {} - '@inquirer/input@4.3.1(@types/node@24.10.0)': + '@inquirer/figures@2.0.1': {} + + '@inquirer/input@4.3.1(@types/node@24.10.1)': + dependencies: + '@inquirer/core': 10.3.2(@types/node@24.10.1) + '@inquirer/type': 3.0.10(@types/node@24.10.1) + optionalDependencies: + '@types/node': 24.10.1 + + '@inquirer/input@5.0.1(@types/node@24.10.1)': dependencies: - '@inquirer/core': 10.3.2(@types/node@24.10.0) - '@inquirer/type': 3.0.10(@types/node@24.10.0) + '@inquirer/core': 11.0.1(@types/node@24.10.1) + '@inquirer/type': 4.0.1(@types/node@24.10.1) optionalDependencies: - '@types/node': 24.10.0 + '@types/node': 24.10.1 - '@inquirer/number@3.0.23(@types/node@24.10.0)': + '@inquirer/number@3.0.23(@types/node@24.10.1)': dependencies: - '@inquirer/core': 10.3.2(@types/node@24.10.0) - '@inquirer/type': 3.0.10(@types/node@24.10.0) + '@inquirer/core': 10.3.2(@types/node@24.10.1) + '@inquirer/type': 3.0.10(@types/node@24.10.1) optionalDependencies: - '@types/node': 24.10.0 + '@types/node': 24.10.1 - '@inquirer/password@4.0.23(@types/node@24.10.0)': + '@inquirer/number@4.0.1(@types/node@24.10.1)': + dependencies: + '@inquirer/core': 11.0.1(@types/node@24.10.1) + '@inquirer/type': 4.0.1(@types/node@24.10.1) + optionalDependencies: + '@types/node': 24.10.1 + + '@inquirer/password@4.0.23(@types/node@24.10.1)': dependencies: '@inquirer/ansi': 1.0.2 - '@inquirer/core': 10.3.2(@types/node@24.10.0) - '@inquirer/type': 3.0.10(@types/node@24.10.0) + '@inquirer/core': 10.3.2(@types/node@24.10.1) + '@inquirer/type': 3.0.10(@types/node@24.10.1) + optionalDependencies: + '@types/node': 24.10.1 + + '@inquirer/password@5.0.1(@types/node@24.10.1)': + dependencies: + '@inquirer/ansi': 2.0.1 + '@inquirer/core': 11.0.1(@types/node@24.10.1) + '@inquirer/type': 4.0.1(@types/node@24.10.1) optionalDependencies: - '@types/node': 24.10.0 - - '@inquirer/prompts@7.10.0(@types/node@24.10.0)': - dependencies: - '@inquirer/checkbox': 4.3.2(@types/node@24.10.0) - '@inquirer/confirm': 5.1.21(@types/node@24.10.0) - '@inquirer/editor': 4.2.23(@types/node@24.10.0) - '@inquirer/expand': 4.0.23(@types/node@24.10.0) - '@inquirer/input': 4.3.1(@types/node@24.10.0) - '@inquirer/number': 3.0.23(@types/node@24.10.0) - '@inquirer/password': 4.0.23(@types/node@24.10.0) - '@inquirer/rawlist': 4.1.11(@types/node@24.10.0) - '@inquirer/search': 3.2.2(@types/node@24.10.0) - '@inquirer/select': 4.4.2(@types/node@24.10.0) + '@types/node': 24.10.1 + + '@inquirer/prompts@7.9.0(@types/node@24.10.1)': + dependencies: + '@inquirer/checkbox': 4.3.2(@types/node@24.10.1) + '@inquirer/confirm': 5.1.19(@types/node@24.10.1) + '@inquirer/editor': 4.2.23(@types/node@24.10.1) + '@inquirer/expand': 4.0.23(@types/node@24.10.1) + '@inquirer/input': 4.3.1(@types/node@24.10.1) + '@inquirer/number': 3.0.23(@types/node@24.10.1) + '@inquirer/password': 4.0.23(@types/node@24.10.1) + '@inquirer/rawlist': 4.1.11(@types/node@24.10.1) + '@inquirer/search': 3.2.2(@types/node@24.10.1) + '@inquirer/select': 4.4.2(@types/node@24.10.1) optionalDependencies: - '@types/node': 24.10.0 - - '@inquirer/prompts@7.9.0(@types/node@24.10.0)': - dependencies: - '@inquirer/checkbox': 4.3.2(@types/node@24.10.0) - '@inquirer/confirm': 5.1.19(@types/node@24.10.0) - '@inquirer/editor': 4.2.23(@types/node@24.10.0) - '@inquirer/expand': 4.0.23(@types/node@24.10.0) - '@inquirer/input': 4.3.1(@types/node@24.10.0) - '@inquirer/number': 3.0.23(@types/node@24.10.0) - '@inquirer/password': 4.0.23(@types/node@24.10.0) - '@inquirer/rawlist': 4.1.11(@types/node@24.10.0) - '@inquirer/search': 3.2.2(@types/node@24.10.0) - '@inquirer/select': 4.4.2(@types/node@24.10.0) + '@types/node': 24.10.1 + + '@inquirer/prompts@8.0.1(@types/node@24.10.1)': + dependencies: + '@inquirer/checkbox': 5.0.1(@types/node@24.10.1) + '@inquirer/confirm': 6.0.1(@types/node@24.10.1) + '@inquirer/editor': 5.0.1(@types/node@24.10.1) + '@inquirer/expand': 5.0.1(@types/node@24.10.1) + '@inquirer/input': 5.0.1(@types/node@24.10.1) + '@inquirer/number': 4.0.1(@types/node@24.10.1) + '@inquirer/password': 5.0.1(@types/node@24.10.1) + '@inquirer/rawlist': 5.0.1(@types/node@24.10.1) + '@inquirer/search': 4.0.1(@types/node@24.10.1) + '@inquirer/select': 5.0.1(@types/node@24.10.1) optionalDependencies: - '@types/node': 24.10.0 + '@types/node': 24.10.1 - '@inquirer/rawlist@4.1.11(@types/node@24.10.0)': + '@inquirer/rawlist@4.1.11(@types/node@24.10.1)': dependencies: - '@inquirer/core': 10.3.2(@types/node@24.10.0) - '@inquirer/type': 3.0.10(@types/node@24.10.0) + '@inquirer/core': 10.3.2(@types/node@24.10.1) + '@inquirer/type': 3.0.10(@types/node@24.10.1) yoctocolors-cjs: 2.1.3 optionalDependencies: - '@types/node': 24.10.0 + '@types/node': 24.10.1 - '@inquirer/search@3.2.2(@types/node@24.10.0)': + '@inquirer/rawlist@5.0.1(@types/node@24.10.1)': dependencies: - '@inquirer/core': 10.3.2(@types/node@24.10.0) + '@inquirer/core': 11.0.1(@types/node@24.10.1) + '@inquirer/type': 4.0.1(@types/node@24.10.1) + optionalDependencies: + '@types/node': 24.10.1 + + '@inquirer/search@3.2.2(@types/node@24.10.1)': + dependencies: + '@inquirer/core': 10.3.2(@types/node@24.10.1) '@inquirer/figures': 1.0.15 - '@inquirer/type': 3.0.10(@types/node@24.10.0) + '@inquirer/type': 3.0.10(@types/node@24.10.1) yoctocolors-cjs: 2.1.3 optionalDependencies: - '@types/node': 24.10.0 + '@types/node': 24.10.1 + + '@inquirer/search@4.0.1(@types/node@24.10.1)': + dependencies: + '@inquirer/core': 11.0.1(@types/node@24.10.1) + '@inquirer/figures': 2.0.1 + '@inquirer/type': 4.0.1(@types/node@24.10.1) + optionalDependencies: + '@types/node': 24.10.1 - '@inquirer/select@4.4.2(@types/node@24.10.0)': + '@inquirer/select@4.4.2(@types/node@24.10.1)': dependencies: '@inquirer/ansi': 1.0.2 - '@inquirer/core': 10.3.2(@types/node@24.10.0) + '@inquirer/core': 10.3.2(@types/node@24.10.1) '@inquirer/figures': 1.0.15 - '@inquirer/type': 3.0.10(@types/node@24.10.0) + '@inquirer/type': 3.0.10(@types/node@24.10.1) yoctocolors-cjs: 2.1.3 optionalDependencies: - '@types/node': 24.10.0 + '@types/node': 24.10.1 + + '@inquirer/select@5.0.1(@types/node@24.10.1)': + dependencies: + '@inquirer/ansi': 2.0.1 + '@inquirer/core': 11.0.1(@types/node@24.10.1) + '@inquirer/figures': 2.0.1 + '@inquirer/type': 4.0.1(@types/node@24.10.1) + optionalDependencies: + '@types/node': 24.10.1 + + '@inquirer/type@3.0.10(@types/node@24.10.1)': + optionalDependencies: + '@types/node': 24.10.1 - '@inquirer/type@3.0.10(@types/node@24.10.0)': + '@inquirer/type@4.0.1(@types/node@24.10.1)': optionalDependencies: - '@types/node': 24.10.0 + '@types/node': 24.10.1 '@isaacs/balanced-match@4.0.1': {} @@ -11400,10 +11610,10 @@ snapshots: '@leichtgewicht/ip-codec@2.0.5': {} - '@listr2/prompt-adapter-inquirer@3.0.5(@inquirer/prompts@7.9.0(@types/node@24.10.0))(@types/node@24.10.0)(listr2@9.0.5)': + '@listr2/prompt-adapter-inquirer@3.0.5(@inquirer/prompts@7.9.0(@types/node@24.10.1))(@types/node@24.10.1)(listr2@9.0.5)': dependencies: - '@inquirer/prompts': 7.9.0(@types/node@24.10.0) - '@inquirer/type': 3.0.10(@types/node@24.10.0) + '@inquirer/prompts': 7.9.0(@types/node@24.10.1) + '@inquirer/type': 3.0.10(@types/node@24.10.1) listr2: 9.0.5 transitivePeerDependencies: - '@types/node' @@ -11632,7 +11842,7 @@ snapshots: '@octokit/auth-oauth-app': 9.0.3 '@octokit/auth-oauth-user': 6.0.2 '@octokit/request': 10.0.7 - '@octokit/request-error': 7.0.2 + '@octokit/request-error': 7.1.0 '@octokit/types': 16.0.0 toad-cache: 3.7.0 universal-github-app-jwt: 2.2.2 @@ -11668,7 +11878,7 @@ snapshots: '@octokit/auth-token': 6.0.0 '@octokit/graphql': 9.0.3 '@octokit/request': 10.0.7 - '@octokit/request-error': 7.0.2 + '@octokit/request-error': 7.1.0 '@octokit/types': 16.0.0 before-after-hook: 4.0.0 universal-user-agent: 7.0.3 @@ -11695,7 +11905,7 @@ snapshots: dependencies: '@octokit/oauth-authorization-url': 8.0.0 '@octokit/request': 10.0.7 - '@octokit/request-error': 7.0.2 + '@octokit/request-error': 7.1.0 '@octokit/types': 16.0.0 '@octokit/openapi-types@27.0.0': {} @@ -11714,14 +11924,14 @@ snapshots: '@octokit/core': 7.0.6 '@octokit/types': 16.0.0 - '@octokit/request-error@7.0.2': + '@octokit/request-error@7.1.0': dependencies: '@octokit/types': 16.0.0 '@octokit/request@10.0.7': dependencies: '@octokit/endpoint': 11.0.2 - '@octokit/request-error': 7.0.2 + '@octokit/request-error': 7.1.0 '@octokit/types': 16.0.0 fast-content-type-parse: 3.0.0 universal-user-agent: 7.0.3 @@ -12307,8 +12517,6 @@ snapshots: dependencies: '@types/jasmine': 5.1.13 - '@types/jasmine@5.1.12': {} - '@types/jasmine@5.1.13': {} '@types/json-schema@7.0.15': {} @@ -12372,7 +12580,7 @@ snapshots: dependencies: undici-types: 7.16.0 - '@types/node@24.10.0': + '@types/node@24.10.1': dependencies: undici-types: 7.16.0 @@ -12483,10 +12691,6 @@ snapshots: '@types/yargs-parser@21.0.3': {} - '@types/yargs@17.0.34': - dependencies: - '@types/yargs-parser': 21.0.3 - '@types/yargs@17.0.35': dependencies: '@types/yargs-parser': 21.0.3 @@ -12753,11 +12957,11 @@ snapshots: lodash: 4.17.21 minimatch: 7.4.6 - '@vitejs/plugin-basic-ssl@2.1.0(vite@7.2.2(@types/node@24.10.0)(jiti@2.6.1)(less@4.4.2)(sass@1.93.2)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1))': + '@vitejs/plugin-basic-ssl@2.1.0(vite@7.2.2(@types/node@24.10.1)(jiti@2.6.1)(less@4.4.2)(sass@1.93.2)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1))': dependencies: - vite: 7.2.2(@types/node@24.10.0)(jiti@2.6.1)(less@4.4.2)(sass@1.93.2)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1) + vite: 7.2.2(@types/node@24.10.1)(jiti@2.6.1)(less@4.4.2)(sass@1.93.2)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1) - '@vitest/coverage-v8@4.0.8(vitest@4.0.8(@types/node@24.10.0)(jiti@2.6.1)(jsdom@27.1.0(bufferutil@4.0.9)(utf-8-validate@6.0.5))(less@4.4.2)(sass@1.93.2)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1))': + '@vitest/coverage-v8@4.0.8(vitest@4.0.8(@types/node@24.10.1)(jiti@2.6.1)(jsdom@27.1.0(bufferutil@4.0.9)(utf-8-validate@6.0.5))(less@4.4.2)(sass@1.93.2)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1))': dependencies: '@bcoe/v8-coverage': 1.0.2 '@vitest/utils': 4.0.8 @@ -12770,7 +12974,7 @@ snapshots: magicast: 0.5.1 std-env: 3.10.0 tinyrainbow: 3.0.3 - vitest: 4.0.8(@types/node@24.10.0)(jiti@2.6.1)(jsdom@27.1.0(bufferutil@4.0.9)(utf-8-validate@6.0.5))(less@4.4.2)(sass@1.93.2)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1) + vitest: 4.0.8(@types/node@24.10.1)(jiti@2.6.1)(jsdom@27.1.0(bufferutil@4.0.9)(utf-8-validate@6.0.5))(less@4.4.2)(sass@1.93.2)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1) transitivePeerDependencies: - supports-color @@ -12783,13 +12987,13 @@ snapshots: chai: 6.2.1 tinyrainbow: 3.0.3 - '@vitest/mocker@4.0.8(vite@7.2.2(@types/node@24.10.0)(jiti@2.6.1)(less@4.4.2)(sass@1.93.2)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1))': + '@vitest/mocker@4.0.8(vite@7.2.2(@types/node@24.10.1)(jiti@2.6.1)(less@4.4.2)(sass@1.93.2)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1))': dependencies: '@vitest/spy': 4.0.8 estree-walker: 3.0.3 magic-string: 0.30.21 optionalDependencies: - vite: 7.2.2(@types/node@24.10.0)(jiti@2.6.1)(less@4.4.2)(sass@1.93.2)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1) + vite: 7.2.2(@types/node@24.10.1)(jiti@2.6.1)(less@4.4.2)(sass@1.93.2)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1) '@vitest/pretty-format@4.0.8': dependencies: @@ -14794,7 +14998,7 @@ snapshots: extract-zip@2.0.1: dependencies: - debug: 4.3.4 + debug: 4.4.3(supports-color@10.2.2) get-stream: 5.2.0 yauzl: 2.10.0 optionalDependencies: @@ -14927,35 +15131,35 @@ snapshots: locate-path: 6.0.0 path-exists: 4.0.0 - firebase@12.5.0: + firebase@12.6.0: dependencies: - '@firebase/ai': 2.5.0(@firebase/app-types@0.9.3)(@firebase/app@0.14.5) - '@firebase/analytics': 0.10.19(@firebase/app@0.14.5) - '@firebase/analytics-compat': 0.2.25(@firebase/app-compat@0.5.5)(@firebase/app@0.14.5) - '@firebase/app': 0.14.5 - '@firebase/app-check': 0.11.0(@firebase/app@0.14.5) - '@firebase/app-check-compat': 0.4.0(@firebase/app-compat@0.5.5)(@firebase/app@0.14.5) - '@firebase/app-compat': 0.5.5 + '@firebase/ai': 2.6.0(@firebase/app-types@0.9.3)(@firebase/app@0.14.6) + '@firebase/analytics': 0.10.19(@firebase/app@0.14.6) + '@firebase/analytics-compat': 0.2.25(@firebase/app-compat@0.5.6)(@firebase/app@0.14.6) + '@firebase/app': 0.14.6 + '@firebase/app-check': 0.11.0(@firebase/app@0.14.6) + '@firebase/app-check-compat': 0.4.0(@firebase/app-compat@0.5.6)(@firebase/app@0.14.6) + '@firebase/app-compat': 0.5.6 '@firebase/app-types': 0.9.3 - '@firebase/auth': 1.11.1(@firebase/app@0.14.5) - '@firebase/auth-compat': 0.6.1(@firebase/app-compat@0.5.5)(@firebase/app-types@0.9.3)(@firebase/app@0.14.5) - '@firebase/data-connect': 0.3.11(@firebase/app@0.14.5) + '@firebase/auth': 1.11.1(@firebase/app@0.14.6) + '@firebase/auth-compat': 0.6.1(@firebase/app-compat@0.5.6)(@firebase/app-types@0.9.3)(@firebase/app@0.14.6) + '@firebase/data-connect': 0.3.12(@firebase/app@0.14.6) '@firebase/database': 1.1.0 '@firebase/database-compat': 2.1.0 - '@firebase/firestore': 4.9.2(@firebase/app@0.14.5) - '@firebase/firestore-compat': 0.4.2(@firebase/app-compat@0.5.5)(@firebase/app-types@0.9.3)(@firebase/app@0.14.5) - '@firebase/functions': 0.13.1(@firebase/app@0.14.5) - '@firebase/functions-compat': 0.4.1(@firebase/app-compat@0.5.5)(@firebase/app@0.14.5) - '@firebase/installations': 0.6.19(@firebase/app@0.14.5) - '@firebase/installations-compat': 0.2.19(@firebase/app-compat@0.5.5)(@firebase/app-types@0.9.3)(@firebase/app@0.14.5) - '@firebase/messaging': 0.12.23(@firebase/app@0.14.5) - '@firebase/messaging-compat': 0.2.23(@firebase/app-compat@0.5.5)(@firebase/app@0.14.5) - '@firebase/performance': 0.7.9(@firebase/app@0.14.5) - '@firebase/performance-compat': 0.2.22(@firebase/app-compat@0.5.5)(@firebase/app@0.14.5) - '@firebase/remote-config': 0.7.0(@firebase/app@0.14.5) - '@firebase/remote-config-compat': 0.2.20(@firebase/app-compat@0.5.5)(@firebase/app@0.14.5) - '@firebase/storage': 0.14.0(@firebase/app@0.14.5) - '@firebase/storage-compat': 0.4.0(@firebase/app-compat@0.5.5)(@firebase/app-types@0.9.3)(@firebase/app@0.14.5) + '@firebase/firestore': 4.9.2(@firebase/app@0.14.6) + '@firebase/firestore-compat': 0.4.2(@firebase/app-compat@0.5.6)(@firebase/app-types@0.9.3)(@firebase/app@0.14.6) + '@firebase/functions': 0.13.1(@firebase/app@0.14.6) + '@firebase/functions-compat': 0.4.1(@firebase/app-compat@0.5.6)(@firebase/app@0.14.6) + '@firebase/installations': 0.6.19(@firebase/app@0.14.6) + '@firebase/installations-compat': 0.2.19(@firebase/app-compat@0.5.6)(@firebase/app-types@0.9.3)(@firebase/app@0.14.6) + '@firebase/messaging': 0.12.23(@firebase/app@0.14.6) + '@firebase/messaging-compat': 0.2.23(@firebase/app-compat@0.5.6)(@firebase/app@0.14.6) + '@firebase/performance': 0.7.9(@firebase/app@0.14.6) + '@firebase/performance-compat': 0.2.22(@firebase/app-compat@0.5.6)(@firebase/app@0.14.6) + '@firebase/remote-config': 0.7.0(@firebase/app@0.14.6) + '@firebase/remote-config-compat': 0.2.20(@firebase/app-compat@0.5.6)(@firebase/app@0.14.6) + '@firebase/storage': 0.14.0(@firebase/app@0.14.6) + '@firebase/storage-compat': 0.4.0(@firebase/app-compat@0.5.6)(@firebase/app-types@0.9.3)(@firebase/app@0.14.6) '@firebase/util': 1.13.0 transitivePeerDependencies: - '@react-native-async-storage/async-storage' @@ -16544,6 +16748,8 @@ snapshots: mute-stream@2.0.0: {} + mute-stream@3.0.0: {} + nanocolors@0.2.13: {} nanoid@3.3.11: {} @@ -18676,7 +18882,7 @@ snapshots: core-util-is: 1.0.2 extsprintf: 1.3.0 - vite@7.2.2(@types/node@24.10.0)(jiti@2.6.1)(less@4.4.2)(sass@1.93.2)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1): + vite@7.2.2(@types/node@24.10.1)(jiti@2.6.1)(less@4.4.2)(sass@1.93.2)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1): dependencies: esbuild: 0.25.12 fdir: 6.5.0(picomatch@4.0.3) @@ -18685,7 +18891,7 @@ snapshots: rollup: 4.52.5 tinyglobby: 0.2.15 optionalDependencies: - '@types/node': 24.10.0 + '@types/node': 24.10.1 fsevents: 2.3.3 jiti: 2.6.1 less: 4.4.2 @@ -18694,10 +18900,10 @@ snapshots: tsx: 4.20.6 yaml: 2.8.1 - vitest@4.0.8(@types/node@24.10.0)(jiti@2.6.1)(jsdom@27.1.0(bufferutil@4.0.9)(utf-8-validate@6.0.5))(less@4.4.2)(sass@1.93.2)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1): + vitest@4.0.8(@types/node@24.10.1)(jiti@2.6.1)(jsdom@27.1.0(bufferutil@4.0.9)(utf-8-validate@6.0.5))(less@4.4.2)(sass@1.93.2)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1): dependencies: '@vitest/expect': 4.0.8 - '@vitest/mocker': 4.0.8(vite@7.2.2(@types/node@24.10.0)(jiti@2.6.1)(less@4.4.2)(sass@1.93.2)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1)) + '@vitest/mocker': 4.0.8(vite@7.2.2(@types/node@24.10.1)(jiti@2.6.1)(less@4.4.2)(sass@1.93.2)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1)) '@vitest/pretty-format': 4.0.8 '@vitest/runner': 4.0.8 '@vitest/snapshot': 4.0.8 @@ -18714,10 +18920,10 @@ snapshots: tinyexec: 0.3.2 tinyglobby: 0.2.15 tinyrainbow: 3.0.3 - vite: 7.2.2(@types/node@24.10.0)(jiti@2.6.1)(less@4.4.2)(sass@1.93.2)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1) + vite: 7.2.2(@types/node@24.10.1)(jiti@2.6.1)(less@4.4.2)(sass@1.93.2)(terser@5.44.0)(tsx@4.20.6)(yaml@2.8.1) why-is-node-running: 2.3.0 optionalDependencies: - '@types/node': 24.10.0 + '@types/node': 24.10.1 jsdom: 27.1.0(bufferutil@4.0.9)(utf-8-validate@6.0.5) transitivePeerDependencies: - jiti From a13b07fdb07646bacda92345f24da2cad286b1c3 Mon Sep 17 00:00:00 2001 From: Joey Perrott Date: Wed, 19 Nov 2025 22:11:45 +0000 Subject: [PATCH 22/54] build: update to latest ng-dev tooling for caretaker handoff update Update to the latest tooling to upate how caretaker handoff is handled, using new standardized groupings (cherry picked from commit f9de11d67d3e0e0524372819583bc77756596d4f) --- .ng-dev/caretaker.mjs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/.ng-dev/caretaker.mjs b/.ng-dev/caretaker.mjs index a16e023b1cd0..d21e783f4af5 100644 --- a/.ng-dev/caretaker.mjs +++ b/.ng-dev/caretaker.mjs @@ -1,6 +1,6 @@ /** * The configuration for `ng-dev caretaker` commands. - * + * * @type { import("@angular/ng-dev").CaretakerConfig } */ export const caretaker = { @@ -14,5 +14,4 @@ export const caretaker = { query: `is:pr is:open label:"action: merge-assistance"`, }, ], - caretakerGroup: 'angular-cli-caretaker', }; From ee4944aeb70764977a56adadcaeab50f2cd90d7b Mon Sep 17 00:00:00 2001 From: Alan Agius <17563226+alan-agius4@users.noreply.github.com> Date: Thu, 20 Nov 2025 10:06:24 +0000 Subject: [PATCH 23/54] build: add README.md to the SSR `ng_package` Adds a readme to the npm package (cherry picked from commit 439c463213b74c5019527875066b07a2972a7e85) --- packages/angular/ssr/BUILD.bazel | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/angular/ssr/BUILD.bazel b/packages/angular/ssr/BUILD.bazel index 64b6f29ee270..dc70ac3fdf5b 100644 --- a/packages/angular/ssr/BUILD.bazel +++ b/packages/angular/ssr/BUILD.bazel @@ -61,6 +61,7 @@ ng_package( "//packages/angular/ssr/third_party/beasties:beasties_dts", ], package = "@angular/ssr", + readme_md = ":README.md", rollup_runtime_deps = [ "//:node_modules/@babel/core", "//:node_modules/@rollup/plugin-commonjs", From 54d542738e23c275ac6827f19da92213c405f9e2 Mon Sep 17 00:00:00 2001 From: Alan Agius <17563226+alan-agius4@users.noreply.github.com> Date: Thu, 20 Nov 2025 11:14:39 +0000 Subject: [PATCH 24/54] fix(@angular/build): ensure correct URL joining for prerender routes This commit addresses an issue where prerendering with i18n and a `routesFile` could lead to infinite redirect loops or failure to prerender `index.html`. The previous `urlJoin` utility was replaced with more robust URL manipulation functions (`joinUrlParts`, `addTrailingSlash`, `stripLeadingSlash`) to ensure that paths are correctly constructed, especially when dealing with base hrefs and locale subpaths. This ensures that routes from the `routesFile` are correctly joined with the base href, preventing malformed URLs that cause the redirection issues. Closes #31877 (cherry picked from commit 0fe572ed7121953300bec373ac2261c8da6f89a4) --- .../build/src/builders/application/options.ts | 6 +- .../src/utils/server-rendering/prerender.ts | 20 +-- packages/angular/build/src/utils/url.ts | 118 +++++++++++++++++- 3 files changed, 120 insertions(+), 24 deletions(-) diff --git a/packages/angular/build/src/builders/application/options.ts b/packages/angular/build/src/builders/application/options.ts index 1b3a15b8cd56..25bd87253357 100644 --- a/packages/angular/build/src/builders/application/options.ts +++ b/packages/angular/build/src/builders/application/options.ts @@ -25,7 +25,7 @@ import { loadPostcssConfiguration, } from '../../utils/postcss-configuration'; import { getProjectRootPaths, normalizeDirectoryPath } from '../../utils/project-metadata'; -import { urlJoin } from '../../utils/url'; +import { addTrailingSlash, joinUrlParts } from '../../utils/url'; import { Schema as ApplicationBuilderOptions, ExperimentalPlatform, @@ -681,7 +681,9 @@ export function getLocaleBaseHref( const baseHrefSuffix = localeData.baseHref ?? localeData.subPath + '/'; - return baseHrefSuffix !== '' ? urlJoin(baseHref, baseHrefSuffix) : undefined; + return baseHrefSuffix !== '' + ? addTrailingSlash(joinUrlParts(baseHref, baseHrefSuffix)) + : undefined; } /** diff --git a/packages/angular/build/src/utils/server-rendering/prerender.ts b/packages/angular/build/src/utils/server-rendering/prerender.ts index 5ece379ec9c0..f33f851f10c4 100644 --- a/packages/angular/build/src/utils/server-rendering/prerender.ts +++ b/packages/angular/build/src/utils/server-rendering/prerender.ts @@ -14,7 +14,7 @@ import { BuildOutputFile, BuildOutputFileType } from '../../tools/esbuild/bundle import { BuildOutputAsset } from '../../tools/esbuild/bundler-execution-result'; import { assertIsError } from '../error'; import { toPosixPath } from '../path'; -import { urlJoin } from '../url'; +import { addLeadingSlash, addTrailingSlash, joinUrlParts, stripLeadingSlash } from '../url'; import { WorkerPool } from '../worker-pool'; import { IMPORT_EXEC_ARGV } from './esm-in-memory-loader/utils'; import { SERVER_APP_MANIFEST_FILENAME } from './manifest'; @@ -240,7 +240,7 @@ async function renderPages( ? addLeadingSlash(route.slice(baseHrefPathnameWithLeadingSlash.length)) : route; - const outPath = posix.join(removeLeadingSlash(routeWithoutBaseHref), 'index.html'); + const outPath = stripLeadingSlash(posix.join(routeWithoutBaseHref, 'index.html')); if (typeof redirectTo === 'string') { output[outPath] = { content: generateRedirectStaticPage(redirectTo), appShellRoute: false }; @@ -298,7 +298,7 @@ async function getAllRoutes( let appShellRoute: string | undefined; if (appShellOptions) { - appShellRoute = urlJoin(baseHref, appShellOptions.route); + appShellRoute = joinUrlParts(baseHref, appShellOptions.route); routes.push({ renderMode: RouteRenderMode.Prerender, @@ -311,7 +311,7 @@ async function getAllRoutes( for (const route of routesFromFile) { routes.push({ renderMode: RouteRenderMode.Prerender, - route: urlJoin(baseHref, route.trim()), + route: joinUrlParts(baseHref, route.trim()), }); } } @@ -369,15 +369,3 @@ async function getAllRoutes( void renderWorker.destroy(); } } - -function addLeadingSlash(value: string): string { - return value[0] === '/' ? value : '/' + value; -} - -function addTrailingSlash(url: string): string { - return url[url.length - 1] === '/' ? url : `${url}/`; -} - -function removeLeadingSlash(value: string): string { - return value[0] === '/' ? value.slice(1) : value; -} diff --git a/packages/angular/build/src/utils/url.ts b/packages/angular/build/src/utils/url.ts index d3f1e5791276..9edbfb3a3de5 100644 --- a/packages/angular/build/src/utils/url.ts +++ b/packages/angular/build/src/utils/url.ts @@ -6,11 +6,117 @@ * found in the LICENSE file at https://angular.dev/license */ -export function urlJoin(...parts: string[]): string { - const [p, ...rest] = parts; +/** + * Removes the trailing slash from a URL if it exists. + * + * @param url - The URL string from which to remove the trailing slash. + * @returns The URL string without a trailing slash. + * + * @example + * ```js + * stripTrailingSlash('path/'); // 'path' + * stripTrailingSlash('/path'); // '/path' + * stripTrailingSlash('/'); // '/' + * stripTrailingSlash(''); // '' + * ``` + */ +export function stripTrailingSlash(url: string): string { + // Check if the last character of the URL is a slash + return url.length > 1 && url[url.length - 1] === '/' ? url.slice(0, -1) : url; +} + +/** + * Removes the leading slash from a URL if it exists. + * + * @param url - The URL string from which to remove the leading slash. + * @returns The URL string without a leading slash. + * + * @example + * ```js + * stripLeadingSlash('/path'); // 'path' + * stripLeadingSlash('/path/'); // 'path/' + * stripLeadingSlash('/'); // '/' + * stripLeadingSlash(''); // '' + * ``` + */ +export function stripLeadingSlash(url: string): string { + // Check if the first character of the URL is a slash + return url.length > 1 && url[0] === '/' ? url.slice(1) : url; +} + +/** + * Adds a leading slash to a URL if it does not already have one. + * + * @param url - The URL string to which the leading slash will be added. + * @returns The URL string with a leading slash. + * + * @example + * ```js + * addLeadingSlash('path'); // '/path' + * addLeadingSlash('/path'); // '/path' + * ``` + */ +export function addLeadingSlash(url: string): string { + // Check if the URL already starts with a slash + return url[0] === '/' ? url : `/${url}`; +} + +/** + * Adds a trailing slash to a URL if it does not already have one. + * + * @param url - The URL string to which the trailing slash will be added. + * @returns The URL string with a trailing slash. + * + * @example + * ```js + * addTrailingSlash('path'); // 'path/' + * addTrailingSlash('path/'); // 'path/' + * ``` + */ +export function addTrailingSlash(url: string): string { + // Check if the URL already end with a slash + return url[url.length - 1] === '/' ? url : `${url}/`; +} + +/** + * Joins URL parts into a single URL string. + * + * This function takes multiple URL segments, normalizes them by removing leading + * and trailing slashes where appropriate, and then joins them into a single URL. + * + * @param parts - The parts of the URL to join. Each part can be a string with or without slashes. + * @returns The joined URL string, with normalized slashes. + * + * @example + * ```js + * joinUrlParts('path/', '/to/resource'); // '/path/to/resource' + * joinUrlParts('/path/', 'to/resource'); // '/path/to/resource' + * joinUrlParts('http://localhost/path/', 'to/resource'); // 'http://localhost/path/to/resource' + * joinUrlParts('', ''); // '/' + * ``` + */ +export function joinUrlParts(...parts: string[]): string { + const normalizeParts: string[] = []; + for (const part of parts) { + if (part === '') { + // Skip any empty parts + continue; + } + + let normalizedPart = part; + if (part[0] === '/') { + normalizedPart = normalizedPart.slice(1); + } + if (part[part.length - 1] === '/') { + normalizedPart = normalizedPart.slice(0, -1); + } + if (normalizedPart !== '') { + normalizeParts.push(normalizedPart); + } + } + + const protocolMatch = normalizeParts.length && /^https?:\/\//.test(normalizeParts[0]); + const joinedParts = normalizeParts.join('/'); - // Remove trailing slash from first part - // Join all parts with `/` - // Dedupe double slashes from path names - return p.replace(/\/$/, '') + ('/' + rest.join('/')).replace(/\/\/+/g, '/'); + return protocolMatch ? joinedParts : addLeadingSlash(joinedParts); } From c973bb9cafc8d59b901a9d763347f4b615257867 Mon Sep 17 00:00:00 2001 From: Charles Lyding <19598772+clydin@users.noreply.github.com> Date: Wed, 19 Nov 2025 15:58:51 -0500 Subject: [PATCH 25/54] fix(@schematics/angular): add mock names to createSpyObj transformation This commit enhances the jasmine-vitest schematic by adding mock names to `vi.fn()` instances created from `jasmine.createSpyObj`. This improves debugging in Vitest by providing meaningful names for mock functions, making test failures easier to understand and trace. (cherry picked from commit f38fadeccdc3cc7b25facb8bd5224bfa99fe9626) --- .../test-file-transformer.integration_spec.ts | 6 ++- .../test-file-transformer_spec.ts | 6 +-- .../transformers/jasmine-spy.ts | 51 +++++++++++++++---- .../transformers/jasmine-spy_spec.ts | 20 ++++---- 4 files changed, 57 insertions(+), 26 deletions(-) diff --git a/packages/schematics/angular/refactor/jasmine-vitest/test-file-transformer.integration_spec.ts b/packages/schematics/angular/refactor/jasmine-vitest/test-file-transformer.integration_spec.ts index ebc7e1631907..0fe0d7c5b3e2 100644 --- a/packages/schematics/angular/refactor/jasmine-vitest/test-file-transformer.integration_spec.ts +++ b/packages/schematics/angular/refactor/jasmine-vitest/test-file-transformer.integration_spec.ts @@ -255,14 +255,15 @@ describe('Jasmine to Vitest Transformer - Integration Tests', () => { }); `; + /* eslint-disable max-len */ const vitestCode = ` describe('Complex Scenarios', () => { let serviceMock; beforeEach(() => { serviceMock = { - getData: vi.fn().mockReturnValue(expect.any(String)), - process: vi.fn().mockReturnValue(undefined), + getData: vi.fn().mockName("MyService.getData").mockReturnValue(expect.any(String)), + process: vi.fn().mockName("MyService.process").mockReturnValue(undefined), }; }); @@ -299,6 +300,7 @@ describe('Jasmine to Vitest Transformer - Integration Tests', () => { }); }); `; + /* eslint-enable max-len */ await expectTransformation(jasmineCode, vitestCode); }); diff --git a/packages/schematics/angular/refactor/jasmine-vitest/test-file-transformer_spec.ts b/packages/schematics/angular/refactor/jasmine-vitest/test-file-transformer_spec.ts index bc55811306b3..45580be66476 100644 --- a/packages/schematics/angular/refactor/jasmine-vitest/test-file-transformer_spec.ts +++ b/packages/schematics/angular/refactor/jasmine-vitest/test-file-transformer_spec.ts @@ -78,7 +78,7 @@ describe('Jasmine to Vitest Transformer', () => { input: `const spy = jasmine.createSpyObj('MyService', { getPromise: Promise.resolve(jasmine.any(String)) });`, expected: ` const spy = { - getPromise: vi.fn().mockReturnValue(Promise.resolve(expect.any(String))), + getPromise: vi.fn().mockName("MyService.getPromise").mockReturnValue(Promise.resolve(expect.any(String))), }; `, }, @@ -105,8 +105,8 @@ describe('Jasmine to Vitest Transformer', () => { `, expected: ` const myService = { - methodA: vi.fn(), - propA: 'valueA' + methodA: vi.fn().mockName("MyService.methodA"), + propA: 'valueA', }; vi.spyOn(myService, 'methodA').mockReturnValue('mocked value'); myService.methodA('test'); diff --git a/packages/schematics/angular/refactor/jasmine-vitest/transformers/jasmine-spy.ts b/packages/schematics/angular/refactor/jasmine-vitest/transformers/jasmine-spy.ts index d2d9af5f01a6..c10fc739f9af 100644 --- a/packages/schematics/angular/refactor/jasmine-vitest/transformers/jasmine-spy.ts +++ b/packages/schematics/angular/refactor/jasmine-vitest/transformers/jasmine-spy.ts @@ -227,6 +227,12 @@ export function transformCreateSpyObj( 'Transformed `jasmine.createSpyObj()` to an object literal with `vi.fn()`.', ); + const baseNameArg = node.arguments[0]; + const baseName = ts.isStringLiteral(baseNameArg) ? baseNameArg.text : undefined; + const methods = node.arguments[1]; + const propertiesArg = node.arguments[2]; + let properties: ts.PropertyAssignment[] = []; + if (node.arguments.length < 2) { const category = 'createSpyObj-single-argument'; reporter.recordTodo(category); @@ -235,14 +241,10 @@ export function transformCreateSpyObj( return node; } - const methods = node.arguments[1]; - const propertiesArg = node.arguments[2]; - let properties: ts.PropertyAssignment[] = []; - if (ts.isArrayLiteralExpression(methods)) { - properties = createSpyObjWithArray(methods); + properties = createSpyObjWithArray(methods, baseName); } else if (ts.isObjectLiteralExpression(methods)) { - properties = createSpyObjWithObject(methods); + properties = createSpyObjWithObject(methods, baseName); } else { const category = 'createSpyObj-dynamic-variable'; reporter.recordTodo(category); @@ -264,13 +266,28 @@ export function transformCreateSpyObj( return ts.factory.createObjectLiteralExpression(properties, true); } -function createSpyObjWithArray(methods: ts.ArrayLiteralExpression): ts.PropertyAssignment[] { +function createSpyObjWithArray( + methods: ts.ArrayLiteralExpression, + baseName: string | undefined, +): ts.PropertyAssignment[] { return methods.elements .map((element) => { if (ts.isStringLiteral(element)) { + const mockFn = createViCallExpression('fn'); + const methodName = element.text; + let finalExpression: ts.Expression = mockFn; + + if (baseName) { + finalExpression = ts.factory.createCallExpression( + createPropertyAccess(finalExpression, 'mockName'), + undefined, + [ts.factory.createStringLiteral(`${baseName}.${methodName}`)], + ); + } + return ts.factory.createPropertyAssignment( - ts.factory.createIdentifier(element.text), - createViCallExpression('fn'), + ts.factory.createIdentifier(methodName), + finalExpression, ); } @@ -279,13 +296,25 @@ function createSpyObjWithArray(methods: ts.ArrayLiteralExpression): ts.PropertyA .filter((p): p is ts.PropertyAssignment => !!p); } -function createSpyObjWithObject(methods: ts.ObjectLiteralExpression): ts.PropertyAssignment[] { +function createSpyObjWithObject( + methods: ts.ObjectLiteralExpression, + baseName: string | undefined, +): ts.PropertyAssignment[] { return methods.properties .map((prop) => { if (ts.isPropertyAssignment(prop) && ts.isIdentifier(prop.name)) { const methodName = prop.name.text; const returnValue = prop.initializer; - const mockFn = createViCallExpression('fn'); + let mockFn = createViCallExpression('fn'); + + if (baseName) { + mockFn = ts.factory.createCallExpression( + createPropertyAccess(mockFn, 'mockName'), + undefined, + [ts.factory.createStringLiteral(`${baseName}.${methodName}`)], + ); + } + const mockReturnValue = createPropertyAccess(mockFn, 'mockReturnValue'); return ts.factory.createPropertyAssignment( diff --git a/packages/schematics/angular/refactor/jasmine-vitest/transformers/jasmine-spy_spec.ts b/packages/schematics/angular/refactor/jasmine-vitest/transformers/jasmine-spy_spec.ts index c84b35c422ac..3fc98aa02601 100644 --- a/packages/schematics/angular/refactor/jasmine-vitest/transformers/jasmine-spy_spec.ts +++ b/packages/schematics/angular/refactor/jasmine-vitest/transformers/jasmine-spy_spec.ts @@ -118,8 +118,8 @@ vi.spyOn(service, 'myMethod').and.unknownStrategy();`, description: 'should transform jasmine.createSpyObj with an array of methods', input: `const myService = jasmine.createSpyObj('MyService', ['methodA', 'methodB']);`, expected: `const myService = { - methodA: vi.fn(), - methodB: vi.fn() + methodA: vi.fn().mockName("MyService.methodA"), + methodB: vi.fn().mockName("MyService.methodB"), };`, }, { @@ -134,8 +134,8 @@ vi.spyOn(service, 'myMethod').and.unknownStrategy();`, description: 'should transform jasmine.createSpyObj with an object of return values', input: `const myService = jasmine.createSpyObj('MyService', { methodA: 'foo', methodB: 42 });`, expected: `const myService = { - methodA: vi.fn().mockReturnValue('foo'), - methodB: vi.fn().mockReturnValue(42) + methodA: vi.fn().mockName("MyService.methodA").mockReturnValue('foo'), + methodB: vi.fn().mockName("MyService.methodB").mockReturnValue(42), };`, }, { @@ -143,7 +143,7 @@ vi.spyOn(service, 'myMethod').and.unknownStrategy();`, 'should transform jasmine.createSpyObj with an object of return values containing an asymmetric matcher', input: `const myService = jasmine.createSpyObj('MyService', { methodA: jasmine.any(String) });`, expected: `const myService = { - methodA: vi.fn().mockReturnValue(expect.any(String)) + methodA: vi.fn().mockName("MyService.methodA").mockReturnValue(expect.any(String)), };`, }, { @@ -158,23 +158,23 @@ vi.spyOn(service, 'myMethod').and.unknownStrategy();`, description: 'should transform jasmine.createSpyObj with a property map', input: `const myService = jasmine.createSpyObj('MyService', ['methodA'], { propA: 'valueA' });`, expected: `const myService = { - methodA: vi.fn(), - propA: 'valueA' + methodA: vi.fn().mockName("MyService.methodA"), + propA: 'valueA', };`, }, { description: 'should transform jasmine.createSpyObj with a method map and a property map', input: `const myService = jasmine.createSpyObj('MyService', { methodA: 'foo' }, { propA: 'valueA' });`, expected: `const myService = { - methodA: vi.fn().mockReturnValue('foo'), - propA: 'valueA' + methodA: vi.fn().mockName("MyService.methodA").mockReturnValue('foo'), + propA: 'valueA', };`, }, { description: 'should ignore non-string literals in the method array', input: `const myService = jasmine.createSpyObj('MyService', ['methodA', 123, someVar]);`, expected: `const myService = { - methodA: vi.fn() + methodA: vi.fn().mockName("MyService.methodA"), };`, }, ]; From b8c99aa4c909647285d1dcc61a2bb97a36100c63 Mon Sep 17 00:00:00 2001 From: Charles Lyding <19598772+clydin@users.noreply.github.com> Date: Wed, 19 Nov 2025 16:04:42 -0500 Subject: [PATCH 26/54] fix(@schematics/angular): improve safety of done callback transformation This commit adds a safety check to the `done` callback transformation in the `jasmine-vitest` schematic. Previously, if a `done` callback was used in an unhandled way (e.g., passed as an argument to a helper function), the schematic would remove the `done` parameter but leave the usage, causing runtime errors. Now, the transformer counts the total usages of the `done` callback and compares it to the number of usages it successfully transformed. If there are unhandled usages, it aborts the transformation for that specific test and adds a TODO comment, ensuring that no broken code is generated. (cherry picked from commit 2b99ce515dc8bf8a06bbc0f88d07f02d7c5ef828) --- .../transformers/jasmine-lifecycle.ts | 35 +++++++++++++++++++ .../transformers/jasmine-lifecycle_spec.ts | 15 ++++++++ .../jasmine-vitest/utils/todo-notes.ts | 3 ++ 3 files changed, 53 insertions(+) diff --git a/packages/schematics/angular/refactor/jasmine-vitest/transformers/jasmine-lifecycle.ts b/packages/schematics/angular/refactor/jasmine-vitest/transformers/jasmine-lifecycle.ts index 235eef129d11..f2b60c35f327 100644 --- a/packages/schematics/angular/refactor/jasmine-vitest/transformers/jasmine-lifecycle.ts +++ b/packages/schematics/angular/refactor/jasmine-vitest/transformers/jasmine-lifecycle.ts @@ -282,6 +282,19 @@ function transformPromiseBasedDone( return undefined; } +function countDoneUsages(node: ts.Node, doneIdentifier: ts.Identifier): number { + let count = 0; + const visitor = (n: ts.Node) => { + if (ts.isIdentifier(n) && n.text === doneIdentifier.text) { + count++; + } + ts.forEachChild(n, visitor); + }; + ts.forEachChild(node, visitor); + + return count; +} + export function transformDoneCallback(node: ts.Node, refactorCtx: RefactorContext): ts.Node { const { sourceFile, reporter, tsContext } = refactorCtx; if ( @@ -309,12 +322,17 @@ export function transformDoneCallback(node: ts.Node, refactorCtx: RefactorContex return node; } const doneIdentifier = doneParam.name; + + // Count total usages of 'done' in the body + const totalUsages = countDoneUsages(functionArg.body, doneIdentifier); + let handledUsages = 0; let doneWasUsed = false; const bodyVisitor = (bodyNode: ts.Node): ts.Node | ts.Node[] | undefined => { const complexTransformed = transformComplexDoneCallback(bodyNode, doneIdentifier, refactorCtx); if (complexTransformed !== bodyNode) { doneWasUsed = true; + handledUsages++; // complex transform handles one usage return complexTransformed; } @@ -330,6 +348,7 @@ export function transformDoneCallback(node: ts.Node, refactorCtx: RefactorContex callExpr.expression.name.text === 'fail' ) { doneWasUsed = true; + handledUsages++; reporter.reportTransformation( sourceFile, bodyNode, @@ -350,6 +369,7 @@ export function transformDoneCallback(node: ts.Node, refactorCtx: RefactorContex const promiseTransformed = transformPromiseBasedDone(callExpr, doneIdentifier, refactorCtx); if (promiseTransformed) { doneWasUsed = true; + handledUsages++; return promiseTransformed; } @@ -360,6 +380,7 @@ export function transformDoneCallback(node: ts.Node, refactorCtx: RefactorContex callExpr.expression.text === doneIdentifier.text ) { doneWasUsed = true; + handledUsages++; return ts.setTextRange(ts.factory.createEmptyStatement(), callExpr.expression); } @@ -383,6 +404,20 @@ export function transformDoneCallback(node: ts.Node, refactorCtx: RefactorContex return bodyVisitor(node); }); + // Safety check: if we found usages but didn't handle all of them, abort. + if (handledUsages < totalUsages) { + reporter.reportTransformation( + sourceFile, + node, + `Found unhandled usage of \`${doneIdentifier.text}\` callback. Skipping transformation.`, + ); + const category = 'unhandled-done-usage'; + reporter.recordTodo(category); + addTodoComment(node, category); + + return node; + } + if (!doneWasUsed) { return node; } diff --git a/packages/schematics/angular/refactor/jasmine-vitest/transformers/jasmine-lifecycle_spec.ts b/packages/schematics/angular/refactor/jasmine-vitest/transformers/jasmine-lifecycle_spec.ts index d5f9e3231180..f41f5fa7ae32 100644 --- a/packages/schematics/angular/refactor/jasmine-vitest/transformers/jasmine-lifecycle_spec.ts +++ b/packages/schematics/angular/refactor/jasmine-vitest/transformers/jasmine-lifecycle_spec.ts @@ -132,6 +132,7 @@ describe('Jasmine to Vitest Transformer', () => { }); `, expected: ` + // TODO: vitest-migration: The 'done' callback was used in an unhandled way. Please migrate manually. it('should not transform a function with a parameter that is not a done callback', (value) => { expect(value).toBe(true); }); @@ -157,6 +158,20 @@ describe('Jasmine to Vitest Transformer', () => { }); `, }, + { + description: 'should add a TODO for unhandled done usage', + input: ` + it('should do something with helper', (done) => { + someHelper(done); + }); + `, + expected: ` + // TODO: vitest-migration: The 'done' callback was used in an unhandled way. Please migrate manually. + it('should do something with helper', (done) => { + someHelper(done); + }); + `, + }, ]; testCases.forEach(({ description, input, expected }) => { diff --git a/packages/schematics/angular/refactor/jasmine-vitest/utils/todo-notes.ts b/packages/schematics/angular/refactor/jasmine-vitest/utils/todo-notes.ts index c0a5eb406e6a..3f43a6e4f838 100644 --- a/packages/schematics/angular/refactor/jasmine-vitest/utils/todo-notes.ts +++ b/packages/schematics/angular/refactor/jasmine-vitest/utils/todo-notes.ts @@ -120,6 +120,9 @@ export const TODO_NOTES = { ' Please refactor to access .args directly or use vi.mocked(spy).mock.lastCall.', url: 'https://vitest.dev/api/mocked.html#mock-lastcall', }, + 'unhandled-done-usage': { + message: "The 'done' callback was used in an unhandled way. Please migrate manually.", + }, } as const; /** From 145de4a584ce8f72746704547282299306d9bafb Mon Sep 17 00:00:00 2001 From: Charles Lyding <19598772+clydin@users.noreply.github.com> Date: Wed, 19 Nov 2025 16:13:07 -0500 Subject: [PATCH 27/54] fix(@schematics/angular): warn about loose matching in arrayWithExactContents This commit improves the transformation of `jasmine.arrayWithExactContents` in the `jasmine-vitest` schematic. While Vitest does not have a direct equivalent for multiset equality, the schematic previously transformed this into a check for length and subset containment, which could lead to false positives (e.g., `[1, 1]` matches `[1, 2]`). Now, the schematic attaches a TODO comment to the generated code, explicitly warning the user that the transformation relies on `expect.arrayContaining` (a subset check) and advising them to verify strict content matching manually. (cherry picked from commit 7c6a643f94a9b6abaf6578e9e98eb45da3bc17b2) --- .../test-file-transformer.integration_spec.ts | 1 + .../jasmine-vitest/test-file-transformer_spec.ts | 3 +++ .../jasmine-vitest/transformers/jasmine-matcher.ts | 12 ++++++++---- .../transformers/jasmine-matcher_spec.ts | 6 ++++++ .../refactor/jasmine-vitest/utils/todo-notes.ts | 4 ++++ 5 files changed, 22 insertions(+), 4 deletions(-) diff --git a/packages/schematics/angular/refactor/jasmine-vitest/test-file-transformer.integration_spec.ts b/packages/schematics/angular/refactor/jasmine-vitest/test-file-transformer.integration_spec.ts index 0fe0d7c5b3e2..8944e34dfa14 100644 --- a/packages/schematics/angular/refactor/jasmine-vitest/test-file-transformer.integration_spec.ts +++ b/packages/schematics/angular/refactor/jasmine-vitest/test-file-transformer.integration_spec.ts @@ -275,6 +275,7 @@ describe('Jasmine to Vitest Transformer - Integration Tests', () => { it('should handle array contents checking', () => { const arr = [1, 2, 3]; + // TODO: vitest-migration: Verify this matches strict array content (multiset equality). Vitest's arrayContaining is a subset check. expect(arr).toHaveLength(3); expect(arr).toEqual(expect.arrayContaining([3, 2, 1])); }); diff --git a/packages/schematics/angular/refactor/jasmine-vitest/test-file-transformer_spec.ts b/packages/schematics/angular/refactor/jasmine-vitest/test-file-transformer_spec.ts index 45580be66476..abe1f3655cdd 100644 --- a/packages/schematics/angular/refactor/jasmine-vitest/test-file-transformer_spec.ts +++ b/packages/schematics/angular/refactor/jasmine-vitest/test-file-transformer_spec.ts @@ -85,10 +85,13 @@ describe('Jasmine to Vitest Transformer', () => { { description: 'should handle arrayWithExactContents containing nested asymmetric matchers', input: `expect(myArray).toEqual(jasmine.arrayWithExactContents([jasmine.objectContaining({ id: 1 })]));`, + /* eslint-disable max-len */ expected: ` + // TODO: vitest-migration: Verify this matches strict array content (multiset equality). Vitest's arrayContaining is a subset check. expect(myArray).toHaveLength(1); expect(myArray).toEqual(expect.arrayContaining([expect.objectContaining({ id: 1 })])); `, + /* eslint-enable max-len */ }, { description: 'should handle a spy rejecting with an asymmetric matcher', diff --git a/packages/schematics/angular/refactor/jasmine-vitest/transformers/jasmine-matcher.ts b/packages/schematics/angular/refactor/jasmine-vitest/transformers/jasmine-matcher.ts index b1b746aad504..5de173bcd52b 100644 --- a/packages/schematics/angular/refactor/jasmine-vitest/transformers/jasmine-matcher.ts +++ b/packages/schematics/angular/refactor/jasmine-vitest/transformers/jasmine-matcher.ts @@ -451,10 +451,14 @@ export function transformArrayWithExactContents( ], ); - return [ - ts.factory.createExpressionStatement(lengthCall), - ts.factory.createExpressionStatement(containingCall), - ]; + const lengthStmt = ts.factory.createExpressionStatement(lengthCall); + const containingStmt = ts.factory.createExpressionStatement(containingCall); + + const category = 'arrayWithExactContents-check'; + reporter.recordTodo(category); + addTodoComment(lengthStmt, category); + + return [lengthStmt, containingStmt]; } export function transformCalledOnceWith( diff --git a/packages/schematics/angular/refactor/jasmine-vitest/transformers/jasmine-matcher_spec.ts b/packages/schematics/angular/refactor/jasmine-vitest/transformers/jasmine-matcher_spec.ts index 69b0637254aa..a46fc63d2a01 100644 --- a/packages/schematics/angular/refactor/jasmine-vitest/transformers/jasmine-matcher_spec.ts +++ b/packages/schematics/angular/refactor/jasmine-vitest/transformers/jasmine-matcher_spec.ts @@ -225,19 +225,25 @@ expect(mySpyObj).toHaveSpyInteractions();`, { description: 'should transform toEqual(jasmine.arrayWithExactContents()) into two calls', input: `expect(myArray).toEqual(jasmine.arrayWithExactContents(['a', 'b']));`, + /* eslint-disable max-len */ expected: ` + // TODO: vitest-migration: Verify this matches strict array content (multiset equality). Vitest's arrayContaining is a subset check. expect(myArray).toHaveLength(2); expect(myArray).toEqual(expect.arrayContaining(['a', 'b'])); `, + /* eslint-enable max-len */ }, { description: 'should transform toEqual(jasmine.arrayWithExactContents()) with asymmetric matchers', input: `expect(myArray).toEqual(jasmine.arrayWithExactContents([jasmine.any(Number), 'a']));`, + /* eslint-disable max-len */ expected: ` + // TODO: vitest-migration: Verify this matches strict array content (multiset equality). Vitest's arrayContaining is a subset check. expect(myArray).toHaveLength(2); expect(myArray).toEqual(expect.arrayContaining([expect.any(Number), 'a'])); `, + /* eslint-enable max-len */ }, { description: diff --git a/packages/schematics/angular/refactor/jasmine-vitest/utils/todo-notes.ts b/packages/schematics/angular/refactor/jasmine-vitest/utils/todo-notes.ts index 3f43a6e4f838..a4964b1e456b 100644 --- a/packages/schematics/angular/refactor/jasmine-vitest/utils/todo-notes.ts +++ b/packages/schematics/angular/refactor/jasmine-vitest/utils/todo-notes.ts @@ -56,6 +56,10 @@ export const TODO_NOTES = { message: 'Cannot transform jasmine.arrayWithExactContents with a dynamic variable. Please migrate this manually.', }, + 'arrayWithExactContents-check': { + message: + "Verify this matches strict array content (multiset equality). Vitest's arrayContaining is a subset check.", + }, 'expect-nothing': { message: 'expect().nothing() has been removed because it is redundant in Vitest. Tests without assertions pass by default.', From cdb607ada4bf9aaec6ed8aafd8826d782fd13109 Mon Sep 17 00:00:00 2001 From: Charles Lyding <19598772+clydin@users.noreply.github.com> Date: Wed, 19 Nov 2025 13:56:20 -0500 Subject: [PATCH 28/54] fix(@angular/build): correctly configure per-browser headless mode in Vitest runner This commit fixes an issue in the Vitest browser setup where headless mode was not correctly configured on a per-browser-instance basis. Previously, the headless mode was applied globally, leading to incorrect behavior when mixing headed and headless browser names, or in specific environments. Now, the configuration correctly: - Determines headless status from individual browser names (e.g., `ChromeHeadless` vs `Chrome`). - Forces all instances to be headless in CI environments. - Ensures the Preview provider forces instances to be headed. - Enables the UI only when running locally with at least one headed browser. (cherry picked from commit a71411fb298c4f0b1537347dd0cf67b93a70eb12) --- .../runners/vitest/browser-provider.ts | 26 +-- .../runners/vitest/browser-provider_spec.ts | 163 ++++++++++++++++++ 2 files changed, 179 insertions(+), 10 deletions(-) create mode 100644 packages/angular/build/src/builders/unit-test/runners/vitest/browser-provider_spec.ts diff --git a/packages/angular/build/src/builders/unit-test/runners/vitest/browser-provider.ts b/packages/angular/build/src/builders/unit-test/runners/vitest/browser-provider.ts index 4f7469ebf28b..3aeeb7afe474 100644 --- a/packages/angular/build/src/builders/unit-test/runners/vitest/browser-provider.ts +++ b/packages/angular/build/src/builders/unit-test/runners/vitest/browser-provider.ts @@ -36,13 +36,17 @@ function findBrowserProvider( return undefined; } -function normalizeBrowserName(browserName: string): string { +function normalizeBrowserName(browserName: string): { browser: string; headless: boolean } { // Normalize browser names to match Vitest's expectations for headless but also supports karma's names // e.g., 'ChromeHeadless' -> 'chrome', 'FirefoxHeadless' -> 'firefox' // and 'Chrome' -> 'chrome', 'Firefox' -> 'firefox'. const normalized = browserName.toLowerCase(); + const headless = normalized.endsWith('headless'); - return normalized.replace(/headless$/, ''); + return { + browser: headless ? normalized.slice(0, -8) : normalized, + headless: headless, + }; } export async function setupBrowserConfiguration( @@ -120,21 +124,23 @@ export async function setupBrowserConfiguration( } const isCI = !!process.env['CI']; - let headless = isCI || browsers.some((name) => name.toLowerCase().includes('headless')); + const instances = browsers.map(normalizeBrowserName); if (providerName === 'preview') { - // `preview` provider does not support headless mode - headless = false; + instances.forEach((instance) => { + instance.headless = false; + }); + } else if (isCI) { + instances.forEach((instance) => { + instance.headless = true; + }); } const browser = { enabled: true, provider, - headless, - ui: !headless, + ui: !isCI && instances.some((instance) => !instance.headless), viewport, - instances: browsers.map((browserName) => ({ - browser: normalizeBrowserName(browserName), - })), + instances, } satisfies BrowserConfigOptions; return { browser }; diff --git a/packages/angular/build/src/builders/unit-test/runners/vitest/browser-provider_spec.ts b/packages/angular/build/src/builders/unit-test/runners/vitest/browser-provider_spec.ts new file mode 100644 index 000000000000..2162ffa6ed5e --- /dev/null +++ b/packages/angular/build/src/builders/unit-test/runners/vitest/browser-provider_spec.ts @@ -0,0 +1,163 @@ +/** + * @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 { mkdir, mkdtemp, rm, writeFile } from 'node:fs/promises'; +import { tmpdir } from 'node:os'; +import { join } from 'node:path'; +import { setupBrowserConfiguration } from './browser-provider'; + +describe('setupBrowserConfiguration', () => { + let workspaceRoot: string; + + beforeEach(async () => { + // Create a temporary workspace root + workspaceRoot = await mkdtemp(join(tmpdir(), 'angular-cli-test-')); + await writeFile(join(workspaceRoot, 'package.json'), '{}'); + + // Create a mock @vitest/browser-playwright package + const playwrightPkgPath = join(workspaceRoot, 'node_modules/@vitest/browser-playwright'); + await mkdir(playwrightPkgPath, { recursive: true }); + await writeFile( + join(playwrightPkgPath, 'package.json'), + JSON.stringify({ name: '@vitest/browser-playwright', main: 'index.js' }), + ); + await writeFile( + join(playwrightPkgPath, 'index.js'), + 'module.exports = { playwright: () => ({ name: "playwright" }) };', + ); + }); + + afterEach(async () => { + await rm(workspaceRoot, { recursive: true, force: true }); + }); + + it('should configure headless mode for specific browsers based on name', async () => { + const { browser } = await setupBrowserConfiguration( + ['ChromeHeadless', 'Firefox'], + false, + workspaceRoot, + undefined, + ); + + expect(browser?.enabled).toBeTrue(); + expect(browser?.instances).toEqual([ + { browser: 'chrome', headless: true }, + { browser: 'firefox', headless: false }, + ]); + }); + + it('should force headless mode in CI environment', async () => { + const originalCI = process.env['CI']; + process.env['CI'] = 'true'; + + try { + const { browser } = await setupBrowserConfiguration( + ['Chrome', 'FirefoxHeadless'], + false, + workspaceRoot, + undefined, + ); + + expect(browser?.instances).toEqual([ + { browser: 'chrome', headless: true }, + { browser: 'firefox', headless: true }, + ]); + } finally { + if (originalCI === undefined) { + delete process.env['CI']; + } else { + process.env['CI'] = originalCI; + } + } + }); + + it('should set ui property based on headless instances (local)', async () => { + // Local run (not CI) + const originalCI = process.env['CI']; + delete process.env['CI']; + + try { + // Case 1: All headless -> UI false + let result = await setupBrowserConfiguration( + ['ChromeHeadless'], + false, + workspaceRoot, + undefined, + ); + expect(result.browser?.ui).toBeFalse(); + + // Case 2: Mixed -> UI true + result = await setupBrowserConfiguration( + ['ChromeHeadless', 'Firefox'], + false, + workspaceRoot, + undefined, + ); + expect(result.browser?.ui).toBeTrue(); + } finally { + if (originalCI !== undefined) { + process.env['CI'] = originalCI; + } + } + }); + + it('should disable UI in CI even if headed browsers are requested', async () => { + const originalCI = process.env['CI']; + process.env['CI'] = 'true'; + + try { + const { browser } = await setupBrowserConfiguration( + ['Chrome'], + false, + workspaceRoot, + undefined, + ); + + expect(browser?.ui).toBeFalse(); + // And verify instances are forced to headless + expect(browser?.instances?.[0].headless).toBeTrue(); + } finally { + if (originalCI === undefined) { + delete process.env['CI']; + } else { + process.env['CI'] = originalCI; + } + } + }); + + it('should support Preview provider forcing headless false', async () => { + // Create mock preview package + const previewPkgPath = join(workspaceRoot, 'node_modules/@vitest/browser-preview'); + await mkdir(previewPkgPath, { recursive: true }); + await writeFile( + join(previewPkgPath, 'package.json'), + JSON.stringify({ name: '@vitest/browser-preview', main: 'index.js' }), + ); + await writeFile( + join(previewPkgPath, 'index.js'), + 'module.exports = { preview: () => ({ name: "preview" }) };', + ); + + // Remove playwright mock for this test to force usage of preview + await rm(join(workspaceRoot, 'node_modules/@vitest/browser-playwright'), { + recursive: true, + force: true, + }); + + const { browser } = await setupBrowserConfiguration( + ['ChromeHeadless'], + false, + workspaceRoot, + undefined, + ); + + expect(browser?.provider).toBeDefined(); + // Preview forces headless false + expect(browser?.instances?.[0].headless).toBeFalse(); + }); +}); From 6c2c10bb5e8091f80b17d71b78d9a17e41e599b7 Mon Sep 17 00:00:00 2001 From: Alan Agius Date: Thu, 20 Nov 2025 16:00:59 +0100 Subject: [PATCH 29/54] refactor: modernize array and string last element access using `.at(-1)` Replace usages of old patterns. (cherry picked from commit 26719451c35288c0b5342eceda3460ed24bd3171) --- .../tests/behavior/serve-live-reload-proxies_spec.ts | 3 +-- .../build/src/builders/dev-server/tests/execute-fetch.ts | 4 ++-- .../angular/build/src/builders/dev-server/vite/index.ts | 4 +--- .../build/src/tools/vite/middlewares/assets-middleware.ts | 2 +- packages/angular/build/src/utils/project-metadata.ts | 2 +- .../angular/build/src/utils/server-rendering/manifest.ts | 2 +- packages/angular/build/src/utils/url.ts | 6 +++--- .../cli/src/command-builder/utilities/json-schema.ts | 2 +- packages/angular/ssr/BUILD.bazel | 2 +- packages/angular/ssr/src/utils/url.ts | 6 +++--- .../architect/src/jobs/simple-scheduler_spec.ts | 2 +- .../tests/behavior/serve-live-reload-proxies_spec.ts | 3 +-- .../src/builders/dev-server/tests/execute-fetch.ts | 2 +- packages/angular_devkit/core/src/utils/template.ts | 4 +--- packages/angular_devkit/core/src/virtual-fs/path.ts | 2 +- packages/angular_devkit/schematics/src/tree/action.ts | 2 +- packages/angular_devkit/schematics/src/workflow/base.ts | 4 ++-- tests/legacy-cli/e2e_runner.ts | 2 +- tsconfig-build-esm.json | 2 +- 19 files changed, 25 insertions(+), 31 deletions(-) diff --git a/packages/angular/build/src/builders/dev-server/tests/behavior/serve-live-reload-proxies_spec.ts b/packages/angular/build/src/builders/dev-server/tests/behavior/serve-live-reload-proxies_spec.ts index 65f34bddf94d..efdd749de258 100644 --- a/packages/angular/build/src/builders/dev-server/tests/behavior/serve-live-reload-proxies_spec.ts +++ b/packages/angular/build/src/builders/dev-server/tests/behavior/serve-live-reload-proxies_spec.ts @@ -105,8 +105,7 @@ DDIy4xXPW1STWfsmSYJfYW3wa0wk+pJQ3j2cTzkPQQ8gwpvM3U9DJl43uwb37v6I async function goToPageAndWaitForWS(page: Page, url: string): Promise { const baseUrl = url.replace(/^http/, 'ws'); - const socksRequest = - baseUrl[baseUrl.length - 1] === '/' ? `${baseUrl}ng-cli-ws` : `${baseUrl}/ng-cli-ws`; + const socksRequest = baseUrl.at(-1) === '/' ? `${baseUrl}ng-cli-ws` : `${baseUrl}/ng-cli-ws`; // Create a Chrome dev tools session so that we can capturing websocket request. // https://github.com/puppeteer/puppeteer/issues/2974 diff --git a/packages/angular/build/src/builders/dev-server/tests/execute-fetch.ts b/packages/angular/build/src/builders/dev-server/tests/execute-fetch.ts index ebbdcf3f1133..75a4e7935ebe 100644 --- a/packages/angular/build/src/builders/dev-server/tests/execute-fetch.ts +++ b/packages/angular/build/src/builders/dev-server/tests/execute-fetch.ts @@ -28,7 +28,7 @@ export async function executeOnceAndFetch( let content = undefined; if (executionResult.result?.success) { let baseUrl = `${executionResult.result.baseUrl}`; - baseUrl = baseUrl[baseUrl.length - 1] === '/' ? baseUrl : `${baseUrl}/`; + baseUrl = baseUrl.at(-1) === '/' ? baseUrl : `${baseUrl}/`; const resolvedUrl = new URL(url, baseUrl); const originalResponse = await fetch(resolvedUrl, options?.request); response = originalResponse.clone(); @@ -68,7 +68,7 @@ export async function executeOnceAndGet( let content = undefined; if (executionResult.result?.success) { let baseUrl = `${executionResult.result.baseUrl}`; - baseUrl = baseUrl[baseUrl.length - 1] === '/' ? baseUrl : `${baseUrl}/`; + baseUrl = baseUrl.at(-1) === '/' ? baseUrl : `${baseUrl}/`; const resolvedUrl = new URL(url, baseUrl); response = await new Promise((resolve) => 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 75987b2c2cc2..8129daac1ba1 100644 --- a/packages/angular/build/src/builders/dev-server/vite/index.ts +++ b/packages/angular/build/src/builders/dev-server/vite/index.ts @@ -243,9 +243,7 @@ export async function* serveWithVite( const baseHref = result.detail['htmlBaseHref'] as string; // Remove trailing slash serverOptions.servePath = - baseHref !== './' && baseHref[baseHref.length - 1] === '/' - ? baseHref.slice(0, -1) - : baseHref; + baseHref !== './' && baseHref.at(-1) === '/' ? baseHref.slice(0, -1) : baseHref; } assetFiles.clear(); diff --git a/packages/angular/build/src/tools/vite/middlewares/assets-middleware.ts b/packages/angular/build/src/tools/vite/middlewares/assets-middleware.ts index 414ec5ca13d1..f0a137f578f8 100644 --- a/packages/angular/build/src/tools/vite/middlewares/assets-middleware.ts +++ b/packages/angular/build/src/tools/vite/middlewares/assets-middleware.ts @@ -40,7 +40,7 @@ export function createAngularAssetsMiddleware( // The base of the URL is unused but required to parse the URL. const pathname = pathnameWithoutBasePath(req.url, server.config.base); const extension = extname(pathname); - const pathnameHasTrailingSlash = pathname[pathname.length - 1] === '/'; + const pathnameHasTrailingSlash = pathname.at(-1) === '/'; // Rewrite all build assets to a vite raw fs URL const asset = assets.get(pathname); diff --git a/packages/angular/build/src/utils/project-metadata.ts b/packages/angular/build/src/utils/project-metadata.ts index bc997652fef1..31912d5e9905 100644 --- a/packages/angular/build/src/utils/project-metadata.ts +++ b/packages/angular/build/src/utils/project-metadata.ts @@ -15,7 +15,7 @@ import { join } from 'node:path'; * @returns A normalized path string. */ export function normalizeDirectoryPath(path: string): string { - const last = path[path.length - 1]; + const last = path.at(-1); if (last === '/' || last === '\\') { return path.slice(0, -1); } diff --git a/packages/angular/build/src/utils/server-rendering/manifest.ts b/packages/angular/build/src/utils/server-rendering/manifest.ts index 2dfad0ff2dfb..b01bff38b58f 100644 --- a/packages/angular/build/src/utils/server-rendering/manifest.ts +++ b/packages/angular/build/src/utils/server-rendering/manifest.ts @@ -77,7 +77,7 @@ export function generateAngularServerAppEngineManifest( // Remove trailing slash but retain leading slash. let basePath = baseHref || '/'; - if (basePath.length > 1 && basePath[basePath.length - 1] === '/') { + if (basePath.length > 1 && basePath.at(-1) === '/') { basePath = basePath.slice(0, -1); } diff --git a/packages/angular/build/src/utils/url.ts b/packages/angular/build/src/utils/url.ts index 9edbfb3a3de5..689eac37eab5 100644 --- a/packages/angular/build/src/utils/url.ts +++ b/packages/angular/build/src/utils/url.ts @@ -22,7 +22,7 @@ */ export function stripTrailingSlash(url: string): string { // Check if the last character of the URL is a slash - return url.length > 1 && url[url.length - 1] === '/' ? url.slice(0, -1) : url; + return url.length > 1 && url.at(-1) === '/' ? url.slice(0, -1) : url; } /** @@ -75,7 +75,7 @@ export function addLeadingSlash(url: string): string { */ export function addTrailingSlash(url: string): string { // Check if the URL already end with a slash - return url[url.length - 1] === '/' ? url : `${url}/`; + return url.at(-1) === '/' ? url : `${url}/`; } /** @@ -107,7 +107,7 @@ export function joinUrlParts(...parts: string[]): string { if (part[0] === '/') { normalizedPart = normalizedPart.slice(1); } - if (part[part.length - 1] === '/') { + if (part.at(-1) === '/') { normalizedPart = normalizedPart.slice(0, -1); } if (normalizedPart !== '') { 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 e9fbd7e0e27a..0a4215be8eed 100644 --- a/packages/angular/cli/src/command-builder/utilities/json-schema.ts +++ b/packages/angular/cli/src/command-builder/utilities/json-schema.ts @@ -334,7 +334,7 @@ export async function parseJsonSchemaToOptions( // Skip any non-property items. return; } - const name = ptr[ptr.length - 1]; + const name = ptr.at(-1) as string; const types = getSupportedTypes(current); diff --git a/packages/angular/ssr/BUILD.bazel b/packages/angular/ssr/BUILD.bazel index dc70ac3fdf5b..2fd35cf8adc3 100644 --- a/packages/angular/ssr/BUILD.bazel +++ b/packages/angular/ssr/BUILD.bazel @@ -20,7 +20,7 @@ ts_project( ), args = [ "--lib", - "dom,es2020", + "dom,es2022", ], data = [ "//packages/angular/ssr/third_party/beasties:beasties_bundled", diff --git a/packages/angular/ssr/src/utils/url.ts b/packages/angular/ssr/src/utils/url.ts index 9b5edede7f8e..55d37ad9a05f 100644 --- a/packages/angular/ssr/src/utils/url.ts +++ b/packages/angular/ssr/src/utils/url.ts @@ -22,7 +22,7 @@ */ export function stripTrailingSlash(url: string): string { // Check if the last character of the URL is a slash - return url.length > 1 && url[url.length - 1] === '/' ? url.slice(0, -1) : url; + return url.length > 1 && url.at(-1) === '/' ? url.slice(0, -1) : url; } /** @@ -75,7 +75,7 @@ export function addLeadingSlash(url: string): string { */ export function addTrailingSlash(url: string): string { // Check if the URL already end with a slash - return url[url.length - 1] === '/' ? url : `${url}/`; + return url.at(-1) === '/' ? url : `${url}/`; } /** @@ -106,7 +106,7 @@ export function joinUrlParts(...parts: string[]): string { if (part[0] === '/') { normalizedPart = normalizedPart.slice(1); } - if (part[part.length - 1] === '/') { + if (part.at(-1) === '/') { normalizedPart = normalizedPart.slice(0, -1); } if (normalizedPart !== '') { diff --git a/packages/angular_devkit/architect/src/jobs/simple-scheduler_spec.ts b/packages/angular_devkit/architect/src/jobs/simple-scheduler_spec.ts index a4b1ee75a922..560927179294 100644 --- a/packages/angular_devkit/architect/src/jobs/simple-scheduler_spec.ts +++ b/packages/angular_devkit/architect/src/jobs/simple-scheduler_spec.ts @@ -168,7 +168,7 @@ describe('SimpleScheduler', () => { // Might be out of order. expect(done).toEqual(jasmine.arrayContaining([1, 2, 3, 4, 5, 6, 7])); // Verify at least partial order. - expect(done[done.length - 1]).toBe(7); + expect(done.at(-1)).toBe(7); expect(done.indexOf(4)).toBeGreaterThan(done.indexOf(1)); expect(done.indexOf(5)).toBeGreaterThan(done.indexOf(2)); expect(done.indexOf(6)).toBeGreaterThan(done.indexOf(3)); diff --git a/packages/angular_devkit/build_angular/src/builders/dev-server/tests/behavior/serve-live-reload-proxies_spec.ts b/packages/angular_devkit/build_angular/src/builders/dev-server/tests/behavior/serve-live-reload-proxies_spec.ts index c2a1758f2b5e..09d50dbb4528 100644 --- a/packages/angular_devkit/build_angular/src/builders/dev-server/tests/behavior/serve-live-reload-proxies_spec.ts +++ b/packages/angular_devkit/build_angular/src/builders/dev-server/tests/behavior/serve-live-reload-proxies_spec.ts @@ -108,8 +108,7 @@ async function createProxy(target: string, secure: boolean, ws = true): Promise< async function goToPageAndWaitForWS(page: Page, url: string): Promise { const baseUrl = url.replace(/^http/, 'ws'); - const socksRequest = - baseUrl[baseUrl.length - 1] === '/' ? `${baseUrl}ng-cli-ws` : `${baseUrl}/ng-cli-ws`; + const socksRequest = baseUrl.at(-1) === '/' ? `${baseUrl}ng-cli-ws` : `${baseUrl}/ng-cli-ws`; // Create a Chrome dev tools session so that we can capturing websocket request. // https://github.com/puppeteer/puppeteer/issues/2974 diff --git a/packages/angular_devkit/build_angular/src/builders/dev-server/tests/execute-fetch.ts b/packages/angular_devkit/build_angular/src/builders/dev-server/tests/execute-fetch.ts index eada7975ba88..489ae5501cda 100644 --- a/packages/angular_devkit/build_angular/src/builders/dev-server/tests/execute-fetch.ts +++ b/packages/angular_devkit/build_angular/src/builders/dev-server/tests/execute-fetch.ts @@ -27,7 +27,7 @@ export async function executeOnceAndFetch( let content = undefined; if (executionResult.result?.success) { let baseUrl = `${executionResult.result.baseUrl}`; - baseUrl = baseUrl[baseUrl.length - 1] === '/' ? baseUrl : `${baseUrl}/`; + baseUrl = baseUrl.at(-1) === '/' ? baseUrl : `${baseUrl}/`; const resolvedUrl = new URL(url, baseUrl); const originalResponse = await fetch(resolvedUrl, options?.request); response = originalResponse.clone(); diff --git a/packages/angular_devkit/core/src/utils/template.ts b/packages/angular_devkit/core/src/utils/template.ts index ebd3778fd4e9..f28bbf7ad417 100644 --- a/packages/angular_devkit/core/src/utils/template.ts +++ b/packages/angular_devkit/core/src/utils/template.ts @@ -253,9 +253,7 @@ function templateWithSourceMap(ast: TemplateAst, options?: TemplateOptions): str ]), ); - const end = ast.children.length - ? ast.children[ast.children.length - 1].end - : { line: 0, column: 0 }; + const end = ast.children.at(-1)?.end ?? { line: 0, column: 0 }; const nodes = ast.children .reduce((chunk, node) => { let code: string | SourceNode | (SourceNode | string)[] = ''; diff --git a/packages/angular_devkit/core/src/virtual-fs/path.ts b/packages/angular_devkit/core/src/virtual-fs/path.ts index 198b07aa7975..783bfe9d4402 100644 --- a/packages/angular_devkit/core/src/virtual-fs/path.ts +++ b/packages/angular_devkit/core/src/virtual-fs/path.ts @@ -57,7 +57,7 @@ export const NormalizedRoot: Path = NormalizedSep; */ export function split(path: Path): PathFragment[] { const fragments = path.split(NormalizedSep).map((x) => fragment(x)); - if (fragments[fragments.length - 1].length === 0) { + if (fragments.at(-1)?.length === 0) { fragments.pop(); } diff --git a/packages/angular_devkit/schematics/src/tree/action.ts b/packages/angular_devkit/schematics/src/tree/action.ts index 2f5f5e38e900..2d76bcc3662e 100644 --- a/packages/angular_devkit/schematics/src/tree/action.ts +++ b/packages/angular_devkit/schematics/src/tree/action.ts @@ -31,7 +31,7 @@ export class ActionList implements Iterable { this._actions.push({ ...(action as Action), id: _id++, - parent: this._actions[this._actions.length - 1]?.id ?? 0, + parent: this._actions.at(-1)?.id ?? 0, }); } diff --git a/packages/angular_devkit/schematics/src/workflow/base.ts b/packages/angular_devkit/schematics/src/workflow/base.ts index 66f1f20ec379..dcf23ff3f755 100644 --- a/packages/angular_devkit/schematics/src/workflow/base.ts +++ b/packages/angular_devkit/schematics/src/workflow/base.ts @@ -91,7 +91,7 @@ export abstract class BaseWorkflow implements Workflow { } get context(): Readonly { - const maybeContext = this._context[this._context.length - 1]; + const maybeContext = this._context.at(-1); if (!maybeContext) { throw new Error('Cannot get context when workflow is not executing...'); } @@ -146,7 +146,7 @@ export abstract class BaseWorkflow implements Workflow { execute( options: Partial & RequiredWorkflowExecutionContext, ): Observable { - const parentContext = this._context[this._context.length - 1]; + const parentContext = this._context.at(-1); if (!parentContext) { this._lifeCycle.next({ kind: 'start' }); diff --git a/tests/legacy-cli/e2e_runner.ts b/tests/legacy-cli/e2e_runner.ts index 0db1dfb01025..6c9e3179411c 100644 --- a/tests/legacy-cli/e2e_runner.ts +++ b/tests/legacy-cli/e2e_runner.ts @@ -121,7 +121,7 @@ const logger = createConsoleLogger(argv.verbose, process.stdout, process.stderr, const logStack = [logger]; function lastLogger() { - return logStack[logStack.length - 1]; + return logStack.at(-1)!; } // Under bazel the compiled file (.js) and types (.d.ts) are available. diff --git a/tsconfig-build-esm.json b/tsconfig-build-esm.json index 5a548be0a88f..8682ad1fbdc5 100644 --- a/tsconfig-build-esm.json +++ b/tsconfig-build-esm.json @@ -8,7 +8,7 @@ "compilerOptions": { "module": "esnext", "target": "es2022", - "lib": ["es2020"], + "lib": ["es2022"], // don't auto-discover @types/node, it results in a /// Date: Thu, 20 Nov 2025 15:18:29 +0000 Subject: [PATCH 30/54] fix(@schematics/angular): support testRunner option in library schematic This commit introduces the `testRunner` option to the library schematic, allowing users to explicitly select between `vitest` and `karma` as their test runner. Additionally, the `ng-new` schematic has been updated to configure the default `testRunner` for libraries in `angular.json` based on the workspace creation options. Closes #31887 (cherry picked from commit a525c939a5f9cdcc3fcdfcaed399672ddfb2ef97) --- .../schematics/angular/application/index.ts | 78 +++---------------- packages/schematics/angular/library/index.ts | 39 +++++----- .../schematics/angular/library/index_spec.ts | 4 +- .../schematics/angular/library/schema.json | 6 ++ packages/schematics/angular/ng-new/index.ts | 15 ++-- .../schematics/angular/ng-new/index_spec.ts | 1 + .../angular/utility/dependencies.ts | 63 ++++++++++++++- 7 files changed, 112 insertions(+), 94 deletions(-) diff --git a/packages/schematics/angular/application/index.ts b/packages/schematics/angular/application/index.ts index 53ddd53acad0..d228c5f12cad 100644 --- a/packages/schematics/angular/application/index.ts +++ b/packages/schematics/angular/application/index.ts @@ -23,6 +23,7 @@ import { url, } from '@angular-devkit/schematics'; import { Schema as ComponentOptions, Style as ComponentStyle } from '../component/schema'; +import { getTestRunnerDependencies } from '../utility/dependencies'; import { DependencyType, ExistingBehavior, @@ -187,62 +188,7 @@ function addDependenciesToPackageJson(options: ApplicationOptions): Rule { } if (!options.skipTests) { - if (options.testRunner === 'vitest') { - rules.push( - addDependency('vitest', latestVersions['vitest'], { - type: DependencyType.Dev, - existing: ExistingBehavior.Skip, - install: options.skipInstall ? InstallBehavior.None : InstallBehavior.Auto, - }), - addDependency('jsdom', latestVersions['jsdom'], { - type: DependencyType.Dev, - existing: ExistingBehavior.Skip, - install: options.skipInstall ? InstallBehavior.None : InstallBehavior.Auto, - }), - ); - } else { - rules.push( - addDependency('karma', latestVersions['karma'], { - type: DependencyType.Dev, - existing: ExistingBehavior.Skip, - install: options.skipInstall ? InstallBehavior.None : InstallBehavior.Auto, - }), - addDependency('karma-chrome-launcher', latestVersions['karma-chrome-launcher'], { - type: DependencyType.Dev, - existing: ExistingBehavior.Skip, - install: options.skipInstall ? InstallBehavior.None : InstallBehavior.Auto, - }), - addDependency('karma-coverage', latestVersions['karma-coverage'], { - type: DependencyType.Dev, - existing: ExistingBehavior.Skip, - install: options.skipInstall ? InstallBehavior.None : InstallBehavior.Auto, - }), - addDependency('karma-jasmine', latestVersions['karma-jasmine'], { - type: DependencyType.Dev, - existing: ExistingBehavior.Skip, - install: options.skipInstall ? InstallBehavior.None : InstallBehavior.Auto, - }), - addDependency( - 'karma-jasmine-html-reporter', - latestVersions['karma-jasmine-html-reporter'], - { - type: DependencyType.Dev, - existing: ExistingBehavior.Skip, - install: options.skipInstall ? InstallBehavior.None : InstallBehavior.Auto, - }, - ), - addDependency('jasmine-core', latestVersions['jasmine-core'], { - type: DependencyType.Dev, - existing: ExistingBehavior.Skip, - install: options.skipInstall ? InstallBehavior.None : InstallBehavior.Auto, - }), - addDependency('@types/jasmine', latestVersions['@types/jasmine'], { - type: DependencyType.Dev, - existing: ExistingBehavior.Skip, - install: options.skipInstall ? InstallBehavior.None : InstallBehavior.Auto, - }), - ); - } + rules.push(...getTestRunnerDependencies(options.testRunner, !!options.skipInstall)); } return chain(rules); @@ -392,17 +338,15 @@ function addAppToWorkspaceFile(options: ApplicationOptions, appDir: string): Rul test: options.skipTests || options.minimal ? undefined - : options.testRunner === 'vitest' - ? { - builder: Builders.BuildUnitTest, - options: {}, - } - : { - builder: Builders.BuildUnitTest, - options: { - runner: 'karma', - }, - }, + : { + builder: Builders.BuildUnitTest, + options: + options.testRunner === 'vitest' + ? {} + : { + runner: 'karma', + }, + }, }, }; diff --git a/packages/schematics/angular/library/index.ts b/packages/schematics/angular/library/index.ts index b02e35b27758..aa01d36f798e 100644 --- a/packages/schematics/angular/library/index.ts +++ b/packages/schematics/angular/library/index.ts @@ -20,6 +20,7 @@ import { url, } from '@angular-devkit/schematics'; import { join } from 'node:path/posix'; +import { getTestRunnerDependencies } from '../utility/dependencies'; import { DependencyType, ExistingBehavior, @@ -69,7 +70,7 @@ function addTsProjectReference(...paths: string[]) { }; } -function addDependenciesToPackageJson(skipInstall: boolean): Rule { +function addDependenciesToPackageJson({ skipInstall, testRunner }: LibraryOptions): Rule { return chain([ ...LIBRARY_DEV_DEPENDENCIES.map((dependency) => addDependency(dependency.name, dependency.version, { @@ -78,6 +79,7 @@ function addDependenciesToPackageJson(skipInstall: boolean): Rule { install: skipInstall ? InstallBehavior.None : InstallBehavior.Auto, }), ), + ...getTestRunnerDependencies(testRunner, !!skipInstall), addDependency('tslib', latestVersions['tslib'], { type: DependencyType.Default, existing: ExistingBehavior.Skip, @@ -91,7 +93,6 @@ function addLibToWorkspaceFile( projectRoot: string, projectName: string, hasZoneDependency: boolean, - hasVitest: boolean, ): Rule { return updateWorkspace((workspace) => { workspace.projects.add({ @@ -113,20 +114,21 @@ function addLibToWorkspaceFile( }, }, }, - test: hasVitest - ? { - builder: Builders.BuildUnitTest, - options: { - tsConfig: `${projectRoot}/tsconfig.spec.json`, + test: + options.testRunner === 'vitest' + ? { + builder: Builders.BuildUnitTest, + options: { + tsConfig: `${projectRoot}/tsconfig.spec.json`, + }, + } + : { + builder: Builders.BuildKarma, + options: { + tsConfig: `${projectRoot}/tsconfig.spec.json`, + polyfills: hasZoneDependency ? ['zone.js', 'zone.js/testing'] : undefined, + }, }, - } - : { - builder: Builders.BuildKarma, - options: { - tsConfig: `${projectRoot}/tsconfig.spec.json`, - polyfills: hasZoneDependency ? ['zone.js', 'zone.js/testing'] : undefined, - }, - }, }, }); }); @@ -158,7 +160,6 @@ export default function (options: LibraryOptions): Rule { const distRoot = `dist/${folderName}`; const sourceDir = `${libDir}/src/lib`; - const hasVitest = getDependency(host, 'vitest') !== null; const templateSource = apply(url('./files'), [ applyTemplates({ @@ -172,7 +173,7 @@ export default function (options: LibraryOptions): Rule { angularLatestVersion: latestVersions.Angular.replace(/~|\^/, ''), tsLibLatestVersion: latestVersions['tslib'].replace(/~|\^/, ''), folderName, - testTypesPackage: hasVitest ? 'vitest/globals' : 'jasmine', + testTypesPackage: options.testRunner === 'vitest' ? 'vitest/globals' : 'jasmine', }), move(libDir), ]); @@ -181,8 +182,8 @@ export default function (options: LibraryOptions): Rule { return chain([ mergeWith(templateSource), - addLibToWorkspaceFile(options, libDir, packageName, hasZoneDependency, hasVitest), - options.skipPackageJson ? noop() : addDependenciesToPackageJson(!!options.skipInstall), + addLibToWorkspaceFile(options, libDir, packageName, hasZoneDependency), + options.skipPackageJson ? noop() : addDependenciesToPackageJson(options), options.skipTsConfig ? noop() : updateTsConfig(packageName, './' + distRoot), options.skipTsConfig ? noop() diff --git a/packages/schematics/angular/library/index_spec.ts b/packages/schematics/angular/library/index_spec.ts index 319abbaa5162..bf4f8714294e 100644 --- a/packages/schematics/angular/library/index_spec.ts +++ b/packages/schematics/angular/library/index_spec.ts @@ -407,11 +407,11 @@ describe('Library Schematic', () => { expect(workspace.projects.foo.architect.build.builder).toBe('@angular/build:ng-packagr'); }); - it(`should add 'karma' test builder`, async () => { + it(`should add 'unit-test' test builder`, async () => { const tree = await schematicRunner.runSchematic('library', defaultOptions, workspaceTree); const workspace = JSON.parse(tree.readContent('/angular.json')); - expect(workspace.projects.foo.architect.test.builder).toBe('@angular/build:karma'); + expect(workspace.projects.foo.architect.test.builder).toBe('@angular/build:unit-test'); }); it(`should add 'unit-test' test builder`, async () => { diff --git a/packages/schematics/angular/library/schema.json b/packages/schematics/angular/library/schema.json index 62ffdbb422a0..bb3d227e5245 100644 --- a/packages/schematics/angular/library/schema.json +++ b/packages/schematics/angular/library/schema.json @@ -53,6 +53,12 @@ "type": "boolean", "default": true, "x-user-analytics": "ep.ng_standalone" + }, + "testRunner": { + "description": "The unit testing runner to use.", + "type": "string", + "enum": ["vitest", "karma"], + "default": "vitest" } }, "required": ["name"] diff --git a/packages/schematics/angular/ng-new/index.ts b/packages/schematics/angular/ng-new/index.ts index 7fca64d69ce3..7e4e7d98d36b 100644 --- a/packages/schematics/angular/ng-new/index.ts +++ b/packages/schematics/angular/ng-new/index.ts @@ -67,16 +67,21 @@ export default function (options: NgNewOptions): Rule { mergeWith( apply(empty(), [ schematic('workspace', workspaceOptions), - options.createApplication ? schematic('application', applicationOptions) : noop, - schematic('ai-config', { - tool: options.aiConfig?.length ? options.aiConfig : undefined, - }), (tree: Tree) => { if (options.testRunner === 'karma') { const file = new JSONFile(tree, 'angular.json'); - file.modify(['schematics', '@schematics/angular:application', 'testRunner'], 'karma'); + // eslint-disable-next-line @typescript-eslint/no-explicit-any + const schematics = file.get(['schematics']) ?? ({} as any); + (schematics['@schematics/angular:application'] ??= {}).testRunner = 'karma'; + (schematics['@schematics/angular:library'] ??= {}).testRunner = 'karma'; + + file.modify(['schematics'], schematics); } }, + options.createApplication ? schematic('application', applicationOptions) : noop, + schematic('ai-config', { + tool: options.aiConfig?.length ? options.aiConfig : undefined, + }), move(options.directory), ]), ), diff --git a/packages/schematics/angular/ng-new/index_spec.ts b/packages/schematics/angular/ng-new/index_spec.ts index 7f136908c747..fa68cf746be2 100644 --- a/packages/schematics/angular/ng-new/index_spec.ts +++ b/packages/schematics/angular/ng-new/index_spec.ts @@ -183,6 +183,7 @@ describe('Ng New Schematic', () => { const { schematics } = JSON.parse(tree.readContent('/bar/angular.json')); expect(schematics['@schematics/angular:application'].testRunner).toBe('karma'); + expect(schematics['@schematics/angular:library'].testRunner).toBe('karma'); }); it(`should not add type to class name when file name style guide is '2016'`, async () => { diff --git a/packages/schematics/angular/utility/dependencies.ts b/packages/schematics/angular/utility/dependencies.ts index 06c4f38653bd..3cbffa49a6a0 100644 --- a/packages/schematics/angular/utility/dependencies.ts +++ b/packages/schematics/angular/utility/dependencies.ts @@ -6,8 +6,11 @@ * found in the LICENSE file at https://angular.dev/license */ -import { Tree } from '@angular-devkit/schematics'; +import { Rule, Tree } from '@angular-devkit/schematics'; +import { TestRunner } from '../ng-new/schema'; +import { DependencyType, ExistingBehavior, InstallBehavior, addDependency } from './dependency'; import { JSONFile } from './json-file'; +import { latestVersions } from './latest-versions'; const PKG_JSON_PATH = '/package.json'; export enum NodeDependencyType { @@ -78,3 +81,61 @@ export function getPackageJsonDependency( return null; } + +export function getTestRunnerDependencies( + testRunner: TestRunner | undefined, + skipInstall: boolean, +): Rule[] { + if (testRunner === TestRunner.Vitest) { + return [ + addDependency('vitest', latestVersions['vitest'], { + type: DependencyType.Dev, + existing: ExistingBehavior.Skip, + install: skipInstall ? InstallBehavior.None : InstallBehavior.Auto, + }), + addDependency('jsdom', latestVersions['jsdom'], { + type: DependencyType.Dev, + existing: ExistingBehavior.Skip, + install: skipInstall ? InstallBehavior.None : InstallBehavior.Auto, + }), + ]; + } + + return [ + addDependency('karma', latestVersions['karma'], { + type: DependencyType.Dev, + existing: ExistingBehavior.Skip, + install: skipInstall ? InstallBehavior.None : InstallBehavior.Auto, + }), + addDependency('karma-chrome-launcher', latestVersions['karma-chrome-launcher'], { + type: DependencyType.Dev, + existing: ExistingBehavior.Skip, + install: skipInstall ? InstallBehavior.None : InstallBehavior.Auto, + }), + addDependency('karma-coverage', latestVersions['karma-coverage'], { + type: DependencyType.Dev, + existing: ExistingBehavior.Skip, + install: skipInstall ? InstallBehavior.None : InstallBehavior.Auto, + }), + addDependency('karma-jasmine', latestVersions['karma-jasmine'], { + type: DependencyType.Dev, + existing: ExistingBehavior.Skip, + install: skipInstall ? InstallBehavior.None : InstallBehavior.Auto, + }), + addDependency('karma-jasmine-html-reporter', latestVersions['karma-jasmine-html-reporter'], { + type: DependencyType.Dev, + existing: ExistingBehavior.Skip, + install: skipInstall ? InstallBehavior.None : InstallBehavior.Auto, + }), + addDependency('jasmine-core', latestVersions['jasmine-core'], { + type: DependencyType.Dev, + existing: ExistingBehavior.Skip, + install: skipInstall ? InstallBehavior.None : InstallBehavior.Auto, + }), + addDependency('@types/jasmine', latestVersions['@types/jasmine'], { + type: DependencyType.Dev, + existing: ExistingBehavior.Skip, + install: skipInstall ? InstallBehavior.None : InstallBehavior.Auto, + }), + ]; +} From c4719c6e38a94743bf71675935b669d138cb61ca Mon Sep 17 00:00:00 2001 From: Alan Agius <17563226+alan-agius4@users.noreply.github.com> Date: Thu, 20 Nov 2025 15:32:00 +0000 Subject: [PATCH 31/54] refactor: replace string literals with TestRunner enum for test runner options. Replace string with enum (cherry picked from commit cc66824fefac0d2fa113e785b2df59d0bd99e81f) --- packages/angular/build/src/builders/unit-test/options.ts | 6 +++--- .../angular/build/src/builders/unit-test/tests/setup.ts | 4 ++-- packages/schematics/angular/application/index.ts | 4 ++-- packages/schematics/angular/application/index_spec.ts | 4 ++-- packages/schematics/angular/library/index.ts | 6 +++--- packages/schematics/angular/ng-new/index.ts | 8 ++++---- packages/schematics/angular/ng-new/index_spec.ts | 6 +++--- 7 files changed, 19 insertions(+), 19 deletions(-) diff --git a/packages/angular/build/src/builders/unit-test/options.ts b/packages/angular/build/src/builders/unit-test/options.ts index ac3d1b4e9652..8fa5b14eda59 100644 --- a/packages/angular/build/src/builders/unit-test/options.ts +++ b/packages/angular/build/src/builders/unit-test/options.ts @@ -12,7 +12,7 @@ import path from 'node:path'; import { normalizeCacheOptions } from '../../utils/normalize-cache'; import { getProjectRootPaths } from '../../utils/project-metadata'; import { isTTY } from '../../utils/tty'; -import type { Schema as UnitTestBuilderOptions } from './schema'; +import { Runner, type Schema as UnitTestBuilderOptions } from './schema'; export type NormalizedUnitTestBuilderOptions = Awaited>; @@ -56,7 +56,7 @@ export async function normalizeOptions( const { runner, browsers, progress, filter, browserViewport, ui, runnerConfig } = options; - if (ui && runner !== 'vitest') { + if (ui && runner !== Runner.Vitest) { throw new Error('The "ui" option is only available for the "vitest" runner.'); } @@ -95,7 +95,7 @@ export async function normalizeOptions( include: options.include ?? ['**/*.spec.ts'], exclude: options.exclude, filter, - runnerName: runner ?? 'vitest', + runnerName: runner ?? Runner.Vitest, coverage: { enabled: options.coverage, exclude: options.coverageExclude, diff --git a/packages/angular/build/src/builders/unit-test/tests/setup.ts b/packages/angular/build/src/builders/unit-test/tests/setup.ts index db03c2b0b348..e6770e115789 100644 --- a/packages/angular/build/src/builders/unit-test/tests/setup.ts +++ b/packages/angular/build/src/builders/unit-test/tests/setup.ts @@ -14,7 +14,7 @@ import { ApplicationBuilderOptions as ApplicationSchema, buildApplication, } from '../../../builders/application'; -import { Schema } from '../schema'; +import { Runner, Schema } from '../schema'; // TODO: Consider using package.json imports field instead of relative path // after the switch to rules_js. @@ -61,7 +61,7 @@ export const UNIT_TEST_BUILDER_INFO = Object.freeze({ export const BASE_OPTIONS = Object.freeze({ buildTarget: 'test:build', tsConfig: 'src/tsconfig.spec.json', - runner: 'vitest' as any, + runner: Runner.Vitest, }); /** diff --git a/packages/schematics/angular/application/index.ts b/packages/schematics/angular/application/index.ts index d228c5f12cad..dc2cd9217fce 100644 --- a/packages/schematics/angular/application/index.ts +++ b/packages/schematics/angular/application/index.ts @@ -35,7 +35,7 @@ import { latestVersions } from '../utility/latest-versions'; import { relativePathToWorkspaceRoot } from '../utility/paths'; import { getWorkspace, updateWorkspace } from '../utility/workspace'; import { Builders, ProjectType } from '../utility/workspace-models'; -import { Schema as ApplicationOptions, Style } from './schema'; +import { Schema as ApplicationOptions, Style, TestRunner } from './schema'; const APPLICATION_DEV_DEPENDENCIES = [ { name: '@angular/compiler-cli', version: latestVersions.Angular }, @@ -341,7 +341,7 @@ function addAppToWorkspaceFile(options: ApplicationOptions, appDir: string): Rul : { builder: Builders.BuildUnitTest, options: - options.testRunner === 'vitest' + options.testRunner === TestRunner.Vitest ? {} : { runner: 'karma', diff --git a/packages/schematics/angular/application/index_spec.ts b/packages/schematics/angular/application/index_spec.ts index 4d95be8b5ea1..c2f91d110f27 100644 --- a/packages/schematics/angular/application/index_spec.ts +++ b/packages/schematics/angular/application/index_spec.ts @@ -10,7 +10,7 @@ import { SchematicTestRunner, UnitTestTree } from '@angular-devkit/schematics/te import { parse as parseJson } from 'jsonc-parser'; import { latestVersions } from '../utility/latest-versions'; import { Schema as WorkspaceOptions } from '../workspace/schema'; -import { Schema as ApplicationOptions, Style, ViewEncapsulation } from './schema'; +import { Schema as ApplicationOptions, Style, TestRunner, ViewEncapsulation } from './schema'; // eslint-disable-next-line @typescript-eslint/no-explicit-any function readJsonFile(tree: UnitTestTree, path: string): any { @@ -442,7 +442,7 @@ describe('Application Schematic', () => { }); it('should set values in angular.json correctly when testRunner is karma', async () => { - const options = { ...defaultOptions, projectRoot: '', testRunner: 'karma' as const }; + const options = { ...defaultOptions, projectRoot: '', testRunner: TestRunner.Karma }; const tree = await schematicRunner.runSchematic('application', options, workspaceTree); const config = JSON.parse(tree.readContent('/angular.json')); diff --git a/packages/schematics/angular/library/index.ts b/packages/schematics/angular/library/index.ts index aa01d36f798e..0dd51ca448df 100644 --- a/packages/schematics/angular/library/index.ts +++ b/packages/schematics/angular/library/index.ts @@ -33,7 +33,7 @@ import { latestVersions } from '../utility/latest-versions'; import { relativePathToWorkspaceRoot } from '../utility/paths'; import { getWorkspace, updateWorkspace } from '../utility/workspace'; import { Builders, ProjectType } from '../utility/workspace-models'; -import { Schema as LibraryOptions } from './schema'; +import { Schema as LibraryOptions, TestRunner } from './schema'; const LIBRARY_DEV_DEPENDENCIES = [ { name: '@angular/compiler-cli', version: latestVersions.Angular }, @@ -115,7 +115,7 @@ function addLibToWorkspaceFile( }, }, test: - options.testRunner === 'vitest' + options.testRunner === TestRunner.Vitest ? { builder: Builders.BuildUnitTest, options: { @@ -173,7 +173,7 @@ export default function (options: LibraryOptions): Rule { angularLatestVersion: latestVersions.Angular.replace(/~|\^/, ''), tsLibLatestVersion: latestVersions['tslib'].replace(/~|\^/, ''), folderName, - testTypesPackage: options.testRunner === 'vitest' ? 'vitest/globals' : 'jasmine', + testTypesPackage: options.testRunner === TestRunner.Vitest ? 'vitest/globals' : 'jasmine', }), move(libDir), ]); diff --git a/packages/schematics/angular/ng-new/index.ts b/packages/schematics/angular/ng-new/index.ts index 7e4e7d98d36b..856343e82b8f 100644 --- a/packages/schematics/angular/ng-new/index.ts +++ b/packages/schematics/angular/ng-new/index.ts @@ -25,7 +25,7 @@ import { import { Schema as ApplicationOptions } from '../application/schema'; import { JSONFile } from '../utility/json-file'; import { Schema as WorkspaceOptions } from '../workspace/schema'; -import { Schema as NgNewOptions } from './schema'; +import { Schema as NgNewOptions, TestRunner } from './schema'; export default function (options: NgNewOptions): Rule { if (!options.directory) { @@ -68,12 +68,12 @@ export default function (options: NgNewOptions): Rule { apply(empty(), [ schematic('workspace', workspaceOptions), (tree: Tree) => { - if (options.testRunner === 'karma') { + if (options.testRunner === TestRunner.Karma) { const file = new JSONFile(tree, 'angular.json'); // eslint-disable-next-line @typescript-eslint/no-explicit-any const schematics = file.get(['schematics']) ?? ({} as any); - (schematics['@schematics/angular:application'] ??= {}).testRunner = 'karma'; - (schematics['@schematics/angular:library'] ??= {}).testRunner = 'karma'; + (schematics['@schematics/angular:application'] ??= {}).testRunner = TestRunner.Karma; + (schematics['@schematics/angular:library'] ??= {}).testRunner = TestRunner.Karma; file.modify(['schematics'], schematics); } diff --git a/packages/schematics/angular/ng-new/index_spec.ts b/packages/schematics/angular/ng-new/index_spec.ts index fa68cf746be2..28e1c13f315b 100644 --- a/packages/schematics/angular/ng-new/index_spec.ts +++ b/packages/schematics/angular/ng-new/index_spec.ts @@ -7,7 +7,7 @@ */ import { SchematicTestRunner } from '@angular-devkit/schematics/testing'; -import { Schema as NgNewOptions } from './schema'; +import { Schema as NgNewOptions, TestRunner } from './schema'; describe('Ng New Schematic', () => { const schematicRunner = new SchematicTestRunner( @@ -159,7 +159,7 @@ describe('Ng New Schematic', () => { }); it(`should set 'testRunner' to 'karma'`, async () => { - const options = { ...defaultOptions, testRunner: 'karma' as const }; + const options = { ...defaultOptions, testRunner: TestRunner.Karma }; const tree = await schematicRunner.runSchematic('ng-new', options); const { @@ -178,7 +178,7 @@ describe('Ng New Schematic', () => { }); it(`should set 'testRunner' to 'karma' in workspace schematic options`, async () => { - const options = { ...defaultOptions, testRunner: 'karma' as const }; + const options = { ...defaultOptions, testRunner: TestRunner.Karma }; const tree = await schematicRunner.runSchematic('ng-new', options); const { schematics } = JSON.parse(tree.readContent('/bar/angular.json')); From 572e559bfcc0d597aefeb1a04ce6694154d12c9e Mon Sep 17 00:00:00 2001 From: Alan Agius <17563226+alan-agius4@users.noreply.github.com> Date: Thu, 20 Nov 2025 15:38:25 +0000 Subject: [PATCH 32/54] refactor: streamline test runner dependency management using array mapping This commit simplifies the `getTestRunnerDependencies` implementation and renames it to `addTestRunnerDependencies`. (cherry picked from commit e28807645af0677f4551dd32681a9e8b08d75255) --- .../schematics/angular/application/index.ts | 4 +- packages/schematics/angular/library/index.ts | 4 +- .../angular/utility/dependencies.ts | 64 +++++-------------- 3 files changed, 20 insertions(+), 52 deletions(-) diff --git a/packages/schematics/angular/application/index.ts b/packages/schematics/angular/application/index.ts index dc2cd9217fce..e84a40530032 100644 --- a/packages/schematics/angular/application/index.ts +++ b/packages/schematics/angular/application/index.ts @@ -23,7 +23,7 @@ import { url, } from '@angular-devkit/schematics'; import { Schema as ComponentOptions, Style as ComponentStyle } from '../component/schema'; -import { getTestRunnerDependencies } from '../utility/dependencies'; +import { addTestRunnerDependencies } from '../utility/dependencies'; import { DependencyType, ExistingBehavior, @@ -188,7 +188,7 @@ function addDependenciesToPackageJson(options: ApplicationOptions): Rule { } if (!options.skipTests) { - rules.push(...getTestRunnerDependencies(options.testRunner, !!options.skipInstall)); + rules.push(...addTestRunnerDependencies(options.testRunner, !!options.skipInstall)); } return chain(rules); diff --git a/packages/schematics/angular/library/index.ts b/packages/schematics/angular/library/index.ts index 0dd51ca448df..3069664c02d7 100644 --- a/packages/schematics/angular/library/index.ts +++ b/packages/schematics/angular/library/index.ts @@ -20,7 +20,7 @@ import { url, } from '@angular-devkit/schematics'; import { join } from 'node:path/posix'; -import { getTestRunnerDependencies } from '../utility/dependencies'; +import { addTestRunnerDependencies } from '../utility/dependencies'; import { DependencyType, ExistingBehavior, @@ -79,7 +79,7 @@ function addDependenciesToPackageJson({ skipInstall, testRunner }: LibraryOption install: skipInstall ? InstallBehavior.None : InstallBehavior.Auto, }), ), - ...getTestRunnerDependencies(testRunner, !!skipInstall), + ...addTestRunnerDependencies(testRunner, !!skipInstall), addDependency('tslib', latestVersions['tslib'], { type: DependencyType.Default, existing: ExistingBehavior.Skip, diff --git a/packages/schematics/angular/utility/dependencies.ts b/packages/schematics/angular/utility/dependencies.ts index 3cbffa49a6a0..deb78ca9c0e2 100644 --- a/packages/schematics/angular/utility/dependencies.ts +++ b/packages/schematics/angular/utility/dependencies.ts @@ -82,60 +82,28 @@ export function getPackageJsonDependency( return null; } -export function getTestRunnerDependencies( +export function addTestRunnerDependencies( testRunner: TestRunner | undefined, skipInstall: boolean, ): Rule[] { - if (testRunner === TestRunner.Vitest) { - return [ - addDependency('vitest', latestVersions['vitest'], { - type: DependencyType.Dev, - existing: ExistingBehavior.Skip, - install: skipInstall ? InstallBehavior.None : InstallBehavior.Auto, - }), - addDependency('jsdom', latestVersions['jsdom'], { - type: DependencyType.Dev, - existing: ExistingBehavior.Skip, - install: skipInstall ? InstallBehavior.None : InstallBehavior.Auto, - }), - ]; - } + const dependencies = + testRunner === TestRunner.Vitest + ? ['vitest', 'jsdom'] + : [ + 'karma', + 'karma-chrome-launcher', + 'karma-coverage', + 'karma-jasmine', + 'karma-jasmine-html-reporter', + 'jasmine-core', + '@types/jasmine', + ]; - return [ - addDependency('karma', latestVersions['karma'], { - type: DependencyType.Dev, - existing: ExistingBehavior.Skip, - install: skipInstall ? InstallBehavior.None : InstallBehavior.Auto, - }), - addDependency('karma-chrome-launcher', latestVersions['karma-chrome-launcher'], { - type: DependencyType.Dev, - existing: ExistingBehavior.Skip, - install: skipInstall ? InstallBehavior.None : InstallBehavior.Auto, - }), - addDependency('karma-coverage', latestVersions['karma-coverage'], { - type: DependencyType.Dev, - existing: ExistingBehavior.Skip, - install: skipInstall ? InstallBehavior.None : InstallBehavior.Auto, - }), - addDependency('karma-jasmine', latestVersions['karma-jasmine'], { - type: DependencyType.Dev, - existing: ExistingBehavior.Skip, - install: skipInstall ? InstallBehavior.None : InstallBehavior.Auto, - }), - addDependency('karma-jasmine-html-reporter', latestVersions['karma-jasmine-html-reporter'], { - type: DependencyType.Dev, - existing: ExistingBehavior.Skip, - install: skipInstall ? InstallBehavior.None : InstallBehavior.Auto, - }), - addDependency('jasmine-core', latestVersions['jasmine-core'], { - type: DependencyType.Dev, - existing: ExistingBehavior.Skip, - install: skipInstall ? InstallBehavior.None : InstallBehavior.Auto, - }), - addDependency('@types/jasmine', latestVersions['@types/jasmine'], { + return dependencies.map((name) => + addDependency(name, latestVersions[name], { type: DependencyType.Dev, existing: ExistingBehavior.Skip, install: skipInstall ? InstallBehavior.None : InstallBehavior.Auto, }), - ]; + ); } From 3cac0188271175e12cc238c6610b542f3ae14db3 Mon Sep 17 00:00:00 2001 From: Alan Agius <17563226+alan-agius4@users.noreply.github.com> Date: Thu, 20 Nov 2025 16:55:05 +0000 Subject: [PATCH 33/54] fix(@angular/ssr): prevent redirect loop with encoded query parameters Previously, encoded query parameters caused a mismatch between the requested URL and the reconstructed URL, leading to a redirect loop. This change ensures both URLs are decoded before comparison. Closes #31881 (cherry picked from commit 61a027dba7f3a569c1ac936c34956b8f96fd102a) --- packages/angular/ssr/src/utils/ng.ts | 30 +++++++++++++++++--- packages/angular/ssr/src/utils/url.ts | 15 ++++++++++ packages/angular/ssr/test/app-engine_spec.ts | 14 +++++++++ 3 files changed, 55 insertions(+), 4 deletions(-) diff --git a/packages/angular/ssr/src/utils/ng.ts b/packages/angular/ssr/src/utils/ng.ts index 120fdf940dd6..5d10560db39d 100644 --- a/packages/angular/ssr/src/utils/ng.ts +++ b/packages/angular/ssr/src/utils/ng.ts @@ -107,13 +107,15 @@ export async function renderAngular( if (!routerIsProvided) { hasNavigationError = false; - } else if (lastSuccessfulNavigation) { + } else if (lastSuccessfulNavigation?.finalUrl) { hasNavigationError = false; + const { pathname, search, hash } = envInjector.get(PlatformLocation); - const finalUrl = [stripTrailingSlash(pathname), search, hash].join(''); + const finalUrl = constructDecodedUrl({ pathname, search, hash }); + const urlToRenderString = constructDecodedUrl(urlToRender); - if (urlToRender.href !== new URL(finalUrl, urlToRender.origin).href) { - redirectTo = finalUrl; + if (urlToRenderString !== finalUrl) { + redirectTo = [pathname, search, hash].join(''); } } @@ -171,3 +173,23 @@ function asyncDestroyPlatform(platformRef: PlatformRef): Promise { }, 0); }); } + +/** + * Constructs a decoded URL string from its components, ensuring consistency for comparison. + * + * This function takes a URL-like object (containing `pathname`, `search`, and `hash`), + * strips the trailing slash from the pathname, joins the components, and then decodes + * the entire string. This normalization is crucial for accurately comparing URLs + * that might differ only in encoding or trailing slashes. + * + * @param url - An object containing the URL components: + * - `pathname`: The path of the URL. + * - `search`: The query string of the URL (including '?'). + * - `hash`: The hash fragment of the URL (including '#'). + * @returns The constructed and decoded URL string. + */ +function constructDecodedUrl(url: { pathname: string; search: string; hash: string }): string { + const joinedUrl = [stripTrailingSlash(url.pathname), url.search, url.hash].join(''); + + return decodeURIComponent(joinedUrl); +} diff --git a/packages/angular/ssr/src/utils/url.ts b/packages/angular/ssr/src/utils/url.ts index 55d37ad9a05f..1fa756e19c19 100644 --- a/packages/angular/ssr/src/utils/url.ts +++ b/packages/angular/ssr/src/utils/url.ts @@ -220,3 +220,18 @@ export function stripMatrixParams(pathname: string): string { // This regex finds all occurrences of a semicolon followed by any characters return pathname.includes(';') ? pathname.replace(MATRIX_PARAMS_REGEX, '') : pathname; } + +/** + * Constructs a decoded URL string from its components. + * + * This function joins the pathname (with trailing slash removed), search, and hash, + * and then decodes the result. + * + * @param pathname - The path of the URL. + * @param search - The query string of the URL (including '?'). + * @param hash - The hash fragment of the URL (including '#'). + * @returns The constructed and decoded URL string. + */ +export function constructUrl(pathname: string, search: string, hash: string): string { + return decodeURIComponent([stripTrailingSlash(pathname), search, hash].join('')); +} diff --git a/packages/angular/ssr/test/app-engine_spec.ts b/packages/angular/ssr/test/app-engine_spec.ts index b08931b9400b..bfc824b6d260 100644 --- a/packages/angular/ssr/test/app-engine_spec.ts +++ b/packages/angular/ssr/test/app-engine_spec.ts @@ -269,5 +269,19 @@ describe('AngularAppEngine', () => { const response = await appEngine.handle(request); expect(await response?.text()).toContain('Home works'); }); + + it('should work with encoded characters', async () => { + const request = new Request('https://example.com/home?email=xyz%40xyz.com'); + const response = await appEngine.handle(request); + expect(response?.status).toBe(200); + expect(await response?.text()).toContain('Home works'); + }); + + it('should work with decoded characters', async () => { + const request = new Request('https://example.com/home?email=xyz@xyz.com'); + const response = await appEngine.handle(request); + expect(response?.status).toBe(200); + expect(await response?.text()).toContain('Home works'); + }); }); }); From a28b38bbeba0977e99142a15d1ecc77c15abc416 Mon Sep 17 00:00:00 2001 From: Alan Agius <17563226+alan-agius4@users.noreply.github.com> Date: Fri, 21 Nov 2025 13:36:19 +0000 Subject: [PATCH 34/54] fix(@angular/build): force dev-server to use HTTP/1.1 when using SSR with SSL When using SSR with SSL, Vite attempts to use HTTP/2 by default. However, the Express server used for SSR does not support HTTP/2, causing requests to fail. This commit forces Vite to use HTTP/1.1 in this scenario by setting the ALPNProtocols to `['http/1.1']`. This is required as now Vite uses HTTP 2 for SSL: https://github.com/vitejs/vite/commit/fc21af7a42dd559a95f54b6165d34f36883eaa7f Closes #31894 (cherry picked from commit 53012c89f324ef4537e86d2a5de29d66e333fe77) --- .../src/builders/dev-server/vite/server.ts | 8 +------- .../src/tools/vite/plugins/ssr-ssl-plugin.ts | 12 ++++++++++++ tests/legacy-cli/e2e/tests/vite/ssr-with-ssl.ts | 17 +++++++++++++---- 3 files changed, 26 insertions(+), 11 deletions(-) diff --git a/packages/angular/build/src/builders/dev-server/vite/server.ts b/packages/angular/build/src/builders/dev-server/vite/server.ts index 9cabeabccfec..73f58ad5c348 100644 --- a/packages/angular/build/src/builders/dev-server/vite/server.ts +++ b/packages/angular/build/src/builders/dev-server/vite/server.ts @@ -60,13 +60,7 @@ async function createServerConfig( headers: serverOptions.headers, // Disable the websocket if live reload is disabled (false/undefined are the only valid values) ws: serverOptions.liveReload === false && serverOptions.hmr === false ? false : undefined, - // When server-side rendering (SSR) is enabled togather with SSL and Express is being used, - // we must configure Vite to use HTTP/1.1. - // This is necessary because Express does not support HTTP/2. - // We achieve this by defining an empty proxy. - // See: https://github.com/vitejs/vite/blob/c4b532cc900bf988073583511f57bd581755d5e3/packages/vite/src/node/http.ts#L106 - proxy: - serverOptions.ssl && ssrMode === ServerSsrMode.ExternalSsrMiddleware ? (proxy ?? {}) : proxy, + proxy, cors: { // This will add the header `Access-Control-Allow-Origin: http://example.com`, // where `http://example.com` is the requesting origin. diff --git a/packages/angular/build/src/tools/vite/plugins/ssr-ssl-plugin.ts b/packages/angular/build/src/tools/vite/plugins/ssr-ssl-plugin.ts index c87e0bd112a0..0cde7f89ef0a 100644 --- a/packages/angular/build/src/tools/vite/plugins/ssr-ssl-plugin.ts +++ b/packages/angular/build/src/tools/vite/plugins/ssr-ssl-plugin.ts @@ -23,6 +23,18 @@ export function createAngularServerSideSSLPlugin(): Plugin { return; } + if (httpServer && 'ALPNProtocols' in httpServer) { + // Force Vite to use HTTP/1.1 when SSR and SSL are enabled. + // This is required because the Express server used for SSR does not support HTTP/2. + // See: https://github.com/vitejs/vite/blob/46d3077f2b63771cc50230bc907c48f5773c00fb/packages/vite/src/node/http.ts#L126 + + // We directly set the `ALPNProtocols` on the HTTP server to override the default behavior. + // Passing `ALPNProtocols` in the TLS options would cause Node.js to automatically include `h2`. + // Additionally, using `ALPNCallback` is not an option as it is mutually exclusive with `ALPNProtocols`. + // See: https://github.com/nodejs/node/blob/b8b4350ed3b73d225eb9e628d69151df56eaf298/lib/internal/http2/core.js#L3351 + httpServer.ALPNProtocols = ['http/1.1']; + } + // TODO(alanagius): Replace `undici` with `tls.setDefaultCACertificates` once we only support Node.js 22.18.0+ and 24.5.0+. // See: https://nodejs.org/api/tls.html#tlssetdefaultcacertificatescerts const { getGlobalDispatcher, setGlobalDispatcher, Agent } = await import('undici'); diff --git a/tests/legacy-cli/e2e/tests/vite/ssr-with-ssl.ts b/tests/legacy-cli/e2e/tests/vite/ssr-with-ssl.ts index 5bb8d9105cf8..90518080f8f3 100644 --- a/tests/legacy-cli/e2e/tests/vite/ssr-with-ssl.ts +++ b/tests/legacy-cli/e2e/tests/vite/ssr-with-ssl.ts @@ -42,14 +42,23 @@ export default async function () { const port = await ngServe('--ssl'); - // Verify the server is running and the API response is correct. - await validateResponse('/main.js', /bootstrapApplication/); - await validateResponse('/home', /home works/); + // http 2 + await validateResponse('/main.js', /bootstrapApplication/, true); + await validateResponse('/home', /home works/, true); - async function validateResponse(pathname: string, match: RegExp): Promise { + // http 1.1 + await validateResponse('/main.js', /bootstrapApplication/, false); + await validateResponse('/home', /home works/, false); + + async function validateResponse( + pathname: string, + match: RegExp, + allowH2: boolean, + ): Promise { const response = await fetch(new URL(pathname, `https://localhost:${port}`), { dispatcher: new Agent({ connect: { + allowH2, rejectUnauthorized: false, }, }), From 7a52e3c4946206858587208c2e2f5c575697efe9 Mon Sep 17 00:00:00 2001 From: Alessio Pelliccione Date: Thu, 20 Nov 2025 15:52:51 +0100 Subject: [PATCH 35/54] fix(@schematics/angular): add MCP configuration file to new workspaces Changes: - Add .vscode/mcp.json template with angular-cli MCP server configuration - Update .gitignore template to whitelist .vscode/mcp.json - Update workspace schematic tests to expect mcp.json file Closes #31888 (cherry picked from commit 18cf6c51b72ce5c7f23012585ed992cf91cef5ed) --- .../angular/workspace/files/__dot__gitignore.template | 1 + .../workspace/files/__dot__vscode/mcp.json.template | 9 +++++++++ packages/schematics/angular/workspace/index_spec.ts | 2 ++ 3 files changed, 12 insertions(+) create mode 100644 packages/schematics/angular/workspace/files/__dot__vscode/mcp.json.template diff --git a/packages/schematics/angular/workspace/files/__dot__gitignore.template b/packages/schematics/angular/workspace/files/__dot__gitignore.template index b1d225e26e57..854acd5fc039 100644 --- a/packages/schematics/angular/workspace/files/__dot__gitignore.template +++ b/packages/schematics/angular/workspace/files/__dot__gitignore.template @@ -26,6 +26,7 @@ yarn-error.log !.vscode/tasks.json !.vscode/launch.json !.vscode/extensions.json +!.vscode/mcp.json .history/* # Miscellaneous diff --git a/packages/schematics/angular/workspace/files/__dot__vscode/mcp.json.template b/packages/schematics/angular/workspace/files/__dot__vscode/mcp.json.template new file mode 100644 index 000000000000..bf4004da9477 --- /dev/null +++ b/packages/schematics/angular/workspace/files/__dot__vscode/mcp.json.template @@ -0,0 +1,9 @@ +{ + // For more information, visit: https://angular.dev/ai/mcp + "mcpServers": { + "angular-cli": { + "command": "npx", + "args": ["-y", "@angular/cli", "mcp"] + } + } +} diff --git a/packages/schematics/angular/workspace/index_spec.ts b/packages/schematics/angular/workspace/index_spec.ts index 22be6e797e14..65dd7987aa41 100644 --- a/packages/schematics/angular/workspace/index_spec.ts +++ b/packages/schematics/angular/workspace/index_spec.ts @@ -29,6 +29,7 @@ describe('Workspace Schematic', () => { jasmine.arrayContaining([ '/.vscode/extensions.json', '/.vscode/launch.json', + '/.vscode/mcp.json', '/.vscode/tasks.json', '/.editorconfig', '/angular.json', @@ -70,6 +71,7 @@ describe('Workspace Schematic', () => { jasmine.arrayContaining([ '/.vscode/extensions.json', '/.vscode/launch.json', + '/.vscode/mcp.json', '/.vscode/tasks.json', '/angular.json', '/.gitignore', From 4534c9848745eea516bdb58d86914252c35b5b9c Mon Sep 17 00:00:00 2001 From: deku-nattsu Date: Fri, 21 Nov 2025 14:53:05 +0100 Subject: [PATCH 36/54] fix(@schematics/angular): do not set `esModuleInterop` and `moduleResolution` when module is `preserve` (cherry picked from commit 50d9c0e3dfdeb20d5677606cf16ab6062e75fd4b) --- .../migrations/use-application-builder/migration.ts | 10 ++++++++-- .../use-application-builder/migration_spec.ts | 13 +++++++++++++ 2 files changed, 21 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 cc858b59de54..9e8c9204d67f 100644 --- a/packages/schematics/angular/migrations/use-application-builder/migration.ts +++ b/packages/schematics/angular/migrations/use-application-builder/migration.ts @@ -362,10 +362,16 @@ export default function (): Rule { ), // Update main tsconfig updateJsonFile('tsconfig.json', (rootJson) => { - rootJson.modify(['compilerOptions', 'esModuleInterop'], true); + const module = rootJson.get(['compilerOptions', 'module']); + const hasPreserveModule = typeof module === 'string' && module.toLowerCase() === 'preserve'; + + if (!hasPreserveModule) { + rootJson.modify(['compilerOptions', 'esModuleInterop'], true); + rootJson.modify(['compilerOptions', 'moduleResolution'], 'bundler'); + } + rootJson.modify(['compilerOptions', 'downlevelIteration'], undefined); rootJson.modify(['compilerOptions', 'allowSyntheticDefaultImports'], undefined); - rootJson.modify(['compilerOptions', 'moduleResolution'], 'bundler'); }), ]); } 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 a8d50193958e..fd10352c6eac 100644 --- a/packages/schematics/angular/migrations/use-application-builder/migration_spec.ts +++ b/packages/schematics/angular/migrations/use-application-builder/migration_spec.ts @@ -6,6 +6,7 @@ * found in the LICENSE file at https://angular.dev/license */ +import { JsonObject } from '@angular-devkit/core'; import { EmptyTree } from '@angular-devkit/schematics'; import { SchematicTestRunner, UnitTestTree } from '@angular-devkit/schematics/testing'; import { Builders, ProjectType, WorkspaceSchema } from '../../utility/workspace-models'; @@ -448,4 +449,16 @@ describe(`Migration to use the application builder`, () => { expect(devDependencies['postcss']).toBeUndefined(); }); + + it('it should not add esModuleInterop and moduleResolution when module is preserve', async () => { + tree.overwrite( + 'tsconfig.json', + JSON.stringify({ + compilerOptions: { module: 'preserve' }, + }), + ); + const newTree = await schematicRunner.runSchematic(schematicName, {}, tree); + const { compilerOptions } = newTree.readJson('tsconfig.json') as JsonObject; + expect(compilerOptions).toEqual({ module: 'preserve' }); + }); }); From 07cff4ef8ca4e093323531e55be79cd52a7adb08 Mon Sep 17 00:00:00 2001 From: Angular Robot Date: Fri, 21 Nov 2025 09:06:12 +0000 Subject: [PATCH 37/54] build: update bazel dependencies See associated pull request for more information. --- MODULE.bazel | 4 ++-- MODULE.bazel.lock | 15 ++++++++------- 2 files changed, 10 insertions(+), 9 deletions(-) diff --git a/MODULE.bazel b/MODULE.bazel index 57200a6c1ae3..bc46e7ed3675 100644 --- a/MODULE.bazel +++ b/MODULE.bazel @@ -6,7 +6,7 @@ module( bazel_dep(name = "yq.bzl", version = "0.3.2") bazel_dep(name = "rules_nodejs", version = "6.6.2") -bazel_dep(name = "aspect_rules_js", version = "2.8.1") +bazel_dep(name = "aspect_rules_js", version = "2.8.2") bazel_dep(name = "aspect_rules_ts", version = "3.7.1") bazel_dep(name = "rules_pkg", version = "0.8.1") @@ -26,7 +26,7 @@ bazel_dep(name = "aspect_rules_jasmine", version = "2.0.0") bazel_dep(name = "rules_angular") git_override( module_name = "rules_angular", - commit = "74d8baec22a5ffd3a1a36bac252399fa125a6c4b", + commit = "9b751f826628cab386d1e8ae9c1fa766dbc6a495", remote = "https://github.com/devversion/rules_angular.git", ) diff --git a/MODULE.bazel.lock b/MODULE.bazel.lock index d616eea2d7cd..6f5d406a120b 100644 --- a/MODULE.bazel.lock +++ b/MODULE.bazel.lock @@ -29,7 +29,8 @@ "https://bcr.bazel.build/modules/aspect_rules_js/2.4.2/MODULE.bazel": "0d01db38b96d25df7ed952a5e96eac4b3802723d146961974bf020f6dd07591d", "https://bcr.bazel.build/modules/aspect_rules_js/2.6.2/MODULE.bazel": "ed2a871f4ab8fbde0cab67c425745069d84ea64b64313fa1a2954017326511f5", "https://bcr.bazel.build/modules/aspect_rules_js/2.8.1/MODULE.bazel": "edcde75a1357952d3acedb6f3622614c87f730927d753af77b36c604ff407f0d", - "https://bcr.bazel.build/modules/aspect_rules_js/2.8.1/source.json": "6da210e9e76eda699f9ca998a6f6c48980f78589f0f6d240842de6cef96543ce", + "https://bcr.bazel.build/modules/aspect_rules_js/2.8.2/MODULE.bazel": "76526405d6a65dae45db16b8b4619b502063ac573d2a2ae0a90fddc7d3247288", + "https://bcr.bazel.build/modules/aspect_rules_js/2.8.2/source.json": "a03164e3f59a05d9a6d205a477ea49ba8ee141ab764a9f38b43e6302eb4fa2b9", "https://bcr.bazel.build/modules/aspect_rules_ts/3.6.3/MODULE.bazel": "d09db394970f076176ce7bab5b5fa7f0d560fd4f30b8432ea5e2c2570505b130", "https://bcr.bazel.build/modules/aspect_rules_ts/3.7.0/MODULE.bazel": "5aace216caf88638950ef061245d23c36f57c8359e56e97f02a36f70bb09c50f", "https://bcr.bazel.build/modules/aspect_rules_ts/3.7.1/MODULE.bazel": "cbed416847e2c46c4c0fe275e3a3c8e302d236d0fb04a094e9af82d14e7c5040", @@ -210,7 +211,7 @@ "moduleExtensions": { "@@aspect_rules_esbuild~//esbuild:extensions.bzl%esbuild": { "general": { - "bzlTransitiveDigest": "GraoR12PYCcA5bpasvNm9vmnBGp+8JXnCK4y7D5+qkg=", + "bzlTransitiveDigest": "Kp1ElwnSsU9URW4hnpM9wzhITxGUNAp4tu7dOwA82Qo=", "usagesDigest": "w3kRc6iou9hC6M+vwECvdfk0P8nsVNjHSl4Ftru44zU=", "recordedFileInputs": {}, "recordedDirentsInputs": {}, @@ -414,8 +415,8 @@ }, "@@aspect_rules_js~//npm:extensions.bzl%pnpm": { "general": { - "bzlTransitiveDigest": "AhiDaIgaI2cWTIbzA5ZbR/OmQSUpMCFEhsCzil+lwW4=", - "usagesDigest": "J526kdgX5AQ2bYrNGwe6lTrakPUSZPfyHG24PGMUG0s=", + "bzlTransitiveDigest": "b2732vQWZpf2g1U6Rf2M0kXVkyN5QVnEn69W2+zHZPQ=", + "usagesDigest": "aGI0J/oETkNLCXhrpWEDlZEAKB8hs563suxOHlpcTj0=", "recordedFileInputs": {}, "recordedDirentsInputs": {}, "envVariables": {}, @@ -636,7 +637,7 @@ "@@aspect_tools_telemetry~//:extension.bzl%telemetry": { "general": { "bzlTransitiveDigest": "gA7tPEdJXhskzPIEUxjX9IdDrM6+WjfbgXJ8Ez47umk=", - "usagesDigest": "SMpx40jPXDQGAklWybhmgSAy5HdV4ZEIYFMuHxifgT0=", + "usagesDigest": "nyE85/XALFsAElY+d7H265tevR5W40tapQPfhmeIU2E=", "recordedFileInputs": {}, "recordedDirentsInputs": {}, "envVariables": {}, @@ -646,7 +647,7 @@ "ruleClassName": "tel_repository", "attributes": { "deps": { - "aspect_rules_js": "2.8.1", + "aspect_rules_js": "2.8.2", "aspect_rules_ts": "3.7.1", "aspect_rules_esbuild": "0.24.0", "aspect_tools_telemetry": "0.2.8" @@ -1150,7 +1151,7 @@ "@@rules_nodejs~//nodejs:extensions.bzl%node": { "general": { "bzlTransitiveDigest": "NwcLXHrbh2hoorA/Ybmcpjxsn/6avQmewDglodkDrgo=", - "usagesDigest": "6u/wPA8vJI6qkxtlJXv2v5SKQPZ1GrCSLH9fuOW/ay8=", + "usagesDigest": "R8gkuknFYSnypceao7XEOC2RaBVFY7V5K0xvOZHUZyY=", "recordedFileInputs": {}, "recordedDirentsInputs": {}, "envVariables": {}, From 3395fb062fc93258a05febaeca7b630d12b28ff9 Mon Sep 17 00:00:00 2001 From: Doug Parker Date: Fri, 21 Nov 2025 09:22:25 -0800 Subject: [PATCH 38/54] Revert "fix(@schematics/angular): add MCP configuration file to new workspaces" This reverts commit 7a52e3c4946206858587208c2e2f5c575697efe9. This is a feature and modifies `ng new` output which should be limited to minor or major releases, not patch releases. --- .../angular/workspace/files/__dot__gitignore.template | 1 - .../workspace/files/__dot__vscode/mcp.json.template | 9 --------- packages/schematics/angular/workspace/index_spec.ts | 2 -- 3 files changed, 12 deletions(-) delete mode 100644 packages/schematics/angular/workspace/files/__dot__vscode/mcp.json.template diff --git a/packages/schematics/angular/workspace/files/__dot__gitignore.template b/packages/schematics/angular/workspace/files/__dot__gitignore.template index 854acd5fc039..b1d225e26e57 100644 --- a/packages/schematics/angular/workspace/files/__dot__gitignore.template +++ b/packages/schematics/angular/workspace/files/__dot__gitignore.template @@ -26,7 +26,6 @@ yarn-error.log !.vscode/tasks.json !.vscode/launch.json !.vscode/extensions.json -!.vscode/mcp.json .history/* # Miscellaneous diff --git a/packages/schematics/angular/workspace/files/__dot__vscode/mcp.json.template b/packages/schematics/angular/workspace/files/__dot__vscode/mcp.json.template deleted file mode 100644 index bf4004da9477..000000000000 --- a/packages/schematics/angular/workspace/files/__dot__vscode/mcp.json.template +++ /dev/null @@ -1,9 +0,0 @@ -{ - // For more information, visit: https://angular.dev/ai/mcp - "mcpServers": { - "angular-cli": { - "command": "npx", - "args": ["-y", "@angular/cli", "mcp"] - } - } -} diff --git a/packages/schematics/angular/workspace/index_spec.ts b/packages/schematics/angular/workspace/index_spec.ts index 65dd7987aa41..22be6e797e14 100644 --- a/packages/schematics/angular/workspace/index_spec.ts +++ b/packages/schematics/angular/workspace/index_spec.ts @@ -29,7 +29,6 @@ describe('Workspace Schematic', () => { jasmine.arrayContaining([ '/.vscode/extensions.json', '/.vscode/launch.json', - '/.vscode/mcp.json', '/.vscode/tasks.json', '/.editorconfig', '/angular.json', @@ -71,7 +70,6 @@ describe('Workspace Schematic', () => { jasmine.arrayContaining([ '/.vscode/extensions.json', '/.vscode/launch.json', - '/.vscode/mcp.json', '/.vscode/tasks.json', '/angular.json', '/.gitignore', From 03e231216d3b8ba0de81da53a446eff0c701658d Mon Sep 17 00:00:00 2001 From: Alan Agius <17563226+alan-agius4@users.noreply.github.com> Date: Fri, 21 Nov 2025 09:40:33 +0000 Subject: [PATCH 39/54] fix(@angular/ssr): handle `X-Forwarded-Prefix` and `APP_BASE_HREF` in redirects This commit ensures that redirects correctly account for the X-Forwarded-Prefix header and APP_BASE_HREF, preventing incorrect redirect loops or invalid URLs when running behind a proxy or with a base href. Closes #31902 (cherry picked from commit 4dac5f25106162d9cbf20ec2bf4fe02c47409c41) --- packages/angular/ssr/src/app.ts | 9 +++- packages/angular/ssr/src/utils/ng.ts | 32 +++++++++--- packages/angular/ssr/test/app-engine_spec.ts | 14 ----- packages/angular/ssr/test/app_spec.ts | 55 +++++++++++++++++++- 4 files changed, 87 insertions(+), 23 deletions(-) diff --git a/packages/angular/ssr/src/app.ts b/packages/angular/ssr/src/app.ts index 4895866d715b..ee14f8a26105 100644 --- a/packages/angular/ssr/src/app.ts +++ b/packages/angular/ssr/src/app.ts @@ -175,8 +175,15 @@ export class AngularServerApp { } const { redirectTo, status, renderMode } = matchedRoute; + if (redirectTo !== undefined) { - return createRedirectResponse(buildPathWithParams(redirectTo, url.pathname), status); + return createRedirectResponse( + joinUrlParts( + request.headers.get('X-Forwarded-Prefix') ?? '', + buildPathWithParams(redirectTo, url.pathname), + ), + status, + ); } if (renderMode === RenderMode.Prerender) { diff --git a/packages/angular/ssr/src/utils/ng.ts b/packages/angular/ssr/src/utils/ng.ts index 5d10560db39d..16e059e6aaf2 100644 --- a/packages/angular/ssr/src/utils/ng.ts +++ b/packages/angular/ssr/src/utils/ng.ts @@ -6,10 +6,11 @@ * found in the LICENSE file at https://angular.dev/license */ -import { PlatformLocation } from '@angular/common'; +import { APP_BASE_HREF, PlatformLocation } from '@angular/common'; import { ApplicationRef, type PlatformRef, + REQUEST, type StaticProvider, type Type, ɵConsole, @@ -23,7 +24,7 @@ import { } from '@angular/platform-server'; import { ActivatedRoute, Router } from '@angular/router'; import { Console } from '../console'; -import { stripIndexHtmlFromURL, stripTrailingSlash } from './url'; +import { addTrailingSlash, joinUrlParts, stripIndexHtmlFromURL, stripTrailingSlash } from './url'; /** * Represents the bootstrap mechanism for an Angular application. @@ -110,9 +111,13 @@ export async function renderAngular( } else if (lastSuccessfulNavigation?.finalUrl) { hasNavigationError = false; + const requestPrefix = + envInjector.get(APP_BASE_HREF, null, { optional: true }) ?? + envInjector.get(REQUEST, null, { optional: true })?.headers.get('X-Forwarded-Prefix'); + const { pathname, search, hash } = envInjector.get(PlatformLocation); - const finalUrl = constructDecodedUrl({ pathname, search, hash }); - const urlToRenderString = constructDecodedUrl(urlToRender); + const finalUrl = constructDecodedUrl({ pathname, search, hash }, requestPrefix); + const urlToRenderString = constructDecodedUrl(urlToRender, requestPrefix); if (urlToRenderString !== finalUrl) { redirectTo = [pathname, search, hash].join(''); @@ -186,10 +191,23 @@ function asyncDestroyPlatform(platformRef: PlatformRef): Promise { * - `pathname`: The path of the URL. * - `search`: The query string of the URL (including '?'). * - `hash`: The hash fragment of the URL (including '#'). + * @param prefix - An optional prefix (e.g., `APP_BASE_HREF`) to prepend to the pathname + * if it is not already present. * @returns The constructed and decoded URL string. */ -function constructDecodedUrl(url: { pathname: string; search: string; hash: string }): string { - const joinedUrl = [stripTrailingSlash(url.pathname), url.search, url.hash].join(''); +function constructDecodedUrl( + url: { pathname: string; search: string; hash: string }, + prefix?: string | null, +): string { + const { pathname, hash, search } = url; + const urlParts: string[] = []; + if (prefix && !addTrailingSlash(pathname).startsWith(addTrailingSlash(prefix))) { + urlParts.push(joinUrlParts(prefix, pathname)); + } else { + urlParts.push(stripTrailingSlash(pathname)); + } + + urlParts.push(search, hash); - return decodeURIComponent(joinedUrl); + return decodeURIComponent(urlParts.join('')); } diff --git a/packages/angular/ssr/test/app-engine_spec.ts b/packages/angular/ssr/test/app-engine_spec.ts index bfc824b6d260..b08931b9400b 100644 --- a/packages/angular/ssr/test/app-engine_spec.ts +++ b/packages/angular/ssr/test/app-engine_spec.ts @@ -269,19 +269,5 @@ describe('AngularAppEngine', () => { const response = await appEngine.handle(request); expect(await response?.text()).toContain('Home works'); }); - - it('should work with encoded characters', async () => { - const request = new Request('https://example.com/home?email=xyz%40xyz.com'); - const response = await appEngine.handle(request); - expect(response?.status).toBe(200); - expect(await response?.text()).toContain('Home works'); - }); - - it('should work with decoded characters', async () => { - const request = new Request('https://example.com/home?email=xyz@xyz.com'); - const response = await appEngine.handle(request); - expect(response?.status).toBe(200); - expect(await response?.text()).toContain('Home works'); - }); }); }); diff --git a/packages/angular/ssr/test/app_spec.ts b/packages/angular/ssr/test/app_spec.ts index f85d4700329f..46b7cebc4e8a 100644 --- a/packages/angular/ssr/test/app_spec.ts +++ b/packages/angular/ssr/test/app_spec.ts @@ -11,7 +11,8 @@ import '@angular/compiler'; /* eslint-enable import/no-unassigned-import */ -import { Component, inject } from '@angular/core'; +import { APP_BASE_HREF } from '@angular/common'; +import { Component, REQUEST, inject } from '@angular/core'; import { CanActivateFn, Router } from '@angular/router'; import { AngularServerApp } from '../src/app'; import { RenderMode } from '../src/routes/route-config'; @@ -124,6 +125,14 @@ describe('AngularServerApp', () => { hash: 'f799132d0a09e0fef93c68a12e443527700eb59e6f67fcb7854c3a60ff082fde', }, }, + undefined, + undefined, + [ + { + provide: APP_BASE_HREF, + useFactory: () => inject(REQUEST)?.headers.get('X-Forwarded-Prefix'), + }, + ], ); app = new AngularServerApp(); @@ -309,6 +318,50 @@ describe('AngularServerApp', () => { expect(response?.headers.get('location')).toBe('/redirect-via-guard?filter=test'); expect(response?.status).toBe(302); }); + + it('should work with encoded characters', async () => { + const request = new Request('http://localhost/home?email=xyz%40xyz.com'); + const response = await app.handle(request); + expect(response?.status).toBe(200); + expect(await response?.text()).toContain('Home works'); + }); + + it('should work with decoded characters', async () => { + const request = new Request('http://localhost/home?email=xyz@xyz.com'); + const response = await app.handle(request); + expect(response?.status).toBe(200); + expect(await response?.text()).toContain('Home works'); + }); + + describe('APP_BASE_HREF / X-Forwarded-Prefix', () => { + const headers = new Headers({ 'X-Forwarded-Prefix': '/base/' }); + + it('should return a rendered page for known paths', async () => { + const request = new Request('https://example.com/home', { headers }); + const response = await app.handle(request); + expect(await response?.text()).toContain('Home works'); + }); + + it('returns a 302 status and redirects to the correct location when `redirectTo` is a function', async () => { + const response = await app.handle( + new Request('http://localhost/redirect-to-function', { + headers, + }), + ); + expect(response?.headers.get('location')).toBe('/base/home'); + expect(response?.status).toBe(302); + }); + + it('returns a 302 status and redirects to the correct location when `redirectTo` is a string', async () => { + const response = await app.handle( + new Request('http://localhost/redirect', { + headers, + }), + ); + expect(response?.headers.get('location')).toBe('/base/home'); + expect(response?.status).toBe(302); + }); + }); }); }); }); From afac5e753739933626c72ddc1e75db8bc11f182f Mon Sep 17 00:00:00 2001 From: Alan Agius <17563226+alan-agius4@users.noreply.github.com> Date: Mon, 24 Nov 2025 13:12:51 +0000 Subject: [PATCH 40/54] refactor: simplify dynamic import type assertions and remove resolution mode hints Remove `any` castings (cherry picked from commit 89a6caeb13e84d6531fb0584f8235a1b800411ae) --- .../build/src/tools/vite/middlewares/ssr-middleware.ts | 6 ++---- .../build/src/utils/server-rendering/launch-server.ts | 3 +-- packages/angular/cli/src/command-builder/command-module.ts | 3 +-- 3 files changed, 4 insertions(+), 8 deletions(-) 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 9719fc6b7482..4b0a8d8390f1 100644 --- a/packages/angular/build/src/tools/vite/middlewares/ssr-middleware.ts +++ b/packages/angular/build/src/tools/vite/middlewares/ssr-middleware.ts @@ -37,8 +37,7 @@ export function createAngularSsrInternalMiddleware( // which must be processed by the runtime linker, even if they are not used. await import('@angular/compiler'); const { writeResponseToNodeResponse, createWebRequestFromNodeRequest } = (await import( - // eslint-disable-next-line @typescript-eslint/no-explicit-any - '@angular/ssr/node' as any + '@angular/ssr/node' as string )) as typeof import('@angular/ssr/node', { with: { 'resolution-mode': 'import' } }); const { ɵgetOrCreateAngularServerApp } = (await server.ssrLoadModule('/main.server.mjs')) as { @@ -88,8 +87,7 @@ export async function createAngularSsrExternalMiddleware( await import('@angular/compiler'); const { createWebRequestFromNodeRequest, writeResponseToNodeResponse } = (await import( - // eslint-disable-next-line @typescript-eslint/no-explicit-any - '@angular/ssr/node' as any + '@angular/ssr/node' as string )) as typeof import('@angular/ssr/node', { with: { 'resolution-mode': 'import' } }); return function angularSsrExternalMiddleware( diff --git a/packages/angular/build/src/utils/server-rendering/launch-server.ts b/packages/angular/build/src/utils/server-rendering/launch-server.ts index c17337178b13..95b2784c6f63 100644 --- a/packages/angular/build/src/utils/server-rendering/launch-server.ts +++ b/packages/angular/build/src/utils/server-rendering/launch-server.ts @@ -21,8 +21,7 @@ export const DEFAULT_URL = new URL('http://ng-localhost/'); export async function launchServer(): Promise { const { reqHandler } = await loadEsmModuleFromMemory('./server.mjs'); const { createWebRequestFromNodeRequest, writeResponseToNodeResponse } = (await import( - // eslint-disable-next-line @typescript-eslint/no-explicit-any - '@angular/ssr/node' as any + '@angular/ssr/node' as string )) as typeof import('@angular/ssr/node', { with: { 'resolution-mode': 'import' } }); if (!isSsrNodeRequestHandler(reqHandler) && !isSsrRequestHandler(reqHandler)) { diff --git a/packages/angular/cli/src/command-builder/command-module.ts b/packages/angular/cli/src/command-builder/command-module.ts index 64f7ac7377c7..d036656cf2dd 100644 --- a/packages/angular/cli/src/command-builder/command-module.ts +++ b/packages/angular/cli/src/command-builder/command-module.ts @@ -14,8 +14,7 @@ import type { Argv, CamelCaseKey, CommandModule as YargsCommandModule, - // Resolution mode is required due to CamelCaseKey missing from esm types -} from 'yargs' with { 'resolution-mode': 'require' }; +} from 'yargs'; import { Parser as yargsParser } from 'yargs/helpers'; import { getAnalyticsUserId } from '../analytics/analytics'; import { AnalyticsCollector } from '../analytics/analytics-collector'; From 4a71e06fcafaadbcb820d285c0c186aa0e92f158 Mon Sep 17 00:00:00 2001 From: deku-nattsu Date: Fri, 21 Nov 2025 16:40:44 +0100 Subject: [PATCH 41/54] fix(@schematics/angular): silently skip when the build target already uses one of the new builders (cherry picked from commit cacd5d9359a3b71cc340353c57543598422b6fa4) --- .../angular/migrations/use-application-builder/migration.ts | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/packages/schematics/angular/migrations/use-application-builder/migration.ts b/packages/schematics/angular/migrations/use-application-builder/migration.ts index 9e8c9204d67f..b481c4f30034 100644 --- a/packages/schematics/angular/migrations/use-application-builder/migration.ts +++ b/packages/schematics/angular/migrations/use-application-builder/migration.ts @@ -174,7 +174,11 @@ function updateProjects(tree: Tree, context: SchematicContext) { } const buildTarget = project.targets.get('build'); - if (!buildTarget || buildTarget.builder === Builders.Application) { + if ( + !buildTarget || + buildTarget.builder === Builders.Application || + buildTarget.builder === Builders.BuildApplication + ) { continue; } From 2f58705cb5389019ceb49616a0e4ec3f92a558ed Mon Sep 17 00:00:00 2001 From: cexbrayat Date: Sat, 22 Nov 2025 13:24:27 +0100 Subject: [PATCH 42/54] fix(@schematics/angular): add missing imports for lifecycle hooks in jasmine-vitest migration (cherry picked from commit 43d5dfaa144b80f4292e4a57a79a4b872166fda2) --- .../jasmine-vitest/test-file-transformer.ts | 15 +++++++- .../test-file-transformer_add-imports_spec.ts | 36 +++++++++++++++++++ 2 files changed, 50 insertions(+), 1 deletion(-) diff --git a/packages/schematics/angular/refactor/jasmine-vitest/test-file-transformer.ts b/packages/schematics/angular/refactor/jasmine-vitest/test-file-transformer.ts index eb8afdfe0449..79f4ee2cfc9a 100644 --- a/packages/schematics/angular/refactor/jasmine-vitest/test-file-transformer.ts +++ b/packages/schematics/angular/refactor/jasmine-vitest/test-file-transformer.ts @@ -56,6 +56,19 @@ import { RefactorReporter } from './utils/refactor-reporter'; */ const BLANK_LINE_PLACEHOLDER = '// __PRESERVE_BLANK_LINE__'; +/** + * Vitest function names that should be imported when using the --add-imports option. + */ +const VITEST_FUNCTION_NAMES = new Set([ + 'describe', + 'it', + 'expect', + 'beforeEach', + 'afterEach', + 'beforeAll', + 'afterAll', +]); + /** * Replaces blank lines in the content with a placeholder to prevent TypeScript's printer * from removing them. This ensures that the original formatting of blank lines is preserved. @@ -183,7 +196,7 @@ export function transformJasmineToVitest( if (ts.isCallExpression(transformedNode)) { if (options.addImports && ts.isIdentifier(transformedNode.expression)) { const name = transformedNode.expression.text; - if (name === 'describe' || name === 'it' || name === 'expect') { + if (VITEST_FUNCTION_NAMES.has(name)) { addVitestValueImport(pendingVitestValueImports, name); } } diff --git a/packages/schematics/angular/refactor/jasmine-vitest/test-file-transformer_add-imports_spec.ts b/packages/schematics/angular/refactor/jasmine-vitest/test-file-transformer_add-imports_spec.ts index fac88bb9ed02..1fd4beb6546e 100644 --- a/packages/schematics/angular/refactor/jasmine-vitest/test-file-transformer_add-imports_spec.ts +++ b/packages/schematics/angular/refactor/jasmine-vitest/test-file-transformer_add-imports_spec.ts @@ -81,5 +81,41 @@ describe('Jasmine to Vitest Transformer', () => { `; await expectTransformation(input, expected, true); }); + + it('should add imports for beforeEach and afterEach when addImports is true', async () => { + const input = ` + describe('My Suite', () => { + beforeEach(() => {}); + afterEach(() => {}); + }); + `; + const expected = ` + import { afterEach, beforeEach, describe } from 'vitest'; + + describe('My Suite', () => { + beforeEach(() => {}); + afterEach(() => {}); + }); + `; + await expectTransformation(input, expected, true); + }); + + it('should add imports for beforeAll and afterAll when addImports is true', async () => { + const input = ` + describe('My Suite', () => { + beforeAll(() => {}); + afterAll(() => {}); + }); + `; + const expected = ` + import { afterAll, beforeAll, describe } from 'vitest'; + + describe('My Suite', () => { + beforeAll(() => {}); + afterAll(() => {}); + }); + `; + await expectTransformation(input, expected, true); + }); }); }); From 9c0b89dd3a31b23936866528f378edc17865dea4 Mon Sep 17 00:00:00 2001 From: deku-nattsu Date: Fri, 21 Nov 2025 17:03:22 +0100 Subject: [PATCH 43/54] refactor(@angular/build): update private exports to expose DiagnosticModes (cherry picked from commit 98636b2903b7bbc68562c4b22c3503b85c512a4f) --- packages/angular/build/src/private.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/angular/build/src/private.ts b/packages/angular/build/src/private.ts index 8012ad7f567a..175dd39530ae 100644 --- a/packages/angular/build/src/private.ts +++ b/packages/angular/build/src/private.ts @@ -61,6 +61,7 @@ export function createCompilerPlugin( } export type { AngularCompilation } from './tools/angular/compilation'; +export { DiagnosticModes } from './tools/angular/compilation'; export { createAngularCompilation }; export { ComponentStylesheetBundler } from './tools/esbuild/angular/component-stylesheets'; From 16d898e7587036d68786cebe764da08304559d41 Mon Sep 17 00:00:00 2001 From: jnizet Date: Sat, 22 Nov 2025 17:34:30 +0100 Subject: [PATCH 44/54] fix(@schematics/angular): fix migration of `jasmine.clock().mockDate()` The migration previously migrated `jasmine.clock().mockDate()` to `vi.setSystemTime()`, which does not compile because `vi.setSystemTime()` requires an argument. This commit fixes it by migrating `jasmine.clock().mockDate()` to `vi.setSystemTime(new Date())`. (cherry picked from commit 32da5a86f597db4823b8b28fe4c27f350840f05d) --- .../jasmine-vitest/transformers/jasmine-misc.ts | 10 +++++++++- .../jasmine-vitest/transformers/jasmine-misc_spec.ts | 5 +++++ 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/packages/schematics/angular/refactor/jasmine-vitest/transformers/jasmine-misc.ts b/packages/schematics/angular/refactor/jasmine-vitest/transformers/jasmine-misc.ts index f9667701e376..058d015c9773 100644 --- a/packages/schematics/angular/refactor/jasmine-vitest/transformers/jasmine-misc.ts +++ b/packages/schematics/angular/refactor/jasmine-vitest/transformers/jasmine-misc.ts @@ -61,7 +61,15 @@ export function transformTimerMocks( node, `Transformed \`jasmine.clock().${pae.name.text}\` to \`vi.${newMethodName}\`.`, ); - const newArgs = newMethodName === 'useFakeTimers' ? [] : node.arguments; + let newArgs: readonly ts.Expression[] = node.arguments; + if (newMethodName === 'useFakeTimers') { + newArgs = []; + } + if (newMethodName === 'setSystemTime' && node.arguments.length === 0) { + newArgs = [ + ts.factory.createNewExpression(ts.factory.createIdentifier('Date'), undefined, []), + ]; + } return createViCallExpression(newMethodName, newArgs); } diff --git a/packages/schematics/angular/refactor/jasmine-vitest/transformers/jasmine-misc_spec.ts b/packages/schematics/angular/refactor/jasmine-vitest/transformers/jasmine-misc_spec.ts index 5095a4448db7..4684f7f69d2d 100644 --- a/packages/schematics/angular/refactor/jasmine-vitest/transformers/jasmine-misc_spec.ts +++ b/packages/schematics/angular/refactor/jasmine-vitest/transformers/jasmine-misc_spec.ts @@ -31,6 +31,11 @@ describe('Jasmine to Vitest Transformer', () => { input: `jasmine.clock().mockDate(new Date('2025-01-01'));`, expected: `vi.setSystemTime(new Date('2025-01-01'));`, }, + { + description: 'should transform jasmine.clock().mockDate() to vi.setSystemTime(new Date())', + input: `jasmine.clock().mockDate();`, + expected: `vi.setSystemTime(new Date());`, + }, ]; testCases.forEach(({ description, input, expected }) => { From 7222b5433a49e102ecc8b6305e266a235f8ede78 Mon Sep 17 00:00:00 2001 From: reins-ch Date: Fri, 21 Nov 2025 23:58:57 +0100 Subject: [PATCH 45/54] docs: mention Vitest instead of Karma in README template of workspace files Since version Angular 21, Vitest is the default test runner. (cherry picked from commit ff519b8ebe32f62e2291309f03b8f672b64e6a0b) --- packages/schematics/angular/workspace/files/README.md.template | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/schematics/angular/workspace/files/README.md.template b/packages/schematics/angular/workspace/files/README.md.template index 85cba41ab1ea..3cf62f4dabcc 100644 --- a/packages/schematics/angular/workspace/files/README.md.template +++ b/packages/schematics/angular/workspace/files/README.md.template @@ -38,7 +38,7 @@ This will compile your project and store the build artifacts in the `dist/` dire ## Running unit tests -To execute unit tests with the [Karma](https://karma-runner.github.io) test runner, use the following command: +To execute unit tests with the [Vitest](https://vitest.dev/) test runner, use the following command: ```bash ng test From 21c3eac726c198132af760ffacc0dab9dfccb430 Mon Sep 17 00:00:00 2001 From: jase88 <804836+jase88@users.noreply.github.com> Date: Tue, 25 Nov 2025 14:11:00 +0100 Subject: [PATCH 46/54] fix(@schematics/angular): handle createSpyObj without base name on refactor-jasmine-vitest (cherry picked from commit 5ef8b9975013733ea64deeec945bc77988191b0c) --- .../transformers/jasmine-spy.ts | 11 +++---- .../transformers/jasmine-spy_spec.ts | 29 ++++++++++++++++++- 2 files changed, 34 insertions(+), 6 deletions(-) diff --git a/packages/schematics/angular/refactor/jasmine-vitest/transformers/jasmine-spy.ts b/packages/schematics/angular/refactor/jasmine-vitest/transformers/jasmine-spy.ts index c10fc739f9af..39c5802ea1dc 100644 --- a/packages/schematics/angular/refactor/jasmine-vitest/transformers/jasmine-spy.ts +++ b/packages/schematics/angular/refactor/jasmine-vitest/transformers/jasmine-spy.ts @@ -227,13 +227,14 @@ export function transformCreateSpyObj( 'Transformed `jasmine.createSpyObj()` to an object literal with `vi.fn()`.', ); - const baseNameArg = node.arguments[0]; - const baseName = ts.isStringLiteral(baseNameArg) ? baseNameArg.text : undefined; - const methods = node.arguments[1]; - const propertiesArg = node.arguments[2]; + const firstArg = node.arguments[0]; + const hasBaseName = ts.isStringLiteral(firstArg); + const baseName = hasBaseName ? firstArg.text : undefined; + const methods = hasBaseName ? node.arguments[1] : firstArg; + const propertiesArg = hasBaseName ? node.arguments[2] : node.arguments[1]; let properties: ts.PropertyAssignment[] = []; - if (node.arguments.length < 2) { + if (node.arguments.length < 2 && hasBaseName) { const category = 'createSpyObj-single-argument'; reporter.recordTodo(category); addTodoComment(node, category); diff --git a/packages/schematics/angular/refactor/jasmine-vitest/transformers/jasmine-spy_spec.ts b/packages/schematics/angular/refactor/jasmine-vitest/transformers/jasmine-spy_spec.ts index 3fc98aa02601..06e26e606b5c 100644 --- a/packages/schematics/angular/refactor/jasmine-vitest/transformers/jasmine-spy_spec.ts +++ b/packages/schematics/angular/refactor/jasmine-vitest/transformers/jasmine-spy_spec.ts @@ -122,6 +122,15 @@ vi.spyOn(service, 'myMethod').and.unknownStrategy();`, methodB: vi.fn().mockName("MyService.methodB"), };`, }, + { + description: + 'should transform jasmine.createSpyObj with an array of methods without base name', + input: `const myService = jasmine.createSpyObj(['methodA', 'methodB']);`, + expected: `const myService = { + methodA: vi.fn(), + methodB: vi.fn(), + };`, + }, { description: 'should add a TODO if the second argument is not a literal', input: `const myService = jasmine.createSpyObj('MyService', methodNames);`, @@ -138,6 +147,15 @@ vi.spyOn(service, 'myMethod').and.unknownStrategy();`, methodB: vi.fn().mockName("MyService.methodB").mockReturnValue(42), };`, }, + { + description: + 'should transform jasmine.createSpyObj with an object of return values without base name', + input: `const myService = jasmine.createSpyObj({ methodA: 'foo', methodB: 42 });`, + expected: `const myService = { + methodA: vi.fn().mockReturnValue('foo'), + methodB: vi.fn().mockReturnValue(42), + };`, + }, { description: 'should transform jasmine.createSpyObj with an object of return values containing an asymmetric matcher', @@ -147,7 +165,7 @@ vi.spyOn(service, 'myMethod').and.unknownStrategy();`, };`, }, { - description: 'should add a TODO for jasmine.createSpyObj with only one argument', + description: 'should add a TODO for jasmine.createSpyObj with only base name argument', input: `const myService = jasmine.createSpyObj('MyService');`, expected: ` // TODO: vitest-migration: jasmine.createSpyObj called with a single argument is not supported for transformation. See: https://vitest.dev/api/vi.html#vi-fn @@ -170,6 +188,15 @@ vi.spyOn(service, 'myMethod').and.unknownStrategy();`, propA: 'valueA', };`, }, + { + description: + 'should transform jasmine.createSpyObj with a method map and a property map without base name', + input: `const myService = jasmine.createSpyObj({ methodA: 'foo' }, { propA: 'valueA' });`, + expected: `const myService = { + methodA: vi.fn().mockReturnValue('foo'), + propA: 'valueA', + };`, + }, { description: 'should ignore non-string literals in the method array', input: `const myService = jasmine.createSpyObj('MyService', ['methodA', 123, someVar]);`, From 30b96bdd818a48f496209925a0b3de883ad35250 Mon Sep 17 00:00:00 2001 From: Angular Robot Date: Tue, 25 Nov 2025 20:38:51 +0000 Subject: [PATCH 47/54] build: update dependency zone.js to ~0.16.0 See associated pull request for more information. --- .../schematics/angular/utility/latest-versions/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/schematics/angular/utility/latest-versions/package.json b/packages/schematics/angular/utility/latest-versions/package.json index 10f2cf8eb6bd..03db4d15a506 100644 --- a/packages/schematics/angular/utility/latest-versions/package.json +++ b/packages/schematics/angular/utility/latest-versions/package.json @@ -26,6 +26,6 @@ "ts-node": "~10.9.0", "typescript": "~5.9.2", "vitest": "^4.0.8", - "zone.js": "~0.15.0" + "zone.js": "~0.16.0" } } From 39ab18ce7dd2c1e0e336e20fa90909d14f9a9e52 Mon Sep 17 00:00:00 2001 From: Angular Robot Date: Tue, 25 Nov 2025 21:05:47 +0000 Subject: [PATCH 48/54] build: update cross-repo angular dependencies to v21.0.1 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 | 254 +++++++++++++------------- 4 files changed, 146 insertions(+), 146 deletions(-) diff --git a/package.json b/package.json index 937ad8e5dd35..29898c01d075 100644 --- a/package.json +++ b/package.json @@ -45,20 +45,20 @@ }, "homepage": "https://github.com/angular/angular-cli", "devDependencies": { - "@angular/animations": "21.0.0", + "@angular/animations": "21.0.1", "@angular/cdk": "21.0.0", - "@angular/common": "21.0.0", - "@angular/compiler": "21.0.0", - "@angular/compiler-cli": "21.0.0", - "@angular/core": "21.0.0", - "@angular/forms": "21.0.0", - "@angular/localize": "21.0.0", + "@angular/common": "21.0.1", + "@angular/compiler": "21.0.1", + "@angular/compiler-cli": "21.0.1", + "@angular/core": "21.0.1", + "@angular/forms": "21.0.1", + "@angular/localize": "21.0.1", "@angular/material": "21.0.0", "@angular/ng-dev": "https://github.com/angular/dev-infra-private-ng-dev-builds.git#e0bb3b2b000ff0c0c18a2020d5d42371bca51ecf", - "@angular/platform-browser": "21.0.0", - "@angular/platform-server": "21.0.0", - "@angular/router": "21.0.0", - "@angular/service-worker": "21.0.0", + "@angular/platform-browser": "21.0.1", + "@angular/platform-server": "21.0.1", + "@angular/router": "21.0.1", + "@angular/service-worker": "21.0.1", "@babel/core": "7.28.4", "@bazel/bazelisk": "1.26.0", "@bazel/buildifier": "8.2.1", diff --git a/packages/angular/ssr/package.json b/packages/angular/ssr/package.json index b97f9c2da6c8..53303cf9d412 100644 --- a/packages/angular/ssr/package.json +++ b/packages/angular/ssr/package.json @@ -29,12 +29,12 @@ }, "devDependencies": { "@angular-devkit/schematics": "workspace:*", - "@angular/common": "21.0.0", - "@angular/compiler": "21.0.0", - "@angular/core": "21.0.0", - "@angular/platform-browser": "21.0.0", - "@angular/platform-server": "21.0.0", - "@angular/router": "21.0.0", + "@angular/common": "21.0.1", + "@angular/compiler": "21.0.1", + "@angular/core": "21.0.1", + "@angular/platform-browser": "21.0.1", + "@angular/platform-server": "21.0.1", + "@angular/router": "21.0.1", "@schematics/angular": "workspace:*", "beasties": "0.3.5" }, diff --git a/packages/ngtools/webpack/package.json b/packages/ngtools/webpack/package.json index 43de41bf8cf3..7febec4638b5 100644 --- a/packages/ngtools/webpack/package.json +++ b/packages/ngtools/webpack/package.json @@ -27,8 +27,8 @@ }, "devDependencies": { "@angular-devkit/core": "workspace:0.0.0-PLACEHOLDER", - "@angular/compiler": "21.0.0", - "@angular/compiler-cli": "21.0.0", + "@angular/compiler": "21.0.1", + "@angular/compiler-cli": "21.0.1", "typescript": "5.9.3", "webpack": "5.102.1" } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 1174da611b91..1424bbe085c5 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -20,47 +20,47 @@ importers: built: true devDependencies: '@angular/animations': - specifier: 21.0.0 - version: 21.0.0(@angular/core@21.0.0(@angular/compiler@21.0.0)(rxjs@7.8.2)(zone.js@0.15.1)) + specifier: 21.0.1 + version: 21.0.1(@angular/core@21.0.1(@angular/compiler@21.0.1)(rxjs@7.8.2)(zone.js@0.15.1)) '@angular/cdk': specifier: 21.0.0 - version: 21.0.0(@angular/common@21.0.0(@angular/core@21.0.0(@angular/compiler@21.0.0)(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/core@21.0.0(@angular/compiler@21.0.0)(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2) + version: 21.0.0(@angular/common@21.0.1(@angular/core@21.0.1(@angular/compiler@21.0.1)(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/core@21.0.1(@angular/compiler@21.0.1)(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2) '@angular/common': - specifier: 21.0.0 - version: 21.0.0(@angular/core@21.0.0(@angular/compiler@21.0.0)(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2) + specifier: 21.0.1 + version: 21.0.1(@angular/core@21.0.1(@angular/compiler@21.0.1)(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2) '@angular/compiler': - specifier: 21.0.0 - version: 21.0.0 + specifier: 21.0.1 + version: 21.0.1 '@angular/compiler-cli': - specifier: 21.0.0 - version: 21.0.0(@angular/compiler@21.0.0)(typescript@5.9.3) + specifier: 21.0.1 + version: 21.0.1(@angular/compiler@21.0.1)(typescript@5.9.3) '@angular/core': - specifier: 21.0.0 - version: 21.0.0(@angular/compiler@21.0.0)(rxjs@7.8.2)(zone.js@0.15.1) + specifier: 21.0.1 + version: 21.0.1(@angular/compiler@21.0.1)(rxjs@7.8.2)(zone.js@0.15.1) '@angular/forms': - specifier: 21.0.0 - version: 21.0.0(@angular/common@21.0.0(@angular/core@21.0.0(@angular/compiler@21.0.0)(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/core@21.0.0(@angular/compiler@21.0.0)(rxjs@7.8.2)(zone.js@0.15.1))(@angular/platform-browser@21.0.0(@angular/animations@21.0.0(@angular/core@21.0.0(@angular/compiler@21.0.0)(rxjs@7.8.2)(zone.js@0.15.1)))(@angular/common@21.0.0(@angular/core@21.0.0(@angular/compiler@21.0.0)(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/core@21.0.0(@angular/compiler@21.0.0)(rxjs@7.8.2)(zone.js@0.15.1)))(@standard-schema/spec@1.0.0)(rxjs@7.8.2) + specifier: 21.0.1 + version: 21.0.1(@angular/common@21.0.1(@angular/core@21.0.1(@angular/compiler@21.0.1)(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/core@21.0.1(@angular/compiler@21.0.1)(rxjs@7.8.2)(zone.js@0.15.1))(@angular/platform-browser@21.0.1(@angular/animations@21.0.1(@angular/core@21.0.1(@angular/compiler@21.0.1)(rxjs@7.8.2)(zone.js@0.15.1)))(@angular/common@21.0.1(@angular/core@21.0.1(@angular/compiler@21.0.1)(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/core@21.0.1(@angular/compiler@21.0.1)(rxjs@7.8.2)(zone.js@0.15.1)))(@standard-schema/spec@1.0.0)(rxjs@7.8.2) '@angular/localize': - specifier: 21.0.0 - version: 21.0.0(@angular/compiler-cli@21.0.0(@angular/compiler@21.0.0)(typescript@5.9.3))(@angular/compiler@21.0.0) + specifier: 21.0.1 + version: 21.0.1(@angular/compiler-cli@21.0.1(@angular/compiler@21.0.1)(typescript@5.9.3))(@angular/compiler@21.0.1) '@angular/material': specifier: 21.0.0 - version: 21.0.0(280d15a59d7c55264f5164ad0fb0f648) + version: 21.0.0(8e7b236207d28338fccf527c5c162c22) '@angular/ng-dev': specifier: https://github.com/angular/dev-infra-private-ng-dev-builds.git#e0bb3b2b000ff0c0c18a2020d5d42371bca51ecf version: https://codeload.github.com/angular/dev-infra-private-ng-dev-builds/tar.gz/e0bb3b2b000ff0c0c18a2020d5d42371bca51ecf(@modelcontextprotocol/sdk@1.20.1) '@angular/platform-browser': - specifier: 21.0.0 - version: 21.0.0(@angular/animations@21.0.0(@angular/core@21.0.0(@angular/compiler@21.0.0)(rxjs@7.8.2)(zone.js@0.15.1)))(@angular/common@21.0.0(@angular/core@21.0.0(@angular/compiler@21.0.0)(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/core@21.0.0(@angular/compiler@21.0.0)(rxjs@7.8.2)(zone.js@0.15.1)) + specifier: 21.0.1 + version: 21.0.1(@angular/animations@21.0.1(@angular/core@21.0.1(@angular/compiler@21.0.1)(rxjs@7.8.2)(zone.js@0.15.1)))(@angular/common@21.0.1(@angular/core@21.0.1(@angular/compiler@21.0.1)(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/core@21.0.1(@angular/compiler@21.0.1)(rxjs@7.8.2)(zone.js@0.15.1)) '@angular/platform-server': - specifier: 21.0.0 - version: 21.0.0(@angular/common@21.0.0(@angular/core@21.0.0(@angular/compiler@21.0.0)(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/compiler@21.0.0)(@angular/core@21.0.0(@angular/compiler@21.0.0)(rxjs@7.8.2)(zone.js@0.15.1))(@angular/platform-browser@21.0.0(@angular/animations@21.0.0(@angular/core@21.0.0(@angular/compiler@21.0.0)(rxjs@7.8.2)(zone.js@0.15.1)))(@angular/common@21.0.0(@angular/core@21.0.0(@angular/compiler@21.0.0)(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/core@21.0.0(@angular/compiler@21.0.0)(rxjs@7.8.2)(zone.js@0.15.1)))(rxjs@7.8.2) + specifier: 21.0.1 + version: 21.0.1(@angular/common@21.0.1(@angular/core@21.0.1(@angular/compiler@21.0.1)(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/compiler@21.0.1)(@angular/core@21.0.1(@angular/compiler@21.0.1)(rxjs@7.8.2)(zone.js@0.15.1))(@angular/platform-browser@21.0.1(@angular/animations@21.0.1(@angular/core@21.0.1(@angular/compiler@21.0.1)(rxjs@7.8.2)(zone.js@0.15.1)))(@angular/common@21.0.1(@angular/core@21.0.1(@angular/compiler@21.0.1)(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/core@21.0.1(@angular/compiler@21.0.1)(rxjs@7.8.2)(zone.js@0.15.1)))(rxjs@7.8.2) '@angular/router': - specifier: 21.0.0 - version: 21.0.0(@angular/common@21.0.0(@angular/core@21.0.0(@angular/compiler@21.0.0)(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/core@21.0.0(@angular/compiler@21.0.0)(rxjs@7.8.2)(zone.js@0.15.1))(@angular/platform-browser@21.0.0(@angular/animations@21.0.0(@angular/core@21.0.0(@angular/compiler@21.0.0)(rxjs@7.8.2)(zone.js@0.15.1)))(@angular/common@21.0.0(@angular/core@21.0.0(@angular/compiler@21.0.0)(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/core@21.0.0(@angular/compiler@21.0.0)(rxjs@7.8.2)(zone.js@0.15.1)))(rxjs@7.8.2) + specifier: 21.0.1 + version: 21.0.1(@angular/common@21.0.1(@angular/core@21.0.1(@angular/compiler@21.0.1)(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/core@21.0.1(@angular/compiler@21.0.1)(rxjs@7.8.2)(zone.js@0.15.1))(@angular/platform-browser@21.0.1(@angular/animations@21.0.1(@angular/core@21.0.1(@angular/compiler@21.0.1)(rxjs@7.8.2)(zone.js@0.15.1)))(@angular/common@21.0.1(@angular/core@21.0.1(@angular/compiler@21.0.1)(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/core@21.0.1(@angular/compiler@21.0.1)(rxjs@7.8.2)(zone.js@0.15.1)))(rxjs@7.8.2) '@angular/service-worker': - specifier: 21.0.0 - version: 21.0.0(@angular/core@21.0.0(@angular/compiler@21.0.0)(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2) + specifier: 21.0.1 + version: 21.0.1(@angular/core@21.0.1(@angular/compiler@21.0.1)(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2) '@babel/core': specifier: 7.28.4 version: 7.28.4 @@ -445,7 +445,7 @@ importers: version: 4.4.2 ng-packagr: specifier: 21.0.0 - version: 21.0.0(@angular/compiler-cli@21.0.0(@angular/compiler@21.0.0)(typescript@5.9.3))(tslib@2.8.1)(typescript@5.9.3) + version: 21.0.0(@angular/compiler-cli@21.0.1(@angular/compiler@21.0.1)(typescript@5.9.3))(tslib@2.8.1)(typescript@5.9.3) postcss: specifier: 8.5.6 version: 8.5.6 @@ -542,23 +542,23 @@ importers: specifier: workspace:* version: link:../../angular_devkit/schematics '@angular/common': - specifier: 21.0.0 - version: 21.0.0(@angular/core@21.0.0(@angular/compiler@21.0.0)(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2) + specifier: 21.0.1 + version: 21.0.1(@angular/core@21.0.1(@angular/compiler@21.0.1)(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2) '@angular/compiler': - specifier: 21.0.0 - version: 21.0.0 + specifier: 21.0.1 + version: 21.0.1 '@angular/core': - specifier: 21.0.0 - version: 21.0.0(@angular/compiler@21.0.0)(rxjs@7.8.2)(zone.js@0.15.1) + specifier: 21.0.1 + version: 21.0.1(@angular/compiler@21.0.1)(rxjs@7.8.2)(zone.js@0.15.1) '@angular/platform-browser': - specifier: 21.0.0 - version: 21.0.0(@angular/animations@21.0.0(@angular/core@21.0.0(@angular/compiler@21.0.0)(rxjs@7.8.2)(zone.js@0.15.1)))(@angular/common@21.0.0(@angular/core@21.0.0(@angular/compiler@21.0.0)(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/core@21.0.0(@angular/compiler@21.0.0)(rxjs@7.8.2)(zone.js@0.15.1)) + specifier: 21.0.1 + version: 21.0.1(@angular/animations@21.0.1(@angular/core@21.0.1(@angular/compiler@21.0.1)(rxjs@7.8.2)(zone.js@0.15.1)))(@angular/common@21.0.1(@angular/core@21.0.1(@angular/compiler@21.0.1)(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/core@21.0.1(@angular/compiler@21.0.1)(rxjs@7.8.2)(zone.js@0.15.1)) '@angular/platform-server': - specifier: 21.0.0 - version: 21.0.0(@angular/common@21.0.0(@angular/core@21.0.0(@angular/compiler@21.0.0)(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/compiler@21.0.0)(@angular/core@21.0.0(@angular/compiler@21.0.0)(rxjs@7.8.2)(zone.js@0.15.1))(@angular/platform-browser@21.0.0(@angular/animations@21.0.0(@angular/core@21.0.0(@angular/compiler@21.0.0)(rxjs@7.8.2)(zone.js@0.15.1)))(@angular/common@21.0.0(@angular/core@21.0.0(@angular/compiler@21.0.0)(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/core@21.0.0(@angular/compiler@21.0.0)(rxjs@7.8.2)(zone.js@0.15.1)))(rxjs@7.8.2) + specifier: 21.0.1 + version: 21.0.1(@angular/common@21.0.1(@angular/core@21.0.1(@angular/compiler@21.0.1)(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/compiler@21.0.1)(@angular/core@21.0.1(@angular/compiler@21.0.1)(rxjs@7.8.2)(zone.js@0.15.1))(@angular/platform-browser@21.0.1(@angular/animations@21.0.1(@angular/core@21.0.1(@angular/compiler@21.0.1)(rxjs@7.8.2)(zone.js@0.15.1)))(@angular/common@21.0.1(@angular/core@21.0.1(@angular/compiler@21.0.1)(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/core@21.0.1(@angular/compiler@21.0.1)(rxjs@7.8.2)(zone.js@0.15.1)))(rxjs@7.8.2) '@angular/router': - specifier: 21.0.0 - version: 21.0.0(@angular/common@21.0.0(@angular/core@21.0.0(@angular/compiler@21.0.0)(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/core@21.0.0(@angular/compiler@21.0.0)(rxjs@7.8.2)(zone.js@0.15.1))(@angular/platform-browser@21.0.0(@angular/animations@21.0.0(@angular/core@21.0.0(@angular/compiler@21.0.0)(rxjs@7.8.2)(zone.js@0.15.1)))(@angular/common@21.0.0(@angular/core@21.0.0(@angular/compiler@21.0.0)(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/core@21.0.0(@angular/compiler@21.0.0)(rxjs@7.8.2)(zone.js@0.15.1)))(rxjs@7.8.2) + specifier: 21.0.1 + version: 21.0.1(@angular/common@21.0.1(@angular/core@21.0.1(@angular/compiler@21.0.1)(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/core@21.0.1(@angular/compiler@21.0.1)(rxjs@7.8.2)(zone.js@0.15.1))(@angular/platform-browser@21.0.1(@angular/animations@21.0.1(@angular/core@21.0.1(@angular/compiler@21.0.1)(rxjs@7.8.2)(zone.js@0.15.1)))(@angular/common@21.0.1(@angular/core@21.0.1(@angular/compiler@21.0.1)(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/core@21.0.1(@angular/compiler@21.0.1)(rxjs@7.8.2)(zone.js@0.15.1)))(rxjs@7.8.2) '@schematics/angular': specifier: workspace:* version: link:../../schematics/angular @@ -773,7 +773,7 @@ importers: version: 3.0.4(bufferutil@4.0.9)(utf-8-validate@6.0.5) ng-packagr: specifier: 21.0.0 - version: 21.0.0(@angular/compiler-cli@21.0.0(@angular/compiler@21.0.0)(typescript@5.9.3))(tslib@2.8.1)(typescript@5.9.3) + version: 21.0.0(@angular/compiler-cli@21.0.1(@angular/compiler@21.0.1)(typescript@5.9.3))(tslib@2.8.1)(typescript@5.9.3) undici: specifier: 7.16.0 version: 7.16.0 @@ -871,11 +871,11 @@ importers: specifier: workspace:0.0.0-PLACEHOLDER version: link:../../angular_devkit/core '@angular/compiler': - specifier: 21.0.0 - version: 21.0.0 + specifier: 21.0.1 + version: 21.0.1 '@angular/compiler-cli': - specifier: 21.0.0 - version: 21.0.0(@angular/compiler@21.0.0)(typescript@5.9.3) + specifier: 21.0.1 + version: 21.0.1(@angular/compiler@21.0.1)(typescript@5.9.3) typescript: specifier: 5.9.3 version: 5.9.3 @@ -984,11 +984,11 @@ packages: resolution: {integrity: sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==} engines: {node: '>=6.0.0'} - '@angular/animations@21.0.0': - resolution: {integrity: sha512-9AX4HFJmSP8SFNiweKNxasBzn3zbL3xRtwaUxw1I+x/WAzubm4ZziLnXqb+tai7C4UmwV+9XDlRVPfw5WxJ9zg==} + '@angular/animations@21.0.1': + resolution: {integrity: sha512-P7i/jpNnzXwo0vHEG0cDXYojwTz0WQlXJHrmOJzLVveyfcFwgXYXJxhGGUI2+k21YrlJTKkR/4QZTEJ0GP0f8Q==} engines: {node: ^20.19.0 || ^22.12.0 || >=24.0.0} peerDependencies: - '@angular/core': 21.0.0 + '@angular/core': 21.0.1 '@angular/cdk@21.0.0': resolution: {integrity: sha512-wCr5D3mEC+p69IMDC7vf8bWx18mfUNNRdsiK3XD0m1PqfeNfnCJb+Bnkks37MC/SU01uCNrAokRaTbWL6pk1Wg==} @@ -997,58 +997,58 @@ packages: '@angular/core': ^21.0.0 || ^22.0.0 rxjs: ^6.5.3 || ^7.4.0 - '@angular/common@21.0.0': - resolution: {integrity: sha512-uFvQDYU5X5nEnI9C4Bkdxcu4aIzNesGLJzmFlnwChVxB4BxIRF0uHL0oRhdkInGTIzPDJPH4nF6B/22c5gDVqA==} + '@angular/common@21.0.1': + resolution: {integrity: sha512-EqdTGpFp7PVdTVztO7TB6+QxdzUbYXKKT2jwG2Gg+PIQZ2A8XrLPRmGXyH/DLlc5IhnoJlLbngmBRCLCO4xWog==} engines: {node: ^20.19.0 || ^22.12.0 || >=24.0.0} peerDependencies: - '@angular/core': 21.0.0 + '@angular/core': 21.0.1 rxjs: ^6.5.3 || ^7.4.0 - '@angular/compiler-cli@21.0.0': - resolution: {integrity: sha512-KTXp+e2UPGyfFew6Wq95ULpHWQ20dhqkAMZ6x6MCYfOe2ccdnGYsAbLLmnWGmSg5BaOI4B0x/1XCFZf/n6WDgA==} + '@angular/compiler-cli@21.0.1': + resolution: {integrity: sha512-BxGLtL5bxlaaAs/kSN4oyXhMfvzqsj1Gc4Jauz39R4xtgOF5cIvjBtj6dJ9mD3PK0s6zaFi7WYd0YwWkxhjgMA==} engines: {node: ^20.19.0 || ^22.12.0 || >=24.0.0} hasBin: true peerDependencies: - '@angular/compiler': 21.0.0 + '@angular/compiler': 21.0.1 typescript: '>=5.9 <6.0' peerDependenciesMeta: typescript: optional: true - '@angular/compiler@21.0.0': - resolution: {integrity: sha512-6jCH3UYga5iokj5F40SR4dlwo9ZRMkT8YzHCTijwZuDX9zvugp9jPof092RvIeNsTvCMVfGWuM9yZ1DRUsU/yg==} + '@angular/compiler@21.0.1': + resolution: {integrity: sha512-YRzHpThgCaC9b3xzK1Wx859ePeHEPR7ewQklUB5TYbpzVacvnJo38PcSAx/nzOmgX9y4mgyros6LzECmBb8d8w==} engines: {node: ^20.19.0 || ^22.12.0 || >=24.0.0} - '@angular/core@21.0.0': - resolution: {integrity: sha512-bqi8fT4csyITeX8vdN5FJDBWx5wuWzdCg4mKSjHd+onVzZLyZ8bcnuAKz4mklgvjvwuXoRYukmclUurLwfq3Rg==} + '@angular/core@21.0.1': + resolution: {integrity: sha512-z0G9Bwzgqr0fQVbtMgqwl+SbbiqtJD7I2xT6U5p45LetKHojcfigH29dxi/vqALPwEdgb2nSIx7RqVhoyynraQ==} engines: {node: ^20.19.0 || ^22.12.0 || >=24.0.0} peerDependencies: - '@angular/compiler': 21.0.0 + '@angular/compiler': 21.0.1 rxjs: ^6.5.3 || ^7.4.0 - zone.js: ~0.15.0 + zone.js: ~0.15.0 || ~0.16.0 peerDependenciesMeta: '@angular/compiler': optional: true zone.js: optional: true - '@angular/forms@21.0.0': - resolution: {integrity: sha512-kcudwbZs/ddKqaELz4eEW9kOGCsX61qsf9jkQsGTARBEOUcU2K+rM6mX5sTf9azHvQ9wlX4N36h0eYzBA4Y4Qg==} + '@angular/forms@21.0.1': + resolution: {integrity: sha512-BVFPuKjxkzjzKMmpc6KxUKICpVs6J2/KzA4HjtPp/UKvdZPe8dj8vIXuc9pGf8DA4XdkjCwvv8szCgzTWi02LQ==} engines: {node: ^20.19.0 || ^22.12.0 || >=24.0.0} peerDependencies: - '@angular/common': 21.0.0 - '@angular/core': 21.0.0 - '@angular/platform-browser': 21.0.0 + '@angular/common': 21.0.1 + '@angular/core': 21.0.1 + '@angular/platform-browser': 21.0.1 '@standard-schema/spec': ^1.0.0 rxjs: ^6.5.3 || ^7.4.0 - '@angular/localize@21.0.0': - resolution: {integrity: sha512-SHK/D6nYkbn3VrM7sZtipiayICc8S6IZyjd4/5ARLeZJ/giYAxqv++bV0EV1MEayAZi4g6t0qsUY4KolDClphQ==} + '@angular/localize@21.0.1': + resolution: {integrity: sha512-ouzParJQEQO9cStBkIioyDkQ839eJaedSwNuNXK/MeTZ1NH+pDcvwgYH0Gcn5BTB7fZEY0oCXyBcVxyz37qTcA==} engines: {node: ^20.19.0 || ^22.12.0 || >=24.0.0} hasBin: true peerDependencies: - '@angular/compiler': 21.0.0 - '@angular/compiler-cli': 21.0.0 + '@angular/compiler': 21.0.1 + '@angular/compiler-cli': 21.0.1 '@angular/material@21.0.0': resolution: {integrity: sha512-s3+fhN7F5T1TAltZXYXOgY1wuVbICCrBJpV2TN8nJXDT0wroTYAljgBmsr6ZjDwYJewwP0OPvcj2NlOGDpa6oA==} @@ -1065,42 +1065,42 @@ packages: version: 0.0.0-f47684669736e28fd77eab64e65b2952c8a948ee hasBin: true - '@angular/platform-browser@21.0.0': - resolution: {integrity: sha512-KQrANla4RBLhcGkwlndqsKzBwVFOWQr1640CfBVjj2oz4M3dW5hyMtXivBACvuwyUhYU/qJbqlDMBXl/OUSudQ==} + '@angular/platform-browser@21.0.1': + resolution: {integrity: sha512-68StH9HILKUqNhQKz6KKNHzpgk1n88CIusWlmJvnb0l6iWGf3ydq5lTMKAKiZQmSDAVP5unTGfNvIkh59GRyVg==} engines: {node: ^20.19.0 || ^22.12.0 || >=24.0.0} peerDependencies: - '@angular/animations': 21.0.0 - '@angular/common': 21.0.0 - '@angular/core': 21.0.0 + '@angular/animations': 21.0.1 + '@angular/common': 21.0.1 + '@angular/core': 21.0.1 peerDependenciesMeta: '@angular/animations': optional: true - '@angular/platform-server@21.0.0': - resolution: {integrity: sha512-5IcmoftT2hLAbLfSoqGoCg0B1FLSk08xDoUdIyEUo1SmxNJMEEgU6WxhkPf6R7aoOlLAwYBoqGGP1Us1Z7rO7g==} + '@angular/platform-server@21.0.1': + resolution: {integrity: sha512-SfDn9u2YG2UaFtuUL35UFedTz6xiMphVD2sbLLYPpYVd3nRZUziUV3VjeZ2xM6mbZTtT4m2zA8XGUbbWVkxOPg==} engines: {node: ^20.19.0 || ^22.12.0 || >=24.0.0} peerDependencies: - '@angular/common': 21.0.0 - '@angular/compiler': 21.0.0 - '@angular/core': 21.0.0 - '@angular/platform-browser': 21.0.0 + '@angular/common': 21.0.1 + '@angular/compiler': 21.0.1 + '@angular/core': 21.0.1 + '@angular/platform-browser': 21.0.1 rxjs: ^6.5.3 || ^7.4.0 - '@angular/router@21.0.0': - resolution: {integrity: sha512-ARx1R2CmTgAezlMkUpV40V4T/IbXhL7dm4SuMVKbuEOsCKZC0TLOSSTsGYY7HKem45JHlJaByv819cJnabFgBg==} + '@angular/router@21.0.1': + resolution: {integrity: sha512-EnNbiScESZ0op9XS9qUNncWc1UcSYy90uCbDMVTTChikZt9b+e19OusFMf50zecb96VMMz+BzNY1see7Rmvx4g==} engines: {node: ^20.19.0 || ^22.12.0 || >=24.0.0} peerDependencies: - '@angular/common': 21.0.0 - '@angular/core': 21.0.0 - '@angular/platform-browser': 21.0.0 + '@angular/common': 21.0.1 + '@angular/core': 21.0.1 + '@angular/platform-browser': 21.0.1 rxjs: ^6.5.3 || ^7.4.0 - '@angular/service-worker@21.0.0': - resolution: {integrity: sha512-ZsJyVBvMQ6c9Xbci3cbPPQUPf+ZptvPshvf4eM5I4r3tJc7xDudpKKUqFBgAzZIN/GY5EvzMwGplgIy7HpKh1w==} + '@angular/service-worker@21.0.1': + resolution: {integrity: sha512-O2ebI7dSiSHjn8QoLQtwLcRsWEqzEwF6o36BSn4tb82q6oufG9txTyZBbqQgGIyBdDhvwVk4z7IdAUHwtrlQjg==} engines: {node: ^20.19.0 || ^22.12.0 || >=24.0.0} hasBin: true peerDependencies: - '@angular/core': 21.0.0 + '@angular/core': 21.0.1 rxjs: ^6.5.3 || ^7.4.0 '@asamuzakjp/css-color@4.0.5': @@ -9611,28 +9611,28 @@ snapshots: '@jridgewell/gen-mapping': 0.3.13 '@jridgewell/trace-mapping': 0.3.31 - '@angular/animations@21.0.0(@angular/core@21.0.0(@angular/compiler@21.0.0)(rxjs@7.8.2)(zone.js@0.15.1))': + '@angular/animations@21.0.1(@angular/core@21.0.1(@angular/compiler@21.0.1)(rxjs@7.8.2)(zone.js@0.15.1))': dependencies: - '@angular/core': 21.0.0(@angular/compiler@21.0.0)(rxjs@7.8.2)(zone.js@0.15.1) + '@angular/core': 21.0.1(@angular/compiler@21.0.1)(rxjs@7.8.2)(zone.js@0.15.1) tslib: 2.8.1 - '@angular/cdk@21.0.0(@angular/common@21.0.0(@angular/core@21.0.0(@angular/compiler@21.0.0)(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/core@21.0.0(@angular/compiler@21.0.0)(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2)': + '@angular/cdk@21.0.0(@angular/common@21.0.1(@angular/core@21.0.1(@angular/compiler@21.0.1)(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/core@21.0.1(@angular/compiler@21.0.1)(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2)': dependencies: - '@angular/common': 21.0.0(@angular/core@21.0.0(@angular/compiler@21.0.0)(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2) - '@angular/core': 21.0.0(@angular/compiler@21.0.0)(rxjs@7.8.2)(zone.js@0.15.1) + '@angular/common': 21.0.1(@angular/core@21.0.1(@angular/compiler@21.0.1)(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2) + '@angular/core': 21.0.1(@angular/compiler@21.0.1)(rxjs@7.8.2)(zone.js@0.15.1) parse5: 8.0.0 rxjs: 7.8.2 tslib: 2.8.1 - '@angular/common@21.0.0(@angular/core@21.0.0(@angular/compiler@21.0.0)(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2)': + '@angular/common@21.0.1(@angular/core@21.0.1(@angular/compiler@21.0.1)(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2)': dependencies: - '@angular/core': 21.0.0(@angular/compiler@21.0.0)(rxjs@7.8.2)(zone.js@0.15.1) + '@angular/core': 21.0.1(@angular/compiler@21.0.1)(rxjs@7.8.2)(zone.js@0.15.1) rxjs: 7.8.2 tslib: 2.8.1 - '@angular/compiler-cli@21.0.0(@angular/compiler@21.0.0)(typescript@5.9.3)': + '@angular/compiler-cli@21.0.1(@angular/compiler@21.0.1)(typescript@5.9.3)': dependencies: - '@angular/compiler': 21.0.0 + '@angular/compiler': 21.0.1 '@babel/core': 7.28.4 '@jridgewell/sourcemap-codec': 1.5.5 chokidar: 4.0.3 @@ -9646,31 +9646,31 @@ snapshots: transitivePeerDependencies: - supports-color - '@angular/compiler@21.0.0': + '@angular/compiler@21.0.1': dependencies: tslib: 2.8.1 - '@angular/core@21.0.0(@angular/compiler@21.0.0)(rxjs@7.8.2)(zone.js@0.15.1)': + '@angular/core@21.0.1(@angular/compiler@21.0.1)(rxjs@7.8.2)(zone.js@0.15.1)': dependencies: rxjs: 7.8.2 tslib: 2.8.1 optionalDependencies: - '@angular/compiler': 21.0.0 + '@angular/compiler': 21.0.1 zone.js: 0.15.1 - '@angular/forms@21.0.0(@angular/common@21.0.0(@angular/core@21.0.0(@angular/compiler@21.0.0)(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/core@21.0.0(@angular/compiler@21.0.0)(rxjs@7.8.2)(zone.js@0.15.1))(@angular/platform-browser@21.0.0(@angular/animations@21.0.0(@angular/core@21.0.0(@angular/compiler@21.0.0)(rxjs@7.8.2)(zone.js@0.15.1)))(@angular/common@21.0.0(@angular/core@21.0.0(@angular/compiler@21.0.0)(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/core@21.0.0(@angular/compiler@21.0.0)(rxjs@7.8.2)(zone.js@0.15.1)))(@standard-schema/spec@1.0.0)(rxjs@7.8.2)': + '@angular/forms@21.0.1(@angular/common@21.0.1(@angular/core@21.0.1(@angular/compiler@21.0.1)(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/core@21.0.1(@angular/compiler@21.0.1)(rxjs@7.8.2)(zone.js@0.15.1))(@angular/platform-browser@21.0.1(@angular/animations@21.0.1(@angular/core@21.0.1(@angular/compiler@21.0.1)(rxjs@7.8.2)(zone.js@0.15.1)))(@angular/common@21.0.1(@angular/core@21.0.1(@angular/compiler@21.0.1)(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/core@21.0.1(@angular/compiler@21.0.1)(rxjs@7.8.2)(zone.js@0.15.1)))(@standard-schema/spec@1.0.0)(rxjs@7.8.2)': dependencies: - '@angular/common': 21.0.0(@angular/core@21.0.0(@angular/compiler@21.0.0)(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2) - '@angular/core': 21.0.0(@angular/compiler@21.0.0)(rxjs@7.8.2)(zone.js@0.15.1) - '@angular/platform-browser': 21.0.0(@angular/animations@21.0.0(@angular/core@21.0.0(@angular/compiler@21.0.0)(rxjs@7.8.2)(zone.js@0.15.1)))(@angular/common@21.0.0(@angular/core@21.0.0(@angular/compiler@21.0.0)(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/core@21.0.0(@angular/compiler@21.0.0)(rxjs@7.8.2)(zone.js@0.15.1)) + '@angular/common': 21.0.1(@angular/core@21.0.1(@angular/compiler@21.0.1)(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2) + '@angular/core': 21.0.1(@angular/compiler@21.0.1)(rxjs@7.8.2)(zone.js@0.15.1) + '@angular/platform-browser': 21.0.1(@angular/animations@21.0.1(@angular/core@21.0.1(@angular/compiler@21.0.1)(rxjs@7.8.2)(zone.js@0.15.1)))(@angular/common@21.0.1(@angular/core@21.0.1(@angular/compiler@21.0.1)(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/core@21.0.1(@angular/compiler@21.0.1)(rxjs@7.8.2)(zone.js@0.15.1)) '@standard-schema/spec': 1.0.0 rxjs: 7.8.2 tslib: 2.8.1 - '@angular/localize@21.0.0(@angular/compiler-cli@21.0.0(@angular/compiler@21.0.0)(typescript@5.9.3))(@angular/compiler@21.0.0)': + '@angular/localize@21.0.1(@angular/compiler-cli@21.0.1(@angular/compiler@21.0.1)(typescript@5.9.3))(@angular/compiler@21.0.1)': dependencies: - '@angular/compiler': 21.0.0 - '@angular/compiler-cli': 21.0.0(@angular/compiler@21.0.0)(typescript@5.9.3) + '@angular/compiler': 21.0.1 + '@angular/compiler-cli': 21.0.1(@angular/compiler@21.0.1)(typescript@5.9.3) '@babel/core': 7.28.4 '@types/babel__core': 7.20.5 tinyglobby: 0.2.15 @@ -9678,13 +9678,13 @@ snapshots: transitivePeerDependencies: - supports-color - '@angular/material@21.0.0(280d15a59d7c55264f5164ad0fb0f648)': + '@angular/material@21.0.0(8e7b236207d28338fccf527c5c162c22)': dependencies: - '@angular/cdk': 21.0.0(@angular/common@21.0.0(@angular/core@21.0.0(@angular/compiler@21.0.0)(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/core@21.0.0(@angular/compiler@21.0.0)(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2) - '@angular/common': 21.0.0(@angular/core@21.0.0(@angular/compiler@21.0.0)(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2) - '@angular/core': 21.0.0(@angular/compiler@21.0.0)(rxjs@7.8.2)(zone.js@0.15.1) - '@angular/forms': 21.0.0(@angular/common@21.0.0(@angular/core@21.0.0(@angular/compiler@21.0.0)(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/core@21.0.0(@angular/compiler@21.0.0)(rxjs@7.8.2)(zone.js@0.15.1))(@angular/platform-browser@21.0.0(@angular/animations@21.0.0(@angular/core@21.0.0(@angular/compiler@21.0.0)(rxjs@7.8.2)(zone.js@0.15.1)))(@angular/common@21.0.0(@angular/core@21.0.0(@angular/compiler@21.0.0)(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/core@21.0.0(@angular/compiler@21.0.0)(rxjs@7.8.2)(zone.js@0.15.1)))(@standard-schema/spec@1.0.0)(rxjs@7.8.2) - '@angular/platform-browser': 21.0.0(@angular/animations@21.0.0(@angular/core@21.0.0(@angular/compiler@21.0.0)(rxjs@7.8.2)(zone.js@0.15.1)))(@angular/common@21.0.0(@angular/core@21.0.0(@angular/compiler@21.0.0)(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/core@21.0.0(@angular/compiler@21.0.0)(rxjs@7.8.2)(zone.js@0.15.1)) + '@angular/cdk': 21.0.0(@angular/common@21.0.1(@angular/core@21.0.1(@angular/compiler@21.0.1)(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/core@21.0.1(@angular/compiler@21.0.1)(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2) + '@angular/common': 21.0.1(@angular/core@21.0.1(@angular/compiler@21.0.1)(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2) + '@angular/core': 21.0.1(@angular/compiler@21.0.1)(rxjs@7.8.2)(zone.js@0.15.1) + '@angular/forms': 21.0.1(@angular/common@21.0.1(@angular/core@21.0.1(@angular/compiler@21.0.1)(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/core@21.0.1(@angular/compiler@21.0.1)(rxjs@7.8.2)(zone.js@0.15.1))(@angular/platform-browser@21.0.1(@angular/animations@21.0.1(@angular/core@21.0.1(@angular/compiler@21.0.1)(rxjs@7.8.2)(zone.js@0.15.1)))(@angular/common@21.0.1(@angular/core@21.0.1(@angular/compiler@21.0.1)(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/core@21.0.1(@angular/compiler@21.0.1)(rxjs@7.8.2)(zone.js@0.15.1)))(@standard-schema/spec@1.0.0)(rxjs@7.8.2) + '@angular/platform-browser': 21.0.1(@angular/animations@21.0.1(@angular/core@21.0.1(@angular/compiler@21.0.1)(rxjs@7.8.2)(zone.js@0.15.1)))(@angular/common@21.0.1(@angular/core@21.0.1(@angular/compiler@21.0.1)(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/core@21.0.1(@angular/compiler@21.0.1)(rxjs@7.8.2)(zone.js@0.15.1)) rxjs: 7.8.2 tslib: 2.8.1 @@ -9748,35 +9748,35 @@ snapshots: - '@modelcontextprotocol/sdk' - '@react-native-async-storage/async-storage' - '@angular/platform-browser@21.0.0(@angular/animations@21.0.0(@angular/core@21.0.0(@angular/compiler@21.0.0)(rxjs@7.8.2)(zone.js@0.15.1)))(@angular/common@21.0.0(@angular/core@21.0.0(@angular/compiler@21.0.0)(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/core@21.0.0(@angular/compiler@21.0.0)(rxjs@7.8.2)(zone.js@0.15.1))': + '@angular/platform-browser@21.0.1(@angular/animations@21.0.1(@angular/core@21.0.1(@angular/compiler@21.0.1)(rxjs@7.8.2)(zone.js@0.15.1)))(@angular/common@21.0.1(@angular/core@21.0.1(@angular/compiler@21.0.1)(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/core@21.0.1(@angular/compiler@21.0.1)(rxjs@7.8.2)(zone.js@0.15.1))': dependencies: - '@angular/common': 21.0.0(@angular/core@21.0.0(@angular/compiler@21.0.0)(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2) - '@angular/core': 21.0.0(@angular/compiler@21.0.0)(rxjs@7.8.2)(zone.js@0.15.1) + '@angular/common': 21.0.1(@angular/core@21.0.1(@angular/compiler@21.0.1)(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2) + '@angular/core': 21.0.1(@angular/compiler@21.0.1)(rxjs@7.8.2)(zone.js@0.15.1) tslib: 2.8.1 optionalDependencies: - '@angular/animations': 21.0.0(@angular/core@21.0.0(@angular/compiler@21.0.0)(rxjs@7.8.2)(zone.js@0.15.1)) + '@angular/animations': 21.0.1(@angular/core@21.0.1(@angular/compiler@21.0.1)(rxjs@7.8.2)(zone.js@0.15.1)) - '@angular/platform-server@21.0.0(@angular/common@21.0.0(@angular/core@21.0.0(@angular/compiler@21.0.0)(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/compiler@21.0.0)(@angular/core@21.0.0(@angular/compiler@21.0.0)(rxjs@7.8.2)(zone.js@0.15.1))(@angular/platform-browser@21.0.0(@angular/animations@21.0.0(@angular/core@21.0.0(@angular/compiler@21.0.0)(rxjs@7.8.2)(zone.js@0.15.1)))(@angular/common@21.0.0(@angular/core@21.0.0(@angular/compiler@21.0.0)(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/core@21.0.0(@angular/compiler@21.0.0)(rxjs@7.8.2)(zone.js@0.15.1)))(rxjs@7.8.2)': + '@angular/platform-server@21.0.1(@angular/common@21.0.1(@angular/core@21.0.1(@angular/compiler@21.0.1)(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/compiler@21.0.1)(@angular/core@21.0.1(@angular/compiler@21.0.1)(rxjs@7.8.2)(zone.js@0.15.1))(@angular/platform-browser@21.0.1(@angular/animations@21.0.1(@angular/core@21.0.1(@angular/compiler@21.0.1)(rxjs@7.8.2)(zone.js@0.15.1)))(@angular/common@21.0.1(@angular/core@21.0.1(@angular/compiler@21.0.1)(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/core@21.0.1(@angular/compiler@21.0.1)(rxjs@7.8.2)(zone.js@0.15.1)))(rxjs@7.8.2)': dependencies: - '@angular/common': 21.0.0(@angular/core@21.0.0(@angular/compiler@21.0.0)(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2) - '@angular/compiler': 21.0.0 - '@angular/core': 21.0.0(@angular/compiler@21.0.0)(rxjs@7.8.2)(zone.js@0.15.1) - '@angular/platform-browser': 21.0.0(@angular/animations@21.0.0(@angular/core@21.0.0(@angular/compiler@21.0.0)(rxjs@7.8.2)(zone.js@0.15.1)))(@angular/common@21.0.0(@angular/core@21.0.0(@angular/compiler@21.0.0)(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/core@21.0.0(@angular/compiler@21.0.0)(rxjs@7.8.2)(zone.js@0.15.1)) + '@angular/common': 21.0.1(@angular/core@21.0.1(@angular/compiler@21.0.1)(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2) + '@angular/compiler': 21.0.1 + '@angular/core': 21.0.1(@angular/compiler@21.0.1)(rxjs@7.8.2)(zone.js@0.15.1) + '@angular/platform-browser': 21.0.1(@angular/animations@21.0.1(@angular/core@21.0.1(@angular/compiler@21.0.1)(rxjs@7.8.2)(zone.js@0.15.1)))(@angular/common@21.0.1(@angular/core@21.0.1(@angular/compiler@21.0.1)(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/core@21.0.1(@angular/compiler@21.0.1)(rxjs@7.8.2)(zone.js@0.15.1)) rxjs: 7.8.2 tslib: 2.8.1 xhr2: 0.2.1 - '@angular/router@21.0.0(@angular/common@21.0.0(@angular/core@21.0.0(@angular/compiler@21.0.0)(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/core@21.0.0(@angular/compiler@21.0.0)(rxjs@7.8.2)(zone.js@0.15.1))(@angular/platform-browser@21.0.0(@angular/animations@21.0.0(@angular/core@21.0.0(@angular/compiler@21.0.0)(rxjs@7.8.2)(zone.js@0.15.1)))(@angular/common@21.0.0(@angular/core@21.0.0(@angular/compiler@21.0.0)(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/core@21.0.0(@angular/compiler@21.0.0)(rxjs@7.8.2)(zone.js@0.15.1)))(rxjs@7.8.2)': + '@angular/router@21.0.1(@angular/common@21.0.1(@angular/core@21.0.1(@angular/compiler@21.0.1)(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/core@21.0.1(@angular/compiler@21.0.1)(rxjs@7.8.2)(zone.js@0.15.1))(@angular/platform-browser@21.0.1(@angular/animations@21.0.1(@angular/core@21.0.1(@angular/compiler@21.0.1)(rxjs@7.8.2)(zone.js@0.15.1)))(@angular/common@21.0.1(@angular/core@21.0.1(@angular/compiler@21.0.1)(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/core@21.0.1(@angular/compiler@21.0.1)(rxjs@7.8.2)(zone.js@0.15.1)))(rxjs@7.8.2)': dependencies: - '@angular/common': 21.0.0(@angular/core@21.0.0(@angular/compiler@21.0.0)(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2) - '@angular/core': 21.0.0(@angular/compiler@21.0.0)(rxjs@7.8.2)(zone.js@0.15.1) - '@angular/platform-browser': 21.0.0(@angular/animations@21.0.0(@angular/core@21.0.0(@angular/compiler@21.0.0)(rxjs@7.8.2)(zone.js@0.15.1)))(@angular/common@21.0.0(@angular/core@21.0.0(@angular/compiler@21.0.0)(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/core@21.0.0(@angular/compiler@21.0.0)(rxjs@7.8.2)(zone.js@0.15.1)) + '@angular/common': 21.0.1(@angular/core@21.0.1(@angular/compiler@21.0.1)(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2) + '@angular/core': 21.0.1(@angular/compiler@21.0.1)(rxjs@7.8.2)(zone.js@0.15.1) + '@angular/platform-browser': 21.0.1(@angular/animations@21.0.1(@angular/core@21.0.1(@angular/compiler@21.0.1)(rxjs@7.8.2)(zone.js@0.15.1)))(@angular/common@21.0.1(@angular/core@21.0.1(@angular/compiler@21.0.1)(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/core@21.0.1(@angular/compiler@21.0.1)(rxjs@7.8.2)(zone.js@0.15.1)) rxjs: 7.8.2 tslib: 2.8.1 - '@angular/service-worker@21.0.0(@angular/core@21.0.0(@angular/compiler@21.0.0)(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2)': + '@angular/service-worker@21.0.1(@angular/core@21.0.1(@angular/compiler@21.0.1)(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2)': dependencies: - '@angular/core': 21.0.0(@angular/compiler@21.0.0)(rxjs@7.8.2)(zone.js@0.15.1) + '@angular/core': 21.0.1(@angular/compiler@21.0.1)(rxjs@7.8.2)(zone.js@0.15.1) rxjs: 7.8.2 tslib: 2.8.1 @@ -16772,10 +16772,10 @@ snapshots: netmask@2.0.2: {} - ng-packagr@21.0.0(@angular/compiler-cli@21.0.0(@angular/compiler@21.0.0)(typescript@5.9.3))(tslib@2.8.1)(typescript@5.9.3): + ng-packagr@21.0.0(@angular/compiler-cli@21.0.1(@angular/compiler@21.0.1)(typescript@5.9.3))(tslib@2.8.1)(typescript@5.9.3): dependencies: '@ampproject/remapping': 2.3.0 - '@angular/compiler-cli': 21.0.0(@angular/compiler@21.0.0)(typescript@5.9.3) + '@angular/compiler-cli': 21.0.1(@angular/compiler@21.0.1)(typescript@5.9.3) '@rollup/plugin-json': 6.1.0(rollup@4.52.5) '@rollup/wasm-node': 4.53.2 ajv: 8.17.1 From 3a4da66cd885af5d9f7f1c1581377739bf90525a Mon Sep 17 00:00:00 2001 From: Charles Lyding <19598772+clydin@users.noreply.github.com> Date: Tue, 25 Nov 2025 17:27:27 -0500 Subject: [PATCH 49/54] refactor(@angular/build): adjust compiler-cli namespace import Updates the type import for `@angular/compiler-cli` from a default import (`import type ng from ...`) to a full namespace import (`import type * as ng from ...`) across the Angular build tooling. This change ensures consistent and correct type resolution, aligning with modern TypeScript module standards and preventing potential import resolution issues. (cherry picked from commit 0fd1646752658025004f9345eed7fb711227682a) --- packages/angular/build/src/tools/angular/angular-host.ts | 2 +- .../build/src/tools/angular/compilation/angular-compilation.ts | 2 +- .../build/src/tools/angular/compilation/aot-compilation.ts | 2 +- .../build/src/tools/angular/compilation/hmr-candidates.ts | 2 +- .../build/src/tools/angular/compilation/jit-compilation.ts | 2 +- .../build/src/tools/angular/compilation/noop-compilation.ts | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) diff --git a/packages/angular/build/src/tools/angular/angular-host.ts b/packages/angular/build/src/tools/angular/angular-host.ts index 38c096f67674..e98ebf49f3eb 100644 --- a/packages/angular/build/src/tools/angular/angular-host.ts +++ b/packages/angular/build/src/tools/angular/angular-host.ts @@ -6,7 +6,7 @@ * found in the LICENSE file at https://angular.dev/license */ -import type ng from '@angular/compiler-cli'; +import type * as ng from '@angular/compiler-cli'; import assert from 'node:assert'; import { createHash } from 'node:crypto'; import nodePath from 'node:path'; diff --git a/packages/angular/build/src/tools/angular/compilation/angular-compilation.ts b/packages/angular/build/src/tools/angular/compilation/angular-compilation.ts index ca4e869aecd5..00a17ccc453e 100644 --- a/packages/angular/build/src/tools/angular/compilation/angular-compilation.ts +++ b/packages/angular/build/src/tools/angular/compilation/angular-compilation.ts @@ -6,7 +6,7 @@ * found in the LICENSE file at https://angular.dev/license */ -import type ng from '@angular/compiler-cli'; +import type * as ng from '@angular/compiler-cli'; import type { PartialMessage } from 'esbuild'; import type ts from 'typescript'; import { convertTypeScriptDiagnostic } from '../../esbuild/angular/diagnostics'; 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 32bd7c586ed2..06a3f6e8c8d6 100644 --- a/packages/angular/build/src/tools/angular/compilation/aot-compilation.ts +++ b/packages/angular/build/src/tools/angular/compilation/aot-compilation.ts @@ -6,7 +6,7 @@ * found in the LICENSE file at https://angular.dev/license */ -import type ng from '@angular/compiler-cli'; +import type * as ng from '@angular/compiler-cli'; import assert from 'node:assert'; import { relative } from 'node:path'; import ts from 'typescript'; diff --git a/packages/angular/build/src/tools/angular/compilation/hmr-candidates.ts b/packages/angular/build/src/tools/angular/compilation/hmr-candidates.ts index e10b935907c0..cba0b18e7414 100644 --- a/packages/angular/build/src/tools/angular/compilation/hmr-candidates.ts +++ b/packages/angular/build/src/tools/angular/compilation/hmr-candidates.ts @@ -6,7 +6,7 @@ * found in the LICENSE file at https://angular.dev/license */ -import type ng from '@angular/compiler-cli'; +import type * as ng from '@angular/compiler-cli'; import assert from 'node:assert'; import ts from 'typescript'; 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 d2876654a15e..4c529df0db08 100644 --- a/packages/angular/build/src/tools/angular/compilation/jit-compilation.ts +++ b/packages/angular/build/src/tools/angular/compilation/jit-compilation.ts @@ -6,7 +6,7 @@ * found in the LICENSE file at https://angular.dev/license */ -import type ng from '@angular/compiler-cli'; +import type * as ng from '@angular/compiler-cli'; import assert from 'node:assert'; import ts from 'typescript'; import { profileSync } from '../../esbuild/profiling'; diff --git a/packages/angular/build/src/tools/angular/compilation/noop-compilation.ts b/packages/angular/build/src/tools/angular/compilation/noop-compilation.ts index a683271b287f..e2c597b4d315 100644 --- a/packages/angular/build/src/tools/angular/compilation/noop-compilation.ts +++ b/packages/angular/build/src/tools/angular/compilation/noop-compilation.ts @@ -6,7 +6,7 @@ * found in the LICENSE file at https://angular.dev/license */ -import type ng from '@angular/compiler-cli'; +import type * as ng from '@angular/compiler-cli'; import type ts from 'typescript'; import { AngularHostOptions } from '../angular-host'; import { AngularCompilation } from './angular-compilation'; From 2bfcbc3bba2b850fcf0e0ee95447cd1bad9adeca Mon Sep 17 00:00:00 2001 From: Angular Robot Date: Wed, 26 Nov 2025 08:42:42 +0000 Subject: [PATCH 50/54] build: update all github actions See associated pull request for more information. --- .github/workflows/assistant-to-the-branch-manager.yml | 2 +- .github/workflows/codeql.yml | 6 +++--- .github/workflows/dev-infra.yml | 4 ++-- .github/workflows/pr.yml | 2 +- .github/workflows/scorecard.yml | 4 ++-- 5 files changed, 9 insertions(+), 9 deletions(-) diff --git a/.github/workflows/assistant-to-the-branch-manager.yml b/.github/workflows/assistant-to-the-branch-manager.yml index 6df4ef55c1e0..e3eb60bd1368 100644 --- a/.github/workflows/assistant-to-the-branch-manager.yml +++ b/.github/workflows/assistant-to-the-branch-manager.yml @@ -13,7 +13,7 @@ jobs: assistant_to_the_branch_manager: runs-on: ubuntu-latest steps: - - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 + - uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5.0.1 with: persist-credentials: false - uses: angular/dev-infra/github-actions/branch-manager@f47684669736e28fd77eab64e65b2952c8a948ee diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml index fb4789033a1a..531005ac0e0f 100644 --- a/.github/workflows/codeql.yml +++ b/.github/workflows/codeql.yml @@ -19,16 +19,16 @@ jobs: fail-fast: false steps: - name: Checkout repository - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 + uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5.0.1 with: persist-credentials: false - name: Initialize CodeQL - uses: github/codeql-action/init@0499de31b99561a6d14a36a5f662c2a54f91beee # v4.31.2 + uses: github/codeql-action/init@fdbfb4d2750291e159f0156def62b853c2798ca2 # v4.31.5 with: languages: javascript-typescript build-mode: none config-file: .github/codeql/config.yml - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@0499de31b99561a6d14a36a5f662c2a54f91beee # v4.31.2 + uses: github/codeql-action/analyze@fdbfb4d2750291e159f0156def62b853c2798ca2 # v4.31.5 with: category: '/language:javascript-typescript' diff --git a/.github/workflows/dev-infra.yml b/.github/workflows/dev-infra.yml index 5a8731c9002e..0b0997b0d9f0 100644 --- a/.github/workflows/dev-infra.yml +++ b/.github/workflows/dev-infra.yml @@ -12,14 +12,14 @@ jobs: labels: runs-on: ubuntu-latest steps: - - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 + - uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5.0.1 - uses: angular/dev-infra/github-actions/pull-request-labeling@f47684669736e28fd77eab64e65b2952c8a948ee with: angular-robot-key: ${{ secrets.ANGULAR_ROBOT_PRIVATE_KEY }} post_approval_changes: runs-on: ubuntu-latest steps: - - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 + - uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5.0.1 - uses: angular/dev-infra/github-actions/post-approval-changes@f47684669736e28fd77eab64e65b2952c8a948ee with: angular-robot-key: ${{ secrets.ANGULAR_ROBOT_PRIVATE_KEY }} diff --git a/.github/workflows/pr.yml b/.github/workflows/pr.yml index 694ef896fa91..92f048b60a3f 100644 --- a/.github/workflows/pr.yml +++ b/.github/workflows/pr.yml @@ -20,7 +20,7 @@ jobs: outputs: snapshots: ${{ steps.filter.outputs.snapshots }} steps: - - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 + - uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5.0.1 with: persist-credentials: false - uses: dorny/paths-filter@de90cc6fb38fc0963ad72b210f1f284cd68cea36 # v3.0.2 diff --git a/.github/workflows/scorecard.yml b/.github/workflows/scorecard.yml index 684af3c43a37..8a268a8211e6 100644 --- a/.github/workflows/scorecard.yml +++ b/.github/workflows/scorecard.yml @@ -25,7 +25,7 @@ jobs: steps: - name: 'Checkout code' - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 + uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5.0.1 with: persist-credentials: false @@ -46,6 +46,6 @@ jobs: # Upload the results to GitHub's code scanning dashboard. - name: 'Upload to code-scanning' - uses: github/codeql-action/upload-sarif@0499de31b99561a6d14a36a5f662c2a54f91beee # v4.31.2 + uses: github/codeql-action/upload-sarif@fdbfb4d2750291e159f0156def62b853c2798ca2 # v4.31.5 with: sarif_file: results.sarif From 3261be643ec98ed312b3d50227d65b8b3b75035b Mon Sep 17 00:00:00 2001 From: Angular Robot Date: Wed, 26 Nov 2025 08:43:23 +0000 Subject: [PATCH 51/54] build: lock file maintenance See associated pull request for more information. --- pnpm-lock.yaml | 308 ++++++++++++++++++++++++------------------------- 1 file changed, 153 insertions(+), 155 deletions(-) diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 1424bbe085c5..377ba910c50b 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -93,7 +93,7 @@ importers: version: 16.0.3(rollup@4.52.5) '@stylistic/eslint-plugin': specifier: ^5.0.0 - version: 5.5.0(eslint@9.38.0(jiti@2.6.1)) + version: 5.6.1(eslint@9.38.0(jiti@2.6.1)) '@types/babel__core': specifier: 7.20.5 version: 7.20.5 @@ -129,7 +129,7 @@ importers: version: 3.0.0(esbuild@0.26.0) '@types/lodash': specifier: ^4.17.0 - version: 4.17.20 + version: 4.17.21 '@types/node': specifier: ^22.12.0 version: 22.19.1 @@ -909,8 +909,8 @@ importers: packages: - '@acemir/cssom@0.9.23': - resolution: {integrity: sha512-2kJ1HxBKzPLbmhZpxBiTZggjtgCwKg1ma5RHShxvd6zgqhDEdEkzpiwe7jLkI2p2BrZvFCXIihdoMkl1H39VnA==} + '@acemir/cssom@0.9.24': + resolution: {integrity: sha512-5YjgMmAiT2rjJZU7XK1SNI7iqTy92DpaYVgG6x63FxkJ11UpYfLndHJATtinWJClAXiOlW9XWaUyAQf8pMrQPg==} '@actions/core@1.11.1': resolution: {integrity: sha512-hXJCSrkwfA46Vd9Z3q4cpEpHB1rL5NG04+/rbqW9d3+CSvtB1tYe8UTpAlixa1vj0m/ULglfEK2UKxMGxCxv5A==} @@ -1103,8 +1103,8 @@ packages: '@angular/core': 21.0.1 rxjs: ^6.5.3 || ^7.4.0 - '@asamuzakjp/css-color@4.0.5': - resolution: {integrity: sha512-lMrXidNhPGsDjytDy11Vwlb6OIGrT3CmLg3VWNFyWkLWtijKl7xjvForlh8vuj0SHGjgl4qZEQzUmYTeQA2JFQ==} + '@asamuzakjp/css-color@4.1.0': + resolution: {integrity: sha512-9xiBAtLn4aNsa4mDnpovJvBn72tNEIACyvlqaNJ+ADemR+yeMJWnBudOi2qGDviJa7SwcDOU/TRh5dnET7qk0w==} '@asamuzakjp/dom-selector@6.7.4': resolution: {integrity: sha512-buQDjkm+wDPXd6c13534URWZqbz0RP5PAhXZ+LIoa5LgwInT9HVJvGIJivg75vi8I13CxDGdTnz+aY5YUJlIAA==} @@ -1677,8 +1677,8 @@ packages: peerDependencies: '@csstools/css-tokenizer': ^3.0.4 - '@csstools/css-syntax-patches-for-csstree@1.0.16': - resolution: {integrity: sha512-2SpS4/UaWQaGpBINyG5ZuCHnUDeVByOhvbkARwfmnfxDvTaj80yOI1cD8Tw93ICV5Fx4fnyDKWQZI1CDtcWyUg==} + '@csstools/css-syntax-patches-for-csstree@1.0.17': + resolution: {integrity: sha512-LCC++2h8pLUSPY+EsZmrrJ1EOUu+5iClpEiDhhdw3zRJpPbABML/N5lmRuBHjxtKm9VnRcsUzioyD0sekFMF0A==} engines: {node: '>=18'} '@csstools/css-tokenizer@3.0.4': @@ -3076,9 +3076,9 @@ packages: resolution: {integrity: sha512-kAQTcEN9E8ERLVg5AsGwLNoFb+oEG6engbqAU2P43gD4JEIkNGMHdVQ096FsOAAYpZPB0RSt0zgInKIAS1l5QA==} engines: {node: ^20.17.0 || >=22.9.0} - '@npmcli/fs@4.0.0': - resolution: {integrity: sha512-/xGlezI6xfGO9NwuJlnwz/K14qD1kCSAGtacBHnGzeAIuJGazcp45KP5NuyARXoKb7cwulAGWVsbeSxdG/cb0Q==} - engines: {node: ^18.17.0 || >=20.5.0} + '@npmcli/fs@5.0.0': + resolution: {integrity: sha512-7OsC1gNORBEawOa5+j2pXN9vsicaIOH5cPXxoR6fJOmH6/EXpJB2CajXOu1fPRFun2m1lktEFX11+P89hqO/og==} + engines: {node: ^20.17.0 || >=22.9.0} '@npmcli/git@7.0.1': resolution: {integrity: sha512-+XTFxK2jJF/EJJ5SoAzXk3qwIDfvFc5/g+bD274LZ7uY7LE8sTfG6Z8rOanPl2ZEvZWqNvmEdtXC25cE54VcoA==} @@ -3093,8 +3093,8 @@ packages: resolution: {integrity: sha512-uuG5HZFXLfyFKqg8QypsmgLQW7smiRjVc45bqD/ofZZcR/uxEjgQU8qDPv0s9TEeMUiAAU/GC5bR6++UdTirIQ==} engines: {node: ^20.17.0 || >=22.9.0} - '@npmcli/package-json@7.0.2': - resolution: {integrity: sha512-0ylN3U5htO1SJTmy2YI78PZZjLkKUGg7EKgukb2CRi0kzyoDr0cfjHAzi7kozVhj2V3SxN1oyKqZ2NSo40z00g==} + '@npmcli/package-json@7.0.4': + resolution: {integrity: sha512-0wInJG3j/K40OJt/33ax47WfWMzZTm6OQxB9cDhTt5huCP2a9g2GnlsxmfN+PulItNPIpPrZ+kfwwUil7eHcZQ==} engines: {node: ^20.17.0 || >=22.9.0} '@npmcli/promise-spawn@8.0.3': @@ -3645,8 +3645,8 @@ packages: cpu: [x64] os: [win32] - '@rollup/wasm-node@4.53.2': - resolution: {integrity: sha512-oPSy4fH0C66muvPr/HU13K8X9QFO74Em+JUegHUpEwD61M3lihIlfrLpilhrEiiReFOfG00Qyhf7NGFuwkX2yA==} + '@rollup/wasm-node@4.53.3': + resolution: {integrity: sha512-mB8z32H6kz4kVjn+tfTGcrXBae7rIeAvm/g6itsE3IqcXpjSRRvk1/EOWDEi5wL8NNmxXiH71t4jtNfr128zpw==} engines: {node: '>=18.0.0', npm: '>=8.0.0'} hasBin: true @@ -3687,8 +3687,8 @@ packages: '@standard-schema/spec@1.0.0': resolution: {integrity: sha512-m2bOd0f2RT9k8QJx1JN85cZYyH1RqFBdlwtkSlf4tBDYLCiiZnv1fIIwacK6cqwXavOydf0NPToMQgpKq+dVlA==} - '@stylistic/eslint-plugin@5.5.0': - resolution: {integrity: sha512-IeZF+8H0ns6prg4VrkhgL+yrvDXWDH2cKchrbh80ejG9dQgZWp10epHMbgRuQvgchLII/lfh6Xn3lu6+6L86Hw==} + '@stylistic/eslint-plugin@5.6.1': + resolution: {integrity: sha512-JCs+MqoXfXrRPGbGmho/zGS/jMcn3ieKl/A8YImqib76C8kjgZwq5uUFzc30lJkMvcchuRn6/v8IApLxli3Jyw==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: eslint: '>=9.0.0' @@ -3883,8 +3883,8 @@ packages: '@types/loader-utils@3.0.0': resolution: {integrity: sha512-oOi4OGpiLUbb+Q/cN9FIkkDFgOpOGZ2cUAzb5i03wrGstnG6Syx1WDMhSiB5rcP10XX7cw7Uev8mv++/aplnNg==} - '@types/lodash@4.17.20': - resolution: {integrity: sha512-H3MHACvFUEiujabxhaI/ImO6gUrd8oOurg7LQtS7mbwIXA/cUqWrvBsaeJ23aZEPk1TAYkurjfMbSELfoCXlGA==} + '@types/lodash@4.17.21': + resolution: {integrity: sha512-FOvQ0YPD5NOfPgMzJihoT+Za5pdkDJWcbpuj1DjaKZIr/gxodQjY/uWEFlTNqW2ugXHUiL8lRQgw63dzKHZdeQ==} '@types/micromatch@2.3.35': resolution: {integrity: sha512-J749bHo/Zu56w0G0NI/IGHLQPiSsjx//0zJhfEVAN95K/xM5C8ZDmhkXtU3qns0sBOao7HuQzr8XV1/2o5LbXA==} @@ -4048,8 +4048,8 @@ packages: resolution: {integrity: sha512-lNCWCbq7rpg7qDsQrd3D6NyWYu+gkTENkG5IKYhUIcxSb59SQC/hEQ+MrG4sTgBVghTonNWq42bA/d4yYumldQ==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@typescript-eslint/types@8.46.4': - resolution: {integrity: sha512-USjyxm3gQEePdUwJBFjjGNG18xY9A2grDVGuk7/9AkjIF1L+ZrVnwR5VAU5JXtUnBL/Nwt3H31KlRDaksnM7/w==} + '@typescript-eslint/types@8.48.0': + resolution: {integrity: sha512-cQMcGQQH7kwKoVswD1xdOytxQR60MWKM1di26xSUtxehaDs/32Zpqsu5WJlXTtTTqyAVK8R7hvsUnIXRS+bjvA==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} '@typescript-eslint/typescript-estree@8.46.2': @@ -4642,8 +4642,8 @@ packages: resolution: {integrity: sha512-lGe34o6EHj9y3Kts9R4ZYs/Gr+6N7MCaMlIFA3F1R2O5/m7K06AxfSeO5530PEERE6/WyEg3lsuyw4GHlPZHog==} engines: {node: ^4.5.0 || >= 5.9} - baseline-browser-mapping@2.8.28: - resolution: {integrity: sha512-gYjt7OIqdM0PcttNYP2aVrr2G0bMALkBaoehD4BuRGjAOtipg0b6wHg1yNL+s5zSnLZZrGHOw4IrND8CD+3oIQ==} + baseline-browser-mapping@2.8.31: + resolution: {integrity: sha512-a28v2eWrrRWPpJSzxc+mKwm0ZtVx/G8SepdQZDArnXYU/XS+IF6mp8aB/4E+hH1tyGCoDo3KlUCdlSxGDsRkAw==} hasBin: true basic-ftp@5.0.5: @@ -4694,8 +4694,8 @@ packages: resolution: {integrity: sha512-7rAxByjUMqQ3/bHJy7D6OGXvx/MMc4IqBn/X0fcM1QUcAItpZrBEYhWGem+tzXH90c+G01ypMcYJBO9Y30203g==} engines: {node: '>= 0.8', npm: 1.2.8000 || >= 1.4.16} - body-parser@2.2.0: - resolution: {integrity: sha512-02qvAaxv8tp7fBa/mw1ga98OGm+eCbqzJOKoRt70sLmfEEi+jyBYVTDGfCL/k06/4EMk/z01gCe7HoCH/f2LTg==} + body-parser@2.2.1: + resolution: {integrity: sha512-nfDwkulwiZYQIGwxdy0RUmowMhKcFVcYXUU7m4QlKYim1rUtg83xm2yjZ40QjDuc291AJjjeSc9b++AWHSgSHw==} engines: {node: '>=18'} bonjour-service@1.3.0: @@ -4770,8 +4770,8 @@ packages: resolution: {integrity: sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==} engines: {node: '>= 0.8'} - cacache@20.0.1: - resolution: {integrity: sha512-+7LYcYGBYoNqTp1Rv7Ny1YjUo5E0/ftkQtraH3vkfAGgVHc+ouWdC8okAwQgQR7EVIdW6JTzTmhKFwzb+4okAQ==} + cacache@20.0.3: + resolution: {integrity: sha512-3pUp4e8hv07k1QlijZu6Kn7c9+ZpWWk4j3F8N3xPuCExULobqJydKYOTj1FTq58srkJsXvO7LbGAH4C0ZU3WGw==} engines: {node: ^20.17.0 || >=22.9.0} cache-content-type@1.0.1: @@ -4810,8 +4810,8 @@ packages: resolution: {integrity: sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==} engines: {node: '>=10'} - caniuse-lite@1.0.30001755: - resolution: {integrity: sha512-44V+Jm6ctPj7R52Na4TLi3Zri4dWUljJd+RDm+j8LtNCc/ihLCT+X1TzoOAkRETEWqjuLnh9581Tl80FvK7jVA==} + caniuse-lite@1.0.30001757: + resolution: {integrity: sha512-r0nnL/I28Zi/yjk1el6ilj27tKcdjLsNqAOZr0yVjWPrSQyHgKI2INaEWw21bAQSv2LXRt1XuCS/GomNpWOxsQ==} caseless@0.12.0: resolution: {integrity: sha512-4tYFyifaFfGacoiObjJegolkwSU4xQNGbVgUiNYVUxbQ2x2lUsFvY4hVgVzGiIe6WLOPqycWXA40l+PWsxthUw==} @@ -5008,9 +5008,9 @@ packages: resolution: {integrity: sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==} engines: {node: '>= 0.6'} - content-disposition@1.0.0: - resolution: {integrity: sha512-Au9nRL8VNUut/XSzbQA38+M78dzP4D+eqg3gfJHMIHHYa3bg067xj1KxMUWj+VULbiZMowKngFFbKczUrNJ1mg==} - engines: {node: '>= 0.6'} + content-disposition@1.0.1: + resolution: {integrity: sha512-oIXISMynqSqm241k6kcQ5UwttDILMK4BiurCfGEREw6+X9jkkpEe5T9FZaApyLGGOnFuyMWZpdolTXMtvEJ08Q==} + engines: {node: '>=18'} content-type@1.0.5: resolution: {integrity: sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==} @@ -5059,8 +5059,8 @@ packages: peerDependencies: webpack: ^5.1.0 - core-js-compat@3.46.0: - resolution: {integrity: sha512-p9hObIIEENxSV8xIu+V68JjSeARg6UVMG5mR+JEUguG3sI6MsiS1njz2jHmyJDvA+8jX/sytkBHup6kxhM9law==} + core-js-compat@3.47.0: + resolution: {integrity: sha512-IGfuznZ/n7Kp9+nypamBhvwdwLsW6KC8IOaURw2doAK5e98AG3acVLdh0woOnEqCfUtS+Vu882JE4k/DAm3ItQ==} core-util-is@1.0.2: resolution: {integrity: sha512-3lqz5YjWTYnW6dlDa5TLaTCcShfar1e40rmcJVwCBJC6mWlFuj0eCHIElmG1g5kyuJ/GD+8Wn4FFCcz4gJPfaQ==} @@ -5416,8 +5416,8 @@ packages: engines: {node: '>=0.10.0'} hasBin: true - electron-to-chromium@1.5.254: - resolution: {integrity: sha512-DcUsWpVhv9svsKRxnSCZ86SjD+sp32SGidNB37KpqXJncp1mfUgKbHvBomE89WJDbfVKw1mdv5+ikrvd43r+Bg==} + electron-to-chromium@1.5.260: + resolution: {integrity: sha512-ov8rBoOBhVawpzdre+Cmz4FB+y66Eqrk6Gwqd8NGxuhv99GQ8XqMAr351KEkOt7gukXWDg6gJWEMKgL2RLMPtA==} emoji-regex@10.6.0: resolution: {integrity: sha512-toUI84YS5YmxW219erniWD0CIVOo46xGKColeNQRgOzDorgBi1v4D71/OFzgD9GO2UGKIv1C3Sp8DAn0+j5w7A==} @@ -5900,8 +5900,8 @@ packages: resolution: {integrity: sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==} engines: {node: '>= 0.12'} - form-data@4.0.4: - resolution: {integrity: sha512-KrGhL9Q4zjj0kiUt5OO4Mr/A/jlI2jDYs5eHBpYHPcBEVSiipAvn2Ko2HnPe20rmcuuvMHNdZFp+4IlGTMF0Ow==} + form-data@4.0.5: + resolution: {integrity: sha512-8RipRLol37bNs2bhoV67fiTEvdTrbMUYcFTiy3+wuuOnUog2QBHCZWXDRijWQfAkhBj2Uf5UnVaiWwA5vdd82w==} engines: {node: '>= 6'} formdata-polyfill@4.0.10: @@ -6035,14 +6035,13 @@ packages: glob-to-regexp@0.4.1: resolution: {integrity: sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==} - glob@10.4.5: - resolution: {integrity: sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==} + glob@10.5.0: + resolution: {integrity: sha512-DfXN8DfhJ7NH3Oe7cFmu3NCu1wKbkReJ8TorzSAFbSKrlNaQSKfIzqYqVY8zlbs2NLBbWpRiU52GX2PbaBVNkg==} hasBin: true - glob@11.0.3: - resolution: {integrity: sha512-2Nim7dha1KVkaiF4q6Dj+ngPPMdfvLJEOpZk/jKiUAkqKebpGAWQXAq9z1xu9HKu5lWfqw/FASuccEjyznjPaA==} + glob@13.0.0: + resolution: {integrity: sha512-tvZgpqk6fz4BaNZ66ZsRaZnbHvP/jG3uKJvAZOwEVUL4RTA5nJeeLYfyN9/VA8NX/V3IBG+hkeuGpKjvELkVhA==} engines: {node: 20 || >=22} - hasBin: true glob@7.2.3: resolution: {integrity: sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==} @@ -6208,6 +6207,10 @@ packages: resolution: {integrity: sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==} engines: {node: '>= 0.8'} + http-errors@2.0.1: + resolution: {integrity: sha512-4FbRdAX+bSdmo4AUFuS0WNiPz8NgFt+r8ThgNWmlrjQjt1Q7ZR9+zTlce2859x4KSXrwIsaeTqDoKQmtP8pLmQ==} + engines: {node: '>= 0.8'} + http-parser-js@0.5.10: resolution: {integrity: sha512-Pysuw9XpUq5dVc/2SMHpuTY01RFl8fttgcyunjL7eEMhGM3cI4eOmiCycJDVCo/7O7ClfQD3SaI6ftDzqOXYMA==} @@ -6676,10 +6679,6 @@ packages: jackspeak@3.4.3: resolution: {integrity: sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==} - jackspeak@4.1.1: - resolution: {integrity: sha512-zptv57P3GpL+O0I7VdMJNBZCu+BPHVQUk55Ft8/QCJjTVxrnJHuVuX/0Bl2A6/+2oyR/ZMEuFKwmzqqZ/U5nPQ==} - engines: {node: 20 || >=22} - jake@10.9.4: resolution: {integrity: sha512-wpHYzhxiVQL+IV05BLE2Xn34zW1S223hvjtqk0+gsPrwd/8JNLXJgZZM/iPFsYc1xyphF+6M6EvdE5E9MBGkDA==} engines: {node: '>=10'} @@ -7136,9 +7135,9 @@ packages: resolution: {integrity: sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==} engines: {node: '>= 0.6'} - mime-types@3.0.1: - resolution: {integrity: sha512-xRc4oEhT6eaBpU1XF7AjpOFD+xQmXNB5OVKwp4tqCuBpHLS/ZbBDrc07mYTDqVMg6PfxUjjNp85O6Cd2Z/5HWA==} - engines: {node: '>= 0.6'} + mime-types@3.0.2: + resolution: {integrity: sha512-Lbgzdk0h4juoQ9fCKXW4by0UJqj+nOOrI9MJ1sSj4nI8aI2eo1qmvQEie4VD1glsS250n15LsWsYtCugiStS5A==} + engines: {node: '>=18'} mime@1.6.0: resolution: {integrity: sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==} @@ -7751,8 +7750,8 @@ packages: resolution: {integrity: sha512-0u3N7H4+hbr40KjuVn2uNhOcthu/9usKhnw5vT3J7ply79v3D3M8naI00el9Klcy16x557VsEkkUQaHCWFXC/g==} engines: {node: '>=20.x'} - pkce-challenge@5.0.0: - resolution: {integrity: sha512-ueGLflrrnvwB3xuo/uGob5pd5FN7l0MsLf0Z87o/UQmRtwjvfylfc9MurIxRAWywCYTgrvpXBcqjV4OfCYGCIQ==} + pkce-challenge@5.0.1: + resolution: {integrity: sha512-wQ0b/W4Fr01qtpHlqSqspcj3EhBvimsdh0KlHhH8HRZnMsEa0ea2fTULOXOS9ccQr3om+GcGRk4e+isrZWV8qQ==} engines: {node: '>=16.20.0'} pkg-dir@8.0.0: @@ -7919,8 +7918,8 @@ packages: resolution: {integrity: sha512-MRtTAZfQTluz3U2oU/X2VqVWPcR1+94nbA2V6ZrSZRVEwLqZ8eclZ551qGFQD/vD2PYqHJwWOW/fpC721uznVw==} engines: {node: '>=14.1.0'} - puppeteer-core@24.30.0: - resolution: {integrity: sha512-2S3Smy0t0W4wJnNvDe7W0bE7wDmZjfZ3ljfMgJd6hn2Hq/f0jgN+x9PULZo2U3fu5UUIJ+JP8cNUGllu8P91Pg==} + puppeteer-core@24.31.0: + resolution: {integrity: sha512-pnAohhSZipWQoFpXuGV7xCZfaGhqcBR9C4pVrU0QSrcMi7tQMH9J9lDBqBvyMAHQqe8HCARuREqFuVKRQOgTvg==} engines: {node: '>=18'} puppeteer@18.2.1: @@ -7976,8 +7975,8 @@ packages: resolution: {integrity: sha512-8zGqypfENjCIqGhgXToC8aB2r7YrBX+AQAfIPs/Mlk+BtPTztOvTS01NRW/3Eh60J+a48lt8qsCzirQ6loCVfA==} engines: {node: '>= 0.8'} - raw-body@3.0.1: - resolution: {integrity: sha512-9G8cA+tuMS75+6G/TzW8OtLzmBDMo8p1JRxN5AZ+LAp8uxGA8V8GZm4GQ4/N5QNQEnLmg6SS7wyuSmbKepiKqA==} + raw-body@3.0.2: + resolution: {integrity: sha512-K5zQjDllxWkf7Z5xJdV0/B0WTNqx6vxG70zJE4N0kBs4LovmEYWJzQGxC9bS9RAKu3bgM40lrd5zoLJ12MQ5BA==} engines: {node: '>= 0.10'} readable-stream@2.3.8: @@ -8731,15 +8730,15 @@ packages: tldts-core@6.1.86: resolution: {integrity: sha512-Je6p7pkk+KMzMv2XXKmAE3McmolOQFdxkKw0R8EYNr7sELW46JqnNeTX8ybPiQgvg1ymCoF8LXs5fzFaZvJPTA==} - tldts-core@7.0.17: - resolution: {integrity: sha512-DieYoGrP78PWKsrXr8MZwtQ7GLCUeLxihtjC1jZsW1DnvSMdKPitJSe8OSYDM2u5H6g3kWJZpePqkp43TfLh0g==} + tldts-core@7.0.19: + resolution: {integrity: sha512-lJX2dEWx0SGH4O6p+7FPwYmJ/bu1JbcGJ8RLaG9b7liIgZ85itUVEPbMtWRVrde/0fnDPEPHW10ZsKW3kVsE9A==} tldts@6.1.86: resolution: {integrity: sha512-WMi/OQ2axVTf/ykqCQgXiIct+mSQDFdH2fkwhPwgEwvJ1kSzZRiinb0zF2Xb8u4+OqPChmyI6MEu4EezNJz+FQ==} hasBin: true - tldts@7.0.17: - resolution: {integrity: sha512-Y1KQBgDd/NUc+LfOtKS6mNsC9CCaH+m2P1RoIZy7RAPo3C3/t8X45+zgut31cRZtZ3xKPjfn3TkGTrctC2TQIQ==} + tldts@7.0.19: + resolution: {integrity: sha512-8PWx8tvC4jDB39BQw1m4x8y5MH1BcQ5xHeL2n7UVFulMPH/3Q0uiamahFJ3lXA0zO2SUyRXuVVbWSDmstlt9YA==} hasBin: true tmp@0.0.30: @@ -8957,13 +8956,13 @@ packages: unicode-trie@2.0.0: resolution: {integrity: sha512-x7bc76x0bm4prf1VLg79uhAzKw8DVboClSN5VxJuQ+LKDOVEW9CdH+VY7SP+vX7xCYQqzzgQpFqz15zeLvAtZQ==} - unique-filename@4.0.0: - resolution: {integrity: sha512-XSnEewXmQ+veP7xX2dS5Q4yZAvO40cBN2MWkJ7D/6sW4Dg6wYBNwM1Vrnz1FhH5AdeLIlUXRI9e28z1YZi71NQ==} - engines: {node: ^18.17.0 || >=20.5.0} + unique-filename@5.0.0: + resolution: {integrity: sha512-2RaJTAvAb4owyjllTfXzFClJ7WsGxlykkPvCr9pA//LD9goVq+m4PPAeBgNodGZ7nSrntT/auWpJ6Y5IFXcfjg==} + engines: {node: ^20.17.0 || >=22.9.0} - unique-slug@5.0.0: - resolution: {integrity: sha512-9OdaqO5kwqR+1kVgHAhsp5vPNU0hnxRa26rBFNfNgM7M6pNtgzeBn3s/xbyCQL3dcjzOatcef6UUHpB/6MaETg==} - engines: {node: ^18.17.0 || >=20.5.0} + unique-slug@6.0.0: + resolution: {integrity: sha512-4Lup7Ezn8W3d52/xBhZBVdx323ckxa7DEvd9kPQHppTkLoJXw6ltrBCyj5pnrxj0qKDxYMJ56CoxNuFCscdTiw==} + engines: {node: ^20.17.0 || >=22.9.0} universal-github-app-jwt@2.2.2: resolution: {integrity: sha512-dcmbeSrOdTnsjGjUfAlqNDJrhxXizjAz94ija9Qw8YkZ1uu0d+GoZzyH+Jb9tIIqvGsadUfwg+22k5aDqqwzbw==} @@ -9156,8 +9155,8 @@ packages: web-vitals@4.2.4: resolution: {integrity: sha512-r4DIlprAGwJ7YM11VZp4R884m0Vmgr6EAKe3P+kO0PPj3Unqyvv59rczf6UiGcb9Z8QxZVcqKNwv/g0WNdWwsw==} - webdriver-bidi-protocol@0.3.8: - resolution: {integrity: sha512-21Yi2GhGntMc671vNBCjiAeEVknXjVRoyu+k+9xOMShu+ZQfpGQwnBqbNz/Sv4GXZ6JmutlPAi2nIJcrymAWuQ==} + webdriver-bidi-protocol@0.3.9: + resolution: {integrity: sha512-uIYvlRQ0PwtZR1EzHlTMol1G0lAlmOe6wPykF9a77AK3bkpvZHzIVxRE2ThOx5vjy2zISe0zhwf5rzuUfbo1PQ==} webdriver-js-extender@2.1.0: resolution: {integrity: sha512-lcUKrjbBfCK6MNsh7xaY2UAUmZwe+/ib03AjVOpFobX4O7+83BUveSrLfU0Qsyb1DaKJdQRbuU+kM9aZ6QUhiQ==} @@ -9488,10 +9487,10 @@ packages: resolution: {integrity: sha512-CzhO+pFNo8ajLM2d2IW/R93ipy99LWjtwblvC1RsoSUMZgyLbYFr221TnSNT7GjGdYui6P459mw9JH/g/zW2ug==} engines: {node: '>=18'} - zod-to-json-schema@3.24.6: - resolution: {integrity: sha512-h/z3PKvcTcTetyjl1fkj79MHNEjm+HpD6NXheWjzOekY7kV+lwDYnHw+ivHkijnCSMz1yJaWBD9vu/Fcmk+vEg==} + zod-to-json-schema@3.25.0: + resolution: {integrity: sha512-HvWtU2UG41LALjajJrML6uQejQhNJx+JBO9IflpSja4R03iNWfKXrj6W2h7ljuLyc1nKS+9yDyL/9tD1U/yBnQ==} peerDependencies: - zod: ^3.24.1 + zod: ^3.25 || ^4 zod@3.25.76: resolution: {integrity: sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ==} @@ -9504,7 +9503,7 @@ packages: snapshots: - '@acemir/cssom@0.9.23': {} + '@acemir/cssom@0.9.24': {} '@actions/core@1.11.1': dependencies: @@ -9780,7 +9779,7 @@ snapshots: rxjs: 7.8.2 tslib: 2.8.1 - '@asamuzakjp/css-color@4.0.5': + '@asamuzakjp/css-color@4.1.0': dependencies: '@csstools/css-calc': 2.1.4(@csstools/css-parser-algorithms@3.0.5(@csstools/css-tokenizer@3.0.4))(@csstools/css-tokenizer@3.0.4) '@csstools/css-color-parser': 3.1.0(@csstools/css-parser-algorithms@3.0.5(@csstools/css-tokenizer@3.0.4))(@csstools/css-tokenizer@3.0.4) @@ -10439,7 +10438,7 @@ snapshots: babel-plugin-polyfill-corejs2: 0.4.14(@babel/core@7.28.4) babel-plugin-polyfill-corejs3: 0.13.0(@babel/core@7.28.4) babel-plugin-polyfill-regenerator: 0.6.5(@babel/core@7.28.4) - core-js-compat: 3.46.0 + core-js-compat: 3.47.0 semver: 6.3.1 transitivePeerDependencies: - supports-color @@ -10514,7 +10513,7 @@ snapshots: dependencies: '@csstools/css-tokenizer': 3.0.4 - '@csstools/css-syntax-patches-for-csstree@1.0.16': {} + '@csstools/css-syntax-patches-for-csstree@1.0.17': {} '@csstools/css-tokenizer@3.0.4': {} @@ -10526,7 +10525,7 @@ snapshots: combined-stream: 1.0.8 extend: 3.0.2 forever-agent: 0.6.1 - form-data: 4.0.4 + form-data: 4.0.5 http-signature: 1.4.0 is-typedarray: 1.0.0 isstream: 0.1.2 @@ -11649,10 +11648,10 @@ snapshots: eventsource-parser: 3.0.6 express: 5.1.0 express-rate-limit: 7.5.1(express@5.1.0) - pkce-challenge: 5.0.0 - raw-body: 3.0.1 + pkce-challenge: 5.0.1 + raw-body: 3.0.2 zod: 3.25.76 - zod-to-json-schema: 3.24.6(zod@3.25.76) + zod-to-json-schema: 3.25.0(zod@3.25.76) transitivePeerDependencies: - supports-color @@ -11784,7 +11783,7 @@ snapshots: transitivePeerDependencies: - supports-color - '@npmcli/fs@4.0.0': + '@npmcli/fs@5.0.0': dependencies: semver: 7.7.3 @@ -11806,10 +11805,10 @@ snapshots: '@npmcli/node-gyp@5.0.0': {} - '@npmcli/package-json@7.0.2': + '@npmcli/package-json@7.0.4': dependencies: '@npmcli/git': 7.0.1 - glob: 11.0.3 + glob: 13.0.0 hosted-git-info: 9.0.2 json-parse-even-better-errors: 5.0.0 proc-log: 6.0.0 @@ -11829,7 +11828,7 @@ snapshots: '@npmcli/run-script@10.0.3': dependencies: '@npmcli/node-gyp': 5.0.0 - '@npmcli/package-json': 7.0.2 + '@npmcli/package-json': 7.0.4 '@npmcli/promise-spawn': 9.0.1 node-gyp: 12.1.0 proc-log: 6.0.0 @@ -12263,7 +12262,7 @@ snapshots: '@rollup/rollup-win32-x64-msvc@4.52.5': optional: true - '@rollup/wasm-node@4.53.2': + '@rollup/wasm-node@4.53.3': dependencies: '@types/estree': 1.0.8 optionalDependencies: @@ -12309,10 +12308,10 @@ snapshots: '@standard-schema/spec@1.0.0': {} - '@stylistic/eslint-plugin@5.5.0(eslint@9.38.0(jiti@2.6.1))': + '@stylistic/eslint-plugin@5.6.1(eslint@9.38.0(jiti@2.6.1))': dependencies: '@eslint-community/eslint-utils': 4.9.0(eslint@9.38.0(jiti@2.6.1)) - '@typescript-eslint/types': 8.46.4 + '@typescript-eslint/types': 8.48.0 eslint: 9.38.0(jiti@2.6.1) eslint-visitor-keys: 4.2.1 espree: 10.4.0 @@ -12559,7 +12558,7 @@ snapshots: - uglify-js - webpack-cli - '@types/lodash@4.17.20': {} + '@types/lodash@4.17.21': {} '@types/micromatch@2.3.35': dependencies: @@ -12570,7 +12569,7 @@ snapshots: '@types/node-fetch@2.6.13': dependencies: '@types/node': 22.19.1 - form-data: 4.0.4 + form-data: 4.0.5 '@types/node-forge@1.3.14': dependencies: @@ -12763,7 +12762,7 @@ snapshots: '@typescript-eslint/types@8.46.2': {} - '@typescript-eslint/types@8.46.4': {} + '@typescript-eslint/types@8.48.0': {} '@typescript-eslint/typescript-estree@8.46.2(typescript@5.9.3)': dependencies: @@ -13092,7 +13091,7 @@ snapshots: '@web/test-runner-core': 0.13.4(bufferutil@4.0.9) '@web/test-runner-coverage-v8': 0.8.0(bufferutil@4.0.9) chrome-launcher: 0.15.2 - puppeteer-core: 24.30.0(bufferutil@4.0.9) + puppeteer-core: 24.31.0(bufferutil@4.0.9) transitivePeerDependencies: - bare-abort-controller - bare-buffer @@ -13291,7 +13290,7 @@ snapshots: accepts@2.0.0: dependencies: - mime-types: 3.0.1 + mime-types: 3.0.2 negotiator: 1.0.0 acorn-import-phases@1.0.4(acorn@8.15.0): @@ -13517,7 +13516,7 @@ snapshots: autoprefixer@10.4.21(postcss@8.5.6): dependencies: browserslist: 4.28.0 - caniuse-lite: 1.0.30001755 + caniuse-lite: 1.0.30001757 fraction.js: 4.3.7 normalize-range: 0.1.2 picocolors: 1.1.1 @@ -13553,7 +13552,7 @@ snapshots: dependencies: '@babel/core': 7.28.4 '@babel/helper-define-polyfill-provider': 0.6.5(@babel/core@7.28.4) - core-js-compat: 3.46.0 + core-js-compat: 3.47.0 transitivePeerDependencies: - supports-color @@ -13607,7 +13606,7 @@ snapshots: base64id@2.0.0: {} - baseline-browser-mapping@2.8.28: {} + baseline-browser-mapping@2.8.31: {} basic-ftp@5.0.5: {} @@ -13671,16 +13670,16 @@ snapshots: transitivePeerDependencies: - supports-color - body-parser@2.2.0: + body-parser@2.2.1: dependencies: bytes: 3.1.2 content-type: 1.0.5 debug: 4.4.3(supports-color@10.2.2) - http-errors: 2.0.0 - iconv-lite: 0.6.3 + http-errors: 2.0.1 + iconv-lite: 0.7.0 on-finished: 2.4.1 qs: 6.14.0 - raw-body: 3.0.1 + raw-body: 3.0.2 type-is: 2.0.1 transitivePeerDependencies: - supports-color @@ -13769,9 +13768,9 @@ snapshots: browserslist@4.28.0: dependencies: - baseline-browser-mapping: 2.8.28 - caniuse-lite: 1.0.30001755 - electron-to-chromium: 1.5.254 + baseline-browser-mapping: 2.8.31 + caniuse-lite: 1.0.30001757 + electron-to-chromium: 1.5.260 node-releases: 2.0.27 update-browserslist-db: 1.1.4(browserslist@4.28.0) @@ -13809,19 +13808,19 @@ snapshots: bytes@3.1.2: {} - cacache@20.0.1: + cacache@20.0.3: dependencies: - '@npmcli/fs': 4.0.0 + '@npmcli/fs': 5.0.0 fs-minipass: 3.0.3 - glob: 11.0.3 + glob: 13.0.0 lru-cache: 11.2.2 minipass: 7.1.2 minipass-collect: 2.0.1 minipass-flush: 1.0.5 minipass-pipeline: 1.2.4 p-map: 7.0.4 - ssri: 12.0.0 - unique-filename: 4.0.0 + ssri: 13.0.0 + unique-filename: 5.0.0 cache-content-type@1.0.1: dependencies: @@ -13863,7 +13862,7 @@ snapshots: camelcase@6.3.0: {} - caniuse-lite@1.0.30001755: {} + caniuse-lite@1.0.30001757: {} caseless@0.12.0: {} @@ -14090,9 +14089,7 @@ snapshots: dependencies: safe-buffer: 5.2.1 - content-disposition@1.0.0: - dependencies: - safe-buffer: 5.2.1 + content-disposition@1.0.1: {} content-type@1.0.5: {} @@ -14132,7 +14129,7 @@ snapshots: tinyglobby: 0.2.15 webpack: 5.102.1(esbuild@0.26.0) - core-js-compat@3.46.0: + core-js-compat@3.47.0: dependencies: browserslist: 4.28.0 @@ -14206,8 +14203,8 @@ snapshots: cssstyle@5.3.3: dependencies: - '@asamuzakjp/css-color': 4.0.5 - '@csstools/css-syntax-patches-for-csstree': 1.0.16 + '@asamuzakjp/css-color': 4.1.0 + '@csstools/css-syntax-patches-for-csstree': 1.0.17 css-tree: 3.1.0 custom-event@1.0.1: {} @@ -14458,7 +14455,7 @@ snapshots: dependencies: jake: 10.9.4 - electron-to-chromium@1.5.254: {} + electron-to-chromium@1.5.260: {} emoji-regex@10.6.0: {} @@ -14965,8 +14962,8 @@ snapshots: express@5.1.0: dependencies: accepts: 2.0.0 - body-parser: 2.2.0 - content-disposition: 1.0.0 + body-parser: 2.2.1 + content-disposition: 1.0.1 content-type: 1.0.5 cookie: 0.7.2 cookie-signature: 1.2.2 @@ -14976,9 +14973,9 @@ snapshots: etag: 1.8.1 finalhandler: 2.1.0 fresh: 2.0.0 - http-errors: 2.0.0 + http-errors: 2.0.1 merge-descriptors: 2.0.0 - mime-types: 3.0.1 + mime-types: 3.0.2 on-finished: 2.4.1 once: 1.4.0 parseurl: 1.3.3 @@ -14998,7 +14995,7 @@ snapshots: extract-zip@2.0.1: dependencies: - debug: 4.4.3(supports-color@10.2.2) + debug: 4.3.4 get-stream: 5.2.0 yauzl: 2.10.0 optionalDependencies: @@ -15203,7 +15200,7 @@ snapshots: combined-stream: 1.0.8 mime-types: 2.1.35 - form-data@4.0.4: + form-data@4.0.5: dependencies: asynckit: 0.4.0 combined-stream: 1.0.8 @@ -15354,7 +15351,7 @@ snapshots: glob-to-regexp@0.4.1: {} - glob@10.4.5: + glob@10.5.0: dependencies: foreground-child: 3.3.1 jackspeak: 3.4.3 @@ -15363,13 +15360,10 @@ snapshots: package-json-from-dist: 1.0.1 path-scurry: 1.11.1 - glob@11.0.3: + glob@13.0.0: dependencies: - foreground-child: 3.3.1 - jackspeak: 4.1.1 minimatch: 10.1.1 minipass: 7.1.2 - package-json-from-dist: 1.0.1 path-scurry: 2.0.1 glob@7.2.3: @@ -15589,6 +15583,14 @@ snapshots: statuses: 2.0.1 toidentifier: 1.0.1 + http-errors@2.0.1: + dependencies: + depd: 2.0.0 + inherits: 2.0.4 + setprototypeof: 1.2.0 + statuses: 2.0.2 + toidentifier: 1.0.1 + http-parser-js@0.5.10: {} http-proxy-agent@5.0.0(supports-color@10.2.2): @@ -16040,10 +16042,6 @@ snapshots: optionalDependencies: '@pkgjs/parseargs': 0.11.0 - jackspeak@4.1.1: - dependencies: - '@isaacs/cliui': 8.0.2 - jake@10.9.4: dependencies: async: 3.2.6 @@ -16073,7 +16071,7 @@ snapshots: jasmine@5.12.0: dependencies: - glob: 10.4.5 + glob: 10.5.0 jasmine-core: 5.12.1 jasminewd2@2.2.0: {} @@ -16104,7 +16102,7 @@ snapshots: jsdom@27.1.0(bufferutil@4.0.9)(utf-8-validate@6.0.5): dependencies: - '@acemir/cssom': 0.9.23 + '@acemir/cssom': 0.9.24 '@asamuzakjp/dom-selector': 6.7.4 cssstyle: 5.3.3 data-urls: 6.0.0 @@ -16559,7 +16557,7 @@ snapshots: make-fetch-happen@15.0.3: dependencies: '@npmcli/agent': 4.0.0 - cacache: 20.0.1 + cacache: 20.0.3 http-cache-semantics: 4.2.0 minipass: 7.1.2 minipass-fetch: 5.0.0 @@ -16616,7 +16614,7 @@ snapshots: dependencies: mime-db: 1.52.0 - mime-types@3.0.1: + mime-types@3.0.2: dependencies: mime-db: 1.54.0 @@ -16777,7 +16775,7 @@ snapshots: '@ampproject/remapping': 2.3.0 '@angular/compiler-cli': 21.0.1(@angular/compiler@21.0.1)(typescript@5.9.3) '@rollup/plugin-json': 6.1.0(rollup@4.52.5) - '@rollup/wasm-node': 4.53.2 + '@rollup/wasm-node': 4.53.3 ajv: 8.17.1 ansi-colors: 4.1.3 browserslist: 4.28.0 @@ -17108,10 +17106,10 @@ snapshots: dependencies: '@npmcli/git': 7.0.1 '@npmcli/installed-package-contents': 3.0.0 - '@npmcli/package-json': 7.0.2 + '@npmcli/package-json': 7.0.4 '@npmcli/promise-spawn': 8.0.3 '@npmcli/run-script': 10.0.3 - cacache: 20.0.1 + cacache: 20.0.3 fs-minipass: 3.0.3 minipass: 7.1.2 npm-package-arg: 13.0.1 @@ -17249,7 +17247,7 @@ snapshots: optionalDependencies: '@napi-rs/nice': 1.1.1 - pkce-challenge@5.0.0: {} + pkce-challenge@5.0.1: {} pkg-dir@8.0.0: dependencies: @@ -17447,14 +17445,14 @@ snapshots: - supports-color - utf-8-validate - puppeteer-core@24.30.0(bufferutil@4.0.9): + puppeteer-core@24.31.0(bufferutil@4.0.9): dependencies: '@puppeteer/browsers': 2.10.13 chromium-bidi: 11.0.0(devtools-protocol@0.0.1521046) debug: 4.4.3(supports-color@10.2.2) devtools-protocol: 0.0.1521046 typed-query-selector: 2.12.0 - webdriver-bidi-protocol: 0.3.8 + webdriver-bidi-protocol: 0.3.9 ws: 8.18.3(bufferutil@4.0.9)(utf-8-validate@6.0.5) transitivePeerDependencies: - bare-abort-controller @@ -17528,10 +17526,10 @@ snapshots: iconv-lite: 0.4.24 unpipe: 1.0.0 - raw-body@3.0.1: + raw-body@3.0.2: dependencies: bytes: 3.1.2 - http-errors: 2.0.0 + http-errors: 2.0.1 iconv-lite: 0.7.0 unpipe: 1.0.0 @@ -17722,7 +17720,7 @@ snapshots: rimraf@5.0.10: dependencies: - glob: 10.4.5 + glob: 10.5.0 rolldown@1.0.0-beta.47: dependencies: @@ -17941,8 +17939,8 @@ snapshots: escape-html: 1.0.3 etag: 1.8.1 fresh: 2.0.0 - http-errors: 2.0.0 - mime-types: 3.0.1 + http-errors: 2.0.1 + mime-types: 3.0.2 ms: 2.1.3 on-finished: 2.4.1 range-parser: 1.2.1 @@ -18518,15 +18516,15 @@ snapshots: tldts-core@6.1.86: {} - tldts-core@7.0.17: {} + tldts-core@7.0.19: {} tldts@6.1.86: dependencies: tldts-core: 6.1.86 - tldts@7.0.17: + tldts@7.0.19: dependencies: - tldts-core: 7.0.17 + tldts-core: 7.0.19 tmp@0.0.30: dependencies: @@ -18553,7 +18551,7 @@ snapshots: tough-cookie@6.0.0: dependencies: - tldts: 7.0.17 + tldts: 7.0.19 tr46@0.0.3: {} @@ -18644,7 +18642,7 @@ snapshots: dependencies: content-type: 1.0.5 media-typer: 1.1.0 - mime-types: 3.0.1 + mime-types: 3.0.2 typed-array-buffer@1.0.3: dependencies: @@ -18747,11 +18745,11 @@ snapshots: pako: 0.2.9 tiny-inflate: 1.0.3 - unique-filename@4.0.0: + unique-filename@5.0.0: dependencies: - unique-slug: 5.0.0 + unique-slug: 6.0.0 - unique-slug@5.0.0: + unique-slug@6.0.0: dependencies: imurmurhash: 0.1.4 @@ -18961,7 +18959,7 @@ snapshots: web-vitals@4.2.4: {} - webdriver-bidi-protocol@0.3.8: {} + webdriver-bidi-protocol@0.3.9: {} webdriver-js-extender@2.1.0: dependencies: @@ -18992,7 +18990,7 @@ snapshots: dependencies: colorette: 2.0.20 memfs: 4.51.0 - mime-types: 3.0.1 + mime-types: 3.0.2 on-finished: 2.4.1 range-parser: 1.2.1 schema-utils: 4.3.3 @@ -19329,7 +19327,7 @@ snapshots: yoctocolors@2.1.2: {} - zod-to-json-schema@3.24.6(zod@3.25.76): + zod-to-json-schema@3.25.0(zod@3.25.76): dependencies: zod: 3.25.76 From 4aa1f7e4447e01af539637e227530fb90a370cd9 Mon Sep 17 00:00:00 2001 From: Angular Robot Date: Wed, 26 Nov 2025 08:42:48 +0000 Subject: [PATCH 52/54] build: update pnpm to v10.23.0 See associated pull request for more information. --- package.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/package.json b/package.json index 29898c01d075..98f5534c8824 100644 --- a/package.json +++ b/package.json @@ -31,12 +31,12 @@ "type": "git", "url": "https://github.com/angular/angular-cli.git" }, - "packageManager": "pnpm@10.22.0", + "packageManager": "pnpm@10.23.0", "engines": { "node": "^20.19.0 || ^22.12.0 || >=24.0.0", "npm": "Please use pnpm instead of NPM to install dependencies", "yarn": "Please use pnpm instead of Yarn to install dependencies", - "pnpm": "10.22.0" + "pnpm": "10.23.0" }, "author": "Angular Authors", "license": "MIT", From 53092c15cb97e9f67eb316ad15f5d85b5f65325a Mon Sep 17 00:00:00 2001 From: Angular Robot Date: Wed, 26 Nov 2025 15:39:16 +0000 Subject: [PATCH 53/54] 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 | 4 +- .github/workflows/feature-requests.yml | 2 +- .github/workflows/perf.yml | 6 +-- .github/workflows/pr.yml | 44 ++++++++-------- MODULE.bazel | 2 +- MODULE.bazel.lock | 1 - package.json | 2 +- pnpm-lock.yaml | 38 +++++++------- 10 files changed, 76 insertions(+), 77 deletions(-) diff --git a/.github/workflows/assistant-to-the-branch-manager.yml b/.github/workflows/assistant-to-the-branch-manager.yml index e3eb60bd1368..26d7170c03d0 100644 --- a/.github/workflows/assistant-to-the-branch-manager.yml +++ b/.github/workflows/assistant-to-the-branch-manager.yml @@ -16,6 +16,6 @@ jobs: - uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5.0.1 with: persist-credentials: false - - uses: angular/dev-infra/github-actions/branch-manager@f47684669736e28fd77eab64e65b2952c8a948ee + - uses: angular/dev-infra/github-actions/branch-manager@95e3a0ede6dfa1aedd34b03918ad72b18f87e5ae with: angular-robot-key: ${{ secrets.ANGULAR_ROBOT_PRIVATE_KEY }} diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 7f8082f2e5c2..5cae93ad550a 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@f47684669736e28fd77eab64e65b2952c8a948ee + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@95e3a0ede6dfa1aedd34b03918ad72b18f87e5ae - name: Setup Bazel - uses: angular/dev-infra/github-actions/bazel/setup@f47684669736e28fd77eab64e65b2952c8a948ee + uses: angular/dev-infra/github-actions/bazel/setup@95e3a0ede6dfa1aedd34b03918ad72b18f87e5ae - 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@f47684669736e28fd77eab64e65b2952c8a948ee + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@95e3a0ede6dfa1aedd34b03918ad72b18f87e5ae - name: Setup Bazel - uses: angular/dev-infra/github-actions/bazel/setup@f47684669736e28fd77eab64e65b2952c8a948ee + uses: angular/dev-infra/github-actions/bazel/setup@95e3a0ede6dfa1aedd34b03918ad72b18f87e5ae - name: Setup Bazel RBE - uses: angular/dev-infra/github-actions/bazel/configure-remote@f47684669736e28fd77eab64e65b2952c8a948ee + uses: angular/dev-infra/github-actions/bazel/configure-remote@95e3a0ede6dfa1aedd34b03918ad72b18f87e5ae 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@f47684669736e28fd77eab64e65b2952c8a948ee + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@95e3a0ede6dfa1aedd34b03918ad72b18f87e5ae - name: Setup Bazel - uses: angular/dev-infra/github-actions/bazel/setup@f47684669736e28fd77eab64e65b2952c8a948ee + uses: angular/dev-infra/github-actions/bazel/setup@95e3a0ede6dfa1aedd34b03918ad72b18f87e5ae - name: Setup Bazel RBE - uses: angular/dev-infra/github-actions/bazel/configure-remote@f47684669736e28fd77eab64e65b2952c8a948ee + uses: angular/dev-infra/github-actions/bazel/configure-remote@95e3a0ede6dfa1aedd34b03918ad72b18f87e5ae with: google_credential: ${{ secrets.RBE_TRUSTED_BUILDS_USER }} - name: Install node modules @@ -85,13 +85,13 @@ jobs: runs-on: ${{ matrix.os }} steps: - name: Initialize environment - uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@f47684669736e28fd77eab64e65b2952c8a948ee + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@95e3a0ede6dfa1aedd34b03918ad72b18f87e5ae - name: Install node modules run: pnpm install --frozen-lockfile - name: Setup Bazel - uses: angular/dev-infra/github-actions/bazel/setup@f47684669736e28fd77eab64e65b2952c8a948ee + uses: angular/dev-infra/github-actions/bazel/setup@95e3a0ede6dfa1aedd34b03918ad72b18f87e5ae - name: Setup Bazel RBE - uses: angular/dev-infra/github-actions/bazel/configure-remote@f47684669736e28fd77eab64e65b2952c8a948ee + uses: angular/dev-infra/github-actions/bazel/configure-remote@95e3a0ede6dfa1aedd34b03918ad72b18f87e5ae with: google_credential: ${{ secrets.RBE_TRUSTED_BUILDS_USER }} - name: Run CLI E2E tests @@ -101,11 +101,11 @@ jobs: runs-on: ubuntu-latest steps: - name: Initialize environment - uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@f47684669736e28fd77eab64e65b2952c8a948ee + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@95e3a0ede6dfa1aedd34b03918ad72b18f87e5ae - name: Setup Bazel - uses: angular/dev-infra/github-actions/bazel/setup@f47684669736e28fd77eab64e65b2952c8a948ee + uses: angular/dev-infra/github-actions/bazel/setup@95e3a0ede6dfa1aedd34b03918ad72b18f87e5ae - name: Setup Bazel RBE - uses: angular/dev-infra/github-actions/bazel/configure-remote@f47684669736e28fd77eab64e65b2952c8a948ee + uses: angular/dev-infra/github-actions/bazel/configure-remote@95e3a0ede6dfa1aedd34b03918ad72b18f87e5ae with: google_credential: ${{ secrets.RBE_TRUSTED_BUILDS_USER }} - name: Install node modules @@ -139,7 +139,7 @@ jobs: runs-on: ${{ matrix.os }} steps: - name: Initialize environment - uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@f47684669736e28fd77eab64e65b2952c8a948ee + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@95e3a0ede6dfa1aedd34b03918ad72b18f87e5ae - name: Install node modules run: pnpm install --frozen-lockfile - name: Download built Windows E2E tests @@ -167,13 +167,13 @@ jobs: runs-on: ${{ matrix.os }} steps: - name: Initialize environment - uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@f47684669736e28fd77eab64e65b2952c8a948ee + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@95e3a0ede6dfa1aedd34b03918ad72b18f87e5ae - name: Install node modules run: pnpm install --frozen-lockfile - name: Setup Bazel - uses: angular/dev-infra/github-actions/bazel/setup@f47684669736e28fd77eab64e65b2952c8a948ee + uses: angular/dev-infra/github-actions/bazel/setup@95e3a0ede6dfa1aedd34b03918ad72b18f87e5ae - name: Setup Bazel RBE - uses: angular/dev-infra/github-actions/bazel/configure-remote@f47684669736e28fd77eab64e65b2952c8a948ee + uses: angular/dev-infra/github-actions/bazel/configure-remote@95e3a0ede6dfa1aedd34b03918ad72b18f87e5ae with: google_credential: ${{ secrets.RBE_TRUSTED_BUILDS_USER }} - name: Run CLI E2E tests @@ -192,13 +192,13 @@ jobs: runs-on: ${{ matrix.os }} steps: - name: Initialize environment - uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@f47684669736e28fd77eab64e65b2952c8a948ee + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@95e3a0ede6dfa1aedd34b03918ad72b18f87e5ae - name: Install node modules run: pnpm install --frozen-lockfile - name: Setup Bazel - uses: angular/dev-infra/github-actions/bazel/setup@f47684669736e28fd77eab64e65b2952c8a948ee + uses: angular/dev-infra/github-actions/bazel/setup@95e3a0ede6dfa1aedd34b03918ad72b18f87e5ae - name: Setup Bazel RBE - uses: angular/dev-infra/github-actions/bazel/configure-remote@f47684669736e28fd77eab64e65b2952c8a948ee + uses: angular/dev-infra/github-actions/bazel/configure-remote@95e3a0ede6dfa1aedd34b03918ad72b18f87e5ae with: google_credential: ${{ secrets.RBE_TRUSTED_BUILDS_USER }} - name: Run CLI E2E tests @@ -212,13 +212,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@f47684669736e28fd77eab64e65b2952c8a948ee + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@95e3a0ede6dfa1aedd34b03918ad72b18f87e5ae - name: Install node modules run: pnpm install --frozen-lockfile - name: Setup Bazel - uses: angular/dev-infra/github-actions/bazel/setup@f47684669736e28fd77eab64e65b2952c8a948ee + uses: angular/dev-infra/github-actions/bazel/setup@95e3a0ede6dfa1aedd34b03918ad72b18f87e5ae - name: Setup Bazel RBE - uses: angular/dev-infra/github-actions/bazel/configure-remote@f47684669736e28fd77eab64e65b2952c8a948ee + uses: angular/dev-infra/github-actions/bazel/configure-remote@95e3a0ede6dfa1aedd34b03918ad72b18f87e5ae with: google_credential: ${{ secrets.RBE_TRUSTED_BUILDS_USER }} - name: Run E2E Browser tests @@ -248,11 +248,11 @@ jobs: CIRCLE_BRANCH: ${{ github.ref_name }} steps: - name: Initialize environment - uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@f47684669736e28fd77eab64e65b2952c8a948ee + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@95e3a0ede6dfa1aedd34b03918ad72b18f87e5ae - name: Install node modules run: pnpm install --frozen-lockfile - name: Setup Bazel - uses: angular/dev-infra/github-actions/bazel/setup@f47684669736e28fd77eab64e65b2952c8a948ee + uses: angular/dev-infra/github-actions/bazel/setup@95e3a0ede6dfa1aedd34b03918ad72b18f87e5ae - 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 0b0997b0d9f0..b53a65d9956b 100644 --- a/.github/workflows/dev-infra.yml +++ b/.github/workflows/dev-infra.yml @@ -13,13 +13,13 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5.0.1 - - uses: angular/dev-infra/github-actions/pull-request-labeling@f47684669736e28fd77eab64e65b2952c8a948ee + - uses: angular/dev-infra/github-actions/pull-request-labeling@95e3a0ede6dfa1aedd34b03918ad72b18f87e5ae with: angular-robot-key: ${{ secrets.ANGULAR_ROBOT_PRIVATE_KEY }} post_approval_changes: runs-on: ubuntu-latest steps: - uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5.0.1 - - uses: angular/dev-infra/github-actions/post-approval-changes@f47684669736e28fd77eab64e65b2952c8a948ee + - uses: angular/dev-infra/github-actions/post-approval-changes@95e3a0ede6dfa1aedd34b03918ad72b18f87e5ae with: angular-robot-key: ${{ secrets.ANGULAR_ROBOT_PRIVATE_KEY }} diff --git a/.github/workflows/feature-requests.yml b/.github/workflows/feature-requests.yml index 5d29b9ef151f..dab00bf96bc2 100644 --- a/.github/workflows/feature-requests.yml +++ b/.github/workflows/feature-requests.yml @@ -16,6 +16,6 @@ jobs: if: github.repository == 'angular/angular-cli' runs-on: ubuntu-latest steps: - - uses: angular/dev-infra/github-actions/feature-request@f47684669736e28fd77eab64e65b2952c8a948ee + - uses: angular/dev-infra/github-actions/feature-request@95e3a0ede6dfa1aedd34b03918ad72b18f87e5ae with: angular-robot-key: ${{ secrets.ANGULAR_ROBOT_PRIVATE_KEY }} diff --git a/.github/workflows/perf.yml b/.github/workflows/perf.yml index a1e0f8dad657..5e7bb8afa786 100644 --- a/.github/workflows/perf.yml +++ b/.github/workflows/perf.yml @@ -23,7 +23,7 @@ jobs: workflows: ${{ steps.workflows.outputs.workflows }} steps: - name: Initialize environment - uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@f47684669736e28fd77eab64e65b2952c8a948ee + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@95e3a0ede6dfa1aedd34b03918ad72b18f87e5ae - name: Install node modules run: pnpm install --frozen-lockfile - id: workflows @@ -38,9 +38,9 @@ jobs: workflow: ${{ fromJSON(needs.list.outputs.workflows) }} steps: - name: Initialize environment - uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@f47684669736e28fd77eab64e65b2952c8a948ee + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@95e3a0ede6dfa1aedd34b03918ad72b18f87e5ae - name: Setup Bazel - uses: angular/dev-infra/github-actions/bazel/setup@f47684669736e28fd77eab64e65b2952c8a948ee + uses: angular/dev-infra/github-actions/bazel/setup@95e3a0ede6dfa1aedd34b03918ad72b18f87e5ae - 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 92f048b60a3f..d0c220417222 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@f47684669736e28fd77eab64e65b2952c8a948ee + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@95e3a0ede6dfa1aedd34b03918ad72b18f87e5ae - name: Setup Bazel - uses: angular/dev-infra/github-actions/bazel/setup@f47684669736e28fd77eab64e65b2952c8a948ee + uses: angular/dev-infra/github-actions/bazel/setup@95e3a0ede6dfa1aedd34b03918ad72b18f87e5ae - name: Setup ESLint Caching uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.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@f47684669736e28fd77eab64e65b2952c8a948ee + uses: angular/dev-infra/github-actions/linting/licenses@95e3a0ede6dfa1aedd34b03918ad72b18f87e5ae build: runs-on: ubuntu-latest steps: - name: Initialize environment - uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@f47684669736e28fd77eab64e65b2952c8a948ee + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@95e3a0ede6dfa1aedd34b03918ad72b18f87e5ae - name: Setup Bazel - uses: angular/dev-infra/github-actions/bazel/setup@f47684669736e28fd77eab64e65b2952c8a948ee + uses: angular/dev-infra/github-actions/bazel/setup@95e3a0ede6dfa1aedd34b03918ad72b18f87e5ae - name: Setup Bazel RBE - uses: angular/dev-infra/github-actions/bazel/configure-remote@f47684669736e28fd77eab64e65b2952c8a948ee + uses: angular/dev-infra/github-actions/bazel/configure-remote@95e3a0ede6dfa1aedd34b03918ad72b18f87e5ae - 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@f47684669736e28fd77eab64e65b2952c8a948ee + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@95e3a0ede6dfa1aedd34b03918ad72b18f87e5ae - name: Setup Bazel - uses: angular/dev-infra/github-actions/bazel/setup@f47684669736e28fd77eab64e65b2952c8a948ee + uses: angular/dev-infra/github-actions/bazel/setup@95e3a0ede6dfa1aedd34b03918ad72b18f87e5ae - name: Setup Bazel RBE - uses: angular/dev-infra/github-actions/bazel/configure-remote@f47684669736e28fd77eab64e65b2952c8a948ee + uses: angular/dev-infra/github-actions/bazel/configure-remote@95e3a0ede6dfa1aedd34b03918ad72b18f87e5ae - name: Install node modules run: pnpm install --frozen-lockfile - name: Run module and package tests @@ -115,13 +115,13 @@ jobs: runs-on: ${{ matrix.os }} steps: - name: Initialize environment - uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@f47684669736e28fd77eab64e65b2952c8a948ee + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@95e3a0ede6dfa1aedd34b03918ad72b18f87e5ae - name: Install node modules run: pnpm install --frozen-lockfile - name: Setup Bazel - uses: angular/dev-infra/github-actions/bazel/setup@f47684669736e28fd77eab64e65b2952c8a948ee + uses: angular/dev-infra/github-actions/bazel/setup@95e3a0ede6dfa1aedd34b03918ad72b18f87e5ae - name: Setup Bazel RBE - uses: angular/dev-infra/github-actions/bazel/configure-remote@f47684669736e28fd77eab64e65b2952c8a948ee + uses: angular/dev-infra/github-actions/bazel/configure-remote@95e3a0ede6dfa1aedd34b03918ad72b18f87e5ae - 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/legacy-cli:e2e.${{ matrix.subset }}_node${{ matrix.node }} @@ -129,11 +129,11 @@ jobs: runs-on: ubuntu-latest steps: - name: Initialize environment - uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@f47684669736e28fd77eab64e65b2952c8a948ee + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@95e3a0ede6dfa1aedd34b03918ad72b18f87e5ae - name: Setup Bazel - uses: angular/dev-infra/github-actions/bazel/setup@f47684669736e28fd77eab64e65b2952c8a948ee + uses: angular/dev-infra/github-actions/bazel/setup@95e3a0ede6dfa1aedd34b03918ad72b18f87e5ae - name: Setup Bazel RBE - uses: angular/dev-infra/github-actions/bazel/configure-remote@f47684669736e28fd77eab64e65b2952c8a948ee + uses: angular/dev-infra/github-actions/bazel/configure-remote@95e3a0ede6dfa1aedd34b03918ad72b18f87e5ae - name: Install node modules run: pnpm install --frozen-lockfile - name: Build E2E tests for Windows on Linux @@ -157,7 +157,7 @@ jobs: runs-on: windows-2025 steps: - name: Initialize environment - uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@f47684669736e28fd77eab64e65b2952c8a948ee + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@95e3a0ede6dfa1aedd34b03918ad72b18f87e5ae - name: Install node modules run: pnpm install --frozen-lockfile - name: Download built Windows E2E tests @@ -185,13 +185,13 @@ jobs: runs-on: ${{ matrix.os }} steps: - name: Initialize environment - uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@f47684669736e28fd77eab64e65b2952c8a948ee + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@95e3a0ede6dfa1aedd34b03918ad72b18f87e5ae - name: Install node modules run: pnpm install --frozen-lockfile - name: Setup Bazel - uses: angular/dev-infra/github-actions/bazel/setup@f47684669736e28fd77eab64e65b2952c8a948ee + uses: angular/dev-infra/github-actions/bazel/setup@95e3a0ede6dfa1aedd34b03918ad72b18f87e5ae - name: Setup Bazel RBE - uses: angular/dev-infra/github-actions/bazel/configure-remote@f47684669736e28fd77eab64e65b2952c8a948ee + uses: angular/dev-infra/github-actions/bazel/configure-remote@95e3a0ede6dfa1aedd34b03918ad72b18f87e5ae - 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/legacy-cli:e2e.${{ matrix.subset }}_node${{ matrix.node }} @@ -208,12 +208,12 @@ jobs: runs-on: ${{ matrix.os }} steps: - name: Initialize environment - uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@f47684669736e28fd77eab64e65b2952c8a948ee + uses: angular/dev-infra/github-actions/npm/checkout-and-setup-node@95e3a0ede6dfa1aedd34b03918ad72b18f87e5ae - name: Install node modules run: pnpm install --frozen-lockfile - name: Setup Bazel - uses: angular/dev-infra/github-actions/bazel/setup@f47684669736e28fd77eab64e65b2952c8a948ee + uses: angular/dev-infra/github-actions/bazel/setup@95e3a0ede6dfa1aedd34b03918ad72b18f87e5ae - name: Setup Bazel RBE - uses: angular/dev-infra/github-actions/bazel/configure-remote@f47684669736e28fd77eab64e65b2952c8a948ee + uses: angular/dev-infra/github-actions/bazel/configure-remote@95e3a0ede6dfa1aedd34b03918ad72b18f87e5ae - 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/legacy-cli:e2e.snapshots.${{ matrix.subset }}_node${{ matrix.node }} diff --git a/MODULE.bazel b/MODULE.bazel index bc46e7ed3675..fada853c7a71 100644 --- a/MODULE.bazel +++ b/MODULE.bazel @@ -33,7 +33,7 @@ git_override( bazel_dep(name = "devinfra") git_override( module_name = "devinfra", - commit = "f47684669736e28fd77eab64e65b2952c8a948ee", + commit = "95e3a0ede6dfa1aedd34b03918ad72b18f87e5ae", remote = "https://github.com/angular/dev-infra.git", ) diff --git a/MODULE.bazel.lock b/MODULE.bazel.lock index 6f5d406a120b..71d6aa83b976 100644 --- a/MODULE.bazel.lock +++ b/MODULE.bazel.lock @@ -28,7 +28,6 @@ "https://bcr.bazel.build/modules/aspect_rules_js/2.0.0/MODULE.bazel": "b45b507574aa60a92796e3e13c195cd5744b3b8aff516a9c0cb5ae6a048161c5", "https://bcr.bazel.build/modules/aspect_rules_js/2.4.2/MODULE.bazel": "0d01db38b96d25df7ed952a5e96eac4b3802723d146961974bf020f6dd07591d", "https://bcr.bazel.build/modules/aspect_rules_js/2.6.2/MODULE.bazel": "ed2a871f4ab8fbde0cab67c425745069d84ea64b64313fa1a2954017326511f5", - "https://bcr.bazel.build/modules/aspect_rules_js/2.8.1/MODULE.bazel": "edcde75a1357952d3acedb6f3622614c87f730927d753af77b36c604ff407f0d", "https://bcr.bazel.build/modules/aspect_rules_js/2.8.2/MODULE.bazel": "76526405d6a65dae45db16b8b4619b502063ac573d2a2ae0a90fddc7d3247288", "https://bcr.bazel.build/modules/aspect_rules_js/2.8.2/source.json": "a03164e3f59a05d9a6d205a477ea49ba8ee141ab764a9f38b43e6302eb4fa2b9", "https://bcr.bazel.build/modules/aspect_rules_ts/3.6.3/MODULE.bazel": "d09db394970f076176ce7bab5b5fa7f0d560fd4f30b8432ea5e2c2570505b130", diff --git a/package.json b/package.json index 98f5534c8824..14e9cafef45d 100644 --- a/package.json +++ b/package.json @@ -54,7 +54,7 @@ "@angular/forms": "21.0.1", "@angular/localize": "21.0.1", "@angular/material": "21.0.0", - "@angular/ng-dev": "https://github.com/angular/dev-infra-private-ng-dev-builds.git#e0bb3b2b000ff0c0c18a2020d5d42371bca51ecf", + "@angular/ng-dev": "https://github.com/angular/dev-infra-private-ng-dev-builds.git#4c28145df03aff8c74d0a53f4f5602140e4d1a23", "@angular/platform-browser": "21.0.1", "@angular/platform-server": "21.0.1", "@angular/router": "21.0.1", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 377ba910c50b..adec08d1979f 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -47,8 +47,8 @@ importers: specifier: 21.0.0 version: 21.0.0(8e7b236207d28338fccf527c5c162c22) '@angular/ng-dev': - specifier: https://github.com/angular/dev-infra-private-ng-dev-builds.git#e0bb3b2b000ff0c0c18a2020d5d42371bca51ecf - version: https://codeload.github.com/angular/dev-infra-private-ng-dev-builds/tar.gz/e0bb3b2b000ff0c0c18a2020d5d42371bca51ecf(@modelcontextprotocol/sdk@1.20.1) + specifier: https://github.com/angular/dev-infra-private-ng-dev-builds.git#4c28145df03aff8c74d0a53f4f5602140e4d1a23 + version: https://codeload.github.com/angular/dev-infra-private-ng-dev-builds/tar.gz/4c28145df03aff8c74d0a53f4f5602140e4d1a23(@modelcontextprotocol/sdk@1.20.1) '@angular/platform-browser': specifier: 21.0.1 version: 21.0.1(@angular/animations@21.0.1(@angular/core@21.0.1(@angular/compiler@21.0.1)(rxjs@7.8.2)(zone.js@0.15.1)))(@angular/common@21.0.1(@angular/core@21.0.1(@angular/compiler@21.0.1)(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/core@21.0.1(@angular/compiler@21.0.1)(rxjs@7.8.2)(zone.js@0.15.1)) @@ -1060,9 +1060,9 @@ packages: '@angular/platform-browser': ^21.0.0 || ^22.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/e0bb3b2b000ff0c0c18a2020d5d42371bca51ecf': - resolution: {tarball: https://codeload.github.com/angular/dev-infra-private-ng-dev-builds/tar.gz/e0bb3b2b000ff0c0c18a2020d5d42371bca51ecf} - version: 0.0.0-f47684669736e28fd77eab64e65b2952c8a948ee + '@angular/ng-dev@https://codeload.github.com/angular/dev-infra-private-ng-dev-builds/tar.gz/4c28145df03aff8c74d0a53f4f5602140e4d1a23': + resolution: {tarball: https://codeload.github.com/angular/dev-infra-private-ng-dev-builds/tar.gz/4c28145df03aff8c74d0a53f4f5602140e4d1a23} + version: 0.0.0-95e3a0ede6dfa1aedd34b03918ad72b18f87e5ae hasBin: true '@angular/platform-browser@21.0.1': @@ -3141,8 +3141,8 @@ packages: resolution: {integrity: sha512-4zCpzP1fWc7QlqunZ5bSEjxc6yLAlRTnDwKtgXfcI/FxxGoqedDG8V2+xJ60bV2kODqcGB+nATdtap/XYq2NZQ==} engines: {node: '>= 20'} - '@octokit/graphql-schema@15.26.0': - resolution: {integrity: sha512-SoVbh+sXe9nsoweFbLT3tAk3XWYbYLs5ku05wij1zhyQ2U3lewdrhjo5Tb7lfaOGWNHSkPZT4uuPZp8neF7P7A==} + '@octokit/graphql-schema@15.26.1': + resolution: {integrity: sha512-RFDC2MpRBd4AxSRvUeBIVeBU7ojN/SxDfALUd7iVYOSeEK3gZaqR2MGOysj4Zh2xj2RY5fQAUT+Oqq7hWTraMA==} '@octokit/graphql@9.0.3': resolution: {integrity: sha512-grAEuupr/C1rALFnXTv6ZQhFuL1D8G5y8CN04RgrO4FIPMrtm+mcZzFG7dcBm+nq+1ppNixu+Jd78aeJOYxlGA==} @@ -3324,16 +3324,16 @@ packages: resolution: {integrity: sha512-tNe7a6U4rCpxLMBaR0SIYTdjxGdL0Vwb3G1zY8++sPtHSvy7qd54u8CIB0Z+Y6t5tc9pNYMYCMwhE/wdSY7ltg==} engines: {node: '>=18.12'} - '@pnpm/dependency-path@1001.1.4': - resolution: {integrity: sha512-AUFsnxZB13ME7JKFis3/zo+Cz4qvYl7PzpzFFrw0bL75OY2+jeXcG3dbNXoVfpjaA3/lyZBtQmxE+Q6xbjyV5Q==} + '@pnpm/dependency-path@1001.1.5': + resolution: {integrity: sha512-powgYgNzuAdrZK+bx1Vxes5LRFp8ByUCcFsCeo0pQpyFbKpRDFF31FUVSE3CGs61WgL0lTBQr7ZoUSRc+BDrCw==} engines: {node: '>=18.12'} '@pnpm/graceful-fs@1000.0.1': resolution: {integrity: sha512-JnzaAVFJIEgwTcB55eww8N3h5B6qJdZqDA2wYkSK+OcTvvMSQb9c2STMhBP6GfkWygG1fs3w8D7JRx9SPZnxJg==} engines: {node: '>=18.12'} - '@pnpm/types@1001.0.0': - resolution: {integrity: sha512-9P7I8Zv8hvAO81+D5KVmwveH4nmxhBNFEEeb77YYPV72bkyqzKTR6I8OGEs7TNZ6gPHufF+lIyBVEqO6SMFpJA==} + '@pnpm/types@1001.0.1': + resolution: {integrity: sha512-v5X09E6LkJFOOw9FgGITpAs7nQJtx6u3N0SNtyIC5mSeIC5SebMrrelpCz6QUTJvyXBEa1AWj2dZhYfLj59xhA==} engines: {node: '>=18.12'} '@protobufjs/aspromise@1.1.2': @@ -9687,7 +9687,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/e0bb3b2b000ff0c0c18a2020d5d42371bca51ecf(@modelcontextprotocol/sdk@1.20.1)': + '@angular/ng-dev@https://codeload.github.com/angular/dev-infra-private-ng-dev-builds/tar.gz/4c28145df03aff8c74d0a53f4f5602140e4d1a23(@modelcontextprotocol/sdk@1.20.1)': dependencies: '@actions/core': 1.11.1 '@google-cloud/spanner': 8.0.0(supports-color@10.2.2) @@ -9697,14 +9697,14 @@ snapshots: '@octokit/auth-app': 8.1.2 '@octokit/core': 7.0.6 '@octokit/graphql': 9.0.3 - '@octokit/graphql-schema': 15.26.0 + '@octokit/graphql-schema': 15.26.1 '@octokit/openapi-types': 27.0.0 '@octokit/plugin-paginate-rest': 14.0.0(@octokit/core@7.0.6) '@octokit/plugin-rest-endpoint-methods': 17.0.0(@octokit/core@7.0.6) '@octokit/request-error': 7.1.0 '@octokit/rest': 22.0.1 '@octokit/types': 16.0.0 - '@pnpm/dependency-path': 1001.1.4 + '@pnpm/dependency-path': 1001.1.5 '@types/cli-progress': 3.11.6 '@types/ejs': 3.1.5 '@types/events': 3.0.3 @@ -11887,7 +11887,7 @@ snapshots: '@octokit/types': 16.0.0 universal-user-agent: 7.0.3 - '@octokit/graphql-schema@15.26.0': + '@octokit/graphql-schema@15.26.1': dependencies: graphql: 16.12.0 graphql-tag: 2.12.6(graphql@16.12.0) @@ -12042,17 +12042,17 @@ snapshots: '@pnpm/crypto.polyfill@1000.1.0': {} - '@pnpm/dependency-path@1001.1.4': + '@pnpm/dependency-path@1001.1.5': dependencies: '@pnpm/crypto.hash': 1000.2.1 - '@pnpm/types': 1001.0.0 + '@pnpm/types': 1001.0.1 semver: 7.7.3 '@pnpm/graceful-fs@1000.0.1': dependencies: graceful-fs: 4.2.11 - '@pnpm/types@1001.0.0': {} + '@pnpm/types@1001.0.1': {} '@protobufjs/aspromise@1.1.2': {} @@ -14995,7 +14995,7 @@ snapshots: extract-zip@2.0.1: dependencies: - debug: 4.3.4 + debug: 4.4.3(supports-color@10.2.2) get-stream: 5.2.0 yauzl: 2.10.0 optionalDependencies: From e09d9a57156f136aff38d48fb3fce94e21570da6 Mon Sep 17 00:00:00 2001 From: Charles Lyding <19598772+clydin@users.noreply.github.com> Date: Wed, 26 Nov 2025 11:29:25 -0500 Subject: [PATCH 54/54] release: cut the v21.0.1 release --- CHANGELOG.md | 44 ++++++++++++++++++++++++++++++++++++++++++++ package.json | 2 +- 2 files changed, 45 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 6fe7240ec258..ce849578115d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,47 @@ + + +# 21.0.1 (2025-11-26) + +### @angular/cli + +| Commit | Type | Description | +| --------------------------------------------------------------------------------------------------- | ---- | --------------------------------------------------------------------------- | +| [363496ae0](https://github.com/angular/angular-cli/commit/363496ae0d2850545274cd7fe4dc6902ccb64e10) | fix | ensure dependencies are resolved correctly for node modules directory check | + +### @schematics/angular + +| Commit | Type | Description | +| --------------------------------------------------------------------------------------------------- | ---- | ----------------------------------------------------------------------------- | +| [2f58705cb](https://github.com/angular/angular-cli/commit/2f58705cb5389019ceb49616a0e4ec3f92a558ed) | fix | add missing imports for lifecycle hooks in jasmine-vitest migration | +| [c973bb9ca](https://github.com/angular/angular-cli/commit/c973bb9cafc8d59b901a9d763347f4b615257867) | fix | add mock names to createSpyObj transformation | +| [4534c9848](https://github.com/angular/angular-cli/commit/4534c9848745eea516bdb58d86914252c35b5b9c) | fix | do not set `esModuleInterop` and `moduleResolution` when module is `preserve` | +| [16d898e75](https://github.com/angular/angular-cli/commit/16d898e7587036d68786cebe764da08304559d41) | fix | fix migration of `jasmine.clock().mockDate()` | +| [21c3eac72](https://github.com/angular/angular-cli/commit/21c3eac726c198132af760ffacc0dab9dfccb430) | fix | handle createSpyObj without base name on refactor-jasmine-vitest | +| [b8c99aa4c](https://github.com/angular/angular-cli/commit/b8c99aa4c909647285d1dcc61a2bb97a36100c63) | fix | improve safety of done callback transformation | +| [4a71e06fc](https://github.com/angular/angular-cli/commit/4a71e06fcafaadbcb820d285c0c186aa0e92f158) | fix | silently skip when the build target already uses one of the new builders | +| [2ffdae421](https://github.com/angular/angular-cli/commit/2ffdae42149b0f3da44f96271af1bca6d09b7ed5) | fix | support testRunner option in library schematic | +| [145de4a58](https://github.com/angular/angular-cli/commit/145de4a584ce8f72746704547282299306d9bafb) | fix | warn about loose matching in arrayWithExactContents | + +### @angular/build + +| Commit | Type | Description | +| --------------------------------------------------------------------------------------------------- | ---- | -------------------------------------------------------------- | +| [d097df2d7](https://github.com/angular/angular-cli/commit/d097df2d7088dd2bb97643c3acfc1f977a767dd9) | fix | correct Vitest coverage path resolution for JSDOM on Windows | +| [cdb607ada](https://github.com/angular/angular-cli/commit/cdb607ada4bf9aaec6ed8aafd8826d782fd13109) | fix | correctly configure per-browser headless mode in Vitest runner | +| [244931ece](https://github.com/angular/angular-cli/commit/244931ece877a1cacd1cfce64314e04a52526f80) | fix | correctly invoke `isTTY` as a function | +| [54d542738](https://github.com/angular/angular-cli/commit/54d542738e23c275ac6827f19da92213c405f9e2) | fix | ensure correct URL joining for prerender routes | +| [a28b38bbe](https://github.com/angular/angular-cli/commit/a28b38bbeba0977e99142a15d1ecc77c15abc416) | fix | force dev-server to use HTTP/1.1 when using SSR with SSL | +| [59ff867f0](https://github.com/angular/angular-cli/commit/59ff867f0d2e7f7f88480deefa0ee470c037197a) | fix | normalize `--include` paths to posix | + +### @angular/ssr + +| Commit | Type | Description | +| --------------------------------------------------------------------------------------------------- | ---- | ------------------------------------------------------------ | +| [03e231216](https://github.com/angular/angular-cli/commit/03e231216d3b8ba0de81da53a446eff0c701658d) | fix | handle `X-Forwarded-Prefix` and `APP_BASE_HREF` in redirects | +| [3cac01882](https://github.com/angular/angular-cli/commit/3cac0188271175e12cc238c6610b542f3ae14db3) | fix | prevent redirect loop with encoded query parameters | + + + # 21.0.0 (2025-11-19) diff --git a/package.json b/package.json index 14e9cafef45d..db622e668e4e 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@angular/devkit-repo", - "version": "21.0.0", + "version": "21.0.1", "private": true, "description": "Software Development Kit for Angular", "keywords": [